r247055 - [modules] Write the options records to a separate subblock rather than writing
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 8 12:40:15 PDT 2015
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())) {
More information about the cfe-commits
mailing list