majnemer updated this revision to Diff 37518. majnemer added a comment. - Add an llvm_unreachable to ASTDeclReader::VisitBuiltinTemplateDecl
http://reviews.llvm.org/D13786 Files: include/clang/AST/ASTContext.h include/clang/AST/DataRecursiveASTVisitor.h include/clang/AST/DeclTemplate.h include/clang/AST/RecursiveASTVisitor.h include/clang/AST/TemplateName.h include/clang/Basic/DeclNodes.td include/clang/Basic/DiagnosticSemaKinds.td include/clang/Basic/TokenKinds.def include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/ASTDumper.cpp lib/AST/ASTImporter.cpp lib/AST/DeclBase.cpp lib/AST/DeclTemplate.cpp lib/AST/ItaniumMangle.cpp lib/AST/TemplateName.cpp lib/AST/Type.cpp lib/CodeGen/CGDecl.cpp lib/Parse/ParseDecl.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTCommon.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp tools/libclang/CIndex.cpp
Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -1392,6 +1392,9 @@ return Visit(MakeCursorTemplateRef( Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), Loc, TU)); + + case TemplateName::BuiltinTemplate: + return false; } llvm_unreachable("Invalid TemplateName::Kind!"); @@ -5110,6 +5113,7 @@ case Decl::Import: case Decl::OMPThreadPrivate: case Decl::ObjCTypeParam: + case Decl::BuiltinTemplate: return C; // Declaration kinds that don't make any sense here, but are Index: lib/Serialization/ASTWriter.cpp =================================================================== --- lib/Serialization/ASTWriter.cpp +++ lib/Serialization/ASTWriter.cpp @@ -5246,6 +5246,9 @@ AddTemplateArgument(SubstPack->getArgumentPack(), Record); break; } + case TemplateName::BuiltinTemplate: { + break; + } } } Index: lib/Serialization/ASTReaderDecl.cpp =================================================================== --- lib/Serialization/ASTReaderDecl.cpp +++ lib/Serialization/ASTReaderDecl.cpp @@ -293,6 +293,7 @@ DeclID VisitTemplateDecl(TemplateDecl *D); RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D); void VisitClassTemplateDecl(ClassTemplateDecl *D); + void VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D); void VisitVarTemplateDecl(VarTemplateDecl *D); void VisitFunctionTemplateDecl(FunctionTemplateDecl *D); void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); @@ -1856,6 +1857,10 @@ } } +void ASTDeclReader::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) { + llvm_unreachable("BuiltinTemplates are not serialized"); +} + /// TODO: Unify with ClassTemplateDecl version? /// May require unifying ClassTemplateDecl and /// VarTemplateDecl beyond TemplateDecl... Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -7619,6 +7619,9 @@ return Context.getSubstTemplateTemplateParmPack(Param, ArgPack); } + case TemplateName::BuiltinTemplate: { + return Context.getBuiltinTemplateName(); + } } llvm_unreachable("Unhandled template name kind!"); Index: lib/Serialization/ASTCommon.cpp =================================================================== --- lib/Serialization/ASTCommon.cpp +++ lib/Serialization/ASTCommon.cpp @@ -329,6 +329,7 @@ case Decl::ClassScopeFunctionSpecialization: case Decl::Import: case Decl::OMPThreadPrivate: + case Decl::BuiltinTemplate: return false; // These indirectly derive from Redeclarable<T> but are not actually Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -3454,6 +3454,9 @@ SubstPack->getArgumentPack()); } + if (Name.getKind() == TemplateName::BuiltinTemplate) + return Name; + // These should be getting filtered out before they reach the AST. llvm_unreachable("overloaded function decl survived to here"); } Index: lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -922,6 +922,11 @@ llvm_unreachable("EnumConstantDecls can only occur within EnumDecls."); } +Decl * +TemplateDeclInstantiator::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) { + llvm_unreachable("BuiltinTemplateDecls cannot be instantiated."); +} + Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { bool isFriend = (D->getFriendObjectKind() != Decl::FOK_None); Index: lib/Sema/SemaTemplate.cpp =================================================================== --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -2017,9 +2017,9 @@ } } -QualType Sema::CheckTemplateIdType(TemplateName Name, - SourceLocation TemplateLoc, - TemplateArgumentListInfo &TemplateArgs) { +QualType +Sema::CheckTemplateIdType(TemplateName Name, SourceLocation TemplateLoc, + TemplateArgumentListInfo &UnderlyingTemplateArgs) { DependentTemplateName *DTN = Name.getUnderlying().getAsDependentTemplateName(); if (DTN && DTN->isIdentifier()) @@ -2030,15 +2030,19 @@ return Context.getDependentTemplateSpecializationType(ETK_None, DTN->getQualifier(), DTN->getIdentifier(), - TemplateArgs); + UnderlyingTemplateArgs); + + bool IsBuiltinTemplate = Name.getKind() == TemplateName::BuiltinTemplate; + TemplateDecl *Template = IsBuiltinTemplate ? Context.getBuiltinTemplateDecl() + : Name.getAsTemplateDecl(); - TemplateDecl *Template = Name.getAsTemplateDecl(); if (!Template || isa<FunctionTemplateDecl>(Template) || isa<VarTemplateDecl>(Template)) { // We might have a substituted template template parameter pack. If so, // build a template specialization type for it. if (Name.getAsSubstTemplateTemplateParmPack()) - return Context.getTemplateSpecializationType(Name, TemplateArgs); + return Context.getTemplateSpecializationType(Name, + UnderlyingTemplateArgs); Diag(TemplateLoc, diag::err_template_id_not_a_type) << Name; @@ -2049,10 +2053,57 @@ // Check that the template argument list is well-formed for this // template. SmallVector<TemplateArgument, 4> Converted; - if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs, + if (CheckTemplateArgumentList(Template, TemplateLoc, UnderlyingTemplateArgs, false, Converted)) return QualType(); + // Instantiations involving __make_integer_seq<S, T, N> are treated like + // S<T, 0, ..., N-1>. + TemplateArgumentListInfo SyntheticTemplateArgs; + TemplateName UnderlyingName = Name; + bool UseSyntheticTemplateArgs = false; + if (IsBuiltinTemplate) { + assert(Converted.size() == 3 && "Unexpected BuiltinTemplate!"); + + // Switch our template from __make_integer_seq to S. + Name = Converted[0].getAsTemplate(); + Template = Name.getAsTemplateDecl(); + TemplateArgument NumArgsArg = Converted[2]; + if (!NumArgsArg.isDependent()) { + // The first template argument will be reused as the template decl that + // our synthetic template arguments will be applied to while the last + // template argument will be replaced with a pack. + TemplateArgument SequenceType = Converted[1]; + Converted.clear(); + Converted.push_back(SequenceType); + UseSyntheticTemplateArgs = true; + + // Diagnose attempts to create integer sequences with a negative length. + llvm::APSInt NumArgs = NumArgsArg.getAsIntegral(); + if (NumArgs < 0) + Diag(UnderlyingTemplateArgs[2].getLocation(), + diag::err_integer_sequence_negative_length); + + QualType Ty = NumArgsArg.getIntegralType(); + SmallVector<TemplateArgument, 2> ArgumentPack; + for (llvm::APSInt I(NumArgs.getBitWidth(), NumArgs.isUnsigned()); + I < NumArgs; ++I) { + TemplateArgument TA(Context, I, Ty); + Expr *E = + BuildExpressionFromIntegralTemplateArgument(TA, SourceLocation()) + .getAs<Expr>(); + ArgumentPack.push_back(TA); + SyntheticTemplateArgs.addArgument( + TemplateArgumentLoc(TemplateArgument(E), E)); + } + Converted.push_back( + TemplateArgument::CreatePackCopy(Context, ArgumentPack)); + } + } + + TemplateArgumentListInfo &TemplateArgs = + UseSyntheticTemplateArgs ? SyntheticTemplateArgs : UnderlyingTemplateArgs; + QualType CanonType; bool InstantiationDependent = false; @@ -2085,15 +2136,15 @@ return QualType(); } else if (Name.isDependent() || TemplateSpecializationType::anyDependentTemplateArguments( - TemplateArgs, InstantiationDependent)) { + TemplateArgs, InstantiationDependent)) { // This class template specialization is a dependent // type. Therefore, its canonical type is another class template // specialization type that contains all of the converted // arguments in canonical form. This ensures that, e.g., A<T> and // A<T, T> have identical types when A is declared as: // // template<typename T, typename U = T> struct A; - TemplateName CanonName = Context.getCanonicalTemplateName(Name); + TemplateName CanonName = Context.getCanonicalTemplateName(UnderlyingName); CanonType = Context.getTemplateSpecializationType(CanonName, Converted.data(), Converted.size()); @@ -2176,7 +2227,8 @@ // Build the fully-sugared type for this class template // specialization, which refers back to the class template // specialization we created or found. - return Context.getTemplateSpecializationType(Name, TemplateArgs, CanonType); + return Context.getTemplateSpecializationType( + UnderlyingName, UnderlyingTemplateArgs, CanonType); } TypeResult Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -727,6 +727,10 @@ return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); } +void Sema::actOnBuiltinTemplateName(TemplateTy &TemplateResult) { + TemplateResult = TemplateTy::make(Context.getBuiltinTemplateName()); +} + Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, SourceLocation NameLoc, const Token &NextToken, Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -2895,6 +2895,63 @@ continue; } + case tok::kw___make_integer_seq: { + assert(getLangOpts().CPlusPlus && + "Can only annotate template-ids in C++"); + TemplateTy Template; + Actions.actOnBuiltinTemplateName(Template); + + if (!NextToken().is(tok::less)) { + DS.SetTypeSpecError(); + break; + } + + // Consume the template-name. + SourceLocation TemplateNameLoc = ConsumeToken(); + + assert(Template && Tok.is(tok::less) && + "Parser isn't at the beginning of a template-id"); + + // Parse the enclosed template argument list. + SourceLocation LAngleLoc, RAngleLoc, TemplateKWLoc; + TemplateArgList TemplateArgs; + CXXScopeSpec SS; + bool IsInvalid = + ParseTemplateIdAfterTemplateName(Template, TemplateNameLoc, SS, false, + LAngleLoc, TemplateArgs, RAngleLoc); + + if (IsInvalid) { + // If we failed to parse the template ID but skipped ahead to a >, + // we're not going to be able to form a token annotation. + // Eat the '>' if present. + TryConsumeToken(tok::greater); + DS.SetTypeSpecError(); + break; + } + + ASTTemplateArgsPtr TemplateArgsPtr(TemplateArgs); + TypeResult Type = Actions.ActOnTemplateIdType(SS, TemplateKWLoc, Template, + TemplateNameLoc, LAngleLoc, + TemplateArgsPtr, RAngleLoc); + if (Type.isInvalid()) { + // If we failed to parse the template ID but skipped ahead to a >, we're + // not + // going to be able to form a token annotation. Eat the '>' if present. + TryConsumeToken(tok::greater); + DS.SetTypeSpecError(); + break; + } + + Tok.setKind(tok::annot_typename); + setTypeAnnotation(Tok, Type.get()); + Tok.setLocation(TemplateNameLoc); + Tok.setAnnotationEndLoc(RAngleLoc); + // In case the tokens were cached, have Preprocessor replace them with the + // annotation token. + PP.AnnotateCachedTokens(Tok); + continue; + } + case tok::kw___is_signed: // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang // typically treats it as a trait. If we see __is_signed as it appears Index: lib/CodeGen/CGDecl.cpp =================================================================== --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -35,6 +35,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) { switch (D.getKind()) { + case Decl::BuiltinTemplate: case Decl::TranslationUnit: case Decl::ExternCContext: case Decl::Namespace: Index: lib/AST/Type.cpp =================================================================== --- lib/AST/Type.cpp +++ lib/AST/Type.cpp @@ -3105,7 +3105,8 @@ "Use DependentTemplateSpecializationType for dependent template-name"); assert((T.getKind() == TemplateName::Template || T.getKind() == TemplateName::SubstTemplateTemplateParm || - T.getKind() == TemplateName::SubstTemplateTemplateParmPack) && + T.getKind() == TemplateName::SubstTemplateTemplateParmPack || + T.getKind() == TemplateName::BuiltinTemplate) && "Unexpected template name for TemplateSpecializationType"); TemplateArgument *TemplateArgs Index: lib/AST/TemplateName.cpp =================================================================== --- lib/AST/TemplateName.cpp +++ lib/AST/TemplateName.cpp @@ -61,6 +61,8 @@ UncommonTemplateNameStorage *uncommon = Storage.get<UncommonTemplateNameStorage*>(); + if (uncommon->isBuiltin()) + return BuiltinTemplate; if (uncommon->getAsOverloadedStorage()) return OverloadedTemplate; if (uncommon->getAsSubstTemplateTemplateParm()) @@ -147,12 +149,13 @@ } else if (SubstTemplateTemplateParmStorage *subst = getAsSubstTemplateTemplateParm()) { subst->getReplacement().print(OS, Policy, SuppressNNS); - } else if (SubstTemplateTemplateParmPackStorage *SubstPack - = getAsSubstTemplateTemplateParmPack()) + } else if (SubstTemplateTemplateParmPackStorage *SubstPack = + getAsSubstTemplateTemplateParmPack()) { OS << *SubstPack->getParameterPack(); - else { - OverloadedTemplateStorage *OTS = getAsOverloadedTemplate(); + } else if (OverloadedTemplateStorage *OTS = getAsOverloadedTemplate()) { (*OTS->begin())->printName(OS); + } else if (getKind() == BuiltinTemplate) { + OS << "__make_integer_seq"; } } Index: lib/AST/ItaniumMangle.cpp =================================================================== --- lib/AST/ItaniumMangle.cpp +++ lib/AST/ItaniumMangle.cpp @@ -1442,6 +1442,14 @@ case TemplateName::OverloadedTemplate: llvm_unreachable("can't mangle an overloaded template name as a <type>"); + case TemplateName::BuiltinTemplate: { + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = + Diags.getCustomDiagID(DiagnosticsEngine::Error, + "mangling __make_integer_seq is not supported"); + Diags.Report(DiagID); + } + case TemplateName::DependentTemplate: { const DependentTemplateName *Dependent = TN.getAsDependentTemplateName(); assert(Dependent->isIdentifier()); @@ -1572,6 +1580,7 @@ break; } + case TemplateName::BuiltinTemplate: case TemplateName::OverloadedTemplate: case TemplateName::DependentTemplate: llvm_unreachable("invalid base for a template specialization type"); Index: lib/AST/DeclTemplate.cpp =================================================================== --- lib/AST/DeclTemplate.cpp +++ lib/AST/DeclTemplate.cpp @@ -1191,3 +1191,52 @@ unsigned ID) { return new (C, ID) VarTemplatePartialSpecializationDecl(C); } + +static TemplateParameterList * +createBuiltinTemplateParameterList(const ASTContext &C, DeclContext *DC) { + // typename T + auto *T = TemplateTypeParmDecl::Create( + C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0, + /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false); + + // Ints... + TypeSourceInfo *TI = + C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0)); + auto *N = NonTypeTemplateParmDecl::Create( + C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, + /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI); + + // <typename T, Ints...> + NamedDecl *P[2] = {T, N}; + auto *TPL = TemplateParameterList::Create( + C, SourceLocation(), SourceLocation(), P, 2, SourceLocation()); + + // template <typename T, Ints...> class IntSeq + auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create( + C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0, + /*ParameterPack=*/false, /*Id=*/nullptr, TPL); + + // typename T + auto *TemplateTypeParm = TemplateTypeParmDecl::Create( + C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, + /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false); + + // Ints... + TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo( + QualType(TemplateTypeParm->getTypeForDecl(), 0)); + auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create( + C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2, + /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo); + NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm, + NonTypeTemplateParm}; + + // template <template <typename T, Ints...> class IntSeq, typename T, Ints...> + return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), + Params, 3, SourceLocation()); +} + +void BuiltinTemplateDecl::anchor() {} + +BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC) + : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), DeclarationName(), + createBuiltinTemplateParameterList(C, DC)) {} Index: lib/AST/DeclBase.cpp =================================================================== --- lib/AST/DeclBase.cpp +++ lib/AST/DeclBase.cpp @@ -639,6 +639,7 @@ case ExternCContext: case UsingDirective: + case BuiltinTemplate: case ClassTemplateSpecialization: case ClassTemplatePartialSpecialization: case ClassScopeFunctionSpecialization: Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -5666,6 +5666,9 @@ return ToContext.getSubstTemplateTemplateParmPack(Param, ArgPack); } + case TemplateName::BuiltinTemplate: { + return ToContext.getBuiltinTemplateName(); + } } llvm_unreachable("Invalid template name kind"); Index: lib/AST/ASTDumper.cpp =================================================================== --- lib/AST/ASTDumper.cpp +++ lib/AST/ASTDumper.cpp @@ -447,6 +447,7 @@ const ClassTemplatePartialSpecializationDecl *D); void VisitClassScopeFunctionSpecializationDecl( const ClassScopeFunctionSpecializationDecl *D); + void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D); void VisitVarTemplateDecl(const VarTemplateDecl *D); void VisitVarTemplateSpecializationDecl( const VarTemplateSpecializationDecl *D); @@ -1333,6 +1334,11 @@ VisitTemplateDecl(D, false); } +void ASTDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) { + dumpName(D); + dumpTemplateParameters(D->getTemplateParameters()); +} + void ASTDumper::VisitVarTemplateSpecializationDecl( const VarTemplateSpecializationDecl *D) { dumpTemplateArgumentList(D->getTemplateArgs()); Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -741,7 +741,7 @@ ucontext_tDecl(nullptr), BlockDescriptorType(nullptr), BlockDescriptorExtendedType(nullptr), cudaConfigureCallDecl(nullptr), FirstLocalImport(), LastLocalImport(), ExternCContext(nullptr), - SourceMgr(SM), LangOpts(LOpts), + BuiltinTemplate(nullptr), SourceMgr(SM), LangOpts(LOpts), SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)), AddrSpaceMap(nullptr), Target(nullptr), AuxTarget(nullptr), PrintingPolicy(LOpts), Idents(idents), Selectors(sels), @@ -904,6 +904,16 @@ return ExternCContext; } +BuiltinTemplateDecl *ASTContext::getBuiltinTemplateDecl() const { + if (!BuiltinTemplate) { + BuiltinTemplate = + BuiltinTemplateDecl::Create(*this, getTranslationUnitDecl()); + BuiltinTemplate->setImplicit(); + } + + return BuiltinTemplate; +} + RecordDecl *ASTContext::buildImplicitRecord(StringRef Name, RecordDecl::TagKind TK) const { SourceLocation Loc; @@ -4215,6 +4225,8 @@ ASTContext::getNameForTemplate(TemplateName Name, SourceLocation NameLoc) const { switch (Name.getKind()) { + case TemplateName::BuiltinTemplate: + return DeclarationNameInfo(); case TemplateName::QualifiedTemplate: case TemplateName::Template: // DNInfo work in progress: CHECKME: what about DNLoc? @@ -4263,6 +4275,8 @@ TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) const { switch (Name.getKind()) { + case TemplateName::BuiltinTemplate: + return Name; case TemplateName::QualifiedTemplate: case TemplateName::Template: { TemplateDecl *Template = Name.getAsTemplateDecl(); @@ -6414,6 +6428,13 @@ ObjCConstantStringType = getObjCInterfaceType(Decl); } +/// \brief Retrieve the template name that corresponds to a __make_integer_seq. +TemplateName ASTContext::getBuiltinTemplateName() const { + void *Memory = Allocate(sizeof(BuiltinTemplateStorage)); + auto *BTS = new (Memory) BuiltinTemplateStorage(); + return TemplateName(BTS); +} + /// \brief Retrieve the template name that corresponds to a non-empty /// lookup. TemplateName Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -5498,6 +5498,8 @@ QualType ObjectType, bool EnteringContext, bool &MemberOfUnknownSpecialization); + void actOnBuiltinTemplateName(TemplateTy &TemplateResult); + TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS, bool hasTemplateKeyword, Index: include/clang/Basic/TokenKinds.def =================================================================== --- include/clang/Basic/TokenKinds.def +++ include/clang/Basic/TokenKinds.def @@ -479,6 +479,7 @@ KEYWORD(__fastcall , KEYALL) KEYWORD(__thiscall , KEYALL) KEYWORD(__vectorcall , KEYALL) +KEYWORD(__make_integer_seq , KEYCXX) KEYWORD(__forceinline , KEYMS) KEYWORD(__unaligned , KEYMS) KEYWORD(__super , KEYMS) Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -1992,7 +1992,11 @@ def warn_cxx98_compat_unicode_type : Warning< "'%0' type specifier is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; - + +// __make_integer_seq +def err_integer_sequence_negative_length : Error< + "integer sequences cannot have a negative sequence length">; + // Objective-C++ def err_objc_decls_may_only_appear_in_global_scope : Error< "Objective-C declarations may only appear in global scope">; Index: include/clang/Basic/DeclNodes.td =================================================================== --- include/clang/Basic/DeclNodes.td +++ include/clang/Basic/DeclNodes.td @@ -59,6 +59,7 @@ def VarTemplate : DDecl<RedeclarableTemplate>; def TypeAliasTemplate : DDecl<RedeclarableTemplate>; def TemplateTemplateParm : DDecl<Template>; + def BuiltinTemplate : DDecl<Template>; def Using : DDecl<Named>; def UsingShadow : DDecl<Named>; def ObjCMethod : DDecl<Named>, DeclContext; Index: include/clang/AST/TemplateName.h =================================================================== --- include/clang/AST/TemplateName.h +++ include/clang/AST/TemplateName.h @@ -41,6 +41,7 @@ class UncommonTemplateNameStorage { protected: enum Kind { + Builtin, Overloaded, SubstTemplateTemplateParm, SubstTemplateTemplateParmPack @@ -67,7 +68,9 @@ public: unsigned size() const { return Bits.Size; } - + + bool isBuiltin() { return Bits.Kind == Builtin; } + OverloadedTemplateStorage *getAsOverloadedStorage() { return Bits.Kind == Overloaded ? reinterpret_cast<OverloadedTemplateStorage *>(this) @@ -86,7 +89,16 @@ : nullptr; } }; - + +/// \brief A structure for storing the information associated with an +/// builtin template name. +class BuiltinTemplateStorage : public UncommonTemplateNameStorage { + friend class ASTContext; + +public: + BuiltinTemplateStorage() : UncommonTemplateNameStorage(Builtin, 0) {} +}; + /// \brief A structure for storing the information associated with an /// overloaded template name. class OverloadedTemplateStorage : public UncommonTemplateNameStorage { @@ -189,25 +201,28 @@ enum NameKind { /// \brief A single template declaration. Template, + /// \brief An instance of __make_integer_seq. + BuiltinTemplate, /// \brief A set of overloaded template declarations. OverloadedTemplate, - /// \brief A qualified template name, where the qualification is kept + /// \brief A qualified template name, where the qualification is kept /// to describe the source code as written. QualifiedTemplate, - /// \brief A dependent template name that has not been resolved to a + /// \brief A dependent template name that has not been resolved to a /// template (or set of templates). DependentTemplate, /// \brief A template template parameter that has been substituted /// for some other template name. SubstTemplateTemplateParm, - /// \brief A template template parameter pack that has been substituted for + /// \brief A template template parameter pack that has been substituted for /// a template template argument pack, but has not yet been expanded into /// individual arguments. SubstTemplateTemplateParmPack }; TemplateName() : Storage() { } explicit TemplateName(TemplateDecl *Template) : Storage(Template) { } + explicit TemplateName(BuiltinTemplateStorage *Storage) : Storage(Storage) {} explicit TemplateName(OverloadedTemplateStorage *Storage) : Storage(Storage) { } explicit TemplateName(SubstTemplateTemplateParmStorage *Storage); Index: include/clang/AST/RecursiveASTVisitor.h =================================================================== --- include/clang/AST/RecursiveASTVisitor.h +++ include/clang/AST/RecursiveASTVisitor.h @@ -1603,6 +1603,10 @@ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); }) +DEF_TRAVERSE_DECL(BuiltinTemplateDecl, { + TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); +}) + DEF_TRAVERSE_DECL(TemplateTypeParmDecl, { // D is the "T" in something like "template<typename T> class vector;" if (D->getTypeForDecl()) Index: include/clang/AST/DeclTemplate.h =================================================================== --- include/clang/AST/DeclTemplate.h +++ include/clang/AST/DeclTemplate.h @@ -1490,6 +1490,28 @@ friend TrailingObjects; }; +/// \brief Represents the builtin template declaration which is used to +/// implement __make_integer_seq. It serves no real purpose beyond existing as +/// a place to hold template parameters. +class BuiltinTemplateDecl : public TemplateDecl { + void anchor() override; + + BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC); + +public: + // Implement isa/cast/dyncast support + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == BuiltinTemplate; } + + static BuiltinTemplateDecl *Create(const ASTContext &C, DeclContext *DC) { + return new (C, DC) BuiltinTemplateDecl(C, DC); + } + + SourceRange getSourceRange() const override LLVM_READONLY { + return SourceRange(); + } +}; + /// \brief Represents a class template specialization, which refers to /// a class template with a given set of template arguments. /// Index: include/clang/AST/DataRecursiveASTVisitor.h =================================================================== --- include/clang/AST/DataRecursiveASTVisitor.h +++ include/clang/AST/DataRecursiveASTVisitor.h @@ -1551,6 +1551,10 @@ TRY_TO(TraverseFunctionInstantiations(D)); }) +DEF_TRAVERSE_DECL(BuiltinTemplateDecl, { + TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); +}) + DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, { // D is the "T" in something like // template <template <typename> class T> class container { }; Index: include/clang/AST/ASTContext.h =================================================================== --- include/clang/AST/ASTContext.h +++ include/clang/AST/ASTContext.h @@ -399,6 +399,7 @@ TranslationUnitDecl *TUDecl; mutable ExternCContextDecl *ExternCContext; + mutable BuiltinTemplateDecl *BuiltinTemplate; /// \brief The associated SourceManager object.a SourceManager &SourceMgr; @@ -821,6 +822,7 @@ TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; } ExternCContextDecl *getExternCContextDecl() const; + BuiltinTemplateDecl *getBuiltinTemplateDecl() const; // Builtin Types. CanQualType VoidTy; @@ -1650,6 +1652,8 @@ DeclarationNameInfo getNameForTemplate(TemplateName Name, SourceLocation NameLoc) const; + TemplateName getBuiltinTemplateName() const; + TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin, UnresolvedSetIterator End) const;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits