slang_rs_context.cpp revision eae0b7ad0195360b0afc37d51553f2917f1aa365
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
3023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/LLVMContext.h"
3123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/DataLayout.h"
32e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang.h"
346e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
35593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "slang_rs_export_foreach.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"
42eae0b7ad0195360b0afc37d51553f2917f1aa365Matt Wala#include "slang_rs_special_func.h"
439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
469e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen HinesRSContext::RSContext(clang::Preprocessor &PP,
479e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines                     clang::ASTContext &Ctx,
483fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines                     const clang::TargetInfo &Target,
494cc67fce91f43215d61b2695746eab102a3db516Stephen Hines                     PragmaList *Pragmas,
50fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                     unsigned int TargetAPI,
51fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                     bool Verbose)
526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    : mPP(PP),
536315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mCtx(Ctx),
543fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines      mPragmas(Pragmas),
554a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines      mTargetAPI(TargetAPI),
56fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines      mVerbose(Verbose),
575abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      mDataLayout(nullptr),
586315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mLLVMContext(llvm::getGlobalContext()),
595abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      mLicenseNote(nullptr),
600a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines      mRSPackageName("android.renderscript"),
613fa286b4c2f110c6be2bbfac9c715bb1ec880338Shih-wei Liao      version(0),
629ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      mMangleCtx(Ctx.createMangleContext()),
639ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      mIs64Bit(Target.getPointerWidth(0) == 64) {
644cc67fce91f43215d61b2695746eab102a3db516Stephen Hines
65109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet  AddPragmaHandlers(PP, this);
6696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Prepare target data
6823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  mDataLayout = new llvm::DataLayout(Target.getTargetDescription());
69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::processExportVar(const clang::VarDecl *VD) {
726e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(!VD->getName().empty() && "Variable name should not be empty");
73537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao
746315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  // TODO(zonr): some check on variable
75462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  RSExportType *ET = RSExportType::CreateFromDecl(this, VD);
779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!ET)
789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
79462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  RSExportVar *EV = new RSExportVar(this, VD, ET);
815abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (EV == nullptr)
829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mExportVars.push_back(EV);
85462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
87462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
88462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
896315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrbool RSContext::processExportFunc(const clang::FunctionDecl *FD) {
906e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(!FD->getName().empty() && "Function name should not be empty");
91462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
923fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines  if (!FD->isThisDeclarationADefinition()) {
933fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines    return true;
943fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines  }
95462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (FD->getStorageClass() != clang::SC_None) {
979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    fprintf(stderr, "RSContext::processExportFunc : cannot export extern or "
989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                    "static function '%s'\n", FD->getName().str().c_str());
999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
101462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
102eae0b7ad0195360b0afc37d51553f2917f1aa365Matt Wala  if (RSSpecialFunc::isSpecialRSFunc(mTargetAPI, FD)) {
1039999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines    // Do not reflect specialized functions like init, dtor, or graphics root.
104eae0b7ad0195360b0afc37d51553f2917f1aa365Matt Wala    return RSSpecialFunc::validateSpecialFuncDecl(mTargetAPI, this, FD);
105f5b882cc561f656eb650d0fa6db7bac57989ab12Matt Wala  } else if (RSExportForEach::isRSForEachFunc(mTargetAPI, FD)) {
106593a894650e81be54173106ec266f0311cebebd3Stephen Hines    RSExportForEach *EFE = RSExportForEach::Create(this, FD);
1075abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    if (EFE == nullptr)
108593a894650e81be54173106ec266f0311cebebd3Stephen Hines      return false;
109593a894650e81be54173106ec266f0311cebebd3Stephen Hines    else
110593a894650e81be54173106ec266f0311cebebd3Stephen Hines      mExportForEach.push_back(EFE);
111593a894650e81be54173106ec266f0311cebebd3Stephen Hines    return true;
1123fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines  }
1133fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines
1149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  RSExportFunc *EF = RSExportFunc::Create(this, FD);
1155abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (EF == nullptr)
1169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mExportFuncs.push_back(EF);
119462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
122462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
123462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::processExportType(const llvm::StringRef &Name) {
1259e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  clang::TranslationUnitDecl *TUDecl = mCtx.getTranslationUnitDecl();
126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1275abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  slangAssert(TUDecl != nullptr && "Translation unit declaration (top-level "
1285abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes                                   "declaration) is null object");
129f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao
1309e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  const clang::IdentifierInfo *II = mPP.getIdentifierInfo(Name);
1315abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (II == nullptr)
1326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    // TODO(zonr): alert identifier @Name mark as an exportable type cannot be
1336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    //             found
1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
135f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao
136c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines  clang::DeclContext::lookup_result R = TUDecl->lookup(II);
1375abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  RSExportType *ET = nullptr;
138f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao
139c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines  for (clang::DeclContext::lookup_iterator I = R.begin(), E = R.end();
1409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       I != E;
1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       I++) {
1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    clang::NamedDecl *const ND = *I;
1435abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    const clang::Type *T = nullptr;
144462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    switch (ND->getKind()) {
1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      case clang::Decl::Typedef: {
1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        T = static_cast<const clang::TypedefDecl*>(
1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            ND)->getCanonicalDecl()->getUnderlyingType().getTypePtr();
1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        break;
1509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      case clang::Decl::Record: {
1529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        T = static_cast<const clang::RecordDecl*>(ND)->getTypeForDecl();
1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        break;
1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      default: {
1569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // unsupported, skip
1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        break;
158ac91815eb4918b9307ec876f34f2b60adf28c78bShih-wei Liao      }
159ac91815eb4918b9307ec876f34f2b60adf28c78bShih-wei Liao    }
160537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao
1615abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    if (T != nullptr)
1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ET = RSExportType::Create(this, T);
1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
164462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1655abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  return (ET != nullptr);
166462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
167462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
168c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
169c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines// Possibly re-order ForEach exports (maybe generating a dummy "root" function).
170c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines// We require "root" to be listed as slot 0 of our exported compute kernels,
171c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines// so this only needs to be created if we have other non-root kernels.
172c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hinesvoid RSContext::cleanupForEach() {
173c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  bool foundNonRoot = false;
174c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  ExportForEachList::iterator begin = mExportForEach.begin();
175c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
176c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  for (ExportForEachList::iterator I = begin, E = mExportForEach.end();
177c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines       I != E;
178c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines       I++) {
179c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    RSExportForEach *EFE = *I;
180c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    if (!EFE->getName().compare("root")) {
181c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines      if (I == begin) {
182c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines        // Nothing to do, since it is the first function
183c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines        return;
184c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines      }
185c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
186c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines      mExportForEach.erase(I);
187c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines      mExportForEach.push_front(EFE);
188c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines      return;
189c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    } else {
190c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines      foundNonRoot = true;
191c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    }
192c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  }
193c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
194c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  // If we found a non-root kernel, but no root() function, we need to add a
195c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  // dummy version (so that script->script calls of rsForEach don't behave
196c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  // erratically).
197c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  if (foundNonRoot) {
198c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    RSExportForEach *DummyRoot = RSExportForEach::CreateDummyRoot(this);
199c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    mExportForEach.push_front(DummyRoot);
200c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  }
201c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines}
202c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
203c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
204c808a99831115928b4648f4c8b86dc682594217aStephen Hinesbool RSContext::processExport() {
205b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines  bool valid = true;
206593a894650e81be54173106ec266f0311cebebd3Stephen Hines
207593a894650e81be54173106ec266f0311cebebd3Stephen Hines  if (getDiagnostics()->hasErrorOccurred()) {
208593a894650e81be54173106ec266f0311cebebd3Stephen Hines    return false;
209593a894650e81be54173106ec266f0311cebebd3Stephen Hines  }
210593a894650e81be54173106ec266f0311cebebd3Stephen Hines
2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Export variable
2129e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  clang::TranslationUnitDecl *TUDecl = mCtx.getTranslationUnitDecl();
2139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(),
2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao           DE = TUDecl->decls_end();
215c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI != DE;
2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       DI++) {
2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (DI->getKind() == clang::Decl::Var) {
2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      clang::VarDecl *VD = (clang::VarDecl*) (*DI);
21944f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines      if (VD->getFormalLinkage() == clang::ExternalLinkage) {
2209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (!processExportVar(VD)) {
221b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines          valid = false;
2229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
2239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
2249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    } else if (DI->getKind() == clang::Decl::Function) {
2259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Export functions
2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      clang::FunctionDecl *FD = (clang::FunctionDecl*) (*DI);
22744f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines      if (FD->getFormalLinkage() == clang::ExternalLinkage) {
2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (!processExportFunc(FD)) {
229b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines          valid = false;
2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
2319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
2323f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
235c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  if (valid) {
236c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    cleanupForEach();
237c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  }
238c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
2399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Finally, export type forcely set to be exported by user
2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (NeedExportTypeSet::const_iterator EI = mNeedExportTypes.begin(),
2419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao           EE = mNeedExportTypes.end();
2429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       EI != EE;
2439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       EI++) {
2449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (!processExportType(EI->getKey())) {
245b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines      valid = false;
2463f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
249b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines  return valid;
2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
251537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao
2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::insertExportType(const llvm::StringRef &TypeName,
2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                 RSExportType *ET) {
2549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ExportTypeMap::value_type *NewItem =
2552eb9a3f7c48fe54eb4e813d80e3363bc79553a1eStephen Hines      ExportTypeMap::value_type::Create(TypeName,
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
267462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSContext::~RSContext() {
2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mLicenseNote;
26923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  delete mDataLayout;
270a41ce1d98094da84643995d40d71c529905123fcZonr Chang  for (ExportableList::iterator I = mExportables.begin(),
271a41ce1d98094da84643995d40d71c529905123fcZonr Chang          E = mExportables.end();
272a41ce1d98094da84643995d40d71c529905123fcZonr Chang       I != E;
273a41ce1d98094da84643995d40d71c529905123fcZonr Chang       I++) {
274641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang    if (!(*I)->isKeep())
275641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang      delete *I;
276a41ce1d98094da84643995d40d71c529905123fcZonr Chang  }
277462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
278e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
279e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
280