diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index bbe9a4de4486..7e4902dff275 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/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/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index e259ccb6d218..f5cbfd0d5976 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/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(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/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index eed3702e5343..f4041553507e 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -989,14 +989,8 @@ NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() { return cast_or_null(NominatedNamespace); } -void UsingDirectiveDecl::setNominatedNamespace(NamedDecl* ND) { - assert((isa(ND) || isa(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(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/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 512d4b571743..cb6f29a07702 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/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(Reader.GetDecl(Record[Idx++]))); - D->setCommonAncestor(cast_or_null( - 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(Reader.GetDecl(Record[Idx++])); + D->CommonAncestor = cast_or_null(Reader.GetDecl(Record[Idx++])); } void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 90d135dfb38a..ce39a1076b8e 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/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(D->getCommonAncestor()), Record); Code = serialization::DECL_USING_DIRECTIVE; diff --git a/clang/test/Index/load-namespaces.cpp b/clang/test/Index/load-namespaces.cpp index e614f7ca98db..9c8db0a3a524 100644 --- a/clang/test/Index/load-namespaces.cpp +++ b/clang/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/clang/test/Index/usrs.cpp b/clang/test/Index/usrs.cpp index 3f50ea28fe23..cacfdf2f56bf 100644 --- a/clang/test/Index/usrs.cpp +++ b/clang/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/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 230631bad9a7..d84918632442 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/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(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/clang/tools/libclang/CIndexUSRs.cpp b/clang/tools/libclang/CIndexUSRs.cpp index 9ef851aeaa2d..5628aef056af 100644 --- a/clang/tools/libclang/CIndexUSRs.cpp +++ b/clang/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/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index 3edbc4d1ef99..75806ffa8d75 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/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(D)) {