DIAGNOSTIC_OPTIONS = 8,
/// \brief Record code for the filesystem options table.
- FILE_SYSTEM_OPTIONS = 9
+ FILE_SYSTEM_OPTIONS = 9,
+
+ /// \brief Record code for the headers search options table.
+ HEADER_SEARCH_OPTIONS = 10
};
/// \brief Record types that occur within the input-files block
return false;
}
+ /// \brief Receives the header search options.
+ ///
+ /// \returns true to indicate the header search options are invalid, or false
+ /// otherwise.
+ virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+ bool Complain) {
+ return false;
+ }
+
/// \brief Receives the contents of the predefines buffer.
///
/// \param Buffers Information about the predefines buffers.
ASTReaderListener &Listener);
static bool ParseFileSystemOptions(const RecordData &Record, bool Complain,
ASTReaderListener &Listener);
+ static bool ParseHeaderSearchOptions(const RecordData &Record, bool Complain,
+ ASTReaderListener &Listener);
struct RecordLocation {
RecordLocation(ModuleFile *M, uint64_t O)
llvm::DenseSet<Stmt *> &ParentStmts);
void WriteBlockInfoBlock();
- void WriteControlBlock(ASTContext &Context, StringRef isysroot,
- const std::string &OutputFile);
+ void WriteControlBlock(Preprocessor &PP, ASTContext &Context,
+ StringRef isysroot, const std::string &OutputFile);
void WriteInputFiles(SourceManager &SourceMgr, StringRef isysroot);
void WriteStatCache(MemorizeStatCalls &StatCalls);
void WriteSourceManagerBlock(SourceManager &SourceMgr,
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Basic/OnDiskHashTable.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SourceManagerInternals.h"
break;
}
+ case HEADER_SEARCH_OPTIONS: {
+ bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
+ if (Listener && &F == *ModuleMgr.begin() &&
+ ParseHeaderSearchOptions(Record, Complain, *Listener) &&
+ !DisableValidation)
+ return ConfigurationMismatch;
+ break;
+ }
+
case ORIGINAL_FILE:
F.OriginalSourceFileID = FileID::get(Record[0]);
F.ActualOriginalSourceFileName.assign(BlobStart, BlobLen);
return false;
break;
+ case FILE_SYSTEM_OPTIONS:
+ if (ParseFileSystemOptions(Record, false, Validator))
+ return false;
+ break;
+
+ case HEADER_SEARCH_OPTIONS:
+ if (ParseHeaderSearchOptions(Record, false, Validator))
+ return false;
+ break;
+
default:
// No other validation to perform.
break;
return Listener.ReadFileSystemOptions(FSOpts, Complain);
}
+bool ASTReader::ParseHeaderSearchOptions(const RecordData &Record,
+ bool Complain,
+ ASTReaderListener &Listener) {
+ HeaderSearchOptions HSOpts;
+ unsigned Idx = 0;
+ HSOpts.Sysroot = ReadString(Record, Idx);
+
+ // Include entries.
+ for (unsigned N = Record[Idx++]; N; --N) {
+ std::string Path = ReadString(Record, Idx);
+ frontend::IncludeDirGroup Group
+ = static_cast<frontend::IncludeDirGroup>(Record[Idx++]);
+ bool IsUserSupplied = Record[Idx++];
+ bool IsFramework = Record[Idx++];
+ bool IgnoreSysRoot = Record[Idx++];
+ bool IsInternal = Record[Idx++];
+ bool ImplicitExternC = Record[Idx++];
+ HSOpts.UserEntries.push_back(
+ HeaderSearchOptions::Entry(Path, Group, IsUserSupplied, IsFramework,
+ IgnoreSysRoot, IsInternal, ImplicitExternC));
+ }
+
+ // System header prefixes.
+ for (unsigned N = Record[Idx++]; N; --N) {
+ std::string Prefix = ReadString(Record, Idx);
+ bool IsSystemHeader = Record[Idx++];
+ HSOpts.SystemHeaderPrefixes.push_back(
+ HeaderSearchOptions::SystemHeaderPrefix(Prefix, IsSystemHeader));
+ }
+
+ HSOpts.ResourceDir = ReadString(Record, Idx);
+ HSOpts.ModuleCachePath = ReadString(Record, Idx);
+ HSOpts.DisableModuleHash = Record[Idx++];
+ HSOpts.UseBuiltinIncludes = Record[Idx++];
+ HSOpts.UseStandardSystemIncludes = Record[Idx++];
+ HSOpts.UseStandardCXXIncludes = Record[Idx++];
+ HSOpts.UseLibcxx = Record[Idx++];
+
+ return Listener.ReadHeaderSearchOptions(HSOpts, Complain);
+}
+
std::pair<ModuleFile *, unsigned>
ASTReader::getModulePreprocessedEntity(unsigned GlobalIndex) {
GlobalPreprocessedEntityMapType::iterator
#include "clang/AST/Type.h"
#include "clang/AST/TypeLocVisitor.h"
#include "clang/Serialization/ASTReader.h"
+#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
RECORD(INPUT_FILE_OFFSETS);
RECORD(DIAGNOSTIC_OPTIONS);
RECORD(FILE_SYSTEM_OPTIONS);
+ RECORD(HEADER_SEARCH_OPTIONS);
BLOCK(INPUT_FILES_BLOCK);
RECORD(INPUT_FILE);
}
/// \brief Write the control block.
-void ASTWriter::WriteControlBlock(ASTContext &Context, StringRef isysroot,
+void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
+ StringRef isysroot,
const std::string &OutputFile) {
using namespace llvm;
Stream.EnterSubblock(CONTROL_BLOCK_ID, 5);
AddString(FSOpts.WorkingDir, Record);
Stream.EmitRecord(FILE_SYSTEM_OPTIONS, Record);
+ // Header search options.
+ Record.clear();
+ const HeaderSearchOptions &HSOpts
+ = PP.getHeaderSearchInfo().getHeaderSearchOpts();
+ AddString(HSOpts.Sysroot, Record);
+
+ // Include entries.
+ Record.push_back(HSOpts.UserEntries.size());
+ for (unsigned I = 0, N = HSOpts.UserEntries.size(); I != N; ++I) {
+ const HeaderSearchOptions::Entry &Entry = HSOpts.UserEntries[I];
+ AddString(Entry.Path, Record);
+ Record.push_back(static_cast<unsigned>(Entry.Group));
+ Record.push_back(Entry.IsUserSupplied);
+ Record.push_back(Entry.IsFramework);
+ Record.push_back(Entry.IgnoreSysRoot);
+ Record.push_back(Entry.IsInternal);
+ Record.push_back(Entry.ImplicitExternC);
+ }
+
+ // System header prefixes.
+ Record.push_back(HSOpts.SystemHeaderPrefixes.size());
+ for (unsigned I = 0, N = HSOpts.SystemHeaderPrefixes.size(); I != N; ++I) {
+ AddString(HSOpts.SystemHeaderPrefixes[I].Prefix, Record);
+ Record.push_back(HSOpts.SystemHeaderPrefixes[I].IsSystemHeader);
+ }
+
+ AddString(HSOpts.ResourceDir, Record);
+ AddString(HSOpts.ModuleCachePath, Record);
+ Record.push_back(HSOpts.DisableModuleHash);
+ Record.push_back(HSOpts.UseBuiltinIncludes);
+ Record.push_back(HSOpts.UseStandardSystemIncludes);
+ Record.push_back(HSOpts.UseStandardCXXIncludes);
+ Record.push_back(HSOpts.UseLibcxx);
+ Stream.EmitRecord(HEADER_SEARCH_OPTIONS, Record);
+
// Original file name and file ID
SourceManager &SM = Context.getSourceManager();
if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
}
// Write the control block
- WriteControlBlock(Context, isysroot, OutputFile);
+ WriteControlBlock(PP, Context, isysroot, OutputFile);
// Write the remaining AST contents.
RecordData Record;