Use a sane encoding for CXCursor_ObjCProtocolRef, using the actual
source locations where the protocols were referenced rather than the
location of some random enclosing declaration.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93637 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index e58a08a..c08243e 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -262,7 +262,10 @@
void CDeclVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
// Issue callbacks for the containing class.
Call(CXCursor_ObjCClassRef, ND);
- // FIXME: Issue callbacks for protocol refs.
+ ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
+ for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
+ E = ND->protocol_end(); I != E; ++I, ++PL)
+ Callback(CDecl, MakeCursorObjCProtocolRef(*I, *PL), CData);
VisitDeclContext(dyn_cast<DeclContext>(ND));
}
@@ -282,9 +285,10 @@
D->getSuperClassLoc()),
CData);
- for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
- E = D->protocol_end(); I != E; ++I)
- Call(CXCursor_ObjCProtocolRef, *I);
+ ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
+ for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
+ E = D->protocol_end(); I != E; ++I, ++PL)
+ Callback(CDecl, MakeCursorObjCProtocolRef(*I, *PL), CData);
VisitDeclContext(dyn_cast<DeclContext>(D));
}
@@ -307,9 +311,10 @@
}
void CDeclVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
+ ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
- E = PID->protocol_end(); I != E; ++I)
- Call(CXCursor_ObjCProtocolRef, *I);
+ E = PID->protocol_end(); I != E; ++I, ++PL)
+ Callback(CDecl, MakeCursorObjCProtocolRef(*I, *PL), CData);
VisitDeclContext(dyn_cast<DeclContext>(PID));
}
@@ -346,12 +351,8 @@
}
case CXCursor_ObjCSuperClassRef:
return getCursorObjCSuperClassRef(C).second;
-
- case CXCursor_ObjCProtocolRef: {
- ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
- assert(OID && "clang_getCursorLine(): Missing protocol decl");
- return OID->getLocation();
- }
+ case CXCursor_ObjCProtocolRef:
+ return getCursorObjCProtocolRef(C).second;
case CXCursor_ObjCSelectorRef: {
ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(getCursorStmt(C));
assert(OME && "clang_getCursorLine(): Missing message expr");
@@ -776,7 +777,7 @@
->getNameStart());
}
case CXCursor_ObjCProtocolRef: {
- ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
+ ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
assert(OID && "clang_getCursorLine(): Missing protocol decl");
return CIndexer::createCXString(OID->getIdentifier()->getNameStart());
}
@@ -884,10 +885,8 @@
CXCursor C = { CXCursor_ObjCClassRef, { Dcl, ALoc.getParentDecl(), 0 }};
return C;
}
- if (isa<ObjCProtocolDecl>(Dcl)) {
- CXCursor C = {CXCursor_ObjCProtocolRef, {Dcl, ALoc.getParentDecl(), 0}};
- return C;
- }
+ if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(Dcl))
+ return MakeCursorObjCProtocolRef(Proto, ALoc.AsNamedRef().Loc);
}
return MakeCXCursor(Dcl);
}
@@ -933,8 +932,7 @@
if (clang_isReference(C.kind)) {
if (getCursorStmt(C)) {
- if (C.kind == CXCursor_ObjCClassRef ||
- C.kind == CXCursor_ObjCProtocolRef)
+ if (C.kind == CXCursor_ObjCClassRef)
return getCursorStmt(C);
else
return getDeclFromExpr(getCursorStmt(C));
diff --git a/tools/CIndex/CXCursor.cpp b/tools/CIndex/CXCursor.cpp
index d6c3867..01d809a 100644
--- a/tools/CIndex/CXCursor.cpp
+++ b/tools/CIndex/CXCursor.cpp
@@ -90,6 +90,21 @@
reinterpret_cast<uintptr_t>(C.data[1])));
}
+CXCursor cxcursor::MakeCursorObjCProtocolRef(ObjCProtocolDecl *Super,
+ SourceLocation Loc) {
+ void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+ CXCursor C = { CXCursor_ObjCProtocolRef, { Super, RawLoc, 0 } };
+ return C;
+}
+
+std::pair<ObjCProtocolDecl *, SourceLocation>
+cxcursor::getCursorObjCProtocolRef(CXCursor C) {
+ assert(C.kind == CXCursor_ObjCProtocolRef);
+ return std::make_pair(static_cast<ObjCProtocolDecl *>(C.data[0]),
+ SourceLocation::getFromRawEncoding(
+ reinterpret_cast<uintptr_t>(C.data[1])));
+}
+
Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
return (Decl *)Cursor.data[0];
}
@@ -99,7 +114,8 @@
}
Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
- if (Cursor.kind == CXCursor_ObjCSuperClassRef)
+ if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
+ Cursor.kind == CXCursor_ObjCProtocolRef)
return 0;
return (Stmt *)Cursor.data[1];
diff --git a/tools/CIndex/CXCursor.h b/tools/CIndex/CXCursor.h
index c2f8de3..26bbc7d 100644
--- a/tools/CIndex/CXCursor.h
+++ b/tools/CIndex/CXCursor.h
@@ -24,6 +24,7 @@
class Expr;
class NamedDecl;
class ObjCInterfaceDecl;
+class ObjCProtocolDecl;
class Stmt;
namespace cxcursor {
@@ -39,7 +40,15 @@
/// \brief Unpack an ObjCSuperClassRef cursor into the interface it references
/// and optionally the location where the reference occurred.
std::pair<ObjCInterfaceDecl *, SourceLocation>
-getCursorObjCSuperClassRef(CXCursor C);
+ getCursorObjCSuperClassRef(CXCursor C);
+
+/// \brief Create an Objective-C protocol reference at the given location.
+CXCursor MakeCursorObjCProtocolRef(ObjCProtocolDecl *Proto, SourceLocation Loc);
+
+/// \brief Unpack an ObjCProtocolRef cursor into the protocol it references
+/// and optionally the location where the reference occurred.
+std::pair<ObjCProtocolDecl *, SourceLocation>
+ getCursorObjCProtocolRef(CXCursor C);
Decl *getCursorDecl(CXCursor Cursor);
Expr *getCursorExpr(CXCursor Cursor);