(De-)serialize the preprocessor options, including macros defined,

-include'd files, etc. 

llvm-svn: 166614
This commit is contained in:
Douglas Gregor 2012-10-24 20:05:57 +00:00
parent 59ed7d45a6
commit b6af6c23cd
5 changed files with 95 additions and 4 deletions

View File

@ -414,6 +414,10 @@ public:
/// \param Target Information about the target.
void Initialize(const TargetInfo &Target);
/// \brief Retrieve the preprocessor options used to initialize this
/// preprocessor.
PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; }
DiagnosticsEngine &getDiagnostics() const { return *Diags; }
void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; }

View File

@ -270,7 +270,10 @@ namespace clang {
FILE_SYSTEM_OPTIONS = 9,
/// \brief Record code for the headers search options table.
HEADER_SEARCH_OPTIONS = 10
HEADER_SEARCH_OPTIONS = 10,
/// \brief Record code for the preprocessor options table.
PREPROCESSOR_OPTIONS = 11
};
/// \brief Record types that occur within the input-files block

View File

@ -73,6 +73,7 @@ class MacroDefinition;
class NamedDecl;
class OpaqueValueExpr;
class Preprocessor;
class PreprocessorOptions;
class Sema;
class SwitchCase;
class ASTDeserializationListener;
@ -148,6 +149,15 @@ public:
return false;
}
/// \brief Receives the preprocessor options.
///
/// \returns true to indicate the preprocessor options are invalid, or false
/// otherwise.
virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
bool Complain) {
return false;
}
/// \brief Receives the contents of the predefines buffer.
///
/// \param Buffers Information about the predefines buffers.
@ -947,6 +957,8 @@ private:
ASTReaderListener &Listener);
static bool ParseHeaderSearchOptions(const RecordData &Record, bool Complain,
ASTReaderListener &Listener);
static bool ParsePreprocessorOptions(const RecordData &Record, bool Complain,
ASTReaderListener &Listener);
struct RecordLocation {
RecordLocation(ModuleFile *M, uint64_t O)

View File

@ -30,6 +30,7 @@
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Basic/OnDiskHashTable.h"
@ -2035,6 +2036,15 @@ ASTReader::ReadControlBlock(ModuleFile &F,
break;
}
case PREPROCESSOR_OPTIONS: {
bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
if (Listener && &F == *ModuleMgr.begin() &&
ParsePreprocessorOptions(Record, Complain, *Listener) &&
!DisableValidation)
return ConfigurationMismatch;
break;
}
case ORIGINAL_FILE:
F.OriginalSourceFileID = FileID::get(Record[0]);
F.ActualOriginalSourceFileName.assign(BlobStart, BlobLen);
@ -3509,6 +3519,11 @@ bool ASTReader::isAcceptableASTFile(StringRef Filename,
return false;
break;
case PREPROCESSOR_OPTIONS:
if (ParsePreprocessorOptions(Record, false, Validator))
return false;
break;
default:
// No other validation to perform.
break;
@ -3914,6 +3929,36 @@ bool ASTReader::ParseHeaderSearchOptions(const RecordData &Record,
return Listener.ReadHeaderSearchOptions(HSOpts, Complain);
}
bool ASTReader::ParsePreprocessorOptions(const RecordData &Record,
bool Complain,
ASTReaderListener &Listener) {
PreprocessorOptions PPOpts;
unsigned Idx = 0;
// Macro definitions/undefs
for (unsigned N = Record[Idx++]; N; --N) {
std::string Macro = ReadString(Record, Idx);
bool IsUndef = Record[Idx++];
PPOpts.Macros.push_back(std::make_pair(Macro, IsUndef));
}
// Includes
for (unsigned N = Record[Idx++]; N; --N) {
PPOpts.Includes.push_back(ReadString(Record, Idx));
}
// Macro Includes
for (unsigned N = Record[Idx++]; N; --N) {
PPOpts.MacroIncludes.push_back(ReadString(Record, Idx));
}
PPOpts.ImplicitPCHInclude = ReadString(Record, Idx);
PPOpts.ImplicitPTHInclude = ReadString(Record, Idx);
PPOpts.ObjCXXARCStandardLibrary =
static_cast<ObjCXXARCStandardLibraryKind>(Record[Idx++]);
return Listener.ReadPreprocessorOptions(PPOpts, Complain);
}
std::pair<ModuleFile *, unsigned>
ASTReader::getModulePreprocessedEntity(unsigned GlobalIndex) {
GlobalPreprocessedEntityMapType::iterator

View File

@ -29,6 +29,7 @@
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemStatCache.h"
@ -780,7 +781,8 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(DIAGNOSTIC_OPTIONS);
RECORD(FILE_SYSTEM_OPTIONS);
RECORD(HEADER_SEARCH_OPTIONS);
RECORD(PREPROCESSOR_OPTIONS);
BLOCK(INPUT_FILES_BLOCK);
RECORD(INPUT_FILE);
@ -1130,6 +1132,32 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
Record.push_back(HSOpts.UseLibcxx);
Stream.EmitRecord(HEADER_SEARCH_OPTIONS, Record);
// Preprocessor options.
Record.clear();
const PreprocessorOptions &PPOpts = PP.getPreprocessorOpts();
// Macro definitions.
Record.push_back(PPOpts.Macros.size());
for (unsigned I = 0, N = PPOpts.Macros.size(); I != N; ++I) {
AddString(PPOpts.Macros[I].first, Record);
Record.push_back(PPOpts.Macros[I].second);
}
// Includes
Record.push_back(PPOpts.Includes.size());
for (unsigned I = 0, N = PPOpts.Includes.size(); I != N; ++I)
AddString(PPOpts.Includes[I], Record);
// Macro includes
Record.push_back(PPOpts.MacroIncludes.size());
for (unsigned I = 0, N = PPOpts.MacroIncludes.size(); I != N; ++I)
AddString(PPOpts.MacroIncludes[I], Record);
AddString(PPOpts.ImplicitPCHInclude, Record);
AddString(PPOpts.ImplicitPTHInclude, Record);
Record.push_back(static_cast<unsigned>(PPOpts.ObjCXXARCStandardLibrary));
Stream.EmitRecord(PREPROCESSOR_OPTIONS, Record);
// Original file name and file ID
SourceManager &SM = Context.getSourceManager();
if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
@ -1146,11 +1174,10 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
const char *MainFileNameStr = MainFilePath.c_str();
MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr,
isysroot);
RecordData Record;
Record.clear();
Record.push_back(ORIGINAL_FILE);
Record.push_back(SM.getMainFileID().getOpaqueValue());
Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr);
Record.clear();
}
// Original PCH directory