diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp | 726 |
1 files changed, 461 insertions, 265 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp index f02dd25..ef09124 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp @@ -76,13 +76,13 @@ static NamedDecl *isAcceptableTemplateName(ASTContext &Context, return 0; } -static void FilterAcceptableTemplateNames(ASTContext &C, LookupResult &R) { +void Sema::FilterAcceptableTemplateNames(LookupResult &R) { // The set of class templates we've already seen. llvm::SmallPtrSet<ClassTemplateDecl *, 8> ClassTemplates; LookupResult::Filter filter = R.makeFilter(); while (filter.hasNext()) { NamedDecl *Orig = filter.next(); - NamedDecl *Repl = isAcceptableTemplateName(C, Orig); + NamedDecl *Repl = isAcceptableTemplateName(Context, Orig); if (!Repl) filter.erase(); else if (Repl != Orig) { @@ -114,6 +114,14 @@ static void FilterAcceptableTemplateNames(ASTContext &C, LookupResult &R) { filter.done(); } +bool Sema::hasAnyAcceptableTemplateNames(LookupResult &R) { + for (LookupResult::iterator I = R.begin(), IEnd = R.end(); I != IEnd; ++I) + if (isAcceptableTemplateName(Context, *I)) + return true; + + return false; +} + TemplateNameKind Sema::isTemplateName(Scope *S, CXXScopeSpec &SS, bool hasTemplateKeyword, @@ -289,7 +297,7 @@ void Sema::LookupTemplateName(LookupResult &Found, DeclarationName Name = Found.getLookupName(); if (DeclarationName Corrected = CorrectTypo(Found, S, &SS, LookupCtx, false, CTC_CXXCasts)) { - FilterAcceptableTemplateNames(Context, Found); + FilterAcceptableTemplateNames(Found); if (!Found.empty()) { if (LookupCtx) Diag(Found.getNameLoc(), diag::err_no_member_template_suggest) @@ -311,7 +319,7 @@ void Sema::LookupTemplateName(LookupResult &Found, } } - FilterAcceptableTemplateNames(Context, Found); + FilterAcceptableTemplateNames(Found); if (Found.empty()) { if (isDependent) MemberOfUnknownSpecialization = true; @@ -327,7 +335,7 @@ void Sema::LookupTemplateName(LookupResult &Found, LookupResult FoundOuter(*this, Found.getLookupName(), Found.getNameLoc(), LookupOrdinaryName); LookupName(FoundOuter, S); - FilterAcceptableTemplateNames(Context, FoundOuter); + FilterAcceptableTemplateNames(FoundOuter); if (FoundOuter.empty()) { // - if the name is not found, the name found in the class of the @@ -368,9 +376,6 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, bool isAddressOfOperand, const TemplateArgumentListInfo *TemplateArgs) { - NestedNameSpecifier *Qualifier - = static_cast<NestedNameSpecifier*>(SS.getScopeRep()); - DeclContext *DC = getFunctionLevelDeclContext(); if (!isAddressOfOperand && @@ -386,7 +391,7 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS, /*This*/ 0, ThisType, /*IsArrow*/ true, /*Op*/ SourceLocation(), - Qualifier, SS.getRange(), + SS.getWithLocInContext(Context), FirstQualifierInScope, NameInfo, TemplateArgs)); @@ -472,7 +477,8 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef, else TArg = Template; return TemplateArgumentLoc(TArg, - Arg.getScopeSpec().getRange(), + Arg.getScopeSpec().getWithLocInContext( + SemaRef.Context), Arg.getLocation(), Arg.getEllipsisLoc()); } @@ -497,7 +503,7 @@ void Sema::translateTemplateArguments(const ASTTemplateArgsPtr &TemplateArgsIn, /// (otherwise, "class" was used), and KeyLoc is the location of the /// "class" or "typename" keyword. ParamName is the name of the /// parameter (NULL indicates an unnamed template parameter) and -/// ParamName is the location of the parameter name (if any). +/// ParamNameLoc is the location of the parameter name (if any). /// If the type parameter has a default argument, it will be added /// later via ActOnTypeParameterDefault. Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis, @@ -527,8 +533,9 @@ Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis, TemplateTypeParmDecl *Param = TemplateTypeParmDecl::Create(Context, Context.getTranslationUnitDecl(), - Loc, Depth, Position, ParamName, Typename, - Ellipsis); + KeyLoc, Loc, Depth, Position, ParamName, + Typename, Ellipsis); + Param->setAccess(AS_public); if (Invalid) Param->setInvalidDecl(); @@ -651,9 +658,12 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, bool IsParameterPack = D.hasEllipsis(); NonTypeTemplateParmDecl *Param = NonTypeTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(), + D.getSourceRange().getBegin(), D.getIdentifierLoc(), Depth, Position, ParamName, T, IsParameterPack, TInfo); + Param->setAccess(AS_public); + if (Invalid) Param->setInvalidDecl(); @@ -678,10 +688,12 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, return Param; TemplateArgument Converted; - if (CheckTemplateArgument(Param, Param->getType(), Default, Converted)) { + ExprResult DefaultRes = CheckTemplateArgument(Param, Param->getType(), Default, Converted); + if (DefaultRes.isInvalid()) { Param->setInvalidDecl(); return Param; } + Default = DefaultRes.take(); Param->setDefaultArgument(Default, false); } @@ -707,13 +719,13 @@ Decl *Sema::ActOnTemplateTemplateParameter(Scope* S, // Construct the parameter object. bool IsParameterPack = EllipsisLoc.isValid(); - // FIXME: Pack-ness is dropped TemplateTemplateParmDecl *Param = TemplateTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(), NameLoc.isInvalid()? TmpLoc : NameLoc, Depth, Position, IsParameterPack, Name, Params); - + Param->setAccess(AS_public); + // If the template template parameter has a name, then link the identifier // into the scope and lookup mechanisms. if (Name) { @@ -791,7 +803,9 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr, TemplateParameterList *TemplateParams, - AccessSpecifier AS) { + AccessSpecifier AS, + unsigned NumOuterTemplateParamLists, + TemplateParameterList** OuterTemplateParamLists) { assert(TemplateParams && TemplateParams->size() > 0 && "No template parameters"); assert(TUK != TUK_Reference && "Can only declare or define class templates"); @@ -961,11 +975,15 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, } CXXRecordDecl *NewClass = - CXXRecordDecl::Create(Context, Kind, SemanticContext, NameLoc, Name, KWLoc, + CXXRecordDecl::Create(Context, Kind, SemanticContext, KWLoc, NameLoc, Name, PrevClassTemplate? PrevClassTemplate->getTemplatedDecl() : 0, /*DelayTypeCreation=*/true); SetNestedNameSpecifier(NewClass, SS); + if (NumOuterTemplateParamLists > 0) + NewClass->setTemplateParameterListsInfo(Context, + NumOuterTemplateParamLists, + OuterTemplateParamLists); ClassTemplateDecl *NewTemplate = ClassTemplateDecl::Create(Context, SemanticContext, NameLoc, @@ -1089,7 +1107,8 @@ static bool DiagnoseDefaultTemplateArgument(Sema &S, /// \brief Check for unexpanded parameter packs within the template parameters /// of a template template parameter, recursively. -bool DiagnoseUnexpandedParameterPacks(Sema &S, TemplateTemplateParmDecl *TTP){ +static bool DiagnoseUnexpandedParameterPacks(Sema &S, + TemplateTemplateParmDecl *TTP) { TemplateParameterList *Params = TTP->getTemplateParameters(); for (unsigned I = 0, N = Params->size(); I != N; ++I) { NamedDecl *P = Params->getParam(I); @@ -1448,9 +1467,9 @@ DependsOnTemplateParameters(const TemplateSpecializationType *TemplateId, /// /// \returns the template parameter list, if any, that corresponds to the /// name that is preceded by the scope specifier @p SS. This template -/// parameter list may be have template parameters (if we're declaring a +/// parameter list may have template parameters (if we're declaring a /// template) or may have no template parameters (if we're declaring a -/// template specialization), or may be NULL (if we were's declaring isn't +/// template specialization), or may be NULL (if what we're declaring isn't /// itself a template). TemplateParameterList * Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc, @@ -1631,14 +1650,42 @@ Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc, return ParamLists[NumParamLists - 1]; } +void Sema::NoteAllFoundTemplates(TemplateName Name) { + if (TemplateDecl *Template = Name.getAsTemplateDecl()) { + Diag(Template->getLocation(), diag::note_template_declared_here) + << (isa<FunctionTemplateDecl>(Template)? 0 + : isa<ClassTemplateDecl>(Template)? 1 + : 2) + << Template->getDeclName(); + return; + } + + if (OverloadedTemplateStorage *OST = Name.getAsOverloadedTemplate()) { + for (OverloadedTemplateStorage::iterator I = OST->begin(), + IEnd = OST->end(); + I != IEnd; ++I) + Diag((*I)->getLocation(), diag::note_template_declared_here) + << 0 << (*I)->getDeclName(); + + return; + } +} + + QualType Sema::CheckTemplateIdType(TemplateName Name, SourceLocation TemplateLoc, - const TemplateArgumentListInfo &TemplateArgs) { + TemplateArgumentListInfo &TemplateArgs) { TemplateDecl *Template = Name.getAsTemplateDecl(); - if (!Template) { - // The template name does not resolve to a template, so we just - // build a dependent template-id type. - return Context.getTemplateSpecializationType(Name, TemplateArgs); + if (!Template || isa<FunctionTemplateDecl>(Template)) { + // We might have a substituted template template parameter pack. If so, + // build a template specialization type for it. + if (Name.getAsSubstTemplateTemplateParmPack()) + return Context.getTemplateSpecializationType(Name, TemplateArgs); + + Diag(TemplateLoc, diag::err_template_id_not_a_type) + << Name; + NoteAllFoundTemplates(Name); + return QualType(); } // Check that the template argument list is well-formed for this @@ -1727,6 +1774,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, ClassTemplate->getTemplatedDecl()->getTagKind(), ClassTemplate->getDeclContext(), ClassTemplate->getLocation(), + ClassTemplate->getLocation(), ClassTemplate, Converted.data(), Converted.size(), 0); @@ -1746,77 +1794,148 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, } TypeResult -Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc, +Sema::ActOnTemplateIdType(CXXScopeSpec &SS, + TemplateTy TemplateD, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgsIn, SourceLocation RAngleLoc) { + if (SS.isInvalid()) + return true; + TemplateName Template = TemplateD.getAsVal<TemplateName>(); // Translate the parser's template argument list in our AST format. TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc); translateTemplateArguments(TemplateArgsIn, TemplateArgs); + if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { + QualType T = Context.getDependentTemplateSpecializationType(ETK_None, + DTN->getQualifier(), + DTN->getIdentifier(), + TemplateArgs); + + // Build type-source information. + TypeLocBuilder TLB; + DependentTemplateSpecializationTypeLoc SpecTL + = TLB.push<DependentTemplateSpecializationTypeLoc>(T); + SpecTL.setKeywordLoc(SourceLocation()); + SpecTL.setNameLoc(TemplateLoc); + SpecTL.setLAngleLoc(LAngleLoc); + SpecTL.setRAngleLoc(RAngleLoc); + SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); + for (unsigned I = 0, N = SpecTL.getNumArgs(); I != N; ++I) + SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); + return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T)); + } + QualType Result = CheckTemplateIdType(Template, TemplateLoc, TemplateArgs); TemplateArgsIn.release(); if (Result.isNull()) return true; - TypeSourceInfo *DI = Context.CreateTypeSourceInfo(Result); - TemplateSpecializationTypeLoc TL - = cast<TemplateSpecializationTypeLoc>(DI->getTypeLoc()); - TL.setTemplateNameLoc(TemplateLoc); - TL.setLAngleLoc(LAngleLoc); - TL.setRAngleLoc(RAngleLoc); - for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) - TL.setArgLocInfo(i, TemplateArgs[i].getLocInfo()); - - return CreateParsedType(Result, DI); + // Build type-source information. + TypeLocBuilder TLB; + TemplateSpecializationTypeLoc SpecTL + = TLB.push<TemplateSpecializationTypeLoc>(Result); + SpecTL.setTemplateNameLoc(TemplateLoc); + SpecTL.setLAngleLoc(LAngleLoc); + SpecTL.setRAngleLoc(RAngleLoc); + for (unsigned i = 0, e = SpecTL.getNumArgs(); i != e; ++i) + SpecTL.setArgLocInfo(i, TemplateArgs[i].getLocInfo()); + + if (SS.isNotEmpty()) { + // Create an elaborated-type-specifier containing the nested-name-specifier. + Result = Context.getElaboratedType(ETK_None, SS.getScopeRep(), Result); + ElaboratedTypeLoc ElabTL = TLB.push<ElaboratedTypeLoc>(Result); + ElabTL.setKeywordLoc(SourceLocation()); + ElabTL.setQualifierLoc(SS.getWithLocInContext(Context)); + } + + return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result)); } -TypeResult Sema::ActOnTagTemplateIdType(CXXScopeSpec &SS, - TypeResult TypeResult, - TagUseKind TUK, +TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK, TypeSpecifierType TagSpec, - SourceLocation TagLoc) { - if (TypeResult.isInvalid()) - return ::TypeResult(); - - TypeSourceInfo *DI; - QualType Type = GetTypeFromParser(TypeResult.get(), &DI); - - // Verify the tag specifier. + SourceLocation TagLoc, + CXXScopeSpec &SS, + TemplateTy TemplateD, + SourceLocation TemplateLoc, + SourceLocation LAngleLoc, + ASTTemplateArgsPtr TemplateArgsIn, + SourceLocation RAngleLoc) { + TemplateName Template = TemplateD.getAsVal<TemplateName>(); + + // Translate the parser's template argument list in our AST format. + TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc); + translateTemplateArguments(TemplateArgsIn, TemplateArgs); + + // Determine the tag kind TagTypeKind TagKind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); + ElaboratedTypeKeyword Keyword + = TypeWithKeyword::getKeywordForTagTypeKind(TagKind); - if (const RecordType *RT = Type->getAs<RecordType>()) { + if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { + QualType T = Context.getDependentTemplateSpecializationType(Keyword, + DTN->getQualifier(), + DTN->getIdentifier(), + TemplateArgs); + + // Build type-source information. + TypeLocBuilder TLB; + DependentTemplateSpecializationTypeLoc SpecTL + = TLB.push<DependentTemplateSpecializationTypeLoc>(T); + SpecTL.setKeywordLoc(TagLoc); + SpecTL.setNameLoc(TemplateLoc); + SpecTL.setLAngleLoc(LAngleLoc); + SpecTL.setRAngleLoc(RAngleLoc); + SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); + for (unsigned I = 0, N = SpecTL.getNumArgs(); I != N; ++I) + SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); + return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T)); + } + + QualType Result = CheckTemplateIdType(Template, TemplateLoc, TemplateArgs); + if (Result.isNull()) + return TypeResult(); + + // Check the tag kind + if (const RecordType *RT = Result->getAs<RecordType>()) { RecordDecl *D = RT->getDecl(); - + IdentifierInfo *Id = D->getIdentifier(); assert(Id && "templated class must have an identifier"); - + if (!isAcceptableTagRedeclaration(D, TagKind, TagLoc, *Id)) { Diag(TagLoc, diag::err_use_with_wrong_tag) - << Type + << Result << FixItHint::CreateReplacement(SourceRange(TagLoc), D->getKindName()); Diag(D->getLocation(), diag::note_previous_use); } } - - ElaboratedTypeKeyword Keyword - = TypeWithKeyword::getKeywordForTagTypeKind(TagKind); - QualType ElabType = Context.getElaboratedType(Keyword, /*NNS=*/0, Type); - - TypeSourceInfo *ElabDI = Context.CreateTypeSourceInfo(ElabType); - ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(ElabDI->getTypeLoc()); - TL.setKeywordLoc(TagLoc); - TL.setQualifierRange(SS.getRange()); - TL.getNamedTypeLoc().initializeFullCopy(DI->getTypeLoc()); - return CreateParsedType(ElabType, ElabDI); + + // Provide source-location information for the template specialization. + TypeLocBuilder TLB; + TemplateSpecializationTypeLoc SpecTL + = TLB.push<TemplateSpecializationTypeLoc>(Result); + SpecTL.setTemplateNameLoc(TemplateLoc); + SpecTL.setLAngleLoc(LAngleLoc); + SpecTL.setRAngleLoc(RAngleLoc); + for (unsigned i = 0, e = SpecTL.getNumArgs(); i != e; ++i) + SpecTL.setArgLocInfo(i, TemplateArgs[i].getLocInfo()); + + // Construct an elaborated type containing the nested-name-specifier (if any) + // and keyword. + Result = Context.getElaboratedType(Keyword, SS.getScopeRep(), Result); + ElaboratedTypeLoc ElabTL = TLB.push<ElaboratedTypeLoc>(Result); + ElabTL.setKeywordLoc(TagLoc); + ElabTL.setQualifierLoc(SS.getWithLocInContext(Context)); + return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result)); } ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, - LookupResult &R, - bool RequiresADL, + LookupResult &R, + bool RequiresADL, const TemplateArgumentListInfo &TemplateArgs) { // FIXME: Can we do any checking at this point? I guess we could check the // template arguments that we have against the template name, if the template @@ -1832,19 +1951,12 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, assert(!R.empty() && "empty lookup results when building templateid"); assert(!R.isAmbiguous() && "ambiguous lookup when building templateid"); - NestedNameSpecifier *Qualifier = 0; - SourceRange QualifierRange; - if (SS.isSet()) { - Qualifier = static_cast<NestedNameSpecifier*>(SS.getScopeRep()); - QualifierRange = SS.getRange(); - } - // We don't want lookup warnings at this point. R.suppressDiagnostics(); UnresolvedLookupExpr *ULE = UnresolvedLookupExpr::Create(Context, R.getNamingClass(), - Qualifier, QualifierRange, + SS.getWithLocInContext(Context), R.getLookupNameInfo(), RequiresADL, TemplateArgs, R.begin(), R.end()); @@ -1935,7 +2047,8 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S, MemberOfUnknownSpecialization); if (TNK == TNK_Non_template && LookupCtx->isDependentContext() && isa<CXXRecordDecl>(LookupCtx) && - cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases()) { + (!cast<CXXRecordDecl>(LookupCtx)->hasDefinition() || + cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases())) { // This is a dependent template. Handle it below. } else if (TNK == TNK_Non_template) { Diag(Name.getSourceRange().getBegin(), @@ -2043,7 +2156,6 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, /// /// \param Converted the list of template arguments provided for template /// parameters that precede \p Param in the template parameter list. -/// /// \returns the substituted template argument, or NULL if an error occurred. static TypeSourceInfo * SubstDefaultTemplateArgument(Sema &SemaRef, @@ -2140,6 +2252,9 @@ SubstDefaultTemplateArgument(Sema &SemaRef, /// \param Converted the list of template arguments provided for template /// parameters that precede \p Param in the template parameter list. /// +/// \param QualifierLoc Will be set to the nested-name-specifier (with +/// source-location information) that precedes the template name. +/// /// \returns the substituted template argument, or NULL if an error occurred. static TemplateName SubstDefaultTemplateArgument(Sema &SemaRef, @@ -2147,7 +2262,8 @@ SubstDefaultTemplateArgument(Sema &SemaRef, SourceLocation TemplateLoc, SourceLocation RAngleLoc, TemplateTemplateParmDecl *Param, - llvm::SmallVectorImpl<TemplateArgument> &Converted) { + llvm::SmallVectorImpl<TemplateArgument> &Converted, + NestedNameSpecifierLoc &QualifierLoc) { TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Converted.data(), Converted.size()); @@ -2159,7 +2275,16 @@ SubstDefaultTemplateArgument(Sema &SemaRef, Converted.size(), SourceRange(TemplateLoc, RAngleLoc)); - return SemaRef.SubstTemplateName( + // Substitute into the nested-name-specifier first, + QualifierLoc = Param->getDefaultArgument().getTemplateQualifierLoc(); + if (QualifierLoc) { + QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, + AllTemplateArgs); + if (!QualifierLoc) + return TemplateName(); + } + + return SemaRef.SubstTemplateName(QualifierLoc, Param->getDefaultArgument().getArgument().getAsTemplate(), Param->getDefaultArgument().getTemplateNameLoc(), AllTemplateArgs); @@ -2195,10 +2320,10 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, return TemplateArgumentLoc(); ExprResult Arg = SubstDefaultTemplateArgument(*this, Template, - TemplateLoc, - RAngleLoc, - NonTypeParm, - Converted); + TemplateLoc, + RAngleLoc, + NonTypeParm, + Converted); if (Arg.isInvalid()) return TemplateArgumentLoc(); @@ -2211,16 +2336,19 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, if (!TempTempParm->hasDefaultArgument()) return TemplateArgumentLoc(); + + NestedNameSpecifierLoc QualifierLoc; TemplateName TName = SubstDefaultTemplateArgument(*this, Template, TemplateLoc, RAngleLoc, TempTempParm, - Converted); + Converted, + QualifierLoc); if (TName.isNull()) return TemplateArgumentLoc(); return TemplateArgumentLoc(TemplateArgument(TName), - TempTempParm->getDefaultArgument().getTemplateQualifierRange(), + TempTempParm->getDefaultArgument().getTemplateQualifierLoc(), TempTempParm->getDefaultArgument().getTemplateNameLoc()); } @@ -2300,9 +2428,11 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, return true; case TemplateArgument::Expression: { - Expr *E = Arg.getArgument().getAsExpr(); TemplateArgument Result; - if (CheckTemplateArgument(NTTP, NTTPType, E, Result, CTAK)) + ExprResult Res = + CheckTemplateArgument(NTTP, NTTPType, Arg.getArgument().getAsExpr(), + Result, CTAK); + if (Res.isInvalid()) return true; Converted.push_back(Result); @@ -2331,28 +2461,23 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, DeclarationNameInfo NameInfo(DTN->getIdentifier(), Arg.getTemplateNameLoc()); - // FIXME: TemplateArgumentLoc should store a NestedNameSpecifierLoc - // for the template name. CXXScopeSpec SS; - SS.MakeTrivial(Context, DTN->getQualifier(), - Arg.getTemplateQualifierRange()); - Expr *E = DependentScopeDeclRefExpr::Create(Context, + SS.Adopt(Arg.getTemplateQualifierLoc()); + ExprResult E = Owned(DependentScopeDeclRefExpr::Create(Context, SS.getWithLocInContext(Context), - NameInfo); + NameInfo)); // If we parsed the template argument as a pack expansion, create a // pack expansion expression. if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){ - ExprResult Expansion = ActOnPackExpansion(E, - Arg.getTemplateEllipsisLoc()); - if (Expansion.isInvalid()) + E = ActOnPackExpansion(E.take(), Arg.getTemplateEllipsisLoc()); + if (E.isInvalid()) return true; - - E = Expansion.get(); } TemplateArgument Result; - if (CheckTemplateArgument(NTTP, NTTPType, E, Result)) + E = CheckTemplateArgument(NTTP, NTTPType, E.take(), Result); + if (E.isInvalid()) return true; Converted.push_back(Result); @@ -2461,7 +2586,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, /// for specializing the given template. bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, - const TemplateArgumentListInfo &TemplateArgs, + TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs, llvm::SmallVectorImpl<TemplateArgument> &Converted) { TemplateParameterList *Params = Template->getTemplateParameters(); @@ -2499,6 +2624,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // a template-id shall match the type and form specified for the // corresponding parameter declared by the template in its // template-parameter-list. + bool isTemplateTemplateParameter = isa<TemplateTemplateParmDecl>(Template); llvm::SmallVector<TemplateArgument, 2> ArgumentPack; TemplateParameterList::iterator Param = Params->begin(), ParamEnd = Params->end(); @@ -2604,17 +2730,18 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, break; } + NestedNameSpecifierLoc QualifierLoc; TemplateName Name = SubstDefaultTemplateArgument(*this, Template, TemplateLoc, RAngleLoc, TempParm, - Converted); + Converted, + QualifierLoc); if (Name.isNull()) return true; - Arg = TemplateArgumentLoc(TemplateArgument(Name), - TempParm->getDefaultArgument().getTemplateQualifierRange(), - TempParm->getDefaultArgument().getTemplateNameLoc()); + Arg = TemplateArgumentLoc(TemplateArgument(Name), QualifierLoc, + TempParm->getDefaultArgument().getTemplateNameLoc()); } // Introduce an instantiation record that describes where we are using @@ -2628,6 +2755,12 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, RAngleLoc, 0, Converted)) return true; + // Core issue 150 (assumed resolution): if this is a template template + // parameter, keep track of the default template arguments from the + // template definition. + if (isTemplateTemplateParameter) + TemplateArgs.addArgument(Arg); + // Move to the next template parameter and argument. ++Param; ++ArgIdx; @@ -2853,7 +2986,7 @@ bool UnnamedLocalNoLinkageFinder::VisitTagDecl(const TagDecl *Tag) { return true; } - if (!Tag->getDeclName() && !Tag->getTypedefForAnonDecl()) { + if (!Tag->getDeclName() && !Tag->getTypedefNameForAnonDecl()) { S.Diag(SR.getBegin(), diag::ext_template_arg_unnamed_type) << SR; S.Diag(Tag->getLocation(), diag::note_template_unnamed_type_here); return true; @@ -2961,13 +3094,25 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, SourceLocation AddrOpLoc; if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) { if (UnOp->getOpcode() == UO_AddrOf) { + // Support &__uuidof(class_with_uuid) as a non-type template argument. + // Very common in Microsoft COM headers. + if (S.getLangOptions().Microsoft && + isa<CXXUuidofExpr>(UnOp->getSubExpr())) { + Converted = TemplateArgument(ArgIn); + return false; + } + DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr()); AddressTaken = true; AddrOpLoc = UnOp->getOperatorLoc(); } - } else + } else { + if (S.getLangOptions().Microsoft && isa<CXXUuidofExpr>(Arg)) { + Converted = TemplateArgument(ArgIn); + return false; + } DRE = dyn_cast<DeclRefExpr>(Arg); - + } if (!DRE) { S.Diag(Arg->getLocStart(), diag::err_template_arg_not_decl_ref) << Arg->getSourceRange(); @@ -3266,15 +3411,14 @@ bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, /// non-type template parameter. /// /// This routine implements the semantics of C++ [temp.arg.nontype]. -/// It returns true if an error occurred, and false otherwise. \p +/// If an error occurred, it returns ExprError(); otherwise, it +/// returns the converted template argument. \p /// InstantiatedParamType is the type of the non-type template /// parameter after it has been instantiated. -/// -/// If no error was detected, Converted receives the converted template argument. -bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, - QualType InstantiatedParamType, Expr *&Arg, - TemplateArgument &Converted, - CheckTemplateArgumentKind CTAK) { +ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, + QualType InstantiatedParamType, Expr *Arg, + TemplateArgument &Converted, + CheckTemplateArgumentKind CTAK) { SourceLocation StartLoc = Arg->getSourceRange().getBegin(); // If either the parameter has a dependent type or the argument is @@ -3282,7 +3426,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, if (InstantiatedParamType->isDependentType() || Arg->isTypeDependent()) { // FIXME: Produce a cloned, canonical expression? Converted = TemplateArgument(Arg); - return false; + return Owned(Arg); } // C++ [temp.arg.nontype]p5: @@ -3312,12 +3456,12 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, diag::err_template_arg_not_integral_or_enumeral) << ArgType << Arg->getSourceRange(); Diag(Param->getLocation(), diag::note_template_param_here); - return true; + return ExprError(); } else if (!Arg->isValueDependent() && !Arg->isIntegerConstantExpr(Value, Context, &NonConstantLoc)) { Diag(NonConstantLoc, diag::err_template_arg_not_ice) << ArgType << Arg->getSourceRange(); - return true; + return ExprError(); } // From here on out, all we care about are the unqualified forms @@ -3340,21 +3484,21 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch) << ArgType << ParamType; Diag(Param->getLocation(), diag::note_template_param_here); - return true; + return ExprError(); } else if (ParamType->isBooleanType()) { // This is an integral-to-boolean conversion. - ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean); + Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean).take(); } else if (IsIntegralPromotion(Arg, ArgType, ParamType) || !ParamType->isEnumeralType()) { // This is an integral promotion or conversion. - ImpCastExprToType(Arg, ParamType, CK_IntegralCast); + Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralCast).take(); } else { // We can't perform this conversion. Diag(Arg->getSourceRange().getBegin(), diag::err_template_arg_not_convertible) << Arg->getType() << InstantiatedParamType << Arg->getSourceRange(); Diag(Param->getLocation(), diag::note_template_param_here); - return true; + return ExprError(); } QualType IntegerType = Context.getCanonicalType(ParamType); @@ -3404,13 +3548,13 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // The argument is value-dependent. Create a new // TemplateArgument with the converted expression. Converted = TemplateArgument(Arg); - return false; + return Owned(Arg); } Converted = TemplateArgument(Value, ParamType->isEnumeralType() ? ParamType : IntegerType); - return false; + return Owned(Arg); } DeclAccessPair FoundResult; // temporary for ResolveOverloadedFunction @@ -3422,7 +3566,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, if (ArgType->isNullPtrType() && (ParamType->isPointerType() || ParamType->isMemberPointerType())) { Converted = TemplateArgument((NamedDecl *)0); - return false; + return Owned(Arg); } // Handle pointer-to-function, reference-to-function, and @@ -3454,22 +3598,25 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, true, FoundResult)) { if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin())) - return true; + return ExprError(); Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn); ArgType = Arg->getType(); } else - return true; + return ExprError(); } - if (!ParamType->isMemberPointerType()) - return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param, - ParamType, - Arg, Converted); + if (!ParamType->isMemberPointerType()) { + if (CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param, + ParamType, + Arg, Converted)) + return ExprError(); + return Owned(Arg); + } if (IsQualificationConversion(ArgType, ParamType.getNonReferenceType(), false)) { - ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg)); + Arg = ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg)).take(); } else if (!Context.hasSameUnqualifiedType(ArgType, ParamType.getNonReferenceType())) { // We can't perform this conversion. @@ -3477,10 +3624,12 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, diag::err_template_arg_not_convertible) << Arg->getType() << InstantiatedParamType << Arg->getSourceRange(); Diag(Param->getLocation(), diag::note_template_param_here); - return true; + return ExprError(); } - return CheckTemplateArgumentPointerToMember(Arg, Converted); + if (CheckTemplateArgumentPointerToMember(Arg, Converted)) + return ExprError(); + return Owned(Arg); } if (ParamType->isPointerType()) { @@ -3491,9 +3640,11 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, assert(ParamType->getPointeeType()->isIncompleteOrObjectType() && "Only object pointers allowed here"); - return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param, - ParamType, - Arg, Converted); + if (CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param, + ParamType, + Arg, Converted)) + return ExprError(); + return Owned(Arg); } if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) { @@ -3512,17 +3663,19 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, true, FoundResult)) { if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin())) - return true; + return ExprError(); Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn); ArgType = Arg->getType(); } else - return true; + return ExprError(); } - return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param, - ParamType, - Arg, Converted); + if (CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param, + ParamType, + Arg, Converted)) + return ExprError(); + return Owned(Arg); } // -- For a non-type template-parameter of type pointer to data @@ -3532,17 +3685,19 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, if (Context.hasSameUnqualifiedType(ParamType, ArgType)) { // Types match exactly: nothing more to do here. } else if (IsQualificationConversion(ArgType, ParamType, false)) { - ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg)); + Arg = ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg)).take(); } else { // We can't perform this conversion. Diag(Arg->getSourceRange().getBegin(), diag::err_template_arg_not_convertible) << Arg->getType() << InstantiatedParamType << Arg->getSourceRange(); Diag(Param->getLocation(), diag::note_template_param_here); - return true; + return ExprError(); } - return CheckTemplateArgumentPointerToMember(Arg, Converted); + if (CheckTemplateArgumentPointerToMember(Arg, Converted)) + return ExprError(); + return Owned(Arg); } /// \brief Check a template argument against its corresponding @@ -3636,11 +3791,8 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, // the element type on the parameter could be more qualified than the // element type in the expression we constructed. if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(), - ParamType.getUnqualifiedType(), false)) { - Expr *RefE = RefExpr.takeAs<Expr>(); - ImpCastExprToType(RefE, ParamType.getUnqualifiedType(), CK_NoOp); - RefExpr = Owned(RefE); - } + ParamType.getUnqualifiedType(), false)) + RefExpr = ImpCastExprToType(RefExpr.take(), ParamType.getUnqualifiedType(), CK_NoOp); assert(!RefExpr.isInvalid() && Context.hasSameType(((Expr*) RefExpr.get())->getType(), @@ -3659,12 +3811,9 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, if (T->isFunctionType() || T->isArrayType()) { // Decay functions and arrays. - Expr *RefE = (Expr *)RefExpr.get(); - DefaultFunctionArrayConversion(RefE); - if (RefE != RefExpr.get()) { - RefExpr.release(); - RefExpr = Owned(RefE); - } + RefExpr = DefaultFunctionArrayConversion(RefExpr.take()); + if (RefExpr.isInvalid()) + return ExprError(); return move(RefExpr); } @@ -3703,18 +3852,18 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg, if (T->isCharType() || T->isWideCharType()) return Owned(new (Context) CharacterLiteral( Arg.getAsIntegral()->getZExtValue(), - T->isWideCharType(), - T, - Loc)); + T->isWideCharType(), T, Loc)); if (T->isBooleanType()) return Owned(new (Context) CXXBoolLiteralExpr( Arg.getAsIntegral()->getBoolValue(), - T, - Loc)); + T, Loc)); + // If this is an enum type that we're instantiating, we need to use an integer + // type the same size as the enumerator. We don't want to build an + // IntegerLiteral with enum type. QualType BT; if (const EnumType *ET = T->getAs<EnumType>()) - BT = ET->getDecl()->getPromotionType(); + BT = ET->getDecl()->getIntegerType(); else BT = T; @@ -3722,10 +3871,9 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg, if (T->isEnumeralType()) { // FIXME: This is a hack. We need a better way to handle substituted // non-type template parameters. - E = CStyleCastExpr::Create(Context, T, VK_RValue, CK_IntegralCast, - E, 0, - Context.getTrivialTypeSourceInfo(T, Loc), - Loc, Loc); + E = CStyleCastExpr::Create(Context, T, VK_RValue, CK_IntegralCast, E, 0, + Context.getTrivialTypeSourceInfo(T, Loc), + Loc, Loc); } return Owned(E); @@ -4245,7 +4393,7 @@ static NamedDecl *getPreviousDecl(NamedDecl *ND) { return FD->getPreviousDeclaration(); if (TagDecl *TD = dyn_cast<TagDecl>(ND)) return TD->getPreviousDeclaration(); - if (TypedefDecl *TD = dyn_cast<TypedefDecl>(ND)) + if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(ND)) return TD->getPreviousDeclaration(); if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND)) return FTD->getPreviousDeclaration(); @@ -4268,6 +4416,11 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, MultiTemplateParamsArg TemplateParameterLists) { assert(TUK != TUK_Reference && "References are not specializations"); + // NOTE: KWLoc is the location of the tag keyword. This will instead + // store the location of the outermost template keyword in the declaration. + SourceLocation TemplateKWLoc = TemplateParameterLists.size() > 0 + ? TemplateParameterLists.get()[0]->getTemplateLoc() : SourceLocation(); + // Find the class template we're specializing TemplateName Name = TemplateD.getAsVal<TemplateName>(); ClassTemplateDecl *ClassTemplate @@ -4298,10 +4451,6 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, if (Invalid) return true; - unsigned NumMatchedTemplateParamLists = TemplateParameterLists.size(); - if (TemplateParams) - --NumMatchedTemplateParamLists; - if (TemplateParams && TemplateParams->size() > 0) { isPartialSpecialization = true; @@ -4443,10 +4592,15 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // Since the only prior class template specialization with these // arguments was referenced but not declared, or we're only // referencing this specialization as a friend, reuse that - // declaration node as our own, updating its source location to - // reflect our new declaration. + // declaration node as our own, updating its source location and + // the list of outer template parameters to reflect our new declaration. Specialization = PrevDecl; Specialization->setLocation(TemplateNameLoc); + if (TemplateParameterLists.size() > 0) { + Specialization->setTemplateParameterListsInfo(Context, + TemplateParameterLists.size(), + (TemplateParameterList**) TemplateParameterLists.release()); + } PrevDecl = 0; CanonType = Context.getTypeDeclType(Specialization); } else if (isPartialSpecialization) { @@ -4471,7 +4625,9 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TemplateNameLoc, Attr, TemplateParams, - AS_none); + AS_none, + TemplateParameterLists.size() - 1, + (TemplateParameterList**) TemplateParameterLists.release()); } // Create a new class template partial specialization declaration node. @@ -4482,7 +4638,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, ClassTemplatePartialSpecializationDecl *Partial = ClassTemplatePartialSpecializationDecl::Create(Context, Kind, ClassTemplate->getDeclContext(), - TemplateNameLoc, + KWLoc, TemplateNameLoc, TemplateParams, ClassTemplate, Converted.data(), @@ -4492,9 +4648,9 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, PrevPartial, SequenceNumber); SetNestedNameSpecifier(Partial, SS); - if (NumMatchedTemplateParamLists > 0 && SS.isSet()) { + if (TemplateParameterLists.size() > 1 && SS.isSet()) { Partial->setTemplateParameterListsInfo(Context, - NumMatchedTemplateParamLists, + TemplateParameterLists.size() - 1, (TemplateParameterList**) TemplateParameterLists.release()); } @@ -4545,15 +4701,15 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, Specialization = ClassTemplateSpecializationDecl::Create(Context, Kind, ClassTemplate->getDeclContext(), - TemplateNameLoc, + KWLoc, TemplateNameLoc, ClassTemplate, Converted.data(), Converted.size(), PrevDecl); SetNestedNameSpecifier(Specialization, SS); - if (NumMatchedTemplateParamLists > 0 && SS.isSet()) { + if (TemplateParameterLists.size() > 0) { Specialization->setTemplateParameterListsInfo(Context, - NumMatchedTemplateParamLists, + TemplateParameterLists.size(), (TemplateParameterList**) TemplateParameterLists.release()); } @@ -4623,8 +4779,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TemplateArgs, CanonType); if (TUK != TUK_Friend) { Specialization->setTypeAsWritten(WrittenTy); - if (TemplateParams) - Specialization->setTemplateKeywordLoc(TemplateParams->getTemplateLoc()); + Specialization->setTemplateKeywordLoc(TemplateKWLoc); } TemplateArgsIn.release(); @@ -4927,7 +5082,7 @@ Sema::CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD, /// this function specialization. bool Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD, - const TemplateArgumentListInfo *ExplicitTemplateArgs, + TemplateArgumentListInfo *ExplicitTemplateArgs, LookupResult &Previous) { // The set of function template specializations that could match this // explicit function template specialization. @@ -4983,7 +5138,17 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD, // Ignore access information; it doesn't figure into redeclaration checking. FunctionDecl *Specialization = cast<FunctionDecl>(*Result); - Specialization->setLocation(FD->getLocation()); + + FunctionTemplateSpecializationInfo *SpecInfo + = Specialization->getTemplateSpecializationInfo(); + assert(SpecInfo && "Function template specialization info missing?"); + { + // Note: do not overwrite location info if previous template + // specialization kind was explicit. + TemplateSpecializationKind TSK = SpecInfo->getTemplateSpecializationKind(); + if (TSK == TSK_Undeclared || TSK == TSK_ImplicitInstantiation) + Specialization->setLocation(FD->getLocation()); + } // FIXME: Check if the prior specialization has a point of instantiation. // If so, we have run afoul of . @@ -5006,10 +5171,6 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD, // before the first use of that specialization that would cause an implicit // instantiation to take place, in every translation unit in which such a // use occurs; no diagnostic is required. - FunctionTemplateSpecializationInfo *SpecInfo - = Specialization->getTemplateSpecializationInfo(); - assert(SpecInfo && "Function template specialization info missing?"); - bool HasNoEffect = false; if (!isFriend && CheckSpecializationInstantiationRedecl(FD->getLocation(), @@ -5402,7 +5563,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, Specialization = ClassTemplateSpecializationDecl::Create(Context, Kind, ClassTemplate->getDeclContext(), - TemplateNameLoc, + KWLoc, TemplateNameLoc, ClassTemplate, Converted.data(), Converted.size(), @@ -5883,26 +6044,34 @@ Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, return true; } + // Create the resulting type. ElaboratedTypeKeyword Kwd = TypeWithKeyword::getKeywordForTagTypeKind(Kind); - return ParsedType::make(Context.getDependentNameType(Kwd, NNS, Name)); + QualType Result = Context.getDependentNameType(Kwd, NNS, Name); + + // Create type-source location information for this type. + TypeLocBuilder TLB; + DependentNameTypeLoc TL = TLB.push<DependentNameTypeLoc>(Result); + TL.setKeywordLoc(TagLoc); + TL.setQualifierLoc(SS.getWithLocInContext(Context)); + TL.setNameLoc(NameLoc); + return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result)); } TypeResult Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, const CXXScopeSpec &SS, const IdentifierInfo &II, SourceLocation IdLoc) { - NestedNameSpecifier *NNS - = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); - if (!NNS) + if (SS.isInvalid()) return true; - + if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() && !getLangOptions().CPlusPlus0x) Diag(TypenameLoc, diag::ext_typename_outside_of_template) << FixItHint::CreateRemoval(TypenameLoc); - QualType T = CheckTypenameType(ETK_Typename, NNS, II, - TypenameLoc, SS.getRange(), IdLoc); + NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); + QualType T = CheckTypenameType(TypenameLoc.isValid()? ETK_Typename : ETK_None, + TypenameLoc, QualifierLoc, II, IdLoc); if (T.isNull()) return true; @@ -5910,12 +6079,12 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, if (isa<DependentNameType>(T)) { DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc()); TL.setKeywordLoc(TypenameLoc); - TL.setQualifierRange(SS.getRange()); + TL.setQualifierLoc(QualifierLoc); TL.setNameLoc(IdLoc); } else { ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc()); TL.setKeywordLoc(TypenameLoc); - TL.setQualifierRange(SS.getRange()); + TL.setQualifierLoc(QualifierLoc); cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(IdLoc); } @@ -5923,91 +6092,94 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, } TypeResult -Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, - const CXXScopeSpec &SS, SourceLocation TemplateLoc, - ParsedType Ty) { +Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, + const CXXScopeSpec &SS, + SourceLocation TemplateLoc, + TemplateTy TemplateIn, + SourceLocation TemplateNameLoc, + SourceLocation LAngleLoc, + ASTTemplateArgsPtr TemplateArgsIn, + SourceLocation RAngleLoc) { if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() && !getLangOptions().CPlusPlus0x) Diag(TypenameLoc, diag::ext_typename_outside_of_template) - << FixItHint::CreateRemoval(TypenameLoc); - - TypeSourceInfo *InnerTSI = 0; - QualType T = GetTypeFromParser(Ty, &InnerTSI); - - assert(isa<TemplateSpecializationType>(T) && - "Expected a template specialization type"); - - if (computeDeclContext(SS, false)) { - // If we can compute a declaration context, then the "typename" - // keyword was superfluous. Just build an ElaboratedType to keep - // track of the nested-name-specifier. - - // Push the inner type, preserving its source locations if possible. + << FixItHint::CreateRemoval(TypenameLoc); + + // Translate the parser's template argument list in our AST format. + TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc); + translateTemplateArguments(TemplateArgsIn, TemplateArgs); + + TemplateName Template = TemplateIn.get(); + if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { + // Construct a dependent template specialization type. + assert(DTN && "dependent template has non-dependent name?"); + assert(DTN->getQualifier() + == static_cast<NestedNameSpecifier*>(SS.getScopeRep())); + QualType T = Context.getDependentTemplateSpecializationType(ETK_Typename, + DTN->getQualifier(), + DTN->getIdentifier(), + TemplateArgs); + + // Create source-location information for this type. TypeLocBuilder Builder; - if (InnerTSI) - Builder.pushFullCopy(InnerTSI->getTypeLoc()); - else - Builder.push<TemplateSpecializationTypeLoc>(T).initialize(Context, - TemplateLoc); - - /* Note: NNS already embedded in template specialization type T. */ - T = Context.getElaboratedType(ETK_Typename, /*NNS=*/0, T); - ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T); - TL.setKeywordLoc(TypenameLoc); - TL.setQualifierRange(SS.getRange()); - - TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T); - return CreateParsedType(T, TSI); - } - - // TODO: it's really silly that we make a template specialization - // type earlier only to drop it again here. - const TemplateSpecializationType *TST = cast<TemplateSpecializationType>(T); - DependentTemplateName *DTN = - TST->getTemplateName().getAsDependentTemplateName(); - assert(DTN && "dependent template has non-dependent name?"); - assert(DTN->getQualifier() - == static_cast<NestedNameSpecifier*>(SS.getScopeRep())); - T = Context.getDependentTemplateSpecializationType(ETK_Typename, - DTN->getQualifier(), - DTN->getIdentifier(), - TST->getNumArgs(), - TST->getArgs()); - TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T); - DependentTemplateSpecializationTypeLoc TL = - cast<DependentTemplateSpecializationTypeLoc>(TSI->getTypeLoc()); - if (InnerTSI) { - TemplateSpecializationTypeLoc TSTL = - cast<TemplateSpecializationTypeLoc>(InnerTSI->getTypeLoc()); - TL.setLAngleLoc(TSTL.getLAngleLoc()); - TL.setRAngleLoc(TSTL.getRAngleLoc()); - for (unsigned I = 0, E = TST->getNumArgs(); I != E; ++I) - TL.setArgLocInfo(I, TSTL.getArgLocInfo(I)); - } else { - // FIXME: Poor source-location information here. - TL.initializeLocal(Context, TemplateLoc); + DependentTemplateSpecializationTypeLoc SpecTL + = Builder.push<DependentTemplateSpecializationTypeLoc>(T); + SpecTL.setLAngleLoc(LAngleLoc); + SpecTL.setRAngleLoc(RAngleLoc); + SpecTL.setKeywordLoc(TypenameLoc); + SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); + SpecTL.setNameLoc(TemplateNameLoc); + for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) + SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); + return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); } + + QualType T = CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs); + if (T.isNull()) + return true; + + // Provide source-location information for the template specialization + // type. + TypeLocBuilder Builder; + TemplateSpecializationTypeLoc SpecTL + = Builder.push<TemplateSpecializationTypeLoc>(T); + + // FIXME: No place to set the location of the 'template' keyword! + 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()); + + T = Context.getElaboratedType(ETK_Typename, SS.getScopeRep(), T); + ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T); TL.setKeywordLoc(TypenameLoc); - TL.setQualifierRange(SS.getRange()); + TL.setQualifierLoc(SS.getWithLocInContext(Context)); + + TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T); return CreateParsedType(T, TSI); } + /// \brief Build the type that describes a C++ typename specifier, /// e.g., "typename T::type". QualType -Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, - NestedNameSpecifier *NNS, const IdentifierInfo &II, - SourceLocation KeywordLoc, SourceRange NNSRange, +Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, + SourceLocation KeywordLoc, + NestedNameSpecifierLoc QualifierLoc, + const IdentifierInfo &II, SourceLocation IILoc) { CXXScopeSpec SS; - SS.MakeTrivial(Context, NNS, NNSRange); + SS.Adopt(QualifierLoc); DeclContext *Ctx = computeDeclContext(SS); if (!Ctx) { // If the nested-name-specifier is dependent and couldn't be // resolved to a type, build a typename type. - assert(NNS->isDependent()); - return Context.getDependentNameType(Keyword, NNS, &II); + assert(QualifierLoc.getNestedNameSpecifier()->isDependent()); + return Context.getDependentNameType(Keyword, + QualifierLoc.getNestedNameSpecifier(), + &II); } // If the nested-name-specifier refers to the current instantiation, @@ -6032,7 +6204,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, case LookupResult::FoundUnresolvedValue: { // We found a using declaration that is a value. Most likely, the using // declaration itself is meant to have the 'typename' keyword. - SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : NNSRange.getBegin(), + SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : SS.getBeginLoc(), IILoc); Diag(IILoc, diag::err_typename_refers_to_using_value_decl) << Name << Ctx << FullRange; @@ -6048,13 +6220,16 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, case LookupResult::NotFoundInCurrentInstantiation: // Okay, it's a member of an unknown instantiation. - return Context.getDependentNameType(Keyword, NNS, &II); + return Context.getDependentNameType(Keyword, + QualifierLoc.getNestedNameSpecifier(), + &II); case LookupResult::Found: if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) { // We found a type. Build an ElaboratedType, since the // typename-specifier was just sugar. - return Context.getElaboratedType(ETK_Typename, NNS, + return Context.getElaboratedType(ETK_Typename, + QualifierLoc.getNestedNameSpecifier(), Context.getTypeDeclType(Type)); } @@ -6077,7 +6252,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, // If we get here, it's because name lookup did not find a // type. Emit an appropriate diagnostic and return an error. - SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : NNSRange.getBegin(), + SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : SS.getBeginLoc(), IILoc); Diag(IILoc, DiagID) << FullRange << Name << Ctx; if (Referenced) @@ -6225,3 +6400,24 @@ Sema::getTemplateArgumentBindingsText(const TemplateParameterList *Params, Out << ']'; return Out.str(); } + +void Sema::MarkAsLateParsedTemplate(FunctionDecl *FD, bool Flag) { + if (!FD) + return; + FD->setLateTemplateParsed(Flag); +} + +bool Sema::IsInsideALocalClassWithinATemplateFunction() { + DeclContext *DC = CurContext; + + while (DC) { + if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(CurContext)) { + const FunctionDecl *FD = RD->isLocalClass(); + return (FD && FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate); + } else if (DC->isTranslationUnit() || DC->isNamespace()) + return false; + + DC = DC->getParent(); + } + return false; +} |