Push nested-name-specifier source location information into using directives.

llvm-svn: 126489
This commit is contained in:
Douglas Gregor 2011-02-25 16:33:46 +00:00
parent fcf51fd298
commit 12441b3bc5
11 changed files with 57 additions and 42 deletions

View File

@ -1741,13 +1741,8 @@ class UsingDirectiveDecl : public NamedDecl {
/// SourceLocation - Location of 'namespace' token. /// SourceLocation - Location of 'namespace' token.
SourceLocation NamespaceLoc; SourceLocation NamespaceLoc;
/// \brief The source range that covers the nested-name-specifier /// \brief The nested-name-specifier that precedes the namespace.
/// preceding the namespace name. NestedNameSpecifierLoc QualifierLoc;
SourceRange QualifierRange;
/// \brief The nested-name-specifier that precedes the namespace
/// name, if any.
NestedNameSpecifier *Qualifier;
/// NominatedNamespace - Namespace nominated by using-directive. /// NominatedNamespace - Namespace nominated by using-directive.
NamedDecl *NominatedNamespace; NamedDecl *NominatedNamespace;
@ -1765,25 +1760,24 @@ class UsingDirectiveDecl : public NamedDecl {
UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc, UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc,
SourceLocation NamespcLoc, SourceLocation NamespcLoc,
SourceRange QualifierRange, NestedNameSpecifierLoc QualifierLoc,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc, SourceLocation IdentLoc,
NamedDecl *Nominated, NamedDecl *Nominated,
DeclContext *CommonAncestor) DeclContext *CommonAncestor)
: NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc), : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc),
NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange), NamespaceLoc(NamespcLoc), QualifierLoc(QualifierLoc),
Qualifier(Qualifier), NominatedNamespace(Nominated), NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) { }
CommonAncestor(CommonAncestor) {
}
public: public:
/// \brief Retrieve the source range of the nested-name-specifier /// \brief Retrieve the nested-name-specifier that qualifies the
/// that qualifies the namespace name. /// name of the namespace, with source-location information.
SourceRange getQualifierRange() const { return QualifierRange; } NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
/// \brief Retrieve the nested-name-specifier that qualifies the /// \brief Retrieve the nested-name-specifier that qualifies the
/// name of the namespace. /// name of the namespace.
NestedNameSpecifier *getQualifier() const { return Qualifier; } NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; } NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
const NamedDecl *getNominatedNamespaceAsWritten() const { const NamedDecl *getNominatedNamespaceAsWritten() const {
@ -1815,8 +1809,7 @@ public:
static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC, static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation UsingLoc, SourceLocation UsingLoc,
SourceLocation NamespaceLoc, SourceLocation NamespaceLoc,
SourceRange QualifierRange, NestedNameSpecifierLoc QualifierLoc,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc, SourceLocation IdentLoc,
NamedDecl *Nominated, NamedDecl *Nominated,
DeclContext *CommonAncestor); DeclContext *CommonAncestor);

View File

@ -1178,7 +1178,7 @@ DEF_TRAVERSE_DECL(UsingDecl, {
}) })
DEF_TRAVERSE_DECL(UsingDirectiveDecl, { DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
TRY_TO(TraverseNestedNameSpecifier(D->getQualifier())); TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
}) })
DEF_TRAVERSE_DECL(UsingShadowDecl, { }) DEF_TRAVERSE_DECL(UsingShadowDecl, { })

View File

@ -841,8 +841,10 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
// UsingDirectiveDecl's are not really NamedDecl's, and all have same name. // UsingDirectiveDecl's are not really NamedDecl's, and all have same name.
// We want to keep it, unless it nominates same namespace. // We want to keep it, unless it nominates same namespace.
if (getKind() == Decl::UsingDirective) { if (getKind() == Decl::UsingDirective) {
return cast<UsingDirectiveDecl>(this)->getNominatedNamespace() == return cast<UsingDirectiveDecl>(this)->getNominatedNamespace()
cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace(); ->getOriginalNamespace() ==
cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace()
->getOriginalNamespace();
} }
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this))

View File

