comparison gen/aa.cpp @ 109:5ab8e92611f9 trunk

[svn r113] Added initial support for associative arrays (AAs). Fixed some problems with the string runtime support functions. Fixed initialization of array of structs. Fixed slice assignment where LHS is slice but RHS is dynamic array. Fixed problems with result of assignment expressions. Fixed foreach problems with key type mismatches.
author lindquist
date Wed, 21 Nov 2007 04:13:15 +0100
parents
children facc562f5674
comparison
equal deleted inserted replaced
108:288fe1029e1f 109:5ab8e92611f9
1 #include "gen/llvm.h"
2
3 #include "mtype.h"
4 #include "declaration.h"
5 #include "aggregate.h"
6
7 #include "gen/aa.h"
8 #include "gen/runtime.h"
9 #include "gen/tollvm.h"
10 #include "gen/logger.h"
11 #include "gen/irstate.h"
12 #include "gen/dvalue.h"
13
14 // makes sure the key value lives in memory so it can be passed to the runtime functions without problems
15 // returns the pointer
16 static llvm::Value* to_pkey(DValue* key)
17 {
18 Type* keytype = key->getType();
19 bool needmem = !DtoIsPassedByRef(keytype);
20 llvm::Value* pkey;
21 if (key->isIm()) {
22 pkey = key->getRVal();
23 }
24 else if (DVarValue* var = key->isVar()) {
25 if (var->lval) {
26 pkey = key->getLVal();
27 needmem = false;
28 }
29 else {
30 pkey = key->getRVal();
31 }
32 }
33 else if (key->isConst()) {
34 needmem = true;
35 pkey = key->getRVal();
36 }
37 else {
38 assert(0);
39 }
40
41 // give memory
42 if (needmem) {
43 llvm::Value* tmp = new llvm::AllocaInst(DtoType(keytype), "aatmpkeystorage", gIR->topallocapoint());
44 DtoStore(pkey, tmp);
45 pkey = tmp;
46 }
47
48 return pkey;
49 }
50
51 /////////////////////////////////////////////////////////////////////////////////////
52
53 DValue* DtoAAIndex(Type* type, DValue* aa, DValue* key)
54 {
55 // call:
56 // extern(C) void* _aaGet(AA* aa, TypeInfo keyti, void* pkey, size_t valuesize)
57
58 // first get the runtime function
59 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaGet");
60 const llvm::FunctionType* funcTy = func->getFunctionType();
61
62 // aa param
63 llvm::Value* aaval = aa->getLVal();
64 aaval = DtoBitCast(aaval, funcTy->getParamType(0));
65
66 // keyti param
67 Type* keytype = key->getType();
68 keytype->getTypeInfo(NULL);
69 TypeInfoDeclaration* tid = keytype->getTypeInfoDeclaration();
70 assert(tid);
71 DtoResolveDsymbol(Type::typeinfo);
72 DtoForceDeclareDsymbol(tid);
73 assert(tid->llvmValue);
74 llvm::Value* keyti = tid->llvmValue;
75 keyti = DtoBitCast(keyti, funcTy->getParamType(1));
76
77 // pkey param
78 llvm::Value* pkey = to_pkey(key);
79 pkey = DtoBitCast(pkey, funcTy->getParamType(2));
80
81 // valuesize param
82 llvm::Value* valsize = DtoConstSize_t(gTargetData->getTypeSize(DtoType(type)));
83
84 // build arg vector
85 std::vector<llvm::Value*> args;
86 args.push_back(aaval);
87 args.push_back(keyti);
88 args.push_back(pkey);
89 args.push_back(valsize);
90
91 // call runtime
92 llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aaGet");
93
94 // cast return value
95 const llvm::Type* targettype = llvm::PointerType::get(DtoType(type));
96 if (ret->getType() != targettype)
97 ret = DtoBitCast(ret, targettype);
98
99 return new DVarValue(type, ret, true);
100 }
101
102 /////////////////////////////////////////////////////////////////////////////////////
103
104 DValue* DtoAAIn(Type* type, DValue* aa, DValue* key)
105 {
106 // call:
107 // extern(C) void* _aaIn(AA aa*, TypeInfo keyti, void* pkey)
108
109 // first get the runtime function
110 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaIn");
111 const llvm::FunctionType* funcTy = func->getFunctionType();
112
113 Logger::cout() << "_aaIn = " << *func << '\n';
114
115 // aa param
116 llvm::Value* aaval = aa->getRVal();
117 Logger::cout() << "aaval: " << *aaval << '\n';
118 Logger::cout() << "totype: " << *funcTy->getParamType(0) << '\n';
119 aaval = DtoBitCast(aaval, funcTy->getParamType(0));
120
121 // keyti param
122 Type* keytype = key->getType();
123 keytype->getTypeInfo(NULL);
124 TypeInfoDeclaration* tid = keytype->getTypeInfoDeclaration();
125 assert(tid);
126 DtoResolveDsymbol(Type::typeinfo);
127 DtoForceDeclareDsymbol(tid);
128 assert(tid->llvmValue);
129 llvm::Value* keyti = tid->llvmValue;
130 keyti = DtoBitCast(keyti, funcTy->getParamType(1));
131
132 // pkey param
133 llvm::Value* pkey = to_pkey(key);
134 pkey = DtoBitCast(pkey, funcTy->getParamType(2));
135
136 // build arg vector
137 std::vector<llvm::Value*> args;
138 args.push_back(aaval);
139 args.push_back(keyti);
140 args.push_back(pkey);
141
142 // call runtime
143 llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aaIn");
144
145 // cast return value
146 const llvm::Type* targettype = DtoType(type);
147 if (ret->getType() != targettype)
148 ret = DtoBitCast(ret, targettype);
149
150 return new DImValue(type, ret);
151 }
152
153 /////////////////////////////////////////////////////////////////////////////////////