slang_rs_backend.cpp revision 7b51b55e4467605a599e868a0dde7cb95c5ab76e
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
22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/Twine.h"
23e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/StringExtras.h"
24462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Constant.h"
269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Constants.h"
279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/DerivedTypes.h"
28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Function.h"
29e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Metadata.h"
30e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Module.h"
31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/IRBuilder.h"
336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
346e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
35592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang#include "slang_rs.h"
366315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h"
374ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines#include "slang_rs_export_foreach.h"
386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h"
396315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h"
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_export_var.h"
41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_metadata.h"
42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
459ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSBackend::RSBackend(RSContext *Context,
469207a2e495c8363606861e4f034504ec5c153dabLogan Chien                     clang::DiagnosticsEngine *DiagEngine,
479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::CodeGenOptions &CodeGenOpts,
489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::TargetOptions &TargetOpts,
493fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines                     PragmaList *Pragmas,
509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     llvm::raw_ostream *OS,
513a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     Slang::OutputType OT,
529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     clang::SourceManager &SourceMgr,
534a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines                     bool AllowRSPrefix)
549207a2e495c8363606861e4f034504ec5c153dabLogan Chien  : Backend(DiagEngine, CodeGenOpts, TargetOpts, Pragmas, OS, OT),
559207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mContext(Context),
569207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mSourceMgr(SourceMgr),
579207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mAllowRSPrefix(AllowRSPrefix),
589207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportVarMetadata(NULL),
599207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportFuncMetadata(NULL),
607b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    mExportForEachNameMetadata(NULL),
617b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    mExportForEachSignatureMetadata(NULL),
629207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportTypeMetadata(NULL),
639207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mRSObjectSlotsMetadata(NULL),
649207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mRefCount(mContext->getASTContext()) {
65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
66462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
67cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines// 1) Add zero initialization of local RS object types
68cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinesvoid RSBackend::AnnotateFunction(clang::FunctionDecl *FD) {
69cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (FD &&
70cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      FD->hasBody() &&
71cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      !SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr)) {
72d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines    mRefCount.Init();
734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    mRefCount.Visit(FD->getBody());
74cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
75cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  return;
76cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
77cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
78fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chienbool RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
79cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Disallow user-defined functions with prefix "rs"
80cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (!mAllowRSPrefix) {
81cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    // Iterate all function declarations in the program.
82cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
83cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines         I != E; I++) {
84ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
85cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (FD == NULL)
86cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
87cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!FD->getName().startswith("rs"))  // Check prefix
88cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
89cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr))
909207a2e495c8363606861e4f034504ec5c153dabLogan Chien        mDiagEngine.Report(
919207a2e495c8363606861e4f034504ec5c153dabLogan Chien          clang::FullSourceLoc(FD->getLocation(), mSourceMgr),
929207a2e495c8363606861e4f034504ec5c153dabLogan Chien          mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
939207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                      "invalid function name prefix, "
949207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                      "\"rs\" is reserved: '%0'"))
959207a2e495c8363606861e4f034504ec5c153dabLogan Chien          << FD->getName();
96cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    }
97cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
98cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
99cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any non-static function declarations
100cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
101ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
102eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    if (FD && FD->isGlobal()) {
103eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      AnnotateFunction(FD);
104eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    }
105cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
106cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
107fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chien  return Backend::HandleTopLevelDecl(D);
108cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
109cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
110c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesnamespace {
111c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
11278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hinesstatic bool ValidateVarDecl(clang::VarDecl *VD) {
11378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  if (!VD) {
11478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    return true;
11578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  }
11678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
11778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  clang::ASTContext &C = VD->getASTContext();
118c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  const clang::Type *T = VD->getType().getTypePtr();
11978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  bool valid = true;
12078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
12178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  if (VD->getLinkage() == clang::ExternalLinkage) {
12278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    llvm::StringRef TypeName;
12378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    if (!RSExportType::NormalizeType(T, TypeName, &C.getDiagnostics(), VD)) {
12478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines      valid = false;
12578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    }
126c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
12778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  valid &= RSExportType::ValidateVarDecl(VD);
12878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
12978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  return valid;
130c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
131c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
13278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hinesstatic bool ValidateASTContext(clang::ASTContext &C) {
133c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  bool valid = true;
134fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
135c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(),
136c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines          DE = TUDecl->decls_end();
137c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI != DE;
138c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI++) {
139ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*DI);
14078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    if (VD && !ValidateVarDecl(VD)) {
14178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines      valid = false;
142c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    }
143c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
144c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
145c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  return valid;
146c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
147c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
148e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines}  // namespace
149c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
150c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesvoid RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
151c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
152c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
15378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  if (!ValidateASTContext(C)) {
154c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
155c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
156fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
15796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  int version = mContext->getVersion();
15896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  if (version == 0) {
15996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    // Not setting a version is an error
1607aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    mDiagEngine.Report(
1617aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
1627aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        mDiagEngine.getCustomDiagID(
1637aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines            clang::DiagnosticsEngine::Error,
1647aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines            "missing pragma for version in source file"));
1657aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines  } else {
1667aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    slangAssert(version == 1);
16796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
16896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
169688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // Create a static global destructor if necessary (to handle RS object
170688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // runtime cleanup).
171688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
172688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  if (FD) {
173688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    HandleTopLevelDecl(clang::DeclGroupRef(FD));
174688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  }
175688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines
176cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any static function declarations
177fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
178fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines          E = TUDecl->decls_end(); I != E; I++) {
179fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    if ((I->getKind() >= clang::Decl::firstFunction) &&
180fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        (I->getKind() <= clang::Decl::lastFunction)) {
181ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
182eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      if (FD && !FD->isGlobal()) {
183eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines        AnnotateFunction(FD);
184eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      }
185fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    }
186fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  }
187fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
188fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  return;
189fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines}
190462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
191fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines///////////////////////////////////////////////////////////////////////////////
19268fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Changvoid RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
193c808a99831115928b4648f4c8b86dc682594217aStephen Hines  if (!mContext->processExport()) {
194c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
195c808a99831115928b4648f4c8b86dc682594217aStephen Hines  }
1969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export variable info
1989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportVar()) {
199b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    int slotCount = 0;
2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportVarMetadata == NULL)
20168fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang      mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
2029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
204b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
205b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // We emit slot information (#rs_object_slots) for any reference counted
206b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // RS type or pointer (which can also be bound).
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2086315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
2096315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_vars_end();
2106315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I != E;
2116315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I++) {
2126315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportVar *EV = *I;
2136315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportType *ET = EV->getType();
214b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      bool countsAsRSObject = false;
2159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Variable name
2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.push_back(
2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
2199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
221a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      switch (ET->getClass()) {
222a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPrimitive: {
223b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          const RSExportPrimitiveType *PT =
224b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines              static_cast<const RSExportPrimitiveType*>(ET);
225a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
226a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
227b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines                mLLVMContext, llvm::utostr_32(PT->getType())));
228b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          if (PT->isRSObjectType()) {
229b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            countsAsRSObject = true;
230b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          }
231a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
232a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
233a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPointer: {
234a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
235a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
237a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  ->getPointeeType()->getName()).c_str()));
238a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
239a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
240a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassMatrix: {
241a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
242a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
243a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                mLLVMContext, llvm::utostr_32(
244a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  RSExportPrimitiveType::DataTypeRSMatrix2x2 +
245a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
246a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
247a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
248a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassVector:
249a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassConstantArray:
250a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassRecord: {
251a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
252a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(mLLVMContext,
253a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                EV->getType()->getName().c_str()));
254a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
255a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
256a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      }
2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportVarMetadata->addOperand(
259d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportVarInfo));
2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.clear();
261b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
262b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (mRSObjectSlotsMetadata == NULL) {
263b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        mRSObjectSlotsMetadata =
264b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
265b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
266b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
267b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (countsAsRSObject) {
268d27a74edb932580d224a7186731aa6be098ad02eStephen Hines        mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
269d27a74edb932580d224a7186731aa6be098ad02eStephen Hines            llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
270b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
271b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
272b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      slotCount++;
273462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export function info
2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportFunc()) {
2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportFuncMetadata == NULL)
2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata =
28068fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang          M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
2839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2846315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_func_iterator
2856315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_funcs_begin(),
2866315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_funcs_end();
2879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
2896315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportFunc *EF = *I;
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Function name
2926315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      if (!EF->hasParam()) {
2936315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
2946315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                                     EF->getName().c_str()));
2956315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      } else {
29668fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang        llvm::Function *F = M->getFunction(EF->getName());
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::Function *HelperFunction;
2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const std::string HelperFunctionName(".helper_" + EF->getName());
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3006e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(F && "Function marked as exported disappeared in Bitcode");
3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Create helper function
303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
3040da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::StructType *HelperFunctionParameterTy = NULL;
3050da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3060da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!F->getArgumentList().empty()) {
3077c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao            std::vector<llvm::Type*> HelperFunctionParameterTys;
3080da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (llvm::Function::arg_iterator AI = F->arg_begin(),
3090da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                 AE = F->arg_end(); AI != AE; AI++)
3100da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTys.push_back(AI->getType());
3110da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3120da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            HelperFunctionParameterTy =
313a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines                llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
3140da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3150da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3160da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
3170da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            fprintf(stderr, "Failed to export function %s: parameter type "
3180da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                            "mismatch during creation of helper function.\n",
3190da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                    EF->getName().c_str());
3200da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3210da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            const RSExportRecordType *Expected = EF->getParamPacketType();
3220da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (Expected) {
3230da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Expected:\n");
3240da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              Expected->getLLVMType()->dump();
3250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3260da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (HelperFunctionParameterTy) {
3270da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Got:\n");
3280da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTy->dump();
3290da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3300da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3310da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3327c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao          std::vector<llvm::Type*> Params;
3330da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (HelperFunctionParameterTy) {
3340da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            llvm::PointerType *HelperFunctionParameterTyP =
3350da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                llvm::PointerType::getUnqual(HelperFunctionParameterTy);
3360da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            Params.push_back(HelperFunctionParameterTyP);
3370da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3390da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::FunctionType * HelperFunctionType =
3400da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              llvm::FunctionType::get(F->getReturnType(),
341a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines                                      Params,
3420da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                                      /* IsVarArgs = */false);
3439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction =
3459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Function::Create(HelperFunctionType,
3469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     llvm::GlobalValue::ExternalLinkage,
3479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     HelperFunctionName,
34868fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang                                     M);
3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->addFnAttr(llvm::Attribute::NoInline);
3519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->setCallingConv(F->getCallingConv());
3529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // Create helper function body
3549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          {
3559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Argument *HelperFunctionParameter =
3569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                &(*HelperFunction->arg_begin());
3579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::BasicBlock *BB =
3589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
3599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
3609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::SmallVector<llvm::Value*, 6> Params;
3619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Value *Idx[2];
3629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            Idx[0] =
3649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
3659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // getelementptr and load instruction for all elements in
3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // parameter .p
3680da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (size_t i = 0; i < EF->getNumParameters(); i++) {
3699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // getelementptr
3709207a2e495c8363606861e4f034504ec5c153dabLogan Chien              Idx[1] = llvm::ConstantInt::get(
3719207a2e495c8363606861e4f034504ec5c153dabLogan Chien                llvm::Type::getInt32Ty(mLLVMContext), i);
3729207a2e495c8363606861e4f034504ec5c153dabLogan Chien
3739207a2e495c8363606861e4f034504ec5c153dabLogan Chien              llvm::Value *Ptr =
3749207a2e495c8363606861e4f034504ec5c153dabLogan Chien                IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
3759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // load
3779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Value *V = IB->CreateLoad(Ptr);
3789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              Params.push_back(V);
3799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
380462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
381a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines            // Call and pass the all elements as parameter to F
382a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines            llvm::CallInst *CI = IB->CreateCall(F, Params);
3831ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
3849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            CI->setCallingConv(F->getCallingConv());
3851ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
3869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRetVoid();
3889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            else
3899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRet(CI);
390462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            delete IB;
3929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
3939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
394462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        ExportFuncInfo.push_back(
3969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
3979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
398462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata->addOperand(
400d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
4019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportFuncInfo.clear();
4029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
4039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
4049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4054ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  // Dump export function info
4064ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  if (mContext->hasExportForEach()) {
4077b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    if (mExportForEachNameMetadata == NULL) {
4087b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachNameMetadata =
4097b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines          M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
4107b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    }
4117b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    if (mExportForEachSignatureMetadata == NULL) {
4127b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachSignatureMetadata =
4134ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
4147b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    }
4154ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4167b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    llvm::SmallVector<llvm::Value*, 1> ExportForEachName;
4174ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo;
4184ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4194ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    for (RSContext::const_export_foreach_iterator
4204ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines            I = mContext->export_foreach_begin(),
4214ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines            E = mContext->export_foreach_end();
4224ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines         I != E;
4234ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines         I++) {
4244ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      const RSExportForEach *EFE = *I;
4254ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4267b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      ExportForEachName.push_back(
4277b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines          llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
4287b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
4297b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachNameMetadata->addOperand(
4307b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportForEachName));
4317b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      ExportForEachName.clear();
4327b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
4334ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      ExportForEachInfo.push_back(
4344ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          llvm::MDString::get(mLLVMContext,
4357b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines                              llvm::utostr_32(EFE->getSignatureMetadata())));
4364ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4377b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachSignatureMetadata->addOperand(
4384ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
4394ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      ExportForEachInfo.clear();
4404ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    }
4414ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  }
4424ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export type info
4449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportType()) {
4459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
4469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4476315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_type_iterator
4486315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_types_begin(),
4496315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_types_end();
4509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
4519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
4529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // First, dump type name list to export
4539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportType *ET = I->getValue();
4549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.clear();
4569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
4579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.push_back(
4589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
4599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (ET->getClass() == RSExportType::ExportClassRecord) {
4619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const RSExportRecordType *ERT =
4629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            static_cast<const RSExportRecordType*>(ET);
4639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (mExportTypeMetadata == NULL)
4659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mExportTypeMetadata =
46668fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang              M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
4679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mExportTypeMetadata->addOperand(
469d27a74edb932580d224a7186731aa6be098ad02eStephen Hines            llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
4709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Now, export struct field information to %[struct name]
4729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        std::string StructInfoMetadataName("%");
4739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        StructInfoMetadataName.append(ET->getName());
4749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::NamedMDNode *StructInfoMetadata =
47568fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang            M->getOrInsertNamedMetadata(StructInfoMetadataName);
4769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::SmallVector<llvm::Value*, 3> FieldInfo;
4779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4786e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
4796e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines                    "Metadata with same name was created before");
4806315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
4816315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                FE = ERT->fields_end();
4826315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr             FI != FE;
4839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             FI++) {
4849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          const RSExportRecordType::Field *F = *FI;
4859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 1. field name
4879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
4889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  F->getName().c_str()));
4899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 2. field type name
4919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(
4929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::MDString::get(mLLVMContext,
4939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                  F->getType()->getName().c_str()));
4949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 3. field kind
4969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          switch (F->getType()->getClass()) {
4979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            case RSExportType::ExportClassPrimitive:
4989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            case RSExportType::ExportClassVector: {
4999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              const RSExportPrimitiveType *EPT =
5009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  static_cast<const RSExportPrimitiveType*>(F->getType());
5019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              FieldInfo.push_back(
5029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::MDString::get(mLLVMContext,
5039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                      llvm::itostr(EPT->getKind())));
5049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              break;
505462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
506462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
5079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            default: {
5089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              FieldInfo.push_back(
5099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::MDString::get(mLLVMContext,
5109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                      llvm::itostr(
5116315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                        RSExportPrimitiveType::DataKindUser)));
5129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              break;
5139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
5149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
515462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
516d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          StructInfoMetadata->addOperand(
517d27a74edb932580d224a7186731aa6be098ad02eStephen Hines              llvm::MDNode::get(mLLVMContext, FieldInfo));
5189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.clear();
519462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
5209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }   // ET->getClass() == RSExportType::ExportClassRecord
521462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
5229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
523462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
5249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
525462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
526462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
527462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() {
5289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
529462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
530e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
531e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
532