slang.cpp revision 3a9ca1f0d6bd8f12c2bb2adea51f95c255996180
16315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang.h" 2462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 36315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <stdlib.h> 4462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 56315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Target/TargetSelect.h" 6462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 73a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "llvm/Support/raw_ostream.h" 86315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/MemoryBuffer.h" 96315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/ErrorHandling.h" 106315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/ManagedStatic.h" 11462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 126315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Basic/LangOptions.h" 133a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/SourceManager.h" 143a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/TargetInfo.h" 156315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Basic/TargetOptions.h" 16462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/Preprocessor.h" 183a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/HeaderSearch.h" 193a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 203a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/AST/ASTConsumer.h" 213a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/AST/ASTContext.h" 223a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/FileManager.h" 243a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 253a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Frontend/CodeGenOptions.h" 266315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Frontend/FrontendDiagnostic.h" 27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 286315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Parse/ParseAST.h" 296315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 303a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "slang_backend.h" 319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaousing namespace slang; 339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 34462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#if defined(__arm__) 35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao# define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi" 36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#elif defined(__x86_64__) 37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao# define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux" 38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#else 399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// let's use x86 as default target 409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao# define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux" 41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#endif 42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::GlobalInitialized = false; 44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// Language option (define the language feature for compiler such as C99) 469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::LangOptions Slang::LangOpts; 47462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 486315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr// Code generation option for the compiler 499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::CodeGenOptions Slang::CodeGenOpts; 50462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 516315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst std::string Slang::TargetDescription = 526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "e-" // little-endian 536315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "p:32:32:32-" // 32-bit pointer 546315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "i1:8:8-" 556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "i8:8:8-" 566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "i16:16:16-" 576315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "i32:32:32-" 586315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "i64:64:64-" 596315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "f32:32:32-" 606315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "f64:64:64-" 616315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "v64:64:64-" // 64-bit vector (e.g. float2, int2, short4) 626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "v128:128:128-" 636315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "a0:0:64-" 646315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "n32"; // native CPU only support 32-bit integer width. 65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// The named of metadata node that pragma resides (should be synced with 679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// bcc.cpp) 68f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liaoconst llvm::StringRef Slang::PragmaMetadataName = "#pragma"; 69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::GlobalInitialization() { 719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!GlobalInitialized) { 729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // We only support x86, x64 and ARM target 73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // For ARM 759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LLVMInitializeARMTargetInfo(); 769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LLVMInitializeARMTarget(); 779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LLVMInitializeARMAsmPrinter(); 78462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // For x86 and x64 809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LLVMInitializeX86TargetInfo(); 819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LLVMInitializeX86Target(); 829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LLVMInitializeX86AsmPrinter(); 83462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 843a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang // Please refer to include/clang/Basic/LangOptions.h to setup 859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // the options. 869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LangOpts.RTTI = 0; // Turn off the RTTI information support 879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LangOpts.NeXTRuntime = 0; // Turn off the NeXT runtime uses 889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LangOpts.Bool = 1; // Turn on 'bool', 'true', 'false' keywords 89462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao CodeGenOpts.OptimizationLevel = 3; /* -O3 */ 91462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao GlobalInitialized = true; 939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 94462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 97462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 98462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::LLVMErrorHandler(void *UserData, const std::string &Message) { 999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Diagnostic* Diags = static_cast<clang::Diagnostic*>(UserData); 1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Diags->Report(clang::diag::err_fe_error_backend) << Message; 1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao exit(1); 102462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createDiagnostic() { 1053a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics = 1063a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang llvm::IntrusiveRefCntPtr<clang::Diagnostic>(new clang::Diagnostic()); 1073a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagClient = new DiagnosticBuffer(); 1083a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang // This takes the ownership of mDiagClient. 1093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics->setClient(mDiagClient); 1103a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return; 1113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 1123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 1139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Slang::createTarget(const char* Triple, const char* CPU, 1149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const char** Features) { 1159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (Triple != NULL) 1169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mTargetOpts.Triple = Triple; 1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING; 119462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (CPU != NULL) 1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mTargetOpts.CPU = CPU; 122462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagnostics, 1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mTargetOpts)); 125462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (Features != NULL) 1276315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr for (int i = 0; Features[i] != NULL; i++) 1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mTargetOpts.Features.push_back(Features[i]); 129462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 130462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 131462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 132462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1333a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createFileManager() { 1343a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mFileMgr.reset(new clang::FileManager()); 1353a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 1363a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 1373a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createSourceManager() { 1383a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mSourceMgr.reset(new clang::SourceManager(*mDiagnostics)); 1393a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return; 1403a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 1413a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 14268e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liaovoid Slang::createPreprocessor() { 1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Default only search header file in current dir 1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::HeaderSearch *HS = new clang::HeaderSearch(*mFileMgr); 1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mPP.reset(new clang::Preprocessor(*mDiagnostics, 1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LangOpts, 1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao *mTarget, 1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao *mSourceMgr, 1509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao *HS, 1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao NULL, 1523a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang /* OwnsHeaderSearch = */true)); 1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Initialize the prepocessor 15468e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao mPragmas.clear(); 155f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao mPP->AddPragmaHandler(new PragmaRecorder(mPragmas)); 15668e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao 1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::vector<clang::DirectoryLookup> SearchList; 1583a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) { 1599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (const clang::DirectoryEntry *DE = 1603a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mFileMgr->getDirectory(mIncludePaths[i])) { 1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao SearchList.push_back(clang::DirectoryLookup(DE, 1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::SrcMgr::C_System, 1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao false, 1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao false)); 1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1669089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao } 1679089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao 1689089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao HS->SetSearchPaths(SearchList, 1, false); 1699089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao 1703a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang initPreprocessor(); 17168e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao return; 17268e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao} 17368e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao 1743a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createASTContext() { 1753a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mASTContext.reset(new clang::ASTContext(LangOpts, 1763a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang *mSourceMgr, 1773a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang *mTarget, 1783a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mPP->getIdentifierTable(), 1793a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mPP->getSelectorTable(), 1803a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mPP->getBuiltinInfo(), 1813a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang /* size_reserve = */0)); 1823a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang initASTContext(); 1833a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return; 1843a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 1853a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 1863a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changclang::ASTConsumer 1873a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang*Slang::createBackend(const clang::CodeGenOptions& CodeGenOpts, 1883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang llvm::raw_ostream *OS, 1893a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang OutputType OT) { 1903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return new Backend(*mDiagnostics, 1913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang CodeGenOpts, 1923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mTargetOpts, 1933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mPragmas, 1943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang OS, 1953a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang OT); 1963a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 1973a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 1986315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrSlang::Slang(const char *Triple, const char *CPU, const char **Features) 1993a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang : mDiagClient(NULL), 2003a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mOT(OT_Default) { 2019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao GlobalInitialization(); 202462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createDiagnostic(); 2043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.getPtr()); 205462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createTarget(Triple, CPU, Features); 2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createFileManager(); 2089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createSourceManager(); 209462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 211462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 212462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2133a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile, 2143a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang const char *Text, 2153a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang size_t TextLength) { 2163a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mInputFileName = InputFile.str(); 217462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Reset the ID tables if we are reusing the SourceManager 2199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mSourceMgr->clearIDTables(); 220462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Load the source 2226315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr llvm::MemoryBuffer *SB = 2233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength); 2249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mSourceMgr->createMainFileIDForMemBuffer(SB); 225462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mSourceMgr->getMainFileID().isInvalid()) { 2273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile; 2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 231462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 232462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2333a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile) { 2343a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mInputFileName = InputFile.str(); 235462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mSourceMgr->clearIDTables(); 237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2383a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang const clang::FileEntry *File = mFileMgr->getFile(InputFile); 2399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (File) 2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mSourceMgr->createMainFileID(File); 241462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mSourceMgr->getMainFileID().isInvalid()) { 2433a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile; 2449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 2459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 246462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 248462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 249462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 250b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liaostatic void _mkdir_given_a_file(const char *file) { 2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao char buf[256]; 2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao char *tmp, *p = NULL; 2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao size_t len = strlen(file); 254807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou 2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (len + 1 <= sizeof(buf)) 2569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao tmp = buf; 2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2586315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr tmp = new char[len + 1]; 2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao strcpy(tmp, file); 261b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao 2629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (tmp[len - 1] == '/') 2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao tmp[len - 1] = 0; 2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (p = tmp + 1; *p; p++) { 2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (*p == '/') { 2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao *p = 0; 2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mkdir(tmp, S_IRWXU); 2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao *p = '/'; 2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 272462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (tmp != buf) 2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete[] tmp; 2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 276b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao 2773a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setOutput(const char *OutputFile) { 2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::string Error; 279462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2803a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang _mkdir_given_a_file(OutputFile); 281462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2823a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang switch (mOT) { 2833a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case OT_Assembly: 2843a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case OT_LLVMAssembly: { 2853a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mOS.reset(new llvm::raw_fd_ostream(OutputFile, Error, 0)); 2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 287462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 2883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case OT_Nothing: { 2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mOS.reset(); 2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 291462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 2923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case OT_Object: 2933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case OT_Bitcode: 2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 2953a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mOS.reset(new llvm::raw_fd_ostream(OutputFile, 2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Error, 2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::raw_fd_ostream::F_Binary)); 2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 301462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Error.empty()) { 3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mOS.reset(); 3043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile 3059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao << Error; 3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 3079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mOutputFileName = OutputFile; 310462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 313462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoint Slang::compile() { 3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((mDiagnostics->getNumErrors() > 0) || (mOS.get() == NULL)) 3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return mDiagnostics->getNumErrors(); 317462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Here is per-compilation needed initialization 3199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createPreprocessor(); 3209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createASTContext(); 3213a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 3223a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mBackend.reset(createBackend(CodeGenOpts, mOS.take(), mOT)); 323462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Inform the diagnostic client we are processing a source file 3259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mDiagClient->BeginSourceFile(LangOpts, mPP.get()); 326462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // The core of the slang compiler 3289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ParseAST(*mPP, mBackend.get(), *mASTContext); 329462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3303a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang // The compilation ended, clear 3319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mBackend.reset(); 3329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mASTContext.reset(); 3339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mPP.reset(); 334462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Inform the diagnostic client we are done with previous source file 3369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mDiagClient->EndSourceFile(); 337462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return mDiagnostics->getNumErrors(); 339462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 340462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3413a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::reset() { 3423a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics->Reset(); 3433a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagClient->reset(); 3449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 345462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 346462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 347462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoSlang::~Slang() { 3489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::llvm_shutdown(); 3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 350462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 351