blob: e1554839e234b552794a2e35d85ff2b53fc2aee2 [file] [log] [blame]
zonr6315f762010-10-05 15:35:14 +08001#include "slang.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07003#include <stdlib.h>
4
Zonr Chang08df36e2010-10-07 18:50:42 +08005// Force linking all passes/vmcore stuffs to libslang.so
6#include "llvm/LinkAllPasses.h"
7#include "llvm/LinkAllVMCore.h"
8
zonr6315f762010-10-05 15:35:14 +08009#include "llvm/Target/TargetSelect.h"
10
Zonr Chang8c6d9b22010-10-07 18:01:19 +080011#include "llvm/System/Path.h"
12
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080013#include "llvm/Support/raw_ostream.h"
zonr6315f762010-10-05 15:35:14 +080014#include "llvm/Support/MemoryBuffer.h"
15#include "llvm/Support/ErrorHandling.h"
16#include "llvm/Support/ManagedStatic.h"
17
zonr6315f762010-10-05 15:35:14 +080018#include "clang/Basic/LangOptions.h"
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080019#include "clang/Basic/SourceManager.h"
20#include "clang/Basic/TargetInfo.h"
zonr6315f762010-10-05 15:35:14 +080021#include "clang/Basic/TargetOptions.h"
22
Stephen Hinescc0efad2010-10-04 16:13:02 -070023#include "clang/Frontend/DependencyOutputOptions.h"
24#include "clang/Frontend/FrontendDiagnostic.h"
25#include "clang/Frontend/Utils.h"
26
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080027#include "clang/Lex/Preprocessor.h"
28#include "clang/Lex/HeaderSearch.h"
29
30#include "clang/AST/ASTConsumer.h"
31#include "clang/AST/ASTContext.h"
32
33#include "clang/Basic/FileManager.h"
34
35#include "clang/Frontend/CodeGenOptions.h"
zonr6315f762010-10-05 15:35:14 +080036#include "clang/Frontend/FrontendDiagnostic.h"
37
38#include "clang/Parse/ParseAST.h"
39
Zonr Chang8c6d9b22010-10-07 18:01:19 +080040#include "slang_utils.h"
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080041#include "slang_backend.h"
zonr6315f762010-10-05 15:35:14 +080042
Zonr Chang08df36e2010-10-07 18:50:42 +080043// More force linking
44#include "llvm/Linker.h"
45#include "llvm/Bitcode/ReaderWriter.h"
46
47namespace {
48 struct ForceSlangLinking {
49 ForceSlangLinking() {
50 // We must reference the functions in such a way that compilers will not
51 // delete it all as dead code, even with whole program optimization,
52 // yet is effectively a NO-OP. As the compiler isn't smart enough
53 // to know that getenv() never returns -1, this will do the job.
54 if (std::getenv("bar") != reinterpret_cast<char*>(-1))
55 return;
56
57 // llvm-rs-link needs following functions existing in libslang.
58 llvm::ParseBitcodeFile(NULL, llvm::getGlobalContext(), NULL);
59 llvm::Linker::LinkModules(NULL, NULL, NULL);
60 }
61 } ForceSlangLinking;
62}
63
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070064using namespace slang;
65
Shih-wei Liao462aefd2010-06-04 15:32:04 -070066#if defined(__arm__)
67# define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
68#elif defined(__x86_64__)
69# define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux"
70#else
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070071// let's use x86 as default target
72# define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070073#endif
74
Shih-wei Liao462aefd2010-06-04 15:32:04 -070075bool Slang::GlobalInitialized = false;
76
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070077// Language option (define the language feature for compiler such as C99)
78clang::LangOptions Slang::LangOpts;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070079
zonr6315f762010-10-05 15:35:14 +080080// Code generation option for the compiler
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070081clang::CodeGenOptions Slang::CodeGenOpts;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070082
zonr6315f762010-10-05 15:35:14 +080083const std::string Slang::TargetDescription =
84 "e-" // little-endian
85 "p:32:32:32-" // 32-bit pointer
86 "i1:8:8-"
87 "i8:8:8-"
88 "i16:16:16-"
89 "i32:32:32-"
90 "i64:64:64-"
91 "f32:32:32-"
92 "f64:64:64-"
93 "v64:64:64-" // 64-bit vector (e.g. float2, int2, short4)
94 "v128:128:128-"
95 "a0:0:64-"
96 "n32"; // native CPU only support 32-bit integer width.
Shih-wei Liao462aefd2010-06-04 15:32:04 -070097
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070098// The named of metadata node that pragma resides (should be synced with
99// bcc.cpp)
Shih-wei Liaof52a6202010-09-10 17:40:53 -0700100const llvm::StringRef Slang::PragmaMetadataName = "#pragma";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700101
102void Slang::GlobalInitialization() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700103 if (!GlobalInitialized) {
104 // We only support x86, x64 and ARM target
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700105
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700106 // For ARM
107 LLVMInitializeARMTargetInfo();
108 LLVMInitializeARMTarget();
109 LLVMInitializeARMAsmPrinter();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700110
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700111 // For x86 and x64
112 LLVMInitializeX86TargetInfo();
113 LLVMInitializeX86Target();
114 LLVMInitializeX86AsmPrinter();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700115
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800116 // Please refer to include/clang/Basic/LangOptions.h to setup
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700117 // the options.
118 LangOpts.RTTI = 0; // Turn off the RTTI information support
119 LangOpts.NeXTRuntime = 0; // Turn off the NeXT runtime uses
120 LangOpts.Bool = 1; // Turn on 'bool', 'true', 'false' keywords
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700121
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700122 CodeGenOpts.OptimizationLevel = 3; /* -O3 */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700123
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700124 GlobalInitialized = true;
125 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700126
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700127 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700128}
129
130void Slang::LLVMErrorHandler(void *UserData, const std::string &Message) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700131 clang::Diagnostic* Diags = static_cast<clang::Diagnostic*>(UserData);
132 Diags->Report(clang::diag::err_fe_error_backend) << Message;
133 exit(1);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700134}
135
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800136void Slang::createDiagnostic() {
137 mDiagnostics =
138 llvm::IntrusiveRefCntPtr<clang::Diagnostic>(new clang::Diagnostic());
139 mDiagClient = new DiagnosticBuffer();
140 // This takes the ownership of mDiagClient.
141 mDiagnostics->setClient(mDiagClient);
142 return;
143}
144
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700145void Slang::createTarget(const char* Triple, const char* CPU,
146 const char** Features) {
147 if (Triple != NULL)
148 mTargetOpts.Triple = Triple;
149 else
150 mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700151
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700152 if (CPU != NULL)
153 mTargetOpts.CPU = CPU;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700154
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700155 mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagnostics,
156 mTargetOpts));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700157
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700158 if (Features != NULL)
zonr6315f762010-10-05 15:35:14 +0800159 for (int i = 0; Features[i] != NULL; i++)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700160 mTargetOpts.Features.push_back(Features[i]);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700161
162 return;
163}
164
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800165void Slang::createFileManager() {
166 mFileMgr.reset(new clang::FileManager());
167}
168
169void Slang::createSourceManager() {
170 mSourceMgr.reset(new clang::SourceManager(*mDiagnostics));
171 return;
172}
173
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700174void Slang::createPreprocessor() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700175 // Default only search header file in current dir
176 clang::HeaderSearch *HS = new clang::HeaderSearch(*mFileMgr);
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700177
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700178 mPP.reset(new clang::Preprocessor(*mDiagnostics,
179 LangOpts,
180 *mTarget,
181 *mSourceMgr,
182 *HS,
183 NULL,
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800184 /* OwnsHeaderSearch = */true));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700185 // Initialize the prepocessor
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700186 mPragmas.clear();
Shih-wei Liaof52a6202010-09-10 17:40:53 -0700187 mPP->AddPragmaHandler(new PragmaRecorder(mPragmas));
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700188
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700189 std::vector<clang::DirectoryLookup> SearchList;
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800190 for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700191 if (const clang::DirectoryEntry *DE =
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800192 mFileMgr->getDirectory(mIncludePaths[i])) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700193 SearchList.push_back(clang::DirectoryLookup(DE,
194 clang::SrcMgr::C_System,
195 false,
196 false));
197 }
Shih-wei Liao90898282010-07-19 18:38:57 -0700198 }
199
200 HS->SetSearchPaths(SearchList, 1, false);
201
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800202 initPreprocessor();
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700203 return;
204}
205
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800206void Slang::createASTContext() {
207 mASTContext.reset(new clang::ASTContext(LangOpts,
208 *mSourceMgr,
209 *mTarget,
210 mPP->getIdentifierTable(),
211 mPP->getSelectorTable(),
212 mPP->getBuiltinInfo(),
213 /* size_reserve = */0));
214 initASTContext();
215 return;
216}
217
218clang::ASTConsumer
219*Slang::createBackend(const clang::CodeGenOptions& CodeGenOpts,
220 llvm::raw_ostream *OS,
221 OutputType OT) {
222 return new Backend(*mDiagnostics,
223 CodeGenOpts,
224 mTargetOpts,
225 mPragmas,
226 OS,
227 OT);
228}
229
zonr6315f762010-10-05 15:35:14 +0800230Slang::Slang(const char *Triple, const char *CPU, const char **Features)
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800231 : mDiagClient(NULL),
232 mOT(OT_Default) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700233 GlobalInitialization();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700234
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700235 createDiagnostic();
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800236 llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.getPtr());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700237
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700238 createTarget(Triple, CPU, Features);
239 createFileManager();
240 createSourceManager();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700241
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700242 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700243}
244
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800245bool Slang::setInputSource(llvm::StringRef InputFile,
246 const char *Text,
247 size_t TextLength) {
248 mInputFileName = InputFile.str();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700249
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700250 // Reset the ID tables if we are reusing the SourceManager
251 mSourceMgr->clearIDTables();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700252
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700253 // Load the source
zonr6315f762010-10-05 15:35:14 +0800254 llvm::MemoryBuffer *SB =
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800255 llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700256 mSourceMgr->createMainFileIDForMemBuffer(SB);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700257
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700258 if (mSourceMgr->getMainFileID().isInvalid()) {
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800259 mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700260 return false;
261 }
262 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700263}
264
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800265bool Slang::setInputSource(llvm::StringRef InputFile) {
266 mInputFileName = InputFile.str();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700267
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700268 mSourceMgr->clearIDTables();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700269
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800270 const clang::FileEntry *File = mFileMgr->getFile(InputFile);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700271 if (File)
272 mSourceMgr->createMainFileID(File);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700273
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700274 if (mSourceMgr->getMainFileID().isInvalid()) {
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800275 mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700276 return false;
277 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700278
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700279 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700280}
281
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800282bool Slang::setOutput(const char *OutputFile) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800283 llvm::sys::Path OutputFilePath(OutputFile);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700284 std::string Error;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700285
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800286 switch (mOT) {
Stephen Hinescc0efad2010-10-04 16:13:02 -0700287 case OT_Dependency:
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800288 case OT_Assembly:
289 case OT_LLVMAssembly: {
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800290 if (!SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
291 &Error))
292 mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
293 << Error;
294 mOS.reset(new llvm::tool_output_file(OutputFile, Error, 0));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700295 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700296 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800297 case OT_Nothing: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700298 mOS.reset();
299 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700300 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800301 case OT_Object:
Stephen Hinescc0efad2010-10-04 16:13:02 -0700302 case OT_Bitcode: {
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800303 if (!SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
304 &Error))
305 mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
306 << Error;
307 mOS.reset(new llvm::tool_output_file(OutputFile,
308 Error,
309 llvm::raw_fd_ostream::F_Binary));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700310 break;
311 }
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800312 default: {
Stephen Hinescc0efad2010-10-04 16:13:02 -0700313 llvm_unreachable("Unknown compiler output type");
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800314 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700315 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700316
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700317 if (!Error.empty()) {
318 mOS.reset();
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800319 mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700320 << Error;
321 return false;
322 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700323
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800324 mOutputFileName = OutputFile;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700325
326 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700327}
328
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700329bool Slang::setDepOutput(const char *OutputFile) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800330 llvm::sys::Path OutputFilePath(OutputFile);
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700331 std::string Error;
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800332
333 if (!SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
334 &Error))
335 mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
336 << Error;
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700337 mDOS.reset(new llvm::raw_fd_ostream(OutputFile, Error, 0));
338
339 if (!Error.empty()) {
340 mDOS.reset();
341 mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
342 << Error;
343 return false;
344 }
345
346 mDepOutputFileName = OutputFile;
347
348 return true;
349}
350
351bool Slang::setDepTargetBC(const char *TargetBCFile) {
352 mDepTargetBCFileName = TargetBCFile;
Stephen Hinescc0efad2010-10-04 16:13:02 -0700353
354 return true;
355}
356
Ying Wang54572312010-10-07 18:27:09 -0700357bool Slang::setAdditionalDepTarget(const char* AdditionalDepTargetFileName) {
358 mAdditionalDepTargetFileName = AdditionalDepTargetFileName;
359}
360
Stephen Hinescc0efad2010-10-04 16:13:02 -0700361int Slang::generateDepFile() {
Stephen Hinesf7de8522010-10-06 11:46:18 -0700362 if(mDiagnostics->getNumErrors() > 0)
Stephen Hinescc0efad2010-10-04 16:13:02 -0700363 return mDiagnostics->getNumErrors();
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700364 if (mDOS.get() == NULL)
Stephen Hinesf7de8522010-10-06 11:46:18 -0700365 return 1;
Stephen Hinescc0efad2010-10-04 16:13:02 -0700366
367 /* Initialize options for generating dependency file */
368 clang::DependencyOutputOptions DepOpts;
369 DepOpts.IncludeSystemHeaders = 1;
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700370 DepOpts.OutputFile = mDepOutputFileName;
Ying Wang54572312010-10-07 18:27:09 -0700371 if (!mAdditionalDepTargetFileName.empty()) {
372 DepOpts.Targets.push_back(mAdditionalDepTargetFileName);
373 }
Stephen Hinescc0efad2010-10-04 16:13:02 -0700374 DepOpts.Targets.push_back(mDepTargetBCFileName);
375
376 /* Per-compilation needed initialization */
377 createPreprocessor();
378 AttachDependencyFileGen(*mPP.get(), DepOpts);
379
380 /* Inform the diagnostic client we are processing a source file */
381 mDiagClient->BeginSourceFile(LangOpts, mPP.get());
382
383 /* Go through the source file (no operations necessary) */
384 clang::Token Tok;
385 mPP->EnterMainSourceFile();
386 do {
387 mPP->Lex(Tok);
388 } while (Tok.isNot(clang::tok::eof));
389
390 mPP->EndSourceFile();
391
392 /* Clean up after compilation */
393 mPP.reset();
394
395 return mDiagnostics->getNumErrors();
396}
397
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700398int Slang::compile() {
Stephen Hinesf7de8522010-10-06 11:46:18 -0700399 if (mDiagnostics->getNumErrors() > 0)
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700400 return mDiagnostics->getNumErrors();
Stephen Hinesf7de8522010-10-06 11:46:18 -0700401 if (mOS.get() == NULL)
402 return 1;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700403
404 // Here is per-compilation needed initialization
405 createPreprocessor();
406 createASTContext();
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800407
408 mBackend.reset(createBackend(CodeGenOpts, mOS.take(), mOT));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700409
410 // Inform the diagnostic client we are processing a source file
411 mDiagClient->BeginSourceFile(LangOpts, mPP.get());
412
413 // The core of the slang compiler
414 ParseAST(*mPP, mBackend.get(), *mASTContext);
415
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800416 // The compilation ended, clear
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700417 mBackend.reset();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700418 mASTContext.reset();
419 mPP.reset();
420
421 // Inform the diagnostic client we are done with previous source file
422 mDiagClient->EndSourceFile();
423
424 return mDiagnostics->getNumErrors();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700425}
426
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800427void Slang::reset() {
428 mDiagnostics->Reset();
429 mDiagClient->reset();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700430 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700431}
432
433Slang::~Slang() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700434 llvm::llvm_shutdown();
435 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700436}