Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
cfe/trunk/lib/Lex/PPDirectives.cpp
Show First 20 Lines • Show All 881 Lines • ▼ Show 20 Lines | ~ResetMacroExpansionHelper() { | ||||
PP->DisableMacroExpansion = save; | PP->DisableMacroExpansion = save; | ||||
} | } | ||||
private: | private: | ||||
Preprocessor *PP; | Preprocessor *PP; | ||||
bool save; | bool save; | ||||
}; | }; | ||||
/// Process a directive while looking for the through header. | |||||
/// Only #include (to check if it is the through header) and #define (to warn | |||||
/// about macros that don't match the PCH) are handled. All other directives | |||||
/// are completely discarded. | |||||
void Preprocessor::HandleSkippedThroughHeaderDirective(Token &Result, | |||||
SourceLocation HashLoc) { | |||||
if (const IdentifierInfo *II = Result.getIdentifierInfo()) { | |||||
if (II->getPPKeywordID() == tok::pp_include) | |||||
return HandleIncludeDirective(HashLoc, Result); | |||||
if (II->getPPKeywordID() == tok::pp_define) | |||||
return HandleDefineDirective(Result, | |||||
/*ImmediatelyAfterHeaderGuard=*/false); | |||||
} | |||||
DiscardUntilEndOfDirective(); | |||||
} | |||||
/// HandleDirective - This callback is invoked when the lexer sees a # token | /// HandleDirective - This callback is invoked when the lexer sees a # token | ||||
/// at the start of a line. This consumes the directive, modifies the | /// at the start of a line. This consumes the directive, modifies the | ||||
/// lexer/preprocessor state, and advances the lexer(s) so that the next token | /// lexer/preprocessor state, and advances the lexer(s) so that the next token | ||||
/// read is the correct one. | /// read is the correct one. | ||||
void Preprocessor::HandleDirective(Token &Result) { | void Preprocessor::HandleDirective(Token &Result) { | ||||
// FIXME: Traditional: # with whitespace before it not recognized by K&R? | // FIXME: Traditional: # with whitespace before it not recognized by K&R? | ||||
// We just parsed a # character at the start of a line, so we're in directive | // We just parsed a # character at the start of a line, so we're in directive | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | if (InMacroArgs) { | ||||
} | } | ||||
Diag(Result, diag::ext_embedded_directive); | Diag(Result, diag::ext_embedded_directive); | ||||
} | } | ||||
// Temporarily enable macro expansion if set so | // Temporarily enable macro expansion if set so | ||||
// and reset to previous state when returning from this function. | // and reset to previous state when returning from this function. | ||||
ResetMacroExpansionHelper helper(this); | ResetMacroExpansionHelper helper(this); | ||||
if (SkippingUntilPCHThroughHeader) | |||||
return HandleSkippedThroughHeaderDirective(Result, SavedHash.getLocation()); | |||||
switch (Result.getKind()) { | switch (Result.getKind()) { | ||||
case tok::eod: | case tok::eod: | ||||
return; // null directive. | return; // null directive. | ||||
case tok::code_completion: | case tok::code_completion: | ||||
if (CodeComplete) | if (CodeComplete) | ||||
CodeComplete->CodeCompleteDirective( | CodeComplete->CodeCompleteDirective( | ||||
CurPPLexer->getConditionalStackDepth() > 0); | CurPPLexer->getConditionalStackDepth() > 0); | ||||
setCodeCompletionReached(); | setCodeCompletionReached(); | ||||
▲ Show 20 Lines • Show All 898 Lines • ▼ Show 20 Lines | if (!SuppressIncludeNotFoundError) { | ||||
// If the file is still not found, just go with the vanilla diagnostic | // If the file is still not found, just go with the vanilla diagnostic | ||||
if (!File) | if (!File) | ||||
Diag(FilenameTok, diag::err_pp_file_not_found) << Filename | Diag(FilenameTok, diag::err_pp_file_not_found) << Filename | ||||
<< FilenameRange; | << FilenameRange; | ||||
} | } | ||||
} | } | ||||
if (usingPCHWithThroughHeader() && SkippingUntilPCHThroughHeader) { | |||||
if (isPCHThroughHeader(File)) | |||||
SkippingUntilPCHThroughHeader = false; | |||||
return; | |||||
} | |||||
// Should we enter the source file? Set to false if either the source file is | // Should we enter the source file? Set to false if either the source file is | ||||
// known to have no effect beyond its effect on module visibility -- that is, | // known to have no effect beyond its effect on module visibility -- that is, | ||||
// if it's got an include guard that is already defined or is a modular header | // if it's got an include guard that is already defined or is a modular header | ||||
// we've imported or already built. | // we've imported or already built. | ||||
bool ShouldEnter = true; | bool ShouldEnter = true; | ||||
if (PPOpts->SingleFileParseMode) | if (PPOpts->SingleFileParseMode) | ||||
ShouldEnter = false; | ShouldEnter = false; | ||||
▲ Show 20 Lines • Show All 709 Lines • ▼ Show 20 Lines | if (MI->getReplacementToken(0).is(tok::hashhash)) { | ||||
return; | return; | ||||
} | } | ||||
if (MI->getReplacementToken(NumTokens-1).is(tok::hashhash)) { | if (MI->getReplacementToken(NumTokens-1).is(tok::hashhash)) { | ||||
Diag(MI->getReplacementToken(NumTokens-1), diag::err_paste_at_end); | Diag(MI->getReplacementToken(NumTokens-1), diag::err_paste_at_end); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
// When skipping just warn about macros that do not match. | |||||
if (SkippingUntilPCHThroughHeader) { | |||||
const MacroInfo *OtherMI = getMacroInfo(MacroNameTok.getIdentifierInfo()); | |||||
if (!OtherMI || !MI->isIdenticalTo(*OtherMI, *this, | |||||
/*Syntactic=*/LangOpts.MicrosoftExt)) | |||||
Diag(MI->getDefinitionLoc(), diag::warn_pp_macro_def_mismatch_with_pch) | |||||
<< MacroNameTok.getIdentifierInfo(); | |||||
return; | |||||
} | |||||
// Finally, if this identifier already had a macro defined for it, verify that | // Finally, if this identifier already had a macro defined for it, verify that | ||||
// the macro bodies are identical, and issue diagnostics if they are not. | // the macro bodies are identical, and issue diagnostics if they are not. | ||||
if (const MacroInfo *OtherMI=getMacroInfo(MacroNameTok.getIdentifierInfo())) { | if (const MacroInfo *OtherMI=getMacroInfo(MacroNameTok.getIdentifierInfo())) { | ||||
// In Objective-C, ignore attempts to directly redefine the builtin | // In Objective-C, ignore attempts to directly redefine the builtin | ||||
// definitions of the ownership qualifiers. It's still possible to | // definitions of the ownership qualifiers. It's still possible to | ||||
// #undef them. | // #undef them. | ||||
auto isObjCProtectedMacro = [](const IdentifierInfo *II) -> bool { | auto isObjCProtectedMacro = [](const IdentifierInfo *II) -> bool { | ||||
▲ Show 20 Lines • Show All 337 Lines • Show Last 20 Lines |