massberg updated this revision to Diff 547804. massberg edited the summary of this revision. massberg added a comment.
Rename `ConceptLoc` back to `ConceptReference`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D155858/new/ https://reviews.llvm.org/D155858 Files: clang/include/clang/AST/ASTConcept.h clang/include/clang/AST/DeclTemplate.h clang/include/clang/AST/ExprConcepts.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/AST/TypeLoc.h clang/include/clang/Serialization/ASTRecordReader.h clang/include/clang/Serialization/ASTRecordWriter.h clang/lib/AST/ASTContext.cpp clang/lib/AST/ASTImporter.cpp clang/lib/AST/DeclTemplate.cpp clang/lib/AST/ExprConcepts.cpp clang/lib/AST/TypeLoc.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateInstantiate.cpp clang/lib/Sema/SemaType.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReaderDecl.cpp clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/Serialization/ASTWriterDecl.cpp clang/lib/Serialization/ASTWriterStmt.cpp clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp
Index: clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp =================================================================== --- clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp +++ clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp @@ -29,12 +29,22 @@ ++ConceptRequirementsTraversed; return ExpectedLocationVisitor::TraverseConceptRequirement(R); } + bool TraverseConceptReference(const ConceptReference *CR) { + ++ConceptReferencesTraversed; + return ExpectedLocationVisitor::TraverseConceptReference(CR); + } + bool VisitConceptReference(const ConceptReference *CR) { + ++ConceptReferencesVisited; + return true; + } bool shouldVisitImplicitCode() { return ShouldVisitImplicitCode; } int ConceptSpecializationExprsVisited = 0; int TypeConstraintsTraversed = 0; int ConceptRequirementsTraversed = 0; + int ConceptReferencesTraversed = 0; + int ConceptReferencesVisited = 0; bool ShouldVisitImplicitCode = false; }; @@ -50,6 +60,8 @@ EXPECT_EQ(1, Visitor.ConceptSpecializationExprsVisited); // Also check we traversed the TypeConstraint that produced the expr. EXPECT_EQ(1, Visitor.TypeConstraintsTraversed); + EXPECT_EQ(1, Visitor.ConceptReferencesTraversed); + EXPECT_EQ(1, Visitor.ConceptReferencesVisited); Visitor = {}; // Don't visit implicit code now. EXPECT_TRUE(Visitor.runOver("template <typename T> concept Fooable = true;\n" @@ -59,6 +71,8 @@ // generated immediately declared expression. EXPECT_EQ(0, Visitor.ConceptSpecializationExprsVisited); EXPECT_EQ(1, Visitor.TypeConstraintsTraversed); + EXPECT_EQ(1, Visitor.ConceptReferencesTraversed); + EXPECT_EQ(1, Visitor.ConceptReferencesVisited); Visitor = {}; EXPECT_TRUE(Visitor.runOver("template <class T> concept A = true;\n" @@ -70,6 +84,8 @@ "};", ConceptVisitor::Lang_CXX2a)); EXPECT_EQ(3, Visitor.ConceptRequirementsTraversed); + EXPECT_EQ(1, Visitor.ConceptReferencesTraversed); + EXPECT_EQ(1, Visitor.ConceptReferencesVisited); } struct VisitDeclOnlyOnce : ExpectedLocationVisitor<VisitDeclOnlyOnce> { @@ -86,6 +102,10 @@ ++AutoTypeLocVisited; return true; } + bool VisitConceptReference(const ConceptReference *) { + ++ConceptReferencesVisited; + return true; + } bool TraverseVarDecl(VarDecl *V) { // The base traversal visits only the `TypeLoc`. @@ -99,6 +119,7 @@ int ConceptDeclsVisited = 0; int AutoTypeVisited = 0; int AutoTypeLocVisited = 0; + int ConceptReferencesVisited = 0; }; TEST(RecursiveASTVisitor, ConceptDeclInAutoType) { @@ -111,6 +132,7 @@ EXPECT_EQ(1, Visitor.AutoTypeVisited); EXPECT_EQ(1, Visitor.AutoTypeLocVisited); EXPECT_EQ(1, Visitor.ConceptDeclsVisited); + EXPECT_EQ(1, Visitor.ConceptReferencesVisited); } } // end anonymous namespace Index: clang/lib/Serialization/ASTWriterStmt.cpp =================================================================== --- clang/lib/Serialization/ASTWriterStmt.cpp +++ clang/lib/Serialization/ASTWriterStmt.cpp @@ -437,13 +437,8 @@ void ASTStmtWriter::VisitConceptSpecializationExpr( ConceptSpecializationExpr *E) { VisitExpr(E); - Record.AddNestedNameSpecifierLoc(E->getNestedNameSpecifierLoc()); - Record.AddSourceLocation(E->getTemplateKWLoc()); - Record.AddDeclarationNameInfo(E->getConceptNameInfo()); - Record.AddDeclRef(E->getNamedConcept()); - Record.AddDeclRef(E->getFoundDecl()); Record.AddDeclRef(E->getSpecializationDecl()); - Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten()); + Record.AddConceptReference(E->getConceptReference()); if (!E->isValueDependent()) addConstraintSatisfaction(Record, E->getSatisfaction()); Index: clang/lib/Serialization/ASTWriterDecl.cpp =================================================================== --- clang/lib/Serialization/ASTWriterDecl.cpp +++ clang/lib/Serialization/ASTWriterDecl.cpp @@ -1774,12 +1774,7 @@ const TypeConstraint *TC = D->getTypeConstraint(); Record.push_back(TC != nullptr); if (TC) { - Record.AddNestedNameSpecifierLoc(TC->getNestedNameSpecifierLoc()); - Record.AddDeclarationNameInfo(TC->getConceptNameInfo()); - Record.AddDeclRef(TC->getNamedConcept()); - Record.push_back(TC->getTemplateArgsAsWritten() != nullptr); - if (TC->getTemplateArgsAsWritten()) - Record.AddASTTemplateArgumentListInfo(TC->getTemplateArgsAsWritten()); + Record.AddConceptReference(TC->getConceptReference()); Record.AddStmt(TC->getImmediatelyDeclaredConstraint()); Record.push_back(D->isExpandedParameterPack()); if (D->isExpandedParameterPack()) Index: clang/lib/Serialization/ASTWriter.cpp =================================================================== --- clang/lib/Serialization/ASTWriter.cpp +++ clang/lib/Serialization/ASTWriter.cpp @@ -469,20 +469,25 @@ Record.AddTypeSourceInfo(TL.getUnderlyingTInfo()); } +void ASTRecordWriter::AddConceptReference(const ConceptReference *CR) { + push_back(CR != nullptr); + if (!CR) + return; + AddNestedNameSpecifierLoc(CR->getNestedNameSpecifierLoc()); + AddSourceLocation(CR->getTemplateKWLoc()); + AddDeclarationNameInfo(CR->getConceptNameInfo()); + AddDeclRef(CR->getFoundDecl()); + AddDeclRef(CR->getNamedConcept()); + push_back(CR->getTemplateArgsAsWritten() != nullptr); + if (CR->getTemplateArgsAsWritten()) + AddASTTemplateArgumentListInfo(CR->getTemplateArgsAsWritten()); +} + void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) { addSourceLocation(TL.getNameLoc()); Record.push_back(TL.isConstrained()); if (TL.isConstrained()) { - Record.AddNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc()); - addSourceLocation(TL.getTemplateKWLoc()); - addSourceLocation(TL.getConceptNameLoc()); - Record.AddDeclRef(TL.getFoundDecl()); - addSourceLocation(TL.getLAngleLoc()); - addSourceLocation(TL.getRAngleLoc()); - for (unsigned I = 0; I < TL.getNumArgs(); ++I) - Record.AddTemplateArgumentLocInfo( - TL.getTypePtr()->getTypeConstraintArguments()[I].getKind(), - TL.getArgLocInfo(I)); + Record.AddConceptReference(TL.getConceptReference()); } Record.push_back(TL.isDecltypeAuto()); if (TL.isDecltypeAuto()) Index: clang/lib/Serialization/ASTReaderStmt.cpp =================================================================== --- clang/lib/Serialization/ASTReaderStmt.cpp +++ clang/lib/Serialization/ASTReaderStmt.cpp @@ -795,13 +795,8 @@ void ASTStmtReader::VisitConceptSpecializationExpr( ConceptSpecializationExpr *E) { VisitExpr(E); - E->NestedNameSpec = Record.readNestedNameSpecifierLoc(); - E->TemplateKWLoc = Record.readSourceLocation(); - E->ConceptName = Record.readDeclarationNameInfo(); - E->NamedConcept = readDeclAs<ConceptDecl>(); - E->FoundDecl = Record.readDeclAs<NamedDecl>(); E->SpecDecl = Record.readDeclAs<ImplicitConceptSpecializationDecl>(); - E->ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); + E->CR = Record.readConceptReference(); E->Satisfaction = E->isValueDependent() ? nullptr : ASTConstraintSatisfaction::Create(Record.getContext(), readConstraintSatisfaction(Record)); Index: clang/lib/Serialization/ASTReaderDecl.cpp =================================================================== --- clang/lib/Serialization/ASTReaderDecl.cpp +++ clang/lib/Serialization/ASTReaderDecl.cpp @@ -2620,15 +2620,10 @@ D->setDeclaredWithTypename(Record.readInt()); if (Record.readBool()) { - NestedNameSpecifierLoc NNS = Record.readNestedNameSpecifierLoc(); - DeclarationNameInfo DN = Record.readDeclarationNameInfo(); - ConceptDecl *NamedConcept = Record.readDeclAs<ConceptDecl>(); - const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; - if (Record.readBool()) - ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); + auto *CR = Record.readConceptReference(); Expr *ImmediatelyDeclaredConstraint = Record.readExpr(); - D->setTypeConstraint(NNS, DN, /*FoundDecl=*/nullptr, NamedConcept, - ArgsAsWritten, ImmediatelyDeclaredConstraint); + + D->setTypeConstraint(CR, ImmediatelyDeclaredConstraint); if ((D->ExpandedParameterPack = Record.readInt())) D->NumExpanded = Record.readInt(); } Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -6806,19 +6806,25 @@ TL.setUnderlyingTInfo(GetTypeSourceInfo()); } +ConceptReference *ASTRecordReader::readConceptReference() { + if (!readBool()) { + return nullptr; + } + auto NNS = readNestedNameSpecifierLoc(); + auto TemplateKWLoc = readSourceLocation(); + auto ConceptNameLoc = readDeclarationNameInfo(); + auto FoundDecl = readDeclAs<NamedDecl>(); + auto NamedConcept = readDeclAs<ConceptDecl>(); + auto *CR = ConceptReference::Create( + getContext(), NNS, TemplateKWLoc, ConceptNameLoc, FoundDecl, NamedConcept, + (readBool() ? readASTTemplateArgumentListInfo() : nullptr)); + return CR; +} + void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) { TL.setNameLoc(readSourceLocation()); if (Reader.readBool()) { - TL.setNestedNameSpecifierLoc(ReadNestedNameSpecifierLoc()); - TL.setTemplateKWLoc(readSourceLocation()); - TL.setConceptNameLoc(readSourceLocation()); - TL.setFoundDecl(Reader.readDeclAs<NamedDecl>()); - TL.setLAngleLoc(readSourceLocation()); - TL.setRAngleLoc(readSourceLocation()); - for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) - TL.setArgLocInfo( - i, Reader.readTemplateArgumentLocInfo( - TL.getTypePtr()->getTypeConstraintArguments()[i].getKind())); + TL.setConceptReference(Reader.readConceptReference()); } if (Reader.readBool()) TL.setRParenLoc(readSourceLocation()); Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -6846,15 +6846,22 @@ AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result); NewTL.setNameLoc(TL.getNameLoc()); - NewTL.setNestedNameSpecifierLoc(NewNestedNameSpec); - NewTL.setTemplateKWLoc(TL.getTemplateKWLoc()); - NewTL.setConceptNameLoc(TL.getConceptNameLoc()); - NewTL.setFoundDecl(TL.getFoundDecl()); - NewTL.setLAngleLoc(TL.getLAngleLoc()); - NewTL.setRAngleLoc(TL.getRAngleLoc()); NewTL.setRParenLoc(TL.getRParenLoc()); - for (unsigned I = 0; I < NewTL.getNumArgs(); ++I) - NewTL.setArgLocInfo(I, NewTemplateArgs.arguments()[I].getLocInfo()); + + if (T->isConstrained()) { + DeclarationNameInfo DNI = DeclarationNameInfo( + TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(), + TL.getConceptNameLoc(), + TL.getTypePtr()->getTypeConstraintConcept()->getDeclName()); + /*DNI.setLoc(TL.getConceptNameLoc()); + DNI.setName(TL.getTypePtr()->getTypeConstraintConcept()->getDeclName()); + DNI.setInfo(TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());*/ + auto *CR = ConceptReference::Create( + SemaRef.Context, NewNestedNameSpec, TL.getTemplateKWLoc(), DNI, + TL.getFoundDecl(), TL.getTypePtr()->getTypeConstraintConcept(), + ASTTemplateArgumentListInfo::Create(SemaRef.Context, NewTemplateArgs)); + NewTL.setConceptReference(CR); + } return Result; } Index: clang/lib/Sema/SemaType.cpp =================================================================== --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -6300,24 +6300,27 @@ TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId(); if (!TemplateId) return; - if (DS.getTypeSpecScope().isNotEmpty()) - TL.setNestedNameSpecifierLoc( - DS.getTypeSpecScope().getWithLocInContext(Context)); - else - TL.setNestedNameSpecifierLoc(NestedNameSpecifierLoc()); - TL.setTemplateKWLoc(TemplateId->TemplateKWLoc); - TL.setConceptNameLoc(TemplateId->TemplateNameLoc); - TL.setFoundDecl(nullptr); - TL.setLAngleLoc(TemplateId->LAngleLoc); - TL.setRAngleLoc(TemplateId->RAngleLoc); - if (TemplateId->NumArgs == 0) - return; - TemplateArgumentListInfo TemplateArgsInfo; - ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), - TemplateId->NumArgs); - SemaRef.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo); - for (unsigned I = 0; I < TemplateId->NumArgs; ++I) - TL.setArgLocInfo(I, TemplateArgsInfo.arguments()[I].getLocInfo()); + + NestedNameSpecifierLoc NNS = + (DS.getTypeSpecScope().isNotEmpty() + ? DS.getTypeSpecScope().getWithLocInContext(Context) + : NestedNameSpecifierLoc()); + TemplateArgumentListInfo TemplateArgsInfo(TemplateId->LAngleLoc, + TemplateId->RAngleLoc); + if (TemplateId->NumArgs > 0) { + ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), + TemplateId->NumArgs); + SemaRef.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo); + } + DeclarationNameInfo DNI = DeclarationNameInfo( + TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(), + TemplateId->TemplateNameLoc); + auto *CR = ConceptReference::Create( + Context, NNS, TemplateId->TemplateKWLoc, DNI, + /*FoundDecl=*/nullptr, + /*NamedDecl=*/TL.getTypePtr()->getTypeConstraintConcept(), + ASTTemplateArgumentListInfo::Create(Context, TemplateArgsInfo)); + TL.setConceptReference(CR); } void VisitTagTypeLoc(TagTypeLoc TL) { TL.setNameLoc(DS.getTypeSpecTypeNameLoc()); Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2764,11 +2764,9 @@ TC->getTemplateArgsAsWritten(); if (!EvaluateConstraints) { - Inst->setTypeConstraint(TC->getNestedNameSpecifierLoc(), - TC->getConceptNameInfo(), TC->getNamedConcept(), - TC->getNamedConcept(), TemplArgInfo, - TC->getImmediatelyDeclaredConstraint()); - return false; + Inst->setTypeConstraint(TC->getConceptReference(), + TC->getImmediatelyDeclaredConstraint()); + return false; } TemplateArgumentListInfo InstArgs; Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -23,6 +23,7 @@ #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/Stack.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/DeclSpec.h" @@ -1256,9 +1257,13 @@ if (ImmediatelyDeclaredConstraint.isInvalid()) return true; - ConstrainedParameter->setTypeConstraint(NS, NameInfo, - /*FoundDecl=*/NamedConcept, - NamedConcept, ArgsAsWritten, + auto *CL = ConceptReference::Create(Context, /*NNS=*/NS, + /*TemplateKWLoc=*/SourceLocation{}, + /*ConceptNameInfo=*/NameInfo, + /*FoundDecl=*/NamedConcept, + /*NamedConcept=*/NamedConcept, + /*ArgsWritten=*/ArgsAsWritten); + ConstrainedParameter->setTypeConstraint(CL, ImmediatelyDeclaredConstraint.get()); return false; } @@ -4941,13 +4946,13 @@ TemplateArgs->getRAngleLoc()), Satisfaction)) return ExprError(); - - return ConceptSpecializationExpr::Create( + auto *CL = ConceptReference::Create( Context, SS.isSet() ? SS.getWithLocInContext(Context) : NestedNameSpecifierLoc{}, TemplateKWLoc, ConceptNameInfo, FoundDecl, NamedConcept, - ASTTemplateArgumentListInfo::Create(Context, *TemplateArgs), CSD, - AreArgsDependent ? nullptr : &Satisfaction); + ASTTemplateArgumentListInfo::Create(Context, *TemplateArgs)); + return ConceptSpecializationExpr::Create( + Context, CL, CSD, AreArgsDependent ? nullptr : &Satisfaction); } ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, Index: clang/lib/AST/TypeLoc.cpp =================================================================== --- clang/lib/AST/TypeLoc.cpp +++ clang/lib/AST/TypeLoc.cpp @@ -621,25 +621,14 @@ } } -DeclarationNameInfo AutoTypeLoc::getConceptNameInfo() const { - return DeclarationNameInfo(getNamedConcept()->getDeclName(), - getLocalData()->ConceptNameLoc); -} - void AutoTypeLoc::initializeLocal(ASTContext &Context, SourceLocation Loc) { - setNestedNameSpecifierLoc(NestedNameSpecifierLoc()); - setTemplateKWLoc(Loc); - setConceptNameLoc(Loc); - setFoundDecl(nullptr); - setRAngleLoc(Loc); - setLAngleLoc(Loc); setRParenLoc(Loc); TemplateSpecializationTypeLoc::initializeArgLocs( Context, getTypePtr()->getTypeConstraintArguments(), getArgInfos(), Loc); setNameLoc(Loc); + setConceptReference(nullptr); } - namespace { class GetContainedAutoTypeLocVisitor : Index: clang/lib/AST/ExprConcepts.cpp =================================================================== --- clang/lib/AST/ExprConcepts.cpp +++ clang/lib/AST/ExprConcepts.cpp @@ -31,26 +31,24 @@ using namespace clang; ConceptSpecializationExpr::ConceptSpecializationExpr( - const ASTContext &C, NestedNameSpecifierLoc NNS, - SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, - NamedDecl *FoundDecl, ConceptDecl *NamedConcept, - const ASTTemplateArgumentListInfo *ArgsAsWritten, + const ASTContext &C, ConceptReference *Loc, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction) : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_PRValue, OK_Ordinary), - ConceptReference(NNS, TemplateKWLoc, ConceptNameInfo, FoundDecl, - NamedConcept, ArgsAsWritten), - SpecDecl(SpecDecl), + CR(Loc), SpecDecl(SpecDecl), Satisfaction(Satisfaction ? ASTConstraintSatisfaction::Create(C, *Satisfaction) : nullptr) { setDependence(computeDependence(this, /*ValueDependent=*/!Satisfaction)); // Currently guaranteed by the fact concepts can only be at namespace-scope. - assert(!NestedNameSpec || - (!NestedNameSpec.getNestedNameSpecifier()->isInstantiationDependent() && - !NestedNameSpec.getNestedNameSpecifier() - ->containsUnexpandedParameterPack())); + assert(!Loc->getNestedNameSpecifierLoc() || + (!Loc->getNestedNameSpecifierLoc() + .getNestedNameSpecifier() + ->isInstantiationDependent() && + !Loc->getNestedNameSpecifierLoc() + .getNestedNameSpecifier() + ->containsUnexpandedParameterPack())); assert((!isValueDependent() || isInstantiationDependent()) && "should not be value-dependent"); } @@ -58,29 +56,20 @@ ConceptSpecializationExpr::ConceptSpecializationExpr(EmptyShell Empty) : Expr(ConceptSpecializationExprClass, Empty) {} -ConceptSpecializationExpr *ConceptSpecializationExpr::Create( - const ASTContext &C, NestedNameSpecifierLoc NNS, - SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, - NamedDecl *FoundDecl, ConceptDecl *NamedConcept, - const ASTTemplateArgumentListInfo *ArgsAsWritten, - ImplicitConceptSpecializationDecl *SpecDecl, - const ConstraintSatisfaction *Satisfaction) { - return new (C) ConceptSpecializationExpr( - C, NNS, TemplateKWLoc, ConceptNameInfo, FoundDecl, NamedConcept, - ArgsAsWritten, SpecDecl, Satisfaction); +ConceptSpecializationExpr * +ConceptSpecializationExpr::Create(const ASTContext &C, ConceptReference *Loc, + ImplicitConceptSpecializationDecl *SpecDecl, + const ConstraintSatisfaction *Satisfaction) { + return new (C) ConceptSpecializationExpr(C, Loc, SpecDecl, Satisfaction); } ConceptSpecializationExpr::ConceptSpecializationExpr( - const ASTContext &C, ConceptDecl *NamedConcept, - const ASTTemplateArgumentListInfo *ArgsAsWritten, + const ASTContext &C, ConceptReference *Loc, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction, bool Dependent, bool ContainsUnexpandedParameterPack) : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_PRValue, OK_Ordinary), - ConceptReference(NestedNameSpecifierLoc(), SourceLocation(), - DeclarationNameInfo(), NamedConcept, NamedConcept, - ArgsAsWritten), - SpecDecl(SpecDecl), + CR(Loc), SpecDecl(SpecDecl), Satisfaction(Satisfaction ? ASTConstraintSatisfaction::Create(C, *Satisfaction) : nullptr) { @@ -94,15 +83,15 @@ setDependence(D); } -ConceptSpecializationExpr *ConceptSpecializationExpr::Create( - const ASTContext &C, ConceptDecl *NamedConcept, - const ASTTemplateArgumentListInfo *ArgsAsWritten, - ImplicitConceptSpecializationDecl *SpecDecl, - const ConstraintSatisfaction *Satisfaction, bool Dependent, - bool ContainsUnexpandedParameterPack) { - return new (C) ConceptSpecializationExpr(C, NamedConcept, ArgsAsWritten, - SpecDecl, Satisfaction, Dependent, - ContainsUnexpandedParameterPack); +ConceptSpecializationExpr * +ConceptSpecializationExpr::Create(const ASTContext &C, ConceptReference *Loc, + ImplicitConceptSpecializationDecl *SpecDecl, + const ConstraintSatisfaction *Satisfaction, + bool Dependent, + bool ContainsUnexpandedParameterPack) { + return new (C) + ConceptSpecializationExpr(C, Loc, SpecDecl, Satisfaction, Dependent, + ContainsUnexpandedParameterPack); } const TypeConstraint * Index: clang/lib/AST/DeclTemplate.cpp =================================================================== --- clang/lib/AST/DeclTemplate.cpp +++ clang/lib/AST/DeclTemplate.cpp @@ -697,17 +697,15 @@ return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack(); } -void TemplateTypeParmDecl::setTypeConstraint(NestedNameSpecifierLoc NNS, - DeclarationNameInfo NameInfo, NamedDecl *FoundDecl, ConceptDecl *CD, - const ASTTemplateArgumentListInfo *ArgsAsWritten, - Expr *ImmediatelyDeclaredConstraint) { +void TemplateTypeParmDecl::setTypeConstraint( + ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint) { assert(HasTypeConstraint && "HasTypeConstraint=true must be passed at construction in order to " "call setTypeConstraint"); assert(!TypeConstraintInitialized && "TypeConstraint was already initialized!"); - new (getTrailingObjects<TypeConstraint>()) TypeConstraint(NNS, NameInfo, - FoundDecl, CD, ArgsAsWritten, ImmediatelyDeclaredConstraint); + new (getTrailingObjects<TypeConstraint>()) + TypeConstraint(Loc, ImmediatelyDeclaredConstraint); TypeConstraintInitialized = true; } @@ -1554,7 +1552,8 @@ createBuiltinTemplateParameterList(C, DC, BTK)), BTK(BTK) {} -void TypeConstraint::print(llvm::raw_ostream &OS, PrintingPolicy Policy) const { +void ConceptReference::print(llvm::raw_ostream &OS, + PrintingPolicy Policy) const { if (NestedNameSpec) NestedNameSpec.getNestedNameSpecifier()->print(OS, Policy); ConceptName.printName(OS, Policy); Index: clang/lib/AST/ASTImporter.cpp =================================================================== --- clang/lib/AST/ASTImporter.cpp +++ clang/lib/AST/ASTImporter.cpp @@ -5652,13 +5652,14 @@ if (Error Err = ImportTemplateArgumentListInfo(*ASTTemplateArgs, ToTAInfo)) return std::move(Err); - - ToD->setTypeConstraint(ToNNS, DeclarationNameInfo(ToName, ToNameLoc), - ToFoundDecl, ToNamedConcept, - ASTTemplateArgs ? - ASTTemplateArgumentListInfo::Create(Importer.getToContext(), - ToTAInfo) : nullptr, - ToIDC); + auto *CL = ConceptReference::Create( + Importer.getToContext(), ToNNS, + ToNameLoc, // What is the right Loc here? + DeclarationNameInfo(ToName, ToNameLoc), ToFoundDecl, ToNamedConcept, + ASTTemplateArgs ? ASTTemplateArgumentListInfo::Create( + Importer.getToContext(), ToTAInfo) + : nullptr); + ToD->setTypeConstraint(CL, ToIDC); } if (D->hasDefaultArgument()) { Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -6345,11 +6345,14 @@ auto *NCY = YTC->getNamedConcept(); if (!NCX || !NCY || !isSameEntity(NCX, NCY)) return false; - if (XTC->hasExplicitTemplateArgs() != YTC->hasExplicitTemplateArgs()) + if (XTC->getConceptReference()->hasExplicitTemplateArgs() != + YTC->getConceptReference()->hasExplicitTemplateArgs()) return false; - if (XTC->hasExplicitTemplateArgs()) - if (XTC->getTemplateArgsAsWritten()->NumTemplateArgs != - YTC->getTemplateArgsAsWritten()->NumTemplateArgs) + if (XTC->getConceptReference()->hasExplicitTemplateArgs()) + if (XTC->getConceptReference() + ->getTemplateArgsAsWritten() + ->NumTemplateArgs != + YTC->getConceptReference()->getTemplateArgsAsWritten()->NumTemplateArgs) return false; // Compare slowly by profiling. Index: clang/include/clang/Serialization/ASTRecordWriter.h =================================================================== --- clang/include/clang/Serialization/ASTRecordWriter.h +++ clang/include/clang/Serialization/ASTRecordWriter.h @@ -222,6 +222,9 @@ void AddASTTemplateArgumentListInfo( const ASTTemplateArgumentListInfo *ASTTemplArgList); + // Emits a concept reference. + void AddConceptReference(const ConceptReference *CR); + /// Emit a reference to a declaration. void AddDeclRef(const Decl *D) { return Writer->AddDeclRef(D, *Record); Index: clang/include/clang/Serialization/ASTRecordReader.h =================================================================== --- clang/include/clang/Serialization/ASTRecordReader.h +++ clang/include/clang/Serialization/ASTRecordReader.h @@ -158,6 +158,9 @@ const ASTTemplateArgumentListInfo* readASTTemplateArgumentListInfo(); + // Reads a concept reference from the given record. + ConceptReference *readConceptReference(); + /// Reads a declarator info from the given record, advancing Idx. TypeSourceInfo *readTypeSourceInfo(); Index: clang/include/clang/AST/TypeLoc.h =================================================================== --- clang/include/clang/AST/TypeLoc.h +++ clang/include/clang/AST/TypeLoc.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_TYPELOC_H #define LLVM_CLANG_AST_TYPELOC_H +#include "clang/AST/ASTConcept.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateBase.h" @@ -2104,16 +2105,10 @@ DeducedType> {}; struct AutoTypeLocInfo : TypeSpecLocInfo { - NestedNameSpecifierLoc NestedNameSpec; - SourceLocation TemplateKWLoc; - SourceLocation ConceptNameLoc; - NamedDecl *FoundDecl = nullptr; - SourceLocation LAngleLoc; - SourceLocation RAngleLoc; - // For decltype(auto). SourceLocation RParenLoc; + ConceptReference *CR = nullptr; // Followed by a TemplateArgumentLocInfo[] }; @@ -2135,79 +2130,82 @@ return getTypePtr()->isConstrained(); } - const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const { - return getLocalData()->NestedNameSpec; - } + void setConceptReference(ConceptReference *CR) { getLocalData()->CR = CR; } - void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { - getLocalData()->NestedNameSpec = NNS; - } + ConceptReference *getConceptReference() const { return getLocalData()->CR; } - SourceLocation getTemplateKWLoc() const { - return getLocalData()->TemplateKWLoc; + // FIXME: Deprecate the following functions and let the caller directly + // work with the ConceptReference. + const NestedNameSpecifierLoc getNestedNameSpecifierLoc() const { + if (getConceptReference()) + return getConceptReference()->getNestedNameSpecifierLoc(); + return NestedNameSpecifierLoc(); } - void setTemplateKWLoc(SourceLocation Loc) { - getLocalData()->TemplateKWLoc = Loc; + SourceLocation getTemplateKWLoc() const { + if (getConceptReference()) + return getConceptReference()->getTemplateKWLoc(); + return SourceLocation(); } SourceLocation getConceptNameLoc() const { - return getLocalData()->ConceptNameLoc; - } - - void setConceptNameLoc(SourceLocation Loc) { - getLocalData()->ConceptNameLoc = Loc; + if (getConceptReference()) + return getConceptReference()->getConceptNameLoc(); + return SourceLocation(); } NamedDecl *getFoundDecl() const { - return getLocalData()->FoundDecl; - } - - void setFoundDecl(NamedDecl *D) { - getLocalData()->FoundDecl = D; + if (getConceptReference()) + return getConceptReference()->getFoundDecl(); + return nullptr; } ConceptDecl *getNamedConcept() const { - return getTypePtr()->getTypeConstraintConcept(); + if (getConceptReference()) + return getConceptReference()->getNamedConcept(); + return nullptr; } - DeclarationNameInfo getConceptNameInfo() const; + DeclarationNameInfo getConceptNameInfo() const { + return getConceptReference()->getConceptNameInfo(); + } bool hasExplicitTemplateArgs() const { - return getLocalData()->LAngleLoc.isValid(); + return (getConceptReference() && + getConceptReference()->getTemplateArgsAsWritten() && + getConceptReference() + ->getTemplateArgsAsWritten() + ->getLAngleLoc() + .isValid()); } SourceLocation getLAngleLoc() const { - return this->getLocalData()->LAngleLoc; - } - - void setLAngleLoc(SourceLocation Loc) { - this->getLocalData()->LAngleLoc = Loc; + if (getConceptReference() && + getConceptReference()->getTemplateArgsAsWritten()) + return getConceptReference()->getTemplateArgsAsWritten()->getLAngleLoc(); + return SourceLocation(); } SourceLocation getRAngleLoc() const { - return this->getLocalData()->RAngleLoc; - } - - void setRAngleLoc(SourceLocation Loc) { - this->getLocalData()->RAngleLoc = Loc; + if (getConceptReference() && + getConceptReference()->getTemplateArgsAsWritten()) + return getConceptReference()->getTemplateArgsAsWritten()->getRAngleLoc(); + return SourceLocation(); } unsigned getNumArgs() const { return getTypePtr()->getTypeConstraintArguments().size(); } - void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { - getArgInfos()[i] = AI; - } - - TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { - return getArgInfos()[i]; - } - TemplateArgumentLoc getArgLoc(unsigned i) const { + if (getConceptReference()) + return getConceptReference() + ->getTemplateArgsAsWritten() + ->getTemplateArgs()[i]; + // FIXME: Check why we still need this fallback in case that there is no + // ConceptReference. return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i], - getArgLocInfo(i)); + getArgInfos()[i]); } SourceRange getLocalSourceRange() const { Index: clang/include/clang/AST/RecursiveASTVisitor.h =================================================================== --- clang/include/clang/AST/RecursiveASTVisitor.h +++ clang/include/clang/AST/RecursiveASTVisitor.h @@ -312,6 +312,13 @@ /// \returns false if the visitation was terminated early, true otherwise. bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc); + /// Recursively visit concept reference with location information. + /// + /// \returns false if the visitation was terminated early, true otherwise. + bool TraverseConceptReference(const ConceptReference *CR); + + // Visit concept reference. + bool VisitConceptReference(const ConceptReference *CR) { return true; } // ---- Methods on Attrs ---- // Visit an attribute. @@ -469,9 +476,6 @@ private: // These are helper methods used by more than one Traverse* method. bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL); - /// Traverses the qualifier, name and template arguments of a concept - /// reference. - bool TraverseConceptReferenceHelper(const ConceptReference &C); // Traverses template parameter lists of either a DeclaratorDecl or TagDecl. template <typename T> @@ -507,7 +511,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTypeConstraint( const TypeConstraint *C) { if (!getDerived().shouldVisitImplicitCode()) { - TRY_TO(TraverseConceptReferenceHelper(*C)); + TRY_TO(TraverseConceptReference(C->getConceptReference())); return true; } if (Expr *IDC = C->getImmediatelyDeclaredConstraint()) { @@ -517,7 +521,7 @@ // if we have an immediately-declared-constraint, otherwise // we'll end up visiting the concept and the arguments in // the TC twice. - TRY_TO(TraverseConceptReferenceHelper(*C)); + TRY_TO(TraverseConceptReference(C->getConceptReference())); } return true; } @@ -540,18 +544,6 @@ llvm_unreachable("unexpected case"); } -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseConceptReferenceHelper( - const ConceptReference &C) { - TRY_TO(TraverseNestedNameSpecifierLoc(C.getNestedNameSpecifierLoc())); - TRY_TO(TraverseDeclarationNameInfo(C.getConceptNameInfo())); - if (C.hasExplicitTemplateArgs()) - TRY_TO(TraverseTemplateArgumentLocsHelper( - C.getTemplateArgsAsWritten()->getTemplateArgs(), - C.getTemplateArgsAsWritten()->NumTemplateArgs)); - return true; -} - template <typename Derived> bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) { @@ -1356,10 +1348,7 @@ DEF_TRAVERSE_TYPELOC(AutoType, { TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType())); if (TL.isConstrained()) { - TRY_TO(TraverseNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc())); - TRY_TO(TraverseDeclarationNameInfo(TL.getConceptNameInfo())); - for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) - TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I))); + TRY_TO(TraverseConceptReference(TL.getConceptReference())); } }) @@ -2522,6 +2511,19 @@ return true; } +template <typename Derived> +bool RecursiveASTVisitor<Derived>::TraverseConceptReference( + const ConceptReference *CR) { + TRY_TO(VisitConceptReference(CR)); + TRY_TO(TraverseNestedNameSpecifierLoc(CR->getNestedNameSpecifierLoc())); + TRY_TO(TraverseDeclarationNameInfo(CR->getConceptNameInfo())); + if (CR->hasExplicitTemplateArgs()) + TRY_TO(TraverseTemplateArgumentLocsHelper( + CR->getTemplateArgsAsWritten()->getTemplateArgs(), + CR->getTemplateArgsAsWritten()->NumTemplateArgs)); + return true; +} + // If shouldVisitImplicitCode() returns false, this method traverses only the // syntactic form of InitListExpr. // If shouldVisitImplicitCode() return true, this method is called once for @@ -2899,8 +2901,9 @@ } }) -DEF_TRAVERSE_STMT(ConceptSpecializationExpr, - { TRY_TO(TraverseConceptReferenceHelper(*S)); }) +DEF_TRAVERSE_STMT(ConceptSpecializationExpr, { + TRY_TO(TraverseConceptReference(S->getConceptReference())); +}) DEF_TRAVERSE_STMT(RequiresExpr, { TRY_TO(TraverseDecl(S->getBody())); Index: clang/include/clang/AST/ExprConcepts.h =================================================================== --- clang/include/clang/AST/ExprConcepts.h +++ clang/include/clang/AST/ExprConcepts.h @@ -38,7 +38,7 @@ /// /// According to C++2a [expr.prim.id]p3 an id-expression that denotes the /// specialization of a concept results in a prvalue of type bool. -class ConceptSpecializationExpr final : public Expr, public ConceptReference { +class ConceptSpecializationExpr final : public Expr { friend class ASTReader; friend class ASTStmtReader; @@ -46,6 +46,8 @@ using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>; protected: + ConceptReference *CR; + /// \brief The Implicit Concept Specialization Decl, which holds the template /// arguments for this specialization. ImplicitConceptSpecializationDecl *SpecDecl; @@ -55,16 +57,11 @@ /// ignored. ASTConstraintSatisfaction *Satisfaction; - ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS, - SourceLocation TemplateKWLoc, - DeclarationNameInfo ConceptNameInfo, - NamedDecl *FoundDecl, ConceptDecl *NamedConcept, - const ASTTemplateArgumentListInfo *ArgsAsWritten, + ConceptSpecializationExpr(const ASTContext &C, ConceptReference *CR, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction); - ConceptSpecializationExpr(const ASTContext &C, ConceptDecl *NamedConcept, - const ASTTemplateArgumentListInfo *ArgsAsWritten, + ConceptSpecializationExpr(const ASTContext &C, ConceptReference *CR, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction, bool Dependent, @@ -73,16 +70,12 @@ public: static ConceptSpecializationExpr * - Create(const ASTContext &C, NestedNameSpecifierLoc NNS, - SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, - NamedDecl *FoundDecl, ConceptDecl *NamedConcept, - const ASTTemplateArgumentListInfo *ArgsAsWritten, + Create(const ASTContext &C, ConceptReference *CR, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction); static ConceptSpecializationExpr * - Create(const ASTContext &C, ConceptDecl *NamedConcept, - const ASTTemplateArgumentListInfo *ArgsAsWritten, + Create(const ASTContext &C, ConceptReference *CR, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction, bool Dependent, bool ContainsUnexpandedParameterPack); @@ -91,6 +84,32 @@ return SpecDecl->getTemplateArguments(); } + const ConceptReference *getConceptReference() const { return CR; } + + // NOTE(massberg): For the first minimal prototype we keep the + // following functions to prevent. Later these functions should + // be accessed getConceptReference(). + ConceptDecl *getNamedConcept() const { return CR->getNamedConcept(); } + + bool hasExplicitTemplateArgs() const { return CR->hasExplicitTemplateArgs(); } + + SourceLocation getConceptNameLoc() const { return CR->getConceptNameLoc(); } + const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { + return CR->getTemplateArgsAsWritten(); + } + + const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const { + return CR->getNestedNameSpecifierLoc(); + } + + SourceLocation getTemplateKWLoc() const { return CR->getTemplateKWLoc(); } + + NamedDecl *getFoundDecl() const { return CR->getFoundDecl(); } + + const DeclarationNameInfo &getConceptNameInfo() const { + return CR->getConceptNameInfo(); + } + const ImplicitConceptSpecializationDecl *getSpecializationDecl() const { assert(SpecDecl && "Template Argument Decl not initialized"); return SpecDecl; @@ -119,17 +138,19 @@ } SourceLocation getBeginLoc() const LLVM_READONLY { - if (auto QualifierLoc = getNestedNameSpecifierLoc()) + if (auto QualifierLoc = CR->getNestedNameSpecifierLoc()) return QualifierLoc.getBeginLoc(); - return ConceptName.getBeginLoc(); + return CR->getConceptNameInfo().getBeginLoc(); } SourceLocation getEndLoc() const LLVM_READONLY { // If the ConceptSpecializationExpr is the ImmediatelyDeclaredConstraint // of a TypeConstraint written syntactically as a constrained-parameter, // there may not be a template argument list. - return ArgsAsWritten->RAngleLoc.isValid() ? ArgsAsWritten->RAngleLoc - : ConceptName.getEndLoc(); + return CR->hasExplicitTemplateArgs() && + CR->getTemplateArgsAsWritten()->getRAngleLoc().isValid() + ? CR->getTemplateArgsAsWritten()->getRAngleLoc() + : CR->getConceptNameInfo().getEndLoc(); } // Iterators Index: clang/include/clang/AST/DeclTemplate.h =================================================================== --- clang/include/clang/AST/DeclTemplate.h +++ clang/include/clang/AST/DeclTemplate.h @@ -1373,10 +1373,7 @@ nullptr; } - void setTypeConstraint(NestedNameSpecifierLoc NNS, - DeclarationNameInfo NameInfo, NamedDecl *FoundDecl, - ConceptDecl *CD, - const ASTTemplateArgumentListInfo *ArgsAsWritten, + void setTypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint); /// Determine whether this template parameter has a type-constraint. Index: clang/include/clang/AST/ASTConcept.h =================================================================== --- clang/include/clang/AST/ASTConcept.h +++ clang/include/clang/AST/ASTConcept.h @@ -14,7 +14,9 @@ #ifndef LLVM_CLANG_AST_ASTCONCEPT_H #define LLVM_CLANG_AST_ASTCONCEPT_H +#include "clang/AST/Decl.h" #include "clang/AST/Expr.h" +#include "clang/AST/PrettyPrinter.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallVector.h" @@ -146,6 +148,15 @@ ConceptReference() : FoundDecl(nullptr), NamedConcept(nullptr), ArgsAsWritten(nullptr) {} + static ConceptReference * + Create(const ASTContext &C, NestedNameSpecifierLoc NNS, + SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, + NamedDecl *FoundDecl, ConceptDecl *NamedConcept, + const ASTTemplateArgumentListInfo *ArgsAsWritten) { + return new (C) ConceptReference(NNS, TemplateKWLoc, ConceptNameInfo, + FoundDecl, NamedConcept, ArgsAsWritten); + } + const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const { return NestedNameSpec; } @@ -175,22 +186,19 @@ bool hasExplicitTemplateArgs() const { return ArgsAsWritten != nullptr; } + + void print(llvm::raw_ostream &OS, PrintingPolicy Policy) const; }; -class TypeConstraint : public ConceptReference { +class TypeConstraint { /// \brief The immediately-declared constraint expression introduced by this /// type-constraint. Expr *ImmediatelyDeclaredConstraint = nullptr; + ConceptReference *CR; public: - TypeConstraint(NestedNameSpecifierLoc NNS, - DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, - ConceptDecl *NamedConcept, - const ASTTemplateArgumentListInfo *ArgsAsWritten, - Expr *ImmediatelyDeclaredConstraint) : - ConceptReference(NNS, /*TemplateKWLoc=*/SourceLocation(), ConceptNameInfo, - FoundDecl, NamedConcept, ArgsAsWritten), - ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint) {} + TypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint) + : ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint), CR(CR) {} /// \brief Get the immediately-declared constraint expression introduced by /// this type-constraint, that is - the constraint expression that is added to @@ -199,7 +207,35 @@ return ImmediatelyDeclaredConstraint; } - void print(llvm::raw_ostream &OS, PrintingPolicy Policy) const; + ConceptReference *getConceptReference() const { return CR; } + + // FIXME: Instead of using these concept related functions the callers should + // directly work with the corresponding ConceptReference. + ConceptDecl *getNamedConcept() const { return CR->getNamedConcept(); } + + SourceLocation getConceptNameLoc() const { return CR->getConceptNameLoc(); } + + bool hasExplicitTemplateArgs() const { return CR->hasExplicitTemplateArgs(); } + + const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { + return CR->getTemplateArgsAsWritten(); + } + + SourceLocation getTemplateKWLoc() const { return CR->getTemplateKWLoc(); } + + NamedDecl *getFoundDecl() const { return CR->getFoundDecl(); } + + const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const { + return CR->getNestedNameSpecifierLoc(); + } + + const DeclarationNameInfo &getConceptNameInfo() const { + return CR->getConceptNameInfo(); + } + + void print(llvm::raw_ostream &OS, PrintingPolicy Policy) const { + CR->print(OS, Policy); + } }; } // clang
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits