slang.cpp revision 3a9ca1f0d6bd8f12c2bb2adea51f95c255996180
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
173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/Preprocessor.h"
183a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/HeaderSearch.h"
193a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
203a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/AST/ASTConsumer.h"
213a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/AST/ASTContext.h"
223a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/FileManager.h"
243a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
253a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Frontend/CodeGenOptions.h"
266315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Frontend/FrontendDiagnostic.h"
27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
286315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Parse/ParseAST.h"
296315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
303a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "slang_backend.h"
319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaousing namespace slang;
339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
34462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#if defined(__arm__)
35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#elif defined(__x86_64__)
37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux"
38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#else
399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// let's use x86 as default target
409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux"
41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#endif
42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::GlobalInitialized = false;
44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// Language option (define the language feature for compiler such as C99)
469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::LangOptions Slang::LangOpts;
47462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
486315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr// Code generation option for the compiler
499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::CodeGenOptions Slang::CodeGenOpts;
50462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
516315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst std::string Slang::TargetDescription =
526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "e-"  // little-endian
536315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "p:32:32:32-"   // 32-bit pointer
546315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i1:8:8-"
556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i8:8:8-"
566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i16:16:16-"
576315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i32:32:32-"
586315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i64:64:64-"
596315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "f32:32:32-"
606315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "f64:64:64-"
616315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "v64:64:64-"  // 64-bit vector (e.g. float2, int2, short4)
626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "v128:128:128-"
636315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "a0:0:64-"
646315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "n32";  // native CPU only support 32-bit integer width.
65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// The named of metadata node that pragma resides (should be synced with
679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// bcc.cpp)
68f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liaoconst llvm::StringRef Slang::PragmaMetadataName = "#pragma";
69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::GlobalInitialization() {
719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!GlobalInitialized) {
729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // We only support x86, x64 and ARM target
73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // For ARM
759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMTargetInfo();
769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMTarget();
779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMAsmPrinter();
78462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // For x86 and x64
809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86TargetInfo();
819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86Target();
829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86AsmPrinter();
83462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
843a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    // Please refer to include/clang/Basic/LangOptions.h to setup
859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // the options.
869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.RTTI = 0;  // Turn off the RTTI information support
879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.NeXTRuntime = 0;   // Turn off the NeXT runtime uses
889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.Bool = 1;  // Turn on 'bool', 'true', 'false' keywords
89462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    CodeGenOpts.OptimizationLevel = 3;  /* -O3 */
91462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    GlobalInitialized = true;
939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
94462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
97462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
98462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::LLVMErrorHandler(void *UserData, const std::string &Message) {
999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clang::Diagnostic* Diags = static_cast<clang::Diagnostic*>(UserData);
1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  Diags->Report(clang::diag::err_fe_error_backend) << Message;
1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  exit(1);
102462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createDiagnostic() {
1053a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagnostics =
1063a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      llvm::IntrusiveRefCntPtr<clang::Diagnostic>(new clang::Diagnostic());
1073a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagClient = new DiagnosticBuffer();
1083a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  // This takes the ownership of mDiagClient.
1093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagnostics->setClient(mDiagClient);
1103a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
1113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Slang::createTarget(const char* Triple, const char* CPU,
1149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                         const char** Features) {
1159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (Triple != NULL)
1169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.Triple = Triple;
1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING;
119462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (CPU != NULL)
1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.CPU = CPU;
122462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagnostics,
1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                    mTargetOpts));
125462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (Features != NULL)
1276315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (int i = 0; Features[i] != NULL; i++)
1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mTargetOpts.Features.push_back(Features[i]);
129462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
130462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
131462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
132462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1333a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createFileManager() {
1343a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mFileMgr.reset(new clang::FileManager());
1353a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1363a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1373a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createSourceManager() {
1383a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mSourceMgr.reset(new clang::SourceManager(*mDiagnostics));
1393a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
1403a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1413a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
14268e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liaovoid Slang::createPreprocessor() {
1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Default only search header file in current dir
1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clang::HeaderSearch *HS = new clang::HeaderSearch(*mFileMgr);
1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mPP.reset(new clang::Preprocessor(*mDiagnostics,
1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    LangOpts,
1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *mTarget,
1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *mSourceMgr,
1509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *HS,
1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    NULL,
1523a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                    /* OwnsHeaderSearch = */true));
1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Initialize the prepocessor
15468e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  mPragmas.clear();
155f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao  mPP->AddPragmaHandler(new PragmaRecorder(mPragmas));
15668e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::vector<clang::DirectoryLookup> SearchList;
1583a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
1599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (const clang::DirectoryEntry *DE =
1603a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang            mFileMgr->getDirectory(mIncludePaths[i])) {
1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      SearchList.push_back(clang::DirectoryLookup(DE,
1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  clang::SrcMgr::C_System,
1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  false,
1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  false));
1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
1669089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  }
1679089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
1689089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  HS->SetSearchPaths(SearchList, 1, false);
1699089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
1703a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initPreprocessor();
17168e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  return;
17268e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao}
17368e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
1743a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createASTContext() {
1753a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mASTContext.reset(new clang::ASTContext(LangOpts,
1763a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          *mSourceMgr,
1773a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          *mTarget,
1783a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          mPP->getIdentifierTable(),
1793a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          mPP->getSelectorTable(),
1803a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          mPP->getBuiltinInfo(),
1813a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          /* size_reserve = */0));
1823a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initASTContext();
1833a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
1843a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1853a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1863a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changclang::ASTConsumer
1873a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang*Slang::createBackend(const clang::CodeGenOptions& CodeGenOpts,
1883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                      llvm::raw_ostream *OS,
1893a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                      OutputType OT) {
1903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return new Backend(*mDiagnostics,
1913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     CodeGenOpts,
1923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     mTargetOpts,
1933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     mPragmas,
1943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     OS,
1953a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     OT);
1963a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1973a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1986315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrSlang::Slang(const char *Triple, const char *CPU, const char **Features)
1993a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    : mDiagClient(NULL),
2003a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      mOT(OT_Default) {
2019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  GlobalInitialization();
202462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createDiagnostic();
2043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.getPtr());
205462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createTarget(Triple, CPU, Features);
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createFileManager();
2089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createSourceManager();
209462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
211462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
212462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2133a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile,
2143a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                           const char *Text,
2153a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                           size_t TextLength) {
2163a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mInputFileName = InputFile.str();
217462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Reset the ID tables if we are reusing the SourceManager
2199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->clearIDTables();
220462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Load the source
2226315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  llvm::MemoryBuffer *SB =
2233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength);
2249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->createMainFileIDForMemBuffer(SB);
225462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mSourceMgr->getMainFileID().isInvalid()) {
2273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
231462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
232462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2333a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile) {
2343a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mInputFileName = InputFile.str();
235462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->clearIDTables();
237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2383a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  const clang::FileEntry *File = mFileMgr->getFile(InputFile);
2399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (File)
2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mSourceMgr->createMainFileID(File);
241462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mSourceMgr->getMainFileID().isInvalid()) {
2433a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
2449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
246462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
248462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
249462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
250b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liaostatic void _mkdir_given_a_file(const char *file) {
2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  char buf[256];
2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  char *tmp, *p = NULL;
2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  size_t len = strlen(file);
254807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou
2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (len + 1 <= sizeof(buf))
2569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    tmp = buf;
2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
2586315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    tmp = new char[len + 1];
2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  strcpy(tmp, file);
261b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
2629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (tmp[len - 1] == '/')
2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    tmp[len - 1] = 0;
2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (p = tmp + 1; *p; p++) {
2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (*p == '/') {
2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      *p = 0;
2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mkdir(tmp, S_IRWXU);
2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      *p = '/';
2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
272462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (tmp != buf)
2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    delete[] tmp;
2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
276b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
2773a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setOutput(const char *OutputFile) {
2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string Error;
279462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2803a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  _mkdir_given_a_file(OutputFile);
281462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2823a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  switch (mOT) {
2833a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Assembly:
2843a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_LLVMAssembly: {
2853a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      mOS.reset(new llvm::raw_fd_ostream(OutputFile, Error, 0));
2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
287462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Nothing: {
2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mOS.reset();
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
291462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Object:
2933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Bitcode:
2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    default: {
2953a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      mOS.reset(new llvm::raw_fd_ostream(OutputFile,
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                         Error,
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                         llvm::raw_fd_ostream::F_Binary));
2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
301462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!Error.empty()) {
3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mOS.reset();
3043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
3059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                            << Error;
3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
3079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mOutputFileName = OutputFile;
310462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
313462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoint Slang::compile() {
3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if ((mDiagnostics->getNumErrors() > 0) || (mOS.get() == NULL))
3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return mDiagnostics->getNumErrors();
317462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Here is per-compilation needed initialization
3199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createPreprocessor();
3209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createASTContext();
3213a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
3223a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mBackend.reset(createBackend(CodeGenOpts, mOS.take(), mOT));
323462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Inform the diagnostic client we are processing a source file
3259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
326462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // The core of the slang compiler
3289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ParseAST(*mPP, mBackend.get(), *mASTContext);
329462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3303a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  // The compilation ended, clear
3319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mBackend.reset();
3329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mASTContext.reset();
3339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mPP.reset();
334462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Inform the diagnostic client we are done with previous source file
3369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mDiagClient->EndSourceFile();
337462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return mDiagnostics->getNumErrors();
339462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
340462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3413a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::reset() {
3423a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagnostics->Reset();
3433a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagClient->reset();
3449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
345462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
346462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
347462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoSlang::~Slang() {
3489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::llvm_shutdown();
3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
350462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
351