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
This commit is contained in:
Douglas Gregor 2011-03-02 18:07:45 +00:00
Родитель 3da5cb2d6e
Коммит fd4ffebd8e
2 изменённых файлов: 218 добавлений и 74 удалений

Просмотреть файл

@ -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<TemplateTemplateParmDecl>(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())

Просмотреть файл

@ -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<Derived>::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<Derived>::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<Derived>::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<Derived>::TransformTemplateName(TemplateName Name,
return TemplateName();
}
template<typename Derived>
TemplateName
TreeTransform<Derived>::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<TemplateDecl>(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<TemplateDecl>(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<TemplateTemplateParmDecl>(
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<typename Derived>
void TreeTransform<Derived>::InventTemplateArgumentLoc(
const TemplateArgument &Arg,
@ -3353,7 +3433,9 @@ TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
= cast<TemplateSpecializationTypeLoc>(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<Derived>::TransformTypeInObjectScope(TypeLoc TL,
= cast<DependentTemplateSpecializationTypeLoc>(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<Derived>::
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<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
template<typename Derived>
TemplateName
TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
bool TemplateKW,
TemplateDecl *Template) {
return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW,
Template);
}
template<typename Derived>
TemplateName
TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
const IdentifierInfo &II,
TreeTransform<Derived>::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<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
template<typename Derived>
TemplateName
TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
TreeTransform<Derived>::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),