blob: 1775563e699d6fc5f0e924f916811e1aebf66f06 [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
Stephen Hinese639eb52010-11-08 19:27:20 -080021#include <string>
22#include <vector>
23
24#include "clang/AST/ASTConsumer.h"
25#include "clang/AST/ASTContext.h"
26
Loganbe274822011-02-16 22:02:54 +080027#include "clang/Basic/DiagnosticIDs.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080028#include "clang/Basic/FileManager.h"
Shih-wei Liaodf5bcce2011-02-28 18:39:23 -080029#include "clang/Basic/FileSystemOptions.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080030#include "clang/Basic/LangOptions.h"
31#include "clang/Basic/SourceManager.h"
32#include "clang/Basic/TargetInfo.h"
33#include "clang/Basic/TargetOptions.h"
34
35#include "clang/Frontend/CodeGenOptions.h"
36#include "clang/Frontend/DiagnosticOptions.h"
37#include "clang/Frontend/DependencyOutputOptions.h"
38#include "clang/Frontend/FrontendDiagnostic.h"
39#include "clang/Frontend/TextDiagnosticPrinter.h"
40#include "clang/Frontend/Utils.h"
41
42#include "clang/Lex/Preprocessor.h"
43#include "clang/Lex/HeaderSearch.h"
44
45#include "clang/Parse/ParseAST.h"
46
Loganbe274822011-02-16 22:02:54 +080047#include "llvm/ADT/IntrusiveRefCntPtr.h"
48
Stephen Hinese639eb52010-11-08 19:27:20 -080049#include "llvm/Bitcode/ReaderWriter.h"
50
51// More force linking
52#include "llvm/Linker.h"
53
Zonr Chang08df36e2010-10-07 18:50:42 +080054// Force linking all passes/vmcore stuffs to libslang.so
55#include "llvm/LinkAllPasses.h"
56#include "llvm/LinkAllVMCore.h"
57
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080058#include "llvm/Support/raw_ostream.h"
zonr6315f762010-10-05 15:35:14 +080059#include "llvm/Support/MemoryBuffer.h"
60#include "llvm/Support/ErrorHandling.h"
61#include "llvm/Support/ManagedStatic.h"
Loganbe274822011-02-16 22:02:54 +080062#include "llvm/Support/Path.h"
Logan Chien9207a2e2011-10-21 15:39:28 +080063#include "llvm/Support/TargetSelect.h"
64#include "llvm/Support/ToolOutputFile.h"
Stephen Hinescc0efad2010-10-04 16:13:02 -070065
Stephen Hines6e6578a2011-02-07 18:05:48 -080066#include "slang_assert.h"
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080067#include "slang_backend.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080068#include "slang_utils.h"
Shih-wei Liaob81c6a42010-10-10 14:15:00 -070069
Zonr Chang08df36e2010-10-07 18:50:42 +080070namespace {
Zonr Chang08df36e2010-10-07 18:50:42 +080071
Stephen Hinese639eb52010-11-08 19:27:20 -080072struct ForceSlangLinking {
73 ForceSlangLinking() {
74 // We must reference the functions in such a way that compilers will not
75 // delete it all as dead code, even with whole program optimization,
76 // yet is effectively a NO-OP. As the compiler isn't smart enough
77 // to know that getenv() never returns -1, this will do the job.
78 if (std::getenv("bar") != reinterpret_cast<char*>(-1))
79 return;
Shih-wei Liaob81c6a42010-10-10 14:15:00 -070080
Stephen Hinese639eb52010-11-08 19:27:20 -080081 // llvm-rs-link needs following functions existing in libslang.
82 llvm::ParseBitcodeFile(NULL, llvm::getGlobalContext(), NULL);
Logan Chien9207a2e2011-10-21 15:39:28 +080083 llvm::Linker::LinkModules(NULL, NULL, 0, NULL);
Zonr Chang08df36e2010-10-07 18:50:42 +080084
Stephen Hinese639eb52010-11-08 19:27:20 -080085 // llvm-rs-cc need this.
86 new clang::TextDiagnosticPrinter(llvm::errs(),
87 clang::DiagnosticOptions());
88 }
89} ForceSlangLinking;
90
91} // namespace
92
93namespace slang {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070094
Shih-wei Liao462aefd2010-06-04 15:32:04 -070095#if defined(__arm__)
96# define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
97#elif defined(__x86_64__)
98# define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux"
99#else
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700100// let's use x86 as default target
101# define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux"
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700102#endif
103
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700104bool Slang::GlobalInitialized = false;
105
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700106// Language option (define the language feature for compiler such as C99)
107clang::LangOptions Slang::LangOpts;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700108
zonr6315f762010-10-05 15:35:14 +0800109// Code generation option for the compiler
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700110clang::CodeGenOptions Slang::CodeGenOpts;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700111
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700112// The named of metadata node that pragma resides (should be synced with
113// bcc.cpp)
Shih-wei Liaof52a6202010-09-10 17:40:53 -0700114const llvm::StringRef Slang::PragmaMetadataName = "#pragma";
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700115
Logan Chien9207a2e2011-10-21 15:39:28 +0800116static inline llvm::tool_output_file *
117OpenOutputFile(const char *OutputFile,
118 unsigned Flags,
119 std::string* Error,
Stephen Hinese67239d2012-02-24 15:08:36 -0800120 clang::DiagnosticsEngine *DiagEngine) {
Logan Chien9207a2e2011-10-21 15:39:28 +0800121 slangAssert((OutputFile != NULL) && (Error != NULL) &&
122 (DiagEngine != NULL) && "Invalid parameter!");
Zonr Change8c263a2010-10-12 00:35:29 +0800123
Logan Chien6f4e0a92011-03-10 01:10:25 +0800124 if (SlangUtils::CreateDirectoryWithParents(
125 llvm::sys::path::parent_path(OutputFile), Error)) {
Zonr Change8c263a2010-10-12 00:35:29 +0800126 llvm::tool_output_file *F =
127 new llvm::tool_output_file(OutputFile, *Error, Flags);
128 if (F != NULL)
129 return F;
130 }
131
132 // Report error here.
Logan Chien9207a2e2011-10-21 15:39:28 +0800133 DiagEngine->Report(clang::diag::err_fe_error_opening)
134 << OutputFile << *Error;
Zonr Change8c263a2010-10-12 00:35:29 +0800135
136 return NULL;
137}
138
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700139void Slang::GlobalInitialization() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700140 if (!GlobalInitialized) {
141 // We only support x86, x64 and ARM target
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700142
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700143 // For ARM
144 LLVMInitializeARMTargetInfo();
145 LLVMInitializeARMTarget();
146 LLVMInitializeARMAsmPrinter();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700147
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700148 // For x86 and x64
149 LLVMInitializeX86TargetInfo();
150 LLVMInitializeX86Target();
151 LLVMInitializeX86AsmPrinter();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700152
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800153 // Please refer to include/clang/Basic/LangOptions.h to setup
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700154 // the options.
155 LangOpts.RTTI = 0; // Turn off the RTTI information support
Shih-wei Liao245eba12011-01-19 02:14:07 -0800156 LangOpts.C99 = 1;
Stephen Hines52d132c2012-08-01 18:48:06 -0700157 LangOpts.Renderscript = 1;
Stephen Hines194d4032012-02-27 18:01:09 -0800158 LangOpts.CharIsSigned = 1; // Signed char is our default.
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700159
mkopec1c460b372012-01-09 11:21:50 -0500160 CodeGenOpts.OptimizationLevel = 3;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700161
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700162 GlobalInitialized = true;
163 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700164}
165
166void Slang::LLVMErrorHandler(void *UserData, const std::string &Message) {
Logan Chien9207a2e2011-10-21 15:39:28 +0800167 clang::DiagnosticsEngine* DiagEngine =
168 static_cast<clang::DiagnosticsEngine *>(UserData);
169
170 DiagEngine->Report(clang::diag::err_fe_error_backend) << Message;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700171 exit(1);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700172}
173
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700174void Slang::createTarget(const std::string &Triple, const std::string &CPU,
175 const std::vector<std::string> &Features) {
176 if (!Triple.empty())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700177 mTargetOpts.Triple = Triple;
178 else
179 mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700180
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700181 if (!CPU.empty())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700182 mTargetOpts.CPU = CPU;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700183
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700184 if (!Features.empty())
185 mTargetOpts.Features = Features;
186
Logan Chien9207a2e2011-10-21 15:39:28 +0800187 mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagEngine,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700188 mTargetOpts));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700189}
190
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800191void Slang::createFileManager() {
Shih-wei Liaodf5bcce2011-02-28 18:39:23 -0800192 mFileSysOpt.reset(new clang::FileSystemOptions());
Loganbe274822011-02-16 22:02:54 +0800193 mFileMgr.reset(new clang::FileManager(*mFileSysOpt));
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800194}
195
196void Slang::createSourceManager() {
Logan Chien9207a2e2011-10-21 15:39:28 +0800197 mSourceMgr.reset(new clang::SourceManager(*mDiagEngine, *mFileMgr));
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800198}
199
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700200void Slang::createPreprocessor() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700201 // Default only search header file in current dir
Stephen Hines4c622e02011-11-10 18:57:34 -0800202 clang::HeaderSearch *HeaderInfo = new clang::HeaderSearch(*mFileMgr,
Stephen Hines0444de02012-03-02 23:19:06 -0800203 *mDiagEngine,
204 LangOpts,
205 mTarget.get());
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700206
Logan Chien9207a2e2011-10-21 15:39:28 +0800207 mPP.reset(new clang::Preprocessor(*mDiagEngine,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700208 LangOpts,
Logan Chien9207a2e2011-10-21 15:39:28 +0800209 mTarget.get(),
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700210 *mSourceMgr,
Logan Chien9207a2e2011-10-21 15:39:28 +0800211 *HeaderInfo,
212 *this,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700213 NULL,
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800214 /* OwnsHeaderSearch = */true));
Stephen Hines3fd0a942011-01-18 12:27:39 -0800215 // Initialize the preprocessor
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700216 mPragmas.clear();
Stephen Hines3fd0a942011-01-18 12:27:39 -0800217 mPP->AddPragmaHandler(new PragmaRecorder(&mPragmas));
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700218
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700219 std::vector<clang::DirectoryLookup> SearchList;
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800220 for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700221 if (const clang::DirectoryEntry *DE =
Loganbe274822011-02-16 22:02:54 +0800222 mFileMgr->getDirectory(mIncludePaths[i])) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700223 SearchList.push_back(clang::DirectoryLookup(DE,
224 clang::SrcMgr::C_System,
225 false,
226 false));
227 }
Shih-wei Liao90898282010-07-19 18:38:57 -0700228 }
229
Logan Chien9207a2e2011-10-21 15:39:28 +0800230 HeaderInfo->SetSearchPaths(SearchList,
231 /* angledDirIdx = */1,
232 /* systemDixIdx = */1,
233 /* noCurDirSearch = */false);
Shih-wei Liao90898282010-07-19 18:38:57 -0700234
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800235 initPreprocessor();
Shih-wei Liao68e8e9f2010-07-18 18:46:49 -0700236}
237
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800238void Slang::createASTContext() {
239 mASTContext.reset(new clang::ASTContext(LangOpts,
240 *mSourceMgr,
Logan Chien9207a2e2011-10-21 15:39:28 +0800241 mTarget.get(),
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800242 mPP->getIdentifierTable(),
243 mPP->getSelectorTable(),
244 mPP->getBuiltinInfo(),
245 /* size_reserve = */0));
246 initASTContext();
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800247}
248
Logan Chien9207a2e2011-10-21 15:39:28 +0800249clang::ASTConsumer *
250Slang::createBackend(const clang::CodeGenOptions& CodeGenOpts,
251 llvm::raw_ostream *OS, OutputType OT) {
Stephen Hines8f4d9722011-12-05 14:14:42 -0800252 return new Backend(mDiagEngine, CodeGenOpts, mTargetOpts,
Logan Chien9207a2e2011-10-21 15:39:28 +0800253 &mPragmas, OS, OT);
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800254}
255
Zonr Chang641558f2010-10-12 21:07:06 +0800256Slang::Slang() : mInitialized(false), mDiagClient(NULL), mOT(OT_Default) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700257 GlobalInitialization();
Zonr Chang641558f2010-10-12 21:07:06 +0800258}
259
260void Slang::init(const std::string &Triple, const std::string &CPU,
Stephen Hines8f4d9722011-12-05 14:14:42 -0800261 const std::vector<std::string> &Features,
262 clang::DiagnosticsEngine *DiagEngine,
263 DiagnosticBuffer *DiagClient) {
Zonr Chang641558f2010-10-12 21:07:06 +0800264 if (mInitialized)
265 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700266
Stephen Hines8f4d9722011-12-05 14:14:42 -0800267 mDiagEngine = DiagEngine;
268 mDiagClient = DiagClient;
269 mDiag.reset(new clang::Diagnostic(mDiagEngine));
270 initDiagnostic();
271 llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagEngine);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700272
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700273 createTarget(Triple, CPU, Features);
274 createFileManager();
275 createSourceManager();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700276
Zonr Chang641558f2010-10-12 21:07:06 +0800277 mInitialized = true;
Logan Chien9207a2e2011-10-21 15:39:28 +0800278}
Zonr Chang641558f2010-10-12 21:07:06 +0800279
Logan Chienac4e1852011-12-16 13:37:10 +0800280clang::Module *Slang::loadModule(clang::SourceLocation ImportLoc,
281 clang::ModuleIdPath Path,
282 clang::Module::NameVisibilityKind Visibility,
283 bool IsInclusionDirective) {
Logan Chien9207a2e2011-10-21 15:39:28 +0800284 slangAssert(0 && "Not implemented");
285 return NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700286}
287
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800288bool Slang::setInputSource(llvm::StringRef InputFile,
289 const char *Text,
290 size_t TextLength) {
291 mInputFileName = InputFile.str();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700292
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700293 // Reset the ID tables if we are reusing the SourceManager
294 mSourceMgr->clearIDTables();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700295
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700296 // Load the source
zonr6315f762010-10-05 15:35:14 +0800297 llvm::MemoryBuffer *SB =
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800298 llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700299 mSourceMgr->createMainFileIDForMemBuffer(SB);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700300
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700301 if (mSourceMgr->getMainFileID().isInvalid()) {
Logan Chien9207a2e2011-10-21 15:39:28 +0800302 mDiagEngine->Report(clang::diag::err_fe_error_reading) << InputFile;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700303 return false;
304 }
305 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700306}
307
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800308bool Slang::setInputSource(llvm::StringRef InputFile) {
309 mInputFileName = InputFile.str();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700310
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700311 mSourceMgr->clearIDTables();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700312
Loganbe274822011-02-16 22:02:54 +0800313 const clang::FileEntry *File = mFileMgr->getFile(InputFile);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700314 if (File)
315 mSourceMgr->createMainFileID(File);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700316
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700317 if (mSourceMgr->getMainFileID().isInvalid()) {
Logan Chien9207a2e2011-10-21 15:39:28 +0800318 mDiagEngine->Report(clang::diag::err_fe_error_reading) << InputFile;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700319 return false;
320 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700321
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700322 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700323}
324
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800325bool Slang::setOutput(const char *OutputFile) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800326 llvm::sys::Path OutputFilePath(OutputFile);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700327 std::string Error;
Zonr Change8c263a2010-10-12 00:35:29 +0800328 llvm::tool_output_file *OS = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700329
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800330 switch (mOT) {
Stephen Hinescc0efad2010-10-04 16:13:02 -0700331 case OT_Dependency:
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800332 case OT_Assembly:
333 case OT_LLVMAssembly: {
Stephen Hines8f4d9722011-12-05 14:14:42 -0800334 OS = OpenOutputFile(OutputFile, 0, &Error, mDiagEngine);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700335 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700336 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800337 case OT_Nothing: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700338 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700339 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800340 case OT_Object:
Stephen Hinescc0efad2010-10-04 16:13:02 -0700341 case OT_Bitcode: {
Logan Chien9207a2e2011-10-21 15:39:28 +0800342 OS = OpenOutputFile(OutputFile, llvm::raw_fd_ostream::F_Binary,
Stephen Hines8f4d9722011-12-05 14:14:42 -0800343 &Error, mDiagEngine);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700344 break;
345 }
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800346 default: {
Stephen Hinescc0efad2010-10-04 16:13:02 -0700347 llvm_unreachable("Unknown compiler output type");
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800348 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700349 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700350
Zonr Change8c263a2010-10-12 00:35:29 +0800351 if (!Error.empty())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700352 return false;
Zonr Change8c263a2010-10-12 00:35:29 +0800353
354 mOS.reset(OS);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700355
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800356 mOutputFileName = OutputFile;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700357
358 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700359}
360
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700361bool Slang::setDepOutput(const char *OutputFile) {
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800362 llvm::sys::Path OutputFilePath(OutputFile);
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700363 std::string Error;
Zonr Chang8c6d9b22010-10-07 18:01:19 +0800364
Stephen Hines8f4d9722011-12-05 14:14:42 -0800365 mDOS.reset(OpenOutputFile(OutputFile, 0, &Error, mDiagEngine));
Zonr Change8c263a2010-10-12 00:35:29 +0800366 if (!Error.empty() || (mDOS.get() == NULL))
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700367 return false;
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700368
369 mDepOutputFileName = OutputFile;
370
371 return true;
372}
373
Stephen Hinescc0efad2010-10-04 16:13:02 -0700374int Slang::generateDepFile() {
Logan Chien9207a2e2011-10-21 15:39:28 +0800375 if (mDiagEngine->hasErrorOccurred())
Loganbe274822011-02-16 22:02:54 +0800376 return 1;
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700377 if (mDOS.get() == NULL)
Stephen Hinesf7de8522010-10-06 11:46:18 -0700378 return 1;
Stephen Hinescc0efad2010-10-04 16:13:02 -0700379
Zonr Change8c263a2010-10-12 00:35:29 +0800380 // Initialize options for generating dependency file
Stephen Hinescc0efad2010-10-04 16:13:02 -0700381 clang::DependencyOutputOptions DepOpts;
382 DepOpts.IncludeSystemHeaders = 1;
Stephen Hines0b7ef1a2010-10-07 16:36:59 -0700383 DepOpts.OutputFile = mDepOutputFileName;
Shih-wei Liaob81c6a42010-10-10 14:15:00 -0700384 DepOpts.Targets = mAdditionalDepTargets;
Stephen Hinescc0efad2010-10-04 16:13:02 -0700385 DepOpts.Targets.push_back(mDepTargetBCFileName);
Stephen Hines4cc67fc2011-01-31 16:48:57 -0800386 for (std::vector<std::string>::const_iterator
387 I = mGeneratedFileNames.begin(), E = mGeneratedFileNames.end();
388 I != E;
389 I++) {
390 DepOpts.Targets.push_back(*I);
391 }
392 mGeneratedFileNames.clear();
Stephen Hinescc0efad2010-10-04 16:13:02 -0700393
Zonr Change8c263a2010-10-12 00:35:29 +0800394 // Per-compilation needed initialization
Stephen Hinescc0efad2010-10-04 16:13:02 -0700395 createPreprocessor();
396 AttachDependencyFileGen(*mPP.get(), DepOpts);
397
Zonr Change8c263a2010-10-12 00:35:29 +0800398 // Inform the diagnostic client we are processing a source file
Stephen Hinescc0efad2010-10-04 16:13:02 -0700399 mDiagClient->BeginSourceFile(LangOpts, mPP.get());
400
Zonr Change8c263a2010-10-12 00:35:29 +0800401 // Go through the source file (no operations necessary)
Stephen Hinescc0efad2010-10-04 16:13:02 -0700402 clang::Token Tok;
403 mPP->EnterMainSourceFile();
404 do {
405 mPP->Lex(Tok);
406 } while (Tok.isNot(clang::tok::eof));
407
408 mPP->EndSourceFile();
409
Zonr Change8c263a2010-10-12 00:35:29 +0800410 // Declare success if no error
Logan Chien9207a2e2011-10-21 15:39:28 +0800411 if (!mDiagEngine->hasErrorOccurred())
Zonr Change8c263a2010-10-12 00:35:29 +0800412 mDOS->keep();
413
414 // Clean up after compilation
Stephen Hinescc0efad2010-10-04 16:13:02 -0700415 mPP.reset();
Zonr Change8c263a2010-10-12 00:35:29 +0800416 mDOS.reset();
Stephen Hinescc0efad2010-10-04 16:13:02 -0700417
Logan Chien9207a2e2011-10-21 15:39:28 +0800418 return mDiagEngine->hasErrorOccurred() ? 1 : 0;
Stephen Hinescc0efad2010-10-04 16:13:02 -0700419}
420
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700421int Slang::compile() {
Logan Chien9207a2e2011-10-21 15:39:28 +0800422 if (mDiagEngine->hasErrorOccurred())
Loganbe274822011-02-16 22:02:54 +0800423 return 1;
Stephen Hinesf7de8522010-10-06 11:46:18 -0700424 if (mOS.get() == NULL)
425 return 1;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700426
427 // Here is per-compilation needed initialization
428 createPreprocessor();
429 createASTContext();
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800430
Shih-wei Liaodf5bcce2011-02-28 18:39:23 -0800431 mBackend.reset(createBackend(CodeGenOpts, &mOS->os(), mOT));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700432
433 // Inform the diagnostic client we are processing a source file
434 mDiagClient->BeginSourceFile(LangOpts, mPP.get());
435
436 // The core of the slang compiler
437 ParseAST(*mPP, mBackend.get(), *mASTContext);
438
Zonr Change8c263a2010-10-12 00:35:29 +0800439 // Inform the diagnostic client we are done with previous source file
440 mDiagClient->EndSourceFile();
441
442 // Declare success if no error
Logan Chien9207a2e2011-10-21 15:39:28 +0800443 if (!mDiagEngine->hasErrorOccurred())
Zonr Change8c263a2010-10-12 00:35:29 +0800444 mOS->keep();
445
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800446 // The compilation ended, clear
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700447 mBackend.reset();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700448 mASTContext.reset();
449 mPP.reset();
Zonr Change8c263a2010-10-12 00:35:29 +0800450 mOS.reset();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700451
Logan Chien9207a2e2011-10-21 15:39:28 +0800452 return mDiagEngine->hasErrorOccurred() ? 1 : 0;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700453}
454
mkopec1c460b372012-01-09 11:21:50 -0500455void Slang::setDebugMetadataEmission(bool EmitDebug) {
Shih-wei Liao43730fe2012-08-02 23:06:18 -0700456 if (EmitDebug)
457 CodeGenOpts.DebugInfo = clang::CodeGenOptions::FullDebugInfo;
458 else
459 CodeGenOpts.DebugInfo = clang::CodeGenOptions::NoDebugInfo;
mkopec1c460b372012-01-09 11:21:50 -0500460}
461
462void Slang::setOptimizationLevel(llvm::CodeGenOpt::Level OptimizationLevel) {
463 CodeGenOpts.OptimizationLevel = OptimizationLevel;
464}
465
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800466void Slang::reset() {
Stephen Hinesc632be22011-09-23 15:53:16 -0700467 llvm::errs() << mDiagClient->str();
Logan Chien9207a2e2011-10-21 15:39:28 +0800468 mDiagEngine->Reset();
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800469 mDiagClient->reset();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700470}
471
472Slang::~Slang() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700473 llvm::llvm_shutdown();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700474}
Stephen Hinese639eb52010-11-08 19:27:20 -0800475
476} // namespace slang