blob: 78428f9cb73ddcfb07b265b5e9fe9df6e8c84c96 [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
Shih-wei Liaob81c6a42010-10-10 14:15:00 -070047#include "clang/Frontend/DiagnosticOptions.h"
48#include "clang/Frontend/TextDiagnosticPrinter.h"
49
Zonr Chang08df36e2010-10-07 18:50:42 +080050namespace {
51 struct ForceSlangLinking {
52 ForceSlangLinking() {
53 // We must reference the functions in such a way that compilers will not
54 // delete it all as dead code, even with whole program optimization,
55 // yet is effectively a NO-OP. As the compiler isn't smart enough
56 // to know that getenv() never returns -1, this will do the job.
57 if (std::getenv("bar") != reinterpret_cast<char*>(-1))
58 return;
59
60 // llvm-rs-link needs following functions existing in libslang.
61 llvm::ParseBitcodeFile(NULL, llvm::getGlobalContext(), NULL);
62 llvm::Linker::LinkModules(NULL, NULL, NULL);
Shih-wei Liaob81c6a42010-10-10 14:15:00 -070063
64 // llvm-rs-cc need this.
65 new clang::TextDiagnosticPrinter(llvm::errs(),
66 clang::DiagnosticOptions());
Zonr Chang08df36e2010-10-07 18:50:42 +080067 }
68 } ForceSlangLinking;
69}
70
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070071using namespace slang;
72
Shih-wei Liao462aefd2010-06-04 15:32:04 -070073#if defined(__arm__)
74# define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
75#elif defined(__x86_64__)
76# define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux"
77#else
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070078// let's use x86 as default target
79# define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070080#endif
81
Shih-wei Liao462aefd2010-06-04 15:32:04 -070082bool Slang::GlobalInitialized = false;
83
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070084// Language option (define the language feature for compiler such as C99)
85clang::LangOptions Slang::LangOpts;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070086
zonr6315f762010-10-05 15:35:14 +080087// Code generation option for the compiler
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070088clang::CodeGenOptions Slang::CodeGenOpts;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070089
zonr6315f762010-10-05 15:35:14 +080090const std::string Slang::TargetDescription =
91 "e-" // little-endian
92 "p:32:32:32-" // 32-bit pointer
93 "i1:8:8-"
94 "i8:8:8-"
95 "i16:16:16-"
96 "i32:32:32-"
97 "i64:64:64-"
98 "f32:32:32-"
99 "f64:64:64-"
100 "v64:64:64-" // 64-bit vector (e.g. float2, int2, short4)
101 "v128:128:128-"
102 "a0:0:64-"
103 "n32"; // native CPU only support 32-bit integer width.
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700104
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700105// The named of metadata node that pragma resides (should be synced with
106// bcc.cpp)
Shih-wei Liaof52a6202010-09-10 17:40:53 -0700107const llvm::StringRef Slang::PragmaMetadataName = "#pragma";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700108
Zonr Change8c263a2010-10-12 00:35:29 +0800109static inline llvm::tool_output_file *OpenOutputFile(const char *OutputFile,
110 unsigned Flags,
111 std::string* Error,
112 clang::Diagnostic* Diag) {
113 assert((OutputFile != NULL) && (Error != NULL) && (Diag != NULL) &&
114 "Invalid parameter!");
115
116 llvm::sys::Path OutputFilePath(OutputFile);
117
118 if (SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
119 Error)) {
120 llvm::tool_output_file *F =
121 new llvm::tool_output_file(OutputFile, *Error, Flags);
122 if (F != NULL)
123 return F;
124 }
125
126 // Report error here.
127 Diag->Report(clang::diag::err_fe_error_opening) << OutputFile << *Error;
128
129 return NULL;
130}
131
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700132void Slang::GlobalInitialization() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700133 if (!GlobalInitialized) {
134 // We only support x86, x64 and ARM target
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700135
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700136 // For ARM
137 LLVMInitializeARMTargetInfo();
138 LLVMInitializeARMTarget();
139 LLVMInitializeARMAsmPrinter();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700140
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700141 // For x86 and x64
142 LLVMInitializeX86TargetInfo();
143 LLVMInitializeX86Target();
144 LLVMInitializeX86AsmPrinter();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700145
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800146 // Please refer to include/clang/Basic/LangOptions.h to setup
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700147 // the options.
148 LangOpts.RTTI = 0; // Turn off the RTTI information support
149 LangOpts.NeXTRuntime = 0; // Turn off the NeXT runtime uses
150 LangOpts.Bool = 1; // Turn on 'bool', 'true', 'false' keywords
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700151
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700152 CodeGenOpts.OptimizationLevel = 3; /* -O3 */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700153
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700154 GlobalInitialized = true;
155 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700156
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700157 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700158}
159
160void Slang::LLVMErrorHandler(void *UserData, const std::string &Message) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700161 clang::Diagnostic* Diags = static_cast<clang::Diagnostic*>(UserData);
162 Diags->Report(clang::diag::err_fe_error_backend) << Message;
163 exit(1);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700164}
165
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800166void Slang::createDiagnostic() {
167 mDiagnostics =
168 llvm::IntrusiveRefCntPtr<clang::Diagnostic>(new clang::Diagnostic());
169 mDiagClient = new DiagnosticBuffer();
170 // This takes the ownership of mDiagClient.
171 mDiagnostics->setClient(mDiagClient);
172 return;
173}
174
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700175void Slang::createTarget(const std::string &Triple, const std::string &CPU,
176 const std::vector<std::string> &Features) {
177 if (!Triple.empty())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700178 mTargetOpts.Triple = Triple;
179 else
180 mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700181
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700182 if (!CPU.empty())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700183 mTargetOpts.CPU = CPU;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700184
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700185 if (!Features.empty())
186 mTargetOpts.Features = Features;
187
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700188 mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagnostics,
189 mTargetOpts));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700190
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700191 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700192}
193
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800194void Slang::createFileManager() {
195 mFileMgr.reset(new clang::FileManager());
196}
197
198void Slang::createSourceManager() {
199 mSourceMgr.reset(new clang::SourceManager(*mDiagnostics));
200 return;
201}
202
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700203void Slang::createPreprocessor() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700204 // Default only search header file in current dir
205 clang::HeaderSearch *HS = new clang::HeaderSearch(*mFileMgr);
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700206
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700207 mPP.reset(new clang::Preprocessor(*mDiagnostics,
208 LangOpts,
209 *mTarget,
210 *mSourceMgr,
211 *HS,
212 NULL,
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800213 /* OwnsHeaderSearch = */true));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700214 // Initialize the prepocessor
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700215 mPragmas.clear();
Shih-wei Liaof52a6202010-09-10 17:40:53 -0700216 mPP->AddPragmaHandler(new PragmaRecorder(mPragmas));
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700217
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700218 std::vector<clang::DirectoryLookup> SearchList;
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800219 for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700220 if (const clang::DirectoryEntry *DE =
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800221 mFileMgr->getDirectory(mIncludePaths[i])) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700222 SearchList.push_back(clang::DirectoryLookup(DE,
223 clang::SrcMgr::C_System,
224 false,
225 false));
226 }
Shih-wei Liao90898282010-07-19 18:38:57 -0700227 }
228
229 HS->SetSearchPaths(SearchList, 1, false);
230
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800231 initPreprocessor();
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700232 return;
233}
234
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800235void Slang::createASTContext() {
236 mASTContext.reset(new clang::ASTContext(LangOpts,
237 *mSourceMgr,
238 *mTarget,
239 mPP->getIdentifierTable(),
240 mPP->getSelectorTable(),
241 mPP->getBuiltinInfo(),
242 /* size_reserve = */0));
243 initASTContext();
244 return;
245}
246
247clang::ASTConsumer
248*Slang::createBackend(const clang::CodeGenOptions& CodeGenOpts,
249 llvm::raw_ostream *OS,
250 OutputType OT) {
251 return new Backend(*mDiagnostics,
252 CodeGenOpts,
253 mTargetOpts,
254 mPragmas,
255 OS,
256 OT);
257}
258
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700259Slang::Slang(const std::string &Triple, const std::string &CPU,
260 const std::vector<std::string> &Features)
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800261 : mDiagClient(NULL),
262 mOT(OT_Default) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700263 GlobalInitialization();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700264
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700265 createDiagnostic();
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800266 llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.getPtr());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700267
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700268 createTarget(Triple, CPU, Features);
269 createFileManager();
270 createSourceManager();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700271
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700272 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700273}
274
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800275bool Slang::setInputSource(llvm::StringRef InputFile,
276 const char *Text,
277 size_t TextLength) {
278 mInputFileName = InputFile.str();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700279
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700280 // Reset the ID tables if we are reusing the SourceManager
281 mSourceMgr->clearIDTables();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700282
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700283 // Load the source
zonr6315f762010-10-05 15:35:14 +0800284 llvm::MemoryBuffer *SB =
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800285 llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700286 mSourceMgr->createMainFileIDForMemBuffer(SB);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700287
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700288 if (mSourceMgr->getMainFileID().isInvalid()) {
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800289 mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700290 return false;
291 }
292 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700293}
294
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800295bool Slang::setInputSource(llvm::StringRef InputFile) {
296 mInputFileName = InputFile.str();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700297
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700298 mSourceMgr->clearIDTables();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700299
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800300 const clang::FileEntry *File = mFileMgr->getFile(InputFile);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700301 if (File)
302 mSourceMgr->createMainFileID(File);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700303
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700304 if (mSourceMgr->getMainFileID().isInvalid()) {
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800305 mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700306 return false;
307 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700308
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700309 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700310}
311
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800312bool Slang::setOutput(const char *OutputFile) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800313 llvm::sys::Path OutputFilePath(OutputFile);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700314 std::string Error;
Zonr Change8c263a2010-10-12 00:35:29 +0800315 llvm::tool_output_file *OS = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700316
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800317 switch (mOT) {
Stephen Hinescc0efad2010-10-04 16:13:02 -0700318 case OT_Dependency:
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800319 case OT_Assembly:
320 case OT_LLVMAssembly: {
Zonr Change8c263a2010-10-12 00:35:29 +0800321 OS = OpenOutputFile(OutputFile, 0, &Error, mDiagnostics.getPtr());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700322 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700323 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800324 case OT_Nothing: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700325 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700326 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800327 case OT_Object:
Stephen Hinescc0efad2010-10-04 16:13:02 -0700328 case OT_Bitcode: {
Zonr Change8c263a2010-10-12 00:35:29 +0800329 OS = OpenOutputFile(OutputFile,
330 llvm::raw_fd_ostream::F_Binary,
331 &Error,
332 mDiagnostics.getPtr());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700333 break;
334 }
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800335 default: {
Stephen Hinescc0efad2010-10-04 16:13:02 -0700336 llvm_unreachable("Unknown compiler output type");
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800337 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700338 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700339
Zonr Change8c263a2010-10-12 00:35:29 +0800340 if (!Error.empty())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700341 return false;
Zonr Change8c263a2010-10-12 00:35:29 +0800342
343 mOS.reset(OS);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700344
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800345 mOutputFileName = OutputFile;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700346
347 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700348}
349
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700350bool Slang::setDepOutput(const char *OutputFile) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800351 llvm::sys::Path OutputFilePath(OutputFile);
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700352 std::string Error;
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800353
Zonr Change8c263a2010-10-12 00:35:29 +0800354 mDOS.reset(OpenOutputFile(OutputFile, 0, &Error, mDiagnostics.getPtr()));
355 if (!Error.empty() || (mDOS.get() == NULL))
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700356 return false;
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700357
358 mDepOutputFileName = OutputFile;
359
360 return true;
361}
362
Stephen Hinescc0efad2010-10-04 16:13:02 -0700363int Slang::generateDepFile() {
Zonr Changb2573012010-10-07 19:35:21 +0800364 if (mDiagnostics->getNumErrors() > 0)
Stephen Hinescc0efad2010-10-04 16:13:02 -0700365 return mDiagnostics->getNumErrors();
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700366 if (mDOS.get() == NULL)
Stephen Hinesf7de8522010-10-06 11:46:18 -0700367 return 1;
Stephen Hinescc0efad2010-10-04 16:13:02 -0700368
Zonr Change8c263a2010-10-12 00:35:29 +0800369 // Initialize options for generating dependency file
Stephen Hinescc0efad2010-10-04 16:13:02 -0700370 clang::DependencyOutputOptions DepOpts;
371 DepOpts.IncludeSystemHeaders = 1;
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700372 DepOpts.OutputFile = mDepOutputFileName;
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700373 DepOpts.Targets = mAdditionalDepTargets;
Stephen Hinescc0efad2010-10-04 16:13:02 -0700374 DepOpts.Targets.push_back(mDepTargetBCFileName);
375
Zonr Change8c263a2010-10-12 00:35:29 +0800376 // Per-compilation needed initialization
Stephen Hinescc0efad2010-10-04 16:13:02 -0700377 createPreprocessor();
378 AttachDependencyFileGen(*mPP.get(), DepOpts);
379
Zonr Change8c263a2010-10-12 00:35:29 +0800380 // Inform the diagnostic client we are processing a source file
Stephen Hinescc0efad2010-10-04 16:13:02 -0700381 mDiagClient->BeginSourceFile(LangOpts, mPP.get());
382
Zonr Change8c263a2010-10-12 00:35:29 +0800383 // Go through the source file (no operations necessary)
Stephen Hinescc0efad2010-10-04 16:13:02 -0700384 clang::Token Tok;
385 mPP->EnterMainSourceFile();
386 do {
387 mPP->Lex(Tok);
388 } while (Tok.isNot(clang::tok::eof));
389
390 mPP->EndSourceFile();
391
Zonr Change8c263a2010-10-12 00:35:29 +0800392 // Declare success if no error
393 if (mDiagnostics->getNumErrors() == 0)
394 mDOS->keep();
395
396 // Clean up after compilation
Stephen Hinescc0efad2010-10-04 16:13:02 -0700397 mPP.reset();
Zonr Change8c263a2010-10-12 00:35:29 +0800398 mDOS.reset();
Stephen Hinescc0efad2010-10-04 16:13:02 -0700399
400 return mDiagnostics->getNumErrors();
401}
402
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700403int Slang::compile() {
Stephen Hinesf7de8522010-10-06 11:46:18 -0700404 if (mDiagnostics->getNumErrors() > 0)
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700405 return mDiagnostics->getNumErrors();
Stephen Hinesf7de8522010-10-06 11:46:18 -0700406 if (mOS.get() == NULL)
407 return 1;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700408
409 // Here is per-compilation needed initialization
410 createPreprocessor();
411 createASTContext();
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800412
Zonr Change8c263a2010-10-12 00:35:29 +0800413 mBackend.reset(createBackend(CodeGenOpts, mOS.get(), mOT));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700414
415 // Inform the diagnostic client we are processing a source file
416 mDiagClient->BeginSourceFile(LangOpts, mPP.get());
417
418 // The core of the slang compiler
419 ParseAST(*mPP, mBackend.get(), *mASTContext);
420
Zonr Change8c263a2010-10-12 00:35:29 +0800421 // Inform the diagnostic client we are done with previous source file
422 mDiagClient->EndSourceFile();
423
424 // Declare success if no error
425 if (mDiagnostics->getNumErrors() == 0)
426 mOS->keep();
427
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800428 // The compilation ended, clear
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700429 mBackend.reset();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700430 mASTContext.reset();
431 mPP.reset();
Zonr Change8c263a2010-10-12 00:35:29 +0800432 mOS.reset();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700433
434 return mDiagnostics->getNumErrors();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700435}
436
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800437void Slang::reset() {
438 mDiagnostics->Reset();
439 mDiagClient->reset();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700440 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700441}
442
443Slang::~Slang() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700444 llvm::llvm_shutdown();
445 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700446}