summaryrefslogtreecommitdiffstats
path: root/lib/Lex
diff options
context:
space:
mode:
authorDavid L. Jones <dlj@google.com>2017-11-15 01:40:05 +0000
committerDavid L. Jones <dlj@google.com>2017-11-15 01:40:05 +0000
commitfdfce82b87b73e18577d493e84bdabe2585b95d0 (patch)
treee8d9290e273dba03920bf15a8c7742fcf5ed0b87 /lib/Lex
parent41af1698c520ea38edf83e7c91f1e519d34f20c1 (diff)
parenta7540887e8b5cb34ee28c12bef863bad85c65b6f (diff)
Creating branches/google/testing and tags/google/testing/2017-11-14 from r317716upstream/google/testing
git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/google/testing@318248 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex')
-rw-r--r--lib/Lex/Lexer.cpp36
-rw-r--r--lib/Lex/PPDirectives.cpp31
-rw-r--r--lib/Lex/PPMacroExpansion.cpp1
-rw-r--r--lib/Lex/Preprocessor.cpp7
4 files changed, 48 insertions, 27 deletions
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 5132d0e62c..67dcff6b71 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -1212,18 +1212,12 @@ const char *Lexer::SkipEscapedNewLines(const char *P) {
}
}
-/// \brief Checks that the given token is the first token that occurs after the
-/// given location (this excludes comments and whitespace). Returns the location
-/// immediately after the specified token. If the token is not found or the
-/// location is inside a macro, the returned source location will be invalid.
-SourceLocation Lexer::findLocationAfterToken(SourceLocation Loc,
- tok::TokenKind TKind,
- const SourceManager &SM,
- const LangOptions &LangOpts,
- bool SkipTrailingWhitespaceAndNewLine) {
+Optional<Token> Lexer::findNextToken(SourceLocation Loc,
+ const SourceManager &SM,
+ const LangOptions &LangOpts) {
if (Loc.isMacroID()) {
if (!Lexer::isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc))
- return SourceLocation();
+ return None;
}
Loc = Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts);
@@ -1234,7 +1228,7 @@ SourceLocation Lexer::findLocationAfterToken(SourceLocation Loc,
bool InvalidTemp = false;
StringRef File = SM.getBufferData(LocInfo.first, &InvalidTemp);
if (InvalidTemp)
- return SourceLocation();
+ return None;
const char *TokenBegin = File.data() + LocInfo.second;
@@ -1244,15 +1238,25 @@ SourceLocation Lexer::findLocationAfterToken(SourceLocation Loc,
// Find the token.
Token Tok;
lexer.LexFromRawLexer(Tok);
- if (Tok.isNot(TKind))
+ return Tok;
+}
+
+/// \brief Checks that the given token is the first token that occurs after the
+/// given location (this excludes comments and whitespace). Returns the location
+/// immediately after the specified token. If the token is not found or the
+/// location is inside a macro, the returned source location will be invalid.
+SourceLocation Lexer::findLocationAfterToken(
+ SourceLocation Loc, tok::TokenKind TKind, const SourceManager &SM,
+ const LangOptions &LangOpts, bool SkipTrailingWhitespaceAndNewLine) {
+ Optional<Token> Tok = findNextToken(Loc, SM, LangOpts);
+ if (!Tok || Tok->isNot(TKind))
return SourceLocation();
- SourceLocation TokenLoc = Tok.getLocation();
+ SourceLocation TokenLoc = Tok->getLocation();
// Calculate how much whitespace needs to be skipped if any.
unsigned NumWhitespaceChars = 0;
if (SkipTrailingWhitespaceAndNewLine) {
- const char *TokenEnd = SM.getCharacterData(TokenLoc) +
- Tok.getLength();
+ const char *TokenEnd = SM.getCharacterData(TokenLoc) + Tok->getLength();
unsigned char C = *TokenEnd;
while (isHorizontalWhitespace(C)) {
C = *(++TokenEnd);
@@ -1269,7 +1273,7 @@ SourceLocation Lexer::findLocationAfterToken(SourceLocation Loc,
}
}
- return TokenLoc.getLocWithOffset(Tok.getLength() + NumWhitespaceChars);
+ return TokenLoc.getLocWithOffset(Tok->getLength() + NumWhitespaceChars);
}
/// getCharAndSizeSlow - Peek a single 'character' from the specified buffer,
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index f9a97505bf..ca3e70fd10 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -350,7 +350,7 @@ void Preprocessor::CheckEndOfDirective(const char *DirType, bool EnableMacros) {
/// If ElseOk is true, then \#else directives are ok, if not, then we have
/// already seen one so a \#else directive is a duplicate. When this returns,
/// the caller can lex the first valid token.
-void Preprocessor::SkipExcludedConditionalBlock(const Token &HashToken,
+void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
SourceLocation IfTokenLoc,
bool FoundNonSkipPortion,
bool FoundElse,
@@ -358,8 +358,11 @@ void Preprocessor::SkipExcludedConditionalBlock(const Token &HashToken,
++NumSkipped;
assert(!CurTokenLexer && CurPPLexer && "Lexing a macro, not a file?");
- CurPPLexer->pushConditionalLevel(IfTokenLoc, /*isSkipping*/false,
- FoundNonSkipPortion, FoundElse);
+ if (PreambleConditionalStack.reachedEOFWhileSkipping())
+ PreambleConditionalStack.clearSkipInfo();
+ else
+ CurPPLexer->pushConditionalLevel(IfTokenLoc, /*isSkipping*/ false,
+ FoundNonSkipPortion, FoundElse);
if (CurPTHLexer) {
PTHSkipExcludedConditionalBlock();
@@ -385,6 +388,9 @@ void Preprocessor::SkipExcludedConditionalBlock(const Token &HashToken,
// We don't emit errors for unterminated conditionals here,
// Lexer::LexEndOfFile can do that propertly.
// Just return and let the caller lex after this #include.
+ if (PreambleConditionalStack.isRecording())
+ PreambleConditionalStack.SkipInfo.emplace(
+ HashTokenLoc, IfTokenLoc, FoundNonSkipPortion, FoundElse, ElseLoc);
break;
}
@@ -554,7 +560,7 @@ void Preprocessor::SkipExcludedConditionalBlock(const Token &HashToken,
if (Callbacks)
Callbacks->SourceRangeSkipped(
- SourceRange(HashToken.getLocation(), CurPPLexer->getSourceLocation()),
+ SourceRange(HashTokenLoc, CurPPLexer->getSourceLocation()),
Tok.getLocation());
}
@@ -2676,7 +2682,8 @@ void Preprocessor::HandleIfdefDirective(Token &Result,
if (MacroNameTok.is(tok::eod)) {
// Skip code until we get to #endif. This helps with recovery by not
// emitting an error when the #endif is reached.
- SkipExcludedConditionalBlock(HashToken, DirectiveTok.getLocation(),
+ SkipExcludedConditionalBlock(HashToken.getLocation(),
+ DirectiveTok.getLocation(),
/*Foundnonskip*/ false, /*FoundElse*/ false);
return;
}
@@ -2725,7 +2732,8 @@ void Preprocessor::HandleIfdefDirective(Token &Result,
/*foundelse*/false);
} else {
// No, skip the contents of this block.
- SkipExcludedConditionalBlock(HashToken, DirectiveTok.getLocation(),
+ SkipExcludedConditionalBlock(HashToken.getLocation(),
+ DirectiveTok.getLocation(),
/*Foundnonskip*/ false,
/*FoundElse*/ false);
}
@@ -2772,7 +2780,7 @@ void Preprocessor::HandleIfDirective(Token &IfToken,
/*foundnonskip*/true, /*foundelse*/false);
} else {
// No, skip the contents of this block.
- SkipExcludedConditionalBlock(HashToken, IfToken.getLocation(),
+ SkipExcludedConditionalBlock(HashToken.getLocation(), IfToken.getLocation(),
/*Foundnonskip*/ false,
/*FoundElse*/ false);
}
@@ -2837,7 +2845,8 @@ void Preprocessor::HandleElseDirective(Token &Result, const Token &HashToken) {
}
// Finally, skip the rest of the contents of this block.
- SkipExcludedConditionalBlock(HashToken, CI.IfLoc, /*Foundnonskip*/ true,
+ SkipExcludedConditionalBlock(HashToken.getLocation(), CI.IfLoc,
+ /*Foundnonskip*/ true,
/*FoundElse*/ true, Result.getLocation());
}
@@ -2881,7 +2890,7 @@ void Preprocessor::HandleElifDirective(Token &ElifToken,
}
// Finally, skip the rest of the contents of this block.
- SkipExcludedConditionalBlock(HashToken, CI.IfLoc, /*Foundnonskip*/ true,
- /*FoundElse*/ CI.FoundElse,
- ElifToken.getLocation());
+ SkipExcludedConditionalBlock(
+ HashToken.getLocation(), CI.IfLoc, /*Foundnonskip*/ true,
+ /*FoundElse*/ CI.FoundElse, ElifToken.getLocation());
}
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index b0330f2881..9f0c88dd97 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -1138,6 +1138,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
.Case("dataflow_sanitizer", LangOpts.Sanitize.has(SanitizerKind::DataFlow))
.Case("efficiency_sanitizer",
LangOpts.Sanitize.hasOneOf(SanitizerKind::Efficiency))
+ .Case("scudo", LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
// Objective-C features
.Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
.Case("objc_arc", LangOpts.ObjCAutoRefCount)
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 65df6a57f1..d80899de8f 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -550,6 +550,13 @@ void Preprocessor::replayPreambleConditionalStack() {
"CurPPLexer is null when calling replayPreambleConditionalStack.");
CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack());
PreambleConditionalStack.doneReplaying();
+ if (PreambleConditionalStack.reachedEOFWhileSkipping())
+ SkipExcludedConditionalBlock(
+ PreambleConditionalStack.SkipInfo->HashTokenLoc,
+ PreambleConditionalStack.SkipInfo->IfTokenLoc,
+ PreambleConditionalStack.SkipInfo->FoundNonSkipPortion,
+ PreambleConditionalStack.SkipInfo->FoundElse,
+ PreambleConditionalStack.SkipInfo->ElseLoc);
}
}