slang.cpp revision 8c6d9b2d36ed2d6d811279fd9bddc05fffe16803
16315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang.h"
2462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
36315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <stdlib.h>
4462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
56315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Target/TargetSelect.h"
6462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
78c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang#include "llvm/System/Path.h"
88c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang
93a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "llvm/Support/raw_ostream.h"
106315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/MemoryBuffer.h"
116315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/ErrorHandling.h"
126315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/ManagedStatic.h"
13462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
146315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Basic/LangOptions.h"
153a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/SourceManager.h"
163a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/TargetInfo.h"
176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Basic/TargetOptions.h"
18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/DependencyOutputOptions.h"
20cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/FrontendDiagnostic.h"
21cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/Utils.h"
22cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/Preprocessor.h"
243a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/HeaderSearch.h"
253a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
263a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/AST/ASTConsumer.h"
273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/AST/ASTContext.h"
283a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
293a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/FileManager.h"
303a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
313a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Frontend/CodeGenOptions.h"
326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Frontend/FrontendDiagnostic.h"
33462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
346315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Parse/ParseAST.h"
356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
368c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang#include "slang_utils.h"
373a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "slang_backend.h"
389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaousing namespace slang;
409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#if defined(__arm__)
42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#elif defined(__x86_64__)
44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux"
45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#else
469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// let's use x86 as default target
479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux"
48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#endif
49462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
50462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::GlobalInitialized = false;
51462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// Language option (define the language feature for compiler such as C99)
539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::LangOptions Slang::LangOpts;
54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr// Code generation option for the compiler
569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::CodeGenOptions Slang::CodeGenOpts;
57462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
586315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst std::string Slang::TargetDescription =
596315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "e-"  // little-endian
606315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "p:32:32:32-"   // 32-bit pointer
616315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i1:8:8-"
626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i8:8:8-"
636315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i16:16:16-"
646315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i32:32:32-"
656315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i64:64:64-"
666315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "f32:32:32-"
676315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "f64:64:64-"
686315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "v64:64:64-"  // 64-bit vector (e.g. float2, int2, short4)
696315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "v128:128:128-"
706315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "a0:0:64-"
716315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "n32";  // native CPU only support 32-bit integer width.
72462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// The named of metadata node that pragma resides (should be synced with
749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// bcc.cpp)
75f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liaoconst llvm::StringRef Slang::PragmaMetadataName = "#pragma";
76462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
77462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::GlobalInitialization() {
789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!GlobalInitialized) {
799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // We only support x86, x64 and ARM target
80462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // For ARM
829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMTargetInfo();
839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMTarget();
849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMAsmPrinter();
85462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // For x86 and x64
879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86TargetInfo();
889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86Target();
899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86AsmPrinter();
90462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    // Please refer to include/clang/Basic/LangOptions.h to setup
929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // the options.
939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.RTTI = 0;  // Turn off the RTTI information support
949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.NeXTRuntime = 0;   // Turn off the NeXT runtime uses
959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.Bool = 1;  // Turn on 'bool', 'true', 'false' keywords
96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    CodeGenOpts.OptimizationLevel = 3;  /* -O3 */
98462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    GlobalInitialized = true;
1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
101462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
104462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
105462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::LLVMErrorHandler(void *UserData, const std::string &Message) {
1069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clang::Diagnostic* Diags = static_cast<clang::Diagnostic*>(UserData);
1079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  Diags->Report(clang::diag::err_fe_error_backend) << Message;
1089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  exit(1);
109462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
110462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createDiagnostic() {
1123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagnostics =
1133a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      llvm::IntrusiveRefCntPtr<clang::Diagnostic>(new clang::Diagnostic());
1143a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagClient = new DiagnosticBuffer();
1153a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  // This takes the ownership of mDiagClient.
1163a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagnostics->setClient(mDiagClient);
1173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
1183a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1193a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Slang::createTarget(const char* Triple, const char* CPU,
1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                         const char** Features) {
1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (Triple != NULL)
1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.Triple = Triple;
1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING;
126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (CPU != NULL)
1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.CPU = CPU;
129462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagnostics,
1319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                    mTargetOpts));
132462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (Features != NULL)
1346315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (int i = 0; Features[i] != NULL; i++)
1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mTargetOpts.Features.push_back(Features[i]);
136462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
137462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
138462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
139462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1403a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createFileManager() {
1413a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mFileMgr.reset(new clang::FileManager());
1423a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1433a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1443a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createSourceManager() {
1453a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mSourceMgr.reset(new clang::SourceManager(*mDiagnostics));
1463a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
1473a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1483a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
14968e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liaovoid Slang::createPreprocessor() {
1509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Default only search header file in current dir
1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clang::HeaderSearch *HS = new clang::HeaderSearch(*mFileMgr);
1529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mPP.reset(new clang::Preprocessor(*mDiagnostics,
1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    LangOpts,
1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *mTarget,
1569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *mSourceMgr,
1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *HS,
1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    NULL,
1593a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                    /* OwnsHeaderSearch = */true));
1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Initialize the prepocessor
16168e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  mPragmas.clear();
162f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao  mPP->AddPragmaHandler(new PragmaRecorder(mPragmas));
16368e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::vector<clang::DirectoryLookup> SearchList;
1653a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (const clang::DirectoryEntry *DE =
1673a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang            mFileMgr->getDirectory(mIncludePaths[i])) {
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      SearchList.push_back(clang::DirectoryLookup(DE,
1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  clang::SrcMgr::C_System,
1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  false,
1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  false));
1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
1739089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  }
1749089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
1759089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  HS->SetSearchPaths(SearchList, 1, false);
1769089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
1773a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initPreprocessor();
17868e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  return;
17968e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao}
18068e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
1813a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createASTContext() {
1823a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mASTContext.reset(new clang::ASTContext(LangOpts,
1833a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          *mSourceMgr,
1843a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          *mTarget,
1853a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          mPP->getIdentifierTable(),
1863a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          mPP->getSelectorTable(),
1873a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          mPP->getBuiltinInfo(),
1883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          /* size_reserve = */0));
1893a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initASTContext();
1903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
1913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changclang::ASTConsumer
1943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang*Slang::createBackend(const clang::CodeGenOptions& CodeGenOpts,
1953a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                      llvm::raw_ostream *OS,
1963a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                      OutputType OT) {
1973a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return new Backend(*mDiagnostics,
1983a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     CodeGenOpts,
1993a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     mTargetOpts,
2003a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     mPragmas,
2013a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     OS,
2023a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     OT);
2033a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
2043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
2056315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrSlang::Slang(const char *Triple, const char *CPU, const char **Features)
2063a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    : mDiagClient(NULL),
2073a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      mOT(OT_Default) {
2089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  GlobalInitialization();
209462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createDiagnostic();
2113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.getPtr());
212462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createTarget(Triple, CPU, Features);
2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createFileManager();
2159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createSourceManager();
216462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
218462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
219462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2203a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile,
2213a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                           const char *Text,
2223a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                           size_t TextLength) {
2233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mInputFileName = InputFile.str();
224462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Reset the ID tables if we are reusing the SourceManager
2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->clearIDTables();
227462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Load the source
2296315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  llvm::MemoryBuffer *SB =
2303a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength);
2319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->createMainFileIDForMemBuffer(SB);
232462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mSourceMgr->getMainFileID().isInvalid()) {
2343a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
2359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
238462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2403a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile) {
2413a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mInputFileName = InputFile.str();
242462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->clearIDTables();
244462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2453a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  const clang::FileEntry *File = mFileMgr->getFile(InputFile);
2469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (File)
2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mSourceMgr->createMainFileID(File);
248462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mSourceMgr->getMainFileID().isInvalid()) {
2503a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
253462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
255462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
256462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2573a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setOutput(const char *OutputFile) {
2588c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang  llvm::sys::Path OutputFilePath(OutputFile);
2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string Error;
260462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2613a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  switch (mOT) {
262cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    case OT_Dependency:
2633a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Assembly:
2643a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_LLVMAssembly: {
2658c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang      if (!SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
2668c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang                                                  &Error))
2678c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang        mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
2688c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang            << Error;
2698c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang      mOS.reset(new llvm::tool_output_file(OutputFile, Error, 0));
2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
271462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2723a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Nothing: {
2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mOS.reset();
2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
275462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2763a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Object:
277cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    case OT_Bitcode: {
2788c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang      if (!SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
2798c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang                                                  &Error))
2808c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang        mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
2818c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang            << Error;
2828c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang      mOS.reset(new llvm::tool_output_file(OutputFile,
2838c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang                                           Error,
2848c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang                                           llvm::raw_fd_ostream::F_Binary));
2859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
2878c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    default: {
288cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines      llvm_unreachable("Unknown compiler output type");
2898c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    }
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
291462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!Error.empty()) {
2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mOS.reset();
2943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                            << Error;
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2993a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mOutputFileName = OutputFile;
300462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
302462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3040b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hinesbool Slang::setDepOutput(const char *OutputFile) {
3058c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang  llvm::sys::Path OutputFilePath(OutputFile);
3060b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  std::string Error;
3078c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang
3088c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang  if (!SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
3098c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang                                              &Error))
3108c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
3118c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang        << Error;
3120b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  mDOS.reset(new llvm::raw_fd_ostream(OutputFile, Error, 0));
3130b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
3140b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  if (!Error.empty()) {
3150b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines    mDOS.reset();
3160b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines    mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
3170b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines                                                            << Error;
3180b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines    return false;
3190b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  }
3200b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
3210b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  mDepOutputFileName = OutputFile;
3220b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
3230b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  return true;
3240b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines}
3250b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
3260b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hinesbool Slang::setDepTargetBC(const char *TargetBCFile) {
3270b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  mDepTargetBCFileName = TargetBCFile;
328cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
329cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  return true;
330cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines}
331cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
3325457231d5201be02c3232ffc1c6d8bc408f276abYing Wangbool Slang::setAdditionalDepTarget(const char* AdditionalDepTargetFileName) {
3335457231d5201be02c3232ffc1c6d8bc408f276abYing Wang  mAdditionalDepTargetFileName = AdditionalDepTargetFileName;
3345457231d5201be02c3232ffc1c6d8bc408f276abYing Wang}
3355457231d5201be02c3232ffc1c6d8bc408f276abYing Wang
336cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hinesint Slang::generateDepFile() {
337f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines  if(mDiagnostics->getNumErrors() > 0)
338cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    return mDiagnostics->getNumErrors();
3390b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  if (mDOS.get() == NULL)
340f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines    return 1;
341cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
342cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  /* Initialize options for generating dependency file */
343cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  clang::DependencyOutputOptions DepOpts;
344cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  DepOpts.IncludeSystemHeaders = 1;
3450b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  DepOpts.OutputFile = mDepOutputFileName;
3465457231d5201be02c3232ffc1c6d8bc408f276abYing Wang  if (!mAdditionalDepTargetFileName.empty()) {
3475457231d5201be02c3232ffc1c6d8bc408f276abYing Wang    DepOpts.Targets.push_back(mAdditionalDepTargetFileName);
3485457231d5201be02c3232ffc1c6d8bc408f276abYing Wang  }
349cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  DepOpts.Targets.push_back(mDepTargetBCFileName);
350cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
351cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  /* Per-compilation needed initialization */
352cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  createPreprocessor();
353cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  AttachDependencyFileGen(*mPP.get(), DepOpts);
354cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
355cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  /* Inform the diagnostic client we are processing a source file */
356cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
357cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
358cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  /* Go through the source file (no operations necessary) */
359cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  clang::Token Tok;
360cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP->EnterMainSourceFile();
361cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  do {
362cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    mPP->Lex(Tok);
363cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  } while (Tok.isNot(clang::tok::eof));
364cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
365cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP->EndSourceFile();
366cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
367cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  /* Clean up after compilation */
368cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP.reset();
369cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
370cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  return mDiagnostics->getNumErrors();
371cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines}
372cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
373462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoint Slang::compile() {
374f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines  if (mDiagnostics->getNumErrors() > 0)
3759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return mDiagnostics->getNumErrors();
376f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines  if (mOS.get() == NULL)
377f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines    return 1;
378462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Here is per-compilation needed initialization
3809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createPreprocessor();
3819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createASTContext();
3823a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
3833a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mBackend.reset(createBackend(CodeGenOpts, mOS.take(), mOT));
384462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Inform the diagnostic client we are processing a source file
3869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
387462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // The core of the slang compiler
3899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ParseAST(*mPP, mBackend.get(), *mASTContext);
390462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  // The compilation ended, clear
3929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mBackend.reset();
3939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mASTContext.reset();
3949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mPP.reset();
395462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Inform the diagnostic client we are done with previous source file
3979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mDiagClient->EndSourceFile();
398462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return mDiagnostics->getNumErrors();
400462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
401462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4023a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::reset() {
4033a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagnostics->Reset();
4043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagClient->reset();
4059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
406462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
407462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
408462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoSlang::~Slang() {
4099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::llvm_shutdown();
4109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
411462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
412