зеркало из https://github.com/microsoft/clang.git
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:
Родитель
438d7f05d3
Коммит
94fdffa4a5
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче