diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-01-06 23:43:31 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-01-06 23:43:31 +0000 |
commit | d8210650ed948de65a08a8daf16d291b747717c4 (patch) | |
tree | 8f2869b4b407886ed599114a71848a4167e960b6 /tools/CIndex/CIndex.cpp | |
parent | 8e5f19d6dfe82155010febb9aa81b80d681d3066 (diff) |
Change clang_getDeclExtent() to have the endpoint point to the last character in the last token.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92869 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/CIndex/CIndex.cpp')
-rw-r--r-- | tools/CIndex/CIndex.cpp | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index e6b3d60e19..2c3f7373a3 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -16,6 +16,7 @@ #include "clang/AST/DeclVisitor.h" #include "clang/AST/StmtVisitor.h" +#include "clang/Lex/Lexer.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/System/Program.h" @@ -627,19 +628,53 @@ unsigned clang_getDeclColumn(CXDecl AnonDecl) { CXDeclExtent clang_getDeclExtent(CXDecl AnonDecl) { assert(AnonDecl && "Passed null CXDecl"); NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl); - SourceManager &SourceMgr = ND->getASTContext().getSourceManager(); + SourceManager &SM = ND->getASTContext().getSourceManager(); SourceRange R = ND->getSourceRange(); - CXDeclExtent extent; + SourceLocation Begin = SM.getInstantiationLoc(R.getBegin()); + SourceLocation End = SM.getInstantiationLoc(R.getEnd()); + + if (!Begin.isValid()) { + CXDeclExtent extent = { { 0, 0 }, { 0, 0 } }; + return extent; + } + + // 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. - SourceLocation L = SourceMgr.getSpellingLoc(R.getBegin()); - extent.begin.line = SourceMgr.getSpellingLineNumber(L); - extent.begin.column = SourceMgr.getSpellingColumnNumber(L); + // If the End location and the start location are the same and are a macro + // location, then the range was something that came from a macro expansion + // or _Pragma. If this is an object-like macro, the best we can do is to + // get the range. If this is a function-like macro, we'd also like to + // get the arguments. + if (Begin == End && R.getEnd().isMacroID()) + End = SM.getInstantiationRange(R.getEnd()).second; + + assert(SM.getFileID(Begin) == SM.getFileID(End)); + unsigned StartLineNo = SM.getInstantiationLineNumber(Begin); + unsigned EndLineNo = SM.getInstantiationLineNumber(End); - L = SourceMgr.getSpellingLoc(R.getEnd()); - extent.end.line = SourceMgr.getSpellingLineNumber(L); - extent.end.column = SourceMgr.getSpellingColumnNumber(L); + // Compute the column number of the start. Keep the column based at 1. + unsigned StartColNo = SM.getInstantiationColumnNumber(Begin); + // Compute the column number of the end. + unsigned EndColNo = SM.getInstantiationColumnNumber(End); + if (EndColNo) { + // Offset the end column by 1 so that we point to the last character + // in the last token. + --EndColNo; + + // Add in the length of the token, so that we cover multi-char tokens. + ASTContext &Ctx = ND->getTranslationUnitDecl()->getASTContext(); + const LangOptions &LOpts = Ctx.getLangOptions(); + + EndColNo += Lexer::MeasureTokenLength(End, SM, LOpts); + } + + // Package up the line/column data and return to the caller. + CXDeclExtent extent = { { StartLineNo, StartColNo }, + { EndLineNo, EndColNo } }; return extent; } |