slang_rs.cpp revision 4cc67fce91f43215d61b2695746eab102a3db516
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 173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "slang_rs.h" 183a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 19b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao#include <cstring> 20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <list> 21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <string> 22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <utility> 23e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <vector> 24fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines 25cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang#include "clang/Frontend/FrontendDiagnostic.h" 26cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Sema/SemaDiagnostic.h" 283a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 29e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/System/Path.h" 30e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 313a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "slang_rs_backend.h" 323a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "slang_rs_context.h" 33641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang#include "slang_rs_export_type.h" 343a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 35e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 363a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 373c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang#define RS_HEADER_SUFFIX "rsh" 383c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang 393ab021f5913736512343730d91e771037954061bZonr Chang/* RS_HEADER_ENTRY(name, default_included) */ 403c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang#define ENUM_RS_HEADER() \ 413ab021f5913736512343730d91e771037954061bZonr Chang RS_HEADER_ENTRY(rs_types, 1) \ 423ab021f5913736512343730d91e771037954061bZonr Chang RS_HEADER_ENTRY(rs_cl, 1) \ 433ab021f5913736512343730d91e771037954061bZonr Chang RS_HEADER_ENTRY(rs_core, 1) \ 44125052390460773d0a4531d5bd26cdb704d08c93Stephen Hines RS_HEADER_ENTRY(rs_math, 1) \ 45125052390460773d0a4531d5bd26cdb704d08c93Stephen Hines RS_HEADER_ENTRY(rs_time, 1) \ 463ab021f5913736512343730d91e771037954061bZonr Chang RS_HEADER_ENTRY(rs_graphics, 0) 473c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang 48cf6af6abc1de499920571308b14a27e19cf57097Zonr Changbool SlangRS::reflectToJava(const std::string &OutputPathBase, 49cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang const std::string &OutputPackageName, 50cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang std::string *RealPackageName) { 51cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang return mRSContext->reflectToJava(OutputPathBase, 52cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang OutputPackageName, 53cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang getInputFileName(), 54cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang getOutputFileName(), 55cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang RealPackageName); 56cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang} 57cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 58cf6af6abc1de499920571308b14a27e19cf57097Zonr Changbool SlangRS::generateBitcodeAccessor(const std::string &OutputPathBase, 59cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang const std::string &PackageName) { 60cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang RSSlangReflectUtils::BitCodeAccessorContext BCAccessorContext; 61cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 62cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang BCAccessorContext.rsFileName = getInputFileName().c_str(); 63cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang BCAccessorContext.bcFileName = getOutputFileName().c_str(); 64cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang BCAccessorContext.reflectPath = OutputPathBase.c_str(); 65cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang BCAccessorContext.packageName = PackageName.c_str(); 66cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang BCAccessorContext.bcStorage = BCST_JAVA_CODE; // Must be BCST_JAVA_CODE 67cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 68cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang return RSSlangReflectUtils::GenerateBitCodeAccessor(BCAccessorContext); 69cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang} 70cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 71e86245a09bb8b9e72f5dc68083444ec938865798Zonr Changbool SlangRS::checkODR(const char *CurInputFile) { 72641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (RSContext::ExportableList::iterator I = mRSContext->exportable_begin(), 73641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang E = mRSContext->exportable_end(); 74641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I != E; 75641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I++) { 76a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines RSExportable *RSE = *I; 77a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines if (RSE->getKind() != RSExportable::EX_TYPE) 78641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang continue; 79641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 80a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines RSExportType *ET = static_cast<RSExportType *>(RSE); 81641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (ET->getClass() != RSExportType::ExportClassRecord) 82641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang continue; 83641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 84641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang RSExportRecordType *ERT = static_cast<RSExportRecordType *>(ET); 85641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 86641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Artificial record types (create by us not by user in the source) always 87641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // conforms the ODR. 88641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (ERT->isArtificial()) 89641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang continue; 90641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 91641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Key to lookup ERT in ReflectedDefinitions 92641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang llvm::StringRef RDKey(ERT->getName()); 93641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang ReflectedDefinitionListTy::const_iterator RD = 94641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang ReflectedDefinitions.find(RDKey); 95641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 96641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (RD != ReflectedDefinitions.end()) { 97641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const RSExportRecordType *Reflected = RD->getValue().first; 98641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // There's a record (struct) with the same name reflected before. Enforce 99641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // ODR checking - the Reflected must hold *exactly* the same "definition" 100641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // as the one defined previously. We say two record types A and B have the 101641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // same definition iff: 102641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // 103641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // struct A { struct B { 104641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Type(a1) a1, Type(b1) b1, 105641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Type(a2) a2, Type(b1) b2, 106641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // ... ... 107641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Type(aN) aN Type(b3) b3, 108641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // }; } 109641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Cond. #1. They have same number of fields, i.e., N = M; 110641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Cond. #2. for (i := 1 to N) 111641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Type(ai) = Type(bi) must hold; 112641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Cond. #3. for (i := 1 to N) 113641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Name(ai) = Name(bi) must hold; 114641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // 115641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // where, 116641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Type(F) = the type of field F and 117641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Name(F) = the field name. 118641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 119641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang bool PassODR = false; 120641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Cond. #1 and Cond. #2 121641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (Reflected->equals(ERT)) { 122641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Cond #3. 123641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang RSExportRecordType::const_field_iterator AI = Reflected->fields_begin(), 124641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang BI = ERT->fields_begin(); 125641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 126641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (unsigned i = 0, e = Reflected->getFields().size(); i != e; i++) { 127641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if ((*AI)->getName() != (*BI)->getName()) 128641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang break; 129641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang AI++; 130641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang BI++; 131641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 132641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang PassODR = (AI == (Reflected->fields_end())); 133641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 134641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 135641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!PassODR) { 136641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang getDiagnostics().Report(mDiagErrorODR) << Reflected->getName() 137641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang << getInputFileName() 138641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang << RD->getValue().second; 139641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 140641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 141641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } else { 142641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang llvm::StringMapEntry<ReflectedDefinitionTy> *ME = 143641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang llvm::StringMapEntry<ReflectedDefinitionTy>::Create(RDKey.begin(), 144641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang RDKey.end()); 145e86245a09bb8b9e72f5dc68083444ec938865798Zonr Chang ME->setValue(std::make_pair(ERT, CurInputFile)); 146641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 147641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!ReflectedDefinitions.insert(ME)) 148641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang delete ME; 149641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 150641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Take the ownership of ERT such that it won't be freed in ~RSContext(). 151641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang ERT->keep(); 152641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 153641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 154641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return true; 155641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 156cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 1573a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid SlangRS::initDiagnostic() { 1583a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang clang::Diagnostic &Diag = getDiagnostics(); 159cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang if (Diag.setDiagnosticGroupMapping("implicit-function-declaration", 160cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang clang::diag::MAP_ERROR)) 161cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang Diag.Report(clang::diag::warn_unknown_warning_option) 162cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang << "implicit-function-declaration"; 163cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 1643a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang Diag.setDiagnosticMapping( 1653a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang clang::diag::ext_typecheck_convert_discards_qualifiers, 1663a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang clang::diag::MAP_ERROR); 167641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 168641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang mDiagErrorInvalidOutputDepParameter = 169641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang Diag.getCustomDiagID(clang::Diagnostic::Error, 170641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang "invalid parameter for output dependencies files."); 171641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 172641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang mDiagErrorODR = 173641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang Diag.getCustomDiagID(clang::Diagnostic::Error, 174641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang "type '%0' in different translation unit (%1 v.s. " 175641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang "%2) has incompatible type definition"); 176641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1773a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return; 1783a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 1793a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 1803a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid SlangRS::initPreprocessor() { 1813a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang clang::Preprocessor &PP = getPreprocessor(); 1823a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 1833c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang std::string RSH; 1843ab021f5913736512343730d91e771037954061bZonr Chang#define RS_HEADER_ENTRY(name, default_included) \ 1853ab021f5913736512343730d91e771037954061bZonr Chang if (default_included) \ 1863ab021f5913736512343730d91e771037954061bZonr Chang RSH.append("#include \"" #name "."RS_HEADER_SUFFIX "\"\n"); 1873ab021f5913736512343730d91e771037954061bZonr Chang ENUM_RS_HEADER() 1883c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang#undef RS_HEADER_ENTRY 1893c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang PP.setPredefines(RSH); 1903c250c5d6cbf4123e959a3466990fda9fa50987aZonr Chang 1913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return; 1923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 1933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 1943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid SlangRS::initASTContext() { 1959e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines mRSContext = new RSContext(getPreprocessor(), 1969e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines getASTContext(), 1973fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines getTargetInfo(), 1984cc67fce91f43215d61b2695746eab102a3db516Stephen Hines &mPragmas, 1994cc67fce91f43215d61b2695746eab102a3db516Stephen Hines &mGeneratedFileNames); 2003a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return; 2013a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 2023a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 2033a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changclang::ASTConsumer 2043a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang*SlangRS::createBackend(const clang::CodeGenOptions& CodeGenOpts, 2053a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang llvm::raw_ostream *OS, 2063a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang Slang::OutputType OT) { 2073a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return new RSBackend(mRSContext, 208e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines &getDiagnostics(), 2093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang CodeGenOpts, 2103a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang getTargetOptions(), 2113fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines &mPragmas, 2123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang OS, 2133a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang OT, 2143a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang getSourceManager(), 2153a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mAllowRSPrefix); 2163a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 2173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 218592a954aae4cb946970b557e94afd5ee453fd57eZonr Changbool SlangRS::IsRSHeaderFile(const char *File) { 2193ab021f5913736512343730d91e771037954061bZonr Chang#define RS_HEADER_ENTRY(name, default_included) \ 2203ab021f5913736512343730d91e771037954061bZonr Chang if (::strcmp(File, #name "."RS_HEADER_SUFFIX) == 0) \ 221592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang return true; 222592a954aae4cb946970b557e94afd5ee453fd57eZonr ChangENUM_RS_HEADER() 223592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang#undef RS_HEADER_ENTRY 224592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang return false; 225592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang} 226592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang 227fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hinesbool SlangRS::IsFunctionInRSHeaderFile(const clang::FunctionDecl *FD, 228fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines const clang::SourceManager &SourceMgr) { 229fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines clang::FullSourceLoc FSL(FD->getLocStart(), SourceMgr); 230fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines clang::PresumedLoc PLoc = SourceMgr.getPresumedLoc(FSL); 231fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines llvm::sys::Path HeaderFilename(PLoc.getFilename()); 232fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines 233fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines return IsRSHeaderFile(HeaderFilename.getLast().data()); 234fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines} 235fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines 236641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr ChangSlangRS::SlangRS() : Slang(), mRSContext(NULL), mAllowRSPrefix(false) { 2373a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return; 2383a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 2393a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 240cf6af6abc1de499920571308b14a27e19cf57097Zonr Changbool SlangRS::compile( 241cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang const std::list<std::pair<const char*, const char*> > &IOFiles, 242cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang const std::list<std::pair<const char*, const char*> > &DepFiles, 243cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang const std::vector<std::string> &IncludePaths, 244cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang const std::vector<std::string> &AdditionalDepTargets, 245cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang Slang::OutputType OutputType, BitCodeStorageType BitcodeStorage, 246cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang bool AllowRSPrefix, bool OutputDep, 247cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang const std::string &JavaReflectionPathBase, 248cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang const std::string &JavaReflectionPackageName) { 249cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang if (IOFiles.empty()) 250cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang return true; 251cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 252cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang if (OutputDep && (DepFiles.size() != IOFiles.size())) { 253641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang getDiagnostics().Report(mDiagErrorInvalidOutputDepParameter); 2543a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return false; 255cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang } 2563a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 257cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang std::string RealPackageName; 258cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 259cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang const char *InputFile, *OutputFile, *BCOutputFile, *DepOutputFile; 260cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang std::list<std::pair<const char*, const char*> >::const_iterator 261cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang IOFileIter = IOFiles.begin(), DepFileIter = DepFiles.begin(); 262cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 263cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang setIncludePaths(IncludePaths); 264cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang setOutputType(OutputType); 2654cc67fce91f43215d61b2695746eab102a3db516Stephen Hines if (OutputDep) { 266cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang setAdditionalDepTargets(AdditionalDepTargets); 2674cc67fce91f43215d61b2695746eab102a3db516Stephen Hines } 268cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 269cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang mAllowRSPrefix = AllowRSPrefix; 270cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 271cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang for (unsigned i = 0, e = IOFiles.size(); i != e; i++) { 272cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang InputFile = IOFileIter->first; 273cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang OutputFile = IOFileIter->second; 274cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 275cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang reset(); 276cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 277cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang if (!setInputSource(InputFile)) 278cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang return false; 279cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 280cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang if (!setOutput(OutputFile)) 281cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang return false; 282cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 283cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang if (Slang::compile() > 0) 284cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang return false; 285cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 286cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang if (OutputType != Slang::OT_Dependency) { 287cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang if (!reflectToJava(JavaReflectionPathBase, 288cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang JavaReflectionPackageName, 289cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang &RealPackageName)) 290cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang return false; 291cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 2924cc67fce91f43215d61b2695746eab102a3db516Stephen Hines for (std::vector<std::string>::const_iterator 2934cc67fce91f43215d61b2695746eab102a3db516Stephen Hines I = mGeneratedFileNames.begin(), E = mGeneratedFileNames.end(); 2944cc67fce91f43215d61b2695746eab102a3db516Stephen Hines I != E; 2954cc67fce91f43215d61b2695746eab102a3db516Stephen Hines I++) { 2964cc67fce91f43215d61b2695746eab102a3db516Stephen Hines std::string ReflectedName = RSSlangReflectUtils::ComputePackagedPath( 2974cc67fce91f43215d61b2695746eab102a3db516Stephen Hines JavaReflectionPathBase.c_str(), 2984cc67fce91f43215d61b2695746eab102a3db516Stephen Hines (RealPackageName + "/" + *I).c_str()); 2994cc67fce91f43215d61b2695746eab102a3db516Stephen Hines appendGeneratedFileName(ReflectedName + ".java"); 3004cc67fce91f43215d61b2695746eab102a3db516Stephen Hines } 3014cc67fce91f43215d61b2695746eab102a3db516Stephen Hines 302cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang if ((OutputType == Slang::OT_Bitcode) && 303cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang (BitcodeStorage == BCST_JAVA_CODE) && 304cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang !generateBitcodeAccessor(JavaReflectionPathBase, 305cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang RealPackageName.c_str())) 306cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang return false; 307cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang } 308cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 3094cc67fce91f43215d61b2695746eab102a3db516Stephen Hines if (OutputDep) { 3104cc67fce91f43215d61b2695746eab102a3db516Stephen Hines BCOutputFile = DepFileIter->first; 3114cc67fce91f43215d61b2695746eab102a3db516Stephen Hines DepOutputFile = DepFileIter->second; 3124cc67fce91f43215d61b2695746eab102a3db516Stephen Hines 3134cc67fce91f43215d61b2695746eab102a3db516Stephen Hines setDepTargetBC(BCOutputFile); 3144cc67fce91f43215d61b2695746eab102a3db516Stephen Hines 3154cc67fce91f43215d61b2695746eab102a3db516Stephen Hines if (!setDepOutput(DepOutputFile)) 3164cc67fce91f43215d61b2695746eab102a3db516Stephen Hines return false; 3174cc67fce91f43215d61b2695746eab102a3db516Stephen Hines 3184cc67fce91f43215d61b2695746eab102a3db516Stephen Hines if (generateDepFile() > 0) 3194cc67fce91f43215d61b2695746eab102a3db516Stephen Hines return false; 3204cc67fce91f43215d61b2695746eab102a3db516Stephen Hines 3214cc67fce91f43215d61b2695746eab102a3db516Stephen Hines DepFileIter++; 3224cc67fce91f43215d61b2695746eab102a3db516Stephen Hines } 3234cc67fce91f43215d61b2695746eab102a3db516Stephen Hines 324e86245a09bb8b9e72f5dc68083444ec938865798Zonr Chang if (!checkODR(InputFile)) 325641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 326641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 327cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang IOFileIter++; 328cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang } 329cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang 330cf6af6abc1de499920571308b14a27e19cf57097Zonr Chang return true; 3313a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 3323a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang 333641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changvoid SlangRS::reset() { 334641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang delete mRSContext; 335641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang mRSContext = NULL; 3364cc67fce91f43215d61b2695746eab102a3db516Stephen Hines mGeneratedFileNames.clear(); 337641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang Slang::reset(); 338641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return; 339641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 340641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 3413a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr ChangSlangRS::~SlangRS() { 3423a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang delete mRSContext; 343641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (ReflectedDefinitionListTy::iterator I = ReflectedDefinitions.begin(), 344641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang E = ReflectedDefinitions.end(); 345641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I != E; 346641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I++) { 347641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang delete I->getValue().first; 348641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 3493a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang return; 3503a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang} 351e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 352e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 353