summaryrefslogtreecommitdiffstats
path: root/tools/libclang/CIndexUSRs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/libclang/CIndexUSRs.cpp')
-rw-r--r--tools/libclang/CIndexUSRs.cpp61
1 files changed, 35 insertions, 26 deletions
diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
index 121d67d..7c79b69 100644
--- a/tools/libclang/CIndexUSRs.cpp
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -30,7 +30,7 @@ using namespace clang::cxstring;
namespace {
class USRGenerator : public DeclVisitor<USRGenerator> {
- llvm::OwningPtr<llvm::SmallString<128> > OwnedBuf;
+ OwningPtr<SmallString<128> > OwnedBuf;
SmallVectorImpl<char> &Buf;
llvm::raw_svector_ostream Out;
bool IgnoreResults;
@@ -41,7 +41,7 @@ class USRGenerator : public DeclVisitor<USRGenerator> {
public:
explicit USRGenerator(ASTContext *Ctx = 0, SmallVectorImpl<char> *extBuf = 0)
- : OwnedBuf(extBuf ? 0 : new llvm::SmallString<128>()),
+ : OwnedBuf(extBuf ? 0 : new SmallString<128>()),
Buf(extBuf ? *extBuf : *OwnedBuf.get()),
Out(Buf),
IgnoreResults(false),
@@ -75,9 +75,7 @@ public:
void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
void VisitClassTemplateDecl(ClassTemplateDecl *D);
- void VisitObjCClassDecl(ObjCClassDecl *CD);
void VisitObjCContainerDecl(ObjCContainerDecl *CD);
- void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *P);
void VisitObjCMethodDecl(ObjCMethodDecl *MD);
void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
@@ -169,7 +167,12 @@ void USRGenerator::VisitDeclContext(DeclContext *DC) {
}
void USRGenerator::VisitFieldDecl(FieldDecl *D) {
- VisitDeclContext(D->getDeclContext());
+ // The USR for an ivar declared in a class extension is based on the
+ // ObjCInterfaceDecl, not the ObjCCategoryDecl.
+ if (ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
+ Visit(ID);
+ else
+ VisitDeclContext(D->getDeclContext());
Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@");
if (EmitDeclName(D)) {
// Bit fields can be anonymous.
@@ -191,9 +194,19 @@ void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
D->printName(Out);
ASTContext &Ctx = *Context;
- if (!Ctx.getLangOptions().CPlusPlus || D->isExternC())
+ if (!Ctx.getLangOpts().CPlusPlus || D->isExternC())
return;
+ if (const TemplateArgumentList *
+ SpecArgs = D->getTemplateSpecializationArgs()) {
+ Out << '<';
+ for (unsigned I = 0, N = SpecArgs->size(); I != N; ++I) {
+ Out << '#';
+ VisitTemplateArgument(SpecArgs->get(I));
+ }
+ Out << '>';
+ }
+
// Mangle in type information for the arguments.
for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end();
I != E; ++I) {
@@ -305,18 +318,6 @@ void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) {
N.printName(Out);
}
-void USRGenerator::VisitObjCClassDecl(ObjCClassDecl *D) {
- // FIXME: @class declarations can refer to multiple classes. We need
- // to be able to traverse these.
- IgnoreResults = true;
-}
-
-void USRGenerator::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
- // FIXME: @protocol declarations can refer to multiple protocols. We need
- // to be able to traverse these.
- IgnoreResults = true;
-}
-
void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
switch (D->getKind()) {
default:
@@ -368,7 +369,12 @@ void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
}
void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
- Visit(cast<Decl>(D->getDeclContext()));
+ // The USR for a property declared in a class extension or category is based
+ // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
+ if (ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
+ Visit(ID);
+ else
+ Visit(cast<Decl>(D->getDeclContext()));
GenObjCProperty(D->getName());
}
@@ -399,7 +405,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
case TTK_Struct: Out << "@ST"; break;
case TTK_Class: Out << "@CT"; break;
case TTK_Union: Out << "@UT"; break;
- case TTK_Enum: llvm_unreachable("enum template"); break;
+ case TTK_Enum: llvm_unreachable("enum template");
}
VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
} else if (ClassTemplatePartialSpecializationDecl *PartialSpec
@@ -410,7 +416,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
case TTK_Struct: Out << "@SP"; break;
case TTK_Class: Out << "@CP"; break;
case TTK_Union: Out << "@UP"; break;
- case TTK_Enum: llvm_unreachable("enum partial specialization"); break;
+ case TTK_Enum: llvm_unreachable("enum partial specialization");
}
VisitTemplateParameterList(PartialSpec->getTemplateParameters());
}
@@ -580,10 +586,10 @@ void USRGenerator::VisitType(QualType T) {
c = 'D'; break;
case BuiltinType::NullPtr:
c = 'n'; break;
- case BuiltinType::Overload:
- case BuiltinType::BoundMember:
+#define BUILTIN_TYPE(Id, SingletonId)
+#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
+#include "clang/AST/BuiltinTypes.def"
case BuiltinType::Dependent:
- case BuiltinType::UnknownAny:
IgnoreResults = true;
return;
case BuiltinType::ObjCId:
@@ -789,7 +795,7 @@ static inline StringRef extractUSRSuffix(StringRef s) {
return s.startswith("c:") ? s.substr(2) : "";
}
-bool cxcursor::getDeclCursorUSR(Decl *D, SmallVectorImpl<char> &Buf) {
+bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf) {
// Don't generate USRs for things with invalid locations.
if (!D || D->getLocStart().isInvalid())
return true;
@@ -819,7 +825,7 @@ bool cxcursor::getDeclCursorUSR(Decl *D, SmallVectorImpl<char> &Buf) {
{
USRGenerator UG(&D->getASTContext(), &Buf);
- UG->Visit(D);
+ UG->Visit(const_cast<Decl*>(D));
if (UG->ignoreResults())
return true;
@@ -835,6 +841,9 @@ CXString clang_getCursorUSR(CXCursor C) {
if (clang_isDeclaration(K)) {
Decl *D = cxcursor::getCursorDecl(C);
+ if (!D)
+ return createCXString("");
+
CXTranslationUnit TU = cxcursor::getCursorTU(C);
if (!TU)
return createCXString("");
OpenPOWER on IntegriCloud