slang_rs_backend.cpp revision b3a12fe7c18a06f99201dc491a932a90ab7d975c
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
34592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang#include "slang_rs.h"
356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h"
366315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h"
376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h"
38e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_export_var.h"
39e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_metadata.h"
40462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
439ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSBackend::RSBackend(RSContext *Context,
44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines                     clang::Diagnostic *Diags,
459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::CodeGenOptions &CodeGenOpts,
469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::TargetOptions &TargetOpts,
473fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines                     PragmaList *Pragmas,
489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     llvm::raw_ostream *OS,
493a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     Slang::OutputType OT,
509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     clang::SourceManager &SourceMgr,
516315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                     bool AllowRSPrefix)
526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    : Backend(Diags,
536315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr              CodeGenOpts,
546315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr              TargetOpts,
556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr              Pragmas,
566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr              OS,
573a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang              OT),
586315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mContext(Context),
593a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      mSourceMgr(SourceMgr),
603a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang      mAllowRSPrefix(AllowRSPrefix),
616315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mExportVarMetadata(NULL),
626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mExportFuncMetadata(NULL),
63b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      mExportTypeMetadata(NULL),
64b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      mRSObjectSlotsMetadata(NULL) {
659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
66462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
67462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
68cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines// 1) Add zero initialization of local RS object types
69cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinesvoid RSBackend::AnnotateFunction(clang::FunctionDecl *FD) {
70cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (FD &&
71cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      FD->hasBody() &&
72cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      !SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr)) {
731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    mRefCount.Init(mContext->getASTContext());
744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    mRefCount.Visit(FD->getBody());
75cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
76cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  return;
77cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
78cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
79cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinesvoid RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
80cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Disallow user-defined functions with prefix "rs"
81cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (!mAllowRSPrefix) {
82cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    // Iterate all function declarations in the program.
83cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
84cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines         I != E; I++) {
85cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I);
86cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (FD == NULL)
87cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
88cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!FD->getName().startswith("rs"))  // Check prefix
89cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
90cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr))
91cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        mDiags.Report(clang::FullSourceLoc(FD->getLocation(), mSourceMgr),
92cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines                      mDiags.getCustomDiagID(clang::Diagnostic::Error,
93cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines                                             "invalid function name prefix, "
94cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines                                             "\"rs\" is reserved: '%0'"))
95cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines            << 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++) {
101eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I);
102eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    if (FD && FD->isGlobal()) {
103eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      AnnotateFunction(FD);
104eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    }
105cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
106cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
107cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  Backend::HandleTopLevelDecl(D);
108cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  return;
109cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
110cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
111c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesnamespace {
112c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
113e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesbool ValidateVar(clang::VarDecl *VD, clang::Diagnostic *Diags,
114e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines    clang::SourceManager *SM) {
115c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  llvm::StringRef TypeName;
116c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  const clang::Type *T = VD->getType().getTypePtr();
117dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines  if (!RSExportType::NormalizeType(T, TypeName, Diags, SM, VD)) {
118c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return false;
119c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
120c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  return true;
121c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
122c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
123c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesbool ValidateASTContext(clang::ASTContext &C, clang::Diagnostic &Diags) {
124c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  bool valid = true;
125fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
126c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(),
127c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines          DE = TUDecl->decls_end();
128c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI != DE;
129c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI++) {
130c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    if (DI->getKind() == clang::Decl::Var) {
131c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines      clang::VarDecl *VD = (clang::VarDecl*) (*DI);
132c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines      if (VD->getLinkage() == clang::ExternalLinkage) {
133e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines        if (!ValidateVar(VD, &Diags, &C.getSourceManager())) {
134c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines          valid = false;
135c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines        }
136c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines      }
137c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    }
138c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
139c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
140c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  return valid;
141c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
142c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
143e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines}  // namespace
144c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
145c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesvoid RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
146c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
147c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
148c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  if (!ValidateASTContext(C, mDiags)) {
149c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
150c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
151fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
15296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  int version = mContext->getVersion();
15396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  if (version == 0) {
15496ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    // Not setting a version is an error
15596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
15696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines                      "Missing pragma for version in source file"));
15796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  } else if (version > 1) {
15896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
15996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines                      "Pragma for version in source file must be set to 1"));
16096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
16196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
162cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any static function declarations
163fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
164fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines          E = TUDecl->decls_end(); I != E; I++) {
165fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    if ((I->getKind() >= clang::Decl::firstFunction) &&
166fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        (I->getKind() <= clang::Decl::lastFunction)) {
167eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I);
168eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      if (FD && !FD->isGlobal()) {
169eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines        AnnotateFunction(FD);
170eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      }
171fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    }
172fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  }
173fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
174fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  return;
175fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines}
176462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
177fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines///////////////////////////////////////////////////////////////////////////////
17868fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Changvoid RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
179c808a99831115928b4648f4c8b86dc682594217aStephen Hines  if (!mContext->processExport()) {
180c808a99831115928b4648f4c8b86dc682594217aStephen Hines    mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
181c808a99831115928b4648f4c8b86dc682594217aStephen Hines                                         "elements cannot be exported"));
182c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
183c808a99831115928b4648f4c8b86dc682594217aStephen Hines  }
1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export variable info
1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportVar()) {
187b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    int slotCount = 0;
1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportVarMetadata == NULL)
18968fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang      mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
192b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    llvm::SmallVector<llvm::Value*, 1> SlotVarInfo;
193b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
194b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // We emit slot information (#rs_object_slots) for any reference counted
195b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // RS type or pointer (which can also be bound).
1969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1976315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
1986315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_vars_end();
1996315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I != E;
2006315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I++) {
2016315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportVar *EV = *I;
2026315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportType *ET = EV->getType();
203b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      bool countsAsRSObject = false;
2049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Variable name
2069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.push_back(
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
2089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
210a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      switch (ET->getClass()) {
211a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPrimitive: {
212b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          const RSExportPrimitiveType *PT =
213b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines              static_cast<const RSExportPrimitiveType*>(ET);
214a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
215a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
216b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines                mLLVMContext, llvm::utostr_32(PT->getType())));
217b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          if (PT->isRSObjectType()) {
218b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            countsAsRSObject = true;
219b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          }
220a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
221a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
222a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPointer: {
223a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
224a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
2259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
226a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  ->getPointeeType()->getName()).c_str()));
227a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
228a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
229a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassMatrix: {
230a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
231a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
232a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                mLLVMContext, llvm::utostr_32(
233a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  RSExportPrimitiveType::DataTypeRSMatrix2x2 +
234a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
235a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
236a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
237a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassVector:
238a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassConstantArray:
239a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassRecord: {
240a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
241a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(mLLVMContext,
242a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                EV->getType()->getName().c_str()));
243a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
244a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
245a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      }
2469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportVarMetadata->addOperand(
2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDNode::get(mLLVMContext,
2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                            ExportVarInfo.data(),
2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                            ExportVarInfo.size()) );
2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.clear();
253b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
254b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (mRSObjectSlotsMetadata == NULL) {
255b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        mRSObjectSlotsMetadata =
256b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
257b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
258b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
259b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (countsAsRSObject) {
260b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        SlotVarInfo.push_back(
261b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount)));
262b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
263b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        mRSObjectSlotsMetadata->addOperand(
264b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            llvm::MDNode::get(mLLVMContext,
265b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines                              SlotVarInfo.data(),
266b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines                              SlotVarInfo.size()));
267b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
268b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
269b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      slotCount++;
270b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      SlotVarInfo.clear();
271462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export function info
2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportFunc()) {
2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportFuncMetadata == NULL)
2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata =
27868fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang          M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2826315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_func_iterator
2836315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_funcs_begin(),
2846315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_funcs_end();
2859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
2876315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportFunc *EF = *I;
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Function name
2906315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      if (!EF->hasParam()) {
2916315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
2926315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                                     EF->getName().c_str()));
2936315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      } else {
29468fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang        llvm::Function *F = M->getFunction(EF->getName());
2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::Function *HelperFunction;
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const std::string HelperFunctionName(".helper_" + EF->getName());
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        assert(F && "Function marked as exported disappeared in Bitcode");
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Create helper function
301462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
3020da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::StructType *HelperFunctionParameterTy = NULL;
3030da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3040da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!F->getArgumentList().empty()) {
3050da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            std::vector<const llvm::Type*> HelperFunctionParameterTys;
3060da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (llvm::Function::arg_iterator AI = F->arg_begin(),
3070da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                 AE = F->arg_end(); AI != AE; AI++)
3080da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTys.push_back(AI->getType());
3090da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3100da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            HelperFunctionParameterTy =
3110da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
3120da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3130da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3140da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
3150da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            fprintf(stderr, "Failed to export function %s: parameter type "
3160da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                            "mismatch during creation of helper function.\n",
3170da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                    EF->getName().c_str());
3180da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3190da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            const RSExportRecordType *Expected = EF->getParamPacketType();
3200da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (Expected) {
3210da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Expected:\n");
3220da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              Expected->getLLVMType()->dump();
3230da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3240da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (HelperFunctionParameterTy) {
3250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Got:\n");
3260da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTy->dump();
3270da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3280da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3290da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          std::vector<const llvm::Type*> Params;
3310da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (HelperFunctionParameterTy) {
3320da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            llvm::PointerType *HelperFunctionParameterTyP =
3330da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                llvm::PointerType::getUnqual(HelperFunctionParameterTy);
3340da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            Params.push_back(HelperFunctionParameterTyP);
3350da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3370da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::FunctionType * HelperFunctionType =
3380da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              llvm::FunctionType::get(F->getReturnType(),
3390da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                                      Params,
3400da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                                      /* IsVarArgs = */false);
3419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction =
3439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Function::Create(HelperFunctionType,
3449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     llvm::GlobalValue::ExternalLinkage,
3459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     HelperFunctionName,
34668fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang                                     M);
3479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->addFnAttr(llvm::Attribute::NoInline);
3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->setCallingConv(F->getCallingConv());
3509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // Create helper function body
3529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          {
3539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Argument *HelperFunctionParameter =
3549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                &(*HelperFunction->arg_begin());
3559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::BasicBlock *BB =
3569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
3579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
3589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::SmallVector<llvm::Value*, 6> Params;
3599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Value *Idx[2];
3609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            Idx[0] =
3629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
3639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // getelementptr and load instruction for all elements in
3659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // parameter .p
3660da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (size_t i = 0; i < EF->getNumParameters(); i++) {
3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // getelementptr
3689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              Idx[1] =
3699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::ConstantInt::get(
3709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                      llvm::Type::getInt32Ty(mLLVMContext), i);
3719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Value *Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter,
3729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                       Idx,
3739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                       Idx + 2);
3749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // load
3769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Value *V = IB->CreateLoad(Ptr);
3779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              Params.push_back(V);
3789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
379462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // Call and pass the all elements as paramter to F
3819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::CallInst *CI = IB->CreateCall(F,
3829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                Params.data(),
3839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                Params.data() + Params.size());
3841ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
3859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            CI->setCallingConv(F->getCallingConv());
3861ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
3889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRetVoid();
3899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            else
3909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRet(CI);
391462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            delete IB;
3939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
3949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
395462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        ExportFuncInfo.push_back(
3979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
3989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
399462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata->addOperand(
4019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDNode::get(mLLVMContext,
4029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                            ExportFuncInfo.data(),
4039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                            ExportFuncInfo.size()));
404462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportFuncInfo.clear();
4069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
4079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
4089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export type info
4109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportType()) {
4119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
4129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4136315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_type_iterator
4146315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_types_begin(),
4156315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_types_end();
4169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
4179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
4189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // First, dump type name list to export
4199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportType *ET = I->getValue();
4209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.clear();
4229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
4239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.push_back(
4249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
4259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (ET->getClass() == RSExportType::ExportClassRecord) {
4279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const RSExportRecordType *ERT =
4289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            static_cast<const RSExportRecordType*>(ET);
4299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (mExportTypeMetadata == NULL)
4319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mExportTypeMetadata =
43268fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang              M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
4339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mExportTypeMetadata->addOperand(
4359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDNode::get(mLLVMContext,
4369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                              ExportTypeInfo.data(),
4379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                              ExportTypeInfo.size()));
4389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Now, export struct field information to %[struct name]
4409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        std::string StructInfoMetadataName("%");
4419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        StructInfoMetadataName.append(ET->getName());
4429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::NamedMDNode *StructInfoMetadata =
44368fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang            M->getOrInsertNamedMetadata(StructInfoMetadataName);
4449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::SmallVector<llvm::Value*, 3> FieldInfo;
4459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        assert(StructInfoMetadata->getNumOperands() == 0 &&
4479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao               "Metadata with same name was created before");
4486315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
4496315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                FE = ERT->fields_end();
4506315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr             FI != FE;
4519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             FI++) {
4529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          const RSExportRecordType::Field *F = *FI;
4539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 1. field name
4559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
4569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  F->getName().c_str()));
4579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 2. field type name
4599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(
4609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::MDString::get(mLLVMContext,
4619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                  F->getType()->getName().c_str()));
4629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 3. field kind
4649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          switch (F->getType()->getClass()) {
4659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            case RSExportType::ExportClassPrimitive:
4669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            case RSExportType::ExportClassVector: {
4679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              const RSExportPrimitiveType *EPT =
4689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  static_cast<const RSExportPrimitiveType*>(F->getType());
4699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              FieldInfo.push_back(
4709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::MDString::get(mLLVMContext,
4719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                      llvm::itostr(EPT->getKind())));
4729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              break;
473462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
474462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            default: {
4769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              FieldInfo.push_back(
4779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::MDString::get(mLLVMContext,
4789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                      llvm::itostr(
4796315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                        RSExportPrimitiveType::DataKindUser)));
4809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              break;
4819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
4829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
483462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4846315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr          StructInfoMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
4856315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                                           FieldInfo.data(),
4866315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                                           FieldInfo.size()));
487462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.clear();
489462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
4909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }   // ET->getClass() == RSExportType::ExportClassRecord
491462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
4929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
493462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
495462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
496462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
497462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() {
4989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
499462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
500e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
501e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
502