blob: 0d9c2d4c0bbb94c96532583f413958703104c182 [file] [log] [blame]
Zonr Changc383a502010-10-12 01:52:08 +08001/*
2 * Copyright 2010, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
zonr6315f762010-10-05 15:35:14 +080017#include "slang_rs_backend.h"
18
zonr6315f762010-10-05 15:35:14 +080019#include <string>
Stephen Hinese639eb52010-11-08 19:27:20 -080020#include <vector>
zonr6315f762010-10-05 15:35:14 +080021
22#include "llvm/ADT/Twine.h"
23#include "llvm/ADT/StringExtras.h"
24
Stephen Hinese639eb52010-11-08 19:27:20 -080025#include "llvm/Constant.h"
26#include "llvm/Constants.h"
27#include "llvm/DerivedTypes.h"
28#include "llvm/Function.h"
29#include "llvm/Metadata.h"
30#include "llvm/Module.h"
31
32#include "llvm/Support/IRBuilder.h"
33
Zonr Chang592a9542010-10-07 20:03:58 +080034#include "slang_rs.h"
zonr6315f762010-10-05 15:35:14 +080035#include "slang_rs_context.h"
zonr6315f762010-10-05 15:35:14 +080036#include "slang_rs_export_func.h"
37#include "slang_rs_export_type.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080038#include "slang_rs_export_var.h"
39#include "slang_rs_metadata.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070040
Stephen Hinese639eb52010-11-08 19:27:20 -080041namespace slang {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070042
43RSBackend::RSBackend(RSContext *Context,
Stephen Hinese639eb52010-11-08 19:27:20 -080044 clang::Diagnostic *Diags,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070045 const clang::CodeGenOptions &CodeGenOpts,
46 const clang::TargetOptions &TargetOpts,
Stephen Hines3fd0a942011-01-18 12:27:39 -080047 PragmaList *Pragmas,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070048 llvm::raw_ostream *OS,
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080049 Slang::OutputType OT,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070050 clang::SourceManager &SourceMgr,
zonr6315f762010-10-05 15:35:14 +080051 bool AllowRSPrefix)
52 : Backend(Diags,
53 CodeGenOpts,
54 TargetOpts,
55 Pragmas,
56 OS,
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080057 OT),
zonr6315f762010-10-05 15:35:14 +080058 mContext(Context),
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080059 mSourceMgr(SourceMgr),
60 mAllowRSPrefix(AllowRSPrefix),
zonr6315f762010-10-05 15:35:14 +080061 mExportVarMetadata(NULL),
62 mExportFuncMetadata(NULL),
63 mExportTypeMetadata(NULL) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070064 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070065}
66
Stephen Hinescfae0f32010-11-01 18:57:31 -070067// 1) Add zero initialization of local RS object types
68void RSBackend::AnnotateFunction(clang::FunctionDecl *FD) {
69 if (FD &&
70 FD->hasBody() &&
71 !SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr)) {
Stephen Hines1bdd4972010-11-08 17:35:08 -080072 mRefCount.Init(mContext->getASTContext());
Stephen Hines4b32ffd2010-11-05 18:47:11 -070073 mRefCount.Visit(FD->getBody());
Stephen Hinescfae0f32010-11-01 18:57:31 -070074 }
75 return;
76}
77
78void RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
79 // Disallow user-defined functions with prefix "rs"
80 if (!mAllowRSPrefix) {
81 // Iterate all function declarations in the program.
82 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
83 I != E; I++) {
84 clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I);
85 if (FD == NULL)
86 continue;
87 if (!FD->getName().startswith("rs")) // Check prefix
88 continue;
89 if (!SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr))
90 mDiags.Report(clang::FullSourceLoc(FD->getLocation(), mSourceMgr),
91 mDiags.getCustomDiagID(clang::Diagnostic::Error,
92 "invalid function name prefix, "
93 "\"rs\" is reserved: '%0'"))
94 << FD->getName();
95 }
96 }
97
98 // Process any non-static function declarations
99 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
Stephen Hineseb2eec92011-01-09 19:13:09 -0800100 clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I);
101 if (FD && FD->isGlobal()) {
102 AnnotateFunction(FD);
103 }
Stephen Hinescfae0f32010-11-01 18:57:31 -0700104 }
105
106 Backend::HandleTopLevelDecl(D);
107 return;
108}
109
Stephen Hinesc97a3332010-11-30 15:31:08 -0800110namespace {
111
Stephen Hinese5e64432010-12-02 18:48:20 -0800112bool ValidateVar(clang::VarDecl *VD, clang::Diagnostic *Diags,
113 clang::SourceManager *SM) {
Stephen Hinesc97a3332010-11-30 15:31:08 -0800114 llvm::StringRef TypeName;
115 const clang::Type *T = VD->getType().getTypePtr();
Stephen Hinesdd6206b2010-12-09 19:39:22 -0800116 if (!RSExportType::NormalizeType(T, TypeName, Diags, SM, VD)) {
Stephen Hinesc97a3332010-11-30 15:31:08 -0800117 return false;
118 }
119 return true;
120}
121
122bool ValidateASTContext(clang::ASTContext &C, clang::Diagnostic &Diags) {
123 bool valid = true;
Stephen Hinesfcda2352010-10-19 16:49:32 -0700124 clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
Stephen Hinesc97a3332010-11-30 15:31:08 -0800125 for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(),
126 DE = TUDecl->decls_end();
127 DI != DE;
128 DI++) {
129 if (DI->getKind() == clang::Decl::Var) {
130 clang::VarDecl *VD = (clang::VarDecl*) (*DI);
131 if (VD->getLinkage() == clang::ExternalLinkage) {
Stephen Hinese5e64432010-12-02 18:48:20 -0800132 if (!ValidateVar(VD, &Diags, &C.getSourceManager())) {
Stephen Hinesc97a3332010-11-30 15:31:08 -0800133 valid = false;
Stephen Hinesc97a3332010-11-30 15:31:08 -0800134 }
135 }
136 }
137 }
138
139 return valid;
140}
141
Stephen Hinese5e64432010-12-02 18:48:20 -0800142} // namespace
Stephen Hinesc97a3332010-11-30 15:31:08 -0800143
144void RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
145 clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
146
147 if (!ValidateASTContext(C, mDiags)) {
148 return;
149 }
Stephen Hinesfcda2352010-10-19 16:49:32 -0700150
Stephen Hines96ab06c2011-01-05 15:29:26 -0800151 int version = mContext->getVersion();
152 if (version == 0) {
153 // Not setting a version is an error
154 mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
155 "Missing pragma for version in source file"));
156 } else if (version > 1) {
157 mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
158 "Pragma for version in source file must be set to 1"));
159 }
160
Stephen Hinescfae0f32010-11-01 18:57:31 -0700161 // Process any static function declarations
Stephen Hinesfcda2352010-10-19 16:49:32 -0700162 for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
163 E = TUDecl->decls_end(); I != E; I++) {
164 if ((I->getKind() >= clang::Decl::firstFunction) &&
165 (I->getKind() <= clang::Decl::lastFunction)) {
Stephen Hineseb2eec92011-01-09 19:13:09 -0800166 clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I);
167 if (FD && !FD->isGlobal()) {
168 AnnotateFunction(FD);
169 }
Stephen Hinesfcda2352010-10-19 16:49:32 -0700170 }
171 }
172
173 return;
174}
175
176///////////////////////////////////////////////////////////////////////////////
Zonr Chang68fc02c2010-10-13 19:09:19 +0800177void RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
Stephen Hinesc808a992010-11-29 17:20:42 -0800178 if (!mContext->processExport()) {
179 mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
180 "elements cannot be exported"));
Stephen Hinesc97a3332010-11-30 15:31:08 -0800181 return;
Stephen Hinesc808a992010-11-29 17:20:42 -0800182 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700183
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700184 // Dump export variable info
185 if (mContext->hasExportVar()) {
186 if (mExportVarMetadata == NULL)
Zonr Chang68fc02c2010-10-13 19:09:19 +0800187 mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700188
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700189 llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700190
zonr6315f762010-10-05 15:35:14 +0800191 for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
192 E = mContext->export_vars_end();
193 I != E;
194 I++) {
195 const RSExportVar *EV = *I;
196 const RSExportType *ET = EV->getType();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700197
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700198 // Variable name
199 ExportVarInfo.push_back(
200 llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700201
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700202 // Type name
Zonr Changa65ec162010-10-17 01:53:05 +0800203 switch (ET->getClass()) {
204 case RSExportType::ExportClassPrimitive: {
205 ExportVarInfo.push_back(
206 llvm::MDString::get(
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700207 mLLVMContext, llvm::utostr_32(
Zonr Changa65ec162010-10-17 01:53:05 +0800208 static_cast<const RSExportPrimitiveType*>(ET)->getType())));
209 break;
210 }
211 case RSExportType::ExportClassPointer: {
212 ExportVarInfo.push_back(
213 llvm::MDString::get(
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700214 mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
Zonr Changa65ec162010-10-17 01:53:05 +0800215 ->getPointeeType()->getName()).c_str()));
216 break;
217 }
218 case RSExportType::ExportClassMatrix: {
219 ExportVarInfo.push_back(
220 llvm::MDString::get(
221 mLLVMContext, llvm::utostr_32(
222 RSExportPrimitiveType::DataTypeRSMatrix2x2 +
223 static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
224 break;
225 }
226 case RSExportType::ExportClassVector:
227 case RSExportType::ExportClassConstantArray:
228 case RSExportType::ExportClassRecord: {
229 ExportVarInfo.push_back(
230 llvm::MDString::get(mLLVMContext,
231 EV->getType()->getName().c_str()));
232 break;
233 }
234 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700235
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700236 mExportVarMetadata->addOperand(
237 llvm::MDNode::get(mLLVMContext,
238 ExportVarInfo.data(),
239 ExportVarInfo.size()) );
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700240
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700241 ExportVarInfo.clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700242 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700243 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700244
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700245 // Dump export function info
246 if (mContext->hasExportFunc()) {
247 if (mExportFuncMetadata == NULL)
248 mExportFuncMetadata =
Zonr Chang68fc02c2010-10-13 19:09:19 +0800249 M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700250
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700251 llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700252
zonr6315f762010-10-05 15:35:14 +0800253 for (RSContext::const_export_func_iterator
254 I = mContext->export_funcs_begin(),
255 E = mContext->export_funcs_end();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700256 I != E;
257 I++) {
zonr6315f762010-10-05 15:35:14 +0800258 const RSExportFunc *EF = *I;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700259
260 // Function name
zonr6315f762010-10-05 15:35:14 +0800261 if (!EF->hasParam()) {
262 ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
263 EF->getName().c_str()));
264 } else {
Zonr Chang68fc02c2010-10-13 19:09:19 +0800265 llvm::Function *F = M->getFunction(EF->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700266 llvm::Function *HelperFunction;
267 const std::string HelperFunctionName(".helper_" + EF->getName());
268
269 assert(F && "Function marked as exported disappeared in Bitcode");
270
271 // Create helper function
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700272 {
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800273 llvm::StructType *HelperFunctionParameterTy = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700274
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800275 if (!F->getArgumentList().empty()) {
276 std::vector<const llvm::Type*> HelperFunctionParameterTys;
277 for (llvm::Function::arg_iterator AI = F->arg_begin(),
278 AE = F->arg_end(); AI != AE; AI++)
279 HelperFunctionParameterTys.push_back(AI->getType());
280
281 HelperFunctionParameterTy =
282 llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
283 }
284
285 if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
286 fprintf(stderr, "Failed to export function %s: parameter type "
287 "mismatch during creation of helper function.\n",
288 EF->getName().c_str());
289
290 const RSExportRecordType *Expected = EF->getParamPacketType();
291 if (Expected) {
292 fprintf(stderr, "Expected:\n");
293 Expected->getLLVMType()->dump();
294 }
295 if (HelperFunctionParameterTy) {
296 fprintf(stderr, "Got:\n");
297 HelperFunctionParameterTy->dump();
298 }
299 }
300
301 std::vector<const llvm::Type*> Params;
302 if (HelperFunctionParameterTy) {
303 llvm::PointerType *HelperFunctionParameterTyP =
304 llvm::PointerType::getUnqual(HelperFunctionParameterTy);
305 Params.push_back(HelperFunctionParameterTyP);
306 }
307
308 llvm::FunctionType * HelperFunctionType =
309 llvm::FunctionType::get(F->getReturnType(),
310 Params,
311 /* IsVarArgs = */false);
Shih-wei Liaocecd11d2010-09-21 08:07:58 -0700312
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700313 HelperFunction =
314 llvm::Function::Create(HelperFunctionType,
315 llvm::GlobalValue::ExternalLinkage,
316 HelperFunctionName,
Zonr Chang68fc02c2010-10-13 19:09:19 +0800317 M);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700318
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700319 HelperFunction->addFnAttr(llvm::Attribute::NoInline);
320 HelperFunction->setCallingConv(F->getCallingConv());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700321
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700322 // Create helper function body
323 {
324 llvm::Argument *HelperFunctionParameter =
325 &(*HelperFunction->arg_begin());
326 llvm::BasicBlock *BB =
327 llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
328 llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
329 llvm::SmallVector<llvm::Value*, 6> Params;
330 llvm::Value *Idx[2];
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700331
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700332 Idx[0] =
333 llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700334
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700335 // getelementptr and load instruction for all elements in
336 // parameter .p
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800337 for (size_t i = 0; i < EF->getNumParameters(); i++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700338 // getelementptr
339 Idx[1] =
340 llvm::ConstantInt::get(
341 llvm::Type::getInt32Ty(mLLVMContext), i);
342 llvm::Value *Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter,
343 Idx,
344 Idx + 2);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700345
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700346 // load
347 llvm::Value *V = IB->CreateLoad(Ptr);
348 Params.push_back(V);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700349 }
350
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700351 // Call and pass the all elements as paramter to F
352 llvm::CallInst *CI = IB->CreateCall(F,
353 Params.data(),
354 Params.data() + Params.size());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700355
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700356 CI->setCallingConv(F->getCallingConv());
357
358 if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
359 IB->CreateRetVoid();
360 else
361 IB->CreateRet(CI);
362
363 delete IB;
364 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700365 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700366
367 ExportFuncInfo.push_back(
368 llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
369 }
370
371 mExportFuncMetadata->addOperand(
372 llvm::MDNode::get(mLLVMContext,
373 ExportFuncInfo.data(),
374 ExportFuncInfo.size()));
375
376 ExportFuncInfo.clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700377 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700378 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700379
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700380 // Dump export type info
381 if (mContext->hasExportType()) {
382 llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700383
zonr6315f762010-10-05 15:35:14 +0800384 for (RSContext::const_export_type_iterator
385 I = mContext->export_types_begin(),
386 E = mContext->export_types_end();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700387 I != E;
388 I++) {
389 // First, dump type name list to export
390 const RSExportType *ET = I->getValue();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700391
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700392 ExportTypeInfo.clear();
393 // Type name
394 ExportTypeInfo.push_back(
395 llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700396
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700397 if (ET->getClass() == RSExportType::ExportClassRecord) {
398 const RSExportRecordType *ERT =
399 static_cast<const RSExportRecordType*>(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700400
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700401 if (mExportTypeMetadata == NULL)
402 mExportTypeMetadata =
Zonr Chang68fc02c2010-10-13 19:09:19 +0800403 M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700404
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700405 mExportTypeMetadata->addOperand(
406 llvm::MDNode::get(mLLVMContext,
407 ExportTypeInfo.data(),
408 ExportTypeInfo.size()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700409
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700410 // Now, export struct field information to %[struct name]
411 std::string StructInfoMetadataName("%");
412 StructInfoMetadataName.append(ET->getName());
413 llvm::NamedMDNode *StructInfoMetadata =
Zonr Chang68fc02c2010-10-13 19:09:19 +0800414 M->getOrInsertNamedMetadata(StructInfoMetadataName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700415 llvm::SmallVector<llvm::Value*, 3> FieldInfo;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700416
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700417 assert(StructInfoMetadata->getNumOperands() == 0 &&
418 "Metadata with same name was created before");
zonr6315f762010-10-05 15:35:14 +0800419 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
420 FE = ERT->fields_end();
421 FI != FE;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700422 FI++) {
423 const RSExportRecordType::Field *F = *FI;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700424
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700425 // 1. field name
426 FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
427 F->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700428
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700429 // 2. field type name
430 FieldInfo.push_back(
431 llvm::MDString::get(mLLVMContext,
432 F->getType()->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700433
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700434 // 3. field kind
435 switch (F->getType()->getClass()) {
436 case RSExportType::ExportClassPrimitive:
437 case RSExportType::ExportClassVector: {
438 const RSExportPrimitiveType *EPT =
439 static_cast<const RSExportPrimitiveType*>(F->getType());
440 FieldInfo.push_back(
441 llvm::MDString::get(mLLVMContext,
442 llvm::itostr(EPT->getKind())));
443 break;
444 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700445
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700446 default: {
447 FieldInfo.push_back(
448 llvm::MDString::get(mLLVMContext,
449 llvm::itostr(
zonr6315f762010-10-05 15:35:14 +0800450 RSExportPrimitiveType::DataKindUser)));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700451 break;
452 }
453 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700454
zonr6315f762010-10-05 15:35:14 +0800455 StructInfoMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
456 FieldInfo.data(),
457 FieldInfo.size()));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700458
459 FieldInfo.clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700460 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700461 } // ET->getClass() == RSExportType::ExportClassRecord
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700462 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700463 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700464
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700465 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700466}
467
468RSBackend::~RSBackend() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700469 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700470}
Stephen Hinese639eb52010-11-08 19:27:20 -0800471
472} // namespace slang