Author: rsmith Date: Tue Sep 8 14:40:14 2015 New Revision: 247055 URL: http://llvm.org/viewvc/llvm-project?rev=247055&view=rev Log: [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.
Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h cfe/trunk/include/clang/Serialization/ASTReader.h cfe/trunk/lib/Serialization/ASTReader.cpp cfe/trunk/lib/Serialization/ASTWriter.cpp Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=247055&r1=247054&r2=247055&view=diff ============================================================================== --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original) +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue Sep 8 14:40:14 2015 @@ -233,7 +233,14 @@ namespace clang { /// to create this AST file. /// /// This block is part of the control block. - INPUT_FILES_BLOCK_ID + INPUT_FILES_BLOCK_ID, + + /// \brief The block of configuration options, used to check that + /// a module is being used in a configuration compatible with the + /// configuration in which it was built. + /// + /// This block is part of the control block. + OPTIONS_BLOCK_ID, }; /// \brief Record types that occur within the control block. @@ -244,59 +251,63 @@ namespace clang { /// \brief Record code for the list of other AST files imported by /// this AST file. - IMPORTS = 2, - - /// \brief Record code for the language options table. - /// - /// The record with this code contains the contents of the - /// LangOptions structure. We serialize the entire contents of - /// the structure, and let the reader decide which options are - /// actually important to check. - LANGUAGE_OPTIONS = 3, - - /// \brief Record code for the target options table. - TARGET_OPTIONS = 4, + IMPORTS, /// \brief Record code for the original file that was used to /// generate the AST file, including both its file ID and its /// name. - ORIGINAL_FILE = 5, + ORIGINAL_FILE, /// \brief The directory that the PCH was originally created in. - ORIGINAL_PCH_DIR = 6, + ORIGINAL_PCH_DIR, /// \brief Record code for file ID of the file or buffer that was used to /// generate the AST file. - ORIGINAL_FILE_ID = 7, + ORIGINAL_FILE_ID, /// \brief Offsets into the input-files block where input files /// reside. - INPUT_FILE_OFFSETS = 8, - - /// \brief Record code for the diagnostic options table. - DIAGNOSTIC_OPTIONS = 9, - - /// \brief Record code for the filesystem options table. - FILE_SYSTEM_OPTIONS = 10, - - /// \brief Record code for the headers search options table. - HEADER_SEARCH_OPTIONS = 11, - - /// \brief Record code for the preprocessor options table. - PREPROCESSOR_OPTIONS = 12, + INPUT_FILE_OFFSETS, /// \brief Record code for the module name. - MODULE_NAME = 13, + MODULE_NAME, /// \brief Record code for the module map file that was used to build this /// AST file. - MODULE_MAP_FILE = 14, + MODULE_MAP_FILE, /// \brief Record code for the signature that identifiers this AST file. - SIGNATURE = 15, + SIGNATURE, /// \brief Record code for the module build directory. - MODULE_DIRECTORY = 16, + MODULE_DIRECTORY, + }; + + /// \brief Record types that occur within the options block inside + /// the control block. + enum OptionsRecordTypes { + /// \brief Record code for the language options table. + /// + /// The record with this code contains the contents of the + /// LangOptions structure. We serialize the entire contents of + /// the structure, and let the reader decide which options are + /// actually important to check. + LANGUAGE_OPTIONS = 1, + + /// \brief Record code for the target options table. + TARGET_OPTIONS, + + /// \brief Record code for the diagnostic options table. + DIAGNOSTIC_OPTIONS, + + /// \brief Record code for the filesystem options table. + FILE_SYSTEM_OPTIONS, + + /// \brief Record code for the headers search options table. + HEADER_SEARCH_OPTIONS, + + /// \brief Record code for the preprocessor options table. + PREPROCESSOR_OPTIONS, }; /// \brief Record types that occur within the input-files block Modified: cfe/trunk/include/clang/Serialization/ASTReader.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=247055&r1=247054&r2=247055&view=diff ============================================================================== --- cfe/trunk/include/clang/Serialization/ASTReader.h (original) +++ cfe/trunk/include/clang/Serialization/ASTReader.h Tue Sep 8 14:40:14 2015 @@ -1117,6 +1117,10 @@ private: SmallVectorImpl<ImportedModule> &Loaded, const ModuleFile *ImportedBy, unsigned ClientLoadCapabilities); + static ASTReadResult ReadOptionsBlock( + llvm::BitstreamCursor &Stream, unsigned ClientLoadCapabilities, + bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener, + std::string &SuggestedPredefines); ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities); bool ParseLineTable(ModuleFile &F, const RecordData &Record); bool ReadSourceManagerBlock(ModuleFile &F); @@ -1689,7 +1693,7 @@ public: /// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the /// specified cursor. Read the abbreviations that are at the top of the block /// and then leave the cursor pointing into the block. - bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID); + static bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID); /// \brief Finds all the visible declarations with a given name. /// The current implementation of this method just loads the entire Modified: cfe/trunk/lib/Serialization/ASTReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=247055&r1=247054&r2=247055&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Sep 8 14:40:14 2015 @@ -1350,10 +1350,8 @@ SourceLocation ASTReader::getImportLocat /// 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: 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 & 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 & 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 & 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(); + + 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; + } + + case INPUT_FILES_BLOCK_ID: + InputFilesCursor = Stream; + if (Stream.SkipBlock() || + (NeedsInputFiles && + ReadBlockAbbrevs(InputFilesCursor, INPUT_FILES_BLOCK_ID))) + return true; + break; - // We expect all abbrevs to be at the start of the block. - if (Code != llvm::bitc::DEFINE_ABBREV) { - InputFilesCursor.JumpToBit(Offset); + default: + if (Stream.SkipBlock()) + return true; break; } - InputFilesCursor.ReadAbbrevRecord(); + + 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; Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=247055&r1=247054&r2=247055&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Sep 8 14:40:14 2015 @@ -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(Prepro 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(Prepro 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())) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits