slang_rs_backend.cpp revision 9ef2f785e0cc490af678dfd685995dec787321ff
1462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_backend.hpp"
2462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_context.hpp"
3462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_var.hpp"
4462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_func.hpp"
5462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_type.hpp"
6462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
79ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Metadata.h"
8462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
99ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/ADT/Twine.h"
109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/ADT/StringExtras.h"
11462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Support/IRBuilder.h"
139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Constant.h"
149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Constants.h"
159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Module.h"
169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Function.h"
179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/DerivedTypes.h"
18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/DeclGroup.h"
209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include <vector>
229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include <string>
23462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaousing namespace slang;
25462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
269ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSBackend::RSBackend(RSContext *Context,
279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     clang::Diagnostic &Diags,
289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::CodeGenOptions &CodeGenOpts,
299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::TargetOptions &TargetOpts,
309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const PragmaList &Pragmas,
319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     llvm::raw_ostream *OS,
326b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart                     SlangCompilerOutputTy OutputType,
339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     clang::SourceManager &SourceMgr,
341fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart                     bool AllowRSPrefix) :
35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    Backend(Diags,
36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            CodeGenOpts,
37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            TargetOpts,
38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            Pragmas,
39462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            OS,
406b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart            OutputType,
411fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart            SourceMgr,
421fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart            AllowRSPrefix),
43cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao    mContext(Context),
444c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao    mExportVarMetadata(NULL),
454c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao    mExportFuncMetadata(NULL),
469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mExportTypeMetadata(NULL) {
479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
49462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  Backend::HandleTopLevelDecl(D);
529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
53462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid RSBackend::HandleTranslationUnitEx(clang::ASTContext &Ctx) {
569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  assert((&Ctx == mContext->getASTContext()) && "Unexpected AST context change"
579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                " during LLVM IR generation");
589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mContext->processExport();
599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export variable info
619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportVar()) {
629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportVarMetadata == NULL)
639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportVarMetadata = mpModule->getOrInsertNamedMetadata("#rs_export_var");
649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (RSContext::const_export_var_iterator I = mContext->export_vars_begin();
689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        I != mContext->export_vars_end();
699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        I++)
709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    {
719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportVar* EV = *I;
729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportType* ET = EV->getType();
739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Variable name
759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.push_back(
769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (ET->getClass() == RSExportType::ExportClassPrimitive)
809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        ExportVarInfo.push_back(
819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDString::get(
829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                mLLVMContext, llvm::utostr_32(
839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                    static_cast<const RSExportPrimitiveType*>(ET)->getType()
849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                              )));
859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      else if (ET->getClass() == RSExportType::ExportClassPointer)
869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        ExportVarInfo.push_back(
879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDString::get(
889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                               ->getPointeeType()->getName()
909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                               ).c_str()
919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                ));
929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      else
939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        ExportVarInfo.push_back(
949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDString::get(mLLVMContext,
959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                EV->getType()->getName().c_str()));
969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportVarMetadata->addOperand(
989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDNode::get(mLLVMContext,
999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                            ExportVarInfo.data(),
1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                            ExportVarInfo.size()) );
1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.clear();
103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
1049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export function info
1079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportFunc()) {
1089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportFuncMetadata == NULL)
1099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata =
1109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mpModule->getOrInsertNamedMetadata("#rs_export_func");
1119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
1139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (RSContext::const_export_func_iterator I=mContext->export_funcs_begin(),
1159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             E = mContext->export_funcs_end();
1169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportFunc* EF = *I;
1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Function name
1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (!EF->hasParam())
1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        ExportFuncInfo.push_back( llvm::MDString::get(mLLVMContext,
1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                      EF->getName().c_str()));
1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      else {
1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::Function *F = mpModule->getFunction(EF->getName());
1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::Function *HelperFunction;
1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const std::string HelperFunctionName(".helper_" + EF->getName());
1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        assert(F && "Function marked as exported disappeared in Bitcode");
1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Create helper function
132462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::PointerType *HelperFunctionParameterTypeP =
1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::PointerType::getUnqual(
1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  EF->getParamPacketType()->getLLVMType());
1369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::FunctionType *HelperFunctionType;
1379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          std::vector<const llvm::Type*> Params;
1389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          Params.push_back(HelperFunctionParameterTypeP);
1409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunctionType = llvm::FunctionType::get(F->getReturnType(),
1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                       Params,
1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                       false);
1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction =
1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Function::Create(HelperFunctionType,
1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     llvm::GlobalValue::ExternalLinkage,
1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     HelperFunctionName,
1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     mpModule);
1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->addFnAttr(llvm::Attribute::NoInline);
1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->setCallingConv(F->getCallingConv());
1529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // Create helper function body
1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          {
1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Argument *HelperFunctionParameter =
1569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                &(*HelperFunction->arg_begin());
1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::BasicBlock *BB =
1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
1599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::SmallVector<llvm::Value*, 6> Params;
1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Value *Idx[2];
1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            Idx[0] =
1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // getelementptr and load instruction for all elements in
1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // parameter .p
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            for (int i = 0; i < EF->getNumParameters(); i++) {
1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // getelementptr
1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              Idx[1] =
1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::ConstantInt::get(
1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                      llvm::Type::getInt32Ty(mLLVMContext), i);
1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Value *Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter,
1749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                       Idx,
1759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                       Idx + 2);
1769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // load
1789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Value *V = IB->CreateLoad(Ptr);
1799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              Params.push_back(V);
1809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
181462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // Call and pass the all elements as paramter to F
1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::CallInst *CI = IB->CreateCall(F,
1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                Params.data(),
1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                Params.data() + Params.size());
1861ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            CI->setCallingConv(F->getCallingConv());
1881ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
1899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRetVoid();
1919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            else
1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRet(CI);
193462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            delete IB;
1959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
1969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
197462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        ExportFuncInfo.push_back(
1999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
201462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata->addOperand(
2039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDNode::get(mLLVMContext,
2049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                            ExportFuncInfo.data(),
2059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                            ExportFuncInfo.size()));
206462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportFuncInfo.clear();
2089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export type info
2129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportType()) {
2139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (RSContext::const_export_type_iterator I=mContext->export_types_begin(),
2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             E = mContext->export_types_end();
2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
2199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // First, dump type name list to export
2209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportType *ET = I->getValue();
2219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.clear();
2239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
2249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.push_back(
2259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (ET->getClass() == RSExportType::ExportClassRecord) {
2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const RSExportRecordType *ERT =
2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            static_cast<const RSExportRecordType*>(ET);
2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (mExportTypeMetadata == NULL)
2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mExportTypeMetadata =
2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              mpModule->getOrInsertNamedMetadata("#rs_export_type");
2349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mExportTypeMetadata->addOperand(
2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDNode::get(mLLVMContext,
2379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                              ExportTypeInfo.data(),
2389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                              ExportTypeInfo.size()));
2399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Now, export struct field information to %[struct name]
2419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        std::string StructInfoMetadataName("%");
2429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        StructInfoMetadataName.append(ET->getName());
2439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::NamedMDNode *StructInfoMetadata =
2449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            mpModule->getOrInsertNamedMetadata(StructInfoMetadataName);
2459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::SmallVector<llvm::Value*, 3> FieldInfo;
2469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        assert(StructInfoMetadata->getNumOperands() == 0 &&
2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao               "Metadata with same name was created before");
2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin();
2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             FI != ERT->fields_end();
2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             FI++) {
2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          const RSExportRecordType::Field *F = *FI;
2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 1. field name
2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
2569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  F->getName().c_str()));
2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 2. field type name
2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(
2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::MDString::get(mLLVMContext,
2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                  F->getType()->getName().c_str()));
2629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 3. field kind
2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          switch (F->getType()->getClass()) {
2659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            case RSExportType::ExportClassPrimitive:
2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            case RSExportType::ExportClassVector: {
2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              const RSExportPrimitiveType *EPT =
2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  static_cast<const RSExportPrimitiveType*>(F->getType());
2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              FieldInfo.push_back(
2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::MDString::get(mLLVMContext,
2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                      llvm::itostr(EPT->getKind())));
2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              break;
273462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
274462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            default: {
2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              FieldInfo.push_back(
2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::MDString::get(mLLVMContext,
2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                      llvm::itostr(
2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                          RSExportPrimitiveType::DataKindUser
2809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                   )));
2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              break;
2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
2839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
284462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          StructInfoMetadata->addOperand( llvm::MDNode::get(mLLVMContext,
2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                            FieldInfo.data(),
2879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                            FieldInfo.size()));
288462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.clear();
290462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }   // ET->getClass() == RSExportType::ExportClassRecord
292462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
294462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
296462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
297462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
298462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() {
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
300462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
301