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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112676 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 2a7e6e9..230631b 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -316,6 +316,7 @@
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 @@
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 @@
}
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("<not implemented>");
@@ -2138,6 +2153,8 @@
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 @@
return createCXString("ClassTemplate");
case CXCursor_ClassTemplatePartialSpecialization:
return createCXString("ClassTemplatePartialSpecialization");
+ case CXCursor_NamespaceAlias:
+ return createCXString("NamespaceAlias");
}
llvm_unreachable("Unhandled CXCursorKind");
@@ -2329,6 +2348,11 @@
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
+ case CXCursor_NamespaceRef: {
+ std::pair<NamedDecl *, SourceLocation> 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 @@
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 @@
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/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
index 6705076..9ef851a 100644
--- a/tools/libclang/CIndexUSRs.cpp
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -65,6 +65,7 @@
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 @@
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<Decl>(D->getDeclContext());
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index 0fa201a..3edbc4d 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/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 @@
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 @@
default:
if (TagDecl *TD = dyn_cast<TagDecl>(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 @@
reinterpret_cast<uintptr_t>(C.data[1])));
}
+CXCursor cxcursor::MakeCursorNamespaceRef(NamedDecl *NS, SourceLocation Loc,
+ ASTUnit *TU) {
+
+ assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU &&
+ "Invalid arguments!");
+ void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+ CXCursor C = { CXCursor_NamespaceRef, { NS, RawLoc, TU } };
+ return C;
+}
+
+std::pair<NamedDecl *, SourceLocation>
+cxcursor::getCursorNamespaceRef(CXCursor C) {
+ assert(C.kind == CXCursor_NamespaceRef);
+ return std::make_pair(static_cast<NamedDecl *>(C.data[0]),
+ SourceLocation::getFromRawEncoding(
+ reinterpret_cast<uintptr_t>(C.data[1])));
+}
+
CXCursor cxcursor::MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU){
CXCursor C = { CXCursor_CXXBaseSpecifier, { B, 0, TU } };
return C;
diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h
index 2e5ff58..a5f111e 100644
--- a/tools/libclang/CXCursor.h
+++ b/tools/libclang/CXCursor.h
@@ -84,7 +84,15 @@
/// \brief Unpack a TemplateRef cursor into the template it references and
/// the location where the reference occurred.
std::pair<TemplateDecl *, SourceLocation> 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<NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C);
+
/// \brief Create a CXX base specifier cursor.
CXCursor MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU);