diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-09-01 03:07:18 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-09-01 03:07:18 +0000 |
commit | 0a35bceb7768fc0be62cb644a4e31d8bfd9fb44a (patch) | |
tree | 4ae71942a6fa3da406572486143a0b314537367c | |
parent | 53b9441b5a81a24fa1f66f3f6416f1e36baa9c2f (diff) |
Implement libclang support for using directives (cursor + visitation +
suppressing USRs). Also, fix up the source location information for
using directives so that the declaration location refers to the
namespace name.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112693 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang-c/Index.h | 5 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 50 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 10 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 13 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 2 | ||||
-rw-r--r-- | test/Index/load-namespaces.cpp | 4 | ||||
-rw-r--r-- | test/Index/usrs.cpp | 2 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 15 | ||||
-rw-r--r-- | tools/libclang/CIndexUSRs.cpp | 6 | ||||
-rw-r--r-- | tools/libclang/CXCursor.cpp | 1 |
10 files changed, 54 insertions, 54 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index bbe9a4de44..7e4902dff2 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -996,8 +996,11 @@ enum CXCursorKind { CXCursor_ClassTemplatePartialSpecialization = 32, /** \brief A C++ namespace alias declaration. */ CXCursor_NamespaceAlias = 33, + /** \brief A C++ using directive. */ + CXCursor_UsingDirective = 34, + CXCursor_FirstDecl = CXCursor_UnexposedDecl, - CXCursor_LastDecl = CXCursor_NamespaceAlias, + CXCursor_LastDecl = CXCursor_UsingDirective, /* References */ CXCursor_FirstRef = 40, /* Decl references */ diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index e259ccb6d2..f5cbfd0d59 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -1707,7 +1707,9 @@ public: // artificial name, for all using-directives in order to store // them in DeclContext effectively. class UsingDirectiveDecl : public NamedDecl { - + /// \brief The location of the "using" keyword. + SourceLocation UsingLoc; + /// SourceLocation - Location of 'namespace' token. SourceLocation NamespaceLoc; @@ -1719,10 +1721,6 @@ class UsingDirectiveDecl : public NamedDecl { /// name, if any. NestedNameSpecifier *Qualifier; - /// IdentLoc - Location of nominated namespace-name identifier. - // FIXME: We don't store location of scope specifier. - SourceLocation IdentLoc; - /// NominatedNamespace - Namespace nominated by using-directive. NamedDecl *NominatedNamespace; @@ -1737,17 +1735,16 @@ class UsingDirectiveDecl : public NamedDecl { return DeclarationName::getUsingDirectiveName(); } - UsingDirectiveDecl(DeclContext *DC, SourceLocation L, + UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc, SourceLocation NamespcLoc, SourceRange QualifierRange, NestedNameSpecifier *Qualifier, SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor) - : NamedDecl(UsingDirective, DC, L, getName()), + : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc), NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange), - Qualifier(Qualifier), IdentLoc(IdentLoc), - NominatedNamespace(Nominated), + Qualifier(Qualifier), NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) { } @@ -1756,18 +1753,10 @@ public: /// that qualifies the namespace name. SourceRange getQualifierRange() const { return QualifierRange; } - /// \brief Set the source range of the nested-name-specifier that - /// qualifies the namespace name. - void setQualifierRange(SourceRange R) { QualifierRange = R; } - /// \brief Retrieve the nested-name-specifier that qualifies the /// name of the namespace. NestedNameSpecifier *getQualifier() const { return Qualifier; } - /// \brief Set the nested-name-specifier that qualifes the name of the - /// namespace. - void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; } - NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; } const NamedDecl *getNominatedNamespaceAsWritten() const { return NominatedNamespace; @@ -1780,34 +1769,23 @@ public: return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace(); } - /// setNominatedNamespace - Set the namespace nominataed by the - /// using-directive. - void setNominatedNamespace(NamedDecl* NS); - /// \brief Returns the common ancestor context of this using-directive and /// its nominated namespace. DeclContext *getCommonAncestor() { return CommonAncestor; } const DeclContext *getCommonAncestor() const { return CommonAncestor; } - /// \brief Set the common ancestor context of this using-directive and its - /// nominated namespace. - void setCommonAncestor(DeclContext* Cxt) { CommonAncestor = Cxt; } - + /// \brief Return the location of the "using" keyword. + SourceLocation getUsingLoc() const { return UsingLoc; } + // FIXME: Could omit 'Key' in name. /// getNamespaceKeyLocation - Returns location of namespace keyword. SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; } - /// setNamespaceKeyLocation - Set the the location of the namespacekeyword. - void setNamespaceKeyLocation(SourceLocation L) { NamespaceLoc = L; } - /// getIdentLocation - Returns location of identifier. - SourceLocation getIdentLocation() const { return IdentLoc; } - - /// setIdentLocation - set the location of the identifier. - void setIdentLocation(SourceLocation L) { IdentLoc = L; } + SourceLocation getIdentLocation() const { return getLocation(); } static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, + SourceLocation UsingLoc, SourceLocation NamespaceLoc, SourceRange QualifierRange, NestedNameSpecifier *Qualifier, @@ -1815,12 +1793,18 @@ public: NamedDecl *Nominated, DeclContext *CommonAncestor); + SourceRange getSourceRange() const { + return SourceRange(UsingLoc, getLocation()); + } + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classof(const UsingDirectiveDecl *D) { return true; } static bool classofKind(Kind K) { return K == UsingDirective; } // Friend for getUsingDirectiveName. friend class DeclContext; + + friend class ASTDeclReader; }; /// NamespaceAliasDecl - Represents a C++ namespace alias. For example: diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index eed3702e53..f404155350 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -989,14 +989,8 @@ NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() { return cast_or_null<NamespaceDecl>(NominatedNamespace); } -void UsingDirectiveDecl::setNominatedNamespace(NamedDecl* ND) { - assert((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) && - "expected a NamespaceDecl or NamespaceAliasDecl"); - NominatedNamespace = ND; -} - NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, + SourceLocation UsingLoc, SourceLocation AliasLoc, IdentifierInfo *Alias, SourceRange QualifierRange, @@ -1005,7 +999,7 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, NamedDecl *Namespace) { if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace)) Namespace = NS->getOriginalNamespace(); - return new (C) NamespaceAliasDecl(DC, L, AliasLoc, Alias, QualifierRange, + return new (C) NamespaceAliasDecl(DC, UsingLoc, AliasLoc, Alias, QualifierRange, Qualifier, IdentLoc, Namespace); } diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 512d4b5717..cb6f29a077 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -676,13 +676,12 @@ void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) { void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { VisitNamedDecl(D); - D->setNamespaceKeyLocation(Reader.ReadSourceLocation(Record, Idx)); - D->setQualifierRange(Reader.ReadSourceRange(Record, Idx)); - D->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx)); - D->setIdentLocation(Reader.ReadSourceLocation(Record, Idx)); - D->setNominatedNamespace(cast<NamedDecl>(Reader.GetDecl(Record[Idx++]))); - D->setCommonAncestor(cast_or_null<DeclContext>( - Reader.GetDecl(Record[Idx++]))); + D->UsingLoc = Reader.ReadSourceLocation(Record, Idx); + D->NamespaceLoc = Reader.ReadSourceLocation(Record, Idx); + D->QualifierRange = Reader.ReadSourceRange(Record, Idx); + D->Qualifier = Reader.ReadNestedNameSpecifier(Record, Idx); + D->NominatedNamespace = cast<NamedDecl>(Reader.GetDecl(Record[Idx++])); + D->CommonAncestor = cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])); } void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 90d135dfb3..ce39a1076b 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -658,10 +658,10 @@ void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) { 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.AddSourceLocation(D->getIdentLocation(), Record); Writer.AddDeclRef(D->getNominatedNamespace(), Record); Writer.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()), Record); Code = serialization::DECL_USING_DIRECTIVE; diff --git a/test/Index/load-namespaces.cpp b/test/Index/load-namespaces.cpp index e614f7ca98..9c8db0a3a5 100644 --- a/test/Index/load-namespaces.cpp +++ b/test/Index/load-namespaces.cpp @@ -13,7 +13,7 @@ namespace std { namespace std98 = std; namespace std0x = std98; -// FIXME: using directives +using namespace std0x; // RUN: c-index-test -test-load-source all %s | FileCheck %s // CHECK: load-namespaces.cpp:3:11: Namespace=std:3:11 (Definition) Extent=[3:11 - 7:2] @@ -25,3 +25,5 @@ namespace std0x = std98; // CHECK: load-namespaces.cpp:13:19: NamespaceRef=std:3:11 Extent=[13:19 - 13:22] // CHECK: load-namespaces.cpp:14:11: NamespaceAlias=std0x:14:11 Extent=[14:1 - 14:24] // CHECK: load-namespaces.cpp:14:19: NamespaceRef=std98:13:11 Extent=[14:19 - 14:24] +// CHECK: load-namespaces.cpp:16:17: UsingDirective=:16:17 Extent=[16:1 - 16:22] +// CHECK: load-namespaces.cpp:16:17: NamespaceRef=std0x:14:11 Extent=[16:17 - 16:22] diff --git a/test/Index/usrs.cpp b/test/Index/usrs.cpp index 3f50ea28fe..cacfdf2f56 100644 --- a/test/Index/usrs.cpp +++ b/test/Index/usrs.cpp @@ -57,6 +57,8 @@ extern "C" { namespace foo_alias = foo; +using namespace foo; + // RUN: c-index-test -test-load-source-usrs all %s | FileCheck %s // CHECK: usrs.cpp c:@N@foo Extent=[1:11 - 4:2] // CHECK: usrs.cpp c:@N@foo@x Extent=[2:3 - 2:8] diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 230631bad9..d849186324 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -317,7 +317,8 @@ public: bool VisitLinkageSpecDecl(LinkageSpecDecl *D); bool VisitNamespaceDecl(NamespaceDecl *D); bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D); - + bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D); + // Name visitor bool VisitDeclarationNameInfo(DeclarationNameInfo Name); @@ -871,6 +872,13 @@ bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { D->getTargetNameLoc(), TU)); } +bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { + // FIXME: Visit nested-name-specifier + + return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(), + D->getIdentLocation(), TU)); +} + bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) { switch (Name.getName().getNameKind()) { case clang::DeclarationName::Identifier: @@ -2022,6 +2030,9 @@ static CXString getDeclSpelling(Decl *D) { // ObjCCategoryImplDecl returns the category name. return createCXString(CIMP->getIdentifier()->getNameStart()); + if (isa<UsingDirectiveDecl>(D)) + return createCXString(""); + llvm::SmallString<1024> S; llvm::raw_svector_ostream os(S); ND->printName(os); @@ -2219,6 +2230,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return createCXString("ClassTemplatePartialSpecialization"); case CXCursor_NamespaceAlias: return createCXString("NamespaceAlias"); + case CXCursor_UsingDirective: + return createCXString("UsingDirective"); } llvm_unreachable("Unhandled CXCursorKind"); diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp index 9ef851aeaa..5628aef056 100644 --- a/tools/libclang/CIndexUSRs.cpp +++ b/tools/libclang/CIndexUSRs.cpp @@ -82,9 +82,11 @@ public: void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); void VisitLinkageSpecDecl(LinkageSpecDecl *D) { IgnoreResults = true; - return; } - + void VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { + IgnoreResults = true; + } + /// Generate the string component containing the location of the /// declaration. bool GenLoc(const Decl *D); diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index 3edbc4d1ef..75806ffa8d 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -69,6 +69,7 @@ static CXCursorKind GetCursorKind(Decl *D) { case Decl::ClassTemplate: return CXCursor_ClassTemplate; case Decl::ClassTemplatePartialSpecialization: return CXCursor_ClassTemplatePartialSpecialization; + case Decl::UsingDirective: return CXCursor_UsingDirective; default: if (TagDecl *TD = dyn_cast<TagDecl>(D)) { |