summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp12
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp13
-rw-r--r--clang/lib/AST/Type.cpp4
-rw-r--r--clang/lib/Parse/ParseExprCXX.cpp35
-rw-r--r--clang/lib/Parse/Parser.cpp1
-rw-r--r--clang/lib/Sema/SemaCXXScopeSpec.cpp67
-rw-r--r--clang/lib/Sema/TreeTransform.h3
7 files changed, 104 insertions, 31 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 9c2455034d6..ef9e7b31338 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2377,7 +2377,8 @@ ASTContext::getDependentTemplateSpecializationType(
const IdentifierInfo *Name,
unsigned NumArgs,
const TemplateArgument *Args) const {
- assert(NNS->isDependent() && "nested-name-specifier must be dependent");
+ assert((!NNS || NNS->isDependent()) &&
+ "nested-name-specifier must be dependent");
llvm::FoldingSetNodeID ID;
DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS,
@@ -3014,10 +3015,11 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
= T->getAs<DependentTemplateSpecializationType>()) {
NestedNameSpecifier *Prefix
= getCanonicalNestedNameSpecifier(DTST->getQualifier());
- TemplateName Name
- = getDependentTemplateName(Prefix, DTST->getIdentifier());
- T = getTemplateSpecializationType(Name,
- DTST->getArgs(), DTST->getNumArgs());
+
+ T = getDependentTemplateSpecializationType(DTST->getKeyword(),
+ Prefix, DTST->getIdentifier(),
+ DTST->getNumArgs(),
+ DTST->getArgs());
T = getCanonicalType(T);
}
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 939ca7a924a..8474ea36332 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -625,6 +625,17 @@ void CXXNameMangler::mangleUnresolvedScope(NestedNameSpecifier *Qualifier) {
TST->getNumArgs());
addSubstitution(QualType(TST, 0));
}
+ } else if (const DependentTemplateSpecializationType *DTST
+ = dyn_cast<DependentTemplateSpecializationType>(QTy)) {
+ TemplateName Template
+ = getASTContext().getDependentTemplateName(DTST->getQualifier(),
+ DTST->getIdentifier());
+ mangleTemplatePrefix(Template);
+
+ // FIXME: GCC does not appear to mangle the template arguments when
+ // the template in question is a dependent template name. Should we
+ // emulate that badness?
+ mangleTemplateArgs(Template, DTST->getArgs(), DTST->getNumArgs());
} else {
// We use the QualType mangle type variant here because it handles
// substitutions.
@@ -1596,7 +1607,7 @@ void CXXNameMangler::mangleType(const DependentNameType *T) {
}
void CXXNameMangler::mangleType(const DependentTemplateSpecializationType *T) {
- // Dependently-scoped template types are always nested
+ // Dependently-scoped template types are nested if they have a prefix.
Out << 'N';
// TODO: avoid making this TemplateName.
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index b03314e11d1..d1136adbab2 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -1040,9 +1040,9 @@ DependentTemplateSpecializationType::DependentTemplateSpecializationType(
QualType Canon)
: TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true,
/*VariablyModified=*/false,
- NNS->containsUnexpandedParameterPack()),
+ NNS && NNS->containsUnexpandedParameterPack()),
NNS(NNS), Name(Name), NumArgs(NumArgs) {
- assert(NNS && NNS->isDependent() &&
+ assert((!NNS || NNS->isDependent()) &&
"DependentTemplateSpecializatonType requires dependent qualifier");
for (unsigned I = 0; I != NumArgs; ++I) {
if (Args[I].containsUnexpandedParameterPack())
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index d8db711809e..a059e0b75a8 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -199,29 +199,32 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
if (TemplateId->Kind == TNK_Type_template ||
TemplateId->Kind == TNK_Dependent_template_name) {
- AnnotateTemplateIdTokenAsType(&SS);
-
- assert(Tok.is(tok::annot_typename) &&
- "AnnotateTemplateIdTokenAsType isn't working");
- Token TypeToken = Tok;
+ // Consume the template-id token.
ConsumeToken();
+
assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
SourceLocation CCLoc = ConsumeToken();
if (!HasScopeSpecifier)
HasScopeSpecifier = true;
-
- if (ParsedType T = getTypeAnnotation(TypeToken)) {
- if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), T, CCLoc, SS))
- SS.SetInvalid(SourceRange(SS.getBeginLoc(), CCLoc));
-
- continue;
- } else {
- SourceLocation Start = SS.getBeginLoc().isValid()? SS.getBeginLoc()
- : CCLoc;
- SS.SetInvalid(SourceRange(Start, CCLoc));
- }
+ ASTTemplateArgsPtr TemplateArgsPtr(Actions,
+ TemplateId->getTemplateArgs(),
+ TemplateId->NumArgs);
+
+ if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(),
+ /*FIXME:*/SourceLocation(),
+ SS,
+ TemplateId->Template,
+ TemplateId->TemplateNameLoc,
+ TemplateId->LAngleLoc,
+ TemplateArgsPtr,
+ TemplateId->RAngleLoc,
+ CCLoc,
+ EnteringContext))
+ SS.SetInvalid(SourceRange(SS.getBeginLoc(), CCLoc));
+
+ TemplateId->Destroy();
continue;
}
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 69d1853c0fe..3ed070321da 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1062,6 +1062,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) {
TemplateId->LAngleLoc,
TemplateArgsPtr,
TemplateId->RAngleLoc);
+ TemplateId->Destroy();
} else {
Diag(Tok, diag::err_expected_type_name_after_typename)
<< SS.getRange();
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index 7ad4b459451..8eb628f59bc 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -641,20 +641,73 @@ bool Sema::IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
}
bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
- ParsedType Type,
+ SourceLocation TemplateLoc,
+ CXXScopeSpec &SS,
+ TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgsIn,
+ SourceLocation RAngleLoc,
SourceLocation CCLoc,
- CXXScopeSpec &SS) {
+ bool EnteringContext) {
if (SS.isInvalid())
return true;
- TypeSourceInfo *TSInfo;
- QualType T = GetTypeFromParser(Type, &TSInfo);
+ // Translate the parser's template argument list in our AST format.
+ TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
+ translateTemplateArguments(TemplateArgsIn, TemplateArgs);
+
+ if (DependentTemplateName *DTN = Template.get().getAsDependentTemplateName()){
+ // Handle a dependent template specialization for which we cannot resolve
+ // the template name.
+ assert(DTN->getQualifier()
+ == static_cast<NestedNameSpecifier*>(SS.getScopeRep()));
+ QualType T = Context.getDependentTemplateSpecializationType(ETK_None,
+ DTN->getQualifier(),
+ DTN->getIdentifier(),
+ TemplateArgs);
+
+ // Create source-location information for this type.
+ TypeLocBuilder Builder;
+ DependentTemplateSpecializationTypeLoc SpecTL
+ = Builder.push<DependentTemplateSpecializationTypeLoc>(T);
+ SpecTL.setLAngleLoc(LAngleLoc);
+ SpecTL.setRAngleLoc(RAngleLoc);
+ SpecTL.setKeywordLoc(SourceLocation());
+ SpecTL.setNameLoc(TemplateNameLoc);
+ for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
+ SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
+
+ SS.Extend(Context, TemplateLoc, Builder.getTypeLocInContext(Context, T),
+ CCLoc);
+ return false;
+ }
+
+ // We were able to resolve the template name to an actual template.
+ // Build an appropriate nested-name-specifier.
+ QualType T = CheckTemplateIdType(Template.get(), TemplateNameLoc,
+ TemplateArgs);
if (T.isNull())
return true;
- assert(TSInfo && "Not TypeSourceInfo in nested-name-specifier?");
- // FIXME: location of the 'template' keyword?
- SS.Extend(Context, SourceLocation(), TSInfo->getTypeLoc(), CCLoc);
+ // FIXME: Template aliases will need to check the resulting type to make
+ // sure that it's either dependent or a tag type.
+
+ // Provide source-location information for the template specialization
+ // type.
+ TypeLocBuilder Builder;
+ TemplateSpecializationTypeLoc SpecTL
+ = Builder.push<TemplateSpecializationTypeLoc>(T);
+
+ SpecTL.setLAngleLoc(LAngleLoc);
+ SpecTL.setRAngleLoc(RAngleLoc);
+ SpecTL.setTemplateNameLoc(TemplateNameLoc);
+ for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
+ SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
+
+
+ SS.Extend(Context, TemplateLoc, Builder.getTypeLocInContext(Context, T),
+ CCLoc);
return false;
}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 57a44ad9d98..fa4637a27e8 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -754,6 +754,9 @@ public:
getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
if (T.isNull()) return QualType();
+ if (Keyword == ETK_None)
+ return T;
+
// NOTE: NNS is already recorded in template specialization type T.
return SemaRef.Context.getElaboratedType(Keyword, /*NNS=*/0, T);
}
OpenPOWER on IntegriCloud