diff --git a/clang/include/clang/AST/ASTConcept.h b/clang/include/clang/AST/ASTConcept.h index 00500e214f4ce..ef560886924b3 100644 --- a/clang/include/clang/AST/ASTConcept.h +++ b/clang/include/clang/AST/ASTConcept.h @@ -26,6 +26,7 @@ namespace clang { class ConceptDecl; +class TemplateDecl; class Expr; class NamedDecl; struct PrintingPolicy; @@ -122,6 +123,7 @@ struct ASTConstraintSatisfaction final : /// template T> void dump(); /// ~~~~~~~~~~~~~~~~~~~~~~~ (in TemplateTypeParmDecl) class ConceptReference { +protected: // \brief The optional nested name specifier used when naming the concept. NestedNameSpecifierLoc NestedNameSpec; @@ -139,7 +141,7 @@ class ConceptReference { NamedDecl *FoundDecl; /// \brief The concept named. - ConceptDecl *NamedConcept; + TemplateDecl *NamedConcept; /// \brief The template argument list source info used to specialize the /// concept. @@ -147,7 +149,7 @@ class ConceptReference { ConceptReference(NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, - ConceptDecl *NamedConcept, + TemplateDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten) : NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc), ConceptName(ConceptNameInfo), FoundDecl(FoundDecl), @@ -157,7 +159,7 @@ class ConceptReference { static ConceptReference * Create(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, - NamedDecl *FoundDecl, ConceptDecl *NamedConcept, + NamedDecl *FoundDecl, TemplateDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten); const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const { @@ -196,9 +198,7 @@ class ConceptReference { return FoundDecl; } - ConceptDecl *getNamedConcept() const { - return NamedConcept; - } + TemplateDecl *getNamedConcept() const { return NamedConcept; } const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { return ArgsAsWritten; @@ -247,7 +247,7 @@ class TypeConstraint { // FIXME: Instead of using these concept related functions the callers should // directly work with the corresponding ConceptReference. - ConceptDecl *getNamedConcept() const { return ConceptRef->getNamedConcept(); } + TemplateDecl *getNamedConcept() const { return ConceptRef->getNamedConcept(); } SourceLocation getConceptNameLoc() const { return ConceptRef->getConceptNameLoc(); @@ -278,8 +278,10 @@ class TypeConstraint { void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const { ConceptRef->print(OS, Policy); } + }; + } // clang #endif // LLVM_CLANG_AST_ASTCONCEPT_H diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 1984310df0442..fc018add76fce 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1660,7 +1660,7 @@ class ASTContext : public RefCountedBase { QualType getAutoTypeInternal(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent, bool IsPack = false, - ConceptDecl *TypeConstraintConcept = nullptr, + TemplateDecl *TypeConstraintConcept = nullptr, ArrayRef TypeConstraintArgs = {}, bool IsCanon = false) const; @@ -1825,10 +1825,11 @@ class ASTContext : public RefCountedBase { UnaryTransformType::UTTKind UKind) const; /// C++11 deduced auto type. - QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, - bool IsDependent, bool IsPack = false, - ConceptDecl *TypeConstraintConcept = nullptr, - ArrayRef TypeConstraintArgs ={}) const; + QualType + getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent, + bool IsPack = false, + TemplateDecl *TypeConstraintConcept = nullptr, + ArrayRef TypeConstraintArgs = {}) const; /// C++11 deduction pattern for 'auto' type. QualType getAutoDeductType() const; diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 687715a22e9fd..d7433640ed009 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -26,6 +26,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" +#include "clang/Basic/TemplateKinds.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerIntPair.h" @@ -1600,15 +1601,22 @@ class TemplateTemplateParmDecl final /// The number of parameters in an expanded parameter pack. unsigned NumExpandedParams = 0; + TemplateNameKind ParameterKind = TemplateNameKind::TNK_Type_template; + TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, - bool Typename, TemplateParameterList *Params) + TemplateNameKind ParameterKind, + bool Typename, + TemplateParameterList *Params) : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), TemplateParmPosition(D, P), Typename(Typename), - ParameterPack(ParameterPack), ExpandedParameterPack(false) {} + ParameterPack(ParameterPack), + ExpandedParameterPack(false), ParameterKind(ParameterKind) {} TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, - unsigned P, IdentifierInfo *Id, bool Typename, + unsigned P, IdentifierInfo *Id, + TemplateNameKind ParameterKind, + bool Typename, TemplateParameterList *Params, ArrayRef Expansions); @@ -1619,14 +1627,17 @@ class TemplateTemplateParmDecl final friend class ASTDeclWriter; friend TrailingObjects; - static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, - SourceLocation L, unsigned D, - unsigned P, bool ParameterPack, - IdentifierInfo *Id, bool Typename, - TemplateParameterList *Params); static TemplateTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, - unsigned P, IdentifierInfo *Id, bool Typename, + unsigned P, bool ParameterPack, IdentifierInfo *Id, + TemplateNameKind ParameterKind, bool Typename, + TemplateParameterList *Params); + + static TemplateTemplateParmDecl * + Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, + unsigned P, IdentifierInfo *Id, + TemplateNameKind ParameterKind, + bool Typename, TemplateParameterList *Params, ArrayRef Expansions); @@ -1741,6 +1752,16 @@ class TemplateTemplateParmDecl final return SourceRange(getTemplateParameters()->getTemplateLoc(), End); } + TemplateNameKind kind() const { + return ParameterKind; + } + + bool isTypeConceptTemplateParam() const { + return kind() == TemplateNameKind::TNK_Concept_template && + getTemplateParameters()->size() > 0 && + isa(getTemplateParameters()->getParam(0)); + } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == TemplateTemplateParm; } @@ -3304,7 +3325,12 @@ inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) { return TD && (isa(TD) || isa(TD) || isa(TD) || - isa(TD)) + [&]() { + if (TemplateTemplateParmDecl *TTP = + dyn_cast(TD)) + return TTP->kind() == TNK_Type_template; + return false; + }()) ? TD : nullptr; } diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 975bcdac5069b..ff49bd9ea09b3 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -38,6 +38,7 @@ #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" +#include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TypeTraits.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerUnion.h" @@ -3132,7 +3133,49 @@ class OverloadExpr : public Expr { bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } /// Determines whether this expression had explicit template arguments. - bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } + bool hasExplicitTemplateArgs() const { + if (!hasTemplateKWAndArgsInfo()) + return false; + // FIXME corentin: deduced function types can have "hidden" args and no < + // investigate that further, but ultimately maybe we want to model concepts + // reference with another kind of expression. + return (isConceptReference() || isVarDeclReference()) + ? getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs + : getLAngleLoc().isValid(); + } + + bool isConceptReference() const { + return getNumDecls() == 1 && [&]() { + if (auto *TTP = dyn_cast_or_null( + getTrailingResults()->getDecl())) + return TTP->kind() == TNK_Concept_template; + if (isa(getTrailingResults()->getDecl())) + return true; + return false; + }(); + } + + bool isVarDeclReference() const { + return getNumDecls() == 1 && [&]() { + if (auto *TTP = dyn_cast_or_null( + getTrailingResults()->getDecl())) + return TTP->kind() == TNK_Var_template; + if (isa(getTrailingResults()->getDecl())) + return true; + return false; + }(); + } + + TemplateDecl *getTemplateDecl() const { + assert(getNumDecls() == 1); + return dyn_cast_or_null(getTrailingResults()->getDecl()); + } + + TemplateTemplateParmDecl *getTemplateTemplateDecl() const { + assert(getNumDecls() == 1); + return dyn_cast_or_null( + getTrailingResults()->getDecl()); + } TemplateArgumentLoc const *getTemplateArgs() const { if (!hasExplicitTemplateArgs()) @@ -4535,7 +4578,7 @@ class SubstNonTypeTemplateParmExpr : public Expr { return PackIndex - 1; } - NonTypeTemplateParmDecl *getParameter() const; + NamedDecl *getParameter() const; bool isReferenceParameter() const { return AssociatedDeclAndRef.getInt(); } diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h index 29913fd84c58b..8911b52cf8e32 100644 --- a/clang/include/clang/AST/ExprConcepts.h +++ b/clang/include/clang/AST/ExprConcepts.h @@ -84,7 +84,7 @@ class ConceptSpecializationExpr final : public Expr { ConceptReference *getConceptReference() const { return ConceptRef; } - ConceptDecl *getNamedConcept() const { return ConceptRef->getNamedConcept(); } + ConceptDecl *getNamedConcept() const { return cast(ConceptRef->getNamedConcept()); } // FIXME: Several of the following functions can be removed. Instead the // caller can directly work with the ConceptReference. @@ -152,6 +152,7 @@ class ConceptSpecializationExpr final : public Expr { return ConceptRef->getLocation(); } + // Iterators child_range children() { return child_range(child_iterator(), child_iterator()); diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index cd9947f7ab980..b0d7fcd9b3bf5 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -934,6 +934,7 @@ bool RecursiveASTVisitor::TraverseTemplateArgumentLoc( case TemplateArgument::Pack: return getDerived().TraverseTemplateArguments(Arg.pack_elements()); + } return true; diff --git a/clang/include/clang/AST/TemplateArgumentVisitor.h b/clang/include/clang/AST/TemplateArgumentVisitor.h index cf0d322015806..bf2f1e9626dc0 100644 --- a/clang/include/clang/AST/TemplateArgumentVisitor.h +++ b/clang/include/clang/AST/TemplateArgumentVisitor.h @@ -65,6 +65,8 @@ class Base { VISIT_METHOD(TemplateExpansion); VISIT_METHOD(Expression); VISIT_METHOD(Pack); + VISIT_METHOD(Universal); + VISIT_METHOD(UniversalExpansion); RetTy VisitTemplateArgument(REF(TemplateArgument), ParamTys...) { return RetTy(); diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h index 0eaa4b0eedb35..3f4c0d397491a 100644 --- a/clang/include/clang/AST/TemplateBase.h +++ b/clang/include/clang/AST/TemplateBase.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H #define LLVM_CLANG_AST_TEMPLATEBASE_H +#include "clang/AST/ASTFwd.h" #include "clang/AST/DependenceFlags.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" @@ -104,7 +105,7 @@ class TemplateArgument { /// The template argument is actually a parameter pack. Arguments are stored /// in the Args struct. - Pack + Pack, }; private: @@ -169,6 +170,7 @@ class TemplateArgument { unsigned IsDefaulted : 1; uintptr_t V; }; + union { struct DA DeclArg; struct I Integer; @@ -315,6 +317,8 @@ class TemplateArgument { /// Determine whether this template argument is a pack expansion. bool isPackExpansion() const; + bool isConceptOrConceptTemplateParameter() const; + /// Retrieve the type for a type template argument. QualType getAsType() const { assert(getKind() == Type && "Unexpected kind"); @@ -480,6 +484,7 @@ struct TemplateArgumentLocInfo { SourceLocation EllipsisLoc; }; + llvm::PointerUnion Pointer; @@ -625,6 +630,7 @@ class TemplateArgumentLoc { return SourceLocation(); return LocInfo.getTemplateEllipsisLoc(); } + }; /// A convenient class for passing around template argument diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index 57100e7ede171..9a32169d70398 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -252,6 +252,8 @@ class TextNodeDumper void VisitTemplateTemplateArgument(const TemplateArgument &TA); void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA); void VisitExpressionTemplateArgument(const TemplateArgument &TA); + void VisitConceptTemplateArgument(const TemplateArgument &TA); + void VisitPackTemplateArgument(const TemplateArgument &TA); void VisitIfStmt(const IfStmt *Node); diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index dc87b84153e74..346034a1b5ae5 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -6445,10 +6445,10 @@ class DeducedType : public Type { class AutoType : public DeducedType, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these - ConceptDecl *TypeConstraintConcept; + TemplateDecl *TypeConstraintConcept; AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, - TypeDependence ExtraDependence, QualType Canon, ConceptDecl *CD, + TypeDependence ExtraDependence, QualType Canon, TemplateDecl *CD, ArrayRef TypeConstraintArgs); public: @@ -6457,7 +6457,7 @@ class AutoType : public DeducedType, public llvm::FoldingSetNode { AutoTypeBits.NumArgs}; } - ConceptDecl *getTypeConstraintConcept() const { + TemplateDecl *getTypeConstraintConcept() const { return TypeConstraintConcept; } @@ -6480,7 +6480,7 @@ class AutoType : public DeducedType, public llvm::FoldingSetNode { void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context); static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, QualType Deduced, AutoTypeKeyword Keyword, - bool IsDependent, ConceptDecl *CD, + bool IsDependent, TemplateDecl *CD, ArrayRef Arguments); static bool classof(const Type *T) { diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index 62ca52e508ba2..f579d4ec16cd5 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -2259,7 +2259,7 @@ class AutoTypeLoc return nullptr; } - ConceptDecl *getNamedConcept() const { + TemplateDecl *getNamedConcept() const { if (const auto *CR = getConceptReference()) return CR->getNamedConcept(); return nullptr; diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td index bb7bfa8cd0b76..1a89dfc67bc9b 100644 --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -506,9 +506,9 @@ let Class = AutoType in { def : Property<"keyword", AutoTypeKeyword> { let Read = [{ node->getKeyword() }]; } - def : Property<"typeConstraintConcept", Optional> { + def : Property<"typeConstraintConcept", Optional> { let Read = [{ makeOptionalFromPointer( - const_cast(node->getTypeConstraintConcept())) }]; + node->getTypeConstraintConcept()) }]; } def : Property<"typeConstraintArguments", Array> { let Read = [{ node->getTypeConstraintArguments() }]; diff --git a/clang/include/clang/AST/UniversalTemplateParameterName.h b/clang/include/clang/AST/UniversalTemplateParameterName.h new file mode 100644 index 0000000000000..f72ab8cfca067 --- /dev/null +++ b/clang/include/clang/AST/UniversalTemplateParameterName.h @@ -0,0 +1,63 @@ +//===- TemplateName.h - C++ Template Name Representation --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the TemplateName interface and subclasses. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_UNIVERSALTEMPLATEPARAMETERNAME_H +#define LLVM_CLANG_AST_UNIVERSALTEMPLATEPARAMETERNAME_H + +#include "clang/AST/DeclarationName.h" +#include "clang/AST/NestedNameSpecifier.h" +#include "clang/Basic/SourceLocation.h" + +namespace clang { + +class UniversalTemplateParmDecl; + +class UniversalTemplateParameterName { + + SourceLocation Loc; + DeclarationNameInfo Name; + UniversalTemplateParmDecl *Param; + +public: + UniversalTemplateParameterName(SourceLocation Loc, DeclarationNameInfo Name, + UniversalTemplateParmDecl *Param); + + SourceLocation getLocation() const { return Loc; } + + UniversalTemplateParmDecl *getDecl() const { return Param; } + + DeclarationNameInfo getNameInfo() const { return Name; } + + bool containsUnexpandedParameterPack() const; + + void Profile(const ASTContext &Context, llvm::FoldingSetNodeID &ID) const { + Profile(ID, Name, Param, Context); + } + + static void Profile(llvm::FoldingSetNodeID &ID, DeclarationNameInfo Name, + const UniversalTemplateParmDecl *Decl, + const ASTContext &Context); + + void print(raw_ostream &OS, const PrintingPolicy &Policy) const; + + void dump(raw_ostream &OS) const; + void dump() const; +}; + +/// Insertion operator for diagnostics. This allows sending TemplateName's +/// into a diagnostic with <<. +const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, + UniversalTemplateParameterName N); + +} // namespace clang + +#endif // LLVM_CLANG_AST_UNIVERSALTEMPLATEPARAMETERNAME_H diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e4e04bff8b512..430184c859d58 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5247,7 +5247,7 @@ def err_template_arg_must_be_expr : Error< def err_template_arg_nontype_ambig : Error< "template argument for non-type template parameter is treated as function type %0">; def err_template_arg_must_be_template : Error< - "template argument for template template parameter must be a class template%select{| or type alias template}0">; + "template argument for template template parameter must be a %select{class template%select{| or type alias template}1|variable template|concept}0">; def ext_template_arg_local_type : ExtWarn< "template argument uses local type %0">, InGroup; def ext_template_arg_unnamed_type : ExtWarn< @@ -5263,10 +5263,18 @@ def note_template_unnamed_type_here : Note< def err_template_arg_overload_type : Error< "template argument is the type of an unresolved overloaded function">; def err_template_arg_not_valid_template : Error< - "template argument does not refer to a class or alias template, or template " + "template argument does not refer to a %select{class or alias template|variable template|concept}0, or template " "template parameter">; -def note_template_arg_refers_here_func : Note< - "template argument refers to function template %0, here">; +def err_partial_concept_valid_template : Error< + "name of template argument does not refer to concept, or concept " + "template parameter">; +def err_partial_concept_param_must_have_one_arg : Error< + "the corresponding template parameter of a partially applied concept must have exactly one argument">; +def note_concept_template_parameter_declared_here : Error< + "concept template parameter declared here">; + +def note_template_arg_refers_to_template_here : Note< + "template argument refers to a %select{function template|class template|variable template|concept}0 %1, here">; def err_template_arg_template_params_mismatch : Error< "template template argument has different template parameters than its " "corresponding template template parameter">; @@ -7663,6 +7671,7 @@ def warn_format_nonliteral : Warning< def err_unexpected_interface : Error< "unexpected interface name %0: expected expression">; def err_ref_non_value : Error<"%0 does not refer to a value">; +def err_ref_utp : Error<"%0 refers to a universal template parameter outside of a template argument list">; def err_ref_vm_type : Error< "cannot refer to declaration with a variably modified type inside block">; def err_ref_flexarray_type : Error< diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index c5c3838407cf4..8441e03ef2bcb 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -860,6 +860,7 @@ ANNOTATION(template_id) // annotation for a C++ template-id that names a // might not have explicit template arguments), // e.g. "C", "C". ANNOTATION(non_type) // annotation for a single non-type declaration +ANNOTATION(universal) // annotation for a universal template parameter ANNOTATION(non_type_undeclared) // annotation for an undeclared identifier that // was assumed to be an ADL-only function name ANNOTATION(non_type_dependent) // annotation for an assumed non-type member of diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index eb8a851da7e04..e247adf80f6ac 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -169,6 +169,9 @@ class Parser : public CodeCompletionHandler { mutable IdentifierInfo *Ident_import; mutable IdentifierInfo *Ident_module; + // C++2c contextual keywords + mutable IdentifierInfo *Ident_universal; + // C++ type trait keywords that can be reverted to identifiers and still be // used as type traits. llvm::SmallDenseMap RevertibleTypeTraits; diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index 06243f2624876..e1495b9731c2d 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -2899,6 +2899,7 @@ struct InventedTemplateParameterInfo { SmallVector TemplateParams; }; + } // end namespace clang #endif // LLVM_CLANG_SEMA_DECLSPEC_H diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h index 0455e1fa5016b..48b497a7f406b 100644 --- a/clang/include/clang/Sema/Initialization.h +++ b/clang/include/clang/Sema/Initialization.h @@ -160,7 +160,7 @@ class alignas(8) InitializedEntity { struct VD { /// The VarDecl, FieldDecl, or BindingDecl being initialized. - ValueDecl *VariableOrMember; + NamedDecl *VariableOrMember; /// When Kind == EK_Member, whether this is an implicit member /// initialization in a copy or move constructor. These can perform array @@ -291,8 +291,8 @@ class alignas(8) InitializedEntity { } /// Create the initialization entity for a template parameter. - static InitializedEntity - InitializeTemplateParameter(QualType T, NonTypeTemplateParmDecl *Param) { + static InitializedEntity InitializeTemplateParameter(QualType T, + NamedDecl *Param) { InitializedEntity Entity; Entity.Kind = EK_TemplateParameter; Entity.Type = T; diff --git a/clang/include/clang/Sema/Ownership.h b/clang/include/clang/Sema/Ownership.h index 0752f5de7e334..b1520837f2f9d 100644 --- a/clang/include/clang/Sema/Ownership.h +++ b/clang/include/clang/Sema/Ownership.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_SEMA_OWNERSHIP_H #define LLVM_CLANG_SEMA_OWNERSHIP_H +#include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/ArrayRef.h" diff --git a/clang/include/clang/Sema/ParsedTemplate.h b/clang/include/clang/Sema/ParsedTemplate.h index ac4dbbf294caf..69932fdf5806b 100644 --- a/clang/include/clang/Sema/ParsedTemplate.h +++ b/clang/include/clang/Sema/ParsedTemplate.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H #define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H +#include "clang/AST/DeclTemplate.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/TemplateKinds.h" @@ -25,114 +26,116 @@ #include namespace clang { - /// Represents the parsed form of a C++ template argument. - class ParsedTemplateArgument { - public: - /// Describes the kind of template argument that was parsed. - enum KindType { - /// A template type parameter, stored as a type. - Type, - /// A non-type template parameter, stored as an expression. - NonType, - /// A template template argument, stored as a template name. - Template - }; - - /// Build an empty template argument. - /// - /// This template argument is invalid. - ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { } - - /// Create a template type argument or non-type template argument. - /// - /// \param Arg the template type argument or non-type template argument. - /// \param Loc the location of the type. - ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc) - : Kind(Kind), Arg(Arg), Loc(Loc) { } - - /// Create a template template argument. - /// - /// \param SS the C++ scope specifier that precedes the template name, if - /// any. - /// - /// \param Template the template to which this template template - /// argument refers. - /// - /// \param TemplateLoc the location of the template name. - ParsedTemplateArgument(const CXXScopeSpec &SS, - ParsedTemplateTy Template, - SourceLocation TemplateLoc) - : Kind(ParsedTemplateArgument::Template), - Arg(Template.getAsOpaquePtr()), SS(SS), Loc(TemplateLoc) {} - - /// Determine whether the given template argument is invalid. - bool isInvalid() const { return Arg == nullptr; } - - /// Determine what kind of template argument we have. - KindType getKind() const { return Kind; } - - /// Retrieve the template type argument's type. - ParsedType getAsType() const { - assert(Kind == Type && "Not a template type argument"); - return ParsedType::getFromOpaquePtr(Arg); - } - - /// Retrieve the non-type template argument's expression. - Expr *getAsExpr() const { - assert(Kind == NonType && "Not a non-type template argument"); - return static_cast(Arg); - } - - /// Retrieve the template template argument's template name. - ParsedTemplateTy getAsTemplate() const { - assert(Kind == Template && "Not a template template argument"); - return ParsedTemplateTy::getFromOpaquePtr(Arg); - } - /// Retrieve the location of the template argument. - SourceLocation getLocation() const { return Loc; } +/// Represents the parsed form of a C++ template argument. +class ParsedTemplateArgument { +public: + /// Describes the kind of template argument that was parsed. + enum KindType { + /// A template type parameter, stored as a type. + Type, + /// A non-type template parameter, stored as an expression. + NonType, + /// A template template argument, stored as a template name. + Template, + }; - /// Retrieve the nested-name-specifier that precedes the template - /// name in a template template argument. - const CXXScopeSpec &getScopeSpec() const { - assert(Kind == Template && - "Only template template arguments can have a scope specifier"); - return SS; - } + /// Build an empty template argument. + /// + /// This template argument is invalid. + ParsedTemplateArgument() : Kind(Type), Arg(nullptr) {} - /// Retrieve the location of the ellipsis that makes a template - /// template argument into a pack expansion. - SourceLocation getEllipsisLoc() const { - assert(Kind == Template && - "Only template template arguments can have an ellipsis"); - return EllipsisLoc; - } + /// Create a template type argument or non-type template argument. + /// + /// \param Arg the template type argument or non-type template argument. + /// \param Loc the location of the type. + ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc) + : Kind(Kind), Arg(Arg), Loc(Loc) {} - /// Retrieve a pack expansion of the given template template - /// argument. - /// - /// \param EllipsisLoc The location of the ellipsis. - ParsedTemplateArgument getTemplatePackExpansion( - SourceLocation EllipsisLoc) const; + /// Create a template template argument. + /// + /// \param SS the C++ scope specifier that precedes the template name, if + /// any. + /// + /// \param Template the template to which this template template + /// argument refers. + /// + /// \param TemplateLoc the location of the template name. + ParsedTemplateArgument(const CXXScopeSpec &SS, ParsedTemplateTy Template, + SourceLocation TemplateLoc) + : Kind(ParsedTemplateArgument::Template), Arg(Template.getAsOpaquePtr()), + SS(SS), Loc(TemplateLoc) {} + + /// Determine whether the given template argument is invalid. + bool isInvalid() const { return Arg == nullptr; } + + /// Determine what kind of template argument we have. + KindType getKind() const { return Kind; } + + /// Retrieve the template type argument's type. + ParsedType getAsType() const { + assert(Kind == Type && "Not a template type argument"); + return ParsedType::getFromOpaquePtr(Arg); + } + + /// Retrieve the non-type template argument's expression. + Expr *getAsExpr() const { + assert(Kind == NonType && "Not a non-type template argument"); + return static_cast(Arg); + } + + /// Retrieve the template template argument's template name. + ParsedTemplateTy getAsTemplate() const { + assert(Kind == Template && "Not a template template argument"); + return ParsedTemplateTy::getFromOpaquePtr(Arg); + } + + /// Retrieve the location of the template argument. + SourceLocation getLocation() const { return Loc; } + + /// Retrieve the nested-name-specifier that precedes the template + /// name in a template template argument. + const CXXScopeSpec &getScopeSpec() const { + assert((Kind == Template) && + "Only template template arguments can have a scope specifier"); + return SS; + } + + /// Retrieve the location of the ellipsis that makes a template + /// template argument into a pack expansion. + SourceLocation getEllipsisLoc() const { + assert( + (Kind == Template) && + "Only template arguments can have an ellipsis"); + return EllipsisLoc; + } + + /// Retrieve a pack expansion of the given template template + /// argument. + /// + /// \param EllipsisLoc The location of the ellipsis. + ParsedTemplateArgument + getTemplatePackExpansion(SourceLocation EllipsisLoc) const; - private: - KindType Kind; +private: + KindType Kind; - /// The actual template argument representation, which may be - /// an \c Sema::TypeTy* (for a type), an Expr* (for an - /// expression), or an Sema::TemplateTy (for a template). - void *Arg; + /// The actual template argument representation, which may be + /// an \c Sema::TypeTy* (for a type), an Expr* (for an + /// expression), or an Sema::TemplateTy (for a template). + void *Arg; - /// The nested-name-specifier that can accompany a template template - /// argument. - CXXScopeSpec SS; + /// The nested-name-specifier that can accompany a template template + /// argument. + CXXScopeSpec SS; - /// the location of the template argument. - SourceLocation Loc; + /// the location of the template argument. + SourceLocation Loc; - /// The ellipsis location that can accompany a template template - /// argument (turning it into a template template argument expansion). - SourceLocation EllipsisLoc; + /// The ellipsis location that can accompany a template/universal template + /// argument (turning it into a template/universal template argument + /// expansion). + SourceLocation EllipsisLoc; }; /// Information about a template-id annotation diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e1c3a99cfa167..657fc85a5d216 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -32,6 +32,8 @@ #include "clang/AST/StmtCXX.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" +#include "clang/AST/TypeOrdering.h" +#include "clang/Basic/BitmaskEnum.h" #include "clang/Basic/AttrSubjectMatchRules.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/CapturedStmt.h" @@ -144,6 +146,7 @@ class MangleNumberingContext; typedef ArrayRef> ModuleIdPath; class ModuleLoader; class MultiLevelTemplateArgumentList; +struct CachedNormalizedConstraint; struct NormalizedConstraint; class ObjCInterfaceDecl; class ObjCMethodDecl; @@ -8912,7 +8915,6 @@ class Sema final : public SemaBase { getCurrentMangleNumberContext(const DeclContext *DC); ///@} - // // // ------------------------------------------------------------------------- @@ -11249,7 +11251,7 @@ class Sema final : public SemaBase { /// of arguments for the named concept). bool AttachTypeConstraint(NestedNameSpecifierLoc NS, DeclarationNameInfo NameInfo, - ConceptDecl *NamedConcept, NamedDecl *FoundDecl, + TemplateDecl *NamedConcept, NamedDecl *FoundDecl, const TemplateArgumentListInfo *TemplateArgs, TemplateTypeParmDecl *ConstrainedParameter, SourceLocation EllipsisLoc); @@ -11274,26 +11276,35 @@ class Sema final : public SemaBase { QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc); NamedDecl *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, - unsigned Depth, unsigned Position, - SourceLocation EqualLoc, - Expr *DefaultArg); + unsigned Depth, + unsigned Position, + SourceLocation EqualLoc, + Expr *DefaultArg); /// ActOnTemplateTemplateParameter - Called when a C++ template template /// parameter (e.g. T in template