Add Preprocessor to CompilerInstance, and move clang-cc CreatePreprocessor to

CompilerInstance::createPreprocessor.

llvm-svn: 87088
This commit is contained in:
Daniel Dunbar 2009-11-13 05:52:11 +00:00
parent 1b4441915a
commit aaa148fd36
3 changed files with 119 additions and 58 deletions

View File

@ -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 &);
/// }
};

View File

@ -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;
}

View File

@ -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();
}