slang.cpp revision cc0efad052e944f64bb71cfdaa8a825e30192e78
16315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang.h"
2462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
36315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <stdlib.h>
4462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
56315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Target/TargetSelect.h"
6462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
73a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "llvm/Support/raw_ostream.h"
86315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/MemoryBuffer.h"
96315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/ErrorHandling.h"
106315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/ManagedStatic.h"
11462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
126315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Basic/LangOptions.h"
133a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/SourceManager.h"
143a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/TargetInfo.h"
156315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Basic/TargetOptions.h"
16462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
17cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/DependencyOutputOptions.h"
18cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/FrontendDiagnostic.h"
19cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/Utils.h"
20cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
213a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/Preprocessor.h"
223a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/HeaderSearch.h"
233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
243a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/AST/ASTConsumer.h"
253a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/AST/ASTContext.h"
263a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/FileManager.h"
283a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
293a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Frontend/CodeGenOptions.h"
306315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Frontend/FrontendDiagnostic.h"
31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Parse/ParseAST.h"
336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
343a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "slang_backend.h"
359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaousing namespace slang;
379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#if defined(__arm__)
39462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
40462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#elif defined(__x86_64__)
41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux"
42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#else
439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// let's use x86 as default target
449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux"
45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#endif
46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
47462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::GlobalInitialized = false;
48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// Language option (define the language feature for compiler such as C99)
509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::LangOptions Slang::LangOpts;
51462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr// Code generation option for the compiler
539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::CodeGenOptions Slang::CodeGenOpts;
54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst std::string Slang::TargetDescription =
566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "e-"  // little-endian
576315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "p:32:32:32-"   // 32-bit pointer
586315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i1:8:8-"
596315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i8:8:8-"
606315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i16:16:16-"
616315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i32:32:32-"
626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i64:64:64-"
636315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "f32:32:32-"
646315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "f64:64:64-"
656315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "v64:64:64-"  // 64-bit vector (e.g. float2, int2, short4)
666315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "v128:128:128-"
676315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "a0:0:64-"
686315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "n32";  // native CPU only support 32-bit integer width.
69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// The named of metadata node that pragma resides (should be synced with
719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// bcc.cpp)
72f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liaoconst llvm::StringRef Slang::PragmaMetadataName = "#pragma";
73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
74462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::GlobalInitialization() {
759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!GlobalInitialized) {
769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // We only support x86, x64 and ARM target
77462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // For ARM
799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMTargetInfo();
809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMTarget();
819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMAsmPrinter();
82462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // For x86 and x64
849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86TargetInfo();
859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86Target();
869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86AsmPrinter();
87462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    // Please refer to include/clang/Basic/LangOptions.h to setup
899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // the options.
909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.RTTI = 0;  // Turn off the RTTI information support
919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.NeXTRuntime = 0;   // Turn off the NeXT runtime uses
929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.Bool = 1;  // Turn on 'bool', 'true', 'false' keywords
93462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    CodeGenOpts.OptimizationLevel = 3;  /* -O3 */
95462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    GlobalInitialized = true;
979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
98462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
100462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
101462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
102462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::LLVMErrorHandler(void *UserData, const std::string &Message) {
1039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clang::Diagnostic* Diags = static_cast<clang::Diagnostic*>(UserData);
1049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  Diags->Report(clang::diag::err_fe_error_backend) << Message;
1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  exit(1);
106462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
107462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1083a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createDiagnostic() {
1093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagnostics =
1103a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      llvm::IntrusiveRefCntPtr<clang::Diagnostic>(new clang::Diagnostic());
1113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagClient = new DiagnosticBuffer();
1123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  // This takes the ownership of mDiagClient.
1133a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagnostics->setClient(mDiagClient);
1143a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
1153a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1163a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Slang::createTarget(const char* Triple, const char* CPU,
1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                         const char** Features) {
1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (Triple != NULL)
1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.Triple = Triple;
1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING;
123462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (CPU != NULL)
1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.CPU = CPU;
126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagnostics,
1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                    mTargetOpts));
129462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (Features != NULL)
1316315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (int i = 0; Features[i] != NULL; i++)
1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mTargetOpts.Features.push_back(Features[i]);
133462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
134462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
135462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
136462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1373a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createFileManager() {
1383a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mFileMgr.reset(new clang::FileManager());
1393a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1403a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1413a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createSourceManager() {
1423a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mSourceMgr.reset(new clang::SourceManager(*mDiagnostics));
1433a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
1443a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1453a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
14668e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liaovoid Slang::createPreprocessor() {
1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Default only search header file in current dir
1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clang::HeaderSearch *HS = new clang::HeaderSearch(*mFileMgr);
1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mPP.reset(new clang::Preprocessor(*mDiagnostics,
1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    LangOpts,
1529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *mTarget,
1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *mSourceMgr,
1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *HS,
1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    NULL,
1563a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                    /* OwnsHeaderSearch = */true));
1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Initialize the prepocessor
15868e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  mPragmas.clear();
159f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao  mPP->AddPragmaHandler(new PragmaRecorder(mPragmas));
16068e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::vector<clang::DirectoryLookup> SearchList;
1623a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (const clang::DirectoryEntry *DE =
1643a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang            mFileMgr->getDirectory(mIncludePaths[i])) {
1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      SearchList.push_back(clang::DirectoryLookup(DE,
1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  clang::SrcMgr::C_System,
1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  false,
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  false));
1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
1709089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  }
1719089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
1729089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  HS->SetSearchPaths(SearchList, 1, false);
1739089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
1743a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initPreprocessor();
17568e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  return;
17668e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao}
17768e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
1783a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createASTContext() {
1793a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mASTContext.reset(new clang::ASTContext(LangOpts,
1803a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          *mSourceMgr,
1813a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          *mTarget,
1823a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          mPP->getIdentifierTable(),
1833a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          mPP->getSelectorTable(),
1843a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          mPP->getBuiltinInfo(),
1853a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          /* size_reserve = */0));
1863a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initASTContext();
1873a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
1883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1893a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changclang::ASTConsumer
1913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang*Slang::createBackend(const clang::CodeGenOptions& CodeGenOpts,
1923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                      llvm::raw_ostream *OS,
1933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                      OutputType OT) {
1943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return new Backend(*mDiagnostics,
1953a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     CodeGenOpts,
1963a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     mTargetOpts,
1973a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     mPragmas,
1983a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     OS,
1993a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     OT);
2003a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
2013a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
2026315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrSlang::Slang(const char *Triple, const char *CPU, const char **Features)
2033a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    : mDiagClient(NULL),
2043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      mOT(OT_Default) {
2059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  GlobalInitialization();
206462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createDiagnostic();
2083a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.getPtr());
209462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createTarget(Triple, CPU, Features);
2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createFileManager();
2129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createSourceManager();
213462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
215462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
216462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile,
2183a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                           const char *Text,
2193a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                           size_t TextLength) {
2203a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mInputFileName = InputFile.str();
221462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Reset the ID tables if we are reusing the SourceManager
2239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->clearIDTables();
224462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Load the source
2266315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  llvm::MemoryBuffer *SB =
2273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength);
2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->createMainFileIDForMemBuffer(SB);
229462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mSourceMgr->getMainFileID().isInvalid()) {
2313a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
235462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
236462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2373a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile) {
2383a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mInputFileName = InputFile.str();
239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->clearIDTables();
241462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2423a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  const clang::FileEntry *File = mFileMgr->getFile(InputFile);
2439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (File)
2449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mSourceMgr->createMainFileID(File);
245462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mSourceMgr->getMainFileID().isInvalid()) {
2473a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
250462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
252462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
253462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
254b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liaostatic void _mkdir_given_a_file(const char *file) {
2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  char buf[256];
2569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  char *tmp, *p = NULL;
2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  size_t len = strlen(file);
258807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou
2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (len + 1 <= sizeof(buf))
2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    tmp = buf;
2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
2626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    tmp = new char[len + 1];
2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  strcpy(tmp, file);
265b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (tmp[len - 1] == '/')
2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    tmp[len - 1] = 0;
2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (p = tmp + 1; *p; p++) {
2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (*p == '/') {
2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      *p = 0;
2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mkdir(tmp, S_IRWXU);
2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      *p = '/';
2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
276462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (tmp != buf)
2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    delete[] tmp;
2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
280b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
2813a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setOutput(const char *OutputFile) {
2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string Error;
283462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
284462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2853a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  switch (mOT) {
286cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    case OT_Dependency:
2873a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Assembly:
2883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_LLVMAssembly: {
289cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines      _mkdir_given_a_file(OutputFile);
2903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      mOS.reset(new llvm::raw_fd_ostream(OutputFile, Error, 0));
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
292462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Nothing: {
2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mOS.reset();
2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
296462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2973a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Object:
298cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    case OT_Bitcode: {
299cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines      _mkdir_given_a_file(OutputFile);
3003a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      mOS.reset(new llvm::raw_fd_ostream(OutputFile,
3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                         Error,
3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                         llvm::raw_fd_ostream::F_Binary));
3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
305cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    default:
306cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines      llvm_unreachable("Unknown compiler output type");
307cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines      break;
3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
309462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!Error.empty()) {
3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mOS.reset();
3123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
3139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                            << Error;
3149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mOutputFileName = OutputFile;
318462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
320462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
321462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
322cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hinesbool Slang::setDepTargetBC(const char *targetBCFile) {
323cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mDepTargetBCFileName = targetBCFile;
324cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
325cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  return true;
326cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines}
327cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
328cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hinesint Slang::generateDepFile() {
329cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  if((mDiagnostics->getNumErrors() > 0) || (mOS.get() == NULL))
330cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    return mDiagnostics->getNumErrors();
331cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
332cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  /* Initialize options for generating dependency file */
333cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  clang::DependencyOutputOptions DepOpts;
334cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  DepOpts.IncludeSystemHeaders = 1;
335cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  DepOpts.OutputFile = mOutputFileName;
336cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  DepOpts.Targets.push_back(mDepTargetBCFileName);
337cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
338cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  /* Per-compilation needed initialization */
339cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  createPreprocessor();
340cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  AttachDependencyFileGen(*mPP.get(), DepOpts);
341cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
342cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  /* Inform the diagnostic client we are processing a source file */
343cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
344cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
345cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  /* Go through the source file (no operations necessary) */
346cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  clang::Token Tok;
347cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP->EnterMainSourceFile();
348cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  do {
349cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    mPP->Lex(Tok);
350cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  } while (Tok.isNot(clang::tok::eof));
351cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
352cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP->EndSourceFile();
353cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
354cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  /* Clean up after compilation */
355cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP.reset();
356cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
357cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  return mDiagnostics->getNumErrors();
358cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines}
359cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
360462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoint Slang::compile() {
361cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  if (mOT == OT_Dependency)
362cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    return generateDepFile();
363cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
3649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if ((mDiagnostics->getNumErrors() > 0) || (mOS.get() == NULL))
3659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return mDiagnostics->getNumErrors();
366462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Here is per-compilation needed initialization
3689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createPreprocessor();
3699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createASTContext();
3703a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
3713a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mBackend.reset(createBackend(CodeGenOpts, mOS.take(), mOT));
372462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Inform the diagnostic client we are processing a source file
3749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
375462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // The core of the slang compiler
3779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ParseAST(*mPP, mBackend.get(), *mASTContext);
378462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3793a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  // The compilation ended, clear
3809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mBackend.reset();
3819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mASTContext.reset();
3829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mPP.reset();
383462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Inform the diagnostic client we are done with previous source file
3859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mDiagClient->EndSourceFile();
386462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return mDiagnostics->getNumErrors();
388462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
389462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::reset() {
3913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagnostics->Reset();
3923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagClient->reset();
3939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
394462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
395462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
396462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoSlang::~Slang() {
3979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::llvm_shutdown();
3989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
399462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
400