majnemer updated this revision to Diff 37612.
majnemer added a comment.
- Add an llvm_unreachable to ASTDeclReader::VisitBuiltinTemplateDecl
- Address Richard's review comments.
- Add logic to check [intseq.intseq]p1.
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,51 @@
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:
+ // Specializations of __make_integer_seq<S, T, N> are treated like
+ // S<T, 0, ..., N-1>.
+
+ // C++14 [inteseq.intseq]p1:
+ // T shall be an integer type.
+ if (!Converted[1].getAsType()->isIntegralType(Context)) {
+ Diag(TemplateArgs[1].getLocation(),
+ diag::err_integer_sequence_integral_element_type);
+ return QualType();
+ }
+
+ // C++14 [inteseq.make]p1:
+ // If N is negative the program is ill-formed.
+ TemplateArgument NumArgsArg = Converted[2];
+ llvm::APSInt NumArgs = NumArgsArg.getAsIntegral();
+ 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
@@ -1993,7 +1993,13 @@
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 must have non-negative sequence length">;
+def err_integer_sequence_integral_element_type : Error<
+ "integer sequences must have integral element type">;
+
// 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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits