Rework the CXSourceLocation and CXSourceRange APIs. They are now
opaque data structures accessed through the new functions
clang_getInstantiationLocation(), clang_getRangeStart(), and
clang_getRangeEnd(). The new API permits later extensions to introduce
new functions to allow CIndex clients to walk macro instantiations, if
we ever care.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93915 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index e6b4baf..a7cbb8a 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -113,9 +113,17 @@
#endif
#endif
+typedef llvm::PointerIntPair<ASTContext *, 1, bool> CXSourceLocationPtr;
+
/// \brief Translate a Clang source location into a CIndex source location.
-static CXSourceLocation translateSourceLocation(SourceManager &SourceMgr,
- SourceLocation Loc) {
+static CXSourceLocation translateSourceLocation(ASTContext &Context,
+ SourceLocation Loc,
+ bool AtEnd = false) {
+ CXSourceLocationPtr Ptr(&Context, AtEnd);
+ CXSourceLocation Result = { Ptr.getOpaqueValue(), Loc.getRawEncoding() };
+ return Result;
+
+#if 0
SourceLocation InstLoc = SourceMgr.getInstantiationLoc(Loc);
if (InstLoc.isInvalid()) {
CXSourceLocation Loc = { 0, 0, 0 };
@@ -128,11 +136,16 @@
Result.line = SourceMgr.getInstantiationLineNumber(InstLoc);
Result.column = SourceMgr.getInstantiationColumnNumber(InstLoc);
return Result;
+#endif
}
/// \brief Translate a Clang source range into a CIndex source range.
-static CXSourceRange translateSourceRange(ASTContext &Context,
- SourceRange R) {
+static CXSourceRange translateSourceRange(ASTContext &Context, SourceRange R) {
+ CXSourceRange Result = { &Context,
+ R.getBegin().getRawEncoding(),
+ R.getEnd().getRawEncoding() };
+ return Result;
+#if 0
if (R.isInvalid()) {
CXSourceRange extent = { { 0, 0, 0 }, { 0, 0, 0 } };
return extent;
@@ -177,8 +190,10 @@
CXSourceRange extent = { { (void *)BeginFile, StartLineNo, StartColNo },
{ (void *)EndFile, EndLineNo, EndColNo } };
return extent;
+#endif
}
+
//===----------------------------------------------------------------------===//
// Visitors.
//===----------------------------------------------------------------------===//
@@ -607,6 +622,80 @@
} // end: extern "C"
//===----------------------------------------------------------------------===//
+// CXSourceLocation and CXSourceRange Operations.
+//===----------------------------------------------------------------------===//
+
+void clang_getInstantiationLocation(CXSourceLocation location,
+ CXFile *file,
+ unsigned *line,
+ unsigned *column) {
+ CXSourceLocationPtr Ptr
+ = CXSourceLocationPtr::getFromOpaqueValue(location.ptr_data);
+ SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
+
+ if (!Ptr.getPointer() || Loc.isInvalid()) {
+ if (file)
+ *file = 0;
+ if (line)
+ *line = 0;
+ if (column)
+ *column = 0;
+ return;
+ }
+
+ // FIXME: This is largely copy-paste from
+ ///TextDiagnosticPrinter::HighlightRange. When it is clear that this is
+ // what we want the two routines should be refactored.
+ ASTContext &Context = *Ptr.getPointer();
+ SourceManager &SM = Context.getSourceManager();
+ SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
+
+ if (Ptr.getInt()) {
+ // We want the last character in this location, so we will adjust
+ // the instantiation location accordingly.
+
+ // If the location is from a macro instantiation, get the end of
+ // the instantiation range.
+ if (Loc.isMacroID())
+ InstLoc = SM.getInstantiationRange(Loc).second;
+
+ // Measure the length token we're pointing at, so we can adjust
+ // the physical location in the file to point at the last
+ // character.
+ // FIXME: This won't cope with trigraphs or escaped newlines
+ // well. For that, we actually need a preprocessor, which isn't
+ // currently available here. Eventually, we'll switch the pointer
+ // data of CXSourceLocation/CXSourceRange to a translation unit
+ // (CXXUnit), so that the preprocessor will be available here. At
+ // that point, we can use Preprocessor::getLocForEndOfToken().
+ unsigned Length = Lexer::MeasureTokenLength(InstLoc, SM,
+ Context.getLangOptions());
+ if (Length > 0)
+ InstLoc = InstLoc.getFileLocWithOffset(Length - 1);
+ }
+
+ if (file)
+ *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc));
+ if (line)
+ *line = SM.getInstantiationLineNumber(InstLoc);
+ if (column)
+ *column = SM.getInstantiationColumnNumber(InstLoc);
+}
+
+CXSourceLocation clang_getRangeStart(CXSourceRange range) {
+ CXSourceLocation Result = { range.ptr_data, range.begin_int_data };
+ return Result;
+}
+
+CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
+ llvm::PointerIntPair<ASTContext *, 1, bool> Ptr;
+ Ptr.setPointer(static_cast<ASTContext *>(range.ptr_data));
+ Ptr.setInt(true);
+ CXSourceLocation Result = { Ptr.getOpaqueValue(), range.end_int_data };
+ return Result;
+}
+
+//===----------------------------------------------------------------------===//
// CXDecl Operations.
//===----------------------------------------------------------------------===//
@@ -896,22 +985,19 @@
case CXCursor_ObjCSuperClassRef: {
std::pair<ObjCInterfaceDecl *, SourceLocation> P
= getCursorObjCSuperClassRef(C);
- SourceManager &SM = P.first->getASTContext().getSourceManager();
- return translateSourceLocation(SM, P.second);
+ return translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_ObjCProtocolRef: {
std::pair<ObjCProtocolDecl *, SourceLocation> P
= getCursorObjCProtocolRef(C);
- SourceManager &SM = P.first->getASTContext().getSourceManager();
- return translateSourceLocation(SM, P.second);
+ return translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_ObjCClassRef: {
std::pair<ObjCInterfaceDecl *, SourceLocation> P
= getCursorObjCClassRef(C);
- SourceManager &SM = P.first->getASTContext().getSourceManager();
- return translateSourceLocation(SM, P.second);
+ return translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_ObjCSelectorRef:
@@ -921,16 +1007,16 @@
case CXCursor_EnumConstantRef:
case CXCursor_MemberRef: {
Expr *E = getCursorExpr(C);
- SourceManager &SM = getCursorContext(C).getSourceManager();
+ ASTContext &Context = getCursorContext(C);
if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
- return translateSourceLocation(SM, /*FIXME:*/Msg->getLeftLoc());
+ return translateSourceLocation(Context, /*FIXME:*/Msg->getLeftLoc());
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
- return translateSourceLocation(SM, DRE->getLocation());
+ return translateSourceLocation(Context, DRE->getLocation());
if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
- return translateSourceLocation(SM, Member->getMemberLoc());
+ return translateSourceLocation(Context, Member->getMemberLoc());
if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
- return translateSourceLocation(SM, Ivar->getLocation());
- return translateSourceLocation(SM, E->getLocStart());
+ return translateSourceLocation(Context, Ivar->getLocation());
+ return translateSourceLocation(Context, E->getLocStart());
}
default:
@@ -940,16 +1026,15 @@
}
if (!getCursorDecl(C)) {
- CXSourceLocation empty = { 0, 0, 0 };
+ CXSourceLocation empty = { 0, 0 };
return empty;
}
Decl *D = getCursorDecl(C);
- SourceManager &SM = D->getASTContext().getSourceManager();
SourceLocation Loc = D->getLocation();
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
Loc = Class->getClassLoc();
- return translateSourceLocation(SM, Loc);
+ return translateSourceLocation(D->getASTContext(), Loc);
}
CXSourceRange clang_getCursorExtent(CXCursor C) {
@@ -990,7 +1075,7 @@
}
if (!getCursorDecl(C)) {
- CXSourceRange empty = { { 0, 0, 0 }, { 0, 0, 0 } };
+ CXSourceRange empty = { 0, 0, 0 };
return empty;
}
diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports
index 0460ba0..3de081d 100644
--- a/tools/CIndex/CIndex.exports
+++ b/tools/CIndex/CIndex.exports
@@ -34,8 +34,11 @@
_clang_getEntityFromDecl
_clang_getFileName
_clang_getFileTime
+_clang_getInstantiationLocation
_clang_getNullCursor
_clang_getNumCompletionChunks
+_clang_getRangeEnd
+_clang_getRangeStart
_clang_getTranslationUnitSpelling
_clang_isCursorDefinition
_clang_isDeclaration