diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 12 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 13 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 35 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCXXScopeSpec.cpp | 67 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 3 |
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); } |