summaryrefslogtreecommitdiffstats
path: root/clang/tools
diff options
context:
space:
mode:
Diffstat (limited to 'clang/tools')
-rw-r--r--clang/tools/libclang/CIndex.cpp31
-rw-r--r--clang/tools/libclang/CXCursor.cpp16
-rw-r--r--clang/tools/libclang/CXCursor.h7
3 files changed, 47 insertions, 7 deletions
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 44493497bdb..4413766b028 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -1357,10 +1357,12 @@ bool CursorVisitor::VisitCaseStmt(CaseStmt *S) {
}
bool CursorVisitor::VisitDeclStmt(DeclStmt *S) {
+ bool isFirst = true;
for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
D != DEnd; ++D) {
- if (*D && Visit(MakeCXCursor(*D, TU)))
+ if (*D && Visit(MakeCXCursor(*D, TU, isFirst)))
return true;
+ isFirst = false;
}
return false;
@@ -2926,6 +2928,16 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
SourceLocation Loc = D->getLocation();
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
Loc = Class->getClassLoc();
+ // FIXME: Multiple variables declared in a single declaration
+ // currently lack the information needed to correctly determine their
+ // ranges when accounting for the type-specifier. We use context
+ // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
+ // and if so, whether it is the first decl.
+ if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (!cxcursor::isFirstInDeclGroup(C))
+ Loc = VD->getLocation();
+ }
+
return cxloc::translateSourceLocation(getCursorContext(C), Loc);
}
@@ -2988,9 +3000,20 @@ static SourceRange getRawCursorExtent(CXCursor C) {
if (C.kind == CXCursor_InclusionDirective)
return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
- if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl)
- return getCursorDecl(C)->getSourceRange();
-
+ if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
+ Decl *D = cxcursor::getCursorDecl(C);
+ SourceRange R = D->getSourceRange();
+ // FIXME: Multiple variables declared in a single declaration
+ // currently lack the information needed to correctly determine their
+ // ranges when accounting for the type-specifier. We use context
+ // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
+ // and if so, whether it is the first decl.
+ if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (!cxcursor::isFirstInDeclGroup(C))
+ R.setBegin(VD->getLocation());
+ }
+ return R;
+ }
return SourceRange();}
extern "C" {
diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp
index d506400407f..9dd94f972ef 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -20,6 +20,7 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
+#include "clang-c/Index.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
@@ -49,9 +50,12 @@ CXCursor cxcursor::MakeCXCursor(const Attr *A, Decl *Parent, ASTUnit *TU) {
return C;
}
-CXCursor cxcursor::MakeCXCursor(Decl *D, ASTUnit *TU) {
+CXCursor cxcursor::MakeCXCursor(Decl *D, ASTUnit *TU,
+ bool FirstInDeclGroup) {
assert(D && TU && "Invalid arguments!");
- CXCursor C = { getCursorKindForDecl(D), { D, 0, TU } };
+ CXCursor C = { getCursorKindForDecl(D),
+ { D, (void*) (FirstInDeclGroup ? 1 : 0), TU }
+ };
return C;
}
@@ -470,3 +474,11 @@ bool cxcursor::operator==(CXCursor X, CXCursor Y) {
return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
X.data[2] == Y.data[2];
}
+
+// FIXME: Remove once we can model DeclGroups and their appropriate ranges
+// properly in the ASTs.
+bool cxcursor::isFirstInDeclGroup(CXCursor C) {
+ assert(clang_isDeclaration(C.kind));
+ return ((uintptr_t) (C.data[1])) != 0;
+}
+
diff --git a/clang/tools/libclang/CXCursor.h b/clang/tools/libclang/CXCursor.h
index a31a3220767..7e518edef96 100644
--- a/clang/tools/libclang/CXCursor.h
+++ b/clang/tools/libclang/CXCursor.h
@@ -45,7 +45,8 @@ class TypeDecl;
namespace cxcursor {
CXCursor MakeCXCursor(const clang::Attr *A, clang::Decl *Parent, ASTUnit *TU);
-CXCursor MakeCXCursor(clang::Decl *D, ASTUnit *TU);
+CXCursor MakeCXCursor(clang::Decl *D, ASTUnit *TU,
+ bool FirstInDeclGroup = true);
CXCursor MakeCXCursor(clang::Stmt *S, clang::Decl *Parent, ASTUnit *TU);
CXCursor MakeCXCursorInvalid(CXCursorKind K);
@@ -183,6 +184,10 @@ inline bool operator!=(CXCursor X, CXCursor Y) {
return !(X == Y);
}
+/// \brief Return true if the cursor represents a declaration that is the
+/// first in a declaration group.
+bool isFirstInDeclGroup(CXCursor C);
+
}} // end namespace: clang::cxcursor
#endif
OpenPOWER on IntegriCloud