diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -116,6 +116,7 @@ class ObjCPropertyImplDecl; class ObjCProtocolDecl; class ObjCTypeParamDecl; +struct OMPTraitInfo; struct ParsedTargetAttr; class Preprocessor; class Stmt; @@ -2962,6 +2963,14 @@ }; llvm::StringMap SectionInfos; + + /// Return a new OMPTraitInfo object owned by this context. + OMPTraitInfo &getNewOMPTraitInfo(); + +private: + /// All OMPTraitInfo objects live in this collection, one per + /// `pragma omp [begin] declare variant` directive. + SmallVector OMPTraitInfoVector; }; /// Utility function for constructing a nullary selector. diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -7116,22 +7116,27 @@ /// collection of selector sets, each with an associated kind and an ordered /// collection of selectors. A selector has a kind, an optional score/condition, /// and an ordered collection of properties. -struct OMPTraitInfo { +class OMPTraitInfo { + /// Private constructor accesible only by ASTContext. + OMPTraitInfo() {} + friend class ASTContext; + +public: struct OMPTraitProperty { llvm::omp::TraitProperty Kind = llvm::omp::TraitProperty::invalid; }; struct OMPTraitSelector { Expr *ScoreOrCondition = nullptr; llvm::omp::TraitSelector Kind = llvm::omp::TraitSelector::invalid; - llvm::SmallVector Properties; + llvm::SmallVector Properties; }; struct OMPTraitSet { llvm::omp::TraitSet Kind = llvm::omp::TraitSet::invalid; - llvm::SmallVector Selectors; + llvm::SmallVector Selectors; }; /// The outermost level of selector sets. - llvm::SmallVector Sets; + llvm::SmallVector Sets; bool anyScoreOrCondition( llvm::function_ref Cond) { @@ -7157,6 +7162,7 @@ void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const; }; llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo &TI); +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI); } // namespace clang diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3314,7 +3314,7 @@ OMPTraitInfoArgument<"TraitInfos">, ]; let AdditionalMembers = [{ - OMPTraitInfo &getTraitInfo() { return traitInfos; } + OMPTraitInfo &getTraitInfo() { return *traitInfos; } void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy) const; }]; diff --git a/clang/include/clang/Serialization/ASTRecordReader.h b/clang/include/clang/Serialization/ASTRecordReader.h --- a/clang/include/clang/Serialization/ASTRecordReader.h +++ b/clang/include/clang/Serialization/ASTRecordReader.h @@ -260,7 +260,7 @@ } /// Read an OMPTraitInfo object, advancing Idx. - OMPTraitInfo readOMPTraitInfo(); + OMPTraitInfo *readOMPTraitInfo(); /// Read an OpenMP clause, advancing Idx. OMPClause *readOMPClause(); diff --git a/clang/include/clang/Serialization/ASTRecordWriter.h b/clang/include/clang/Serialization/ASTRecordWriter.h --- a/clang/include/clang/Serialization/ASTRecordWriter.h +++ b/clang/include/clang/Serialization/ASTRecordWriter.h @@ -267,7 +267,7 @@ void AddCXXDefinitionData(const CXXRecordDecl *D); /// Write an OMPTraitInfo object. - void writeOMPTraitInfo(const OMPTraitInfo &TI); + void writeOMPTraitInfo(const OMPTraitInfo *TI); void writeOMPClause(OMPClause *C); diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1005,6 +1005,9 @@ for (APValue *Value : APValueCleanups) Value->~APValue(); + + // Destroy the OMPTraitInfo objects that life here. + llvm::DeleteContainerPointers(OMPTraitInfoVector); } void ASTContext::setTraversalScope(const std::vector &TopLevelDecls) { @@ -10838,3 +10841,8 @@ Target->getTargetOpts().Features); } } + +OMPTraitInfo &ASTContext::getNewOMPTraitInfo() { + OMPTraitInfoVector.push_back(new OMPTraitInfo()); + return *OMPTraitInfoVector.back(); +} diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp --- a/clang/lib/AST/AttrImpl.cpp +++ b/clang/lib/AST/AttrImpl.cpp @@ -159,7 +159,7 @@ OS << ")"; } OS << " match("; - traitInfos.print(OS, Policy); + traitInfos->print(OS, Policy); OS << ")"; } diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -1964,3 +1964,7 @@ TI.print(OS, Policy); return OS; } +llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS, + const OMPTraitInfo *TI) { + return TI ? OS << *TI : OS; +} diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -11393,7 +11393,7 @@ SmallVector VariantExprs; SmallVector VMIs; for (const auto *A : FD->specific_attrs()) { - const OMPTraitInfo &TI = A->getTraitInfos(); + const OMPTraitInfo &TI = *A->getTraitInfos(); VMIs.push_back(VariantMatchInfo()); TI.getAsVariantMatchInfo(CGM.getContext(), VMIs.back()); VariantExprs.push_back(A->getVariantFuncRef()); diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1365,7 +1365,7 @@ } // Parse inner context selectors. - OMPTraitInfo TI; + OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo(); parseOMPContextSelectors(Loc, TI); // Parse ')' diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5703,7 +5703,7 @@ OMPTraitInfo &TI, SourceRange SR) { auto *NewAttr = - OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, TI, SR); + OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); FD->addAttr(NewAttr); } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -398,7 +398,8 @@ // Copy the template version of the OMPTraitInfo and run substitute on all // score and condition expressiosn. - OMPTraitInfo TI = Attr.getTraitInfos(); + OMPTraitInfo &TI = S.getASTContext().getNewOMPTraitInfo(); + TI = *Attr.getTraitInfos(); // Try to substitute template parameters in score and condition expressions. auto SubstScoreOrConditionExpr = [&S, Subst](Expr *&E, bool) { diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -12684,8 +12684,8 @@ C->setKindKwLoc(Record.readSourceLocation()); } -OMPTraitInfo ASTRecordReader::readOMPTraitInfo() { - OMPTraitInfo TI; +OMPTraitInfo *ASTRecordReader::readOMPTraitInfo() { + OMPTraitInfo &TI = getContext().getNewOMPTraitInfo(); TI.Sets.resize(readUInt32()); for (auto &Set : TI.Sets) { Set.Kind = readEnum(); @@ -12700,5 +12700,5 @@ Property.Kind = readEnum(); } } - return TI; + return &TI; } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2744,7 +2744,7 @@ return Reader.readVersionTuple(); } - OMPTraitInfo readOMPTraitInfo() { return Reader.readOMPTraitInfo(); } + OMPTraitInfo *readOMPTraitInfo() { return Reader.readOMPTraitInfo(); } template T *GetLocalDeclAs(uint32_t LocalID) { return Reader.GetLocalDeclAs(LocalID); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6624,9 +6624,9 @@ Record.AddSourceLocation(C->getKindKwLoc()); } -void ASTRecordWriter::writeOMPTraitInfo(const OMPTraitInfo &TI) { - writeUInt32(TI.Sets.size()); - for (const auto &Set : TI.Sets) { +void ASTRecordWriter::writeOMPTraitInfo(const OMPTraitInfo *TI) { + writeUInt32(TI->Sets.size()); + for (const auto &Set : TI->Sets) { writeEnum(Set.Kind); writeUInt32(Set.Selectors.size()); for (const auto &Selector : Set.Selectors) { diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -107,7 +107,7 @@ .Case("IdentifierInfo *", "Record.readIdentifier()") .Case("StringRef", "Record.readString()") .Case("ParamIdx", "ParamIdx::deserialize(Record.readInt())") - .Case("OMPTraitInfo", "Record.readOMPTraitInfo()") + .Case("OMPTraitInfo *", "Record.readOMPTraitInfo()") .Default("Record.readInt()"); } @@ -131,7 +131,7 @@ .Case("StringRef", "AddString(" + std::string(name) + ");\n") .Case("ParamIdx", "push_back(" + std::string(name) + ".serialize());\n") - .Case("OMPTraitInfo", + .Case("OMPTraitInfo *", "writeOMPTraitInfo(" + std::string(name) + ");\n") .Default("push_back(" + std::string(name) + ");\n"); } @@ -363,7 +363,7 @@ OS << " if (SA->get" << getUpperName() << "().isValid())\n "; OS << " OS << \" \" << SA->get" << getUpperName() << "().getSourceIndex();\n"; - } else if (type == "OMPTraitInfo") { + } else if (type == "OMPTraitInfo *") { OS << " OS << \" \" << SA->get" << getUpperName() << "();\n"; } else { llvm_unreachable("Unknown SimpleArgument type!"); @@ -1331,7 +1331,7 @@ else if (ArgName == "VersionArgument") Ptr = std::make_unique(Arg, Attr); else if (ArgName == "OMPTraitInfoArgument") - Ptr = std::make_unique(Arg, Attr, "OMPTraitInfo"); + Ptr = std::make_unique(Arg, Attr, "OMPTraitInfo *"); if (!Ptr) { // Search in reverse order so that the most-derived type is handled first.