diff options
Diffstat (limited to 'lib/Frontend/CompilerInstance.cpp')
-rw-r--r-- | lib/Frontend/CompilerInstance.cpp | 93 |
1 files changed, 91 insertions, 2 deletions
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 2a6a8a8..19c740d 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -14,10 +14,12 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/Version.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PTHManager.h" #include "clang/Frontend/ChainedDiagnosticClient.h" +#include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/PCHReader.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/TextDiagnosticPrinter.h" @@ -28,6 +30,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Timer.h" +#include "llvm/System/Host.h" #include "llvm/System/Path.h" #include "llvm/System/Program.h" using namespace clang; @@ -155,7 +158,8 @@ void CompilerInstance::createPreprocessor() { PP.reset(createPreprocessor(getDiagnostics(), getLangOpts(), getPreprocessorOpts(), getHeaderSearchOpts(), getDependencyOutputOpts(), getTarget(), - getSourceManager(), getFileManager())); + getFrontendOpts(), getSourceManager(), + getFileManager())); } Preprocessor * @@ -165,6 +169,7 @@ CompilerInstance::createPreprocessor(Diagnostic &Diags, const HeaderSearchOptions &HSOpts, const DependencyOutputOptions &DepOpts, const TargetInfo &Target, + const FrontendOptions &FEOpts, SourceManager &SourceMgr, FileManager &FileMgr) { // Create a PTH manager if we are using some form of a token cache. @@ -186,7 +191,7 @@ CompilerInstance::createPreprocessor(Diagnostic &Diags, PP->setPTHManager(PTHMgr); } - InitializePreprocessor(*PP, PPOpts, HSOpts); + InitializePreprocessor(*PP, PPOpts, HSOpts, FEOpts); // Handle generating dependencies, if requested. if (!DepOpts.OutputFile.empty()) @@ -409,3 +414,87 @@ bool CompilerInstance::InitializeSourceManager(llvm::StringRef InputFile, return true; } + +// High-Level Operations + +bool CompilerInstance::ExecuteAction(FrontendAction &Act) { + assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); + assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); + assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); + + // FIXME: Take this as an argument, once all the APIs we used have moved to + // taking it as an input instead of hard-coding llvm::errs. + llvm::raw_ostream &OS = llvm::errs(); + + // Create the target instance. + setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), getTargetOpts())); + if (!hasTarget()) + return false; + + // Inform the target of the language options. + // + // FIXME: We shouldn't need to do this, the target should be immutable once + // created. This complexity should be lifted elsewhere. + getTarget().setForcedLangOptions(getLangOpts()); + + // Validate/process some options. + if (getHeaderSearchOpts().Verbose) + OS << "clang -cc1 version " CLANG_VERSION_STRING + << " based upon " << PACKAGE_STRING + << " hosted on " << llvm::sys::getHostTriple() << "\n"; + + if (getFrontendOpts().ShowTimers) + createFrontendTimer(); + + for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) { + const std::string &InFile = getFrontendOpts().Inputs[i].second; + + // If we aren't using an AST file, setup the file and source managers and + // the preprocessor. + bool IsAST = getFrontendOpts().Inputs[i].first == FrontendOptions::IK_AST; + if (!IsAST) { + if (!i) { + // Create a file manager object to provide access to and cache the + // filesystem. + createFileManager(); + + // Create the source manager. + createSourceManager(); + } else { + // Reset the ID tables if we are reusing the SourceManager. + getSourceManager().clearIDTables(); + } + + // Create the preprocessor. + createPreprocessor(); + } + + if (Act.BeginSourceFile(*this, InFile, IsAST)) { + Act.Execute(); + Act.EndSourceFile(); + } + } + + if (getDiagnosticOpts().ShowCarets) + if (unsigned NumDiagnostics = getDiagnostics().getNumDiagnostics()) + OS << NumDiagnostics << " diagnostic" + << (NumDiagnostics == 1 ? "" : "s") + << " generated.\n"; + + if (getFrontendOpts().ShowStats) { + getFileManager().PrintStats(); + OS << "\n"; + } + + // Return the appropriate status when verifying diagnostics. + // + // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need + // this. + if (getDiagnosticOpts().VerifyDiagnostics) + return !static_cast<VerifyDiagnosticsClient&>( + getDiagnosticClient()).HadErrors(); + + return !getDiagnostics().getNumErrors(); +} + + |