142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "Compiler.h"
242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include <cassert>
442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include <cstdlib>
542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include <string>
642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include <vector>
742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/AST/ASTConsumer.h"
942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/AST/ASTContext.h"
1042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
1142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Basic/DiagnosticIDs.h"
1242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Basic/FileManager.h"
1342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Basic/FileSystemOptions.h"
1442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Basic/LangOptions.h"
1542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Basic/SourceManager.h"
1642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Basic/TargetInfo.h"
1742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Basic/TargetOptions.h"
1842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
1942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Frontend/CodeGenOptions.h"
2042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Frontend/DiagnosticOptions.h"
2142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Frontend/DependencyOutputOptions.h"
2242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Frontend/CompilerInstance.h"
2342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Frontend/FrontendDiagnostic.h"
2442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Frontend/TextDiagnosticPrinter.h"
2542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Frontend/Utils.h"
2642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
2742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Lex/Preprocessor.h"
2842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Lex/HeaderSearch.h"
2942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
3042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "clang/Parse/ParseAST.h"
3142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
3242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "llvm/LLVMContext.h"
3342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
3442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "llvm/ADT/IntrusiveRefCntPtr.h"
3542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
3642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "llvm/Bitcode/ReaderWriter.h"
3742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
3842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "llvm/Support/raw_ostream.h"
3942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "llvm/Support/MemoryBuffer.h"
4042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "llvm/Support/ErrorHandling.h"
4142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "llvm/Support/ManagedStatic.h"
4242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "llvm/Support/ToolOutputFile.h"
4342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "llvm/Support/Path.h"
4442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
4542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "llvm/Support/TargetSelect.h"
4642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
4742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh#include "Backend.h"
4842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
4942552ec6168d994991696a04c1626ac91218a720Andrew Hsiehnamespace ndkpc {
5042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
5142552ec6168d994991696a04c1626ac91218a720Andrew Hsiehstatic inline llvm::tool_output_file *openOutputFile(const char *OutputFile,
5242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                                     unsigned Flags,
5342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                                     std::string* Error,
5442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                                     clang::DiagnosticsEngine* Diag) {
5542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  assert((OutputFile != NULL) && (Error != NULL) && (Diag != NULL) &&
5642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh              "Invalid parameter!");
5742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
5842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  llvm::tool_output_file *F =
5942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh        new llvm::tool_output_file(OutputFile, *Error, Flags);
6042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  if (F != NULL)
6142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    return F;
6242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
6342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  // Report error here.
6442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  Diag->Report(clang::diag::err_fe_error_opening) << OutputFile << *Error;
6542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
6642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return NULL;
6742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
6842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
6942552ec6168d994991696a04c1626ac91218a720Andrew Hsiehvoid Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
7042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  clang::DiagnosticsEngine* Diags = static_cast<clang::DiagnosticsEngine*>(UserData);
7142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  Diags->Report(clang::diag::err_fe_error_backend) << Message;
7242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  exit(1);
7342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
7442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
7542552ec6168d994991696a04c1626ac91218a720Andrew Hsiehvoid Compiler::createDiagnostic() {
7642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mpDiagClient = new clang::TextDiagnosticPrinter(llvm::errs(),
7742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                                 clang::DiagnosticOptions());
7842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mDiagIDs = new clang::DiagnosticIDs();
7942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mDiagnostics = new clang::DiagnosticsEngine(mDiagIDs, mpDiagClient);
8042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  initDiagnostic();
8142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return;
8242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
8342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
8442552ec6168d994991696a04c1626ac91218a720Andrew Hsiehvoid Compiler::createTarget(const std::string &Triple, const std::string &CPU,
8542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                         const std::vector<std::string> &Features) {
8642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  if (!Triple.empty())
8742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    mTargetOpts.Triple = Triple;
8842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  else
8942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    mTargetOpts.Triple = llvm::Triple::normalize(DEFAULT_TARGET_TRIPLE_STRING);
9042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
9142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  if (!CPU.empty())
9242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    mTargetOpts.CPU = CPU;
9342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
9442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  if (!Features.empty())
9542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    mTargetOpts.Features = Features;
9642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
9742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagnostics,
9842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                                    mTargetOpts));
9942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
10042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return;
10142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
10242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
10342552ec6168d994991696a04c1626ac91218a720Andrew Hsiehvoid Compiler::createFileManager() {
10442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mFileSysOpt.reset(new clang::FileSystemOptions());
10542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mFileMgr.reset(new clang::FileManager(*mFileSysOpt));
10642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
10742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
10842552ec6168d994991696a04c1626ac91218a720Andrew Hsiehvoid Compiler::createSourceManager() {
10942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mSourceMgr.reset(new clang::SourceManager(*mDiagnostics, *mFileMgr));
11042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return;
11142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
11242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
11342552ec6168d994991696a04c1626ac91218a720Andrew Hsiehvoid Compiler::createPreprocessor() {
11442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  clang::HeaderSearch *HS = new clang::HeaderSearch(*mFileMgr,
11542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh						    *mDiagnostics,
11642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh						    mLangOpts,
11742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh						    mTarget.get());
11842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
11942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  llvm::OwningPtr<clang::CompilerInstance> Clang(new clang::CompilerInstance());
12078f458bce9998570544356ed5b41afb0a8625ceeShih-wei Liao
12142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mPP.reset(new clang::Preprocessor(*mDiagnostics,
12242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                    mLangOpts,
12342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                    mTarget.get(),
12442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                    *mSourceMgr,
12542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                    *HS,
12642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh				    *Clang,
12742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                    /* IILookup */0,
12842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                    /* OwnsHeaderSearch = */true,
12942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                    /*DelayInitialization=*/true));
13042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
13142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  std::vector<clang::DirectoryLookup> SearchList;
13242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
13342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    if (const clang::DirectoryEntry *DE =
13442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh            mFileMgr->getDirectory(mIncludePaths[i])) {
13542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh      SearchList.push_back(clang::DirectoryLookup(DE,
13642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                                  clang::SrcMgr::C_System,
13742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                                  false, /* isUser */
13842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                                  false /* isFramework */));
13942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    }
14042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  }
14142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
14242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  HS->SetSearchPaths(SearchList, 0/* angledDirIdx FIXME CHECK */, 0/* systemDirIdx */, false/* noCurDirSearch */);
14342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
14442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  initPreprocessor();
14542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return;
14642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
14742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
14842552ec6168d994991696a04c1626ac91218a720Andrew Hsiehvoid Compiler::createASTContext() {
14942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mASTContext.reset(new clang::ASTContext(mLangOpts,
15042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                          *mSourceMgr,
15142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                          mTarget.get(),
15242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                          mPP->getIdentifierTable(),
15342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                          mPP->getSelectorTable(),
15442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                          mPP->getBuiltinInfo(),
15542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                          /* size_reserve = */0,
15642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                                          /*DelayInitialization=*/true));
15742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  initASTContext();
15842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return;
15942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
16042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
16142552ec6168d994991696a04c1626ac91218a720Andrew Hsiehclang::ASTConsumer
16242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh*Compiler::createBackend(const clang::CodeGenOptions& CodeGenOpts,
16342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                      llvm::raw_ostream *OS,
16442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                      OutputType OT) {
16542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return new Backend(CodeGenOpts,
16642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                     mTargetOpts,
16742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                     mDiagnostics.getPtr(),
16842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                     OS,
16942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                     OT);
17042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
17142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
17242552ec6168d994991696a04c1626ac91218a720Andrew HsiehCompiler::Compiler() : mInitialized(false), mpDiagClient(NULL), mOT(OT_Default) {
17342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
17442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
17542552ec6168d994991696a04c1626ac91218a720Andrew Hsiehvoid Compiler::injectPreDefined() {
17642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  typedef std::map<std::string, std::string> SymbolMapTy;
17742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  for (SymbolMapTy::iterator
17842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh          it = mPreDefinedSymbolMap.begin(), et = mPreDefinedSymbolMap.end();
17942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh       it != et; ++it) {
18042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    std::string Str = "#define "+it->first+" "+it->second+"\n";
18142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    mPP->setPredefines(Str);
18242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  }
18342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
18442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
18542552ec6168d994991696a04c1626ac91218a720Andrew Hsiehvoid Compiler::init(const std::string &Triple, const std::string &CPU,
18642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                    const std::vector<std::string> &Features, bool isCXX) {
18742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mLangOpts.RTTI = 0;  // Turn off the RTTI information support
18842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mLangOpts.C99 = 1;
18942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  if (isCXX) {
19042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    mLangOpts.CPlusPlus = 1;
19142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  }
19242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
19342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mCodeGenOpts.OptimizationLevel = 3;  /* -O3 */
19442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
19542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  createDiagnostic();
19642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.getPtr());
19742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
19842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  createTarget(Triple, CPU, Features);
19942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  createFileManager();
20042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  createSourceManager();
20142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
20242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mInitialized = true;
20342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
20442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return;
20542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
20642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
20742552ec6168d994991696a04c1626ac91218a720Andrew Hsiehbool Compiler::setInputSource(llvm::StringRef InputFile,
20842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                              const char *Text,
20942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                              size_t TextLength) {
21042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mInputFileName = InputFile.str();
21142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
21242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  // Reset the ID tables if we are reusing the SourceManager
21342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mSourceMgr->clearIDTables();
21442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
21542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  // Load the source
21642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  llvm::MemoryBuffer *SB =
21742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh      llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength);
21842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mSourceMgr->createMainFileIDForMemBuffer(SB);
21942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
22042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  if (mSourceMgr->getMainFileID().isInvalid()) {
22142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
22242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    return false;
22342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  }
22442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return true;
22542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
22642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
22742552ec6168d994991696a04c1626ac91218a720Andrew Hsiehbool Compiler::setInputSource(llvm::StringRef InputFile) {
22842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mInputFileName = InputFile.str();
22942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
23042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mSourceMgr->clearIDTables();
23142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
23242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  const clang::FileEntry *File = mFileMgr->getFile(InputFile);
23342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  if (File)
23442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    mSourceMgr->createMainFileID(File);
23542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
23642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  if (mSourceMgr->getMainFileID().isInvalid()) {
23742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
23842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    return false;
23942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  }
24042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
24142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return true;
24242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
24342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
24442552ec6168d994991696a04c1626ac91218a720Andrew Hsiehbool Compiler::setOutput(const char *OutputFile) {
24542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  llvm::sys::Path OutputFilePath(OutputFile);
24642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  std::string Error;
24742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  llvm::tool_output_file *OS = NULL;
24842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
24942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  switch (mOT) {
25042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    case OT_Dependency:
25142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    case OT_Assembly:
25242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    case OT_LLVMAssembly: {
25342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh      OS = openOutputFile(OutputFile, 0, &Error, mDiagnostics.getPtr());
25442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh      break;
25542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    }
25642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    case OT_Nothing: {
25742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh      break;
25842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    }
25942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    case OT_Object:
26042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    case OT_Bitcode: {
26142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh      OS = openOutputFile(OutputFile,
26242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                          llvm::raw_fd_ostream::F_Binary,
26342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                          &Error,
26442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh                          mDiagnostics.getPtr());
26542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh      break;
26642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    }
26742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    default: {
26842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh      llvm_unreachable("Unknown compiler output type");
26942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    }
27042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  }
27142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
27242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  if (!Error.empty())
27342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    return false;
27442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
27542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mOS.reset(OS);
27642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
27742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mOutputFileName = OutputFile;
27842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
27942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return true;
28042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
28142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
28242552ec6168d994991696a04c1626ac91218a720Andrew Hsiehint Compiler::compile() {
28342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  if (mDiagnostics->hasErrorOccurred())
28442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    return 1;
28542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  if (mOS.get() == NULL)
28642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    return 1;
28742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
28842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  // Here is per-compilation needed initialization
28942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  createPreprocessor();
29042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  createASTContext();
29142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
29242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mBackend.reset(createBackend(mCodeGenOpts, &mOS->os(), mOT));
29342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
29442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  // Inform the diagnostic client we are processing a source file
29542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mpDiagClient->BeginSourceFile(mLangOpts, mPP.get());
29642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
29742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  if (mLangOpts.CPlusPlus == 1) {
29842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    mPP->setPredefines("#define __cplusplus\n");
29942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  }
30042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
30142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  this->injectPreDefined();
30242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
30342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  // The core of the slang compiler
30442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  ParseAST(*mPP, mBackend.get(), *mASTContext);
30542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
30642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  // Inform the diagnostic client we are done with previous source file
30742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mpDiagClient->EndSourceFile();
30842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
30942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  // Declare success if no error
31042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  if (!mDiagnostics->hasErrorOccurred())
31142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh    mOS->keep();
31242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
31342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  // The compilation ended, clear
31442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mBackend.reset();
31542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mASTContext.reset();
31642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mPP.reset();
31742552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mOS.reset();
31842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
31942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return mDiagnostics->hasErrorOccurred() ? 1 : 0;
32042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
32142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
32242552ec6168d994991696a04c1626ac91218a720Andrew Hsiehvoid Compiler::reset() {
32342552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  mDiagnostics->Reset();
32442552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return;
32542552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
32642552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
32742552ec6168d994991696a04c1626ac91218a720Andrew HsiehCompiler::~Compiler() {
32842552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  llvm::llvm_shutdown();
32942552ec6168d994991696a04c1626ac91218a720Andrew Hsieh  return;
33042552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
33142552ec6168d994991696a04c1626ac91218a720Andrew Hsieh
33242552ec6168d994991696a04c1626ac91218a720Andrew Hsieh}
333