зеркало из https://github.com/microsoft/clang.git
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:
Родитель
db44a6b007
Коммит
998b3d3e85
|
@ -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());
|
||||
|
|
Загрузка…
Ссылка в новой задаче