Push nested-name-specifier source-location information into dependent
template specialization types. There are still a few rough edges to
clean up with some of the parser actions dropping
nested-name-specifiers too early.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126776 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 6139aae..d92f759 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -663,8 +663,8 @@
assert(DTN->getQualifier()
== static_cast<NestedNameSpecifier*>(SS.getScopeRep()));
QualType T = Context.getDependentTemplateSpecializationType(ETK_None,
- DTN->getQualifier(),
- DTN->getIdentifier(),
+ DTN->getQualifier(),
+ DTN->getIdentifier(),
TemplateArgs);
// Create source-location information for this type.
@@ -675,7 +675,7 @@
SpecTL.setRAngleLoc(RAngleLoc);
SpecTL.setKeywordLoc(SourceLocation());
SpecTL.setNameLoc(TemplateNameLoc);
- SpecTL.setQualifierRange(SS.getRange());
+ SpecTL.setQualifierLoc(SS.getWithLocInContext(Context));
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index a710f94..16edbf7 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1767,7 +1767,11 @@
SpecTL.setNameLoc(TemplateLoc);
SpecTL.setLAngleLoc(LAngleLoc);
SpecTL.setRAngleLoc(RAngleLoc);
- SpecTL.setQualifierRange(TemplateLoc); // FIXME: nested-name-specifier loc
+
+ // FIXME: Poor nested-name-specifier source-location information.
+ CXXScopeSpec SS;
+ SS.MakeTrivial(Context, DTN->getQualifier(), TemplateLoc);
+ 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));
@@ -5967,12 +5971,10 @@
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());
-
- // FIXME: Nested-name-specifier source locations.
- SpecTL.setQualifierRange(SS.getRange());
return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
}
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index afd118e..a2f1a6b 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -2276,8 +2276,7 @@
? DS.getTypeSpecTypeLoc()
: SourceLocation());
const CXXScopeSpec& SS = DS.getTypeSpecScope();
- TL.setQualifierRange(SS.isEmpty() ? SourceRange() : SS.getRange());
- // FIXME: load appropriate source location.
+ TL.setQualifierLoc(SS.getWithLocInContext(Context));
TL.setNameLoc(DS.getTypeSpecTypeLoc());
}
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 5485dfb..bd1e676 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -498,6 +498,11 @@
DependentTemplateSpecializationTypeLoc TL,
NestedNameSpecifier *Prefix);
+ QualType
+ TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
+ DependentTemplateSpecializationTypeLoc TL,
+ NestedNameSpecifierLoc QualifierLoc);
+
/// \brief Transforms the parameters of a function type into the
/// given vectors.
///
@@ -768,6 +773,48 @@
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
+ /// nested-name-specifier and the given type. Subclasses may override
+ /// this routine to provide different behavior.
+ QualType RebuildDependentTemplateSpecializationType(
+ ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifierLoc QualifierLoc,
+ const IdentifierInfo *Name,
+ SourceLocation NameLoc,
+ const TemplateArgumentListInfo &Args) {
+ // Rebuild the template name.
+ // TODO: avoid TemplateName abstraction
+ TemplateName InstName
+ = getDerived().RebuildTemplateName(QualifierLoc.getNestedNameSpecifier(),
+ QualifierLoc.getSourceRange(), *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,
+ QualifierLoc.getNestedNameSpecifier(),
+ 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 && QualifierLoc.getNestedNameSpecifier() == 0)
+ return T;
+
+ return SemaRef.Context.getElaboratedType(Keyword,
+ QualifierLoc.getNestedNameSpecifier(),
+ T);
+ }
+
/// \brief Build a new typename type that refers to an identifier.
///
/// By default, performs semantic analysis when building the typename type
@@ -4405,7 +4452,12 @@
DependentTemplateSpecializationTypeLoc NewTL
= TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
NewTL.setKeywordLoc(TL.getKeywordLoc());
- NewTL.setQualifierRange(TL.getQualifierRange());
+
+ // FIXME: Poor nested-name-specifier source-location information.
+ CXXScopeSpec SS;
+ SS.MakeTrivial(SemaRef.Context,
+ DTN->getQualifier(), TL.getQualifierLoc().getSourceRange());
+ NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
NewTL.setNameLoc(TL.getNameLoc());
NewTL.setLAngleLoc(TL.getLAngleLoc());
NewTL.setRAngleLoc(TL.getRAngleLoc());
@@ -4567,18 +4619,16 @@
QualType TreeTransform<Derived>::
TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
DependentTemplateSpecializationTypeLoc TL) {
- const DependentTemplateSpecializationType *T = TL.getTypePtr();
-
- NestedNameSpecifier *NNS = 0;
- if (T->getQualifier()) {
- NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
- TL.getQualifierRange());
- if (!NNS)
+ NestedNameSpecifierLoc QualifierLoc;
+ if (TL.getQualifierLoc()) {
+ QualifierLoc
+ = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
+ if (!QualifierLoc)
return QualType();
}
return getDerived()
- .TransformDependentTemplateSpecializationType(TLB, TL, NNS);
+ .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
}
template<typename Derived>
@@ -4586,6 +4636,7 @@
TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
DependentTemplateSpecializationTypeLoc TL,
NestedNameSpecifier *NNS) {
+ // FIXME: This routine needs to go away.
const DependentTemplateSpecializationType *T = TL.getTypePtr();
TemplateArgumentListInfo NewTemplateArgs;
@@ -4603,7 +4654,7 @@
QualType Result
= getDerived().RebuildDependentTemplateSpecializationType(T->getKeyword(),
NNS,
- TL.getQualifierRange(),
+ TL.getQualifierLoc().getSourceRange(),
T->getIdentifier(),
TL.getNameLoc(),
NewTemplateArgs);
@@ -4628,7 +4679,8 @@
// FIXME: DependentTemplateSpecializationType needs better source-location
// info.
NestedNameSpecifierLocBuilder Builder;
- Builder.MakeTrivial(SemaRef.Context, NNS, TL.getQualifierRange());
+ Builder.MakeTrivial(SemaRef.Context,
+ NNS, TL.getQualifierLoc().getSourceRange());
NewTL.setQualifierLoc(Builder.getWithLocInContext(SemaRef.Context));
} else {
TypeLoc NewTL(Result, TL.getOpaqueData());
@@ -4638,6 +4690,55 @@
}
template<typename Derived>
+QualType TreeTransform<Derived>::
+TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
+ DependentTemplateSpecializationTypeLoc TL,
+ NestedNameSpecifierLoc QualifierLoc) {
+ const DependentTemplateSpecializationType *T = TL.getTypePtr();
+
+ TemplateArgumentListInfo NewTemplateArgs;
+ NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
+ NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
+
+ typedef TemplateArgumentLocContainerIterator<
+ DependentTemplateSpecializationTypeLoc> ArgIterator;
+ if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
+ ArgIterator(TL, TL.getNumArgs()),
+ NewTemplateArgs))
+ return QualType();
+
+ QualType Result
+ = getDerived().RebuildDependentTemplateSpecializationType(T->getKeyword(),
+ QualifierLoc,
+ T->getIdentifier(),
+ TL.getNameLoc(),
+ NewTemplateArgs);
+ if (Result.isNull())
+ return QualType();
+
+ if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
+ QualType NamedT = ElabT->getNamedType();
+
+ // Copy information relevant to the template specialization.
+ TemplateSpecializationTypeLoc NamedTL
+ = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
+ NamedTL.setLAngleLoc(TL.getLAngleLoc());
+ NamedTL.setRAngleLoc(TL.getRAngleLoc());
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
+ NamedTL.setArgLocInfo(I, TL.getArgLocInfo(I));
+
+ // Copy information relevant to the elaborated type.
+ ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
+ NewTL.setKeywordLoc(TL.getKeywordLoc());
+ NewTL.setQualifierLoc(QualifierLoc);
+ } else {
+ TypeLoc NewTL(Result, TL.getOpaqueData());
+ TLB.pushFullCopy(NewTL);
+ }
+ return Result;
+}
+
+template<typename Derived>
QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
PackExpansionTypeLoc TL) {
QualType Pattern