blob: 98610c6d8a7ad79b6a155828553b186f6253c2c7 [file] [log] [blame]
Zonr Changc383a502010-10-12 01:52:08 +08001/*
2 * Copyright 2010, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
zonr6315f762010-10-05 15:35:14 +080017#include "slang.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070018
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070019#include <stdlib.h>
20
Zonr Chang08df36e2010-10-07 18:50:42 +080021// Force linking all passes/vmcore stuffs to libslang.so
22#include "llvm/LinkAllPasses.h"
23#include "llvm/LinkAllVMCore.h"
24
zonr6315f762010-10-05 15:35:14 +080025#include "llvm/Target/TargetSelect.h"
26
Zonr Chang8c6d9b22010-10-07 18:01:19 +080027#include "llvm/System/Path.h"
28
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080029#include "llvm/Support/raw_ostream.h"
zonr6315f762010-10-05 15:35:14 +080030#include "llvm/Support/MemoryBuffer.h"
31#include "llvm/Support/ErrorHandling.h"
32#include "llvm/Support/ManagedStatic.h"
33
zonr6315f762010-10-05 15:35:14 +080034#include "clang/Basic/LangOptions.h"
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080035#include "clang/Basic/SourceManager.h"
36#include "clang/Basic/TargetInfo.h"
zonr6315f762010-10-05 15:35:14 +080037#include "clang/Basic/TargetOptions.h"
38
Stephen Hinescc0efad2010-10-04 16:13:02 -070039#include "clang/Frontend/DependencyOutputOptions.h"
40#include "clang/Frontend/FrontendDiagnostic.h"
41#include "clang/Frontend/Utils.h"
42
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080043#include "clang/Lex/Preprocessor.h"
44#include "clang/Lex/HeaderSearch.h"
45
46#include "clang/AST/ASTConsumer.h"
47#include "clang/AST/ASTContext.h"
48
49#include "clang/Basic/FileManager.h"
50
51#include "clang/Frontend/CodeGenOptions.h"
zonr6315f762010-10-05 15:35:14 +080052#include "clang/Frontend/FrontendDiagnostic.h"
53
54#include "clang/Parse/ParseAST.h"
55
Zonr Chang8c6d9b22010-10-07 18:01:19 +080056#include "slang_utils.h"
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080057#include "slang_backend.h"
zonr6315f762010-10-05 15:35:14 +080058
Zonr Chang08df36e2010-10-07 18:50:42 +080059// More force linking
60#include "llvm/Linker.h"
61#include "llvm/Bitcode/ReaderWriter.h"
62
Shih-wei Liaob81c6a42010-10-10 14:15:00 -070063#include "clang/Frontend/DiagnosticOptions.h"
64#include "clang/Frontend/TextDiagnosticPrinter.h"
65
Zonr Chang08df36e2010-10-07 18:50:42 +080066namespace {
67 struct ForceSlangLinking {
68 ForceSlangLinking() {
69 // We must reference the functions in such a way that compilers will not
70 // delete it all as dead code, even with whole program optimization,
71 // yet is effectively a NO-OP. As the compiler isn't smart enough
72 // to know that getenv() never returns -1, this will do the job.
73 if (std::getenv("bar") != reinterpret_cast<char*>(-1))
74 return;
75
76 // llvm-rs-link needs following functions existing in libslang.
77 llvm::ParseBitcodeFile(NULL, llvm::getGlobalContext(), NULL);
78 llvm::Linker::LinkModules(NULL, NULL, NULL);
Shih-wei Liaob81c6a42010-10-10 14:15:00 -070079
80 // llvm-rs-cc need this.
81 new clang::TextDiagnosticPrinter(llvm::errs(),
82 clang::DiagnosticOptions());
Zonr Chang08df36e2010-10-07 18:50:42 +080083 }
84 } ForceSlangLinking;
85}
86
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070087using namespace slang;
88
Shih-wei Liao462aefd2010-06-04 15:32:04 -070089#if defined(__arm__)
90# define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
91#elif defined(__x86_64__)
92# define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux"
93#else
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070094// let's use x86 as default target
95# define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070096#endif
97
Shih-wei Liao462aefd2010-06-04 15:32:04 -070098bool Slang::GlobalInitialized = false;
99
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700100// Language option (define the language feature for compiler such as C99)
101clang::LangOptions Slang::LangOpts;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700102
zonr6315f762010-10-05 15:35:14 +0800103// Code generation option for the compiler
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700104clang::CodeGenOptions Slang::CodeGenOpts;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700105
zonr6315f762010-10-05 15:35:14 +0800106const std::string Slang::TargetDescription =
107 "e-" // little-endian
108 "p:32:32:32-" // 32-bit pointer
109 "i1:8:8-"
110 "i8:8:8-"
111 "i16:16:16-"
112 "i32:32:32-"
113 "i64:64:64-"
114 "f32:32:32-"
115 "f64:64:64-"
116 "v64:64:64-" // 64-bit vector (e.g. float2, int2, short4)
117 "v128:128:128-"
118 "a0:0:64-"
119 "n32"; // native CPU only support 32-bit integer width.
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700120
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700121// The named of metadata node that pragma resides (should be synced with
122// bcc.cpp)
Shih-wei Liaof52a6202010-09-10 17:40:53 -0700123const llvm::StringRef Slang::PragmaMetadataName = "#pragma";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700124
Zonr Change8c263a2010-10-12 00:35:29 +0800125static inline llvm::tool_output_file *OpenOutputFile(const char *OutputFile,
126 unsigned Flags,
127 std::string* Error,
128 clang::Diagnostic* Diag) {
129 assert((OutputFile != NULL) && (Error != NULL) && (Diag != NULL) &&
130 "Invalid parameter!");
131
132 llvm::sys::Path OutputFilePath(OutputFile);
133
134 if (SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
135 Error)) {
136 llvm::tool_output_file *F =
137 new llvm::tool_output_file(OutputFile, *Error, Flags);
138 if (F != NULL)
139 return F;
140 }
141
142 // Report error here.
143 Diag->Report(clang::diag::err_fe_error_opening) << OutputFile << *Error;
144
145 return NULL;
146}
147
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700148void Slang::GlobalInitialization() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700149 if (!GlobalInitialized) {
150 // We only support x86, x64 and ARM target
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700151
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700152 // For ARM
153 LLVMInitializeARMTargetInfo();
154 LLVMInitializeARMTarget();
155 LLVMInitializeARMAsmPrinter();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700156
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700157 // For x86 and x64
158 LLVMInitializeX86TargetInfo();
159 LLVMInitializeX86Target();
160 LLVMInitializeX86AsmPrinter();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700161
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800162 // Please refer to include/clang/Basic/LangOptions.h to setup
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700163 // the options.
164 LangOpts.RTTI = 0; // Turn off the RTTI information support
165 LangOpts.NeXTRuntime = 0; // Turn off the NeXT runtime uses
166 LangOpts.Bool = 1; // Turn on 'bool', 'true', 'false' keywords
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700167
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700168 CodeGenOpts.OptimizationLevel = 3; /* -O3 */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700169
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700170 GlobalInitialized = true;
171 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700172
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700173 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700174}
175
176void Slang::LLVMErrorHandler(void *UserData, const std::string &Message) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700177 clang::Diagnostic* Diags = static_cast<clang::Diagnostic*>(UserData);
178 Diags->Report(clang::diag::err_fe_error_backend) << Message;
179 exit(1);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700180}
181
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800182void Slang::createDiagnostic() {
183 mDiagnostics =
184 llvm::IntrusiveRefCntPtr<clang::Diagnostic>(new clang::Diagnostic());
185 mDiagClient = new DiagnosticBuffer();
186 // This takes the ownership of mDiagClient.
187 mDiagnostics->setClient(mDiagClient);
Zonr Chang641558f2010-10-12 21:07:06 +0800188 initDiagnostic();
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800189 return;
190}
191
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700192void Slang::createTarget(const std::string &Triple, const std::string &CPU,
193 const std::vector<std::string> &Features) {
194 if (!Triple.empty())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700195 mTargetOpts.Triple = Triple;
196 else
197 mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700198
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700199 if (!CPU.empty())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700200 mTargetOpts.CPU = CPU;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700201
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700202 if (!Features.empty())
203 mTargetOpts.Features = Features;
204
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700205 mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagnostics,
206 mTargetOpts));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700207
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700208 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700209}
210
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800211void Slang::createFileManager() {
212 mFileMgr.reset(new clang::FileManager());
213}
214
215void Slang::createSourceManager() {
216 mSourceMgr.reset(new clang::SourceManager(*mDiagnostics));
217 return;
218}
219
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700220void Slang::createPreprocessor() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700221 // Default only search header file in current dir
222 clang::HeaderSearch *HS = new clang::HeaderSearch(*mFileMgr);
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700223
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700224 mPP.reset(new clang::Preprocessor(*mDiagnostics,
225 LangOpts,
226 *mTarget,
227 *mSourceMgr,
228 *HS,
229 NULL,
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800230 /* OwnsHeaderSearch = */true));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700231 // Initialize the prepocessor
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700232 mPragmas.clear();
Shih-wei Liaof52a6202010-09-10 17:40:53 -0700233 mPP->AddPragmaHandler(new PragmaRecorder(mPragmas));
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700234
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700235 std::vector<clang::DirectoryLookup> SearchList;
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800236 for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700237 if (const clang::DirectoryEntry *DE =
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800238 mFileMgr->getDirectory(mIncludePaths[i])) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700239 SearchList.push_back(clang::DirectoryLookup(DE,
240 clang::SrcMgr::C_System,
241 false,
242 false));
243 }
Shih-wei Liao90898282010-07-19 18:38:57 -0700244 }
245
246 HS->SetSearchPaths(SearchList, 1, false);
247
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800248 initPreprocessor();
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700249 return;
250}
251
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800252void Slang::createASTContext() {
253 mASTContext.reset(new clang::ASTContext(LangOpts,
254 *mSourceMgr,
255 *mTarget,
256 mPP->getIdentifierTable(),
257 mPP->getSelectorTable(),
258 mPP->getBuiltinInfo(),
259 /* size_reserve = */0));
260 initASTContext();
261 return;
262}
263
264clang::ASTConsumer
265*Slang::createBackend(const clang::CodeGenOptions& CodeGenOpts,
266 llvm::raw_ostream *OS,
267 OutputType OT) {
268 return new Backend(*mDiagnostics,
269 CodeGenOpts,
270 mTargetOpts,
271 mPragmas,
272 OS,
273 OT);
274}
275
Zonr Chang641558f2010-10-12 21:07:06 +0800276Slang::Slang() : mInitialized(false), mDiagClient(NULL), mOT(OT_Default) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700277 GlobalInitialization();
Zonr Chang641558f2010-10-12 21:07:06 +0800278 return;
279}
280
281void Slang::init(const std::string &Triple, const std::string &CPU,
282 const std::vector<std::string> &Features) {
283 if (mInitialized)
284 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700285
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700286 createDiagnostic();
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800287 llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.getPtr());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700288
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700289 createTarget(Triple, CPU, Features);
290 createFileManager();
291 createSourceManager();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700292
Zonr Chang641558f2010-10-12 21:07:06 +0800293 mInitialized = true;
294
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700295 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700296}
297
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800298bool Slang::setInputSource(llvm::StringRef InputFile,
299 const char *Text,
300 size_t TextLength) {
301 mInputFileName = InputFile.str();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700302
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700303 // Reset the ID tables if we are reusing the SourceManager
304 mSourceMgr->clearIDTables();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700305
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700306 // Load the source
zonr6315f762010-10-05 15:35:14 +0800307 llvm::MemoryBuffer *SB =
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800308 llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700309 mSourceMgr->createMainFileIDForMemBuffer(SB);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700310
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700311 if (mSourceMgr->getMainFileID().isInvalid()) {
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800312 mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700313 return false;
314 }
315 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700316}
317
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800318bool Slang::setInputSource(llvm::StringRef InputFile) {
319 mInputFileName = InputFile.str();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700320
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700321 mSourceMgr->clearIDTables();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700322
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800323 const clang::FileEntry *File = mFileMgr->getFile(InputFile);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700324 if (File)
325 mSourceMgr->createMainFileID(File);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700326
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700327 if (mSourceMgr->getMainFileID().isInvalid()) {
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800328 mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700329 return false;
330 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700331
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700332 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700333}
334
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800335bool Slang::setOutput(const char *OutputFile) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800336 llvm::sys::Path OutputFilePath(OutputFile);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700337 std::string Error;
Zonr Change8c263a2010-10-12 00:35:29 +0800338 llvm::tool_output_file *OS = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700339
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800340 switch (mOT) {
Stephen Hinescc0efad2010-10-04 16:13:02 -0700341 case OT_Dependency:
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800342 case OT_Assembly:
343 case OT_LLVMAssembly: {
Zonr Change8c263a2010-10-12 00:35:29 +0800344 OS = OpenOutputFile(OutputFile, 0, &Error, mDiagnostics.getPtr());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700345 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700346 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800347 case OT_Nothing: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700348 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700349 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800350 case OT_Object:
Stephen Hinescc0efad2010-10-04 16:13:02 -0700351 case OT_Bitcode: {
Zonr Change8c263a2010-10-12 00:35:29 +0800352 OS = OpenOutputFile(OutputFile,
353 llvm::raw_fd_ostream::F_Binary,
354 &Error,
355 mDiagnostics.getPtr());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700356 break;
357 }
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800358 default: {
Stephen Hinescc0efad2010-10-04 16:13:02 -0700359 llvm_unreachable("Unknown compiler output type");
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800360 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700361 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700362
Zonr Change8c263a2010-10-12 00:35:29 +0800363 if (!Error.empty())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700364 return false;
Zonr Change8c263a2010-10-12 00:35:29 +0800365
366 mOS.reset(OS);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700367
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800368 mOutputFileName = OutputFile;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700369
370 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700371}
372
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700373bool Slang::setDepOutput(const char *OutputFile) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800374 llvm::sys::Path OutputFilePath(OutputFile);
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700375 std::string Error;
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800376
Zonr Change8c263a2010-10-12 00:35:29 +0800377 mDOS.reset(OpenOutputFile(OutputFile, 0, &Error, mDiagnostics.getPtr()));
378 if (!Error.empty() || (mDOS.get() == NULL))
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700379 return false;
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700380
381 mDepOutputFileName = OutputFile;
382
383 return true;
384}
385
Stephen Hinescc0efad2010-10-04 16:13:02 -0700386int Slang::generateDepFile() {
Zonr Changb2573012010-10-07 19:35:21 +0800387 if (mDiagnostics->getNumErrors() > 0)
Stephen Hinescc0efad2010-10-04 16:13:02 -0700388 return mDiagnostics->getNumErrors();
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700389 if (mDOS.get() == NULL)
Stephen Hinesf7de8522010-10-06 11:46:18 -0700390 return 1;
Stephen Hinescc0efad2010-10-04 16:13:02 -0700391
Zonr Change8c263a2010-10-12 00:35:29 +0800392 // Initialize options for generating dependency file
Stephen Hinescc0efad2010-10-04 16:13:02 -0700393 clang::DependencyOutputOptions DepOpts;
394 DepOpts.IncludeSystemHeaders = 1;
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700395 DepOpts.OutputFile = mDepOutputFileName;
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700396 DepOpts.Targets = mAdditionalDepTargets;
Stephen Hinescc0efad2010-10-04 16:13:02 -0700397 DepOpts.Targets.push_back(mDepTargetBCFileName);
398
Zonr Change8c263a2010-10-12 00:35:29 +0800399 // Per-compilation needed initialization
Stephen Hinescc0efad2010-10-04 16:13:02 -0700400 createPreprocessor();
401 AttachDependencyFileGen(*mPP.get(), DepOpts);
402
Zonr Change8c263a2010-10-12 00:35:29 +0800403 // Inform the diagnostic client we are processing a source file
Stephen Hinescc0efad2010-10-04 16:13:02 -0700404 mDiagClient->BeginSourceFile(LangOpts, mPP.get());
405
Zonr Change8c263a2010-10-12 00:35:29 +0800406 // Go through the source file (no operations necessary)
Stephen Hinescc0efad2010-10-04 16:13:02 -0700407 clang::Token Tok;
408 mPP->EnterMainSourceFile();
409 do {
410 mPP->Lex(Tok);
411 } while (Tok.isNot(clang::tok::eof));
412
413 mPP->EndSourceFile();
414
Zonr Change8c263a2010-10-12 00:35:29 +0800415 // Declare success if no error
416 if (mDiagnostics->getNumErrors() == 0)
417 mDOS->keep();
418
419 // Clean up after compilation
Stephen Hinescc0efad2010-10-04 16:13:02 -0700420 mPP.reset();
Zonr Change8c263a2010-10-12 00:35:29 +0800421 mDOS.reset();
Stephen Hinescc0efad2010-10-04 16:13:02 -0700422
423 return mDiagnostics->getNumErrors();
424}
425
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700426int Slang::compile() {
Stephen Hinesf7de8522010-10-06 11:46:18 -0700427 if (mDiagnostics->getNumErrors() > 0)
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700428 return mDiagnostics->getNumErrors();
Stephen Hinesf7de8522010-10-06 11:46:18 -0700429 if (mOS.get() == NULL)
430 return 1;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700431
432 // Here is per-compilation needed initialization
433 createPreprocessor();
434 createASTContext();
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800435
Zonr Change8c263a2010-10-12 00:35:29 +0800436 mBackend.reset(createBackend(CodeGenOpts, mOS.get(), mOT));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700437
438 // Inform the diagnostic client we are processing a source file
439 mDiagClient->BeginSourceFile(LangOpts, mPP.get());
440
441 // The core of the slang compiler
442 ParseAST(*mPP, mBackend.get(), *mASTContext);
443
Zonr Change8c263a2010-10-12 00:35:29 +0800444 // Inform the diagnostic client we are done with previous source file
445 mDiagClient->EndSourceFile();
446
447 // Declare success if no error
448 if (mDiagnostics->getNumErrors() == 0)
449 mOS->keep();
450
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800451 // The compilation ended, clear
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700452 mBackend.reset();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700453 mASTContext.reset();
454 mPP.reset();
Zonr Change8c263a2010-10-12 00:35:29 +0800455 mOS.reset();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700456
457 return mDiagnostics->getNumErrors();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700458}
459
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800460void Slang::reset() {
461 mDiagnostics->Reset();
462 mDiagClient->reset();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700463 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700464}
465
466Slang::~Slang() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700467 llvm::llvm_shutdown();
468 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700469}