slang.cpp revision 6315f76e3cc6ff2d012d1183a0b030d4ff0dc808
16315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang.h"
2462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
36315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <stdlib.h>
4462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
56315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Target/TargetSelect.h"
6462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
76315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/MemoryBuffer.h"
86315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/ErrorHandling.h"
96315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/ManagedStatic.h"
10462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
116315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Basic/TargetInfo.h"
126315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Basic/LangOptions.h"
136315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Basic/TargetOptions.h"
14462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
156315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Frontend/FrontendDiagnostic.h"
16462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Parse/ParseAST.h"
186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
196315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "libslang.h"
206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h"
219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaousing namespace slang;
239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
24462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#if defined(__arm__)
25462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
26462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#elif defined(__x86_64__)
27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux"
28462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#else
299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// let's use x86 as default target
309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux"
31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#endif
32462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
33462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::GlobalInitialized = false;
34462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// Language option (define the language feature for compiler such as C99)
369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::LangOptions Slang::LangOpts;
37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr// Code generation option for the compiler
399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::CodeGenOptions Slang::CodeGenOpts;
40462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
416315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst std::string Slang::TargetDescription =
426315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "e-"  // little-endian
436315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "p:32:32:32-"   // 32-bit pointer
446315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i1:8:8-"
456315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i8:8:8-"
466315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i16:16:16-"
476315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i32:32:32-"
486315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "i64:64:64-"
496315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "f32:32:32-"
506315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "f64:64:64-"
516315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "v64:64:64-"  // 64-bit vector (e.g. float2, int2, short4)
526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "v128:128:128-"
536315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "a0:0:64-"
546315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  "n32";  // native CPU only support 32-bit integer width.
55462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// The named of metadata node that pragma resides (should be synced with
579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// bcc.cpp)
58f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liaoconst llvm::StringRef Slang::PragmaMetadataName = "#pragma";
59462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
60462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::GlobalInitialization() {
619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!GlobalInitialized) {
629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // We only support x86, x64 and ARM target
63462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // For ARM
659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMTargetInfo();
669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMTarget();
679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMAsmPrinter();
68462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // For x86 and x64
709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86TargetInfo();
719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86Target();
729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86AsmPrinter();
73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // Please refer to clang/include/clang/Basic/LangOptions.h to set up
759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // the options.
769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.RTTI = 0;  // Turn off the RTTI information support
779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.NeXTRuntime = 0;   // Turn off the NeXT runtime uses
789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.Bool = 1;  // Turn on 'bool', 'true', 'false' keywords
79462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    CodeGenOpts.OptimizationLevel = 3;  /* -O3 */
81462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    GlobalInitialized = true;
839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
84462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
86462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
87462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
88462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::LLVMErrorHandler(void *UserData, const std::string &Message) {
899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clang::Diagnostic* Diags = static_cast<clang::Diagnostic*>(UserData);
909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  Diags->Report(clang::diag::err_fe_error_backend) << Message;
919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  exit(1);
92462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
93462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Slang::createTarget(const char* Triple, const char* CPU,
959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                         const char** Features) {
969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (Triple != NULL)
979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.Triple = Triple;
989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING;
100462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (CPU != NULL)
1029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.CPU = CPU;
103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagnostics,
1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                    mTargetOpts));
106462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (Features != NULL)
1086315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (int i = 0; Features[i] != NULL; i++)
1099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mTargetOpts.Features.push_back(Features[i]);
110462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
111462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
112462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
113462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
11468e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liaovoid Slang::createPreprocessor() {
1159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Default only search header file in current dir
1169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clang::HeaderSearch *HS = new clang::HeaderSearch(*mFileMgr);
1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mPP.reset(new clang::Preprocessor(*mDiagnostics,
1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    LangOpts,
1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *mTarget,
1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *mSourceMgr,
1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *HS,
1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    NULL,
1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    /* OwnsHeaderSearch */true));
1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Initialize the prepocessor
12668e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  mPragmas.clear();
127f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao  mPP->AddPragmaHandler(new PragmaRecorder(mPragmas));
12868e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
12960de5bd34649e3a0acfdbc881a07b16781fd2661Shih-wei Liao  std::string inclFiles("#include \"rs_types.rsh\"");
13060de5bd34649e3a0acfdbc881a07b16781fd2661Shih-wei Liao  mPP->setPredefines(inclFiles + "\n" + "#include \"rs_math.rsh\"" + "\n");
13160de5bd34649e3a0acfdbc881a07b16781fd2661Shih-wei Liao
1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::vector<clang::DirectoryLookup> SearchList;
1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (unsigned i = 0; i < mIncludePaths.size(); ++i) {
1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (const clang::DirectoryEntry *DE =
1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mFileMgr->getDirectory(mIncludePaths[i])) {
1369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      SearchList.push_back(clang::DirectoryLookup(DE,
1379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  clang::SrcMgr::C_System,
1389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  false,
1399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  false));
1409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
1419089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  }
1429089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
1439089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  HS->SetSearchPaths(SearchList, 1, false);
1449089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
14568e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  return;
14668e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao}
14768e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
1486315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrSlang::Slang(const char *Triple, const char *CPU, const char **Features)
1496315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    : mOutputType(SlangCompilerOutput_Default),
1506315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mAllowRSPrefix(false) {
1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  GlobalInitialization();
152462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createDiagnostic();
1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.get());
155462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createTarget(Triple, CPU, Features);
1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createFileManager();
1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createSourceManager();
159462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
161462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
162462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1636315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrbool Slang::setInputSource(llvm::StringRef inputFile,
1646315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                           const char *text,
1656315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                           size_t textLength) {
1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mInputFileName = inputFile.str();
167462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Reset the ID tables if we are reusing the SourceManager
1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->clearIDTables();
170462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Load the source
1726315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  llvm::MemoryBuffer *SB =
1736315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      llvm::MemoryBuffer::getMemBuffer(text, text + textLength);
1749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->createMainFileIDForMemBuffer(SB);
175462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mSourceMgr->getMainFileID().isInvalid()) {
1779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mDiagnostics->Report(clang::diag::err_fe_error_reading) << inputFile;
1789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
1799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
181462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
182462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
183462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::setInputSource(llvm::StringRef inputFile) {
1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mInputFileName = inputFile.str();
185462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->clearIDTables();
187462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const clang::FileEntry *File = mFileMgr->getFile(inputFile);
1899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (File)
1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mSourceMgr->createMainFileID(File);
191462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mSourceMgr->getMainFileID().isInvalid()) {
1939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mDiagnostics->Report(clang::diag::err_fe_error_reading) << inputFile;
1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
1959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
196462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
198462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
199462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Slang::addIncludePath(const char *path) {
2019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mIncludePaths.push_back(path);
202e2e522f0d23c074ecd1025f1f2ed161ed485d9c8Ying Wang}
203e2e522f0d23c074ecd1025f1f2ed161ed485d9c8Ying Wang
204462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::setOutputType(SlangCompilerOutputTy outputType) {
2059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mOutputType = outputType;
2069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if ( mOutputType != SlangCompilerOutput_Assembly &&
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       mOutputType != SlangCompilerOutput_LL &&
2089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       mOutputType != SlangCompilerOutput_Bitcode &&
2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       mOutputType != SlangCompilerOutput_Nothing &&
2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       mOutputType != SlangCompilerOutput_Obj)
2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mOutputType = SlangCompilerOutput_Default;
2129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
213462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
214462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
215b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liaostatic void _mkdir_given_a_file(const char *file) {
2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  char buf[256];
2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  char *tmp, *p = NULL;
2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  size_t len = strlen(file);
219807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou
2209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (len + 1 <= sizeof(buf))
2219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    tmp = buf;
2229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
2236315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    tmp = new char[len + 1];
2249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  strcpy(tmp, file);
226b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
2279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (tmp[len - 1] == '/')
2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    tmp[len - 1] = 0;
2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (p = tmp + 1; *p; p++) {
2319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (*p == '/') {
2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      *p = 0;
2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mkdir(tmp, S_IRWXU);
2349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      *p = '/';
2359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (tmp != buf)
2399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    delete[] tmp;
2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
241b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
2429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool Slang::setOutput(const char *outputFile) {
2439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string Error;
244462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  _mkdir_given_a_file(outputFile);
246462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  switch (mOutputType) {
2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    case SlangCompilerOutput_Assembly:
2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    case SlangCompilerOutput_LL: {
2506315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mOS.reset(new llvm::raw_fd_ostream(outputFile, Error, 0));
2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
252462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    case SlangCompilerOutput_Nothing: {
2549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mOS.reset();
2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
256462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    case SlangCompilerOutput_Obj:
2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    case SlangCompilerOutput_Bitcode:
2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    default: {
2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mOS.reset(new llvm::raw_fd_ostream(outputFile,
2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                         Error,
2629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                         llvm::raw_fd_ostream::F_Binary));
2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
2659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
266462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!Error.empty()) {
2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mOS.reset();
2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mDiagnostics->Report(clang::diag::err_fe_error_opening) << outputFile
2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                            << Error;
2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mOutputFileName = outputFile;
275462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
277462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
278462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
279462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoint Slang::compile() {
2809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if ((mDiagnostics->getNumErrors() > 0) || (mOS.get() == NULL))
2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return mDiagnostics->getNumErrors();
282462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Here is per-compilation needed initialization
2849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createPreprocessor();
2859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createASTContext();
2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createRSContext();
2879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  //createBackend();
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createRSBackend();
289462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Inform the diagnostic client we are processing a source file
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
292462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // The core of the slang compiler
2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ParseAST(*mPP, mBackend.get(), *mASTContext);
295462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // The compilation ended, clear up
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mBackend.reset();
2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Can't reset yet because the reflection later on still needs mRSContext
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  //mRSContext.reset();
3009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mASTContext.reset();
3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mPP.reset();
302462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Inform the diagnostic client we are done with previous source file
3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mDiagClient->EndSourceFile();
305462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return mDiagnostics->getNumErrors();
307462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
308462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool Slang::reflectToJava(const char *outputPackageName,
3109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                          char *realPackageName,
3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                          int bSize) {
3129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mRSContext.get())
3139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return mRSContext->reflectToJava(outputPackageName,
3149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     mInputFileName,
3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     mOutputFileName,
3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     realPackageName,
3179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     bSize);
3189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
3199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
320462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
321462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool Slang::reflectToJavaPath(const char *outputPathName) {
3239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mRSContext.get())
3249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return mRSContext->reflectToJavaPath(outputPathName);
3259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
3269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
3276de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao}
3286de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao
3299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Slang::getPragmas(size_t *actualStringCount,
3309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                       size_t maxStringCount,
3319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                       char **strings) {
3329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  unsigned stringCount = mPragmas.size() * 2;
3339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (actualStringCount)
3359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    *actualStringCount = stringCount;
3369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (stringCount > maxStringCount)
3379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    stringCount = maxStringCount;
3389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (strings)
3399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (PragmaList::const_iterator it = mPragmas.begin();
3409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         stringCount > 0;
3419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         stringCount -= 2, it++) {
3429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      *strings++ = const_cast<char*>(it->first.c_str());
3439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      *strings++ = const_cast<char*>(it->second.c_str());
3449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
345462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
347462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
348462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3494c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liaotypedef std::list<RSExportFunc*> ExportFuncList;
3504c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao
3514c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liaoconst char* Slang::exportFuncs() {
3524c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao  std::string fNames;
3536315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  for (RSContext::const_export_func_iterator
3546315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr          I = mRSContext->export_funcs_begin(),
3556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr          E = mRSContext->export_funcs_end();
3566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr       I != E;
3576315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr       I++) {
3584c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao    RSExportFunc* func = *I;
3594c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao    fNames.push_back(',');
3604c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao    fNames.append(func->getName());
3614c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao  }
3624c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao  return fNames.c_str();
3634c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao}
3644c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao
365462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoSlang::~Slang() {
3669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::llvm_shutdown();
3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
368462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
369