1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/*
20a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines * Copyright 2010-2012, The Android Open Source Project
3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License.
6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at
7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software
11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and
14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License.
15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */
16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang
178b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "clang/Basic/DiagnosticOptions.h"
18b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Driver/DriverDiagnostic.h"
19a1f95ee8df425089100148a42954cf61dc285015Stephen Hines#include "clang/Driver/Options.h"
205309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet#include "clang/Frontend/CompilerInvocation.h"
215309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet#include "clang/Frontend/FrontendDiagnostic.h"
22b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include "clang/Frontend/TextDiagnosticPrinter.h"
238f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#include "clang/Frontend/Utils.h"
24b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/SmallVector.h"
26be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/ADT/IntrusiveRefCntPtr.h"
27b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
28a1f95ee8df425089100148a42954cf61dc285015Stephen Hines#include "llvm/Option/OptTable.h"
291906a00dce8e32fe3bb8a957e333ebbbee0888e3Pirama Arumuga Nainar#include "llvm/Support/Allocator.h"
30e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/ManagedStatic.h"
31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/MemoryBuffer.h"
32be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/Support/Path.h"
33ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#include "llvm/Support/raw_ostream.h"
345309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet#include "llvm/Support/Signals.h"
351906a00dce8e32fe3bb8a957e333ebbbee0888e3Pirama Arumuga Nainar#include "llvm/Support/StringSaver.h"
36b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar#include "llvm/Support/TargetSelect.h"
37c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "llvm/Target/TargetMachine.h"
38e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
399534de12d6a243d8cbee7f3ef99829bab786e89aElliott Hughes#include "os_sep.h"
408b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "rs_cc_options.h"
41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang.h"
426e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
438f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#include "slang_diagnostic_buffer.h"
44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_reflect_utils.h"
45b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
468b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <list>
478b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <set>
488b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <string>
49b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
50c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouilletnamespace {
5198cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainarclass StringSet {
52c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouilletpublic:
5398cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainar  const char *save(const char *Str) {
5498cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainar    return Strings.save(Str);
55c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet  }
56c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet
5798cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainar  StringSet() : Strings(A), A() {}
5898cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainar
5998cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainar  llvm::StringSaver & getStringSaver() { return Strings; }
601906a00dce8e32fe3bb8a957e333ebbbee0888e3Pirama Arumuga Nainar
61c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouilletprivate:
6298cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainar  llvm::StringSaver Strings;
631906a00dce8e32fe3bb8a957e333ebbbee0888e3Pirama Arumuga Nainar  llvm::BumpPtrAllocator A;
64c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet};
65b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
66b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
67b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const char *DetermineOutputFile(const std::string &OutputDir,
689ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines                                       const std::string &PathSuffix,
69b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                       const char *InputFile,
70e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                       slang::Slang::OutputType OutputType,
71c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet                                       StringSet *SavedStrings) {
72e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Nothing)
73b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return "/dev/null";
74b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
75b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string OutputFile(OutputDir);
76b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
777f5704efe0c59d5599f1ac7056976225dbfab946Stephen Hines  // Append '/' to Opts.mBitcodeOutputDir if not presents
78b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (!OutputFile.empty() &&
798d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael      (OutputFile[OutputFile.size() - 1]) != OS_PATH_SEPARATOR)
808d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael    OutputFile.append(1, OS_PATH_SEPARATOR);
81b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
829ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  if (!PathSuffix.empty()) {
839ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    OutputFile.append(PathSuffix);
849ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    OutputFile.append(1, OS_PATH_SEPARATOR);
859ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  }
869ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
87e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Dependency) {
88b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // The build system wants the .d file name stem to be exactly the same as
89b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // the source .rs file, instead of the .bc file.
90e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(slang::RSSlangReflectUtils::GetFileNameStem(InputFile));
91e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  } else {
92e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(
93e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        slang::RSSlangReflectUtils::BCFileNameFromRSFileName(InputFile));
94e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  }
95b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
96e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  switch (OutputType) {
97e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Dependency: {
98b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".d");
99b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
100b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
101e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Assembly: {
102b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".S");
103b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
104b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
105e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_LLVMAssembly: {
106b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".ll");
107b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
108b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
109e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Object: {
110b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".o");
111b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
112b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
113e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Bitcode: {
114b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".bc");
115b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
116b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
117e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Nothing:
118b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    default: {
1196e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "Invalid output type!");
120b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
121b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
122b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1231906a00dce8e32fe3bb8a957e333ebbbee0888e3Pirama Arumuga Nainar  return SavedStrings->save(OutputFile.c_str());
124b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
125b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1269ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinestypedef std::list<std::pair<const char*, const char*> > NamePairList;
1279ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1289ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines/*
1299ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * Compile the Inputs.
1309ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines *
1319ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * Returns 0 on success and nonzero on failure.
1329ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines *
1339ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * IOFiles - list of (foo.rs, foo.bc) pairs of input/output files.
1349ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * IOFiles32 - list of input/output pairs for 32-bit compilation.
1359ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * Inputs - input filenames.
1369ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * Opts - options controlling compilation.
1379ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * DiagEngine - Clang diagnostic engine (for creating diagnostics).
1389ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * DiagClient - Slang diagnostic consumer (collects and displays diagnostics).
1399ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * SavedStrings - expanded strings copied from argv source input files.
1409ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines *
1419ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * We populate IOFiles dynamically while working through the list of Inputs.
1429ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * On any 64-bit compilation, we pass back in the 32-bit pairs of files as
1439ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * IOFiles32. This allows the 64-bit compiler to later bundle up both the
1449ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * 32-bit and 64-bit bitcode outputs to be included in the final reflected
1459ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * source code that is emitted.
1469ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines */
1475309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouilletstatic void makeFileList(NamePairList *IOFiles, NamePairList *DepFiles,
1489ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    const llvm::SmallVector<const char*, 16> &Inputs, slang::RSCCOptions &Opts,
149c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet    StringSet *SavedStrings) {
1509ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  std::string PathSuffix = "";
1519ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  // In our mixed 32/64-bit path, we need to suffix our files differently for
1529ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  // both 32-bit and 64-bit versions.
1539ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  if (Opts.mEmit3264) {
1549ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    if (Opts.mBitWidth == 64) {
1559ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      PathSuffix = "bc64";
1569ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    } else {
1579ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      PathSuffix = "bc32";
1589ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    }
1599ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  }
1609ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1619ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  for (int i = 0, e = Inputs.size(); i != e; i++) {
1629ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    const char *InputFile = Inputs[i];
1639ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1649ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    const char *BCOutputFile = DetermineOutputFile(Opts.mBitcodeOutputDir,
1659ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines                                                   PathSuffix, InputFile,
16676837a1d0d86300c09c093b535d5fc4b638f6805Yang Ni                                                   Opts.mOutputType,
167c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet                                                   SavedStrings);
1689ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    const char *OutputFile = BCOutputFile;
1699ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1709ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    if (Opts.mEmitDependency) {
1719ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      // The dependency file is always emitted without a PathSuffix.
1729ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      // Collisions between 32-bit and 64-bit files don't make a difference,
1739ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      // because they share the same sources/dependencies.
1749ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      const char *DepOutputFile =
1759ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines          DetermineOutputFile(Opts.mDependencyOutputDir, "", InputFile,
176c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet                              slang::Slang::OT_Dependency, SavedStrings);
1779ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      if (Opts.mOutputType == slang::Slang::OT_Dependency) {
1789ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines        OutputFile = DepOutputFile;
1799ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      }
1809ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1815309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      DepFiles->push_back(std::make_pair(BCOutputFile, DepOutputFile));
1829ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    }
1839ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1849ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    IOFiles->push_back(std::make_pair(InputFile, OutputFile));
1859ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  }
1869ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines}
1879ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
188ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define str(s) #s
189ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define wrap_str(s) str(s)
190ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hinesstatic void llvm_rs_cc_VersionPrinter() {
191ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  llvm::raw_ostream &OS = llvm::outs();
192ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "llvm-rs-cc: Renderscript compiler\n"
193ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << "  (http://developer.android.com/guide/topics/renderscript)\n"
194ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << "  based on LLVM (http://llvm.org):\n";
195ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "  Target APIs: " << SLANG_MINIMUM_TARGET_API << " - "
196ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << SLANG_MAXIMUM_TARGET_API;
197ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "\n  Build type: " << wrap_str(TARGET_BUILD_VARIANT);
198ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#ifndef __DISABLE_ASSERTS
199ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << " with assertions";
200ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#endif
201ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << ".\n";
202ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines}
2038f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef wrap_str
2048f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#undef str
205ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines
2065309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouilletstatic void LLVMErrorHandler(void *UserData, const std::string &Message,
2075309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                             bool GenCrashDialog) {
2085309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  clang::DiagnosticsEngine *DiagEngine =
2095309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      static_cast<clang::DiagnosticsEngine *>(UserData);
210b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2115309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  DiagEngine->Report(clang::diag::err_fe_error_backend) << Message;
212b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2135309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // Run the interrupt handlers to make sure any special cleanups get done, in
2145309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // particular that we remove files registered with RemoveFileOnSignal.
2155309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  llvm::sys::RunInterruptHandlers();
216b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2175309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  exit(1);
2185309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet}
219be27482cdeaf08576bc39b72a15d35d13014a636Logan
2205309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouilletint main(int argc, const char **argv) {
2215309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  llvm::llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
2225309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LLVMInitializeARMTargetInfo();
2235309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LLVMInitializeARMTarget();
2245309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LLVMInitializeARMAsmPrinter();
2259207a2e495c8363606861e4f034504ec5c153dabLogan Chien
2265309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  StringSet SavedStrings; // Keeps track of strings to be destroyed at the end.
227b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2285309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // Parse the command line arguments and respond to show help & version
2295309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // commands.
2305309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  llvm::SmallVector<const char *, 16> Inputs;
231c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet  slang::RSCCOptions Opts;
2325309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts =
2335309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      new clang::DiagnosticOptions();
2345309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  if (!slang::ParseArguments(llvm::makeArrayRef(argv, argc), Inputs, Opts,
23598cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainar                             *DiagOpts, SavedStrings.getStringSaver())) {
2365309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    // Exits when there's any error occurred during parsing the arguments
237b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 1;
2388f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines  }
239b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Opts.mShowHelp) {
2407ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines    std::unique_ptr<llvm::opt::OptTable> OptTbl(slang::createRSCCOptTable());
2415309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    const std::string Argv0 = llvm::sys::path::stem(argv[0]);
242b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    OptTbl->PrintHelp(llvm::outs(), Argv0.c_str(),
243b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines                      "Renderscript source compiler");
244b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 0;
245b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
246b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Opts.mShowVersion) {
247ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines    llvm_rs_cc_VersionPrinter();
248b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 0;
249b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
250b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2515309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // Initialize the diagnostic objects
2525309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(
2535309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      new clang::DiagnosticIDs());
2545309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  slang::DiagnosticBuffer DiagsBuffer;
2555309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  clang::DiagnosticsEngine DiagEngine(DiagIDs, &*DiagOpts, &DiagsBuffer, false);
2565309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  clang::ProcessWarningOptions(DiagEngine, *DiagOpts);
2575309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  (void)DiagEngine.setSeverityForGroup(clang::diag::Flavor::WarningOrError,
2585309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                       "implicit-function-declaration",
2595309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                       clang::diag::Severity::Error);
2605309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
2615309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // Report error if no input file
262b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (Inputs.empty()) {
2639207a2e495c8363606861e4f034504ec5c153dabLogan Chien    DiagEngine.Report(clang::diag::err_drv_no_input_files);
2645309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    llvm::errs() << DiagsBuffer.str();
265b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return 1;
266b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
267b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
2685309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  llvm::install_fatal_error_handler(LLVMErrorHandler, &DiagEngine);
2695309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
2705309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // Compile the 32 bit version
2719ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  NamePairList IOFiles32;
2725309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  NamePairList DepFiles32;
2735309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  makeFileList(&IOFiles32, &DepFiles32, Inputs, Opts, &SavedStrings);
274b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
275bfbdd981372bf0694e5be3bffaaeae421d017dccMiao Wang  int CompileFailed = 0;
276bfbdd981372bf0694e5be3bffaaeae421d017dccMiao Wang  // Handle 32-bit case for Java and C++ reflection.
277bfbdd981372bf0694e5be3bffaaeae421d017dccMiao Wang  // For Java, both 32bit and 64bit will be generated.
278bfbdd981372bf0694e5be3bffaaeae421d017dccMiao Wang  // For C++, either 64bit or 32bit will be generated based on the target.
279bfbdd981372bf0694e5be3bffaaeae421d017dccMiao Wang  if (Opts.mEmit3264 || Opts.mBitWidth == 32) {
280bfbdd981372bf0694e5be3bffaaeae421d017dccMiao Wang      std::unique_ptr<slang::Slang> Compiler(
281bfbdd981372bf0694e5be3bffaaeae421d017dccMiao Wang          new slang::Slang(32, &DiagEngine, &DiagsBuffer));
282bfbdd981372bf0694e5be3bffaaeae421d017dccMiao Wang      CompileFailed =
283bfbdd981372bf0694e5be3bffaaeae421d017dccMiao Wang          !Compiler->compile(IOFiles32, IOFiles32, DepFiles32, Opts, *DiagOpts);
284bfbdd981372bf0694e5be3bffaaeae421d017dccMiao Wang  }
285cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
2869ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  // Handle the 64-bit case too!
287bfbdd981372bf0694e5be3bffaaeae421d017dccMiao Wang  bool needEmit64 = Opts.mEmit3264 || Opts.mBitWidth == 64;
288bfbdd981372bf0694e5be3bffaaeae421d017dccMiao Wang  if (needEmit64 && !CompileFailed) {
2899ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    Opts.mBitWidth = 64;
2905309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    NamePairList IOFiles64;
2915309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    NamePairList DepFiles64;
2925309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    makeFileList(&IOFiles64, &DepFiles64, Inputs, Opts, &SavedStrings);
2935309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
2945309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    std::unique_ptr<slang::Slang> Compiler(
2955309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        new slang::Slang(64, &DiagEngine, &DiagsBuffer));
2965309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    CompileFailed =
2975309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        !Compiler->compile(IOFiles64, IOFiles32, DepFiles64, Opts, *DiagOpts);
298cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang  }
299cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang
3005309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  llvm::errs() << DiagsBuffer.str();
3015309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  llvm::remove_fatal_error_handler();
302d7f0ea21058abbdd1edfd3df65762fa3c91cb224Stephen Hines  return CompileFailed;
303b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
304