From: Douglas Gregor Date: Tue, 31 Aug 2010 23:48:11 +0000 (+0000) Subject: Add libclang support for namespace aliases (visitation + USRs) along X-Git-Tag: llvmorg-2.8.0-rc0~338 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a89314e396bda8b7c0f9b3e7a9d9a014b7beef0c;p=platform%2Fupstream%2Fllvm.git Add libclang support for namespace aliases (visitation + USRs) along with a new cursor kind for a reference to a namespace. There's still some oddities in the source location information for NamespaceAliasDecl that I'll address with a separate commit, so the source locations displayed in the load-namespaces.cpp test will change. llvm-svn: 112676 --- diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 404d7aa51406..bbe9a4de4486 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -994,9 +994,10 @@ enum CXCursorKind { CXCursor_ClassTemplate = 31, /** \brief A C++ class template partial specialization. */ CXCursor_ClassTemplatePartialSpecialization = 32, - + /** \brief A C++ namespace alias declaration. */ + CXCursor_NamespaceAlias = 33, CXCursor_FirstDecl = CXCursor_UnexposedDecl, - CXCursor_LastDecl = CXCursor_ClassTemplatePartialSpecialization, + CXCursor_LastDecl = CXCursor_NamespaceAlias, /* References */ CXCursor_FirstRef = 40, /* Decl references */ @@ -1025,7 +1026,11 @@ enum CXCursorKind { * template parameter. */ CXCursor_TemplateRef = 45, - CXCursor_LastRef = CXCursor_TemplateRef, + /** + * \brief A reference to a namespace or namespace alias. + */ + CXCursor_NamespaceRef = 46, + CXCursor_LastRef = CXCursor_NamespaceRef, /* Error conditions */ CXCursor_FirstInvalid = 70, diff --git a/clang/test/Index/load-namespaces.cpp b/clang/test/Index/load-namespaces.cpp index 2bd7cd4ca28f..cf94546a2474 100644 --- a/clang/test/Index/load-namespaces.cpp +++ b/clang/test/Index/load-namespaces.cpp @@ -10,7 +10,10 @@ namespace std { void g(); } -// FIXME: using directives, namespace aliases +namespace std98 = std; +namespace std0x = std98; + +// FIXME: using directives // 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] @@ -18,5 +21,8 @@ namespace std { // CHECK: load-namespaces.cpp:5:10: FunctionDecl=f:5:10 Extent=[5:10 - 5:13] // CHECK: load-namespaces.cpp:9:11: Namespace=std:9:11 (Definition) Extent=[9:11 - 11:2] // CHECK: load-namespaces.cpp:10:8: FunctionDecl=g:10:8 Extent=[10:8 - 10:11] - +// CHECK: load-namespaces.cpp:13:1: NamespaceAlias=std98:13:1 Extent=[13:1 - 13:10] +// CHECK: load-namespaces.cpp:13:19: NamespaceRef=std:3:11 Extent=[13:19 - 13:22] +// CHECK: load-namespaces.cpp:14:1: NamespaceAlias=std0x:14:1 Extent=[14:1 - 14:10] +// CHECK: load-namespaces.cpp:14:19: NamespaceRef=std98:13:1 Extent=[14:19 - 14:24] diff --git a/clang/test/Index/usrs.cpp b/clang/test/Index/usrs.cpp index 833e312b7830..3f50ea28fe23 100644 --- a/clang/test/Index/usrs.cpp +++ b/clang/test/Index/usrs.cpp @@ -55,6 +55,8 @@ extern "C" { void rez(int a, int b); } +namespace foo_alias = 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] @@ -107,4 +109,4 @@ extern "C" { // CHECK: usrs.cpp c:@F@rez Extent=[55:8 - 55:25] // CHECK: usrs.cpp c:usrs.cpp@941@F@rez@a Extent=[55:12 - 55:17] // CHECK: usrs.cpp c:usrs.cpp@948@F@rez@b Extent=[55:19 - 55:24] - +// CHECK: usrs.cpp c:@NA@foo_alias diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 2a7e6e9b0659..230631bad9a7 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -316,6 +316,7 @@ public: bool VisitObjCClassDecl(ObjCClassDecl *D); bool VisitLinkageSpecDecl(LinkageSpecDecl *D); bool VisitNamespaceDecl(NamespaceDecl *D); + bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D); // Name visitor bool VisitDeclarationNameInfo(DeclarationNameInfo Name); @@ -863,6 +864,13 @@ bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) { return VisitDeclContext(D); } +bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { + // FIXME: Visit nested-name-specifier + + return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(), + D->getTargetNameLoc(), TU)); +} + bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) { switch (Name.getName().getNameKind()) { case clang::DeclarationName::Identifier: @@ -2053,10 +2061,17 @@ CXString clang_getCursorSpelling(CXCursor C) { } case CXCursor_TemplateRef: { TemplateDecl *Template = getCursorTemplateRef(C).first; - assert(Template && "Missing type decl"); + assert(Template && "Missing template decl"); return createCXString(Template->getNameAsString()); } + + case CXCursor_NamespaceRef: { + NamedDecl *NS = getCursorNamespaceRef(C).first; + assert(NS && "Missing namespace decl"); + + return createCXString(NS->getNameAsString()); + } default: return createCXString(""); @@ -2138,6 +2153,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return createCXString("TypeRef"); case CXCursor_TemplateRef: return createCXString("TemplateRef"); + case CXCursor_NamespaceRef: + return createCXString("NamespaceRef"); case CXCursor_UnexposedExpr: return createCXString("UnexposedExpr"); case CXCursor_BlockExpr: @@ -2200,6 +2217,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return createCXString("ClassTemplate"); case CXCursor_ClassTemplatePartialSpecialization: return createCXString("ClassTemplatePartialSpecialization"); + case CXCursor_NamespaceAlias: + return createCXString("NamespaceAlias"); } llvm_unreachable("Unhandled CXCursorKind"); @@ -2329,6 +2348,11 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); } + case CXCursor_NamespaceRef: { + std::pair P = getCursorNamespaceRef(C); + return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); + } + case CXCursor_CXXBaseSpecifier: { // FIXME: Figure out what location to return for a CXXBaseSpecifier. return clang_getNullLocation(); @@ -2390,6 +2414,9 @@ static SourceRange getRawCursorExtent(CXCursor C) { case CXCursor_TemplateRef: return getCursorTemplateRef(C).second; + case CXCursor_NamespaceRef: + return getCursorNamespaceRef(C).second; + case CXCursor_CXXBaseSpecifier: // FIXME: Figure out what source range to use for a CXBaseSpecifier. return SourceRange(); @@ -2470,6 +2497,9 @@ CXCursor clang_getCursorReferenced(CXCursor C) { case CXCursor_TemplateRef: return MakeCXCursor(getCursorTemplateRef(C).first, CXXUnit); + case CXCursor_NamespaceRef: + return MakeCXCursor(getCursorNamespaceRef(C).first, CXXUnit); + case CXCursor_CXXBaseSpecifier: { CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C); return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), diff --git a/clang/tools/libclang/CIndexUSRs.cpp b/clang/tools/libclang/CIndexUSRs.cpp index 6705076c9f01..9ef851aeaa2d 100644 --- a/clang/tools/libclang/CIndexUSRs.cpp +++ b/clang/tools/libclang/CIndexUSRs.cpp @@ -65,6 +65,7 @@ public: void VisitFunctionDecl(FunctionDecl *D); void VisitNamedDecl(NamedDecl *D); void VisitNamespaceDecl(NamespaceDecl *D); + void VisitNamespaceAliasDecl(NamespaceAliasDecl *D); void VisitFunctionTemplateDecl(FunctionTemplateDecl *D); void VisitClassTemplateDecl(ClassTemplateDecl *D); void VisitObjCClassDecl(ObjCClassDecl *CD); @@ -257,6 +258,11 @@ void USRGenerator::VisitClassTemplateDecl(ClassTemplateDecl *D) { VisitTagDecl(D->getTemplatedDecl()); } +void USRGenerator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { + VisitDeclContext(D->getDeclContext()); + if (!IgnoreResults) + Out << "@NA@" << D->getName(); +} void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) { Decl *container = cast(D->getDeclContext()); diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index 0fa201a146c7..3edbc4d1ef99 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -16,6 +16,7 @@ #include "CXCursor.h" #include "clang/Frontend/ASTUnit.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "llvm/Support/ErrorHandling.h" @@ -60,6 +61,7 @@ static CXCursorKind GetCursorKind(Decl *D) { case Decl::Typedef: return CXCursor_TypedefDecl; case Decl::Var: return CXCursor_VarDecl; case Decl::Namespace: return CXCursor_Namespace; + case Decl::NamespaceAlias: return CXCursor_NamespaceAlias; case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter; case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter; case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter; @@ -71,10 +73,10 @@ static CXCursorKind GetCursorKind(Decl *D) { default: if (TagDecl *TD = dyn_cast(D)) { switch (TD->getTagKind()) { - case TTK_Struct: return CXCursor_StructDecl; - case TTK_Class: return CXCursor_ClassDecl; - case TTK_Union: return CXCursor_UnionDecl; - case TTK_Enum: return CXCursor_EnumDecl; + case TTK_Struct: return CXCursor_StructDecl; + case TTK_Class: return CXCursor_ClassDecl; + case TTK_Union: return CXCursor_UnionDecl; + case TTK_Enum: return CXCursor_EnumDecl; } } @@ -329,6 +331,24 @@ cxcursor::getCursorTemplateRef(CXCursor C) { reinterpret_cast(C.data[1]))); } +CXCursor cxcursor::MakeCursorNamespaceRef(NamedDecl *NS, SourceLocation Loc, + ASTUnit *TU) { + + assert(NS && (isa(NS) || isa(NS)) && TU && + "Invalid arguments!"); + void *RawLoc = reinterpret_cast(Loc.getRawEncoding()); + CXCursor C = { CXCursor_NamespaceRef, { NS, RawLoc, TU } }; + return C; +} + +std::pair +cxcursor::getCursorNamespaceRef(CXCursor C) { + assert(C.kind == CXCursor_NamespaceRef); + return std::make_pair(static_cast(C.data[0]), + SourceLocation::getFromRawEncoding( + reinterpret_cast(C.data[1]))); +} + CXCursor cxcursor::MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU){ CXCursor C = { CXCursor_CXXBaseSpecifier, { B, 0, TU } }; return C; diff --git a/clang/tools/libclang/CXCursor.h b/clang/tools/libclang/CXCursor.h index 2e5ff5811c08..a5f111edc1d8 100644 --- a/clang/tools/libclang/CXCursor.h +++ b/clang/tools/libclang/CXCursor.h @@ -84,7 +84,15 @@ CXCursor MakeCursorTemplateRef(TemplateDecl *Template, SourceLocation Loc, /// \brief Unpack a TemplateRef cursor into the template it references and /// the location where the reference occurred. std::pair getCursorTemplateRef(CXCursor C); - + +/// \brief Create a reference to a namespace or namespace alias at the given +/// location. +CXCursor MakeCursorNamespaceRef(NamedDecl *NS, SourceLocation Loc, ASTUnit *TU); + +/// \brief Unpack a NamespaceRef cursor into the namespace or namespace alias +/// it references and the location where the reference occurred. +std::pair getCursorNamespaceRef(CXCursor C); + /// \brief Create a CXX base specifier cursor. CXCursor MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU);