slang_rs_backend.cpp revision cecd11d2af5d45d8ba322bed61fb48a99c305528
1462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include <vector>
2462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include <string>
3462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_backend.hpp"
5462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_context.hpp"
6462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_var.hpp"
7462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_func.hpp"
8462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_type.hpp"
9462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
10462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Metadata.h"          /* for class llvm::NamedMDNode */
11462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/ADT/Twine.h"         /* for class llvm::Twine */
12462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
13462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/AST/DeclGroup.h"    /* for class clang::DeclGroup */
14462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/ADT/StringExtras.h"  /* for function llvm::utostr_32() and llvm::itostr() */
15462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
16462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Support/IRBuilder.h" /* for class llvm::IRBuilder */
17462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Constant.h"          /* for class llvm::Constant */
18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Constants.h"          /* for class llvm::Constant* */
19462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Module.h"            /* for class llvm::Module */
20462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Function.h"          /* for class llvm::Function */
21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/DerivedTypes.h"      /* for class llvm::*Type */
22462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
23462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#define MAKE
24462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
25462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaonamespace slang {
26462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::RSBackend(RSContext* Context,
28462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                     Diagnostic &Diags,
29462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                     const CodeGenOptions& CodeGenOpts,
30462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                     const TargetOptions& TargetOpts,
31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                     const PragmaList& Pragmas,
32462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                     llvm::raw_ostream* OS,
336b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart                     SlangCompilerOutputTy OutputType,
341fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart                     SourceManager& SourceMgr,
351fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart                     bool AllowRSPrefix) :
36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    Backend(Diags,
37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            CodeGenOpts,
38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            TargetOpts,
39462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            Pragmas,
40462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            OS,
416b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart            OutputType,
421fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart            SourceMgr,
431fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart            AllowRSPrefix),
44cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao    mContext(Context),
454c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao    mExportVarMetadata(NULL),
464c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao    mExportFuncMetadata(NULL),
474c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao    mExportTypeMetadata(NULL)
48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao{
49462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
50462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
51462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
52462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid RSBackend::HandleTopLevelDecl(DeclGroupRef D) {
53462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    Backend::HandleTopLevelDecl(D);
54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
55462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
56462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
57462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid RSBackend::HandleTranslationUnitEx(ASTContext& Ctx) {
58001fb6dddbf1cc794532eeb6a55f7b500eab1abcShih-wei Liao    assert((&Ctx == mContext->getASTContext()) && "Unexpected AST context change during LLVM IR generation");
59001fb6dddbf1cc794532eeb6a55f7b500eab1abcShih-wei Liao    mContext->processExport();
60462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
61462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Dump export variable info */
62462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(mContext->hasExportVar()) {
63462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        if(mExportVarMetadata == NULL)
64f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao            mExportVarMetadata = mpModule->getOrInsertNamedMetadata("#rs_export_var");
65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
66462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
67462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
68462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        for(RSContext::const_export_var_iterator I = mContext->export_vars_begin();
69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            I != mContext->export_vars_end();
70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            I++)
71462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
72462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const RSExportVar* EV = *I;
73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const RSExportType* ET = EV->getType();
74462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
75462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* variable name */
76462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            ExportVarInfo.push_back( llvm::MDString::get(mLLVMContext, EV->getName().c_str()) );
77462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
78462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* type name */
794c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao            if(ET->getClass() == RSExportType::ExportClassPrimitive)
80462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                ExportVarInfo.push_back( llvm::MDString::get(mLLVMContext, llvm::utostr_32(static_cast<const RSExportPrimitiveType*>(ET)->getType())) );
81462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            else if(ET->getClass() == RSExportType::ExportClassPointer)
82462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                ExportVarInfo.push_back( llvm::MDString::get(mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)->getPointeeType()->getName()).c_str()) );
83462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            else
84462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                ExportVarInfo.push_back( llvm::MDString::get(mLLVMContext, EV->getType()->getName().c_str()) );
85462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
86462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            mExportVarMetadata->addOperand( llvm::MDNode::get(mLLVMContext, ExportVarInfo.data(), ExportVarInfo.size()) );
87462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
88462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            ExportVarInfo.clear();
89462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
90462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
91462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
92462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Dump export function info */
93462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(mContext->hasExportFunc()) {
94462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        if(mExportFuncMetadata == NULL)
95f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao            mExportFuncMetadata = mpModule->getOrInsertNamedMetadata("#rs_export_func");
96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
97462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
98462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
99462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        for(RSContext::const_export_func_iterator I = mContext->export_funcs_begin();
100462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            I != mContext->export_funcs_end();
101462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            I++)
102462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const RSExportFunc* EF = *I;
104462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
105462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* function name */
106cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao
1074c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao            if(!EF->hasParam())
108462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                ExportFuncInfo.push_back( llvm::MDString::get(mLLVMContext, EF->getName().c_str()) );
109462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            else {
110462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                llvm::Function* F = mpModule->getFunction(EF->getName());
111462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                llvm::Function* HelperFunction;
1124c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao                const std::string HelperFunctionName(".helper_" + EF->getName());
113462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
114462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                assert(F && "Function marked as exported disappeared in Bitcode");
115462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
116462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                /* Create helper function */
117462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                {
118462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    llvm::PointerType* HelperFunctionParameterTypeP = llvm::PointerType::getUnqual(EF->getParamPacketType()->getLLVMType());
119462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    llvm::FunctionType* HelperFunctionType;
120462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    std::vector<const llvm::Type*> Params;
121462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
122462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    Params.push_back(HelperFunctionParameterTypeP);
123462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    HelperFunctionType = llvm::FunctionType::get(F->getReturnType(), Params, false);
124462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
125462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    HelperFunction = llvm::Function::Create(HelperFunctionType, llvm::GlobalValue::ExternalLinkage, HelperFunctionName, mpModule);
126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
127462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    HelperFunction->addFnAttr(llvm::Attribute::NoInline);
128462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    HelperFunction->setCallingConv(F->getCallingConv());
129462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
130462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    /* Create helper function body */
131462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    {
132462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        llvm::Argument* HelperFunctionParameter = &(*HelperFunction->arg_begin());
133462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        llvm::BasicBlock* BB = llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
134462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        llvm::IRBuilder<>* IB = new llvm::IRBuilder<>(BB);
135462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        llvm::SmallVector<llvm::Value*, 6> Params;
136462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        llvm::Value* Idx[2];
137462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
138462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        Idx[0] = llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
139462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
140462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        /* getelementptr and load instruction for all elements in parameter .p */
1411ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao                        int i;
1421ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao                        for (i=0; i < EF->getNumParameters(); i++) {
1431ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
1441ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao                          /* getelementptr */
1451ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao                          Idx[1] = llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), i);
1461ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao                          llvm::Value* Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx, Idx + 2);
1471ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
1481ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao                          /* load */
1491ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao                          llvm::Value* V = IB->CreateLoad(Ptr);
1501ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao                          Params.push_back(V);
151462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        }
152462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
153462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        /* call and pass the all elements as paramter to F */
154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        llvm::CallInst* CI = IB->CreateCall(F, Params.data(), Params.data() + Params.size());
155462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        CI->setCallingConv(F->getCallingConv());
156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        if(F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
158462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                            IB->CreateRetVoid();
159462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        else
160462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                            IB->CreateRet(CI);
161462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
162462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        delete IB;
163462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    }
164462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                }
165462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
166462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                ExportFuncInfo.push_back( llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()) );
167462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
168462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
169462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            mExportFuncMetadata->addOperand( llvm::MDNode::get(mLLVMContext, ExportFuncInfo.data(), ExportFuncInfo.size()) );
170462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
171462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            ExportFuncInfo.clear();
172462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
173462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
174462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
175462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    /* Dump export type info */
176462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if(mContext->hasExportType()) {
177462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
178462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
179462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        for(RSContext::const_export_type_iterator I = mContext->export_types_begin();
180462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            I != mContext->export_types_end();
181462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            I++)
182462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
183462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* First, dump type name list to export */
184462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            const RSExportType* ET = I->getValue();
185462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
186462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            ExportTypeInfo.clear();
187462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            /* type name */
188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            ExportTypeInfo.push_back( llvm::MDString::get(mLLVMContext, ET->getName().c_str()) );
189462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
190462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            if(ET->getClass() == RSExportType::ExportClassRecord) {
191462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET);
192462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
193462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                if(mExportTypeMetadata == NULL)
194f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao                    mExportTypeMetadata = mpModule->getOrInsertNamedMetadata("#rs_export_type");
195462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
196462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                mExportTypeMetadata->addOperand( llvm::MDNode::get(mLLVMContext, ExportTypeInfo.data(), ExportTypeInfo.size()) );
197462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
198462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                /* Now, export struct field information to %[struct name] */
1994c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao                std::string StructInfoMetadataName("%");
2004c9f742efa36b1037acc640184681d421aa0f6baShih-wei Liao                StructInfoMetadataName.append(ET->getName());
201f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao                llvm::NamedMDNode* StructInfoMetadata = mpModule->getOrInsertNamedMetadata(StructInfoMetadataName);
202462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                llvm::SmallVector<llvm::Value*, 3> FieldInfo;
203462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
204462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                assert(StructInfoMetadata->getNumOperands() == 0 && "Metadata with same name was created before");
205462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin();
206462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    FI != ERT->fields_end();
207462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    FI++)
208462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                {
209462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    const RSExportRecordType::Field* F = *FI;
210462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
211462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    /* 1. field name */
212462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    FieldInfo.push_back( llvm::MDString::get(mLLVMContext, F->getName().c_str()) );
213462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    /* 2. field type name */
214462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    FieldInfo.push_back( llvm::MDString::get(mLLVMContext, F->getType()->getName().c_str()) );
215462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
216462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    /* 3. field kind */
217462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    switch(F->getType()->getClass()) {
218462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        case RSExportType::ExportClassPrimitive:
219462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        case RSExportType::ExportClassVector:
220462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        {
221cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao                            const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(F->getType());
222462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                            FieldInfo.push_back( llvm::MDString::get(mLLVMContext, llvm::itostr(EPT->getKind())) );
223462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        }
224462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        break;
225462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
226462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        default:
227462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                            FieldInfo.push_back( llvm::MDString::get(mLLVMContext, llvm::itostr(RSExportPrimitiveType::DataKindUser)) );
228462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                        break;
229462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    }
230462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
231462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    StructInfoMetadata->addOperand( llvm::MDNode::get(mLLVMContext, FieldInfo.data(), FieldInfo.size()) );
232462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
233462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                    FieldInfo.clear();
234462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                }
235462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }   /* ET->getClass() == RSExportType::ExportClassRecord */
236462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
238462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
240462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
241462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
242462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() {
243462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return;
244462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
245462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
246462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}   /* namespace slang */
247