From 62e4b501ab3bc4c5815a179fdd2c4b49574506c1 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 21 Jan 2020 19:01:38 -0800 Subject: [PATCH] Revert "[Concepts] Placeholder constraints and abbreviated templates" This temporarily reverts commit e03ead6771fc97b11cb0c94b7f023142184ad25f because it breaks LLDB. http://lab.llvm.org:8011/builders/lldb-x86_64-debian/builds/3356 http://lab.llvm.org:8011/builders/lldb-x64-windows-ninja/builds/12872 http://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/6407/ --- clang/include/clang/AST/ASTContext.h | 7 +- clang/include/clang/AST/ASTNodeTraverser.h | 4 +- clang/include/clang/AST/DeclTemplate.h | 43 +-- clang/include/clang/AST/PropertiesBase.td | 2 - clang/include/clang/AST/RecursiveASTVisitor.h | 14 +- clang/include/clang/AST/TemplateBase.h | 7 +- clang/include/clang/AST/Type.h | 74 ++--- clang/include/clang/AST/TypeLoc.h | 138 +--------- clang/include/clang/AST/TypeProperties.td | 11 +- .../clang/Basic/DiagnosticParseKinds.td | 2 - .../clang/Basic/DiagnosticSemaKinds.td | 12 +- clang/include/clang/Sema/DeclSpec.h | 72 +---- clang/include/clang/Sema/Scope.h | 6 - clang/include/clang/Sema/ScopeInfo.h | 20 +- clang/include/clang/Sema/Sema.h | 47 +--- clang/lib/AST/ASTContext.cpp | 152 +++++----- clang/lib/AST/ASTImporter.cpp | 18 +- clang/lib/AST/ASTStructuralEquivalence.cpp | 26 +- clang/lib/AST/DeclTemplate.cpp | 44 +-- clang/lib/AST/ODRHash.cpp | 7 - clang/lib/AST/TemplateBase.cpp | 2 +- clang/lib/AST/TextNodeDumper.cpp | 5 - clang/lib/AST/Type.cpp | 36 +-- clang/lib/AST/TypeLoc.cpp | 95 ------- clang/lib/AST/TypePrinter.cpp | 29 +- clang/lib/Parse/ParseCXXInlineMethods.cpp | 4 +- clang/lib/Parse/ParseDecl.cpp | 73 +---- clang/lib/Parse/ParseDeclCXX.cpp | 2 - clang/lib/Parse/ParseTemplate.cpp | 5 +- clang/lib/Parse/ParseTentative.cpp | 21 -- clang/lib/Parse/Parser.cpp | 24 -- clang/lib/Sema/DeclSpec.cpp | 9 - clang/lib/Sema/Sema.cpp | 15 - clang/lib/Sema/SemaDecl.cpp | 39 +-- clang/lib/Sema/SemaDeclCXX.cpp | 47 ---- clang/lib/Sema/SemaLambda.cpp | 3 +- clang/lib/Sema/SemaTemplate.cpp | 190 +++++-------- clang/lib/Sema/SemaTemplateDeduction.cpp | 77 +----- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 10 - clang/lib/Sema/SemaType.cpp | 227 +++------------ clang/lib/Sema/TreeTransform.h | 137 +++------ clang/lib/Serialization/ASTReader.cpp | 11 - clang/lib/Serialization/ASTReaderDecl.cpp | 22 +- clang/lib/Serialization/ASTWriter.cpp | 12 - clang/lib/Serialization/ASTWriterDecl.cpp | 4 - .../ast-dump-record-definition-data-json.cpp | 57 +--- clang/test/CXX/dcl/dcl.fct/p17.cpp | 260 ------------------ .../dcl.spec/dcl.type/dcl.spec.auto/p6.cpp | 44 --- .../expr.prim.lambda.closure/p3.cpp | 6 +- clang/test/CXX/temp/temp.param/p10-2a.cpp | 25 +- .../cxx2a-placeholder-type-constraint.cpp | 26 -- clang/test/SemaCXX/cxx1y-generic-lambdas.cpp | 2 +- .../ms-delayed-default-template-args.cpp | 3 +- 53 files changed, 361 insertions(+), 1867 deletions(-) delete mode 100644 clang/test/CXX/dcl/dcl.fct/p17.cpp delete mode 100644 clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp delete mode 100644 clang/test/Parser/cxx2a-placeholder-type-constraint.cpp diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index f8403cf13c4a..fb269cef1ce8 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -88,7 +88,6 @@ class AtomicExpr; class BlockExpr; class BuiltinTemplateDecl; class CharUnits; -class ConceptDecl; class CXXABI; class CXXConstructorDecl; class CXXMethodDecl; @@ -212,7 +211,7 @@ class ASTContext : public RefCountedBase { mutable llvm::FoldingSet ObjCObjectPointerTypes; mutable llvm::FoldingSet DependentUnaryTransformTypes; - mutable llvm::ContextualFoldingSet AutoTypes; + mutable llvm::FoldingSet AutoTypes; mutable llvm::FoldingSet DeducedTemplateSpecializationTypes; mutable llvm::FoldingSet AtomicTypes; @@ -1543,9 +1542,7 @@ public: /// C++11 deduced auto type. QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, - bool IsDependent, bool IsPack = false, - ConceptDecl *TypeConstraintConcept = nullptr, - ArrayRef TypeConstraintArgs ={}) const; + bool IsDependent, bool IsPack = false) const; /// C++11 deduction pattern for 'auto' type. QualType getAutoDeductType() const; diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h index 9ebf64a12af5..e0ebb020e697 100644 --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -548,8 +548,8 @@ public: } void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { - if (const auto *E = D->getPlaceholderTypeConstraint()) - Visit(E); + if (const auto *TC = D->getPlaceholderTypeConstraint()) + Visit(TC->getImmediatelyDeclaredConstraint()); if (D->hasDefaultArgument()) Visit(D->getDefaultArgument(), SourceRange(), D->getDefaultArgStorage().getInheritedFrom(), diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 7a9f623d8152..7a55d04a0f35 100755 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -1102,17 +1102,6 @@ public: /// template. ArrayRef getInjectedTemplateArgs(); - /// Return whether this function template is an abbreviated function template, - /// e.g. `void foo(auto x)` or `template void foo(auto x)` - bool isAbbreviated() const { - // Since the invented template parameters generated from 'auto' parameters - // are either appended to the end of the explicit template parameter list or - // form a new template paramter list, we can simply observe the last - // parameter to determine if such a thing happened. - const TemplateParameterList *TPL = getTemplateParameters(); - return TPL->getParam(TPL->size() - 1)->isImplicit(); - } - /// Merge \p Prev with our RedeclarableTemplateDecl::Common. void mergePrevDecl(FunctionTemplateDecl *Prev); @@ -1226,6 +1215,7 @@ public: bool ParameterPack, bool HasTypeConstraint = false, Optional NumExpanded = None); + static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, unsigned ID); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, @@ -1384,8 +1374,7 @@ class NonTypeTemplateParmDecl final : public DeclaratorDecl, protected TemplateParmPosition, private llvm::TrailingObjects, - Expr *> { + std::pair> { friend class ASTDeclReader; friend TrailingObjects; @@ -1440,12 +1429,10 @@ public: ArrayRef ExpandedTInfos); static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, - unsigned ID, - bool HasTypeConstraint); + unsigned ID); static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, unsigned ID, - unsigned NumExpandedTypes, - bool HasTypeConstraint); + unsigned NumExpandedTypes); using TemplateParmPosition::getDepth; using TemplateParmPosition::setDepth; @@ -1556,22 +1543,20 @@ public: return TypesAndInfos[I].second; } - /// Return the constraint introduced by the placeholder type of this non-type + /// Return the type-constraint in the placeholder type of this non-type /// template parameter (if any). - Expr *getPlaceholderTypeConstraint() const { - return hasPlaceholderTypeConstraint() ? *getTrailingObjects() : - nullptr; - } - - void setPlaceholderTypeConstraint(Expr *E) { - *getTrailingObjects() = E; + TypeConstraint *getPlaceholderTypeConstraint() const { + // TODO: Concepts: Implement once we have actual placeholders with type + // constraints. + return nullptr; } /// Determine whether this non-type template parameter's type has a /// placeholder with a type-constraint. bool hasPlaceholderTypeConstraint() const { - auto *AT = getType()->getContainedAutoType(); - return AT && AT->isConstrained(); + // TODO: Concepts: Implement once we have actual placeholders with type + // constraints. + return false; } /// \brief Get the associated-constraints of this template parameter. @@ -1581,8 +1566,8 @@ public: /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for /// concepts APIs that accept an ArrayRef of constraint expressions. void getAssociatedConstraints(llvm::SmallVectorImpl &AC) const { - if (Expr *E = getPlaceholderTypeConstraint()) - AC.push_back(E); + if (TypeConstraint *TC = getPlaceholderTypeConstraint()) + AC.push_back(TC->getImmediatelyDeclaredConstraint()); } // Implement isa/cast/dyncast/etc. diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td index ba0f237a3bc3..9aacdb9fee36 100644 --- a/clang/include/clang/AST/PropertiesBase.td +++ b/clang/include/clang/AST/PropertiesBase.td @@ -99,8 +99,6 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; } SubclassPropertyType<"TagDecl", DeclRef>; def TemplateDeclRef : SubclassPropertyType<"TemplateDecl", DeclRef>; - def ConceptDeclRef : - SubclassPropertyType<"ConceptDecl", DeclRef>; def TemplateTypeParmDeclRef : SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>; def TemplateTemplateParmDeclRef : diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 86521d82c6ff..4633122aba48 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1040,13 +1040,7 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, { TRY_TO(TraverseType(T->getUnderlyingType())); }) -DEF_TRAVERSE_TYPE(AutoType, { - TRY_TO(TraverseType(T->getDeducedType())); - if (T->isConstrained()) { - TRY_TO(TraverseDecl(T->getTypeConstraintConcept())); - TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs())); - } -}) +DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); }) DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, { TRY_TO(TraverseTemplateName(T->getTemplateName())); TRY_TO(TraverseType(T->getDeducedType())); @@ -1293,12 +1287,6 @@ DEF_TRAVERSE_TYPELOC(UnaryTransformType, { 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))); - } }) DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, { diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h index 93f7b62b8aea..058a5bc0a067 100644 --- a/clang/include/clang/AST/TemplateBase.h +++ b/clang/include/clang/AST/TemplateBase.h @@ -637,7 +637,7 @@ public: } static const ASTTemplateArgumentListInfo * - Create(const ASTContext &C, const TemplateArgumentListInfo &List); + Create(ASTContext &C, const TemplateArgumentListInfo &List); }; /// Represents an explicit template argument list in C++, e.g., @@ -702,11 +702,6 @@ inline const TemplateArgument & return getArgs()[Idx]; } -inline const TemplateArgument &AutoType::getArg(unsigned Idx) const { - assert(Idx < getNumArgs() && "Template argument out of range"); - return getArgs()[Idx]; -} - } // namespace clang #endif // LLVM_CLANG_AST_TEMPLATEBASE_H diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index e8248147f9ad..2291d776db3e 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -58,7 +58,6 @@ namespace clang { class ExtQuals; class QualType; -class ConceptDecl; class TagDecl; class Type; @@ -1684,15 +1683,6 @@ protected: /// Was this placeholder type spelled as 'auto', 'decltype(auto)', /// or '__auto_type'? AutoTypeKeyword value. unsigned Keyword : 2; - - /// The number of template arguments in the type-constraints, which is - /// expected to be able to hold at least 1024 according to [implimits]. - /// However as this limit is somewhat easy to hit with template - /// metaprogramming we'd prefer to keep it as large as possible. - /// At the moment it has been left as a non-bitfield since this type - /// safely fits in 64 bits as an unsigned, so there is no reason to - /// introduce the performance impact of a bitfield. - unsigned NumArgs; }; class SubstTemplateTypeParmPackTypeBitfields { @@ -4824,7 +4814,8 @@ public: /// Common base class for placeholders for types that get replaced by /// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced -/// class template types, and constrained type names. +/// class template types, and (eventually) constrained type names from the C++ +/// Concepts TS. /// /// These types are usually a placeholder for a deduced type. However, before /// the initializer is attached, or (usually) if the initializer is @@ -4869,50 +4860,18 @@ public: } }; -/// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained -/// by a type-constraint. -class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode { +/// Represents a C++11 auto or C++14 decltype(auto) type. +class AutoType : public DeducedType, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these - ConceptDecl *TypeConstraintConcept; - AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, - bool IsDeducedAsDependent, bool IsDeducedAsPack, ConceptDecl *CD, - ArrayRef TypeConstraintArgs); - - const TemplateArgument *getArgBuffer() const { - return reinterpret_cast(this+1); - } - - TemplateArgument *getArgBuffer() { - return reinterpret_cast(this+1); + bool IsDeducedAsDependent, bool IsDeducedAsPack) + : DeducedType(Auto, DeducedAsType, IsDeducedAsDependent, + IsDeducedAsDependent, IsDeducedAsPack) { + AutoTypeBits.Keyword = (unsigned)Keyword; } public: - /// Retrieve the template arguments. - const TemplateArgument *getArgs() const { - return getArgBuffer(); - } - - /// Retrieve the number of template arguments. - unsigned getNumArgs() const { - return AutoTypeBits.NumArgs; - } - - const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h - - ArrayRef getTypeConstraintArguments() const { - return {getArgs(), getNumArgs()}; - } - - ConceptDecl *getTypeConstraintConcept() const { - return TypeConstraintConcept; - } - - bool isConstrained() const { - return TypeConstraintConcept != nullptr; - } - bool isDecltypeAuto() const { return getKeyword() == AutoTypeKeyword::DecltypeAuto; } @@ -4921,15 +4880,18 @@ public: return (AutoTypeKeyword)AutoTypeBits.Keyword; } - void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { - Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(), - getTypeConstraintConcept(), getTypeConstraintArguments()); + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getDeducedType(), getKeyword(), isDependentType(), + containsUnexpandedParameterPack()); } - static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, - QualType Deduced, AutoTypeKeyword Keyword, - bool IsDependent, ConceptDecl *CD, - ArrayRef Arguments); + static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced, + AutoTypeKeyword Keyword, bool IsDependent, bool IsPack) { + ID.AddPointer(Deduced.getAsOpaquePtr()); + ID.AddInteger((unsigned)Keyword); + ID.AddBoolean(IsDependent); + ID.AddBoolean(IsPack); + } static bool classof(const Type *T) { return T->getTypeClass() == Auto; diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index 3fc53d823c37..c3baaa3e4174 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -14,7 +14,6 @@ #ifndef LLVM_CLANG_AST_TYPELOC_H #define LLVM_CLANG_AST_TYPELOC_H -#include "clang/AST/DeclarationName.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" @@ -35,7 +34,6 @@ namespace clang { class Attr; class ASTContext; class CXXRecordDecl; -class ConceptDecl; class Expr; class ObjCInterfaceDecl; class ObjCProtocolDecl; @@ -183,11 +181,6 @@ public: /// AttributedTypeLoc, for those type attributes that behave as qualifiers TypeLoc findExplicitQualifierLoc() const; - /// Get the typeloc of an AutoType whose type will be deduced for a variable - /// with an initializer of this type. This looks through declarators like - /// pointer types, but not through decltype or typedefs. - AutoTypeLoc getContainedAutoTypeLoc() const; - /// Initializes this to state that every location in this /// type is the given location. /// @@ -1930,137 +1923,8 @@ class DeducedTypeLoc : public InheritingConcreteTypeLoc {}; -struct AutoTypeLocInfo : TypeSpecLocInfo { - NestedNameSpecifierLoc NestedNameSpec; - SourceLocation TemplateKWLoc; - SourceLocation ConceptNameLoc; - NamedDecl *FoundDecl; - SourceLocation LAngleLoc; - SourceLocation RAngleLoc; -}; - class AutoTypeLoc - : public ConcreteTypeLoc { -public: - AutoTypeKeyword getAutoKeyword() const { - return getTypePtr()->getKeyword(); - } - - bool isConstrained() const { - return getTypePtr()->isConstrained(); - } - - const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const { - return getLocalData()->NestedNameSpec; - } - - void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { - getLocalData()->NestedNameSpec = NNS; - } - - SourceLocation getTemplateKWLoc() const { - return getLocalData()->TemplateKWLoc; - } - - void setTemplateKWLoc(SourceLocation Loc) { - getLocalData()->TemplateKWLoc = Loc; - } - - SourceLocation getConceptNameLoc() const { - return getLocalData()->ConceptNameLoc; - } - - void setConceptNameLoc(SourceLocation Loc) { - getLocalData()->ConceptNameLoc = Loc; - } - - NamedDecl *getFoundDecl() const { - return getLocalData()->FoundDecl; - } - - void setFoundDecl(NamedDecl *D) { - getLocalData()->FoundDecl = D; - } - - ConceptDecl *getNamedConcept() const { - return getTypePtr()->getTypeConstraintConcept(); - } - - DeclarationNameInfo getConceptNameInfo() const; - - bool hasExplicitTemplateArgs() const { - return getLocalData()->LAngleLoc.isValid(); - } - - SourceLocation getLAngleLoc() const { - return this->getLocalData()->LAngleLoc; - } - - void setLAngleLoc(SourceLocation Loc) { - this->getLocalData()->LAngleLoc = Loc; - } - - SourceLocation getRAngleLoc() const { - return this->getLocalData()->RAngleLoc; - } - - void setRAngleLoc(SourceLocation Loc) { - this->getLocalData()->RAngleLoc = Loc; - } - - unsigned getNumArgs() const { - return getTypePtr()->getNumArgs(); - } - - void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { - getArgInfos()[i] = AI; - } - - TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { - return getArgInfos()[i]; - } - - TemplateArgumentLoc getArgLoc(unsigned i) const { - return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i], - getArgLocInfo(i)); - } - - SourceRange getLocalSourceRange() const { - return{ - isConstrained() - ? (getNestedNameSpecifierLoc() - ? getNestedNameSpecifierLoc().getBeginLoc() - : (getTemplateKWLoc().isValid() - ? getTemplateKWLoc() - : getConceptNameLoc())) - : getNameLoc(), - getNameLoc() - }; - } - - void copy(AutoTypeLoc Loc) { - unsigned size = getFullDataSize(); - assert(size == Loc.getFullDataSize()); - memcpy(Data, Loc.Data, size); - } - - void initializeLocal(ASTContext &Context, SourceLocation Loc); - - unsigned getExtraLocalDataSize() const { - return getNumArgs() * sizeof(TemplateArgumentLocInfo); - } - - unsigned getExtraLocalDataAlignment() const { - return alignof(TemplateArgumentLocInfo); - } - -private: - TemplateArgumentLocInfo *getArgInfos() const { - return static_cast(getExtraLocalData()); - } + : public InheritingConcreteTypeLoc { }; class DeducedTemplateSpecializationTypeLoc diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td index 3cf56e5a5629..4df2e2f77e2b 100644 --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -395,13 +395,6 @@ let Class = AutoType in { def : Property<"keyword", AutoTypeKeyword> { let Read = [{ node->getKeyword() }]; } - def : Property<"typeConstraintConcept", Optional> { - let Read = [{ makeOptionalFromPointer( - const_cast(node->getTypeConstraintConcept())) }]; - } - def : Property<"typeConstraintArguments", Array> { - let Read = [{ node->getTypeConstraintArguments() }]; - } // FIXME: better enumerated value // Only really required when the deduced type is null def : Property<"dependence", UInt32> { @@ -413,9 +406,7 @@ let Class = AutoType in { def : Creator<[{ return ctx.getAutoType(makeNullableFromOptional(deducedType), keyword, /*isDependentWithoutDeducedType*/ dependence > 0, - /*isPackWithoutDeducedType*/ dependence > 1, - makePointerFromOptional(typeConstraintConcept), - typeConstraintArguments); + /*isPackWithoutDeducedType*/ dependence > 1); }]>; } diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 04b103e3087a..105ed7bf6c84 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1371,8 +1371,6 @@ def err_concept_definition_not_identifier : Error< def ext_concept_legacy_bool_keyword : ExtWarn< "ISO C++2a does not permit the 'bool' keyword after 'concept'">, InGroup>; -def err_placeholder_expected_auto_or_decltype_auto : Error< - "expected 'auto' or 'decltype(auto)' after concept name">; } } // end of Parser diagnostics diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 488f7477d248..b87419d393e2 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2102,8 +2102,11 @@ def err_auto_not_allowed : Error< "|in template argument|in typedef|in type alias|in function return type" "|in conversion function type|here|in lambda parameter" "|in type allocated by 'new'|in K&R-style function parameter" - "|in template parameter|in friend declaration|in function prototype that is " - "not a function declaration|in requires expression parameter}1">; + "|in template parameter|in friend declaration" + "|in requires expression parameter}1">; +def err_auto_not_allowed_in_return_type_requirement : Error< + "%select{'auto'|'decltype(auto)'|'__auto_type'}0 not allowed in expression " + "type requirement">; def err_dependent_deduced_tst : Error< "typename specifier refers to " "%select{class template|function template|variable template|alias template|" @@ -2652,9 +2655,6 @@ def note_ambiguous_atomic_constraints : Note< "same concept">; def note_ambiguous_atomic_constraints_similar_expression : Note< "similar constraint expression here">; -def err_unsupported_placeholder_constraint : Error< - "constrained placeholder types other than simple 'auto' on non-type template " - "parameters not supported yet">; def err_template_different_requires_clause : Error< "requires clause differs in template redeclaration">; @@ -2669,8 +2669,6 @@ def err_type_constraint_non_type_concept : Error< def err_type_constraint_missing_arguments : Error< "%0 requires more than 1 template argument; provide the remaining arguments " "explicitly to use it here">; -def err_placeholder_constraints_not_satisfied : Error< - "deduced type %0 does not satisfy %1">; // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index 1559b51ea77f..1222549161e4 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -349,7 +349,6 @@ private: unsigned TypeSpecOwned : 1; unsigned TypeSpecPipe : 1; unsigned TypeSpecSat : 1; - unsigned ConstrainedAuto : 1; // type-qualifiers unsigned TypeQualifiers : 5; // Bitwise OR of TQ. @@ -370,7 +369,6 @@ private: UnionParsedType TypeRep; Decl *DeclRep; Expr *ExprRep; - TemplateIdAnnotation *TemplateIdRep; }; /// ExplicitSpecifier - Store information about explicit spicifer. @@ -415,9 +413,6 @@ private: static bool isExprRep(TST T) { return (T == TST_typeofExpr || T == TST_decltype); } - static bool isTemplateIdRep(TST T) { - return (T == TST_auto || T == TST_decltype_auto); - } DeclSpec(const DeclSpec &) = delete; void operator=(const DeclSpec &) = delete; @@ -435,8 +430,7 @@ public: TypeSpecComplex(TSC_unspecified), TypeSpecSign(TSS_unspecified), TypeSpecType(TST_unspecified), TypeAltiVecVector(false), TypeAltiVecPixel(false), TypeAltiVecBool(false), TypeSpecOwned(false), - TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false), - TypeQualifiers(TQ_unspecified), + TypeSpecPipe(false), TypeSpecSat(false), TypeQualifiers(TQ_unspecified), FS_inline_specified(false), FS_forceinline_specified(false), FS_virtual_specified(false), FS_noreturn_specified(false), Friend_specified(false), ConstexprSpecifier(CSK_unspecified), @@ -484,7 +478,6 @@ public: bool isTypeRep() const { return isTypeRep((TST) TypeSpecType); } bool isTypeSpecPipe() const { return TypeSpecPipe; } bool isTypeSpecSat() const { return TypeSpecSat; } - bool isConstrainedAuto() const { return ConstrainedAuto; } ParsedType getRepAsType() const { assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type"); @@ -498,11 +491,6 @@ public: assert(isExprRep((TST) TypeSpecType) && "DeclSpec does not store an expr"); return ExprRep; } - TemplateIdAnnotation *getRepAsTemplateId() const { - assert(isTemplateIdRep((TST) TypeSpecType) && - "DeclSpec does not store a template id"); - return TemplateIdRep; - } CXXScopeSpec &getTypeSpecScope() { return TypeScope; } const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; } @@ -678,9 +666,6 @@ public: SourceLocation TagNameLoc, const char *&PrevSpec, unsigned &DiagID, Decl *Rep, bool Owned, const PrintingPolicy &Policy); - bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, TemplateIdAnnotation *Rep, - const PrintingPolicy &Policy); bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, Expr *Rep, @@ -1846,14 +1831,6 @@ private: /// requires-clause, or null if no such clause was specified. Expr *TrailingRequiresClause; - /// If this declarator declares a template, its template parameter lists. - ArrayRef TemplateParameterLists; - - /// If the declarator declares an abbreviated function template, the innermost - /// template parameter list containing the invented and explicit template - /// parameters (if any). - TemplateParameterList *InventedTemplateParameterList; - #ifndef _MSC_VER union { #endif @@ -1884,8 +1861,7 @@ public: Redeclaration(false), Extension(false), ObjCIvar(false), ObjCWeakProperty(false), InlineStorageUsed(false), Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr), - TrailingRequiresClause(nullptr), - InventedTemplateParameterList(nullptr) {} + TrailingRequiresClause(nullptr) {} ~Declarator() { clear(); @@ -2453,30 +2429,6 @@ public: return TrailingRequiresClause != nullptr; } - /// Sets the template parameter lists that preceded the declarator. - void setTemplateParameterLists(ArrayRef TPLs) { - TemplateParameterLists = TPLs; - } - - /// The template parameter lists that preceded the declarator. - ArrayRef getTemplateParameterLists() const { - return TemplateParameterLists; - } - - /// Sets the template parameter list generated from the explicit template - /// parameters along with any invented template parameters from - /// placeholder-typed parameters. - void setInventedTemplateParameterList(TemplateParameterList *Invented) { - InventedTemplateParameterList = Invented; - } - - /// The template parameter list generated from the explicit template - /// parameters along with any invented template parameters from - /// placeholder-typed parameters, if there were any such parameters. - TemplateParameterList * getInventedTemplateParameterList() const { - return InventedTemplateParameterList; - } - /// takeAttributes - Takes attributes from the given parsed-attributes /// set and add them to this declarator. /// @@ -2677,26 +2629,6 @@ struct LambdaIntroducer { } }; -struct InventedTemplateParameterInfo { - /// The number of parameters in the template parameter list that were - /// explicitly specified by the user, as opposed to being invented by use - /// of an auto parameter. - unsigned NumExplicitTemplateParams = 0; - - /// If this is a generic lambda or abbreviated function template, use this - /// as the depth of each 'auto' parameter, during initial AST construction. - unsigned AutoTemplateParameterDepth = 0; - - /// Store the list of the template parameters for a generic lambda or an - /// abbreviated function template. - /// If this is a generic lambda or abbreviated function template, this holds - /// the explicit template parameters followed by the auto parameters - /// converted into TemplateTypeParmDecls. - /// It can be used to construct the generic lambda or abbreviated template's - /// template parameter list during initial AST construction. - SmallVector TemplateParams; -}; - } // end namespace clang #endif // LLVM_CLANG_SEMA_DECLSPEC_H diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h index 6133425a42a6..7848df8f70d9 100644 --- a/clang/include/clang/Sema/Scope.h +++ b/clang/include/clang/Sema/Scope.h @@ -385,12 +385,6 @@ public: return getFlags() & Scope::FunctionPrototypeScope; } - /// isFunctionDeclarationScope - Return true if this scope is a - /// function prototype scope. - bool isFunctionDeclarationScope() const { - return getFlags() & Scope::FunctionDeclarationScope; - } - /// isAtCatchScope - Return true if this scope is \@catch. bool isAtCatchScope() const { return getFlags() & Scope::AtCatchScope; diff --git a/clang/include/clang/Sema/ScopeInfo.h b/clang/include/clang/Sema/ScopeInfo.h index 3c4847a2932c..4f7534f9ef1a 100644 --- a/clang/include/clang/Sema/ScopeInfo.h +++ b/clang/include/clang/Sema/ScopeInfo.h @@ -22,7 +22,6 @@ #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/CleanupInfo.h" -#include "clang/Sema/DeclSpec.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/MapVector.h" @@ -790,8 +789,7 @@ public: } }; -class LambdaScopeInfo final : - public CapturingScopeInfo, public InventedTemplateParameterInfo { +class LambdaScopeInfo final : public CapturingScopeInfo { public: /// The class that describes the lambda. CXXRecordDecl *Lambda = nullptr; @@ -825,9 +823,25 @@ public: /// Packs introduced by this lambda, if any. SmallVector LocalPacks; + /// If this is a generic lambda, use this as the depth of + /// each 'auto' parameter, during initial AST construction. + unsigned AutoTemplateParameterDepth = 0; + + /// The number of parameters in the template parameter list that were + /// explicitly specified by the user, as opposed to being invented by use + /// of an auto parameter. + unsigned NumExplicitTemplateParams = 0; + /// Source range covering the explicit template parameter list (if it exists). SourceRange ExplicitTemplateParamsRange; + /// Store the list of the template parameters for a generic lambda. + /// If this is a generic lambda, this holds the explicit template parameters + /// followed by the auto parameters converted into TemplateTypeParmDecls. + /// It can be used to construct the generic lambda's template parameter list + /// during initial AST construction. + SmallVector TemplateParams; + /// If this is a generic lambda, and the template parameter /// list has been created (from the TemplateParams) then store /// a reference to it (cache it to avoid reconstructing it). diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index ebd24b0d71da..08f657374bcf 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -620,13 +620,6 @@ public: /// function, block, and method scopes that are currently active. SmallVector FunctionScopes; - /// Stack containing information needed when in C++2a an 'auto' is encountered - /// in a function declaration parameter type specifier in order to invent a - /// corresponding template parameter in the enclosing abbreviated function - /// template. This information is also present in LambdaScopeInfo, stored in - /// the FunctionScopes stack. - SmallVector InventedParameterInfos; - typedef LazyVector ExtVectorDeclsType; @@ -1432,11 +1425,6 @@ public: /// Retrieve the module loader associated with the preprocessor. ModuleLoader &getModuleLoader() const; - /// Invent a new identifier for parameters of abbreviated templates. - IdentifierInfo * - InventAbbreviatedTemplateParameterTypeName(IdentifierInfo *ParamName, - unsigned Index); - void emitAndClearUnusedLocalTypedefWarnings(); enum TUFragmentKind { @@ -1531,15 +1519,6 @@ public: /// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls SmallVectorImpl &WeakTopLevelDecls() { return WeakTopLevelDecl; } - /// Called before parsing a function declarator belonging to a function - /// declaration. - void ActOnStartFunctionDeclarationDeclarator(Declarator &D, - unsigned TemplateParameterDepth); - - /// Called after parsing a function declarator belonging to a function - /// declaration. - void ActOnFinishFunctionDeclarationDeclarator(Declarator &D); - void ActOnComment(SourceRange Comment); //===--------------------------------------------------------------------===// @@ -1943,8 +1922,6 @@ public: NC_FunctionTemplate, /// The name was classified as an ADL-only function template name. NC_UndeclaredTemplate, - /// The name was classified as a concept name. - NC_Concept, }; class NameClassification { @@ -2009,12 +1986,6 @@ public: return Result; } - static NameClassification Concept(TemplateName Name) { - NameClassification Result(NC_Concept); - Result.Template = Name; - return Result; - } - static NameClassification UndeclaredTemplate(TemplateName Name) { NameClassification Result(NC_UndeclaredTemplate); Result.Template = Name; @@ -2040,8 +2011,7 @@ public: TemplateName getTemplateName() const { assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || - Kind == NC_VarTemplate || Kind == NC_Concept || - Kind == NC_UndeclaredTemplate); + Kind == NC_VarTemplate || Kind == NC_UndeclaredTemplate); return Template; } @@ -2053,8 +2023,6 @@ public: return TNK_Function_template; case NC_VarTemplate: return TNK_Var_template; - case NC_Concept: - return TNK_Concept_template; case NC_UndeclaredTemplate: return TNK_Undeclared_template; default: @@ -6914,10 +6882,6 @@ public: TemplateTypeParmDecl *ConstrainedParameter, SourceLocation EllipsisLoc); - bool AttachTypeConstraint(AutoTypeLoc TL, - NonTypeTemplateParmDecl *ConstrainedParameter, - SourceLocation EllipsisLoc); - QualType CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, SourceLocation Loc); QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc); @@ -6967,8 +6931,7 @@ public: SourceLocation DeclStartLoc, SourceLocation DeclLoc, const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId, ArrayRef ParamLists, - bool IsFriend, bool &IsMemberSpecialization, bool &Invalid, - bool SuppressDiagnostic = false); + bool IsFriend, bool &IsMemberSpecialization, bool &Invalid); DeclResult CheckClassTemplate( Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, @@ -7880,12 +7843,10 @@ public: DeduceAutoResult DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, QualType &Result, - Optional DependentDeductionDepth = None, - bool IgnoreConstraints = false); + Optional DependentDeductionDepth = None); DeduceAutoResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, QualType &Result, - Optional DependentDeductionDepth = None, - bool IgnoreConstraints = false); + Optional DependentDeductionDepth = None); void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init); bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose = true); diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 6d1db38e36cc..a51429264dbe 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -716,61 +716,6 @@ ASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID, RequiresClause->Profile(ID, C, /*Canonical=*/true); } -static Expr * -canonicalizeImmediatelyDeclaredConstraint(const ASTContext &C, Expr *IDC, - QualType ConstrainedType) { - // This is a bit ugly - we need to form a new immediately-declared - // constraint that references the new parameter; this would ideally - // require semantic analysis (e.g. template struct S {}; - the - // converted arguments of C could be an argument pack if C is - // declared as template concept C = ...). - // We don't have semantic analysis here so we dig deep into the - // ready-made constraint expr and change the thing manually. - ConceptSpecializationExpr *CSE; - if (const auto *Fold = dyn_cast(IDC)) - CSE = cast(Fold->getLHS()); - else - CSE = cast(IDC); - ArrayRef OldConverted = CSE->getTemplateArguments(); - SmallVector NewConverted; - NewConverted.reserve(OldConverted.size()); - if (OldConverted.front().getKind() == TemplateArgument::Pack) { - // The case: - // template concept C = true; - // template T> struct S; -> constraint is C<{T, int}> - NewConverted.push_back(ConstrainedType); - for (auto &Arg : OldConverted.front().pack_elements().drop_front(1)) - NewConverted.push_back(Arg); - TemplateArgument NewPack(NewConverted); - - NewConverted.clear(); - NewConverted.push_back(NewPack); - assert(OldConverted.size() == 1 && - "Template parameter pack should be the last parameter"); - } else { - assert(OldConverted.front().getKind() == TemplateArgument::Type && - "Unexpected first argument kind for immediately-declared " - "constraint"); - NewConverted.push_back(ConstrainedType); - for (auto &Arg : OldConverted.drop_front(1)) - NewConverted.push_back(Arg); - } - Expr *NewIDC = ConceptSpecializationExpr::Create( - C, NestedNameSpecifierLoc(), /*TemplateKWLoc=*/SourceLocation(), - CSE->getConceptNameInfo(), /*FoundDecl=*/CSE->getNamedConcept(), - CSE->getNamedConcept(), - // Actually canonicalizing a TemplateArgumentLoc is difficult so we - // simply omit the ArgsAsWritten - /*ArgsAsWritten=*/nullptr, NewConverted, nullptr); - - if (auto *OrigFold = dyn_cast(IDC)) - NewIDC = new (C) CXXFoldExpr(OrigFold->getType(), SourceLocation(), NewIDC, - BinaryOperatorKind::BO_LAnd, - SourceLocation(), /*RHS=*/nullptr, - SourceLocation(), /*NumExpansions=*/None); - return NewIDC; -} - TemplateTemplateParmDecl * ASTContext::getCanonicalTemplateTemplateParmDecl( TemplateTemplateParmDecl *TTP) const { @@ -798,23 +743,68 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( TTP->isExpandedParameterPack() ? llvm::Optional(TTP->getNumExpansionParameters()) : None); if (const auto *TC = TTP->getTypeConstraint()) { + // This is a bit ugly - we need to form a new immediately-declared + // constraint that references the new parameter; this would ideally + // require semantic analysis (e.g. template struct S {}; - the + // converted arguments of C could be an argument pack if C is + // declared as template concept C = ...). + // We don't have semantic analysis here so we dig deep into the + // ready-made constraint expr and change the thing manually. + Expr *IDC = TC->getImmediatelyDeclaredConstraint(); + ConceptSpecializationExpr *CSE; + if (const auto *Fold = dyn_cast(IDC)) + CSE = cast(Fold->getLHS()); + else + CSE = cast(IDC); + ArrayRef OldConverted = CSE->getTemplateArguments(); + SmallVector NewConverted; + NewConverted.reserve(OldConverted.size()); + QualType ParamAsArgument(NewTTP->getTypeForDecl(), 0); - Expr *NewIDC = canonicalizeImmediatelyDeclaredConstraint( - *this, TC->getImmediatelyDeclaredConstraint(), - ParamAsArgument); - TemplateArgumentListInfo CanonArgsAsWritten; - if (auto *Args = TC->getTemplateArgsAsWritten()) - for (const auto &ArgLoc : Args->arguments()) - CanonArgsAsWritten.addArgument( - TemplateArgumentLoc(ArgLoc.getArgument(), - TemplateArgumentLocInfo())); + if (OldConverted.front().getKind() == TemplateArgument::Pack) { + // The case: + // template concept C = true; + // template T> struct S; -> constraint is C<{T, int}> + NewConverted.push_back(ParamAsArgument); + for (auto &Arg : OldConverted.front().pack_elements().drop_front(1)) + NewConverted.push_back(Arg); + TemplateArgument NewPack(NewConverted); + + NewConverted.clear(); + NewConverted.push_back(NewPack); + assert(OldConverted.size() == 1 && + "Template parameter pack should be the last parameter"); + } else { + assert(OldConverted.front().getKind() == TemplateArgument::Type && + "Unexpected first argument kind for immediately-declared " + "constraint"); + NewConverted.push_back(ParamAsArgument); + for (auto &Arg : OldConverted.drop_front(1)) + NewConverted.push_back(Arg); + } + Expr *NewIDC = ConceptSpecializationExpr::Create(*this, + NestedNameSpecifierLoc(), /*TemplateKWLoc=*/SourceLocation(), + CSE->getConceptNameInfo(), /*FoundDecl=*/CSE->getNamedConcept(), + CSE->getNamedConcept(), + // Actually canonicalizing a TemplateArgumentLoc is difficult so we + // simply omit the ArgsAsWritten + /*ArgsAsWritten=*/nullptr, NewConverted, nullptr); + + if (auto *OrigFold = dyn_cast(IDC)) + NewIDC = new (*this) CXXFoldExpr(OrigFold->getType(), + SourceLocation(), NewIDC, + BinaryOperatorKind::BO_LAnd, + SourceLocation(), /*RHS=*/nullptr, + SourceLocation(), + /*NumExpansions=*/None); + NewTTP->setTypeConstraint( NestedNameSpecifierLoc(), DeclarationNameInfo(TC->getNamedConcept()->getDeclName(), SourceLocation()), /*FoundDecl=*/nullptr, // Actually canonicalizing a TemplateArgumentLoc is difficult so we // simply omit the ArgsAsWritten - TC->getNamedConcept(), /*ArgsAsWritten=*/nullptr, NewIDC); + CSE->getNamedConcept(), /*ArgsAsWritten=*/nullptr, NewIDC); } CanonParams.push_back(NewTTP); } else if (const auto *NTTP = dyn_cast(*P)) { @@ -849,13 +839,6 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( NTTP->isParameterPack(), TInfo); } - if (AutoType *AT = T->getContainedAutoType()) { - if (AT->isConstrained()) { - Param->setPlaceholderTypeConstraint( - canonicalizeImmediatelyDeclaredConstraint( - *this, NTTP->getPlaceholderTypeConstraint(), T)); - } - } CanonParams.push_back(Param); } else @@ -960,7 +943,7 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM, Builtin::Context &builtins) : ConstantArrayTypes(this_()), FunctionProtoTypes(this_()), TemplateSpecializationTypes(this_()), - DependentTemplateSpecializationTypes(this_()), AutoTypes(this_()), + DependentTemplateSpecializationTypes(this_()), SubstTemplateTemplateParmPacks(this_()), CanonTemplateTemplateParms(this_()), SourceMgr(SM), LangOpts(LOpts), SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)), @@ -5141,29 +5124,21 @@ QualType ASTContext::getUnaryTransformType(QualType BaseType, /// getAutoType - Return the uniqued reference to the 'auto' type which has been /// deduced to the given type, or to the canonical undeduced 'auto' type, or the /// canonical deduced-but-dependent 'auto' type. -QualType -ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, - bool IsDependent, bool IsPack, - ConceptDecl *TypeConstraintConcept, - ArrayRef TypeConstraintArgs) const { +QualType ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, + bool IsDependent, bool IsPack) const { assert((!IsPack || IsDependent) && "only use IsPack for a dependent pack"); - if (DeducedType.isNull() && Keyword == AutoTypeKeyword::Auto && - !TypeConstraintConcept && !IsDependent) + if (DeducedType.isNull() && Keyword == AutoTypeKeyword::Auto && !IsDependent) return getAutoDeductType(); // Look in the folding set for an existing type. void *InsertPos = nullptr; llvm::FoldingSetNodeID ID; - AutoType::Profile(ID, *this, DeducedType, Keyword, IsDependent, - TypeConstraintConcept, TypeConstraintArgs); + AutoType::Profile(ID, DeducedType, Keyword, IsDependent, IsPack); if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(AT, 0); - void *Mem = Allocate(sizeof(AutoType) + - sizeof(TemplateArgument) * TypeConstraintArgs.size(), - TypeAlignment); - auto *AT = new (Mem) AutoType(DeducedType, Keyword, IsDependent, IsPack, - TypeConstraintConcept, TypeConstraintArgs); + auto *AT = new (*this, TypeAlignment) + AutoType(DeducedType, Keyword, IsDependent, IsPack); Types.push_back(AT); if (InsertPos) AutoTypes.InsertNode(AT, InsertPos); @@ -5225,8 +5200,7 @@ QualType ASTContext::getAutoDeductType() const { if (AutoDeductTy.isNull()) AutoDeductTy = QualType( new (*this, TypeAlignment) AutoType(QualType(), AutoTypeKeyword::Auto, - /*dependent*/false, /*pack*/false, - /*concept*/nullptr, /*args*/{}), + /*dependent*/false, /*pack*/false), 0); return AutoDeductTy; } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 1f2ce30398c9..22fb67478c96 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -1366,21 +1366,9 @@ ExpectedType ASTNodeImporter::VisitAutoType(const AutoType *T) { if (!ToDeducedTypeOrErr) return ToDeducedTypeOrErr.takeError(); - ExpectedDecl ToTypeConstraintConcept = import(T->getTypeConstraintConcept()); - if (!ToTypeConstraintConcept) - return ToTypeConstraintConcept.takeError(); - - SmallVector ToTemplateArgs; - ArrayRef FromTemplateArgs = T->getTypeConstraintArguments(); - if (Error Err = ImportTemplateArguments(FromTemplateArgs.data(), - FromTemplateArgs.size(), - ToTemplateArgs)) - return std::move(Err); - - return Importer.getToContext().getAutoType( - *ToDeducedTypeOrErr, T->getKeyword(), /*IsDependent*/false, - /*IsPack=*/false, cast_or_null(*ToTypeConstraintConcept), - ToTemplateArgs); + return Importer.getToContext().getAutoType(*ToDeducedTypeOrErr, + T->getKeyword(), + /*IsDependent*/false); } ExpectedType ASTNodeImporter::VisitInjectedClassNameType( diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp index 91a2f3a8391b..db48405055cd 100644 --- a/clang/lib/AST/ASTStructuralEquivalence.cpp +++ b/clang/lib/AST/ASTStructuralEquivalence.cpp @@ -729,31 +729,11 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, return false; break; - case Type::Auto: { - auto *Auto1 = cast(T1); - auto *Auto2 = cast(T2); - if (!IsStructurallyEquivalent(Context, Auto1->getDeducedType(), - Auto2->getDeducedType())) + case Type::Auto: + if (!IsStructurallyEquivalent(Context, cast(T1)->getDeducedType(), + cast(T2)->getDeducedType())) return false; - if (Auto1->isConstrained() != Auto2->isConstrained()) - return false; - if (Auto1->isConstrained()) { - if (Auto1->getTypeConstraintConcept() != - Auto2->getTypeConstraintConcept()) - return false; - ArrayRef Auto1Args = - Auto1->getTypeConstraintArguments(); - ArrayRef Auto2Args = - Auto2->getTypeConstraintArguments(); - if (Auto1Args.size() != Auto2Args.size()) - return false; - for (unsigned I = 0, N = Auto1Args.size(); I != N; ++I) { - if (!IsStructurallyEquivalent(Context, Auto1Args[I], Auto2Args[I])) - return false; - } - } break; - } case Type::DeducedTemplateSpecialization: { const auto *DT1 = cast(T1); diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 1abd51272057..95a2e26e0df8 100755 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -164,15 +164,10 @@ static void AdoptTemplateParameterList(TemplateParameterList *Params, void TemplateParameterList:: getAssociatedConstraints(llvm::SmallVectorImpl &AC) const { if (HasConstrainedParameters) - for (const NamedDecl *Param : *this) { - if (const auto *TTP = dyn_cast(Param)) { + for (const NamedDecl *Param : *this) + if (const auto *TTP = dyn_cast(Param)) if (const auto *TC = TTP->getTypeConstraint()) AC.push_back(TC->getImmediatelyDeclaredConstraint()); - } else if (const auto *NTTP = dyn_cast(Param)) { - if (const Expr *E = NTTP->getPlaceholderTypeConstraint()) - AC.push_back(E); - } - } if (HasRequiresClause) AC.push_back(getRequiresClause()); } @@ -689,13 +684,8 @@ NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, unsigned D, unsigned P, IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo) { - AutoType *AT = TInfo->getType()->getContainedAutoType(); - return new (C, DC, - additionalSizeToAlloc, - Expr *>(0, - AT && AT->isConstrained() ? 1 : 0)) - NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack, - TInfo); + return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, + T, ParameterPack, TInfo); } NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( @@ -703,34 +693,26 @@ NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, ArrayRef ExpandedTypes, ArrayRef ExpandedTInfos) { - AutoType *AT = TInfo->getType()->getContainedAutoType(); return new (C, DC, - additionalSizeToAlloc, - Expr *>( - ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0)) + additionalSizeToAlloc>( + ExpandedTypes.size())) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo, ExpandedTypes, ExpandedTInfos); } NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, - bool HasTypeConstraint) { - return new (C, ID, additionalSizeToAlloc, - Expr *>(0, - HasTypeConstraint ? 1 : 0)) - NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), - 0, 0, nullptr, QualType(), false, nullptr); +NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { + return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(), + SourceLocation(), 0, 0, nullptr, + QualType(), false, nullptr); } NonTypeTemplateParmDecl * NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, - unsigned NumExpandedTypes, - bool HasTypeConstraint) { + unsigned NumExpandedTypes) { auto *NTTP = - new (C, ID, additionalSizeToAlloc, - Expr *>( - NumExpandedTypes, HasTypeConstraint ? 1 : 0)) + new (C, ID, additionalSizeToAlloc>( + NumExpandedTypes)) NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 0, 0, nullptr, QualType(), nullptr, None, None); diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp index 1f9ff9e407dc..27fdca1c4b9c 100644 --- a/clang/lib/AST/ODRHash.cpp +++ b/clang/lib/AST/ODRHash.cpp @@ -857,13 +857,6 @@ public: void VisitAutoType(const AutoType *T) { ID.AddInteger((unsigned)T->getKeyword()); - ID.AddInteger(T->isConstrained()); - if (T->isConstrained()) { - AddDecl(T->getTypeConstraintConcept()); - ID.AddInteger(T->getNumArgs()); - for (const auto &TA : T->getTypeConstraintArguments()) - Hash.AddTemplateArgument(TA); - } VisitDeducedType(T); } diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index 6f0ebf232e77..db16c2a06b64 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -561,7 +561,7 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, } const ASTTemplateArgumentListInfo * -ASTTemplateArgumentListInfo::Create(const ASTContext &C, +ASTTemplateArgumentListInfo::Create(ASTContext &C, const TemplateArgumentListInfo &List) { std::size_t size = totalSizeToAlloc(List.size()); void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo)); diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index c9b571862c19..965ad17fcfa5 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1201,11 +1201,6 @@ void TextNodeDumper::VisitAutoType(const AutoType *T) { OS << " decltype(auto)"; if (!T->isDeduced()) OS << " undeduced"; - if (T->isConstrained()) { - dumpDeclRef(T->getTypeConstraintConcept()); - for (const auto &Arg : T->getTypeConstraintArguments()) - VisitTemplateArgument(Arg); - } } void TextNodeDumper::VisitTemplateSpecializationType( diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 5099494da5fd..c5ad711d872e 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1114,9 +1114,7 @@ public: return QualType(T, 0); return Ctx.getAutoType(deducedType, T->getKeyword(), - T->isDependentType(), /*IsPack=*/false, - T->getTypeConstraintConcept(), - T->getTypeConstraintArguments()); + T->isDependentType()); } // FIXME: Non-trivial to implement, but important for C++ @@ -4160,35 +4158,3 @@ void clang::FixedPointValueToString(SmallVectorImpl &Str, /*HasUnsignedPadding=*/false); APFixedPoint(Val, FXSema).toString(Str); } - -AutoType::AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, - bool IsDeducedAsDependent, bool IsDeducedAsPack, - ConceptDecl *TypeConstraintConcept, - ArrayRef TypeConstraintArgs) - : DeducedType(Auto, DeducedAsType, IsDeducedAsDependent, - IsDeducedAsDependent, IsDeducedAsPack) { - AutoTypeBits.Keyword = (unsigned)Keyword; - AutoTypeBits.NumArgs = TypeConstraintArgs.size(); - this->TypeConstraintConcept = TypeConstraintConcept; - if (TypeConstraintConcept) { - TemplateArgument *ArgBuffer = getArgBuffer(); - for (const TemplateArgument &Arg : TypeConstraintArgs) { - if (Arg.containsUnexpandedParameterPack()) - setContainsUnexpandedParameterPack(); - - new (ArgBuffer++) TemplateArgument(Arg); - } - } -} - -void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, - QualType Deduced, AutoTypeKeyword Keyword, - bool IsDependent, ConceptDecl *CD, - ArrayRef Arguments) { - ID.AddPointer(Deduced.getAsOpaquePtr()); - ID.AddInteger((unsigned)Keyword); - ID.AddBoolean(IsDependent); - ID.AddPointer(CD); - for (const TemplateArgument &Arg : Arguments) - Arg.Profile(ID, Context); -} diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 665a86f2c143..6e67ca8e0af7 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -11,7 +11,6 @@ //===----------------------------------------------------------------------===// #include "clang/AST/TypeLoc.h" -#include "clang/AST/DeclTemplate.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" #include "clang/AST/Expr.h" @@ -590,97 +589,3 @@ void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context, } } } - -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); - TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(), - getTypePtr()->getArgs(), - getArgInfos(), Loc); - setNameLoc(Loc); -} - - -namespace { - - class GetContainedAutoTypeLocVisitor : - public TypeLocVisitor { - public: - using TypeLocVisitor::Visit; - - TypeLoc VisitAutoTypeLoc(AutoTypeLoc TL) { - return TL; - } - - // Only these types can contain the desired 'auto' type. - - TypeLoc VisitElaboratedTypeLoc(ElaboratedTypeLoc T) { - return Visit(T.getNamedTypeLoc()); - } - - TypeLoc VisitQualifiedTypeLoc(QualifiedTypeLoc T) { - return Visit(T.getUnqualifiedLoc()); - } - - TypeLoc VisitPointerTypeLoc(PointerTypeLoc T) { - return Visit(T.getPointeeLoc()); - } - - TypeLoc VisitBlockPointerTypeLoc(BlockPointerTypeLoc T) { - return Visit(T.getPointeeLoc()); - } - - TypeLoc VisitReferenceTypeLoc(ReferenceTypeLoc T) { - return Visit(T.getPointeeLoc()); - } - - TypeLoc VisitMemberPointerTypeLoc(MemberPointerTypeLoc T) { - return Visit(T.getPointeeLoc()); - } - - TypeLoc VisitArrayTypeLoc(ArrayTypeLoc T) { - return Visit(T.getElementLoc()); - } - - TypeLoc VisitFunctionTypeLoc(FunctionTypeLoc T) { - return Visit(T.getReturnLoc()); - } - - TypeLoc VisitParenTypeLoc(ParenTypeLoc T) { - return Visit(T.getInnerLoc()); - } - - TypeLoc VisitAttributedTypeLoc(AttributedTypeLoc T) { - return Visit(T.getModifiedLoc()); - } - - TypeLoc VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc T) { - return Visit(T.getInnerLoc()); - } - - TypeLoc VisitAdjustedTypeLoc(AdjustedTypeLoc T) { - return Visit(T.getOriginalLoc()); - } - - TypeLoc VisitPackExpansionTypeLoc(PackExpansionTypeLoc T) { - return Visit(T.getPatternLoc()); - } - }; - -} // namespace - -AutoTypeLoc TypeLoc::getContainedAutoTypeLoc() const { - TypeLoc Res = GetContainedAutoTypeLocVisitor().Visit(*this); - if (Res.isNull()) - return AutoTypeLoc(); - return Res.getAs(); -} diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 1495162ac081..3a00a6c11ddb 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1046,13 +1046,6 @@ void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) { if (!T->getDeducedType().isNull()) { printBefore(T->getDeducedType(), OS); } else { - if (T->isConstrained()) { - OS << T->getTypeConstraintConcept()->getName(); - auto Args = T->getTypeConstraintArguments(); - if (!Args.empty()) - printTemplateArgumentList(OS, Args, Policy); - OS << ' '; - } switch (T->getKeyword()) { case AutoTypeKeyword::Auto: OS << "auto"; break; case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break; @@ -1241,18 +1234,20 @@ void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {} void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T, raw_ostream &OS) { - TemplateTypeParmDecl *D = T->getDecl(); - if (D && D->isImplicit()) { - if (auto *TC = D->getTypeConstraint()) { - TC->print(OS, Policy); - OS << ' '; - } - OS << "auto"; - } else if (IdentifierInfo *Id = T->getIdentifier()) + if (IdentifierInfo *Id = T->getIdentifier()) OS << Id->getName(); - else - OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex(); + else { + bool IsLambdaAutoParam = false; + if (auto D = T->getDecl()) { + if (auto M = dyn_cast_or_null(D->getDeclContext())) + IsLambdaAutoParam = D->isImplicit() && M->getParent()->isLambda(); + } + if (IsLambdaAutoParam) + OS << "auto"; + else + OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex(); + } spaceBeforePlaceHolder(OS); } diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index a75965784168..f8b5fec43800 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -133,9 +133,7 @@ NamedDecl *Parser::ParseCXXInlineMethodDef( LexedMethod* LM = new LexedMethod(this, FnD); getCurrentClass().LateParsedDeclarations.push_back(LM); - LM->TemplateScope = getCurScope()->isTemplateParamScope() || - (FnD && isa(FnD) && - cast(FnD)->isAbbreviated()); + LM->TemplateScope = getCurScope()->isTemplateParamScope(); CachedTokens &Toks = LM->Toks; tok::TokenKind kind = Tok.getKind(); diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 4af993c4527f..065a82b9298a 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2962,7 +2962,6 @@ Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS, case Sema::NC_ContextIndependentExpr: case Sema::NC_VarTemplate: case Sema::NC_FunctionTemplate: - case Sema::NC_Concept: // Might be a redeclaration of a prior entity. break; } @@ -3194,18 +3193,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, continue; } - if (Next.is(tok::annot_template_id) && - static_cast(Next.getAnnotationValue()) - ->Kind == TNK_Concept_template && - GetLookAheadToken(2).isOneOf(tok::kw_auto, tok::kw_decltype)) { - DS.getTypeSpecScope() = SS; - // This is a qualified placeholder-specifier, e.g., ::C auto ... - // Consume the scope annotation and continue to consume the template-id - // as a placeholder-specifier. - ConsumeAnnotationToken(); - continue; - } - if (Next.is(tok::annot_typename)) { DS.getTypeSpecScope() = SS; ConsumeAnnotationToken(); // The C++ scope. @@ -3248,10 +3235,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the // typename. if (!TypeRep) { - if (TryAnnotateTypeConstraint()) - goto DoneWithDeclSpec; - if (isTypeConstraintAnnotation()) - continue; // Eat the scope spec so the identifier is current. ConsumeAnnotationToken(); ParsedAttributesWithRange Attrs(AttrFactory); @@ -3401,10 +3384,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // If this is not a typedef name, don't parse it as part of the declspec, // it must be an implicit int or an error. if (!TypeRep) { - if (TryAnnotateTypeConstraint()) - goto DoneWithDeclSpec; - if (isTypeConstraintAnnotation()) - continue; ParsedAttributesWithRange Attrs(AttrFactory); if (ParseImplicitInt(DS, nullptr, TemplateInfo, AS, DSContext, Attrs)) { if (!Attrs.empty()) { @@ -3454,51 +3433,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, continue; } - // type-name or placeholder-specifier + // type-name case tok::annot_template_id: { TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); - if (TemplateId->Kind == TNK_Concept_template) { - if (NextToken().is(tok::identifier)) { - Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto) - << FixItHint::CreateInsertion(NextToken().getLocation(), "auto"); - // Attempt to continue as if 'auto' was placed here. - isInvalid = DS.SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID, - TemplateId, Policy); - break; - } - if (!NextToken().isOneOf(tok::kw_auto, tok::kw_decltype)) - goto DoneWithDeclSpec; - ConsumeAnnotationToken(); - SourceLocation AutoLoc = Tok.getLocation(); - if (TryConsumeToken(tok::kw_decltype)) { - BalancedDelimiterTracker Tracker(*this, tok::l_paren); - if (Tracker.consumeOpen()) { - // Something like `void foo(Iterator decltype i)` - Diag(Tok, diag::err_expected) << tok::l_paren; - } else { - if (!TryConsumeToken(tok::kw_auto)) { - // Something like `void foo(Iterator decltype(int) i)` - Tracker.skipToEnd(); - Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto) - << FixItHint::CreateReplacement(SourceRange(AutoLoc, - Tok.getLocation()), - "auto"); - } else { - Tracker.consumeClose(); - } - } - ConsumedEnd = Tok.getLocation(); - // Even if something went wrong above, continue as if we've seen - // `decltype(auto)`. - isInvalid = DS.SetTypeSpecType(TST_decltype_auto, Loc, PrevSpec, - DiagID, TemplateId, Policy); - } else { - isInvalid = DS.SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID, - TemplateId, Policy); - } - break; - } - if (TemplateId->Kind != TNK_Type_template && TemplateId->Kind != TNK_Undeclared_template) { // This template-id does not refer to a type name, so we're @@ -6090,12 +6027,11 @@ void Parser::ParseDirectDeclarator(Declarator &D) { while (1) { if (Tok.is(tok::l_paren)) { - bool IsFunctionDeclaration = D.isFunctionDeclaratorAFunctionDeclaration(); // Enter function-declaration scope, limiting any declarators to the // function prototype scope, including parameter declarators. ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope|Scope::DeclScope| - (IsFunctionDeclaration + (D.isFunctionDeclaratorAFunctionDeclaration() ? Scope::FunctionDeclarationScope : 0)); // The paren may be part of a C++ direct initializer, eg. "int x(1);". @@ -6114,12 +6050,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { ParsedAttributes attrs(AttrFactory); BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); - if (IsFunctionDeclaration) - Actions.ActOnStartFunctionDeclarationDeclarator(D, - TemplateParameterDepth); ParseFunctionDeclarator(D, attrs, T, IsAmbiguous); - if (IsFunctionDeclaration) - Actions.ActOnFinishFunctionDeclarationDeclarator(D); PrototypeScope.Exit(); } else if (Tok.is(tok::l_square)) { ParseBracketDeclarator(D); diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index f872aa3a950c..9c7d3c566554 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -2642,8 +2642,6 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, } ParsingDeclarator DeclaratorInfo(*this, DS, DeclaratorContext::MemberContext); - if (TemplateInfo.TemplateParams) - DeclaratorInfo.setTemplateParameterLists(TemplateParams); VirtSpecifiers VS; // Hold late-parsed attributes so we can attach a Decl to them later. diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index a1010ab2e3fc..0f7aefaa147a 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -240,8 +240,6 @@ Decl *Parser::ParseSingleDeclarationAfterTemplate( // Parse the declarator. ParsingDeclarator DeclaratorInfo(*this, DS, (DeclaratorContext)Context); - if (TemplateInfo.TemplateParams) - DeclaratorInfo.setTemplateParameterLists(*TemplateInfo.TemplateParams); ParseDeclarator(DeclaratorInfo); // Error parsing the declarator? if (!DeclaratorInfo.hasName()) { @@ -603,7 +601,6 @@ Parser::TPResult Parser::isStartOfTemplateTypeParameter() { /// typename /// NamedDecl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) { - switch (isStartOfTemplateTypeParameter()) { case TPResult::True: // Is there just a typo in the input code? ('typedef' instead of @@ -621,6 +618,7 @@ NamedDecl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) { } return ParseTypeParameter(Depth, Position); + case TPResult::False: break; @@ -680,6 +678,7 @@ bool Parser::isTypeConstraintAnnotation() { bool Parser::TryAnnotateTypeConstraint() { if (!getLangOpts().ConceptsTS) return false; + CXXScopeSpec SS; bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope); if (ParseOptionalCXXScopeSpecifier( diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index ad0a15b0c8a6..79e96816f864 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -1313,18 +1313,6 @@ public: Parser::TPResult Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult, bool *InvalidAsDeclSpec) { - auto IsPlaceholderSpecifier = [&] (TemplateIdAnnotation *TemplateId, - int Lookahead) { - // We have a placeholder-constraint (we check for 'auto' or 'decltype' to - // distinguish 'C;' from 'C auto c = 1;') - return TemplateId->Kind == TNK_Concept_template && - GetLookAheadToken(Lookahead + 1).isOneOf(tok::kw_auto, tok::kw_decltype, - // If we have an identifier here, the user probably forgot the - // 'auto' in the placeholder constraint, e.g. 'C x = 2;' - // This will be diagnosed nicely later, so disambiguate as a - // declaration. - tok::identifier); - }; switch (Tok.getKind()) { case tok::identifier: { // Check for need to substitute AltiVec __vector keyword @@ -1528,8 +1516,6 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult, *InvalidAsDeclSpec = NextToken().is(tok::l_paren); return TPResult::Ambiguous; } - if (IsPlaceholderSpecifier(TemplateId, /*Lookahead=*/0)) - return TPResult::True; if (TemplateId->Kind != TNK_Type_template) return TPResult::False; CXXScopeSpec SS; @@ -1543,13 +1529,6 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult, if (TryAnnotateTypeOrScopeToken()) return TPResult::Error; if (!Tok.is(tok::annot_typename)) { - if (Tok.is(tok::annot_cxxscope) && - NextToken().is(tok::annot_template_id)) { - TemplateIdAnnotation *TemplateId = - takeTemplateIdAnnotation(NextToken()); - if (IsPlaceholderSpecifier(TemplateId, /*Lookahead=*/1)) - return TPResult::True; - } // If the next token is an identifier or a type qualifier, then this // can't possibly be a valid expression either. if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) { diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 0b778bd24277..0194c243f93d 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1136,7 +1136,6 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, // Poison SEH identifiers so they are flagged as illegal in function bodies. PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true); const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); - TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); // If this is C90 and the declspecs were completely missing, fudge in an // implicit int. We do this here because this is the only place where @@ -1263,15 +1262,6 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, // safe because we're always the sole owner. D.getMutableDeclSpec().abort(); - // With abbreviated function templates - we need to explicitly add depth to - // account for the implicit template parameter list induced by the template. - if (auto *Template = dyn_cast_or_null(Res)) - if (Template->isAbbreviated() && - Template->getTemplateParameters()->getParam(0)->isImplicit()) - // First template parameter is implicit - meaning no explicit template - // parameter list was specified. - CurTemplateDepthTracker.addDepth(1); - if (TryConsumeToken(tok::equal)) { assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='"); @@ -1742,20 +1732,6 @@ Parser::TryAnnotateName(CorrectionCandidateCallback *CCC) { return ANK_Error; return ANK_Success; } - case Sema::NC_Concept: { - UnqualifiedId Id; - Id.setIdentifier(Name, NameLoc); - if (Next.is(tok::less)) - // We have a concept name followed by '<'. Consume the identifier token so - // we reach the '<' and annotate it. - ConsumeToken(); - if (AnnotateTemplateIdToken( - TemplateTy::make(Classification.getTemplateName()), - Classification.getTemplateNameKind(), SS, SourceLocation(), Id, - /*AllowTypeAnnotation=*/false, /*TypeConstraint=*/true)) - return ANK_Error; - return ANK_Success; - } } // Unable to classify the name, but maybe we can annotate a scope specifier. diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index 94d87974624e..639231c87232 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -784,15 +784,6 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, return false; } -bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, TemplateIdAnnotation *Rep, - const PrintingPolicy &Policy) { - assert(T == TST_auto || T == TST_decltype_auto); - ConstrainedAuto = true; - TemplateIdRep = Rep; - return SetTypeSpecType(T, Loc, PrevSpec, DiagID, Policy); -} - bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 9cfce5a63b1d..7eb8c8d2f760 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -52,21 +52,6 @@ SourceLocation Sema::getLocForEndOfToken(SourceLocation Loc, unsigned Offset) { ModuleLoader &Sema::getModuleLoader() const { return PP.getModuleLoader(); } -IdentifierInfo * -Sema::InventAbbreviatedTemplateParameterTypeName(IdentifierInfo *ParamName, - unsigned int Index) { - std::string InventedName; - llvm::raw_string_ostream OS(InventedName); - - if (!ParamName) - OS << "auto:" << Index + 1; - else - OS << ParamName->getName() << ":auto"; - - OS.flush(); - return &Context.Idents.get(OS.str()); -} - PrintingPolicy Sema::getPrintingPolicy(const ASTContext &Context, const Preprocessor &PP) { PrintingPolicy Policy = Context.getPrintingPolicy(); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0bf490336537..372f3d158597 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -10,7 +10,6 @@ // //===----------------------------------------------------------------------===// -#include "TreeTransform.h" #include "TypeLocBuilder.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" @@ -1154,10 +1153,6 @@ Corrected: return ParsedType::make(T); } - if (isa(FirstDecl)) - return NameClassification::Concept( - TemplateName(cast(FirstDecl))); - // We can have a type template here if we're classifying a template argument. if (isa(FirstDecl) && !isa(FirstDecl) && !isa(FirstDecl)) @@ -8661,21 +8656,11 @@ static Scope *getTagInjectionScope(Scope *S, const LangOptions &LangOpts) { NamedDecl* Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo, LookupResult &Previous, - MultiTemplateParamsArg TemplateParamListsRef, + MultiTemplateParamsArg TemplateParamLists, bool &AddToScope) { QualType R = TInfo->getType(); assert(R->isFunctionType()); - SmallVector TemplateParamLists; - for (TemplateParameterList *TPL : TemplateParamListsRef) - TemplateParamLists.push_back(TPL); - if (TemplateParameterList *Invented = D.getInventedTemplateParameterList()) { - if (!TemplateParamLists.empty() && - Invented->getDepth() == TemplateParamLists.back()->getDepth()) - TemplateParamLists.back() = Invented; - else - TemplateParamLists.push_back(Invented); - } // TODO: consider using NameInfo for diagnostic. DeclarationNameInfo NameInfo = GetNameForDeclarator(D); @@ -8755,16 +8740,15 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Match up the template parameter lists with the scope specifier, then // determine whether we have a template or a template specialization. bool Invalid = false; - TemplateParameterList *TemplateParams = - MatchTemplateParametersToScopeSpecifier( - D.getDeclSpec().getBeginLoc(), D.getIdentifierLoc(), - D.getCXXScopeSpec(), - D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId - ? D.getName().TemplateId - : nullptr, - TemplateParamLists, isFriend, isMemberSpecialization, - Invalid); - if (TemplateParams) { + if (TemplateParameterList *TemplateParams = + MatchTemplateParametersToScopeSpecifier( + D.getDeclSpec().getBeginLoc(), D.getIdentifierLoc(), + D.getCXXScopeSpec(), + D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId + ? D.getName().TemplateId + : nullptr, + TemplateParamLists, isFriend, isMemberSpecialization, + Invalid)) { if (TemplateParams->size() > 0) { // This is a function template @@ -8797,8 +8781,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // For source fidelity, store the other template param lists. if (TemplateParamLists.size() > 1) { NewFD->setTemplateParameterListsInfo(Context, - ArrayRef(TemplateParamLists) - .drop_back(1)); + TemplateParamLists.drop_back(1)); } } else { // This is a function template specialization. diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 523daf370fc7..d1e720ebcc2a 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -17386,50 +17386,3 @@ MSPropertyDecl *Sema::HandleMSProperty(Scope *S, RecordDecl *Record, return NewPD; } - -void Sema::ActOnStartFunctionDeclarationDeclarator( - Declarator &Declarator, unsigned TemplateParameterDepth) { - auto &Info = InventedParameterInfos.emplace_back(); - TemplateParameterList *ExplicitParams = nullptr; - ArrayRef ExplicitLists = - Declarator.getTemplateParameterLists(); - if (!ExplicitLists.empty()) { - bool IsMemberSpecialization, IsInvalid; - ExplicitParams = MatchTemplateParametersToScopeSpecifier( - Declarator.getBeginLoc(), Declarator.getIdentifierLoc(), - Declarator.getCXXScopeSpec(), /*TemplateId=*/nullptr, - ExplicitLists, /*IsFriend=*/false, IsMemberSpecialization, IsInvalid, - /*SuppressDiagnostic=*/true); - } - if (ExplicitParams) { - Info.AutoTemplateParameterDepth = ExplicitParams->getDepth(); - for (NamedDecl *Param : *ExplicitParams) - Info.TemplateParams.push_back(Param); - Info.NumExplicitTemplateParams = ExplicitParams->size(); - } else { - Info.AutoTemplateParameterDepth = TemplateParameterDepth; - Info.NumExplicitTemplateParams = 0; - } -} - -void Sema::ActOnFinishFunctionDeclarationDeclarator(Declarator &Declarator) { - auto &FSI = InventedParameterInfos.back(); - if (FSI.TemplateParams.size() > FSI.NumExplicitTemplateParams) { - if (FSI.NumExplicitTemplateParams != 0) { - TemplateParameterList *ExplicitParams = - Declarator.getTemplateParameterLists().back(); - Declarator.setInventedTemplateParameterList( - TemplateParameterList::Create( - Context, ExplicitParams->getTemplateLoc(), - ExplicitParams->getLAngleLoc(), FSI.TemplateParams, - ExplicitParams->getRAngleLoc(), - ExplicitParams->getRequiresClause())); - } else { - Declarator.setInventedTemplateParameterList( - TemplateParameterList::Create( - Context, SourceLocation(), SourceLocation(), FSI.TemplateParams, - SourceLocation(), /*RequiresClause=*/nullptr)); - } - } - InventedParameterInfos.pop_back(); -} diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index ae89b146c409..c2d14a44f53d 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -791,8 +791,7 @@ QualType Sema::buildLambdaInitCaptureInitialization( // deduce against. QualType DeductType = Context.getAutoDeductType(); TypeLocBuilder TLB; - AutoTypeLoc TL = TLB.push(DeductType); - TL.setNameLoc(Loc); + TLB.pushTypeSpec(DeductType).setNameLoc(Loc); if (ByRef) { DeductType = BuildReferenceType(DeductType, true, Loc, Id); assert(!DeductType.isNull() && "can't build reference to auto"); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 2f44f8f08d08..2d87e7b367f3 100755 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1088,50 +1088,6 @@ bool Sema::ActOnTypeConstraint(const CXXScopeSpec &SS, ConstrainedParameter, EllipsisLoc); } -template -static ExprResult formImmediatelyDeclaredConstraint( - Sema &S, NestedNameSpecifierLoc NS, DeclarationNameInfo NameInfo, - ConceptDecl *NamedConcept, SourceLocation LAngleLoc, - SourceLocation RAngleLoc, QualType ConstrainedType, - SourceLocation ParamNameLoc, ArgumentLocAppender Appender, - SourceLocation EllipsisLoc) { - - TemplateArgumentListInfo ConstraintArgs; - ConstraintArgs.addArgument( - S.getTrivialTemplateArgumentLoc(TemplateArgument(ConstrainedType), - /*NTTPType=*/QualType(), ParamNameLoc)); - - ConstraintArgs.setRAngleLoc(RAngleLoc); - ConstraintArgs.setLAngleLoc(LAngleLoc); - Appender(ConstraintArgs); - - // C++2a [temp.param]p4: - // [...] This constraint-expression E is called the immediately-declared - // constraint of T. [...] - CXXScopeSpec SS; - SS.Adopt(NS); - ExprResult ImmediatelyDeclaredConstraint = S.CheckConceptTemplateId( - SS, /*TemplateKWLoc=*/SourceLocation(), NameInfo, - /*FoundDecl=*/NamedConcept, NamedConcept, &ConstraintArgs); - if (ImmediatelyDeclaredConstraint.isInvalid() || !EllipsisLoc.isValid()) - return ImmediatelyDeclaredConstraint; - - // C++2a [temp.param]p4: - // [...] If T is not a pack, then E is E', otherwise E is (E' && ...). - // - // We have the following case: - // - // template concept C1 = true; - // template struct s1; - // - // The constraint: (C1 && ...) - return S.BuildCXXFoldExpr(/*LParenLoc=*/SourceLocation(), - ImmediatelyDeclaredConstraint.get(), BO_LAnd, - EllipsisLoc, /*RHS=*/nullptr, - /*RParenLoc=*/SourceLocation(), - /*NumExpansions=*/None); -} - /// Attach a type-constraint to a template parameter. /// \returns true if an error occured. This can happen if the /// immediately-declared constraint could not be formed (e.g. incorrect number @@ -1150,21 +1106,51 @@ bool Sema::AttachTypeConstraint(NestedNameSpecifierLoc NS, *TemplateArgs) : nullptr; QualType ParamAsArgument(ConstrainedParameter->getTypeForDecl(), 0); + TemplateArgumentListInfo ConstraintArgs; + ConstraintArgs.addArgument( + TemplateArgumentLoc( + TemplateArgument(ParamAsArgument), + TemplateArgumentLocInfo( + Context.getTrivialTypeSourceInfo(ParamAsArgument, + ConstrainedParameter->getLocation())))); + if (TemplateArgs) { + ConstraintArgs.setRAngleLoc(TemplateArgs->getRAngleLoc()); + ConstraintArgs.setLAngleLoc(TemplateArgs->getLAngleLoc()); + for (const TemplateArgumentLoc &ArgLoc : TemplateArgs->arguments()) + ConstraintArgs.addArgument(ArgLoc); + } - ExprResult ImmediatelyDeclaredConstraint = - formImmediatelyDeclaredConstraint( - *this, NS, NameInfo, NamedConcept, - TemplateArgs ? TemplateArgs->getLAngleLoc() : SourceLocation(), - TemplateArgs ? TemplateArgs->getRAngleLoc() : SourceLocation(), - ParamAsArgument, ConstrainedParameter->getLocation(), - [&] (TemplateArgumentListInfo &ConstraintArgs) { - if (TemplateArgs) - for (const auto &ArgLoc : TemplateArgs->arguments()) - ConstraintArgs.addArgument(ArgLoc); - }, EllipsisLoc); + // C++2a [temp.param]p4: + // [...] This constraint-expression E is called the immediately-declared + // constraint of T. [...] + CXXScopeSpec SS; + SS.Adopt(NS); + ExprResult ImmediatelyDeclaredConstraint = CheckConceptTemplateId(SS, + /*TemplateKWLoc=*/SourceLocation(), NameInfo, /*FoundDecl=*/NamedConcept, + NamedConcept, &ConstraintArgs); if (ImmediatelyDeclaredConstraint.isInvalid()) return true; + if (ConstrainedParameter->isParameterPack()) { + // C++2a [temp.param]p4: + // [...] If T is not a pack, then E is E', otherwise E is (E' && ...). + // + // We have the following case: + // + // template concept C1 = true; + // template struct s1; + // + // The constraint: (C1 && ...) + ImmediatelyDeclaredConstraint = + BuildCXXFoldExpr(/*LParenLoc=*/SourceLocation(), + ImmediatelyDeclaredConstraint.get(), BO_LAnd, + EllipsisLoc, /*RHS=*/nullptr, + /*RParenLoc=*/SourceLocation(), + /*NumExpansions=*/None).get(); + if (ImmediatelyDeclaredConstraint.isInvalid()) + return true; + } + ConstrainedParameter->setTypeConstraint(NS, NameInfo, /*FoundDecl=*/NamedConcept, NamedConcept, ArgsAsWritten, @@ -1172,38 +1158,6 @@ bool Sema::AttachTypeConstraint(NestedNameSpecifierLoc NS, return false; } -bool Sema::AttachTypeConstraint(AutoTypeLoc TL, NonTypeTemplateParmDecl *NTTP, - SourceLocation EllipsisLoc) { - if (NTTP->getType() != TL.getType() || - TL.getAutoKeyword() != AutoTypeKeyword::Auto) { - Diag(NTTP->getTypeSourceInfo()->getTypeLoc().getBeginLoc(), - diag::err_unsupported_placeholder_constraint) - << NTTP->getTypeSourceInfo()->getTypeLoc().getSourceRange(); - return true; - } - // FIXME: Concepts: This should be the type of the placeholder, but this is - // unclear in the wording right now. - DeclRefExpr *Ref = BuildDeclRefExpr(NTTP, NTTP->getType(), VK_RValue, - NTTP->getLocation()); - if (!Ref) - return true; - ExprResult ImmediatelyDeclaredConstraint = - formImmediatelyDeclaredConstraint( - *this, TL.getNestedNameSpecifierLoc(), TL.getConceptNameInfo(), - TL.getNamedConcept(), TL.getLAngleLoc(), TL.getRAngleLoc(), - BuildDecltypeType(Ref, NTTP->getLocation()), NTTP->getLocation(), - [&] (TemplateArgumentListInfo &ConstraintArgs) { - for (unsigned I = 0, C = TL.getNumArgs(); I != C; ++I) - ConstraintArgs.addArgument(TL.getArgLoc(I)); - }, EllipsisLoc); - if (ImmediatelyDeclaredConstraint.isInvalid() || - !ImmediatelyDeclaredConstraint.isUsable()) - return true; - - NTTP->setPlaceholderTypeConstraint(ImmediatelyDeclaredConstraint.get()); - return false; -} - /// Check that the type of a non-type template parameter is /// well-formed. /// @@ -1365,11 +1319,6 @@ NamedDecl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, TInfo); Param->setAccess(AS_public); - if (AutoTypeLoc TL = TInfo->getTypeLoc().getContainedAutoTypeLoc()) - if (TL.isConstrained()) - if (AttachTypeConstraint(TL, Param, D.getEllipsisLoc())) - Invalid = true; - if (Invalid) Param->setInvalidDecl(); @@ -2813,7 +2762,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( SourceLocation DeclStartLoc, SourceLocation DeclLoc, const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId, ArrayRef ParamLists, bool IsFriend, - bool &IsMemberSpecialization, bool &Invalid, bool SuppressDiagnostic) { + bool &IsMemberSpecialization, bool &Invalid) { IsMemberSpecialization = false; Invalid = false; @@ -2921,9 +2870,8 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( auto CheckExplicitSpecialization = [&](SourceRange Range, bool Recovery) { if (SawNonEmptyTemplateParameterList) { - if (!SuppressDiagnostic) - Diag(DeclLoc, diag::err_specialize_member_of_template) - << !Recovery << Range; + Diag(DeclLoc, diag::err_specialize_member_of_template) + << !Recovery << Range; Invalid = true; IsMemberSpecialization = false; return true; @@ -2944,10 +2892,9 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( else ExpectedTemplateLoc = DeclStartLoc; - if (!SuppressDiagnostic) - Diag(DeclLoc, diag::err_template_spec_needs_header) - << Range - << FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> "); + Diag(DeclLoc, diag::err_template_spec_needs_header) + << Range + << FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> "); return false; }; @@ -3037,13 +2984,12 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( if (ParamIdx < ParamLists.size()) { if (ParamLists[ParamIdx]->size() > 0) { // The header has template parameters when it shouldn't. Complain. - if (!SuppressDiagnostic) - Diag(ParamLists[ParamIdx]->getTemplateLoc(), - diag::err_template_param_list_matches_nontemplate) - << T - << SourceRange(ParamLists[ParamIdx]->getLAngleLoc(), - ParamLists[ParamIdx]->getRAngleLoc()) - << getRangeOfTypeInNestedNameSpecifier(Context, T, SS); + Diag(ParamLists[ParamIdx]->getTemplateLoc(), + diag::err_template_param_list_matches_nontemplate) + << T + << SourceRange(ParamLists[ParamIdx]->getLAngleLoc(), + ParamLists[ParamIdx]->getRAngleLoc()) + << getRangeOfTypeInNestedNameSpecifier(Context, T, SS); Invalid = true; return nullptr; } @@ -3079,7 +3025,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( if (ExpectedTemplateParams && !TemplateParameterListsAreEqual(ParamLists[ParamIdx], ExpectedTemplateParams, - !SuppressDiagnostic, TPL_TemplateMatch)) + true, TPL_TemplateMatch)) Invalid = true; if (!Invalid && @@ -3091,10 +3037,9 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( continue; } - if (!SuppressDiagnostic) - Diag(DeclLoc, diag::err_template_spec_needs_template_parameters) - << T - << getRangeOfTypeInNestedNameSpecifier(Context, T, SS); + Diag(DeclLoc, diag::err_template_spec_needs_template_parameters) + << T + << getRangeOfTypeInNestedNameSpecifier(Context, T, SS); Invalid = true; continue; } @@ -3130,18 +3075,16 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( AllExplicitSpecHeaders = false; } - if (!SuppressDiagnostic) - Diag(ParamLists[ParamIdx]->getTemplateLoc(), - AllExplicitSpecHeaders ? diag::warn_template_spec_extra_headers - : diag::err_template_spec_extra_headers) - << SourceRange(ParamLists[ParamIdx]->getTemplateLoc(), - ParamLists[ParamLists.size() - 2]->getRAngleLoc()); + Diag(ParamLists[ParamIdx]->getTemplateLoc(), + AllExplicitSpecHeaders ? diag::warn_template_spec_extra_headers + : diag::err_template_spec_extra_headers) + << SourceRange(ParamLists[ParamIdx]->getTemplateLoc(), + ParamLists[ParamLists.size() - 2]->getRAngleLoc()); // If there was a specialization somewhere, such that 'template<>' is // not required, and there were any 'template<>' headers, note where the // specialization occurred. - if (ExplicitSpecLoc.isValid() && HasAnyExplicitSpecHeader && - !SuppressDiagnostic) + if (ExplicitSpecLoc.isValid() && HasAnyExplicitSpecHeader) Diag(ExplicitSpecLoc, diag::note_explicit_template_spec_does_not_need_header) << NestedTypes.back(); @@ -6587,12 +6530,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, DeductionArg = PE->getPattern(); if (DeduceAutoType( Context.getTrivialTypeSourceInfo(ParamType, Param->getLocation()), - DeductionArg, ParamType, Depth, - // We do not check constraints right now because the - // immediately-declared constraint of the auto type is also an - // associated constraint, and will be checked along with the other - // associated constraints after checking the template argument list. - /*IgnoreConstraints=*/true) == DAR_Failed) { + DeductionArg, ParamType, Depth) == DAR_Failed) { Diag(Arg->getExprLoc(), diag::err_non_type_template_parm_type_deduction_failure) << Param->getDeclName() << Param->getType() << Arg->getType() diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 394c81c82794..048a50a741e4 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -4414,10 +4414,9 @@ namespace { QualType Result = SemaRef.Context.getAutoType( Replacement, TL.getTypePtr()->getKeyword(), Replacement.isNull(), - ReplacementIsPack, TL.getTypePtr()->getTypeConstraintConcept(), - TL.getTypePtr()->getTypeConstraintArguments()); + ReplacementIsPack); auto NewTL = TLB.push(Result); - NewTL.copy(TL); + NewTL.setNameLoc(TL.getNameLoc()); return Result; } @@ -4452,10 +4451,9 @@ namespace { Sema::DeduceAutoResult Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, QualType &Result, - Optional DependentDeductionDepth, - bool IgnoreConstraints) { + Optional DependentDeductionDepth) { return DeduceAutoType(Type->getTypeLoc(), Init, Result, - DependentDeductionDepth, IgnoreConstraints); + DependentDeductionDepth); } /// Attempt to produce an informative diagostic explaining why auto deduction @@ -4483,49 +4481,6 @@ static bool diagnoseAutoDeductionFailure(Sema &S, } } -static Sema::DeduceAutoResult -CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, - AutoTypeLoc TypeLoc, QualType Deduced) { - ConstraintSatisfaction Satisfaction; - ConceptDecl *Concept = Type.getTypeConstraintConcept(); - TemplateArgumentListInfo TemplateArgs(TypeLoc.getLAngleLoc(), - TypeLoc.getRAngleLoc()); - TemplateArgs.addArgument( - TemplateArgumentLoc(TemplateArgument(Deduced), - S.Context.getTrivialTypeSourceInfo( - Deduced, TypeLoc.getNameLoc()))); - for (unsigned I = 0, C = TypeLoc.getNumArgs(); I != C; ++I) - TemplateArgs.addArgument(TypeLoc.getArgLoc(I)); - - llvm::SmallVector Converted; - if (S.CheckTemplateArgumentList(Concept, SourceLocation(), TemplateArgs, - /*PartialTemplateArgs=*/false, Converted)) - return Sema::DAR_FailedAlreadyDiagnosed; - if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()}, - Converted, TypeLoc.getLocalSourceRange(), - Satisfaction)) - return Sema::DAR_FailedAlreadyDiagnosed; - if (!Satisfaction.IsSatisfied) { - std::string Buf; - llvm::raw_string_ostream OS(Buf); - OS << "'" << Concept->getName(); - if (TypeLoc.hasExplicitTemplateArgs()) { - OS << "<"; - for (const auto &Arg : Type.getTypeConstraintArguments()) - Arg.print(S.getPrintingPolicy(), OS); - OS << ">"; - } - OS << "'"; - OS.flush(); - S.Diag(TypeLoc.getConceptNameLoc(), - diag::err_placeholder_constraints_not_satisfied) - << Deduced << Buf << TypeLoc.getLocalSourceRange(); - S.DiagnoseUnsatisfiedConstraint(Satisfaction); - return Sema::DAR_FailedAlreadyDiagnosed; - } - return Sema::DAR_Succeeded; -} - /// Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6) /// /// Note that this is done even if the initializer is dependent. (This is @@ -4540,12 +4495,9 @@ CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, /// dependent cases. This is necessary for template partial ordering with /// 'auto' template parameters. The value specified is the template /// parameter depth at which we should perform 'auto' deduction. -/// \param IgnoreConstraints Set if we should not fail if the deduced type does -/// not satisfy the type-constraint in the auto type. Sema::DeduceAutoResult Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, - Optional DependentDeductionDepth, - bool IgnoreConstraints) { + Optional DependentDeductionDepth) { if (Init->getType()->isNonOverloadPlaceholderType()) { ExprResult NonPlaceholder = CheckPlaceholderExpr(Init); if (NonPlaceholder.isInvalid()) @@ -4586,14 +4538,6 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, return DAR_FailedAlreadyDiagnosed; // FIXME: Support a non-canonical deduced type for 'auto'. Deduced = Context.getCanonicalType(Deduced); - if (AT->isConstrained() && !IgnoreConstraints) { - auto ConstraintsResult = - CheckDeducedPlaceholderConstraints(*this, *AT, - Type.getContainedAutoTypeLoc(), - Deduced); - if (ConstraintsResult != DAR_Succeeded) - return ConstraintsResult; - } Result = SubstituteDeducedTypeTransform(*this, Deduced).Apply(Type); if (Result.isNull()) return DAR_FailedAlreadyDiagnosed; @@ -4701,17 +4645,6 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, return DAR_FailedAlreadyDiagnosed; } - if (const auto *AT = Type.getType()->getAs()) { - if (AT->isConstrained() && !IgnoreConstraints) { - auto ConstraintsResult = - CheckDeducedPlaceholderConstraints(*this, *AT, - Type.getContainedAutoTypeLoc(), - DeducedType); - if (ConstraintsResult != DAR_Succeeded) - return ConstraintsResult; - } - } - Result = SubstituteDeducedTypeTransform(*this, DeducedType).Apply(Type); if (Result.isNull()) return DAR_FailedAlreadyDiagnosed; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 2f2c06bb72de..a470cfc87440 100755 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2685,16 +2685,6 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), D->getPosition(), D->getIdentifier(), T, D->isParameterPack(), DI); - if (AutoTypeLoc AutoLoc = DI->getTypeLoc().getContainedAutoTypeLoc()) - if (AutoLoc.isConstrained()) - if (SemaRef.AttachTypeConstraint( - AutoLoc, Param, - IsExpandedParameterPack - ? DI->getTypeLoc().getAs() - .getEllipsisLoc() - : SourceLocation())) - Invalid = true; - Param->setAccess(AS_public); Param->setImplicit(D->isImplicit()); if (Invalid) diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 02ca73e9fc59..efb4437b3e60 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -11,7 +11,6 @@ //===----------------------------------------------------------------------===// #include "TypeLocBuilder.h" -#include "TreeTransform.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTMutationListener.h" @@ -28,7 +27,6 @@ #include "clang/Sema/DeclSpec.h" #include "clang/Sema/DelayedDiagnostic.h" #include "clang/Sema/Lookup.h" -#include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/Template.h" @@ -1253,26 +1251,6 @@ getImageAccess(const ParsedAttributesView &Attrs) { return OpenCLAccessAttr::Keyword_read_only; } -static QualType ConvertConstrainedAutoDeclSpecToType(Sema &S, DeclSpec &DS, - AutoTypeKeyword AutoKW) { - assert(DS.isConstrainedAuto()); - TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId(); - TemplateArgumentListInfo TemplateArgsInfo; - TemplateArgsInfo.setLAngleLoc(TemplateId->LAngleLoc); - TemplateArgsInfo.setRAngleLoc(TemplateId->RAngleLoc); - ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), - TemplateId->NumArgs); - S.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo); - llvm::SmallVector TemplateArgs; - for (auto &ArgLoc : TemplateArgsInfo.arguments()) - TemplateArgs.push_back(ArgLoc.getArgument()); - return S.Context.getAutoType(QualType(), AutoTypeKeyword::Auto, false, - /*IsPack=*/false, - cast(TemplateId->Template.get() - .getAsTemplateDecl()), - TemplateArgs); -} - /// Convert the specified declspec to the appropriate type /// object. /// \param state Specifies the declarator containing the declaration specifier @@ -1617,11 +1595,6 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { break; case DeclSpec::TST_auto: - if (DS.isConstrainedAuto()) { - Result = ConvertConstrainedAutoDeclSpecToType(S, DS, - AutoTypeKeyword::Auto); - break; - } Result = Context.getAutoType(QualType(), AutoTypeKeyword::Auto, false); break; @@ -1630,12 +1603,6 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { break; case DeclSpec::TST_decltype_auto: - if (DS.isConstrainedAuto()) { - Result = - ConvertConstrainedAutoDeclSpecToType(S, DS, - AutoTypeKeyword::DecltypeAuto); - break; - } Result = Context.getAutoType(QualType(), AutoTypeKeyword::DecltypeAuto, /*IsDependent*/ false); break; @@ -2954,87 +2921,6 @@ static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy, D.getDeclSpec().getUnalignedSpecLoc()); } -static void CopyTypeConstraintFromAutoType(Sema &SemaRef, const AutoType *Auto, - AutoTypeLoc AutoLoc, - TemplateTypeParmDecl *TP, - SourceLocation EllipsisLoc) { - - TemplateArgumentListInfo TAL(AutoLoc.getLAngleLoc(), AutoLoc.getRAngleLoc()); - for (unsigned Idx = 0; Idx < AutoLoc.getNumArgs(); ++Idx) - TAL.addArgument(AutoLoc.getArgLoc(Idx)); - - SemaRef.AttachTypeConstraint( - AutoLoc.getNestedNameSpecifierLoc(), AutoLoc.getConceptNameInfo(), - AutoLoc.getNamedConcept(), - AutoLoc.hasExplicitTemplateArgs() ? &TAL : nullptr, TP, EllipsisLoc); -} - -static QualType InventTemplateParameter( - TypeProcessingState &state, QualType T, TypeSourceInfo *TSI, AutoType *Auto, - InventedTemplateParameterInfo &Info) { - Sema &S = state.getSema(); - Declarator &D = state.getDeclarator(); - - const unsigned TemplateParameterDepth = Info.AutoTemplateParameterDepth; - const unsigned AutoParameterPosition = Info.TemplateParams.size(); - const bool IsParameterPack = D.hasEllipsis(); - - // If auto is mentioned in a lambda parameter or abbreviated function - // template context, convert it to a template parameter type. - - // Create the TemplateTypeParmDecl here to retrieve the corresponding - // template parameter type. Template parameters are temporarily added - // to the TU until the associated TemplateDecl is created. - TemplateTypeParmDecl *InventedTemplateParam = - TemplateTypeParmDecl::Create( - S.Context, S.Context.getTranslationUnitDecl(), - /*KeyLoc=*/D.getDeclSpec().getTypeSpecTypeLoc(), - /*NameLoc=*/D.getIdentifierLoc(), - TemplateParameterDepth, AutoParameterPosition, - S.InventAbbreviatedTemplateParameterTypeName( - D.getIdentifier(), AutoParameterPosition), false, - IsParameterPack, /*HasTypeConstraint=*/Auto->isConstrained()); - InventedTemplateParam->setImplicit(); - Info.TemplateParams.push_back(InventedTemplateParam); - // Attach type constraints - if (Auto->isConstrained()) { - if (TSI) { - CopyTypeConstraintFromAutoType( - S, Auto, TSI->getTypeLoc().getContainedAutoTypeLoc(), - InventedTemplateParam, D.getEllipsisLoc()); - } else { - TemplateIdAnnotation *TemplateId = D.getDeclSpec().getRepAsTemplateId(); - TemplateArgumentListInfo TemplateArgsInfo; - if (TemplateId->LAngleLoc.isValid()) { - ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), - TemplateId->NumArgs); - S.translateTemplateArguments(TemplateArgsPtr, TemplateArgsInfo); - } - S.AttachTypeConstraint( - D.getDeclSpec().getTypeSpecScope().getWithLocInContext(S.Context), - DeclarationNameInfo(DeclarationName(TemplateId->Name), - TemplateId->TemplateNameLoc), - cast(TemplateId->Template.get().getAsTemplateDecl()), - TemplateId->LAngleLoc.isValid() ? &TemplateArgsInfo : nullptr, - InventedTemplateParam, D.getEllipsisLoc()); - } - } - - // If TSI is nullptr, this is a constrained declspec auto and the type - // constraint will be attached later in TypeSpecLocFiller - - // Replace the 'auto' in the function parameter with this invented - // template type parameter. - // FIXME: Retain some type sugar to indicate that this was written - // as 'auto'? - return state.ReplaceAutoType( - T, QualType(InventedTemplateParam->getTypeForDecl(), 0)); -} - -static TypeSourceInfo * -GetTypeSourceInfoForDeclarator(TypeProcessingState &State, - QualType T, TypeSourceInfo *ReturnTypeInfo); - static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, TypeSourceInfo *&ReturnTypeInfo) { Sema &SemaRef = state.getSema(); @@ -3105,43 +2991,46 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, break; case DeclaratorContext::ObjCParameterContext: case DeclaratorContext::ObjCResultContext: + case DeclaratorContext::PrototypeContext: Error = 0; break; case DeclaratorContext::RequiresExprContext: - Error = 22; + Error = 21; break; - case DeclaratorContext::PrototypeContext: - case DeclaratorContext::LambdaExprParameterContext: { - InventedTemplateParameterInfo *Info = nullptr; - if (D.getContext() == DeclaratorContext::PrototypeContext) { - // With concepts we allow 'auto' in function parameters. - if (!SemaRef.getLangOpts().ConceptsTS || !Auto || - Auto->getKeyword() != AutoTypeKeyword::Auto) { - Error = 0; - break; - } else if (!SemaRef.getCurScope()->isFunctionDeclarationScope()) { - Error = 21; - break; - } else if (D.hasTrailingReturnType()) { - // This might be OK, but we'll need to convert the trailing return - // type later. - break; - } + case DeclaratorContext::LambdaExprParameterContext: + // In C++14, generic lambdas allow 'auto' in their parameters. + if (!SemaRef.getLangOpts().CPlusPlus14 || + !Auto || Auto->getKeyword() != AutoTypeKeyword::Auto) + Error = 16; + else { + // If auto is mentioned in a lambda parameter context, convert it to a + // template parameter type. + sema::LambdaScopeInfo *LSI = SemaRef.getCurLambda(); + assert(LSI && "No LambdaScopeInfo on the stack!"); + const unsigned TemplateParameterDepth = LSI->AutoTemplateParameterDepth; + const unsigned AutoParameterPosition = LSI->TemplateParams.size(); + const bool IsParameterPack = D.hasEllipsis(); - Info = &SemaRef.InventedParameterInfos.back(); - } else { - // In C++14, generic lambdas allow 'auto' in their parameters. - if (!SemaRef.getLangOpts().CPlusPlus14 || !Auto || - Auto->getKeyword() != AutoTypeKeyword::Auto) { - Error = 16; - break; - } - Info = SemaRef.getCurLambda(); - assert(Info && "No LambdaScopeInfo on the stack!"); + // Create the TemplateTypeParmDecl here to retrieve the corresponding + // template parameter type. Template parameters are temporarily added + // to the TU until the associated TemplateDecl is created. + TemplateTypeParmDecl *CorrespondingTemplateParam = + TemplateTypeParmDecl::Create( + SemaRef.Context, SemaRef.Context.getTranslationUnitDecl(), + /*KeyLoc*/ SourceLocation(), /*NameLoc*/ D.getBeginLoc(), + TemplateParameterDepth, AutoParameterPosition, + /*Identifier*/ nullptr, false, IsParameterPack, + /*HasTypeConstraint=*/false); + CorrespondingTemplateParam->setImplicit(); + LSI->TemplateParams.push_back(CorrespondingTemplateParam); + // Replace the 'auto' in the function parameter with this invented + // template type parameter. + // FIXME: Retain some type sugar to indicate that this was written + // as 'auto'. + T = state.ReplaceAutoType( + T, QualType(CorrespondingTemplateParam->getTypeForDecl(), 0)); } - T = InventTemplateParameter(state, T, nullptr, Auto, *Info); break; - } case DeclaratorContext::MemberContext: { if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static || D.isFunctionDeclarator()) @@ -4143,6 +4032,10 @@ static bool DiagnoseMultipleAddrSpaceAttributes(Sema &S, LangAS ASOld, return false; } +static TypeSourceInfo * +GetTypeSourceInfoForDeclarator(TypeProcessingState &State, + QualType T, TypeSourceInfo *ReturnTypeInfo); + static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, QualType declSpecType, TypeSourceInfo *TInfo) { @@ -4718,8 +4611,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, } else if (D.getContext() != DeclaratorContext::LambdaExprContext && (T.hasQualifiers() || !isa(T) || cast(T)->getKeyword() != - AutoTypeKeyword::Auto || - cast(T)->isConstrained())) { + AutoTypeKeyword::Auto)) { S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(), diag::err_trailing_return_without_auto) << T << D.getDeclSpec().getSourceRange(); @@ -4730,12 +4622,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // An error occurred parsing the trailing return type. T = Context.IntTy; D.setInvalidType(true); - } else if (S.getLangOpts().ConceptsTS) - // Handle cases like: `auto f() -> auto` or `auto f() -> C auto`. - if (AutoType *Auto = T->getContainedAutoType()) - if (S.getCurScope()->isFunctionDeclarationScope()) - T = InventTemplateParameter(state, T, TInfo, Auto, - S.InventedParameterInfos.back()); + } } else { // This function type is not the type of the entity being declared, // so checking the 'auto' is not the responsibility of this chunk. @@ -5355,8 +5242,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // // We represent function parameter packs as function parameters whose // type is a pack expansion. - if (!T->containsUnexpandedParameterPack() && - (!LangOpts.ConceptsTS || !T->getContainedAutoType())) { + if (!T->containsUnexpandedParameterPack()) { S.Diag(D.getEllipsisLoc(), diag::err_function_parameter_pack_without_parameter_packs) << T << D.getSourceRange(); @@ -5564,15 +5450,14 @@ static void fillAttributedTypeLoc(AttributedTypeLoc TL, namespace { class TypeSpecLocFiller : public TypeLocVisitor { - Sema &SemaRef; ASTContext &Context; TypeProcessingState &State; const DeclSpec &DS; public: - TypeSpecLocFiller(Sema &S, ASTContext &Context, TypeProcessingState &State, + TypeSpecLocFiller(ASTContext &Context, TypeProcessingState &State, const DeclSpec &DS) - : SemaRef(S), Context(Context), State(State), DS(DS) {} + : Context(Context), State(State), DS(DS) {} void VisitAttributedTypeLoc(AttributedTypeLoc TL) { Visit(TL.getModifiedLoc()); @@ -5700,32 +5585,6 @@ namespace { TL.copy( TInfo->getTypeLoc().castAs()); } - void VisitAutoTypeLoc(AutoTypeLoc TL) { - assert(DS.getTypeSpecType() == TST_auto || - DS.getTypeSpecType() == TST_decltype_auto || - DS.getTypeSpecType() == TST_auto_type || - DS.getTypeSpecType() == TST_unspecified); - TL.setNameLoc(DS.getTypeSpecTypeLoc()); - if (!DS.isConstrainedAuto()) - return; - TemplateIdAnnotation *TemplateId = DS.getRepAsTemplateId(); - if (DS.getTypeSpecScope().isNotEmpty()) - TL.setNestedNameSpecifierLoc( - DS.getTypeSpecScope().getWithLocInContext(Context)); - else - TL.setNestedNameSpecifierLoc(NestedNameSpecifierLoc()); - TL.setConceptNameLoc(TemplateId->TemplateNameLoc); - 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()); - } void VisitTagTypeLoc(TagTypeLoc TL) { TL.setNameLoc(DS.getTypeSpecTypeNameLoc()); } @@ -5995,7 +5854,7 @@ GetTypeSourceInfoForDeclarator(TypeProcessingState &State, assert(TL.getFullDataSize() == CurrTL.getFullDataSize()); memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(), TL.getFullDataSize()); } else { - TypeSpecLocFiller(S, S.Context, State, D.getDeclSpec()).Visit(CurrTL); + TypeSpecLocFiller(S.Context, State, D.getDeclSpec()).Visit(CurrTL); } return TInfo; diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index d6105353bbdf..1f7251173838 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -951,16 +951,12 @@ public: /// Build a new C++11 auto type. /// /// By default, builds a new AutoType with the given deduced type. - QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword, - ConceptDecl *TypeConstraintConcept, - ArrayRef TypeConstraintArgs) { + QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword) { // Note, IsDependent is always false here: we implicitly convert an 'auto' // which has been deduced to a dependent type into an undeduced 'auto', so // that we'll retry deduction after the transformation. return SemaRef.Context.getAutoType(Deduced, Keyword, - /*IsDependent*/ false, /*IsPack=*/false, - TypeConstraintConcept, - TypeConstraintArgs); + /*IsDependent*/ false); } /// By default, builds a new DeducedTemplateSpecializationType with the given @@ -4504,10 +4500,7 @@ QualType TreeTransform::RebuildQualifiedType(QualType T, Deduced = SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs); T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(), - AutoTy->isDependentType(), - /*isPack=*/false, - AutoTy->getTypeConstraintConcept(), - AutoTy->getTypeConstraintArguments()); + AutoTy->isDependentType()); } else { // Otherwise, complain about the addition of a qualifier to an // already-qualified type. @@ -5240,29 +5233,21 @@ bool TreeTransform::TransformFunctionTypeParams( PackExpansionTypeLoc ExpansionTL = TL.castAs(); TypeLoc Pattern = ExpansionTL.getPatternLoc(); SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded); + assert(Unexpanded.size() > 0 && "Could not find parameter packs!"); // Determine whether we should expand the parameter packs. bool ShouldExpand = false; bool RetainExpansion = false; - Optional OrigNumExpansions; - if (Unexpanded.size() > 0) { - OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions(); - NumExpansions = OrigNumExpansions; - if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(), - Pattern.getSourceRange(), - Unexpanded, - ShouldExpand, - RetainExpansion, - NumExpansions)) { - return true; - } - } else { -#ifndef NDEBUG - const AutoType *AT = - Pattern.getType().getTypePtr()->getContainedAutoType(); - assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) && - "Could not find parameter packs or undeduced auto type!"); -#endif + Optional OrigNumExpansions = + ExpansionTL.getTypePtr()->getNumExpansions(); + NumExpansions = OrigNumExpansions; + if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(), + Pattern.getSourceRange(), + Unexpanded, + ShouldExpand, + RetainExpansion, + NumExpansions)) { + return true; } if (ShouldExpand) { @@ -5322,9 +5307,6 @@ bool TreeTransform::TransformFunctionTypeParams( indexAdjustment, NumExpansions, /*ExpectParameterPack=*/true); - assert(NewParm->isParameterPack() && - "Parameter pack no longer a parameter pack after " - "transformation."); } else { NewParm = getDerived().TransformFunctionTypeParam( OldParm, indexAdjustment, None, /*ExpectParameterPack=*/ false); @@ -5829,6 +5811,32 @@ QualType TreeTransform::TransformUnaryTransformType( return Result; } +template +QualType TreeTransform::TransformAutoType(TypeLocBuilder &TLB, + AutoTypeLoc TL) { + const AutoType *T = TL.getTypePtr(); + QualType OldDeduced = T->getDeducedType(); + QualType NewDeduced; + if (!OldDeduced.isNull()) { + NewDeduced = getDerived().TransformType(OldDeduced); + if (NewDeduced.isNull()) + return QualType(); + } + + QualType Result = TL.getType(); + if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced || + T->isDependentType()) { + Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword()); + if (Result.isNull()) + return QualType(); + } + + AutoTypeLoc NewTL = TLB.push(Result); + NewTL.setNameLoc(TL.getNameLoc()); + + return Result; +} + template QualType TreeTransform::TransformDeducedTemplateSpecializationType( TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) { @@ -6090,71 +6098,6 @@ QualType TreeTransform::TransformPipeType(TypeLocBuilder &TLB, } }; -template -QualType TreeTransform::TransformAutoType(TypeLocBuilder &TLB, - AutoTypeLoc TL) { - const AutoType *T = TL.getTypePtr(); - QualType OldDeduced = T->getDeducedType(); - QualType NewDeduced; - if (!OldDeduced.isNull()) { - NewDeduced = getDerived().TransformType(OldDeduced); - if (NewDeduced.isNull()) - return QualType(); - } - - ConceptDecl *NewCD = nullptr; - TemplateArgumentListInfo NewTemplateArgs; - NestedNameSpecifierLoc NewNestedNameSpec; - if (TL.getTypePtr()->isConstrained()) { - NewCD = cast_or_null( - getDerived().TransformDecl( - TL.getConceptNameLoc(), - TL.getTypePtr()->getTypeConstraintConcept())); - - NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); - NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); - typedef TemplateArgumentLocContainerIterator ArgIterator; - if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), - ArgIterator(TL, - TL.getNumArgs()), - NewTemplateArgs)) - return QualType(); - - if (TL.getNestedNameSpecifierLoc()) { - NewNestedNameSpec - = getDerived().TransformNestedNameSpecifierLoc( - TL.getNestedNameSpecifierLoc()); - if (!NewNestedNameSpec) - return QualType(); - } - } - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced || - T->isDependentType()) { - llvm::SmallVector NewArgList; - NewArgList.reserve(NewArgList.size()); - for (const auto &ArgLoc : NewTemplateArgs.arguments()) - NewArgList.push_back(ArgLoc.getArgument()); - Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD, - NewArgList); - if (Result.isNull()) - return QualType(); - } - - AutoTypeLoc NewTL = TLB.push(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()); - for (unsigned I = 0; I < TL.getNumArgs(); ++I) - NewTL.setArgLocInfo(I, NewTemplateArgs.arguments()[I].getLocInfo()); - - return Result; -} template QualType TreeTransform::TransformTemplateSpecializationType( diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 21f6a36565ef..6497a4b06f7a 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -6576,17 +6576,6 @@ void TypeLocReader::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) { TL.setNameLoc(readSourceLocation()); - if (Reader.readBool()) { - TL.setNestedNameSpecifierLoc(ReadNestedNameSpecifierLoc()); - TL.setTemplateKWLoc(readSourceLocation()); - TL.setConceptNameLoc(readSourceLocation()); - TL.setFoundDecl(Reader.readDeclAs()); - TL.setLAngleLoc(readSourceLocation()); - TL.setRAngleLoc(readSourceLocation()); - for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) - TL.setArgLocInfo(i, Reader.readTemplateArgumentLocInfo( - TL.getTypePtr()->getArg(i).getKind())); - } } void TypeLocReader::VisitDeducedTemplateSpecializationTypeLoc( diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 093b69ab19d0..4fd079e9d8e1 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2317,12 +2317,12 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { D->setDeclaredWithTypename(Record.readInt()); - if (Record.readBool()) { + if (Record.readInt()) { NestedNameSpecifierLoc NNS = Record.readNestedNameSpecifierLoc(); DeclarationNameInfo DN = Record.readDeclarationNameInfo(); - ConceptDecl *NamedConcept = Record.readDeclAs(); + ConceptDecl *NamedConcept = cast(Record.readDecl()); const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; - if (Record.readBool()) + if (Record.readInt()) ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); Expr *ImmediatelyDeclaredConstraint = Record.readExpr(); D->setTypeConstraint(NNS, DN, /*FoundDecl=*/nullptr, NamedConcept, @@ -2340,8 +2340,6 @@ void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { // TemplateParmPosition. D->setDepth(Record.readInt()); D->setPosition(Record.readInt()); - if (D->hasPlaceholderTypeConstraint()) - D->setPlaceholderTypeConstraint(Record.readExpr()); if (D->isExpandedParameterPack()) { auto TypesAndInfos = D->getTrailingObjects>(); @@ -3825,19 +3823,13 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { HasTypeConstraint); break; } - case DECL_NON_TYPE_TEMPLATE_PARM: { - bool HasTypeConstraint = Record.readInt(); - D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID, - HasTypeConstraint); + case DECL_NON_TYPE_TEMPLATE_PARM: + D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID); break; - } - case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK: { - bool HasTypeConstraint = Record.readInt(); + case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK: D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID, - Record.readInt(), - HasTypeConstraint); + Record.readInt()); break; - } case DECL_TEMPLATE_TEMPLATE_PARM: D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID); break; diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 79f7d577c672..c216b14661d4 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -349,18 +349,6 @@ void TypeLocWriter::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) { Record.AddSourceLocation(TL.getNameLoc()); - Record.push_back(TL.isConstrained()); - if (TL.isConstrained()) { - Record.AddNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc()); - Record.AddSourceLocation(TL.getTemplateKWLoc()); - Record.AddSourceLocation(TL.getConceptNameLoc()); - Record.AddDeclRef(TL.getFoundDecl()); - Record.AddSourceLocation(TL.getLAngleLoc()); - Record.AddSourceLocation(TL.getRAngleLoc()); - for (unsigned I = 0; I < TL.getNumArgs(); ++I) - Record.AddTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(), - TL.getArgLocInfo(I)); - } } void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc( diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 472136d99a13..459e61713ed1 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1675,8 +1675,6 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { // For an expanded parameter pack, record the number of expansion types here // so that it's easier for deserialization to allocate the right amount of // memory. - Expr *TypeConstraint = D->getPlaceholderTypeConstraint(); - Record.push_back(!!TypeConstraint); if (D->isExpandedParameterPack()) Record.push_back(D->getNumExpansionTypes()); @@ -1684,8 +1682,6 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { // TemplateParmPosition. Record.push_back(D->getDepth()); Record.push_back(D->getPosition()); - if (TypeConstraint) - Record.AddStmt(TypeConstraint); if (D->isExpandedParameterPack()) { for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) { diff --git a/clang/test/AST/ast-dump-record-definition-data-json.cpp b/clang/test/AST/ast-dump-record-definition-data-json.cpp index 44ec2a2f7bc6..2603eedcd817 100644 --- a/clang/test/AST/ast-dump-record-definition-data-json.cpp +++ b/clang/test/AST/ast-dump-record-definition-data-json.cpp @@ -417,24 +417,15 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "id": "0x{{.*}}", // CHECK-NEXT: "kind": "TemplateTypeParmDecl", // CHECK-NEXT: "loc": { -// CHECK-NEXT: "offset": 197, -// CHECK-NEXT: "col": 33, -// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: "offset": 193, +// CHECK-NEXT: "col": 29, +// CHECK-NEXT: "tokLen": 4 // CHECK-NEXT: }, // CHECK-NEXT: "range": { -// CHECK-NEXT: "begin": { -// CHECK-NEXT: "offset": 193, -// CHECK-NEXT: "col": 29, -// CHECK-NEXT: "tokLen": 4 -// CHECK-NEXT: }, -// CHECK-NEXT: "end": { -// CHECK-NEXT: "offset": 197, -// CHECK-NEXT: "col": 33, -// CHECK-NEXT: "tokLen": 1 -// CHECK-NEXT: } +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "isImplicit": true, -// CHECK-NEXT: "name": "auto:1", // CHECK-NEXT: "tagUsed": "class", // CHECK-NEXT: "depth": 0, // CHECK-NEXT: "index": 0 @@ -533,24 +524,15 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "id": "0x{{.*}}", // CHECK-NEXT: "kind": "TemplateTypeParmDecl", // CHECK-NEXT: "loc": { -// CHECK-NEXT: "offset": 197, -// CHECK-NEXT: "col": 33, -// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: "offset": 193, +// CHECK-NEXT: "col": 29, +// CHECK-NEXT: "tokLen": 4 // CHECK-NEXT: }, // CHECK-NEXT: "range": { -// CHECK-NEXT: "begin": { -// CHECK-NEXT: "offset": 193, -// CHECK-NEXT: "col": 29, -// CHECK-NEXT: "tokLen": 4 -// CHECK-NEXT: }, -// CHECK-NEXT: "end": { -// CHECK-NEXT: "offset": 197, -// CHECK-NEXT: "col": 33, -// CHECK-NEXT: "tokLen": 1 -// CHECK-NEXT: } +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "isImplicit": true, -// CHECK-NEXT: "name": "auto:1", // CHECK-NEXT: "tagUsed": "class", // CHECK-NEXT: "depth": 0, // CHECK-NEXT: "index": 0 @@ -608,24 +590,15 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "id": "0x{{.*}}", // CHECK-NEXT: "kind": "TemplateTypeParmDecl", // CHECK-NEXT: "loc": { -// CHECK-NEXT: "offset": 197, -// CHECK-NEXT: "col": 33, -// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: "offset": 193, +// CHECK-NEXT: "col": 29, +// CHECK-NEXT: "tokLen": 4 // CHECK-NEXT: }, // CHECK-NEXT: "range": { -// CHECK-NEXT: "begin": { -// CHECK-NEXT: "offset": 193, -// CHECK-NEXT: "col": 29, -// CHECK-NEXT: "tokLen": 4 -// CHECK-NEXT: }, -// CHECK-NEXT: "end": { -// CHECK-NEXT: "offset": 197, -// CHECK-NEXT: "col": 33, -// CHECK-NEXT: "tokLen": 1 -// CHECK-NEXT: } +// CHECK-NEXT: "begin": {}, +// CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "isImplicit": true, -// CHECK-NEXT: "name": "auto:1", // CHECK-NEXT: "tagUsed": "class", // CHECK-NEXT: "depth": 0, // CHECK-NEXT: "index": 0 diff --git a/clang/test/CXX/dcl/dcl.fct/p17.cpp b/clang/test/CXX/dcl/dcl.fct/p17.cpp deleted file mode 100644 index bf19e57e7964..000000000000 --- a/clang/test/CXX/dcl/dcl.fct/p17.cpp +++ /dev/null @@ -1,260 +0,0 @@ -// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -verify %s -template constexpr bool is_same_v = false; -template constexpr bool is_same_v = true; - -template -struct type_list; - -namespace unconstrained { - decltype(auto) f1(auto x) { return x; } - static_assert(is_same_v); - static_assert(is_same_v); - - decltype(auto) f2(auto &x) { return x; } - // expected-note@-1{{candidate function [with x:auto = int] not viable: expects an l-value for 1st argument}} - // expected-note@-2{{candidate function [with x:auto = char] not viable: expects an l-value for 1st argument}} - static_assert(is_same_v); // expected-error{{no matching}} - static_assert(is_same_v); // expected-error{{no matching}} - - decltype(auto) f3(const auto &x) { return x; } - static_assert(is_same_v); - static_assert(is_same_v); - - decltype(auto) f4(auto (*x)(auto y)) { return x; } // expected-error{{'auto' not allowed in function prototype}} - - decltype(auto) f5(void (*x)(decltype(auto) y)) { return x; } // expected-error{{'decltype(auto)' not allowed in function prototype}} - - int return_int(); void return_void(); int foo(int); - - decltype(auto) f6(auto (*x)()) { return x; } - // expected-note@-1{{candidate template ignored: failed template argument deduction}} - static_assert(is_same_v); - static_assert(is_same_v); - using f6c1 = decltype(f6(foo)); // expected-error{{no matching}} - - decltype(auto) f7(auto (*x)() -> int) { return x; } - // expected-note@-1{{candidate function not viable: no known conversion from 'void ()' to 'auto (*)() -> int' for 1st argument}} - // expected-note@-2{{candidate function not viable: no known conversion from 'int (int)' to 'auto (*)() -> int' for 1st argument}} - static_assert(is_same_v); - using f7c1 = decltype(f7(return_void)); // expected-error{{no matching}} - using f7c2 = decltype(f7(foo)); // expected-error{{no matching}} - static_assert(is_same_v); - - decltype(auto) f8(auto... x) { return (x + ...); } - static_assert(is_same_v); - static_assert(is_same_v); - static_assert(is_same_v); - - decltype(auto) f9(auto &... x) { return (x, ...); } - // expected-note@-1{{candidate function [with x:auto = ] not viable: expects an l-value for 2nd argument}} - using f9c1 = decltype(f9(return_int, 1)); // expected-error{{no matching}} - - decltype(auto) f11(decltype(auto) x) { return x; } // expected-error{{'decltype(auto)' not allowed in function prototype}} - - template - auto f12(auto x, T y) -> type_list; - static_assert(is_same_v>); - static_assert(is_same_v(1, 'c')), type_list>); - - template - auto f13(T x, auto y) -> type_list; - static_assert(is_same_v>); - static_assert(is_same_v(1, 'c')), type_list>); - - template - auto f14(auto y) -> type_list; - static_assert(is_same_v('c')), type_list>); - static_assert(is_same_v('c')), type_list>); - - template - auto f15(auto y, U u) -> type_list; - static_assert(is_same_v('c', nullptr)), type_list>); - static_assert(is_same_v('c', nullptr)), type_list>); - - auto f16(auto x, auto y) -> type_list; - static_assert(is_same_v>); - static_assert(is_same_v('c', 1)), type_list>); - static_assert(is_same_v('c', 1)), type_list>); - - void f17(auto x, auto y) requires (sizeof(x) > 1); - // expected-note@-1{{candidate template ignored: constraints not satisfied [with x:auto = char, y:auto = int]}} - // expected-note@-2{{because 'sizeof (x) > 1' (1 > 1) evaluated to false}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v('c', 1)), void>); - static_assert(is_same_v('c', 1)), void>); - - void f18(auto... x) requires (sizeof...(x) == 2); - // expected-note@-1{{candidate template ignored: constraints not satisfied [with x:auto = ]}} - // expected-note@-2{{candidate template ignored: constraints not satisfied [with x:auto = ]}} - // expected-note@-3{{because 'sizeof...(x) == 2' (1 == 2) evaluated to false}} - // expected-note@-4{{because 'sizeof...(x) == 2' (3 == 2) evaluated to false}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - static_assert(is_same_v); - // expected-error@-1{{no matching}} - - template - struct S { - constexpr auto f1(auto x, T t) -> decltype(x + t); - - template - constexpr auto f2(U u, auto x, T t) -> decltype(x + u + t); - }; - - template - constexpr auto S::f1(auto x, T t) -> decltype(x + t) { return x + t; } - - template - template - constexpr auto S::f2(auto x, U u, T t) -> decltype(x + u + t) { return x + u + t; } - // expected-error@-1 {{out-of-line definition of 'f2' does not match any declaration in 'S'}} - - template - template - constexpr auto S::f2(U u, auto x, T t) -> decltype(x + u + t) { return x + u + t; } - - template<> - template<> - constexpr auto S::f2(double u, char x, int t) -> double { return 42; } - - static_assert(S{}.f1(1, 2) == 3); - static_assert(S{}.f2(1, 2, '\x00') == 3); - static_assert(S{}.f2(1, 2, '\x00') == 3.); - static_assert(S{}.f2(1, '2', '\x00') == 42); -} - -namespace constrained { - template - concept C = is_same_v; - // expected-note@-1 12{{because}} - template - concept C2 = is_same_v; - // expected-note@-1 12{{because}} - - int i; - const int ci = 1; - char c; - const char cc = 'a'; - int g(int); - char h(int); - - void f1(C auto x); - // expected-note@-1 {{candidate template ignored: constraints not satisfied [with x:auto = }} - // expected-note@-2{{because}} - static_assert(is_same_v); - static_assert(is_same_v); - // expected-error@-1{{no matching}} - void f2(C auto &x); - // expected-note@-1 2{{candidate template ignored}} expected-note@-1 2{{because}} - static_assert(is_same_v); - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - void f3(const C auto &x); - // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}} - static_assert(is_same_v); - static_assert(is_same_v); - static_assert(is_same_v); - // expected-error@-1{{no matching}} - void f4(C auto (*x)(C auto y)); // expected-error{{'auto' not allowed}} - void f5(C auto (*x)(int y)); - // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}} - static_assert(is_same_v); - static_assert(is_same_v); - // expected-error@-1{{no matching}} - void f6(C auto (*x)() -> int); // expected-error{{function with trailing return type must specify return type 'auto', not 'C auto'}} - void f7(C auto... x); - // expected-note@-1 2{{candidate template ignored}} expected-note@-1 2{{because}} - static_assert(is_same_v); - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - void f8(C auto &... x); - // expected-note@-1 2{{candidate template ignored}} expected-note@-1 2{{because}} - static_assert(is_same_v); - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - void f9(const C auto &... x); - // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}} - static_assert(is_same_v); - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - void f10(C decltype(auto) x); - auto f11 = [] (C auto x) { }; - // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}} - static_assert(is_same_v); - static_assert(is_same_v); - // expected-error@-1{{no matching}} - - void f12(C2 auto x); - // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - void f13(C2 auto &x); - // expected-note@-1 2{{candidate template ignored}} expected-note@-1 2{{because}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - void f14(const C2 auto &x); - // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - static_assert(is_same_v); - void f15(C2 auto (*x)(C2 auto y)); // expected-error{{'auto' not allowed}} - void f16(C2 auto (*x)(int y)); - // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - void f17(C2 auto (*x)() -> int); // expected-error{{function with trailing return type must specify return type 'auto', not 'C2 auto'}} - void f18(C2 auto... x); - // expected-note@-1 2{{candidate template ignored}} expected-note@-1 2{{because}} - static_assert(is_same_v); - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - void f19(C2 auto &... x); - // expected-note@-1 2{{candidate template ignored}} expected-note@-1 2{{because}} - static_assert(is_same_v); - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - void f20(const C2 auto &... x); - // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}} - static_assert(is_same_v); - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - void f21(C2 decltype(auto) x); - auto f22 = [] (C2 auto x) { }; - // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); - - struct S1 { S1(C auto); }; - // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}} - // expected-note@-2 2{{candidate constructor}} - static_assert(is_same_v); - static_assert(is_same_v); - // expected-error@-1{{no matching}} - struct S2 { S2(C2 auto); }; - // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}} - // expected-note@-2 2{{candidate constructor}} - static_assert(is_same_v); - // expected-error@-1{{no matching}} - static_assert(is_same_v); -} diff --git a/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp b/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp deleted file mode 100644 index a4e71d341cd7..000000000000 --- a/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -verify %s - -template -concept LargerThan = sizeof(T) > size; -// expected-note@-1 2{{because 'sizeof(char) > 1U' (1 > 1) evaluated to false}} -// expected-note@-2 {{because 'sizeof(int) > 10U' (4 > 10) evaluated to false}} -// expected-note@-3 {{because 'sizeof(int) > 4U' (4 > 4) evaluated to false}} - -template -concept Large = LargerThan; -// expected-note@-1 2{{because 'LargerThan' evaluated to false}} - -namespace X { - template - concept SmallerThan = sizeof(T) < size; - template - concept Small = SmallerThan; -} - -Large auto test1() { // expected-error{{deduced type 'char' does not satisfy 'Large'}} - Large auto i = 'a'; - // expected-error@-1{{deduced type 'char' does not satisfy 'Large'}} - Large auto j = 10; - ::Large auto k = 10; - LargerThan<1> auto l = 10; - ::LargerThan<1> auto m = 10; - LargerThan<10> auto n = 10; - // expected-error@-1{{deduced type 'int' does not satisfy 'LargerThan<10>'}} - X::Small auto o = 'x'; - X::SmallerThan<5> auto p = 1; - return 'a'; -} - -::Large auto test2() { return 10; } -LargerThan<4> auto test3() { return 10; } -// expected-error@-1{{deduced type 'int' does not satisfy 'LargerThan<4>'}} -::LargerThan<2> auto test4() { return 10; } - -Large auto test5() -> void; -// expected-error@-1{{function with trailing return type must specify return type 'auto', not 'Large auto'}} -auto test6() -> Large auto { return 1; } - -X::Small auto test7() { return 'a'; } -X::SmallerThan<5> auto test8() { return 10; } \ No newline at end of file diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.closure/p3.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.closure/p3.cpp index 0c0f820d1689..942280e1059f 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.closure/p3.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.closure/p3.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -std=c++2a -fconcepts-ts -verify %s auto l1 = [] (auto x) requires (sizeof(decltype(x)) == 1) { return x; }; -// expected-note@-1{{candidate template ignored: constraints not satisfied [with x:auto = int]}} +// expected-note@-1{{candidate template ignored: constraints not satisfied [with $0 = int]}} // expected-note@-2{{because 'sizeof(decltype(x)) == 1' (4 == 1) evaluated to false}} auto l1t1 = l1('a'); @@ -9,8 +9,8 @@ auto l1t2 = l1(1); // expected-error@-1{{no matching function for call to object of type '(lambda at}} auto l2 = [] (auto... x) requires ((sizeof(decltype(x)) >= 2) && ...) { return (x + ...); }; -// expected-note@-1{{candidate template ignored: constraints not satisfied [with x:auto = ]}} -// expected-note@-2{{candidate template ignored: constraints not satisfied [with x:auto = ]}} +// expected-note@-1{{candidate template ignored: constraints not satisfied [with $0 = ]}} +// expected-note@-2{{candidate template ignored: constraints not satisfied [with $0 = ]}} // expected-note@-3 2{{because 'sizeof(decltype(x)) >= 2' (1 >= 2) evaluated to false}} auto l2t1 = l2('a'); diff --git a/clang/test/CXX/temp/temp.param/p10-2a.cpp b/clang/test/CXX/temp/temp.param/p10-2a.cpp index 3d2be1a92be1..de40f8cca5d5 100644 --- a/clang/test/CXX/temp/temp.param/p10-2a.cpp +++ b/clang/test/CXX/temp/temp.param/p10-2a.cpp @@ -94,8 +94,6 @@ concept OneOf = (is_same_v || ...); // expected-note@-5 {{and 'is_same_v' evaluated to false}} // expected-note@-6 3{{because 'is_same_v' evaluated to false}} // expected-note@-7 3{{and 'is_same_v' evaluated to false}} -// expected-note@-8 2{{because 'is_same_v' evaluated to false}} -// expected-note@-9 2{{and 'is_same_v' evaluated to false}} template T, OneOf U> // expected-note@-1 2{{because 'OneOf' evaluated to false}} @@ -116,25 +114,4 @@ using h1 = H; // expected-error@-1 {{constraints not satisfied for alias template 'H' [with Ts = ]}} using h2 = H; // expected-error@-1 {{constraints not satisfied for alias template 'H' [with Ts = ]}} -using h3 = H; - -template auto x> -// expected-note@-1 {{because 'OneOf' evaluated to false}} -using I = int; - -using i1 = I<1>; -using i2 = I<'a'>; -using i3 = I; -// expected-error@-1 {{constraints not satisfied for alias template 'I' [with x = nullptr]}} - -template auto... x> -// expected-note@-1 {{because 'OneOf' evaluated to false}} -using J = int; - -using j1 = J<1, 'b'>; -using j2 = J<'a', nullptr>; -// expected-error@-1 {{constraints not satisfied for alias template 'J' [with x = <'a', nullptr>]}} - -template auto &x> -// expected-error@-1 {{constrained placeholder types other than simple 'auto' on non-type template parameters not supported yet}} -using K = int; +using h3 = H; \ No newline at end of file diff --git a/clang/test/Parser/cxx2a-placeholder-type-constraint.cpp b/clang/test/Parser/cxx2a-placeholder-type-constraint.cpp deleted file mode 100644 index a1bd08827b93..000000000000 --- a/clang/test/Parser/cxx2a-placeholder-type-constraint.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify - -template -concept C = true; - -int foo() { - C auto a4 = 1; - C<> auto a5 = 1; - C auto a6 = 1; - const C auto &a7 = 1; - const C<> auto &a8 = 1; - const C auto &a9 = 1; - C decltype(auto) a10 = 1; - C<> decltype(auto) a11 = 1; - C decltype(auto) a12 = 1; - const C<> decltype(auto) &a13 = 1; // expected-error{{'decltype(auto)' cannot be combined with other type specifiers}} - // expected-error@-1{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}} - const C decltype(auto) &a14 = 1; // expected-error{{'decltype(auto)' cannot be combined with other type specifiers}} - // expected-error@-1{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}} - C a15 = 1; - // expected-error@-1{{expected 'auto' or 'decltype(auto)' after concept name}} - C decltype a19 = 1; - // expected-error@-1{{expected '('}} - C decltype(1) a20 = 1; - // expected-error@-1{{expected 'auto' or 'decltype(auto)' after concept name}} -} \ No newline at end of file diff --git a/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp b/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp index 13ab7aae6c32..087982327c72 100644 --- a/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp +++ b/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp @@ -181,7 +181,7 @@ int test() { int (*fp2)(int) = [](auto b) -> int { return b; }; int (*fp3)(char) = [](auto c) -> int { return c; }; char (*fp4)(int) = [](auto d) { return d; }; //expected-error{{no viable conversion}}\ - //expected-note{{candidate function [with d:auto = int]}} + //expected-note{{candidate function [with $0 = int]}} char (*fp5)(char) = [](auto e) -> int { return e; }; //expected-error{{no viable conversion}}\ //expected-note{{candidate template ignored}} diff --git a/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp b/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp index b2350c900e63..276464875342 100644 --- a/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp +++ b/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp @@ -93,8 +93,7 @@ namespace test_undeclared_nontype_parm_arg { // template parameter. template struct Bar { T x; }; -template *P> // expected-error {{use of undeclared identifier 'Xylophone'}} -// expected-note@-1{{template parameter is declared here}} +template *P> // expected-error {{use of undeclared identifier 'Xylophone'}} expected-note {{declared here}} struct Foo { }; typedef int Xylophone;