Conceptually, what I would like to do is quite simple. I use the Alloca method described in the Kaleidoscope example paired with mem2reg to reduce the need to manually create Phi nodes.
I implemented several aspects of my custom language, but I had a problem with implementing post increment / decment in a general way.
My AST node PostIncrDecrNodecontains a token denoting ++or --, and an AST node expression that is encoded to return llvm::Value*, like the Kaleidoscope example. I already noticed that I probably would need to return something else, and then llvm::Value*, since my language is very type safe, and I need to know things like signature of integral types, but now I feel that I can also need to track llvm::AllocaInst.
A simple example of a situation is this code:
int myfunction(int i)
{
return i++;
}
My AST print debugging is as follows:
- CompilationUnit:test.str
- FunctionDeclarationNode
- IdentifierNode:int
- IdentifierNode:myfunction
- FunctionParameterNode
- IdentifierNode:int
- IdentifierNode:i
- BlockNode
- ReturnNode
- PostIncrDecrNode
- IdentifierNode:i
The last two lines are an important part here, since I have PostIncrDecrNodeone that contains IdentifierNode, which will be encoded as follows:
Value* IdentifierNode::codeGenInternal(CodeGenContext& context)
{
Value* rtn = NULL;
SharedSymbolEntry entry = context.getSymbolInScopeByName(*value);
Value* val = entry ? entry->llvmVal : NULL;
if(val)
{
IRBuilder<>* builder = context.getIRBuilder();
rtn = builder->CreateLoad(val, value->c_str());
}
else
{
context.handleCodeGenError(*this, "Unknown variable name: " + Twine(value->c_str()));
}
return rtn;
}
SharedSymbolEntry entry = context.getSymbolInScopeByName(*value); shared_ptr to std::String ' IdentifierNode ( ) SharedSymbolEntry ( , llvm::Value*, llvm::AllocaInst*) , AST.
, PostIncrDecrNode alloca, llvm::Value* rtn = builder->CreateLoad(val, value->c_str());.
LLVM llvm::AllocaInst* llvm::Value*, ( , )?
, , .
, , , .