slang_rs_backend.cpp revision ab992e59a36a18df49bf4878968ef0598299afd3
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++) {
87ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::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++) {
103ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    clang::FunctionDecl *FD = llvm::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
11578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hinesstatic bool ValidateVarDecl(clang::VarDecl *VD) {
11678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  if (!VD) {
11778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    return true;
11878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  }
11978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
12078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  clang::ASTContext &C = VD->getASTContext();
121c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  const clang::Type *T = VD->getType().getTypePtr();
12278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  bool valid = true;
12378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
12478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  if (VD->getLinkage() == clang::ExternalLinkage) {
12578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    llvm::StringRef TypeName;
12678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    if (!RSExportType::NormalizeType(T, TypeName, &C.getDiagnostics(), VD)) {
12778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines      valid = false;
12878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    }
129c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
13078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  valid &= RSExportType::ValidateVarDecl(VD);
13178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
13278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  return valid;
133c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
134c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
13578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hinesstatic bool ValidateASTContext(clang::ASTContext &C) {
136c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  bool valid = true;
137fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
138c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(),
139c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines          DE = TUDecl->decls_end();
140c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI != DE;
141c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI++) {
142ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*DI);
14378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    if (VD && !ValidateVarDecl(VD)) {
14478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines      valid = false;
145c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    }
146c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
147c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
148c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  return valid;
149c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
150c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
151e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines}  // namespace
152c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
153c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesvoid RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
154c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
155c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
15678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  if (!ValidateASTContext(C)) {
157c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
158c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
159fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
16096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  int version = mContext->getVersion();
16196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  if (version == 0) {
16296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    // Not setting a version is an error
16396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
16496ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines                      "Missing pragma for version in source file"));
16596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  } else if (version > 1) {
16696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
16796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines                      "Pragma for version in source file must be set to 1"));
16896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
16996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
170cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any static function declarations
171fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
172fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines          E = TUDecl->decls_end(); I != E; I++) {
173fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    if ((I->getKind() >= clang::Decl::firstFunction) &&
174fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        (I->getKind() <= clang::Decl::lastFunction)) {
175ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
176eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      if (FD && !FD->isGlobal()) {
177eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines        AnnotateFunction(FD);
178eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      }
179fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    }
180fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  }
181fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
182fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  return;
183fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines}
184462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
185fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines///////////////////////////////////////////////////////////////////////////////
18668fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Changvoid RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
187c808a99831115928b4648f4c8b86dc682594217aStephen Hines  if (!mContext->processExport()) {
188c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
189c808a99831115928b4648f4c8b86dc682594217aStephen Hines  }
1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export variable info
1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportVar()) {
193b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    int slotCount = 0;
1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportVarMetadata == NULL)
19568fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang      mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
1969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
198b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
199b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // We emit slot information (#rs_object_slots) for any reference counted
200b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // RS type or pointer (which can also be bound).
2019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2026315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
2036315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_vars_end();
2046315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I != E;
2056315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I++) {
2066315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportVar *EV = *I;
2076315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportType *ET = EV->getType();
208b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      bool countsAsRSObject = false;
2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Variable name
2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.push_back(
2129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
2139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
215a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      switch (ET->getClass()) {
216a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPrimitive: {
217b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          const RSExportPrimitiveType *PT =
218b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines              static_cast<const RSExportPrimitiveType*>(ET);
219a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
220a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
221b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines                mLLVMContext, llvm::utostr_32(PT->getType())));
222b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          if (PT->isRSObjectType()) {
223b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            countsAsRSObject = true;
224b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          }
225a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
226a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
227a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPointer: {
228a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
229a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
231a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  ->getPointeeType()->getName()).c_str()));
232a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
233a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
234a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassMatrix: {
235a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
236a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
237a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                mLLVMContext, llvm::utostr_32(
238a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  RSExportPrimitiveType::DataTypeRSMatrix2x2 +
239a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
240a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
241a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
242a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassVector:
243a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassConstantArray:
244a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassRecord: {
245a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
246a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(mLLVMContext,
247a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                EV->getType()->getName().c_str()));
248a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
249a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
250a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      }
2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportVarMetadata->addOperand(
253d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportVarInfo));
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) {
262d27a74edb932580d224a7186731aa6be098ad02eStephen Hines        mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
263d27a74edb932580d224a7186731aa6be098ad02eStephen Hines            llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
264b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
265b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
266b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      slotCount++;
267462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export function info
2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportFunc()) {
2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportFuncMetadata == NULL)
2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata =
27468fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang          M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2786315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_func_iterator
2796315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_funcs_begin(),
2806315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_funcs_end();
2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
2836315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportFunc *EF = *I;
2849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Function name
2866315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      if (!EF->hasParam()) {
2876315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
2886315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                                     EF->getName().c_str()));
2896315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      } else {
29068fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang        llvm::Function *F = M->getFunction(EF->getName());
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::Function *HelperFunction;
2929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const std::string HelperFunctionName(".helper_" + EF->getName());
2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2946e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(F && "Function marked as exported disappeared in Bitcode");
2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Create helper function
297462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
2980da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::StructType *HelperFunctionParameterTy = NULL;
2990da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3000da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!F->getArgumentList().empty()) {
3017c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao            std::vector<llvm::Type*> HelperFunctionParameterTys;
3020da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (llvm::Function::arg_iterator AI = F->arg_begin(),
3030da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                 AE = F->arg_end(); AI != AE; AI++)
3040da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTys.push_back(AI->getType());
3050da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3060da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            HelperFunctionParameterTy =
307a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines                llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
3080da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3090da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3100da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
3110da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            fprintf(stderr, "Failed to export function %s: parameter type "
3120da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                            "mismatch during creation of helper function.\n",
3130da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                    EF->getName().c_str());
3140da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3150da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            const RSExportRecordType *Expected = EF->getParamPacketType();
3160da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (Expected) {
3170da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Expected:\n");
3180da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              Expected->getLLVMType()->dump();
3190da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3200da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (HelperFunctionParameterTy) {
3210da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Got:\n");
3220da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTy->dump();
3230da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3240da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3267c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao          std::vector<llvm::Type*> Params;
3270da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (HelperFunctionParameterTy) {
3280da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            llvm::PointerType *HelperFunctionParameterTyP =
3290da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                llvm::PointerType::getUnqual(HelperFunctionParameterTy);
3300da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            Params.push_back(HelperFunctionParameterTyP);
3310da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3330da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::FunctionType * HelperFunctionType =
3340da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              llvm::FunctionType::get(F->getReturnType(),
335a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines                                      Params,
3360da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                                      /* IsVarArgs = */false);
3379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction =
3399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Function::Create(HelperFunctionType,
3409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     llvm::GlobalValue::ExternalLinkage,
3419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     HelperFunctionName,
34268fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang                                     M);
3439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->addFnAttr(llvm::Attribute::NoInline);
3459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->setCallingConv(F->getCallingConv());
3469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // Create helper function body
3489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          {
3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Argument *HelperFunctionParameter =
3509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                &(*HelperFunction->arg_begin());
3519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::BasicBlock *BB =
3529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
3539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
3549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::SmallVector<llvm::Value*, 6> Params;
3559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Value *Idx[2];
3569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            Idx[0] =
3589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
3599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // getelementptr and load instruction for all elements in
3619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // parameter .p
3620da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (size_t i = 0; i < EF->getNumParameters(); i++) {
3639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // getelementptr
3649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              Idx[1] =
3659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::ConstantInt::get(
3669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                      llvm::Type::getInt32Ty(mLLVMContext), i);
3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Value *Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter,
3689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                       Idx,
3699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                       Idx + 2);
3709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // load
3729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Value *V = IB->CreateLoad(Ptr);
3739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              Params.push_back(V);
3749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
375462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
376a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines            // Call and pass the all elements as parameter to F
377a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines            llvm::CallInst *CI = IB->CreateCall(F, Params);
3781ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
3799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            CI->setCallingConv(F->getCallingConv());
3801ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
3819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
3829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRetVoid();
3839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            else
3849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRet(CI);
385462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            delete IB;
3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
3889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
389462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        ExportFuncInfo.push_back(
3919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
3929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
393462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata->addOperand(
395d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
3969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportFuncInfo.clear();
3979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
3999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export type info
4019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportType()) {
4029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
4039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4046315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_type_iterator
4056315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_types_begin(),
4066315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_types_end();
4079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
4089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
4099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // First, dump type name list to export
4109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportType *ET = I->getValue();
4119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.clear();
4139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
4149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.push_back(
4159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
4169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (ET->getClass() == RSExportType::ExportClassRecord) {
4189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const RSExportRecordType *ERT =
4199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            static_cast<const RSExportRecordType*>(ET);
4209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (mExportTypeMetadata == NULL)
4229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mExportTypeMetadata =
42368fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang              M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
4249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mExportTypeMetadata->addOperand(
426d27a74edb932580d224a7186731aa6be098ad02eStephen Hines            llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
4279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Now, export struct field information to %[struct name]
4299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        std::string StructInfoMetadataName("%");
4309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        StructInfoMetadataName.append(ET->getName());
4319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::NamedMDNode *StructInfoMetadata =
43268fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang            M->getOrInsertNamedMetadata(StructInfoMetadataName);
4339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::SmallVector<llvm::Value*, 3> FieldInfo;
4349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4356e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
4366e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines                    "Metadata with same name was created before");
4376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
4386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                FE = ERT->fields_end();
4396315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr             FI != FE;
4409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             FI++) {
4419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          const RSExportRecordType::Field *F = *FI;
4429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 1. field name
4449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
4459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  F->getName().c_str()));
4469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 2. field type name
4489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(
4499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::MDString::get(mLLVMContext,
4509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                  F->getType()->getName().c_str()));
4519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 3. field kind
4539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          switch (F->getType()->getClass()) {
4549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            case RSExportType::ExportClassPrimitive:
4559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            case RSExportType::ExportClassVector: {
4569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              const RSExportPrimitiveType *EPT =
4579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  static_cast<const RSExportPrimitiveType*>(F->getType());
4589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              FieldInfo.push_back(
4599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::MDString::get(mLLVMContext,
4609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                      llvm::itostr(EPT->getKind())));
4619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              break;
462462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
463462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            default: {
4659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              FieldInfo.push_back(
4669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::MDString::get(mLLVMContext,
4679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                      llvm::itostr(
4686315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                        RSExportPrimitiveType::DataKindUser)));
4699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              break;
4709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
4719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
472462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
473d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          StructInfoMetadata->addOperand(
474d27a74edb932580d224a7186731aa6be098ad02eStephen Hines              llvm::MDNode::get(mLLVMContext, FieldInfo));
4759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.clear();
476462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
4779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }   // ET->getClass() == RSExportType::ExportClassRecord
478462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
4799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
480462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
482462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
483462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
484462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() {
4859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
486462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
487e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
488e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
489