summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/SourceLocation.h1
-rw-r--r--clang/include/clang/Lex/Lexer.h6
-rw-r--r--clang/lib/Lex/Lexer.cpp59
-rw-r--r--clang/unittests/Lex/LexerTest.cpp24
4 files changed, 52 insertions, 38 deletions
diff --git a/clang/include/clang/Basic/SourceLocation.h b/clang/include/clang/Basic/SourceLocation.h
index 154148c16b0..58546399145 100644
--- a/clang/include/clang/Basic/SourceLocation.h
+++ b/clang/include/clang/Basic/SourceLocation.h
@@ -245,6 +245,7 @@ public:
/// the last token. Return false if the end of this range specifies the last
/// character in the range.
bool isTokenRange() const { return IsTokenRange; }
+ bool isCharRange() const { return !IsTokenRange; }
SourceLocation getBegin() const { return Range.getBegin(); }
SourceLocation getEnd() const { return Range.getEnd(); }
diff --git a/clang/include/clang/Lex/Lexer.h b/clang/include/clang/Lex/Lexer.h
index a935718e6f0..bad9844f66b 100644
--- a/clang/include/clang/Lex/Lexer.h
+++ b/clang/include/clang/Lex/Lexer.h
@@ -331,11 +331,11 @@ public:
const LangOptions &LangOpts,
SourceLocation *MacroEnd = 0);
- /// \brief Accepts a token source range and returns a character range with
- /// file locations.
+ /// \brief Accepts a range and returns a character range with file locations.
+ ///
/// Returns a null range if a part of the range resides inside a macro
/// expansion or the range does not reside on the same FileID.
- static CharSourceRange makeFileCharRange(SourceRange TokenRange,
+ static CharSourceRange makeFileCharRange(CharSourceRange Range,
const SourceManager &SM,
const LangOptions &LangOpts);
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 8ae6e98a4f3..c9f73764c92 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -793,14 +793,17 @@ bool Lexer::isAtEndOfMacroExpansion(SourceLocation loc,
return isAtEndOfMacroExpansion(expansionLoc, SM, LangOpts, MacroEnd);
}
-static CharSourceRange makeRangeFromFileLocs(SourceLocation Begin,
- SourceLocation End,
+static CharSourceRange makeRangeFromFileLocs(CharSourceRange Range,
const SourceManager &SM,
const LangOptions &LangOpts) {
+ SourceLocation Begin = Range.getBegin();
+ SourceLocation End = Range.getEnd();
assert(Begin.isFileID() && End.isFileID());
- End = Lexer::getLocForEndOfToken(End, 0, SM,LangOpts);
- if (End.isInvalid())
- return CharSourceRange();
+ if (Range.isTokenRange()) {
+ End = Lexer::getLocForEndOfToken(End, 0, SM,LangOpts);
+ if (End.isInvalid())
+ return CharSourceRange();
+ }
// Break down the source locations.
FileID FID;
@@ -817,38 +820,49 @@ static CharSourceRange makeRangeFromFileLocs(SourceLocation Begin,
return CharSourceRange::getCharRange(Begin, End);
}
-/// \brief Accepts a token source range and returns a character range with
-/// file locations.
+/// \brief Accepts a range and returns a character range with file locations.
+///
/// Returns a null range if a part of the range resides inside a macro
/// expansion or the range does not reside on the same FileID.
-CharSourceRange Lexer::makeFileCharRange(SourceRange TokenRange,
+CharSourceRange Lexer::makeFileCharRange(CharSourceRange Range,
const SourceManager &SM,
const LangOptions &LangOpts) {
- SourceLocation Begin = TokenRange.getBegin();
- SourceLocation End = TokenRange.getEnd();
+ SourceLocation Begin = Range.getBegin();
+ SourceLocation End = Range.getEnd();
if (Begin.isInvalid() || End.isInvalid())
return CharSourceRange();
if (Begin.isFileID() && End.isFileID())
- return makeRangeFromFileLocs(Begin, End, SM, LangOpts);
+ return makeRangeFromFileLocs(Range, SM, LangOpts);
if (Begin.isMacroID() && End.isFileID()) {
if (!isAtStartOfMacroExpansion(Begin, SM, LangOpts, &Begin))
return CharSourceRange();
- return makeRangeFromFileLocs(Begin, End, SM, LangOpts);
+ Range.setBegin(Begin);
+ return makeRangeFromFileLocs(Range, SM, LangOpts);
}
if (Begin.isFileID() && End.isMacroID()) {
- if (!isAtEndOfMacroExpansion(End, SM, LangOpts, &End))
+ if ((Range.isTokenRange() && !isAtEndOfMacroExpansion(End, SM, LangOpts,
+ &End)) ||
+ (Range.isCharRange() && !isAtStartOfMacroExpansion(End, SM, LangOpts,
+ &End)))
return CharSourceRange();
- return makeRangeFromFileLocs(Begin, End, SM, LangOpts);
+ Range.setEnd(End);
+ return makeRangeFromFileLocs(Range, SM, LangOpts);
}
assert(Begin.isMacroID() && End.isMacroID());
SourceLocation MacroBegin, MacroEnd;
if (isAtStartOfMacroExpansion(Begin, SM, LangOpts, &MacroBegin) &&
- isAtEndOfMacroExpansion(End, SM, LangOpts, &MacroEnd))
- return makeRangeFromFileLocs(MacroBegin, MacroEnd, SM, LangOpts);
+ ((Range.isTokenRange() && isAtEndOfMacroExpansion(End, SM, LangOpts,
+ &MacroEnd)) ||
+ (Range.isCharRange() && isAtStartOfMacroExpansion(End, SM, LangOpts,
+ &MacroEnd)))) {
+ Range.setBegin(MacroBegin);
+ Range.setEnd(MacroEnd);
+ return makeRangeFromFileLocs(Range, SM, LangOpts);
+ }
FileID FID;
unsigned BeginOffs;
@@ -866,9 +880,9 @@ CharSourceRange Lexer::makeFileCharRange(SourceRange TokenRange,
if (Expansion.isMacroArgExpansion() &&
Expansion.getSpellingLoc().isFileID()) {
SourceLocation SpellLoc = Expansion.getSpellingLoc();
- return makeRangeFromFileLocs(SpellLoc.getLocWithOffset(BeginOffs),
- SpellLoc.getLocWithOffset(EndOffs),
- SM, LangOpts);
+ Range.setBegin(SpellLoc.getLocWithOffset(BeginOffs));
+ Range.setEnd(SpellLoc.getLocWithOffset(EndOffs));
+ return makeRangeFromFileLocs(Range, SM, LangOpts);
}
return CharSourceRange();
@@ -878,11 +892,8 @@ StringRef Lexer::getSourceText(CharSourceRange Range,
const SourceManager &SM,
const LangOptions &LangOpts,
bool *Invalid) {
- if (Range.isTokenRange())
- Range = makeFileCharRange(Range.getAsRange(), SM, LangOpts);
-
- if (Range.isInvalid() ||
- Range.getBegin().isMacroID() || Range.getEnd().isMacroID()) {
+ Range = makeFileCharRange(Range, SM, LangOpts);
+ if (Range.isInvalid()) {
if (Invalid) *Invalid = true;
return StringRef();
}
diff --git a/clang/unittests/Lex/LexerTest.cpp b/clang/unittests/Lex/LexerTest.cpp
index 2742f66663b..28199c4aace 100644
--- a/clang/unittests/Lex/LexerTest.cpp
+++ b/clang/unittests/Lex/LexerTest.cpp
@@ -115,13 +115,13 @@ TEST_F(LexerTest, LexAPI) {
EXPECT_TRUE(Lexer::isAtEndOfMacroExpansion(rsqrLoc, SourceMgr, LangOpts, &Loc));
EXPECT_EQ(Loc, macroRange.getEnd());
- CharSourceRange range = Lexer::makeFileCharRange(SourceRange(lsqrLoc, idLoc),
- SourceMgr, LangOpts);
+ CharSourceRange range = Lexer::makeFileCharRange(
+ CharSourceRange::getTokenRange(lsqrLoc, idLoc), SourceMgr, LangOpts);
EXPECT_TRUE(range.isInvalid());
- range = Lexer::makeFileCharRange(SourceRange(idLoc, rsqrLoc),
+ range = Lexer::makeFileCharRange(CharSourceRange::getTokenRange(idLoc, rsqrLoc),
SourceMgr, LangOpts);
EXPECT_TRUE(range.isInvalid());
- range = Lexer::makeFileCharRange(SourceRange(lsqrLoc, rsqrLoc),
+ range = Lexer::makeFileCharRange(CharSourceRange::getTokenRange(lsqrLoc, rsqrLoc),
SourceMgr, LangOpts);
EXPECT_TRUE(!range.isTokenRange());
EXPECT_EQ(range.getAsRange(),
@@ -129,8 +129,8 @@ TEST_F(LexerTest, LexAPI) {
macroRange.getEnd().getLocWithOffset(1)));
StringRef text = Lexer::getSourceText(
- CharSourceRange::getTokenRange(SourceRange(lsqrLoc, rsqrLoc)),
- SourceMgr, LangOpts);
+ CharSourceRange::getTokenRange(lsqrLoc, rsqrLoc),
+ SourceMgr, LangOpts);
EXPECT_EQ(text, "M(foo)");
SourceLocation macroLsqrLoc = toks[3].getLocation();
@@ -140,19 +140,21 @@ TEST_F(LexerTest, LexAPI) {
SourceLocation fileIdLoc = SourceMgr.getSpellingLoc(macroIdLoc);
SourceLocation fileRsqrLoc = SourceMgr.getSpellingLoc(macroRsqrLoc);
- range = Lexer::makeFileCharRange(SourceRange(macroLsqrLoc, macroIdLoc),
- SourceMgr, LangOpts);
+ range = Lexer::makeFileCharRange(
+ CharSourceRange::getTokenRange(macroLsqrLoc, macroIdLoc),
+ SourceMgr, LangOpts);
EXPECT_EQ(SourceRange(fileLsqrLoc, fileIdLoc.getLocWithOffset(3)),
range.getAsRange());
- range = Lexer::makeFileCharRange(SourceRange(macroIdLoc, macroRsqrLoc),
+ range = Lexer::makeFileCharRange(CharSourceRange::getTokenRange(macroIdLoc, macroRsqrLoc),
SourceMgr, LangOpts);
EXPECT_EQ(SourceRange(fileIdLoc, fileRsqrLoc.getLocWithOffset(1)),
range.getAsRange());
macroPair = SourceMgr.getExpansionRange(macroLsqrLoc);
- range = Lexer::makeFileCharRange(SourceRange(macroLsqrLoc, macroRsqrLoc),
- SourceMgr, LangOpts);
+ range = Lexer::makeFileCharRange(
+ CharSourceRange::getTokenRange(macroLsqrLoc, macroRsqrLoc),
+ SourceMgr, LangOpts);
EXPECT_EQ(SourceRange(macroPair.first, macroPair.second.getLocWithOffset(1)),
range.getAsRange());
OpenPOWER on IntegriCloud