slang.cpp revision f83d3c396d5d7eacd97cf0a5d3b6a01d75535b67
1113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "slang.hpp" 2113e0824d6bddf4376240681f9cf6a2deded9498John Reck 3113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include <stdlib.h> /* for getenv */ 4113e0824d6bddf4376240681f9cf6a2deded9498John Reck 5113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "libslang.h" 6113e0824d6bddf4376240681f9cf6a2deded9498John Reck 7113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "llvm/ADT/Twine.h" /* for class llvm::Twine */ 8113e0824d6bddf4376240681f9cf6a2deded9498John Reck 9113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "llvm/Target/TargetSelect.h" /* for function LLVMInitialize[ARM|X86][TargetInfo|Target|AsmPrinter]() */ 10113e0824d6bddf4376240681f9cf6a2deded9498John Reck 11113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "llvm/Support/MemoryBuffer.h" /* for class llvm::MemoryBuffer */ 12113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "llvm/Support/ErrorHandling.h" /* for function llvm::install_fatal_error_handler() */ 13113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "llvm/Support/ManagedStatic.h" /* for class llvm::llvm_shutdown */ 14113e0824d6bddf4376240681f9cf6a2deded9498John Reck 15113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "clang/Basic/TargetInfo.h" /* for class clang::TargetInfo */ 16113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "clang/Basic/LangOptions.h" /* for class clang::LangOptions */ 17113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "clang/Basic/TargetOptions.h" /* for class clang::TargetOptions */ 18113e0824d6bddf4376240681f9cf6a2deded9498John Reck 19113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "clang/Frontend/FrontendDiagnostic.h" /* for clang::diag::* */ 20113e0824d6bddf4376240681f9cf6a2deded9498John Reck 21113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "clang/Sema/ParseAST.h" /* for function clang::ParseAST() */ 22113e0824d6bddf4376240681f9cf6a2deded9498John Reck 23113e0824d6bddf4376240681f9cf6a2deded9498John Reck#if defined(__arm__) 24113e0824d6bddf4376240681f9cf6a2deded9498John Reck# define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi" 25113e0824d6bddf4376240681f9cf6a2deded9498John Reck#elif defined(__x86_64__) 26113e0824d6bddf4376240681f9cf6a2deded9498John Reck# define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux" 27113e0824d6bddf4376240681f9cf6a2deded9498John Reck#else 28113e0824d6bddf4376240681f9cf6a2deded9498John Reck# define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux" // let's use x86 as default target 29113e0824d6bddf4376240681f9cf6a2deded9498John Reck#endif 3068bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 31113e0824d6bddf4376240681f9cf6a2deded9498John Recknamespace slang { 32113e0824d6bddf4376240681f9cf6a2deded9498John Reck 33b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikbool Slang::GlobalInitialized = false; 34113e0824d6bddf4376240681f9cf6a2deded9498John Reck 35113e0824d6bddf4376240681f9cf6a2deded9498John Reck/* Language option (define the language feature for compiler such as C99) */ 36272a685f17cc4828257e521a6f62b7b17870f75eJohn ReckLangOptions Slang::LangOpts; 37272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck 38113e0824d6bddf4376240681f9cf6a2deded9498John Reck/* Code generation option for the compiler */ 39113e0824d6bddf4376240681f9cf6a2deded9498John ReckCodeGenOptions Slang::CodeGenOpts; 40113e0824d6bddf4376240681f9cf6a2deded9498John Reck 41113e0824d6bddf4376240681f9cf6a2deded9498John Reckconst 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"; 42113e0824d6bddf4376240681f9cf6a2deded9498John Reck 43113e0824d6bddf4376240681f9cf6a2deded9498John Reck/* The named of metadata node that pragma resides (should be synced with bcc.cpp) */ 44113e0824d6bddf4376240681f9cf6a2deded9498John Reckconst llvm::Twine Slang::PragmaMetadataName = "#pragma"; 45113e0824d6bddf4376240681f9cf6a2deded9498John Reck 46b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid Slang::GlobalInitialization() { 47db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik if(!GlobalInitialized) { 480b7e8245db728d127ada698be63d78b33fc6e4daChris Craik /* We only support x86, x64 and ARM target */ 49113e0824d6bddf4376240681f9cf6a2deded9498John Reck 500b7e8245db728d127ada698be63d78b33fc6e4daChris Craik /* For ARM */ 51113e0824d6bddf4376240681f9cf6a2deded9498John Reck LLVMInitializeARMTargetInfo(); 52113e0824d6bddf4376240681f9cf6a2deded9498John Reck LLVMInitializeARMTarget(); 53113e0824d6bddf4376240681f9cf6a2deded9498John Reck LLVMInitializeARMAsmPrinter(); 540b7e8245db728d127ada698be63d78b33fc6e4daChris Craik 550b7e8245db728d127ada698be63d78b33fc6e4daChris Craik /* For x86 and x64 */ 568d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik LLVMInitializeX86TargetInfo(); 570b7e8245db728d127ada698be63d78b33fc6e4daChris Craik LLVMInitializeX86Target(); 588d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik LLVMInitializeX86AsmPrinter(); 590b7e8245db728d127ada698be63d78b33fc6e4daChris Craik 600b7e8245db728d127ada698be63d78b33fc6e4daChris Craik /* Please refer to clang/include/clang/Basic/LangOptions.h for setting up the options */ 610b7e8245db728d127ada698be63d78b33fc6e4daChris Craik LangOpts.RTTI = 0; /* turn off the RTTI information support */ 628d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik LangOpts.NeXTRuntime = 0; /* turn off the NeXT runtime uses */ 630b7e8245db728d127ada698be63d78b33fc6e4daChris Craik LangOpts.Bool = 1; /* turn on 'bool', 'true', 'false' keywords. */ 640b7e8245db728d127ada698be63d78b33fc6e4daChris Craik 65113e0824d6bddf4376240681f9cf6a2deded9498John Reck CodeGenOpts.OptimizationLevel = 3; /* -O3 */ 668d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik 67113e0824d6bddf4376240681f9cf6a2deded9498John Reck GlobalInitialized = true; 68113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 69113e0824d6bddf4376240681f9cf6a2deded9498John Reck 702dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson return; 71113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 72e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck 73e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reckvoid Slang::LLVMErrorHandler(void *UserData, const std::string &Message) { 74e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck Diagnostic* Diags = static_cast<Diagnostic*>(UserData); 75e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck Diags->Report(clang::diag::err_fe_error_backend) << Message; 76113e0824d6bddf4376240681f9cf6a2deded9498John Reck exit(1); 77113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 78113e0824d6bddf4376240681f9cf6a2deded9498John Reck 79113e0824d6bddf4376240681f9cf6a2deded9498John Reckvoid Slang::createTarget(const char* Triple, const char* CPU, const char** Features) { 80003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if(Triple != NULL) 81113e0824d6bddf4376240681f9cf6a2deded9498John Reck mTargetOpts.Triple = Triple; 82113e0824d6bddf4376240681f9cf6a2deded9498John Reck else 83113e0824d6bddf4376240681f9cf6a2deded9498John Reck mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING; 84003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik 85003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if(CPU != NULL) 86113e0824d6bddf4376240681f9cf6a2deded9498John Reck mTargetOpts.CPU = CPU; 87113e0824d6bddf4376240681f9cf6a2deded9498John Reck 88087bc0c14bdccf7c258dce0cdef46a69a839b427John Reck mTarget.reset(TargetInfo::CreateTargetInfo(*mDiagnostics, mTargetOpts)); 89b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 908d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik if(Features != NULL) 91113e0824d6bddf4376240681f9cf6a2deded9498John Reck for(int i=0;Features[i]!=NULL;i++) 92ff941dcd815021bb20d6504eb486acb1e50592c3John Reck mTargetOpts.Features.push_back(Features[i]); 93ff941dcd815021bb20d6504eb486acb1e50592c3John Reck 94ff941dcd815021bb20d6504eb486acb1e50592c3John Reck return; 95ff941dcd815021bb20d6504eb486acb1e50592c3John Reck} 96ff941dcd815021bb20d6504eb486acb1e50592c3John Reck 97ff941dcd815021bb20d6504eb486acb1e50592c3John Reckvoid Slang::createPreprocessor() { 98ff941dcd815021bb20d6504eb486acb1e50592c3John Reck HeaderSearch* HS = new HeaderSearch(*mFileMgr); /* Default only search header file in current dir */ 99ff941dcd815021bb20d6504eb486acb1e50592c3John Reck 100ff941dcd815021bb20d6504eb486acb1e50592c3John Reck mPP.reset(new Preprocessor( *mDiagnostics, 101ff941dcd815021bb20d6504eb486acb1e50592c3John Reck LangOpts, 102ff941dcd815021bb20d6504eb486acb1e50592c3John Reck *mTarget, 103ff941dcd815021bb20d6504eb486acb1e50592c3John Reck *mSourceMgr, 104ff941dcd815021bb20d6504eb486acb1e50592c3John Reck *HS, 105ff941dcd815021bb20d6504eb486acb1e50592c3John Reck NULL, 106a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck true /* OwnsHeaderSearch */)); 107ff941dcd815021bb20d6504eb486acb1e50592c3John Reck /* Initialize the prepocessor */ 108ff941dcd815021bb20d6504eb486acb1e50592c3John Reck mPragmas.clear(); 109113e0824d6bddf4376240681f9cf6a2deded9498John Reck mPP->AddPragmaHandler(NULL, new PragmaRecorder(mPragmas)); 110e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 111113e0824d6bddf4376240681f9cf6a2deded9498John Reck std::string inclFiles("#include \"rs_types.rsh\""); 112113e0824d6bddf4376240681f9cf6a2deded9498John Reck mPP->setPredefines(inclFiles + "\n" + "#include \"rs_math.rsh\"" + "\n"); 113113e0824d6bddf4376240681f9cf6a2deded9498John Reck 114113e0824d6bddf4376240681f9cf6a2deded9498John Reck /* Like ApplyHeaderSearchOptions in InitHeaderSearch.cpp */ 115113e0824d6bddf4376240681f9cf6a2deded9498John Reck const char *inclDir = getenv("ANDROID_BUILD_TOP"); 116113e0824d6bddf4376240681f9cf6a2deded9498John Reck std::vector<DirectoryLookup> SearchList; 117443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck if (inclDir) { 118113e0824d6bddf4376240681f9cf6a2deded9498John Reck char *dirPath = new char[strlen(inclDir) + 33]; 119003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik strcpy(dirPath, inclDir); 120113e0824d6bddf4376240681f9cf6a2deded9498John Reck strcpy(dirPath + strlen(inclDir), "/frameworks/base/libs/rs/scriptc"); 121113e0824d6bddf4376240681f9cf6a2deded9498John Reck 122b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik if (const DirectoryEntry *DE = mFileMgr->getDirectory(dirPath, dirPath + strlen(dirPath))) { 12380d4902196899d1325cd9f52c06ae0174cf9bd4cChris Craik SearchList.push_back(DirectoryLookup(DE, SrcMgr::C_System, false, false)); 12480d4902196899d1325cd9f52c06ae0174cf9bd4cChris Craik } 125113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 126113e0824d6bddf4376240681f9cf6a2deded9498John Reck 127fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck int siz = 256; 128e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck char *currDir = new char[siz]; 129113e0824d6bddf4376240681f9cf6a2deded9498John Reck while (!getcwd(currDir, siz)) { 130113e0824d6bddf4376240681f9cf6a2deded9498John Reck siz *= 2; 131003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik } 132113e0824d6bddf4376240681f9cf6a2deded9498John Reck 133113e0824d6bddf4376240681f9cf6a2deded9498John Reck if (siz - strlen(currDir) >= 33) { 134a447d29c65fb811cd184775a3476101a1cede929John Reck strcpy(currDir + strlen(currDir), "/frameworks/base/libs/rs/scriptc"); 135003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik } else { 136a447d29c65fb811cd184775a3476101a1cede929John Reck char *tmp = new char[strlen(currDir) + 33]; 137a447d29c65fb811cd184775a3476101a1cede929John Reck strcpy(tmp, currDir); 138defb7f37fe67ef2389666f7adc5da1260df87017Chris Craik strcpy(tmp + strlen(currDir), "/frameworks/base/libs/rs/scriptc"); 139defb7f37fe67ef2389666f7adc5da1260df87017Chris Craik currDir = tmp; 140defb7f37fe67ef2389666f7adc5da1260df87017Chris Craik } 141defb7f37fe67ef2389666f7adc5da1260df87017Chris Craik 142113e0824d6bddf4376240681f9cf6a2deded9498John Reck if (const DirectoryEntry *DE = mFileMgr->getDirectory(currDir, currDir + strlen(currDir))) { 143113e0824d6bddf4376240681f9cf6a2deded9498John Reck SearchList.push_back(DirectoryLookup(DE, SrcMgr::C_System, false, false)); 144113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 145113e0824d6bddf4376240681f9cf6a2deded9498John Reck 146113e0824d6bddf4376240681f9cf6a2deded9498John Reck HS->SetSearchPaths(SearchList, 1, false); 147113e0824d6bddf4376240681f9cf6a2deded9498John Reck 148113e0824d6bddf4376240681f9cf6a2deded9498John Reck return; 149113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 150113e0824d6bddf4376240681f9cf6a2deded9498John Reck 151113e0824d6bddf4376240681f9cf6a2deded9498John ReckSlang::Slang(const char* Triple, const char* CPU, const char** Features) : 152113e0824d6bddf4376240681f9cf6a2deded9498John Reck mOutputType(SlangCompilerOutput_Default), 153ff941dcd815021bb20d6504eb486acb1e50592c3John Reck mAllowRSPrefix(false) 154ff941dcd815021bb20d6504eb486acb1e50592c3John Reck{ 155ff941dcd815021bb20d6504eb486acb1e50592c3John Reck GlobalInitialization(); 156ff941dcd815021bb20d6504eb486acb1e50592c3John Reck 157ff941dcd815021bb20d6504eb486acb1e50592c3John Reck createDiagnostic(); 158ff941dcd815021bb20d6504eb486acb1e50592c3John Reck llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.get()); 159ff941dcd815021bb20d6504eb486acb1e50592c3John Reck 160ff941dcd815021bb20d6504eb486acb1e50592c3John Reck createTarget(Triple, CPU, Features); 161e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck createFileManager(); 162113e0824d6bddf4376240681f9cf6a2deded9498John Reck createSourceManager(); 163113e0824d6bddf4376240681f9cf6a2deded9498John Reck 164113e0824d6bddf4376240681f9cf6a2deded9498John Reck return; 16552244fff29042926e21fa897ef5ab11148e35299John Reck} 16652244fff29042926e21fa897ef5ab11148e35299John Reck 16752244fff29042926e21fa897ef5ab11148e35299John Reckbool Slang::setInputSource(llvm::StringRef inputFile, const char* text, size_t textLength) { 16852244fff29042926e21fa897ef5ab11148e35299John Reck mInputFileName = inputFile.str(); 169d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck 170d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck /* Reset the ID tables if we are reusing the SourceManager */ 171d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck mSourceMgr->clearIDTables(); 172d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck 173d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck /* Load the source */ 174d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getMemBuffer(text, text + textLength); 175d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck mSourceMgr->createMainFileIDForMemBuffer(SB); 176d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck 17776caecf421b42e9b8294a65f62ff2d90b55a337bChris Craik if(mSourceMgr->getMainFileID().isInvalid()) { 178113e0824d6bddf4376240681f9cf6a2deded9498John Reck mDiagnostics->Report(clang::diag::err_fe_error_reading) << inputFile; 179113e0824d6bddf4376240681f9cf6a2deded9498John Reck return false; 180113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 18176caecf421b42e9b8294a65f62ff2d90b55a337bChris Craik 182113e0824d6bddf4376240681f9cf6a2deded9498John Reck return true; 183113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 184113e0824d6bddf4376240681f9cf6a2deded9498John Reck 185e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckbool Slang::setInputSource(llvm::StringRef inputFile) { 186dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck mInputFileName = inputFile.str(); 187e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck 188e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck mSourceMgr->clearIDTables(); 18968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 190668f0e38ef0277d55d3118af37e17b8c435df85cJohn Reck const FileEntry* File = mFileMgr->getFile(inputFile); 191119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck if(File) 192119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck mSourceMgr->createMainFileID(File, SourceLocation()); 19369e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik 19469e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik if(mSourceMgr->getMainFileID().isInvalid()) { 195b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mDiagnostics->Report(clang::diag::err_fe_error_reading) << inputFile; 196b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return false; 197003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik } 198b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 199b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return true; 200b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 201b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 202b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid Slang::setOutputType(SlangCompilerOutputTy outputType) { 203b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mOutputType = outputType; 2040b7e8245db728d127ada698be63d78b33fc6e4daChris Craik if( mOutputType != SlangCompilerOutput_Assembly && 2050b7e8245db728d127ada698be63d78b33fc6e4daChris Craik mOutputType != SlangCompilerOutput_LL && 206b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mOutputType != SlangCompilerOutput_Bitcode && 2070b7e8245db728d127ada698be63d78b33fc6e4daChris Craik mOutputType != SlangCompilerOutput_Nothing && 2080b7e8245db728d127ada698be63d78b33fc6e4daChris Craik mOutputType != SlangCompilerOutput_Obj) 2090b7e8245db728d127ada698be63d78b33fc6e4daChris Craik mOutputType = SlangCompilerOutput_Default; 2100b7e8245db728d127ada698be63d78b33fc6e4daChris Craik return; 211b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 212113e0824d6bddf4376240681f9cf6a2deded9498John Reck 213a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craikstatic void _mkdir_given_a_file(const char *file) { 214113e0824d6bddf4376240681f9cf6a2deded9498John Reck char buf[256]; 215272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck char *tmp, *p = NULL; 216113e0824d6bddf4376240681f9cf6a2deded9498John Reck size_t len = strlen(file); 217113e0824d6bddf4376240681f9cf6a2deded9498John Reck 218113e0824d6bddf4376240681f9cf6a2deded9498John Reck if (len + 1 <= sizeof(buf)) 219113e0824d6bddf4376240681f9cf6a2deded9498John Reck tmp = buf; 220113e0824d6bddf4376240681f9cf6a2deded9498John Reck else 221113e0824d6bddf4376240681f9cf6a2deded9498John Reck tmp = new char [len + 1]; 222b9ce116dac378b4cf4490f265dcbd5704a1dd43cChris Craik 223b9ce116dac378b4cf4490f265dcbd5704a1dd43cChris Craik strcpy(tmp, file); 224b9ce116dac378b4cf4490f265dcbd5704a1dd43cChris Craik 225113e0824d6bddf4376240681f9cf6a2deded9498John Reck if (tmp[len - 1] == '/') 226113e0824d6bddf4376240681f9cf6a2deded9498John Reck tmp[len - 1] = 0; 2278d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik 2288d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik for (p = tmp + 1; *p; p++) { 229113e0824d6bddf4376240681f9cf6a2deded9498John Reck if (*p == '/') { 230113e0824d6bddf4376240681f9cf6a2deded9498John Reck *p = 0; 231113e0824d6bddf4376240681f9cf6a2deded9498John Reck mkdir(tmp, S_IRWXU); 232b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik *p = '/'; 233113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 234003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik } 235272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck 236113e0824d6bddf4376240681f9cf6a2deded9498John Reck if (tmp != buf) 237b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik delete[] tmp; 238b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik} 239b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik 240113e0824d6bddf4376240681f9cf6a2deded9498John Reckbool Slang::setOutput(const char* outputFile) { 241c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3Chris Craik std::string Error; 242272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck 24380d4902196899d1325cd9f52c06ae0174cf9bd4cChris Craik _mkdir_given_a_file(outputFile); 244113e0824d6bddf4376240681f9cf6a2deded9498John Reck 245113e0824d6bddf4376240681f9cf6a2deded9498John Reck switch(mOutputType) { 246b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik case SlangCompilerOutput_Assembly: 247113e0824d6bddf4376240681f9cf6a2deded9498John Reck case SlangCompilerOutput_LL: 248b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik mOS.reset( new llvm::raw_fd_ostream(outputFile, Error, 0) ); 249b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik break; 250a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik 251b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik case SlangCompilerOutput_Nothing: 252113e0824d6bddf4376240681f9cf6a2deded9498John Reck mOS.reset(); 253b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik break; 254113e0824d6bddf4376240681f9cf6a2deded9498John Reck 255113e0824d6bddf4376240681f9cf6a2deded9498John Reck case SlangCompilerOutput_Obj: 256113e0824d6bddf4376240681f9cf6a2deded9498John Reck case SlangCompilerOutput_Bitcode: 257113e0824d6bddf4376240681f9cf6a2deded9498John Reck default: 258113e0824d6bddf4376240681f9cf6a2deded9498John Reck mOS.reset( new llvm::raw_fd_ostream(outputFile, Error, llvm::raw_fd_ostream::F_Binary) ); 259113e0824d6bddf4376240681f9cf6a2deded9498John Reck break; 260113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 261113e0824d6bddf4376240681f9cf6a2deded9498John Reck 262113e0824d6bddf4376240681f9cf6a2deded9498John Reck if(!Error.empty()) { 263113e0824d6bddf4376240681f9cf6a2deded9498John Reck mOS.reset(); 264113e0824d6bddf4376240681f9cf6a2deded9498John Reck mDiagnostics->Report(clang::diag::err_fe_error_opening) << outputFile << Error; 265113e0824d6bddf4376240681f9cf6a2deded9498John Reck return false; 266113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 267113e0824d6bddf4376240681f9cf6a2deded9498John Reck 268113e0824d6bddf4376240681f9cf6a2deded9498John Reck mOutputFileName = outputFile; 269b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 270b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return true; 271b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 272b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 273a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craikint Slang::compile() { 27425fbb3fa1138675379102a44405852555cefccbdJohn Reck if((mDiagnostics->getNumErrors() > 0) || (mOS.get() == NULL)) 27525fbb3fa1138675379102a44405852555cefccbdJohn Reck return mDiagnostics->getNumErrors(); 276003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik 2770b7e8245db728d127ada698be63d78b33fc6e4daChris Craik /* Here is per-compilation needed initialization */ 27825fbb3fa1138675379102a44405852555cefccbdJohn Reck createPreprocessor(); 2790b7e8245db728d127ada698be63d78b33fc6e4daChris Craik createASTContext(); 280a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck createRSContext(); 28125fbb3fa1138675379102a44405852555cefccbdJohn Reck //createBackend(); 282003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik createRSBackend(); 2830a97330b98dd633b58dcfff405d94476c89e867dJohn Reck 284dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck /* Inform the diagnostic client we are processing a source file */ 285dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck mDiagClient->BeginSourceFile(LangOpts, mPP.get()); 286dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck 2878de65a8e05285df52a1e6f0c1d5616dd233298a7John Reck /* The core of the slang compiler */ 288113e0824d6bddf4376240681f9cf6a2deded9498John Reck ParseAST(*mPP, mBackend.get(), *mASTContext); 289113e0824d6bddf4376240681f9cf6a2deded9498John Reck 290ff941dcd815021bb20d6504eb486acb1e50592c3John Reck /* The compilation ended, clear up */ 291113e0824d6bddf4376240681f9cf6a2deded9498John Reck mBackend.reset(); 292d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck // Can't reset yet because the reflection later on still needs mRSContext 293d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck // mRSContext.reset(); 294003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik mASTContext.reset(); 295003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik mPP.reset(); 296003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik 297003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik /* Inform the diagnostic client we are done with previous source file */ 298113e0824d6bddf4376240681f9cf6a2deded9498John Reck mDiagClient->EndSourceFile(); 29968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 30068bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck return mDiagnostics->getNumErrors(); 301e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} 30225fbb3fa1138675379102a44405852555cefccbdJohn Reck 30325fbb3fa1138675379102a44405852555cefccbdJohn Reckbool Slang::reflectToJava(const char* outputPackageName) { 3040b7e8245db728d127ada698be63d78b33fc6e4daChris Craik if(mRSContext.get()) 30525fbb3fa1138675379102a44405852555cefccbdJohn Reck return mRSContext->reflectToJava(outputPackageName, mInputFileName, mOutputFileName); 306113e0824d6bddf4376240681f9cf6a2deded9498John Reck else 307113e0824d6bddf4376240681f9cf6a2deded9498John Reck return false; 308113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 309113e0824d6bddf4376240681f9cf6a2deded9498John Reck 310113e0824d6bddf4376240681f9cf6a2deded9498John Reckbool Slang::reflectToJavaPath(const char* outputPathName) { 3118d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik if(mRSContext.get()) 312dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck return mRSContext->reflectToJavaPath(outputPathName); 313dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck else 314dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck return false; 315dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck} 316dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck 317dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reckvoid Slang::getPragmas(size_t* actualStringCount, size_t maxStringCount, char** strings) { 318003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik int stringCount = mPragmas.size() * 2; 319dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck 320113e0824d6bddf4376240681f9cf6a2deded9498John Reck if(actualStringCount) 321113e0824d6bddf4376240681f9cf6a2deded9498John Reck *actualStringCount = stringCount; 322113e0824d6bddf4376240681f9cf6a2deded9498John Reck if(stringCount > maxStringCount) 323113e0824d6bddf4376240681f9cf6a2deded9498John Reck stringCount = maxStringCount; 324113e0824d6bddf4376240681f9cf6a2deded9498John Reck if(strings) 325113e0824d6bddf4376240681f9cf6a2deded9498John Reck for(PragmaList::const_iterator it = mPragmas.begin(); 326 stringCount > 0; 327 stringCount-=2, it++) 328 { 329 *strings++ = const_cast<char*>(it->first.c_str()); 330 *strings++ = const_cast<char*>(it->second.c_str()); 331 } 332 333 return; 334} 335 336Slang::~Slang() { 337 llvm::llvm_shutdown(); 338 return; 339} 340 341} /* namespace slang */ 342