slang_rs_context.cpp revision 2615f383dfc1542a05f19aee23b03a09bd018f4e
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"
22fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni#include "clang/AST/Attr.h"
239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/Decl.h"
249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/DeclBase.h"
25be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "clang/AST/Mangle.h"
26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/Type.h"
27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/Linkage.h"
29e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/TargetInfo.h"
3041ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang
3123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/LLVMContext.h"
3223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/DataLayout.h"
33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
346315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang.h"
356e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
36593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "slang_rs_export_foreach.h"
376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h"
38c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#include "slang_rs_export_reduce.h"
396315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h"
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_export_var.h"
41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_exportable.h"
426315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_pragma_handler.h"
43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_reflection.h"
44eae0b7ad0195360b0afc37d51553f2917f1aa365Matt Wala#include "slang_rs_special_func.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,
52fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                     unsigned int TargetAPI,
53fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                     bool Verbose)
546315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    : mPP(PP),
556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mCtx(Ctx),
563fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines      mPragmas(Pragmas),
574a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines      mTargetAPI(TargetAPI),
58fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines      mVerbose(Verbose),
595abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      mDataLayout(nullptr),
606315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mLLVMContext(llvm::getGlobalContext()),
615abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      mLicenseNote(nullptr),
620a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines      mRSPackageName("android.renderscript"),
633fa286b4c2f110c6be2bbfac9c715bb1ec880338Shih-wei Liao      version(0),
649ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines      mMangleCtx(Ctx.createMangleContext()),
65fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      mIs64Bit(Target.getPointerWidth(0) == 64),
66fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      mNextSlot(1) {
674cc67fce91f43215d61b2695746eab102a3db516Stephen Hines
68109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet  AddPragmaHandlers(PP, this);
6996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Prepare target data
7123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  mDataLayout = new llvm::DataLayout(Target.getTargetDescription());
72fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
73fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  // Reserve slot 0 for the root kernel.
74fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  mExportForEach.push_back(nullptr);
75462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
76462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::processExportVar(const clang::VarDecl *VD) {
786e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(!VD->getName().empty() && "Variable name should not be empty");
79537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao
809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  RSExportType *ET = RSExportType::CreateFromDecl(this, VD);
819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!ET)
829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
83462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  RSExportVar *EV = new RSExportVar(this, VD, ET);
855abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (EV == nullptr)
869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mExportVars.push_back(EV);
89462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
91462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
92462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
93fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Niint RSContext::getForEachSlotNumber(const clang::FunctionDecl* FD) {
94fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  const clang::StringRef& funcName = FD->getName();
95fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  return getForEachSlotNumber(funcName);
96fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni}
97fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
98fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Niint RSContext::getForEachSlotNumber(const clang::StringRef& funcName) {
99fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  auto it = mExportForEachMap.find(funcName);
100fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  if (it == mExportForEachMap.end()) {
101fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    return -1;
102fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  }
103fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  return it->second;
104fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni}
105fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
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
119c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  // Specialized function
120eae0b7ad0195360b0afc37d51553f2917f1aa365Matt Wala  if (RSSpecialFunc::isSpecialRSFunc(mTargetAPI, FD)) {
1219999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines    // Do not reflect specialized functions like init, dtor, or graphics root.
122eae0b7ad0195360b0afc37d51553f2917f1aa365Matt Wala    return RSSpecialFunc::validateSpecialFuncDecl(mTargetAPI, this, FD);
123c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  }
124c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
125c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  // Foreach kernel
126c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  if (RSExportForEach::isRSForEachFunc(mTargetAPI, FD)) {
127fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    RSExportForEach *EFE = RSExportForEach::Create(this, FD);
128fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    if (EFE == nullptr) {
129fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      return false;
130fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    }
131fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    const llvm::StringRef& funcName = FD->getName();
132fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    if (funcName.equals("root")) {
133fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      mExportForEach[0] = EFE;
134fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    } else {
1355d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines      mExportForEach.push_back(EFE);
1365d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines    }
137fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    return true;
1383fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines  }
1393fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines
140c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  // Reduce kernel
141c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  if (RSExportReduce::isRSReduceFunc(mTargetAPI, FD)) {
142c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    if (auto *ER = RSExportReduce::Create(this, FD)) {
143c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      mExportReduce.push_back(ER);
144c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      return true;
145c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    }
1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
147c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  }
148c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
149c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  // Invokable
150c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  if (auto *EF = RSExportFunc::Create(this, FD)) {
1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mExportFuncs.push_back(EF);
152c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    return true;
153c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  }
154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
155c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  return false;
1569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
158fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Nibool RSContext::addForEach(const clang::FunctionDecl* FD) {
159fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  const llvm::StringRef& funcName = FD->getName();
160fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
161fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  if (funcName.equals("root")) {
162fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    // The root kernel should always be in slot 0.
163fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    mExportForEachMap.insert(std::make_pair(funcName, 0));
164fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  } else {
165fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    mExportForEachMap.insert(std::make_pair(funcName, mNextSlot++));
166fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  }
167fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
168fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  return true;
169fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni}
170462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::processExportType(const llvm::StringRef &Name) {
1729e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  clang::TranslationUnitDecl *TUDecl = mCtx.getTranslationUnitDecl();
173462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1745abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  slangAssert(TUDecl != nullptr && "Translation unit declaration (top-level "
1755abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes                                   "declaration) is null object");
176f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao
1779e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines  const clang::IdentifierInfo *II = mPP.getIdentifierInfo(Name);
1785abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (II == nullptr)
1796315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    // TODO(zonr): alert identifier @Name mark as an exportable type cannot be
1806315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    //             found
1819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
182f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao
183c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines  clang::DeclContext::lookup_result R = TUDecl->lookup(II);
1845abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  RSExportType *ET = nullptr;
185f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao
186c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines  for (clang::DeclContext::lookup_iterator I = R.begin(), E = R.end();
1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       I != E;
1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       I++) {
1899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    clang::NamedDecl *const ND = *I;
1905abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    const clang::Type *T = nullptr;
191462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    switch (ND->getKind()) {
1939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      case clang::Decl::Typedef: {
1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        T = static_cast<const clang::TypedefDecl*>(
1959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            ND)->getCanonicalDecl()->getUnderlyingType().getTypePtr();
1969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        break;
1979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
1989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      case clang::Decl::Record: {
1999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        T = static_cast<const clang::RecordDecl*>(ND)->getTypeForDecl();
2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        break;
2019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
2029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      default: {
2039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // unsupported, skip
2049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        break;
205ac91815eb4918b9307ec876f34f2b60adf28c78bShih-wei Liao      }
206ac91815eb4918b9307ec876f34f2b60adf28c78bShih-wei Liao    }
207537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao
2085abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    if (T != nullptr)
2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ET = RSExportType::Create(this, T);
2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
211462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2125abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  return (ET != nullptr);
213462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
214462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
21588f21e16250d2e52a75607b7f0c396e1c2a34201Yang Nivoid RSContext::setAllocationType(const clang::TypeDecl* TD) {
21688f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni  mAllocationType = mCtx.getTypeDeclType(TD);
21788f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni}
21888f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni
2192615f383dfc1542a05f19aee23b03a09bd018f4eYang Nivoid RSContext::setScriptCallType(const clang::TypeDecl* TD) {
2202615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni  mScriptCallType = mCtx.getTypeDeclType(TD);
2212615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni}
2222615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni
223fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Nibool RSContext::processExports() {
224b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines  bool valid = true;
225593a894650e81be54173106ec266f0311cebebd3Stephen Hines
226593a894650e81be54173106ec266f0311cebebd3Stephen Hines  if (getDiagnostics()->hasErrorOccurred()) {
227593a894650e81be54173106ec266f0311cebebd3Stephen Hines    return false;
228593a894650e81be54173106ec266f0311cebebd3Stephen Hines  }
229593a894650e81be54173106ec266f0311cebebd3Stephen Hines
2305d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines  clang::TranslationUnitDecl *TUDecl = mCtx.getTranslationUnitDecl();
231fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  for (auto I = TUDecl->decls_begin(), E = TUDecl->decls_end(); I != E; I++) {
232fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    clang::Decl* D = *I;
233fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    switch (D->getKind()) {
234fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    case clang::Decl::Var: {
235fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      clang::VarDecl* VD = llvm::dyn_cast<clang::VarDecl>(D);
236a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines      bool ShouldExportVariable = true;
2375d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines      if (VD->getFormalLinkage() == clang::ExternalLinkage) {
238a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines        clang::QualType QT = VD->getTypeSourceInfo()->getType();
239a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines        if (QT.isConstQualified() && !VD->hasInit()) {
240a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines          if (Slang::IsLocInRSHeaderFile(VD->getLocation(),
241a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines                                         *getSourceManager())) {
242a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines            // We don't export variables internal to the runtime's
243a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines            // implementation.
244a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines            ShouldExportVariable = false;
245a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines          } else {
246a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines            clang::DiagnosticsEngine *DiagEngine = getDiagnostics();
247a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines            DiagEngine->Report(VD->getLocation(), DiagEngine->getCustomDiagID(
248a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines                clang::DiagnosticsEngine::Error,
249a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines                "invalid declaration of uninitialized constant variable '%0'"))
250a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines              << VD->getName();
251a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines            valid = false;
252a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines          }
253a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines        }
254a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines        if (valid && ShouldExportVariable && !processExportVar(VD)) {
2555d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines          valid = false;
2565d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines        }
2575d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines      }
258fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      break;
259fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    }
260fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    case clang::Decl::Function: {
261fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      clang::FunctionDecl* FD = llvm::dyn_cast<clang::FunctionDecl>(D);
2625d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines      if (FD->getFormalLinkage() == clang::ExternalLinkage) {
2635d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines        if (!processExportFunc(FD)) {
2645d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines          valid = false;
2655d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines        }
2665d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines      }
267fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      break;
268fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    }
269fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    default:
270fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      break;
2715d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines    }
2725d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines  }
2735d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines
27415410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni  // Create a dummy root in slot 0 if a root kernel is not seen
27515410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni  // and there exists a non-root kernel.
276fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  if (valid && mExportForEach[0] == nullptr) {
27715410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni    const size_t numExportedForEach = mExportForEach.size();
27815410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni    if (numExportedForEach > 1) {
27915410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni      mExportForEach[0] = RSExportForEach::CreateDummyRoot(this);
28015410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni    } else {
28115410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni      slangAssert(numExportedForEach == 1);
28215410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni      mExportForEach.pop_back();
28315410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni    }
284c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  }
285c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Finally, export type forcely set to be exported by user
2879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  for (NeedExportTypeSet::const_iterator EI = mNeedExportTypes.begin(),
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao           EE = mNeedExportTypes.end();
2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       EI != EE;
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao       EI++) {
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (!processExportType(EI->getKey())) {
292b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines      valid = false;
2933f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
296b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines  return valid;
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
298537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::insertExportType(const llvm::StringRef &TypeName,
3009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                 RSExportType *ET) {
3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ExportTypeMap::value_type *NewItem =
3022eb9a3f7c48fe54eb4e813d80e3363bc79553a1eStephen Hines      ExportTypeMap::value_type::Create(TypeName,
3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                        mExportTypes.getAllocator(),
3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                        ET);
3059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mExportTypes.insert(NewItem)) {
3079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return true;
3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else {
3093f45a25c23fa0f2cca4070f4d8713dc1a83f5ff7Matt Wala    NewItem->Destroy(mExportTypes.getAllocator());
3109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
313462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSContext::~RSContext() {
3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mLicenseNote;
31623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines  delete mDataLayout;
317a41ce1d98094da84643995d40d71c529905123fcZonr Chang  for (ExportableList::iterator I = mExportables.begin(),
318a41ce1d98094da84643995d40d71c529905123fcZonr Chang          E = mExportables.end();
319a41ce1d98094da84643995d40d71c529905123fcZonr Chang       I != E;
320a41ce1d98094da84643995d40d71c529905123fcZonr Chang       I++) {
321641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang    if (!(*I)->isKeep())
322641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang      delete *I;
323a41ce1d98094da84643995d40d71c529905123fcZonr Chang  }
324462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
325e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
326e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
327