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
36ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murray#include "llvm/IR/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}
83cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
84fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chienbool RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
85cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Disallow user-defined functions with prefix "rs"
86cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (!mAllowRSPrefix) {
87cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    // Iterate all function declarations in the program.
88cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
89cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines         I != E; I++) {
90ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
91cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (FD == NULL)
92cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
93cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!FD->getName().startswith("rs"))  // Check prefix
94cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
9511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines      if (!SlangRS::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
96d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet        mContext->ReportError(FD->getLocation(),
97d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet                              "invalid function name prefix, "
98d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet                              "\"rs\" is reserved: '%0'")
99d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet            << 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()) {
114d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet          mContext->ReportError(
115d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet              PVD->getTypeSpecStartLoc(),
116d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet              "exported function parameters may not have array type: %0")
117d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet              << QT;
118ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines        }
119ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines      }
120eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      AnnotateFunction(FD);
121eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    }
122cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
123cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
124fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chien  return Backend::HandleTopLevelDecl(D);
125cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
126cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
127c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
128c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesvoid RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
129c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
130c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
13111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines  // If we have an invalid RS/FS AST, don't check further.
13211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines  if (!mASTChecker.Validate()) {
133c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
134c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
135fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
13611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines  if (mIsFilterscript) {
13711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines    mContext->addPragma("rs_fp_relaxed", "");
13811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines  }
13911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines
14096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  int version = mContext->getVersion();
14196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  if (version == 0) {
14296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    // Not setting a version is an error
1437aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    mDiagEngine.Report(
1447aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
1457aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        mDiagEngine.getCustomDiagID(
1467aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines            clang::DiagnosticsEngine::Error,
1477aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines            "missing pragma for version in source file"));
1487aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines  } else {
1497aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    slangAssert(version == 1);
15096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
15196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
152cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines  if (mContext->getReflectJavaPackageName().empty()) {
153cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines    mDiagEngine.Report(
154cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
155cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines        mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
156cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines                                    "missing \"#pragma rs "
157cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines                                    "java_package_name(com.foo.bar)\" "
158cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines                                    "in source file"));
159cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines    return;
160cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines  }
161cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines
162688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // Create a static global destructor if necessary (to handle RS object
163688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // runtime cleanup).
164688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
165688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  if (FD) {
166688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    HandleTopLevelDecl(clang::DeclGroupRef(FD));
167688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  }
168688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines
169cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any static function declarations
170fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
171fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines          E = TUDecl->decls_end(); I != E; I++) {
172fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    if ((I->getKind() >= clang::Decl::firstFunction) &&
173fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        (I->getKind() <= clang::Decl::lastFunction)) {
174ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
175eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      if (FD && !FD->isGlobal()) {
176eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines        AnnotateFunction(FD);
177eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      }
178fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    }
179fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  }
180fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines}
181462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
182fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines///////////////////////////////////////////////////////////////////////////////
183d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::dumpExportVarInfo(llvm::Module *M) {
184d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  int slotCount = 0;
185d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mExportVarMetadata == NULL)
186d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
187d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
188d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
189d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
190d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  // We emit slot information (#rs_object_slots) for any reference counted
191d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  // RS type or pointer (which can also be bound).
192d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
193d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
194d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          E = mContext->export_vars_end();
195d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I != E;
196d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I++) {
197d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    const RSExportVar *EV = *I;
198d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    const RSExportType *ET = EV->getType();
199d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    bool countsAsRSObject = false;
200d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
201d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    // Variable name
202d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportVarInfo.push_back(
203d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
204d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
205d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    // Type name
206d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    switch (ET->getClass()) {
207d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      case RSExportType::ExportClassPrimitive: {
208d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        const RSExportPrimitiveType *PT =
209d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            static_cast<const RSExportPrimitiveType*>(ET);
210d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        ExportVarInfo.push_back(
211d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::MDString::get(
212d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              mLLVMContext, llvm::utostr_32(PT->getType())));
213d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        if (PT->isRSObjectType()) {
214d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          countsAsRSObject = true;
215a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
216d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        break;
217a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      }
218d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      case RSExportType::ExportClassPointer: {
219d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        ExportVarInfo.push_back(
220d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::MDString::get(
221d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
222d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                ->getPointeeType()->getName()).c_str()));
223d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        break;
224b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
225d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      case RSExportType::ExportClassMatrix: {
226d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        ExportVarInfo.push_back(
227d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::MDString::get(
228d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              mLLVMContext, llvm::utostr_32(
229eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet                  /* TODO Strange value.  This pushes just a number, quite
230eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet                   * different than the other cases.  What is this used for?
231eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet                   * These are the metadata values that some partner drivers
232eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet                   * want to reference (for TBAA, etc.). We may want to look
233eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet                   * at whether these provide any reasonable value (or have
234eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet                   * distinct enough values to actually depend on).
235eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet                   */
236cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet                DataTypeRSMatrix2x2 +
237d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
238d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        break;
239b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
240d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      case RSExportType::ExportClassVector:
241d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      case RSExportType::ExportClassConstantArray:
242d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      case RSExportType::ExportClassRecord: {
243d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        ExportVarInfo.push_back(
244d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::MDString::get(mLLVMContext,
245d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              EV->getType()->getName().c_str()));
246d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        break;
247d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      }
248d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    }
249d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
250d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportVarMetadata->addOperand(
251d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDNode::get(mLLVMContext, ExportVarInfo));
252d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportVarInfo.clear();
253b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
254d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    if (mRSObjectSlotsMetadata == NULL) {
255d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      mRSObjectSlotsMetadata =
256d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
257462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
259d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    if (countsAsRSObject) {
260d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
261d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
262d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    }
2630da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
264d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    slotCount++;
265d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  }
266d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser}
2670da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
268d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::dumpExportFunctionInfo(llvm::Module *M) {
269d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mExportFuncMetadata == NULL)
270d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportFuncMetadata =
271d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
272d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
273d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
274d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
275d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  for (RSContext::const_export_func_iterator
276d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          I = mContext->export_funcs_begin(),
277d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          E = mContext->export_funcs_end();
278d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I != E;
279d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I++) {
280d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    const RSExportFunc *EF = *I;
281d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
282d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    // Function name
283d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    if (!EF->hasParam()) {
284d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
285d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                                   EF->getName().c_str()));
286d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    } else {
287d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      llvm::Function *F = M->getFunction(EF->getName());
288d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      llvm::Function *HelperFunction;
289d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      const std::string HelperFunctionName(".helper_" + EF->getName());
290d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
291d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      slangAssert(F && "Function marked as exported disappeared in Bitcode");
292d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
293d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      // Create helper function
294d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      {
295d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::StructType *HelperFunctionParameterTy = NULL;
296d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray        std::vector<bool> isStructInput;
297d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        if (!F->getArgumentList().empty()) {
298d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          std::vector<llvm::Type*> HelperFunctionParameterTys;
299d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          for (llvm::Function::arg_iterator AI = F->arg_begin(),
300d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray                   AE = F->arg_end(); AI != AE; AI++) {
301d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray              if (AI->getType()->isPointerTy() && AI->getType()->getPointerElementType()->isStructTy()) {
302d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray                  HelperFunctionParameterTys.push_back(AI->getType()->getPointerElementType());
303d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray                  isStructInput.push_back(true);
304d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray              } else {
305d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray                  HelperFunctionParameterTys.push_back(AI->getType());
306d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray                  isStructInput.push_back(false);
307d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray              }
308d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray          }
309d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          HelperFunctionParameterTy =
310d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
311d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        }
3120da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
313d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
314d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          fprintf(stderr, "Failed to export function %s: parameter type "
315d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                          "mismatch during creation of helper function.\n",
316d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                  EF->getName().c_str());
3170da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
318d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          const RSExportRecordType *Expected = EF->getParamPacketType();
319d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          if (Expected) {
320d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            fprintf(stderr, "Expected:\n");
321d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            Expected->getLLVMType()->dump();
322d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          }
3230da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (HelperFunctionParameterTy) {
324d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            fprintf(stderr, "Got:\n");
325d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            HelperFunctionParameterTy->dump();
3260da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
327d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        }
3289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
329d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        std::vector<llvm::Type*> Params;
330d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        if (HelperFunctionParameterTy) {
331d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::PointerType *HelperFunctionParameterTyP =
332d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              llvm::PointerType::getUnqual(HelperFunctionParameterTy);
333d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          Params.push_back(HelperFunctionParameterTyP);
3349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
335462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
336d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::FunctionType * HelperFunctionType =
337d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::FunctionType::get(F->getReturnType(),
338d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                    Params,
339d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                    /* IsVarArgs = */false);
340d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
341d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        HelperFunction =
342d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::Function::Create(HelperFunctionType,
343d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                   llvm::GlobalValue::ExternalLinkage,
344d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                   HelperFunctionName,
345d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                   M);
346d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
347d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        HelperFunction->addFnAttr(llvm::Attribute::NoInline);
348d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        HelperFunction->setCallingConv(F->getCallingConv());
349d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
350d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        // Create helper function body
351d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        {
352d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::Argument *HelperFunctionParameter =
353d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              &(*HelperFunction->arg_begin());
354d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::BasicBlock *BB =
355d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
356d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
357d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::SmallVector<llvm::Value*, 6> Params;
358d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::Value *Idx[2];
359d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
360d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          Idx[0] =
361d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
362d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
363d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          // getelementptr and load instruction for all elements in
364d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          // parameter .p
365d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          for (size_t i = 0; i < EF->getNumParameters(); i++) {
366d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            // getelementptr
367d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            Idx[1] = llvm::ConstantInt::get(
368d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              llvm::Type::getInt32Ty(mLLVMContext), i);
369d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
370d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray            llvm::Value *Ptr = NULL;
371d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray
372d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray            Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
373d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
374d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray            // Load is only required for non-struct ptrs
375d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray            if (isStructInput[i]) {
376d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray                Params.push_back(Ptr);
377d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray            } else {
378d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray                llvm::Value *V = IB->CreateLoad(Ptr);
379d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray                Params.push_back(V);
380d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray            }
381d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          }
382d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
383d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          // Call and pass the all elements as parameter to F
384d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::CallInst *CI = IB->CreateCall(F, Params);
385d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
386d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          CI->setCallingConv(F->getCallingConv());
387d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
388d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
389d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            IB->CreateRetVoid();
390d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          else
391d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            IB->CreateRet(CI);
392d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
393d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          delete IB;
394d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        }
3959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
396462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
397d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      ExportFuncInfo.push_back(
398d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
3999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
400d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
401d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportFuncMetadata->addOperand(
402d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
403d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportFuncInfo.clear();
4049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
405d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser}
4069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
407d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::dumpExportForEachInfo(llvm::Module *M) {
408d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mExportForEachNameMetadata == NULL) {
409d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportForEachNameMetadata =
410d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
411d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  }
412d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mExportForEachSignatureMetadata == NULL) {
413d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportForEachSignatureMetadata =
414d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
415d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  }
4164ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
417d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  llvm::SmallVector<llvm::Value*, 1> ExportForEachName;
418d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo;
4194ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
420d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  for (RSContext::const_export_foreach_iterator
421d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          I = mContext->export_foreach_begin(),
422d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          E = mContext->export_foreach_end();
423d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I != E;
424d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I++) {
425d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    const RSExportForEach *EFE = *I;
4264ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
427d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportForEachName.push_back(
428d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
4297b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
430d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportForEachNameMetadata->addOperand(
431d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDNode::get(mLLVMContext, ExportForEachName));
432d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportForEachName.clear();
4337b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines
434d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportForEachInfo.push_back(
435d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDString::get(mLLVMContext,
436d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                            llvm::utostr_32(EFE->getSignatureMetadata())));
4374ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
438d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    mExportForEachSignatureMetadata->addOperand(
439d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
440d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportForEachInfo.clear();
4414ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  }
442d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser}
4434ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
444d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::dumpExportTypeInfo(llvm::Module *M) {
445d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
446d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
447d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  for (RSContext::const_export_type_iterator
448d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          I = mContext->export_types_begin(),
449d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          E = mContext->export_types_end();
450d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I != E;
451d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser       I++) {
452d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    // First, dump type name list to export
453d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    const RSExportType *ET = I->getValue();
454d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
455d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportTypeInfo.clear();
456d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    // Type name
457d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    ExportTypeInfo.push_back(
458d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
459d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
460d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    if (ET->getClass() == RSExportType::ExportClassRecord) {
461d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      const RSExportRecordType *ERT =
462d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          static_cast<const RSExportRecordType*>(ET);
463d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
464d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      if (mExportTypeMetadata == NULL)
465d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        mExportTypeMetadata =
466d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
467d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
468d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      mExportTypeMetadata->addOperand(
469d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
470d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
471d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      // Now, export struct field information to %[struct name]
472d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      std::string StructInfoMetadataName("%");
473d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      StructInfoMetadataName.append(ET->getName());
474d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      llvm::NamedMDNode *StructInfoMetadata =
475d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser          M->getOrInsertNamedMetadata(StructInfoMetadataName);
476d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      llvm::SmallVector<llvm::Value*, 3> FieldInfo;
477d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
478d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
479d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                  "Metadata with same name was created before");
480d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
481d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser              FE = ERT->fields_end();
482d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser           FI != FE;
483d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser           FI++) {
484d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        const RSExportRecordType::Field *F = *FI;
485d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
486d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        // 1. field name
487d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
488d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                                F->getName().c_str()));
489d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
490d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        // 2. field type name
491d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        FieldInfo.push_back(
492d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::MDString::get(mLLVMContext,
493d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser                                F->getType()->getName().c_str()));
494d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
495d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        StructInfoMetadata->addOperand(
496d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser            llvm::MDNode::get(mLLVMContext, FieldInfo));
497d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser        FieldInfo.clear();
498d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser      }
499d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    }   // ET->getClass() == RSExportType::ExportClassRecord
500d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  }
501d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser}
502d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
503d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
504d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (!mContext->processExport()) {
505d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    return;
5069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
507462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
508d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mContext->hasExportVar())
509d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    dumpExportVarInfo(M);
510d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
511d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mContext->hasExportFunc())
512d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    dumpExportFunctionInfo(M);
513d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
514d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mContext->hasExportForEach())
515d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    dumpExportForEachInfo(M);
516d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser
517d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser  if (mContext->hasExportType())
518d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser    dumpExportTypeInfo(M);
519462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
520462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
521462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() {
522462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
523e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
524e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
525