slang_rs_backend.cpp revision 43730fe3c839af391efe6bdf56b0479860121924
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,
574a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines                     bool AllowRSPrefix)
589207a2e495c8363606861e4f034504ec5c153dabLogan Chien  : Backend(DiagEngine, CodeGenOpts, TargetOpts, Pragmas, OS, OT),
599207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mContext(Context),
609207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mSourceMgr(SourceMgr),
619207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mAllowRSPrefix(AllowRSPrefix),
629207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportVarMetadata(NULL),
639207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportFuncMetadata(NULL),
647b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    mExportForEachNameMetadata(NULL),
657b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    mExportForEachSignatureMetadata(NULL),
669207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportTypeMetadata(NULL),
679207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mRSObjectSlotsMetadata(NULL),
689207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mRefCount(mContext->getASTContext()) {
69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
71cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines// 1) Add zero initialization of local RS object types
72cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinesvoid RSBackend::AnnotateFunction(clang::FunctionDecl *FD) {
73cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (FD &&
74cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      FD->hasBody() &&
75cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      !SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr)) {
76d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines    mRefCount.Init();
774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    mRefCount.Visit(FD->getBody());
78cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
79cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  return;
80cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
81cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
82fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chienbool RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
83cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Disallow user-defined functions with prefix "rs"
84cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (!mAllowRSPrefix) {
85cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    // Iterate all function declarations in the program.
86cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
87cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines         I != E; I++) {
88ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
89cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (FD == NULL)
90cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
91cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!FD->getName().startswith("rs"))  // Check prefix
92cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
93cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr))
949207a2e495c8363606861e4f034504ec5c153dabLogan Chien        mDiagEngine.Report(
959207a2e495c8363606861e4f034504ec5c153dabLogan Chien          clang::FullSourceLoc(FD->getLocation(), mSourceMgr),
969207a2e495c8363606861e4f034504ec5c153dabLogan Chien          mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
979207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                      "invalid function name prefix, "
989207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                      "\"rs\" is reserved: '%0'"))
999207a2e495c8363606861e4f034504ec5c153dabLogan Chien          << FD->getName();
100cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    }
101cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
102cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
103cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any non-static function declarations
104cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
105ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
106eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    if (FD && FD->isGlobal()) {
107eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      AnnotateFunction(FD);
108eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    }
109cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
110cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
111fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chien  return Backend::HandleTopLevelDecl(D);
112cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
113cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
114c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesnamespace {
115c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
116d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hinesstatic bool ValidateVarDecl(clang::VarDecl *VD, unsigned int TargetAPI) {
11778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  if (!VD) {
11878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    return true;
11978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  }
12078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
12178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  clang::ASTContext &C = VD->getASTContext();
122c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  const clang::Type *T = VD->getType().getTypePtr();
12378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  bool valid = true;
12478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
12578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  if (VD->getLinkage() == clang::ExternalLinkage) {
12678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    llvm::StringRef TypeName;
1275bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines    if (!RSExportType::NormalizeType(T, TypeName, &C.getDiagnostics(), VD)) {
12878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines      valid = false;
12978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    }
130c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
131d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines  valid &= RSExportType::ValidateVarDecl(VD, TargetAPI);
13278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
13378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  return valid;
134c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
135c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
136d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hinesstatic bool ValidateASTContext(clang::ASTContext &C, unsigned int TargetAPI) {
137c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  bool valid = true;
138fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
139c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(),
140c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines          DE = TUDecl->decls_end();
141c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI != DE;
142c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI++) {
143ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*DI);
144d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines    if (VD && !ValidateVarDecl(VD, TargetAPI)) {
14578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines      valid = false;
146c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    }
147c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
148c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
149c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  return valid;
150c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
151c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
152e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines}  // namespace
153c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
154c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesvoid RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
155c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
156c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
157d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines  if (!ValidateASTContext(C, getTargetAPI())) {
158c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
159c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
160fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
16196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  int version = mContext->getVersion();
16296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  if (version == 0) {
16396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    // Not setting a version is an error
1647aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    mDiagEngine.Report(
1657aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
1667aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        mDiagEngine.getCustomDiagID(
1677aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines            clang::DiagnosticsEngine::Error,
1687aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines            "missing pragma for version in source file"));
1697aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines  } else {
1707aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    slangAssert(version == 1);
17196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
17296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
173688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // Create a static global destructor if necessary (to handle RS object
174688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // runtime cleanup).
175688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
176688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  if (FD) {
177688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    HandleTopLevelDecl(clang::DeclGroupRef(FD));
178688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  }
179688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines
180cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any static function declarations
181fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
182fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines          E = TUDecl->decls_end(); I != E; I++) {
183fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    if ((I->getKind() >= clang::Decl::firstFunction) &&
184fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        (I->getKind() <= clang::Decl::lastFunction)) {
185ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
186eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      if (FD && !FD->isGlobal()) {
187eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines        AnnotateFunction(FD);
188eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      }
189fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    }
190fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  }
191fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
192fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  return;
193fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines}
194462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
195fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines///////////////////////////////////////////////////////////////////////////////
19668fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Changvoid RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
197c808a99831115928b4648f4c8b86dc682594217aStephen Hines  if (!mContext->processExport()) {
198c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
199c808a99831115928b4648f4c8b86dc682594217aStephen Hines  }
2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
201c460b37ffb50819a32c2a8967754b6f784b28263mkopec  // Write optimization level
202c460b37ffb50819a32c2a8967754b6f784b28263mkopec  llvm::SmallVector<llvm::Value*, 1> OptimizationOption;
203c460b37ffb50819a32c2a8967754b6f784b28263mkopec  OptimizationOption.push_back(llvm::ConstantInt::get(
204c460b37ffb50819a32c2a8967754b6f784b28263mkopec    mLLVMContext, llvm::APInt(32, mCodeGenOpts.OptimizationLevel)));
205c460b37ffb50819a32c2a8967754b6f784b28263mkopec
2069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export variable info
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportVar()) {
208b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    int slotCount = 0;
2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportVarMetadata == NULL)
21068fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang      mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
213b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
214b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // We emit slot information (#rs_object_slots) for any reference counted
215b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // RS type or pointer (which can also be bound).
2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
2186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_vars_end();
2196315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I != E;
2206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I++) {
2216315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportVar *EV = *I;
2226315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportType *ET = EV->getType();
223b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      bool countsAsRSObject = false;
2249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Variable name
2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.push_back(
2279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
230a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      switch (ET->getClass()) {
231a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPrimitive: {
232b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          const RSExportPrimitiveType *PT =
233b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines              static_cast<const RSExportPrimitiveType*>(ET);
234a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
235a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
236b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines                mLLVMContext, llvm::utostr_32(PT->getType())));
237b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          if (PT->isRSObjectType()) {
238b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            countsAsRSObject = true;
239b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          }
240a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
241a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
242a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPointer: {
243a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
244a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
2459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
246a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  ->getPointeeType()->getName()).c_str()));
247a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
248a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
249a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassMatrix: {
250a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
251a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
252a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                mLLVMContext, llvm::utostr_32(
253a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  RSExportPrimitiveType::DataTypeRSMatrix2x2 +
254a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
255a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
256a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
257a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassVector:
258a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassConstantArray:
259a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassRecord: {
260a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
261a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(mLLVMContext,
262a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                EV->getType()->getName().c_str()));
263a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
264a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
265a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      }
2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportVarMetadata->addOperand(
268d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportVarInfo));
2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.clear();
270b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
271b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (mRSObjectSlotsMetadata == NULL) {
272b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        mRSObjectSlotsMetadata =
273b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
274b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
275b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
276b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (countsAsRSObject) {
277d27a74edb932580d224a7186731aa6be098ad02eStephen Hines        mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
278d27a74edb932580d224a7186731aa6be098ad02eStephen Hines            llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
279b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
280b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
281b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      slotCount++;
282462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export function info
2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportFunc()) {
2879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportFuncMetadata == NULL)
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata =
28968fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang          M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
2929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2936315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_func_iterator
2946315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_funcs_begin(),
2956315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_funcs_end();
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
2986315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportFunc *EF = *I;
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Function name
3016315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      if (!EF->hasParam()) {
3026315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
3036315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                                     EF->getName().c_str()));
3046315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      } else {
30568fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang        llvm::Function *F = M->getFunction(EF->getName());
3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::Function *HelperFunction;
3079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const std::string HelperFunctionName(".helper_" + EF->getName());
3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3096e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(F && "Function marked as exported disappeared in Bitcode");
3109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Create helper function
312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
3130da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::StructType *HelperFunctionParameterTy = NULL;
3140da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3150da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!F->getArgumentList().empty()) {
3167c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao            std::vector<llvm::Type*> HelperFunctionParameterTys;
3170da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (llvm::Function::arg_iterator AI = F->arg_begin(),
3180da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                 AE = F->arg_end(); AI != AE; AI++)
3190da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTys.push_back(AI->getType());
3200da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3210da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            HelperFunctionParameterTy =
322a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines                llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
3230da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3240da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
3260da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            fprintf(stderr, "Failed to export function %s: parameter type "
3270da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                            "mismatch during creation of helper function.\n",
3280da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                    EF->getName().c_str());
3290da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3300da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            const RSExportRecordType *Expected = EF->getParamPacketType();
3310da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (Expected) {
3320da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Expected:\n");
3330da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              Expected->getLLVMType()->dump();
3340da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3350da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (HelperFunctionParameterTy) {
3360da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Got:\n");
3370da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTy->dump();
3380da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3390da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3400da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3417c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao          std::vector<llvm::Type*> Params;
3420da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (HelperFunctionParameterTy) {
3430da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            llvm::PointerType *HelperFunctionParameterTyP =
3440da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                llvm::PointerType::getUnqual(HelperFunctionParameterTy);
3450da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            Params.push_back(HelperFunctionParameterTyP);
3460da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3480da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::FunctionType * HelperFunctionType =
3490da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              llvm::FunctionType::get(F->getReturnType(),
350a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines                                      Params,
3510da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                                      /* IsVarArgs = */false);
3529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction =
3549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Function::Create(HelperFunctionType,
3559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     llvm::GlobalValue::ExternalLinkage,
3569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     HelperFunctionName,
35768fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang                                     M);
3589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->addFnAttr(llvm::Attribute::NoInline);
3609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->setCallingConv(F->getCallingConv());
3619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // Create helper function body
3639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          {
3649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Argument *HelperFunctionParameter =
3659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                &(*HelperFunction->arg_begin());
3669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::BasicBlock *BB =
3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
3689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
3699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::SmallVector<llvm::Value*, 6> Params;
3709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Value *Idx[2];
3719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            Idx[0] =
3739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
3749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // getelementptr and load instruction for all elements in
3769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // parameter .p
3770da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (size_t i = 0; i < EF->getNumParameters(); i++) {
3789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // getelementptr
3799207a2e495c8363606861e4f034504ec5c153dabLogan Chien              Idx[1] = llvm::ConstantInt::get(
3809207a2e495c8363606861e4f034504ec5c153dabLogan Chien                llvm::Type::getInt32Ty(mLLVMContext), i);
3819207a2e495c8363606861e4f034504ec5c153dabLogan Chien
3829207a2e495c8363606861e4f034504ec5c153dabLogan Chien              llvm::Value *Ptr =
3839207a2e495c8363606861e4f034504ec5c153dabLogan Chien                IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
3849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // load
3869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Value *V = IB->CreateLoad(Ptr);
3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              Params.push_back(V);
3889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
389462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
390a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines            // Call and pass the all elements as parameter to F
391a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines            llvm::CallInst *CI = IB->CreateCall(F, Params);
3921ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
3939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            CI->setCallingConv(F->getCallingConv());
3941ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
3959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
3969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRetVoid();
3979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            else
3989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRet(CI);
399462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            delete IB;
4019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
4029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
403462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        ExportFuncInfo.push_back(
4059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
4069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
407462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata->addOperand(
409d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
4109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportFuncInfo.clear();
4119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
4129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
4139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4144ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  // Dump export function info
4154ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  if (mContext->hasExportForEach()) {
4167b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    if (mExportForEachNameMetadata == NULL) {
4177b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachNameMetadata =
4187b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines          M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
4197b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    }
4207b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    if (mExportForEachSignatureMetadata == NULL) {
4217b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachSignatureMetadata =
4224ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
4237b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    }
4244ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4257b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    llvm::SmallVector<llvm::Value*, 1> ExportForEachName;
4264ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo;
4274ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4284ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    for (RSContext::const_export_foreach_iterator
4294ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines            I = mContext->export_foreach_begin(),
4304ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines            E = mContext->export_foreach_end();
4314ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines         I != E;
4324ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines         I++) {
4334ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      const RSExportForEach *EFE = *I;
4344ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4357b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      ExportForEachName.push_back(
4367b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines          llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
4377b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
4387b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachNameMetadata->addOperand(
4397b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportForEachName));
4407b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      ExportForEachName.clear();
4417b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
4424ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      ExportForEachInfo.push_back(
4434ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          llvm::MDString::get(mLLVMContext,
4447b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines                              llvm::utostr_32(EFE->getSignatureMetadata())));
4454ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4467b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachSignatureMetadata->addOperand(
4474ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
4484ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      ExportForEachInfo.clear();
4494ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    }
4504ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  }
4514ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export type info
4539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportType()) {
4549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
4559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_type_iterator
4576315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_types_begin(),
4586315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_types_end();
4599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
4609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
4619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // First, dump type name list to export
4629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportType *ET = I->getValue();
4639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.clear();
4659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
4669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.push_back(
4679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
4689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (ET->getClass() == RSExportType::ExportClassRecord) {
4709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const RSExportRecordType *ERT =
4719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            static_cast<const RSExportRecordType*>(ET);
4729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (mExportTypeMetadata == NULL)
4749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mExportTypeMetadata =
47568fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang              M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
4769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mExportTypeMetadata->addOperand(
478d27a74edb932580d224a7186731aa6be098ad02eStephen Hines            llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
4799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Now, export struct field information to %[struct name]
4819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        std::string StructInfoMetadataName("%");
4829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        StructInfoMetadataName.append(ET->getName());
4839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::NamedMDNode *StructInfoMetadata =
48468fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang            M->getOrInsertNamedMetadata(StructInfoMetadataName);
4859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::SmallVector<llvm::Value*, 3> FieldInfo;
4869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4876e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
4886e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines                    "Metadata with same name was created before");
4896315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
4906315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                FE = ERT->fields_end();
4916315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr             FI != FE;
4929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             FI++) {
4939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          const RSExportRecordType::Field *F = *FI;
4949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 1. field name
4969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
4979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  F->getName().c_str()));
4989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 2. field type name
5009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(
5019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::MDString::get(mLLVMContext,
5029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                  F->getType()->getName().c_str()));
5039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
504d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          StructInfoMetadata->addOperand(
505d27a74edb932580d224a7186731aa6be098ad02eStephen Hines              llvm::MDNode::get(mLLVMContext, FieldInfo));
5069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.clear();
507462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
5089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }   // ET->getClass() == RSExportType::ExportClassRecord
509462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
5109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
511462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
5129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
513462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
514462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
515462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() {
5169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
517462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
518e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
519e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
520