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
This commit is contained in:
Douglas Gregor 2011-03-01 20:11:18 +00:00
Родитель 438d7f05d3
Коммит 94fdffa4a5
12 изменённых файлов: 260 добавлений и 43 удалений

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

@ -999,7 +999,10 @@ DEF_TRAVERSE_TYPELOC(DependentNameType, {
})
DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
if (TL.getQualifierLoc()) {
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
}
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
}

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

@ -1501,10 +1501,8 @@ public:
void initializeLocal(ASTContext &Context, SourceLocation Loc);
};
struct DependentTemplateSpecializationLocInfo {
struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
SourceLocation KeywordLoc;
SourceLocation NameLoc;
SourceRange QualifierRange;
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
// followed by a TemplateArgumentLocInfo[]
@ -1523,11 +1521,28 @@ public:
this->getLocalData()->KeywordLoc = Loc;
}
SourceRange getQualifierRange() const {
return this->getLocalData()->QualifierRange;
NestedNameSpecifierLoc getQualifierLoc() const {
if (!getLocalData()->QualifierData)
return NestedNameSpecifierLoc();
return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
getLocalData()->QualifierData);
}
void setQualifierRange(SourceRange Range) {
this->getLocalData()->QualifierRange = Range;
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
if (!QualifierLoc) {
// Even if we have a nested-name-specifier in the dependent
// template specialization type, we won't record the nested-name-specifier
// location information when this type-source location information is
// part of a nested-name-specifier.
getLocalData()->QualifierData = 0;
return;
}
assert(QualifierLoc.getNestedNameSpecifier()
== getTypePtr()->getQualifier() &&
"Inconsistent nested-name-specifier pointer");
getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
SourceLocation getNameLoc() const {
@ -1569,8 +1584,8 @@ public:
SourceRange getLocalSourceRange() const {
if (getKeywordLoc().isValid())
return SourceRange(getKeywordLoc(), getRAngleLoc());
else if (getQualifierRange().isValid())
return SourceRange(getQualifierRange().getBegin(), getRAngleLoc());
else if (getQualifierLoc())
return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
else
return SourceRange(getNameLoc(), getRAngleLoc());
}
@ -1581,16 +1596,7 @@ public:
memcpy(Data, Loc.Data, size);
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setKeywordLoc(Loc);
setQualifierRange(SourceRange(Loc));
setNameLoc(Loc);
setLAngleLoc(Loc);
setRAngleLoc(Loc);
TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
getTypePtr()->getArgs(),
getArgInfos(), Loc);
}
void initializeLocal(ASTContext &Context, SourceLocation Loc);
unsigned getExtraLocalDataSize() const {
return getNumArgs() * sizeof(TemplateArgumentLocInfo);

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

@ -246,6 +246,26 @@ void DependentNameTypeLoc::initializeLocal(ASTContext &Context,
setNameLoc(Loc);
}
void
DependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,
SourceLocation Loc) {
setKeywordLoc(Loc);
if (getTypePtr()->getQualifier()) {
NestedNameSpecifierLocBuilder Builder;
Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
setQualifierLoc(Builder.getWithLocInContext(Context));
} else {
setQualifierLoc(NestedNameSpecifierLoc());
}
setNameLoc(Loc);
setLAngleLoc(Loc);
setRAngleLoc(Loc);
TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
getTypePtr()->getArgs(),
getArgInfos(), Loc);
}
void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context,
unsigned NumArgs,
const TemplateArgument *Args,

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

@ -663,8 +663,8 @@ bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
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 @@ bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
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());

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

@ -1767,7 +1767,11 @@ Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
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 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
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));
}

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

@ -2276,8 +2276,7 @@ namespace {
? 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());
}

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

