diff options
Diffstat (limited to 'clang/tools')
| -rw-r--r-- | clang/tools/libclang/CIndex.cpp | 31 | ||||
| -rw-r--r-- | clang/tools/libclang/CXCursor.cpp | 16 | ||||
| -rw-r--r-- | clang/tools/libclang/CXCursor.h | 7 |
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 |

