Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
cfe/trunk/lib/Lex/Preprocessor.cpp
Show First 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts, | ||||
} else { | } else { | ||||
Ident__exception_info = Ident__exception_code = nullptr; | Ident__exception_info = Ident__exception_code = nullptr; | ||||
Ident__abnormal_termination = Ident___exception_info = nullptr; | Ident__abnormal_termination = Ident___exception_info = nullptr; | ||||
Ident___exception_code = Ident___abnormal_termination = nullptr; | Ident___exception_code = Ident___abnormal_termination = nullptr; | ||||
Ident_GetExceptionInfo = Ident_GetExceptionCode = nullptr; | Ident_GetExceptionInfo = Ident_GetExceptionCode = nullptr; | ||||
Ident_AbnormalTermination = nullptr; | Ident_AbnormalTermination = nullptr; | ||||
} | } | ||||
// If using a PCH with a through header, start skipping tokens. | |||||
if (!this->PPOpts->PCHThroughHeader.empty() && | |||||
!this->PPOpts->ImplicitPCHInclude.empty()) | |||||
SkippingUntilPCHThroughHeader = true; | |||||
if (this->PPOpts->GeneratePreamble) | if (this->PPOpts->GeneratePreamble) | ||||
PreambleConditionalStack.startRecording(); | PreambleConditionalStack.startRecording(); | ||||
} | } | ||||
Preprocessor::~Preprocessor() { | Preprocessor::~Preprocessor() { | ||||
assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!"); | assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!"); | ||||
IncludeMacroStack.clear(); | IncludeMacroStack.clear(); | ||||
▲ Show 20 Lines • Show All 386 Lines • ▼ Show 20 Lines | std::unique_ptr<llvm::MemoryBuffer> SB = | ||||
llvm::MemoryBuffer::getMemBufferCopy(Predefines, "<built-in>"); | llvm::MemoryBuffer::getMemBufferCopy(Predefines, "<built-in>"); | ||||
assert(SB && "Cannot create predefined source buffer"); | assert(SB && "Cannot create predefined source buffer"); | ||||
FileID FID = SourceMgr.createFileID(std::move(SB)); | FileID FID = SourceMgr.createFileID(std::move(SB)); | ||||
assert(FID.isValid() && "Could not create FileID for predefines?"); | assert(FID.isValid() && "Could not create FileID for predefines?"); | ||||
setPredefinesFileID(FID); | setPredefinesFileID(FID); | ||||
// Start parsing the predefines. | // Start parsing the predefines. | ||||
EnterSourceFile(FID, nullptr, SourceLocation()); | EnterSourceFile(FID, nullptr, SourceLocation()); | ||||
if (!PPOpts->PCHThroughHeader.empty()) { | |||||
// Lookup and save the FileID for the through header. If it isn't found | |||||
// in the search path, it's a fatal error. | |||||
const DirectoryLookup *CurDir; | |||||
const FileEntry *File = LookupFile( | |||||
SourceLocation(), PPOpts->PCHThroughHeader, | |||||
/*isAngled=*/false, /*FromDir=*/nullptr, /*FromFile=*/nullptr, CurDir, | |||||
/*SearchPath=*/nullptr, /*RelativePath=*/nullptr, | |||||
/*SuggestedModule=*/nullptr, /*IsMapped=*/nullptr); | |||||
if (!File) { | |||||
Diag(SourceLocation(), diag::err_pp_through_header_not_found) | |||||
<< PPOpts->PCHThroughHeader; | |||||
return; | |||||
} | |||||
setPCHThroughHeaderFileID( | |||||
SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User)); | |||||
} | |||||
// Skip tokens from the Predefines and if needed the main file. | |||||
if (usingPCHWithThroughHeader() && SkippingUntilPCHThroughHeader) | |||||
SkipTokensUntilPCHThroughHeader(); | |||||
} | |||||
void Preprocessor::setPCHThroughHeaderFileID(FileID FID) { | |||||
assert(PCHThroughHeaderFileID.isInvalid() && | |||||
"PCHThroughHeaderFileID already set!"); | |||||
PCHThroughHeaderFileID = FID; | |||||
} | |||||
bool Preprocessor::isPCHThroughHeader(const FileEntry *FE) { | |||||
assert(PCHThroughHeaderFileID.isValid() && | |||||
"Invalid PCH through header FileID"); | |||||
return FE == SourceMgr.getFileEntryForID(PCHThroughHeaderFileID); | |||||
} | |||||
bool Preprocessor::creatingPCHWithThroughHeader() { | |||||
return TUKind == TU_Prefix && !PPOpts->PCHThroughHeader.empty() && | |||||
PCHThroughHeaderFileID.isValid(); | |||||
} | |||||
bool Preprocessor::usingPCHWithThroughHeader() { | |||||
return TUKind != TU_Prefix && !PPOpts->PCHThroughHeader.empty() && | |||||
PCHThroughHeaderFileID.isValid(); | |||||
} | |||||
/// Skip tokens until after the #include of the through header. | |||||
/// Tokens in the predefines file and the main file may be skipped. If the end | |||||
/// of the predefines file is reached, skipping continues into the main file. | |||||
/// If the end of the main file is reached, it's a fatal error. | |||||
void Preprocessor::SkipTokensUntilPCHThroughHeader() { | |||||
bool ReachedMainFileEOF = false; | |||||
Token Tok; | |||||
while (true) { | |||||
bool InPredefines = (CurLexer->getFileID() == getPredefinesFileID()); | |||||
CurLexer->Lex(Tok); | |||||
if (Tok.is(tok::eof) && !InPredefines) { | |||||
ReachedMainFileEOF = true; | |||||
break; | |||||
} | |||||
if (!SkippingUntilPCHThroughHeader) | |||||
break; | |||||
} | |||||
if (ReachedMainFileEOF) | |||||
Diag(SourceLocation(), diag::err_pp_through_header_not_seen) | |||||
<< PPOpts->PCHThroughHeader << 1; | |||||
} | } | ||||
void Preprocessor::replayPreambleConditionalStack() { | void Preprocessor::replayPreambleConditionalStack() { | ||||
// Restore the conditional stack from the preamble, if there is one. | // Restore the conditional stack from the preamble, if there is one. | ||||
if (PreambleConditionalStack.isReplaying()) { | if (PreambleConditionalStack.isReplaying()) { | ||||
assert(CurPPLexer && | assert(CurPPLexer && | ||||
"CurPPLexer is null when calling replayPreambleConditionalStack."); | "CurPPLexer is null when calling replayPreambleConditionalStack."); | ||||
CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack()); | CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack()); | ||||
▲ Show 20 Lines • Show All 430 Lines • Show Last 20 Lines |