SUBMODULE_BLOCK_ID,
/// \brief The block containing comments.
- COMMENTS_BLOCK_ID
+ COMMENTS_BLOCK_ID,
+
+ /// \brief The control block, which contains all of the
+ /// information that needs to be validated prior to committing
+ /// to loading the AST file.
+ CONTROL_BLOCK_ID
+ };
+
+ /// \brief Record types that occur within the control block.
+ enum ControlRecordTypes {
+ /// \brief AST file metadata, including the AST file version number
+ /// and the target triple used to build the AST file.
+ METADATA = 1,
+
+ /// \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 original file that was used to
+ /// generate the AST file.
+ ORIGINAL_FILE_NAME = 4,
+
+ /// \brief Record code for the file ID of the original file used to
+ /// generate the AST file.
+ ORIGINAL_FILE_ID = 5,
+
+ /// \brief The directory that the PCH was originally created in.
+ ORIGINAL_PCH_DIR = 6,
+
+ /// \brief Record code for the version control branch and revision
+ /// information of the compiler used to build this AST file.
+ VERSION_CONTROL_BRANCH_REVISION = 7
};
/// \brief Record types that occur within the AST block itself.
/// reserved for the translation unit declaration.
DECL_OFFSET = 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 AST file metadata, including the AST file version number
- /// and the target triple used to build the AST file.
- METADATA = 4,
-
/// \brief Record code for the table of offsets of each
/// identifier ID.
///
/// The offset table contains offsets into the blob stored in
/// the IDENTIFIER_TABLE record. Each offset points to the
/// NULL-terminated string that corresponds to that identifier.
- IDENTIFIER_OFFSET = 5,
+ IDENTIFIER_OFFSET = 3,
/// \brief Record code for the identifier table.
///
/// between offsets (for unresolved identifier IDs) and
/// IdentifierInfo pointers (for already-resolved identifier
/// IDs).
- IDENTIFIER_TABLE = 6,
+ IDENTIFIER_TABLE = 4,
/// \brief Record code for the array of external definitions.
///
/// reported to the AST consumer after the AST file has been
/// read, since their presence can affect the semantics of the
/// program (e.g., for code generation).
- EXTERNAL_DEFINITIONS = 7,
+ EXTERNAL_DEFINITIONS = 5,
/// \brief Record code for the set of non-builtin, special
/// types.
/// that are constructed during semantic analysis (e.g.,
/// __builtin_va_list). The SPECIAL_TYPE_* constants provide
/// offsets into this record.
- SPECIAL_TYPES = 8,
+ SPECIAL_TYPES = 6,
/// \brief Record code for the extra statistics we gather while
/// generating an AST file.
- STATISTICS = 9,
+ STATISTICS = 7,
/// \brief Record code for the array of tentative definitions.
- TENTATIVE_DEFINITIONS = 10,
+ TENTATIVE_DEFINITIONS = 8,
/// \brief Record code for the array of locally-scoped external
/// declarations.
- LOCALLY_SCOPED_EXTERNAL_DECLS = 11,
+ LOCALLY_SCOPED_EXTERNAL_DECLS = 9,
/// \brief Record code for the table of offsets into the
/// Objective-C method pool.
- SELECTOR_OFFSETS = 12,
+ SELECTOR_OFFSETS = 10,
/// \brief Record code for the Objective-C method pool,
- METHOD_POOL = 13,
+ METHOD_POOL = 11,
/// \brief The value of the next __COUNTER__ to dispense.
/// [PP_COUNTER_VALUE, Val]
- PP_COUNTER_VALUE = 14,
+ PP_COUNTER_VALUE = 12,
/// \brief Record code for the table of offsets into the block
/// of source-location information.
- SOURCE_LOCATION_OFFSETS = 15,
+ SOURCE_LOCATION_OFFSETS = 13,
/// \brief Record code for the set of source location entries
/// that need to be preloaded by the AST reader.
/// This set contains the source location entry for the
/// predefines buffer and for any file entries that need to be
/// preloaded.
- SOURCE_LOCATION_PRELOADS = 16,
+ SOURCE_LOCATION_PRELOADS = 14,
/// \brief Record code for the stat() cache.
- STAT_CACHE = 17,
+ STAT_CACHE = 15,
/// \brief Record code for the set of ext_vector type names.
- EXT_VECTOR_DECLS = 18,
-
- /// \brief Record code for the original file that was used to
- /// generate the AST file.
- ORIGINAL_FILE_NAME = 19,
-
- /// \brief Record code for the file ID of the original file used to
- /// generate the AST file.
- ORIGINAL_FILE_ID = 20,
-
- /// \brief Record code for the version control branch and revision
- /// information of the compiler used to build this AST file.
- VERSION_CONTROL_BRANCH_REVISION = 21,
+ EXT_VECTOR_DECLS = 16,
/// \brief Record code for the array of unused file scoped decls.
- UNUSED_FILESCOPED_DECLS = 22,
+ UNUSED_FILESCOPED_DECLS = 17,
/// \brief Record code for the table of offsets to entries in the
/// preprocessing record.
- PPD_ENTITIES_OFFSETS = 23,
+ PPD_ENTITIES_OFFSETS = 18,
/// \brief Record code for the array of VTable uses.
- VTABLE_USES = 24,
+ VTABLE_USES = 19,
/// \brief Record code for the array of dynamic classes.
- DYNAMIC_CLASSES = 25,
-
- /// \brief Record code for the list of other AST files imported by
- /// this AST file.
- IMPORTS = 26,
+ DYNAMIC_CLASSES = 20,
/// \brief Record code for referenced selector pool.
- REFERENCED_SELECTOR_POOL = 27,
+ REFERENCED_SELECTOR_POOL = 21,
/// \brief Record code for an update to the TU's lexically contained
/// declarations.
- TU_UPDATE_LEXICAL = 28,
+ TU_UPDATE_LEXICAL = 22,
/// \brief Record code for the array describing the locations (in the
/// LOCAL_REDECLARATIONS record) of the redeclaration chains, indexed by
/// the first known ID.
- LOCAL_REDECLARATIONS_MAP = 29,
+ LOCAL_REDECLARATIONS_MAP = 23,
/// \brief Record code for declarations that Sema keeps references of.
- SEMA_DECL_REFS = 30,
+ SEMA_DECL_REFS = 24,
/// \brief Record code for weak undeclared identifiers.
- WEAK_UNDECLARED_IDENTIFIERS = 31,
+ WEAK_UNDECLARED_IDENTIFIERS = 25,
/// \brief Record code for pending implicit instantiations.
- PENDING_IMPLICIT_INSTANTIATIONS = 32,
+ PENDING_IMPLICIT_INSTANTIATIONS = 26,
/// \brief Record code for a decl replacement block.
///
/// If a declaration is modified after having been deserialized, and then
/// written to a dependent AST file, its ID and offset must be added to
/// the replacement block.
- DECL_REPLACEMENTS = 33,
+ DECL_REPLACEMENTS = 27,
/// \brief Record code for an update to a decl context's lookup table.
///
/// In practice, this should only be used for the TU and namespaces.
- UPDATE_VISIBLE = 34,
+ UPDATE_VISIBLE = 28,
/// \brief Record for offsets of DECL_UPDATES records for declarations
/// that were modified after being deserialized and need updates.
- DECL_UPDATE_OFFSETS = 35,
+ DECL_UPDATE_OFFSETS = 29,
/// \brief Record of updates for a declaration that was modified after
/// being deserialized.
- DECL_UPDATES = 36,
+ DECL_UPDATES = 30,
/// \brief Record code for the table of offsets to CXXBaseSpecifier
/// sets.
- CXX_BASE_SPECIFIER_OFFSETS = 37,
+ CXX_BASE_SPECIFIER_OFFSETS = 31,
/// \brief Record code for \#pragma diagnostic mappings.
- DIAG_PRAGMA_MAPPINGS = 38,
+ DIAG_PRAGMA_MAPPINGS = 32,
/// \brief Record code for special CUDA declarations.
- CUDA_SPECIAL_DECL_REFS = 39,
+ CUDA_SPECIAL_DECL_REFS = 33,
/// \brief Record code for header search information.
- HEADER_SEARCH_TABLE = 40,
-
- /// \brief The directory that the PCH was originally created in.
- ORIGINAL_PCH_DIR = 41,
+ HEADER_SEARCH_TABLE = 34,
/// \brief Record code for floating point \#pragma options.
- FP_PRAGMA_OPTIONS = 42,
+ FP_PRAGMA_OPTIONS = 35,
/// \brief Record code for enabled OpenCL extensions.
- OPENCL_EXTENSIONS = 43,
+ OPENCL_EXTENSIONS = 36,
/// \brief The list of delegating constructor declarations.
- DELEGATING_CTORS = 44,
+ DELEGATING_CTORS = 37,
/// \brief Record code for the table of offsets into the block
/// of file source-location information.
- FILE_SOURCE_LOCATION_OFFSETS = 45,
+ FILE_SOURCE_LOCATION_OFFSETS = 38,
/// \brief Record code for the set of known namespaces, which are used
/// for typo correction.
- KNOWN_NAMESPACES = 46,
+ KNOWN_NAMESPACES = 39,
/// \brief Record code for the remapping information used to relate
/// loaded modules to the various offsets and IDs(e.g., source location
/// offests, declaration and type IDs) that are used in that module to
/// refer to other modules.
- MODULE_OFFSET_MAP = 47,
+ MODULE_OFFSET_MAP = 40,
/// \brief Record code for the source manager line table information,
/// which stores information about \#line directives.
- SOURCE_MANAGER_LINE_TABLE = 48,
+ SOURCE_MANAGER_LINE_TABLE = 41,
/// \brief Record code for map of Objective-C class definition IDs to the
/// ObjC categories in a module that are attached to that class.
- OBJC_CATEGORIES_MAP = 49,
+ OBJC_CATEGORIES_MAP = 42,
/// \brief Record code for a file sorted array of DeclIDs in a module.
- FILE_SORTED_DECLS = 50,
+ FILE_SORTED_DECLS = 43,
/// \brief Record code for an array of all of the (sub)modules that were
/// imported by the AST file.
- IMPORTED_MODULES = 51,
+ IMPORTED_MODULES = 44,
/// \brief Record code for the set of merged declarations in an AST file.
- MERGED_DECLARATIONS = 52,
+ MERGED_DECLARATIONS = 45,
/// \brief Record code for the array of redeclaration chains.
///
/// This array can only be interpreted properly using the local
/// redeclarations map.
- LOCAL_REDECLARATIONS = 53,
+ LOCAL_REDECLARATIONS = 46,
/// \brief Record code for the array of Objective-C categories (including
/// extensions).
///
/// This array can only be interpreted properly using the Objective-C
/// categories map.
- OBJC_CATEGORIES = 54,
+ OBJC_CATEGORIES = 47,
/// \brief Record code for the table of offsets of each macro ID.
///
/// The offset table contains offsets into the blob stored in
/// the preprocessor block. Each offset points to the corresponding
/// macro definition.
- MACRO_OFFSET = 55,
+ MACRO_OFFSET = 48,
/// \brief Record of updates for a macro that was modified after
/// being deserialized.
- MACRO_UPDATES = 56
+ MACRO_UPDATES = 49
};
/// \brief Record types used within a source manager block.
void MaybeAddSystemRootToFilename(std::string &Filename);
ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type,
- ModuleFile *ImportedBy);
+ ModuleFile *ImportedBy,
+ llvm::SmallVectorImpl<ModuleFile *> &Loaded);
+ ASTReadResult ReadControlBlock(ModuleFile &F,
+ llvm::SmallVectorImpl<ModuleFile *> &Loaded);
ASTReadResult ReadASTBlock(ModuleFile &F);
bool CheckPredefinesBuffers();
bool ParseLineTable(ModuleFile &F, SmallVectorImpl<uint64_t> &Record);
llvm::DenseSet<Stmt *> &ParentStmts);
void WriteBlockInfoBlock();
- void WriteMetadata(ASTContext &Context, StringRef isysroot,
- const std::string &OutputFile);
- void WriteLanguageOptions(const LangOptions &LangOpts);
+ void WriteControlBlock(ASTContext &Context, StringRef isysroot,
+ const std::string &OutputFile);
void WriteStatCache(MemorizeStatCalls &StatCalls);
void WriteSourceManagerBlock(SourceManager &SourceMgr,
const Preprocessor &PP,
Filename.insert(Filename.begin(), isysroot.begin(), isysroot.end());
}
+ASTReader::ASTReadResult ASTReader::ReadControlBlock(ModuleFile &F,
+ llvm::SmallVectorImpl<ModuleFile *> &Loaded) {
+ llvm::BitstreamCursor &Stream = F.Stream;
+
+ if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) {
+ Error("malformed block record in AST file");
+ return Failure;
+ }
+
+ // Read all of the records and blocks in the control block.
+ RecordData Record;
+ while (!Stream.AtEndOfStream()) {
+ unsigned Code = Stream.ReadCode();
+ if (Code == llvm::bitc::END_BLOCK) {
+ if (Stream.ReadBlockEnd()) {
+ Error("error at end of control block in AST file");
+ return Failure;
+ }
+
+ return Success;
+ }
+
+ if (Code == llvm::bitc::ENTER_SUBBLOCK) {
+ Stream.ReadSubBlockID();
+ if (!Stream.SkipBlock())
+ continue;
+
+ Error("malformed block record in AST file");
+ return Failure;
+ }
+
+ if (Code == llvm::bitc::DEFINE_ABBREV) {
+ Stream.ReadAbbrevRecord();
+ continue;
+ }
+
+ // Read and process a record.
+ Record.clear();
+ const char *BlobStart = 0;
+ unsigned BlobLen = 0;
+ switch ((ControlRecordTypes)Stream.ReadRecord(Code, Record,
+ &BlobStart, &BlobLen)) {
+ case METADATA: {
+ if (Record[0] != VERSION_MAJOR && !DisableValidation) {
+ Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
+ : diag::warn_pch_version_too_new);
+ return IgnorePCH;
+ }
+
+ bool hasErrors = Record[5];
+ if (hasErrors && !DisableValidation && !AllowASTWithCompilerErrors) {
+ Diag(diag::err_pch_with_compiler_errors);
+ return IgnorePCH;
+ }
+
+ RelocatablePCH = Record[4];
+ if (Listener && &F == *ModuleMgr.begin()) {
+ unsigned Idx = 6;
+ TargetOptions TargetOpts;
+ TargetOpts.Triple = ReadString(Record, Idx);
+ TargetOpts.CPU = ReadString(Record, Idx);
+ TargetOpts.ABI = ReadString(Record, Idx);
+ TargetOpts.CXXABI = ReadString(Record, Idx);
+ TargetOpts.LinkerVersion = ReadString(Record, Idx);
+ for (unsigned N = Record[Idx++]; N; --N) {
+ TargetOpts.FeaturesAsWritten.push_back(ReadString(Record, Idx));
+ }
+ for (unsigned N = Record[Idx++]; N; --N) {
+ TargetOpts.Features.push_back(ReadString(Record, Idx));
+ }
+
+ if (Listener->ReadTargetOptions(F, TargetOpts))
+ return IgnorePCH;
+ }
+ break;
+ }
+
+ case IMPORTS: {
+ // Load each of the imported PCH files.
+ unsigned Idx = 0, N = Record.size();
+ while (Idx < N) {
+ // Read information about the AST file.
+ ModuleKind ImportedKind = (ModuleKind)Record[Idx++];
+ unsigned Length = Record[Idx++];
+ SmallString<128> ImportedFile(Record.begin() + Idx,
+ Record.begin() + Idx + Length);
+ Idx += Length;
+
+ // Load the AST file.
+ switch(ReadASTCore(ImportedFile, ImportedKind, &F, Loaded)) {
+ case Failure: return Failure;
+ // If we have to ignore the dependency, we'll have to ignore this too.
+ case IgnorePCH: return IgnorePCH;
+ case Success: break;
+ }
+ }
+ break;
+ }
+
+ case LANGUAGE_OPTIONS:
+ if (&F == *ModuleMgr.begin() &&
+ ParseLanguageOptions(F, Record) && !DisableValidation)
+ return IgnorePCH;
+ break;
+
+ case ORIGINAL_FILE_NAME:
+ // Only record from the primary AST file.
+ if (&F == *ModuleMgr.begin()) {
+ // The primary AST will be the last to get here, so it will be the one
+ // that's used.
+ ActualOriginalFileName.assign(BlobStart, BlobLen);
+ OriginalFileName = ActualOriginalFileName;
+ MaybeAddSystemRootToFilename(OriginalFileName);
+ }
+ break;
+
+ case ORIGINAL_FILE_ID:
+ // Only record from the primary AST file.
+ if (&F == *ModuleMgr.begin()) {
+ OriginalFileID = FileID::get(Record[0]);
+ }
+ break;
+
+ case ORIGINAL_PCH_DIR:
+ // Only record from the primary AST file.
+ if (&F == *ModuleMgr.begin()) {
+ OriginalDir.assign(BlobStart, BlobLen);
+ }
+ break;
+
+ case VERSION_CONTROL_BRANCH_REVISION: {
+ const std::string &CurBranch = getClangFullRepositoryVersion();
+ StringRef ASTBranch(BlobStart, BlobLen);
+ if (StringRef(CurBranch) != ASTBranch && !DisableValidation) {
+ Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch;
+ return IgnorePCH;
+ }
+ break;
+ }
+ }
+ }
+
+ Error("premature end of bitstream in AST file");
+ return Failure;
+}
+
ASTReader::ASTReadResult
ASTReader::ReadASTBlock(ModuleFile &F) {
llvm::BitstreamCursor &Stream = F.Stream;
return Failure;
}
- // Read all of the records and blocks for the ASt file.
+ // Read all of the records and blocks for the AST file.
RecordData Record;
while (!Stream.AtEndOfStream()) {
unsigned Code = Stream.ReadCode();
default: // Default behavior: ignore.
break;
- case METADATA: {
- if (Record[0] != VERSION_MAJOR && !DisableValidation) {
- Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
- : diag::warn_pch_version_too_new);
- return IgnorePCH;
- }
-
- bool hasErrors = Record[5];
- if (hasErrors && !DisableValidation && !AllowASTWithCompilerErrors) {
- Diag(diag::err_pch_with_compiler_errors);
- return IgnorePCH;
- }
-
- RelocatablePCH = Record[4];
- if (Listener) {
- unsigned Idx = 6;
- TargetOptions TargetOpts;
- TargetOpts.Triple = ReadString(Record, Idx);
- TargetOpts.CPU = ReadString(Record, Idx);
- TargetOpts.ABI = ReadString(Record, Idx);
- TargetOpts.CXXABI = ReadString(Record, Idx);
- TargetOpts.LinkerVersion = ReadString(Record, Idx);
- for (unsigned N = Record[Idx++]; N; --N) {
- TargetOpts.FeaturesAsWritten.push_back(ReadString(Record, Idx));
- }
- for (unsigned N = Record[Idx++]; N; --N) {
- TargetOpts.Features.push_back(ReadString(Record, Idx));
- }
-
- if (Listener->ReadTargetOptions(F, TargetOpts))
- return IgnorePCH;
- }
- break;
- }
-
- case IMPORTS: {
- // Load each of the imported PCH files.
- unsigned Idx = 0, N = Record.size();
- while (Idx < N) {
- // Read information about the AST file.
- ModuleKind ImportedKind = (ModuleKind)Record[Idx++];
- unsigned Length = Record[Idx++];
- SmallString<128> ImportedFile(Record.begin() + Idx,
- Record.begin() + Idx + Length);
- Idx += Length;
-
- // Load the AST file.
- switch(ReadASTCore(ImportedFile, ImportedKind, &F)) {
- case Failure: return Failure;
- // If we have to ignore the dependency, we'll have to ignore this too.
- case IgnorePCH: return IgnorePCH;
- case Success: break;
- }
- }
- break;
- }
-
case TYPE_OFFSET: {
if (F.LocalNumTypes != 0) {
Error("duplicate TYPE_OFFSET record in AST file");
break;
}
- case LANGUAGE_OPTIONS:
- if (ParseLanguageOptions(F, Record) && !DisableValidation)
- return IgnorePCH;
- break;
-
case IDENTIFIER_TABLE:
F.IdentifierTableData = BlobStart;
if (Record[0]) {
SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
break;
- case ORIGINAL_FILE_NAME:
- // The primary AST will be the last to get here, so it will be the one
- // that's used.
- ActualOriginalFileName.assign(BlobStart, BlobLen);
- OriginalFileName = ActualOriginalFileName;
- MaybeAddSystemRootToFilename(OriginalFileName);
- break;
-
- case ORIGINAL_FILE_ID:
- OriginalFileID = FileID::get(Record[0]);
- break;
-
- case ORIGINAL_PCH_DIR:
- // The primary AST will be the last to get here, so it will be the one
- // that's used.
- OriginalDir.assign(BlobStart, BlobLen);
- break;
-
- case VERSION_CONTROL_BRANCH_REVISION: {
- const std::string &CurBranch = getClangFullRepositoryVersion();
- StringRef ASTBranch(BlobStart, BlobLen);
- if (StringRef(CurBranch) != ASTBranch && !DisableValidation) {
- Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch;
- return IgnorePCH;
- }
- break;
- }
-
case PPD_ENTITIES_OFFSETS: {
F.PreprocessedEntityOffsets = (const PPEntityOffset *)BlobStart;
assert(BlobLen % sizeof(PPEntityOffset) == 0);
ModuleKind Type) {
// Bump the generation number.
unsigned PreviousGeneration = CurrentGeneration++;
-
- switch(ReadASTCore(FileName, Type, /*ImportedBy=*/0)) {
+
+ // Load the core of the AST files.
+ llvm::SmallVector<ModuleFile *, 4> Loaded;
+ switch(ReadASTCore(FileName, Type, /*ImportedBy=*/0, Loaded)) {
case Failure: return Failure;
case IgnorePCH: return IgnorePCH;
case Success: break;
// Here comes stuff that we only do once the entire chain is loaded.
+ // Load the AST blocks of all of the modules that we loaded.
+ for (llvm::SmallVectorImpl<ModuleFile *>::iterator M = Loaded.begin(),
+ MEnd = Loaded.end();
+ M != MEnd; ++M) {
+ ModuleFile &F = **M;
+
+ // Read the AST block.
+ switch(ReadASTBlock(F)) {
+ case Failure: return Failure;
+ case IgnorePCH: return IgnorePCH;
+ case Success: break;
+ }
+
+ // Once read, set the ModuleFile bit base offset and update the size in
+ // bits of all files we've seen.
+ F.GlobalBitOffset = TotalModulesSizeInBits;
+ TotalModulesSizeInBits += F.SizeInBits;
+ GlobalBitOffsetsMap.insert(std::make_pair(F.GlobalBitOffset, &F));
+
+ // Make sure that the files this module was built against are
+ // still available.
+ // FIXME: Move this validation into ReadControlBlock.
+ if (!DisableValidation) {
+ switch(validateFileEntries(F)) {
+ case Failure: return Failure;
+ case IgnorePCH: return IgnorePCH;
+ case Success: break;
+ }
+ }
+
+ // Preload SLocEntries.
+ for (unsigned I = 0, N = F.PreloadSLocEntries.size(); I != N; ++I) {
+ int Index = int(F.PreloadSLocEntries[I] - 1) + F.SLocEntryBaseID;
+ // Load it through the SourceManager and don't call ReadSLocEntryRecord()
+ // directly because the entry may have already been loaded in which case
+ // calling ReadSLocEntryRecord() directly would trigger an assertion in
+ // SourceManager.
+ SourceMgr.getLoadedSLocEntryByID(Index);
+ }
+ }
+
// Check the predefines buffers.
if (!DisableValidation && Type == MK_PCH &&
// FIXME: CheckPredefinesBuffers also sets the SuggestedPredefines;
ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName,
ModuleKind Type,
- ModuleFile *ImportedBy) {
+ ModuleFile *ImportedBy,
+ llvm::SmallVectorImpl<ModuleFile *> &Loaded) {
ModuleFile *M;
bool NewModule;
std::string ErrorStr;
return Failure;
}
break;
- case AST_BLOCK_ID:
- switch (ReadASTBlock(F)) {
+ case CONTROL_BLOCK_ID:
+ switch (ReadControlBlock(F, Loaded)) {
case Success:
break;
// FIXME: We could consider reading through to the end of this
// AST block, skipping subblocks, to see if there are other
// AST blocks elsewhere.
-
- // FIXME: We can't clear loaded slocentries anymore.
- //SourceMgr.ClearPreallocatedSLocEntries();
-
- // Remove the stat cache.
- if (F.StatCache)
- FileMgr.removeStatCache((ASTStatCache*)F.StatCache);
-
return IgnorePCH;
}
break;
+ case AST_BLOCK_ID:
+ // Record that we've loaded this module.
+ Loaded.push_back(M);
+ return Success;
+
default:
if (Stream.SkipBlock()) {
Error("malformed block record in AST file");
}
}
- // Once read, set the ModuleFile bit base offset and update the size in
- // bits of all files we've seen.
- F.GlobalBitOffset = TotalModulesSizeInBits;
- TotalModulesSizeInBits += F.SizeInBits;
- GlobalBitOffsetsMap.insert(std::make_pair(F.GlobalBitOffset, &F));
-
- // Make sure that the files this module was built against are still available.
- if (!DisableValidation) {
- switch(validateFileEntries(*M)) {
- case Failure: return Failure;
- case IgnorePCH: return IgnorePCH;
- case Success: break;
- }
- }
-
- // Preload SLocEntries.
- for (unsigned I = 0, N = M->PreloadSLocEntries.size(); I != N; ++I) {
- int Index = int(M->PreloadSLocEntries[I] - 1) + F.SLocEntryBaseID;
- // Load it through the SourceManager and don't call ReadSLocEntryRecord()
- // directly because the entry may have already been loaded in which case
- // calling ReadSLocEntryRecord() directly would trigger an assertion in
- // SourceManager.
- SourceMgr.getLoadedSLocEntryByID(Index);
- }
-
-
return Success;
}
// We only know the AST subblock ID.
switch (BlockID) {
- case AST_BLOCK_ID:
- if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
+ case CONTROL_BLOCK_ID:
+ if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) {
Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
return std::string();
}
return Filename + Pos;
}
-/// \brief Write the AST metadata (e.g., i686-apple-darwin9).
-void ASTWriter::WriteMetadata(ASTContext &Context, StringRef isysroot,
- const std::string &OutputFile) {
+/// \brief Write the control block.
+void ASTWriter::WriteControlBlock(ASTContext &Context, StringRef isysroot,
+ const std::string &OutputFile) {
using namespace llvm;
-
+ Stream.EnterSubblock(CONTROL_BLOCK_ID, 4);
+
// Metadata
const TargetInfo &Target = Context.getTargetInfo();
const TargetOptions &TargetOpts = Target.getTargetOpts();
}
Stream.EmitRecord(METADATA, Record);
+ // Imports
if (Chain) {
serialization::ModuleManager &Mgr = Chain->getModuleManager();
llvm::SmallVector<char, 128> ModulePaths;
Stream.EmitRecord(IMPORTS, Record);
}
+ // Language options.
+ Record.clear();
+ const LangOptions &LangOpts = Context.getLangOpts();
+#define LANGOPT(Name, Bits, Default, Description) \
+ Record.push_back(LangOpts.Name);
+#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
+ Record.push_back(static_cast<unsigned>(LangOpts.get##Name()));
+#include "clang/Basic/LangOptions.def"
+
+ Record.push_back((unsigned) LangOpts.ObjCRuntime.getKind());
+ AddVersionTuple(LangOpts.ObjCRuntime.getVersion(), Record);
+
+ Record.push_back(LangOpts.CurrentModule.size());
+ Record.append(LangOpts.CurrentModule.begin(), LangOpts.CurrentModule.end());
+ Stream.EmitRecord(LANGUAGE_OPTIONS, Record);
+
// Original file name and file ID
SourceManager &SM = Context.getSourceManager();
if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
Record.push_back(VERSION_CONTROL_BRANCH_REVISION);
Stream.EmitRecordWithBlob(RepoAbbrevCode, Record,
getClangFullRepositoryVersion());
-}
-/// \brief Write the LangOptions structure.
-void ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
- RecordData Record;
-#define LANGOPT(Name, Bits, Default, Description) \
- Record.push_back(LangOpts.Name);
-#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
- Record.push_back(static_cast<unsigned>(LangOpts.get##Name()));
-#include "clang/Basic/LangOptions.def"
-
- Record.push_back((unsigned) LangOpts.ObjCRuntime.getKind());
- AddVersionTuple(LangOpts.ObjCRuntime.getVersion(), Record);
-
- Record.push_back(LangOpts.CurrentModule.size());
- Record.append(LangOpts.CurrentModule.begin(), LangOpts.CurrentModule.end());
- Stream.EmitRecord(LANGUAGE_OPTIONS, Record);
+ Stream.ExitBlock();
}
//===----------------------------------------------------------------------===//
if (!I->second)
AddDeclRef(I->first, KnownNamespaces);
}
-
+
+ // Write the control block
+ WriteControlBlock(Context, isysroot, OutputFile);
+
// Write the remaining AST contents.
RecordData Record;
Stream.EnterSubblock(AST_BLOCK_ID, 5);
- WriteLanguageOptions(Context.getLangOpts());
- WriteMetadata(Context, isysroot, OutputFile);
if (StatCalls && isysroot.empty())
WriteStatCache(*StatCalls);