slang_rs_backend.cpp revision 48d893dc7794b3cfb74f35955ca763ee4170f9ad
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/*
27b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines * Copyright 2010-2012, The Android Open Source Project
3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License.
6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at
7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software
11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and
14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License.
15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */
16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang
176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_backend.h"
18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
196315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <string>
20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <vector>
21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
2243730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao#include "clang/AST/ASTContext.h"
23c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "clang/Frontend/CodeGenOptions.h"
24c460b37ffb50819a32c2a8967754b6f784b28263mkopec
25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/Twine.h"
26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/StringExtras.h"
27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Constant.h"
2923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Constants.h"
3023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/DerivedTypes.h"
3123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Function.h"
3223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/IRBuilder.h"
3323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Metadata.h"
3423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Module.h"
35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
36c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "llvm/Support/DebugLoc.h"
376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
386e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
39592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang#include "slang_rs.h"
406315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h"
414ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines#include "slang_rs_export_foreach.h"
426315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h"
436315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h"
44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_export_var.h"
45e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_metadata.h"
46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
47e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
499ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSBackend::RSBackend(RSContext *Context,
509207a2e495c8363606861e4f034504ec5c153dabLogan Chien                     clang::DiagnosticsEngine *DiagEngine,
519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::CodeGenOptions &CodeGenOpts,
529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::TargetOptions &TargetOpts,
533fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines                     PragmaList *Pragmas,
549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     llvm::raw_ostream *OS,
553a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     Slang::OutputType OT,
569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     clang::SourceManager &SourceMgr,
5711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines                     bool AllowRSPrefix,
5811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines                     bool IsFilterscript)
599207a2e495c8363606861e4f034504ec5c153dabLogan Chien  : Backend(DiagEngine, CodeGenOpts, TargetOpts, Pragmas, OS, OT),
609207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mContext(Context),
619207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mSourceMgr(SourceMgr),
629207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mAllowRSPrefix(AllowRSPrefix),
6311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines    mIsFilterscript(IsFilterscript),
649207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportVarMetadata(NULL),
659207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportFuncMetadata(NULL),
667b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    mExportForEachNameMetadata(NULL),
677b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    mExportForEachSignatureMetadata(NULL),
689207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportTypeMetadata(NULL),
699207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mRSObjectSlotsMetadata(NULL),
7011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines    mRefCount(mContext->getASTContext()),
7148d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines    mASTChecker(Context, Context->getTargetAPI(), IsFilterscript) {
72462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
74cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines// 1) Add zero initialization of local RS object types
75cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinesvoid RSBackend::AnnotateFunction(clang::FunctionDecl *FD) {
76cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (FD &&
77cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      FD->hasBody() &&
7811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines      !SlangRS::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
79d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines    mRefCount.Init();
804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    mRefCount.Visit(FD->getBody());
81cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
82cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  return;
83cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
84cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
85fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chienbool RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
86cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Disallow user-defined functions with prefix "rs"
87cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (!mAllowRSPrefix) {
88cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    // Iterate all function declarations in the program.
89cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
90cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines         I != E; I++) {
91ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
92cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (FD == NULL)
93cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
94cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!FD->getName().startswith("rs"))  // Check prefix
95cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
9611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines      if (!SlangRS::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
979207a2e495c8363606861e4f034504ec5c153dabLogan Chien        mDiagEngine.Report(
989207a2e495c8363606861e4f034504ec5c153dabLogan Chien          clang::FullSourceLoc(FD->getLocation(), mSourceMgr),
999207a2e495c8363606861e4f034504ec5c153dabLogan Chien          mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
1009207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                      "invalid function name prefix, "
1019207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                      "\"rs\" is reserved: '%0'"))
1029207a2e495c8363606861e4f034504ec5c153dabLogan Chien          << FD->getName();
103cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    }
104cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
105cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
106cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any non-static function declarations
107cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
108ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
109eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    if (FD && FD->isGlobal()) {
110ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      // Check that we don't have any array parameters being misintrepeted as
111ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      // kernel pointers due to the C type system's array to pointer decay.
112ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      size_t numParams = FD->getNumParams();
113ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      for (size_t i = 0; i < numParams; i++) {
114ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines        const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
115ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines        clang::QualType QT = PVD->getOriginalType();
116ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines        if (QT->isArrayType()) {
117ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines          mDiagEngine.Report(
118ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines            clang::FullSourceLoc(PVD->getTypeSpecStartLoc(), mSourceMgr),
119ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines            mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
120ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines                                        "exported function parameters may "
121ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines                                        "not have array type: %0")) << QT;
122ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines        }
123ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      }
124eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      AnnotateFunction(FD);
125eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    }
126cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
127cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
128fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chien  return Backend::HandleTopLevelDecl(D);
129cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
130cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
131c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
132c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesvoid RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
133c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
134c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
13511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines  // If we have an invalid RS/FS AST, don't check further.
13611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines  if (!mASTChecker.Validate()) {
137c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
138c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
139fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
14011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines  if (mIsFilterscript) {
14111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines    mContext->addPragma("rs_fp_relaxed", "");
14211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines  }
14311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines
14496ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  int version = mContext->getVersion();
14596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  if (version == 0) {
14696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    // Not setting a version is an error
1477aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    mDiagEngine.Report(
1487aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
1497aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        mDiagEngine.getCustomDiagID(
1507aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines            clang::DiagnosticsEngine::Error,
1517aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines            "missing pragma for version in source file"));
1527aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines  } else {
1537aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    slangAssert(version == 1);
15496ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
15596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
156cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines  if (mContext->getReflectJavaPackageName().empty()) {
157cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines    mDiagEngine.Report(
158cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
159cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines        mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
160cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines                                    "missing \"#pragma rs "
161cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines                                    "java_package_name(com.foo.bar)\" "
162cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines                                    "in source file"));
163cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines    return;
164cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines  }
165cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines
166688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // Create a static global destructor if necessary (to handle RS object
167688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // runtime cleanup).
168688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
169688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  if (FD) {
170688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    HandleTopLevelDecl(clang::DeclGroupRef(FD));
171688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  }
172688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines
173cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any static function declarations
174fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
175fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines          E = TUDecl->decls_end(); I != E; I++) {
176fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    if ((I->getKind() >= clang::Decl::firstFunction) &&
177fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        (I->getKind() <= clang::Decl::lastFunction)) {
178ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
179eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      if (FD && !FD->isGlobal()) {
180eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines        AnnotateFunction(FD);
181eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      }
182fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    }
183fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  }
184fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
185fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  return;
186fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines}
187462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
188fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines///////////////////////////////////////////////////////////////////////////////
189d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::dumpExportVarInfo(llvm::Module *M) {
190d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  int slotCount = 0;
191d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mExportVarMetadata == NULL)
192d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
193d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
194d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
195d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
196d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  // We emit slot information (#rs_object_slots) for any reference counted
197d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  // RS type or pointer (which can also be bound).
198d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
199d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
200d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          E = mContext->export_vars_end();
201d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I != E;
202d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I++) {
203d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    const RSExportVar *EV = *I;
204d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    const RSExportType *ET = EV->getType();
205d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    bool countsAsRSObject = false;
206d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
207d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    // Variable name
208d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportVarInfo.push_back(
209d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
210d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
211d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    // Type name
212d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    switch (ET->getClass()) {
213d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      case RSExportType::ExportClassPrimitive: {
214d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        const RSExportPrimitiveType *PT =
215d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            static_cast<const RSExportPrimitiveType*>(ET);
216d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        ExportVarInfo.push_back(
217d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::MDString::get(
218d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              mLLVMContext, llvm::utostr_32(PT->getType())));
219d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        if (PT->isRSObjectType()) {
220d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          countsAsRSObject = true;
221a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
222d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        break;
223a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      }
224d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      case RSExportType::ExportClassPointer: {
225d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        ExportVarInfo.push_back(
226d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::MDString::get(
227d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
228d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                ->getPointeeType()->getName()).c_str()));
229d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        break;
230b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
231d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      case RSExportType::ExportClassMatrix: {
232d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        ExportVarInfo.push_back(
233d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::MDString::get(
234d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              mLLVMContext, llvm::utostr_32(
235d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                RSExportPrimitiveType::DataTypeRSMatrix2x2 +
236d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
237d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        break;
238b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
239d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      case RSExportType::ExportClassVector:
240d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      case RSExportType::ExportClassConstantArray:
241d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      case RSExportType::ExportClassRecord: {
242d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        ExportVarInfo.push_back(
243d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::MDString::get(mLLVMContext,
244d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              EV->getType()->getName().c_str()));
245d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        break;
246d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      }
247d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    }
248d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
249d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportVarMetadata->addOperand(
250d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDNode::get(mLLVMContext, ExportVarInfo));
251d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportVarInfo.clear();
252b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
253d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    if (mRSObjectSlotsMetadata == NULL) {
254d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      mRSObjectSlotsMetadata =
255d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
256462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
258d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    if (countsAsRSObject) {
259d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
260d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
261d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    }
2620da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
263d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    slotCount++;
264d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  }
265d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser}
2660da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
267d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::dumpExportFunctionInfo(llvm::Module *M) {
268d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mExportFuncMetadata == NULL)
269d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportFuncMetadata =
270d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
271d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
272d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
273d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
274d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  for (RSContext::const_export_func_iterator
275d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          I = mContext->export_funcs_begin(),
276d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          E = mContext->export_funcs_end();
277d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I != E;
278d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I++) {
279d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    const RSExportFunc *EF = *I;
280d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
281d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    // Function name
282d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    if (!EF->hasParam()) {
283d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
284d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                                   EF->getName().c_str()));
285d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    } else {
286d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      llvm::Function *F = M->getFunction(EF->getName());
287d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      llvm::Function *HelperFunction;
288d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      const std::string HelperFunctionName(".helper_" + EF->getName());
289d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
290d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      slangAssert(F && "Function marked as exported disappeared in Bitcode");
291d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
292d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      // Create helper function
293d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      {
294d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::StructType *HelperFunctionParameterTy = NULL;
295d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
296d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        if (!F->getArgumentList().empty()) {
297d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          std::vector<llvm::Type*> HelperFunctionParameterTys;
298d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          for (llvm::Function::arg_iterator AI = F->arg_begin(),
299d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser               AE = F->arg_end(); AI != AE; AI++)
300d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            HelperFunctionParameterTys.push_back(AI->getType());
301d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
302d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          HelperFunctionParameterTy =
303d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
304d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        }
3050da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
306d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
307d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          fprintf(stderr, "Failed to export function %s: parameter type "
308d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                          "mismatch during creation of helper function.\n",
309d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                  EF->getName().c_str());
3100da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
311d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          const RSExportRecordType *Expected = EF->getParamPacketType();
312d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          if (Expected) {
313d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            fprintf(stderr, "Expected:\n");
314d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            Expected->getLLVMType()->dump();
315d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          }
3160da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (HelperFunctionParameterTy) {
317d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            fprintf(stderr, "Got:\n");
318d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            HelperFunctionParameterTy->dump();
3190da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
320d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        }
3219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
322d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        std::vector<llvm::Type*> Params;
323d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        if (HelperFunctionParameterTy) {
324d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::PointerType *HelperFunctionParameterTyP =
325d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              llvm::PointerType::getUnqual(HelperFunctionParameterTy);
326d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          Params.push_back(HelperFunctionParameterTyP);
3279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
328462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
329d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::FunctionType * HelperFunctionType =
330d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::FunctionType::get(F->getReturnType(),
331d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                    Params,
332d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                    /* IsVarArgs = */false);
333d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
334d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        HelperFunction =
335d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::Function::Create(HelperFunctionType,
336d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                   llvm::GlobalValue::ExternalLinkage,
337d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                   HelperFunctionName,
338d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                   M);
339d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
340d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        HelperFunction->addFnAttr(llvm::Attribute::NoInline);
341d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        HelperFunction->setCallingConv(F->getCallingConv());
342d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
343d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        // Create helper function body
344d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        {
345d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::Argument *HelperFunctionParameter =
346d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              &(*HelperFunction->arg_begin());
347d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::BasicBlock *BB =
348d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
349d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
350d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::SmallVector<llvm::Value*, 6> Params;
351d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::Value *Idx[2];
352d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
353d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          Idx[0] =
354d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
355d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
356d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          // getelementptr and load instruction for all elements in
357d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          // parameter .p
358d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          for (size_t i = 0; i < EF->getNumParameters(); i++) {
359d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            // getelementptr
360d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            Idx[1] = llvm::ConstantInt::get(
361d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              llvm::Type::getInt32Ty(mLLVMContext), i);
362d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
363d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::Value *Ptr =
364d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
365d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
366d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            // load
367d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::Value *V = IB->CreateLoad(Ptr);
368d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            Params.push_back(V);
369d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          }
370d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
371d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          // Call and pass the all elements as parameter to F
372d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::CallInst *CI = IB->CreateCall(F, Params);
373d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
374d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          CI->setCallingConv(F->getCallingConv());
375d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
376d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
377d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            IB->CreateRetVoid();
378d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          else
379d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            IB->CreateRet(CI);
380d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
381d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          delete IB;
382d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        }
3839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
384462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
385d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      ExportFuncInfo.push_back(
386d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
388d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
389d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportFuncMetadata->addOperand(
390d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
391d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportFuncInfo.clear();
3929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
393d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser}
3949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
395d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::dumpExportForEachInfo(llvm::Module *M) {
396d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mExportForEachNameMetadata == NULL) {
397d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportForEachNameMetadata =
398d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
399d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  }
400d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mExportForEachSignatureMetadata == NULL) {
401d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportForEachSignatureMetadata =
402d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
403d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  }
4044ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
405d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  llvm::SmallVector<llvm::Value*, 1> ExportForEachName;
406d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo;
4074ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
408d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  for (RSContext::const_export_foreach_iterator
409d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          I = mContext->export_foreach_begin(),
410d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          E = mContext->export_foreach_end();
411d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I != E;
412d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I++) {
413d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    const RSExportForEach *EFE = *I;
4144ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
415d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportForEachName.push_back(
416d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
4177b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
418d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportForEachNameMetadata->addOperand(
419d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDNode::get(mLLVMContext, ExportForEachName));
420d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportForEachName.clear();
4217b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
422d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportForEachInfo.push_back(
423d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDString::get(mLLVMContext,
424d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                            llvm::utostr_32(EFE->getSignatureMetadata())));
4254ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
426d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportForEachSignatureMetadata->addOperand(
427d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
428d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportForEachInfo.clear();
4294ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  }
430d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser}
4314ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
432d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::dumpExportTypeInfo(llvm::Module *M) {
433d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
434d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
435d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  for (RSContext::const_export_type_iterator
436d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          I = mContext->export_types_begin(),
437d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          E = mContext->export_types_end();
438d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I != E;
439d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I++) {
440d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    // First, dump type name list to export
441d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    const RSExportType *ET = I->getValue();
442d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
443d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportTypeInfo.clear();
444d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    // Type name
445d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportTypeInfo.push_back(
446d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
447d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
448d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    if (ET->getClass() == RSExportType::ExportClassRecord) {
449d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      const RSExportRecordType *ERT =
450d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          static_cast<const RSExportRecordType*>(ET);
451d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
452d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      if (mExportTypeMetadata == NULL)
453d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        mExportTypeMetadata =
454d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
455d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
456d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      mExportTypeMetadata->addOperand(
457d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
458d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
459d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      // Now, export struct field information to %[struct name]
460d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      std::string StructInfoMetadataName("%");
461d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      StructInfoMetadataName.append(ET->getName());
462d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      llvm::NamedMDNode *StructInfoMetadata =
463d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          M->getOrInsertNamedMetadata(StructInfoMetadataName);
464d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      llvm::SmallVector<llvm::Value*, 3> FieldInfo;
465d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
466d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
467d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                  "Metadata with same name was created before");
468d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
469d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              FE = ERT->fields_end();
470d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser           FI != FE;
471d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser           FI++) {
472d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        const RSExportRecordType::Field *F = *FI;
473d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
474d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        // 1. field name
475d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
476d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                                F->getName().c_str()));
477d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
478d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        // 2. field type name
479d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        FieldInfo.push_back(
480d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::MDString::get(mLLVMContext,
481d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                F->getType()->getName().c_str()));
482d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
483d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        StructInfoMetadata->addOperand(
484d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::MDNode::get(mLLVMContext, FieldInfo));
485d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        FieldInfo.clear();
486d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      }
487d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    }   // ET->getClass() == RSExportType::ExportClassRecord
488d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  }
489d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser}
490d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
491d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
492d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (!mContext->processExport()) {
493d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    return;
4949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
495462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
496d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mContext->hasExportVar())
497d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    dumpExportVarInfo(M);
498d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
499d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mContext->hasExportFunc())
500d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    dumpExportFunctionInfo(M);
501d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
502d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mContext->hasExportForEach())
503d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    dumpExportForEachInfo(M);
504d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
505d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mContext->hasExportType())
506d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    dumpExportTypeInfo(M);
507d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
5089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
509462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
510462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
511462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() {
5129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
513462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
514e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
515e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
516