//===-- sotoc/src/TargetRegionVariable.cpp --------------------------------===////// The LLVM Compiler Infrastructure//// This file is distributed under the University of Illinois Open Source// License. See LICENSE.TXT for details.////===----------------------------------------------------------------------===////===----------------------------------------------------------------------===//#include"clang/AST/Decl.h"#include"clang/AST/Expr.h"#include"clang/AST/Type.h"#include"TargetRegionVariable.h"TargetRegionVariable::TargetRegionVariable(constclang::CapturedStmt::Capture*Capture,conststd::map<clang::VarDecl*,clang::Expr*>&MappingLowerBounds):Capture(Capture),Decl(Capture->getCapturedVar()),NumVariableArrayDims(0),OmpMappingLowerBound(MappingLowerBounds){VarName=Decl->getDeclName().getAsString();determineShapes(Decl->getType());}voidTargetRegionVariable::determineShapes(constclang::QualTypeT){// We want to determine the shapes of this variable from it's qualifiersif(constauto*AT=llvm::dyn_cast<clang::ArrayType>(T.getTypePtr())){// We have a constant or variable length arrayif(constauto*CAT=llvm::dyn_cast<clang::ConstantArrayType>(AT)){Shapes.push_back(TargetRegionVariableShape(CAT));}elseif(constauto*VAT=llvm::dyn_cast<clang::VariableArrayType>(AT)){Shapes.push_back(TargetRegionVariableShape(VAT,NumVariableArrayDims));}// The variable NumVariableArrayDims is basically stored to keep track how// many array dimensions there are. Each variable length array dimension we// record gets an index, later used to generate the __sotoc_vla_dimX// parameters in which the host sends the variable size to the target// region.NumVariableArrayDims++;returndetermineShapes(AT->getElementType());}elseif(auto*PT=llvm::dyn_cast<clang::PointerType>(T.getTypePtr())){// Pointers are easy: just record that we have a pointer (default constructed)Shapes.push_back(TargetRegionVariableShape());returndetermineShapes(PT->getPointeeType());}elseif(auto*PT=llvm::dyn_cast<clang::ParenType>(T.getTypePtr())){// Clang uses ParenType as when there are parenthesis in the type declaration.Shapes.push_back(TargetRegionVariableShape(PT));returndetermineShapes(PT->getInnerType());}else{// We have found the base type (without array dimensions or pointer specifiers).BaseTypeName=T.getAsString();}}boolTargetRegionVariable::containsArray()const{if(!Shapes.empty()){for(autoShape:Shapes){if(Shape.isArray()){returntrue;}}}returnfalse;}boolTargetRegionVariable::containsPointer()const{if(!Shapes.empty()){for(autoShape:Shapes){if(Shape.isPointer()){returntrue;}}}returnfalse;}//TODO: We might not need this anymoreboolTargetRegionVariable::passedByPointer()const{if(containsArray()||containsPointer()){// Arrays are always passed by pointerreturntrue;}returnCapture->capturesVariable();}llvm::Optional<clang::Expr*>TargetRegionVariable::arrayLowerBound()const{autoFindBound=OmpMappingLowerBound.find(Decl);if(FindBound!=OmpMappingLowerBound.cend()){returnllvm::Optional<clang::Expr*>(FindBound->second);}returnllvm::Optional<clang::Expr*>();}