slang.cpp revision df5bcce1582d839eead432a5e24435236c90fb05
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/*
2c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Copyright 2010, The Android Open Source Project
3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License.
6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at
7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software
11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and
14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License.
15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */
16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang
176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang.h"
18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
196315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <stdlib.h>
20462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <string>
22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <vector>
238c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang
24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/ASTConsumer.h"
25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/ASTContext.h"
26462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/FileManager.h"
28df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao#include "clang/Basic/FileSystemOptions.h"
296315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Basic/LangOptions.h"
303a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/SourceManager.h"
313a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/TargetInfo.h"
326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Basic/TargetOptions.h"
33462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
34e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Frontend/CodeGenOptions.h"
35e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Frontend/DiagnosticOptions.h"
36cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/DependencyOutputOptions.h"
37cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/FrontendDiagnostic.h"
38e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Frontend/TextDiagnosticPrinter.h"
39cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/Utils.h"
40cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
413a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/Preprocessor.h"
423a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/HeaderSearch.h"
433a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
446315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Parse/ParseAST.h"
456315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
46e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Bitcode/ReaderWriter.h"
479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4808df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang// More force linking
4908df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang#include "llvm/Linker.h"
5008df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang
51e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines// Force linking all passes/vmcore stuffs to libslang.so
52e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/LinkAllPasses.h"
53e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/LinkAllVMCore.h"
54e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
55e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/raw_ostream.h"
56e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/MemoryBuffer.h"
57e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/ErrorHandling.h"
58e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/ManagedStatic.h"
59df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao#include "llvm/Support/ToolOutputFile.h"
60e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
61e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/System/Path.h"
62e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
63e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Target/TargetSelect.h"
64e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
66e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_backend.h"
67e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_utils.h"
68b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
6908df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Changnamespace {
7008df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang
71e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesstruct ForceSlangLinking {
72e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  ForceSlangLinking() {
73e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    // We must reference the functions in such a way that compilers will not
74e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    // delete it all as dead code, even with whole program optimization,
75e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    // yet is effectively a NO-OP. As the compiler isn't smart enough
76e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    // to know that getenv() never returns -1, this will do the job.
77e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    if (std::getenv("bar") != reinterpret_cast<char*>(-1))
78e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines      return;
79e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
80e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    // llvm-rs-link needs following functions existing in libslang.
81e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    llvm::ParseBitcodeFile(NULL, llvm::getGlobalContext(), NULL);
82e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    llvm::Linker::LinkModules(NULL, NULL, NULL);
83e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
84e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    // llvm-rs-cc need this.
85e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    new clang::TextDiagnosticPrinter(llvm::errs(),
86e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                     clang::DiagnosticOptions());
87e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  }
88e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} ForceSlangLinking;
89e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
90e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace
91e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
92e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
94462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#if defined(__arm__)
95462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#elif defined(__x86_64__)
97462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux"
98462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#else
999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// let's use x86 as default target
1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#   define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux"
101462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#endif
102462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Slang::GlobalInitialized = false;
104462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// Language option (define the language feature for compiler such as C99)
1069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::LangOptions Slang::LangOpts;
107462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1086315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr// Code generation option for the compiler
1099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclang::CodeGenOptions Slang::CodeGenOpts;
110462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// The named of metadata node that pragma resides (should be synced with
1129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// bcc.cpp)
113f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liaoconst llvm::StringRef Slang::PragmaMetadataName = "#pragma";
114462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
115e8c263a1c5df81594cf302ecadd813909c894487Zonr Changstatic inline llvm::tool_output_file *OpenOutputFile(const char *OutputFile,
116e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang                                                     unsigned Flags,
117e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang                                                     std::string* Error,
118e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang                                                     clang::Diagnostic* Diag) {
1196e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert((OutputFile != NULL) && (Error != NULL) && (Diag != NULL) &&
1206e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Invalid parameter!");
121e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
122e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  llvm::sys::Path OutputFilePath(OutputFile);
123e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
124e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  if (SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
125e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang                                             Error)) {
126e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    llvm::tool_output_file *F =
127e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang          new llvm::tool_output_file(OutputFile, *Error, Flags);
128e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    if (F != NULL)
129e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang      return F;
130e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  }
131e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
132e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Report error here.
133e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  Diag->Report(clang::diag::err_fe_error_opening) << OutputFile << *Error;
134e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
135e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  return NULL;
136e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang}
137e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
138462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::GlobalInitialization() {
1399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!GlobalInitialized) {
1409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // We only support x86, x64 and ARM target
141462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // For ARM
1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMTargetInfo();
1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMTarget();
1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeARMAsmPrinter();
146462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // For x86 and x64
1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86TargetInfo();
1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86Target();
1509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LLVMInitializeX86AsmPrinter();
151462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1523a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    // Please refer to include/clang/Basic/LangOptions.h to setup
1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // the options.
1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.RTTI = 0;  // Turn off the RTTI information support
1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    LangOpts.NeXTRuntime = 0;   // Turn off the NeXT runtime uses
156245eba133628ef5b52c78d6f538c9268c9bc5828Shih-wei Liao    LangOpts.C99 = 1;
157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    CodeGenOpts.OptimizationLevel = 3;  /* -O3 */
159462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    GlobalInitialized = true;
1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
162462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
164462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
165462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
166462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Slang::LLVMErrorHandler(void *UserData, const std::string &Message) {
1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clang::Diagnostic* Diags = static_cast<clang::Diagnostic*>(UserData);
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  Diags->Report(clang::diag::err_fe_error_backend) << Message;
1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  exit(1);
170462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
171462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1723a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createDiagnostic() {
1733a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagnostics =
1743a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      llvm::IntrusiveRefCntPtr<clang::Diagnostic>(new clang::Diagnostic());
1753a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagClient = new DiagnosticBuffer();
1763a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  // This takes the ownership of mDiagClient.
1773a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagnostics->setClient(mDiagClient);
178641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang  initDiagnostic();
1793a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
1803a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1813a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
182b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaovoid Slang::createTarget(const std::string &Triple, const std::string &CPU,
183b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                         const std::vector<std::string> &Features) {
184b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (!Triple.empty())
1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.Triple = Triple;
1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING;
188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
189b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (!CPU.empty())
1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mTargetOpts.CPU = CPU;
191462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
192b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (!Features.empty())
193b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    mTargetOpts.Features = Features;
194b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagnostics,
1969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                    mTargetOpts));
197462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
198b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  return;
199462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
200462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2013a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createFileManager() {
2023a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mFileMgr.reset(new clang::FileManager());
203df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao  mFileSysOpt.reset(new clang::FileSystemOptions());
2043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
2053a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
2063a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createSourceManager() {
207df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao  mSourceMgr.reset(new clang::SourceManager(*mDiagnostics,
208df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao                                            *mFileMgr,
209df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao                                            *mFileSysOpt));
2103a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
2113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
2123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
21368e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liaovoid Slang::createPreprocessor() {
2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Default only search header file in current dir
215df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao  clang::HeaderSearch *HS = new clang::HeaderSearch(*mFileMgr, *mFileSysOpt);
2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mPP.reset(new clang::Preprocessor(*mDiagnostics,
2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    LangOpts,
2199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *mTarget,
2209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *mSourceMgr,
2219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *HS,
2229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    NULL,
2233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                    /* OwnsHeaderSearch = */true));
2243fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines  // Initialize the preprocessor
22568e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  mPragmas.clear();
2263fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines  mPP->AddPragmaHandler(new PragmaRecorder(&mPragmas));
22768e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::vector<clang::DirectoryLookup> SearchList;
2293a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (const clang::DirectoryEntry *DE =
231df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao            mFileMgr->getDirectory(mIncludePaths[i], *mFileSysOpt)) {
2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      SearchList.push_back(clang::DirectoryLookup(DE,
2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  clang::SrcMgr::C_System,
2349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  false,
2359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  false));
2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
2379089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  }
2389089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
2399089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  HS->SetSearchPaths(SearchList, 1, false);
2409089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
2413a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initPreprocessor();
24268e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  return;
24368e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao}
24468e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
2453a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createASTContext() {
2463a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mASTContext.reset(new clang::ASTContext(LangOpts,
2473a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          *mSourceMgr,
2483a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          *mTarget,
2493a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          mPP->getIdentifierTable(),
2503a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          mPP->getSelectorTable(),
2513a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          mPP->getBuiltinInfo(),
2523a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                          /* size_reserve = */0));
2533a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initASTContext();
2543a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  return;
2553a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
2563a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
2573a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changclang::ASTConsumer
2583a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang*Slang::createBackend(const clang::CodeGenOptions& CodeGenOpts,
2593a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                      llvm::raw_ostream *OS,
2603a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                      OutputType OT) {
261e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  return new Backend(mDiagnostics.getPtr(),
2623a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     CodeGenOpts,
2633a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     mTargetOpts,
2643fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines                     &mPragmas,
2653a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     OS,
2663a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     OT);
2673a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
2683a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
269641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr ChangSlang::Slang() : mInitialized(false), mDiagClient(NULL), mOT(OT_Default) {
2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  GlobalInitialization();
271641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang  return;
272641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang}
273641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang
274641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changvoid Slang::init(const std::string &Triple, const std::string &CPU,
275641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang                 const std::vector<std::string> &Features) {
276641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang  if (mInitialized)
277641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang    return;
278462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createDiagnostic();
2803a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.getPtr());
281462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createTarget(Triple, CPU, Features);
2839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createFileManager();
2849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createSourceManager();
285462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
286641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang  mInitialized = true;
287641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
289462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
290462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile,
2923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                           const char *Text,
2933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                           size_t TextLength) {
2943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mInputFileName = InputFile.str();
295462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Reset the ID tables if we are reusing the SourceManager
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->clearIDTables();
298462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Load the source
3006315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  llvm::MemoryBuffer *SB =
3013a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength);
3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->createMainFileIDForMemBuffer(SB);
303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mSourceMgr->getMainFileID().isInvalid()) {
3053a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
3079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
309462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
310462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile) {
3123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mInputFileName = InputFile.str();
313462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->clearIDTables();
315462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
316df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao  const clang::FileEntry *File = mFileMgr->getFile(InputFile, *mFileSysOpt);
3179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (File)
3189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mSourceMgr->createMainFileID(File);
319462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mSourceMgr->getMainFileID().isInvalid()) {
3213a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
3229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
3239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
324462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
326462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
327462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3283a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setOutput(const char *OutputFile) {
3298c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang  llvm::sys::Path OutputFilePath(OutputFile);
3309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string Error;
331e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  llvm::tool_output_file *OS = NULL;
332462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3333a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  switch (mOT) {
334cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    case OT_Dependency:
3353a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Assembly:
3363a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_LLVMAssembly: {
337e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang      OS = OpenOutputFile(OutputFile, 0, &Error, mDiagnostics.getPtr());
3389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
339462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3403a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Nothing: {
3419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
342462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3433a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Object:
344cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    case OT_Bitcode: {
345e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang      OS = OpenOutputFile(OutputFile,
346e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang                          llvm::raw_fd_ostream::F_Binary,
347e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang                          &Error,
348e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang                          mDiagnostics.getPtr());
3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3518c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    default: {
352cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines      llvm_unreachable("Unknown compiler output type");
3538c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    }
3549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
355462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
356e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  if (!Error.empty())
3579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
358e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
359e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mOS.reset(OS);
3609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3613a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mOutputFileName = OutputFile;
362462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
364462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
365462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3660b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hinesbool Slang::setDepOutput(const char *OutputFile) {
3678c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang  llvm::sys::Path OutputFilePath(OutputFile);
3680b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  std::string Error;
3698c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang
370e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mDOS.reset(OpenOutputFile(OutputFile, 0, &Error, mDiagnostics.getPtr()));
371e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  if (!Error.empty() || (mDOS.get() == NULL))
3720b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines    return false;
3730b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
3740b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  mDepOutputFileName = OutputFile;
3750b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
3760b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  return true;
3770b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines}
3780b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
379cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hinesint Slang::generateDepFile() {
380b257301a1c711ba81458a4f8bf3c99c91c91a047Zonr Chang  if (mDiagnostics->getNumErrors() > 0)
381cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    return mDiagnostics->getNumErrors();
3820b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  if (mDOS.get() == NULL)
383f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines    return 1;
384cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
385e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Initialize options for generating dependency file
386cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  clang::DependencyOutputOptions DepOpts;
387cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  DepOpts.IncludeSystemHeaders = 1;
3880b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  DepOpts.OutputFile = mDepOutputFileName;
389b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  DepOpts.Targets = mAdditionalDepTargets;
390cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  DepOpts.Targets.push_back(mDepTargetBCFileName);
3914cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  for (std::vector<std::string>::const_iterator
3924cc67fce91f43215d61b2695746eab102a3db516Stephen Hines           I = mGeneratedFileNames.begin(), E = mGeneratedFileNames.end();
3934cc67fce91f43215d61b2695746eab102a3db516Stephen Hines       I != E;
3944cc67fce91f43215d61b2695746eab102a3db516Stephen Hines       I++) {
3954cc67fce91f43215d61b2695746eab102a3db516Stephen Hines    DepOpts.Targets.push_back(*I);
3964cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  }
3974cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  mGeneratedFileNames.clear();
398cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
399e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Per-compilation needed initialization
400cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  createPreprocessor();
401cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  AttachDependencyFileGen(*mPP.get(), DepOpts);
402cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
403e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Inform the diagnostic client we are processing a source file
404cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
405cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
406e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Go through the source file (no operations necessary)
407cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  clang::Token Tok;
408cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP->EnterMainSourceFile();
409cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  do {
410cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    mPP->Lex(Tok);
411cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  } while (Tok.isNot(clang::tok::eof));
412cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
413cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP->EndSourceFile();
414cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
415e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Declare success if no error
416e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  if (mDiagnostics->getNumErrors() == 0)
417e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    mDOS->keep();
418e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
419e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Clean up after compilation
420cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP.reset();
421e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mDOS.reset();
422cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
423cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  return mDiagnostics->getNumErrors();
424cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines}
425cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
426462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoint Slang::compile() {
427f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines  if (mDiagnostics->getNumErrors() > 0)
4289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return mDiagnostics->getNumErrors();
429f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines  if (mOS.get() == NULL)
430f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines    return 1;
431462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Here is per-compilation needed initialization
4339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createPreprocessor();
4349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createASTContext();
4353a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
436df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao  mBackend.reset(createBackend(CodeGenOpts, &mOS->os(), mOT));
437462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Inform the diagnostic client we are processing a source file
4399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
440462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // The core of the slang compiler
4429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ParseAST(*mPP, mBackend.get(), *mASTContext);
443462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
444e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Inform the diagnostic client we are done with previous source file
445e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mDiagClient->EndSourceFile();
446e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
447e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Declare success if no error
448e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  if (mDiagnostics->getNumErrors() == 0)
449e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    mOS->keep();
450e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
4513a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  // The compilation ended, clear
4529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mBackend.reset();
4539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mASTContext.reset();
4549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mPP.reset();
455e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mOS.reset();
456462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return mDiagnostics->getNumErrors();
458462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
459462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4603a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::reset() {
4613a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagnostics->Reset();
4623a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mDiagClient->reset();
4639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
464462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
465462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
466462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoSlang::~Slang() {
4679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::llvm_shutdown();
4689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
469462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
470e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
471e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
472