Hi Richard, I've filed this issue as PR31783. Douglas Yung
> -----Original Message----- > From: cfe-commits [mailto:cfe-commits-boun...@lists.llvm.org] On Behalf > Of Yung, Douglas via cfe-commits > Sent: Thursday, January 26, 2017 15:36 > To: Richard Smith > Cc: cfe-commits@lists.llvm.org > Subject: RE: r293207 - PR0091R3: Implement parsing support for using > templates as types. > > Hi Richard, > > I don't know if you have noticed, but the test you added in this commit > is failing on both the Linux and Windows PS4 bots. The test is failing > with an assertion failure: > > Assertion failed: !A->getDeducedType().isNull() && "cannot request the > size of an undeduced or dependent auto type", file > C:\Buildbot\Slave\llvm-clang-lld-x86_64-scei-ps4-windows10pro- > fast\llvm.src\tools\clang\lib\AST\ASTContext.cpp, line 1884 > > Can you take a look? > > Windows PS4 bot failure: http://lab.llvm.org:8011/builders/llvm-clang- > lld-x86_64-scei-ps4-windows10pro-fast/builds/4531 > Linux PS4 bot failure: http://lab.llvm.org:8011/builders/llvm-clang- > lld-x86_64-scei-ps4-ubuntu-fast/builds/5093 > > Douglas Yung > > > -----Original Message----- > > From: cfe-commits [mailto:cfe-commits-boun...@lists.llvm.org] On > Behalf > > Of Richard Smith via cfe-commits > > Sent: Thursday, January 26, 2017 12:41 > > To: cfe-commits@lists.llvm.org > > Subject: r293207 - PR0091R3: Implement parsing support for using > > templates as types. > > > > Author: rsmith > > Date: Thu Jan 26 14:40:47 2017 > > New Revision: 293207 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=293207&view=rev > > Log: > > PR0091R3: Implement parsing support for using templates as types. > > > > This change adds a new type node, DeducedTemplateSpecializationType, > to > > represent a type template name that has been used as a type. This is > > modeled > > around AutoType, and shares a common base class for representing a > > deduced > > placeholder type. > > > > We allow deduced class template types in a few more places than the > > standard > > does: in conditions and for-range-declarators, and in new-type-ids. > > This is > > consistent with GCC and with discussion on the core reflector. This > > patch > > does not yet support deduced class template types being named in > > typename > > specifiers. > > > > Added: > > cfe/trunk/test/Parser/cxx1z-class-template-argument-deduction.cpp > > Modified: > > cfe/trunk/include/clang/AST/ASTContext.h > > cfe/trunk/include/clang/AST/RecursiveASTVisitor.h > > cfe/trunk/include/clang/AST/Type.h > > cfe/trunk/include/clang/AST/TypeLoc.h > > cfe/trunk/include/clang/AST/TypeNodes.def > > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > > cfe/trunk/include/clang/Parse/Parser.h > > cfe/trunk/include/clang/Sema/DeclSpec.h > > cfe/trunk/include/clang/Sema/Sema.h > > cfe/trunk/include/clang/Serialization/ASTBitCodes.h > > cfe/trunk/lib/AST/ASTContext.cpp > > cfe/trunk/lib/AST/ASTImporter.cpp > > cfe/trunk/lib/AST/ExprConstant.cpp > > cfe/trunk/lib/AST/ItaniumMangle.cpp > > cfe/trunk/lib/AST/MicrosoftMangle.cpp > > cfe/trunk/lib/AST/Type.cpp > > cfe/trunk/lib/AST/TypePrinter.cpp > > cfe/trunk/lib/CodeGen/CGDebugInfo.cpp > > cfe/trunk/lib/CodeGen/CodeGenFunction.cpp > > cfe/trunk/lib/CodeGen/CodeGenTypes.cpp > > cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp > > cfe/trunk/lib/Parse/ParseDecl.cpp > > cfe/trunk/lib/Parse/ParseDeclCXX.cpp > > cfe/trunk/lib/Parse/ParseExprCXX.cpp > > cfe/trunk/lib/Parse/Parser.cpp > > cfe/trunk/lib/Sema/SemaDecl.cpp > > cfe/trunk/lib/Sema/SemaExpr.cpp > > cfe/trunk/lib/Sema/SemaExprCXX.cpp > > cfe/trunk/lib/Sema/SemaLookup.cpp > > cfe/trunk/lib/Sema/SemaTemplate.cpp > > cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp > > cfe/trunk/lib/Sema/SemaType.cpp > > cfe/trunk/lib/Sema/TreeTransform.h > > cfe/trunk/lib/Serialization/ASTReader.cpp > > cfe/trunk/lib/Serialization/ASTWriter.cpp > > cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp > > cfe/trunk/test/CXX/drs/dr5xx.cpp > > cfe/trunk/test/Parser/backtrack-off-by-one.cpp > > cfe/trunk/test/SemaTemplate/temp_arg.cpp > > cfe/trunk/test/SemaTemplate/typename-specifier-3.cpp > > cfe/trunk/tools/libclang/CIndex.cpp > > cfe/trunk/tools/libclang/CXType.cpp > > > > Modified: cfe/trunk/include/clang/AST/ASTContext.h > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/include/clang/AST/ASTContext.h?rev=293207&r1=293206&r > > 2=293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/include/clang/AST/ASTContext.h (original) > > +++ cfe/trunk/include/clang/AST/ASTContext.h Thu Jan 26 14:40:47 2017 > > @@ -167,6 +167,8 @@ class ASTContext : public RefCountedBase > > mutable llvm::FoldingSet<DependentUnaryTransformType> > > DependentUnaryTransformTypes; > > mutable llvm::FoldingSet<AutoType> AutoTypes; > > + mutable llvm::FoldingSet<DeducedTemplateSpecializationType> > > + DeducedTemplateSpecializationTypes; > > mutable llvm::FoldingSet<AtomicType> AtomicTypes; > > llvm::FoldingSet<AttributedType> AttributedTypes; > > mutable llvm::FoldingSet<PipeType> PipeTypes; > > @@ -1412,6 +1414,11 @@ public: > > /// \brief C++11 deduction pattern for 'auto &&' type. > > QualType getAutoRRefDeductType() const; > > > > + /// \brief C++1z deduced class template specialization type. > > + QualType getDeducedTemplateSpecializationType(TemplateName > Template, > > + QualType > DeducedType, > > + bool IsDependent) > > const; > > + > > /// \brief Return the unique reference to the type for the > specified > > TagDecl > > /// (struct/union/class/enum) decl. > > QualType getTagDeclType(const TagDecl *Decl) const; > > > > Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=293207&r1 > > =293206&r2=293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original) > > +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Thu Jan 26 > > 14:40:47 2017 > > @@ -1008,6 +1008,10 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, { > > }) > > > > DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T- > > >getDeducedType())); }) > > +DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, { > > + TRY_TO(TraverseTemplateName(T->getTemplateName())); > > + TRY_TO(TraverseType(T->getDeducedType())); > > +}) > > > > DEF_TRAVERSE_TYPE(RecordType, {}) > > DEF_TRAVERSE_TYPE(EnumType, {}) > > @@ -1232,6 +1236,11 @@ DEF_TRAVERSE_TYPELOC(AutoType, { > > TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType())); > > }) > > > > +DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, { > > + TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName())); > > + TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType())); > > +}) > > + > > DEF_TRAVERSE_TYPELOC(RecordType, {}) > > DEF_TRAVERSE_TYPELOC(EnumType, {}) > > DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {}) > > > > Modified: cfe/trunk/include/clang/AST/Type.h > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/include/clang/AST/Type.h?rev=293207&r1=293206&r2=2932 > > 07&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/include/clang/AST/Type.h (original) > > +++ cfe/trunk/include/clang/AST/Type.h Thu Jan 26 14:40:47 2017 > > @@ -1785,7 +1785,8 @@ public: > > } > > > > /// \brief Determine whether this type is an undeduced type, > meaning > > that > > - /// it somehow involves a C++11 'auto' type which has not yet been > > deduced. > > + /// it somehow involves a C++11 'auto' type or similar which has > not > > yet been > > + /// deduced. > > bool isUndeducedType() const; > > > > /// \brief Whether this type is a variably-modified type (C99 > > 6.7.5). > > @@ -1862,10 +1863,17 @@ public: > > /// not refer to a CXXRecordDecl, returns NULL. > > const CXXRecordDecl *getPointeeCXXRecordDecl() const; > > > > + /// Get the DeducedType 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. > > + DeducedType *getContainedDeducedType() const; > > + > > /// Get the 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. > > - AutoType *getContainedAutoType() const; > > + AutoType *getContainedAutoType() const { > > + return dyn_cast_or_null<AutoType>(getContainedDeducedType()); > > + } > > > > /// Determine whether this type was written with a leading 'auto' > > /// corresponding to a trailing return type (possibly for a nested > > @@ -4094,43 +4102,38 @@ public: > > } > > }; > > > > -/// \brief Represents a C++11 auto or C++14 decltype(auto) type. > > +/// \brief 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 (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 > > -/// type-dependent, there is no deduced type and an auto type is > > canonical. In > > +/// type-dependent, there is no deduced type and the type is > > canonical. In > > /// the latter case, it is also a dependent type. > > -class AutoType : public Type, public llvm::FoldingSetNode { > > - AutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool > > IsDependent) > > - : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : > > DeducedType, > > - /*Dependent=*/IsDependent, > > /*InstantiationDependent=*/IsDependent, > > - /*VariablyModified=*/false, > > /*ContainsParameterPack=*/false) { > > - if (!DeducedType.isNull()) { > > - if (DeducedType->isDependentType()) > > +class DeducedType : public Type { > > +protected: > > + DeducedType(TypeClass TC, QualType DeducedAsType, bool > IsDependent, > > + bool IsInstantiationDependent, bool > > ContainsParameterPack) > > + : Type(TC, DeducedAsType.isNull() ? QualType(this, 0) : > > DeducedAsType, > > + IsDependent, IsInstantiationDependent, > > + /*VariablyModified=*/false, ContainsParameterPack) { > > + if (!DeducedAsType.isNull()) { > > + if (DeducedAsType->isDependentType()) > > setDependent(); > > - if (DeducedType->isInstantiationDependentType()) > > + if (DeducedAsType->isInstantiationDependentType()) > > setInstantiationDependent(); > > - if (DeducedType->containsUnexpandedParameterPack()) > > + if (DeducedAsType->containsUnexpandedParameterPack()) > > setContainsUnexpandedParameterPack(); > > } > > - AutoTypeBits.Keyword = (unsigned)Keyword; > > } > > > > - friend class ASTContext; // ASTContext creates these > > - > > public: > > - bool isDecltypeAuto() const { > > - return getKeyword() == AutoTypeKeyword::DecltypeAuto; > > - } > > - AutoTypeKeyword getKeyword() const { > > - return (AutoTypeKeyword)AutoTypeBits.Keyword; > > - } > > - > > bool isSugared() const { return !isCanonicalUnqualified(); } > > QualType desugar() const { return getCanonicalTypeInternal(); } > > > > - /// \brief Get the type deduced for this auto type, or null if > it's > > either > > - /// not been deduced or was deduced to a dependent type. > > + /// \brief Get the type deduced for this placeholder type, or null > > if it's > > + /// either not been deduced or was deduced to a dependent type. > > QualType getDeducedType() const { > > return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : > > QualType(); > > } > > @@ -4138,6 +4141,31 @@ public: > > return !isCanonicalUnqualified() || isDependentType(); > > } > > > > + static bool classof(const Type *T) { > > + return T->getTypeClass() == Auto || > > + T->getTypeClass() == DeducedTemplateSpecialization; > > + } > > +}; > > + > > +/// \brief Represents a C++11 auto or C++14 decltype(auto) type. > > +class AutoType : public DeducedType, public llvm::FoldingSetNode { > > + AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, > > + bool IsDeducedAsDependent) > > + : DeducedType(Auto, DeducedAsType, IsDeducedAsDependent, > > + IsDeducedAsDependent, /*ContainsPack=*/false) { > > + AutoTypeBits.Keyword = (unsigned)Keyword; > > + } > > + > > + friend class ASTContext; // ASTContext creates these > > + > > +public: > > + bool isDecltypeAuto() const { > > + return getKeyword() == AutoTypeKeyword::DecltypeAuto; > > + } > > + AutoTypeKeyword getKeyword() const { > > + return (AutoTypeKeyword)AutoTypeBits.Keyword; > > + } > > + > > void Profile(llvm::FoldingSetNodeID &ID) { > > Profile(ID, getDeducedType(), getKeyword(), isDependentType()); > > } > > @@ -4154,6 +4182,43 @@ public: > > } > > }; > > > > +/// \brief Represents a C++17 deduced template specialization type. > > +class DeducedTemplateSpecializationType : public DeducedType, > > + public > llvm::FoldingSetNode > > { > > + /// The name of the template whose arguments will be deduced. > > + TemplateName Template; > > + > > + DeducedTemplateSpecializationType(TemplateName Template, > > + QualType DeducedAsType, > > + bool IsDeducedAsDependent) > > + : DeducedType(DeducedTemplateSpecialization, DeducedAsType, > > + IsDeducedAsDependent || Template.isDependent(), > > + IsDeducedAsDependent || > > Template.isInstantiationDependent(), > > + Template.containsUnexpandedParameterPack()), > > + Template(Template) {} > > + > > + friend class ASTContext; // ASTContext creates these > > + > > +public: > > + /// Retrieve the name of the template that we are deducing. > > + TemplateName getTemplateName() const { return Template;} > > + > > + void Profile(llvm::FoldingSetNodeID &ID) { > > + Profile(ID, getTemplateName(), getDeducedType(), > > isDependentType()); > > + } > > + > > + static void Profile(llvm::FoldingSetNodeID &ID, TemplateName > > Template, > > + QualType Deduced, bool IsDependent) { > > + Template.Profile(ID); > > + ID.AddPointer(Deduced.getAsOpaquePtr()); > > + ID.AddBoolean(IsDependent); > > + } > > + > > + static bool classof(const Type *T) { > > + return T->getTypeClass() == DeducedTemplateSpecialization; > > + } > > +}; > > + > > /// \brief Represents a type template specialization; the template > > /// must be a class template, a type alias template, or a template > > /// template parameter. A template which cannot be resolved to one > of > > @@ -5857,8 +5922,8 @@ inline bool Type::isBooleanType() const > > } > > > > inline bool Type::isUndeducedType() const { > > - const AutoType *AT = getContainedAutoType(); > > - return AT && !AT->isDeduced(); > > + auto *DT = getContainedDeducedType(); > > + return DT && !DT->isDeduced(); > > } > > > > /// \brief Determines whether this is a type for which one can > define > > > > Modified: cfe/trunk/include/clang/AST/TypeLoc.h > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=293207&r1=293206&r2=2 > > 93207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/include/clang/AST/TypeLoc.h (original) > > +++ cfe/trunk/include/clang/AST/TypeLoc.h Thu Jan 26 14:40:47 2017 > > @@ -1827,9 +1827,25 @@ public: > > } > > }; > > > > -class AutoTypeLoc : public > InheritingConcreteTypeLoc<TypeSpecTypeLoc, > > - AutoTypeLoc, > > - AutoType> { > > +class DeducedTypeLoc > > + : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, > > DeducedTypeLoc, > > + DeducedType> {}; > > + > > +class AutoTypeLoc > > + : public InheritingConcreteTypeLoc<DeducedTypeLoc, AutoTypeLoc, > > AutoType> { > > +}; > > + > > +class DeducedTemplateSpecializationTypeLoc > > + : public InheritingConcreteTypeLoc<DeducedTypeLoc, > > + > > DeducedTemplateSpecializationTypeLoc, > > + > > DeducedTemplateSpecializationType> { > > +public: > > + SourceLocation getTemplateNameLoc() const { > > + return getNameLoc(); > > + } > > + void setTemplateNameLoc(SourceLocation Loc) { > > + setNameLoc(Loc); > > + } > > }; > > > > struct ElaboratedLocInfo { > > > > Modified: cfe/trunk/include/clang/AST/TypeNodes.def > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=293207&r1=293206& > > r2=293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/include/clang/AST/TypeNodes.def (original) > > +++ cfe/trunk/include/clang/AST/TypeNodes.def Thu Jan 26 14:40:47 > 2017 > > @@ -96,7 +96,9 @@ DEPENDENT_TYPE(TemplateTypeParm, Type) > > NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type) > > DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type) > > NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type) > > -TYPE(Auto, Type) > > +ABSTRACT_TYPE(Deduced, Type) > > +TYPE(Auto, DeducedType) > > +TYPE(DeducedTemplateSpecialization, DeducedType) > > DEPENDENT_TYPE(InjectedClassName, Type) > > DEPENDENT_TYPE(DependentName, Type) > > DEPENDENT_TYPE(DependentTemplateSpecialization, Type) > > > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=293207 > > &r1=293206&r2=293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jan 26 > > 14:40:47 2017 > > @@ -1870,16 +1870,20 @@ def err_illegal_decl_array_of_auto : Err > > def err_new_array_of_auto : Error< > > "cannot allocate array of 'auto'">; > > def err_auto_not_allowed : Error< > > - "%select{'auto'|'decltype(auto)'|'__auto_type'}0 not allowed " > > + "%select{'auto'|'decltype(auto)'|'__auto_type'|" > > + "use of " > > + "%select{class template|function template|variable template|alias > > template|" > > + "template template parameter|template}2 %3 requires template > > arguments; " > > + "argument deduction}0 not allowed " > > "%select{in function prototype" > > "|in non-static struct member|in struct member" > > "|in non-static union member|in union member" > > "|in non-static class member|in interface member" > > - "|in exception declaration|in template parameter|in block literal" > > + "|in exception declaration|in template parameter until C++1z|in > > block literal" > > "|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}1" > > - "%select{|||||||| until C++1z||||||||||}1">; > > + "|in type allocated by 'new'|in K&R-style function parameter" > > + "|in template parameter|in friend declaration}1">; > > def err_auto_not_allowed_var_inst : Error< > > "'auto' variable template instantiation is not allowed">; > > def err_auto_var_requires_init : Error< > > @@ -1944,6 +1948,14 @@ def err_decltype_auto_compound_type : Er > > def err_decltype_auto_initializer_list : Error< > > "cannot deduce 'decltype(auto)' from initializer list">; > > > > +// C++1z deduced class template specialization types > > +def err_deduced_class_template_compound_type : Error< > > + "cannot %select{form pointer to|form reference to|form array of|" > > + "form function returning|use parentheses when declaring variable > > with}0 " > > + "deduced class template specialization type">; > > +def err_deduced_class_template_not_supported : Error< > > + "deduction of template arguments for class templates is not yet > > supported">; > > + > > // C++1y deduced return types > > def err_auto_fn_deduction_failure : Error< > > "cannot deduce return type %0 from returned value of type %1">; > > > > Modified: cfe/trunk/include/clang/Parse/Parser.h > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/include/clang/Parse/Parser.h?rev=293207&r1=293206&r2= > > 293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/include/clang/Parse/Parser.h (original) > > +++ cfe/trunk/include/clang/Parse/Parser.h Thu Jan 26 14:40:47 2017 > > @@ -1834,6 +1834,26 @@ private: > > llvm_unreachable("Missing DeclSpecContext case"); > > } > > > > + /// Is this a context in which we can perform class template > > argument > > + /// deduction? > > + static bool isClassTemplateDeductionContext(DeclSpecContext DSC) { > > + switch (DSC) { > > + case DSC_normal: > > + case DSC_class: > > + case DSC_top_level: > > + case DSC_condition: > > + case DSC_type_specifier: > > + return true; > > + > > + case DSC_objc_method_result: > > + case DSC_template_type_arg: > > + case DSC_trailing: > > + case DSC_alias_declaration: > > + return false; > > + } > > + llvm_unreachable("Missing DeclSpecContext case"); > > + } > > + > > /// Information on a C++0x for-range-initializer found while > parsing > > a > > /// declaration which turns out to be a for-range-declaration. > > struct ForRangeInit { > > > > Modified: cfe/trunk/include/clang/Sema/DeclSpec.h > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=293207&r1=293206&r2 > > =293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/include/clang/Sema/DeclSpec.h (original) > > +++ cfe/trunk/include/clang/Sema/DeclSpec.h Thu Jan 26 14:40:47 2017 > > @@ -1709,6 +1709,7 @@ public: > > ObjCParameterContext,// An ObjC method parameter type. > > KNRTypeListContext, // K&R type definition list for formals. > > TypeNameContext, // Abstract declarator for types. > > + FunctionalCastContext, // Type in a C++ functional cast > > expression. > > MemberContext, // Struct/Union field. > > BlockContext, // Declaration within a block in a > function. > > ForContext, // Declaration within first part of a for > > loop. > > @@ -1911,6 +1912,7 @@ public: > > return false; > > > > case TypeNameContext: > > + case FunctionalCastContext: > > case AliasDeclContext: > > case AliasTemplateContext: > > case PrototypeContext: > > @@ -1951,6 +1953,7 @@ public: > > return true; > > > > case TypeNameContext: > > + case FunctionalCastContext: > > case CXXNewContext: > > case AliasDeclContext: > > case AliasTemplateContext: > > @@ -1983,6 +1986,7 @@ public: > > case CXXCatchContext: > > case ObjCCatchContext: > > case TypeNameContext: > > + case FunctionalCastContext: > > case ConversionIdContext: > > case ObjCParameterContext: > > case ObjCResultContext: > > @@ -2021,6 +2025,7 @@ public: > > // These contexts don't allow any kind of non-abstract > declarator. > > case KNRTypeListContext: > > case TypeNameContext: > > + case FunctionalCastContext: > > case AliasDeclContext: > > case AliasTemplateContext: > > case LambdaExprParameterContext: > > @@ -2078,6 +2083,7 @@ public: > > case CXXCatchContext: > > case ObjCCatchContext: > > case TypeNameContext: > > + case FunctionalCastContext: // FIXME > > case CXXNewContext: > > case AliasDeclContext: > > case AliasTemplateContext: > > @@ -2279,6 +2285,7 @@ public: > > case ConditionContext: > > case KNRTypeListContext: > > case TypeNameContext: > > + case FunctionalCastContext: > > case AliasDeclContext: > > case AliasTemplateContext: > > case PrototypeContext: > > > > Modified: cfe/trunk/include/clang/Sema/Sema.h > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/include/clang/Sema/Sema.h?rev=293207&r1=293206&r2=293 > > 207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/include/clang/Sema/Sema.h (original) > > +++ cfe/trunk/include/clang/Sema/Sema.h Thu Jan 26 14:40:47 2017 > > @@ -1548,6 +1548,7 @@ public: > > ParsedType ObjectType = nullptr, > > bool IsCtorOrDtorName = false, > > bool WantNontrivialTypeSourceInfo = false, > > + bool IsClassTemplateDeductionContext = > true, > > IdentifierInfo **CorrectedII = nullptr); > > TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S); > > bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S); > > > > Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=293207& > > r1=293206&r2=293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original) > > +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Thu Jan 26 > > 14:40:47 2017 > > @@ -914,7 +914,9 @@ namespace clang { > > /// \brief A PipeType record. > > TYPE_PIPE = 43, > > /// \brief An ObjCTypeParamType record. > > - TYPE_OBJC_TYPE_PARAM = 44 > > + TYPE_OBJC_TYPE_PARAM = 44, > > + /// \brief A DeducedTemplateSpecializationType record. > > + TYPE_DEDUCED_TEMPLATE_SPECIALIZATION = 45 > > }; > > > > /// \brief The type IDs for special types constructed by > semantic > > > > Modified: cfe/trunk/lib/AST/ASTContext.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/AST/ASTContext.cpp?rev=293207&r1=293206&r2=293207 > > &view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/AST/ASTContext.cpp (original) > > +++ cfe/trunk/lib/AST/ASTContext.cpp Thu Jan 26 14:40:47 2017 > > @@ -1877,8 +1877,9 @@ TypeInfo ASTContext::getTypeInfoImpl(con > > return getTypeInfo(cast<SubstTemplateTypeParmType>(T)-> > > getReplacementType().getTypePtr()); > > > > - case Type::Auto: { > > - const AutoType *A = cast<AutoType>(T); > > + case Type::Auto: > > + case Type::DeducedTemplateSpecialization: { > > + const DeducedType *A = cast<DeducedType>(T); > > assert(!A->getDeducedType().isNull() && > > "cannot request the size of an undeduced or dependent > auto > > type"); > > return getTypeInfo(A->getDeducedType().getTypePtr()); > > @@ -2765,6 +2766,7 @@ QualType ASTContext::getVariableArrayDec > > case Type::TemplateTypeParm: > > case Type::SubstTemplateTypeParmPack: > > case Type::Auto: > > + case Type::DeducedTemplateSpecialization: > > case Type::PackExpansion: > > llvm_unreachable("type should never be variably-modified"); > > > > @@ -4435,6 +4437,28 @@ QualType ASTContext::getAutoType(QualTyp > > return QualType(AT, 0); > > } > > > > +/// Return the uniqued reference to the deduced template > > specialization type > > +/// which has been deduced to the given type, or to the canonical > > undeduced > > +/// such type, or the canonical deduced-but-dependent such type. > > +QualType ASTContext::getDeducedTemplateSpecializationType( > > + TemplateName Template, QualType DeducedType, bool IsDependent) > > const { > > + // Look in the folding set for an existing type. > > + void *InsertPos = nullptr; > > + llvm::FoldingSetNodeID ID; > > + DeducedTemplateSpecializationType::Profile(ID, Template, > > DeducedType, > > + IsDependent); > > + if (DeducedTemplateSpecializationType *DTST = > > + DeducedTemplateSpecializationTypes.FindNodeOrInsertPos(ID, > > InsertPos)) > > + return QualType(DTST, 0); > > + > > + DeducedTemplateSpecializationType *DTST = new (*this, > TypeAlignment) > > + DeducedTemplateSpecializationType(Template, DeducedType, > > IsDependent); > > + Types.push_back(DTST); > > + if (InsertPos) > > + DeducedTemplateSpecializationTypes.InsertNode(DTST, InsertPos); > > + return QualType(DTST, 0); > > +} > > + > > /// getAtomicType - Return the uniqued reference to the atomic type > > for > > /// the given value type. > > QualType ASTContext::getAtomicType(QualType T) const { > > @@ -6333,6 +6357,7 @@ void ASTContext::getObjCEncodingForTypeI > > // We could see an undeduced auto type here during error recovery. > > // Just ignore it. > > case Type::Auto: > > + case Type::DeducedTemplateSpecialization: > > return; > > > > case Type::Pipe: > > @@ -8132,6 +8157,7 @@ QualType ASTContext::mergeTypes(QualType > > llvm_unreachable("Non-canonical and dependent types shouldn't > get > > here"); > > > > case Type::Auto: > > + case Type::DeducedTemplateSpecialization: > > case Type::LValueReference: > > case Type::RValueReference: > > case Type::MemberPointer: > > > > Modified: cfe/trunk/lib/AST/ASTImporter.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=293207&r1=293206&r2=29320 > > 7&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/AST/ASTImporter.cpp (original) > > +++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Jan 26 14:40:47 2017 > > @@ -883,6 +883,20 @@ static bool IsStructurallyEquivalent(Str > > return false; > > break; > > > > + case Type::DeducedTemplateSpecialization: { > > + auto *DT1 = cast<DeducedTemplateSpecializationType>(T1); > > + auto *DT2 = cast<DeducedTemplateSpecializationType>(T2); > > + if (!IsStructurallyEquivalent(Context, > > + DT1->getTemplateName(), > > + DT2->getTemplateName())) > > + return false; > > + if (!IsStructurallyEquivalent(Context, > > + DT1->getDeducedType(), > > + DT2->getDeducedType())) > > + return false; > > + break; > > + } > > + > > case Type::Record: > > case Type::Enum: > > if (!IsStructurallyEquivalent(Context, > > > > Modified: cfe/trunk/lib/AST/ExprConstant.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=293207&r1=293206&r2=2932 > > 07&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/AST/ExprConstant.cpp (original) > > +++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Jan 26 14:40:47 2017 > > @@ -7004,6 +7004,7 @@ static int EvaluateBuiltinClassifyType(c > > case Type::Vector: > > case Type::ExtVector: > > case Type::Auto: > > + case Type::DeducedTemplateSpecialization: > > case Type::ObjCObject: > > case Type::ObjCInterface: > > case Type::ObjCObjectPointer: > > > > Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=293207&r1=293206&r2=293 > > 207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original) > > +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Thu Jan 26 14:40:47 2017 > > @@ -1870,6 +1870,7 @@ bool CXXNameMangler::mangleUnresolvedTyp > > case Type::Paren: > > case Type::Attributed: > > case Type::Auto: > > + case Type::DeducedTemplateSpecialization: > > case Type::PackExpansion: > > case Type::ObjCObject: > > case Type::ObjCInterface: > > @@ -3145,6 +3146,16 @@ void CXXNameMangler::mangleType(const Au > > mangleType(D); > > } > > > > +void CXXNameMangler::mangleType(const > > DeducedTemplateSpecializationType *T) { > > + // FIXME: This is not the right mangling. We also need to include > a > > scope > > + // here in some cases. > > + QualType D = T->getDeducedType(); > > + if (D.isNull()) > > + mangleUnscopedTemplateName(T->getTemplateName(), nullptr); > > + else > > + mangleType(D); > > +} > > + > > void CXXNameMangler::mangleType(const AtomicType *T) { > > // <type> ::= U <source-name> <type> # vendor extended type > > qualifier > > // (Until there's a standardized mangling...) > > > > Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=293207&r1=293206&r2=2 > > 93207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original) > > +++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Thu Jan 26 14:40:47 2017 > > @@ -2474,6 +2474,17 @@ void MicrosoftCXXNameMangler::mangleType > > << Range; > > } > > > > +void MicrosoftCXXNameMangler::mangleType( > > + const DeducedTemplateSpecializationType *T, Qualifiers, > > SourceRange Range) { > > + assert(T->getDeducedType().isNull() && "expecting a dependent > > type!"); > > + > > + DiagnosticsEngine &Diags = Context.getDiags(); > > + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, > > + "cannot mangle this deduced class template specialization type > > yet"); > > + Diags.Report(Range.getBegin(), DiagID) > > + << Range; > > +} > > + > > void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, > > Qualifiers, > > SourceRange Range) { > > QualType ValueType = T->getValueType(); > > > > Modified: cfe/trunk/lib/AST/Type.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/AST/Type.cpp?rev=293207&r1=293206&r2=293207&view= > > diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/AST/Type.cpp (original) > > +++ cfe/trunk/lib/AST/Type.cpp Thu Jan 26 14:40:47 2017 > > @@ -1559,25 +1559,29 @@ TagDecl *Type::getAsTagDecl() const { > > } > > > > namespace { > > - class GetContainedAutoVisitor : > > - public TypeVisitor<GetContainedAutoVisitor, Type*> { > > + class GetContainedDeducedTypeVisitor : > > + public TypeVisitor<GetContainedDeducedTypeVisitor, Type*> { > > bool Syntactic; > > public: > > - GetContainedAutoVisitor(bool Syntactic = false) : > > Syntactic(Syntactic) {} > > + GetContainedDeducedTypeVisitor(bool Syntactic = false) > > + : Syntactic(Syntactic) {} > > > > - using TypeVisitor<GetContainedAutoVisitor, Type*>::Visit; > > + using TypeVisitor<GetContainedDeducedTypeVisitor, Type*>::Visit; > > Type *Visit(QualType T) { > > if (T.isNull()) > > return nullptr; > > return Visit(T.getTypePtr()); > > } > > > > - // The 'auto' type itself. > > - Type *VisitAutoType(const AutoType *AT) { > > - return const_cast<AutoType*>(AT); > > + // The deduced type itself. > > + Type *VisitDeducedType(const DeducedType *AT) { > > + return const_cast<DeducedType*>(AT); > > } > > > > // Only these types can contain the desired 'auto' type. > > + Type *VisitElaboratedType(const ElaboratedType *T) { > > + return Visit(T->getNamedType()); > > + } > > Type *VisitPointerType(const PointerType *T) { > > return Visit(T->getPointeeType()); > > } > > @@ -1620,13 +1624,14 @@ namespace { > > }; > > } > > > > -AutoType *Type::getContainedAutoType() const { > > - return > > cast_or_null<AutoType>(GetContainedAutoVisitor().Visit(this)); > > +DeducedType *Type::getContainedDeducedType() const { > > + return cast_or_null<DeducedType>( > > + GetContainedDeducedTypeVisitor().Visit(this)); > > } > > > > bool Type::hasAutoForTrailingReturnType() const { > > return dyn_cast_or_null<FunctionType>( > > - GetContainedAutoVisitor(true).Visit(this)); > > + GetContainedDeducedTypeVisitor(true).Visit(this)); > > } > > > > bool Type::hasIntegerRepresentation() const { > > @@ -3378,6 +3383,7 @@ static CachedProperties computeCachedPro > > return CachedProperties(ExternalLinkage, false); > > > > case Type::Auto: > > + case Type::DeducedTemplateSpecialization: > > // Give non-deduced 'auto' types external linkage. We should > only > > see them > > // here in error recovery. > > return CachedProperties(ExternalLinkage, false); > > @@ -3485,6 +3491,7 @@ static LinkageInfo computeLinkageInfo(co > > return LinkageInfo::external(); > > > > case Type::Auto: > > + case Type::DeducedTemplateSpecialization: > > return LinkageInfo::external(); > > > > case Type::Record: > > @@ -3621,7 +3628,8 @@ bool Type::canHaveNullability() const { > > > > // auto is considered dependent when it isn't deduced. > > case Type::Auto: > > - return !cast<AutoType>(type.getTypePtr())->isDeduced(); > > + case Type::DeducedTemplateSpecialization: > > + return !cast<DeducedType>(type.getTypePtr())->isDeduced(); > > > > case Type::Builtin: > > switch (cast<BuiltinType>(type.getTypePtr())->getKind()) { > > > > Modified: cfe/trunk/lib/AST/TypePrinter.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=293207&r1=293206&r2=29320 > > 7&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/AST/TypePrinter.cpp (original) > > +++ cfe/trunk/lib/AST/TypePrinter.cpp Thu Jan 26 14:40:47 2017 > > @@ -189,6 +189,7 @@ bool TypePrinter::canPrefixQualifiers(co > > case Type::Elaborated: > > case Type::TemplateTypeParm: > > case Type::SubstTemplateTypeParmPack: > > + case Type::DeducedTemplateSpecialization: > > case Type::TemplateSpecialization: > > case Type::InjectedClassName: > > case Type::DependentName: > > @@ -887,6 +888,24 @@ void TypePrinter::printAutoAfter(const A > > if (!T->getDeducedType().isNull()) > > printAfter(T->getDeducedType(), OS); > > } > > + > > +void TypePrinter::printDeducedTemplateSpecializationBefore( > > + const DeducedTemplateSpecializationType *T, raw_ostream &OS) { > > + // If the type has been deduced, print the deduced type. > > + if (!T->getDeducedType().isNull()) { > > + printBefore(T->getDeducedType(), OS); > > + } else { > > + IncludeStrongLifetimeRAII Strong(Policy); > > + T->getTemplateName().print(OS, Policy); > > + spaceBeforePlaceHolder(OS); > > + } > > +} > > +void TypePrinter::printDeducedTemplateSpecializationAfter( > > + const DeducedTemplateSpecializationType *T, raw_ostream &OS) { > > + // If the type has been deduced, print the deduced type. > > + if (!T->getDeducedType().isNull()) > > + printAfter(T->getDeducedType(), OS); > > +} > > > > void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream > > &OS) { > > IncludeStrongLifetimeRAII Strong(Policy); > > > > Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=293207&r1=293206&r2=2 > > 93207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu Jan 26 14:40:47 2017 > > @@ -2618,6 +2618,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNod > > case Type::Attributed: > > case Type::Adjusted: > > case Type::Decayed: > > + case Type::DeducedTemplateSpecialization: > > case Type::Elaborated: > > case Type::Paren: > > case Type::SubstTemplateTypeParm: > > > > Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=293207&r1=293206& > > r2=293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Thu Jan 26 14:40:47 > 2017 > > @@ -200,7 +200,8 @@ TypeEvaluationKind CodeGenFunction::getE > > llvm_unreachable("non-canonical or dependent type in IR- > > generation"); > > > > case Type::Auto: > > - llvm_unreachable("undeduced auto type in IR-generation"); > > + case Type::DeducedTemplateSpecialization: > > + llvm_unreachable("undeduced type in IR-generation"); > > > > // Various scalar types. > > case Type::Builtin: > > @@ -1899,6 +1900,7 @@ void CodeGenFunction::EmitVariablyModifi > > case Type::Typedef: > > case Type::Decltype: > > case Type::Auto: > > + case Type::DeducedTemplateSpecialization: > > // Stop walking: nothing to do. > > return; > > > > > > Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=293207&r1=293206&r2= > > 293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Thu Jan 26 14:40:47 2017 > > @@ -487,7 +487,8 @@ llvm::Type *CodeGenTypes::ConvertType(Qu > > break; > > } > > case Type::Auto: > > - llvm_unreachable("Unexpected undeduced auto type!"); > > + case Type::DeducedTemplateSpecialization: > > + llvm_unreachable("Unexpected undeduced type!"); > > case Type::Complex: { > > llvm::Type *EltTy = ConvertType(cast<ComplexType>(Ty)- > > >getElementType()); > > ResultType = llvm::StructType::get(EltTy, EltTy, nullptr); > > > > Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=293207&r1=293206&r2 > > =293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original) > > +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Thu Jan 26 14:40:47 2017 > > @@ -2815,7 +2815,8 @@ void ItaniumRTTIBuilder::BuildVTablePoin > > llvm_unreachable("References shouldn't get here"); > > > > case Type::Auto: > > - llvm_unreachable("Undeduced auto type shouldn't get here"); > > + case Type::DeducedTemplateSpecialization: > > + llvm_unreachable("Undeduced type shouldn't get here"); > > > > case Type::Pipe: > > llvm_unreachable("Pipe types shouldn't get here"); > > @@ -3045,7 +3046,8 @@ llvm::Constant *ItaniumRTTIBuilder::Buil > > llvm_unreachable("References shouldn't get here"); > > > > case Type::Auto: > > - llvm_unreachable("Undeduced auto type shouldn't get here"); > > + case Type::DeducedTemplateSpecialization: > > + llvm_unreachable("Undeduced type shouldn't get here"); > > > > case Type::Pipe: > > llvm_unreachable("Pipe type shouldn't get here"); > > > > Modified: cfe/trunk/lib/Parse/ParseDecl.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=293207&r1=293206&r2=29320 > > 7&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) > > +++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Jan 26 14:40:47 2017 > > @@ -2884,7 +2884,8 @@ void Parser::ParseDeclarationSpecifiers( > > Actions.getTypeName(*Next.getIdentifierInfo(), > > Next.getLocation(), > > getCurScope(), &SS, false, false, > > nullptr, > > /*IsCtorOrDtorName=*/false, > > - /*NonTrivialSourceInfo=*/true); > > + /*WantNonTrivialSourceInfo=*/true, > > + > > isClassTemplateDeductionContext(DSContext)); > > > > // If the referenced identifier is not a type, then this > > declspec is > > // erroneous: We already checked about that it has no type > > specifier, and > > @@ -2998,9 +2999,10 @@ void Parser::ParseDeclarationSpecifiers( > > continue; > > } > > > > - ParsedType TypeRep = > > - Actions.getTypeName(*Tok.getIdentifierInfo(), > > - Tok.getLocation(), getCurScope()); > > + ParsedType TypeRep = Actions.getTypeName( > > + *Tok.getIdentifierInfo(), Tok.getLocation(), > getCurScope(), > > nullptr, > > + false, false, nullptr, false, false, > > + isClassTemplateDeductionContext(DSContext)); > > > > // 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. > > > > Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=293207&r1=293206&r2=29 > > 3207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) > > +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Jan 26 14:40:47 2017 > > @@ -1144,10 +1144,11 @@ TypeResult Parser::ParseBaseTypeSpecifie > > > > // We have an identifier; check whether it is actually a type. > > IdentifierInfo *CorrectedII = nullptr; > > - ParsedType Type = > > - Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true, > false, > > nullptr, > > - /*IsCtorOrDtorName=*/false, > > - /*NonTrivialTypeSourceInfo=*/true, > > &CorrectedII); > > + ParsedType Type = Actions.getTypeName( > > + *Id, IdLoc, getCurScope(), &SS, true, false, nullptr, > > + /*IsCtorOrDtorName=*/false, > > + /*NonTrivialTypeSourceInfo=*/true, > > + /*IsClassTemplateDeductionContext*/ false, &CorrectedII); > > if (!Type) { > > Diag(IdLoc, diag::err_expected_class_name); > > return true; > > > > Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=293207&r1=293206&r2=29 > > 3207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original) > > +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Jan 26 14:40:47 2017 > > @@ -1639,9 +1639,10 @@ ExprResult Parser::ParseCXXThis() { > > /// typename-specifier '(' expression-list[opt] ')' > > /// [C++0x] typename-specifier braced-init-list > > /// > > +/// In C++1z onwards, the type specifier can also be a template- > name. > > ExprResult > > Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { > > - Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); > > + Declarator DeclaratorInfo(DS, Declarator::FunctionalCastContext); > > ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), > > DeclaratorInfo).get(); > > > > assert((Tok.is(tok::l_paren) || > > > > Modified: cfe/trunk/lib/Parse/Parser.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Parse/Parser.cpp?rev=293207&r1=293206&r2=293207&v > > iew=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Parse/Parser.cpp (original) > > +++ cfe/trunk/lib/Parse/Parser.cpp Thu Jan 26 14:40:47 2017 > > @@ -1743,7 +1743,8 @@ bool Parser::TryAnnotateTypeOrScopeToken > > *Tok.getIdentifierInfo(), Tok.getLocation(), > > getCurScope(), &SS, > > false, NextToken().is(tok::period), nullptr, > > /*IsCtorOrDtorName=*/false, > > - /*NonTrivialTypeSourceInfo*/ true)) { > > + /*NonTrivialTypeSourceInfo*/ true, > > + > /*IsClassTemplateDeductionContext*/GreaterThanIsOperator)) > > { > > SourceLocation BeginLoc = Tok.getLocation(); > > if (SS.isNotEmpty()) // it was a C++ qualified type name. > > BeginLoc = SS.getBeginLoc(); > > > > Modified: cfe/trunk/lib/Sema/SemaDecl.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=293207&r1=293206&r2=293207& > > view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jan 26 14:40:47 2017 > > @@ -60,6 +60,11 @@ Sema::DeclGroupPtrTy Sema::ConvertDeclTo > > return DeclGroupPtrTy::make(DeclGroupRef(Ptr)); > > } > > > > +static bool isTypeTemplate(NamedDecl *ND) { > > + return isa<ClassTemplateDecl>(ND) || > isa<TypeAliasTemplateDecl>(ND) > > || > > + isa<TemplateTemplateParmDecl>(ND); > > +} > > + > > namespace { > > > > class TypeNameValidatorCCC : public CorrectionCandidateCallback { > > @@ -67,7 +72,7 @@ class TypeNameValidatorCCC : public Corr > > TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false, > > bool AllowTemplates=false) > > : AllowInvalidDecl(AllowInvalid), WantClassName(WantClass), > > - AllowClassTemplates(AllowTemplates) { > > + AllowTemplates(AllowTemplates) { > > WantExpressionKeywords = false; > > WantCXXNamedCasts = false; > > WantRemainingKeywords = false; > > @@ -76,7 +81,7 @@ class TypeNameValidatorCCC : public Corr > > bool ValidateCandidate(const TypoCorrection &candidate) override { > > if (NamedDecl *ND = candidate.getCorrectionDecl()) { > > bool IsType = isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND); > > - bool AllowedTemplate = AllowClassTemplates && > > isa<ClassTemplateDecl>(ND); > > + bool AllowedTemplate = AllowTemplates && isTypeTemplate(ND); > > return (IsType || AllowedTemplate) && > > (AllowInvalidDecl || !ND->isInvalidDecl()); > > } > > @@ -86,7 +91,7 @@ class TypeNameValidatorCCC : public Corr > > private: > > bool AllowInvalidDecl; > > bool WantClassName; > > - bool AllowClassTemplates; > > + bool AllowTemplates; > > }; > > > > } // end anonymous namespace > > @@ -252,7 +257,13 @@ ParsedType Sema::getTypeName(const Ident > > ParsedType ObjectTypePtr, > > bool IsCtorOrDtorName, > > bool WantNontrivialTypeSourceInfo, > > + bool IsClassTemplateDeductionContext, > > IdentifierInfo **CorrectedII) { > > + // FIXME: Consider allowing this outside C++1z mode as an > extension. > > + bool AllowDeducedTemplate = IsClassTemplateDeductionContext && > > + getLangOpts().CPlusPlus1z && > > !IsCtorOrDtorName && > > + !isClassName && !HasTrailingDot; > > + > > // Determine where we will perform name lookup. > > DeclContext *LookupCtx = nullptr; > > if (ObjectTypePtr) { > > @@ -334,10 +345,11 @@ ParsedType Sema::getTypeName(const Ident > > case LookupResult::NotFound: > > case LookupResult::NotFoundInCurrentInstantiation: > > if (CorrectedII) { > > - TypoCorrection Correction = CorrectTypo( > > - Result.getLookupNameInfo(), Kind, S, SS, > > - llvm::make_unique<TypeNameValidatorCCC>(true, > isClassName), > > - CTK_ErrorRecovery); > > + TypoCorrection Correction = > > + CorrectTypo(Result.getLookupNameInfo(), Kind, S, SS, > > + llvm::make_unique<TypeNameValidatorCCC>( > > + true, isClassName, AllowDeducedTemplate), > > + CTK_ErrorRecovery); > > IdentifierInfo *NewII = > > Correction.getCorrectionAsIdentifierInfo(); > > TemplateTy Template; > > bool MemberOfUnknownSpecialization; > > @@ -359,7 +371,8 @@ ParsedType Sema::getTypeName(const Ident > > ParsedType Ty = getTypeName(*NewII, NameLoc, S, NewSSPtr, > > isClassName, HasTrailingDot, > > ObjectTypePtr, > > IsCtorOrDtorName, > > - WantNontrivialTypeSourceInfo); > > + WantNontrivialTypeSourceInfo, > > + > IsClassTemplateDeductionContext); > > if (Ty) { > > diagnoseTypo(Correction, > > > > PDiag(diag::err_unknown_type_or_class_name_suggest) > > @@ -391,7 +404,8 @@ ParsedType Sema::getTypeName(const Ident > > // Look to see if we have a type anywhere in the list of > results. > > for (LookupResult::iterator Res = Result.begin(), ResEnd = > > Result.end(); > > Res != ResEnd; ++Res) { > > - if (isa<TypeDecl>(*Res) || isa<ObjCInterfaceDecl>(*Res)) { > > + if (isa<TypeDecl>(*Res) || isa<ObjCInterfaceDecl>(*Res) || > > + (AllowDeducedTemplate && isTypeTemplate(*Res))) { > > if (!IIDecl || > > (*Res)->getLocation().getRawEncoding() < > > IIDecl->getLocation().getRawEncoding()) > > @@ -440,29 +454,13 @@ ParsedType Sema::getTypeName(const Ident > > > > T = Context.getTypeDeclType(TD); > > MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false); > > - > > - // NOTE: avoid constructing an ElaboratedType(Loc) if this is a > > - // constructor or destructor name (in such a case, the scope > > specifier > > - // will be attached to the enclosing Expr or Decl node). > > - if (SS && SS->isNotEmpty() && !IsCtorOrDtorName) { > > - if (WantNontrivialTypeSourceInfo) { > > - // Construct a type with type-source information. > > - TypeLocBuilder Builder; > > - Builder.pushTypeSpec(T).setNameLoc(NameLoc); > > - > > - T = getElaboratedType(ETK_None, *SS, T); > > - ElaboratedTypeLoc ElabTL = > Builder.push<ElaboratedTypeLoc>(T); > > - ElabTL.setElaboratedKeywordLoc(SourceLocation()); > > - ElabTL.setQualifierLoc(SS->getWithLocInContext(Context)); > > - return CreateParsedType(T, > Builder.getTypeSourceInfo(Context, > > T)); > > - } else { > > - T = getElaboratedType(ETK_None, *SS, T); > > - } > > - } > > } else if (ObjCInterfaceDecl *IDecl = > > dyn_cast<ObjCInterfaceDecl>(IIDecl)) { > > (void)DiagnoseUseOfDecl(IDecl, NameLoc); > > if (!HasTrailingDot) > > T = Context.getObjCInterfaceType(IDecl); > > + } else if (AllowDeducedTemplate && isTypeTemplate(IIDecl)) { > > + T = Context.getDeducedTemplateSpecializationType( > > + TemplateName(cast<TemplateDecl>(IIDecl)), QualType(), > false); > > } > > > > if (T.isNull()) { > > @@ -470,6 +468,27 @@ ParsedType Sema::getTypeName(const Ident > > Result.suppressDiagnostics(); > > return nullptr; > > } > > + > > + // NOTE: avoid constructing an ElaboratedType(Loc) if this is a > > + // constructor or destructor name (in such a case, the scope > > specifier > > + // will be attached to the enclosing Expr or Decl node). > > + if (SS && SS->isNotEmpty() && !IsCtorOrDtorName && > > + !isa<ObjCInterfaceDecl>(IIDecl)) { > > + if (WantNontrivialTypeSourceInfo) { > > + // Construct a type with type-source information. > > + TypeLocBuilder Builder; > > + Builder.pushTypeSpec(T).setNameLoc(NameLoc); > > + > > + T = getElaboratedType(ETK_None, *SS, T); > > + ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T); > > + ElabTL.setElaboratedKeywordLoc(SourceLocation()); > > + ElabTL.setQualifierLoc(SS->getWithLocInContext(Context)); > > + return CreateParsedType(T, Builder.getTypeSourceInfo(Context, > > T)); > > + } else { > > + T = getElaboratedType(ETK_None, *SS, T); > > + } > > + } > > + > > return ParsedType::make(T); > > } > > > > @@ -647,6 +666,7 @@ void Sema::DiagnoseUnknownTypeName(Ident > > if (Corrected.getCorrectionSpecifier()) > > tmpSS.MakeTrivial(Context, > Corrected.getCorrectionSpecifier(), > > SourceRange(IILoc)); > > + // FIXME: Support class template argument deduction here. > > SuggestedType = > > getTypeName(*Corrected.getCorrectionAsIdentifierInfo(), > > IILoc, S, > > tmpSS.isSet() ? &tmpSS : SS, false, false, > > nullptr, > > @@ -9740,6 +9760,14 @@ QualType Sema::deduceVarTypeFromInitiali > > > > VarDeclOrName VN{VDecl, Name}; > > > > + DeducedType *Deduced = Type->getContainedDeducedType(); > > + assert(Deduced && "deduceVarTypeFromInitializer for non-deduced > > type"); > > + > > + if (isa<DeducedTemplateSpecializationType>(Deduced)) { > > + Diag(Init->getLocStart(), > > diag::err_deduced_class_template_not_supported); > > + return QualType(); > > + } > > + > > ArrayRef<Expr *> DeduceInits = Init; > > if (DirectInit) { > > if (auto *PL = dyn_cast<ParenListExpr>(Init)) > > > > Modified: cfe/trunk/lib/Sema/SemaExpr.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=293207&r1=293206&r2=293207& > > view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) > > +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jan 26 14:40:47 2017 > > @@ -3976,7 +3976,8 @@ static void captureVariablyModifiedType( > > T = cast<DecltypeType>(Ty)->desugar(); > > break; > > case Type::Auto: > > - T = cast<AutoType>(Ty)->getDeducedType(); > > + case Type::DeducedTemplateSpecialization: > > + T = cast<DeducedType>(Ty)->getDeducedType(); > > break; > > case Type::TypeOfExpr: > > T = cast<TypeOfExprType>(Ty)->getUnderlyingExpr()->getType(); > > > > Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=293207&r1=293206&r2=2932 > > 07&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) > > +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jan 26 14:40:47 2017 > > @@ -1255,9 +1255,19 @@ Sema::BuildCXXTypeConstructExpr(TypeSour > > RParenLoc); > > } > > > > + // C++1z [expr.type.conv]p1: > > + // If the type is a placeholder for a deduced class type, > > [...perform class > > + // template argument deduction...] > > + DeducedType *Deduced = Ty->getContainedDeducedType(); > > + if (Deduced && isa<DeducedTemplateSpecializationType>(Deduced)) { > > + Diag(TyBeginLoc, > diag::err_deduced_class_template_not_supported); > > + return ExprError(); > > + } > > + > > bool ListInitialization = LParenLoc.isInvalid(); > > - assert((!ListInitialization || (Exprs.size() == 1 && > > isa<InitListExpr>(Exprs[0]))) > > - && "List initialization must have initializer list as > > expression."); > > + assert((!ListInitialization || > > + (Exprs.size() == 1 && isa<InitListExpr>(Exprs[0]))) && > > + "List initialization must have initializer list as > > expression."); > > SourceRange FullRange = SourceRange(TyBeginLoc, > > ListInitialization ? Exprs[0]->getSourceRange().getEnd() : > > RParenLoc); > > > > @@ -1646,6 +1656,11 @@ Sema::BuildCXXNew(SourceRange Range, boo > > > > // C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in > > for. > > if (AllocType->isUndeducedType()) { > > + if (isa<DeducedTemplateSpecializationType>( > > + AllocType->getContainedDeducedType())) > > + return ExprError(Diag(TypeRange.getBegin(), > > + > > diag::err_deduced_class_template_not_supported)); > > + > > if (initStyle == CXXNewExpr::NoInit || NumInits == 0) > > return ExprError(Diag(StartLoc, > > diag::err_auto_new_requires_ctor_arg) > > << AllocType << TypeRange); > > > > Modified: cfe/trunk/lib/Sema/SemaLookup.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=293207&r1=293206&r2=29320 > > 7&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Sema/SemaLookup.cpp (original) > > +++ cfe/trunk/lib/Sema/SemaLookup.cpp Thu Jan 26 14:40:47 2017 > > @@ -2694,6 +2694,7 @@ addAssociatedClassesAndNamespaces(Associ > > > > // Non-deduced auto types only get here for error cases. > > case Type::Auto: > > + case Type::DeducedTemplateSpecialization: > > break; > > > > // If T is an Objective-C object or interface type, or a pointer > > to an > > > > Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=293207&r1=293206&r2=293 > > 207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) > > +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Jan 26 14:40:47 2017 > > @@ -4439,6 +4439,11 @@ bool UnnamedLocalNoLinkageFinder::VisitA > > return Visit(T->getDeducedType()); > > } > > > > +bool > > UnnamedLocalNoLinkageFinder::VisitDeducedTemplateSpecializationType( > > + const DeducedTemplateSpecializationType *T) { > > + return Visit(T->getDeducedType()); > > +} > > + > > bool UnnamedLocalNoLinkageFinder::VisitRecordType(const RecordType* > T) > > { > > return VisitTagDecl(T->getDecl()); > > } > > @@ -8786,6 +8791,9 @@ Sema::CheckTypenameType(ElaboratedTypeKe > > > Context.getTypeDeclType(Type)); > > } > > > > + // FIXME: Form a deduced template specialization type if we get > a > > template > > + // declaration here. > > + > > DiagID = diag::err_typename_nested_not_type; > > Referenced = Result.getFoundDecl(); > > break; > > > > Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=293207&r1=2932 > > 06&r2=293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original) > > +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Jan 26 14:40:47 > > 2017 > > @@ -1723,6 +1723,7 @@ DeduceTemplateArgumentsByTypeMatch(Sema > > case Type::Decltype: > > case Type::UnaryTransform: > > case Type::Auto: > > + case Type::DeducedTemplateSpecialization: > > case Type::DependentTemplateSpecialization: > > case Type::PackExpansion: > > case Type::Pipe: > > @@ -5152,8 +5153,9 @@ MarkUsedTemplateParameters(ASTContext &C > > break; > > > > case Type::Auto: > > + case Type::DeducedTemplateSpecialization: > > MarkUsedTemplateParameters(Ctx, > > - cast<AutoType>(T)->getDeducedType(), > > + cast<DeducedType>(T)- > >getDeducedType(), > > OnlyDeduced, Depth, Used); > > > > // None of these types have any template parameters in them. > > > > Modified: cfe/trunk/lib/Sema/SemaType.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Sema/SemaType.cpp?rev=293207&r1=293206&r2=293207& > > view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Sema/SemaType.cpp (original) > > +++ cfe/trunk/lib/Sema/SemaType.cpp Thu Jan 26 14:40:47 2017 > > @@ -2778,12 +2778,20 @@ static QualType GetDeclSpecTypeForDeclar > > distributeTypeAttrsFromDeclarator(state, T); > > > > // C++11 [dcl.spec.auto]p5: reject 'auto' if it is not in an > allowed > > context. > > - if (D.getDeclSpec().containsPlaceholderType()) { > > + if (DeducedType *Deduced = T->getContainedDeducedType()) { > > + AutoType *Auto = dyn_cast<AutoType>(Deduced); > > int Error = -1; > > > > + // Is this a 'auto' or 'decltype(auto)' type (as opposed to > > __auto_type or > > + // class template argument deduction)? > > + bool IsCXXAutoType = > > + (Auto && Auto->getKeyword() != > AutoTypeKeyword::GNUAutoType); > > + > > switch (D.getContext()) { > > case Declarator::LambdaExprContext: > > - llvm_unreachable("Can't specify a type specifier in lambda > > grammar"); > > + // Declared return type of a lambda-declarator is implicit and > > is always > > + // 'auto'. > > + break; > > case Declarator::ObjCParameterContext: > > case Declarator::ObjCResultContext: > > case Declarator::PrototypeContext: > > @@ -2791,8 +2799,8 @@ static QualType GetDeclSpecTypeForDeclar > > break; > > case Declarator::LambdaExprParameterContext: > > // In C++14, generic lambdas allow 'auto' in their parameters. > > - if (!(SemaRef.getLangOpts().CPlusPlus14 > > - && D.getDeclSpec().getTypeSpecType() == > > DeclSpec::TST_auto)) > > + if (!SemaRef.getLangOpts().CPlusPlus14 || > > + !Auto || Auto->getKeyword() != AutoTypeKeyword::Auto) > > Error = 16; > > break; > > case Declarator::MemberContext: { > > @@ -2807,6 +2815,8 @@ static QualType GetDeclSpecTypeForDeclar > > case TTK_Class: Error = 5; /* Class member */ break; > > case TTK_Interface: Error = 6; /* Interface member */ break; > > } > > + if (D.getDeclSpec().isFriendSpecified()) > > + Error = 20; // Friend type > > break; > > } > > case Declarator::CXXCatchContext: > > @@ -2814,8 +2824,10 @@ static QualType GetDeclSpecTypeForDeclar > > Error = 7; // Exception declaration > > break; > > case Declarator::TemplateParamContext: > > - if (!SemaRef.getLangOpts().CPlusPlus1z) > > - Error = 8; // Template parameter > > + if (isa<DeducedTemplateSpecializationType>(Deduced)) > > + Error = 19; // Template parameter > > + else if (!SemaRef.getLangOpts().CPlusPlus1z) > > + Error = 8; // Template parameter (until C++1z) > > break; > > case Declarator::BlockLiteralContext: > > Error = 9; // Block literal > > @@ -2828,15 +2840,17 @@ static QualType GetDeclSpecTypeForDeclar > > Error = 12; // Type alias > > break; > > case Declarator::TrailingReturnContext: > > - if (!SemaRef.getLangOpts().CPlusPlus14 || > > - D.getDeclSpec().getTypeSpecType() == > > DeclSpec::TST_auto_type) > > + if (!SemaRef.getLangOpts().CPlusPlus14 || !IsCXXAutoType) > > Error = 13; // Function return type > > break; > > case Declarator::ConversionIdContext: > > - if (!SemaRef.getLangOpts().CPlusPlus14 || > > - D.getDeclSpec().getTypeSpecType() == > > DeclSpec::TST_auto_type) > > + if (!SemaRef.getLangOpts().CPlusPlus14 || !IsCXXAutoType) > > Error = 14; // conversion-type-id > > break; > > + case Declarator::FunctionalCastContext: > > + if (isa<DeducedTemplateSpecializationType>(Deduced)) > > + break; > > + LLVM_FALLTHROUGH; > > case Declarator::TypeNameContext: > > Error = 15; // Generic > > break; > > @@ -2845,9 +2859,14 @@ static QualType GetDeclSpecTypeForDeclar > > case Declarator::ForContext: > > case Declarator::InitStmtContext: > > case Declarator::ConditionContext: > > + // FIXME: P0091R3 (erroneously) does not permit class template > > argument > > + // deduction in conditions, for-init-statements, and other > > declarations > > + // that are not simple-declarations. > > break; > > case Declarator::CXXNewContext: > > - if (D.getDeclSpec().getTypeSpecType() == > > DeclSpec::TST_auto_type) > > + // FIXME: P0091R3 does not permit class template argument > > deduction here, > > + // but we follow GCC and allow it anyway. > > + if (!IsCXXAutoType && > > !isa<DeducedTemplateSpecializationType>(Deduced)) > > Error = 17; // 'new' type > > break; > > case Declarator::KNRTypeListContext: > > @@ -2861,8 +2880,7 @@ static QualType GetDeclSpecTypeForDeclar > > // In Objective-C it is an error to use 'auto' on a function > > declarator > > // (and everywhere for '__auto_type'). > > if (D.isFunctionDeclarator() && > > - (!SemaRef.getLangOpts().CPlusPlus11 || > > - D.getDeclSpec().getTypeSpecType() == > > DeclSpec::TST_auto_type)) > > + (!SemaRef.getLangOpts().CPlusPlus11 || !IsCXXAutoType)) > > Error = 13; > > > > bool HaveTrailing = false; > > @@ -2872,8 +2890,8 @@ static QualType GetDeclSpecTypeForDeclar > > // level. Check all declarator chunks (outermost first) anyway, > to > > give > > // better diagnostics. > > // We don't support '__auto_type' with trailing return types. > > - if (SemaRef.getLangOpts().CPlusPlus11 && > > - D.getDeclSpec().getTypeSpecType() != > DeclSpec::TST_auto_type) > > { > > + // FIXME: Should we only do this for 'auto' and not > > 'decltype(auto)'? > > + if (SemaRef.getLangOpts().CPlusPlus11 && IsCXXAutoType) { > > for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) { > > unsigned chunkIndex = e - i - 1; > > state.setCurrentChunkIndex(chunkIndex); > > @@ -2894,15 +2912,28 @@ static QualType GetDeclSpecTypeForDeclar > > AutoRange = D.getName().getSourceRange(); > > > > if (Error != -1) { > > - unsigned Keyword; > > - switch (D.getDeclSpec().getTypeSpecType()) { > > - case DeclSpec::TST_auto: Keyword = 0; break; > > - case DeclSpec::TST_decltype_auto: Keyword = 1; break; > > - case DeclSpec::TST_auto_type: Keyword = 2; break; > > - default: llvm_unreachable("unknown auto TypeSpecType"); > > + unsigned Kind; > > + if (Auto) { > > + switch (Auto->getKeyword()) { > > + case AutoTypeKeyword::Auto: Kind = 0; break; > > + case AutoTypeKeyword::DecltypeAuto: Kind = 1; break; > > + case AutoTypeKeyword::GNUAutoType: Kind = 2; break; > > + } > > + } else { > > + assert(isa<DeducedTemplateSpecializationType>(Deduced) && > > + "unknown auto type"); > > + Kind = 3; > > } > > + > > + auto *DTST = > > dyn_cast<DeducedTemplateSpecializationType>(Deduced); > > + TemplateName TN = DTST ? DTST->getTemplateName() : > > TemplateName(); > > + > > SemaRef.Diag(AutoRange.getBegin(), diag::err_auto_not_allowed) > > - << Keyword << Error << AutoRange; > > + << Kind << Error << > > (int)SemaRef.getTemplateNameKindForDiagnostics(TN) > > + << QualType(Deduced, 0) << AutoRange; > > + if (auto *TD = TN.getAsTemplateDecl()) > > + SemaRef.Diag(TD->getLocation(), > > diag::note_template_decl_here); > > + > > T = SemaRef.Context.IntTy; > > D.setInvalidType(true); > > } else if (!HaveTrailing) { > > @@ -2942,6 +2973,7 @@ static QualType GetDeclSpecTypeForDeclar > > DiagID = diag::err_type_defined_in_alias_template; > > break; > > case Declarator::TypeNameContext: > > + case Declarator::FunctionalCastContext: > > case Declarator::ConversionIdContext: > > case Declarator::TemplateParamContext: > > case Declarator::CXXNewContext: > > @@ -3623,17 +3655,32 @@ static TypeSourceInfo *GetFullTypeForDec > > > > // If T is 'decltype(auto)', the only declarators we can have are > > parens > > // and at most one function declarator if this is a function > > declaration. > > - if (const AutoType *AT = T->getAs<AutoType>()) { > > - if (AT->isDecltypeAuto()) { > > + // If T is a deduced class template specialization type, we can > have > > no > > + // declarator chunks at all. > > + if (auto *DT = T->getAs<DeducedType>()) { > > + const AutoType *AT = T->getAs<AutoType>(); > > + bool IsClassTemplateDeduction = > > isa<DeducedTemplateSpecializationType>(DT); > > + if ((AT && AT->isDecltypeAuto()) || IsClassTemplateDeduction) { > > for (unsigned I = 0, E = D.getNumTypeObjects(); I != E; ++I) { > > unsigned Index = E - I - 1; > > DeclaratorChunk &DeclChunk = D.getTypeObject(Index); > > - unsigned DiagId = diag::err_decltype_auto_compound_type; > > + unsigned DiagId = IsClassTemplateDeduction > > + ? > > diag::err_deduced_class_template_compound_type > > + : > diag::err_decltype_auto_compound_type; > > unsigned DiagKind = 0; > > switch (DeclChunk.Kind) { > > case DeclaratorChunk::Paren: > > + // FIXME: Rejecting this is a little silly. > > + if (IsClassTemplateDeduction) { > > + DiagKind = 4; > > + break; > > + } > > continue; > > case DeclaratorChunk::Function: { > > + if (IsClassTemplateDeduction) { > > + DiagKind = 3; > > + break; > > + } > > unsigned FnIndex; > > if (D.isFunctionDeclarationContext() && > > D.isFunctionDeclarator(FnIndex) && FnIndex == Index) > > @@ -3834,6 +3881,7 @@ static TypeSourceInfo *GetFullTypeForDec > > case Declarator::TemplateParamContext: > > case Declarator::TemplateTypeArgContext: > > case Declarator::TypeNameContext: > > + case Declarator::FunctionalCastContext: > > // Don't infer in these contexts. > > break; > > } > > @@ -4713,6 +4761,7 @@ static TypeSourceInfo *GetFullTypeForDec > > case Declarator::ObjCParameterContext: // FIXME: special > > diagnostic here? > > case Declarator::ObjCResultContext: // FIXME: special > > diagnostic here? > > case Declarator::TypeNameContext: > > + case Declarator::FunctionalCastContext: > > case Declarator::CXXNewContext: > > case Declarator::AliasDeclContext: > > case Declarator::AliasTemplateContext: > > > > Modified: cfe/trunk/lib/Sema/TreeTransform.h > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Sema/TreeTransform.h?rev=293207&r1=293206&r2=2932 > > 07&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Sema/TreeTransform.h (original) > > +++ cfe/trunk/lib/Sema/TreeTransform.h Thu Jan 26 14:40:47 2017 > > @@ -876,6 +876,14 @@ public: > > /*IsDependent*/ false); > > } > > > > + /// By default, builds a new DeducedTemplateSpecializationType > with > > the given > > + /// deduced type. > > + QualType RebuildDeducedTemplateSpecializationType(TemplateName > > Template, > > + QualType Deduced) { > > + return SemaRef.Context.getDeducedTemplateSpecializationType( > > + Template, Deduced, /*IsDependent*/ false); > > + } > > + > > /// \brief Build a new template specialization type. > > /// > > /// By default, performs semantic analysis when building the > > template > > @@ -5344,6 +5352,37 @@ QualType TreeTransform<Derived>::Transfo > > > > return Result; > > } > > + > > +template<typename Derived> > > +QualType > > TreeTransform<Derived>::TransformDeducedTemplateSpecializationType( > > + TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) { > > + const DeducedTemplateSpecializationType *T = TL.getTypePtr(); > > + > > + CXXScopeSpec SS; > > + TemplateName TemplateName = getDerived().TransformTemplateName( > > + SS, T->getTemplateName(), TL.getTemplateNameLoc()); > > + if (TemplateName.isNull()) > > + return QualType(); > > + > > + QualType OldDeduced = T->getDeducedType(); > > + QualType NewDeduced; > > + if (!OldDeduced.isNull()) { > > + NewDeduced = getDerived().TransformType(OldDeduced); > > + if (NewDeduced.isNull()) > > + return QualType(); > > + } > > + > > + QualType Result = > > getDerived().RebuildDeducedTemplateSpecializationType( > > + TemplateName, NewDeduced); > > + if (Result.isNull()) > > + return QualType(); > > + > > + DeducedTemplateSpecializationTypeLoc NewTL = > > + TLB.push<DeducedTemplateSpecializationTypeLoc>(Result); > > + NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); > > + > > + return Result; > > +} > > > > template<typename Derived> > > QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder > > &TLB, > > > > Modified: cfe/trunk/lib/Serialization/ASTReader.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=293207&r1=293206& > > r2=293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) > > +++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Jan 26 14:40:47 > 2017 > > @@ -5651,6 +5651,14 @@ QualType ASTReader::readTypeRecord(unsig > > return Context.getAutoType(Deduced, Keyword, IsDependent); > > } > > > > + case TYPE_DEDUCED_TEMPLATE_SPECIALIZATION: { > > + TemplateName Name = ReadTemplateName(*Loc.F, Record, Idx); > > + QualType Deduced = readType(*Loc.F, Record, Idx); > > + bool IsDependent = Deduced.isNull() ? Record[Idx++] : false; > > + return Context.getDeducedTemplateSpecializationType(Name, > Deduced, > > + > IsDependent); > > + } > > + > > case TYPE_RECORD: { > > if (Record.size() != 2) { > > Error("incorrect encoding of record type"); > > @@ -6082,6 +6090,11 @@ void TypeLocReader::VisitAutoTypeLoc(Aut > > TL.setNameLoc(ReadSourceLocation()); > > } > > > > +void TypeLocReader::VisitDeducedTemplateSpecializationTypeLoc( > > + DeducedTemplateSpecializationTypeLoc TL) { > > + TL.setTemplateNameLoc(ReadSourceLocation()); > > +} > > + > > void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) { > > TL.setNameLoc(ReadSourceLocation()); > > } > > > > Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=293207&r1=293206& > > r2=293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) > > +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu Jan 26 14:40:47 > 2017 > > @@ -349,6 +349,15 @@ void ASTTypeWriter::VisitAutoType(const > > Code = TYPE_AUTO; > > } > > > > +void ASTTypeWriter::VisitDeducedTemplateSpecializationType( > > + const DeducedTemplateSpecializationType *T) { > > + Record.AddTemplateName(T->getTemplateName()); > > + Record.AddTypeRef(T->getDeducedType()); > > + if (T->getDeducedType().isNull()) > > + Record.push_back(T->isDependentType()); > > + Code = TYPE_DEDUCED_TEMPLATE_SPECIALIZATION; > > +} > > + > > void ASTTypeWriter::VisitTagType(const TagType *T) { > > Record.push_back(T->isDependentType()); > > Record.AddDeclRef(T->getDecl()->getCanonicalDecl()); > > @@ -683,6 +692,11 @@ void TypeLocWriter::VisitAutoTypeLoc(Aut > > Record.AddSourceLocation(TL.getNameLoc()); > > } > > > > +void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc( > > + DeducedTemplateSpecializationTypeLoc TL) { > > + Record.AddSourceLocation(TL.getTemplateNameLoc()); > > +} > > + > > void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) { > > Record.AddSourceLocation(TL.getNameLoc()); > > } > > > > Modified: > > cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.c > > pp?rev=293207&r1=293206&r2=293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp > > (original) > > +++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp > > Thu Jan 26 14:40:47 2017 > > @@ -9,7 +9,7 @@ struct S { > > > > void f() throw (auto); // expected-error{{'auto' not allowed > here}} > > > > - friend auto; // expected-error{{'auto' not allowed in non-static > > struct member}} > > + friend auto; // expected-error{{'auto' not allowed in friend > > declaration}} > > > > operator auto(); // expected-error{{'auto' not allowed in > conversion > > function type}} > > }; > > > > Modified: cfe/trunk/test/CXX/drs/dr5xx.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/test/CXX/drs/dr5xx.cpp?rev=293207&r1=293206&r2=293207 > > &view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/test/CXX/drs/dr5xx.cpp (original) > > +++ cfe/trunk/test/CXX/drs/dr5xx.cpp Thu Jan 26 14:40:47 2017 > > @@ -877,13 +877,25 @@ namespace dr583 { // dr583: 4 > > namespace dr585 { // dr585: yes > > template<typename> struct T; > > struct A { > > - friend T; // expected-error {{requires a type specifier}} > > expected-error {{can only be classes or functions}} > > + friend T; > > +#if __cplusplus <= 201402L > > + // expected-error@-2 {{requires a type specifier}} expected- > > error@-2 {{can only be classes or functions}} > > +#else > > + // expected-error@-4 {{use of class template 'T' requires > template > > arguments; argument deduction not allowed in friend declaration}} > > + // expected-note@-7 {{here}} > > +#endif > > // FIXME: It's not clear whether the standard allows this or > what > > it means, > > // but the DR585 writeup suggests it as an alternative. > > template<typename U> friend T<U>; // expected-error {{must use > an > > elaborated type}} > > }; > > template<template<typename> class T> struct B { > > - friend T; // expected-error {{requires a type specifier}} > > expected-error {{can only be classes or functions}} > > + friend T; > > +#if __cplusplus <= 201402L > > + // expected-error@-2 {{requires a type specifier}} expected- > > error@-2 {{can only be classes or functions}} > > +#else > > + // expected-error@-4 {{use of template template parameter 'T' > > requires template arguments; argument deduction not allowed in friend > > declaration}} > > + // expected-note@-6 {{here}} > > +#endif > > template<typename U> friend T<U>; // expected-error {{must use > an > > elaborated type}} > > }; > > } > > > > Modified: cfe/trunk/test/Parser/backtrack-off-by-one.cpp > > URL: http://llvm.org/viewvc/llvm- > > project/cfe/trunk/test/Parser/backtrack-off-by- > > one.cpp?rev=293207&r1=293206&r2=293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/test/Parser/backtrack-off-by-one.cpp (original) > > +++ cfe/trunk/test/Parser/backtrack-off-by-one.cpp Thu Jan 26 > 14:40:47 > > 2017 > > @@ -1,6 +1,7 @@ > > // RUN: %clang_cc1 -verify %s > > // RUN: %clang_cc1 -verify %s -std=c++98 > > // RUN: %clang_cc1 -verify %s -std=c++11 > > +// RUN: %clang_cc1 -verify %s -std=c++1z > > > > // PR25946 > > // We had an off-by-one error in an assertion when annotating A<int> > > below. Our > > @@ -13,9 +14,13 @@ template <typename T> class A {}; > > // expected-error@+1 {{expected '{' after base class list}} > > template <typename T> class B : T // not ',' or '{' > > #if __cplusplus < 201103L > > -// expected-error@+4 {{expected ';' after top level declarator}} > > +// expected-error@+8 {{expected ';' after top level declarator}} > > +#endif > > +#if __cplusplus <= 201402L > > +// expected-error@+5 {{C++ requires a type specifier for all > > declarations}} > > +#else > > +// expected-error@+3 {{expected unqualified-id}} > > #endif > > -// expected-error@+2 {{C++ requires a type specifier for all > > declarations}} > > // expected-error@+1 {{expected ';' after class}} > > A<int> { > > }; > > > > Added: cfe/trunk/test/Parser/cxx1z-class-template-argument- > > deduction.cpp > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx1z- > > class-template-argument-deduction.cpp?rev=293207&view=auto > > > ======================================================================= > > ======= > > --- cfe/trunk/test/Parser/cxx1z-class-template-argument-deduction.cpp > > (added) > > +++ cfe/trunk/test/Parser/cxx1z-class-template-argument-deduction.cpp > > Thu Jan 26 14:40:47 2017 > > @@ -0,0 +1,131 @@ > > +// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s > > + > > +template<typename T> struct A {}; // expected-note 31{{declared > here}} > > + > > +// Make sure we still correctly parse cases where a template can > > appear without arguments. > > +namespace template_template_arg { > > + template<template<typename> typename> struct X {}; > > + template<typename> struct Y {}; > > + > > + X<A> xa; > > + Y<A> ya; // expected-error {{requires template arguments}} > > + X<::A> xcca; > > + Y<::A> ycca; // expected-error {{requires template arguments}} > > + > > + template<template<typename> typename = A> struct XD {}; > > + template<typename = A> struct YD {}; // expected-error {{requires > > template arguments}} > > + template<template<typename> typename = ::A> struct XCCD {}; > > + template<typename = ::A> struct YCCD {}; // expected-error > > {{requires template arguments}} > > + > > + // FIXME: replacing the invalid type with 'int' here is horrible > > + template <A a = A<int>()> class C { }; // expected-error > {{requires > > template arguments}} expected-error {{not implicitly convertible to > > 'int'}} > > + template<typename T = A> struct G { }; // expected-error > {{requires > > template arguments}} > > +} > > + > > +namespace injected_class_name { > > + template<typename T> struct A { > > + A(T); > > + void f(int) { > > + A a = 1; > > + injected_class_name::A b = 1; // expected-error {{not yet > > supported}} > > + } > > + void f(T); > > + }; > > + A<short> ai = 1; > > + A<double>::A b(1); // expected-error {{constructor name}} > > +} > > + > > +struct member { > > + A a; // expected-error {{requires template arguments}} > > + A *b; // expected-error {{requires template arguments}} > > + const A c; // expected-error {{requires template arguments}} > > + > > + void f() throw (A); // expected-error {{requires template > > arguments}} > > + > > + friend A; // expected-error {{requires template arguments; > argument > > deduction not allowed in friend declaration}} > > + > > + operator A(); // expected-error {{requires template arguments; > > argument deduction not allowed in conversion function type}} > > + > > + static A x; // expected-error {{requires an initializer}} > > + static A y = 0; // expected-error {{not yet supported}} > > +}; > > + > > +namespace in_typedef { > > + typedef A *AutoPtr; // expected-error {{requires template > arguments; > > argument deduction not allowed in typedef}} > > + typedef A (*PFun)(int a); // expected-error{{requires template > > arguments; argument deduction not allowed in typedef}} > > + typedef A Fun(int a) -> decltype(a + a); // expected- > error{{requires > > template arguments; argument deduction not allowed in function return > > type}} > > +} > > + > > +namespace stmt { > > + void g(A a) { // expected-error{{requires template arguments; > > argument deduction not allowed in function prototype}} > > + try { } > > + catch (A &a) { } // expected-error{{requires template arguments; > > argument deduction not allowed in exception declaration}} > > + catch (const A a) { } // expected-error{{requires template > > arguments; argument deduction not allowed in exception declaration}} > > + try { } catch (A a) { } // expected-error{{requires template > > arguments; argument deduction not allowed in exception declaration}} > > + > > + // FIXME: The standard only permits class template argument > > deduction in a > > + // simple-declaration or cast. We also permit it in conditions, > > + // for-range-declarations, member-declarations for static data > > members, and > > + // new-expressions, because not doing so would be bizarre. > > + A local = 0; // expected-error {{not yet supported}} > > + static A local_static = 0; // expected-error {{not yet > supported}} > > + static thread_local A thread_local_static = 0; // expected-error > > {{not yet supported}} > > + if (A a = 0) {} // expected-error {{not yet supported}} > > + if (A a = 0; a) {} // expected-error {{not yet supported}} > > + switch (A a = 0) {} // expected-error {{not yet supported}} > > + switch (A a = 0; a) {} // expected-error {{not yet supported}} > > + for (A a = 0; a; /**/) {} // expected-error {{not yet > supported}} > > + for (/**/; A a = 0; /**/) {} // expected-error {{not yet > > supported}} > > + while (A a = 0) {} // expected-error {{not yet supported}} > > + int arr[3]; > > + for (A a : arr) {} // expected-error {{not yet supported}} > > + } > > + > > + namespace std { > > + class type_info; > > + } > > +} > > + > > +namespace expr { > > + template<typename T> struct U {}; > > + void j() { > > + (void)typeid(A); // expected-error{{requires template arguments; > > argument deduction not allowed here}} > > + (void)sizeof(A); // expected-error{{requires template arguments; > > argument deduction not allowed here}} > > + (void)__alignof(A); // expected-error{{requires template > > arguments; argument deduction not allowed here}} > > + > > + U<A> v; // expected-error {{requires template arguments}} > > + > > + int n; > > + (void)dynamic_cast<A&>(n); // expected-error{{requires template > > arguments; argument deduction not allowed here}} > > + (void)static_cast<A*>(&n); // expected-error{{requires template > > arguments; argument deduction not allowed here}} > > + (void)reinterpret_cast<A*>(&n); // expected-error{{requires > > template arguments; argument deduction not allowed here}} > > + (void)const_cast<A>(n); // expected-error{{requires template > > arguments; argument deduction not allowed here}} > > + (void)*(A*)(&n); // expected-error{{requires template arguments; > > argument deduction not allowed here}} > > + > > + (void)A(n); // expected-error {{not yet supported}} > > + (void)A{n}; // expected-error {{not yet supported}} > > + (void)new A(n); // expected-error {{not yet supported}} > > + (void)new A{n}; // expected-error {{not yet supported}} > > + // FIXME: We should diagnose the lack of an initializer here. > > + (void)new A; // expected-error {{not yet supported}} > > + } > > +} > > + > > +namespace decl { > > + enum E : A {}; // expected-error{{requires template arguments; > > argument deduction not allowed here}} > > + struct F : A {}; // expected-error{{expected class name}} > > + > > + using B = A; // expected-error{{requires template arguments}} > > + > > + auto k() -> A; // expected-error{{requires template arguments}} > > + > > + A a; // expected-error {{requires an initializer}} > > + A b = 0; // expected-error {{not yet supported}} > > + A (parens) = 0; // expected-error {{cannot use parentheses when > > declaring variable with deduced class template specialization type}} > > + A *p = 0; // expected-error {{cannot form pointer to deduced class > > template specialization type}} > > + A &r = *p; // expected-error {{cannot form reference to deduced > > class template specialization type}} > > + A arr[3] = 0; // expected-error {{cannot form array of deduced > class > > template specialization type}} > > + A F::*pm = 0; // expected-error {{cannot form pointer to deduced > > class template specialization type}} > > + A (*fp)() = 0; // expected-error {{cannot form function returning > > deduced class template specialization type}} > > + A [x, y] = 0; // expected-error {{cannot be declared with type > 'A'}} > > expected-error {{not yet supported}} > > +} > > > > Modified: cfe/trunk/test/SemaTemplate/temp_arg.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/test/SemaTemplate/temp_arg.cpp?rev=293207&r1=293206&r > > 2=293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/test/SemaTemplate/temp_arg.cpp (original) > > +++ cfe/trunk/test/SemaTemplate/temp_arg.cpp Thu Jan 26 14:40:47 2017 > > @@ -10,7 +10,7 @@ A<int, 0, X> * a1; > > > > A<float, 1, X, double> *a2; // expected-error{{too many template > > arguments for class template 'A'}} > > A<float, 1> *a3; // expected-error{{too few template arguments for > > class template 'A'}} > > -A a3; // expected-error{{use of class template 'A' requires template > > arguments}} > > +A a4; // expected-error{{use of class template 'A' requires template > > arguments}} > > > > namespace test0 { > > template <class t> class foo {}; > > > > Modified: cfe/trunk/test/SemaTemplate/typename-specifier-3.cpp > > URL: http://llvm.org/viewvc/llvm- > > project/cfe/trunk/test/SemaTemplate/typename-specifier- > > 3.cpp?rev=293207&r1=293206&r2=293207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/test/SemaTemplate/typename-specifier-3.cpp (original) > > +++ cfe/trunk/test/SemaTemplate/typename-specifier-3.cpp Thu Jan 26 > > 14:40:47 2017 > > @@ -1,7 +1,7 @@ > > // RUN: %clang_cc1 -fsyntax-only -verify %s > > > > // PR4364 > > -template<class T> struct a { > > +template<class T> struct a { // expected-note {{here}} > > T b() { > > return typename T::x(); > > } > > @@ -17,3 +17,4 @@ B c() { > > // Some extra tests for invalid cases > > template<class T> struct test2 { T b() { return typename T::a; } }; > // > > expected-error{{expected '(' for function-style cast or type > > construction}} > > template<class T> struct test3 { T b() { return typename a; } }; // > > expected-error{{expected a qualified name after 'typename'}} > > +template<class T> struct test4 { T b() { return typename ::a; } }; > // > > expected-error{{refers to non-type member}} expected-error{{expected > > '(' for function-style cast or type construction}} > > > > Modified: cfe/trunk/tools/libclang/CIndex.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/tools/libclang/CIndex.cpp?rev=293207&r1=293206&r2=293 > > 207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/tools/libclang/CIndex.cpp (original) > > +++ cfe/trunk/tools/libclang/CIndex.cpp Thu Jan 26 14:40:47 2017 > > @@ -1640,6 +1640,15 @@ bool CursorVisitor::VisitAdjustedTypeLoc > > return Visit(TL.getOriginalLoc()); > > } > > > > +bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc( > > + DeducedTemplateSpecializationTypeLoc TL) { > > + if (VisitTemplateName(TL.getTypePtr()->getTemplateName(), > > + TL.getTemplateNameLoc())) > > + return true; > > + > > + return false; > > +} > > + > > bool CursorVisitor::VisitTemplateSpecializationTypeLoc( > > > > TemplateSpecializationTypeLoc TL) { > > // Visit the template name. > > > > Modified: cfe/trunk/tools/libclang/CXType.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/tools/libclang/CXType.cpp?rev=293207&r1=293206&r2=293 > > 207&view=diff > > > ======================================================================= > > ======= > > --- cfe/trunk/tools/libclang/CXType.cpp (original) > > +++ cfe/trunk/tools/libclang/CXType.cpp Thu Jan 26 14:40:47 2017 > > @@ -452,7 +452,8 @@ try_again: > > break; > > > > case Type::Auto: > > - TP = cast<AutoType>(TP)->getDeducedType().getTypePtrOrNull(); > > + case Type::DeducedTemplateSpecialization: > > + TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull(); > > if (TP) > > goto try_again; > > break; > > > > > > _______________________________________________ > > cfe-commits mailing list > > cfe-commits@lists.llvm.org > > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits