forked from OSchip/llvm-project
Add Preprocessor to CompilerInstance, and move clang-cc CreatePreprocessor to
CompilerInstance::createPreprocessor. llvm-svn: 87088
This commit is contained in:
parent
1b4441915a
commit
aaa148fd36
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
class LLVMContext;
|
||||
|
@ -20,6 +21,7 @@ class LLVMContext;
|
|||
namespace clang {
|
||||
class Diagnostic;
|
||||
class DiagnosticClient;
|
||||
class Preprocessor;
|
||||
class FileManager;
|
||||
class SourceManager;
|
||||
class TargetInfo;
|
||||
|
@ -65,6 +67,9 @@ class CompilerInstance {
|
|||
/// The source manager.
|
||||
llvm::OwningPtr<SourceManager> SourceMgr;
|
||||
|
||||
/// The preprocessor.
|
||||
llvm::OwningPtr<Preprocessor> PP;
|
||||
|
||||
public:
|
||||
/// Create a new compiler instance with the given LLVM context, optionally
|
||||
/// taking ownership of it.
|
||||
|
@ -75,7 +80,10 @@ public:
|
|||
/// @name LLVM Context
|
||||
/// {
|
||||
|
||||
llvm::LLVMContext &getLLVMContext() { return *LLVMContext; }
|
||||
llvm::LLVMContext &getLLVMContext() {
|
||||
assert(LLVMContext && "Compiler instance has no LLVM context!");
|
||||
return *LLVMContext;
|
||||
}
|
||||
|
||||
/// setLLVMContext - Replace the current LLVM context and take ownership of
|
||||
/// \arg Value.
|
||||
|
@ -163,7 +171,10 @@ public:
|
|||
/// @name Diagnostics Engine
|
||||
/// {
|
||||
|
||||
Diagnostic &getDiagnostics() const { return *Diagnostics; }
|
||||
Diagnostic &getDiagnostics() const {
|
||||
assert(Diagnostics && "Compiler instance has no diagnostics!");
|
||||
return *Diagnostics;
|
||||
}
|
||||
|
||||
/// takeDiagnostics - Remove the current diagnostics engine and give ownership
|
||||
/// to the caller.
|
||||
|
@ -189,7 +200,10 @@ public:
|
|||
/// @name Target Info
|
||||
/// {
|
||||
|
||||
TargetInfo &getTarget() const { return *Target; }
|
||||
TargetInfo &getTarget() const {
|
||||
assert(Target && "Compiler instance has no target!");
|
||||
return *Target;
|
||||
}
|
||||
|
||||
/// takeTarget - Remove the current diagnostics engine and give ownership
|
||||
/// to the caller.
|
||||
|
@ -203,7 +217,10 @@ public:
|
|||
/// @name File Manager
|
||||
/// {
|
||||
|
||||
FileManager &getFileManager() const { return *FileMgr; }
|
||||
FileManager &getFileManager() const {
|
||||
assert(FileMgr && "Compiler instance has no file manager!");
|
||||
return *FileMgr;
|
||||
}
|
||||
|
||||
/// takeFileManager - Remove the current file manager and give ownership to
|
||||
/// the caller.
|
||||
|
@ -217,7 +234,10 @@ public:
|
|||
/// @name Source Manager
|
||||
/// {
|
||||
|
||||
SourceManager &getSourceManager() const { return *SourceMgr; }
|
||||
SourceManager &getSourceManager() const {
|
||||
assert(SourceMgr && "Compiler instance has no source manager!");
|
||||
return *SourceMgr;
|
||||
}
|
||||
|
||||
/// takeSourceManager - Remove the current source manager and give ownership
|
||||
/// to the caller.
|
||||
|
@ -227,6 +247,23 @@ public:
|
|||
/// instance takes ownership of \arg Value.
|
||||
void setSourceManager(SourceManager *Value) { SourceMgr.reset(Value); }
|
||||
|
||||
/// }
|
||||
/// @name Preprocessor
|
||||
/// {
|
||||
|
||||
Preprocessor &getPreprocessor() const {
|
||||
assert(PP && "Compiler instance has no preprocessor!");
|
||||
return *PP;
|
||||
}
|
||||
|
||||
/// takePreprocessor - Remove the current preprocessor and give ownership to
|
||||
/// the caller.
|
||||
Preprocessor *takePreprocessor() { return PP.take(); }
|
||||
|
||||
/// setPreprocessor - Replace the current preprocessor; the compiler instance
|
||||
/// takes ownership of \arg Value.
|
||||
void setPreprocessor(Preprocessor *Value) { PP.reset(Value); }
|
||||
|
||||
/// }
|
||||
/// @name Construction Utility Methods
|
||||
/// {
|
||||
|
@ -237,6 +274,23 @@ public:
|
|||
/// Create the source manager and replace any existing one with it.
|
||||
void createSourceManager();
|
||||
|
||||
/// Create the preprocessor, using the invocation, file, and source managers,
|
||||
/// and replace any existing one with it.
|
||||
void createPreprocessor();
|
||||
|
||||
/// Create a Preprocessor object.
|
||||
///
|
||||
/// Note that this also creates a new HeaderSearch object which will be owned
|
||||
/// by the resulting Preprocessor.
|
||||
///
|
||||
/// \return The new object on success, or null on failure.
|
||||
static Preprocessor *createPreprocessor(Diagnostic &, const LangOptions &,
|
||||
const PreprocessorOptions &,
|
||||
const HeaderSearchOptions &,
|
||||
const DependencyOutputOptions &,
|
||||
const TargetInfo &,
|
||||
SourceManager &, FileManager &);
|
||||
|
||||
/// }
|
||||
};
|
||||
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Lex/HeaderSearch.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "clang/Lex/PTHManager.h"
|
||||
#include "clang/Frontend/Utils.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
using namespace clang;
|
||||
|
||||
|
@ -33,3 +37,51 @@ void CompilerInstance::createFileManager() {
|
|||
void CompilerInstance::createSourceManager() {
|
||||
SourceMgr.reset(new SourceManager());
|
||||
}
|
||||
|
||||
void CompilerInstance::createPreprocessor() {
|
||||
PP.reset(createPreprocessor(getDiagnostics(), getLangOpts(),
|
||||
getPreprocessorOpts(), getHeaderSearchOpts(),
|
||||
getDependencyOutputOpts(), getTarget(),
|
||||
getSourceManager(), getFileManager()));
|
||||
}
|
||||
|
||||
Preprocessor *
|
||||
CompilerInstance::createPreprocessor(Diagnostic &Diags,
|
||||
const LangOptions &LangInfo,
|
||||
const PreprocessorOptions &PPOpts,
|
||||
const HeaderSearchOptions &HSOpts,
|
||||
const DependencyOutputOptions &DepOpts,
|
||||
const TargetInfo &Target,
|
||||
SourceManager &SourceMgr,
|
||||
FileManager &FileMgr) {
|
||||
// Create a PTH manager if we are using some form of a token cache.
|
||||
PTHManager *PTHMgr = 0;
|
||||
if (!PPOpts.getTokenCache().empty())
|
||||
PTHMgr = PTHManager::Create(PPOpts.getTokenCache(), Diags);
|
||||
|
||||
// FIXME: Don't fail like this.
|
||||
if (Diags.hasErrorOccurred())
|
||||
exit(1);
|
||||
|
||||
// Create the Preprocessor.
|
||||
HeaderSearch *HeaderInfo = new HeaderSearch(FileMgr);
|
||||
Preprocessor *PP = new Preprocessor(Diags, LangInfo, Target,
|
||||
SourceMgr, *HeaderInfo, PTHMgr,
|
||||
/*OwnsHeaderSearch=*/true);
|
||||
|
||||
// Note that this is different then passing PTHMgr to Preprocessor's ctor.
|
||||
// That argument is used as the IdentifierInfoLookup argument to
|
||||
// IdentifierTable's ctor.
|
||||
if (PTHMgr) {
|
||||
PTHMgr->setPreprocessor(PP);
|
||||
PP->setPTHManager(PTHMgr);
|
||||
}
|
||||
|
||||
InitializePreprocessor(*PP, PPOpts, HSOpts);
|
||||
|
||||
// Handle generating dependencies, if requested.
|
||||
if (!DepOpts.OutputFile.empty())
|
||||
AttachDependencyFileGen(*PP, DepOpts);
|
||||
|
||||
return PP;
|
||||
}
|
||||
|
|
|
@ -219,45 +219,6 @@ std::string GetBuiltinIncludePath(const char *Argv0) {
|
|||
return P.str();
|
||||
}
|
||||
|
||||
static Preprocessor *
|
||||
CreatePreprocessor(Diagnostic &Diags, const LangOptions &LangInfo,
|
||||
const PreprocessorOptions &PPOpts,
|
||||
const HeaderSearchOptions &HSOpts,
|
||||
const DependencyOutputOptions &DepOpts,
|
||||
const TargetInfo &Target, SourceManager &SourceMgr,
|
||||
FileManager &FileMgr) {
|
||||
// Create a PTH manager if we are using some form of a token cache.
|
||||
PTHManager *PTHMgr = 0;
|
||||
if (!PPOpts.getTokenCache().empty())
|
||||
PTHMgr = PTHManager::Create(PPOpts.getTokenCache(), Diags);
|
||||
|
||||
// FIXME: Don't fail like this.
|
||||
if (Diags.hasErrorOccurred())
|
||||
exit(1);
|
||||
|
||||
// Create the Preprocessor.
|
||||
HeaderSearch *HeaderInfo = new HeaderSearch(FileMgr);
|
||||
Preprocessor *PP = new Preprocessor(Diags, LangInfo, Target,
|
||||
SourceMgr, *HeaderInfo, PTHMgr,
|
||||
/*OwnsHeaderSearch=*/true);
|
||||
|
||||
// Note that this is different then passing PTHMgr to Preprocessor's ctor.
|
||||
// That argument is used as the IdentifierInfoLookup argument to
|
||||
// IdentifierTable's ctor.
|
||||
if (PTHMgr) {
|
||||
PTHMgr->setPreprocessor(PP);
|
||||
PP->setPTHManager(PTHMgr);
|
||||
}
|
||||
|
||||
InitializePreprocessor(*PP, PPOpts, HSOpts);
|
||||
|
||||
// Handle generating dependencies, if requested.
|
||||
if (!DepOpts.OutputFile.empty())
|
||||
AttachDependencyFileGen(*PP, DepOpts);
|
||||
|
||||
return PP;
|
||||
}
|
||||
|
||||
/// \brief Buld a new code-completion consumer that prints the results of
|
||||
/// code completion to standard output.
|
||||
static CodeCompleteConsumer *BuildPrintingCodeCompleter(Sema &S,
|
||||
|
@ -499,9 +460,9 @@ static ExternalASTSource *ReadPCHFile(llvm::StringRef Path,
|
|||
}
|
||||
|
||||
/// ProcessInputFile - Process a single input file with the specified state.
|
||||
///
|
||||
static void ProcessInputFile(CompilerInstance &CI, Preprocessor &PP,
|
||||
const std::string &InFile, ProgActions PA) {
|
||||
static void ProcessInputFile(CompilerInstance &CI, const std::string &InFile,
|
||||
ProgActions PA) {
|
||||
Preprocessor &PP = CI.getPreprocessor();
|
||||
const FrontendOptions &FEOpts = CI.getFrontendOpts();
|
||||
llvm::OwningPtr<llvm::raw_ostream> OS;
|
||||
llvm::OwningPtr<ASTConsumer> Consumer;
|
||||
|
@ -759,8 +720,8 @@ static void ProcessInputFile(CompilerInstance &CI, Preprocessor &PP,
|
|||
OutPath.eraseFromDisk();
|
||||
}
|
||||
|
||||
/// ProcessInputFile - Process a single AST input file with the specified state.
|
||||
///
|
||||
/// ProcessASTInputFile - Process a single AST input file with the specified
|
||||
/// state.
|
||||
static void ProcessASTInputFile(CompilerInstance &CI, const std::string &InFile,
|
||||
ProgActions PA) {
|
||||
std::string Error;
|
||||
|
@ -1006,18 +967,12 @@ int main(int argc, char **argv) {
|
|||
if (i)
|
||||
Clang.getSourceManager().clearIDTables();
|
||||
|
||||
// Set up the preprocessor with these options.
|
||||
llvm::OwningPtr<Preprocessor>
|
||||
PP(CreatePreprocessor(Clang.getDiagnostics(), Clang.getLangOpts(),
|
||||
Clang.getPreprocessorOpts(),
|
||||
Clang.getHeaderSearchOpts(),
|
||||
Clang.getDependencyOutputOpts(),
|
||||
Clang.getTarget(), Clang.getSourceManager(),
|
||||
Clang.getFileManager()));
|
||||
// Create the preprocessor.
|
||||
Clang.createPreprocessor();
|
||||
|
||||
// Process the source file.
|
||||
Clang.getDiagnostics().getClient()->BeginSourceFile(Clang.getLangOpts());
|
||||
ProcessInputFile(Clang, *PP, InFile, ProgAction);
|
||||
ProcessInputFile(Clang, InFile, ProgAction);
|
||||
Clang.getDiagnostics().getClient()->EndSourceFile();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue