slang.cpp revision df5bcce1582d839eead432a5e24435236c90fb05
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright 2010, The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
51badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich * you may not use this file except in compliance with the License.
61badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich * You may obtain a copy of the License at
71badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
91badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
111badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich * distributed under the License is distributed on an "AS IS" BASIS,
121badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich * See the License for the specific language governing permissions and
141badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "slang.h"
188451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
20289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn
21e5e0c50f7dfaccc220725c5595080e921ffda1e4Romain Guy#include <string>
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <vector>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
248335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include "clang/AST/ASTConsumer.h"
258335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include "clang/AST/ASTContext.h"
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "clang/Basic/FileManager.h"
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "clang/Basic/FileSystemOptions.h"
298335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include "clang/Basic/LangOptions.h"
30d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden#include "clang/Basic/SourceManager.h"
3152800617946c456e78ed010c82d0ec4358368164Mathias Agopian#include "clang/Basic/TargetInfo.h"
328ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy#include "clang/Basic/TargetOptions.h"
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "clang/Frontend/CodeGenOptions.h"
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "clang/Frontend/DiagnosticOptions.h"
36af01feafc30152baf8e0a5cfddbf02bd14731fd2Mathias Agopian#include "clang/Frontend/DependencyOutputOptions.h"
37af01feafc30152baf8e0a5cfddbf02bd14731fd2Mathias Agopian#include "clang/Frontend/FrontendDiagnostic.h"
3854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn#include "clang/Frontend/TextDiagnosticPrinter.h"
398b73ae4a1e5321753e54354e5202a38c5560fea9Mathias Agopian#include "clang/Frontend/Utils.h"
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "clang/Lex/Preprocessor.h"
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "clang/Lex/HeaderSearch.h"
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "clang/Parse/ParseAST.h"
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "llvm/Bitcode/ReaderWriter.h"
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// More force linking
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "llvm/Linker.h"
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Force linking all passes/vmcore stuffs to libslang.so
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "llvm/LinkAllPasses.h"
53863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat#include "llvm/LinkAllVMCore.h"
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "llvm/Support/raw_ostream.h"
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "llvm/Support/MemoryBuffer.h"
57863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat#include "llvm/Support/ErrorHandling.h"
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "llvm/Support/ManagedStatic.h"
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "llvm/Support/ToolOutputFile.h"
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
61863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat#include "llvm/System/Path.h"
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "llvm/Target/TargetSelect.h"
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
65863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat#include "slang_assert.h"
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "slang_backend.h"
67863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat#include "slang_utils.h"
68863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat
69863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhatnamespace {
70863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat
71863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhatstruct ForceSlangLinking {
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  ForceSlangLinking() {
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // We must reference the functions in such a way that compilers will not
74dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes    // delete it all as dead code, even with whole program optimization,
75dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes    // yet is effectively a NO-OP. As the compiler isn't smart enough
76863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat    // to know that getenv() never returns -1, this will do the job.
77863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat    if (std::getenv("bar") != reinterpret_cast<char*>(-1))
78dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes      return;
79dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes
80863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat    // llvm-rs-link needs following functions existing in libslang.
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    llvm::ParseBitcodeFile(NULL, llvm::getGlobalContext(), NULL);
82dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes    llvm::Linker::LinkModules(NULL, NULL, NULL);
83863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat
841badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    // llvm-rs-cc need this.
85dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes    new clang::TextDiagnosticPrinter(llvm::errs(),
86863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat                                     clang::DiagnosticOptions());
87863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  }
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} ForceSlangLinking;
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
90a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat}  // namespace
911badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
921badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevichnamespace slang {
931badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
941badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich#if defined(__arm__)
951badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich#   define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
961badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich#elif defined(__x86_64__)
971badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich#   define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux"
981badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich#else
991badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich// let's use x86 as default target
1001badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich#   define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux"
1011badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich#endif
1021badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
1031badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevichbool Slang::GlobalInitialized = false;
1041badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
1051badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich// Language option (define the language feature for compiler such as C99)
1061badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevichclang::LangOptions Slang::LangOpts;
1071badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
1081badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich// Code generation option for the compiler
1091badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevichclang::CodeGenOptions Slang::CodeGenOpts;
110b5066245365e932775ca6087cd74e53efa364642Michael Chock
1111badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich// The named of metadata node that pragma resides (should be synced with
1121badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich// bcc.cpp)
1131badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevichconst llvm::StringRef Slang::PragmaMetadataName = "#pragma";
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline llvm::tool_output_file *OpenOutputFile(const char *OutputFile,
1161badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                                     unsigned Flags,
1171badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                                     std::string* Error,
1186a5e6df96858bd581151cc99421f67a0674b76d1Mathieu Chartier                                                     clang::Diagnostic* Diag) {
1191badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  slangAssert((OutputFile != NULL) && (Error != NULL) && (Diag != NULL) &&
1201badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich              "Invalid parameter!");
1211badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
1221badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  llvm::sys::Path OutputFilePath(OutputFile);
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1241badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  if (SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
1251badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                             Error)) {
1268451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    llvm::tool_output_file *F =
1271badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich          new llvm::tool_output_file(OutputFile, *Error, Flags);
1281badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    if (F != NULL)
1291badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich      return F;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
131863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  // Report error here.
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  Diag->Report(clang::diag::err_fe_error_opening) << OutputFile << *Error;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  return NULL;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Slang::GlobalInitialization() {
1396a5e6df96858bd581151cc99421f67a0674b76d1Mathieu Chartier  if (!GlobalInitialized) {
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // We only support x86, x64 and ARM target
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
142863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat    // For ARM
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LLVMInitializeARMTargetInfo();
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LLVMInitializeARMTarget();
1451badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    LLVMInitializeARMAsmPrinter();
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1471badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    // For x86 and x64
1481badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    LLVMInitializeX86TargetInfo();
1498451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    LLVMInitializeX86Target();
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LLVMInitializeX86AsmPrinter();
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1521badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    // Please refer to include/clang/Basic/LangOptions.h to setup
1531badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    // the options.
154863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat    LangOpts.RTTI = 0;  // Turn off the RTTI information support
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LangOpts.NeXTRuntime = 0;   // Turn off the NeXT runtime uses
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LangOpts.C99 = 1;
157b5066245365e932775ca6087cd74e53efa364642Michael Chock
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CodeGenOpts.OptimizationLevel = 3;  /* -O3 */
1596a5e6df96858bd581151cc99421f67a0674b76d1Mathieu Chartier
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    GlobalInitialized = true;
161863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  }
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1631badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  return;
1641badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich}
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1661badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevichvoid Slang::LLVMErrorHandler(void *UserData, const std::string &Message) {
1671badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  clang::Diagnostic* Diags = static_cast<clang::Diagnostic*>(UserData);
1688451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes  Diags->Report(clang::diag::err_fe_error_backend) << Message;
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  exit(1);
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1711badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
1721badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevichvoid Slang::createDiagnostic() {
1731badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  mDiagnostics =
174863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat      llvm::IntrusiveRefCntPtr<clang::Diagnostic>(new clang::Diagnostic());
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mDiagClient = new DiagnosticBuffer();
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  // This takes the ownership of mDiagClient.
177b5066245365e932775ca6087cd74e53efa364642Michael Chock  mDiagnostics->setClient(mDiagClient);
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  initDiagnostic();
1796a5e6df96858bd581151cc99421f67a0674b76d1Mathieu Chartier  return;
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
181863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Slang::createTarget(const std::string &Triple, const std::string &CPU,
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                         const std::vector<std::string> &Features) {
1848ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy  if (!Triple.empty())
1858ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mTargetOpts.Triple = Triple;
1869847f311f63301ca7d9553abcb0aec56b47cd60cJesse Hall  else
1878ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mTargetOpts.Triple = DEFAULT_TARGET_TRIPLE_STRING;
1888ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy
1898ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy  if (!CPU.empty())
1908ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mTargetOpts.CPU = CPU;
191863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat
1928ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy  if (!Features.empty())
1938ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy    mTargetOpts.Features = Features;
1941badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
1951badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagnostics,
1961badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                                    mTargetOpts));
1971badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
1981badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  return;
1991badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich}
2008451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid Slang::createFileManager() {
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mFileMgr.reset(new clang::FileManager());
2031badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  mFileSysOpt.reset(new clang::FileSystemOptions());
204863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat}
2051badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
2061badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevichvoid Slang::createSourceManager() {
2071badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  mSourceMgr.reset(new clang::SourceManager(*mDiagnostics,
2081badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                            *mFileMgr,
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            *mFileSysOpt));
2101badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  return;
2111badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich}
2121badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
2131badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevichvoid Slang::createPreprocessor() {
2141badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  // Default only search header file in current dir
2151badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  clang::HeaderSearch *HS = new clang::HeaderSearch(*mFileMgr, *mFileSysOpt);
2161badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
2171badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  mPP.reset(new clang::Preprocessor(*mDiagnostics,
2181badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                    LangOpts,
2191badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                    *mTarget,
2201badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                    *mSourceMgr,
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    *HS,
222863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat                                    NULL,
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    /* OwnsHeaderSearch = */true));
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  // Initialize the preprocessor
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mPragmas.clear();
226863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  mPP->AddPragmaHandler(new PragmaRecorder(&mPragmas));
2271badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  std::vector<clang::DirectoryLookup> SearchList;
229863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (const clang::DirectoryEntry *DE =
2311badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich            mFileMgr->getDirectory(mIncludePaths[i], *mFileSysOpt)) {
2321badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich      SearchList.push_back(clang::DirectoryLookup(DE,
2338451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes                                                  clang::SrcMgr::C_System,
2341badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                                  false,
2351badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                                  false));
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2391badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  HS->SetSearchPaths(SearchList, 1, false);
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2411badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  initPreprocessor();
242863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  return;
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
245863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhatvoid Slang::createASTContext() {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mASTContext.reset(new clang::ASTContext(LangOpts,
2471badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                          *mSourceMgr,
2481badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                          *mTarget,
2498451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes                                          mPP->getIdentifierTable(),
2501badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                          mPP->getSelectorTable(),
2511badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                                          mPP->getBuiltinInfo(),
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                          /* size_reserve = */0));
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  initASTContext();
2541badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  return;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2561badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
257863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhatclang::ASTConsumer
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*Slang::createBackend(const clang::CodeGenOptions& CodeGenOpts,
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      llvm::raw_ostream *OS,
2601103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed                      OutputType OT) {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  return new Backend(mDiagnostics.getPtr(),
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     CodeGenOpts,
2631103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed                     mTargetOpts,
2641103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed                     &mPragmas,
2651103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed                     OS,
2661103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed                     OT);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSlang::Slang() : mInitialized(false), mDiagClient(NULL), mOT(OT_Default) {
2701badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  GlobalInitialization();
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  return;
2721badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich}
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2741badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevichvoid Slang::init(const std::string &Triple, const std::string &CPU,
2751badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich                 const std::vector<std::string> &Features) {
2768451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes  if (mInitialized)
2771badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    return;
2781badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  createDiagnostic();
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagnostics.getPtr());
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  createTarget(Triple, CPU, Features);
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  createFileManager();
284a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat  createSourceManager();
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mInitialized = true;
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2888451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes  return;
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2911badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevichbool Slang::setInputSource(llvm::StringRef InputFile,
2926062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger                           const char *Text,
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           size_t TextLength) {
2941badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  mInputFileName = InputFile.str();
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  // Reset the ID tables if we are reusing the SourceManager
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mSourceMgr->clearIDTables();
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  // Load the source
3001103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed  llvm::MemoryBuffer *SB =
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      llvm::MemoryBuffer::getMemBuffer(Text, Text + TextLength);
3021badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  mSourceMgr->createMainFileIDForMemBuffer(SB);
3031badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (mSourceMgr->getMainFileID().isInvalid()) {
3051badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
308863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  return true;
309863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat}
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool Slang::setInputSource(llvm::StringRef InputFile) {
3126062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger  mInputFileName = InputFile.str();
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mSourceMgr->clearIDTables();
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
316863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  const clang::FileEntry *File = mFileMgr->getFile(InputFile, *mFileSysOpt);
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (File)
3181badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    mSourceMgr->createMainFileID(File);
3191badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
3208451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes  if (mSourceMgr->getMainFileID().isInvalid()) {
3211badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    mDiagnostics->Report(clang::diag::err_fe_error_reading) << InputFile;
3221badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    return false;
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32554a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn  return true;
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3288451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughesbool Slang::setOutput(const char *OutputFile) {
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  llvm::sys::Path OutputFilePath(OutputFile);
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  std::string Error;
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  llvm::tool_output_file *OS = NULL;
3328b73ae4a1e5321753e54354e5202a38c5560fea9Mathias Agopian
33364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown  switch (mOT) {
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case OT_Dependency:
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case OT_Assembly:
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case OT_LLVMAssembly: {
3371badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich      OS = OpenOutputFile(OutputFile, 0, &Error, mDiagnostics.getPtr());
33854a181b1a2b1517a9479b21fbf7705a688232fafDianne Hackborn      break;
3391badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    }
340863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat    case OT_Nothing: {
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      break;
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
343863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat    case OT_Object:
344e5e0c50f7dfaccc220725c5595080e921ffda1e4Romain Guy    case OT_Bitcode: {
3458f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy      OS = OpenOutputFile(OutputFile,
3468f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                          llvm::raw_fd_ostream::F_Binary,
3478f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy                          &Error,
348863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat                          mDiagnostics.getPtr());
3498f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy      break;
3508f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    }
3518f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    default: {
3528f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy      llvm_unreachable("Unknown compiler output type");
3538f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    }
3548f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy  }
3558f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3568f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy  if (!Error.empty())
3578f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy    return false;
3588f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3590fa257fe53bf520bdde93996a1901ce6bc3e1788Jesse Hall  mOS.reset(OS);
36052a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian
3610fa257fe53bf520bdde93996a1901ce6bc3e1788Jesse Hall  mOutputFileName = OutputFile;
3628f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3638f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy  return true;
3648f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy}
3658f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3668f0095cd33558e9cc8a440047908e53b68906f5fRomain Guybool Slang::setDepOutput(const char *OutputFile) {
3678f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy  llvm::sys::Path OutputFilePath(OutputFile);
368863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  std::string Error;
3698f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy
3708f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy  mDOS.reset(OpenOutputFile(OutputFile, 0, &Error, mDiagnostics.getPtr()));
3711badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  if (!Error.empty() || (mDOS.get() == NULL))
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
3731badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
3741badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  mDepOutputFileName = OutputFile;
3758451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  return true;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3781badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
3791badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevichint Slang::generateDepFile() {
380863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  if (mDiagnostics->getNumErrors() > 0)
3811badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    return mDiagnostics->getNumErrors();
3821badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  if (mDOS.get() == NULL)
3831badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    return 1;
3841badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  // Initialize options for generating dependency file
386863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  clang::DependencyOutputOptions DepOpts;
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  DepOpts.IncludeSystemHeaders = 1;
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  DepOpts.OutputFile = mDepOutputFileName;
3891badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  DepOpts.Targets = mAdditionalDepTargets;
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  DepOpts.Targets.push_back(mDepTargetBCFileName);
3911badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  for (std::vector<std::string>::const_iterator
3921badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich           I = mGeneratedFileNames.begin(), E = mGeneratedFileNames.end();
3938451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes       I != E;
3941badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich       I++) {
3951badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich    DepOpts.Targets.push_back(*I);
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
397863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  mGeneratedFileNames.clear();
3981badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
3991badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  // Per-compilation needed initialization
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  createPreprocessor();
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  AttachDependencyFileGen(*mPP.get(), DepOpts);
4021badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
4031badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  // Inform the diagnostic client we are processing a source file
4041badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
4051badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
4061badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  // Go through the source file (no operations necessary)
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  clang::Token Tok;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mPP->EnterMainSourceFile();
409863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  do {
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mPP->Lex(Tok);
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  } while (Tok.isNot(clang::tok::eof));
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
413863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  mPP->EndSourceFile();
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4151badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  // Declare success if no error
4161badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  if (mDiagnostics->getNumErrors() == 0)
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mDOS->keep();
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  // Clean up after compilation
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mPP.reset();
421863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  mDOS.reset();
422863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  return mDiagnostics->getNumErrors();
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
425863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat
426863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhatint Slang::compile() {
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (mDiagnostics->getNumErrors() > 0)
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mDiagnostics->getNumErrors();
429863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  if (mOS.get() == NULL)
4309b7146db6d9c0586b98b062fbcdb3fac6cc54d19Romain Guy    return 1;
4318451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
4321badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  // Here is per-compilation needed initialization
4331badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  createPreprocessor();
434863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  createASTContext();
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mBackend.reset(createBackend(CodeGenOpts, &mOS->os(), mOT));
4371badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
4381badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  // Inform the diagnostic client we are processing a source file
4398451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
4401badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
4411badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  // The core of the slang compiler
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  ParseAST(*mPP, mBackend.get(), *mASTContext);
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
444863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  // Inform the diagnostic client we are done with previous source file
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mDiagClient->EndSourceFile();
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4471badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  // Declare success if no error
4481badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  if (mDiagnostics->getNumErrors() == 0)
4498451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    mOS->keep();
4501badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
4511badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich  // The compilation ended, clear
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mBackend.reset();
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mASTContext.reset();
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mPP.reset();
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mOS.reset();
456863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  return mDiagnostics->getNumErrors();
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4606062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenbergervoid Slang::reset() {
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mDiagnostics->Reset();
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  mDiagClient->reset();
463863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  return;
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
466863f98bbb3e234e18c62ce2678ae970b75995f69Ashok BhatSlang::~Slang() {
467863f98bbb3e234e18c62ce2678ae970b75995f69Ashok Bhat  llvm::llvm_shutdown();
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  return;
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4701badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich
4711badb712b94f5d4a14ca8c3bdb55c215a4915000Jack Palevich}  // namespace slang
4728451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes