bool Sema::ActOnCXXNestedNameSpecifier(Scope *S, SourceLocation TemplateLoc, CXXScopeSpec &SS, TemplateTy Template, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgsIn, SourceLocation RAngleLoc, SourceLocation CCLoc, bool EnteringContext) { if (SS.isInvalid()) return true; // 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); SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); 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; } if (Template.get().getAsOverloadedTemplate() || isa<FunctionTemplateDecl>(Template.get().getAsTemplateDecl())) { SourceRange R(TemplateNameLoc, RAngleLoc); if (SS.getRange().isValid()) R.setBegin(SS.getRange().getBegin()); Diag(CCLoc, diag::err_non_type_template_in_nested_name_specifier) << Template.get() << R; NoteAllFoundTemplates(Template.get()); return true; } // 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; // Alias template specializations can produce types which are not valid // nested name specifiers. if (!T->isDependentType() && !T->getAs<TagType>()) { Diag(TemplateNameLoc, diag::err_nested_name_spec_non_tag) << T; NoteAllFoundTemplates(Template.get()); return true; } // 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; }