Update UsingDecl, UnresolvedUsingTypenameDecl, and
UnresolvedUsingValueDecl to use NestedNameSpecifierLoc rather than the
extremely-lossy NestedNameSpecifier/SourceRange pair it used to use,
improving source-location information.
Various infrastructure updates to support NestedNameSpecifierLoc:
- AST/PCH (de-)serialization
- Recursive AST visitor
- libclang traversal (including the first tests of this
functionality)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126459 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index c0300c5..ccc883e 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -868,9 +868,13 @@
return cast<UsingShadowDecl>(this)->getTargetDecl() ==
cast<UsingShadowDecl>(OldD)->getTargetDecl();
- if (isa<UsingDecl>(this) && isa<UsingDecl>(OldD))
- return cast<UsingDecl>(this)->getTargetNestedNameDecl() ==
- cast<UsingDecl>(OldD)->getTargetNestedNameDecl();
+ if (isa<UsingDecl>(this) && isa<UsingDecl>(OldD)) {
+ ASTContext &Context = getASTContext();
+ return Context.getCanonicalNestedNameSpecifier(
+ cast<UsingDecl>(this)->getQualifier()) ==
+ Context.getCanonicalNestedNameSpecifier(
+ cast<UsingDecl>(OldD)->getQualifier());
+ }
// For non-function declarations, if the declarations are of the
// same kind then this must be a redeclaration, or semantic analysis
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index fba73f5..a1d6cc3 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -1337,35 +1337,31 @@
S->UsingOrNextShadow = this;
}
-UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC,
- SourceRange NNR, SourceLocation UL,
- NestedNameSpecifier* TargetNNS,
+UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL,
+ NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
bool IsTypeNameArg) {
- return new (C) UsingDecl(DC, NNR, UL, TargetNNS, NameInfo, IsTypeNameArg);
+ return new (C) UsingDecl(DC, UL, QualifierLoc, NameInfo, IsTypeNameArg);
}
UnresolvedUsingValueDecl *
UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation UsingLoc,
- SourceRange TargetNNR,
- NestedNameSpecifier *TargetNNS,
+ NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo) {
return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
- TargetNNR, TargetNNS, NameInfo);
+ QualifierLoc, NameInfo);
}
UnresolvedUsingTypenameDecl *
UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation UsingLoc,
SourceLocation TypenameLoc,
- SourceRange TargetNNR,
- NestedNameSpecifier *TargetNNS,
+ NestedNameSpecifierLoc QualifierLoc,
SourceLocation TargetNameLoc,
DeclarationName TargetName) {
return new (C) UnresolvedUsingTypenameDecl(DC, UsingLoc, TypenameLoc,
- TargetNNR, TargetNNS,
- TargetNameLoc,
+ QualifierLoc, TargetNameLoc,
TargetName.getAsIdentifierInfo());
}
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 77b4257..c6ae128 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -918,20 +918,20 @@
void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
Out << "using ";
- D->getTargetNestedNameDecl()->print(Out, Policy);
+ D->getQualifier()->print(Out, Policy);
Out << D;
}
void
DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
Out << "using typename ";
- D->getTargetNestedNameSpecifier()->print(Out, Policy);
+ D->getQualifier()->print(Out, Policy);
Out << D->getDeclName();
}
void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Out << "using ";
- D->getTargetNestedNameSpecifier()->print(Out, Policy);
+ D->getQualifier()->print(Out, Policy);
Out << D->getDeclName();
}
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index da12aa7..0689ae1 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -320,7 +320,7 @@
}
}
-SourceRange NestedNameSpecifierLoc::getSourceRange() {
+SourceRange NestedNameSpecifierLoc::getSourceRange() const {
NestedNameSpecifierLoc First = *this;
while (NestedNameSpecifierLoc Prefix= First.getPrefix())
First = Prefix;
@@ -329,7 +329,7 @@
getLocalSourceRange().getEnd());
}
-SourceRange NestedNameSpecifierLoc::getLocalSourceRange() {
+SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
unsigned Offset = getDataLength(Qualifier->getPrefix());
switch (Qualifier->getKind()) {
case NestedNameSpecifier::Global:
@@ -354,3 +354,14 @@
return SourceRange();
}
+
+TypeLoc NestedNameSpecifierLoc::getTypeLoc() const {
+ assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec ||
+ Qualifier->getKind() == NestedNameSpecifier::TypeSpecWithTemplate) &&
+ "Nested-name-specifier location is not a type");
+
+ // The "void*" that points at the TypeLoc data.
+ unsigned Offset = getDataLength(Qualifier->getPrefix());
+ void *TypeData = LoadPointer(Data, Offset);
+ return TypeLoc(Qualifier->getAsType(), TypeData);
+}
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index 846bd4c..5c7dbb3 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -279,8 +279,8 @@
// print using decl (e.g. "using std::string;")
const char *tn = UD->isTypeName() ? "typename " : "";
OS << '"' << UD->getDeclKindName() << tn;
- UD->getTargetNestedNameDecl()->print(OS,
- PrintingPolicy(UD->getASTContext().getLangOptions()));
+ UD->getQualifier()->print(OS,
+ PrintingPolicy(UD->getASTContext().getLangOptions()));
OS << ";\"";
} else if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) {
OS << "label " << LD->getNameAsString();
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 8e1792b..89b2263 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -3919,16 +3919,16 @@
if (OrigDC == CurContext) {
Diag(Using->getLocation(),
diag::err_using_decl_nested_name_specifier_is_current_class)
- << Using->getNestedNameRange();
+ << Using->getQualifierLoc().getSourceRange();
Diag(Orig->getLocation(), diag::note_using_decl_target);
return true;
}
- Diag(Using->getNestedNameRange().getBegin(),
+ Diag(Using->getQualifierLoc().getBeginLoc(),
diag::err_using_decl_nested_name_specifier_is_not_base_class)
- << Using->getTargetNestedNameDecl()
+ << Using->getQualifier()
<< cast<CXXRecordDecl>(CurContext)
- << Using->getNestedNameRange();
+ << Using->getQualifierLoc().getSourceRange();
Diag(Orig->getLocation(), diag::note_using_decl_target);
return true;
}
@@ -4134,8 +4134,6 @@
LookupQualifiedName(Previous, CurContext);
}
- NestedNameSpecifier *NNS = SS.getScopeRep();
-
// Check for invalid redeclarations.
if (CheckUsingDeclRedeclaration(UsingLoc, IsTypeName, SS, IdentLoc, Previous))
return 0;
@@ -4146,22 +4144,21 @@
DeclContext *LookupContext = computeDeclContext(SS);
NamedDecl *D;
+ NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
if (!LookupContext) {
if (IsTypeName) {
// FIXME: not all declaration name kinds are legal here
D = UnresolvedUsingTypenameDecl::Create(Context, CurContext,
UsingLoc, TypenameLoc,
- SS.getRange(), NNS,
+ QualifierLoc,
IdentLoc, NameInfo.getName());
} else {
- D = UnresolvedUsingValueDecl::Create(Context, CurContext,
- UsingLoc, SS.getRange(),
- NNS, NameInfo);
+ D = UnresolvedUsingValueDecl::Create(Context, CurContext, UsingLoc,
+ QualifierLoc, NameInfo);
}
} else {
- D = UsingDecl::Create(Context, CurContext,
- SS.getRange(), UsingLoc, NNS, NameInfo,
- IsTypeName);
+ D = UsingDecl::Create(Context, CurContext, UsingLoc, QualifierLoc,
+ NameInfo, IsTypeName);
}
D->setAccess(AS);
CurContext->addDecl(D);
@@ -4252,7 +4249,7 @@
return true;
}
- const Type *SourceType = UD->getTargetNestedNameDecl()->getAsType();
+ const Type *SourceType = UD->getQualifier()->getAsType();
assert(SourceType &&
"Using decl naming constructor doesn't have type in scope spec.");
CXXRecordDecl *TargetClass = cast<CXXRecordDecl>(CurContext);
@@ -4309,15 +4306,15 @@
NestedNameSpecifier *DQual;
if (UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
DTypename = UD->isTypeName();
- DQual = UD->getTargetNestedNameDecl();
+ DQual = UD->getQualifier();
} else if (UnresolvedUsingValueDecl *UD
= dyn_cast<UnresolvedUsingValueDecl>(D)) {
DTypename = false;
- DQual = UD->getTargetNestedNameSpecifier();
+ DQual = UD->getQualifier();
} else if (UnresolvedUsingTypenameDecl *UD
= dyn_cast<UnresolvedUsingTypenameDecl>(D)) {
DTypename = true;
- DQual = UD->getTargetNestedNameSpecifier();
+ DQual = UD->getQualifier();
} else continue;
// using decls differ if one says 'typename' and the other doesn't.
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 474a18d..8f7b7da 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -6036,7 +6036,7 @@
<< Name << Ctx << FullRange;
if (UnresolvedUsingValueDecl *Using
= dyn_cast<UnresolvedUsingValueDecl>(Result.getRepresentativeDecl())){
- SourceLocation Loc = Using->getTargetNestedNameRange().getBegin();
+ SourceLocation Loc = Using->getQualifierLoc().getBeginLoc();
Diag(Loc, diag::note_using_value_decl_missing_typename)
<< FixItHint::CreateInsertion(Loc, "typename ");
}
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index de4cd46..e1a7065 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1661,12 +1661,12 @@
// template struct t<int>;
// Here, in using s1::f1, s1 refers to t<T>::s1;
// we need to substitute for t<int>::s1.
- NestedNameSpecifier *NNS =
- SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameDecl(),
- D->getNestedNameRange(),
- TemplateArgs);
+ NestedNameSpecifier *NNS
+ = SemaRef.SubstNestedNameSpecifier(D->getQualifier(),
+ D->getQualifierRange(),
+ TemplateArgs);
if (!NNS)
- return 0;
+ return 0;
// The name info is non-dependent, so no transformation
// is required.
@@ -1680,16 +1680,18 @@
LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName,
Sema::ForRedeclaration);
+ CXXScopeSpec SS;
+ if (NNS == D->getQualifier())
+ SS.Adopt(D->getQualifierLoc());
+ else
+ SS.MakeTrivial(SemaRef.Context, NNS, D->getQualifierRange());
+
UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner,
- D->getNestedNameRange(),
D->getUsingLocation(),
- NNS,
+ SS.getWithLocInContext(SemaRef.Context),
NameInfo,
D->isTypeName());
- CXXScopeSpec SS;
- SS.MakeTrivial(SemaRef.Context, NNS, D->getNestedNameRange());
-
if (CheckRedeclaration) {
Prev.setHideTags(false);
SemaRef.LookupQualifiedName(Prev, Owner);
@@ -1749,14 +1751,13 @@
Decl * TemplateDeclInstantiator
::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
NestedNameSpecifier *NNS =
- SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameSpecifier(),
- D->getTargetNestedNameRange(),
+ SemaRef.SubstNestedNameSpecifier(D->getQualifier(), D->getQualifierRange(),
TemplateArgs);
if (!NNS)
return 0;
CXXScopeSpec SS;
- SS.MakeTrivial(SemaRef.Context, NNS, D->getTargetNestedNameRange());
+ SS.MakeTrivial(SemaRef.Context, NNS, D->getQualifierRange());
// Since NameInfo refers to a typename, it cannot be a C++ special name.
// Hence, no tranformation is required for it.
@@ -1775,14 +1776,13 @@
Decl * TemplateDeclInstantiator
::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
NestedNameSpecifier *NNS =
- SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameSpecifier(),
- D->getTargetNestedNameRange(),
+ SemaRef.SubstNestedNameSpecifier(D->getQualifier(), D->getQualifierRange(),
TemplateArgs);
if (!NNS)
return 0;
CXXScopeSpec SS;
- SS.MakeTrivial(SemaRef.Context, NNS, D->getTargetNestedNameRange());
+ SS.MakeTrivial(SemaRef.Context, NNS, D->getQualifierRange());
DeclarationNameInfo NameInfo
= SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 6f8856c..93e3606 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -4759,6 +4759,109 @@
return NNS;
}
+NestedNameSpecifierLoc
+ASTReader::ReadNestedNameSpecifierLoc(PerFileData &F, const RecordData &Record,
+ unsigned &Idx) {
+ unsigned N = Record[Idx++];
+ NestedNameSpecifier *NNS = 0, *Prev = 0;
+ llvm::SmallVector<char, 32> LocationData;
+ for (unsigned I = 0; I != N; ++I) {
+ NestedNameSpecifier::SpecifierKind Kind
+ = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
+ switch (Kind) {
+ case NestedNameSpecifier::Identifier: {
+ // Nested-name-specifier
+ IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
+ NNS = NestedNameSpecifier::Create(*Context, Prev, II);
+
+ // Location information
+ SourceRange Range = ReadSourceRange(F, Record, Idx);
+ unsigned RawStart = Range.getBegin().getRawEncoding();
+ unsigned RawEnd = Range.getEnd().getRawEncoding();
+ LocationData.append(reinterpret_cast<char*>(&RawStart),
+ reinterpret_cast<char*>(&RawStart) +sizeof(unsigned));
+ LocationData.append(reinterpret_cast<char*>(&RawEnd),
+ reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned));
+ break;
+ }
+
+ case NestedNameSpecifier::Namespace: {
+ // Nested-name-specifier
+ NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
+ NNS = NestedNameSpecifier::Create(*Context, Prev, NS);
+
+ // Location information
+ SourceRange Range = ReadSourceRange(F, Record, Idx);
+ unsigned RawStart = Range.getBegin().getRawEncoding();
+ unsigned RawEnd = Range.getEnd().getRawEncoding();
+ LocationData.append(reinterpret_cast<char*>(&RawStart),
+ reinterpret_cast<char*>(&RawStart) +sizeof(unsigned));
+ LocationData.append(reinterpret_cast<char*>(&RawEnd),
+ reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned));
+ break;
+ }
+
+ case NestedNameSpecifier::NamespaceAlias: {
+ // Nested-name-specifier
+ NamespaceAliasDecl *Alias
+ = cast<NamespaceAliasDecl>(GetDecl(Record[Idx++]));
+ NNS = NestedNameSpecifier::Create(*Context, Prev, Alias);
+
+ // Location information
+ SourceRange Range = ReadSourceRange(F, Record, Idx);
+ unsigned RawStart = Range.getBegin().getRawEncoding();
+ unsigned RawEnd = Range.getEnd().getRawEncoding();
+ LocationData.append(reinterpret_cast<char*>(&RawStart),
+ reinterpret_cast<char*>(&RawStart) +sizeof(unsigned));
+ LocationData.append(reinterpret_cast<char*>(&RawEnd),
+ reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned));
+
+ break;
+ }
+
+ case NestedNameSpecifier::TypeSpec:
+ case NestedNameSpecifier::TypeSpecWithTemplate: {
+ // Nested-name-specifier
+ bool Template = Record[Idx++];
+ TypeSourceInfo *T = GetTypeSourceInfo(F, Record, Idx);
+ if (!T)
+ return NestedNameSpecifierLoc();
+ NNS = NestedNameSpecifier::Create(*Context, Prev, Template,
+ T->getType().getTypePtr());
+
+ // Location information.
+ SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
+ unsigned RawLocation = ColonColonLoc.getRawEncoding();
+ void *OpaqueTypeData = T->getTypeLoc().getOpaqueData();
+ LocationData.append(reinterpret_cast<char*>(&OpaqueTypeData),
+ (reinterpret_cast<char*>(&OpaqueTypeData)
+ + sizeof(void *)));
+ LocationData.append(reinterpret_cast<char*>(&RawLocation),
+ (reinterpret_cast<char*>(&RawLocation) +
+ sizeof(unsigned)));
+ break;
+ }
+
+ case NestedNameSpecifier::Global: {
+ // Nested-name-specifier
+ NNS = NestedNameSpecifier::GlobalSpecifier(*Context);
+
+ SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
+ unsigned RawLocation = ColonColonLoc.getRawEncoding();
+ LocationData.append(reinterpret_cast<char*>(&RawLocation),
+ (reinterpret_cast<char*>(&RawLocation) +
+ sizeof(unsigned)));
+ break;
+ }
+ }
+ Prev = NNS;
+ }
+
+ void *Mem = Context->Allocate(LocationData.size(), llvm::alignOf<void*>());
+ memcpy(Mem, LocationData.data(), LocationData.size());
+ return NestedNameSpecifierLoc(NNS, Mem);
+}
+
SourceRange
ASTReader::ReadSourceRange(PerFileData &F, const RecordData &Record,
unsigned &Idx) {
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index dec15dd..caa5132 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -753,8 +753,7 @@
void ASTDeclReader::VisitUsingDecl(UsingDecl *D) {
VisitNamedDecl(D);
D->setUsingLocation(ReadSourceLocation(Record, Idx));
- D->setNestedNameRange(ReadSourceRange(Record, Idx));
- D->setTargetNestedNameDecl(Reader.ReadNestedNameSpecifier(Record, Idx));
+ D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
D->FirstUsingShadow = cast_or_null<UsingShadowDecl>(Reader.GetDecl(Record[Idx++]));
D->setTypeName(Record[Idx++]);
@@ -785,19 +784,17 @@
void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
VisitValueDecl(D);
- D->setTargetNestedNameRange(ReadSourceRange(Record, Idx));
D->setUsingLoc(ReadSourceLocation(Record, Idx));
- D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+ D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
}
void ASTDeclReader::VisitUnresolvedUsingTypenameDecl(
UnresolvedUsingTypenameDecl *D) {
VisitTypeDecl(D);
- D->TargetNestedNameRange = ReadSourceRange(Record, Idx);
D->UsingLocation = ReadSourceLocation(Record, Idx);
D->TypenameLocation = ReadSourceLocation(Record, Idx);
- D->TargetNestedNameSpecifier = Reader.ReadNestedNameSpecifier(Record, Idx);
+ D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
}
void ASTDeclReader::ReadCXXDefinitionData(
@@ -1436,8 +1433,9 @@
SourceLocation(), 0);
break;
case DECL_USING:
- D = UsingDecl::Create(*Context, 0, SourceRange(), SourceLocation(),
- 0, DeclarationNameInfo(), false);
+ D = UsingDecl::Create(*Context, 0, SourceLocation(),
+ NestedNameSpecifierLoc(), DeclarationNameInfo(),
+ false);
break;
case DECL_USING_SHADOW:
D = UsingShadowDecl::Create(*Context, 0, SourceLocation(), 0, 0);
@@ -1449,13 +1447,14 @@
break;
case DECL_UNRESOLVED_USING_VALUE:
D = UnresolvedUsingValueDecl::Create(*Context, 0, SourceLocation(),
- SourceRange(), 0,
+ NestedNameSpecifierLoc(),
DeclarationNameInfo());
break;
case DECL_UNRESOLVED_USING_TYPENAME:
D = UnresolvedUsingTypenameDecl::Create(*Context, 0, SourceLocation(),
- SourceLocation(), SourceRange(),
- 0, SourceLocation(),
+ SourceLocation(),
+ NestedNameSpecifierLoc(),
+ SourceLocation(),
DeclarationName());
break;
case DECL_CXX_RECORD:
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 42ca293..ba2494b 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -3276,15 +3276,21 @@
Record);
}
-void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record) {
+void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo,
+ RecordDataImpl &Record) {
if (TInfo == 0) {
AddTypeRef(QualType(), Record);
return;
}
- AddTypeRef(TInfo->getType(), Record);
+ AddTypeLoc(TInfo->getTypeLoc(), Record);
+}
+
+void ASTWriter::AddTypeLoc(TypeLoc TL, RecordDataImpl &Record) {
+ AddTypeRef(TL.getType(), Record);
+
TypeLocWriter TLW(*this, Record);
- for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
+ for (; !TL.isNull(); TL = TL.getNextTypeLoc())
TLW.Visit(TL);
}
@@ -3487,6 +3493,55 @@
}
}
+void ASTWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
+ RecordDataImpl &Record) {
+ // Nested name specifiers usually aren't too long. I think that 8 would
+ // typically accomodate the vast majority.
+ llvm::SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
+
+ // Push each of the nested-name-specifiers's onto a stack for
+ // serialization in reverse order.
+ while (NNS) {
+ NestedNames.push_back(NNS);
+ NNS = NNS.getPrefix();
+ }
+
+ Record.push_back(NestedNames.size());
+ while(!NestedNames.empty()) {
+ NNS = NestedNames.pop_back_val();
+ NestedNameSpecifier::SpecifierKind Kind
+ = NNS.getNestedNameSpecifier()->getKind();
+ Record.push_back(Kind);
+ switch (Kind) {
+ case NestedNameSpecifier::Identifier:
+ AddIdentifierRef(NNS.getNestedNameSpecifier()->getAsIdentifier(), Record);
+ AddSourceRange(NNS.getLocalSourceRange(), Record);
+ break;
+
+ case NestedNameSpecifier::Namespace:
+ AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespace(), Record);
+ AddSourceRange(NNS.getLocalSourceRange(), Record);
+ break;
+
+ case NestedNameSpecifier::NamespaceAlias:
+ AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(), Record);
+ AddSourceRange(NNS.getLocalSourceRange(), Record);
+ break;
+
+ case NestedNameSpecifier::TypeSpec:
+ case NestedNameSpecifier::TypeSpecWithTemplate:
+ Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate);
+ AddTypeLoc(NNS.getTypeLoc(), Record);
+ AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record);
+ break;
+
+ case NestedNameSpecifier::Global:
+ AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record);
+ break;
+ }
+ }
+}
+
void ASTWriter::AddTemplateName(TemplateName Name, RecordDataImpl &Record) {
TemplateName::NameKind Kind = Name.getKind();
Record.push_back(Kind);
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index ce07e13..5d0514f 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -706,9 +706,8 @@
void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) {
VisitNamedDecl(D);
- Writer.AddSourceRange(D->getNestedNameRange(), Record);
Writer.AddSourceLocation(D->getUsingLocation(), Record);
- Writer.AddNestedNameSpecifier(D->getTargetNestedNameDecl(), Record);
+ Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
Writer.AddDeclRef(D->FirstUsingShadow, Record);
Record.push_back(D->isTypeName());
@@ -737,9 +736,8 @@
void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
VisitValueDecl(D);
- Writer.AddSourceRange(D->getTargetNestedNameRange(), Record);
Writer.AddSourceLocation(D->getUsingLoc(), Record);
- Writer.AddNestedNameSpecifier(D->getTargetNestedNameSpecifier(), Record);
+ Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
Code = serialization::DECL_UNRESOLVED_USING_VALUE;
}
@@ -747,10 +745,9 @@
void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl(
UnresolvedUsingTypenameDecl *D) {
VisitTypeDecl(D);
- Writer.AddSourceRange(D->getTargetNestedNameRange(), Record);
Writer.AddSourceLocation(D->getUsingLoc(), Record);
Writer.AddSourceLocation(D->getTypenameLoc(), Record);
- Writer.AddNestedNameSpecifier(D->getTargetNestedNameSpecifier(), Record);
+ Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
Code = serialization::DECL_UNRESOLVED_USING_TYPENAME;
}