diff options
| author | Chris Lattner <sabre@nondot.org> | 2007-07-16 06:48:38 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2007-07-16 06:48:38 +0000 |
| commit | 8a7003cd9f8f72720c2a9050a899d541fac03c1a (patch) | |
| tree | 6ca385d544aad9b62942870c41fdc68c174bfabe /clang/Lex/Preprocessor.cpp | |
| parent | eb5b20ae48618d2b0a685ed7d1cf27a32fd74d05 (diff) | |
| download | bcm5719-llvm-8a7003cd9f8f72720c2a9050a899d541fac03c1a.tar.gz bcm5719-llvm-8a7003cd9f8f72720c2a9050a899d541fac03c1a.zip | |
Add a new Preprocessor::AdvanceToTokenCharacter method which, given a sloc
specifying the start of a token and a logical (phase 3) character number,
returns a sloc representing the input character corresponding to it.
llvm-svn: 39905
Diffstat (limited to 'clang/Lex/Preprocessor.cpp')
| -rw-r--r-- | clang/Lex/Preprocessor.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/clang/Lex/Preprocessor.cpp b/clang/Lex/Preprocessor.cpp index 8376b9f8a30..93017937d53 100644 --- a/clang/Lex/Preprocessor.cpp +++ b/clang/Lex/Preprocessor.cpp @@ -36,6 +36,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/MemoryBuffer.h" #include <iostream> using namespace clang; @@ -253,6 +254,42 @@ CreateString(const char *Buf, unsigned Len, SourceLocation SLoc) { } +/// AdvanceToTokenCharacter - Given a location that specifies the start of a +/// token, return a new location that specifies a character within the token. +SourceLocation Preprocessor::AdvanceToTokenCharacter(SourceLocation TokStart, + unsigned CharNo) { + // If they request the first char of the token, we're trivially done. + if (CharNo == 0) return TokStart; + + // Figure out how many physical characters away the specified logical + // character is. This needs to take into consideration newlines and + // trigraphs. + const char *TokStartPtr = SourceMgr.getCharacterData(TokStart); + const char *TokPtr = TokStartPtr; + + // The usual case is that tokens don't contain anything interesting. Skip + // over the uninteresting characters. If a token only consists of simple + // chars, this method is extremely fast. + while (CharNo && Lexer::isObviouslySimpleCharacter(*TokPtr)) + ++TokPtr, --CharNo; + + // If we have a character that may be a trigraph or escaped newline, create a + // lexer to parse it correctly. + unsigned FileID = TokStart.getFileID(); + const llvm::MemoryBuffer *SrcBuf = SourceMgr.getBuffer(FileID); + if (CharNo != 0) { + // Create a lexer starting at this token position. + Lexer TheLexer(SrcBuf, FileID, *this, TokPtr); + LexerToken Tok; + // Skip over characters the remaining characters. + for (; CharNo; --CharNo) + TheLexer.getAndAdvanceChar(TokPtr, Tok); + } + return SourceLocation(FileID, TokPtr-SrcBuf->getBufferStart()); +} + + + //===----------------------------------------------------------------------===// // Source File Location Methods. //===----------------------------------------------------------------------===// |

