diff options
| author | Nagi5Yeq <wu@x-nagi.com> | 2020-05-30 15:52:36 +0800 |
|---|---|---|
| committer | Nagi5Yeq <wu@x-nagi.com> | 2020-05-30 15:52:36 +0800 |
| commit | 30726a1872c92d40424d496fc52043ca452d935f (patch) | |
| tree | 86ce09251183ee544033ba8bfa9f51199aa58628 /TypeManager.cc | |
| parent | 4c9d2d541c90968db2065260dc94c3be9e8adef9 (diff) | |
support for array access (partial)
Diffstat (limited to 'TypeManager.cc')
| -rw-r--r-- | TypeManager.cc | 76 |
1 files changed, 34 insertions, 42 deletions
diff --git a/TypeManager.cc b/TypeManager.cc index 55b172e..4a510eb 100644 --- a/TypeManager.cc +++ b/TypeManager.cc @@ -36,56 +36,41 @@ std::pair<std::shared_ptr<Type>, Value> std::dynamic_pointer_cast<IntegerBaseType>(RightType); std::shared_ptr<PointerType> LeftPointerType = std::dynamic_pointer_cast<PointerType>(LeftType); + std::shared_ptr<PointerType> RightPointerType = + std::dynamic_pointer_cast<PointerType>(RightType); std::shared_ptr<ArrayType> LeftArrayType = std::dynamic_pointer_cast<ArrayType>(LeftType); - // array or pointer access - if (op == BinaryOperator::ARRAY_ACCESS) { - if (LeftArrayType != nullptr) { - if (RightIntegerBaseType == nullptr) { - Log(LogLevel::PCC_ERROR, - "cannot access the array %s with a non-integer type %s", - LeftType->GetCommonName(), RightType->GetCommonName()); - return {nullptr, nullptr}; - } - std::shared_ptr<Type> LeftIndexType = LeftArrayType->GetIndexType(); - Value CastedInedx = - builder->CreateSExtOrTrunc(right, LeftIndexType->GetLLVMType()); - return {LeftArrayType->GetElementType(), - LeftType->CreateBinaryOperation(op, left, CastedInedx, - context)}; + // add/sub a pointer with a integer + if (LeftPointerType != nullptr && RightPointerType == nullptr) { + if (op != BinaryOperator::ADD && op != BinaryOperator::SUB) { + Log(LogLevel::PCC_ERROR, "unsupported operation %s on %s and %s", + GetOperatorName(op), LeftType->GetCommonName(), + RightType->GetCommonName()); + return {nullptr, nullptr}; } - if (LeftPointerType != nullptr) { - if (RightIntegerBaseType == nullptr) { - Log(LogLevel::PCC_ERROR, - "cannot access the pointer %s with a non-integer type %s", - LeftType->GetCommonName(), RightType->GetCommonName()); - return {nullptr, nullptr}; - } - Value CastedInedx = builder->CreateSExtOrTrunc( - right, PointerIndexType_->GetLLVMType()); - return {LeftPointerType->GetElementType(), - LeftType->CreateBinaryOperation(op, left, CastedInedx, - context)}; + if (RightIntegerBaseType == nullptr) { + Log(LogLevel::PCC_ERROR, + "can not add pointer with non-integer type %s", + RightType->GetCommonName()); + return {nullptr, nullptr}; } - Log(LogLevel::PCC_ERROR, - "the left operand type %s is not array or pointer", - LeftType->GetCommonName()); - return {nullptr, nullptr}; + Value CastedInedx = + builder->CreateSExtOrTrunc(right, PointerIndexType_->GetLLVMType()); + return {LeftType, builder->CreateInBoundsGEP(left, CastedInedx)}; } - // add/sub a pointer with a integer - if (op == BinaryOperator::ADD || op == BinaryOperator::SUB) { - if (LeftPointerType != nullptr) { - if (RightIntegerBaseType == nullptr) { - Log(LogLevel::PCC_ERROR, - "can not add pointer with non-integer type %s"); - return {nullptr, nullptr}; - } - Value CastedInedx = builder->CreateSExtOrTrunc( - right, PointerIndexType_->GetLLVMType()); - return {LeftType, builder->CreateInBoundsGEP(left, CastedInedx)}; + // pointer sub case + if (LeftPointerType != nullptr && RightPointerType != nullptr && + op == BinaryOperator::SUB) { + if (LeftType != RightType) { + Log(LogLevel::PCC_ERROR, + "cannot sub to pointers of different type"); + return {nullptr, nullptr}; } + Value result = + LeftType->CreateBinaryOperation(op, left, right, context); + return {PointerDifferenceType_, result}; } // other operations will require the types of left and right are the same. @@ -242,5 +227,12 @@ std::shared_ptr<FunctionType> TypeManager::CreateFunctionType( FunctionTypes_.push_back(NewType); return NewType; } +std::shared_ptr<Type> TypeManager::GetPointerIndexType_() { + return PointerIndexType_; +} + +std::shared_ptr<Type> TypeManager::GetPointerDifferenceType_() { + return PointerDifferenceType_; +} } // namespace pcc |
