From: Douglas Gregor Date: Wed, 2 Mar 2011 18:07:45 +0000 (+0000) Subject: Start migrating TreeTransform's TransformTemplateName over to version X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fd4ffebd8e8e77346e70dfbc2d72dd673ebd7c6d;p=clang Start migrating TreeTransform's TransformTemplateName over to version that preserve source-location information. This commit adds more redundancy than it removes; WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126849 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index fa69e70d28..287dc173e1 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -737,6 +737,12 @@ namespace { QualType ObjectType = QualType(), NamedDecl *FirstQualifierInScope = 0); + TemplateName TransformTemplateName(CXXScopeSpec &SS, + TemplateName Name, + SourceLocation NameLoc, + QualType ObjectType = QualType(), + NamedDecl *FirstQualifierInScope = 0); + ExprResult TransformPredefinedExpr(PredefinedExpr *E); ExprResult TransformDeclRefExpr(DeclRefExpr *E); ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E); @@ -977,6 +983,62 @@ TemplateName TemplateInstantiator::TransformTemplateName(TemplateName Name, FirstQualifierInScope); } +TemplateName TemplateInstantiator::TransformTemplateName(CXXScopeSpec &SS, + TemplateName Name, + SourceLocation NameLoc, + QualType ObjectType, + NamedDecl *FirstQualifierInScope) { + if (TemplateTemplateParmDecl *TTP + = dyn_cast_or_null(Name.getAsTemplateDecl())) { + if (TTP->getDepth() < TemplateArgs.getNumLevels()) { + // If the corresponding template argument is NULL or non-existent, it's + // because we are performing instantiation from explicitly-specified + // template arguments in a function template, but there were some + // arguments left unspecified. + if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(), + TTP->getPosition())) + return Name; + + TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition()); + + if (TTP->isParameterPack()) { + assert(Arg.getKind() == TemplateArgument::Pack && + "Missing argument pack"); + + if (getSema().ArgumentPackSubstitutionIndex == -1) { + // We have the template argument pack to substitute, but we're not + // actually expanding the enclosing pack expansion yet. So, just + // keep the entire argument pack. + return getSema().Context.getSubstTemplateTemplateParmPack(TTP, Arg); + } + + assert(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size()); + Arg = Arg.pack_begin()[getSema().ArgumentPackSubstitutionIndex]; + } + + TemplateName Template = Arg.getAsTemplate(); + assert(!Template.isNull() && Template.getAsTemplateDecl() && + "Wrong kind of template template argument"); + return Template; + } + } + + if (SubstTemplateTemplateParmPackStorage *SubstPack + = Name.getAsSubstTemplateTemplateParmPack()) { + if (getSema().ArgumentPackSubstitutionIndex == -1) + return Name; + + const TemplateArgument &ArgPack = SubstPack->getArgumentPack(); + assert(getSema().ArgumentPackSubstitutionIndex < (int)ArgPack.pack_size() && + "Pack substitution index out-of-range"); + return ArgPack.pack_begin()[getSema().ArgumentPackSubstitutionIndex] + .getAsTemplate(); + } + + return inherited::TransformTemplateName(SS, Name, NameLoc, ObjectType, + FirstQualifierInScope); +} + ExprResult TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) { if (!E->isTypeDependent()) diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index ce633cde2a..f11f1ef052 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -414,6 +414,32 @@ public: QualType ObjectType = QualType(), NamedDecl *FirstQualifierInScope = 0); + /// \brief Transform the given template name. + /// + /// \param SS The nested-name-specifier that qualifies the template + /// name. This nested-name-specifier must already have been transformed. + /// + /// \param Name The template name to transform. + /// + /// \param NameLoc The source location of the template name. + /// + /// \param ObjectType If we're translating a template name within a member + /// access expression, this is the type of the object whose member template + /// is being referenced. + /// + /// \param FirstQualifierInScope If the first part of a nested-name-specifier + /// also refers to a name within the current (lexical) scope, this is the + /// declaration it refers to. + /// + /// By default, transforms the template name by transforming the declarations + /// and nested-name-specifiers that occur within the template name. + /// Subclasses may override this function to provide alternate behavior. + TemplateName TransformTemplateName(CXXScopeSpec &SS, + TemplateName Name, + SourceLocation NameLoc, + QualType ObjectType = QualType(), + NamedDecl *FirstQualifierInScope = 0); + /// \brief Transform the given template argument. /// /// By default, this operation transforms the type, expression, or @@ -735,44 +761,6 @@ public: Named); } - /// \brief Build a new typename type that refers to a template-id. - /// - /// By default, builds a new DependentNameType type from the - /// nested-name-specifier and the given type. Subclasses may override - /// this routine to provide different behavior. - QualType RebuildDependentTemplateSpecializationType( - ElaboratedTypeKeyword Keyword, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, - const IdentifierInfo *Name, - SourceLocation NameLoc, - const TemplateArgumentListInfo &Args) { - // Rebuild the template name. - // TODO: avoid TemplateName abstraction - TemplateName InstName = - getDerived().RebuildTemplateName(Qualifier, QualifierRange, *Name, - QualType(), 0); - - if (InstName.isNull()) - return QualType(); - - // If it's still dependent, make a dependent specialization. - if (InstName.getAsDependentTemplateName()) - return SemaRef.Context.getDependentTemplateSpecializationType( - Keyword, Qualifier, Name, Args); - - // Otherwise, make an elaborated type wrapping a non-dependent - // specialization. - QualType T = - getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args); - if (T.isNull()) return QualType(); - - if (Keyword == ETK_None && Qualifier == 0) - return T; - - return SemaRef.Context.getElaboratedType(Keyword, Qualifier, T); - } - /// \brief Build a new typename type that refers to a template-id. /// /// By default, builds a new DependentNameType type from the @@ -786,10 +774,10 @@ public: const TemplateArgumentListInfo &Args) { // Rebuild the template name. // TODO: avoid TemplateName abstraction + CXXScopeSpec SS; + SS.Adopt(QualifierLoc); TemplateName InstName - = getDerived().RebuildTemplateName(QualifierLoc.getNestedNameSpecifier(), - QualifierLoc.getSourceRange(), *Name, - QualType(), 0); + = getDerived().RebuildTemplateName(SS, *Name, NameLoc, QualType(), 0); if (InstName.isNull()) return QualType(); @@ -974,7 +962,7 @@ public: /// /// By default, builds the new template name directly. Subclasses may override /// this routine to provide different behavior. - TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier, + TemplateName RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW, TemplateDecl *Template); @@ -985,9 +973,9 @@ public: /// be resolved to a specific template, then builds the appropriate kind of /// template name. Subclasses may override this routine to provide different /// behavior. - TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, - const IdentifierInfo &II, + TemplateName RebuildTemplateName(CXXScopeSpec &SS, + const IdentifierInfo &Name, + SourceLocation NameLoc, QualType ObjectType, NamedDecl *FirstQualifierInScope); @@ -998,8 +986,9 @@ public: /// be resolved to a specific template, then builds the appropriate kind of /// template name. Subclasses may override this routine to provide different /// behavior. - TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier, + TemplateName RebuildTemplateName(CXXScopeSpec &SS, OverloadedOperatorKind Operator, + SourceLocation NameLoc, QualType ObjectType); /// \brief Build a new template name given a template template parameter pack @@ -2728,6 +2717,7 @@ TemplateName TreeTransform::TransformTemplateName(TemplateName Name, QualType ObjectType, NamedDecl *FirstQualifierInScope) { + // FIXME: This routine needs to go away. SourceLocation Loc = getDerived().getBaseLocation(); if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) { @@ -2750,7 +2740,9 @@ TreeTransform::TransformTemplateName(TemplateName Name, TransTemplate == Template) return Name; - return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(), + CXXScopeSpec SS; + SS.MakeTrivial(SemaRef.Context, NNS, Loc); + return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(), TransTemplate); } @@ -2777,16 +2769,19 @@ TreeTransform::TransformTemplateName(TemplateName Name, ObjectType.isNull()) return Name; + // FIXME: Bad source-location information all around. + CXXScopeSpec SS; + SS.MakeTrivial(SemaRef.Context, NNS, getDerived().getBaseLocation()); if (DTN->isIdentifier()) { - // FIXME: Bad range - SourceRange QualifierRange(getDerived().getBaseLocation()); - return getDerived().RebuildTemplateName(NNS, QualifierRange, - *DTN->getIdentifier(), + return getDerived().RebuildTemplateName(SS, + *DTN->getIdentifier(), + getDerived().getBaseLocation(), ObjectType, FirstQualifierInScope); } - return getDerived().RebuildTemplateName(NNS, DTN->getOperator(), + return getDerived().RebuildTemplateName(SS, DTN->getOperator(), + getDerived().getBaseLocation(), ObjectType); } @@ -2824,6 +2819,91 @@ TreeTransform::TransformTemplateName(TemplateName Name, return TemplateName(); } +template +TemplateName +TreeTransform::TransformTemplateName(CXXScopeSpec &SS, + TemplateName Name, + SourceLocation NameLoc, + QualType ObjectType, + NamedDecl *FirstQualifierInScope) { + if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) { + TemplateDecl *Template = QTN->getTemplateDecl(); + assert(Template && "qualified template name must refer to a template"); + + TemplateDecl *TransTemplate + = cast_or_null(getDerived().TransformDecl(NameLoc, + Template)); + if (!TransTemplate) + return TemplateName(); + + if (!getDerived().AlwaysRebuild() && + SS.getScopeRep() == QTN->getQualifier() && + TransTemplate == Template) + return Name; + + return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(), + TransTemplate); + } + + if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) { + if (SS.getScopeRep()) { + // These apply to the scope specifier, not the template. + ObjectType = QualType(); + FirstQualifierInScope = 0; + } + + if (!getDerived().AlwaysRebuild() && + SS.getScopeRep() == DTN->getQualifier() && + ObjectType.isNull()) + return Name; + + if (DTN->isIdentifier()) { + return getDerived().RebuildTemplateName(SS, + *DTN->getIdentifier(), + NameLoc, + ObjectType, + FirstQualifierInScope); + } + + return getDerived().RebuildTemplateName(SS, DTN->getOperator(), NameLoc, + ObjectType); + } + + if (TemplateDecl *Template = Name.getAsTemplateDecl()) { + TemplateDecl *TransTemplate + = cast_or_null(getDerived().TransformDecl(NameLoc, + Template)); + if (!TransTemplate) + return TemplateName(); + + if (!getDerived().AlwaysRebuild() && + TransTemplate == Template) + return Name; + + return TemplateName(TransTemplate); + } + + if (SubstTemplateTemplateParmPackStorage *SubstPack + = Name.getAsSubstTemplateTemplateParmPack()) { + TemplateTemplateParmDecl *TransParam + = cast_or_null( + getDerived().TransformDecl(NameLoc, SubstPack->getParameterPack())); + if (!TransParam) + return TemplateName(); + + if (!getDerived().AlwaysRebuild() && + TransParam == SubstPack->getParameterPack()) + return Name; + + return getDerived().RebuildTemplateName(TransParam, + SubstPack->getArgumentPack()); + } + + // These should be getting filtered out before they reach the AST. + llvm_unreachable("overloaded function decl survived to here"); + return TemplateName(); +} + template void TreeTransform::InventTemplateArgumentLoc( const TemplateArgument &Arg, @@ -3353,7 +3433,9 @@ TreeTransform::TransformTypeInObjectScope(TypeLoc TL, = cast(TL); TemplateName Template = - getDerived().TransformTemplateName(SpecTL.getTypePtr()->getTemplateName(), + getDerived().TransformTemplateName(SS, + SpecTL.getTypePtr()->getTemplateName(), + SpecTL.getTemplateNameLoc(), ObjectType, UnqualLookup); if (Template.isNull()) return TypeLoc(); @@ -3365,8 +3447,9 @@ TreeTransform::TransformTypeInObjectScope(TypeLoc TL, = cast(TL); TemplateName Template - = getDerived().RebuildTemplateName(SS.getScopeRep(), SS.getRange(), + = getDerived().RebuildTemplateName(SS, *SpecTL.getTypePtr()->getIdentifier(), + SpecTL.getNameLoc(), ObjectType, UnqualLookup); if (Template.isNull()) return TypeLoc(); @@ -4678,10 +4761,12 @@ QualType TreeTransform:: NewTemplateArgs)) return QualType(); + CXXScopeSpec SS; + SS.MakeTrivial(SemaRef.Context, NNS, + TL.getQualifierLoc().getSourceRange()); QualType Result = getDerived().RebuildDependentTemplateSpecializationType(T->getKeyword(), - NNS, - TL.getQualifierLoc().getSourceRange(), + SS.getWithLocInContext(SemaRef.Context), T->getIdentifier(), TL.getNameLoc(), NewTemplateArgs); @@ -7976,29 +8061,27 @@ TreeTransform::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix, template TemplateName -TreeTransform::RebuildTemplateName(NestedNameSpecifier *Qualifier, +TreeTransform::RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW, TemplateDecl *Template) { - return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, + return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW, Template); } template TemplateName -TreeTransform::RebuildTemplateName(NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, - const IdentifierInfo &II, +TreeTransform::RebuildTemplateName(CXXScopeSpec &SS, + const IdentifierInfo &Name, + SourceLocation NameLoc, QualType ObjectType, NamedDecl *FirstQualifierInScope) { - CXXScopeSpec SS; - SS.MakeTrivial(SemaRef.Context, Qualifier, QualifierRange); - UnqualifiedId Name; - Name.setIdentifier(&II, /*FIXME:*/getDerived().getBaseLocation()); + UnqualifiedId TemplateName; + TemplateName.setIdentifier(&Name, NameLoc); Sema::TemplateTy Template; getSema().ActOnDependentTemplateName(/*Scope=*/0, - /*FIXME:*/getDerived().getBaseLocation(), + /*FIXME:*/SourceLocation(), SS, - Name, + TemplateName, ParsedType::make(ObjectType), /*EnteringContext=*/false, Template); @@ -8007,18 +8090,17 @@ TreeTransform::RebuildTemplateName(NestedNameSpecifier *Qualifier, template TemplateName -TreeTransform::RebuildTemplateName(NestedNameSpecifier *Qualifier, +TreeTransform::RebuildTemplateName(CXXScopeSpec &SS, OverloadedOperatorKind Operator, + SourceLocation NameLoc, QualType ObjectType) { - CXXScopeSpec SS; - SS.MakeTrivial(SemaRef.Context, Qualifier, SourceRange(getDerived().getBaseLocation())); UnqualifiedId Name; - SourceLocation SymbolLocations[3]; // FIXME: Bogus location information. - Name.setOperatorFunctionId(/*FIXME:*/getDerived().getBaseLocation(), - Operator, SymbolLocations); + // FIXME: Bogus location information. + SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc }; + Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations); Sema::TemplateTy Template; getSema().ActOnDependentTemplateName(/*Scope=*/0, - /*FIXME:*/getDerived().getBaseLocation(), + /*FIXME:*/SourceLocation(), SS, Name, ParsedType::make(ObjectType),