diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-09-08 19:40:14 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-09-08 19:40:14 +0000 |
commit | 0516b1864d1cf92c497d64a7cd712e47a74396bc (patch) | |
tree | bcbd497228efe85a7dfd92f947438dc9f891f63a /clang/lib/Serialization | |
parent | 966a94f8614266c5b964f185cd2e288fbdeb802f (diff) | |
download | bcm5719-llvm-0516b1864d1cf92c497d64a7cd712e47a74396bc.tar.gz bcm5719-llvm-0516b1864d1cf92c497d64a7cd712e47a74396bc.zip |
[modules] Write the options records to a separate subblock rather than writing
them directly to the control block. These are fairly large, and in a build with
lots of modules / chained PCH, we don't need to read most of them. No
functionality change intended.
llvm-svn: 247055
Diffstat (limited to 'clang/lib/Serialization')
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 280 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 12 |
2 files changed, 160 insertions, 132 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 577a1678941..43d6074120b 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1350,10 +1350,8 @@ SourceLocation ASTReader::getImportLocation(ModuleFile *F) { /// specified cursor. Read the abbreviations that are at the top of the block /// and then leave the cursor pointing into the block. bool ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, unsigned BlockID) { - if (Cursor.EnterSubBlock(BlockID)) { - Error("malformed block record in AST file"); - return Failure; - } + if (Cursor.EnterSubBlock(BlockID)) + return true; while (true) { uint64_t Offset = Cursor.GetCurrentBitNo(); @@ -2059,6 +2057,86 @@ static bool isDiagnosedResult(ASTReader::ASTReadResult ARR, unsigned Caps) { llvm_unreachable("unknown ASTReadResult"); } +ASTReader::ASTReadResult ASTReader::ReadOptionsBlock( + BitstreamCursor &Stream, unsigned ClientLoadCapabilities, + bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener, + std::string &SuggestedPredefines) { + if (Stream.EnterSubBlock(OPTIONS_BLOCK_ID)) + return Failure; + + // Read all of the records in the options block. + RecordData Record; + ASTReadResult Result = Success; + while (1) { + llvm::BitstreamEntry Entry = Stream.advance(); + + switch (Entry.Kind) { + case llvm::BitstreamEntry::Error: + case llvm::BitstreamEntry::SubBlock: + return Failure; + + case llvm::BitstreamEntry::EndBlock: + return Result; + + case llvm::BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read and process a record. + Record.clear(); + switch ((OptionsRecordTypes)Stream.readRecord(Entry.ID, Record)) { + case LANGUAGE_OPTIONS: { + bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; + if (ParseLanguageOptions(Record, Complain, Listener, + AllowCompatibleConfigurationMismatch)) + Result = ConfigurationMismatch; + break; + } + + case TARGET_OPTIONS: { + bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; + if (ParseTargetOptions(Record, Complain, Listener, + AllowCompatibleConfigurationMismatch)) + Result = ConfigurationMismatch; + break; + } + + case DIAGNOSTIC_OPTIONS: { + bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0; + if (!AllowCompatibleConfigurationMismatch && + ParseDiagnosticOptions(Record, Complain, Listener)) + return OutOfDate; + break; + } + + case FILE_SYSTEM_OPTIONS: { + bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; + if (!AllowCompatibleConfigurationMismatch && + ParseFileSystemOptions(Record, Complain, Listener)) + Result = ConfigurationMismatch; + break; + } + + case HEADER_SEARCH_OPTIONS: { + bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; + if (!AllowCompatibleConfigurationMismatch && + ParseHeaderSearchOptions(Record, Complain, Listener)) + Result = ConfigurationMismatch; + break; + } + + case PREPROCESSOR_OPTIONS: + bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; + if (!AllowCompatibleConfigurationMismatch && + ParsePreprocessorOptions(Record, Complain, Listener, + SuggestedPredefines)) + Result = ConfigurationMismatch; + break; + } + } +} + ASTReader::ASTReadResult ASTReader::ReadControlBlock(ModuleFile &F, SmallVectorImpl<ImportedModule> &Loaded, @@ -2071,12 +2149,6 @@ ASTReader::ReadControlBlock(ModuleFile &F, return Failure; } - // Should we allow the configuration of the module file to differ from the - // configuration of the current translation unit in a compatible way? - // - // FIXME: Allow this for files explicitly specified with -include-pch too. - bool AllowCompatibleConfigurationMismatch = F.Kind == MK_ExplicitModule; - // Read all of the records and blocks in the control block. RecordData Record; unsigned NumInputs = 0; @@ -2145,6 +2217,36 @@ ASTReader::ReadControlBlock(ModuleFile &F, return Failure; } continue; + + case OPTIONS_BLOCK_ID: + // If we're reading the first module for this group, check its options + // are compatible with ours. For modules it imports, no further checking + // is required, because we checked them when we built it. + if (Listener && !ImportedBy) { + // Should we allow the configuration of the module file to differ from + // the configuration of the current translation unit in a compatible + // way? + // + // FIXME: Allow this for files explicitly specified with -include-pch. + bool AllowCompatibleConfigurationMismatch = + F.Kind == MK_ExplicitModule; + + auto Result = ReadOptionsBlock(Stream, ClientLoadCapabilities, + AllowCompatibleConfigurationMismatch, + *Listener, SuggestedPredefines); + if (Result == Failure) { + Error("malformed block record in AST file"); + return Result; + } + + if (!DisableValidation && Result != Success && + (Result != ConfigurationMismatch || !AllowConfigurationMismatch)) + return Result; + } else if (Stream.SkipBlock()) { + Error("malformed block record in AST file"); + return Failure; + } + continue; default: if (Stream.SkipBlock()) { @@ -2245,68 +2347,6 @@ ASTReader::ReadControlBlock(ModuleFile &F, break; } - case LANGUAGE_OPTIONS: { - bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; - // FIXME: The &F == *ModuleMgr.begin() check is wrong for modules. - if (Listener && &F == *ModuleMgr.begin() && - ParseLanguageOptions(Record, Complain, *Listener, - AllowCompatibleConfigurationMismatch) && - !DisableValidation && !AllowConfigurationMismatch) - return ConfigurationMismatch; - break; - } - - case TARGET_OPTIONS: { - bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0; - if (Listener && &F == *ModuleMgr.begin() && - ParseTargetOptions(Record, Complain, *Listener, - AllowCompatibleConfigurationMismatch) && - !DisableValidation && !AllowConfigurationMismatch) - return ConfigurationMismatch; - break; - } - - case DIAGNOSTIC_OPTIONS: { - bool Complain = (ClientLoadCapabilities & ARR_OutOfDate)==0; - if (Listener && &F == *ModuleMgr.begin() && - !AllowCompatibleConfigurationMismatch && - ParseDiagnosticOptions(Record, Complain, *Listener) && - !DisableValidation) - return OutOfDate; - break; - } - - case FILE_SYSTEM_OPTIONS: { - bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0; - if (Listener && &F == *ModuleMgr.begin() && - !AllowCompatibleConfigurationMismatch && - ParseFileSystemOptions(Record, Complain, *Listener) && - !DisableValidation && !AllowConfigurationMismatch) - return ConfigurationMismatch; - break; - } - - case HEADER_SEARCH_OPTIONS: { - bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0; - if (Listener && &F == *ModuleMgr.begin() && - !AllowCompatibleConfigurationMismatch && - ParseHeaderSearchOptions(Record, Complain, *Listener) && - !DisableValidation && !AllowConfigurationMismatch) - return ConfigurationMismatch; - break; - } - - case PREPROCESSOR_OPTIONS: { - bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0; - if (Listener && &F == *ModuleMgr.begin() && - !AllowCompatibleConfigurationMismatch && - ParsePreprocessorOptions(Record, Complain, *Listener, - SuggestedPredefines) && - !DisableValidation && !AllowConfigurationMismatch) - return ConfigurationMismatch; - break; - } - case ORIGINAL_FILE: F.OriginalSourceFileID = FileID::get(Record[0]); F.ActualOriginalSourceFileName = Blob; @@ -4080,36 +4120,51 @@ bool ASTReader::readASTFileControlBlock( bool NeedsSystemInputFiles = Listener.needsSystemInputFileVisitation(); bool NeedsImports = Listener.needsImportVisitation(); BitstreamCursor InputFilesCursor; - if (NeedsInputFiles) { - InputFilesCursor = Stream; - if (SkipCursorToBlock(InputFilesCursor, INPUT_FILES_BLOCK_ID)) - return true; - // Read the abbreviations - while (true) { - uint64_t Offset = InputFilesCursor.GetCurrentBitNo(); - unsigned Code = InputFilesCursor.ReadCode(); + RecordData Record; + std::string ModuleDir; + while (1) { + llvm::BitstreamEntry Entry = Stream.advance(); - // We expect all abbrevs to be at the start of the block. - if (Code != llvm::bitc::DEFINE_ABBREV) { - InputFilesCursor.JumpToBit(Offset); + switch (Entry.Kind) { + case llvm::BitstreamEntry::SubBlock: { + switch (Entry.ID) { + case OPTIONS_BLOCK_ID: { + std::string IgnoredSuggestedPredefines; + if (ReadOptionsBlock(Stream, ARR_ConfigurationMismatch | ARR_OutOfDate, + /*AllowCompatibleConfigurationMismatch*/ false, + Listener, IgnoredSuggestedPredefines) != Success) + return true; break; } - InputFilesCursor.ReadAbbrevRecord(); + + case INPUT_FILES_BLOCK_ID: + InputFilesCursor = Stream; + if (Stream.SkipBlock() || + (NeedsInputFiles && + ReadBlockAbbrevs(InputFilesCursor, INPUT_FILES_BLOCK_ID))) + return true; + break; + + default: + if (Stream.SkipBlock()) + return true; + break; + } + + continue; } - } - - // Scan for ORIGINAL_FILE inside the control block. - RecordData Record; - std::string ModuleDir; - while (1) { - llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); - if (Entry.Kind == llvm::BitstreamEntry::EndBlock) + + case llvm::BitstreamEntry::EndBlock: return false; - - if (Entry.Kind != llvm::BitstreamEntry::Record) + + case llvm::BitstreamEntry::Error: return true; - + + case llvm::BitstreamEntry::Record: + break; + } + Record.clear(); StringRef Blob; unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob); @@ -4136,41 +4191,6 @@ bool ASTReader::readASTFileControlBlock( Listener.ReadModuleMapFile(Path); break; } - case LANGUAGE_OPTIONS: - if (ParseLanguageOptions(Record, false, Listener, - /*AllowCompatibleConfigurationMismatch*/false)) - return true; - break; - - case TARGET_OPTIONS: - if (ParseTargetOptions(Record, false, Listener, - /*AllowCompatibleConfigurationMismatch*/ false)) - return true; - break; - - case DIAGNOSTIC_OPTIONS: - if (ParseDiagnosticOptions(Record, false, Listener)) - return true; - break; - - case FILE_SYSTEM_OPTIONS: - if (ParseFileSystemOptions(Record, false, Listener)) - return true; - break; - - case HEADER_SEARCH_OPTIONS: - if (ParseHeaderSearchOptions(Record, false, Listener)) - return true; - break; - - case PREPROCESSOR_OPTIONS: { - std::string IgnoredSuggestedPredefines; - if (ParsePreprocessorOptions(Record, false, Listener, - IgnoredSuggestedPredefines)) - return true; - break; - } - case INPUT_FILE_OFFSETS: { if (!NeedsInputFiles) break; diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 225a00c942f..dfcc539284b 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -881,12 +881,14 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(MODULE_DIRECTORY); RECORD(MODULE_MAP_FILE); RECORD(IMPORTS); - RECORD(LANGUAGE_OPTIONS); - RECORD(TARGET_OPTIONS); RECORD(ORIGINAL_FILE); RECORD(ORIGINAL_PCH_DIR); RECORD(ORIGINAL_FILE_ID); RECORD(INPUT_FILE_OFFSETS); + + BLOCK(OPTIONS_BLOCK); + RECORD(LANGUAGE_OPTIONS); + RECORD(TARGET_OPTIONS); RECORD(DIAGNOSTIC_OPTIONS); RECORD(FILE_SYSTEM_OPTIONS); RECORD(HEADER_SEARCH_OPTIONS); @@ -1288,6 +1290,9 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, Stream.EmitRecord(IMPORTS, Record); } + // Write the options block. + Stream.EnterSubblock(OPTIONS_BLOCK_ID, 4); + // Language options. Record.clear(); const LangOptions &LangOpts = Context.getLangOpts(); @@ -1427,6 +1432,9 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, Record.push_back(static_cast<unsigned>(PPOpts.ObjCXXARCStandardLibrary)); Stream.EmitRecord(PREPROCESSOR_OPTIONS, Record); + // Leave the options block. + Stream.ExitBlock(); + // Original file name and file ID SourceManager &SM = Context.getSourceManager(); if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) { |