diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/OpenMPClause.cpp | 83 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 270 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 47 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 17 |
4 files changed, 267 insertions, 150 deletions
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index cacfa53d8c9..73981cf0ff7 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -530,25 +530,78 @@ OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N) { return new (Mem) OMPDependClause(N); } -OMPMapClause *OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc, ArrayRef<Expr *> VL, - OpenMPMapClauseKind TypeModifier, - OpenMPMapClauseKind Type, - bool TypeIsImplicit, - SourceLocation TypeLoc) { - void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size())); - OMPMapClause *Clause = - new (Mem) OMPMapClause(TypeModifier, Type, TypeIsImplicit, TypeLoc, - StartLoc, LParenLoc, EndLoc, VL.size()); - Clause->setVarRefs(VL); +unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber( + MappableExprComponentListsRef ComponentLists) { + unsigned TotalNum = 0u; + for (auto &C : ComponentLists) + TotalNum += C.size(); + return TotalNum; +} + +unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber( + ArrayRef<ValueDecl *> Declarations) { + unsigned TotalNum = 0u; + llvm::SmallPtrSet<const ValueDecl *, 8> Cache; + for (auto *D : Declarations) { + const ValueDecl *VD = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr; + if (Cache.count(VD)) + continue; + ++TotalNum; + Cache.insert(VD); + } + return TotalNum; +} + +OMPMapClause * +OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists, + OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, + bool TypeIsImplicit, SourceLocation TypeLoc) { + + unsigned NumVars = Vars.size(); + unsigned NumUniqueDeclarations = + getUniqueDeclarationsTotalNumber(Declarations); + unsigned NumComponentLists = ComponentLists.size(); + unsigned NumComponents = getComponentsTotalNumber(ComponentLists); + + // We need to allocate: + // NumVars x Expr* - we have an original list expression for each clause list + // entry. + // NumUniqueDeclarations x ValueDecl* - unique base declarations associated + // with each component list. + // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the + // number of lists for each unique declaration and the size of each component + // list. + // NumComponents x MappableComponent - the total of all the components in all + // the lists. + void *Mem = C.Allocate( + totalSizeToAlloc<Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent>( + NumVars, NumUniqueDeclarations, + NumUniqueDeclarations + NumComponentLists, NumComponents)); + OMPMapClause *Clause = new (Mem) OMPMapClause( + TypeModifier, Type, TypeIsImplicit, TypeLoc, StartLoc, LParenLoc, EndLoc, + NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents); + + Clause->setVarRefs(Vars); + Clause->setClauseInfo(Declarations, ComponentLists); Clause->setMapTypeModifier(TypeModifier); Clause->setMapType(Type); Clause->setMapLoc(TypeLoc); return Clause; } -OMPMapClause *OMPMapClause::CreateEmpty(const ASTContext &C, unsigned N) { - void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N)); - return new (Mem) OMPMapClause(N); +OMPMapClause *OMPMapClause::CreateEmpty(const ASTContext &C, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, + unsigned NumComponents) { + void *Mem = C.Allocate( + totalSizeToAlloc<Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent>( + NumVars, NumUniqueDeclarations, + NumUniqueDeclarations + NumComponentLists, NumComponents)); + return new (Mem) OMPMapClause(NumVars, NumUniqueDeclarations, + NumComponentLists, NumComponents); } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index d2c08ca9728..07417020758 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -81,8 +81,6 @@ public: }; private: - typedef SmallVector<Expr *, 4> MapInfo; - struct DSAInfo { OpenMPClauseKind Attributes; Expr *RefExpr; @@ -92,14 +90,16 @@ private: typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy; typedef std::pair<unsigned, VarDecl *> LCDeclInfo; typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy; - typedef llvm::DenseMap<ValueDecl *, MapInfo> MappedDeclsTy; + typedef llvm::DenseMap< + ValueDecl *, OMPClauseMappableExprCommon::MappableExprComponentLists> + MappedExprComponentsTy; typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>> CriticalsWithHintsTy; struct SharingMapTy { DeclSAMapTy SharingMap; AlignedMapTy AlignedMap; - MappedDeclsTy MappedDecls; + MappedExprComponentsTy MappedExprComponents; LoopControlVariablesMapTy LCVMap; DefaultDataSharingAttributes DefaultAttr; SourceLocation DefaultAttrLoc; @@ -340,11 +340,12 @@ public: Scope *getCurScope() { return Stack.back().CurScope; } SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; } - // Do the check specified in MapInfoCheck and return true if any issue is - // found. - template <class MapInfoCheck> - bool checkMapInfoForVar(ValueDecl *VD, bool CurrentRegionOnly, - MapInfoCheck Check) { + // Do the check specified in \a Check to all component lists and return true + // if any issue is found. + bool checkMappableExprComponentListsForDecl( + ValueDecl *VD, bool CurrentRegionOnly, + const llvm::function_ref<bool( + OMPClauseMappableExprCommon::MappableExprComponentListRef)> &Check) { auto SI = Stack.rbegin(); auto SE = Stack.rend(); @@ -358,21 +359,26 @@ public: } for (; SI != SE; ++SI) { - auto MI = SI->MappedDecls.find(VD); - if (MI != SI->MappedDecls.end()) { - for (Expr *E : MI->second) { - if (Check(E)) + auto MI = SI->MappedExprComponents.find(VD); + if (MI != SI->MappedExprComponents.end()) + for (auto &L : MI->second) + if (Check(L)) return true; - } - } } return false; } - void addExprToVarMapInfo(ValueDecl *VD, Expr *E) { - if (Stack.size() > 1) { - Stack.back().MappedDecls[VD].push_back(E); - } + // Create a new mappable expression component list associated with a given + // declaration and initialize it with the provided list of components. + void addMappableExpressionComponents( + ValueDecl *VD, + OMPClauseMappableExprCommon::MappableExprComponentListRef Components) { + assert(Stack.size() > 1 && + "Not expecting to retrieve components from a empty stack!"); + auto &MEC = Stack.back().MappedExprComponents[VD]; + // Create new entry and append the new components there. + MEC.resize(MEC.size() + 1); + MEC.back().append(Components.begin(), Components.end()); } }; bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { @@ -7554,8 +7560,10 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, // A list item cannot appear in both a map clause and a data-sharing // attribute clause on the same construct if (DSAStack->getCurrentDirective() == OMPD_target) { - if(DSAStack->checkMapInfoForVar(VD, /* CurrentRegionOnly = */ true, - [&](Expr *RE) -> bool {return true;})) { + if (DSAStack->checkMappableExprComponentListsForDecl( + VD, /* CurrentRegionOnly = */ true, + [&](OMPClauseMappableExprCommon::MappableExprComponentListRef) + -> bool { return true; })) { Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) << getOpenMPClauseName(OMPC_private) << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); @@ -7799,8 +7807,10 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, // A list item cannot appear in both a map clause and a data-sharing // attribute clause on the same construct if (CurrDir == OMPD_target) { - if(DSAStack->checkMapInfoForVar(VD, /* CurrentRegionOnly = */ true, - [&](Expr *RE) -> bool {return true;})) { + if (DSAStack->checkMappableExprComponentListsForDecl( + VD, /* CurrentRegionOnly = */ true, + [&](OMPClauseMappableExprCommon::MappableExprComponentListRef) + -> bool { return true; })) { Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) << getOpenMPClauseName(OMPC_firstprivate) << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); @@ -9706,8 +9716,11 @@ static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, // Return the expression of the base of the map clause or null if it cannot // be determined and do all the necessary checks to see if the expression is -// valid as a standalone map clause expression. -static Expr *CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E) { +// valid as a standalone map clause expression. In the process, record all the +// components of the expression. +static Expr *CheckMapClauseExpressionBase( + Sema &SemaRef, Expr *E, + OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents) { SourceLocation ELoc = E->getExprLoc(); SourceRange ERange = E->getSourceRange(); @@ -9765,6 +9778,10 @@ static Expr *CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E) { // section before that. AllowUnitySizeArraySection = false; AllowWholeSizeArraySection = false; + + // Record the component. + CurComponents.push_back(OMPClauseMappableExprCommon::MappableComponent( + CurE, CurE->getDecl())); continue; } @@ -9819,6 +9836,10 @@ static Expr *CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E) { // AllowUnitySizeArraySection = false; AllowWholeSizeArraySection = false; + + // Record the component. + CurComponents.push_back( + OMPClauseMappableExprCommon::MappableComponent(CurE, FD)); continue; } @@ -9837,6 +9858,10 @@ static Expr *CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E) { if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, E->getType())) AllowWholeSizeArraySection = false; + + // Record the component - we don't have any declaration associated. + CurComponents.push_back( + OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); continue; } @@ -9882,6 +9907,10 @@ static Expr *CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E) { << CurE->getSourceRange(); break; } + + // Record the component - we don't have any declaration associated. + CurComponents.push_back( + OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); continue; } @@ -9897,57 +9926,11 @@ static Expr *CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E) { // Return true if expression E associated with value VD has conflicts with other // map information. -static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, - Expr *E, bool CurrentRegionOnly) { +static bool CheckMapConflicts( + Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, + bool CurrentRegionOnly, + OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents) { assert(VD && E); - - // Types used to organize the components of a valid map clause. - typedef std::pair<Expr *, ValueDecl *> MapExpressionComponent; - typedef SmallVector<MapExpressionComponent, 4> MapExpressionComponents; - - // Helper to extract the components in the map clause expression E and store - // them into MEC. This assumes that E is a valid map clause expression, i.e. - // it has already passed the single clause checks. - auto ExtractMapExpressionComponents = [](Expr *TE, - MapExpressionComponents &MEC) { - while (true) { - TE = TE->IgnoreParenImpCasts(); - - if (auto *CurE = dyn_cast<DeclRefExpr>(TE)) { - MEC.push_back( - MapExpressionComponent(CurE, cast<VarDecl>(CurE->getDecl()))); - break; - } - - if (auto *CurE = dyn_cast<MemberExpr>(TE)) { - auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); - - MEC.push_back(MapExpressionComponent( - CurE, cast<FieldDecl>(CurE->getMemberDecl()))); - if (isa<CXXThisExpr>(BaseE)) - break; - - TE = BaseE; - continue; - } - - if (auto *CurE = dyn_cast<ArraySubscriptExpr>(TE)) { - MEC.push_back(MapExpressionComponent(CurE, nullptr)); - TE = CurE->getBase()->IgnoreParenImpCasts(); - continue; - } - - if (auto *CurE = dyn_cast<OMPArraySectionExpr>(TE)) { - MEC.push_back(MapExpressionComponent(CurE, nullptr)); - TE = CurE->getBase()->IgnoreParenImpCasts(); - continue; - } - - llvm_unreachable( - "Expecting only valid map clause expressions at this point!"); - } - }; - SourceLocation ELoc = E->getExprLoc(); SourceRange ERange = E->getSourceRange(); @@ -9955,26 +9938,27 @@ static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, // the expression under test with the components of the expressions that are // already in the stack. - MapExpressionComponents CurComponents; - ExtractMapExpressionComponents(E, CurComponents); - assert(!CurComponents.empty() && "Map clause expression with no components!"); - assert(CurComponents.back().second == VD && + assert(CurComponents.back().getAssociatedDeclaration() == VD && "Map clause expression with unexpected base!"); // Variables to help detecting enclosing problems in data environment nests. bool IsEnclosedByDataEnvironmentExpr = false; - Expr *EnclosingExpr = nullptr; + const Expr *EnclosingExpr = nullptr; + + bool FoundError = DSAS->checkMappableExprComponentListsForDecl( + VD, CurrentRegionOnly, + [&](OMPClauseMappableExprCommon::MappableExprComponentListRef + StackComponents) -> bool { - bool FoundError = - DSAS->checkMapInfoForVar(VD, CurrentRegionOnly, [&](Expr *RE) -> bool { - MapExpressionComponents StackComponents; - ExtractMapExpressionComponents(RE, StackComponents); assert(!StackComponents.empty() && "Map clause expression with no components!"); - assert(StackComponents.back().second == VD && + assert(StackComponents.back().getAssociatedDeclaration() == VD && "Map clause expression with unexpected base!"); + // The whole expression in the stack. + auto *RE = StackComponents.front().getAssociatedExpression(); + // Expressions must start from the same base. Here we detect at which // point both expressions diverge from each other and see if we can // detect if the memory referred to both expressions is contiguous and @@ -9988,25 +9972,27 @@ static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] // At most one list item can be an array item derived from a given // variable in map clauses of the same construct. - if (CurrentRegionOnly && (isa<ArraySubscriptExpr>(CI->first) || - isa<OMPArraySectionExpr>(CI->first)) && - (isa<ArraySubscriptExpr>(SI->first) || - isa<OMPArraySectionExpr>(SI->first))) { - SemaRef.Diag(CI->first->getExprLoc(), + if (CurrentRegionOnly && + (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || + isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && + (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || + isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { + SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), diag::err_omp_multiple_array_items_in_map_clause) - << CI->first->getSourceRange(); - ; - SemaRef.Diag(SI->first->getExprLoc(), diag::note_used_here) - << SI->first->getSourceRange(); + << CI->getAssociatedExpression()->getSourceRange(); + SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), + diag::note_used_here) + << SI->getAssociatedExpression()->getSourceRange(); return true; } // Do both expressions have the same kind? - if (CI->first->getStmtClass() != SI->first->getStmtClass()) + if (CI->getAssociatedExpression()->getStmtClass() != + SI->getAssociatedExpression()->getStmtClass()) break; // Are we dealing with different variables/fields? - if (CI->second != SI->second) + if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) break; } @@ -10030,14 +10016,15 @@ static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, } } - QualType DerivedType = std::prev(CI)->first->getType(); - SourceLocation DerivedLoc = std::prev(CI)->first->getExprLoc(); + QualType DerivedType = + std::prev(CI)->getAssociatedDeclaration()->getType(); + SourceLocation DerivedLoc = + std::prev(CI)->getAssociatedExpression()->getExprLoc(); // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] // If the type of a list item is a reference to a type T then the type // will be considered to be T for all purposes of this clause. - if (DerivedType->isReferenceType()) - DerivedType = DerivedType->getPointeeType(); + DerivedType = DerivedType.getNonReferenceType(); // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] // A variable for which the type is pointer and an array section @@ -10079,7 +10066,7 @@ static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, } // The current expression uses the same base as other expression in the - // data environment but does not contain it completelly. + // data environment but does not contain it completely. if (!CurrentRegionOnly && SI != SE) EnclosingExpr = RE; @@ -10102,7 +10089,7 @@ static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, // If a list item is an element of a structure, and a different element of // the structure has a corresponding list item in the device data environment // prior to a task encountering the construct associated with the map clause, - // then the list item must also have a correspnding list item in the device + // then the list item must also have a corresponding list item in the device // data environment prior to the task encountering the construct. // if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { @@ -10125,6 +10112,17 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, SourceLocation LParenLoc, SourceLocation EndLoc) { SmallVector<Expr *, 4> Vars; + // Keep track of the mappable components and base declarations in this clause. + // Each entry in the list is going to have a list of components associated. We + // record each set of the components so that we can build the clause later on. + // In the end we should have the same amount of declarations and component + // lists. + OMPClauseMappableExprCommon::MappableExprComponentLists ClauseComponents; + SmallVector<ValueDecl *, 16> ClauseBaseDeclarations; + + ClauseComponents.reserve(VarList.size()); + ClauseBaseDeclarations.reserve(VarList.size()); + for (auto &RE : VarList) { assert(RE && "Null expr in omp map"); if (isa<DependentScopeDeclRefExpr>(RE)) { @@ -10153,25 +10151,29 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, continue; } - // Obtain the array or member expression bases if required. - auto *BE = CheckMapClauseExpressionBase(*this, SimpleExpr); + OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; + ValueDecl *CurDeclaration = nullptr; + + // Obtain the array or member expression bases if required. Also, fill the + // components array with all the components identified in the process. + auto *BE = CheckMapClauseExpressionBase(*this, SimpleExpr, CurComponents); if (!BE) continue; - // If the base is a reference to a variable, we rely on that variable for - // the following checks. If it is a 'this' expression we rely on the field. - ValueDecl *D = nullptr; - if (auto *DRE = dyn_cast<DeclRefExpr>(BE)) { - D = DRE->getDecl(); - } else { - auto *ME = cast<MemberExpr>(BE); - assert(isa<CXXThisExpr>(ME->getBase()) && "Unexpected expression!"); - D = ME->getMemberDecl(); - } - assert(D && "Null decl on map clause."); + assert(!CurComponents.empty() && + "Invalid mappable expression information."); - auto *VD = dyn_cast<VarDecl>(D); - auto *FD = dyn_cast<FieldDecl>(D); + // For the following checks, we rely on the base declaration which is + // expected to be associated with the last component. The declaration is + // expected to be a variable or a field (if 'this' is being mapped). + CurDeclaration = CurComponents.back().getAssociatedDeclaration(); + assert(CurDeclaration && "Null decl on map clause."); + assert( + CurDeclaration->isCanonicalDecl() && + "Expecting components to have associated only canonical declarations."); + + auto *VD = dyn_cast<VarDecl>(CurDeclaration); + auto *FD = dyn_cast<FieldDecl>(CurDeclaration); assert((VD || FD) && "Only variables or fields are expected here!"); (void)FD; @@ -10196,19 +10198,17 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, // Check conflicts with other map clause expressions. We check the conflicts // with the current construct separately from the enclosing data // environment, because the restrictions are different. - if (CheckMapConflicts(*this, DSAStack, D, SimpleExpr, - /*CurrentRegionOnly=*/true)) + if (CheckMapConflicts(*this, DSAStack, CurDeclaration, SimpleExpr, + /*CurrentRegionOnly=*/true, CurComponents)) break; - if (CheckMapConflicts(*this, DSAStack, D, SimpleExpr, - /*CurrentRegionOnly=*/false)) + if (CheckMapConflicts(*this, DSAStack, CurDeclaration, SimpleExpr, + /*CurrentRegionOnly=*/false, CurComponents)) break; // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] // If the type of a list item is a reference to a type T then the type will // be considered to be T for all purposes of this clause. - QualType Type = D->getType(); - if (Type->isReferenceType()) - Type = Type->getPointeeType(); + QualType Type = CurDeclaration->getType().getNonReferenceType(); // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] // A list item must have a mappable type. @@ -10254,20 +10254,32 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); - ReportOriginalDSA(*this, DSAStack, D, DVar); + ReportOriginalDSA(*this, DSAStack, CurDeclaration, DVar); continue; } } + // Save the current expression. Vars.push_back(RE); - DSAStack->addExprToVarMapInfo(D, RE); + + // Store the components in the stack so that they can be used to check + // against other clauses later on. + DSAStack->addMappableExpressionComponents(CurDeclaration, CurComponents); + + // Save the components and declaration to create the clause. For purposes of + // the clause creation, any component list that has has base 'this' uses + // null has + ClauseComponents.resize(ClauseComponents.size() + 1); + ClauseComponents.back().append(CurComponents.begin(), CurComponents.end()); + ClauseBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr + : CurDeclaration); } // We need to produce a map clause even if we don't have variables so that // other diagnostics related with non-existing map clauses are accurate. - return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, - MapTypeModifier, MapType, IsMapTypeImplicit, - MapLoc); + return OMPMapClause::Create( + Context, StartLoc, LParenLoc, EndLoc, Vars, ClauseBaseDeclarations, + ClauseComponents, MapTypeModifier, MapType, IsMapTypeImplicit, MapLoc); } QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 2de0b58fa4a..3d6b8acedac 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1861,9 +1861,15 @@ OMPClause *OMPClauseReader::readClause() { case OMPC_device: C = new (Context) OMPDeviceClause(); break; - case OMPC_map: - C = OMPMapClause::CreateEmpty(Context, Record[Idx++]); + case OMPC_map: { + unsigned NumVars = Record[Idx++]; + unsigned NumDeclarations = Record[Idx++]; + unsigned NumLists = Record[Idx++]; + unsigned NumComponents = Record[Idx++]; + C = OMPMapClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists, + NumComponents); break; + } case OMPC_num_teams: C = new (Context) OMPNumTeamsClause(); break; @@ -2225,12 +2231,45 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) { C->setMapLoc(Reader->ReadSourceLocation(Record, Idx)); C->setColonLoc(Reader->ReadSourceLocation(Record, Idx)); auto NumVars = C->varlist_size(); + auto UniqueDecls = C->getUniqueDeclarationsNum(); + auto TotalLists = C->getTotalComponentListNum(); + auto TotalComponents = C->getTotalComponentsNum(); + SmallVector<Expr *, 16> Vars; Vars.reserve(NumVars); - for (unsigned i = 0; i != NumVars; ++i) { + for (unsigned i = 0; i != NumVars; ++i) Vars.push_back(Reader->Reader.ReadSubExpr()); - } C->setVarRefs(Vars); + + SmallVector<ValueDecl *, 16> Decls; + Decls.reserve(UniqueDecls); + for (unsigned i = 0; i < UniqueDecls; ++i) + Decls.push_back( + Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx)); + C->setUniqueDecls(Decls); + + SmallVector<unsigned, 16> ListsPerDecl; + ListsPerDecl.reserve(UniqueDecls); + for (unsigned i = 0; i < UniqueDecls; ++i) + ListsPerDecl.push_back(Record[Idx++]); + C->setDeclNumLists(ListsPerDecl); + + SmallVector<unsigned, 32> ListSizes; + ListSizes.reserve(TotalLists); + for (unsigned i = 0; i < TotalLists; ++i) + ListSizes.push_back(Record[Idx++]); + C->setComponentListSizes(ListSizes); + + SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components; + Components.reserve(TotalComponents); + for (unsigned i = 0; i < TotalComponents; ++i) { + Expr *AssociatedExpr = Reader->Reader.ReadSubExpr(); + ValueDecl *AssociatedDecl = + Reader->Reader.ReadDeclAs<ValueDecl>(Reader->F, Record, Idx); + Components.push_back(OMPClauseMappableExprCommon::MappableComponent( + AssociatedExpr, AssociatedDecl)); + } + C->setComponents(Components, ListSizes); } void OMPClauseReader::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) { diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 39d6361303f..929faccbad8 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2021,13 +2021,26 @@ void OMPClauseWriter::VisitOMPDeviceClause(OMPDeviceClause *C) { void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) { Record.push_back(C->varlist_size()); + Record.push_back(C->getUniqueDeclarationsNum()); + Record.push_back(C->getTotalComponentListNum()); + Record.push_back(C->getTotalComponentsNum()); Record.AddSourceLocation(C->getLParenLoc()); Record.push_back(C->getMapTypeModifier()); Record.push_back(C->getMapType()); Record.AddSourceLocation(C->getMapLoc()); Record.AddSourceLocation(C->getColonLoc()); - for (auto *VE : C->varlists()) - Record.AddStmt(VE); + for (auto *E : C->varlists()) + Record.AddStmt(E); + for (auto *D : C->all_decls()) + Record.AddDeclRef(D); + for (auto N : C->all_num_lists()) + Record.push_back(N); + for (auto N : C->all_lists_sizes()) + Record.push_back(N); + for (auto &M : C->all_components()) { + Record.AddStmt(M.getAssociatedExpression()); + Record.AddDeclRef(M.getAssociatedDeclaration()); + } } void OMPClauseWriter::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) { |