slang_rs_backend.cpp revision d0b5edd02be5f09c1d8d211f4a06b031a7b66510
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/*
2c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Copyright 2010, 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"
376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h"
386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h"
39e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_export_var.h"
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_metadata.h"
41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
42e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
449ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSBackend::RSBackend(RSContext *Context,
45e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                     clang::Diagnostic *Diags,
469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::CodeGenOptions &CodeGenOpts,
479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::TargetOptions &TargetOpts,
483fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines                     PragmaList *Pragmas,
499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     llvm::raw_ostream *OS,
503a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     Slang::OutputType OT,
519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     clang::SourceManager &SourceMgr,
526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                     bool AllowRSPrefix)
536315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    : Backend(Diags,
546315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr              CodeGenOpts,
556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr              TargetOpts,
566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr              Pragmas,
576315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr              OS,
583a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang              OT),
596315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mContext(Context),
603a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      mSourceMgr(SourceMgr),
613a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      mAllowRSPrefix(AllowRSPrefix),
626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mExportVarMetadata(NULL),
636315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mExportFuncMetadata(NULL),
64b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      mExportTypeMetadata(NULL),
65d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines      mRSObjectSlotsMetadata(NULL),
66d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines      mRefCount(mContext->getASTContext()) {
679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
68462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
70cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines// 1) Add zero initialization of local RS object types
71cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinesvoid RSBackend::AnnotateFunction(clang::FunctionDecl *FD) {
72cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (FD &&
73cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      FD->hasBody() &&
74cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      !SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr)) {
75d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines    mRefCount.Init();
764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    mRefCount.Visit(FD->getBody());
77cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
78cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  return;
79cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
80cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
81cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinesvoid RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
82cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Disallow user-defined functions with prefix "rs"
83cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (!mAllowRSPrefix) {
84cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    // Iterate all function declarations in the program.
85cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
86cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines         I != E; I++) {
87cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I);
88cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (FD == NULL)
89cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
90cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!FD->getName().startswith("rs"))  // Check prefix
91cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
92cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr))
93cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        mDiags.Report(clang::FullSourceLoc(FD->getLocation(), mSourceMgr),
94cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines                      mDiags.getCustomDiagID(clang::Diagnostic::Error,
95cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines                                             "invalid function name prefix, "
96cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines                                             "\"rs\" is reserved: '%0'"))
97cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines            << FD->getName();
98cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    }
99cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
100cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
101cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any non-static function declarations
102cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
103eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I);
104eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    if (FD && FD->isGlobal()) {
105eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      AnnotateFunction(FD);
106eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    }
107cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
108cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
109cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  Backend::HandleTopLevelDecl(D);
110cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  return;
111cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
112cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
113c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesnamespace {
114c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
115e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesbool ValidateVar(clang::VarDecl *VD, clang::Diagnostic *Diags,
116e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines    clang::SourceManager *SM) {
117c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  llvm::StringRef TypeName;
118c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  const clang::Type *T = VD->getType().getTypePtr();
119dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines  if (!RSExportType::NormalizeType(T, TypeName, Diags, SM, VD)) {
120c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return false;
121c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
122c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  return true;
123c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
124c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
125c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesbool ValidateASTContext(clang::ASTContext &C, clang::Diagnostic &Diags) {
126c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  bool valid = true;
127fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
128c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(),
129c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines          DE = TUDecl->decls_end();
130c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI != DE;
131c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI++) {
132c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    if (DI->getKind() == clang::Decl::Var) {
133c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines      clang::VarDecl *VD = (clang::VarDecl*) (*DI);
134c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines      if (VD->getLinkage() == clang::ExternalLinkage) {
135e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines        if (!ValidateVar(VD, &Diags, &C.getSourceManager())) {
136c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines          valid = false;
137c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines        }
138c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines      }
139c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    }
140c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
141c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
142c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  return valid;
143c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
144c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
145e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines}  // namespace
146c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
147c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesvoid RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
148c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
149c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
150c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  if (!ValidateASTContext(C, mDiags)) {
151c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
152c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
153fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
15496ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  int version = mContext->getVersion();
15596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  if (version == 0) {
15696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    // Not setting a version is an error
15796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
15896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines                      "Missing pragma for version in source file"));
15996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  } else if (version > 1) {
16096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
16196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines                      "Pragma for version in source file must be set to 1"));
16296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
16396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
164cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any static function declarations
165fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
166fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines          E = TUDecl->decls_end(); I != E; I++) {
167fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    if ((I->getKind() >= clang::Decl::firstFunction) &&
168fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        (I->getKind() <= clang::Decl::lastFunction)) {
169eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I);
170eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      if (FD && !FD->isGlobal()) {
171eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines        AnnotateFunction(FD);
172eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      }
173fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    }
174fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  }
175fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
176fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  return;
177fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines}
178462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
179fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines///////////////////////////////////////////////////////////////////////////////
18068fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Changvoid RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
181c808a99831115928b4648f4c8b86dc682594217aStephen Hines  if (!mContext->processExport()) {
182c808a99831115928b4648f4c8b86dc682594217aStephen Hines    mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
183c808a99831115928b4648f4c8b86dc682594217aStephen Hines                                         "elements cannot be exported"));
184c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
185c808a99831115928b4648f4c8b86dc682594217aStephen Hines  }
1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export variable info
1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportVar()) {
189b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    int slotCount = 0;
1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportVarMetadata == NULL)
19168fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang      mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
194b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    llvm::SmallVector<llvm::Value*, 1> SlotVarInfo;
195b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
196b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // We emit slot information (#rs_object_slots) for any reference counted
197b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // RS type or pointer (which can also be bound).
1989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1996315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
2006315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_vars_end();
2016315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I != E;
2026315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I++) {
2036315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportVar *EV = *I;
2046315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportType *ET = EV->getType();
205b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      bool countsAsRSObject = false;
2069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Variable name
2089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.push_back(
2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
212a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      switch (ET->getClass()) {
213a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPrimitive: {
214b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          const RSExportPrimitiveType *PT =
215b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines              static_cast<const RSExportPrimitiveType*>(ET);
216a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
217a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
218b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines                mLLVMContext, llvm::utostr_32(PT->getType())));
219b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          if (PT->isRSObjectType()) {
220b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            countsAsRSObject = true;
221b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          }
222a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
223a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
224a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPointer: {
225a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
226a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
2279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
228a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  ->getPointeeType()->getName()).c_str()));
229a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
230a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
231a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassMatrix: {
232a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
233a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
234a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                mLLVMContext, llvm::utostr_32(
235a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  RSExportPrimitiveType::DataTypeRSMatrix2x2 +
236a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
237a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
238a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
239a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassVector:
240a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassConstantArray:
241a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassRecord: {
242a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
243a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(mLLVMContext,
244a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                EV->getType()->getName().c_str()));
245a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
246a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
247a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      }
2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportVarMetadata->addOperand(
2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDNode::get(mLLVMContext,
2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                            ExportVarInfo.data(),
2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                            ExportVarInfo.size()) );
2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.clear();
255b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
256b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (mRSObjectSlotsMetadata == NULL) {
257b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        mRSObjectSlotsMetadata =
258b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
259b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
260b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
261b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (countsAsRSObject) {
262b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        SlotVarInfo.push_back(
263b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount)));
264b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
265b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        mRSObjectSlotsMetadata->addOperand(
266b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            llvm::MDNode::get(mLLVMContext,
267b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines                              SlotVarInfo.data(),
268b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines                              SlotVarInfo.size()));
269b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
270b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
271b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      slotCount++;
272b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      SlotVarInfo.clear();
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()) {
3070da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            std::vector<const 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 =
3130da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                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
3329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          std::vector<const 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(),
3410da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                                      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
3709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              Idx[1] =
3719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::ConstantInt::get(
3729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                      llvm::Type::getInt32Ty(mLLVMContext), i);
3739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Value *Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter,
3749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                       Idx,
3759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                       Idx + 2);
3769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // load
3789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Value *V = IB->CreateLoad(Ptr);
3799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              Params.push_back(V);
3809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
381462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // Call and pass the all elements as paramter to F
3839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::CallInst *CI = IB->CreateCall(F,
3849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                Params.data(),
3859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                Params.data() + Params.size());
3861ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            CI->setCallingConv(F->getCallingConv());
3881ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
3899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
3909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRetVoid();
3919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            else
3929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRet(CI);
393462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            delete IB;
3959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
3969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
397462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        ExportFuncInfo.push_back(
3999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
4009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
401462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata->addOperand(
4039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDNode::get(mLLVMContext,
4049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                            ExportFuncInfo.data(),
4059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                            ExportFuncInfo.size()));
406462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportFuncInfo.clear();
4089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
4099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
4109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export type info
4129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportType()) {
4139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
4149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4156315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_type_iterator
4166315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_types_begin(),
4176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_types_end();
4189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
4199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
4209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // First, dump type name list to export
4219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportType *ET = I->getValue();
4229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.clear();
4249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
4259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.push_back(
4269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
4279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (ET->getClass() == RSExportType::ExportClassRecord) {
4299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const RSExportRecordType *ERT =
4309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            static_cast<const RSExportRecordType*>(ET);
4319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (mExportTypeMetadata == NULL)
4339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mExportTypeMetadata =
43468fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang              M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
4359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mExportTypeMetadata->addOperand(
4379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDNode::get(mLLVMContext,
4389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                              ExportTypeInfo.data(),
4399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                              ExportTypeInfo.size()));
4409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Now, export struct field information to %[struct name]
4429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        std::string StructInfoMetadataName("%");
4439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        StructInfoMetadataName.append(ET->getName());
4449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::NamedMDNode *StructInfoMetadata =
44568fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang            M->getOrInsertNamedMetadata(StructInfoMetadataName);
4469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::SmallVector<llvm::Value*, 3> FieldInfo;
4479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4486e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
4496e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines                    "Metadata with same name was created before");
4506315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
4516315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                FE = ERT->fields_end();
4526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr             FI != FE;
4539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             FI++) {
4549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          const RSExportRecordType::Field *F = *FI;
4559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 1. field name
4579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
4589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  F->getName().c_str()));
4599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 2. field type name
4619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(
4629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::MDString::get(mLLVMContext,
4639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                  F->getType()->getName().c_str()));
4649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 3. field kind
4669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          switch (F->getType()->getClass()) {
4679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            case RSExportType::ExportClassPrimitive:
4689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            case RSExportType::ExportClassVector: {
4699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              const RSExportPrimitiveType *EPT =
4709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  static_cast<const RSExportPrimitiveType*>(F->getType());
4719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              FieldInfo.push_back(
4729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::MDString::get(mLLVMContext,
4739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                      llvm::itostr(EPT->getKind())));
4749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              break;
475462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
476462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            default: {
4789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              FieldInfo.push_back(
4799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::MDString::get(mLLVMContext,
4809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                      llvm::itostr(
4816315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                        RSExportPrimitiveType::DataKindUser)));
4829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              break;
4839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
4849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
485462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4866315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr          StructInfoMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
4876315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                                           FieldInfo.data(),
4886315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                                           FieldInfo.size()));
489462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.clear();
491462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
4929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }   // ET->getClass() == RSExportType::ExportClassRecord
493462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
4949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
495462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
497462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
498462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
499462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() {
5009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
501462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
502e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
503e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
504