irgenerator/std-function-manager.spice
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright (c) 2021-2026 ChilliBits. All rights reserved. | ||
| 2 | |||
| 3 | // Std imports | ||
| 4 | import "std/data/vector"; | ||
| 5 | import "std/bindings/llvm/llvm" as llvm; | ||
| 6 | |||
| 7 | // Own imports | ||
| 8 | import "@/source-file"; | ||
| 9 | import "@/irgenerator/abi-info"; | ||
| 10 | import "@/irgenerator/ir-generator"; | ||
| 11 | import "@/irgenerator/name-mangling"; | ||
| 12 | import "@/model/function" as model; // Aliased, because Function clashes with llvm::Function | ||
| 13 | import "@/ast/ast-nodes"; | ||
| 14 | import "@/model/generic-type"; | ||
| 15 | import "@/symboltablebuilder/qual-type"; | ||
| 16 | import "@/symboltablebuilder/super-type"; | ||
| 17 | import "@/symboltablebuilder/symbol-table-entry"; | ||
| 18 | |||
| 19 | /** | ||
| 20 | * Helper for the IRGenerator to retrieve the declarations of functions from the C standard library, LLVM intrinsics and the | ||
| 21 | * Spice runtime modules | ||
| 22 | */ | ||
| 23 | public type StdFunctionManager struct { | ||
| 24 | SourceFile* sourceFile | ||
| 25 | llvm::IRBuilder* builder | ||
| 26 | llvm::Module* module | ||
| 27 | IRGenerator* irGenerator | ||
| 28 | } | ||
| 29 | |||
| 30 | 3499 | public p StdFunctionManager.ctor(SourceFile* sourceFile, llvm::Module* module, IRGenerator* irGenerator) { | |
| 31 | 3499 | this.sourceFile = sourceFile; | |
| 32 | 3499 | this.builder = &sourceFile.builder; | |
| 33 | 3499 | this.module = module; | |
| 34 | 3499 | this.irGenerator = irGenerator; | |
| 35 | 3499 | } | |
| 36 | |||
| 37 | 2346 | public f<llvm::Function> StdFunctionManager.getPrintfFct() { | |
| 38 | 2346 | Vector<llvm::Type> paramTypes; | |
| 39 | 2346 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 40 | 2346 | llvm::Function printfFct = this.getFunction("printf", this.builder.getInt32Ty(), paramTypes, true); | |
| 41 | // Set attributes | ||
| 42 | 2346 | printfFct.setUnnamedAddr(llvm::LLVMUnnamedAddr::LocalUnnamedAddr); | |
| 43 | 2346 | printfFct.addFnAttr("nofree"); | |
| 44 | 2346 | printfFct.addFnAttr("nounwind"); | |
| 45 | 2346 | printfFct.addParamAttr(0, "captures", 0l); // captures(none) | |
| 46 | 2346 | printfFct.addParamAttr(0, "noundef"); | |
| 47 | 2346 | printfFct.addParamAttr(0, "readonly"); | |
| 48 | 2346 | printfFct.addRetAttr("noundef"); | |
| 49 | 4692 | return printfFct; | |
| 50 | 2346 | } | |
| 51 | |||
| 52 | 7755 | public f<llvm::Function> StdFunctionManager.getFPrintfFct() { | |
| 53 | 7755 | Vector<llvm::Type> paramTypes; | |
| 54 | 7755 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 55 | 7755 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 56 | 7755 | llvm::Function fprintfFct = this.getFunction("fprintf", this.builder.getInt32Ty(), paramTypes, true); | |
| 57 | // Set attributes | ||
| 58 | 7755 | fprintfFct.setUnnamedAddr(llvm::LLVMUnnamedAddr::LocalUnnamedAddr); | |
| 59 | 7755 | fprintfFct.addFnAttr("nofree"); | |
| 60 | 7755 | fprintfFct.addParamAttr(0, "captures", 0l); // captures(none) | |
| 61 | 7755 | fprintfFct.addParamAttr(0, "noundef"); | |
| 62 | 7755 | fprintfFct.addParamAttr(1, "captures", 0l); // captures(none) | |
| 63 | 7755 | fprintfFct.addParamAttr(1, "noundef"); | |
| 64 | 7755 | fprintfFct.addParamAttr(1, "readonly"); | |
| 65 | 7755 | fprintfFct.addRetAttr("noundef"); | |
| 66 | 15510 | return fprintfFct; | |
| 67 | 7755 | } | |
| 68 | |||
| 69 | 7755 | public f<llvm::Function> StdFunctionManager.getExitFct() { | |
| 70 | 7755 | Vector<llvm::Type> paramTypes; | |
| 71 | 7755 | paramTypes.pushBack(this.builder.getInt32Ty()); | |
| 72 | 7755 | llvm::Function exitFct = this.getProcedure("exit", paramTypes); | |
| 73 | // Set attributes | ||
| 74 | 7755 | exitFct.addFnAttr("cold"); | |
| 75 | 7755 | exitFct.addFnAttr("noreturn"); | |
| 76 | 7755 | exitFct.addFnAttr("nounwind"); | |
| 77 | 15510 | return exitFct; | |
| 78 | 7755 | } | |
| 79 | |||
| 80 | ✗ | public f<llvm::Function> StdFunctionManager.getFreeFct() { | |
| 81 | ✗ | Vector<llvm::Type> paramTypes; | |
| 82 | ✗ | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 83 | ✗ | llvm::Function freeFct = this.getProcedure("free", paramTypes); | |
| 84 | // Set attributes | ||
| 85 | ✗ | freeFct.addFnAttr("nounwind"); | |
| 86 | ✗ | freeFct.addParamAttr(0, "captures", 0l); // captures(none) | |
| 87 | ✗ | freeFct.addParamAttr(0, "noundef"); | |
| 88 | ✗ | freeFct.addParamAttr(0, "readonly"); | |
| 89 | ✗ | return freeFct; | |
| 90 | ✗ | } | |
| 91 | |||
| 92 | 68 | public f<llvm::Function> StdFunctionManager.getMemcmpFct() { | |
| 93 | 68 | Vector<llvm::Type> paramTypes; | |
| 94 | 68 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 95 | 68 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 96 | 68 | paramTypes.pushBack(this.builder.getInt64Ty()); | |
| 97 | 68 | llvm::Function memcmpFct = this.getFunction("memcmp", this.builder.getInt32Ty(), paramTypes); | |
| 98 | // Set attributes | ||
| 99 | 68 | memcmpFct.addFnAttr("nounwind"); | |
| 100 | 68 | memcmpFct.addParamAttr(0, "captures", 0l); // captures(none) | |
| 101 | 68 | memcmpFct.addParamAttr(0, "noundef"); | |
| 102 | 68 | memcmpFct.addParamAttr(0, "readonly"); | |
| 103 | 68 | memcmpFct.addParamAttr(1, "captures", 0l); // captures(none) | |
| 104 | 68 | memcmpFct.addParamAttr(1, "noundef"); | |
| 105 | 68 | memcmpFct.addParamAttr(1, "readonly"); | |
| 106 | 68 | memcmpFct.addParamAttr(2, "noundef"); | |
| 107 | 68 | memcmpFct.addRetAttr("noundef"); | |
| 108 | 136 | return memcmpFct; | |
| 109 | 68 | } | |
| 110 | |||
| 111 | 2136 | public f<llvm::Function> StdFunctionManager.getMemcpyIntrinsic() { | |
| 112 | 2136 | Vector<llvm::Type> paramTypes; | |
| 113 | 2136 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 114 | 2136 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 115 | 2136 | paramTypes.pushBack(this.builder.getInt64Ty()); | |
| 116 | 2136 | paramTypes.pushBack(this.builder.getInt1Ty()); | |
| 117 | 2136 | llvm::Function memcpyFct = this.getProcedure("llvm.memcpy.p0.p0.i64", paramTypes); | |
| 118 | // Set attributes | ||
| 119 | 2136 | memcpyFct.addFnAttr("nocallback"); | |
| 120 | 2136 | memcpyFct.addFnAttr("nofree"); | |
| 121 | 2136 | memcpyFct.addFnAttr("nounwind"); | |
| 122 | 2136 | memcpyFct.addFnAttr("willreturn"); | |
| 123 | 4272 | return memcpyFct; | |
| 124 | 2136 | } | |
| 125 | |||
| 126 | 99 | public f<llvm::Function> StdFunctionManager.getStringGetRawLengthStringFct() { | |
| 127 | 99 | model::ParamList paramLst; | |
| 128 | 99 | paramLst.pushBack(model::Param{QualType(SuperType::TY_STRING), false}); | |
| 129 | 99 | const String mangledName = mangleStdFunction("getRawLength", QualType(SuperType::TY_LONG), paramLst); | |
| 130 | 99 | Vector<llvm::Type> paramTypes; | |
| 131 | 99 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 132 | 198 | return this.getFunction(mangledName.getRaw(), this.builder.getInt64Ty(), paramTypes); | |
| 133 | 99 | } | |
| 134 | |||
| 135 | 529 | public f<llvm::Function> StdFunctionManager.getStringIsRawEqualStringStringFct() { | |
| 136 | 529 | model::ParamList paramLst; | |
| 137 | 529 | paramLst.pushBack(model::Param{QualType(SuperType::TY_STRING), false}); | |
| 138 | 529 | paramLst.pushBack(model::Param{QualType(SuperType::TY_STRING), false}); | |
| 139 | 529 | const String mangledName = mangleStdFunction("isRawEqual", QualType(SuperType::TY_BOOL), paramLst); | |
| 140 | 529 | Vector<llvm::Type> paramTypes; | |
| 141 | 529 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 142 | 529 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 143 | 1058 | return this.getFunction(mangledName.getRaw(), this.builder.getInt1Ty(), paramTypes); | |
| 144 | 529 | } | |
| 145 | |||
| 146 | 244 | public f<llvm::Function> StdFunctionManager.getAllocUnsafeLongFct() { | |
| 147 | 244 | QualType unsignedLong = QualType(SuperType::TY_LONG); | |
| 148 | 244 | unsignedLong.makeUnsigned(); | |
| 149 | 244 | model::ParamList paramLst; | |
| 150 | 244 | paramLst.pushBack(model::Param{unsignedLong, false}); | |
| 151 | 244 | const QualType bytePtrType = QualType(SuperType::TY_BYTE); | |
| 152 | 244 | const String mangledName = mangleStdFunction("sAllocUnsafe", bytePtrType.toPtr(nil<ASTNode*>), paramLst); | |
| 153 | 244 | Vector<llvm::Type> paramTypes; | |
| 154 | 244 | paramTypes.pushBack(this.builder.getInt64Ty()); | |
| 155 | 488 | return this.getFunction(mangledName.getRaw(), this.builder.getPtrTy(), paramTypes); | |
| 156 | 244 | } | |
| 157 | |||
| 158 | 324 | public f<llvm::Function> StdFunctionManager.getDeallocBytePtrRefFct() { | |
| 159 | 324 | const QualType byteType = QualType(SuperType::TY_BYTE); | |
| 160 | 324 | QualType heapBytePtrType = byteType.toPtr(nil<ASTNode*>); | |
| 161 | 324 | heapBytePtrType.makeHeap(); | |
| 162 | 324 | model::ParamList paramLst; | |
| 163 | 324 | paramLst.pushBack(model::Param{heapBytePtrType.toRef(nil<ASTNode*>), false}); | |
| 164 | 324 | const String mangledName = mangleStdFunction("sDealloc", QualType(SuperType::TY_DYN), paramLst); | |
| 165 | 324 | Vector<llvm::Type> paramTypes; | |
| 166 | 324 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 167 | 648 | return this.getProcedure(mangledName.getRaw(), paramTypes); | |
| 168 | 324 | } | |
| 169 | |||
| 170 | 7 | public f<llvm::Function> StdFunctionManager.getIterateFct(const model::Function* spiceFunc) { | |
| 171 | 7 | const String functionName = mangleFunction(*spiceFunc); | |
| 172 | 7 | Vector<llvm::Type> paramTypes; | |
| 173 | 7 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 174 | 7 | paramTypes.pushBack(this.builder.getInt64Ty()); | |
| 175 | 14 | return this.getSpiceFunction(functionName.getRaw(), spiceFunc.returnType, paramTypes); | |
| 176 | 7 | } | |
| 177 | |||
| 178 | 393 | public f<llvm::Function> StdFunctionManager.getIteratorFct(const model::Function* spiceFunc) { | |
| 179 | 393 | const String functionName = mangleFunction(*spiceFunc); | |
| 180 | 393 | Vector<llvm::Type> paramTypes; | |
| 181 | 393 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 182 | 786 | return this.getSpiceFunction(functionName.getRaw(), spiceFunc.returnType, paramTypes); | |
| 183 | 393 | } | |
| 184 | |||
| 185 | 408 | public f<llvm::Function> StdFunctionManager.getIteratorGetFct(const model::Function* spiceFunc) { | |
| 186 | 408 | const String functionName = mangleFunction(*spiceFunc); | |
| 187 | 408 | Vector<llvm::Type> paramTypes; | |
| 188 | 408 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 189 | 816 | return this.getFunction(functionName.getRaw(), this.builder.getPtrTy(), paramTypes); | |
| 190 | 408 | } | |
| 191 | |||
| 192 | 30 | public f<llvm::Function> StdFunctionManager.getIteratorGetIdxFct(const model::Function* spiceFunc) { | |
| 193 | 30 | const String functionName = mangleFunction(*spiceFunc); | |
| 194 | 30 | Vector<llvm::Type> paramTypes; | |
| 195 | 30 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 196 | 60 | return this.getSpiceFunction(functionName.getRaw(), spiceFunc.returnType, paramTypes); | |
| 197 | 30 | } | |
| 198 | |||
| 199 | 438 | public f<llvm::Function> StdFunctionManager.getIteratorIsValidFct(const model::Function* spiceFunc) { | |
| 200 | 438 | const String functionName = mangleFunction(*spiceFunc); | |
| 201 | 438 | Vector<llvm::Type> paramTypes; | |
| 202 | 438 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 203 | 876 | return this.getFunction(functionName.getRaw(), this.builder.getInt1Ty(), paramTypes); | |
| 204 | 438 | } | |
| 205 | |||
| 206 | 438 | public f<llvm::Function> StdFunctionManager.getIteratorNextFct(const model::Function* spiceFunc) { | |
| 207 | 438 | const String functionName = mangleFunction(*spiceFunc); | |
| 208 | 438 | Vector<llvm::Type> paramTypes; | |
| 209 | 438 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 210 | 876 | return this.getProcedure(functionName.getRaw(), paramTypes); | |
| 211 | 438 | } | |
| 212 | |||
| 213 | 93 | public f<llvm::Function> StdFunctionManager.getResultIsErrFct(const model::Function* spiceFunc) { | |
| 214 | 93 | const String functionName = mangleFunction(*spiceFunc); | |
| 215 | 93 | Vector<llvm::Type> paramTypes; | |
| 216 | 93 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 217 | 186 | return this.getFunction(functionName.getRaw(), this.builder.getInt1Ty(), paramTypes); | |
| 218 | 93 | } | |
| 219 | |||
| 220 | 93 | public f<llvm::Function> StdFunctionManager.getResultUnwrapFct(const model::Function* spiceFunc) { | |
| 221 | 93 | const String functionName = mangleFunction(*spiceFunc); | |
| 222 | 93 | Vector<llvm::Type> paramTypes; | |
| 223 | 93 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 224 | 186 | return this.getFunction(functionName.getRaw(), this.builder.getPtrTy(), paramTypes); | |
| 225 | 93 | } | |
| 226 | |||
| 227 | 93 | public f<llvm::Function> StdFunctionManager.getResultGetErrFct(const model::Function* spiceFunc) { | |
| 228 | 93 | const String functionName = mangleFunction(*spiceFunc); | |
| 229 | 93 | Vector<llvm::Type> paramTypes; | |
| 230 | 93 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 231 | 186 | return this.getFunction(functionName.getRaw(), this.builder.getPtrTy(), paramTypes); | |
| 232 | 93 | } | |
| 233 | |||
| 234 | 93 | public f<llvm::Function> StdFunctionManager.getResultErrCtorFct(const model::Function* spiceFunc) { | |
| 235 | 93 | const String functionName = mangleFunction(*spiceFunc); | |
| 236 | 93 | Vector<llvm::Type> paramTypes; | |
| 237 | 93 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 238 | 186 | return this.getSpiceFunction(functionName.getRaw(), spiceFunc.returnType, paramTypes); | |
| 239 | 93 | } | |
| 240 | |||
| 241 | 5 | public f<llvm::Function> StdFunctionManager.getErrTraceResetFct() { | |
| 242 | 5 | const String mangledName = mangleStdFunction("sErrTraceReset", QualType(SuperType::TY_DYN), getErrTraceParamList()); | |
| 243 | 10 | return this.getProcedure(mangledName.getRaw(), this.getErrTraceParamTypes()); | |
| 244 | 5 | } | |
| 245 | |||
| 246 | 3 | public f<llvm::Function> StdFunctionManager.getErrTracePushFct() { | |
| 247 | 3 | const String mangledName = mangleStdFunction("sErrTracePush", QualType(SuperType::TY_DYN), getErrTraceParamList()); | |
| 248 | 6 | return this.getProcedure(mangledName.getRaw(), this.getErrTraceParamTypes()); | |
| 249 | 3 | } | |
| 250 | |||
| 251 | 2933 | public f<llvm::Function> StdFunctionManager.getErrTraceDumpFct() { | |
| 252 | 2933 | const model::ParamList paramLst; | |
| 253 | 2933 | const String mangledName = mangleStdFunction("sErrTraceDump", QualType(SuperType::TY_DYN), paramLst); | |
| 254 | 2933 | const Vector<llvm::Type> paramTypes; | |
| 255 | 5866 | return this.getProcedure(mangledName.getRaw(), paramTypes); | |
| 256 | 2933 | } | |
| 257 | |||
| 258 | ✗ | public f<llvm::Function> StdFunctionManager.getDumpStacktraceFct() { | |
| 259 | // Defaults are resolved by the time a function is mangled, so the params are not optional | ||
| 260 | ✗ | model::ParamList paramLst; | |
| 261 | ✗ | paramLst.pushBack(model::Param{QualType(SuperType::TY_BOOL), false}); | |
| 262 | ✗ | paramLst.pushBack(model::Param{QualType(SuperType::TY_BOOL), false}); | |
| 263 | ✗ | const String mangledName = mangleStdFunction("sDumpStacktrace", QualType(SuperType::TY_DYN), paramLst); | |
| 264 | ✗ | Vector<llvm::Type> paramTypes; | |
| 265 | ✗ | paramTypes.pushBack(this.builder.getInt1Ty()); | |
| 266 | ✗ | paramTypes.pushBack(this.builder.getInt1Ty()); | |
| 267 | ✗ | return this.getProcedure(mangledName.getRaw(), paramTypes); | |
| 268 | ✗ | } | |
| 269 | |||
| 270 | 58 | public f<llvm::Function> StdFunctionManager.getAcrtIOFuncFct() { | |
| 271 | 58 | Vector<llvm::Type> paramTypes; | |
| 272 | 58 | paramTypes.pushBack(this.builder.getInt32Ty()); | |
| 273 | 58 | llvm::Function stdErrPFct = this.getFunction("__acrt_iob_func", this.builder.getPtrTy(), paramTypes); | |
| 274 | // ToDo: Set dso_local as soon as the LLVM C API allows it | ||
| 275 | // Set attributes | ||
| 276 | 58 | stdErrPFct.addFnAttr("nounwind"); | |
| 277 | 58 | stdErrPFct.addParamAttr(0, "noundef"); | |
| 278 | 58 | stdErrPFct.addRetAttr("noundef"); | |
| 279 | 116 | return stdErrPFct; | |
| 280 | 58 | } | |
| 281 | |||
| 282 | 25818 | f<llvm::Function> StdFunctionManager.getFunction(string funcName, llvm::Type returnType, const Vector<llvm::Type>& args, bool varArg = false) { | |
| 283 | // Check if function already exists in the current module | ||
| 284 | 25818 | const llvm::Function opFct = this.module.getFunction(funcName); | |
| 285 | 25818 | if !opFct.isNull() { | |
| 286 | 19458 | return opFct; | |
| 287 | } | ||
| 288 | |||
| 289 | // Add function to the current module | ||
| 290 | 6360 | const llvm::Type opFctTy = llvm::getFunctionType(returnType, args, varArg); | |
| 291 | 6360 | return this.module.getOrInsertFunction(funcName, opFctTy); | |
| 292 | } | ||
| 293 | |||
| 294 | 523 | f<llvm::Function> StdFunctionManager.getSpiceFunction(string funcName, const QualType& returnType, const Vector<llvm::Type>& args) { | |
| 295 | // Check if function already exists in the current module | ||
| 296 | 523 | const llvm::Function existingFct = this.module.getFunction(funcName); | |
| 297 | 523 | if !existingFct.isNull() { | |
| 298 | 280 | return existingFct; | |
| 299 | } | ||
| 300 | |||
| 301 | // Add function with the return value lowered to the calling convention of the target to the current module | ||
| 302 | 243 | llvm::Function fct = this.module.getOrInsertFunction(funcName, this.irGenerator.getFunctionType(returnType, args)); | |
| 303 | 243 | const ReturnABIInfo returnABI = this.irGenerator.getReturnABIInfo(returnType); | |
| 304 | 243 | if returnABI.isIndirect() { | |
| 305 | 228 | this.irGenerator.addSRetParamAttrs(fct, returnABI.memoryType); | |
| 306 | 228 | } | |
| 307 | 243 | return fct; | |
| 308 | } | ||
| 309 | |||
| 310 | 13594 | f<llvm::Function> StdFunctionManager.getProcedure(string procName, const Vector<llvm::Type>& args) { | |
| 311 | 13594 | return this.getFunction(procName, this.builder.getVoidTy(), args, false); | |
| 312 | } | ||
| 313 | |||
| 314 | 8 | f<Vector<llvm::Type>> StdFunctionManager.getErrTraceParamTypes() { | |
| 315 | 8 | Vector<llvm::Type> paramTypes; | |
| 316 | 8 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 317 | 8 | paramTypes.pushBack(this.builder.getPtrTy()); | |
| 318 | 8 | paramTypes.pushBack(this.builder.getInt32Ty()); | |
| 319 | 8 | paramTypes.pushBack(this.builder.getInt32Ty()); | |
| 320 | 8 | return paramTypes; | |
| 321 | } | ||
| 322 | |||
| 323 | /** | ||
| 324 | * Build the parameter list (string, string, unsigned int, unsigned int) of the error trace runtime functions | ||
| 325 | * | ||
| 326 | * @return Parameter list | ||
| 327 | */ | ||
| 328 | 8 | f<model::ParamList> getErrTraceParamList() { | |
| 329 | 8 | QualType unsignedInt = QualType(SuperType::TY_INT); | |
| 330 | 8 | unsignedInt.makeUnsigned(); | |
| 331 | 8 | model::ParamList paramLst; | |
| 332 | 8 | paramLst.pushBack(model::Param{QualType(SuperType::TY_STRING), false}); | |
| 333 | 8 | paramLst.pushBack(model::Param{QualType(SuperType::TY_STRING), false}); | |
| 334 | 8 | paramLst.pushBack(model::Param{unsignedInt, false}); | |
| 335 | 8 | paramLst.pushBack(model::Param{unsignedInt, false}); | |
| 336 | 8 | return paramLst; | |
| 337 | } | ||
| 338 | |||
| 339 | /** | ||
| 340 | * Mangle a runtime function, that is known by its name and signature only | ||
| 341 | * | ||
| 342 | * @param name Function name | ||
| 343 | * @param returnType Return type | ||
| 344 | * @param paramLst Parameter list | ||
| 345 | * @return Mangled name | ||
| 346 | */ | ||
| 347 | 4137 | f<String> mangleStdFunction(string name, const QualType& returnType, const model::ParamList& paramLst) { | |
| 348 | 4137 | const Vector<GenericType> noTemplateTypes; | |
| 349 | 4137 | const model::Function function = model::Function(String(name), nil<SymbolTableEntry*>, QualType(SuperType::TY_DYN), returnType, paramLst, noTemplateTypes, nil<ASTNode*>); | |
| 350 | 8274 | return mangleFunction(function); | |
| 351 | 4137 | } | |
| 352 |