From 4a5bc55769804d003d6cd9f8c16eefb76bb53d1b Mon Sep 17 00:00:00 2001 From: Nagi5Yeq Date: Sun, 31 May 2020 13:11:44 +0800 Subject: full support of array, pointer and record stuffs --- node/ExprNode.cc | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'node/ExprNode.cc') diff --git a/node/ExprNode.cc b/node/ExprNode.cc index e15d39e..13a85e9 100644 --- a/node/ExprNode.cc +++ b/node/ExprNode.cc @@ -152,6 +152,62 @@ Value ArrayAccessNode::CodeGen() { return nullptr; } +DereferenceNode::DereferenceNode(Context* context, + std::shared_ptr lhs) + : ExprNode(context) + , lhs_(lhs) {} + +Value DereferenceNode::CodeGen() { + Value value = lhs_->CodeGen(); + std::shared_ptr pointer = + std::dynamic_pointer_cast(lhs_->GetType()); + if (pointer == nullptr) { + Log(LogLevel::PCC_ERROR, "type %s is not a valid type for dereference", + lhs_->GetType()->GetCommonName()); + return nullptr; + } + Value zero = llvm::ConstantInt::get( + context_->GetTypeManager()->GetPointerIndexType_()->GetLLVMType(), 0); + type_ = pointer; + return context_->GetBuilder()->CreateInBoundsGEP(value, zero); +} + +MemberAccessNode::MemberAccessNode(Context* context, + std::shared_ptr lhs, + std::string&& rhs) + : ExprNode(context) + , lhs_(lhs) + , rhs_(std::move(rhs)) {} + +Value MemberAccessNode::CodeGen() { + llvm::IRBuilder<>* builder = context_->GetBuilder(); + TypeManager* manager = context_->GetTypeManager(); + Value left = lhs_->CodeGen(); + std::shared_ptr LeftType = + std::dynamic_pointer_cast(lhs_->GetType()); + if (LeftType == nullptr) { + Log(LogLevel::PCC_ERROR, + "type %s is not a valid type for member access", + lhs_->GetType()->GetCommonName()); + return nullptr; + } + std::shared_ptr LeftInner = + std::dynamic_pointer_cast(LeftType->GetElementType()); + if (LeftInner == nullptr) { + Log(LogLevel::PCC_ERROR, "type %s is not a record type", + LeftType->GetElementType()->GetCommonName()); + return nullptr; + } + int MemberIndex; + std::shared_ptr MemberType; + std::tie(MemberIndex, MemberType) = LeftInner->GetMember(rhs_); + llvm::Type* IndexLLLVMType = manager->GetPointerIndexType_()->GetLLVMType(); + Value indices[2] = {llvm::ConstantInt::get(IndexLLLVMType, 0), + llvm::ConstantInt::get(IndexLLLVMType, MemberIndex)}; + type_ = manager->GetPointerType(MemberType); + return builder->CreateInBoundsGEP(left, indices); +} + IdentifierNode::IdentifierNode(Context* context, const std::string& name) : ExprNode(context) , name_(name) {} -- cgit