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);
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<ConceptDecl> {
protected:
Expr *ConstraintExpr;
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<ImplicitConceptSpecializationDecl,
- TemplateArgument> {
- unsigned NumTemplateArgs;
-
- ImplicitConceptSpecializationDecl(DeclContext *DC, SourceLocation SL,
- ArrayRef<TemplateArgument> ConvertedArgs);
- ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
-
-public:
- static ImplicitConceptSpecializationDecl *
- Create(const ASTContext &C, DeclContext *DC, SourceLocation SL,
- ArrayRef<TemplateArgument> ConvertedArgs);
- static ImplicitConceptSpecializationDecl *
- CreateDeserialized(const ASTContext &C, unsigned ID,
- unsigned NumTemplateArgs);
-
- ArrayRef<TemplateArgument> getTemplateArguments() const {
- return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
- NumTemplateArgs);
- }
- void setTemplateArguments(ArrayRef<TemplateArgument> 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
///
/// 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<ConceptSpecializationExpr,
+ TemplateArgument> {
friend class ASTStmtReader;
-
+ friend TrailingObjects;
public:
using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>;
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
DeclarationNameInfo ConceptNameInfo,
NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ImplicitConceptSpecializationDecl *SpecDecl,
+ ArrayRef<TemplateArgument> ConvertedArgs,
const ConstraintSatisfaction *Satisfaction);
ConceptSpecializationExpr(const ASTContext &C, ConceptDecl *NamedConcept,
- ImplicitConceptSpecializationDecl *SpecDecl,
+ ArrayRef<TemplateArgument> 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<TemplateArgument> ConvertedArgs,
const ConstraintSatisfaction *Satisfaction);
static ConceptSpecializationExpr *
Create(const ASTContext &C, ConceptDecl *NamedConcept,
- ImplicitConceptSpecializationDecl *SpecDecl,
- const ConstraintSatisfaction *Satisfaction, bool Dependent,
+ ArrayRef<TemplateArgument> ConvertedArgs,
+ const ConstraintSatisfaction *Satisfaction,
+ bool Dependent,
bool ContainsUnexpandedParameterPack);
+ static ConceptSpecializationExpr *
+ Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
+
ArrayRef<TemplateArgument> getTemplateArguments() const {
- return SpecDecl->getTemplateArguments();
+ return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
+ 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<TemplateArgument> 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;
}
/// 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;
}
DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {})
-DEF_TRAVERSE_DECL(ImplicitConceptSpecializationDecl, {
- TRY_TO(TraverseTemplateArguments(D->getTemplateArguments().data(),
- D->getTemplateArguments().size()));
-})
-
#undef DEF_TRAVERSE_DECL
// ----------------- Stmt traversal -----------------
def ObjCImplementation : DeclNode<ObjCImpl>;
def ObjCProperty : DeclNode<Named, "Objective-C properties">;
def ObjCCompatibleAlias : DeclNode<Named>;
-def ImplicitConceptSpecialization : DeclNode<Decl>;
def LinkageSpec : DeclNode<Decl>, DeclContext;
def Export : DeclNode<Decl>, DeclContext;
def ObjCPropertyImpl : DeclNode<Decl>;
/// 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.
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<CXXFoldExpr>(IDC))
NewIDC = new (C) CXXFoldExpr(
case Empty:
case LifetimeExtendedTemporary:
case RequiresExprBody:
- case ImplicitConceptSpecialization:
// Never looked up by name.
return 0;
}
}
//===----------------------------------------------------------------------===//
-// ImplicitConceptSpecializationDecl Implementation
-//===----------------------------------------------------------------------===//
-ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
- DeclContext *DC, SourceLocation SL,
- ArrayRef<TemplateArgument> 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<TemplateArgument> ConvertedArgs) {
- return new (C, DC,
- additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
- ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
-}
-
-ImplicitConceptSpecializationDecl *
-ImplicitConceptSpecializationDecl::CreateDeserialized(
- const ASTContext &C, unsigned ID, unsigned NumTemplateArgs) {
- return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
- ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
-}
-
-void ImplicitConceptSpecializationDecl::setTemplateArguments(
- ArrayRef<TemplateArgument> Converted) {
- assert(Converted.size() == NumTemplateArgs);
- std::uninitialized_copy(Converted.begin(), Converted.end(),
- getTrailingObjects<TemplateArgument>());
-}
-
-//===----------------------------------------------------------------------===//
// ClassTemplatePartialSpecializationDecl Implementation
//===----------------------------------------------------------------------===//
void ClassTemplatePartialSpecializationDecl::anchor() {}
SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ImplicitConceptSpecializationDecl *SpecDecl,
+ ArrayRef<TemplateArgument> 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.
"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<TemplateArgument> Converted) {
+ assert(Converted.size() == NumTemplateArgs);
+ std::uninitialized_copy(Converted.begin(), Converted.end(),
+ getTrailingObjects<TemplateArgument>());
+}
+
+ConceptSpecializationExpr *
+ConceptSpecializationExpr::Create(const ASTContext &C,
+ NestedNameSpecifierLoc NNS,
+ SourceLocation TemplateKWLoc,
+ DeclarationNameInfo ConceptNameInfo,
+ NamedDecl *FoundDecl,
+ ConceptDecl *NamedConcept,
+ const ASTTemplateArgumentListInfo *ArgsAsWritten,
+ ArrayRef<TemplateArgument> ConvertedArgs,
+ const ConstraintSatisfaction *Satisfaction) {
+ void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
+ 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<TemplateArgument> 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;
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<TemplateArgument> ConvertedArgs,
+ const ConstraintSatisfaction *Satisfaction,
+ bool Dependent,
+ bool ContainsUnexpandedParameterPack) {
+ void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
+ 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<TemplateArgument>(
+ NumTemplateArgs));
+ return new (Buffer) ConceptSpecializationExpr(Empty, NumTemplateArgs);
}
const TypeConstraint *
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.
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;
DataMember,
StaticDataMember,
InlineVariable,
- VariableTemplate,
- Concept
+ VariableTemplate
} Kind = Normal;
// Default arguments of member function parameters that appear in a class
}
} else if (isa<FieldDecl>(ManglingContextDecl)) {
Kind = DataMember;
- } else if (isa<ImplicitConceptSpecializationDecl>(ManglingContextDecl)) {
- Kind = Concept;
}
}
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)
/*UpdateArgsWithConversions=*/false))
return ExprError();
- auto *CSD = ImplicitConceptSpecializationDecl::Create(
- Context, NamedConcept->getDeclContext(), NamedConcept->getLocation(),
- Converted);
ConstraintSatisfaction Satisfaction;
bool AreArgsDependent =
TemplateSpecializationType::anyDependentTemplateArguments(*TemplateArgs,
MultiLevelTemplateArgumentList MLTAL;
MLTAL.addOuterTemplateArguments(NamedConcept, Converted);
LocalInstantiationScope Scope(*this);
-
- EnterExpressionEvaluationContext EECtx{
- *this, ExpressionEvaluationContext::ConstantEvaluated, CSD};
-
if (!AreArgsDependent &&
CheckConstraintSatisfaction(
NamedConcept, {NamedConcept->getConstraintExpr()}, MLTAL,
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);
}
return Response::UseNextDecl(Rec);
}
-Response HandleImplicitConceptSpecializationDecl(
- const ImplicitConceptSpecializationDecl *CSD,
- MultiLevelTemplateArgumentList &Result) {
- Result.addOuterTemplateArguments(
- const_cast<ImplicitConceptSpecializationDecl *>(CSD),
- CSD->getTemplateArguments());
- return Response::UseNextDecl(CSD);
-}
-
Response HandleGenericDeclContext(const Decl *CurDecl) {
return Response::UseNextDecl(CurDecl);
}
ForConstraintInstantiation);
} else if (const auto *Rec = dyn_cast<CXXRecordDecl>(CurDecl)) {
R = HandleRecordDecl(Rec, Result, Context, ForConstraintInstantiation);
- } else if (const auto *CSD =
- dyn_cast<ImplicitConceptSpecializationDecl>(CurDecl)) {
- R = HandleImplicitConceptSpecializationDecl(CSD, Result);
} else if (!isa<DeclContext>(CurDecl)) {
R = Response::DontClearRelativeToPrimaryNextDecl(CurDecl);
if (CurDecl->getDeclContext()->isTranslationUnit()) {
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(),
// 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,
case Decl::Decomposition:
case Decl::Binding:
case Decl::Concept:
- case Decl::ImplicitConceptSpecialization:
case Decl::LifetimeExtendedTemporary:
case Decl::RequiresExprBody:
case Decl::UnresolvedUsingIfExists:
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);
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<TemplateArgument, 4> Args;
- for (unsigned I = 0; I < D->NumTemplateArgs; ++I)
- Args.push_back(Record.readTemplateArgument(/*Canonicalize=*/true));
- D->setTemplateArguments(Args);
-}
-
void ASTDeclReader::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) {
}
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");
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<ConceptDecl>();
E->FoundDecl = Record.readDeclAs<NamedDecl>();
- E->SpecDecl = Record.readDeclAs<ImplicitConceptSpecializationDecl>();
E->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
+ llvm::SmallVector<TemplateArgument, 4> 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));
break;
case EXPR_CONCEPT_SPECIALIZATION: {
- S = new (Context) ConceptSpecializationExpr(Empty);
+ unsigned numTemplateArgs = Record[ASTStmtReader::NumExprFields];
+ S = ConceptSpecializationExpr::Create(Context, Empty, numTemplateArgs);
break;
}
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);
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;
}
void ASTStmtWriter::VisitConceptSpecializationExpr(
ConceptSpecializationExpr *E) {
VisitExpr(E);
+ ArrayRef<TemplateArgument> 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());
struct Foo {
// CHECK: TemplateTypeParmDecl {{.*}} referenced Concept {{.*}} 'binary_concept'
// CHECK-NEXT: `-ConceptSpecializationExpr {{.*}} <col:13, col:31> 'bool' Concept {{.*}} 'binary_concept'
- // CHECK-NEXT: |-ImplicitConceptSpecializationDecl {{.*}} <line:13:9> 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'
// CHECK: TemplateTypeParmDecl {{.*}} referenced Concept {{.*}} 'unary_concept'
// CHECK-NEXT: `-ConceptSpecializationExpr {{.*}} <col:13> 'bool'
- // CHECK-NEXT: |-ImplicitConceptSpecializationDecl {{.*}} <line:10:9> col:9
- // CHECK-NEXT: | `-TemplateArgument type 'type-parameter-1-0'
- // CHECK-NEXT: | `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' dependent {{.*}}depth 1 index 0
template <unary_concept R>
Foo(R);
using function_ptr = void(*)(int);
function_ptr ptr = f<void>;
}
-
-// 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<size_t...Ts>
-struct IdxSeq{};
-
-template <class T, class... Ts>
-concept NotLike = true;
-
-template <size_t, class... Ts>
-struct AnyExcept {
- template <NotLike<Ts...> T> operator T&() const;
- template <NotLike<Ts...> T> operator T&&() const;
-};
-
-template <class T>
- concept ConstructibleWithN = (requires {
- []<size_t I, size_t... Idxs>
- (IdxSeq<I, Idxs...>)
- requires requires { T{AnyExcept<I, T>{}}; }
- { }
- (IdxSeq<1,2,3>{});
- });
-
-struct Foo {
- int i;
- double j;
- char k;
-};
-
-static_assert(ConstructibleWithN<Foo>);
-
-}
case Decl::PragmaDetectMismatch:
case Decl::UsingPack:
case Decl::Concept:
- case Decl::ImplicitConceptSpecialization:
case Decl::LifetimeExtendedTemporary:
case Decl::RequiresExprBody:
case Decl::UnresolvedUsingIfExists: