slang.cpp revision f7de85223c8728d5dc147e8a19ddf039da72b431
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang#include "slang.h" 2c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang#include <stdlib.h> 4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang#include "llvm/Target/TargetSelect.h" 6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang#include "llvm/Support/raw_ostream.h" 8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang#include "llvm/Support/MemoryBuffer.h" 9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang#include "llvm/Support/ErrorHandling.h" 10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang#include "llvm/Support/ManagedStatic.h" 11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang#include "clang/Basic/LangOptions.h" 13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang#include "clang/Basic/SourceManager.h" 14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang#include "clang/Basic/TargetInfo.h" 15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang#include "clang/Basic/TargetOptions.h" 16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Frontend/DependencyOutputOptions.h" 18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Frontend/FrontendDiagnostic.h" 196315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Frontend/Utils.h" 20462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Lex/Preprocessor.h" 22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Lex/HeaderSearch.h" 238c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang 24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/ASTConsumer.h" 25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/ASTContext.h" 26462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 27be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "clang/Basic/FileManager.h" 28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 29df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao#include "clang/Frontend/CodeGenOptions.h" 306315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Frontend/FrontendDiagnostic.h" 313a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 323a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Parse/ParseAST.h" 336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 34462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_backend.h" 35e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 36e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing namespace slang; 37cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 38cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#if defined(__arm__) 39e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines# define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi" 40cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#elif defined(__x86_64__) 41cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines# define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux" 423a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#else 433a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang// let's use x86 as default target 443a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang# define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux" 456315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#endif 466315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 47be27482cdeaf08576bc39b72a15d35d13014a636Loganbool Slang::GlobalInitialized = false; 48be27482cdeaf08576bc39b72a15d35d13014a636Logan 49e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines// Language option (define the language feature for compiler such as C99) 509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::LangOptions Slang::LangOpts; 5108df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang 5208df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang// Code generation option for the compiler 5308df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Changclang::CodeGenOptions Slang::CodeGenOpts; 54e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 55e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesconst std::string Slang::TargetDescription = 56e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines "e-" // little-endian 57e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines "p:32:32:32-" // 32-bit pointer 58e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines "i1:8:8-" 59e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines "i8:8:8-" 60e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines "i16:16:16-" 61e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines "i32:32:32-" 62be27482cdeaf08576bc39b72a15d35d13014a636Logan "i64:64:64-" 639207a2e495c8363606861e4f034504ec5c153dabLogan Chien "f32:32:32-" 649207a2e495c8363606861e4f034504ec5c153dabLogan Chien "f64:64:64-" 65e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines "v64:64:64-" // 64-bit vector (e.g. float2, int2, short4) 666e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "v128:128:128-" 67e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines "a0:0:64-" 68e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines "n32"; // native CPU only support 32-bit integer width. 69b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 7008df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang// The named of metadata node that pragma resides (should be synced with 7108df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang// bcc.cpp) 72e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesconst llvm::StringRef Slang::PragmaMetadataName = "#pragma"; 73e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 74e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesvoid Slang::GlobalInitialization() { 75e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (!GlobalInitialized) { 76e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // We only support x86, x64 and ARM target 77e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 78e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // For ARM 79e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines LLVMInitializeARMTargetInfo(); 80e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines LLVMInitializeARMTarget(); 81e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines LLVMInitializeARMAsmPrinter(); 82e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 839207a2e495c8363606861e4f034504ec5c153dabLogan Chien // For x86 and x64 84e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines LLVMInitializeX86TargetInfo(); 85e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines LLVMInitializeX86Target(); 86e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines LLVMInitializeX86AsmPrinter(); 87e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 88e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // Please refer to include/clang/Basic/LangOptions.h to setup 89e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // the options. 90e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines LangOpts.RTTI = 0; // Turn off the RTTI information support 91e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines LangOpts.NeXTRuntime = 0; // Turn off the NeXT runtime uses 92e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines LangOpts.Bool = 1; // Turn on 'bool', 'true', 'false' keywords 93e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao CodeGenOpts.OptimizationLevel = 3; /* -O3 */ 95462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao GlobalInitialized = true; 97462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 98462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 99462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 102462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::LLVMErrorHandler(void *UserData, const std::string &Message) { 103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao clang::Diagnostic* Diags = static_cast<clang::Diagnostic*>(UserData); 104462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Diags->Report(clang::diag::err_fe_error_backend) << Message; 105462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao exit(1); 1069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 1079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 108462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::createDiagnostic() { 1096315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mDiagnostics = 1109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::IntrusiveRefCntPtr<clang::Diagnostic>(new clang::Diagnostic()); 111462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mDiagClient = new DiagnosticBuffer(); 1129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // This takes the ownership of mDiagClient. 1139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mDiagnostics->setClient(mDiagClient); 114f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao return; 115462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1169207a2e495c8363606861e4f034504ec5c153dabLogan Chien 1179207a2e495c8363606861e4f034504ec5c153dabLogan Chienvoid Slang::createTarget(const char* Triple, const char* CPU, 1189207a2e495c8363606861e4f034504ec5c153dabLogan Chien const char** Features) { 1199207a2e495c8363606861e4f034504ec5c153dabLogan Chien if (Triple != NULL) 1209207a2e495c8363606861e4f034504ec5c153dabLogan Chien mTargetOpts.Triple = Triple; 1219207a2e495c8363606861e4f034504ec5c153dabLogan Chien else 1229207a2e495c8363606861e4f034504ec5c153dabLogan Chien mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING; 1239207a2e495c8363606861e4f034504ec5c153dabLogan Chien 124e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang if (CPU != NULL) 1256f4e0a9955a53a6f715af7e674e68ed15270a47cLogan Chien mTargetOpts.CPU = CPU; 1266f4e0a9955a53a6f715af7e674e68ed15270a47cLogan Chien 127e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagnostics, 128e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang mTargetOpts)); 129e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang 130e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang if (Features != NULL) 131e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang for (int i = 0; Features[i] != NULL; i++) 132e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang mTargetOpts.Features.push_back(Features[i]); 133e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang 1349207a2e495c8363606861e4f034504ec5c153dabLogan Chien return; 1359207a2e495c8363606861e4f034504ec5c153dabLogan Chien} 136e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang 137e8c263a1c5df81594cf302ecadd813909c894487Zonr Changvoid Slang::createFileManager() { 138e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang mFileMgr.reset(new clang::FileManager()); 139e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang} 140462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Slang::createSourceManager() { 1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mSourceMgr.reset(new clang::SourceManager(*mDiagnostics)); 143462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Slang::createPreprocessor() { 1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Default only search header file in current dir 148462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-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, 153462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao *mSourceMgr, 1543a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang *HS, 1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao NULL, 1569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao /* OwnsHeaderSearch = */true)); 1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Initialize the prepocessor 158245eba133628ef5b52c78d6f538c9268c9bc5828Shih-wei Liao mPragmas.clear(); 159462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPP->AddPragmaHandler(new PragmaRecorder(mPragmas)); 160c460b37ffb50819a32c2a8967754b6f784b28263mkopec 161462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao std::vector<clang::DirectoryLookup> SearchList; 1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) { 1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (const clang::DirectoryEntry *DE = 164462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mFileMgr->getDirectory(mIncludePaths[i])) { 165462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao SearchList.push_back(clang::DirectoryLookup(DE, 166462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao clang::SrcMgr::C_System, 1679207a2e495c8363606861e4f034504ec5c153dabLogan Chien false, 1689207a2e495c8363606861e4f034504ec5c153dabLogan Chien false)); 1699207a2e495c8363606861e4f034504ec5c153dabLogan Chien } 1709207a2e495c8363606861e4f034504ec5c153dabLogan Chien } 1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 172462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao HS->SetSearchPaths(SearchList, 1, false); 173462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1743a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang initPreprocessor(); 1753a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return; 1769207a2e495c8363606861e4f034504ec5c153dabLogan Chien} 177be27482cdeaf08576bc39b72a15d35d13014a636Logan 1789207a2e495c8363606861e4f034504ec5c153dabLogan Chienvoid Slang::createASTContext() { 1799207a2e495c8363606861e4f034504ec5c153dabLogan Chien mASTContext.reset(new clang::ASTContext(LangOpts, 1809207a2e495c8363606861e4f034504ec5c153dabLogan Chien *mSourceMgr, 181641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang *mTarget, 1823a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mPP->getIdentifierTable(), 1833a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mPP->getSelectorTable(), 184b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao mPP->getBuiltinInfo(), 185b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao /* size_reserve = */0)); 186b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao initASTContext(); 1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 1899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 190462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoclang::ASTConsumer 191b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao*Slang::createBackend(const clang::CodeGenOptions& CodeGenOpts, 1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::raw_ostream *OS, 193462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao OutputType OT) { 194b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao return new Backend(*mDiagnostics, 195b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao CodeGenOpts, 196b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao mTargetOpts, 1979207a2e495c8363606861e4f034504ec5c153dabLogan Chien mPragmas, 1989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao OS, 199462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao OT); 200462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 2013a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 202df5bcce1582d839eead432a5e24435236c90fb05Shih-wei LiaoSlang::Slang(const char *Triple, const char *CPU, const char **Features) 203be27482cdeaf08576bc39b72a15d35d13014a636Logan : mDiagClient(NULL), 2043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mOT(OT_Default) { 2053a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang GlobalInitialization(); 2063a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 2079207a2e495c8363606861e4f034504ec5c153dabLogan Chien createDiagnostic(); 2083a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.getPtr()); 2093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 21068e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao createTarget(Triple, CPU, Features); 2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createFileManager(); 2129207a2e495c8363606861e4f034504ec5c153dabLogan Chien createSourceManager(); 2139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2149207a2e495c8363606861e4f034504ec5c153dabLogan Chien return; 2159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 2169207a2e495c8363606861e4f034504ec5c153dabLogan Chien 2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool Slang::setInputSource(llvm::StringRef InputFile, 2189207a2e495c8363606861e4f034504ec5c153dabLogan Chien const char *Text, 2199207a2e495c8363606861e4f034504ec5c153dabLogan Chien size_t TextLength) { 2209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mInputFileName = InputFile.str(); 2213a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 2223fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines // Reset the ID tables if we are reusing the SourceManager 22368e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao mSourceMgr->clearIDTables(); 2243fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines 22568e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao // Load the source 2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::MemoryBuffer *SB = 2273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength); 2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mSourceMgr->createMainFileIDForMemBuffer(SB); 229be27482cdeaf08576bc39b72a15d35d13014a636Logan 2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mSourceMgr->getMainFileID().isInvalid()) { 2319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile; 2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 2359089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao} 2369089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao 2379207a2e495c8363606861e4f034504ec5c153dabLogan Chienbool Slang::setInputSource(llvm::StringRef InputFile) { 2389207a2e495c8363606861e4f034504ec5c153dabLogan Chien mInputFileName = InputFile.str(); 2399207a2e495c8363606861e4f034504ec5c153dabLogan Chien 2409207a2e495c8363606861e4f034504ec5c153dabLogan Chien mSourceMgr->clearIDTables(); 2419089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao 2423a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang const clang::FileEntry *File = mFileMgr->getFile(InputFile); 24368e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao if (File) 24468e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao mSourceMgr->createMainFileID(File); 2453a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 2463a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang if (mSourceMgr->getMainFileID().isInvalid()) { 2473a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile; 2489207a2e495c8363606861e4f034504ec5c153dabLogan Chien return false; 2493a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang } 2503a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 2513a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return true; 2523a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 2533a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 2543a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changstatic void _mkdir_given_a_file(const char *file) { 2553a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang char buf[256]; 2569207a2e495c8363606861e4f034504ec5c153dabLogan Chien char *tmp, *p = NULL; 2579207a2e495c8363606861e4f034504ec5c153dabLogan Chien size_t len = strlen(file); 2589207a2e495c8363606861e4f034504ec5c153dabLogan Chien 2599207a2e495c8363606861e4f034504ec5c153dabLogan Chien if (len + 1 <= sizeof(buf)) 2609207a2e495c8363606861e4f034504ec5c153dabLogan Chien tmp = buf; 2613a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang else 2623a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang tmp = new char[len + 1]; 263641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao strcpy(tmp, file); 265641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 266641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (tmp[len - 1] == '/') 267641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang tmp[len - 1] = 0; 268641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 269641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (p = tmp + 1; *p; p++) { 270641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (*p == '/') { 271462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao *p = 0; 2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mkdir(tmp, S_IRWXU); 2739207a2e495c8363606861e4f034504ec5c153dabLogan Chien *p = '/'; 274462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (tmp != buf) 278462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao delete[] tmp; 279641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 2809207a2e495c8363606861e4f034504ec5c153dabLogan Chien 281641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool Slang::setOutput(const char *OutputFile) { 2829207a2e495c8363606861e4f034504ec5c153dabLogan Chien std::string Error; 2839207a2e495c8363606861e4f034504ec5c153dabLogan Chien 2849207a2e495c8363606861e4f034504ec5c153dabLogan Chien switch (mOT) { 2859207a2e495c8363606861e4f034504ec5c153dabLogan Chien case OT_Dependency: 2869207a2e495c8363606861e4f034504ec5c153dabLogan Chien case OT_Assembly: 2879207a2e495c8363606861e4f034504ec5c153dabLogan Chien case OT_LLVMAssembly: { 288462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao _mkdir_given_a_file(OutputFile); 289462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mOS.reset(new llvm::raw_fd_ostream(OutputFile, Error, 0)); 2903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang break; 2913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang } 2923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang case OT_Nothing: { 2933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mOS.reset(); 294462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao break; 2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case OT_Object: 297462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao case OT_Bitcode: { 2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao _mkdir_given_a_file(OutputFile); 2996315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mOS.reset(new llvm::raw_fd_ostream(OutputFile, 3003a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang Error, 3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::raw_fd_ostream::F_Binary)); 302462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao break; 3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3049207a2e495c8363606861e4f034504ec5c153dabLogan Chien default: 3059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm_unreachable("Unknown compiler output type"); 3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 3079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 308462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 309462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if (!Error.empty()) { 3103a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mOS.reset(); 3113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile 312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao << Error; 3139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 315be27482cdeaf08576bc39b72a15d35d13014a636Logan 3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mOutputFileName = OutputFile; 3179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 318462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return true; 3199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 3209207a2e495c8363606861e4f034504ec5c153dabLogan Chien 3219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool Slang::setDepTargetBC(const char *targetBCFile) { 3229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mDepTargetBCFileName = targetBCFile; 323462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 325462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 326462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changint Slang::generateDepFile() { 3288c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang if(mDiagnostics->getNumErrors() > 0) 3299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return mDiagnostics->getNumErrors(); 330e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang if (mOS.get() == NULL) 331462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return 1; 3323a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 333cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines /* Initialize options for generating dependency file */ 3343a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang clang::DependencyOutputOptions DepOpts; 3353a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang DepOpts.IncludeSystemHeaders = 1; 3369207a2e495c8363606861e4f034504ec5c153dabLogan Chien DepOpts.OutputFile = mOutputFileName; 3379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DepOpts.Targets.push_back(mDepTargetBCFileName); 338462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3393a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang /* Per-compilation needed initialization */ 3409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao createPreprocessor(); 341462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao AttachDependencyFileGen(*mPP.get(), DepOpts); 3423a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 343cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines /* Inform the diagnostic client we are processing a source file */ 3449207a2e495c8363606861e4f034504ec5c153dabLogan Chien mDiagClient->BeginSourceFile(LangOpts, mPP.get()); 3459207a2e495c8363606861e4f034504ec5c153dabLogan Chien 3469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao /* Go through the source file (no operations necessary) */ 3479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::Token Tok; 3488c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang mPP->EnterMainSourceFile(); 349cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines do { 3508c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang mPP->Lex(Tok); 3519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } while (Tok.isNot(clang::tok::eof)); 352462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 353e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang mPP->EndSourceFile(); 3549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 355e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang /* Clean up after compilation */ 356e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang mPP.reset(); 3579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3583a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return mDiagnostics->getNumErrors(); 359462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 3609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 361462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoint Slang::compile() { 362462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if (mOT == OT_Dependency) 3630b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines return generateDepFile(); 3648c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang 3650b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines if (mDiagnostics->getNumErrors() > 0) 3668c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang return mDiagnostics->getNumErrors(); 3679207a2e495c8363606861e4f034504ec5c153dabLogan Chien if (mOS.get() == NULL) 368e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang return 1; 3690b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines 3700b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines // Here is per-compilation needed initialization 3710b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines createPreprocessor(); 3720b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines createASTContext(); 3730b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines 3740b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines mBackend.reset(createBackend(CodeGenOpts, mOS.take(), mOT)); 3750b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines 376cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines // Inform the diagnostic client we are processing a source file 3779207a2e495c8363606861e4f034504ec5c153dabLogan Chien mDiagClient->BeginSourceFile(LangOpts, mPP.get()); 378be27482cdeaf08576bc39b72a15d35d13014a636Logan 3790b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines // The core of the slang compiler 380f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines ParseAST(*mPP, mBackend.get(), *mASTContext); 381cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 382e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang // The compilation ended, clear 383cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines mBackend.reset(); 384cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines mASTContext.reset(); 3850b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines mPP.reset(); 386b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 387cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines // Inform the diagnostic client we are done with previous source file 3884cc67fce91f43215d61b2695746eab102a3db516Stephen Hines mDiagClient->EndSourceFile(); 3894cc67fce91f43215d61b2695746eab102a3db516Stephen Hines 3904cc67fce91f43215d61b2695746eab102a3db516Stephen Hines return mDiagnostics->getNumErrors(); 3914cc67fce91f43215d61b2695746eab102a3db516Stephen Hines} 3924cc67fce91f43215d61b2695746eab102a3db516Stephen Hines 3934cc67fce91f43215d61b2695746eab102a3db516Stephen Hinesvoid Slang::reset() { 3944cc67fce91f43215d61b2695746eab102a3db516Stephen Hines mDiagnostics->Reset(); 395cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines mDiagClient->reset(); 396e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang return; 397cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines} 398cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines 399cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen HinesSlang::~Slang() { 400e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang llvm::llvm_shutdown(); 401cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines return; 402cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines} 403e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang