diff options
Diffstat (limited to 'lib/Lex/Lexer.cpp')
-rw-r--r-- | lib/Lex/Lexer.cpp | 66 |
1 files changed, 49 insertions, 17 deletions
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index 003c9b5eed1b..3d6fe91115a9 100644 --- a/lib/Lex/Lexer.cpp +++ b/lib/Lex/Lexer.cpp @@ -452,6 +452,29 @@ bool Lexer::getRawToken(SourceLocation Loc, Token &Result, return false; } +/// Returns the pointer that points to the beginning of line that contains +/// the given offset, or null if the offset if invalid. +static const char *findBeginningOfLine(StringRef Buffer, unsigned Offset) { + const char *BufStart = Buffer.data(); + if (Offset >= Buffer.size()) + return nullptr; + const char *StrData = BufStart + Offset; + + if (StrData[0] == '\n' || StrData[0] == '\r') + return StrData; + + const char *LexStart = StrData; + while (LexStart != BufStart) { + if (LexStart[0] == '\n' || LexStart[0] == '\r') { + ++LexStart; + break; + } + + --LexStart; + } + return LexStart; +} + static SourceLocation getBeginningOfFileToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts) { @@ -467,27 +490,15 @@ static SourceLocation getBeginningOfFileToken(SourceLocation Loc, // Back up from the current location until we hit the beginning of a line // (or the buffer). We'll relex from that point. - const char *BufStart = Buffer.data(); - if (LocInfo.second >= Buffer.size()) - return Loc; - - const char *StrData = BufStart+LocInfo.second; - if (StrData[0] == '\n' || StrData[0] == '\r') + const char *StrData = Buffer.data() + LocInfo.second; + const char *LexStart = findBeginningOfLine(Buffer, LocInfo.second); + if (!LexStart || LexStart == StrData) return Loc; - - const char *LexStart = StrData; - while (LexStart != BufStart) { - if (LexStart[0] == '\n' || LexStart[0] == '\r') { - ++LexStart; - break; - } - - --LexStart; - } // Create a lexer starting at the beginning of this token. SourceLocation LexerStartLoc = Loc.getLocWithOffset(-LocInfo.second); - Lexer TheLexer(LexerStartLoc, LangOpts, BufStart, LexStart, Buffer.end()); + Lexer TheLexer(LexerStartLoc, LangOpts, Buffer.data(), LexStart, + Buffer.end()); TheLexer.SetCommentRetentionState(true); // Lex tokens until we find the token that contains the source location. @@ -1038,6 +1049,27 @@ bool Lexer::isIdentifierBodyChar(char c, const LangOptions &LangOpts) { return isIdentifierBody(c, LangOpts.DollarIdents); } +StringRef Lexer::getIndentationForLine(SourceLocation Loc, + const SourceManager &SM) { + if (Loc.isInvalid() || Loc.isMacroID()) + return ""; + std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); + if (LocInfo.first.isInvalid()) + return ""; + bool Invalid = false; + StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid); + if (Invalid) + return ""; + const char *Line = findBeginningOfLine(Buffer, LocInfo.second); + if (!Line) + return ""; + StringRef Rest = Buffer.substr(Line - Buffer.data()); + size_t NumWhitespaceChars = Rest.find_first_not_of(" \t"); + return NumWhitespaceChars == StringRef::npos + ? "" + : Rest.take_front(NumWhitespaceChars); +} + //===----------------------------------------------------------------------===// // Diagnostics forwarding code. //===----------------------------------------------------------------------===// |