diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h index 6df3a83b6404a..44dc52b419af5 100644 --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -623,14 +623,7 @@ class ASTNodeTraverser Visit(D->getConstraintExpr()); } - void VisitImplicitConceptSpecializationDecl( - const ImplicitConceptSpecializationDecl *CSD) { - for (const TemplateArgument &Arg : CSD->getTemplateArguments()) - Visit(Arg); - } - void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *CSE) { - Visit(CSE->getSpecializationDecl()); if (CSE->hasExplicitTemplateArgs()) for (const auto &ArgLoc : CSE->getTemplateArgsAsWritten()->arguments()) dumpTemplateArgumentLoc(ArgLoc); diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index d1dfe73a51182..ae10744383559 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -3259,7 +3259,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl { static bool classofKind(Kind K) { return K == VarTemplate; } }; -/// Declaration of a C++20 concept. +/// Declaration of a C++2a concept. class ConceptDecl : public TemplateDecl, public Mergeable { protected: Expr *ConstraintExpr; @@ -3304,40 +3304,6 @@ class ConceptDecl : public TemplateDecl, public Mergeable { friend class ASTDeclWriter; }; -// An implementation detail of ConceptSpecialicationExpr that holds the template -// arguments, so we can later use this to reconstitute the template arguments -// during constraint checking. -class ImplicitConceptSpecializationDecl final - : public Decl, - private llvm::TrailingObjects { - unsigned NumTemplateArgs; - - ImplicitConceptSpecializationDecl(DeclContext *DC, SourceLocation SL, - ArrayRef ConvertedArgs); - ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs); - -public: - static ImplicitConceptSpecializationDecl * - Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, - ArrayRef ConvertedArgs); - static ImplicitConceptSpecializationDecl * - CreateDeserialized(const ASTContext &C, unsigned ID, - unsigned NumTemplateArgs); - - ArrayRef getTemplateArguments() const { - return ArrayRef(getTrailingObjects(), - NumTemplateArgs); - } - void setTemplateArguments(ArrayRef Converted); - - static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; } - static bool classof(const Decl *D) { return classofKind(D->getKind()); } - - friend TrailingObjects; - friend class ASTDeclReader; -}; - /// A template parameter object. /// /// Template parameter objects represent values of class type used as template diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h index 6dedeb5c8ddfa..fd9cd31f3b90b 100644 --- a/clang/include/clang/AST/ExprConcepts.h +++ b/clang/include/clang/AST/ExprConcepts.h @@ -37,17 +37,18 @@ class ASTStmtWriter; /// /// 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 { - friend class ASTReader; +class ConceptSpecializationExpr final : public Expr, public ConceptReference, + private llvm::TrailingObjects { friend class ASTStmtReader; - + friend TrailingObjects; public: using SubstitutionDiagnostic = std::pair; protected: - /// \brief The Implicit Concept Specialization Decl, which holds the template - /// arguments for this specialization. - ImplicitConceptSpecializationDecl *SpecDecl; + /// \brief The number of template arguments in the tail-allocated list of + /// converted template arguments. + unsigned NumTemplateArgs; /// \brief Information about the satisfaction of the named concept with the /// given arguments. If this expression is value dependent, this is to be @@ -59,46 +60,51 @@ class ConceptSpecializationExpr final : public Expr, public ConceptReference { DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten, - ImplicitConceptSpecializationDecl *SpecDecl, + ArrayRef ConvertedArgs, const ConstraintSatisfaction *Satisfaction); ConceptSpecializationExpr(const ASTContext &C, ConceptDecl *NamedConcept, - ImplicitConceptSpecializationDecl *SpecDecl, + ArrayRef ConvertedArgs, const ConstraintSatisfaction *Satisfaction, bool Dependent, bool ContainsUnexpandedParameterPack); - ConceptSpecializationExpr(EmptyShell Empty); + + ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs); public: + static ConceptSpecializationExpr * Create(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten, - ImplicitConceptSpecializationDecl *SpecDecl, + ArrayRef ConvertedArgs, const ConstraintSatisfaction *Satisfaction); static ConceptSpecializationExpr * Create(const ASTContext &C, ConceptDecl *NamedConcept, - ImplicitConceptSpecializationDecl *SpecDecl, - const ConstraintSatisfaction *Satisfaction, bool Dependent, + ArrayRef ConvertedArgs, + const ConstraintSatisfaction *Satisfaction, + bool Dependent, bool ContainsUnexpandedParameterPack); + static ConceptSpecializationExpr * + Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs); + ArrayRef getTemplateArguments() const { - return SpecDecl->getTemplateArguments(); + return ArrayRef(getTrailingObjects(), + NumTemplateArgs); } - const ImplicitConceptSpecializationDecl *getSpecializationDecl() const { - assert(SpecDecl && "Template Argument Decl not initialized"); - return SpecDecl; - } + /// \brief Set new template arguments for this concept specialization. + void setTemplateArguments(ArrayRef Converted); /// \brief Whether or not the concept with the given arguments was satisfied /// when the expression was created. /// The expression must not be dependent. bool isSatisfied() const { - assert(!isValueDependent() && - "isSatisfied called on a dependent ConceptSpecializationExpr"); + assert(!isValueDependent() + && "isSatisfied called on a dependent ConceptSpecializationExpr"); return Satisfaction->IsSatisfied; } @@ -106,8 +112,8 @@ class ConceptSpecializationExpr final : public Expr, public ConceptReference { /// satisfaction of the named concept. /// The expression must not be dependent. const ASTConstraintSatisfaction &getSatisfaction() const { - assert(!isValueDependent() && - "getSatisfaction called on dependent ConceptSpecializationExpr"); + assert(!isValueDependent() + && "getSatisfaction called on dependent ConceptSpecializationExpr"); return *Satisfaction; } diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 8c5412648bcd4..b5c24e1a7661a 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2304,11 +2304,6 @@ DEF_TRAVERSE_DECL(ParmVarDecl, { DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {}) -DEF_TRAVERSE_DECL(ImplicitConceptSpecializationDecl, { - TRY_TO(TraverseTemplateArguments(D->getTemplateArguments().data(), - D->getTemplateArguments().size())); -}) - #undef DEF_TRAVERSE_DECL // ----------------- Stmt traversal ----------------- diff --git a/clang/include/clang/Basic/DeclNodes.td b/clang/include/clang/Basic/DeclNodes.td index c94c84ba25370..386c0a1b3dbaa 100644 --- a/clang/include/clang/Basic/DeclNodes.td +++ b/clang/include/clang/Basic/DeclNodes.td @@ -90,7 +90,6 @@ def Named : DeclNode; def ObjCImplementation : DeclNode; def ObjCProperty : DeclNode; def ObjCCompatibleAlias : DeclNode; -def ImplicitConceptSpecialization : DeclNode; def LinkageSpec : DeclNode, DeclContext; def Export : DeclNode, DeclContext; def ObjCPropertyImpl : DeclNode; diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index ff8be544d5a46..3bbd2723be676 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1514,10 +1514,7 @@ enum DeclCode { /// A HLSLBufferDecl record. DECL_HLSL_BUFFER, - /// An ImplicitConceptSpecializationDecl record. - DECL_IMPLICIT_CONCEPT_SPECIALIZATION, - - DECL_LAST = DECL_IMPLICIT_CONCEPT_SPECIALIZATION + DECL_LAST = DECL_HLSL_BUFFER }; /// Record codes for each kind of statement or expression. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 08cbe2a9a5811..16852149792bb 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -761,13 +761,9 @@ canonicalizeImmediatelyDeclaredConstraint(const ASTContext &C, Expr *IDC, NewConverted.push_back(ConstrainedType); llvm::append_range(NewConverted, OldConverted.drop_front(1)); } - auto *CSD = ImplicitConceptSpecializationDecl::Create( - C, CSE->getNamedConcept()->getDeclContext(), - CSE->getNamedConcept()->getLocation(), NewConverted); - Expr *NewIDC = ConceptSpecializationExpr::Create( - C, CSE->getNamedConcept(), CSD, nullptr, CSE->isInstantiationDependent(), - CSE->containsUnexpandedParameterPack()); + C, CSE->getNamedConcept(), NewConverted, nullptr, + CSE->isInstantiationDependent(), CSE->containsUnexpandedParameterPack()); if (auto *OrigFold = dyn_cast(IDC)) NewIDC = new (C) CXXFoldExpr( diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 5cb552372497d..72922ef977f92 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -874,7 +874,6 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case Empty: case LifetimeExtendedTemporary: case RequiresExprBody: - case ImplicitConceptSpecialization: // Never looked up by name. return 0; } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index deed47ec4a298..9a2932c0bcbd8 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -1052,44 +1052,6 @@ ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, return Result; } -//===----------------------------------------------------------------------===// -// ImplicitConceptSpecializationDecl Implementation -//===----------------------------------------------------------------------===// -ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl( - DeclContext *DC, SourceLocation SL, - ArrayRef ConvertedArgs) - : Decl(ImplicitConceptSpecialization, DC, SL), - NumTemplateArgs(ConvertedArgs.size()) { - setTemplateArguments(ConvertedArgs); -} - -ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl( - EmptyShell Empty, unsigned NumTemplateArgs) - : Decl(ImplicitConceptSpecialization, Empty), - NumTemplateArgs(NumTemplateArgs) {} - -ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create( - const ASTContext &C, DeclContext *DC, SourceLocation SL, - ArrayRef ConvertedArgs) { - return new (C, DC, - additionalSizeToAlloc(ConvertedArgs.size())) - ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs); -} - -ImplicitConceptSpecializationDecl * -ImplicitConceptSpecializationDecl::CreateDeserialized( - const ASTContext &C, unsigned ID, unsigned NumTemplateArgs) { - return new (C, ID, additionalSizeToAlloc(NumTemplateArgs)) - ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs); -} - -void ImplicitConceptSpecializationDecl::setTemplateArguments( - ArrayRef Converted) { - assert(Converted.size() == NumTemplateArgs); - std::uninitialized_copy(Converted.begin(), Converted.end(), - getTrailingObjects()); -} - //===----------------------------------------------------------------------===// // ClassTemplatePartialSpecializationDecl Implementation //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/ExprConcepts.cpp b/clang/lib/AST/ExprConcepts.cpp index fc8f1eb2abf14..c17453fb45fb8 100644 --- a/clang/lib/AST/ExprConcepts.cpp +++ b/clang/lib/AST/ExprConcepts.cpp @@ -35,15 +35,16 @@ ConceptSpecializationExpr::ConceptSpecializationExpr( SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten, - ImplicitConceptSpecializationDecl *SpecDecl, + ArrayRef ConvertedArgs, const ConstraintSatisfaction *Satisfaction) : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_PRValue, OK_Ordinary), ConceptReference(NNS, TemplateKWLoc, ConceptNameInfo, FoundDecl, NamedConcept, ArgsAsWritten), - SpecDecl(SpecDecl), + NumTemplateArgs(ConvertedArgs.size()), Satisfaction(Satisfaction ? ASTConstraintSatisfaction::Create(C, *Satisfaction) : nullptr) { + setTemplateArguments(ConvertedArgs); setDependence(computeDependence(this, /*ValueDependent=*/!Satisfaction)); // Currently guaranteed by the fact concepts can only be at namespace-scope. @@ -55,34 +56,50 @@ ConceptSpecializationExpr::ConceptSpecializationExpr( "should not be value-dependent"); } -ConceptSpecializationExpr::ConceptSpecializationExpr(EmptyShell Empty) - : Expr(ConceptSpecializationExprClass, Empty) {} +ConceptSpecializationExpr::ConceptSpecializationExpr(EmptyShell Empty, + unsigned NumTemplateArgs) + : Expr(ConceptSpecializationExprClass, Empty), + NumTemplateArgs(NumTemplateArgs) {} -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); +void ConceptSpecializationExpr::setTemplateArguments( + ArrayRef Converted) { + assert(Converted.size() == NumTemplateArgs); + std::uninitialized_copy(Converted.begin(), Converted.end(), + getTrailingObjects()); +} + +ConceptSpecializationExpr * +ConceptSpecializationExpr::Create(const ASTContext &C, + NestedNameSpecifierLoc NNS, + SourceLocation TemplateKWLoc, + DeclarationNameInfo ConceptNameInfo, + NamedDecl *FoundDecl, + ConceptDecl *NamedConcept, + const ASTTemplateArgumentListInfo *ArgsAsWritten, + ArrayRef ConvertedArgs, + const ConstraintSatisfaction *Satisfaction) { + void *Buffer = C.Allocate(totalSizeToAlloc( + ConvertedArgs.size())); + return new (Buffer) ConceptSpecializationExpr(C, NNS, TemplateKWLoc, + ConceptNameInfo, FoundDecl, + NamedConcept, ArgsAsWritten, + ConvertedArgs, Satisfaction); } ConceptSpecializationExpr::ConceptSpecializationExpr( const ASTContext &C, ConceptDecl *NamedConcept, - ImplicitConceptSpecializationDecl *SpecDecl, + ArrayRef ConvertedArgs, const ConstraintSatisfaction *Satisfaction, bool Dependent, bool ContainsUnexpandedParameterPack) : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_PRValue, OK_Ordinary), ConceptReference(NestedNameSpecifierLoc(), SourceLocation(), DeclarationNameInfo(), NamedConcept, NamedConcept, nullptr), - SpecDecl(SpecDecl), + NumTemplateArgs(ConvertedArgs.size()), Satisfaction(Satisfaction ? ASTConstraintSatisfaction::Create(C, *Satisfaction) : nullptr) { + setTemplateArguments(ConvertedArgs); ExprDependence D = ExprDependence::None; if (!Satisfaction) D |= ExprDependence::Value; @@ -93,14 +110,26 @@ ConceptSpecializationExpr::ConceptSpecializationExpr( setDependence(D); } -ConceptSpecializationExpr *ConceptSpecializationExpr::Create( - const ASTContext &C, ConceptDecl *NamedConcept, - ImplicitConceptSpecializationDecl *SpecDecl, - const ConstraintSatisfaction *Satisfaction, bool Dependent, - bool ContainsUnexpandedParameterPack) { - return new (C) - ConceptSpecializationExpr(C, NamedConcept, SpecDecl, Satisfaction, - Dependent, ContainsUnexpandedParameterPack); +ConceptSpecializationExpr * +ConceptSpecializationExpr::Create(const ASTContext &C, + ConceptDecl *NamedConcept, + ArrayRef ConvertedArgs, + const ConstraintSatisfaction *Satisfaction, + bool Dependent, + bool ContainsUnexpandedParameterPack) { + void *Buffer = C.Allocate(totalSizeToAlloc( + ConvertedArgs.size())); + return new (Buffer) ConceptSpecializationExpr( + C, NamedConcept, ConvertedArgs, Satisfaction, Dependent, + ContainsUnexpandedParameterPack); +} + +ConceptSpecializationExpr * +ConceptSpecializationExpr::Create(ASTContext &C, EmptyShell Empty, + unsigned NumTemplateArgs) { + void *Buffer = C.Allocate(totalSizeToAlloc( + NumTemplateArgs)); + return new (Buffer) ConceptSpecializationExpr(Empty, NumTemplateArgs); } const TypeConstraint * diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 2bf104b58d947..8f28f96e93785 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -127,7 +127,6 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::OMPRequires: case Decl::Empty: case Decl::Concept: - case Decl::ImplicitConceptSpecialization: case Decl::LifetimeExtendedTemporary: case Decl::RequiresExprBody: // None of these decls require codegen support. diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index e5ee950e67997..484c02498f20b 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -265,8 +265,7 @@ static ExprResult calculateConstraintSatisfaction( return calculateConstraintSatisfaction( S, ConstraintExpr, Satisfaction, [&](const Expr *AtomicExpr) { EnterExpressionEvaluationContext ConstantEvaluated( - S, Sema::ExpressionEvaluationContext::ConstantEvaluated, - Sema::ReuseLambdaContextDecl); + S, Sema::ExpressionEvaluationContext::ConstantEvaluated); // Atomic constraint - substitute arguments and check satisfaction. ExprResult SubstitutedExpression; diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index a22708df5dbed..2143b811668af 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -282,8 +282,7 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) { DataMember, StaticDataMember, InlineVariable, - VariableTemplate, - Concept + VariableTemplate } Kind = Normal; // Default arguments of member function parameters that appear in a class @@ -308,8 +307,6 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) { } } else if (isa(ManglingContextDecl)) { Kind = DataMember; - } else if (isa(ManglingContextDecl)) { - Kind = Concept; } } @@ -333,11 +330,6 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) { return std::make_tuple(nullptr, nullptr); } - case Concept: - // Concept definitions aren't code generated and thus aren't mangled, - // however the ManglingContextDecl is important for the purposes of - // re-forming the template argument list of the lambda for constraint - // evaluation. case StaticDataMember: // -- the initializers of nonspecialized static members of template classes if (!IsInNonspecializedTemplate) diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index d81ed15f979f1..f6627c9bc53c3 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4866,9 +4866,6 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS, /*UpdateArgsWithConversions=*/false)) return ExprError(); - auto *CSD = ImplicitConceptSpecializationDecl::Create( - Context, NamedConcept->getDeclContext(), NamedConcept->getLocation(), - Converted); ConstraintSatisfaction Satisfaction; bool AreArgsDependent = TemplateSpecializationType::anyDependentTemplateArguments(*TemplateArgs, @@ -4876,10 +4873,6 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS, MultiLevelTemplateArgumentList MLTAL; MLTAL.addOuterTemplateArguments(NamedConcept, Converted); LocalInstantiationScope Scope(*this); - - EnterExpressionEvaluationContext EECtx{ - *this, ExpressionEvaluationContext::ConstantEvaluated, CSD}; - if (!AreArgsDependent && CheckConstraintSatisfaction( NamedConcept, {NamedConcept->getConstraintExpr()}, MLTAL, @@ -4888,11 +4881,10 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS, Satisfaction)) return ExprError(); - return ConceptSpecializationExpr::Create( - Context, + return ConceptSpecializationExpr::Create(Context, SS.isSet() ? SS.getWithLocInContext(Context) : NestedNameSpecifierLoc{}, TemplateKWLoc, ConceptNameInfo, FoundDecl, NamedConcept, - ASTTemplateArgumentListInfo::Create(Context, *TemplateArgs), CSD, + ASTTemplateArgumentListInfo::Create(Context, *TemplateArgs), Converted, AreArgsDependent ? nullptr : &Satisfaction); } diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 7475289745c7d..1400693f664ea 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -231,15 +231,6 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec, return Response::UseNextDecl(Rec); } -Response HandleImplicitConceptSpecializationDecl( - const ImplicitConceptSpecializationDecl *CSD, - MultiLevelTemplateArgumentList &Result) { - Result.addOuterTemplateArguments( - const_cast(CSD), - CSD->getTemplateArguments()); - return Response::UseNextDecl(CSD); -} - Response HandleGenericDeclContext(const Decl *CurDecl) { return Response::UseNextDecl(CurDecl); } @@ -298,9 +289,6 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs( ForConstraintInstantiation); } else if (const auto *Rec = dyn_cast(CurDecl)) { R = HandleRecordDecl(Rec, Result, Context, ForConstraintInstantiation); - } else if (const auto *CSD = - dyn_cast(CurDecl)) { - R = HandleImplicitConceptSpecializationDecl(CSD, Result); } else if (!isa(CurDecl)) { R = Response::DontClearRelativeToPrimaryNextDecl(CurDecl); if (CurDecl->getDeclContext()->isTranslationUnit()) { diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index dc694b2cb7c97..2c7fc8d56dbdb 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3965,11 +3965,6 @@ Decl *TemplateDeclInstantiator::VisitConceptDecl(ConceptDecl *D) { llvm_unreachable("Concept definitions cannot reside inside a template"); } -Decl *TemplateDeclInstantiator::VisitImplicitConceptSpecializationDecl( - ImplicitConceptSpecializationDecl *D) { - llvm_unreachable("Concept specializations cannot reside inside a template"); -} - Decl * TemplateDeclInstantiator::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) { return RequiresExprBodyDecl::Create(SemaRef.Context, D->getDeclContext(), diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index ebb83f12b6566..4f6ee0772c3c7 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -12606,8 +12606,7 @@ TreeTransform::TransformRequiresExpr(RequiresExpr *E) { // C++2a [expr.prim.req]p2 // Expressions appearing within a requirement-body are unevaluated operands. EnterExpressionEvaluationContext Ctx( - SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, - Sema::ReuseLambdaContextDecl); + SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create( getSema().Context, getSema().CurContext, diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index 152037dfc9269..53e4c889f5298 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -430,7 +430,6 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) { case Decl::Decomposition: case Decl::Binding: case Decl::Concept: - case Decl::ImplicitConceptSpecialization: case Decl::LifetimeExtendedTemporary: case Decl::RequiresExprBody: case Decl::UnresolvedUsingIfExists: diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 94a1d243918dd..36629101b7de4 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -384,8 +384,6 @@ namespace clang { void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); void VisitTemplateDecl(TemplateDecl *D); void VisitConceptDecl(ConceptDecl *D); - void VisitImplicitConceptSpecializationDecl( - ImplicitConceptSpecializationDecl *D); void VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D); RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D); void VisitClassTemplateDecl(ClassTemplateDecl *D); @@ -2236,17 +2234,6 @@ void ASTDeclReader::VisitConceptDecl(ConceptDecl *D) { mergeMergeable(D); } -void ASTDeclReader::VisitImplicitConceptSpecializationDecl( - ImplicitConceptSpecializationDecl *D) { - // The size of the template list was read during creation of the Decl, so we - // don't have to re-read it here. - VisitDecl(D); - llvm::SmallVector Args; - for (unsigned I = 0; I < D->NumTemplateArgs; ++I) - Args.push_back(Record.readTemplateArgument(/*Canonicalize=*/true)); - D->setTemplateArguments(Args); -} - void ASTDeclReader::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) { } @@ -3913,10 +3900,6 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { case DECL_HLSL_BUFFER: D = HLSLBufferDecl::CreateDeserialized(Context, ID); break; - case DECL_IMPLICIT_CONCEPT_SPECIALIZATION: - D = ImplicitConceptSpecializationDecl::CreateDeserialized(Context, ID, - Record.readInt()); - break; } assert(D && "Unknown declaration reading AST file"); diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index f6a2f85682b2a..98b8a960aef7c 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -794,13 +794,17 @@ readConstraintSatisfaction(ASTRecordReader &Record) { void ASTStmtReader::VisitConceptSpecializationExpr( ConceptSpecializationExpr *E) { VisitExpr(E); + unsigned NumTemplateArgs = Record.readInt(); E->NestedNameSpec = Record.readNestedNameSpecifierLoc(); E->TemplateKWLoc = Record.readSourceLocation(); E->ConceptName = Record.readDeclarationNameInfo(); E->NamedConcept = readDeclAs(); E->FoundDecl = Record.readDeclAs(); - E->SpecDecl = Record.readDeclAs(); E->ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); + llvm::SmallVector Args; + for (unsigned I = 0; I < NumTemplateArgs; ++I) + Args.push_back(Record.readTemplateArgument(/*Canonicalize*/ true)); + E->setTemplateArguments(Args); E->Satisfaction = E->isValueDependent() ? nullptr : ASTConstraintSatisfaction::Create(Record.getContext(), readConstraintSatisfaction(Record)); @@ -3999,7 +4003,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case EXPR_CONCEPT_SPECIALIZATION: { - S = new (Context) ConceptSpecializationExpr(Empty); + unsigned numTemplateArgs = Record[ASTStmtReader::NumExprFields]; + S = ConceptSpecializationExpr::Create(Context, Empty, numTemplateArgs); break; } diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 93785eeb9e880..afe59ef98c8e2 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -107,8 +107,6 @@ namespace clang { void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); void VisitTemplateDecl(TemplateDecl *D); void VisitConceptDecl(ConceptDecl *D); - void VisitImplicitConceptSpecializationDecl( - ImplicitConceptSpecializationDecl *D); void VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D); void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D); void VisitClassTemplateDecl(ClassTemplateDecl *D); @@ -1519,15 +1517,6 @@ void ASTDeclWriter::VisitConceptDecl(ConceptDecl *D) { Code = serialization::DECL_CONCEPT; } -void ASTDeclWriter::VisitImplicitConceptSpecializationDecl( - ImplicitConceptSpecializationDecl *D) { - Record.push_back(D->getTemplateArguments().size()); - VisitDecl(D); - for (const TemplateArgument &Arg : D->getTemplateArguments()) - Record.AddTemplateArgument(Arg); - Code = serialization::DECL_IMPLICIT_CONCEPT_SPECIALIZATION; -} - void ASTDeclWriter::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) { Code = serialization::DECL_REQUIRES_EXPR_BODY; } diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index be28ad6b2a668..65761566ab060 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -433,13 +433,16 @@ addSubstitutionDiagnostic( void ASTStmtWriter::VisitConceptSpecializationExpr( ConceptSpecializationExpr *E) { VisitExpr(E); + ArrayRef TemplateArgs = E->getTemplateArguments(); + Record.push_back(TemplateArgs.size()); 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()); + for (const TemplateArgument &Arg : TemplateArgs) + Record.AddTemplateArgument(Arg); if (!E->isValueDependent()) addConstraintSatisfaction(Record, E->getSatisfaction()); diff --git a/clang/test/AST/ast-dump-concepts.cpp b/clang/test/AST/ast-dump-concepts.cpp index 06518a71987a2..dff300a559517 100644 --- a/clang/test/AST/ast-dump-concepts.cpp +++ b/clang/test/AST/ast-dump-concepts.cpp @@ -19,11 +19,6 @@ template struct Foo { // CHECK: TemplateTypeParmDecl {{.*}} referenced Concept {{.*}} 'binary_concept' // CHECK-NEXT: `-ConceptSpecializationExpr {{.*}} 'bool' Concept {{.*}} 'binary_concept' - // CHECK-NEXT: |-ImplicitConceptSpecializationDecl {{.*}} col:9 - // CHECK-NEXT: | |-TemplateArgument type 'type-parameter-1-0' - // CHECK-NEXT: | | `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' dependent {{.*}}depth 1 index 0 - // CHECK-NEXT: | `-TemplateArgument type 'int' - // CHECK-NEXT: | `-BuiltinType {{.*}} 'int' // CHECK-NEXT: |-TemplateArgument {{.*}} type 'R' // CHECK-NEXT: | `-TemplateTypeParmType {{.*}} 'R' // CHECK-NEXT: | `-TemplateTypeParm {{.*}} 'R' @@ -34,9 +29,6 @@ struct Foo { // CHECK: TemplateTypeParmDecl {{.*}} referenced Concept {{.*}} 'unary_concept' // CHECK-NEXT: `-ConceptSpecializationExpr {{.*}} 'bool' - // CHECK-NEXT: |-ImplicitConceptSpecializationDecl {{.*}} col:9 - // CHECK-NEXT: | `-TemplateArgument type 'type-parameter-1-0' - // CHECK-NEXT: | `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' dependent {{.*}}depth 1 index 0 template Foo(R); diff --git a/clang/test/SemaTemplate/concepts-lambda.cpp b/clang/test/SemaTemplate/concepts-lambda.cpp index a4e8e0e50f026..13c402e3ca7a8 100644 --- a/clang/test/SemaTemplate/concepts-lambda.cpp +++ b/clang/test/SemaTemplate/concepts-lambda.cpp @@ -55,39 +55,3 @@ namespace GH57971 { using function_ptr = void(*)(int); function_ptr ptr = f; } - -// GH58368: A lambda defined in a concept requires we store -// the concept as a part of the lambda context. -namespace LambdaInConcept { -using size_t = unsigned long; - -template -struct IdxSeq{}; - -template -concept NotLike = true; - -template -struct AnyExcept { - template T> operator T&() const; - template T> operator T&&() const; -}; - -template - concept ConstructibleWithN = (requires { - [] - (IdxSeq) - requires requires { T{AnyExcept{}}; } - { } - (IdxSeq<1,2,3>{}); - }); - -struct Foo { - int i; - double j; - char k; -}; - -static_assert(ConstructibleWithN); - -} diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 9cdbddd82f76c..69d34646ca937 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -6700,7 +6700,6 @@ CXCursor clang_getCursorDefinition(CXCursor C) { case Decl::PragmaDetectMismatch: case Decl::UsingPack: case Decl::Concept: - case Decl::ImplicitConceptSpecialization: case Decl::LifetimeExtendedTemporary: case Decl::RequiresExprBody: case Decl::UnresolvedUsingIfExists: