|
@@ -76,24 +76,24 @@ Preprocessor::AllocateVisibilityMacroDirective(SourceLocation Loc,
|
|
|
bool isPublic) {
|
|
|
return new (BP) VisibilityMacroDirective(Loc, isPublic);
|
|
|
}
|
|
|
-
|
|
|
-/// Read and discard all tokens remaining on the current line until
|
|
|
-/// the tok::eod token is found.
|
|
|
-SourceRange Preprocessor::DiscardUntilEndOfDirective() {
|
|
|
- Token Tmp;
|
|
|
- SourceRange Res;
|
|
|
-
|
|
|
- LexUnexpandedToken(Tmp);
|
|
|
- Res.setBegin(Tmp.getLocation());
|
|
|
- while (Tmp.isNot(tok::eod)) {
|
|
|
- assert(Tmp.isNot(tok::eof) && "EOF seen while discarding directive tokens");
|
|
|
- LexUnexpandedToken(Tmp);
|
|
|
- }
|
|
|
- Res.setEnd(Tmp.getLocation());
|
|
|
- return Res;
|
|
|
-}
|
|
|
-
|
|
|
-/// Enumerates possible cases of #define/#undef a reserved identifier.
|
|
|
+
|
|
|
+/// Read and discard all tokens remaining on the current line until
|
|
|
+/// the tok::eod token is found.
|
|
|
+SourceRange Preprocessor::DiscardUntilEndOfDirective() {
|
|
|
+ Token Tmp;
|
|
|
+ SourceRange Res;
|
|
|
+
|
|
|
+ LexUnexpandedToken(Tmp);
|
|
|
+ Res.setBegin(Tmp.getLocation());
|
|
|
+ while (Tmp.isNot(tok::eod)) {
|
|
|
+ assert(Tmp.isNot(tok::eof) && "EOF seen while discarding directive tokens");
|
|
|
+ LexUnexpandedToken(Tmp);
|
|
|
+ }
|
|
|
+ Res.setEnd(Tmp.getLocation());
|
|
|
+ return Res;
|
|
|
+}
|
|
|
+
|
|
|
+/// Enumerates possible cases of #define/#undef a reserved identifier.
|
|
|
enum MacroDiag {
|
|
|
MD_NoWarn, //> Not a reserved identifier
|
|
|
MD_KeywordDef, //> Macro hides keyword, enabled by default
|
|
@@ -541,25 +541,25 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
|
|
|
|
|
|
// If this is in a skipping block or if we're already handled this #if
|
|
|
// block, don't bother parsing the condition.
|
|
|
- if (CondInfo.WasSkipping || CondInfo.FoundNonSkip) {
|
|
|
- DiscardUntilEndOfDirective();
|
|
|
- } else {
|
|
|
- // Restore the value of LexingRawMode so that identifiers are
|
|
|
- // looked up, etc, inside the #elif expression.
|
|
|
- assert(CurPPLexer->LexingRawMode && "We have to be skipping here!");
|
|
|
- CurPPLexer->LexingRawMode = false;
|
|
|
- IdentifierInfo *IfNDefMacro = nullptr;
|
|
|
- DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
|
|
|
- const bool CondValue = DER.Conditional;
|
|
|
- CurPPLexer->LexingRawMode = true;
|
|
|
- if (Callbacks) {
|
|
|
- Callbacks->Elif(
|
|
|
- Tok.getLocation(), DER.ExprRange,
|
|
|
- (CondValue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False),
|
|
|
- CondInfo.IfLoc);
|
|
|
- }
|
|
|
- // If this condition is true, enter it!
|
|
|
- if (CondValue) {
|
|
|
+ if (CondInfo.WasSkipping || CondInfo.FoundNonSkip) {
|
|
|
+ DiscardUntilEndOfDirective();
|
|
|
+ } else {
|
|
|
+ // Restore the value of LexingRawMode so that identifiers are
|
|
|
+ // looked up, etc, inside the #elif expression.
|
|
|
+ assert(CurPPLexer->LexingRawMode && "We have to be skipping here!");
|
|
|
+ CurPPLexer->LexingRawMode = false;
|
|
|
+ IdentifierInfo *IfNDefMacro = nullptr;
|
|
|
+ DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
|
|
|
+ const bool CondValue = DER.Conditional;
|
|
|
+ CurPPLexer->LexingRawMode = true;
|
|
|
+ if (Callbacks) {
|
|
|
+ Callbacks->Elif(
|
|
|
+ Tok.getLocation(), DER.ExprRange,
|
|
|
+ (CondValue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False),
|
|
|
+ CondInfo.IfLoc);
|
|
|
+ }
|
|
|
+ // If this condition is true, enter it!
|
|
|
+ if (CondValue) {
|
|
|
CondInfo.FoundNonSkip = true;
|
|
|
break;
|
|
|
}
|
|
@@ -1119,30 +1119,30 @@ void Preprocessor::HandleLineDirective() {
|
|
|
// If the StrTok is "eod", then it wasn't present. Otherwise, it must be a
|
|
|
// string followed by eod.
|
|
|
if (StrTok.is(tok::eod))
|
|
|
- ; // ok
|
|
|
- else if (StrTok.isNot(tok::string_literal)) {
|
|
|
- Diag(StrTok, diag::err_pp_line_invalid_filename);
|
|
|
- DiscardUntilEndOfDirective();
|
|
|
- return;
|
|
|
- } else if (StrTok.hasUDSuffix()) {
|
|
|
- Diag(StrTok, diag::err_invalid_string_udl);
|
|
|
- DiscardUntilEndOfDirective();
|
|
|
- return;
|
|
|
- } else {
|
|
|
- // Parse and validate the string, converting it into a unique ID.
|
|
|
- StringLiteralParser Literal(StrTok, *this);
|
|
|
- assert(Literal.isAscii() && "Didn't allow wide strings in");
|
|
|
- if (Literal.hadError) {
|
|
|
- DiscardUntilEndOfDirective();
|
|
|
- return;
|
|
|
- }
|
|
|
- if (Literal.Pascal) {
|
|
|
- Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
|
|
|
- DiscardUntilEndOfDirective();
|
|
|
- return;
|
|
|
- }
|
|
|
- FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString());
|
|
|
-
|
|
|
+ ; // ok
|
|
|
+ else if (StrTok.isNot(tok::string_literal)) {
|
|
|
+ Diag(StrTok, diag::err_pp_line_invalid_filename);
|
|
|
+ DiscardUntilEndOfDirective();
|
|
|
+ return;
|
|
|
+ } else if (StrTok.hasUDSuffix()) {
|
|
|
+ Diag(StrTok, diag::err_invalid_string_udl);
|
|
|
+ DiscardUntilEndOfDirective();
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ // Parse and validate the string, converting it into a unique ID.
|
|
|
+ StringLiteralParser Literal(StrTok, *this);
|
|
|
+ assert(Literal.isAscii() && "Didn't allow wide strings in");
|
|
|
+ if (Literal.hadError) {
|
|
|
+ DiscardUntilEndOfDirective();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (Literal.Pascal) {
|
|
|
+ Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
|
|
|
+ DiscardUntilEndOfDirective();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString());
|
|
|
+
|
|
|
// Verify that there is nothing after the string, other than EOD. Because
|
|
|
// of C99 6.10.4p5, macros that expand to empty tokens are ok.
|
|
|
CheckEndOfDirective("line", true);
|
|
@@ -1269,30 +1269,30 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) {
|
|
|
// string followed by eod.
|
|
|
if (StrTok.is(tok::eod)) {
|
|
|
// Treat this like "#line NN", which doesn't change file characteristics.
|
|
|
- FileKind = SourceMgr.getFileCharacteristic(DigitTok.getLocation());
|
|
|
- } else if (StrTok.isNot(tok::string_literal)) {
|
|
|
- Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
|
|
|
- DiscardUntilEndOfDirective();
|
|
|
- return;
|
|
|
- } else if (StrTok.hasUDSuffix()) {
|
|
|
- Diag(StrTok, diag::err_invalid_string_udl);
|
|
|
- DiscardUntilEndOfDirective();
|
|
|
- return;
|
|
|
- } else {
|
|
|
- // Parse and validate the string, converting it into a unique ID.
|
|
|
- StringLiteralParser Literal(StrTok, *this);
|
|
|
- assert(Literal.isAscii() && "Didn't allow wide strings in");
|
|
|
- if (Literal.hadError) {
|
|
|
- DiscardUntilEndOfDirective();
|
|
|
- return;
|
|
|
- }
|
|
|
- if (Literal.Pascal) {
|
|
|
- Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
|
|
|
- DiscardUntilEndOfDirective();
|
|
|
- return;
|
|
|
- }
|
|
|
- FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString());
|
|
|
-
|
|
|
+ FileKind = SourceMgr.getFileCharacteristic(DigitTok.getLocation());
|
|
|
+ } else if (StrTok.isNot(tok::string_literal)) {
|
|
|
+ Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
|
|
|
+ DiscardUntilEndOfDirective();
|
|
|
+ return;
|
|
|
+ } else if (StrTok.hasUDSuffix()) {
|
|
|
+ Diag(StrTok, diag::err_invalid_string_udl);
|
|
|
+ DiscardUntilEndOfDirective();
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ // Parse and validate the string, converting it into a unique ID.
|
|
|
+ StringLiteralParser Literal(StrTok, *this);
|
|
|
+ assert(Literal.isAscii() && "Didn't allow wide strings in");
|
|
|
+ if (Literal.hadError) {
|
|
|
+ DiscardUntilEndOfDirective();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (Literal.Pascal) {
|
|
|
+ Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
|
|
|
+ DiscardUntilEndOfDirective();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString());
|
|
|
+
|
|
|
// If a filename was present, read any flags that are present.
|
|
|
if (ReadLineMarkerFlags(IsFileEntry, IsFileExit, FileKind, *this))
|
|
|
return;
|
|
@@ -1356,14 +1356,14 @@ void Preprocessor::HandleIdentSCCSDirective(Token &Tok) {
|
|
|
DiscardUntilEndOfDirective();
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
- if (StrTok.hasUDSuffix()) {
|
|
|
- Diag(StrTok, diag::err_invalid_string_udl);
|
|
|
- DiscardUntilEndOfDirective();
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // Verify that there is nothing after the string, other than EOD.
|
|
|
+
|
|
|
+ if (StrTok.hasUDSuffix()) {
|
|
|
+ Diag(StrTok, diag::err_invalid_string_udl);
|
|
|
+ DiscardUntilEndOfDirective();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Verify that there is nothing after the string, other than EOD.
|
|
|
CheckEndOfDirective("ident");
|
|
|
|
|
|
if (Callbacks) {
|
|
@@ -2805,29 +2805,29 @@ void Preprocessor::HandleIfDirective(Token &IfToken,
|
|
|
const Token &HashToken,
|
|
|
bool ReadAnyTokensBeforeDirective) {
|
|
|
++NumIf;
|
|
|
-
|
|
|
- // Parse and evaluate the conditional expression.
|
|
|
- IdentifierInfo *IfNDefMacro = nullptr;
|
|
|
- const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
|
|
|
- const bool ConditionalTrue = DER.Conditional;
|
|
|
-
|
|
|
- // If this condition is equivalent to #ifndef X, and if this is the first
|
|
|
- // directive seen, handle it for the multiple-include optimization.
|
|
|
+
|
|
|
+ // Parse and evaluate the conditional expression.
|
|
|
+ IdentifierInfo *IfNDefMacro = nullptr;
|
|
|
+ const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
|
|
|
+ const bool ConditionalTrue = DER.Conditional;
|
|
|
+
|
|
|
+ // If this condition is equivalent to #ifndef X, and if this is the first
|
|
|
+ // directive seen, handle it for the multiple-include optimization.
|
|
|
if (CurPPLexer->getConditionalStackDepth() == 0) {
|
|
|
if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)
|
|
|
// FIXME: Pass in the location of the macro name, not the 'if' token.
|
|
|
CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.getLocation());
|
|
|
else
|
|
|
CurPPLexer->MIOpt.EnterTopLevelConditional();
|
|
|
- }
|
|
|
-
|
|
|
- if (Callbacks)
|
|
|
- Callbacks->If(
|
|
|
- IfToken.getLocation(), DER.ExprRange,
|
|
|
- (ConditionalTrue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False));
|
|
|
-
|
|
|
- // Should we include the stuff contained by this directive?
|
|
|
- if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Callbacks)
|
|
|
+ Callbacks->If(
|
|
|
+ IfToken.getLocation(), DER.ExprRange,
|
|
|
+ (ConditionalTrue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False));
|
|
|
+
|
|
|
+ // Should we include the stuff contained by this directive?
|
|
|
+ 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,
|
|
@@ -2914,13 +2914,13 @@ void Preprocessor::HandleElifDirective(Token &ElifToken,
|
|
|
const Token &HashToken) {
|
|
|
++NumElse;
|
|
|
|
|
|
- // #elif directive in a non-skipping conditional... start skipping.
|
|
|
- // We don't care what the condition is, because we will always skip it (since
|
|
|
- // the block immediately before it was included).
|
|
|
- SourceRange ConditionRange = DiscardUntilEndOfDirective();
|
|
|
-
|
|
|
- PPConditionalInfo CI;
|
|
|
- if (CurPPLexer->popConditionalLevel(CI)) {
|
|
|
+ // #elif directive in a non-skipping conditional... start skipping.
|
|
|
+ // We don't care what the condition is, because we will always skip it (since
|
|
|
+ // the block immediately before it was included).
|
|
|
+ SourceRange ConditionRange = DiscardUntilEndOfDirective();
|
|
|
+
|
|
|
+ PPConditionalInfo CI;
|
|
|
+ if (CurPPLexer->popConditionalLevel(CI)) {
|
|
|
Diag(ElifToken, diag::pp_err_elif_without_if);
|
|
|
return;
|
|
|
}
|
|
@@ -2930,13 +2930,13 @@ void Preprocessor::HandleElifDirective(Token &ElifToken,
|
|
|
CurPPLexer->MIOpt.EnterTopLevelConditional();
|
|
|
|
|
|
// If this is a #elif with a #else before it, report the error.
|
|
|
- if (CI.FoundElse) Diag(ElifToken, diag::pp_err_elif_after_else);
|
|
|
-
|
|
|
- if (Callbacks)
|
|
|
- Callbacks->Elif(ElifToken.getLocation(), ConditionRange,
|
|
|
- PPCallbacks::CVK_NotEvaluated, CI.IfLoc);
|
|
|
-
|
|
|
- if (PPOpts->SingleFileParseMode && !CI.FoundNonSkip) {
|
|
|
+ if (CI.FoundElse) Diag(ElifToken, diag::pp_err_elif_after_else);
|
|
|
+
|
|
|
+ if (Callbacks)
|
|
|
+ Callbacks->Elif(ElifToken.getLocation(), ConditionRange,
|
|
|
+ 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,
|