slang.cpp revision 9089828a995422a5ed3beeed0890b755c4abe188
1462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang.hpp"
268e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
368e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao#include <stdlib.h>                     /* for getenv */
468e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
5462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "libslang.h"
6462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
7462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/ADT/Twine.h"     /* for class llvm::Twine */
8462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
9462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Target/TargetSelect.h"       /* for function LLVMInitialize[ARM|X86][TargetInfo|Target|AsmPrinter]() */
10462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
11462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Support/MemoryBuffer.h"      /* for class llvm::MemoryBuffer */
12462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Support/ErrorHandling.h"     /* for function llvm::install_fatal_error_handler() */
13462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Support/ManagedStatic.h"     /* for class llvm::llvm_shutdown */
14462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
15462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Basic/TargetInfo.h"     /* for class clang::TargetInfo */
16462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Basic/LangOptions.h"    /* for class clang::LangOptions */
17462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Basic/TargetOptions.h"  /* for class clang::TargetOptions */
18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Frontend/FrontendDiagnostic.h"      /* for clang::diag::* */
20462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Sema/ParseAST.h"        /* for function clang::ParseAST() */
22462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
23462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#if defined(__arm__)
24462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
25462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#elif defined(__x86_64__)
26462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux"
27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#else
28462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux"    // let's use x86 as default target
29462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#endif
30462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaonamespace slang {
32462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
33462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::GlobalInitialized = false;
34462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao/* Language option (define the language feature for compiler such as C99) */
36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoLangOptions Slang::LangOpts;
37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao/* Code generation option for the compiler */
39462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoCodeGenOptions Slang::CodeGenOpts;
40462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoconst std::string Slang::TargetDescription = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32";
42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao/* The named of metadata node that pragma resides (should be synced with bcc.cpp) */
44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoconst llvm::Twine Slang::PragmaMetadataName = "#pragma";
45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::GlobalInitialization() {
47462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(!GlobalInitialized) {
48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        /* We only support x86, x64 and ARM target */
49462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
50462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        /* For ARM */
51462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        LLVMInitializeARMTargetInfo();
52462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        LLVMInitializeARMTarget();
53462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        LLVMInitializeARMAsmPrinter();
54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
55462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        /* For x86 and x64 */
56462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        LLVMInitializeX86TargetInfo();
57462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        LLVMInitializeX86Target();
58462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        LLVMInitializeX86AsmPrinter();
59462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
60462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        /* Please refer to clang/include/clang/Basic/LangOptions.h for setting up the options */
61462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        LangOpts.RTTI = 0;  /* turn off the RTTI information support */
62462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        LangOpts.NeXTRuntime = 0;   /* turn off the NeXT runtime uses */
63462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        LangOpts.Bool = 1;  /* turn on 'bool', 'true', 'false' keywords. */
64462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        CodeGenOpts.OptimizationLevel = 3;  /* -O3 */
66462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
67462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        GlobalInitialized = true;
68462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
71462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
72462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::LLVMErrorHandler(void *UserData, const std::string &Message) {
74462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    Diagnostic* Diags = static_cast<Diagnostic*>(UserData);
75462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    Diags->Report(clang::diag::err_fe_error_backend) << Message;
76462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    exit(1);
77462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
78462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
79462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::createTarget(const char* Triple, const char* CPU, const char** Features) {
80462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(Triple != NULL)
81462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mTargetOpts.Triple = Triple;
82462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    else
83462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING;
84462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
85462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(CPU != NULL)
86462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mTargetOpts.CPU = CPU;
87462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
88462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mTarget.reset(TargetInfo::CreateTargetInfo(*mDiagnostics, mTargetOpts));
89462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
90462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(Features != NULL)
91462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        for(int i=0;Features[i]!=NULL;i++)
92462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            mTargetOpts.Features.push_back(Features[i]);
93462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
94462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
95462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
9768e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liaovoid Slang::createPreprocessor() {
9868e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  HeaderSearch* HS = new HeaderSearch(*mFileMgr); /* Default only search header file in current dir */
9968e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
10068e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  mPP.reset(new Preprocessor( *mDiagnostics,
10168e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao                              LangOpts,
10268e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao                              *mTarget,
10368e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao                              *mSourceMgr,
10468e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao                              *HS,
10568e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao                              NULL,
10668e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao                              true /* OwnsHeaderSearch */));
10768e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  /* Initialize the prepocessor */
10868e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  mPragmas.clear();
10968e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  mPP->AddPragmaHandler(NULL, new PragmaRecorder(mPragmas));
11068e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
11168e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  /* Like ApplyHeaderSearchOptions in InitHeaderSearch.cpp */
1129089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  const char *inclDir = getenv("ANDROID_BUILD_TOP");
1139089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  std::vector<DirectoryLookup> SearchList;
11468e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  if (inclDir) {
1158eac0940b8d13f8c4bad50942bf8527d64ccd12cShih-wei Liao    char *dirPath = new char[strlen(inclDir) + 33];
1168eac0940b8d13f8c4bad50942bf8527d64ccd12cShih-wei Liao    strcpy(dirPath, inclDir);
1178eac0940b8d13f8c4bad50942bf8527d64ccd12cShih-wei Liao    strcpy(dirPath + strlen(inclDir), "/frameworks/base/libs/rs/scriptc");
1188eac0940b8d13f8c4bad50942bf8527d64ccd12cShih-wei Liao
1198eac0940b8d13f8c4bad50942bf8527d64ccd12cShih-wei Liao    if (const DirectoryEntry *DE = mFileMgr->getDirectory(dirPath, dirPath + strlen(dirPath))) {
12068e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao      SearchList.push_back(DirectoryLookup(DE, SrcMgr::C_System, false, false));
12168e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao    }
12268e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  }
12368e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
1249089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  int siz = 256;
1259089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  char *currDir = new char[siz];
1269089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  while (!getcwd(currDir, siz)) {
1279089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao    siz *= 2;
1289089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  }
1299089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
1309089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  if (siz - strlen(currDir) >= 33) {
1319089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao    strcpy(currDir + strlen(currDir), "/frameworks/base/libs/rs/scriptc");
1329089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  } else {
1339089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao    char *tmp = new char[strlen(currDir) + 33];
1349089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao    strcpy(tmp, currDir);
1359089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao    strcpy(tmp + strlen(currDir), "/frameworks/base/libs/rs/scriptc");
1369089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao    currDir = tmp;
1379089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  }
1389089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
1399089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  if (const DirectoryEntry *DE = mFileMgr->getDirectory(currDir, currDir + strlen(currDir))) {
1409089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao    SearchList.push_back(DirectoryLookup(DE, SrcMgr::C_System, false, false));
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
148462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoSlang::Slang(const char* Triple, const char* CPU, const char** Features) :
1491fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart    mOutputType(SlangCompilerOutput_Default),
1501fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart    mAllowRSPrefix(false)
151462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao{
152462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    GlobalInitialization();
153462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createDiagnostic();
155462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.get());
156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createTarget(Triple, CPU, Features);
158462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createFileManager();
159462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createSourceManager();
160462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
161462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
162462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
163462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
164462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::setInputSource(llvm::StringRef inputFile, const char* text, size_t textLength) {
165462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mInputFileName = inputFile.str();
166462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
167462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Reset the ID tables if we are reusing the SourceManager */
168462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mSourceMgr->clearIDTables();
169462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
170462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Load the source */
171462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getMemBuffer(text, text + textLength);
172462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mSourceMgr->createMainFileIDForMemBuffer(SB);
173462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
174462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(mSourceMgr->getMainFileID().isInvalid()) {
175462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mDiagnostics->Report(clang::diag::err_fe_error_reading) << inputFile;
176462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return false;
177462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
178462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
179462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return true;
180462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
181462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
182462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::setInputSource(llvm::StringRef inputFile) {
183462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mInputFileName = inputFile.str();
184462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
185462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mSourceMgr->clearIDTables();
186462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
187462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    const FileEntry* File = mFileMgr->getFile(inputFile);
188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(File)
189462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mSourceMgr->createMainFileID(File, SourceLocation());
190462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
191462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(mSourceMgr->getMainFileID().isInvalid()) {
192462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mDiagnostics->Report(clang::diag::err_fe_error_reading) << inputFile;
193462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return false;
194462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
195462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
196462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return true;
197462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
198462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
199462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::setOutputType(SlangCompilerOutputTy outputType) {
200462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mOutputType = outputType;
201462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if( mOutputType != SlangCompilerOutput_Assembly &&
202462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mOutputType != SlangCompilerOutput_LL &&
203462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mOutputType != SlangCompilerOutput_Bitcode &&
204462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mOutputType != SlangCompilerOutput_Nothing &&
205462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mOutputType != SlangCompilerOutput_Obj)
206462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mOutputType = SlangCompilerOutput_Default;
207462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
208462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
209462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
210b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liaostatic void _mkdir_given_a_file(const char *file) {
211807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    char buf[256];
212807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    char *tmp, *p = NULL;
213807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    size_t len = strlen(file);
214b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
215807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    if (len + 1 <= sizeof(buf))
216807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou        tmp = buf;
217807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    else
218807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou        tmp = new char [len + 1];
219807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou
220807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    strcpy(tmp, file);
221b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
222b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao    if (tmp[len - 1] == '/')
223b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao        tmp[len - 1] = 0;
224b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
225b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao    for (p = tmp + 1; *p; p++) {
226b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao        if (*p == '/') {
227b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao            *p = 0;
228b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao            mkdir(tmp, S_IRWXU);
229b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao            *p = '/';
230b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao        }
231b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao    }
232807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou
233807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    if (tmp != buf)
234807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou        delete[] tmp;
235b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao}
236b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::setOutput(const char* outputFile) {
238462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    std::string Error;
239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
240b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao    _mkdir_given_a_file(outputFile);
241b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
242462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    switch(mOutputType) {
243462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case SlangCompilerOutput_Assembly:
244462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case SlangCompilerOutput_LL:
245462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            mOS.reset( new llvm::raw_fd_ostream(outputFile, Error, 0) );
246462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
247462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
248462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case SlangCompilerOutput_Nothing:
249462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            mOS.reset();
250462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
251462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
252462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case SlangCompilerOutput_Obj:
253462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case SlangCompilerOutput_Bitcode:
254462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        default:
255462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            mOS.reset( new llvm::raw_fd_ostream(outputFile, Error, llvm::raw_fd_ostream::F_Binary) );
256462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
257462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
258462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
259462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(!Error.empty()) {
260462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mOS.reset();
261462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mDiagnostics->Report(clang::diag::err_fe_error_opening) << outputFile << Error;
262462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return false;
263462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
264462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
265462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mOutputFileName = outputFile;
266462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
267462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return true;
268462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
269462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
270462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoint Slang::compile() {
271462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if((mDiagnostics->getNumErrors() > 0) || (mOS.get() == NULL))
272462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return mDiagnostics->getNumErrors();
273462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
274462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Here is per-compilation needed initialization */
275462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createPreprocessor();
276462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createASTContext();
277001fb6dddbf1cc794532eeb6a55f7b500eab1abcShih-wei Liao    createRSContext();
278462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    //createBackend();
279462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createRSBackend();
280462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
281462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Inform the diagnostic client we are processing a source file */
282462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mDiagClient->BeginSourceFile(LangOpts, mPP.get());
283462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
284462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* The core of the slang compiler */
285462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    ParseAST(*mPP, mBackend.get(), *mASTContext);
286462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
287462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* The compilation ended, clear up */
288462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mBackend.reset();
289462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mASTContext.reset();
290462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mPP.reset();
291462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
292462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Inform the diagnostic client we are done with previous source file */
293462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mDiagClient->EndSourceFile();
294462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
295462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return mDiagnostics->getNumErrors();
296462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
297462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
298462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::reflectToJava(const char* outputPackageName) {
299462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(mRSContext.get())
300462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return mRSContext->reflectToJava(outputPackageName, mInputFileName, mOutputFileName);
301462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    else
302462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return false;
303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
304462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3056de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liaobool Slang::reflectToJavaPath(const char* outputPathName) {
3066de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao    if(mRSContext.get())
3076de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao        return mRSContext->reflectToJavaPath(outputPathName);
3086de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao    else
3096de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao        return false;
3106de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao}
3116de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao
312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::getPragmas(size_t* actualStringCount, size_t maxStringCount, char** strings) {
313462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    int stringCount = mPragmas.size() * 2;
314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
315462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(actualStringCount)
316462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        *actualStringCount = stringCount;
317462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(stringCount > maxStringCount)
318462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        stringCount = maxStringCount;
319462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(strings)
320462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        for(PragmaList::const_iterator it = mPragmas.begin();
321462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            stringCount > 0;
322462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            stringCount-=2, it++)
323462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
324462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            *strings++ = const_cast<char*>(it->first.c_str());
325462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            *strings++ = const_cast<char*>(it->second.c_str());
326462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
327462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
328462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
329462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
330462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
331462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoSlang::~Slang() {
332462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    llvm::llvm_shutdown();
333462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
334462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
335462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
336462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}   /* namespace slang */
337