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"
438f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar#include "clang/Frontend/PCHContainerOperations.h"
44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Frontend/TextDiagnosticPrinter.h"
45cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines#include "clang/Frontend/Utils.h"
46cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
473a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Lex/HeaderSearch.h"
4823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "clang/Lex/HeaderSearchOptions.h"
498f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar#include "clang/Lex/Preprocessor.h"
508f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar#include "clang/Lex/PreprocessorOptions.h"
513a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "clang/Parse/ParseAST.h"
536315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "clang/Sema/SemaDiagnostic.h"
558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
56be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/ADT/IntrusiveRefCntPtr.h"
57be27482cdeaf08576bc39b72a15d35d13014a636Logan
58e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Bitcode/ReaderWriter.h"
599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
6008df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang// More force linking
61ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murray#include "llvm/Linker/Linker.h"
6208df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang
63e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines// Force linking all passes/vmcore stuffs to libslang.so
640da7f6c8201b27938d3b9f048d71fd784cd1df9aStephen Hines#include "llvm/LinkAllIR.h"
65e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/LinkAllPasses.h"
66e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
67e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/raw_ostream.h"
68e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/MemoryBuffer.h"
69e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/ErrorHandling.h"
70e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Support/ManagedStatic.h"
71be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/Support/Path.h"
729207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Support/TargetSelect.h"
739207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Support/ToolOutputFile.h"
74e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "os_sep.h"
768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "rs_cc_options.h"
776e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
78e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_backend.h"
79b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_context.h"
818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_type.h"
828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_reflection.h"
848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_reflection_cpp.h"
858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8708df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Changnamespace {
8808df36e5c0a990306d958c9f6d59a5de23b748f6Zonr Chang
899ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesstatic const char *kRSTriple32 = "armv7-none-linux-gnueabi";
909ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesstatic const char *kRSTriple64 = "aarch64-none-linux-gnueabi";
919ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
92e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace
93e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
94e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#define FS_SUFFIX  "fs"
988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#define RS_HEADER_SUFFIX  "rsh"
1008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
1018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet/* RS_HEADER_ENTRY(name) */
1028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#define ENUM_RS_HEADER()  \
103d118c0278865c0760a5c37972b57cc3a016d0952Pirama Arumuga Nainar  RS_HEADER_ENTRY(rs_allocation_create) \
1048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_allocation_data) \
1058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_atomic) \
1068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_convert) \
1078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_core) \
1088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_debug) \
1098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_for_each) \
1108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_graphics) \
1118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_graphics_types) \
1128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_io) \
1138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_math) \
1148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_matrix) \
1158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_object_info) \
1168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_object_types) \
1178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_quaternion) \
1188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_time) \
1198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_value_types) \
1208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_vector_math) \
1218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
1228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// The named of metadata node that pragma resides (should be synced with
1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// bcc.cpp)
125f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liaoconst llvm::StringRef Slang::PragmaMetadataName = "#pragma";
126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1279207a2e495c8363606861e4f034504ec5c153dabLogan Chienstatic inline llvm::tool_output_file *
1289207a2e495c8363606861e4f034504ec5c153dabLogan ChienOpenOutputFile(const char *OutputFile,
129a1f95ee8df425089100148a42954cf61dc285015Stephen Hines               llvm::sys::fs::OpenFlags Flags,
1303eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines               std::error_code &EC,
131e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines               clang::DiagnosticsEngine *DiagEngine) {
1323eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  slangAssert((OutputFile != nullptr) &&
1335abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes              (DiagEngine != nullptr) && "Invalid parameter!");
134e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
1353eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  EC = llvm::sys::fs::create_directories(
1363eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines      llvm::sys::path::parent_path(OutputFile));
1373eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  if (!EC) {
138e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    llvm::tool_output_file *F =
1393eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines          new llvm::tool_output_file(OutputFile, EC, Flags);
1405abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    if (F != nullptr)
141e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang      return F;
142e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  }
143e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
144e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Report error here.
1459207a2e495c8363606861e4f034504ec5c153dabLogan Chien  DiagEngine->Report(clang::diag::err_fe_error_opening)
1463eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines    << OutputFile << EC.message();
147e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
1485abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  return nullptr;
149e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang}
150e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
1519ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesvoid Slang::createTarget(uint32_t BitWidth) {
1529ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  std::vector<std::string> features;
153462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1549ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  if (BitWidth == 64) {
1559ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    mTargetOpts->Triple = kRSTriple64;
1569ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  } else {
1579ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    mTargetOpts->Triple = kRSTriple32;
1589ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    // Treat long as a 64-bit type for our 32-bit RS code.
1599ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    features.push_back("+long64");
1609ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    mTargetOpts->FeaturesAsWritten = features;
1619ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  }
162b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1639207a2e495c8363606861e4f034504ec5c153dabLogan Chien  mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagEngine,
1647ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines                                                    mTargetOpts));
165462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
166462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1673a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createFileManager() {
168df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao  mFileSysOpt.reset(new clang::FileSystemOptions());
169be27482cdeaf08576bc39b72a15d35d13014a636Logan  mFileMgr.reset(new clang::FileManager(*mFileSysOpt));
1703a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1713a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1723a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createSourceManager() {
1739207a2e495c8363606861e4f034504ec5c153dabLogan Chien  mSourceMgr.reset(new clang::SourceManager(*mDiagEngine, *mFileMgr));
1743a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1753a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
17668e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liaovoid Slang::createPreprocessor() {
1779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Default only search header file in current dir
1788f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  clang::HeaderSearch *HeaderInfo = new clang::HeaderSearch(&getHeaderSearchOpts(),
179eeb251e8db802b836af7461d0f6eb1252c527ab8Stephen Hines                                                            *mSourceMgr,
1800444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines                                                            *mDiagEngine,
1810444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines                                                            LangOpts,
1820444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines                                                            mTarget.get());
1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1848f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  mPP.reset(new clang::Preprocessor(&getPreprocessorOpts(),
18523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines                                    *mDiagEngine,
1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    LangOpts,
1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *mSourceMgr,
1889207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                    *HeaderInfo,
1899207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                    *this,
1905abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes                                    nullptr,
1913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                    /* OwnsHeaderSearch = */true));
1923fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines  // Initialize the preprocessor
19375d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines  mPP->Initialize(getTargetInfo());
1940e4ee65a2ba6b32fcd16c5d4a57fc7542d4032b4Stephen Hines  clang::FrontendOptions FEOpts;
1958f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar
1968f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  auto *Reader = mPCHContainerOperations->getReaderOrNull(
1978f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      getHeaderSearchOpts().ModuleFormat);
1988f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  clang::InitializePreprocessor(*mPP, getPreprocessorOpts(), *Reader, FEOpts);
1998f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar
2008f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  clang::ApplyHeaderSearchOptions(*HeaderInfo, getHeaderSearchOpts(), LangOpts,
2018f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      mPP->getTargetInfo().getTriple());
2020e4ee65a2ba6b32fcd16c5d4a57fc7542d4032b4Stephen Hines
20368e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  mPragmas.clear();
20468e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
2059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::vector<clang::DirectoryLookup> SearchList;
2063a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (const clang::DirectoryEntry *DE =
208be27482cdeaf08576bc39b72a15d35d13014a636Logan            mFileMgr->getDirectory(mIncludePaths[i])) {
2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      SearchList.push_back(clang::DirectoryLookup(DE,
2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  clang::SrcMgr::C_System,
2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  false));
2129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
2139089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  }
2149089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
2159207a2e495c8363606861e4f034504ec5c153dabLogan Chien  HeaderInfo->SetSearchPaths(SearchList,
2169207a2e495c8363606861e4f034504ec5c153dabLogan Chien                             /* angledDirIdx = */1,
2179207a2e495c8363606861e4f034504ec5c153dabLogan Chien                             /* systemDixIdx = */1,
2189207a2e495c8363606861e4f034504ec5c153dabLogan Chien                             /* noCurDirSearch = */false);
2199089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
2203a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initPreprocessor();
22168e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao}
22268e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
2233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createASTContext() {
2248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mASTContext.reset(
2258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      new clang::ASTContext(LangOpts, *mSourceMgr, mPP->getIdentifierTable(),
2268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                            mPP->getSelectorTable(), mPP->getBuiltinInfo()));
22775d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines  mASTContext->InitBuiltinTypes(getTargetInfo());
2283a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initASTContext();
2293a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
2303a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
2319207a2e495c8363606861e4f034504ec5c153dabLogan Chienclang::ASTConsumer *
2322770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid GrossSlang::createBackend(const RSCCOptions &Opts, const clang::CodeGenOptions &CodeGenOpts,
2335309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                     llvm::raw_ostream *OS, OutputType OT) {
2348f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  auto *B = new Backend(mRSContext, &getDiagnostics(), Opts,
2358f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar                        getHeaderSearchOpts(), getPreprocessorOpts(),
2368f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar                        CodeGenOpts, getTargetOptions(), &mPragmas, OS, OT,
2378f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar                        getSourceManager(), mAllowRSPrefix, mIsFilterscript);
2388f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  B->Initialize(getASTContext());
2398f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  return B;
2403a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
2413a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
2425309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc BrouilletSlang::Slang(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine,
2435309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet             DiagnosticBuffer *DiagClient)
2445309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    : mDiagEngine(DiagEngine), mDiagClient(DiagClient),
2458f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      mTargetOpts(new clang::TargetOptions()),
2468f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      mHSOpts(new clang::HeaderSearchOptions()),
2478f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      mPPOpts(new clang::PreprocessorOptions()),
2488f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      mPCHContainerOperations(std::make_shared<clang::PCHContainerOperations>()),
2498f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      mOT(OT_Default), mRSContext(nullptr), mAllowRSPrefix(false), mTargetAPI(0),
2508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mVerbose(false), mIsFilterscript(false) {
2515309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // Please refer to include/clang/Basic/LangOptions.h to setup
2525309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // the options.
2535309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.RTTI = 0;  // Turn off the RTTI information support
2545309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.LineComment = 1;
2555309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.C99 = 1;
2565309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.Renderscript = 1;
2575309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.LaxVectorConversions = 0;  // Do not bitcast vectors!
2585309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.CharIsSigned = 1;  // Signed char is our default.
2595309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
2605309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  CodeGenOpts.OptimizationLevel = 3;
2615309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
262fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  // We must set StackRealignment, because the default is for the actual
263fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  // Clang driver to pass this option (-mstackrealign) directly to cc1.
264fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  // Since we don't use Clang's driver, we need to similarly supply it.
265fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  // If StackRealignment is zero (i.e. the option wasn't set), then the
266fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  // backend assumes that it can't adjust the stack in any way, which breaks
267fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  // alignment for vector loads/stores.
268fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  CodeGenOpts.StackRealignment = 1;
269fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines
2705309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  createTarget(BitWidth);
2715309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  createFileManager();
2725309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  createSourceManager();
273641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang}
274641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang
2758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc BrouilletSlang::~Slang() {
2768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  delete mRSContext;
2778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (ReflectedDefinitionListTy::iterator I = ReflectedDefinitions.begin(),
2788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                           E = ReflectedDefinitions.end();
2798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E; I++) {
2808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    delete I->getValue().first;
2818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
2828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
2838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
28423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hinesclang::ModuleLoadResult Slang::loadModule(
28523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    clang::SourceLocation ImportLoc,
28623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    clang::ModuleIdPath Path,
28723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    clang::Module::NameVisibilityKind Visibility,
28823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    bool IsInclusionDirective) {
2899207a2e495c8363606861e4f034504ec5c153dabLogan Chien  slangAssert(0 && "Not implemented");
29023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  return clang::ModuleLoadResult();
291462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
292462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile) {
2943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mInputFileName = InputFile.str();
295462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->clearIDTables();
297462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
298be27482cdeaf08576bc39b72a15d35d13014a636Logan  const clang::FileEntry *File = mFileMgr->getFile(InputFile);
29975d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines  if (File) {
30075d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines    mSourceMgr->setMainFileID(mSourceMgr->createFileID(File,
30175d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines        clang::SourceLocation(), clang::SrcMgr::C_User));
30275d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines  }
303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mSourceMgr->getMainFileID().isInvalid()) {
3059207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mDiagEngine->Report(clang::diag::err_fe_error_reading) << InputFile;
3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
3079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
308462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
310462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
311462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setOutput(const char *OutputFile) {
3133eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  std::error_code EC;
3145abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  llvm::tool_output_file *OS = nullptr;
315462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3163a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  switch (mOT) {
317cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    case OT_Dependency:
3183a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Assembly:
3193a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_LLVMAssembly: {
3203eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines      OS = OpenOutputFile(OutputFile, llvm::sys::fs::F_Text, EC, mDiagEngine);
3219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
322462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Nothing: {
3249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
325462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3263a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Object:
327cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    case OT_Bitcode: {
3283eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines      OS = OpenOutputFile(OutputFile, llvm::sys::fs::F_None, EC, mDiagEngine);
3299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3318c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    default: {
332cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines      llvm_unreachable("Unknown compiler output type");
3338c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    }
3349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
335462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3363eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  if (EC)
3379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
338e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
339e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mOS.reset(OS);
3409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3413a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mOutputFileName = OutputFile;
342462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
344462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
345462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3460b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hinesbool Slang::setDepOutput(const char *OutputFile) {
3473eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  std::error_code EC;
3488c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang
349a1f95ee8df425089100148a42954cf61dc285015Stephen Hines  mDOS.reset(
3503eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines      OpenOutputFile(OutputFile, llvm::sys::fs::F_Text, EC, mDiagEngine));
3513eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  if (EC || (mDOS.get() == nullptr))
3520b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines    return false;
3530b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
3540b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  mDepOutputFileName = OutputFile;
3550b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
3560b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  return true;
3570b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines}
3580b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
35921c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wangint Slang::generateDepFile(bool PhonyTarget) {
3609207a2e495c8363606861e4f034504ec5c153dabLogan Chien  if (mDiagEngine->hasErrorOccurred())
361be27482cdeaf08576bc39b72a15d35d13014a636Logan    return 1;
3625abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (mDOS.get() == nullptr)
363f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines    return 1;
364cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
365e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Initialize options for generating dependency file
366cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  clang::DependencyOutputOptions DepOpts;
367cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  DepOpts.IncludeSystemHeaders = 1;
36821c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wang  if (PhonyTarget)
36921c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wang    DepOpts.UsePhonyTargets = 1;
3700b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  DepOpts.OutputFile = mDepOutputFileName;
371b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  DepOpts.Targets = mAdditionalDepTargets;
372cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  DepOpts.Targets.push_back(mDepTargetBCFileName);
3734cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  for (std::vector<std::string>::const_iterator
3744cc67fce91f43215d61b2695746eab102a3db516Stephen Hines           I = mGeneratedFileNames.begin(), E = mGeneratedFileNames.end();
3754cc67fce91f43215d61b2695746eab102a3db516Stephen Hines       I != E;
3764cc67fce91f43215d61b2695746eab102a3db516Stephen Hines       I++) {
3774cc67fce91f43215d61b2695746eab102a3db516Stephen Hines    DepOpts.Targets.push_back(*I);
3784cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  }
3794cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  mGeneratedFileNames.clear();
380cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
381e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Per-compilation needed initialization
382cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  createPreprocessor();
383ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murray  clang::DependencyFileGenerator::CreateAndAttachToPreprocessor(*mPP.get(), DepOpts);
384cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
385e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Inform the diagnostic client we are processing a source file
386cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
387cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
388e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Go through the source file (no operations necessary)
389cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  clang::Token Tok;
390cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP->EnterMainSourceFile();
391cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  do {
392cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    mPP->Lex(Tok);
393cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  } while (Tok.isNot(clang::tok::eof));
394cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
395cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP->EndSourceFile();
396cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
397e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Declare success if no error
3989207a2e495c8363606861e4f034504ec5c153dabLogan Chien  if (!mDiagEngine->hasErrorOccurred())
399e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    mDOS->keep();
400e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
401e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Clean up after compilation
402cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP.reset();
403e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mDOS.reset();
404cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
4059207a2e495c8363606861e4f034504ec5c153dabLogan Chien  return mDiagEngine->hasErrorOccurred() ? 1 : 0;
406cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines}
407cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
4082770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Grossint Slang::compile(const RSCCOptions &Opts) {
4099207a2e495c8363606861e4f034504ec5c153dabLogan Chien  if (mDiagEngine->hasErrorOccurred())
410be27482cdeaf08576bc39b72a15d35d13014a636Logan    return 1;
4115abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (mOS.get() == nullptr)
412f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines    return 1;
413462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Here is per-compilation needed initialization
4159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createPreprocessor();
4169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createASTContext();
4173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
4182770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  mBackend.reset(createBackend(Opts, CodeGenOpts, &mOS->os(), mOT));
419462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Inform the diagnostic client we are processing a source file
4219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
422462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // The core of the slang compiler
4249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ParseAST(*mPP, mBackend.get(), *mASTContext);
425462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
426e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Inform the diagnostic client we are done with previous source file
427e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mDiagClient->EndSourceFile();
428e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
429e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Declare success if no error
4309207a2e495c8363606861e4f034504ec5c153dabLogan Chien  if (!mDiagEngine->hasErrorOccurred())
431e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    mOS->keep();
432e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
4333a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  // The compilation ended, clear
4349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mBackend.reset();
435e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mOS.reset();
436462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4379207a2e495c8363606861e4f034504ec5c153dabLogan Chien  return mDiagEngine->hasErrorOccurred() ? 1 : 0;
438462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
439462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
440c460b37ffb50819a32c2a8967754b6f784b28263mkopecvoid Slang::setDebugMetadataEmission(bool EmitDebug) {
44143730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao  if (EmitDebug)
44223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    CodeGenOpts.setDebugInfo(clang::CodeGenOptions::FullDebugInfo);
44343730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao  else
44423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    CodeGenOpts.setDebugInfo(clang::CodeGenOptions::NoDebugInfo);
445c460b37ffb50819a32c2a8967754b6f784b28263mkopec}
446c460b37ffb50819a32c2a8967754b6f784b28263mkopec
447c460b37ffb50819a32c2a8967754b6f784b28263mkopecvoid Slang::setOptimizationLevel(llvm::CodeGenOpt::Level OptimizationLevel) {
448c460b37ffb50819a32c2a8967754b6f784b28263mkopec  CodeGenOpts.OptimizationLevel = OptimizationLevel;
449c460b37ffb50819a32c2a8967754b6f784b28263mkopec}
450c460b37ffb50819a32c2a8967754b6f784b28263mkopec
4518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::isFilterscript(const char *Filename) {
4528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  const char *c = strrchr(Filename, '.');
4538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (c && !strncmp(FS_SUFFIX, c + 1, strlen(FS_SUFFIX) + 1)) {
4548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return true;
4558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  } else {
4568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
4578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::generateJavaBitcodeAccessor(const std::string &OutputPathBase,
4618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                          const std::string &PackageName,
4628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                          const std::string *LicenseNote) {
4638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RSSlangReflectUtils::BitCodeAccessorContext BCAccessorContext;
4648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.rsFileName = getInputFileName().c_str();
4665309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  BCAccessorContext.bc32FileName = mOutput32FileName.c_str();
4675309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  BCAccessorContext.bc64FileName = mOutputFileName.c_str();
4688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.reflectPath = OutputPathBase.c_str();
4698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.packageName = PackageName.c_str();
4708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.licenseNote = LicenseNote;
4718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.bcStorage = BCST_JAVA_CODE;   // Must be BCST_JAVA_CODE
4728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.verbose = false;
4738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return RSSlangReflectUtils::GenerateJavaBitCodeAccessor(BCAccessorContext);
4758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::checkODR(const char *CurInputFile) {
4788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::ExportableList::iterator I = mRSContext->exportable_begin(),
4798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mRSContext->exportable_end();
4808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
4818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
4828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    RSExportable *RSE = *I;
4838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (RSE->getKind() != RSExportable::EX_TYPE)
4848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      continue;
4858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    RSExportType *ET = static_cast<RSExportType *>(RSE);
4878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (ET->getClass() != RSExportType::ExportClassRecord)
4888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      continue;
4898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    RSExportRecordType *ERT = static_cast<RSExportRecordType *>(ET);
4918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Artificial record types (create by us not by user in the source) always
4938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // conforms the ODR.
4948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (ERT->isArtificial())
4958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      continue;
4968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Key to lookup ERT in ReflectedDefinitions
4988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    llvm::StringRef RDKey(ERT->getName());
4998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ReflectedDefinitionListTy::const_iterator RD =
5008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ReflectedDefinitions.find(RDKey);
5018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (RD != ReflectedDefinitions.end()) {
5038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const RSExportRecordType *Reflected = RD->getValue().first;
5048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // There's a record (struct) with the same name reflected before. Enforce
5058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // ODR checking - the Reflected must hold *exactly* the same "definition"
5068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // as the one defined previously. We say two record types A and B have the
5078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // same definition iff:
5088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //
5098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  struct A {              struct B {
5108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //    Type(a1) a1,            Type(b1) b1,
5118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //    Type(a2) a2,            Type(b1) b2,
5128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //    ...                     ...
5138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //    Type(aN) aN             Type(b3) b3,
5148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  };                      }
5158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Cond. #1. They have same number of fields, i.e., N = M;
5168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Cond. #2. for (i := 1 to N)
5178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //              Type(ai) = Type(bi) must hold;
5188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Cond. #3. for (i := 1 to N)
5198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //              Name(ai) = Name(bi) must hold;
5208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //
5218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // where,
5228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Type(F) = the type of field F and
5238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Name(F) = the field name.
5248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      bool PassODR = false;
5268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Cond. #1 and Cond. #2
5278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (Reflected->equals(ERT)) {
5288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // Cond #3.
5298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        RSExportRecordType::const_field_iterator AI = Reflected->fields_begin(),
5308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                 BI = ERT->fields_begin();
5318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        for (unsigned i = 0, e = Reflected->getFields().size(); i != e; i++) {
5338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if ((*AI)->getName() != (*BI)->getName())
5348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            break;
5358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          AI++;
5368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          BI++;
5378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
5388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        PassODR = (AI == (Reflected->fields_end()));
5398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!PassODR) {
5425309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        unsigned DiagID = mDiagEngine->getCustomDiagID(
5435309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet            clang::DiagnosticsEngine::Error,
5445309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet            "type '%0' in different translation unit (%1 v.s. %2) "
5455309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet            "has incompatible type definition");
5465309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        getDiagnostics().Report(DiagID) << Reflected->getName()
5475309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                        << getInputFileName()
5485309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                        << RD->getValue().second;
5498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        return false;
5508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    } else {
5528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::StringMapEntry<ReflectedDefinitionTy> *ME =
5538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::StringMapEntry<ReflectedDefinitionTy>::Create(RDKey);
5548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ME->setValue(std::make_pair(ERT, CurInputFile));
5558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5563f45a25c23fa0f2cca4070f4d8713dc1a83f5ff7Matt Wala      if (!ReflectedDefinitions.insert(ME)) {
5573f45a25c23fa0f2cca4070f4d8713dc1a83f5ff7Matt Wala        slangAssert(false && "Type shouldn't be in map yet!");
5583f45a25c23fa0f2cca4070f4d8713dc1a83f5ff7Matt Wala      }
5598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Take the ownership of ERT such that it won't be freed in ~RSContext().
5618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ERT->keep();
5628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return true;
5658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Slang::initPreprocessor() {
5688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::Preprocessor &PP = getPreprocessor();
5698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  std::stringstream RSH;
5718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RSH << PP.getPredefines();
5728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RSH << "#define RS_VERSION " << mTargetAPI << "\n";
5738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RSH << "#include \"rs_core." RS_HEADER_SUFFIX "\"\n";
5748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  PP.setPredefines(RSH.str());
5758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Slang::initASTContext() {
5788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mRSContext = new RSContext(getPreprocessor(),
5798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             getASTContext(),
5808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             getTargetInfo(),
5818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             &mPragmas,
5828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             mTargetAPI,
5838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             mVerbose);
5848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::IsRSHeaderFile(const char *File) {
5878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#define RS_HEADER_ENTRY(name)  \
5888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (::strcmp(File, #name "." RS_HEADER_SUFFIX) == 0)  \
5898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return true;
5908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc BrouilletENUM_RS_HEADER()
5918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#undef RS_HEADER_ENTRY
5928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return false;
5938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::IsLocInRSHeaderFile(const clang::SourceLocation &Loc,
5968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                  const clang::SourceManager &SourceMgr) {
5978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::FullSourceLoc FSL(Loc, SourceMgr);
5988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::PresumedLoc PLoc = SourceMgr.getPresumedLoc(FSL);
5998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  const char *Filename = PLoc.getFilename();
6018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!Filename) {
6028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
6038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  } else {
6048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return IsRSHeaderFile(llvm::sys::path::filename(Filename).data());
6058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
6078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::compile(
6098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const std::list<std::pair<const char*, const char*> > &IOFiles64,
6108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const std::list<std::pair<const char*, const char*> > &IOFiles32,
6118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const std::list<std::pair<const char*, const char*> > &DepFiles,
6125309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    const RSCCOptions &Opts,
6135309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    clang::DiagnosticOptions &DiagOpts) {
6148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (IOFiles32.empty())
6158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return true;
6168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (Opts.mEmitDependency && (DepFiles.size() != IOFiles32.size())) {
6185309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    unsigned DiagID = mDiagEngine->getCustomDiagID(
6195309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        clang::DiagnosticsEngine::Error,
6205309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        "invalid parameter for output dependencies files.");
6215309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    getDiagnostics().Report(DiagID);
6228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
6238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (Opts.mEmit3264 && (IOFiles64.size() != IOFiles32.size())) {
6268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slangAssert(false && "Should have equal number of 32/64-bit files");
6278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
6288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  std::string RealPackageName;
6318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  const char *InputFile, *Output64File, *Output32File, *BCOutputFile,
6338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet             *DepOutputFile;
6348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  setIncludePaths(Opts.mIncludePaths);
6368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  setOutputType(Opts.mOutputType);
6378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (Opts.mEmitDependency) {
6388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    setAdditionalDepTargets(Opts.mAdditionalDepTargets);
6398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  setDebugMetadataEmission(Opts.mDebugEmission);
6428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  setOptimizationLevel(Opts.mOptimizationLevel);
6448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mAllowRSPrefix = Opts.mAllowRSPrefix;
6468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mTargetAPI = Opts.mTargetAPI;
6488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mTargetAPI != SLANG_DEVELOPMENT_TARGET_API &&
6498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      (mTargetAPI < SLANG_MINIMUM_TARGET_API ||
6508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       mTargetAPI > SLANG_MAXIMUM_TARGET_API)) {
6515309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    unsigned DiagID = mDiagEngine->getCustomDiagID(
6525309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        clang::DiagnosticsEngine::Error,
6535309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        "target API level '%0' is out of range ('%1' - '%2')");
6545309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    getDiagnostics().Report(DiagID) << mTargetAPI << SLANG_MINIMUM_TARGET_API
6555309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                    << SLANG_MAXIMUM_TARGET_API;
6568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
6578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
659bd0a7ddceac6c135ea975cefbac73877a1f9dae7Stephen Hines  if (mTargetAPI >= SLANG_M_TARGET_API) {
660e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar    LangOpts.NativeHalfType = 1;
661e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar    LangOpts.HalfArgsAndReturns = 1;
662e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar  }
663e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar
6648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mVerbose = Opts.mVerbose;
6658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Skip generation of warnings a second time if we are doing more than just
6678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // a single pass over the input file.
6688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  bool SuppressAllWarnings = (Opts.mOutputType != Slang::OT_Dependency);
6698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6705309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  std::list<std::pair<const char*, const char*> >::const_iterator
6715309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      IOFile64Iter = IOFiles64.begin(),
6725309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      IOFile32Iter = IOFiles32.begin(),
6735309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      DepFileIter = DepFiles.begin();
6748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (unsigned i = 0, e = IOFiles32.size(); i != e; i++) {
6768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    InputFile = IOFile64Iter->first;
6778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    Output64File = IOFile64Iter->second;
6788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    Output32File = IOFile32Iter->second;
6798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!setInputSource(InputFile))
6818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      return false;
6828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!setOutput(Output64File))
6848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      return false;
6858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6865309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    // For use with 64-bit compilation/reflection. This only sets the filename of
6875309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    // the 32-bit bitcode file, and doesn't actually verify it already exists.
6885309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    mOutput32FileName = Output32File;
6898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mIsFilterscript = isFilterscript(InputFile);
6918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
69268e562f8cac58df367861670e554c3c1f498426cStephen McGroarty    CodeGenOpts.MainFileName = mInputFileName;
69368e562f8cac58df367861670e554c3c1f498426cStephen McGroarty
6942770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross    if (Slang::compile(Opts) > 0)
6958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      return false;
6968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!Opts.mJavaReflectionPackageName.empty()) {
6988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSContext->setReflectJavaPackageName(Opts.mJavaReflectionPackageName);
6998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const std::string &RealPackageName =
7018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mRSContext->getReflectJavaPackageName();
7028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    bool doReflection = true;
7048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (Opts.mEmit3264 && (Opts.mBitWidth == 32)) {
7058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Skip reflection on the 32-bit path if we are going to emit it on the
7068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // 64-bit path.
7078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      doReflection = false;
7088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (Opts.mOutputType != Slang::OT_Dependency && doReflection) {
7108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (Opts.mBitcodeStorage == BCST_CPP_CODE) {
7128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const std::string &outputFileName = (Opts.mBitWidth == 64) ?
7135309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                            mOutputFileName : mOutput32FileName;
7148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        RSReflectionCpp R(mRSContext, Opts.mJavaReflectionPathBase,
7158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                          getInputFileName(), outputFileName);
7168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!R.reflect()) {
7178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            return false;
7188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      } else {
7208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!Opts.mRSPackageName.empty()) {
7218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          mRSContext->setRSPackageName(Opts.mRSPackageName);
7228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
724ff5abc6892aedb25215689bd679eb7cc1588a8e3Jean-Luc Brouillet        std::vector<std::string> generatedFileNames;
725ff5abc6892aedb25215689bd679eb7cc1588a8e3Jean-Luc Brouillet        RSReflectionJava R(mRSContext, &generatedFileNames,
7268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                           Opts.mJavaReflectionPathBase, getInputFileName(),
7275309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                           mOutputFileName,
7288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                           Opts.mBitcodeStorage == BCST_JAVA_CODE);
7298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!R.reflect()) {
7308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // TODO Is this needed or will the error message have been printed
7318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // already? and why not for the C++ case?
7328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          fprintf(stderr, "RSContext::reflectToJava : failed to do reflection "
7338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                          "(%s)\n",
7348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  R.getLastError());
7358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          return false;
7368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        for (std::vector<std::string>::const_iterator
739ff5abc6892aedb25215689bd679eb7cc1588a8e3Jean-Luc Brouillet                 I = generatedFileNames.begin(), E = generatedFileNames.end();
7408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet             I != E;
7418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet             I++) {
7428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          std::string ReflectedName = RSSlangReflectUtils::ComputePackagedPath(
7438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              Opts.mJavaReflectionPathBase.c_str(),
7448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              (RealPackageName + OS_PATH_SEPARATOR_STR + *I).c_str());
7458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          appendGeneratedFileName(ReflectedName + ".java");
7468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if ((Opts.mOutputType == Slang::OT_Bitcode) &&
7498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            (Opts.mBitcodeStorage == BCST_JAVA_CODE) &&
7508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            !generateJavaBitcodeAccessor(Opts.mJavaReflectionPathBase,
7518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                         RealPackageName.c_str(),
7528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                         mRSContext->getLicenseNote())) {
7538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          return false;
7548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (Opts.mEmitDependency) {
7598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      BCOutputFile = DepFileIter->first;
7608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      DepOutputFile = DepFileIter->second;
7618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      setDepTargetBC(BCOutputFile);
7638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!setDepOutput(DepOutputFile))
7658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        return false;
7668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (SuppressAllWarnings) {
7688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        getDiagnostics().setSuppressAllDiagnostics(true);
7698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
77021c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wang      if (generateDepFile(Opts.mEmitPhonyDependency) > 0)
7718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        return false;
7728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (SuppressAllWarnings) {
7738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        getDiagnostics().setSuppressAllDiagnostics(false);
7748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      DepFileIter++;
7778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!checkODR(InputFile))
7808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      return false;
7818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    IOFile64Iter++;
7838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    IOFile32Iter++;
7848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return true;
786462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
787e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
788e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
789