slang.cpp revision 3f45a25c23fa0f2cca4070f4d8713dc1a83f5ff7
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/*
2c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Copyright 2010, 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
176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang.h"
18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
196315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <stdlib.h>
20462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include <cstring>
228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include <list>
238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include <sstream>
24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <string>
258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include <utility>
26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <vector>
278c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang
28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/ASTConsumer.h"
29e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/ASTContext.h"
30462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
31be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "clang/Basic/DiagnosticIDs.h"
3223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "clang/Basic/DiagnosticOptions.h"
33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/FileManager.h"
34df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao#include "clang/Basic/FileSystemOptions.h"
358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "clang/Basic/SourceLocation.h"
363a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/SourceManager.h"
373a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Basic/TargetInfo.h"
386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Basic/TargetOptions.h"
39462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
40cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/DependencyOutputOptions.h"
41cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/FrontendDiagnostic.h"
420e4ee65a2ba6b32fcd16c5d4a57fc7542d4032b4Stephen Hines#include "clang/Frontend/FrontendOptions.h"
43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Frontend/TextDiagnosticPrinter.h"
44cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/Utils.h"
45cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
463a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/Preprocessor.h"
4723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "clang/Lex/PreprocessorOptions.h"
483a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/HeaderSearch.h"
4923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "clang/Lex/HeaderSearchOptions.h"
503a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
516315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Parse/ParseAST.h"
526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "clang/Sema/SemaDiagnostic.h"
548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
55be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/ADT/IntrusiveRefCntPtr.h"
56be27482cdeaf08576bc39b72a15d35d13014a636Logan
57e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Bitcode/ReaderWriter.h"
589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
5908df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang// More force linking
60ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murray#include "llvm/Linker/Linker.h"
6108df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang
62e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines// Force linking all passes/vmcore stuffs to libslang.so
630da7f6c8201b27938d3b9f048d71fd784cd1df9aStephen Hines#include "llvm/LinkAllIR.h"
64e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/LinkAllPasses.h"
65e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
66e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/raw_ostream.h"
67e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/MemoryBuffer.h"
68e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/ErrorHandling.h"
69e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/ManagedStatic.h"
70be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/Support/Path.h"
719207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Support/TargetSelect.h"
729207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Support/ToolOutputFile.h"
73e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "os_sep.h"
758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "rs_cc_options.h"
766e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
77e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_backend.h"
78b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_context.h"
808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_type.h"
818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_reflection.h"
838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_reflection_cpp.h"
848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8608df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Changnamespace {
8708df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang
889ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesstatic const char *kRSTriple32 = "armv7-none-linux-gnueabi";
899ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesstatic const char *kRSTriple64 = "aarch64-none-linux-gnueabi";
909ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
91e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace
92e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
93e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#define FS_SUFFIX  "fs"
978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#define RS_HEADER_SUFFIX  "rsh"
998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
1008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet/* RS_HEADER_ENTRY(name) */
1018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#define ENUM_RS_HEADER()  \
1028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_allocation_data) \
1038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_atomic) \
1048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_convert) \
1058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_core) \
1068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_debug) \
1078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_for_each) \
1088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_graphics) \
1098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_graphics_types) \
1108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_io) \
1118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_math) \
1128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_matrix) \
1138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_object_info) \
1148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_object_types) \
1158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_quaternion) \
1168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_time) \
1178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_value_types) \
1188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_vector_math) \
1198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
1208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// The named of metadata node that pragma resides (should be synced with
1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// bcc.cpp)
123f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liaoconst llvm::StringRef Slang::PragmaMetadataName = "#pragma";
124462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1259207a2e495c8363606861e4f034504ec5c153dabLogan Chienstatic inline llvm::tool_output_file *
1269207a2e495c8363606861e4f034504ec5c153dabLogan ChienOpenOutputFile(const char *OutputFile,
127a1f95ee8df425089100148a42954cf61dc285015Stephen Hines               llvm::sys::fs::OpenFlags Flags,
1283eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines               std::error_code &EC,
129e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines               clang::DiagnosticsEngine *DiagEngine) {
1303eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  slangAssert((OutputFile != nullptr) &&
1315abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes              (DiagEngine != nullptr) && "Invalid parameter!");
132e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
1333eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  EC = llvm::sys::fs::create_directories(
1343eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines      llvm::sys::path::parent_path(OutputFile));
1353eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  if (!EC) {
136e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    llvm::tool_output_file *F =
1373eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines          new llvm::tool_output_file(OutputFile, EC, Flags);
1385abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    if (F != nullptr)
139e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang      return F;
140e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  }
141e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
142e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Report error here.
1439207a2e495c8363606861e4f034504ec5c153dabLogan Chien  DiagEngine->Report(clang::diag::err_fe_error_opening)
1443eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines    << OutputFile << EC.message();
145e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
1465abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  return nullptr;
147e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang}
148e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
1499ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesvoid Slang::createTarget(uint32_t BitWidth) {
1509ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  std::vector<std::string> features;
151462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1529ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  if (BitWidth == 64) {
1539ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    mTargetOpts->Triple = kRSTriple64;
1549ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  } else {
1559ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    mTargetOpts->Triple = kRSTriple32;
1569ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    // Treat long as a 64-bit type for our 32-bit RS code.
1579ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    features.push_back("+long64");
1589ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    mTargetOpts->FeaturesAsWritten = features;
1599ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  }
160b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1619207a2e495c8363606861e4f034504ec5c153dabLogan Chien  mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagEngine,
1627ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines                                                    mTargetOpts));
163462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
164462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1653a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createFileManager() {
166df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao  mFileSysOpt.reset(new clang::FileSystemOptions());
167be27482cdeaf08576bc39b72a15d35d13014a636Logan  mFileMgr.reset(new clang::FileManager(*mFileSysOpt));
1683a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1693a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1703a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createSourceManager() {
1719207a2e495c8363606861e4f034504ec5c153dabLogan Chien  mSourceMgr.reset(new clang::SourceManager(*mDiagEngine, *mFileMgr));
1723a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1733a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
17468e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liaovoid Slang::createPreprocessor() {
1759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Default only search header file in current dir
17623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> HSOpts =
17723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines      new clang::HeaderSearchOptions();
17823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  clang::HeaderSearch *HeaderInfo = new clang::HeaderSearch(HSOpts,
179eeb251e8db802b836af7461d0f6eb1252c527ab8Stephen Hines                                                            *mSourceMgr,
1800444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines                                                            *mDiagEngine,
1810444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines                                                            LangOpts,
1820444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines                                                            mTarget.get());
1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
18423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  llvm::IntrusiveRefCntPtr<clang::PreprocessorOptions> PPOpts =
18523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines      new clang::PreprocessorOptions();
18623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  mPP.reset(new clang::Preprocessor(PPOpts,
18723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines                                    *mDiagEngine,
1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    LangOpts,
1899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *mSourceMgr,
1909207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                    *HeaderInfo,
1919207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                    *this,
1925abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes                                    nullptr,
1933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                    /* OwnsHeaderSearch = */true));
1943fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines  // Initialize the preprocessor
19575d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines  mPP->Initialize(getTargetInfo());
1960e4ee65a2ba6b32fcd16c5d4a57fc7542d4032b4Stephen Hines  clang::FrontendOptions FEOpts;
1977ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines  clang::InitializePreprocessor(*mPP, *PPOpts, FEOpts);
1980e4ee65a2ba6b32fcd16c5d4a57fc7542d4032b4Stephen Hines
19968e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  mPragmas.clear();
2003fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines  mPP->AddPragmaHandler(new PragmaRecorder(&mPragmas));
20168e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
2029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::vector<clang::DirectoryLookup> SearchList;
2033a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
2049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (const clang::DirectoryEntry *DE =
205be27482cdeaf08576bc39b72a15d35d13014a636Logan            mFileMgr->getDirectory(mIncludePaths[i])) {
2069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      SearchList.push_back(clang::DirectoryLookup(DE,
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  clang::SrcMgr::C_System,
2089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  false));
2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
2109089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  }
2119089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
2129207a2e495c8363606861e4f034504ec5c153dabLogan Chien  HeaderInfo->SetSearchPaths(SearchList,
2139207a2e495c8363606861e4f034504ec5c153dabLogan Chien                             /* angledDirIdx = */1,
2149207a2e495c8363606861e4f034504ec5c153dabLogan Chien                             /* systemDixIdx = */1,
2159207a2e495c8363606861e4f034504ec5c153dabLogan Chien                             /* noCurDirSearch = */false);
2169089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
2173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initPreprocessor();
21868e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao}
21968e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
2203a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createASTContext() {
2218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mASTContext.reset(
2228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      new clang::ASTContext(LangOpts, *mSourceMgr, mPP->getIdentifierTable(),
2238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                            mPP->getSelectorTable(), mPP->getBuiltinInfo()));
22475d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines  mASTContext->InitBuiltinTypes(getTargetInfo());
2253a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initASTContext();
2263a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
2273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
2289207a2e495c8363606861e4f034504ec5c153dabLogan Chienclang::ASTConsumer *
2298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc BrouilletSlang::createBackend(const clang::CodeGenOptions &CodeGenOpts,
2305309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                     llvm::raw_ostream *OS, OutputType OT) {
2318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return new Backend(mRSContext, &getDiagnostics(), CodeGenOpts,
2328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                     getTargetOptions(), &mPragmas, OS, OT, getSourceManager(),
2338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                     mAllowRSPrefix, mIsFilterscript);
2343a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
2353a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
2365309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc BrouilletSlang::Slang(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine,
2375309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet             DiagnosticBuffer *DiagClient)
2385309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    : mDiagEngine(DiagEngine), mDiagClient(DiagClient),
2398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mTargetOpts(new clang::TargetOptions()), mOT(OT_Default),
2408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSContext(nullptr), mAllowRSPrefix(false), mTargetAPI(0),
2418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mVerbose(false), mIsFilterscript(false) {
2425309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // Please refer to include/clang/Basic/LangOptions.h to setup
2435309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // the options.
2445309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.RTTI = 0;  // Turn off the RTTI information support
2455309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.LineComment = 1;
2465309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.C99 = 1;
2475309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.Renderscript = 1;
2485309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.LaxVectorConversions = 0;  // Do not bitcast vectors!
2495309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.CharIsSigned = 1;  // Signed char is our default.
2505309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
2515309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  CodeGenOpts.OptimizationLevel = 3;
2525309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
2535309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  createTarget(BitWidth);
2545309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  createFileManager();
2555309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  createSourceManager();
256641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang}
257641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang
2588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc BrouilletSlang::~Slang() {
2598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  delete mRSContext;
2608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (ReflectedDefinitionListTy::iterator I = ReflectedDefinitions.begin(),
2618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                           E = ReflectedDefinitions.end();
2628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E; I++) {
2638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    delete I->getValue().first;
2648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
2658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
2668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
26723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hinesclang::ModuleLoadResult Slang::loadModule(
26823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    clang::SourceLocation ImportLoc,
26923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    clang::ModuleIdPath Path,
27023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    clang::Module::NameVisibilityKind Visibility,
27123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    bool IsInclusionDirective) {
2729207a2e495c8363606861e4f034504ec5c153dabLogan Chien  slangAssert(0 && "Not implemented");
27323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  return clang::ModuleLoadResult();
274462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
275462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2763a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile) {
2773a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mInputFileName = InputFile.str();
278462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->clearIDTables();
280462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
281be27482cdeaf08576bc39b72a15d35d13014a636Logan  const clang::FileEntry *File = mFileMgr->getFile(InputFile);
28275d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines  if (File) {
28375d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines    mSourceMgr->setMainFileID(mSourceMgr->createFileID(File,
28475d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines        clang::SourceLocation(), clang::SrcMgr::C_User));
28575d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines  }
286462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mSourceMgr->getMainFileID().isInvalid()) {
2889207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mDiagEngine->Report(clang::diag::err_fe_error_reading) << InputFile;
2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
291462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
293462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
294462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2953a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setOutput(const char *OutputFile) {
2963eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  std::error_code EC;
2975abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  llvm::tool_output_file *OS = nullptr;
298462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2993a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  switch (mOT) {
300cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    case OT_Dependency:
3013a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Assembly:
3023a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_LLVMAssembly: {
3033eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines      OS = OpenOutputFile(OutputFile, llvm::sys::fs::F_Text, EC, mDiagEngine);
3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
305462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3063a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Nothing: {
3079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
308462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Object:
310cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    case OT_Bitcode: {
3113eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines      OS = OpenOutputFile(OutputFile, llvm::sys::fs::F_None, EC, mDiagEngine);
3129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3148c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    default: {
315cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines      llvm_unreachable("Unknown compiler output type");
3168c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    }
3179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
318462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3193eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  if (EC)
3209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
321e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
322e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mOS.reset(OS);
3239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3243a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mOutputFileName = OutputFile;
325462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
327462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
328462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3290b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hinesbool Slang::setDepOutput(const char *OutputFile) {
3303eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  std::error_code EC;
3318c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang
332a1f95ee8df425089100148a42954cf61dc285015Stephen Hines  mDOS.reset(
3333eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines      OpenOutputFile(OutputFile, llvm::sys::fs::F_Text, EC, mDiagEngine));
3343eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  if (EC || (mDOS.get() == nullptr))
3350b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines    return false;
3360b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
3370b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  mDepOutputFileName = OutputFile;
3380b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
3390b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  return true;
3400b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines}
3410b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
342cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hinesint Slang::generateDepFile() {
3439207a2e495c8363606861e4f034504ec5c153dabLogan Chien  if (mDiagEngine->hasErrorOccurred())
344be27482cdeaf08576bc39b72a15d35d13014a636Logan    return 1;
3455abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (mDOS.get() == nullptr)
346f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines    return 1;
347cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
348e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Initialize options for generating dependency file
349cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  clang::DependencyOutputOptions DepOpts;
350cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  DepOpts.IncludeSystemHeaders = 1;
3510b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  DepOpts.OutputFile = mDepOutputFileName;
352b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  DepOpts.Targets = mAdditionalDepTargets;
353cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  DepOpts.Targets.push_back(mDepTargetBCFileName);
3544cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  for (std::vector<std::string>::const_iterator
3554cc67fce91f43215d61b2695746eab102a3db516Stephen Hines           I = mGeneratedFileNames.begin(), E = mGeneratedFileNames.end();
3564cc67fce91f43215d61b2695746eab102a3db516Stephen Hines       I != E;
3574cc67fce91f43215d61b2695746eab102a3db516Stephen Hines       I++) {
3584cc67fce91f43215d61b2695746eab102a3db516Stephen Hines    DepOpts.Targets.push_back(*I);
3594cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  }
3604cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  mGeneratedFileNames.clear();
361cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
362e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Per-compilation needed initialization
363cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  createPreprocessor();
364ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murray  clang::DependencyFileGenerator::CreateAndAttachToPreprocessor(*mPP.get(), DepOpts);
365cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
366e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Inform the diagnostic client we are processing a source file
367cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
368cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
369e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Go through the source file (no operations necessary)
370cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  clang::Token Tok;
371cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP->EnterMainSourceFile();
372cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  do {
373cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    mPP->Lex(Tok);
374cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  } while (Tok.isNot(clang::tok::eof));
375cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
376cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP->EndSourceFile();
377cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
378e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Declare success if no error
3799207a2e495c8363606861e4f034504ec5c153dabLogan Chien  if (!mDiagEngine->hasErrorOccurred())
380e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    mDOS->keep();
381e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
382e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Clean up after compilation
383cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP.reset();
384e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mDOS.reset();
385cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
3869207a2e495c8363606861e4f034504ec5c153dabLogan Chien  return mDiagEngine->hasErrorOccurred() ? 1 : 0;
387cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines}
388cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
389462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaoint Slang::compile() {
3909207a2e495c8363606861e4f034504ec5c153dabLogan Chien  if (mDiagEngine->hasErrorOccurred())
391be27482cdeaf08576bc39b72a15d35d13014a636Logan    return 1;
3925abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (mOS.get() == nullptr)
393f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines    return 1;
394462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Here is per-compilation needed initialization
3969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createPreprocessor();
3979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createASTContext();
3983a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
399df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao  mBackend.reset(createBackend(CodeGenOpts, &mOS->os(), mOT));
400462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Inform the diagnostic client we are processing a source file
4029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
403462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // The core of the slang compiler
4059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ParseAST(*mPP, mBackend.get(), *mASTContext);
406462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
407e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Inform the diagnostic client we are done with previous source file
408e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mDiagClient->EndSourceFile();
409e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
410e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Declare success if no error
4119207a2e495c8363606861e4f034504ec5c153dabLogan Chien  if (!mDiagEngine->hasErrorOccurred())
412e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    mOS->keep();
413e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
4143a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  // The compilation ended, clear
4159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mBackend.reset();
416e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mOS.reset();
417462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4189207a2e495c8363606861e4f034504ec5c153dabLogan Chien  return mDiagEngine->hasErrorOccurred() ? 1 : 0;
419462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
420462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
421c460b37ffb50819a32c2a8967754b6f784b28263mkopecvoid Slang::setDebugMetadataEmission(bool EmitDebug) {
42243730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao  if (EmitDebug)
42323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    CodeGenOpts.setDebugInfo(clang::CodeGenOptions::FullDebugInfo);
42443730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao  else
42523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    CodeGenOpts.setDebugInfo(clang::CodeGenOptions::NoDebugInfo);
426c460b37ffb50819a32c2a8967754b6f784b28263mkopec}
427c460b37ffb50819a32c2a8967754b6f784b28263mkopec
428c460b37ffb50819a32c2a8967754b6f784b28263mkopecvoid Slang::setOptimizationLevel(llvm::CodeGenOpt::Level OptimizationLevel) {
429c460b37ffb50819a32c2a8967754b6f784b28263mkopec  CodeGenOpts.OptimizationLevel = OptimizationLevel;
430c460b37ffb50819a32c2a8967754b6f784b28263mkopec}
431c460b37ffb50819a32c2a8967754b6f784b28263mkopec
4328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::isFilterscript(const char *Filename) {
4338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  const char *c = strrchr(Filename, '.');
4348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (c && !strncmp(FS_SUFFIX, c + 1, strlen(FS_SUFFIX) + 1)) {
4358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return true;
4368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  } else {
4378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
4388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::generateJavaBitcodeAccessor(const std::string &OutputPathBase,
4428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                          const std::string &PackageName,
4438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                          const std::string *LicenseNote) {
4448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RSSlangReflectUtils::BitCodeAccessorContext BCAccessorContext;
4458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.rsFileName = getInputFileName().c_str();
4475309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  BCAccessorContext.bc32FileName = mOutput32FileName.c_str();
4485309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  BCAccessorContext.bc64FileName = mOutputFileName.c_str();
4498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.reflectPath = OutputPathBase.c_str();
4508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.packageName = PackageName.c_str();
4518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.licenseNote = LicenseNote;
4528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.bcStorage = BCST_JAVA_CODE;   // Must be BCST_JAVA_CODE
4538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.verbose = false;
4548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return RSSlangReflectUtils::GenerateJavaBitCodeAccessor(BCAccessorContext);
4568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::checkODR(const char *CurInputFile) {
4598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::ExportableList::iterator I = mRSContext->exportable_begin(),
4608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mRSContext->exportable_end();
4618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
4628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
4638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    RSExportable *RSE = *I;
4648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (RSE->getKind() != RSExportable::EX_TYPE)
4658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      continue;
4668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    RSExportType *ET = static_cast<RSExportType *>(RSE);
4688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (ET->getClass() != RSExportType::ExportClassRecord)
4698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      continue;
4708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    RSExportRecordType *ERT = static_cast<RSExportRecordType *>(ET);
4728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Artificial record types (create by us not by user in the source) always
4748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // conforms the ODR.
4758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (ERT->isArtificial())
4768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      continue;
4778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Key to lookup ERT in ReflectedDefinitions
4798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    llvm::StringRef RDKey(ERT->getName());
4808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ReflectedDefinitionListTy::const_iterator RD =
4818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ReflectedDefinitions.find(RDKey);
4828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (RD != ReflectedDefinitions.end()) {
4848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const RSExportRecordType *Reflected = RD->getValue().first;
4858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // There's a record (struct) with the same name reflected before. Enforce
4868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // ODR checking - the Reflected must hold *exactly* the same "definition"
4878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // as the one defined previously. We say two record types A and B have the
4888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // same definition iff:
4898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //
4908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  struct A {              struct B {
4918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //    Type(a1) a1,            Type(b1) b1,
4928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //    Type(a2) a2,            Type(b1) b2,
4938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //    ...                     ...
4948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //    Type(aN) aN             Type(b3) b3,
4958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  };                      }
4968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Cond. #1. They have same number of fields, i.e., N = M;
4978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Cond. #2. for (i := 1 to N)
4988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //              Type(ai) = Type(bi) must hold;
4998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Cond. #3. for (i := 1 to N)
5008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //              Name(ai) = Name(bi) must hold;
5018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //
5028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // where,
5038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Type(F) = the type of field F and
5048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Name(F) = the field name.
5058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      bool PassODR = false;
5078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Cond. #1 and Cond. #2
5088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (Reflected->equals(ERT)) {
5098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // Cond #3.
5108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        RSExportRecordType::const_field_iterator AI = Reflected->fields_begin(),
5118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                 BI = ERT->fields_begin();
5128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        for (unsigned i = 0, e = Reflected->getFields().size(); i != e; i++) {
5148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if ((*AI)->getName() != (*BI)->getName())
5158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            break;
5168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          AI++;
5178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          BI++;
5188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
5198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        PassODR = (AI == (Reflected->fields_end()));
5208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!PassODR) {
5235309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        unsigned DiagID = mDiagEngine->getCustomDiagID(
5245309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet            clang::DiagnosticsEngine::Error,
5255309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet            "type '%0' in different translation unit (%1 v.s. %2) "
5265309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet            "has incompatible type definition");
5275309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        getDiagnostics().Report(DiagID) << Reflected->getName()
5285309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                        << getInputFileName()
5295309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                        << RD->getValue().second;
5308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        return false;
5318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    } else {
5338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::StringMapEntry<ReflectedDefinitionTy> *ME =
5348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::StringMapEntry<ReflectedDefinitionTy>::Create(RDKey);
5358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ME->setValue(std::make_pair(ERT, CurInputFile));
5368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5373f45a25c23fa0f2cca4070f4d8713dc1a83f5ff7Matt Wala      if (!ReflectedDefinitions.insert(ME)) {
5383f45a25c23fa0f2cca4070f4d8713dc1a83f5ff7Matt Wala        slangAssert(false && "Type shouldn't be in map yet!");
5393f45a25c23fa0f2cca4070f4d8713dc1a83f5ff7Matt Wala      }
5408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Take the ownership of ERT such that it won't be freed in ~RSContext().
5428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ERT->keep();
5438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return true;
5468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Slang::initPreprocessor() {
5498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::Preprocessor &PP = getPreprocessor();
5508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  std::stringstream RSH;
5528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RSH << PP.getPredefines();
5538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RSH << "#define RS_VERSION " << mTargetAPI << "\n";
5548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RSH << "#include \"rs_core." RS_HEADER_SUFFIX "\"\n";
5558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  PP.setPredefines(RSH.str());
5568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Slang::initASTContext() {
5598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mRSContext = new RSContext(getPreprocessor(),
5608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             getASTContext(),
5618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             getTargetInfo(),
5628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             &mPragmas,
5638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             mTargetAPI,
5648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             mVerbose);
5658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::IsRSHeaderFile(const char *File) {
5688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#define RS_HEADER_ENTRY(name)  \
5698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (::strcmp(File, #name "." RS_HEADER_SUFFIX) == 0)  \
5708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return true;
5718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc BrouilletENUM_RS_HEADER()
5728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#undef RS_HEADER_ENTRY
5738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return false;
5748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::IsLocInRSHeaderFile(const clang::SourceLocation &Loc,
5778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                  const clang::SourceManager &SourceMgr) {
5788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::FullSourceLoc FSL(Loc, SourceMgr);
5798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::PresumedLoc PLoc = SourceMgr.getPresumedLoc(FSL);
5808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  const char *Filename = PLoc.getFilename();
5828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!Filename) {
5838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
5848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  } else {
5858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return IsRSHeaderFile(llvm::sys::path::filename(Filename).data());
5868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::compile(
5908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const std::list<std::pair<const char*, const char*> > &IOFiles64,
5918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const std::list<std::pair<const char*, const char*> > &IOFiles32,
5928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const std::list<std::pair<const char*, const char*> > &DepFiles,
5935309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    const RSCCOptions &Opts,
5945309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    clang::DiagnosticOptions &DiagOpts) {
5958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (IOFiles32.empty())
5968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return true;
5978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (Opts.mEmitDependency && (DepFiles.size() != IOFiles32.size())) {
5995309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    unsigned DiagID = mDiagEngine->getCustomDiagID(
6005309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        clang::DiagnosticsEngine::Error,
6015309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        "invalid parameter for output dependencies files.");
6025309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    getDiagnostics().Report(DiagID);
6038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
6048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (Opts.mEmit3264 && (IOFiles64.size() != IOFiles32.size())) {
6078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slangAssert(false && "Should have equal number of 32/64-bit files");
6088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
6098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  std::string RealPackageName;
6128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  const char *InputFile, *Output64File, *Output32File, *BCOutputFile,
6148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet             *DepOutputFile;
6158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  setIncludePaths(Opts.mIncludePaths);
6178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  setOutputType(Opts.mOutputType);
6188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (Opts.mEmitDependency) {
6198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    setAdditionalDepTargets(Opts.mAdditionalDepTargets);
6208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  setDebugMetadataEmission(Opts.mDebugEmission);
6238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  setOptimizationLevel(Opts.mOptimizationLevel);
6258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mAllowRSPrefix = Opts.mAllowRSPrefix;
6278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mTargetAPI = Opts.mTargetAPI;
6298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mTargetAPI != SLANG_DEVELOPMENT_TARGET_API &&
6308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      (mTargetAPI < SLANG_MINIMUM_TARGET_API ||
6318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       mTargetAPI > SLANG_MAXIMUM_TARGET_API)) {
6325309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    unsigned DiagID = mDiagEngine->getCustomDiagID(
6335309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        clang::DiagnosticsEngine::Error,
6345309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        "target API level '%0' is out of range ('%1' - '%2')");
6355309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    getDiagnostics().Report(DiagID) << mTargetAPI << SLANG_MINIMUM_TARGET_API
6365309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                    << SLANG_MAXIMUM_TARGET_API;
6378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
6388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
640e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar  if (mTargetAPI >= SLANG_23_TARGET_API) {
641e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar    LangOpts.NativeHalfType = 1;
642e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar    LangOpts.HalfArgsAndReturns = 1;
643e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar  }
644e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar
6458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mVerbose = Opts.mVerbose;
6468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Skip generation of warnings a second time if we are doing more than just
6488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // a single pass over the input file.
6498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  bool SuppressAllWarnings = (Opts.mOutputType != Slang::OT_Dependency);
6508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6515309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  std::list<std::pair<const char*, const char*> >::const_iterator
6525309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      IOFile64Iter = IOFiles64.begin(),
6535309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      IOFile32Iter = IOFiles32.begin(),
6545309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      DepFileIter = DepFiles.begin();
6558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (unsigned i = 0, e = IOFiles32.size(); i != e; i++) {
6578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    InputFile = IOFile64Iter->first;
6588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    Output64File = IOFile64Iter->second;
6598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    Output32File = IOFile32Iter->second;
6608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!setInputSource(InputFile))
6628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      return false;
6638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!setOutput(Output64File))
6658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      return false;
6668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6675309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    // For use with 64-bit compilation/reflection. This only sets the filename of
6685309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    // the 32-bit bitcode file, and doesn't actually verify it already exists.
6695309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    mOutput32FileName = Output32File;
6708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mIsFilterscript = isFilterscript(InputFile);
6728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (Slang::compile() > 0)
6748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      return false;
6758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!Opts.mJavaReflectionPackageName.empty()) {
6778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSContext->setReflectJavaPackageName(Opts.mJavaReflectionPackageName);
6788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
6798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const std::string &RealPackageName =
6808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mRSContext->getReflectJavaPackageName();
6818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    bool doReflection = true;
6838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (Opts.mEmit3264 && (Opts.mBitWidth == 32)) {
6848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Skip reflection on the 32-bit path if we are going to emit it on the
6858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // 64-bit path.
6868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      doReflection = false;
6878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
6888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (Opts.mOutputType != Slang::OT_Dependency && doReflection) {
6898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (Opts.mBitcodeStorage == BCST_CPP_CODE) {
6918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const std::string &outputFileName = (Opts.mBitWidth == 64) ?
6925309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                            mOutputFileName : mOutput32FileName;
6938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        RSReflectionCpp R(mRSContext, Opts.mJavaReflectionPathBase,
6948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                          getInputFileName(), outputFileName);
6958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!R.reflect()) {
6968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            return false;
6978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      } else {
6998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!Opts.mRSPackageName.empty()) {
7008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          mRSContext->setRSPackageName(Opts.mRSPackageName);
7018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
703ff5abc6892aedb25215689bd679eb7cc1588a8e3Jean-Luc Brouillet        std::vector<std::string> generatedFileNames;
704ff5abc6892aedb25215689bd679eb7cc1588a8e3Jean-Luc Brouillet        RSReflectionJava R(mRSContext, &generatedFileNames,
7058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                           Opts.mJavaReflectionPathBase, getInputFileName(),
7065309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                           mOutputFileName,
7078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                           Opts.mBitcodeStorage == BCST_JAVA_CODE);
7088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!R.reflect()) {
7098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // TODO Is this needed or will the error message have been printed
7108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // already? and why not for the C++ case?
7118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          fprintf(stderr, "RSContext::reflectToJava : failed to do reflection "
7128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                          "(%s)\n",
7138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  R.getLastError());
7148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          return false;
7158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        for (std::vector<std::string>::const_iterator
718ff5abc6892aedb25215689bd679eb7cc1588a8e3Jean-Luc Brouillet                 I = generatedFileNames.begin(), E = generatedFileNames.end();
7198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet             I != E;
7208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet             I++) {
7218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          std::string ReflectedName = RSSlangReflectUtils::ComputePackagedPath(
7228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              Opts.mJavaReflectionPathBase.c_str(),
7238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              (RealPackageName + OS_PATH_SEPARATOR_STR + *I).c_str());
7248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          appendGeneratedFileName(ReflectedName + ".java");
7258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if ((Opts.mOutputType == Slang::OT_Bitcode) &&
7288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            (Opts.mBitcodeStorage == BCST_JAVA_CODE) &&
7298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            !generateJavaBitcodeAccessor(Opts.mJavaReflectionPathBase,
7308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                         RealPackageName.c_str(),
7318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                         mRSContext->getLicenseNote())) {
7328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          return false;
7338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (Opts.mEmitDependency) {
7388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      BCOutputFile = DepFileIter->first;
7398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      DepOutputFile = DepFileIter->second;
7408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      setDepTargetBC(BCOutputFile);
7428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!setDepOutput(DepOutputFile))
7448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        return false;
7458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (SuppressAllWarnings) {
7478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        getDiagnostics().setSuppressAllDiagnostics(true);
7488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (generateDepFile() > 0)
7508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        return false;
7518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (SuppressAllWarnings) {
7528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        getDiagnostics().setSuppressAllDiagnostics(false);
7538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      DepFileIter++;
7568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!checkODR(InputFile))
7598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      return false;
7608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    IOFile64Iter++;
7628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    IOFile32Iter++;
7638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return true;
765462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
766e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
767e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
768