summaryrefslogtreecommitdiff
path: root/lib/Lex/PPDirectives.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Lex/PPDirectives.cpp')
-rw-r--r--lib/Lex/PPDirectives.cpp38
1 files changed, 33 insertions, 5 deletions
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 89c2ebd00a683..8c79e50176e18 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -538,7 +538,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
assert(CurPPLexer->LexingRawMode && "We have to be skipping here!");
CurPPLexer->LexingRawMode = false;
IdentifierInfo *IfNDefMacro = nullptr;
- const bool CondValue = EvaluateDirectiveExpression(IfNDefMacro);
+ const bool CondValue = EvaluateDirectiveExpression(IfNDefMacro).Conditional;
CurPPLexer->LexingRawMode = true;
if (Callbacks) {
const SourceLocation CondEnd = CurPPLexer->getSourceLocation();
@@ -635,7 +635,7 @@ void Preprocessor::PTHSkipExcludedConditionalBlock() {
// Evaluate the condition of the #elif.
IdentifierInfo *IfNDefMacro = nullptr;
CurPTHLexer->ParsingPreprocessorDirective = true;
- bool ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro);
+ bool ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro).Conditional;
CurPTHLexer->ParsingPreprocessorDirective = false;
// If this condition is true, enter it!
@@ -2654,7 +2654,13 @@ void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef,
}
// Should we include the stuff contained by this directive?
- if (!MI == isIfndef) {
+ if (PPOpts->SingleFileParseMode && !MI) {
+ // In 'single-file-parse mode' undefined identifiers trigger parsing of all
+ // the directive blocks.
+ CurPPLexer->pushConditionalLevel(DirectiveTok.getLocation(),
+ /*wasskip*/false, /*foundnonskip*/false,
+ /*foundelse*/false);
+ } else if (!MI == isIfndef) {
// Yes, remember that we are inside a conditional, then lex the next token.
CurPPLexer->pushConditionalLevel(DirectiveTok.getLocation(),
/*wasskip*/false, /*foundnonskip*/true,
@@ -2676,7 +2682,8 @@ void Preprocessor::HandleIfDirective(Token &IfToken,
// Parse and evaluate the conditional expression.
IdentifierInfo *IfNDefMacro = nullptr;
const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation();
- const bool ConditionalTrue = EvaluateDirectiveExpression(IfNDefMacro);
+ const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
+ const bool ConditionalTrue = DER.Conditional;
const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation();
// If this condition is equivalent to #ifndef X, and if this is the first
@@ -2695,7 +2702,12 @@ void Preprocessor::HandleIfDirective(Token &IfToken,
(ConditionalTrue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False));
// Should we include the stuff contained by this directive?
- if (ConditionalTrue) {
+ if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
+ // In 'single-file-parse mode' undefined identifiers trigger parsing of all
+ // the directive blocks.
+ CurPPLexer->pushConditionalLevel(IfToken.getLocation(), /*wasskip*/false,
+ /*foundnonskip*/false, /*foundelse*/false);
+ } else if (ConditionalTrue) {
// Yes, remember that we are inside a conditional, then lex the next token.
CurPPLexer->pushConditionalLevel(IfToken.getLocation(), /*wasskip*/false,
/*foundnonskip*/true, /*foundelse*/false);
@@ -2756,6 +2768,14 @@ void Preprocessor::HandleElseDirective(Token &Result) {
if (Callbacks)
Callbacks->Else(Result.getLocation(), CI.IfLoc);
+ if (PPOpts->SingleFileParseMode && !CI.FoundNonSkip) {
+ // In 'single-file-parse mode' undefined identifiers trigger parsing of all
+ // the directive blocks.
+ CurPPLexer->pushConditionalLevel(CI.IfLoc, /*wasskip*/false,
+ /*foundnonskip*/false, /*foundelse*/true);
+ return;
+ }
+
// Finally, skip the rest of the contents of this block.
SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true,
/*FoundElse*/true, Result.getLocation());
@@ -2791,6 +2811,14 @@ void Preprocessor::HandleElifDirective(Token &ElifToken) {
SourceRange(ConditionalBegin, ConditionalEnd),
PPCallbacks::CVK_NotEvaluated, CI.IfLoc);
+ if (PPOpts->SingleFileParseMode && !CI.FoundNonSkip) {
+ // In 'single-file-parse mode' undefined identifiers trigger parsing of all
+ // the directive blocks.
+ CurPPLexer->pushConditionalLevel(ElifToken.getLocation(), /*wasskip*/false,
+ /*foundnonskip*/false, /*foundelse*/false);
+ return;
+ }
+
// Finally, skip the rest of the contents of this block.
SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true,
/*FoundElse*/CI.FoundElse,