@ -498,6 +498,11 @@ public:
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 @@ public:
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 @@ QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
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 @@ template<typename Derived>
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 @@ QualType TreeTransform<Derived>::
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 TreeTransform<Derived>::
QualType Result
= getDerived().RebuildDependentTemplateSpecializationType(T->getKeyword(),
NNS,
TL.getQualifierRange(),
TL.getQualifierLoc().getSourceRange(),
T->getIdentifier(),
TL.getNameLoc(),
NewTemplateArgs);
@ -4628,7 +4679,8 @@ QualType TreeTransform<Derived>::
// 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());
@ -4637,6 +4689,55 @@ QualType TreeTransform<Derived>::
return Result;
}
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) {

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

@ -3533,7 +3533,7 @@ void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
DependentTemplateSpecializationTypeLoc TL) {
TL.setKeywordLoc(ReadSourceLocation(Record, Idx));
TL.setQualifierRange(Reader.ReadSourceRange(F, Record, Idx));
TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
TL.setNameLoc(ReadSourceLocation(Record, Idx));
TL.setLAngleLoc(ReadSourceLocation(Record, Idx));
TL.setRAngleLoc(ReadSourceLocation(Record, Idx));

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

@ -545,7 +545,7 @@ void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
void TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc(
DependentTemplateSpecializationTypeLoc TL) {
Writer.AddSourceLocation(TL.getKeywordLoc(), Record);
Writer.AddSourceRange(TL.getQualifierRange(), Record);
Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record);
Writer.AddSourceLocation(TL.getNameLoc(), Record);
Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
Writer.AddSourceLocation(TL.getRAngleLoc(), Record);

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

@ -101,7 +101,14 @@ struct X5 {
typedef typename outer_alias::inner::vector<int>::iterator int_ptr_type;
};
// RUN: c-index-test -test-annotate-tokens=%s:13:1:102:1 %s | FileCheck %s
template<typename T>
struct X6 {
typedef T type;
typedef typename outer_alias::inner::vector<type>::template rebind<type> type1;
typedef typename outer_alias::inner::vector<type>::template rebind<type>::other type2;
};
// RUN: c-index-test -test-annotate-tokens=%s:13:1:109:1 %s | FileCheck %s
// CHECK: Keyword: "using" [14:1 - 14:6] UsingDeclaration=vector[4:12]
// CHECK: Identifier: "outer_alias" [14:7 - 14:18] NamespaceRef=outer_alias:10:11
@ -321,3 +328,40 @@ struct X5 {
// CHECK: Identifier: "iterator" [101:53 - 101:61] TypeRef=iterator:5:18
// CHECK: Identifier: "int_ptr_type" [101:62 - 101:74] TypedefDecl=int_ptr_type:101:62 (Definition)
// Dependent template specialization types
// CHECK: Keyword: "typename" [107:11 - 107:19] TypedefDecl=type1:107:76 (Definition)
// CHECK: Identifier: "outer_alias" [107:20 - 107:31] NamespaceRef=outer_alias:10:11
// CHECK: Punctuation: "::" [107:31 - 107:33] TypedefDecl=type1:107:76 (Definition)
// CHECK: Identifier: "inner" [107:33 - 107:38] NamespaceRef=inner:62:13
// CHECK: Punctuation: "::" [107:38 - 107:40] TypedefDecl=type1:107:76 (Definition)
// CHECK: Identifier: "vector" [107:40 - 107:46] TemplateRef=vector:4:12
// CHECK: Punctuation: "<" [107:46 - 107:47] TypedefDecl=type1:107:76 (Definition)
// CHECK: Identifier: "type" [107:47 - 107:51] TypeRef=type:106:13
// CHECK: Punctuation: ">" [107:51 - 107:52] TypedefDecl=type1:107:76 (Definition)
// CHECK: Punctuation: "::" [107:52 - 107:54] TypedefDecl=type1:107:76 (Definition)
// CHECK: Keyword: "template" [107:54 - 107:62] TypedefDecl=type1:107:76 (Definition)
// CHECK: Identifier: "rebind" [107:63 - 107:69] TypedefDecl=type1:107:76 (Definition)
// CHECK: Punctuation: "<" [107:69 - 107:70] TypedefDecl=type1:107:76 (Definition)
// CHECK: Identifier: "type" [107:70 - 107:74] TypeRef=type:106:13
// CHECK: Punctuation: ">" [107:74 - 107:75] TypedefDecl=type1:107:76 (Definition)
// CHECK: Identifier: "type1" [107:76 - 107:81] TypedefDecl=type1:107:76 (Definition)
// CHECK: Keyword: "typedef" [108:3 - 108:10] ClassTemplate=X6:105:8 (Definition)
// CHECK: Keyword: "typename" [108:11 - 108:19] TypedefDecl=type2:108:83 (Definition)
// CHECK: Identifier: "outer_alias" [108:20 - 108:31] NamespaceRef=outer_alias:10:11
// CHECK: Punctuation: "::" [108:31 - 108:33] TypedefDecl=type2:108:83 (Definition)
// CHECK: Identifier: "inner" [108:33 - 108:38] NamespaceRef=inner:62:13
// CHECK: Punctuation: "::" [108:38 - 108:40] TypedefDecl=type2:108:83 (Definition)
// CHECK: Identifier: "vector" [108:40 - 108:46] TemplateRef=vector:4:12
// CHECK: Punctuation: "<" [108:46 - 108:47] TypedefDecl=type2:108:83 (Definition)
// CHECK: Identifier: "type" [108:47 - 108:51] TypeRef=type:106:13
// CHECK: Punctuation: ">" [108:51 - 108:52] TypedefDecl=type2:108:83 (Definition)
// CHECK: Punctuation: "::" [108:52 - 108:54] TypedefDecl=type2:108:83 (Definition)
// CHECK: Keyword: "template" [108:54 - 108:62] TypedefDecl=type2:108:83 (Definition)
// CHECK: Identifier: "rebind" [108:63 - 108:69] TypedefDecl=type2:108:83 (Definition)
// CHECK: Punctuation: "<" [108:69 - 108:70] TypedefDecl=type2:108:83 (Definition)
// CHECK: Identifier: "type" [108:70 - 108:74] TypeRef=type:106:13
// CHECK: Punctuation: ">" [108:74 - 108:75] TypedefDecl=type2:108:83 (Definition)
// CHECK: Punctuation: "::" [108:75 - 108:77] TypedefDecl=type2:108:83 (Definition)
// CHECK: Identifier: "other" [108:77 - 108:82] TypedefDecl=type2:108:83 (Definition)
// CHECK: Identifier: "type2" [108:83 - 108:88] TypedefDecl=type2:108:83 (Definition)

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

@ -85,3 +85,28 @@ struct TypenameTypeTester {
};
TypenameTypeTester<int> TypenameTypeCheck; // expected-note{{in instantiation of template class}}
template<typename T, typename U>
struct DependentTemplateSpecializationTypeTester {
typedef typename T::template apply<typename add_reference<U>::type
* // expected-error{{declared as a pointer to a reference of type}}
>::type type;
};
struct HasApply {
template<typename T>
struct apply {
typedef T type;
};
};
DependentTemplateSpecializationTypeTester<HasApply, int> DTSTCheck; // expected-note{{in instantiation of template class}}
template<typename T, typename U>
struct DependentTemplateSpecializationTypeTester2 {
typedef typename T::template apply<typename add_reference<U>::type
* // expected-error{{declared as a pointer to a reference of type}}
> type;
};
DependentTemplateSpecializationTypeTester2<HasApply, int> DTSTCheck2; // expected-note{{in instantiation of template class}}

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

@ -343,6 +343,8 @@ public:
bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
bool VisitDependentTemplateSpecializationTypeLoc(
DependentTemplateSpecializationTypeLoc TL);
bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
// Data-recursive visitor functions.
@ -1512,6 +1514,21 @@ bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
return false;
}
bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
DependentTemplateSpecializationTypeLoc TL) {
// Visit the nested-name-specifier, if there is one.
if (TL.getQualifierLoc() &&
VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
return true;
// Visit the template arguments.
for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
return true;
return false;
}
bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
return true;