slang_rs_backend.cpp revision cf9a73a4140402c0e9e4fbab27477f22cc7d8e3c
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
289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Constant.h"
299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Constants.h"
309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/DerivedTypes.h"
31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Function.h"
3243730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao#include "llvm/IRBuilder.h"
33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Metadata.h"
34e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/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,
574a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines                     bool AllowRSPrefix)
589207a2e495c8363606861e4f034504ec5c153dabLogan Chien  : Backend(DiagEngine, CodeGenOpts, TargetOpts, Pragmas, OS, OT),
599207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mContext(Context),
609207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mSourceMgr(SourceMgr),
619207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mAllowRSPrefix(AllowRSPrefix),
629207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportVarMetadata(NULL),
639207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportFuncMetadata(NULL),
647b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    mExportForEachNameMetadata(NULL),
657b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    mExportForEachSignatureMetadata(NULL),
669207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportTypeMetadata(NULL),
679207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mRSObjectSlotsMetadata(NULL),
689207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mRefCount(mContext->getASTContext()) {
69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
71cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines// 1) Add zero initialization of local RS object types
72cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinesvoid RSBackend::AnnotateFunction(clang::FunctionDecl *FD) {
73cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (FD &&
74cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      FD->hasBody() &&
75cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      !SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr)) {
76d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines    mRefCount.Init();
774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    mRefCount.Visit(FD->getBody());
78cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
79cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  return;
80cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
81cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
82fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chienbool RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
83cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Disallow user-defined functions with prefix "rs"
84cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (!mAllowRSPrefix) {
85cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    // Iterate all function declarations in the program.
86cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
87cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines         I != E; I++) {
88ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
89cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (FD == NULL)
90cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
91cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!FD->getName().startswith("rs"))  // Check prefix
92cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
93cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr))
949207a2e495c8363606861e4f034504ec5c153dabLogan Chien        mDiagEngine.Report(
959207a2e495c8363606861e4f034504ec5c153dabLogan Chien          clang::FullSourceLoc(FD->getLocation(), mSourceMgr),
969207a2e495c8363606861e4f034504ec5c153dabLogan Chien          mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
979207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                      "invalid function name prefix, "
989207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                      "\"rs\" is reserved: '%0'"))
999207a2e495c8363606861e4f034504ec5c153dabLogan Chien          << FD->getName();
100cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    }
101cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
102cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
103cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any non-static function declarations
104cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
105ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
106eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    if (FD && FD->isGlobal()) {
107ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      // Check that we don't have any array parameters being misintrepeted as
108ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      // kernel pointers due to the C type system's array to pointer decay.
109ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      size_t numParams = FD->getNumParams();
110ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      for (size_t i = 0; i < numParams; i++) {
111ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines        const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
112ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines        clang::QualType QT = PVD->getOriginalType();
113ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines        if (QT->isArrayType()) {
114ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines          mDiagEngine.Report(
115ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines            clang::FullSourceLoc(PVD->getTypeSpecStartLoc(), mSourceMgr),
116ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines            mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
117ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines                                        "exported function parameters may "
118ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines                                        "not have array type: %0")) << QT;
119ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines        }
120ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      }
121eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      AnnotateFunction(FD);
122eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    }
123cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
124cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
125fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chien  return Backend::HandleTopLevelDecl(D);
126cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
127cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
128c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesnamespace {
129c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
130d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hinesstatic bool ValidateVarDecl(clang::VarDecl *VD, unsigned int TargetAPI) {
13178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  if (!VD) {
13278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    return true;
13378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  }
13478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
13578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  clang::ASTContext &C = VD->getASTContext();
136c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  const clang::Type *T = VD->getType().getTypePtr();
13778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  bool valid = true;
13878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
13978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  if (VD->getLinkage() == clang::ExternalLinkage) {
14078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    llvm::StringRef TypeName;
1415bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines    if (!RSExportType::NormalizeType(T, TypeName, &C.getDiagnostics(), VD)) {
14278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines      valid = false;
14378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    }
144c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
145d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines  valid &= RSExportType::ValidateVarDecl(VD, TargetAPI);
14678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
14778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  return valid;
148c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
149c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
150d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hinesstatic bool ValidateASTContext(clang::ASTContext &C, unsigned int TargetAPI) {
151c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  bool valid = true;
152fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
153c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(),
154c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines          DE = TUDecl->decls_end();
155c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI != DE;
156c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI++) {
157ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*DI);
158d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines    if (VD && !ValidateVarDecl(VD, TargetAPI)) {
15978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines      valid = false;
160c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    }
161c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
162c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
163c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  return valid;
164c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
165c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
166e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines}  // namespace
167c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
168c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesvoid RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
169c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
170c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
171d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines  if (!ValidateASTContext(C, getTargetAPI())) {
172c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
173c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
174fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
17596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  int version = mContext->getVersion();
17696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  if (version == 0) {
17796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    // Not setting a version is an error
1787aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    mDiagEngine.Report(
1797aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
1807aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        mDiagEngine.getCustomDiagID(
1817aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines            clang::DiagnosticsEngine::Error,
1827aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines            "missing pragma for version in source file"));
1837aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines  } else {
1847aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    slangAssert(version == 1);
18596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
18696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
187cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines  if (mContext->getReflectJavaPackageName().empty()) {
188cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines    mDiagEngine.Report(
189cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
190cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines        mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
191cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines                                    "missing \"#pragma rs "
192cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines                                    "java_package_name(com.foo.bar)\" "
193cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines                                    "in source file"));
194cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines    return;
195cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines  }
196cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines
197688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // Create a static global destructor if necessary (to handle RS object
198688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // runtime cleanup).
199688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
200688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  if (FD) {
201688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    HandleTopLevelDecl(clang::DeclGroupRef(FD));
202688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  }
203688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines
204cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any static function declarations
205fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
206fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines          E = TUDecl->decls_end(); I != E; I++) {
207fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    if ((I->getKind() >= clang::Decl::firstFunction) &&
208fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        (I->getKind() <= clang::Decl::lastFunction)) {
209ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
210eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      if (FD && !FD->isGlobal()) {
211eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines        AnnotateFunction(FD);
212eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      }
213fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    }
214fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  }
215fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
216fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  return;
217fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines}
218462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
219fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines///////////////////////////////////////////////////////////////////////////////
22068fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Changvoid RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
221c808a99831115928b4648f4c8b86dc682594217aStephen Hines  if (!mContext->processExport()) {
222c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
223c808a99831115928b4648f4c8b86dc682594217aStephen Hines  }
2249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
225c460b37ffb50819a32c2a8967754b6f784b28263mkopec  // Write optimization level
226c460b37ffb50819a32c2a8967754b6f784b28263mkopec  llvm::SmallVector<llvm::Value*, 1> OptimizationOption;
227c460b37ffb50819a32c2a8967754b6f784b28263mkopec  OptimizationOption.push_back(llvm::ConstantInt::get(
228c460b37ffb50819a32c2a8967754b6f784b28263mkopec    mLLVMContext, llvm::APInt(32, mCodeGenOpts.OptimizationLevel)));
229c460b37ffb50819a32c2a8967754b6f784b28263mkopec
2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export variable info
2319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportVar()) {
232b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    int slotCount = 0;
2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportVarMetadata == NULL)
23468fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang      mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
2359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
237b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
238b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // We emit slot information (#rs_object_slots) for any reference counted
239b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // RS type or pointer (which can also be bound).
2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2416315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
2426315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_vars_end();
2436315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I != E;
2446315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I++) {
2456315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportVar *EV = *I;
2466315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportType *ET = EV->getType();
247b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      bool countsAsRSObject = false;
2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Variable name
2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.push_back(
2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
254a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      switch (ET->getClass()) {
255a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPrimitive: {
256b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          const RSExportPrimitiveType *PT =
257b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines              static_cast<const RSExportPrimitiveType*>(ET);
258a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
259a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
260b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines                mLLVMContext, llvm::utostr_32(PT->getType())));
261b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          if (PT->isRSObjectType()) {
262b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            countsAsRSObject = true;
263b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          }
264a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
265a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
266a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPointer: {
267a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
268a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
270a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  ->getPointeeType()->getName()).c_str()));
271a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
272a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
273a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassMatrix: {
274a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
275a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
276a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                mLLVMContext, llvm::utostr_32(
277a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  RSExportPrimitiveType::DataTypeRSMatrix2x2 +
278a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
279a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
280a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
281a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassVector:
282a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassConstantArray:
283a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassRecord: {
284a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
285a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(mLLVMContext,
286a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                EV->getType()->getName().c_str()));
287a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
288a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
289a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      }
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportVarMetadata->addOperand(
292d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportVarInfo));
2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.clear();
294b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
295b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (mRSObjectSlotsMetadata == NULL) {
296b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        mRSObjectSlotsMetadata =
297b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
298b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
299b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
300b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (countsAsRSObject) {
301d27a74edb932580d224a7186731aa6be098ad02eStephen Hines        mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
302d27a74edb932580d224a7186731aa6be098ad02eStephen Hines            llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
303b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
304b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
305b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      slotCount++;
306462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export function info
3109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportFunc()) {
3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportFuncMetadata == NULL)
3129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata =
31368fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang          M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
3149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_func_iterator
3186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_funcs_begin(),
3196315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_funcs_end();
3209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
3219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
3226315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportFunc *EF = *I;
3239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Function name
3256315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      if (!EF->hasParam()) {
3266315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
3276315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                                     EF->getName().c_str()));
3286315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      } else {
32968fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang        llvm::Function *F = M->getFunction(EF->getName());
3309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::Function *HelperFunction;
3319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const std::string HelperFunctionName(".helper_" + EF->getName());
3329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3336e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(F && "Function marked as exported disappeared in Bitcode");
3349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Create helper function
336462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
3370da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::StructType *HelperFunctionParameterTy = NULL;
3380da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3390da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!F->getArgumentList().empty()) {
3407c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao            std::vector<llvm::Type*> HelperFunctionParameterTys;
3410da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (llvm::Function::arg_iterator AI = F->arg_begin(),
3420da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                 AE = F->arg_end(); AI != AE; AI++)
3430da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTys.push_back(AI->getType());
3440da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3450da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            HelperFunctionParameterTy =
346a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines                llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
3470da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3480da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3490da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
3500da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            fprintf(stderr, "Failed to export function %s: parameter type "
3510da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                            "mismatch during creation of helper function.\n",
3520da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                    EF->getName().c_str());
3530da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3540da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            const RSExportRecordType *Expected = EF->getParamPacketType();
3550da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (Expected) {
3560da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Expected:\n");
3570da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              Expected->getLLVMType()->dump();
3580da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3590da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (HelperFunctionParameterTy) {
3600da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Got:\n");
3610da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTy->dump();
3620da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3630da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3640da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3657c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao          std::vector<llvm::Type*> Params;
3660da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (HelperFunctionParameterTy) {
3670da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            llvm::PointerType *HelperFunctionParameterTyP =
3680da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                llvm::PointerType::getUnqual(HelperFunctionParameterTy);
3690da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            Params.push_back(HelperFunctionParameterTyP);
3700da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3720da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::FunctionType * HelperFunctionType =
3730da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              llvm::FunctionType::get(F->getReturnType(),
374a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines                                      Params,
3750da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                                      /* IsVarArgs = */false);
3769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction =
3789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Function::Create(HelperFunctionType,
3799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     llvm::GlobalValue::ExternalLinkage,
3809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     HelperFunctionName,
38168fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang                                     M);
3829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->addFnAttr(llvm::Attribute::NoInline);
3849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->setCallingConv(F->getCallingConv());
3859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // Create helper function body
3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          {
3889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Argument *HelperFunctionParameter =
3899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                &(*HelperFunction->arg_begin());
3909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::BasicBlock *BB =
3919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
3929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
3939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::SmallVector<llvm::Value*, 6> Params;
3949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Value *Idx[2];
3959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            Idx[0] =
3979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
3989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // getelementptr and load instruction for all elements in
4009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // parameter .p
4010da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (size_t i = 0; i < EF->getNumParameters(); i++) {
4029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // getelementptr
4039207a2e495c8363606861e4f034504ec5c153dabLogan Chien              Idx[1] = llvm::ConstantInt::get(
4049207a2e495c8363606861e4f034504ec5c153dabLogan Chien                llvm::Type::getInt32Ty(mLLVMContext), i);
4059207a2e495c8363606861e4f034504ec5c153dabLogan Chien
4069207a2e495c8363606861e4f034504ec5c153dabLogan Chien              llvm::Value *Ptr =
4079207a2e495c8363606861e4f034504ec5c153dabLogan Chien                IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
4089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // load
4109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Value *V = IB->CreateLoad(Ptr);
4119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              Params.push_back(V);
4129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
413462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
414a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines            // Call and pass the all elements as parameter to F
415a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines            llvm::CallInst *CI = IB->CreateCall(F, Params);
4161ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
4179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            CI->setCallingConv(F->getCallingConv());
4181ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
4199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
4209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRetVoid();
4219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            else
4229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRet(CI);
423462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            delete IB;
4259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
4269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
427462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        ExportFuncInfo.push_back(
4299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
4309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
431462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata->addOperand(
433d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
4349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportFuncInfo.clear();
4359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
4369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
4379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4384ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  // Dump export function info
4394ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  if (mContext->hasExportForEach()) {
4407b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    if (mExportForEachNameMetadata == NULL) {
4417b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachNameMetadata =
4427b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines          M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
4437b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    }
4447b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    if (mExportForEachSignatureMetadata == NULL) {
4457b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachSignatureMetadata =
4464ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
4477b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    }
4484ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4497b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    llvm::SmallVector<llvm::Value*, 1> ExportForEachName;
4504ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo;
4514ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4524ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    for (RSContext::const_export_foreach_iterator
4534ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines            I = mContext->export_foreach_begin(),
4544ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines            E = mContext->export_foreach_end();
4554ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines         I != E;
4564ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines         I++) {
4574ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      const RSExportForEach *EFE = *I;
4584ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4597b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      ExportForEachName.push_back(
4607b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines          llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
4617b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
4627b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachNameMetadata->addOperand(
4637b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportForEachName));
4647b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      ExportForEachName.clear();
4657b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
4664ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      ExportForEachInfo.push_back(
4674ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          llvm::MDString::get(mLLVMContext,
4687b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines                              llvm::utostr_32(EFE->getSignatureMetadata())));
4694ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4707b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines      mExportForEachSignatureMetadata->addOperand(
4714ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
4724ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      ExportForEachInfo.clear();
4734ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    }
4744ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  }
4754ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export type info
4779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportType()) {
4789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
4799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4806315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_type_iterator
4816315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_types_begin(),
4826315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_types_end();
4839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
4849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
4859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // First, dump type name list to export
4869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportType *ET = I->getValue();
4879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.clear();
4899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
4909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.push_back(
4919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
4929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (ET->getClass() == RSExportType::ExportClassRecord) {
4949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const RSExportRecordType *ERT =
4959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            static_cast<const RSExportRecordType*>(ET);
4969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (mExportTypeMetadata == NULL)
4989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mExportTypeMetadata =
49968fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang              M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
5009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
5019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mExportTypeMetadata->addOperand(
502d27a74edb932580d224a7186731aa6be098ad02eStephen Hines            llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
5039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
5049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Now, export struct field information to %[struct name]
5059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        std::string StructInfoMetadataName("%");
5069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        StructInfoMetadataName.append(ET->getName());
5079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::NamedMDNode *StructInfoMetadata =
50868fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang            M->getOrInsertNamedMetadata(StructInfoMetadataName);
5099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::SmallVector<llvm::Value*, 3> FieldInfo;
5109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
5116e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
5126e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines                    "Metadata with same name was created before");
5136315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
5146315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                FE = ERT->fields_end();
5156315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr             FI != FE;
5169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             FI++) {
5179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          const RSExportRecordType::Field *F = *FI;
5189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
5199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 1. field name
5209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
5219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  F->getName().c_str()));
5229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
5239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 2. field type name
5249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(
5259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::MDString::get(mLLVMContext,
5269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                  F->getType()->getName().c_str()));
5279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
528d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          StructInfoMetadata->addOperand(
529d27a74edb932580d224a7186731aa6be098ad02eStephen Hines              llvm::MDNode::get(mLLVMContext, FieldInfo));
5309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.clear();
531462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
5329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }   // ET->getClass() == RSExportType::ExportClassRecord
533462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
5349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
535462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
5369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
537462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
538462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
539462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() {
5409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
541462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
542e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
543e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
544