blob: 19d6ceeeea4eacf1b85287e20d7c461e24a4d186 [file] [log] [blame]
zonr6315f762010-10-05 15:35:14 +08001#include "slang_rs_export_func.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07003#include "llvm/Target/TargetData.h"
Shih-wei Liao0a3f20e2010-08-10 13:09:49 -07004
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07005#include "clang/AST/Decl.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -07006
zonr6315f762010-10-05 15:35:14 +08007#include "slang_rs_context.h"
8#include "slang_rs_export_type.h"
9
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070010using namespace slang;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070011
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070012RSExportFunc *RSExportFunc::Create(RSContext *Context,
13 const clang::FunctionDecl *FD) {
14 llvm::StringRef Name = FD->getName();
15 RSExportFunc *F;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070016
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070017 assert(!Name.empty() && "Function must have a name");
Shih-wei Liao462aefd2010-06-04 15:32:04 -070018
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070019 F = new RSExportFunc(Context, Name);
Shih-wei Liao462aefd2010-06-04 15:32:04 -070020
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070021 // Check whether the parameters passed to the function is exportable
zonr6315f762010-10-05 15:35:14 +080022 for (unsigned i = 0, e = FD->getNumParams(); i != e; i++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070023 const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
24 const llvm::StringRef ParamName = PVD->getName();
Shih-wei Liao462aefd2010-06-04 15:32:04 -070025
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070026 assert(!ParamName.empty() && "Parameter must have a name");
Shih-wei Liao462aefd2010-06-04 15:32:04 -070027
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070028 if (PVD->hasDefaultArg())
29 fprintf(stderr,
30 "Note: parameter '%s' in function '%s' has default value "
31 "will not support\n",
32 ParamName.str().c_str(),
33 Name.str().c_str());
Shih-wei Liao462aefd2010-06-04 15:32:04 -070034
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070035 // Check type
36 RSExportType *PET = RSExportType::CreateFromDecl(Context, PVD);
37 if (PET != NULL) {
38 F->mParams.push_back(new Parameter(PET, ParamName));
39 } else {
40 fprintf(stderr, "Note: parameter '%s' in function '%s' uses unsupported "
41 "type\n", ParamName.str().c_str(), Name.str().c_str());
42 delete F;
43 return NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070044 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070045 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070046
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070047 return F;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070048}
49
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070050const RSExportRecordType *RSExportFunc::getParamPacketType() const {
51 // Pack parameters
52 if ((mParamPacketType == NULL) && hasParam()) {
53 int Index = 0;
54 RSExportRecordType *ParamPacketType =
55 new RSExportRecordType(mContext,
56 "",
57 /* IsPacked = */false,
58 /* IsArtificial = */true);
Shih-wei Liao462aefd2010-06-04 15:32:04 -070059
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070060 for (const_param_iterator PI = params_begin(),
61 PE = params_end();
62 PI != PE;
63 PI++, Index++) {
zonr6315f762010-10-05 15:35:14 +080064 // For-Loop's body should be:
65 const RSExportFunc::Parameter *P = *PI;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070066 std::string nam = P->getName();
zonr6315f762010-10-05 15:35:14 +080067 const RSExportType *typ = P->getType();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070068 std::string typNam = typ->getName();
69 // If (type conversion is needed)
70 if (typNam.find("rs_") == 0) {
71 // P's type set to [1 x i32];
zonr6315f762010-10-05 15:35:14 +080072 RSExportConstantArrayType *ECT = new RSExportConstantArrayType
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070073 (mContext, "addObj",
74 RSExportPrimitiveType::DataTypeSigned32,
75 RSExportPrimitiveType::DataKindUser,
76 false,
77 1);
78 ParamPacketType->mFields.push_back(
79 new RSExportRecordType::Field(ECT,
80 nam,
81 ParamPacketType,
82 Index) );
83 } else {
84 ParamPacketType->mFields.push_back(
85 new RSExportRecordType::Field(P->getType(),
86 nam,
87 ParamPacketType,
88 Index) );
89 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070090 }
91
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070092
93
94 ParamPacketType->AllocSize =
95 mContext->getTargetData()->getTypeAllocSize(
zonr6315f762010-10-05 15:35:14 +080096 ParamPacketType->getLLVMType());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070097
98 mParamPacketType = ParamPacketType;
99 }
100
101 return mParamPacketType;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700102}
103
104RSExportFunc::~RSExportFunc() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700105 for (const_param_iterator PI = params_begin(),
106 PE = params_end();
107 PI != params_end();
108 PI++)
109 delete *PI;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700110
zonr6315f762010-10-05 15:35:14 +0800111 if (mParamPacketType != NULL)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700112 delete mParamPacketType;
Shih-wei Liao1f0d88f2010-06-25 00:15:24 -0700113
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700114 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700115}