slang.cpp revision d118c0278865c0760a5c37972b57cc3a016d0952
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()  \
102d118c0278865c0760a5c37972b57cc3a016d0952Pirama Arumuga Nainar  RS_HEADER_ENTRY(rs_allocation_create) \
1038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_allocation_data) \
1048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_atomic) \
1058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_convert) \
1068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_core) \
1078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_debug) \
1088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_for_each) \
1098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_graphics) \
1108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_graphics_types) \
1118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_io) \
1128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_math) \
1138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_matrix) \
1148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_object_info) \
1158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_object_types) \
1168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_quaternion) \
1178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_time) \
1188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_value_types) \
1198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RS_HEADER_ENTRY(rs_vector_math) \
1208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
1218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// The named of metadata node that pragma resides (should be synced with
1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// bcc.cpp)
124f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liaoconst llvm::StringRef Slang::PragmaMetadataName = "#pragma";
125462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1269207a2e495c8363606861e4f034504ec5c153dabLogan Chienstatic inline llvm::tool_output_file *
1279207a2e495c8363606861e4f034504ec5c153dabLogan ChienOpenOutputFile(const char *OutputFile,
128a1f95ee8df425089100148a42954cf61dc285015Stephen Hines               llvm::sys::fs::OpenFlags Flags,
1293eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines               std::error_code &EC,
130e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines               clang::DiagnosticsEngine *DiagEngine) {
1313eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  slangAssert((OutputFile != nullptr) &&
1325abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes              (DiagEngine != nullptr) && "Invalid parameter!");
133e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
1343eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  EC = llvm::sys::fs::create_directories(
1353eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines      llvm::sys::path::parent_path(OutputFile));
1363eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  if (!EC) {
137e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    llvm::tool_output_file *F =
1383eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines          new llvm::tool_output_file(OutputFile, EC, Flags);
1395abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    if (F != nullptr)
140e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang      return F;
141e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  }
142e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
143e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Report error here.
1449207a2e495c8363606861e4f034504ec5c153dabLogan Chien  DiagEngine->Report(clang::diag::err_fe_error_opening)
1453eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines    << OutputFile << EC.message();
146e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
1475abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  return nullptr;
148e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang}
149e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
1509ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesvoid Slang::createTarget(uint32_t BitWidth) {
1519ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  std::vector<std::string> features;
152462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1539ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  if (BitWidth == 64) {
1549ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    mTargetOpts->Triple = kRSTriple64;
1559ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  } else {
1569ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    mTargetOpts->Triple = kRSTriple32;
1579ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    // Treat long as a 64-bit type for our 32-bit RS code.
1589ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    features.push_back("+long64");
1599ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    mTargetOpts->FeaturesAsWritten = features;
1609ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  }
161b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
1629207a2e495c8363606861e4f034504ec5c153dabLogan Chien  mTarget.reset(clang::TargetInfo::CreateTargetInfo(*mDiagEngine,
1637ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines                                                    mTargetOpts));
164462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
165462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1663a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createFileManager() {
167df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao  mFileSysOpt.reset(new clang::FileSystemOptions());
168be27482cdeaf08576bc39b72a15d35d13014a636Logan  mFileMgr.reset(new clang::FileManager(*mFileSysOpt));
1693a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1703a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
1713a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createSourceManager() {
1729207a2e495c8363606861e4f034504ec5c153dabLogan Chien  mSourceMgr.reset(new clang::SourceManager(*mDiagEngine, *mFileMgr));
1733a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1743a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
17568e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liaovoid Slang::createPreprocessor() {
1769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Default only search header file in current dir
17723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> HSOpts =
17823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines      new clang::HeaderSearchOptions();
17923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  clang::HeaderSearch *HeaderInfo = new clang::HeaderSearch(HSOpts,
180eeb251e8db802b836af7461d0f6eb1252c527ab8Stephen Hines                                                            *mSourceMgr,
1810444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines                                                            *mDiagEngine,
1820444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines                                                            LangOpts,
1830444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines                                                            mTarget.get());
1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
18523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  llvm::IntrusiveRefCntPtr<clang::PreprocessorOptions> PPOpts =
18623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines      new clang::PreprocessorOptions();
18723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  mPP.reset(new clang::Preprocessor(PPOpts,
18823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines                                    *mDiagEngine,
1899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    LangOpts,
1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                    *mSourceMgr,
1919207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                    *HeaderInfo,
1929207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                    *this,
1935abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes                                    nullptr,
1943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                                    /* OwnsHeaderSearch = */true));
1953fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines  // Initialize the preprocessor
19675d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines  mPP->Initialize(getTargetInfo());
1970e4ee65a2ba6b32fcd16c5d4a57fc7542d4032b4Stephen Hines  clang::FrontendOptions FEOpts;
1987ac9d0de26d325071ad3f26f8d34514efca2d3d6Stephen Hines  clang::InitializePreprocessor(*mPP, *PPOpts, FEOpts);
1990e4ee65a2ba6b32fcd16c5d4a57fc7542d4032b4Stephen Hines
20068e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao  mPragmas.clear();
2013fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines  mPP->AddPragmaHandler(new PragmaRecorder(&mPragmas));
20268e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
2039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::vector<clang::DirectoryLookup> SearchList;
2043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  for (unsigned i = 0, e = mIncludePaths.size(); i != e; i++) {
2059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (const clang::DirectoryEntry *DE =
206be27482cdeaf08576bc39b72a15d35d13014a636Logan            mFileMgr->getDirectory(mIncludePaths[i])) {
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      SearchList.push_back(clang::DirectoryLookup(DE,
2089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  clang::SrcMgr::C_System,
2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  false));
2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
2119089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao  }
2129089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
2139207a2e495c8363606861e4f034504ec5c153dabLogan Chien  HeaderInfo->SetSearchPaths(SearchList,
2149207a2e495c8363606861e4f034504ec5c153dabLogan Chien                             /* angledDirIdx = */1,
2159207a2e495c8363606861e4f034504ec5c153dabLogan Chien                             /* systemDixIdx = */1,
2169207a2e495c8363606861e4f034504ec5c153dabLogan Chien                             /* noCurDirSearch = */false);
2179089828a995422a5ed3beeed0890b755c4abe188Shih-wei Liao
2183a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initPreprocessor();
21968e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao}
22068e8e9f98730b3672fb96d49e33b9db70a90ed3fShih-wei Liao
2213a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Slang::createASTContext() {
2228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mASTContext.reset(
2238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      new clang::ASTContext(LangOpts, *mSourceMgr, mPP->getIdentifierTable(),
2248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                            mPP->getSelectorTable(), mPP->getBuiltinInfo()));
22575d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines  mASTContext->InitBuiltinTypes(getTargetInfo());
2263a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  initASTContext();
2273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
2283a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
2299207a2e495c8363606861e4f034504ec5c153dabLogan Chienclang::ASTConsumer *
2302770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid GrossSlang::createBackend(const RSCCOptions &Opts, const clang::CodeGenOptions &CodeGenOpts,
2315309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                     llvm::raw_ostream *OS, OutputType OT) {
2322770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  return new Backend(mRSContext, &getDiagnostics(), Opts, CodeGenOpts,
2338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                     getTargetOptions(), &mPragmas, OS, OT, getSourceManager(),
2348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                     mAllowRSPrefix, mIsFilterscript);
2353a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
2363a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
2375309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc BrouilletSlang::Slang(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine,
2385309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet             DiagnosticBuffer *DiagClient)
2395309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    : mDiagEngine(DiagEngine), mDiagClient(DiagClient),
2408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mTargetOpts(new clang::TargetOptions()), mOT(OT_Default),
2418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSContext(nullptr), mAllowRSPrefix(false), mTargetAPI(0),
2428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mVerbose(false), mIsFilterscript(false) {
2435309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // Please refer to include/clang/Basic/LangOptions.h to setup
2445309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  // the options.
2455309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.RTTI = 0;  // Turn off the RTTI information support
2465309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.LineComment = 1;
2475309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.C99 = 1;
2485309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.Renderscript = 1;
2495309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.LaxVectorConversions = 0;  // Do not bitcast vectors!
2505309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  LangOpts.CharIsSigned = 1;  // Signed char is our default.
2515309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
2525309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  CodeGenOpts.OptimizationLevel = 3;
2535309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet
254fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  // We must set StackRealignment, because the default is for the actual
255fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  // Clang driver to pass this option (-mstackrealign) directly to cc1.
256fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  // Since we don't use Clang's driver, we need to similarly supply it.
257fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  // If StackRealignment is zero (i.e. the option wasn't set), then the
258fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  // backend assumes that it can't adjust the stack in any way, which breaks
259fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  // alignment for vector loads/stores.
260fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines  CodeGenOpts.StackRealignment = 1;
261fac3b024d115fa1a71f3f7e0b7b29a9b03f9b436Stephen Hines
2625309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  createTarget(BitWidth);
2635309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  createFileManager();
2645309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  createSourceManager();
265641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang}
266641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang
2678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc BrouilletSlang::~Slang() {
2688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  delete mRSContext;
2698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (ReflectedDefinitionListTy::iterator I = ReflectedDefinitions.begin(),
2708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                           E = ReflectedDefinitions.end();
2718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E; I++) {
2728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    delete I->getValue().first;
2738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
2748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
2758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
27623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hinesclang::ModuleLoadResult Slang::loadModule(
27723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    clang::SourceLocation ImportLoc,
27823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    clang::ModuleIdPath Path,
27923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    clang::Module::NameVisibilityKind Visibility,
28023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    bool IsInclusionDirective) {
2819207a2e495c8363606861e4f034504ec5c153dabLogan Chien  slangAssert(0 && "Not implemented");
28223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  return clang::ModuleLoadResult();
283462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
284462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2853a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setInputSource(llvm::StringRef InputFile) {
2863a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mInputFileName = InputFile.str();
287462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mSourceMgr->clearIDTables();
289462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
290be27482cdeaf08576bc39b72a15d35d13014a636Logan  const clang::FileEntry *File = mFileMgr->getFile(InputFile);
29175d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines  if (File) {
29275d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines    mSourceMgr->setMainFileID(mSourceMgr->createFileID(File,
29375d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines        clang::SourceLocation(), clang::SrcMgr::C_User));
29475d471819f1810e0e65224d6e57fe1106af0d340Stephen Hines  }
295462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mSourceMgr->getMainFileID().isInvalid()) {
2979207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mDiagEngine->Report(clang::diag::err_fe_error_reading) << InputFile;
2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
300462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
302462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changbool Slang::setOutput(const char *OutputFile) {
3053eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  std::error_code EC;
3065abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  llvm::tool_output_file *OS = nullptr;
307462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3083a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  switch (mOT) {
309cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    case OT_Dependency:
3103a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Assembly:
3113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_LLVMAssembly: {
3123eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines      OS = OpenOutputFile(OutputFile, llvm::sys::fs::F_Text, EC, mDiagEngine);
3139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3153a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Nothing: {
3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
317462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3183a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case OT_Object:
319cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    case OT_Bitcode: {
3203eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines      OS = OpenOutputFile(OutputFile, llvm::sys::fs::F_None, EC, mDiagEngine);
3219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3238c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    default: {
324cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines      llvm_unreachable("Unknown compiler output type");
3258c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang    }
3269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
327462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3283eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  if (EC)
3299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
330e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
331e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mOS.reset(OS);
3329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3333a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  mOutputFileName = OutputFile;
334462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
336462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
337462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3380b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hinesbool Slang::setDepOutput(const char *OutputFile) {
3393eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  std::error_code EC;
3408c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang
341a1f95ee8df425089100148a42954cf61dc285015Stephen Hines  mDOS.reset(
3423eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines      OpenOutputFile(OutputFile, llvm::sys::fs::F_Text, EC, mDiagEngine));
3433eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines  if (EC || (mDOS.get() == nullptr))
3440b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines    return false;
3450b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
3460b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  mDepOutputFileName = OutputFile;
3470b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
3480b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  return true;
3490b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines}
3500b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines
35121c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wangint Slang::generateDepFile(bool PhonyTarget) {
3529207a2e495c8363606861e4f034504ec5c153dabLogan Chien  if (mDiagEngine->hasErrorOccurred())
353be27482cdeaf08576bc39b72a15d35d13014a636Logan    return 1;
3545abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (mDOS.get() == nullptr)
355f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines    return 1;
356cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
357e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Initialize options for generating dependency file
358cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  clang::DependencyOutputOptions DepOpts;
359cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  DepOpts.IncludeSystemHeaders = 1;
36021c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wang  if (PhonyTarget)
36121c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wang    DepOpts.UsePhonyTargets = 1;
3620b7ef1a176b9ddd1e0d437efdce20743373fd7dbStephen Hines  DepOpts.OutputFile = mDepOutputFileName;
363b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  DepOpts.Targets = mAdditionalDepTargets;
364cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  DepOpts.Targets.push_back(mDepTargetBCFileName);
3654cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  for (std::vector<std::string>::const_iterator
3664cc67fce91f43215d61b2695746eab102a3db516Stephen Hines           I = mGeneratedFileNames.begin(), E = mGeneratedFileNames.end();
3674cc67fce91f43215d61b2695746eab102a3db516Stephen Hines       I != E;
3684cc67fce91f43215d61b2695746eab102a3db516Stephen Hines       I++) {
3694cc67fce91f43215d61b2695746eab102a3db516Stephen Hines    DepOpts.Targets.push_back(*I);
3704cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  }
3714cc67fce91f43215d61b2695746eab102a3db516Stephen Hines  mGeneratedFileNames.clear();
372cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
373e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Per-compilation needed initialization
374cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  createPreprocessor();
375ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murray  clang::DependencyFileGenerator::CreateAndAttachToPreprocessor(*mPP.get(), DepOpts);
376cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
377e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Inform the diagnostic client we are processing a source file
378cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
379cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
380e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Go through the source file (no operations necessary)
381cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  clang::Token Tok;
382cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP->EnterMainSourceFile();
383cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  do {
384cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines    mPP->Lex(Tok);
385cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  } while (Tok.isNot(clang::tok::eof));
386cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
387cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP->EndSourceFile();
388cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
389e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Declare success if no error
3909207a2e495c8363606861e4f034504ec5c153dabLogan Chien  if (!mDiagEngine->hasErrorOccurred())
391e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    mDOS->keep();
392e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
393e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Clean up after compilation
394cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines  mPP.reset();
395e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mDOS.reset();
396cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
3979207a2e495c8363606861e4f034504ec5c153dabLogan Chien  return mDiagEngine->hasErrorOccurred() ? 1 : 0;
398cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines}
399cc0efad052e944f64bb71cfdaa8a825e30192e78Stephen Hines
4002770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Grossint Slang::compile(const RSCCOptions &Opts) {
4019207a2e495c8363606861e4f034504ec5c153dabLogan Chien  if (mDiagEngine->hasErrorOccurred())
402be27482cdeaf08576bc39b72a15d35d13014a636Logan    return 1;
4035abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (mOS.get() == nullptr)
404f7de85223c8728d5dc147e8a19ddf039da72b431Stephen Hines    return 1;
405462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Here is per-compilation needed initialization
4079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createPreprocessor();
4089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  createASTContext();
4093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
4102770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  mBackend.reset(createBackend(Opts, CodeGenOpts, &mOS->os(), mOT));
411462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Inform the diagnostic client we are processing a source file
4139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mDiagClient->BeginSourceFile(LangOpts, mPP.get());
414462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // The core of the slang compiler
4169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ParseAST(*mPP, mBackend.get(), *mASTContext);
417462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
418e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Inform the diagnostic client we are done with previous source file
419e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mDiagClient->EndSourceFile();
420e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
421e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  // Declare success if no error
4229207a2e495c8363606861e4f034504ec5c153dabLogan Chien  if (!mDiagEngine->hasErrorOccurred())
423e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang    mOS->keep();
424e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang
4253a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  // The compilation ended, clear
4269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mBackend.reset();
427e8c263a1c5df81594cf302ecadd813909c894487Zonr Chang  mOS.reset();
428462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4299207a2e495c8363606861e4f034504ec5c153dabLogan Chien  return mDiagEngine->hasErrorOccurred() ? 1 : 0;
430462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
431462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
432c460b37ffb50819a32c2a8967754b6f784b28263mkopecvoid Slang::setDebugMetadataEmission(bool EmitDebug) {
43343730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao  if (EmitDebug)
43423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    CodeGenOpts.setDebugInfo(clang::CodeGenOptions::FullDebugInfo);
43543730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao  else
43623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines    CodeGenOpts.setDebugInfo(clang::CodeGenOptions::NoDebugInfo);
437c460b37ffb50819a32c2a8967754b6f784b28263mkopec}
438c460b37ffb50819a32c2a8967754b6f784b28263mkopec
439c460b37ffb50819a32c2a8967754b6f784b28263mkopecvoid Slang::setOptimizationLevel(llvm::CodeGenOpt::Level OptimizationLevel) {
440c460b37ffb50819a32c2a8967754b6f784b28263mkopec  CodeGenOpts.OptimizationLevel = OptimizationLevel;
441c460b37ffb50819a32c2a8967754b6f784b28263mkopec}
442c460b37ffb50819a32c2a8967754b6f784b28263mkopec
4438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::isFilterscript(const char *Filename) {
4448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  const char *c = strrchr(Filename, '.');
4458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (c && !strncmp(FS_SUFFIX, c + 1, strlen(FS_SUFFIX) + 1)) {
4468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return true;
4478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  } else {
4488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
4498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::generateJavaBitcodeAccessor(const std::string &OutputPathBase,
4538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                          const std::string &PackageName,
4548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                          const std::string *LicenseNote) {
4558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RSSlangReflectUtils::BitCodeAccessorContext BCAccessorContext;
4568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.rsFileName = getInputFileName().c_str();
4585309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  BCAccessorContext.bc32FileName = mOutput32FileName.c_str();
4595309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  BCAccessorContext.bc64FileName = mOutputFileName.c_str();
4608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.reflectPath = OutputPathBase.c_str();
4618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.packageName = PackageName.c_str();
4628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.licenseNote = LicenseNote;
4638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.bcStorage = BCST_JAVA_CODE;   // Must be BCST_JAVA_CODE
4648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  BCAccessorContext.verbose = false;
4658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return RSSlangReflectUtils::GenerateJavaBitCodeAccessor(BCAccessorContext);
4678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::checkODR(const char *CurInputFile) {
4708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::ExportableList::iterator I = mRSContext->exportable_begin(),
4718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mRSContext->exportable_end();
4728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
4738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
4748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    RSExportable *RSE = *I;
4758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (RSE->getKind() != RSExportable::EX_TYPE)
4768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      continue;
4778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    RSExportType *ET = static_cast<RSExportType *>(RSE);
4798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (ET->getClass() != RSExportType::ExportClassRecord)
4808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      continue;
4818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    RSExportRecordType *ERT = static_cast<RSExportRecordType *>(ET);
4838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Artificial record types (create by us not by user in the source) always
4858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // conforms the ODR.
4868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (ERT->isArtificial())
4878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      continue;
4888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Key to lookup ERT in ReflectedDefinitions
4908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    llvm::StringRef RDKey(ERT->getName());
4918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ReflectedDefinitionListTy::const_iterator RD =
4928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ReflectedDefinitions.find(RDKey);
4938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (RD != ReflectedDefinitions.end()) {
4958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const RSExportRecordType *Reflected = RD->getValue().first;
4968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // There's a record (struct) with the same name reflected before. Enforce
4978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // ODR checking - the Reflected must hold *exactly* the same "definition"
4988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // as the one defined previously. We say two record types A and B have the
4998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // same definition iff:
5008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //
5018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  struct A {              struct B {
5028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //    Type(a1) a1,            Type(b1) b1,
5038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //    Type(a2) a2,            Type(b1) b2,
5048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //    ...                     ...
5058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //    Type(aN) aN             Type(b3) b3,
5068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  };                      }
5078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Cond. #1. They have same number of fields, i.e., N = M;
5088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Cond. #2. for (i := 1 to N)
5098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //              Type(ai) = Type(bi) must hold;
5108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Cond. #3. for (i := 1 to N)
5118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //              Name(ai) = Name(bi) must hold;
5128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //
5138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // where,
5148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Type(F) = the type of field F and
5158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      //  Name(F) = the field name.
5168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      bool PassODR = false;
5188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Cond. #1 and Cond. #2
5198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (Reflected->equals(ERT)) {
5208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // Cond #3.
5218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        RSExportRecordType::const_field_iterator AI = Reflected->fields_begin(),
5228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                 BI = ERT->fields_begin();
5238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        for (unsigned i = 0, e = Reflected->getFields().size(); i != e; i++) {
5258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if ((*AI)->getName() != (*BI)->getName())
5268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            break;
5278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          AI++;
5288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          BI++;
5298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
5308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        PassODR = (AI == (Reflected->fields_end()));
5318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!PassODR) {
5345309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        unsigned DiagID = mDiagEngine->getCustomDiagID(
5355309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet            clang::DiagnosticsEngine::Error,
5365309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet            "type '%0' in different translation unit (%1 v.s. %2) "
5375309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet            "has incompatible type definition");
5385309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        getDiagnostics().Report(DiagID) << Reflected->getName()
5395309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                        << getInputFileName()
5405309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                        << RD->getValue().second;
5418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        return false;
5428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    } else {
5448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::StringMapEntry<ReflectedDefinitionTy> *ME =
5458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::StringMapEntry<ReflectedDefinitionTy>::Create(RDKey);
5468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ME->setValue(std::make_pair(ERT, CurInputFile));
5478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5483f45a25c23fa0f2cca4070f4d8713dc1a83f5ff7Matt Wala      if (!ReflectedDefinitions.insert(ME)) {
5493f45a25c23fa0f2cca4070f4d8713dc1a83f5ff7Matt Wala        slangAssert(false && "Type shouldn't be in map yet!");
5503f45a25c23fa0f2cca4070f4d8713dc1a83f5ff7Matt Wala      }
5518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Take the ownership of ERT such that it won't be freed in ~RSContext().
5538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ERT->keep();
5548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return true;
5578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Slang::initPreprocessor() {
5608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::Preprocessor &PP = getPreprocessor();
5618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  std::stringstream RSH;
5638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RSH << PP.getPredefines();
5648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RSH << "#define RS_VERSION " << mTargetAPI << "\n";
5658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  RSH << "#include \"rs_core." RS_HEADER_SUFFIX "\"\n";
5668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  PP.setPredefines(RSH.str());
5678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Slang::initASTContext() {
5708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mRSContext = new RSContext(getPreprocessor(),
5718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             getASTContext(),
5728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             getTargetInfo(),
5738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             &mPragmas,
5748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             mTargetAPI,
5758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                             mVerbose);
5768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::IsRSHeaderFile(const char *File) {
5798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#define RS_HEADER_ENTRY(name)  \
5808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (::strcmp(File, #name "." RS_HEADER_SUFFIX) == 0)  \
5818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return true;
5828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc BrouilletENUM_RS_HEADER()
5838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#undef RS_HEADER_ENTRY
5848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return false;
5858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::IsLocInRSHeaderFile(const clang::SourceLocation &Loc,
5888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                  const clang::SourceManager &SourceMgr) {
5898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::FullSourceLoc FSL(Loc, SourceMgr);
5908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::PresumedLoc PLoc = SourceMgr.getPresumedLoc(FSL);
5918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  const char *Filename = PLoc.getFilename();
5938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!Filename) {
5948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
5958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  } else {
5968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return IsRSHeaderFile(llvm::sys::path::filename(Filename).data());
5978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Slang::compile(
6018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const std::list<std::pair<const char*, const char*> > &IOFiles64,
6028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const std::list<std::pair<const char*, const char*> > &IOFiles32,
6038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const std::list<std::pair<const char*, const char*> > &DepFiles,
6045309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    const RSCCOptions &Opts,
6055309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    clang::DiagnosticOptions &DiagOpts) {
6068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (IOFiles32.empty())
6078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return true;
6088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (Opts.mEmitDependency && (DepFiles.size() != IOFiles32.size())) {
6105309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    unsigned DiagID = mDiagEngine->getCustomDiagID(
6115309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        clang::DiagnosticsEngine::Error,
6125309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        "invalid parameter for output dependencies files.");
6135309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    getDiagnostics().Report(DiagID);
6148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
6158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (Opts.mEmit3264 && (IOFiles64.size() != IOFiles32.size())) {
6188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slangAssert(false && "Should have equal number of 32/64-bit files");
6198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
6208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  std::string RealPackageName;
6238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  const char *InputFile, *Output64File, *Output32File, *BCOutputFile,
6258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet             *DepOutputFile;
6268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  setIncludePaths(Opts.mIncludePaths);
6288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  setOutputType(Opts.mOutputType);
6298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (Opts.mEmitDependency) {
6308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    setAdditionalDepTargets(Opts.mAdditionalDepTargets);
6318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  setDebugMetadataEmission(Opts.mDebugEmission);
6348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  setOptimizationLevel(Opts.mOptimizationLevel);
6368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mAllowRSPrefix = Opts.mAllowRSPrefix;
6388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mTargetAPI = Opts.mTargetAPI;
6408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mTargetAPI != SLANG_DEVELOPMENT_TARGET_API &&
6418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      (mTargetAPI < SLANG_MINIMUM_TARGET_API ||
6428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       mTargetAPI > SLANG_MAXIMUM_TARGET_API)) {
6435309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    unsigned DiagID = mDiagEngine->getCustomDiagID(
6445309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        clang::DiagnosticsEngine::Error,
6455309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet        "target API level '%0' is out of range ('%1' - '%2')");
6465309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    getDiagnostics().Report(DiagID) << mTargetAPI << SLANG_MINIMUM_TARGET_API
6475309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                    << SLANG_MAXIMUM_TARGET_API;
6488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return false;
6498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
651bd0a7ddceac6c135ea975cefbac73877a1f9dae7Stephen Hines  if (mTargetAPI >= SLANG_M_TARGET_API) {
652e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar    LangOpts.NativeHalfType = 1;
653e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar    LangOpts.HalfArgsAndReturns = 1;
654e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar  }
655e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar
6568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  mVerbose = Opts.mVerbose;
6578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Skip generation of warnings a second time if we are doing more than just
6598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // a single pass over the input file.
6608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  bool SuppressAllWarnings = (Opts.mOutputType != Slang::OT_Dependency);
6618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6625309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet  std::list<std::pair<const char*, const char*> >::const_iterator
6635309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      IOFile64Iter = IOFiles64.begin(),
6645309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      IOFile32Iter = IOFiles32.begin(),
6655309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet      DepFileIter = DepFiles.begin();
6668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (unsigned i = 0, e = IOFiles32.size(); i != e; i++) {
6688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    InputFile = IOFile64Iter->first;
6698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    Output64File = IOFile64Iter->second;
6708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    Output32File = IOFile32Iter->second;
6718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!setInputSource(InputFile))
6738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      return false;
6748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!setOutput(Output64File))
6768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      return false;
6778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6785309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    // For use with 64-bit compilation/reflection. This only sets the filename of
6795309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    // the 32-bit bitcode file, and doesn't actually verify it already exists.
6805309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet    mOutput32FileName = Output32File;
6818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mIsFilterscript = isFilterscript(InputFile);
6838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
68468e562f8cac58df367861670e554c3c1f498426cStephen McGroarty    CodeGenOpts.MainFileName = mInputFileName;
68568e562f8cac58df367861670e554c3c1f498426cStephen McGroarty
6862770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross    if (Slang::compile(Opts) > 0)
6878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      return false;
6888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!Opts.mJavaReflectionPackageName.empty()) {
6908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSContext->setReflectJavaPackageName(Opts.mJavaReflectionPackageName);
6918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
6928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const std::string &RealPackageName =
6938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mRSContext->getReflectJavaPackageName();
6948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    bool doReflection = true;
6968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (Opts.mEmit3264 && (Opts.mBitWidth == 32)) {
6978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Skip reflection on the 32-bit path if we are going to emit it on the
6988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // 64-bit path.
6998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      doReflection = false;
7008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (Opts.mOutputType != Slang::OT_Dependency && doReflection) {
7028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (Opts.mBitcodeStorage == BCST_CPP_CODE) {
7048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const std::string &outputFileName = (Opts.mBitWidth == 64) ?
7055309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                                            mOutputFileName : mOutput32FileName;
7068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        RSReflectionCpp R(mRSContext, Opts.mJavaReflectionPathBase,
7078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                          getInputFileName(), outputFileName);
7088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!R.reflect()) {
7098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            return false;
7108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      } else {
7128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!Opts.mRSPackageName.empty()) {
7138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          mRSContext->setRSPackageName(Opts.mRSPackageName);
7148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
716ff5abc6892aedb25215689bd679eb7cc1588a8e3Jean-Luc Brouillet        std::vector<std::string> generatedFileNames;
717ff5abc6892aedb25215689bd679eb7cc1588a8e3Jean-Luc Brouillet        RSReflectionJava R(mRSContext, &generatedFileNames,
7188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                           Opts.mJavaReflectionPathBase, getInputFileName(),
7195309b0cbeda2c75eedf6627e06f4471c77f98f83Jean-Luc Brouillet                           mOutputFileName,
7208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                           Opts.mBitcodeStorage == BCST_JAVA_CODE);
7218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!R.reflect()) {
7228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // TODO Is this needed or will the error message have been printed
7238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // already? and why not for the C++ case?
7248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          fprintf(stderr, "RSContext::reflectToJava : failed to do reflection "
7258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                          "(%s)\n",
7268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  R.getLastError());
7278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          return false;
7288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        for (std::vector<std::string>::const_iterator
731ff5abc6892aedb25215689bd679eb7cc1588a8e3Jean-Luc Brouillet                 I = generatedFileNames.begin(), E = generatedFileNames.end();
7328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet             I != E;
7338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet             I++) {
7348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          std::string ReflectedName = RSSlangReflectUtils::ComputePackagedPath(
7358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              Opts.mJavaReflectionPathBase.c_str(),
7368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              (RealPackageName + OS_PATH_SEPARATOR_STR + *I).c_str());
7378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          appendGeneratedFileName(ReflectedName + ".java");
7388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if ((Opts.mOutputType == Slang::OT_Bitcode) &&
7418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            (Opts.mBitcodeStorage == BCST_JAVA_CODE) &&
7428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            !generateJavaBitcodeAccessor(Opts.mJavaReflectionPathBase,
7438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                         RealPackageName.c_str(),
7448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                         mRSContext->getLicenseNote())) {
7458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          return false;
7468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (Opts.mEmitDependency) {
7518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      BCOutputFile = DepFileIter->first;
7528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      DepOutputFile = DepFileIter->second;
7538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      setDepTargetBC(BCOutputFile);
7558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!setDepOutput(DepOutputFile))
7578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        return false;
7588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (SuppressAllWarnings) {
7608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        getDiagnostics().setSuppressAllDiagnostics(true);
7618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
76221c94c9b4cc3c139c0d2c08f81e773aa3e269cffYing Wang      if (generateDepFile(Opts.mEmitPhonyDependency) > 0)
7638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        return false;
7648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (SuppressAllWarnings) {
7658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        getDiagnostics().setSuppressAllDiagnostics(false);
7668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      DepFileIter++;
7698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!checkODR(InputFile))
7728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      return false;
7738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    IOFile64Iter++;
7758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    IOFile32Iter++;
7768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return true;
778462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
779e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
780e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
781