Allow the preprocessor to be constructed without performing target-

and language-specific initialization. Use this to allow ASTUnit to
create a preprocessor object *before* loading the AST file. No actual
functionality change.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138983 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2011-09-01 23:39:15 +00:00
Родитель db44a6b007
Коммит 998b3d3e85
6 изменённых файлов: 137 добавлений и 92 удалений

Просмотреть файл

@ -62,8 +62,11 @@ class Context {
const Info *TSRecords;
unsigned NumTSRecords;
public:
Context(const TargetInfo &Target);
Context();
/// \brief Perform target-specific initialization
void InitializeTarget(const TargetInfo &Target);
/// InitializeBuiltins - Mark the identifiers for all the builtins with their
/// appropriate builtin ID # and mark any non-portable builtin identifiers as
/// such.

Просмотреть файл

@ -59,7 +59,7 @@ class ModuleLoader;
class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
Diagnostic *Diags;
LangOptions &Features;
const TargetInfo &Target;
const TargetInfo *Target;
FileManager &FileMgr;
SourceManager &SourceMgr;
ScratchBuffer *ScratchBuf;
@ -295,19 +295,26 @@ private: // Cached tokens state.
public:
Preprocessor(Diagnostic &diags, LangOptions &opts,
const TargetInfo &target,
const TargetInfo *target,
SourceManager &SM, HeaderSearch &Headers,
ModuleLoader &TheModuleLoader,
IdentifierInfoLookup *IILookup = 0,
bool OwnsHeaderSearch = false);
bool OwnsHeaderSearch = false,
bool DelayInitialization = false);
~Preprocessor();
/// \brief Initialize the preprocessor, if the constructor did not already
/// perform the initialization.
///
/// \param Target Information about the target.
void Initialize(const TargetInfo &Target);
Diagnostic &getDiagnostics() const { return *Diags; }
void setDiagnostics(Diagnostic &D) { Diags = &D; }
const LangOptions &getLangOptions() const { return Features; }
const TargetInfo &getTargetInfo() const { return Target; }
const TargetInfo &getTargetInfo() const { return *Target; }
FileManager &getFileManager() const { return FileMgr; }
SourceManager &getSourceManager() const { return SourceMgr; }
HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }

Просмотреть файл

@ -32,11 +32,15 @@ const Builtin::Info &Builtin::Context::GetRecord(unsigned ID) const {
return TSRecords[ID - Builtin::FirstTSBuiltin];
}
Builtin::Context::Context(const TargetInfo &Target) {
Builtin::Context::Context() {
// Get the target specific builtins from the target.
TSRecords = 0;
NumTSRecords = 0;
Target.getTargetBuiltins(TSRecords, NumTSRecords);
}
void Builtin::Context::InitializeTarget(const TargetInfo &Target) {
assert(NumTSRecords == 0 && "Already initialized target?");
Target.getTargetBuiltins(TSRecords, NumTSRecords);
}
/// InitializeBuiltins - Mark the identifiers for all the builtins with their

Просмотреть файл

@ -376,28 +376,51 @@ namespace {
/// \brief Gathers information from ASTReader that will be used to initialize
/// a Preprocessor.
class ASTInfoCollector : public ASTReaderListener {
Preprocessor &PP;
LangOptions &LangOpt;
HeaderSearch &HSI;
std::string &TargetTriple;
llvm::IntrusiveRefCntPtr<TargetInfo> &Target;
std::string &Predefines;
unsigned &Counter;
unsigned NumHeaderInfos;
bool InitializedPreprocessor;
public:
ASTInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI,
std::string &TargetTriple, std::string &Predefines,
ASTInfoCollector(Preprocessor &PP,
LangOptions &LangOpt, HeaderSearch &HSI,
llvm::IntrusiveRefCntPtr<TargetInfo> &Target,
std::string &Predefines,
unsigned &Counter)
: LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple),
Predefines(Predefines), Counter(Counter), NumHeaderInfos(0) {}
: PP(PP), LangOpt(LangOpt), HSI(HSI), Target(Target),
Predefines(Predefines), Counter(Counter), NumHeaderInfos(0),
InitializedPreprocessor(false) {}
virtual bool ReadLanguageOptions(const LangOptions &LangOpts) {
if (InitializedPreprocessor)
return false;
LangOpt = LangOpts;
// Initialize the preprocessor.
PP.Initialize(*Target);
InitializedPreprocessor = true;
return false;
}
virtual bool ReadTargetTriple(StringRef Triple) {
TargetTriple = Triple;
// If we've already initialized the target, don't do it again.
if (Target)
return false;
// FIXME: This is broken, we should store the TargetOptions in the AST file.
TargetOptions TargetOpts;
TargetOpts.ABI = "";
TargetOpts.CXXABI = "";
TargetOpts.CPU = "";
TargetOpts.Features.clear();
TargetOpts.Triple = Triple;
Target = TargetInfo::CreateTargetInfo(PP.getDiagnostics(), TargetOpts);
return false;
}
@ -573,12 +596,18 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,
// Gather Info for preprocessor construction later on.
HeaderSearch &HeaderInfo = *AST->HeaderInfo.get();
std::string TargetTriple;
std::string Predefines;
unsigned Counter;
llvm::OwningPtr<ASTReader> Reader;
AST->PP = new Preprocessor(AST->getDiagnostics(), AST->ASTFileLangOpts,
/*Target=*/0, AST->getSourceManager(), HeaderInfo,
*AST,
/*IILookup=*/0,
/*OwnsHeaderSearch=*/false,
/*DelayInitialization=*/true);
Reader.reset(new ASTReader(AST->getSourceManager(), AST->getFileManager(),
AST->getDiagnostics()));
@ -586,8 +615,9 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,
llvm::CrashRecoveryContextCleanupRegistrar<ASTReader>
ReaderCleanup(Reader.get());
Reader->setListener(new ASTInfoCollector(AST->ASTFileLangOpts, HeaderInfo,
TargetTriple, Predefines, Counter));
Reader->setListener(new ASTInfoCollector(*AST->PP,
AST->ASTFileLangOpts, HeaderInfo,
AST->Target, Predefines, Counter));
switch (Reader->ReadAST(Filename, serialization::MK_MainFile)) {
case ASTReader::Success:
@ -602,21 +632,6 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,
AST->OriginalSourceFile = Reader->getOriginalSourceFile();
// AST file loaded successfully. Now create the preprocessor.
// Get information about the target being compiled for.
//
// FIXME: This is broken, we should store the TargetOptions in the AST file.
TargetOptions TargetOpts;
TargetOpts.ABI = "";
TargetOpts.CXXABI = "";
TargetOpts.CPU = "";
TargetOpts.Features.clear();
TargetOpts.Triple = TargetTriple;
AST->Target = TargetInfo::CreateTargetInfo(AST->getDiagnostics(),
TargetOpts);
AST->PP = new Preprocessor(AST->getDiagnostics(), AST->ASTFileLangOpts,
*AST->Target, AST->getSourceManager(), HeaderInfo,
*AST);
Preprocessor &PP = *AST->PP;
PP.setPredefines(Reader->getSuggestedPredefines());

Просмотреть файл

@ -200,7 +200,7 @@ void CompilerInstance::createPreprocessor() {
// Create the Preprocessor.
HeaderSearch *HeaderInfo = new HeaderSearch(getFileManager());
PP = new Preprocessor(getDiagnostics(), getLangOpts(), getTarget(),
PP = new Preprocessor(getDiagnostics(), getLangOpts(), &getTarget(),
getSourceManager(), *HeaderInfo, *this, PTHMgr,
/*OwnsHeaderSearch=*/true);

Просмотреть файл

@ -50,75 +50,25 @@ using namespace clang;
ExternalPreprocessorSource::~ExternalPreprocessorSource() { }
Preprocessor::Preprocessor(Diagnostic &diags, LangOptions &opts,
const TargetInfo &target, SourceManager &SM,
const TargetInfo *target, SourceManager &SM,
HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
IdentifierInfoLookup* IILookup,
bool OwnsHeaders)
bool OwnsHeaders,
bool DelayInitialization)
: Diags(&diags), Features(opts), Target(target),FileMgr(Headers.getFileMgr()),
SourceMgr(SM), HeaderInfo(Headers), TheModuleLoader(TheModuleLoader),
ExternalSource(0),
Identifiers(opts, IILookup), BuiltinInfo(Target), CodeComplete(0),
Identifiers(opts, IILookup), CodeComplete(0),
CodeCompletionFile(0), SkipMainFilePreamble(0, true), CurPPLexer(0),
CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0), MIChainHead(0),
MICache(0) {
ScratchBuf = new ScratchBuffer(SourceMgr);
CounterValue = 0; // __COUNTER__ starts at 0.
MICache(0)
{
OwnsHeaderSearch = OwnsHeaders;
// Clear stats.
NumDirectives = NumDefined = NumUndefined = NumPragma = 0;
NumIf = NumElse = NumEndif = 0;
NumEnteredSourceFiles = 0;
NumMacroExpanded = NumFnMacroExpanded = NumBuiltinMacroExpanded = 0;
NumFastMacroExpanded = NumTokenPaste = NumFastTokenPaste = 0;
MaxIncludeStackDepth = 0;
NumSkipped = 0;
// Default to discarding comments.
KeepComments = false;
KeepMacroComments = false;
SuppressIncludeNotFoundError = false;
// Macro expansion is enabled.
DisableMacroExpansion = false;
InMacroArgs = false;
NumCachedTokenLexers = 0;
CachedLexPos = 0;
// We haven't read anything from the external source.
ReadMacrosFromExternalSource = false;
LexDepth = 0;
// "Poison" __VA_ARGS__, which can only appear in the expansion of a macro.
// This gets unpoisoned where it is allowed.
(Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned();
SetPoisonReason(Ident__VA_ARGS__,diag::ext_pp_bad_vaargs_use);
// Initialize the pragma handlers.
PragmaHandlers = new PragmaNamespace(StringRef());
RegisterBuiltinPragmas();
// Initialize builtin macros like __LINE__ and friends.
RegisterBuiltinMacros();
if(Features.Borland) {
Ident__exception_info = getIdentifierInfo("_exception_info");
Ident___exception_info = getIdentifierInfo("__exception_info");
Ident_GetExceptionInfo = getIdentifierInfo("GetExceptionInformation");
Ident__exception_code = getIdentifierInfo("_exception_code");
Ident___exception_code = getIdentifierInfo("__exception_code");
Ident_GetExceptionCode = getIdentifierInfo("GetExceptionCode");
Ident__abnormal_termination = getIdentifierInfo("_abnormal_termination");
Ident___abnormal_termination = getIdentifierInfo("__abnormal_termination");
Ident_AbnormalTermination = getIdentifierInfo("AbnormalTermination");
} else {
Ident__exception_info = Ident__exception_code = Ident__abnormal_termination = 0;
Ident___exception_info = Ident___exception_code = Ident___abnormal_termination = 0;
Ident_GetExceptionInfo = Ident_GetExceptionCode = Ident_AbnormalTermination = 0;
if (!DelayInitialization) {
assert(Target && "Must provide target information for PP initialization");
Initialize(*Target);
}
}
Preprocessor::~Preprocessor() {
@ -157,6 +107,72 @@ Preprocessor::~Preprocessor() {
delete Callbacks;
}
void Preprocessor::Initialize(const TargetInfo &Target) {
assert((!this->Target || this->Target == &Target) &&
"Invalid override of target information");
this->Target = &Target;
// Initialize information about built-ins.
BuiltinInfo.InitializeTarget(Target);
ScratchBuf = new ScratchBuffer(SourceMgr);
CounterValue = 0; // __COUNTER__ starts at 0.
// Clear stats.
NumDirectives = NumDefined = NumUndefined = NumPragma = 0;
NumIf = NumElse = NumEndif = 0;
NumEnteredSourceFiles = 0;
NumMacroExpanded = NumFnMacroExpanded = NumBuiltinMacroExpanded = 0;
NumFastMacroExpanded = NumTokenPaste = NumFastTokenPaste = 0;
MaxIncludeStackDepth = 0;
NumSkipped = 0;
// Default to discarding comments.
KeepComments = false;
KeepMacroComments = false;
SuppressIncludeNotFoundError = false;
// Macro expansion is enabled.
DisableMacroExpansion = false;
InMacroArgs = false;
NumCachedTokenLexers = 0;
CachedLexPos = 0;
// We haven't read anything from the external source.
ReadMacrosFromExternalSource = false;
LexDepth = 0;
// "Poison" __VA_ARGS__, which can only appear in the expansion of a macro.
// This gets unpoisoned where it is allowed.
(Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned();
SetPoisonReason(Ident__VA_ARGS__,diag::ext_pp_bad_vaargs_use);
// Initialize the pragma handlers.
PragmaHandlers = new PragmaNamespace(StringRef());
RegisterBuiltinPragmas();
// Initialize builtin macros like __LINE__ and friends.
RegisterBuiltinMacros();
if(Features.Borland) {
Ident__exception_info = getIdentifierInfo("_exception_info");
Ident___exception_info = getIdentifierInfo("__exception_info");
Ident_GetExceptionInfo = getIdentifierInfo("GetExceptionInformation");
Ident__exception_code = getIdentifierInfo("_exception_code");
Ident___exception_code = getIdentifierInfo("__exception_code");
Ident_GetExceptionCode = getIdentifierInfo("GetExceptionCode");
Ident__abnormal_termination = getIdentifierInfo("_abnormal_termination");
Ident___abnormal_termination = getIdentifierInfo("__abnormal_termination");
Ident_AbnormalTermination = getIdentifierInfo("AbnormalTermination");
} else {
Ident__exception_info = Ident__exception_code = Ident__abnormal_termination = 0;
Ident___exception_info = Ident___exception_code = Ident___abnormal_termination = 0;
Ident_GetExceptionInfo = Ident_GetExceptionCode = Ident_AbnormalTermination = 0;
}
}
void Preprocessor::setPTHManager(PTHManager* pm) {
PTH.reset(pm);
FileMgr.addStatCache(PTH->createStatCache());