slang.cpp revision cc0efad052e944f64bb71cfdaa8a825e30192e78
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 17cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/DependencyOutputOptions.h" 18cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/FrontendDiagnostic.h" 19cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/Utils.h" 20cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 213a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/Preprocessor.h" 223a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/HeaderSearch.h" 233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 243a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/AST/ASTConsumer.h" 253a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/AST/ASTContext.h" 263a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/FileManager.h" 283a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 293a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Frontend/CodeGenOptions.h" 306315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Frontend/FrontendDiagnostic.h" 31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Parse/ParseAST.h" 336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 343a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "slang_backend.h" 359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaousing namespace slang; 379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#if defined(__arm__) 39462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao# define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi" 40462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#elif defined(__x86_64__) 41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao# define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux" 42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#else 439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// let's use x86 as default target 449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao# define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux" 45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#endif 46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 47462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::GlobalInitialized = false; 48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// Language option (define the language feature for compiler such as C99) 509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::LangOptions Slang::LangOpts; 51462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr// Code generation option for the compiler 539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::CodeGenOptions Slang::CodeGenOpts; 54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst std::string Slang::TargetDescription = 566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "e-" // little-endian 576315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "p:32:32:32-" // 32-bit pointer 586315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "i1:8:8-" 596315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "i8:8:8-" 606315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "i16:16:16-" 616315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "i32:32:32-" 626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "i64:64:64-" 636315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "f32:32:32-" 646315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "f64:64:64-" 656315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "v64:64:64-" // 64-bit vector (e.g. float2, int2, short4) 666315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "v128:128:128-" 676315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "a0:0:64-" 686315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr "n32"; // native CPU only support 32-bit integer width. 69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// The named of metadata node that pragma resides (should be synced with 719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// bcc.cpp) 72f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liaoconst llvm::StringRef Slang::PragmaMetadataName = "#pragma"; 73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 74462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::GlobalInitialization() { 759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!GlobalInitialized) { 769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // We only support x86, x64 and ARM target 77462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // For ARM 799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LLVMInitializeARMTargetInfo(); 809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LLVMInitializeARMTarget(); 819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LLVMInitializeARMAsmPrinter(); 82462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // For x86 and x64 849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LLVMInitializeX86TargetInfo(); 859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LLVMInitializeX86Target(); 869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LLVMInitializeX86AsmPrinter(); 87462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang // Please refer to include/clang/Basic/LangOptions.h to setup 899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // the options. 909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LangOpts.RTTI = 0; // Turn off the RTTI information support 919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LangOpts.NeXTRuntime = 0; // Turn off the NeXT runtime uses 929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LangOpts.Bool = 1; // Turn on 'bool', 'true', 'false' keywords 93462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao CodeGenOpts.OptimizationLevel = 3; /* -O3 */ 95462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao GlobalInitialized = true; 979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 98462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 100462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 101462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 102462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::LLVMErrorHandler(void *UserData, const std::string &Message) { 1039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Diagnostic* Diags = static_cast<clang::Diagnostic*>(UserData); 1049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Diags->Report(clang::diag::err_fe_error_backend) << Message; 1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao exit(1); 106462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 107462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1083a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createDiagnostic() { 1093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics = 1103a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang llvm::IntrusiveRefCntPtr<clang::Diagnostic>(new clang::Diagnostic()); 1113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagClient = new DiagnosticBuffer(); 1123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang // This takes the ownership of mDiagClient. 1133a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics->setClient(mDiagClient); 1143a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return; 1153a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 1163a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Slang::createTarget(const char* Triple, const char* CPU, 1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const char** Features) { 1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (Triple != NULL) 1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mTargetOpts.Triple = Triple; 1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING; 123462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (CPU != NULL) 1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mTargetOpts.CPU = CPU; 126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagnostics, 1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mTargetOpts)); 129462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (Features != NULL) 1316315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr for (int i = 0; Features[i] != NULL; i++) 1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mTargetOpts.Features.push_back(Features[i]); 133462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 134462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 135462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 136462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1373a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createFileManager() { 1383a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mFileMgr.reset(new clang::FileManager()); 1393a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 1403a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 1413a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createSourceManager() { 1423a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mSourceMgr.reset(new clang::SourceManager(*mDiagnostics)); 1433a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return; 1443a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 1453a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 14668e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liaovoid Slang::createPreprocessor() { 1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Default only search header file in current dir 1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::HeaderSearch *HS = new clang::HeaderSearch(*mFileMgr); 1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mPP.reset(new clang::Preprocessor(*mDiagnostics, 1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao LangOpts, 1529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao *mTarget, 1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao *mSourceMgr, 1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao *HS, 1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao NULL, 1563a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang /* OwnsHeaderSearch = */true)); 1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Initialize the prepocessor 15868e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao mPragmas.clear(); 159f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao mPP->AddPragmaHandler(new PragmaRecorder(mPragmas)); 16068e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao 1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::vector<clang::DirectoryLookup> SearchList; 1623a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) { 1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (const clang::DirectoryEntry *DE = 1643a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mFileMgr->getDirectory(mIncludePaths[i])) { 1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao SearchList.push_back(clang::DirectoryLookup(DE, 1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::SrcMgr::C_System, 1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao false, 1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao false)); 1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1709089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao } 1719089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao 1729089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao HS->SetSearchPaths(SearchList, 1, false); 1739089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao 1743a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang initPreprocessor(); 17568e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao return; 17668e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao} 17768e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao 1783a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createASTContext() { 1793a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mASTContext.reset(new clang::ASTContext(LangOpts, 1803a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang *mSourceMgr, 1813a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang *mTarget, 1823a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mPP->getIdentifierTable(), 1833a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mPP->getSelectorTable(), 1843a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mPP->getBuiltinInfo(), 1853a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang /* size_reserve = */0)); 1863a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang initASTContext(); 1873a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return; 1883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 1893a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 1903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changclang::ASTConsumer 1913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang*Slang::createBackend(const clang::CodeGenOptions& CodeGenOpts, 1923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang llvm::raw_ostream *OS, 1933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang OutputType OT) { 1943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return new Backend(*mDiagnostics, 1953a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang CodeGenOpts, 1963a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mTargetOpts, 1973a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mPragmas, 1983a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang OS, 1993a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang OT); 2003a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 2013a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 2026315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrSlang::Slang(const char *Triple, const char *CPU, const char **Features) 2033a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang : mDiagClient(NULL), 2043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mOT(OT_Default) { 2059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao GlobalInitialization(); 206462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createDiagnostic(); 2083a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.getPtr()); 209462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createTarget(Triple, CPU, Features); 2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createFileManager(); 2129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createSourceManager(); 213462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 215462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 216462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile, 2183a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang const char *Text, 2193a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang size_t TextLength) { 2203a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mInputFileName = InputFile.str(); 221462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Reset the ID tables if we are reusing the SourceManager 2239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mSourceMgr->clearIDTables(); 224462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Load the source 2266315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr llvm::MemoryBuffer *SB = 2273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength); 2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mSourceMgr->createMainFileIDForMemBuffer(SB); 229462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mSourceMgr->getMainFileID().isInvalid()) { 2313a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile; 2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 235462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 236462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2373a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile) { 2383a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mInputFileName = InputFile.str(); 239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mSourceMgr->clearIDTables(); 241462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2423a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang const clang::FileEntry *File = mFileMgr->getFile(InputFile); 2439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (File) 2449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mSourceMgr->createMainFileID(File); 245462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mSourceMgr->getMainFileID().isInvalid()) { 2473a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile; 2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 250462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 252462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 253462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 254b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liaostatic void _mkdir_given_a_file(const char *file) { 2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao char buf[256]; 2569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao char *tmp, *p = NULL; 2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao size_t len = strlen(file); 258807a0eaf3c19dc067becdca46a10e8c703d1e871Che-Liang Chiou 2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (len + 1 <= sizeof(buf)) 2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao tmp = buf; 2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr tmp = new char[len + 1]; 2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao strcpy(tmp, file); 265b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao 2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (tmp[len - 1] == '/') 2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao tmp[len - 1] = 0; 2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (p = tmp + 1; *p; p++) { 2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (*p == '/') { 2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao *p = 0; 2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mkdir(tmp, S_IRWXU); 2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao *p = '/'; 2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 276462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (tmp != buf) 2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete[] tmp; 2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 280b55d7ef3333534fc6aad80f9a9133f2bf945faf1Shih-wei Liao 2813a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setOutput(const char *OutputFile) { 2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::string Error; 283462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 284462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2853a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang switch (mOT) { 286cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines case OT_Dependency: 2873a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case OT_Assembly: 2883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case OT_LLVMAssembly: { 289cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines _mkdir_given_a_file(OutputFile); 2903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mOS.reset(new llvm::raw_fd_ostream(OutputFile, Error, 0)); 2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 292462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 2933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case OT_Nothing: { 2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mOS.reset(); 2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 296462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 2973a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case OT_Object: 298cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines case OT_Bitcode: { 299cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines _mkdir_given_a_file(OutputFile); 3003a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mOS.reset(new llvm::raw_fd_ostream(OutputFile, 3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Error, 3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::raw_fd_ostream::F_Binary)); 3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 305cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines default: 306cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines llvm_unreachable("Unknown compiler output type"); 307cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines break; 3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 309462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Error.empty()) { 3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mOS.reset(); 3123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile 3139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao << Error; 3149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mOutputFileName = OutputFile; 318462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 320462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 321462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 322cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hinesbool Slang::setDepTargetBC(const char *targetBCFile) { 323cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines mDepTargetBCFileName = targetBCFile; 324cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 325cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines return true; 326cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines} 327cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 328cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hinesint Slang::generateDepFile() { 329cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines if((mDiagnostics->getNumErrors() > 0) || (mOS.get() == NULL)) 330cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines return mDiagnostics->getNumErrors(); 331cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 332cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines /* Initialize options for generating dependency file */ 333cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines clang::DependencyOutputOptions DepOpts; 334cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines DepOpts.IncludeSystemHeaders = 1; 335cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines DepOpts.OutputFile = mOutputFileName; 336cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines DepOpts.Targets.push_back(mDepTargetBCFileName); 337cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 338cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines /* Per-compilation needed initialization */ 339cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines createPreprocessor(); 340cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines AttachDependencyFileGen(*mPP.get(), DepOpts); 341cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 342cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines /* Inform the diagnostic client we are processing a source file */ 343cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines mDiagClient->BeginSourceFile(LangOpts, mPP.get()); 344cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 345cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines /* Go through the source file (no operations necessary) */ 346cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines clang::Token Tok; 347cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines mPP->EnterMainSourceFile(); 348cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines do { 349cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines mPP->Lex(Tok); 350cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines } while (Tok.isNot(clang::tok::eof)); 351cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 352cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines mPP->EndSourceFile(); 353cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 354cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines /* Clean up after compilation */ 355cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines mPP.reset(); 356cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 357cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines return mDiagnostics->getNumErrors(); 358cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines} 359cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 360462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoint Slang::compile() { 361cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines if (mOT == OT_Dependency) 362cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines return generateDepFile(); 363cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 3649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((mDiagnostics->getNumErrors() > 0) || (mOS.get() == NULL)) 3659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return mDiagnostics->getNumErrors(); 366462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Here is per-compilation needed initialization 3689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createPreprocessor(); 3699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createASTContext(); 3703a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 3713a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mBackend.reset(createBackend(CodeGenOpts, mOS.take(), mOT)); 372462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Inform the diagnostic client we are processing a source file 3749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mDiagClient->BeginSourceFile(LangOpts, mPP.get()); 375462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // The core of the slang compiler 3779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ParseAST(*mPP, mBackend.get(), *mASTContext); 378462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3793a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang // The compilation ended, clear 3809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mBackend.reset(); 3819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mASTContext.reset(); 3829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mPP.reset(); 383462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Inform the diagnostic client we are done with previous source file 3859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mDiagClient->EndSourceFile(); 386462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return mDiagnostics->getNumErrors(); 388462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 389462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::reset() { 3913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics->Reset(); 3923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagClient->reset(); 3939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 394462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 395462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 396462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoSlang::~Slang() { 3979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::llvm_shutdown(); 3989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 399462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 400