1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/*
27b51b55e4467605a599e868a0dde7cb95c5ab76eStephen 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_backend.h"
18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
196315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <string>
20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <vector>
21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
2243730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao#include "clang/AST/ASTContext.h"
23c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "clang/Frontend/CodeGenOptions.h"
24c460b37ffb50819a32c2a8967754b6f784b28263mkopec
25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/Twine.h"
26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/StringExtras.h"
27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Constant.h"
299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Constants.h"
309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/DerivedTypes.h"
31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Function.h"
3243730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao#include "llvm/IRBuilder.h"
33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Metadata.h"
34e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Module.h"
35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
36c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "llvm/Support/DebugLoc.h"
376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
386e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
39592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang#include "slang_rs.h"
406315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h"
414ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines#include "slang_rs_export_foreach.h"
426315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h"
436315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h"
44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_export_var.h"
45e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_metadata.h"
46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
47e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
499ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSBackend::RSBackend(RSContext *Context,
509207a2e495c8363606861e4f034504ec5c153dabLogan Chien                     clang::DiagnosticsEngine *DiagEngine,
519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::CodeGenOptions &CodeGenOpts,
529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::TargetOptions &TargetOpts,
533fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines                     PragmaList *Pragmas,
549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     llvm::raw_ostream *OS,
553a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     Slang::OutputType OT,
569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     clang::SourceManager &SourceMgr,
5711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines                     bool AllowRSPrefix,
5811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines                     bool IsFilterscript)
599207a2e495c8363606861e4f034504ec5c153dabLogan Chien  : Backend(DiagEngine, CodeGenOpts, TargetOpts, Pragmas, OS, OT),
609207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mContext(Context),
619207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mSourceMgr(SourceMgr),
629207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mAllowRSPrefix(AllowRSPrefix),
6311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines    mIsFilterscript(IsFilterscript),
649207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportVarMetadata(NULL),
659207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportFuncMetadata(NULL),
667b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    mExportForEachNameMetadata(NULL),
677b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    mExportForEachSignatureMetadata(NULL),
689207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportTypeMetadata(NULL),
699207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mRSObjectSlotsMetadata(NULL),
7011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines    mRefCount(mContext->getASTContext()),
7111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines    mASTChecker(mContext->getASTContext(), mContext->getTargetAPI(),
7211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines                IsFilterscript) {
73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
74462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
75cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines// 1) Add zero initialization of local RS object types
76cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinesvoid RSBackend::AnnotateFunction(clang::FunctionDecl *FD) {
77cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (FD &&
78cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      FD->hasBody() &&
7911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines      !SlangRS::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
80d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines    mRefCount.Init();
814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    mRefCount.Visit(FD->getBody());
82cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
83cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  return;
84cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
85cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
86fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chienbool RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
87cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Disallow user-defined functions with prefix "rs"
88cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (!mAllowRSPrefix) {
89cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    // Iterate all function declarations in the program.
90cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
91cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines         I != E; I++) {
92ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
93cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (FD == NULL)
94cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
95cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!FD->getName().startswith("rs"))  // Check prefix
96cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
9711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines      if (!SlangRS::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
989207a2e495c8363606861e4f034504ec5c153dabLogan Chien        mDiagEngine.Report(
999207a2e495c8363606861e4f034504ec5c153dabLogan Chien          clang::FullSourceLoc(FD->getLocation(), mSourceMgr),
1009207a2e495c8363606861e4f034504ec5c153dabLogan Chien          mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
1019207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                      "invalid function name prefix, "
1029207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                      "\"rs\" is reserved: '%0'"))
1039207a2e495c8363606861e4f034504ec5c153dabLogan Chien          << FD->getName();
104cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    }
105cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
106cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
107cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any non-static function declarations
108cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
109ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
110eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    if (FD && FD->isGlobal()) {
111ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      // Check that we don't have any array parameters being misintrepeted as
112ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      // kernel pointers due to the C type system's array to pointer decay.
113ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      size_t numParams = FD->getNumParams();
114ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      for (size_t i = 0; i < numParams; i++) {
115ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines        const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
116ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines        clang::QualType QT = PVD->getOriginalType();
117ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines        if (QT->isArrayType()) {
118ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines          mDiagEngine.Report(
119ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines            clang::FullSourceLoc(PVD->getTypeSpecStartLoc(), mSourceMgr),
120ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines            mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
121ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines                                        "exported function parameters may "
122ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines                                        "not have array type: %0")) << QT;
123ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines        }
124ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      }
125eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      AnnotateFunction(FD);
126eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    }
127cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
128cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
129fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chien  return Backend::HandleTopLevelDecl(D);
130cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
131cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
132c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
133c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesvoid RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
134c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
135c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
13611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines  // If we have an invalid RS/FS AST, don't check further.
13711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines  if (!mASTChecker.Validate()) {
138c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
139c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
140fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
14111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines  if (mIsFilterscript) {
14211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines    mContext->addPragma("rs_fp_relaxed", "");
14311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines  }
14411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines
14596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  int version = mContext->getVersion();
14696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  if (version == 0) {
14796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    // Not setting a version is an error
1487aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    mDiagEngine.Report(
1497aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
1507aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        mDiagEngine.getCustomDiagID(
1517aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines            clang::DiagnosticsEngine::Error,
1527aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines            "missing pragma for version in source file"));
1537aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines  } else {
1547aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    slangAssert(version == 1);
15596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
15696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
157cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines  if (mContext->getReflectJavaPackageName().empty()) {
158cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines    mDiagEngine.Report(
159cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
160cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines        mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
161cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines                                    "missing \"#pragma rs "
162cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines                                    "java_package_name(com.foo.bar)\" "
163cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines                                    "in source file"));
164cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines    return;
165cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines  }
166cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines
167688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // Create a static global destructor if necessary (to handle RS object
168688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // runtime cleanup).
169688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
170688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  if (FD) {
171688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    HandleTopLevelDecl(clang::DeclGroupRef(FD));
172688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  }
173688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines
174cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any static function declarations
175fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
176fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines          E = TUDecl->decls_end(); I != E; I++) {
177fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    if ((I->getKind() >= clang::Decl::firstFunction) &&
178fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        (I->getKind() <= clang::Decl::lastFunction)) {
179ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
180eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      if (FD && !FD->isGlobal()) {
181eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines        AnnotateFunction(FD);
182eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      }
183fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    }
184fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  }
185fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
186fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  return;
187fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines}
188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
189fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines///////////////////////////////////////////////////////////////////////////////
19068fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Changvoid RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
191c808a99831115928b4648f4c8b86dc682594217aStephen Hines  if (!mContext->processExport()) {
192c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
193c808a99831115928b4648f4c8b86dc682594217aStephen Hines  }
1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
195c460b37ffb50819a32c2a8967754b6f784b28263mkopec  // Write optimization level
196c460b37ffb50819a32c2a8967754b6f784b28263mkopec  llvm::SmallVector<llvm::Value*, 1> OptimizationOption;
197c460b37ffb50819a32c2a8967754b6f784b28263mkopec  OptimizationOption.push_back(llvm::ConstantInt::get(
198c460b37ffb50819a32c2a8967754b6f784b28263mkopec    mLLVMContext, llvm::APInt(32, mCodeGenOpts.OptimizationLevel)));
199c460b37ffb50819a32c2a8967754b6f784b28263mkopec
2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export variable info
2019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportVar()) {
202b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    int slotCount = 0;
2039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportVarMetadata == NULL)
20468fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang      mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
2059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
207b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
208b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // We emit slot information (#rs_object_slots) for any reference counted
209b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // RS type or pointer (which can also be bound).
2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2116315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
2126315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_vars_end();
2136315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I != E;
2146315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I++) {
2156315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportVar *EV = *I;
2166315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportType *ET = EV->getType();
217b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      bool countsAsRSObject = false;
2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Variable name
2209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.push_back(
2219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
2229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
224a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      switch (ET->getClass()) {
225a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPrimitive: {
226b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          const RSExportPrimitiveType *PT =
227b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines              static_cast<const RSExportPrimitiveType*>(ET);
228a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
229a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
230b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines                mLLVMContext, llvm::utostr_32(PT->getType())));
231b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          if (PT->isRSObjectType()) {
232b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            countsAsRSObject = true;
233b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          }
234a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
235a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
236a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPointer: {
237a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
238a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
2399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
240a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  ->getPointeeType()->getName()).c_str()));
241a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
242a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
243a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassMatrix: {
244a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
245a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
246a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                mLLVMContext, llvm::utostr_32(
247a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  RSExportPrimitiveType::DataTypeRSMatrix2x2 +
248a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
249a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
250a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
251a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassVector:
252a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassConstantArray:
253a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassRecord: {
254a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
255a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(mLLVMContext,
256a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                EV->getType()->getName().c_str()));
257a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
258a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
259a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      }
2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportVarMetadata->addOperand(
262d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportVarInfo));
2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.clear();
264b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
265b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (mRSObjectSlotsMetadata == NULL) {
266b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        mRSObjectSlotsMetadata =
267b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
268b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
269b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
270b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (countsAsRSObject) {
271d27a74edb932580d224a7186731aa6be098ad02eStephen Hines        mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
272d27a74edb932580d224a7186731aa6be098ad02eStephen Hines            llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
273b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
274b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
275b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      slotCount++;
276462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export function info
2809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportFunc()) {
2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportFuncMetadata == NULL)
2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata =
28368fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang          M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
2849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2876315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_func_iterator
2886315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_funcs_begin(),
2896315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_funcs_end();
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
2926315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportFunc *EF = *I;
2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Function name
2956315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      if (!EF->hasParam()) {
2966315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
2976315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                                     EF->getName().c_str()));
2986315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      } else {
29968fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang        llvm::Function *F = M->getFunction(EF->getName());
3009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::Function *HelperFunction;
3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const std::string HelperFunctionName(".helper_" + EF->getName());
3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3036e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(F && "Function marked as exported disappeared in Bitcode");
3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Create helper function
306462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
3070da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::StructType *HelperFunctionParameterTy = NULL;
3080da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3090da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!F->getArgumentList().empty()) {
3107c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao            std::vector<llvm::Type*> HelperFunctionParameterTys;
3110da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (llvm::Function::arg_iterator AI = F->arg_begin(),
3120da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                 AE = F->arg_end(); AI != AE; AI++)
3130da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTys.push_back(AI->getType());
3140da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3150da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            HelperFunctionParameterTy =
316a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines                llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
3170da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3180da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3190da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
3200da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            fprintf(stderr, "Failed to export function %s: parameter type "
3210da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                            "mismatch during creation of helper function.\n",
3220da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                    EF->getName().c_str());
3230da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3240da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            const RSExportRecordType *Expected = EF->getParamPacketType();
3250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (Expected) {
3260da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Expected:\n");
3270da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              Expected->getLLVMType()->dump();
3280da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3290da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (HelperFunctionParameterTy) {
3300da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Got:\n");
3310da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTy->dump();
3320da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3330da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3340da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3357c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao          std::vector<llvm::Type*> Params;
3360da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (HelperFunctionParameterTy) {
3370da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            llvm::PointerType *HelperFunctionParameterTyP =
3380da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                llvm::PointerType::getUnqual(HelperFunctionParameterTy);
3390da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            Params.push_back(HelperFunctionParameterTyP);
3400da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3420da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::FunctionType * HelperFunctionType =
3430da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              llvm::FunctionType::get(F->getReturnType(),
344a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines                                      Params,
3450da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                                      /* IsVarArgs = */false);
3469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction =
3489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Function::Create(HelperFunctionType,
3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     llvm::GlobalValue::ExternalLinkage,
3509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     HelperFunctionName,
35168fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang                                     M);
3529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->addFnAttr(llvm::Attribute::NoInline);
3549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->setCallingConv(F->getCallingConv());
3559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // Create helper function body
3579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          {
3589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Argument *HelperFunctionParameter =
3599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                &(*HelperFunction->arg_begin());
3609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::BasicBlock *BB =
3619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
3629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
3639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::SmallVector<llvm::Value*, 6> Params;
3649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Value *Idx[2];
3659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            Idx[0] =
3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
3689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // getelementptr and load instruction for all elements in
3709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // parameter .p
3710da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (size_t i = 0; i < EF->getNumParameters(); i++) {
3729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // getelementptr
3739207a2e495c8363606861e4f034504ec5c153dabLogan Chien              Idx[1] = llvm::ConstantInt::get(
3749207a2e495c8363606861e4f034504ec5c153dabLogan Chien                llvm::Type::getInt32Ty(mLLVMContext), i);
3759207a2e495c8363606861e4f034504ec5c153dabLogan Chien
3769207a2e495c8363606861e4f034504ec5c153dabLogan Chien              llvm::Value *Ptr =
3779207a2e495c8363606861e4f034504ec5c153dabLogan Chien                IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
3789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // load
3809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Value *V = IB->CreateLoad(Ptr);
3819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              Params.push_back(V);
3829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
383462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
384a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines            // Call and pass the all elements as parameter to F
385a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines            llvm::CallInst *CI = IB->CreateCall(F, Params);
3861ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            CI->setCallingConv(F->getCallingConv());
3881ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
3899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
3909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRetVoid();
3919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            else
3929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRet(CI);
393462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            delete IB;
3959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
3969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
397462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        ExportFuncInfo.push_back(
3999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
4009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
401462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata->addOperand(
403d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
4049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportFuncInfo.clear();
4059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
4069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
4079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4084ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  // Dump export function info
4094ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  if (mContext->hasExportForEach()) {
4107b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    if (mExportForEachNameMetadata == NULL) {
4117b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachNameMetadata =
4127b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines          M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
4137b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    }
4147b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    if (mExportForEachSignatureMetadata == NULL) {
4157b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachSignatureMetadata =
4164ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
4177b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    }
4184ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4197b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    llvm::SmallVector<llvm::Value*, 1> ExportForEachName;
4204ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo;
4214ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4224ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    for (RSContext::const_export_foreach_iterator
4234ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines            I = mContext->export_foreach_begin(),
4244ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines            E = mContext->export_foreach_end();
4254ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines         I != E;
4264ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines         I++) {
4274ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      const RSExportForEach *EFE = *I;
4284ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4297b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      ExportForEachName.push_back(
4307b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines          llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
4317b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
4327b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachNameMetadata->addOperand(
4337b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportForEachName));
4347b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      ExportForEachName.clear();
4357b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
4364ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      ExportForEachInfo.push_back(
4374ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          llvm::MDString::get(mLLVMContext,
4387b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines                              llvm::utostr_32(EFE->getSignatureMetadata())));
4394ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4407b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachSignatureMetadata->addOperand(
4414ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
4424ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      ExportForEachInfo.clear();
4434ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    }
4444ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  }
4454ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export type info
4479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportType()) {
4489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
4499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4506315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_type_iterator
4516315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_types_begin(),
4526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_types_end();
4539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
4549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
4559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // First, dump type name list to export
4569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportType *ET = I->getValue();
4579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.clear();
4599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
4609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.push_back(
4619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
4629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (ET->getClass() == RSExportType::ExportClassRecord) {
4649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const RSExportRecordType *ERT =
4659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            static_cast<const RSExportRecordType*>(ET);
4669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (mExportTypeMetadata == NULL)
4689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mExportTypeMetadata =
46968fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang              M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
4709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mExportTypeMetadata->addOperand(
472d27a74edb932580d224a7186731aa6be098ad02eStephen Hines            llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
4739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Now, export struct field information to %[struct name]
4759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        std::string StructInfoMetadataName("%");
4769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        StructInfoMetadataName.append(ET->getName());
4779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::NamedMDNode *StructInfoMetadata =
47868fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang            M->getOrInsertNamedMetadata(StructInfoMetadataName);
4799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::SmallVector<llvm::Value*, 3> FieldInfo;
4809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4816e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
4826e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines                    "Metadata with same name was created before");
4836315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
4846315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                FE = ERT->fields_end();
4856315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr             FI != FE;
4869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             FI++) {
4879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          const RSExportRecordType::Field *F = *FI;
4889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 1. field name
4909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
4919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  F->getName().c_str()));
4929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 2. field type name
4949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(
4959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::MDString::get(mLLVMContext,
4969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                  F->getType()->getName().c_str()));
4979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
498d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          StructInfoMetadata->addOperand(
499d27a74edb932580d224a7186731aa6be098ad02eStephen Hines              llvm::MDNode::get(mLLVMContext, FieldInfo));
5009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.clear();
501462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
5029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }   // ET->getClass() == RSExportType::ExportClassRecord
503462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
5049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
505462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
5069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
507462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
508462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
509462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() {
5109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
511462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
512e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
513e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
514