slang.cpp revision 68e8e9f98730b3672fb96d49e33b9db70a90ed3f
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 */
11268e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  const char*inclDir = getenv("ANDROID_BUILD_TOP");
11368e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
11468e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  printf("%s\n", inclDir);
11568e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  if (inclDir) {
11668e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao    std::vector<DirectoryLookup> SearchList;
11768e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao    if (const DirectoryEntry *DE = mFileMgr->getDirectory(inclDir, inclDir + strlen(inclDir))) {
11868e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao      SearchList.push_back(DirectoryLookup(DE, SrcMgr::C_System, false, false));
11968e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao      HS->SetSearchPaths(SearchList, 1, false);
12068e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao    }
12168e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  }
12268e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
12368e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  return;
12468e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao}
12568e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoSlang::Slang(const char* Triple, const char* CPU, const char** Features) :
1271fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart    mOutputType(SlangCompilerOutput_Default),
1281fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart    mAllowRSPrefix(false)
129462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao{
130462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    GlobalInitialization();
131462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
132462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createDiagnostic();
133462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.get());
134462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
135462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createTarget(Triple, CPU, Features);
136462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createFileManager();
137462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createSourceManager();
138462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
139462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
140462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
141462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
142462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::setInputSource(llvm::StringRef inputFile, const char* text, size_t textLength) {
143462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mInputFileName = inputFile.str();
144462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
145462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Reset the ID tables if we are reusing the SourceManager */
146462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mSourceMgr->clearIDTables();
147462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
148462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Load the source */
149462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getMemBuffer(text, text + textLength);
150462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mSourceMgr->createMainFileIDForMemBuffer(SB);
151462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
152462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(mSourceMgr->getMainFileID().isInvalid()) {
153462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mDiagnostics->Report(clang::diag::err_fe_error_reading) << inputFile;
154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return false;
155462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return true;
158462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
159462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
160462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::setInputSource(llvm::StringRef inputFile) {
161462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mInputFileName = inputFile.str();
162462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
163462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mSourceMgr->clearIDTables();
164462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
165462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    const FileEntry* File = mFileMgr->getFile(inputFile);
166462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(File)
167462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mSourceMgr->createMainFileID(File, SourceLocation());
168462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
169462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(mSourceMgr->getMainFileID().isInvalid()) {
170462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mDiagnostics->Report(clang::diag::err_fe_error_reading) << inputFile;
171462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return false;
172462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
173462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
174462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return true;
175462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
176462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
177462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::setOutputType(SlangCompilerOutputTy outputType) {
178462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mOutputType = outputType;
179462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if( mOutputType != SlangCompilerOutput_Assembly &&
180462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mOutputType != SlangCompilerOutput_LL &&
181462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mOutputType != SlangCompilerOutput_Bitcode &&
182462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mOutputType != SlangCompilerOutput_Nothing &&
183462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mOutputType != SlangCompilerOutput_Obj)
184462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mOutputType = SlangCompilerOutput_Default;
185462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
186462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
187462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
188b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liaostatic void _mkdir_given_a_file(const char *file) {
189807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    char buf[256];
190807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    char *tmp, *p = NULL;
191807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    size_t len = strlen(file);
192b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
193807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    if (len + 1 <= sizeof(buf))
194807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou        tmp = buf;
195807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    else
196807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou        tmp = new char [len + 1];
197807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou
198807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    strcpy(tmp, file);
199b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
200b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao    if (tmp[len - 1] == '/')
201b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao        tmp[len - 1] = 0;
202b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
203b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao    for (p = tmp + 1; *p; p++) {
204b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao        if (*p == '/') {
205b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao            *p = 0;
206b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao            mkdir(tmp, S_IRWXU);
207b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao            *p = '/';
208b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao        }
209b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao    }
210807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou
211807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou    if (tmp != buf)
212807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou        delete[] tmp;
213b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao}
214b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
215462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::setOutput(const char* outputFile) {
216462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    std::string Error;
217462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
218b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao    _mkdir_given_a_file(outputFile);
219b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao
220462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    switch(mOutputType) {
221462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case SlangCompilerOutput_Assembly:
222462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case SlangCompilerOutput_LL:
223462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            mOS.reset( new llvm::raw_fd_ostream(outputFile, Error, 0) );
224462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
225462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
226462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case SlangCompilerOutput_Nothing:
227462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            mOS.reset();
228462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
229462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
230462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case SlangCompilerOutput_Obj:
231462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        case SlangCompilerOutput_Bitcode:
232462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        default:
233462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            mOS.reset( new llvm::raw_fd_ostream(outputFile, Error, llvm::raw_fd_ostream::F_Binary) );
234462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        break;
235462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
236462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(!Error.empty()) {
238462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mOS.reset();
239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        mDiagnostics->Report(clang::diag::err_fe_error_opening) << outputFile << Error;
240462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return false;
241462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
242462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
243462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mOutputFileName = outputFile;
244462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
245462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return true;
246462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
247462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
248462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoint Slang::compile() {
249462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if((mDiagnostics->getNumErrors() > 0) || (mOS.get() == NULL))
250462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return mDiagnostics->getNumErrors();
251462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
252462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Here is per-compilation needed initialization */
253462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createPreprocessor();
254462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createASTContext();
255001fb6dddbf1cc794532eeb6a55f7b500eab1abcShih-wei Liao    createRSContext();
256462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    //createBackend();
257462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    createRSBackend();
258462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
259462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Inform the diagnostic client we are processing a source file */
260462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mDiagClient->BeginSourceFile(LangOpts, mPP.get());
261462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
262462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* The core of the slang compiler */
263462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    ParseAST(*mPP, mBackend.get(), *mASTContext);
264462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
265462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* The compilation ended, clear up */
266462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mBackend.reset();
267462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mASTContext.reset();
268462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mPP.reset();
269462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
270462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Inform the diagnostic client we are done with previous source file */
271462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    mDiagClient->EndSourceFile();
272462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
273462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return mDiagnostics->getNumErrors();
274462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
275462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
276462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::reflectToJava(const char* outputPackageName) {
277462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(mRSContext.get())
278462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return mRSContext->reflectToJava(outputPackageName, mInputFileName, mOutputFileName);
279462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    else
280462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        return false;
281462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
282462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2836de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liaobool Slang::reflectToJavaPath(const char* outputPathName) {
2846de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao    if(mRSContext.get())
2856de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao        return mRSContext->reflectToJavaPath(outputPathName);
2866de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao    else
2876de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao        return false;
2886de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao}
2896de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao
290462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::getPragmas(size_t* actualStringCount, size_t maxStringCount, char** strings) {
291462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    int stringCount = mPragmas.size() * 2;
292462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
293462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(actualStringCount)
294462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        *actualStringCount = stringCount;
295462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(stringCount > maxStringCount)
296462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        stringCount = maxStringCount;
297462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(strings)
298462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        for(PragmaList::const_iterator it = mPragmas.begin();
299462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            stringCount > 0;
300462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            stringCount-=2, it++)
301462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
302462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            *strings++ = const_cast<char*>(it->first.c_str());
303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            *strings++ = const_cast<char*>(it->second.c_str());
304462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
305462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
306462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
307462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
308462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
309462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoSlang::~Slang() {
310462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    llvm::llvm_shutdown();
311462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
313462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}   /* namespace slang */
315