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"
36c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "llvm/Target/TargetMachine.h"
37e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
389534de12d6a243d8cbee7f3ef99829bab786e89aElliott Hughes#include "os_sep.h"
398b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include "rs_cc_options.h"
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang.h"
416e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
428f4d972ef6c6796ffdde603e456979a7004d1e20Stephen Hines#include "slang_diagnostic_buffer.h"
43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_reflect_utils.h"
44b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
458b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <list>
468b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <set>
478b5c5c6566078d49c4dcd8d8c7a6364c33c09037Stephen Hines#include <string>
48b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
49c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouilletnamespace {
508f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainarclass StringSet {
51c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouilletpublic:
528f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  const char *save(const char *Str) {
538f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar    return Strings.save(Str);
54c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet  }
55c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet
568f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  StringSet() : Strings(A), A() {}
578f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar
588f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  llvm::StringSaver & getStringSaver() { return Strings; }
591906a00dce8e32fe3bb8a957e333ebbbee0888e3Pirama Arumuga Nainar
60c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouilletprivate:
618f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  llvm::StringSaver Strings;
621906a00dce8e32fe3bb8a957e333ebbbee0888e3Pirama Arumuga Nainar  llvm::BumpPtrAllocator A;
63c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet};
64b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
65b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
66b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaostatic const char *DetermineOutputFile(const std::string &OutputDir,
679ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines                                       const std::string &PathSuffix,
68b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                       const char *InputFile,
69e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                                       slang::Slang::OutputType OutputType,
70c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet                                       StringSet *SavedStrings) {
71e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Nothing)
72b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return "/dev/null";
73b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
74b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  std::string OutputFile(OutputDir);
75b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
767f5704efe0c59d5599f1ac7056976225dbfab946Stephen Hines  // Append '/' to Opts.mBitcodeOutputDir if not presents
77b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (!OutputFile.empty() &&
788d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael      (OutputFile[OutputFile.size() - 1]) != OS_PATH_SEPARATOR)
798d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael    OutputFile.append(1, OS_PATH_SEPARATOR);
80b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
819ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  if (!PathSuffix.empty()) {
829ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    OutputFile.append(PathSuffix);
839ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    OutputFile.append(1, OS_PATH_SEPARATOR);
849ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  }
859ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
86e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  if (OutputType == slang::Slang::OT_Dependency) {
87b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // The build system wants the .d file name stem to be exactly the same as
88b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // the source .rs file, instead of the .bc file.
89e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(slang::RSSlangReflectUtils::GetFileNameStem(InputFile));
90e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  } else {
91e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    OutputFile.append(
92e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        slang::RSSlangReflectUtils::BCFileNameFromRSFileName(InputFile));
93e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  }
94b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
95e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  switch (OutputType) {
96e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Dependency: {
97b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".d");
98b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
99b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
100e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Assembly: {
101b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".S");
102b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
103b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
104e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_LLVMAssembly: {
105b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".ll");
106b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
107b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
108e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Object: {
109b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".o");
110b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
111b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
112e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Bitcode: {
113b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      OutputFile.append(".bc");
114b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      break;
115b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
116e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    case slang::Slang::OT_Nothing:
117b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    default: {
1186e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "Invalid output type!");
119b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    }
120b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  }
121b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1221906a00dce8e32fe3bb8a957e333ebbbee0888e3Pirama Arumuga Nainar  return SavedStrings->save(OutputFile.c_str());
123b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao}
124b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1259ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinestypedef std::list<std::pair<const char*, const char*> > NamePairList;
1269ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1279ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines/*
1289ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * Compile the Inputs.
1299ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines *
1309ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * Returns 0 on success and nonzero on failure.
1319ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines *
1329ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * IOFiles - list of (foo.rs, foo.bc) pairs of input/output files.
1339ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * IOFiles32 - list of input/output pairs for 32-bit compilation.
1349ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * Inputs - input filenames.
1359ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * Opts - options controlling compilation.
1369ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * DiagEngine - Clang diagnostic engine (for creating diagnostics).
1379ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * DiagClient - Slang diagnostic consumer (collects and displays diagnostics).
1389ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * SavedStrings - expanded strings copied from argv source input files.
1399ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines *
1409ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * We populate IOFiles dynamically while working through the list of Inputs.
1419ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * On any 64-bit compilation, we pass back in the 32-bit pairs of files as
1429ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * IOFiles32. This allows the 64-bit compiler to later bundle up both the
1439ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * 32-bit and 64-bit bitcode outputs to be included in the final reflected
1449ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines * source code that is emitted.
1459ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines */
1465309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouilletstatic void makeFileList(NamePairList *IOFiles, NamePairList *DepFiles,
1479ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    const llvm::SmallVector<const char*, 16> &Inputs, slang::RSCCOptions &Opts,
148c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet    StringSet *SavedStrings) {
1499ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  std::string PathSuffix = "";
1509ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  // In our mixed 32/64-bit path, we need to suffix our files differently for
1519ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  // both 32-bit and 64-bit versions.
1529ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  if (Opts.mEmit3264) {
1539ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    if (Opts.mBitWidth == 64) {
1549ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      PathSuffix = "bc64";
1559ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    } else {
1569ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      PathSuffix = "bc32";
1579ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    }
1589ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  }
1599ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1609ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  for (int i = 0, e = Inputs.size(); i != e; i++) {
1619ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    const char *InputFile = Inputs[i];
1629ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1639ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    const char *BCOutputFile = DetermineOutputFile(Opts.mBitcodeOutputDir,
1649ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines                                                   PathSuffix, InputFile,
16576837a1d0d86300c09c093b535d5fc4b638f6805Yang Ni                                                   Opts.mOutputType,
166c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet                                                   SavedStrings);
1679ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    const char *OutputFile = BCOutputFile;
1689ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1699ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    if (Opts.mEmitDependency) {
1709ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      // The dependency file is always emitted without a PathSuffix.
1719ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      // Collisions between 32-bit and 64-bit files don't make a difference,
1729ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      // because they share the same sources/dependencies.
1739ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      const char *DepOutputFile =
1749ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines          DetermineOutputFile(Opts.mDependencyOutputDir, "", InputFile,
175c247363f17b7b2c80a787941069d6e25fe5c0770Jean-Luc Brouillet                              slang::Slang::OT_Dependency, SavedStrings);
1769ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      if (Opts.mOutputType == slang::Slang::OT_Dependency) {
1779ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines        OutputFile = DepOutputFile;
1789ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      }
1799ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1805309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      DepFiles->push_back(std::make_pair(BCOutputFile, DepOutputFile));
1819ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    }
1829ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1839ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    IOFiles->push_back(std::make_pair(InputFile, OutputFile));
1849ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  }
1859ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines}
1869ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
187ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define str(s) #s
188ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines#define wrap_str(s) str(s)
189ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hinesstatic void llvm_rs_cc_VersionPrinter() {
190ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  llvm::raw_ostream &OS = llvm::outs();
191ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "llvm-rs-cc: Renderscript compiler\n"
192ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << "  (http://developer.android.com/guide/topics/renderscript)\n"
193ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines     << "  based on LLVM (http://llvm.org):\n";
194ba7c6dc08e1ab8486ccaf842e8ae87dc5c99d8cfStephen Hines  OS << "  Built " << __DATE__ << " (" << __TIME__ ").\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,
2358f093e05e28046b6fc74175b66a06152f72e0c66Pirama 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