majnemer updated this revision to Diff 37558. majnemer marked 2 inline comments as done. majnemer added a comment.
- Address Richard's review comments. 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/Builtins.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,12 @@ AddTemplateArgument(SubstPack->getArgumentPack(), Record); break; } + case TemplateName::BuiltinTemplate: { + BuiltinTemplateStorage *BTS = Name.getAsBuiltinTemplate(); + BuiltinTemplateNameKind BTNK = BTS->getKind(); + Record.push_back(BTNK); + 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,10 @@ return Context.getSubstTemplateTemplateParmPack(Param, ArgPack); } + case TemplateName::BuiltinTemplate: { + BuiltinTemplateNameKind BTNK = (BuiltinTemplateNameKind)Record[Idx++]; + return Context.getBuiltinTemplateName(BTNK); + } } 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 @@ -18,6 +18,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TypeVisitor.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/TargetInfo.h" @@ -2032,7 +2033,18 @@ DTN->getIdentifier(), TemplateArgs); - TemplateDecl *Template = Name.getAsTemplateDecl(); + BuiltinTemplateStorage *BTS = Name.getAsBuiltinTemplate(); + TemplateDecl *Template; + if (BTS) { + switch (BTS->getKind()) { + case BTNK__make_integer_seq: + Template = Context.getMakeIntegerSeqDecl(); + break; + } + } else { + Template = Name.getAsTemplateDecl(); + } + if (!Template || isa<FunctionTemplateDecl>(Template) || isa<VarTemplateDecl>(Template)) { // We might have a substituted template template parameter pack. If so, @@ -2171,6 +2183,42 @@ CanonType = Context.getTypeDeclType(Decl); assert(isa<RecordType>(CanonType) && "type of non-dependent specialization is not a RecordType"); + } else if (BTS) { + switch (BTS->getKind()) { + case BTNK__make_integer_seq: + // Instantiations involving __make_integer_seq<S, T, N> are treated like + // S<T, 0, ..., N-1>. + TemplateArgument NumArgsArg = Converted[2]; + llvm::APSInt NumArgs = NumArgsArg.getAsIntegral(); + + // Diagnose attempts to create integer sequences with a negative length. + if (NumArgs < 0) { + Diag(TemplateArgs[2].getLocation(), + diag::err_integer_sequence_negative_length); + return QualType(); + } + + QualType ArgTy = NumArgsArg.getIntegralType(); + TemplateArgumentListInfo SyntheticTemplateArgs; + // The type argument gets reused as the first template argument in the + // synthetic template argument list. + SyntheticTemplateArgs.addArgument(TemplateArgs[1]); + // Expand N into 0 ... N-1. + for (llvm::APSInt I(NumArgs.getBitWidth(), NumArgs.isUnsigned()); + I < NumArgs; ++I) { + TemplateArgument TA(Context, I, ArgTy); + Expr *E = + BuildExpressionFromIntegralTemplateArgument(TA, SourceLocation()) + .getAs<Expr>(); + SyntheticTemplateArgs.addArgument( + TemplateArgumentLoc(TemplateArgument(E), E)); + } + // The first template argument will be reused as the template decl that + // our synthetic template arguments will be applied to. + CanonType = CheckTemplateIdType(Converted[0].getAsTemplate(), TemplateLoc, + SyntheticTemplateArgs); + break; + } } // Build the fully-sugared type for this class template Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -727,6 +727,11 @@ return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); } +void Sema::actOnBuiltinTemplateName(TemplateTy &TemplateResult, + BuiltinTemplateNameKind BTNK) { + TemplateResult = TemplateTy::make(Context.getBuiltinTemplateName(BTNK)); +} + 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, BTNK__make_integer_seq); + + 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 @@ -16,6 +16,7 @@ #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/TemplateBase.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/LangOptions.h" #include "llvm/Support/raw_ostream.h" @@ -61,6 +62,8 @@ UncommonTemplateNameStorage *uncommon = Storage.get<UncommonTemplateNameStorage*>(); + if (uncommon->getAsBuiltinTemplate()) + return BuiltinTemplate; if (uncommon->getAsOverloadedStorage()) return OverloadedTemplate; if (uncommon->getAsSubstTemplateTemplateParm()) @@ -92,6 +95,12 @@ return Template->getDeclContext() && Template->getDeclContext()->isDependentContext(); } + if (BuiltinTemplateStorage *BTS = getAsBuiltinTemplate()) { + switch (BTS->getKind()) { + case BTNK__make_integer_seq: + return false; + } + } assert(!getAsOverloadedTemplate() && "overloaded templates shouldn't survive to here"); @@ -147,12 +156,17 @@ } 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 (BuiltinTemplateStorage *BTS = getAsBuiltinTemplate()) { + switch (BTS->getKind()) { + case BTNK__make_integer_seq: + OS << "__make_integer_seq"; + break; + } } } 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 builtin templates 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 @@ -18,6 +18,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/TypeLoc.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/IdentifierTable.h" #include "llvm/ADT/STLExtras.h" #include <memory> @@ -1191,3 +1192,65 @@ unsigned ID) { return new (C, ID) VarTemplatePartialSpecializationDecl(C); } + +static TemplateParameterList * +createMakeIntegerSeqParameterList(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()); +} + +static TemplateParameterList *createBuiltinTemplateParameterList( + const ASTContext &C, BuiltinTemplateNameKind BTNK, DeclContext *DC) { + switch (BTNK) { + case BTNK__make_integer_seq: + return createMakeIntegerSeqParameterList(C, DC); + } + + llvm_unreachable("unhandled BuiltinTemplateNameKind!"); +} + +void BuiltinTemplateDecl::anchor() {} + +BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, + BuiltinTemplateNameKind BTNK, + DeclContext *DC) + : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), DeclarationName(), + createBuiltinTemplateParameterList(C, BTNK, DC)), + BTNK(BTNK) {} 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,10 @@ return ToContext.getSubstTemplateTemplateParmPack(Param, ArgPack); } + case TemplateName::BuiltinTemplate: { + return ToContext.getBuiltinTemplateName( + From.getAsBuiltinTemplate()->getKind()); + } } llvm_unreachable("Invalid template name kind"); Index: lib/AST/ASTDumper.cpp =================================================================== --- lib/AST/ASTDumper.cpp +++ lib/AST/ASTDumper.cpp @@ -21,6 +21,7 @@ #include "clang/AST/DeclVisitor.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TypeVisitor.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/raw_ostream.h" @@ -447,6 +448,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 +1335,16 @@ VisitTemplateDecl(D, false); } +void ASTDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) { + dumpName(D); + switch (D->getBuiltinTemplateNameKind()) { + case BTNK__make_integer_seq: + OS << " __make_integer_seq"; + break; + } + 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), + MakeIntegerSeqDecl(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,22 @@ return ExternCContext; } +BuiltinTemplateDecl * +ASTContext::buildBuiltinTemplateDecl(BuiltinTemplateNameKind BTNK) const { + auto *BuiltinTemplate = + BuiltinTemplateDecl::Create(*this, BTNK, getTranslationUnitDecl()); + BuiltinTemplate->setImplicit(); + + return BuiltinTemplate; +} + +BuiltinTemplateDecl * +ASTContext::getMakeIntegerSeqDecl() const { + if (!MakeIntegerSeqDecl) + MakeIntegerSeqDecl = buildBuiltinTemplateDecl(BTNK__make_integer_seq); + return MakeIntegerSeqDecl; +} + RecordDecl *ASTContext::buildImplicitRecord(StringRef Name, RecordDecl::TagKind TK) const { SourceLocation Loc; @@ -4215,6 +4231,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 +4281,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 +6434,14 @@ ObjCConstantStringType = getObjCInterfaceType(Decl); } +/// \brief Retrieve the template name that corresponds to a __make_integer_seq. +TemplateName +ASTContext::getBuiltinTemplateName(BuiltinTemplateNameKind BTNK) const { + void *Memory = Allocate(sizeof(BuiltinTemplateStorage)); + auto *BTS = new (Memory) BuiltinTemplateStorage(BTNK); + 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,9 @@ QualType ObjectType, bool EnteringContext, bool &MemberOfUnknownSpecialization); + void actOnBuiltinTemplateName(TemplateTy &TemplateResult, + BuiltinTemplateNameKind BTNK); + 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/Basic/Builtins.h =================================================================== --- include/clang/Basic/Builtins.h +++ include/clang/Basic/Builtins.h @@ -206,5 +206,12 @@ }; } + +/// \brief Kinds of BuiltinTemplate TemplateNames. +enum BuiltinTemplateNameKind : int { + /// \brief This names the __make_integer_seq BuiltinTemplateDecl. + BTNK__make_integer_seq +}; + } // end namespace clang #endif Index: include/clang/AST/TemplateName.h =================================================================== --- include/clang/AST/TemplateName.h +++ include/clang/AST/TemplateName.h @@ -21,6 +21,8 @@ namespace clang { class ASTContext; +class BuiltinTemplateStorage; +enum BuiltinTemplateNameKind : int; class DependentTemplateName; class DiagnosticBuilder; class IdentifierInfo; @@ -41,6 +43,7 @@ class UncommonTemplateNameStorage { protected: enum Kind { + Builtin, Overloaded, SubstTemplateTemplateParm, SubstTemplateTemplateParmPack @@ -67,7 +70,13 @@ public: unsigned size() const { return Bits.Size; } - + + BuiltinTemplateStorage *getAsBuiltinTemplate() { + return Bits.Kind == Builtin + ? reinterpret_cast<BuiltinTemplateStorage *>(this) + : nullptr; + } + OverloadedTemplateStorage *getAsOverloadedStorage() { return Bits.Kind == Overloaded ? reinterpret_cast<OverloadedTemplateStorage *>(this) @@ -86,7 +95,20 @@ : nullptr; } }; - + +/// \brief A structure for storing the information associated with an +/// builtin template name. +class BuiltinTemplateStorage : public UncommonTemplateNameStorage { + friend class ASTContext; + BuiltinTemplateNameKind BTNK; + +public: + BuiltinTemplateStorage(BuiltinTemplateNameKind BTNK) + : UncommonTemplateNameStorage(Builtin, 0), BTNK(BTNK) {} + + BuiltinTemplateNameKind getKind() const { return BTNK; } +}; + /// \brief A structure for storing the information associated with an /// overloaded template name. class OverloadedTemplateStorage : public UncommonTemplateNameStorage { @@ -189,25 +211,28 @@ enum NameKind { /// \brief A single template declaration. Template, + /// \brief A builtin, compiler defined template. + 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); @@ -285,6 +310,13 @@ return Storage.dyn_cast<DependentTemplateName *>(); } + /// \brief Retrieve the underlying builtin template name structure, if any. + BuiltinTemplateStorage *getAsBuiltinTemplate() const { + if (auto *Uncommon = Storage.dyn_cast<UncommonTemplateNameStorage *>()) + return Uncommon->getAsBuiltinTemplate(); + return nullptr; + } + TemplateName getUnderlying() const; /// \brief Determines whether this is a dependent template name. 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 @@ -25,6 +25,7 @@ namespace clang { +enum BuiltinTemplateNameKind : int; class TemplateParameterList; class TemplateDecl; class RedeclarableTemplateDecl; @@ -1490,6 +1491,34 @@ 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, BuiltinTemplateNameKind BTNK, + DeclContext *DC); + + BuiltinTemplateNameKind BTNK; + +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, BuiltinTemplateNameKind BTNK, DeclContext *DC) { + return new (C, DC) BuiltinTemplateDecl(C, BTNK, DC); + } + + SourceRange getSourceRange() const override LLVM_READONLY { + return SourceRange(); + } + + BuiltinTemplateNameKind getBuiltinTemplateNameKind() const { return BTNK; } +}; + /// \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 @@ -70,6 +70,7 @@ class VTableContextBase; namespace Builtin { class Context; } + enum BuiltinTemplateNameKind : int; namespace comments { class FullComment; @@ -399,6 +400,7 @@ TranslationUnitDecl *TUDecl; mutable ExternCContextDecl *ExternCContext; + mutable BuiltinTemplateDecl *MakeIntegerSeqDecl; /// \brief The associated SourceManager object.a SourceManager &SourceMgr; @@ -821,6 +823,7 @@ TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; } ExternCContextDecl *getExternCContextDecl() const; + BuiltinTemplateDecl *getMakeIntegerSeqDecl() const; // Builtin Types. CanQualType VoidTy; @@ -894,6 +897,9 @@ void PrintStats() const; const SmallVectorImpl<Type *>& getTypes() const { return Types; } + BuiltinTemplateDecl * + buildBuiltinTemplateDecl(BuiltinTemplateNameKind BTNK) const; + /// \brief Create a new implicit TU-level CXXRecordDecl or RecordDecl /// declaration. RecordDecl *buildImplicitRecord(StringRef Name, @@ -1650,6 +1656,8 @@ DeclarationNameInfo getNameForTemplate(TemplateName Name, SourceLocation NameLoc) const; + TemplateName getBuiltinTemplateName(BuiltinTemplateNameKind BTNK) 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