slang_rs_context.cpp revision c17e198ffcd37bfc57e3add1f6eee952ae2a2eab
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 29999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines * Copyright 2010-2012, The Android Open Source Project 3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License. 6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at 7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software 11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and 14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License. 15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */ 16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <string> 2041ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang 21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/ASTContext.h" 229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/Decl.h" 239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/DeclBase.h" 24be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "clang/AST/Mangle.h" 25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/Type.h" 26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/Linkage.h" 28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/TargetInfo.h" 2941ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang 309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Index/ASTLocation.h" 319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 32e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/LLVMContext.h" 33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 34e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Target/TargetData.h" 35e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 366315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang.h" 376e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 38593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "slang_rs_export_foreach.h" 396315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h" 406315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h" 41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_export_var.h" 42e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_exportable.h" 436315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_pragma_handler.h" 44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_reflection.h" 459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 46e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 489e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen HinesRSContext::RSContext(clang::Preprocessor &PP, 499e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines clang::ASTContext &Ctx, 503fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines const clang::TargetInfo &Target, 514cc67fce91f43215d61b2695746eab102a3db516Stephen Hines PragmaList *Pragmas, 524a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines unsigned int TargetAPI, 534cc67fce91f43215d61b2695746eab102a3db516Stephen Hines std::vector<std::string> *GeneratedFileNames) 546315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr : mPP(PP), 556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mCtx(Ctx), 566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mTarget(Target), 573fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines mPragmas(Pragmas), 584a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines mTargetAPI(TargetAPI), 594cc67fce91f43215d61b2695746eab102a3db516Stephen Hines mGeneratedFileNames(GeneratedFileNames), 606315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mTargetData(NULL), 616315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mLLVMContext(llvm::getGlobalContext()), 6296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines mLicenseNote(NULL), 633fa286b4c2f110c6be2bbfac9c715bb1ec880338Shih-wei Liao version(0), 64be27482cdeaf08576bc39b72a15d35d13014a636Logan mMangleCtx(Ctx.createMangleContext()) { 656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames"); 664cc67fce91f43215d61b2695746eab102a3db516Stephen Hines 679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // For #pragma rs export_type 689e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines PP.AddPragmaHandler( 699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao "rs", RSPragmaHandler::CreatePragmaExportTypeHandler(this)); 70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // For #pragma rs java_package_name 729e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines PP.AddPragmaHandler( 739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao "rs", RSPragmaHandler::CreatePragmaJavaPackageNameHandler(this)); 749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // For #pragma rs set_reflect_license 769e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines PP.AddPragmaHandler( 779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao "rs", RSPragmaHandler::CreatePragmaReflectLicenseHandler(this)); 789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines // For #pragma version 8096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines PP.AddPragmaHandler(RSPragmaHandler::CreatePragmaVersionHandler(this)); 8196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Prepare target data 839e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines mTargetData = new llvm::TargetData(Target.getTargetDescription()); 849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 86462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 87462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::processExportVar(const clang::VarDecl *VD) { 896e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(!VD->getName().empty() && "Variable name should not be empty"); 90537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao 916315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // TODO(zonr): some check on variable 92462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET = RSExportType::CreateFromDecl(this, VD); 949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!ET) 959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportVar *EV = new RSExportVar(this, VD, ET); 989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EV == NULL) 999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mExportVars.push_back(EV); 102462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 104462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 105462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1066315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrbool RSContext::processExportFunc(const clang::FunctionDecl *FD) { 1076e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(!FD->getName().empty() && "Function name should not be empty"); 108462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1093fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines if (!FD->isThisDeclarationADefinition()) { 1103fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines return true; 1113fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines } 112462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (FD->getStorageClass() != clang::SC_None) { 1149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao fprintf(stderr, "RSContext::processExportFunc : cannot export extern or " 1159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao "static function '%s'\n", FD->getName().str().c_str()); 1169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 118462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1199999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines if (RSExportForEach::isSpecialRSFunc(mTargetAPI, FD)) { 1209999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines // Do not reflect specialized functions like init, dtor, or graphics root. 1219999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines return RSExportForEach::validateSpecialFuncDecl(mTargetAPI, 1229999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines getDiagnostics(), FD); 1239999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines } else if (RSExportForEach::isRSForEachFunc(mTargetAPI, FD)) { 124593a894650e81be54173106ec266f0311cebebd3Stephen Hines RSExportForEach *EFE = RSExportForEach::Create(this, FD); 125593a894650e81be54173106ec266f0311cebebd3Stephen Hines if (EFE == NULL) 126593a894650e81be54173106ec266f0311cebebd3Stephen Hines return false; 127593a894650e81be54173106ec266f0311cebebd3Stephen Hines else 128593a894650e81be54173106ec266f0311cebebd3Stephen Hines mExportForEach.push_back(EFE); 129593a894650e81be54173106ec266f0311cebebd3Stephen Hines return true; 1303fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines } 1313fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines 1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportFunc *EF = RSExportFunc::Create(this, FD); 1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EF == NULL) 1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 1369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mExportFuncs.push_back(EF); 137462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 1399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 140462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 141462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::processExportType(const llvm::StringRef &Name) { 1439e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines clang::TranslationUnitDecl *TUDecl = mCtx.getTranslationUnitDecl(); 144462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1456e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(TUDecl != NULL && "Translation unit declaration (top-level " 1466e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "declaration) is null object"); 147f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao 1489e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines const clang::IdentifierInfo *II = mPP.getIdentifierInfo(Name); 1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (II == NULL) 1506315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // TODO(zonr): alert identifier @Name mark as an exportable type cannot be 1516315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // found 1529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 153f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao 1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::DeclContext::lookup_const_result R = TUDecl->lookup(II); 1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET = NULL; 156f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao 1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::DeclContext::lookup_const_iterator I = R.first, E = R.second; 1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I != E; 1599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I++) { 1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::NamedDecl *const ND = *I; 1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T = NULL; 162462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (ND->getKind()) { 1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Decl::Typedef: { 1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = static_cast<const clang::TypedefDecl*>( 1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ND)->getCanonicalDecl()->getUnderlyingType().getTypePtr(); 1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Decl::Record: { 1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = static_cast<const clang::RecordDecl*>(ND)->getTypeForDecl(); 1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // unsupported, skip 1759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 176ac91815eb4918b9307ec876f34f2b60adf28c78bShih-wei Liao } 177ac91815eb4918b9307ec876f34f2b60adf28c78bShih-wei Liao } 178537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao 1799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (T != NULL) 1809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportType::Create(this, T); 1819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 182462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return (ET != NULL); 184462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 185462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 186c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines 187c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines// Possibly re-order ForEach exports (maybe generating a dummy "root" function). 188c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines// We require "root" to be listed as slot 0 of our exported compute kernels, 189c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines// so this only needs to be created if we have other non-root kernels. 190c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hinesvoid RSContext::cleanupForEach() { 191c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines bool foundNonRoot = false; 192c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines ExportForEachList::iterator begin = mExportForEach.begin(); 193c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines 194c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines for (ExportForEachList::iterator I = begin, E = mExportForEach.end(); 195c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines I != E; 196c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines I++) { 197c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines RSExportForEach *EFE = *I; 198c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines if (!EFE->getName().compare("root")) { 199c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines if (I == begin) { 200c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines // Nothing to do, since it is the first function 201c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines return; 202c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines } 203c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines 204c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines mExportForEach.erase(I); 205c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines mExportForEach.push_front(EFE); 206c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines return; 207c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines } else { 208c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines foundNonRoot = true; 209c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines } 210c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines } 211c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines 212c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines // If we found a non-root kernel, but no root() function, we need to add a 213c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines // dummy version (so that script->script calls of rsForEach don't behave 214c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines // erratically). 215c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines if (foundNonRoot) { 216c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines RSExportForEach *DummyRoot = RSExportForEach::CreateDummyRoot(this); 217c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines mExportForEach.push_front(DummyRoot); 218c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines } 219c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines} 220c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines 221c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines 222c808a99831115928b4648f4c8b86dc682594217aStephen Hinesbool RSContext::processExport() { 223b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines bool valid = true; 224593a894650e81be54173106ec266f0311cebebd3Stephen Hines 225593a894650e81be54173106ec266f0311cebebd3Stephen Hines if (getDiagnostics()->hasErrorOccurred()) { 226593a894650e81be54173106ec266f0311cebebd3Stephen Hines return false; 227593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 228593a894650e81be54173106ec266f0311cebebd3Stephen Hines 2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Export variable 2309e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines clang::TranslationUnitDecl *TUDecl = mCtx.getTranslationUnitDecl(); 2319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(), 2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DE = TUDecl->decls_end(); 233c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines DI != DE; 2349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DI++) { 2359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (DI->getKind() == clang::Decl::Var) { 2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::VarDecl *VD = (clang::VarDecl*) (*DI); 2372d2512c5703bb238b7935ab5228beff6563f2f94Stephen Hines if (VD->getLinkage() == clang::ExternalLinkage) { 2389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!processExportVar(VD)) { 239b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines valid = false; 2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else if (DI->getKind() == clang::Decl::Function) { 2439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Export functions 2449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::FunctionDecl *FD = (clang::FunctionDecl*) (*DI); 2452d2512c5703bb238b7935ab5228beff6563f2f94Stephen Hines if (FD->getLinkage() == clang::ExternalLinkage) { 2469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!processExportFunc(FD)) { 247b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines valid = false; 2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2503f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 253c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines if (valid) { 254c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines cleanupForEach(); 255c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines } 256c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines 2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Finally, export type forcely set to be exported by user 2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (NeedExportTypeSet::const_iterator EI = mNeedExportTypes.begin(), 2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EE = mNeedExportTypes.end(); 2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI != EE; 2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI++) { 2629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!processExportType(EI->getKey())) { 263b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines valid = false; 2643f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 2659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 267b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines return valid; 2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 269537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao 2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::insertExportType(const llvm::StringRef &TypeName, 2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET) { 2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportTypeMap::value_type *NewItem = 2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportTypeMap::value_type::Create(TypeName.begin(), 2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName.end(), 2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mExportTypes.getAllocator(), 2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET); 2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mExportTypes.insert(NewItem)) { 2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 2809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao free(NewItem); 2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 2839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 284462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 285462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 286b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaobool RSContext::reflectToJava(const std::string &OutputPathBase, 287b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao const std::string &OutputPackageName, 2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const std::string &InputFileName, 2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const std::string &OutputBCFileName, 290b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao std::string *RealPackageName) { 291b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao if (RealPackageName != NULL) 292b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao RealPackageName->clear(); 293b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao 294b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao const std::string &PackageName = 295b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao ((OutputPackageName.empty()) ? mReflectJavaPackageName : 296b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao OutputPackageName); 29735f5b39f0490953f1fe13ef803b43e3ced9a01d9Stephen Hines if (PackageName.empty()) { 2987aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines clang::DiagnosticsEngine *DiagEngine = getDiagnostics(); 2997aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines const clang::SourceManager *SM = getSourceManager(); 3007aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines DiagEngine->Report( 3017aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines SM->getLocForEndOfFile(SM->getMainFileID()), 3027aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 3037aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines "missing \"#pragma rs " 3047aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines "java_package_name(com.foo.bar)\" " 3057aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines "in source file")); 30635f5b39f0490953f1fe13ef803b43e3ced9a01d9Stephen Hines return false; 30735f5b39f0490953f1fe13ef803b43e3ced9a01d9Stephen Hines } 3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Copy back the really applied package name 310b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao RealPackageName->assign(PackageName); 3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3124cc67fce91f43215d61b2695746eab102a3db516Stephen Hines RSReflection *R = new RSReflection(this, mGeneratedFileNames); 313b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao bool ret = R->reflect(OutputPathBase, PackageName, 314b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao InputFileName, OutputBCFileName); 3156315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr if (!ret) 3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao fprintf(stderr, "RSContext::reflectToJava : failed to do reflection " 3179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao "(%s)\n", R->getLastError()); 3189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete R; 3199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ret; 3209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 3216de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao 322462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSContext::~RSContext() { 3239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete mLicenseNote; 3249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete mTargetData; 325a41ce1d98094da84643995d40d71c529905123fcZonr Chang for (ExportableList::iterator I = mExportables.begin(), 326a41ce1d98094da84643995d40d71c529905123fcZonr Chang E = mExportables.end(); 327a41ce1d98094da84643995d40d71c529905123fcZonr Chang I != E; 328a41ce1d98094da84643995d40d71c529905123fcZonr Chang I++) { 329641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!(*I)->isKeep()) 330641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang delete *I; 331a41ce1d98094da84643995d40d71c529905123fcZonr Chang } 332462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 333e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 334e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 335