Writing LLVM int/string input

Viewed 916

I am trying to generate llvm-ir from AST.

For displaying the integer output I added,

Constant *CalleeF = TheModule->getOrInsertFunction("printf",FunctionType::get(IntegerType::getInt32Ty(Context), PointerType::get(Type::getInt8Ty(Context), 0), true);`

And while calling print function I wrote,

Value* PrintStmt::codegen(){
  Value* V,*val,*to_print;
  vector<Value *> ArgsV;
  for (unsigned int i = 0, e = outs.size(); i != e; ++i){
     to_print = outs[i]->codegen();
     if(outs[i]->type=="int"){
         val=Builder.CreateGlobalStringPtr("%d");
     }
  ArgsV.push_back(val);
  ArgsV.push_back(to_print);
  V =  Builder.CreateCall(CalleeF, ArgsV, "printfCall");
 }
 return V;
}

What similar code should I write for getting input from user, i.e for scanf call?

1 Answers

For a scanf call you could first declare its prototype

llvm::FunctionType *readFnType = llvm::FunctionType::get(builder.getInt32Ty(), true); 
llvm::Function* readfn = llvm::Function::Create(readFnType, llvm::GlobalValue::ExternalLinkage, "scanf", TheModule));

And call it like so

std::vector<Value*> ArgsV; // holds codegen IR for each argument
std::string StringFormat; // holds string formatting for all arguments
for(auto& arg : Args){
        if(auto v = arg->codegen()){ 
            if(v->getType()->isDoubleTy())
                StringFormat += "%lf "; // 
            else if(v->getType()->isIntegerTy())
                StringFormat += "%d ";
            ArgsV.push_back(symbolTable[arg.name]);
        }else return nullptr;
    }
ArgsV.insert(ArgsV.begin(), builder.CreateGlobalStringPtr(StringFormat));
return builder.CreateCall(TheModule->getFunction("scanf"), ArgsV, "scanfCall");

Where symbolTable is a map of variable/argument names to a Value* holding the variable's stack allocated address. Recall that scanf takes the address of the variable to be written to, which explains the symbol table lookup.

It is also worth mentioning that this makes scanf inherently unsafe. You should consider using the fgets and gets functions instead.

Related