@ -1267,15 +1267,14 @@ LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, SourceLocation L,
SourceLocation NamespaceLoc, SourceLocation NamespaceLoc,
SourceRange QualifierRange, NestedNameSpecifierLoc QualifierLoc,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc, SourceLocation IdentLoc,
NamedDecl *Used, NamedDecl *Used,
DeclContext *CommonAncestor) { DeclContext *CommonAncestor) {
if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used)) if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used))
Used = NS->getOriginalNamespace(); Used = NS->getOriginalNamespace();
return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange, return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierLoc,
Qualifier, IdentLoc, Used, CommonAncestor); IdentLoc, Used, CommonAncestor);
} }
NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() { NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {

View File

@ -321,8 +321,11 @@ namespace {
} }
SourceRange NestedNameSpecifierLoc::getSourceRange() const { SourceRange NestedNameSpecifierLoc::getSourceRange() const {
if (!Qualifier)
return SourceRange();
NestedNameSpecifierLoc First = *this; NestedNameSpecifierLoc First = *this;
while (NestedNameSpecifierLoc Prefix= First.getPrefix()) while (NestedNameSpecifierLoc Prefix = First.getPrefix())
First = Prefix; First = Prefix;
return SourceRange(First.getLocalSourceRange().getBegin(), return SourceRange(First.getLocalSourceRange().getBegin(),
@ -330,6 +333,9 @@ SourceRange NestedNameSpecifierLoc::getSourceRange() const {
} }
SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const { SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
if (!Qualifier)
return SourceRange();
unsigned Offset = getDataLength(Qualifier->getPrefix()); unsigned Offset = getDataLength(Qualifier->getPrefix());
switch (Qualifier->getKind()) { switch (Qualifier->getKind()) {
case NestedNameSpecifier::Global: case NestedNameSpecifier::Global:

View File

@ -3623,8 +3623,7 @@ Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
= UsingDirectiveDecl::Create(Context, CurContext, = UsingDirectiveDecl::Create(Context, CurContext,
/* 'using' */ LBrace, /* 'using' */ LBrace,
/* 'namespace' */ SourceLocation(), /* 'namespace' */ SourceLocation(),
/* qualifier */ SourceRange(), /* qualifier */ NestedNameSpecifierLoc(),
/* NNS */ NULL,
/* identifier */ SourceLocation(), /* identifier */ SourceLocation(),
Namespc, Namespc,
/* Ancestor */ CurContext); /* Ancestor */ CurContext);
@ -3768,8 +3767,7 @@ Decl *Sema::ActOnUsingDirective(Scope *S,
CommonAncestor = CommonAncestor->getParent(); CommonAncestor = CommonAncestor->getParent();
UDir = UsingDirectiveDecl::Create(Context, CurContext, UsingLoc, NamespcLoc, UDir = UsingDirectiveDecl::Create(Context, CurContext, UsingLoc, NamespcLoc,
SS.getRange(), SS.getWithLocInContext(Context),
(NestedNameSpecifier *)SS.getScopeRep(),
IdentLoc, Named, CommonAncestor); IdentLoc, Named, CommonAncestor);
PushUsingDirective(S, UDir); PushUsingDirective(S, UDir);
} else { } else {

View File

@ -1638,12 +1638,13 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
} }
Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
// Using directives are never dependent, so they require no explicit // Using directives are never dependent (and never contain any types or
// expressions), so they require no explicit instantiation work.
UsingDirectiveDecl *Inst UsingDirectiveDecl *Inst
= UsingDirectiveDecl::Create(SemaRef.Context, Owner, D->getLocation(), = UsingDirectiveDecl::Create(SemaRef.Context, Owner, D->getLocation(),
D->getNamespaceKeyLocation(), D->getNamespaceKeyLocation(),
D->getQualifierRange(), D->getQualifier(), D->getQualifierLoc(),
D->getIdentLocation(), D->getIdentLocation(),
D->getNominatedNamespace(), D->getNominatedNamespace(),
D->getCommonAncestor()); D->getCommonAncestor());

View File

@ -776,8 +776,7 @@ void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
VisitNamedDecl(D); VisitNamedDecl(D);
D->UsingLoc = ReadSourceLocation(Record, Idx); D->UsingLoc = ReadSourceLocation(Record, Idx);
D->NamespaceLoc = ReadSourceLocation(Record, Idx); D->NamespaceLoc = ReadSourceLocation(Record, Idx);
D->QualifierRange = ReadSourceRange(Record, Idx); D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
D->Qualifier = Reader.ReadNestedNameSpecifier(Record, Idx);
D->NominatedNamespace = cast<NamedDecl>(Reader.GetDecl(Record[Idx++])); D->NominatedNamespace = cast<NamedDecl>(Reader.GetDecl(Record[Idx++]));
D->CommonAncestor = cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])); D->CommonAncestor = cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++]));
} }
@ -1442,7 +1441,7 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
break; break;
case DECL_USING_DIRECTIVE: case DECL_USING_DIRECTIVE:
D = UsingDirectiveDecl::Create(*Context, 0, SourceLocation(), D = UsingDirectiveDecl::Create(*Context, 0, SourceLocation(),
SourceLocation(), SourceRange(), 0, SourceLocation(), NestedNameSpecifierLoc(),
SourceLocation(), 0, 0); SourceLocation(), 0, 0);
break; break;
case DECL_UNRESOLVED_USING_VALUE: case DECL_UNRESOLVED_USING_VALUE:

View File

@ -727,8 +727,7 @@ void ASTDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
VisitNamedDecl(D); VisitNamedDecl(D);
Writer.AddSourceLocation(D->getUsingLoc(), Record); Writer.AddSourceLocation(D->getUsingLoc(), Record);
Writer.AddSourceLocation(D->getNamespaceKeyLocation(), Record); Writer.AddSourceLocation(D->getNamespaceKeyLocation(), Record);
Writer.AddSourceRange(D->getQualifierRange(), Record); Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
Writer.AddNestedNameSpecifier(D->getQualifier(), Record);
Writer.AddDeclRef(D->getNominatedNamespace(), Record); Writer.AddDeclRef(D->getNominatedNamespace(), Record);
Writer.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()), Record); Writer.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()), Record);
Code = serialization::DECL_USING_DIRECTIVE; Code = serialization::DECL_USING_DIRECTIVE;

View File

@ -41,7 +41,16 @@ struct X2 : outer::inner::vector<T> {
using outer::inner::vector<type>::push_back; using outer::inner::vector<type>::push_back;
}; };
// RUN: c-index-test -test-annotate-tokens=%s:13:1:42:1 %s | FileCheck %s namespace outer {
namespace inner {
namespace secret {
}
}
}
using namespace outer_alias::inner::secret;
// RUN: c-index-test -test-annotate-tokens=%s:13:1:52:1 %s | FileCheck %s
// CHECK: Keyword: "using" [14:1 - 14:6] UsingDeclaration=vector[4:12] // CHECK: Keyword: "using" [14:1 - 14:6] UsingDeclaration=vector[4:12]
// CHECK: Identifier: "outer_alias" [14:7 - 14:18] NamespaceRef=outer_alias:10:11 // CHECK: Identifier: "outer_alias" [14:7 - 14:18] NamespaceRef=outer_alias:10:11
@ -89,3 +98,12 @@ struct X2 : outer::inner::vector<T> {
// CHECK: Punctuation: ">" [41:34 - 41:35] UsingDeclaration=push_back:41:37 // CHECK: Punctuation: ">" [41:34 - 41:35] UsingDeclaration=push_back:41:37
// CHECK: Punctuation: "::" [41:35 - 41:37] UsingDeclaration=push_back:41:37 // CHECK: Punctuation: "::" [41:35 - 41:37] UsingDeclaration=push_back:41:37
// CHECK: Identifier: "push_back" [41:37 - 41:46] UsingDeclaration=push_back:41:37 // CHECK: Identifier: "push_back" [41:37 - 41:46] UsingDeclaration=push_back:41:37
// Using directive
// CHECK: Keyword: "using" [51:1 - 51:6] UsingDirective=:51:37
// CHECK: Keyword: "namespace" [51:7 - 51:16] UsingDirective=:51:37
// CHECK: Identifier: "outer_alias" [51:17 - 51:28] NamespaceRef=outer_alias:10:11
// CHECK: Punctuation: "::" [51:28 - 51:30] UsingDirective=:51:37
// CHECK: Identifier: "inner" [51:30 - 51:35] NamespaceRef=inner:45:13
// CHECK: Punctuation: "::" [51:35 - 51:37] UsingDirective=:51:37
// CHECK: Identifier: "secret" [51:37 - 51:43] NamespaceRef=secret:46:15

View File

@ -1103,8 +1103,8 @@ bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
// Visit nested-name-specifier. // Visit nested-name-specifier.
if (NestedNameSpecifier *Qualifier = D->getQualifier()) if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
if (VisitNestedNameSpecifier(Qualifier, D->getQualifierRange())) if (VisitNestedNameSpecifierLoc(QualifierLoc))
return true; return true;
return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(), return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),