slang_rs_context.cpp revision 3fbe68a4ec20fec25f8a40191437bbc02d00f591
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_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"
24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/Type.h"
25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/Linkage.h"
27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/TargetInfo.h"
2841ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang
299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Index/ASTLocation.h"
309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/LLVMContext.h"
32e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Target/TargetData.h"
34e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang.h"
366315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h"
376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h"
38e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_export_var.h"
39e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_exportable.h"
406315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_pragma_handler.h"
41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_reflection.h"
429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
459e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen HinesRSContext::RSContext(clang::Preprocessor &PP,
469e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines                     clang::ASTContext &Ctx,
479e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines                     const clang::TargetInfo &Target)
486315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    : mPP(PP),
496315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mCtx(Ctx),
506315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mTarget(Target),
516315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mTargetData(NULL),
526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mLLVMContext(llvm::getGlobalContext()),
532df25dbc3b09764b7bed9f02aee7cbd3d9720ef2Stephen Hines      mExportAllNonStaticVars(true),
543fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines      mExportAllNonStaticFuncs(true),
556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mLicenseNote(NULL) {
569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // For #pragma rs export_var
579e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  PP.AddPragmaHandler(
589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      "rs", RSPragmaHandler::CreatePragmaExportVarHandler(this));
59462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // For #pragma rs export_var_all
619e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  PP.AddPragmaHandler(
629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      "rs", RSPragmaHandler::CreatePragmaExportVarAllHandler(this));
63462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // For #pragma rs export_func
659e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  PP.AddPragmaHandler(
669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      "rs", RSPragmaHandler::CreatePragmaExportFuncHandler(this));
67462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // For #pragma rs export_func_all
699e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  PP.AddPragmaHandler(
709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      "rs", RSPragmaHandler::CreatePragmaExportFuncAllHandler(this));
71462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // For #pragma rs export_type
739e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  PP.AddPragmaHandler(
749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      "rs", RSPragmaHandler::CreatePragmaExportTypeHandler(this));
75462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // For #pragma rs java_package_name
779e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  PP.AddPragmaHandler(
789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      "rs", RSPragmaHandler::CreatePragmaJavaPackageNameHandler(this));
799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // For #pragma rs set_reflect_license
819e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  PP.AddPragmaHandler(
829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      "rs", RSPragmaHandler::CreatePragmaReflectLicenseHandler(this));
839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Prepare target data
859e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  mTargetData = new llvm::TargetData(Target.getTargetDescription());
869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
88462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
89462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::processExportVar(const clang::VarDecl *VD) {
919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  assert(!VD->getName().empty() && "Variable name should not be empty");
92537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao
936315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  // TODO(zonr): some check on variable
94462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  RSExportType *ET = RSExportType::CreateFromDecl(this, VD);
969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!ET)
979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
98462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  RSExportVar *EV = new RSExportVar(this, VD, ET);
1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (EV == NULL)
1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
1029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
1039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mExportVars.push_back(EV);
104462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
106462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
107462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1083fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hinesstatic bool isSpecialRSFunc(const llvm::StringRef& Name) {
1093fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines  static llvm::StringRef FuncInit("init");
1103fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines  static llvm::StringRef FuncRoot("root");
1113fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines  return Name.equals(FuncInit) || Name.equals(FuncRoot);
1123fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines}
1133fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines
1146315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrbool RSContext::processExportFunc(const clang::FunctionDecl *FD) {
1159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  assert(!FD->getName().empty() && "Function name should not be empty");
116462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1173fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines  if (!FD->isThisDeclarationADefinition()) {
1183fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines    return true;
1193fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines  }
120462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (FD->getStorageClass() != clang::SC_None) {
1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    fprintf(stderr, "RSContext::processExportFunc : cannot export extern or "
1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                    "static function '%s'\n", FD->getName().str().c_str());
1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1273fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines  // Do not reflect specialized RS functions like init/root.
1283fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines  if (isSpecialRSFunc(FD->getName())) {
1293fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen 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
1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  assert(TUDecl != NULL && "Translation unit declaration (top-level "
1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                           "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
1579e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  RSExportPointerType::IntegerType = mCtx.IntTy.getTypePtr();
158462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (clang::DeclContext::lookup_const_iterator I = R.first, E = R.second;
1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       I != E;
1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       I++) {
1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    clang::NamedDecl *const ND = *I;
1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    const clang::Type *T = NULL;
164462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    switch (ND->getKind()) {
1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      case clang::Decl::Typedef: {
1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        T = static_cast<const clang::TypedefDecl*>(
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            ND)->getCanonicalDecl()->getUnderlyingType().getTypePtr();
1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        break;
1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      case clang::Decl::Record: {
1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        T = static_cast<const clang::RecordDecl*>(ND)->getTypeForDecl();
1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        break;
1749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
1759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      default: {
1769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // unsupported, skip
1779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        break;
178ac91815eb4918b9307ec876f34f2b60adf28c78bShih-wei Liao      }
179ac91815eb4918b9307ec876f34f2b60adf28c78bShih-wei Liao    }
180537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao
1819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (T != NULL)
1829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ET = RSExportType::Create(this, T);
1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
184462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  RSExportPointerType::IntegerType = NULL;
186462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return (ET != NULL);
188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
189462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid RSContext::processExport() {
1919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mNeedExportVars.empty() &&
1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mNeedExportFuncs.empty() &&
1939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      !mExportAllNonStaticVars && !mExportAllNonStaticFuncs) {
1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    fprintf(stderr, "note: No reflection because there are no #pragma "
1959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                    "rs export_var(...), #pragma rs export_func(...), "
1966315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                    "#pragma rs export_var_all, or #pragma rs "
1976315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                    "export_func_all\n");
1989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Export variable
2019e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  clang::TranslationUnitDecl *TUDecl = mCtx.getTranslationUnitDecl();
2029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(),
2039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao           DE = TUDecl->decls_end();
2049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       DI != TUDecl->decls_end();
2059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       DI++) {
2069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (DI->getKind() == clang::Decl::Var) {
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      clang::VarDecl *VD = (clang::VarDecl*) (*DI);
2089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (mExportAllNonStaticVars &&
2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          (VD->getLinkage() == clang::ExternalLinkage)) {
2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (!processExportVar(VD)) {
2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          fprintf(stderr, "RSContext::processExport : failed to export var "
2129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                          "'%s'\n", VD->getNameAsString().c_str());
2139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      } else {
2159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        NeedExportVarSet::iterator EI = mNeedExportVars.find(VD->getName());
2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (EI != mNeedExportVars.end() && processExportVar(VD)) {
2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mNeedExportVars.erase(EI);
2183f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang        }
2199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
2209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    } else if (DI->getKind() == clang::Decl::Function) {
2219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Export functions
2229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      clang::FunctionDecl *FD = (clang::FunctionDecl*) (*DI);
2239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (mExportAllNonStaticFuncs &&
2249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          (FD->getLinkage() == clang::ExternalLinkage)) {
2259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (!processExportFunc(FD)) {
2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          fprintf(stderr, "RSContext::processExport : failed to export func "
2279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                          "'%s'\n", FD->getNameAsString().c_str());
2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      } else {
2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        NeedExportFuncSet::iterator EI = mNeedExportFuncs.find(FD->getName());
2319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (EI != mNeedExportFuncs.end() && processExportFunc(FD))
2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mNeedExportFuncs.erase(EI);
2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
2343f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
2359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Finally, export type forcely set to be exported by user
2389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (NeedExportTypeSet::const_iterator EI = mNeedExportTypes.begin(),
2399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao           EE = mNeedExportTypes.end();
2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       EI != EE;
2419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       EI++) {
2429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (!processExportType(EI->getKey())) {
2439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      fprintf(stderr, "RSContext::processExport : failed to export type "
2449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              "'%s'\n", EI->getKey().str().c_str());
2453f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
2469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
250537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao
2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::insertExportType(const llvm::StringRef &TypeName,
2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                 RSExportType *ET) {
2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ExportTypeMap::value_type *NewItem =
2549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeMap::value_type::Create(TypeName.begin(),
2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                        TypeName.end(),
2569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                        mExportTypes.getAllocator(),
2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                        ET);
2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mExportTypes.insert(NewItem)) {
2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return true;
2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else {
2629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    free(NewItem);
2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
265462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
266462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
267b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liaobool RSContext::reflectToJava(const std::string &OutputPathBase,
268b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              const std::string &OutputPackageName,
2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                              const std::string &InputFileName,
2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                              const std::string &OutputBCFileName,
271b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                              std::string *RealPackageName) {
272b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (RealPackageName != NULL)
273b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    RealPackageName->clear();
274b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao
275b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  const std::string &PackageName =
276b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao      ((OutputPackageName.empty()) ? mReflectJavaPackageName :
277b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                                     OutputPackageName);
278b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  if (PackageName.empty())
279b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    // no package name, just return
280b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao    return true;
2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Copy back the really applied package name
283b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  RealPackageName->assign(PackageName);
2849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  RSReflection *R = new RSReflection(this);
286b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao  bool ret = R->reflect(OutputPathBase, PackageName,
287b81c6a4cbd9c08e0b20ea4fbc615b416ac1bc9ecShih-wei Liao                        InputFileName, OutputBCFileName);
2886315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  if (!ret)
2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    fprintf(stderr, "RSContext::reflectToJava : failed to do reflection "
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                    "(%s)\n", R->getLastError());
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete R;
2929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return ret;
2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
2946de89272b00a31f2a73e2f56edf9cc511df46265Shih-wei Liao
295462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSContext::~RSContext() {
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mLicenseNote;
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mTargetData;
298a41ce1d98094da84643995d40d71c529905123fcZonr Chang  for (ExportableList::iterator I = mExportables.begin(),
299a41ce1d98094da84643995d40d71c529905123fcZonr Chang          E = mExportables.end();
300a41ce1d98094da84643995d40d71c529905123fcZonr Chang       I != E;
301a41ce1d98094da84643995d40d71c529905123fcZonr Chang       I++) {
302641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang    if (!(*I)->isKeep())
303641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang      delete *I;
304a41ce1d98094da84643995d40d71c529905123fcZonr Chang  }
305462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
306e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
307e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
308