[go: nahoru, domu]

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