From: Douglas Gregor Date: Fri, 25 Feb 2011 16:33:46 +0000 (+0000) Subject: Push nested-name-specifier source location information into using directives. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=db9924191092b4d426cc066637d81698211846aa;p=clang Push nested-name-specifier source location information into using directives. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126489 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 7e8bc44396..c231e4703b 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -1741,13 +1741,8 @@ class UsingDirectiveDecl : public NamedDecl { /// SourceLocation - Location of 'namespace' token. SourceLocation NamespaceLoc; - /// \brief The source range that covers the nested-name-specifier - /// preceding the namespace name. - SourceRange QualifierRange; - - /// \brief The nested-name-specifier that precedes the namespace - /// name, if any. - NestedNameSpecifier *Qualifier; + /// \brief The nested-name-specifier that precedes the namespace. + NestedNameSpecifierLoc QualifierLoc; /// NominatedNamespace - Namespace nominated by using-directive. NamedDecl *NominatedNamespace; @@ -1765,25 +1760,24 @@ class UsingDirectiveDecl : public NamedDecl { UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc, SourceLocation NamespcLoc, - SourceRange QualifierRange, - NestedNameSpecifier *Qualifier, + NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor) : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc), - NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange), - Qualifier(Qualifier), NominatedNamespace(Nominated), - CommonAncestor(CommonAncestor) { - } + NamespaceLoc(NamespcLoc), QualifierLoc(QualifierLoc), + NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) { } public: - /// \brief Retrieve the source range of the nested-name-specifier - /// that qualifies the namespace name. - SourceRange getQualifierRange() const { return QualifierRange; } - + /// \brief Retrieve the nested-name-specifier that qualifies the + /// name of the namespace, with source-location information. + NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } + /// \brief Retrieve the nested-name-specifier that qualifies the /// name of the namespace. - NestedNameSpecifier *getQualifier() const { return Qualifier; } + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); + } NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; } const NamedDecl *getNominatedNamespaceAsWritten() const { @@ -1815,8 +1809,7 @@ public: static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, SourceLocation NamespaceLoc, - SourceRange QualifierRange, - NestedNameSpecifier *Qualifier, + NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor); diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 6359241660..ff59450b6a 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1178,7 +1178,7 @@ DEF_TRAVERSE_DECL(UsingDecl, { }) DEF_TRAVERSE_DECL(UsingDirectiveDecl, { - TRY_TO(TraverseNestedNameSpecifier(D->getQualifier())); + TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); }) DEF_TRAVERSE_DECL(UsingShadowDecl, { }) diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index d7e389e616..73fe117b1e 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -841,8 +841,10 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const { // UsingDirectiveDecl's are not really NamedDecl's, and all have same name. // We want to keep it, unless it nominates same namespace. if (getKind() == Decl::UsingDirective) { - return cast(this)->getNominatedNamespace() == - cast(OldD)->getNominatedNamespace(); + return cast(this)->getNominatedNamespace() + ->getOriginalNamespace() == + cast(OldD)->getNominatedNamespace() + ->getOriginalNamespace(); } if (const FunctionDecl *FD = dyn_cast(this)) diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index a1d6cc369e..aafe480e80 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -1267,15 +1267,14 @@ LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, SourceLocation NamespaceLoc, - SourceRange QualifierRange, - NestedNameSpecifier *Qualifier, + NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc, NamedDecl *Used, DeclContext *CommonAncestor) { if (NamespaceDecl *NS = dyn_cast_or_null(Used)) Used = NS->getOriginalNamespace(); - return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange, - Qualifier, IdentLoc, Used, CommonAncestor); + return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierLoc, + IdentLoc, Used, CommonAncestor); } NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() { diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp index 0689ae1c88..6f1ec058d7 100644 --- a/lib/AST/NestedNameSpecifier.cpp +++ b/lib/AST/NestedNameSpecifier.cpp @@ -321,8 +321,11 @@ namespace { } SourceRange NestedNameSpecifierLoc::getSourceRange() const { + if (!Qualifier) + return SourceRange(); + NestedNameSpecifierLoc First = *this; - while (NestedNameSpecifierLoc Prefix= First.getPrefix()) + while (NestedNameSpecifierLoc Prefix = First.getPrefix()) First = Prefix; return SourceRange(First.getLocalSourceRange().getBegin(), @@ -330,6 +333,9 @@ SourceRange NestedNameSpecifierLoc::getSourceRange() const { } SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const { + if (!Qualifier) + return SourceRange(); + unsigned Offset = getDataLength(Qualifier->getPrefix()); switch (Qualifier->getKind()) { case NestedNameSpecifier::Global: diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 89b2263329..fb65dd822b 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -3623,8 +3623,7 @@ Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope, = UsingDirectiveDecl::Create(Context, CurContext, /* 'using' */ LBrace, /* 'namespace' */ SourceLocation(), - /* qualifier */ SourceRange(), - /* NNS */ NULL, + /* qualifier */ NestedNameSpecifierLoc(), /* identifier */ SourceLocation(), Namespc, /* Ancestor */ CurContext); @@ -3768,8 +3767,7 @@ Decl *Sema::ActOnUsingDirective(Scope *S, CommonAncestor = CommonAncestor->getParent(); UDir = UsingDirectiveDecl::Create(Context, CurContext, UsingLoc, NamespcLoc, - SS.getRange(), - (NestedNameSpecifier *)SS.getScopeRep(), + SS.getWithLocInContext(Context), IdentLoc, Named, CommonAncestor); PushUsingDirective(S, UDir); } else { diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index c96430a5d5..1d75da71f5 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1638,12 +1638,13 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl( } 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::Create(SemaRef.Context, Owner, D->getLocation(), D->getNamespaceKeyLocation(), - D->getQualifierRange(), D->getQualifier(), + D->getQualifierLoc(), D->getIdentLocation(), D->getNominatedNamespace(), D->getCommonAncestor()); diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index caa5132473..f7c8e17a34 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -776,8 +776,7 @@ void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { VisitNamedDecl(D); D->UsingLoc = ReadSourceLocation(Record, Idx); D->NamespaceLoc = ReadSourceLocation(Record, Idx); - D->QualifierRange = ReadSourceRange(Record, Idx); - D->Qualifier = Reader.ReadNestedNameSpecifier(Record, Idx); + D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); D->NominatedNamespace = cast(Reader.GetDecl(Record[Idx++])); D->CommonAncestor = cast_or_null(Reader.GetDecl(Record[Idx++])); } @@ -1442,7 +1441,7 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { break; case DECL_USING_DIRECTIVE: D = UsingDirectiveDecl::Create(*Context, 0, SourceLocation(), - SourceLocation(), SourceRange(), 0, + SourceLocation(), NestedNameSpecifierLoc(), SourceLocation(), 0, 0); break; case DECL_UNRESOLVED_USING_VALUE: diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 5d0514fca2..43eff0997f 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -727,8 +727,7 @@ void ASTDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { VisitNamedDecl(D); Writer.AddSourceLocation(D->getUsingLoc(), Record); Writer.AddSourceLocation(D->getNamespaceKeyLocation(), Record); - Writer.AddSourceRange(D->getQualifierRange(), Record); - Writer.AddNestedNameSpecifier(D->getQualifier(), Record); + Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record); Writer.AddDeclRef(D->getNominatedNamespace(), Record); Writer.AddDeclRef(dyn_cast(D->getCommonAncestor()), Record); Code = serialization::DECL_USING_DIRECTIVE; diff --git a/test/Index/annotate-nested-name-specifier.cpp b/test/Index/annotate-nested-name-specifier.cpp index 62eb419cd9..cc8e8eedf3 100644 --- a/test/Index/annotate-nested-name-specifier.cpp +++ b/test/Index/annotate-nested-name-specifier.cpp @@ -41,7 +41,16 @@ struct X2 : outer::inner::vector { using outer::inner::vector::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: Identifier: "outer_alias" [14:7 - 14:18] NamespaceRef=outer_alias:10:11 @@ -89,3 +98,12 @@ struct X2 : outer::inner::vector { // CHECK: Punctuation: ">" [41:34 - 41:35] 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 + +// 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 diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 425832596a..ccaeaa69af 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -1103,8 +1103,8 @@ bool CursorVisitor::VisitUsingDecl(UsingDecl *D) { bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { // Visit nested-name-specifier. - if (NestedNameSpecifier *Qualifier = D->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, D->getQualifierRange())) + if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) + if (VisitNestedNameSpecifierLoc(QualifierLoc)) return true; return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),