Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2021-2025 ChilliBits. All rights reserved. | ||
2 | |||
3 | #include "IRGenerator.h" | ||
4 | |||
5 | #include <llvm/IR/Module.h> | ||
6 | |||
7 | #include <SourceFile.h> | ||
8 | #include <ast/ASTNodes.h> | ||
9 | #include <ast/Attributes.h> | ||
10 | #include <driver/Driver.h> | ||
11 | #include <irgenerator/NameMangling.h> | ||
12 | #include <symboltablebuilder/SymbolTableBuilder.h> | ||
13 | |||
14 | namespace spice::compiler { | ||
15 | |||
16 | 221 | std::any IRGenerator::visitMainFctDef(const MainFctDefNode *node) { | |
17 | // Ignore main function definitions if this is not the main source file | ||
18 |
1/2✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→5) taken 221 times.
|
221 | if (!sourceFile->isMainFile) |
19 | ✗ | return nullptr; | |
20 | |||
21 | // Do not generate main function if it is explicitly specified | ||
22 |
2/2✓ Branch 0 (5→6) taken 1 times.
✓ Branch 1 (5→8) taken 220 times.
|
221 | if (cliOptions.noEntryFct) |
23 |
1/2✓ Branch 0 (6→7) taken 1 times.
✗ Branch 1 (6→129) not taken.
|
1 | return nullptr; |
24 | |||
25 | // Change scope to function scope | ||
26 | 220 | currentScope = node->bodyScope; | |
27 |
1/2✗ Branch 0 (8→9) not taken.
✓ Branch 1 (8→10) taken 220 times.
|
220 | assert(currentScope != nullptr); |
28 | |||
29 | // Visit parameters | ||
30 | 220 | std::vector<std::pair<std::string, SymbolTableEntry *>> paramInfoList; | |
31 | 220 | QualTypeList paramSymbolTypes; | |
32 | 220 | std::vector<llvm::Type *> paramTypes; | |
33 |
2/2✓ Branch 0 (10→11) taken 4 times.
✓ Branch 1 (10→34) taken 216 times.
|
220 | if (node->takesArgs) { |
34 | 4 | const size_t numOfParams = node->paramLst->params.size(); | |
35 |
1/2✓ Branch 0 (12→13) taken 4 times.
✗ Branch 1 (12→179) not taken.
|
4 | paramInfoList.reserve(numOfParams); |
36 |
1/2✓ Branch 0 (13→14) taken 4 times.
✗ Branch 1 (13→179) not taken.
|
4 | paramSymbolTypes.reserve(numOfParams); |
37 |
1/2✓ Branch 0 (14→15) taken 4 times.
✗ Branch 1 (14→179) not taken.
|
4 | paramTypes.reserve(numOfParams); |
38 |
2/2✓ Branch 0 (32→17) taken 8 times.
✓ Branch 1 (32→33) taken 4 times.
|
12 | for (DeclStmtNode *param : node->paramLst->params) { |
39 | // Get symbol table entry of param | ||
40 |
1/2✓ Branch 0 (18→19) taken 8 times.
✗ Branch 1 (18→133) not taken.
|
8 | SymbolTableEntry *paramSymbol = node->bodyScope->lookupStrict(param->varName); |
41 |
1/2✗ Branch 0 (21→22) not taken.
✓ Branch 1 (21→23) taken 8 times.
|
8 | assert(paramSymbol != nullptr); |
42 | // Retrieve type of param | ||
43 |
2/4✓ Branch 0 (23→24) taken 8 times.
✗ Branch 1 (23→132) not taken.
✓ Branch 2 (24→25) taken 8 times.
✗ Branch 3 (24→130) not taken.
|
8 | auto paramType = any_cast<llvm::Type *>(visit(param->dataType)); |
44 | // Add it to the lists | ||
45 |
1/2✓ Branch 0 (26→27) taken 8 times.
✗ Branch 1 (26→133) not taken.
|
8 | paramInfoList.emplace_back(param->varName, paramSymbol); |
46 |
2/4✓ Branch 0 (27→28) taken 8 times.
✗ Branch 1 (27→133) not taken.
✓ Branch 2 (28→29) taken 8 times.
✗ Branch 3 (28→133) not taken.
|
8 | paramSymbolTypes.push_back(paramSymbol->getQualType()); |
47 |
1/2✓ Branch 0 (29→30) taken 8 times.
✗ Branch 1 (29→133) not taken.
|
8 | paramTypes.push_back(paramType); |
48 | } | ||
49 | } | ||
50 | |||
51 | // Build the function | ||
52 |
1/2✓ Branch 0 (34→35) taken 220 times.
✗ Branch 1 (34→179) not taken.
|
220 | llvm::Type *returnType = builder.getInt32Ty(); |
53 |
1/2✓ Branch 0 (36→37) taken 220 times.
✗ Branch 1 (36→135) not taken.
|
220 | llvm::FunctionType *fctType = llvm::FunctionType::get(returnType, paramTypes, false); |
54 |
2/4✓ Branch 0 (37→38) taken 220 times.
✗ Branch 1 (37→136) not taken.
✓ Branch 2 (38→39) taken 220 times.
✗ Branch 3 (38→136) not taken.
|
220 | llvm::Function *fct = llvm::Function::Create(fctType, llvm::Function::ExternalLinkage, MAIN_FUNCTION_NAME, module); |
55 | 220 | fct->setDSOLocal(true); | |
56 | |||
57 | // Add function attributes | ||
58 |
1/2✓ Branch 0 (40→41) taken 220 times.
✗ Branch 1 (40→179) not taken.
|
220 | fct->addFnAttr(llvm::Attribute::NoInline); |
59 |
1/2✓ Branch 0 (41→42) taken 220 times.
✗ Branch 1 (41→179) not taken.
|
220 | fct->addFnAttr(llvm::Attribute::NoUnwind); |
60 |
1/2✓ Branch 0 (42→43) taken 220 times.
✗ Branch 1 (42→44) not taken.
|
220 | if (cliOptions.optLevel == OptLevel::O0) |
61 |
1/2✓ Branch 0 (43→46) taken 220 times.
✗ Branch 1 (43→179) not taken.
|
220 | fct->addFnAttr(llvm::Attribute::OptimizeNone); |
62 | ✗ | else if (cliOptions.optLevel >= OptLevel::Os) | |
63 | ✗ | fct->addFnAttr(llvm::Attribute::OptimizeForSize); | |
64 |
2/4✓ Branch 0 (46→47) taken 220 times.
✗ Branch 1 (46→179) not taken.
✓ Branch 2 (47→48) taken 220 times.
✗ Branch 3 (47→179) not taken.
|
220 | fct->addFnAttr(llvm::Attribute::getWithUWTableKind(context, llvm::UWTableKind::Default)); |
65 | |||
66 | // Add debug info | ||
67 |
2/2✓ Branch 0 (48→49) taken 2 times.
✓ Branch 1 (48→54) taken 218 times.
|
220 | if (cliOptions.generateDebugInfo) { |
68 | 2 | const auto nonConstNode = const_cast<MainFctDefNode *>(node); | |
69 |
1/2✓ Branch 0 (49→50) taken 2 times.
✗ Branch 1 (49→139) not taken.
|
2 | const Function spiceFunc = FunctionManager::createMainFunction(node->entry, paramSymbolTypes, nonConstNode); |
70 |
1/2✓ Branch 0 (50→51) taken 2 times.
✗ Branch 1 (50→137) not taken.
|
2 | diGenerator.generateFunctionDebugInfo(fct, &spiceFunc); |
71 |
1/2✓ Branch 0 (51→52) taken 2 times.
✗ Branch 1 (51→137) not taken.
|
2 | diGenerator.setSourceLocation(node); |
72 | 2 | } | |
73 | |||
74 | // Create entry block | ||
75 |
2/4✓ Branch 0 (56→57) taken 220 times.
✗ Branch 1 (56→142) not taken.
✓ Branch 2 (57→58) taken 220 times.
✗ Branch 3 (57→140) not taken.
|
220 | llvm::BasicBlock *bEntry = createBlock(); |
76 |
1/2✓ Branch 0 (60→61) taken 220 times.
✗ Branch 1 (60→179) not taken.
|
220 | switchToBlock(bEntry, fct); |
77 | |||
78 | // Reset alloca insert markers to this block | ||
79 | 220 | allocaInsertBlock = bEntry; | |
80 | 220 | allocaInsertInst = nullptr; | |
81 | |||
82 | // Allocate result variable | ||
83 |
2/4✓ Branch 0 (63→64) taken 220 times.
✗ Branch 1 (63→148) not taken.
✓ Branch 2 (64→65) taken 220 times.
✗ Branch 3 (64→146) not taken.
|
220 | llvm::Value *resultAddress = insertAlloca(returnType, RETURN_VARIABLE_NAME); |
84 | // Update the symbol table entry | ||
85 |
1/2✓ Branch 0 (69→70) taken 220 times.
✗ Branch 1 (69→154) not taken.
|
660 | SymbolTableEntry *resultEntry = currentScope->lookupStrict(RETURN_VARIABLE_NAME); |
86 |
1/2✗ Branch 0 (75→76) not taken.
✓ Branch 1 (75→77) taken 220 times.
|
220 | assert(resultEntry != nullptr); |
87 |
1/2✓ Branch 0 (77→78) taken 220 times.
✗ Branch 1 (77→179) not taken.
|
220 | resultEntry->updateAddress(resultAddress); |
88 | // Generate debug info | ||
89 |
2/4✓ Branch 0 (80→81) taken 220 times.
✗ Branch 1 (80→160) not taken.
✓ Branch 2 (81→82) taken 220 times.
✗ Branch 3 (81→158) not taken.
|
440 | diGenerator.generateLocalVarDebugInfo(RETURN_VARIABLE_NAME, resultAddress); |
90 | // Store the default result value | ||
91 |
2/4✓ Branch 0 (84→85) taken 220 times.
✗ Branch 1 (84→179) not taken.
✓ Branch 2 (85→86) taken 220 times.
✗ Branch 3 (85→179) not taken.
|
220 | insertStore(builder.getInt32(0), resultAddress); |
92 | |||
93 | // Store function argument values | ||
94 |
3/4✓ Branch 0 (86→87) taken 220 times.
✗ Branch 1 (86→170) not taken.
✓ Branch 2 (105→89) taken 8 times.
✓ Branch 3 (105→106) taken 220 times.
|
228 | for (auto &arg : fct->args()) { |
95 | // Get information about the parameter | ||
96 | 8 | const size_t argNumber = arg.getArgNo(); | |
97 |
2/4✓ Branch 0 (90→91) taken 8 times.
✗ Branch 1 (90→169) not taken.
✓ Branch 2 (91→92) taken 8 times.
✗ Branch 3 (91→169) not taken.
|
8 | auto [paramName, paramSymbol] = paramInfoList.at(argNumber); |
98 |
1/2✗ Branch 0 (94→95) not taken.
✓ Branch 1 (94→96) taken 8 times.
|
8 | assert(paramSymbol != nullptr); |
99 | // Allocate space for it | ||
100 |
1/2✓ Branch 0 (96→97) taken 8 times.
✗ Branch 1 (96→167) not taken.
|
8 | llvm::Type *paramType = fctType->getParamType(argNumber); |
101 |
2/4✓ Branch 0 (97→98) taken 8 times.
✗ Branch 1 (97→166) not taken.
✓ Branch 2 (98→99) taken 8 times.
✗ Branch 3 (98→164) not taken.
|
8 | llvm::Value *paramAddress = insertAlloca(paramType, paramName); |
102 | // Update the symbol table entry | ||
103 |
1/2✓ Branch 0 (100→101) taken 8 times.
✗ Branch 1 (100→167) not taken.
|
8 | paramSymbol->updateAddress(paramAddress); |
104 | // Store the value at the new address | ||
105 |
1/2✓ Branch 0 (101→102) taken 8 times.
✗ Branch 1 (101→167) not taken.
|
8 | insertStore(&arg, paramAddress); |
106 | // Generate debug info | ||
107 |
1/2✓ Branch 0 (102→103) taken 8 times.
✗ Branch 1 (102→167) not taken.
|
8 | diGenerator.generateLocalVarDebugInfo(paramName, paramAddress, argNumber + 1); |
108 | 8 | } | |
109 | |||
110 | // Visit function body | ||
111 |
1/2✓ Branch 0 (106→107) taken 220 times.
✗ Branch 1 (106→171) not taken.
|
220 | visit(node->body); |
112 | |||
113 | // Create return statement if the block is not terminated yet | ||
114 |
2/2✓ Branch 0 (108→109) taken 217 times.
✓ Branch 1 (108→118) taken 3 times.
|
220 | if (!blockAlreadyTerminated) { |
115 |
4/8✓ Branch 0 (111→112) taken 217 times.
✗ Branch 1 (111→174) not taken.
✓ Branch 2 (112→113) taken 217 times.
✗ Branch 3 (112→172) not taken.
✓ Branch 4 (113→114) taken 217 times.
✗ Branch 5 (113→172) not taken.
✓ Branch 6 (114→115) taken 217 times.
✗ Branch 7 (114→172) not taken.
|
217 | llvm::Value *result = insertLoad(fct->getReturnType(), resultEntry->getAddress()); |
116 |
1/2✓ Branch 0 (117→118) taken 217 times.
✗ Branch 1 (117→179) not taken.
|
217 | builder.CreateRet(result); |
117 | } | ||
118 | |||
119 | // Conclude debug info for function | ||
120 |
1/2✓ Branch 0 (118→119) taken 220 times.
✗ Branch 1 (118→179) not taken.
|
220 | diGenerator.concludeFunctionDebugInfo(); |
121 | |||
122 | // Verify function | ||
123 |
1/2✓ Branch 0 (119→120) taken 220 times.
✗ Branch 1 (119→179) not taken.
|
220 | verifyFunction(fct, node->codeLoc); |
124 | |||
125 | // Change back to root scope | ||
126 | 220 | currentScope = rootScope; | |
127 |
1/2✗ Branch 0 (120→121) not taken.
✓ Branch 1 (120→122) taken 220 times.
|
220 | assert(currentScope != nullptr); |
128 | |||
129 |
1/2✓ Branch 0 (122→123) taken 220 times.
✗ Branch 1 (122→178) not taken.
|
220 | return nullptr; |
130 | 220 | } | |
131 | |||
132 | 5541 | std::any IRGenerator::visitFctDef(const FctDefNode *node) { | |
133 | // Loop through manifestations | ||
134 | 5541 | manIdx = 0; // Reset the symbolTypeIndex | |
135 |
2/2✓ Branch 0 (230→4) taken 6950 times.
✓ Branch 1 (230→231) taken 5541 times.
|
12491 | for (Function *manifestation : node->manifestations) { |
136 |
1/2✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→7) taken 6950 times.
|
6950 | assert(manifestation->entry != nullptr); |
137 | |||
138 | // Check if the manifestation is substantiated or not public and not used by anybody | ||
139 |
2/4✓ Branch 0 (7→8) taken 6950 times.
✗ Branch 1 (7→326) not taken.
✓ Branch 2 (8→9) taken 6950 times.
✗ Branch 3 (8→326) not taken.
|
6950 | const bool isPublic = manifestation->entry->getQualType().isPublic(); |
140 |
9/10✓ Branch 0 (9→10) taken 6950 times.
✗ Branch 1 (9→326) not taken.
✓ Branch 2 (10→11) taken 5467 times.
✓ Branch 3 (10→13) taken 1483 times.
✓ Branch 4 (11→12) taken 154 times.
✓ Branch 5 (11→14) taken 5313 times.
✓ Branch 6 (12→13) taken 7 times.
✓ Branch 7 (12→14) taken 147 times.
✓ Branch 8 (15→16) taken 1490 times.
✓ Branch 9 (15→17) taken 5460 times.
|
6950 | if (!manifestation->isFullySubstantiated() || (!isPublic && !manifestation->used)) { |
141 | 1490 | manIdx++; // Increment symbolTypeIndex | |
142 | 1490 | continue; | |
143 | } | ||
144 | |||
145 | // Change to struct scope | ||
146 |
2/2✓ Branch 0 (20→21) taken 2827 times.
✓ Branch 1 (20→31) taken 2633 times.
|
5460 | if (manifestation->isMethod()) { |
147 | 2827 | const QualType &thisType = manifestation->thisType; | |
148 |
3/6✓ Branch 0 (21→22) taken 2827 times.
✗ Branch 1 (21→241) not taken.
✓ Branch 2 (22→23) taken 2827 times.
✗ Branch 3 (22→241) not taken.
✓ Branch 4 (23→24) taken 2827 times.
✗ Branch 5 (23→241) not taken.
|
2827 | const std::string signature = Struct::getSignature(thisType.getSubType(), thisType.getTemplateTypes()); |
149 |
2/4✓ Branch 0 (24→25) taken 2827 times.
✗ Branch 1 (24→238) not taken.
✓ Branch 2 (25→26) taken 2827 times.
✗ Branch 3 (25→236) not taken.
|
2827 | currentScope = currentScope->getChildScope(STRUCT_SCOPE_PREFIX + signature); |
150 |
1/2✗ Branch 0 (27→28) not taken.
✓ Branch 1 (27→29) taken 2827 times.
|
2827 | assert(currentScope != nullptr); |
151 | 2827 | } | |
152 | |||
153 | // Change scope | ||
154 |
2/4✓ Branch 0 (31→32) taken 5460 times.
✗ Branch 1 (31→244) not taken.
✓ Branch 2 (32→33) taken 5460 times.
✗ Branch 3 (32→242) not taken.
|
5460 | currentScope = currentScope->getChildScope(manifestation->getSignature(false)); |
155 |
1/2✗ Branch 0 (34→35) not taken.
✓ Branch 1 (34→36) taken 5460 times.
|
5460 | assert(currentScope != nullptr); |
156 | |||
157 | // Get 'this' entry | ||
158 | 5460 | std::vector<std::pair<std::string, SymbolTableEntry *>> paramInfoList; | |
159 | 5460 | std::vector<llvm::Type *> paramTypes; | |
160 |
1/2✓ Branch 0 (36→37) taken 5460 times.
✗ Branch 1 (36→322) not taken.
|
5460 | SymbolTableEntry *thisEntry = nullptr; |
161 |
2/2✓ Branch 0 (39→40) taken 2827 times.
✓ Branch 1 (39→54) taken 2633 times.
|
5460 | if (manifestation->isMethod()) { |
162 |
1/2✓ Branch 0 (42→43) taken 2827 times.
✗ Branch 1 (42→247) not taken.
|
8481 | thisEntry = currentScope->lookupStrict(THIS_VARIABLE_NAME); |
163 |
1/2✗ Branch 0 (48→49) not taken.
✓ Branch 1 (48→50) taken 2827 times.
|
2827 | assert(thisEntry != nullptr); |
164 |
1/2✓ Branch 0 (50→51) taken 2827 times.
✗ Branch 1 (50→322) not taken.
|
2827 | paramInfoList.emplace_back(THIS_VARIABLE_NAME, thisEntry); |
165 |
2/4✓ Branch 0 (51→52) taken 2827 times.
✗ Branch 1 (51→251) not taken.
✓ Branch 2 (52→53) taken 2827 times.
✗ Branch 3 (52→251) not taken.
|
2827 | paramTypes.push_back(builder.getPtrTy()); |
166 | } | ||
167 | |||
168 | // Visit parameters | ||
169 | 5460 | size_t argIdx = 0; | |
170 |
2/2✓ Branch 0 (54→55) taken 4232 times.
✓ Branch 1 (54→84) taken 1228 times.
|
5460 | if (node->hasParams) { |
171 | 4232 | const size_t numOfParams = manifestation->paramList.size(); | |
172 |
1/2✓ Branch 0 (56→57) taken 4232 times.
✗ Branch 1 (56→322) not taken.
|
4232 | paramInfoList.reserve(numOfParams); |
173 |
1/2✓ Branch 0 (57→58) taken 4232 times.
✗ Branch 1 (57→322) not taken.
|
4232 | paramTypes.reserve(numOfParams); |
174 |
2/2✓ Branch 0 (83→59) taken 6762 times.
✓ Branch 1 (83→84) taken 4232 times.
|
10994 | for (; argIdx < numOfParams; argIdx++) { |
175 |
1/2✓ Branch 0 (59→60) taken 6762 times.
✗ Branch 1 (59→257) not taken.
|
6762 | const DeclStmtNode *param = node->paramLst->params.at(argIdx); |
176 | // Get symbol table entry of param | ||
177 |
1/2✓ Branch 0 (60→61) taken 6762 times.
✗ Branch 1 (60→257) not taken.
|
6762 | SymbolTableEntry *paramSymbol = currentScope->lookupStrict(param->varName); |
178 |
1/2✗ Branch 0 (63→64) not taken.
✓ Branch 1 (63→65) taken 6762 times.
|
6762 | assert(paramSymbol != nullptr); |
179 |
2/4✓ Branch 0 (65→66) taken 6762 times.
✗ Branch 1 (65→254) not taken.
✓ Branch 2 (66→67) taken 6762 times.
✗ Branch 3 (66→252) not taken.
|
6762 | const QualType paramSymbolType = manifestation->getParamTypes().at(argIdx); |
180 | // Pass the information if captures are taken for function/procedure types | ||
181 |
6/10✓ Branch 0 (68→69) taken 6762 times.
✗ Branch 1 (68→255) not taken.
✓ Branch 2 (69→70) taken 25 times.
✓ Branch 3 (69→73) taken 6737 times.
✓ Branch 4 (70→71) taken 25 times.
✗ Branch 5 (70→255) not taken.
✗ Branch 6 (71→72) not taken.
✓ Branch 7 (71→73) taken 25 times.
✗ Branch 8 (74→75) not taken.
✓ Branch 9 (74→79) taken 6762 times.
|
6762 | if (paramSymbolType.isOneOf({TY_FUNCTION, TY_PROCEDURE}) && paramSymbolType.hasLambdaCaptures()) |
182 | ✗ | paramSymbol->updateType(paramSymbol->getQualType().getWithLambdaCaptures(), true); | |
183 | // Retrieve type of param | ||
184 |
1/2✓ Branch 0 (79→80) taken 6762 times.
✗ Branch 1 (79→257) not taken.
|
6762 | llvm::Type *paramType = paramSymbolType.toLLVMType(sourceFile); |
185 | // Add it to the lists | ||
186 |
1/2✓ Branch 0 (80→81) taken 6762 times.
✗ Branch 1 (80→257) not taken.
|
6762 | paramInfoList.emplace_back(param->varName, paramSymbol); |
187 |
1/2✓ Branch 0 (81→82) taken 6762 times.
✗ Branch 1 (81→257) not taken.
|
6762 | paramTypes.push_back(paramType); |
188 | } | ||
189 | } | ||
190 | |||
191 | // Get return type | ||
192 |
1/2✓ Branch 0 (84→85) taken 5460 times.
✗ Branch 1 (84→322) not taken.
|
5460 | llvm::Type *returnType = manifestation->returnType.toLLVMType(sourceFile); |
193 | |||
194 | // Check if function is explicitly inlined | ||
195 |
2/4✓ Branch 0 (85→86) taken 5460 times.
✗ Branch 1 (85→322) not taken.
✓ Branch 2 (86→87) taken 5460 times.
✗ Branch 3 (86→322) not taken.
|
5460 | const bool explicitlyInlined = manifestation->entry->getQualType().isInline(); |
196 | // Get function linkage | ||
197 | 5460 | bool externalLinkage = isPublic; | |
198 |
12/18✓ Branch 0 (87→88) taken 360 times.
✓ Branch 1 (87→94) taken 5100 times.
✓ Branch 2 (90→91) taken 360 times.
✗ Branch 3 (90→258) not taken.
✓ Branch 4 (91→92) taken 360 times.
✗ Branch 5 (91→258) not taken.
✓ Branch 6 (92→93) taken 10 times.
✓ Branch 7 (92→94) taken 350 times.
✓ Branch 8 (95→96) taken 360 times.
✓ Branch 9 (95→97) taken 5100 times.
✓ Branch 10 (97→98) taken 360 times.
✓ Branch 11 (97→100) taken 5100 times.
✓ Branch 12 (100→101) taken 10 times.
✓ Branch 13 (100→108) taken 5450 times.
✗ Branch 14 (258→259) not taken.
✗ Branch 15 (258→260) not taken.
✗ Branch 16 (262→263) not taken.
✗ Branch 17 (262→265) not taken.
|
6180 | if (node->attrs && node->attrs->attrLst->hasAttr(ATTR_TEST)) |
199 |
2/4✓ Branch 0 (103→104) taken 10 times.
✗ Branch 1 (103→269) not taken.
✓ Branch 2 (104→105) taken 10 times.
✗ Branch 3 (104→267) not taken.
|
30 | externalLinkage |= node->attrs->attrLst->getAttrValueByName(ATTR_TEST)->boolValue; |
200 |
2/2✓ Branch 0 (108→109) taken 5321 times.
✓ Branch 1 (108→110) taken 139 times.
|
5460 | const llvm::GlobalValue::LinkageTypes linkage = externalLinkage ? llvm::Function::ExternalLinkage : llvm::Function::PrivateLinkage; |
201 | |||
202 | // Create function or implement declared function | ||
203 |
1/2✓ Branch 0 (111→112) taken 5460 times.
✗ Branch 1 (111→322) not taken.
|
5460 | const std::string mangledName = manifestation->getMangledName(); |
204 |
1/2✓ Branch 0 (113→114) taken 5460 times.
✗ Branch 1 (113→273) not taken.
|
5460 | llvm::FunctionType *funcType = llvm::FunctionType::get(returnType, paramTypes, false); |
205 |
1/2✓ Branch 0 (115→116) taken 5460 times.
✗ Branch 1 (115→274) not taken.
|
5460 | module->getOrInsertFunction(mangledName, funcType); |
206 |
1/2✓ Branch 0 (117→118) taken 5460 times.
✗ Branch 1 (117→275) not taken.
|
5460 | llvm::Function *func = module->getFunction(mangledName); |
207 |
1/2✓ Branch 0 (118→119) taken 5460 times.
✗ Branch 1 (118→320) not taken.
|
5460 | node->entry->updateAddress(func); |
208 | 5460 | manifestation->llvmFunction = func; | |
209 |
2/4✓ Branch 0 (119→120) taken 5460 times.
✗ Branch 1 (119→320) not taken.
✗ Branch 2 (120→121) not taken.
✓ Branch 3 (120→122) taken 5460 times.
|
5460 | assert(func->empty()); |
210 | |||
211 | // Set attributes to function | ||
212 | 5460 | func->setDSOLocal(true); | |
213 |
1/2✓ Branch 0 (123→124) taken 5460 times.
✗ Branch 1 (123→320) not taken.
|
5460 | func->setLinkage(linkage); |
214 |
2/2✓ Branch 0 (124→125) taken 2007 times.
✓ Branch 1 (124→126) taken 3453 times.
|
5460 | if (explicitlyInlined) |
215 |
1/2✓ Branch 0 (125→126) taken 2007 times.
✗ Branch 1 (125→320) not taken.
|
2007 | func->addFnAttr(llvm::Attribute::AlwaysInline); |
216 | |||
217 | // Set attributes to 'this' param | ||
218 |
2/2✓ Branch 0 (129→130) taken 2827 times.
✓ Branch 1 (129→147) taken 2633 times.
|
5460 | if (manifestation->isMethod()) { |
219 |
1/2✓ Branch 0 (130→131) taken 2827 times.
✗ Branch 1 (130→320) not taken.
|
2827 | func->addParamAttr(0, llvm::Attribute::NoUndef); |
220 |
1/2✓ Branch 0 (131→132) taken 2827 times.
✗ Branch 1 (131→320) not taken.
|
2827 | func->addParamAttr(0, llvm::Attribute::NonNull); |
221 |
1/2✗ Branch 0 (132→133) not taken.
✓ Branch 1 (132→134) taken 2827 times.
|
2827 | assert(thisEntry != nullptr); |
222 |
3/6✓ Branch 0 (134→135) taken 2827 times.
✗ Branch 1 (134→276) not taken.
✓ Branch 2 (135→136) taken 2827 times.
✗ Branch 3 (135→276) not taken.
✓ Branch 4 (136→137) taken 2827 times.
✗ Branch 5 (136→276) not taken.
|
2827 | llvm::Type *structType = thisEntry->getQualType().getContained().toLLVMType(sourceFile); |
223 |
1/2✗ Branch 0 (137→138) not taken.
✓ Branch 1 (137→139) taken 2827 times.
|
2827 | assert(structType != nullptr); |
224 |
3/6✓ Branch 0 (140→141) taken 2827 times.
✗ Branch 1 (140→277) not taken.
✓ Branch 2 (141→142) taken 2827 times.
✗ Branch 3 (141→277) not taken.
✓ Branch 4 (142→143) taken 2827 times.
✗ Branch 5 (142→277) not taken.
|
2827 | func->addDereferenceableParamAttr(0, module->getDataLayout().getTypeStoreSize(structType)); |
225 |
3/6✓ Branch 0 (144→145) taken 2827 times.
✗ Branch 1 (144→320) not taken.
✓ Branch 2 (145→146) taken 2827 times.
✗ Branch 3 (145→320) not taken.
✓ Branch 4 (146→147) taken 2827 times.
✗ Branch 5 (146→320) not taken.
|
2827 | func->addParamAttr(0, llvm::Attribute::getWithAlignment(context, module->getDataLayout().getABITypeAlign(structType))); |
226 | } | ||
227 | |||
228 | // Add debug info | ||
229 |
1/2✓ Branch 0 (147→148) taken 5460 times.
✗ Branch 1 (147→320) not taken.
|
5460 | diGenerator.generateFunctionDebugInfo(func, manifestation); |
230 |
1/2✓ Branch 0 (148→149) taken 5460 times.
✗ Branch 1 (148→320) not taken.
|
5460 | diGenerator.setSourceLocation(node); |
231 | |||
232 | // Create entry block | ||
233 |
2/4✓ Branch 0 (151→152) taken 5460 times.
✗ Branch 1 (151→280) not taken.
✓ Branch 2 (152→153) taken 5460 times.
✗ Branch 3 (152→278) not taken.
|
5460 | llvm::BasicBlock *bEntry = createBlock(); |
234 |
1/2✓ Branch 0 (155→156) taken 5460 times.
✗ Branch 1 (155→320) not taken.
|
5460 | switchToBlock(bEntry, func); |
235 | |||
236 | // Reset alloca insert markers to this block | ||
237 | 5460 | allocaInsertBlock = bEntry; | |
238 | 5460 | allocaInsertInst = nullptr; | |
239 | |||
240 | // Declare result variable | ||
241 |
2/4✓ Branch 0 (158→159) taken 5460 times.
✗ Branch 1 (158→286) not taken.
✓ Branch 2 (159→160) taken 5460 times.
✗ Branch 3 (159→284) not taken.
|
5460 | llvm::Value *resultAddr = insertAlloca(returnType, RETURN_VARIABLE_NAME); |
242 |
1/2✓ Branch 0 (164→165) taken 5460 times.
✗ Branch 1 (164→292) not taken.
|
16380 | SymbolTableEntry *resultEntry = currentScope->lookupStrict(RETURN_VARIABLE_NAME); |
243 |
1/2✗ Branch 0 (170→171) not taken.
✓ Branch 1 (170→172) taken 5460 times.
|
5460 | assert(resultEntry != nullptr); |
244 |
1/2✓ Branch 0 (172→173) taken 5460 times.
✗ Branch 1 (172→320) not taken.
|
5460 | resultEntry->updateAddress(resultAddr); |
245 | // Generate debug info | ||
246 |
2/4✓ Branch 0 (175→176) taken 5460 times.
✗ Branch 1 (175→298) not taken.
✓ Branch 2 (176→177) taken 5460 times.
✗ Branch 3 (176→296) not taken.
|
10920 | diGenerator.generateLocalVarDebugInfo(RETURN_VARIABLE_NAME, resultAddr); |
247 | |||
248 | // Store function argument values | ||
249 |
3/4✓ Branch 0 (179→180) taken 5460 times.
✗ Branch 1 (179→308) not taken.
✓ Branch 2 (199→182) taken 9589 times.
✓ Branch 3 (199→200) taken 5460 times.
|
15049 | for (auto &arg : func->args()) { |
250 | // Get information about the parameter | ||
251 | 9589 | const size_t argNumber = arg.getArgNo(); | |
252 |
2/4✓ Branch 0 (183→184) taken 9589 times.
✗ Branch 1 (183→307) not taken.
✓ Branch 2 (184→185) taken 9589 times.
✗ Branch 3 (184→307) not taken.
|
9589 | auto [paramName, paramSymbol] = paramInfoList.at(argNumber); |
253 |
1/2✗ Branch 0 (187→188) not taken.
✓ Branch 1 (187→189) taken 9589 times.
|
9589 | assert(paramSymbol != nullptr); |
254 | // Allocate space for it | ||
255 |
1/2✓ Branch 0 (189→190) taken 9589 times.
✗ Branch 1 (189→305) not taken.
|
9589 | llvm::Type *paramType = funcType->getParamType(argNumber); |
256 |
2/4✓ Branch 0 (190→191) taken 9589 times.
✗ Branch 1 (190→304) not taken.
✓ Branch 2 (191→192) taken 9589 times.
✗ Branch 3 (191→302) not taken.
|
9589 | llvm::Value *paramAddress = insertAlloca(paramType, paramName); |
257 | // Update the symbol table entry | ||
258 |
1/2✓ Branch 0 (193→194) taken 9589 times.
✗ Branch 1 (193→305) not taken.
|
9589 | paramSymbol->updateAddress(paramAddress); |
259 | // Set source location | ||
260 |
1/2✓ Branch 0 (194→195) taken 9589 times.
✗ Branch 1 (194→305) not taken.
|
9589 | diGenerator.setSourceLocation(paramSymbol->declNode); |
261 | // Store the value at the new address | ||
262 |
1/2✓ Branch 0 (195→196) taken 9589 times.
✗ Branch 1 (195→305) not taken.
|
9589 | insertStore(&arg, paramAddress); |
263 | // Generate debug info to declare variable | ||
264 |
1/2✓ Branch 0 (196→197) taken 9589 times.
✗ Branch 1 (196→305) not taken.
|
9589 | diGenerator.generateLocalVarDebugInfo(paramName, paramAddress, argNumber + 1); |
265 | 9589 | } | |
266 | |||
267 | // Store the default values for optional function args | ||
268 |
2/2✓ Branch 0 (200→201) taken 4232 times.
✓ Branch 1 (200→211) taken 1228 times.
|
5460 | if (node->paramLst) { |
269 |
1/2✓ Branch 0 (201→202) taken 4232 times.
✗ Branch 1 (201→312) not taken.
|
4232 | const std::vector<DeclStmtNode *> params = node->paramLst->params; |
270 |
2/2✓ Branch 0 (208→203) taken 480 times.
✓ Branch 1 (208→209) taken 4232 times.
|
4712 | for (; argIdx < params.size(); argIdx++) |
271 |
2/4✓ Branch 0 (203→204) taken 480 times.
✗ Branch 1 (203→309) not taken.
✓ Branch 2 (204→205) taken 480 times.
✗ Branch 3 (204→309) not taken.
|
480 | visit(params.at(argIdx)); |
272 | 4232 | } | |
273 | |||
274 | // Visit function body | ||
275 |
1/2✓ Branch 0 (211→212) taken 5460 times.
✗ Branch 1 (211→313) not taken.
|
5460 | visit(node->body); |
276 | |||
277 | // Create return statement if the block is not terminated yet | ||
278 |
2/2✓ Branch 0 (213→214) taken 191 times.
✓ Branch 1 (213→222) taken 5269 times.
|
5460 | if (!blockAlreadyTerminated) { |
279 |
3/6✓ Branch 0 (216→217) taken 191 times.
✗ Branch 1 (216→316) not taken.
✓ Branch 2 (217→218) taken 191 times.
✗ Branch 3 (217→314) not taken.
✓ Branch 4 (218→219) taken 191 times.
✗ Branch 5 (218→314) not taken.
|
191 | llvm::Value *result = insertLoad(returnType, resultEntry->getAddress()); |
280 |
1/2✓ Branch 0 (221→222) taken 191 times.
✗ Branch 1 (221→320) not taken.
|
191 | builder.CreateRet(result); |
281 | } | ||
282 | |||
283 | // Conclude debug info for function | ||
284 |
1/2✓ Branch 0 (222→223) taken 5460 times.
✗ Branch 1 (222→320) not taken.
|
5460 | diGenerator.concludeFunctionDebugInfo(); |
285 | |||
286 | // Verify function | ||
287 |
1/2✓ Branch 0 (223→224) taken 5460 times.
✗ Branch 1 (223→320) not taken.
|
5460 | verifyFunction(func, node->codeLoc); |
288 | |||
289 | // Change to root scope | ||
290 | 5460 | currentScope = rootScope; | |
291 | |||
292 | 5460 | manIdx++; // Increment symbolTypeIndex | |
293 | 5460 | } | |
294 | 5541 | manIdx = 0; // Reset the symbolTypeIndex | |
295 | |||
296 | // Ensure that we are at the root scope again | ||
297 |
1/2✗ Branch 0 (231→232) not taken.
✓ Branch 1 (231→233) taken 5541 times.
|
5541 | assert(currentScope == rootScope); |
298 | |||
299 |
1/2✓ Branch 0 (233→234) taken 5541 times.
✗ Branch 1 (233→328) not taken.
|
5541 | return nullptr; |
300 | } | ||
301 | |||
302 | 2721 | std::any IRGenerator::visitProcDef(const ProcDefNode *node) { | |
303 | // Loop through manifestations | ||
304 | 2721 | manIdx = 0; // Reset the symbolTypeIndex | |
305 |
2/2✓ Branch 0 (183→4) taken 3584 times.
✓ Branch 1 (183→184) taken 2721 times.
|
6305 | for (Function *manifestation : node->manifestations) { |
306 |
1/2✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→7) taken 3584 times.
|
3584 | assert(manifestation->entry != nullptr); |
307 | |||
308 | // Check if the manifestation is substantiated or not public and not used by anybody | ||
309 |
2/4✓ Branch 0 (7→8) taken 3584 times.
✗ Branch 1 (7→240) not taken.
✓ Branch 2 (8→9) taken 3584 times.
✗ Branch 3 (8→240) not taken.
|
3584 | const bool isPublic = manifestation->entry->getQualType().isPublic(); |
310 |
9/10✓ Branch 0 (9→10) taken 3584 times.
✗ Branch 1 (9→240) not taken.
✓ Branch 2 (10→11) taken 2455 times.
✓ Branch 3 (10→13) taken 1129 times.
✓ Branch 4 (11→12) taken 274 times.
✓ Branch 5 (11→14) taken 2181 times.
✓ Branch 6 (12→13) taken 8 times.
✓ Branch 7 (12→14) taken 266 times.
✓ Branch 8 (15→16) taken 1137 times.
✓ Branch 9 (15→17) taken 2447 times.
|
3584 | if (!manifestation->isFullySubstantiated() || (!isPublic && !manifestation->used)) { |
311 | 1137 | manIdx++; // Increment symbolTypeIndex | |
312 | 1137 | continue; | |
313 | } | ||
314 |
1/2✗ Branch 0 (17→18) not taken.
✓ Branch 1 (17→19) taken 2447 times.
|
2447 | assert(manifestation->alreadyTypeChecked); |
315 | |||
316 | // Change to struct scope | ||
317 |
2/2✓ Branch 0 (22→23) taken 2250 times.
✓ Branch 1 (22→33) taken 197 times.
|
2447 | if (manifestation->isMethod()) { |
318 | 2250 | const QualType &thisType = manifestation->thisType; | |
319 |
3/6✓ Branch 0 (23→24) taken 2250 times.
✗ Branch 1 (23→194) not taken.
✓ Branch 2 (24→25) taken 2250 times.
✗ Branch 3 (24→194) not taken.
✓ Branch 4 (25→26) taken 2250 times.
✗ Branch 5 (25→194) not taken.
|
2250 | const std::string signature = Struct::getSignature(thisType.getSubType(), thisType.getTemplateTypes()); |
320 |
2/4✓ Branch 0 (26→27) taken 2250 times.
✗ Branch 1 (26→191) not taken.
✓ Branch 2 (27→28) taken 2250 times.
✗ Branch 3 (27→189) not taken.
|
2250 | currentScope = currentScope->getChildScope(STRUCT_SCOPE_PREFIX + signature); |
321 |
1/2✗ Branch 0 (29→30) not taken.
✓ Branch 1 (29→31) taken 2250 times.
|
2250 | assert(currentScope != nullptr); |
322 | 2250 | } | |
323 | |||
324 | // Change scope | ||
325 |
2/4✓ Branch 0 (33→34) taken 2447 times.
✗ Branch 1 (33→197) not taken.
✓ Branch 2 (34→35) taken 2447 times.
✗ Branch 3 (34→195) not taken.
|
2447 | currentScope = currentScope->getChildScope(manifestation->getSignature(false)); |
326 |
1/2✗ Branch 0 (36→37) not taken.
✓ Branch 1 (36→38) taken 2447 times.
|
2447 | assert(currentScope != nullptr); |
327 | |||
328 | // Get 'this' entry | ||
329 | 2447 | std::vector<std::pair<std::string, SymbolTableEntry *>> paramInfoList; | |
330 | 2447 | std::vector<llvm::Type *> paramTypes; | |
331 |
1/2✓ Branch 0 (38→39) taken 2447 times.
✗ Branch 1 (38→236) not taken.
|
2447 | SymbolTableEntry *thisEntry = nullptr; |
332 |
2/2✓ Branch 0 (41→42) taken 2250 times.
✓ Branch 1 (41→56) taken 197 times.
|
2447 | if (manifestation->isMethod()) { |
333 |
1/2✓ Branch 0 (44→45) taken 2250 times.
✗ Branch 1 (44→200) not taken.
|
6750 | thisEntry = currentScope->lookupStrict(THIS_VARIABLE_NAME); |
334 |
1/2✗ Branch 0 (50→51) not taken.
✓ Branch 1 (50→52) taken 2250 times.
|
2250 | assert(thisEntry != nullptr); |
335 |
1/2✓ Branch 0 (52→53) taken 2250 times.
✗ Branch 1 (52→236) not taken.
|
2250 | paramInfoList.emplace_back(THIS_VARIABLE_NAME, thisEntry); |
336 |
2/4✓ Branch 0 (53→54) taken 2250 times.
✗ Branch 1 (53→204) not taken.
✓ Branch 2 (54→55) taken 2250 times.
✗ Branch 3 (54→204) not taken.
|
2250 | paramTypes.push_back(builder.getPtrTy()); |
337 | } | ||
338 | |||
339 | // Visit parameters | ||
340 | 2447 | size_t argIdx = 0; | |
341 |
2/2✓ Branch 0 (56→57) taken 1700 times.
✓ Branch 1 (56→86) taken 747 times.
|
2447 | if (node->hasParams) { |
342 | 1700 | const size_t numOfParams = manifestation->paramList.size(); | |
343 |
1/2✓ Branch 0 (58→59) taken 1700 times.
✗ Branch 1 (58→236) not taken.
|
1700 | paramInfoList.reserve(numOfParams); |
344 |
1/2✓ Branch 0 (59→60) taken 1700 times.
✗ Branch 1 (59→236) not taken.
|
1700 | paramTypes.reserve(numOfParams); |
345 |
2/2✓ Branch 0 (85→61) taken 1935 times.
✓ Branch 1 (85→86) taken 1700 times.
|
3635 | for (; argIdx < numOfParams; argIdx++) { |
346 |
1/2✓ Branch 0 (61→62) taken 1935 times.
✗ Branch 1 (61→210) not taken.
|
1935 | const DeclStmtNode *param = node->paramLst->params.at(argIdx); |
347 | // Get symbol table entry of param | ||
348 |
1/2✓ Branch 0 (62→63) taken 1935 times.
✗ Branch 1 (62→210) not taken.
|
1935 | SymbolTableEntry *paramSymbol = currentScope->lookupStrict(param->varName); |
349 |
1/2✗ Branch 0 (65→66) not taken.
✓ Branch 1 (65→67) taken 1935 times.
|
1935 | assert(paramSymbol != nullptr); |
350 |
2/4✓ Branch 0 (67→68) taken 1935 times.
✗ Branch 1 (67→207) not taken.
✓ Branch 2 (68→69) taken 1935 times.
✗ Branch 3 (68→205) not taken.
|
1935 | const QualType paramSymbolType = manifestation->getParamTypes().at(argIdx); |
351 | // Pass the information if captures are taken for function/procedure types | ||
352 |
8/10✓ Branch 0 (70→71) taken 1935 times.
✗ Branch 1 (70→208) not taken.
✓ Branch 2 (71→72) taken 20 times.
✓ Branch 3 (71→75) taken 1915 times.
✓ Branch 4 (72→73) taken 20 times.
✗ Branch 5 (72→208) not taken.
✓ Branch 6 (73→74) taken 3 times.
✓ Branch 7 (73→75) taken 17 times.
✓ Branch 8 (76→77) taken 3 times.
✓ Branch 9 (76→81) taken 1932 times.
|
1935 | if (paramSymbolType.isOneOf({TY_FUNCTION, TY_PROCEDURE}) && paramSymbolType.hasLambdaCaptures()) |
353 |
3/6✓ Branch 0 (77→78) taken 3 times.
✗ Branch 1 (77→209) not taken.
✓ Branch 2 (78→79) taken 3 times.
✗ Branch 3 (78→209) not taken.
✓ Branch 4 (79→80) taken 3 times.
✗ Branch 5 (79→209) not taken.
|
3 | paramSymbol->updateType(paramSymbol->getQualType().getWithLambdaCaptures(), true); |
354 | // Retrieve type of param | ||
355 |
1/2✓ Branch 0 (81→82) taken 1935 times.
✗ Branch 1 (81→210) not taken.
|
1935 | llvm::Type *paramType = paramSymbolType.toLLVMType(sourceFile); |
356 | // Add it to the lists | ||
357 |
1/2✓ Branch 0 (82→83) taken 1935 times.
✗ Branch 1 (82→210) not taken.
|
1935 | paramInfoList.emplace_back(param->varName, paramSymbol); |
358 |
1/2✓ Branch 0 (83→84) taken 1935 times.
✗ Branch 1 (83→210) not taken.
|
1935 | paramTypes.push_back(paramType); |
359 | } | ||
360 | } | ||
361 | |||
362 | // Get return type | ||
363 |
1/2✓ Branch 0 (86→87) taken 2447 times.
✗ Branch 1 (86→236) not taken.
|
2447 | llvm::Type *returnType = builder.getVoidTy(); |
364 | |||
365 | // Check if procedure is explicitly inlined | ||
366 |
2/4✓ Branch 0 (87→88) taken 2447 times.
✗ Branch 1 (87→236) not taken.
✓ Branch 2 (88→89) taken 2447 times.
✗ Branch 3 (88→236) not taken.
|
2447 | const bool explicitlyInlined = manifestation->entry->getQualType().isInline(); |
367 | // Get procedure linkage | ||
368 |
2/2✓ Branch 0 (89→90) taken 2181 times.
✓ Branch 1 (89→91) taken 266 times.
|
2447 | const llvm::GlobalValue::LinkageTypes linkage = isPublic ? llvm::Function::ExternalLinkage : llvm::Function::PrivateLinkage; |
369 | |||
370 | // Create procedure or implement declared procedure | ||
371 |
1/2✓ Branch 0 (92→93) taken 2447 times.
✗ Branch 1 (92→236) not taken.
|
2447 | const std::string mangledName = manifestation->getMangledName(); |
372 |
1/2✓ Branch 0 (94→95) taken 2447 times.
✗ Branch 1 (94→211) not taken.
|
2447 | llvm::FunctionType *procType = llvm::FunctionType::get(returnType, paramTypes, false); |
373 |
1/2✓ Branch 0 (96→97) taken 2447 times.
✗ Branch 1 (96→212) not taken.
|
2447 | module->getOrInsertFunction(mangledName, procType); |
374 |
1/2✓ Branch 0 (98→99) taken 2447 times.
✗ Branch 1 (98→213) not taken.
|
2447 | llvm::Function *proc = module->getFunction(mangledName); |
375 |
1/2✓ Branch 0 (99→100) taken 2447 times.
✗ Branch 1 (99→234) not taken.
|
2447 | node->entry->updateAddress(proc); |
376 | 2447 | manifestation->llvmFunction = proc; | |
377 |
2/4✓ Branch 0 (100→101) taken 2447 times.
✗ Branch 1 (100→234) not taken.
✗ Branch 2 (101→102) not taken.
✓ Branch 3 (101→103) taken 2447 times.
|
2447 | assert(proc->empty()); |
378 | |||
379 | // Set attributes to procedure | ||
380 | 2447 | proc->setDSOLocal(true); | |
381 |
1/2✓ Branch 0 (104→105) taken 2447 times.
✗ Branch 1 (104→234) not taken.
|
2447 | proc->setLinkage(linkage); |
382 |
2/2✓ Branch 0 (105→106) taken 213 times.
✓ Branch 1 (105→107) taken 2234 times.
|
2447 | if (explicitlyInlined) |
383 |
1/2✓ Branch 0 (106→107) taken 213 times.
✗ Branch 1 (106→234) not taken.
|
213 | proc->addFnAttr(llvm::Attribute::AlwaysInline); |
384 | |||
385 | // Set attributes to 'this' param | ||
386 |
2/2✓ Branch 0 (110→111) taken 2250 times.
✓ Branch 1 (110→128) taken 197 times.
|
2447 | if (manifestation->isMethod()) { |
387 |
1/2✓ Branch 0 (111→112) taken 2250 times.
✗ Branch 1 (111→234) not taken.
|
2250 | proc->addParamAttr(0, llvm::Attribute::NoUndef); |
388 |
1/2✓ Branch 0 (112→113) taken 2250 times.
✗ Branch 1 (112→234) not taken.
|
2250 | proc->addParamAttr(0, llvm::Attribute::NonNull); |
389 |
1/2✗ Branch 0 (113→114) not taken.
✓ Branch 1 (113→115) taken 2250 times.
|
2250 | assert(thisEntry != nullptr); |
390 |
3/6✓ Branch 0 (115→116) taken 2250 times.
✗ Branch 1 (115→214) not taken.
✓ Branch 2 (116→117) taken 2250 times.
✗ Branch 3 (116→214) not taken.
✓ Branch 4 (117→118) taken 2250 times.
✗ Branch 5 (117→214) not taken.
|
2250 | llvm::Type *structType = thisEntry->getQualType().getContained().toLLVMType(sourceFile); |
391 |
1/2✗ Branch 0 (118→119) not taken.
✓ Branch 1 (118→120) taken 2250 times.
|
2250 | assert(structType != nullptr); |
392 |
3/6✓ Branch 0 (121→122) taken 2250 times.
✗ Branch 1 (121→215) not taken.
✓ Branch 2 (122→123) taken 2250 times.
✗ Branch 3 (122→215) not taken.
✓ Branch 4 (123→124) taken 2250 times.
✗ Branch 5 (123→215) not taken.
|
2250 | proc->addDereferenceableParamAttr(0, module->getDataLayout().getTypeStoreSize(structType)); |
393 |
3/6✓ Branch 0 (125→126) taken 2250 times.
✗ Branch 1 (125→234) not taken.
✓ Branch 2 (126→127) taken 2250 times.
✗ Branch 3 (126→234) not taken.
✓ Branch 4 (127→128) taken 2250 times.
✗ Branch 5 (127→234) not taken.
|
2250 | proc->addParamAttr(0, llvm::Attribute::getWithAlignment(context, module->getDataLayout().getABITypeAlign(structType))); |
394 | } | ||
395 | |||
396 | // Add debug info | ||
397 |
1/2✓ Branch 0 (128→129) taken 2447 times.
✗ Branch 1 (128→234) not taken.
|
2447 | diGenerator.generateFunctionDebugInfo(proc, manifestation); |
398 |
1/2✓ Branch 0 (129→130) taken 2447 times.
✗ Branch 1 (129→234) not taken.
|
2447 | diGenerator.setSourceLocation(node); |
399 | |||
400 | // Create entry block | ||
401 |
2/4✓ Branch 0 (132→133) taken 2447 times.
✗ Branch 1 (132→218) not taken.
✓ Branch 2 (133→134) taken 2447 times.
✗ Branch 3 (133→216) not taken.
|
2447 | llvm::BasicBlock *bEntry = createBlock(); |
402 |
1/2✓ Branch 0 (136→137) taken 2447 times.
✗ Branch 1 (136→234) not taken.
|
2447 | switchToBlock(bEntry, proc); |
403 | |||
404 | // Reset alloca insert markers to this block | ||
405 | 2447 | allocaInsertBlock = bEntry; | |
406 | 2447 | allocaInsertInst = nullptr; | |
407 | |||
408 | // Store procedure argument values | ||
409 |
3/4✓ Branch 0 (137→138) taken 2447 times.
✗ Branch 1 (137→228) not taken.
✓ Branch 2 (157→140) taken 4185 times.
✓ Branch 3 (157→158) taken 2447 times.
|
6632 | for (auto &arg : proc->args()) { |
410 | // Get information about the parameter | ||
411 | 4185 | const size_t argNumber = arg.getArgNo(); | |
412 |
2/4✓ Branch 0 (141→142) taken 4185 times.
✗ Branch 1 (141→227) not taken.
✓ Branch 2 (142→143) taken 4185 times.
✗ Branch 3 (142→227) not taken.
|
4185 | auto [paramName, paramSymbol] = paramInfoList.at(argNumber); |
413 |
1/2✗ Branch 0 (145→146) not taken.
✓ Branch 1 (145→147) taken 4185 times.
|
4185 | assert(paramSymbol != nullptr); |
414 | // Allocate space for it | ||
415 |
1/2✓ Branch 0 (147→148) taken 4185 times.
✗ Branch 1 (147→225) not taken.
|
4185 | llvm::Type *paramType = procType->getParamType(argNumber); |
416 |
2/4✓ Branch 0 (148→149) taken 4185 times.
✗ Branch 1 (148→224) not taken.
✓ Branch 2 (149→150) taken 4185 times.
✗ Branch 3 (149→222) not taken.
|
4185 | llvm::Value *paramAddress = insertAlloca(paramType, paramName); |
417 | // Update the symbol table entry | ||
418 |
1/2✓ Branch 0 (151→152) taken 4185 times.
✗ Branch 1 (151→225) not taken.
|
4185 | paramSymbol->updateAddress(paramAddress); |
419 | // Set source location | ||
420 |
1/2✓ Branch 0 (152→153) taken 4185 times.
✗ Branch 1 (152→225) not taken.
|
4185 | diGenerator.setSourceLocation(paramSymbol->declNode); |
421 | // Store the value at the new address | ||
422 |
1/2✓ Branch 0 (153→154) taken 4185 times.
✗ Branch 1 (153→225) not taken.
|
4185 | insertStore(&arg, paramAddress); |
423 | // Generate debug info to declare variable | ||
424 |
1/2✓ Branch 0 (154→155) taken 4185 times.
✗ Branch 1 (154→225) not taken.
|
4185 | diGenerator.generateLocalVarDebugInfo(paramName, paramAddress, argNumber + 1); |
425 | 4185 | } | |
426 | |||
427 | // Store the default values for optional procedure args | ||
428 |
2/2✓ Branch 0 (158→159) taken 1700 times.
✓ Branch 1 (158→169) taken 747 times.
|
2447 | if (node->paramLst) { |
429 |
1/2✓ Branch 0 (159→160) taken 1700 times.
✗ Branch 1 (159→232) not taken.
|
1700 | const std::vector<DeclStmtNode *> params = node->paramLst->params; |
430 |
2/2✓ Branch 0 (166→161) taken 141 times.
✓ Branch 1 (166→167) taken 1700 times.
|
1841 | for (; argIdx < params.size(); argIdx++) |
431 |
2/4✓ Branch 0 (161→162) taken 141 times.
✗ Branch 1 (161→229) not taken.
✓ Branch 2 (162→163) taken 141 times.
✗ Branch 3 (162→229) not taken.
|
141 | visit(params.at(argIdx)); |
432 | 1700 | } | |
433 | |||
434 | // Generate special ctor preamble before generating the body to store VTable, default field values, etc. if required | ||
435 |
2/2✓ Branch 0 (169→170) taken 1057 times.
✓ Branch 1 (169→171) taken 1390 times.
|
2447 | if (node->isCtor) |
436 |
1/2✓ Branch 0 (170→171) taken 1057 times.
✗ Branch 1 (170→234) not taken.
|
1057 | generateCtorBodyPreamble(currentScope); |
437 | |||
438 | // Visit procedure body | ||
439 |
1/2✓ Branch 0 (171→172) taken 2447 times.
✗ Branch 1 (171→233) not taken.
|
2447 | visit(node->body); |
440 | |||
441 | // Create return statement if the block is not terminated yet | ||
442 |
2/2✓ Branch 0 (173→174) taken 2363 times.
✓ Branch 1 (173→175) taken 84 times.
|
2447 | if (!blockAlreadyTerminated) |
443 |
1/2✓ Branch 0 (174→175) taken 2363 times.
✗ Branch 1 (174→234) not taken.
|
2363 | builder.CreateRetVoid(); |
444 | |||
445 | // Conclude debug info for procedure | ||
446 |
1/2✓ Branch 0 (175→176) taken 2447 times.
✗ Branch 1 (175→234) not taken.
|
2447 | diGenerator.concludeFunctionDebugInfo(); |
447 | |||
448 | // Verify procedure | ||
449 |
1/2✓ Branch 0 (176→177) taken 2447 times.
✗ Branch 1 (176→234) not taken.
|
2447 | verifyFunction(proc, node->codeLoc); |
450 | |||
451 | // Change to root scope | ||
452 | 2447 | currentScope = rootScope; | |
453 | |||
454 | 2447 | manIdx++; // Increment symbolTypeIndex | |
455 | 2447 | } | |
456 | 2721 | manIdx = 0; // Reset the symbolTypeIndex | |
457 | |||
458 | // Ensure that we are at the root scope again | ||
459 |
1/2✗ Branch 0 (184→185) not taken.
✓ Branch 1 (184→186) taken 2721 times.
|
2721 | assert(currentScope == rootScope); |
460 | |||
461 |
1/2✓ Branch 0 (186→187) taken 2721 times.
✗ Branch 1 (186→242) not taken.
|
2721 | return nullptr; |
462 | } | ||
463 | |||
464 | 498 | std::any IRGenerator::visitStructDef(const StructDefNode *node) { | |
465 | // Get all substantiated structs which result from this struct def | ||
466 |
1/2✓ Branch 0 (2→3) taken 498 times.
✗ Branch 1 (2→115) not taken.
|
498 | std::vector<Struct *> manifestations = node->structManifestations; |
467 | |||
468 | // Sort the manifestations to prevent generating the struct types in the wrong order (in case of dependencies between structs) | ||
469 | 642 | const auto comp = [](const Struct *lhs, const Struct *rhs) { return lhs->manifestationIndex < rhs->manifestationIndex; }; | |
470 |
1/2✓ Branch 0 (3→4) taken 498 times.
✗ Branch 1 (3→113) not taken.
|
498 | std::ranges::sort(manifestations, comp); |
471 | |||
472 |
2/2✓ Branch 0 (71→6) taken 819 times.
✓ Branch 1 (71→72) taken 498 times.
|
1317 | for (Struct *spiceStruct : manifestations) { |
473 | // Skip structs, that are not fully substantiated | ||
474 |
3/4✓ Branch 0 (7→8) taken 819 times.
✗ Branch 1 (7→110) not taken.
✓ Branch 2 (8→9) taken 198 times.
✓ Branch 3 (8→10) taken 621 times.
|
819 | if (!spiceStruct->isFullySubstantiated()) |
475 | 200 | continue; | |
476 | |||
477 | // Do not generate this struct if it is private and used by nobody | ||
478 |
8/10✓ Branch 0 (10→11) taken 7 times.
✓ Branch 1 (10→15) taken 614 times.
✓ Branch 2 (11→12) taken 7 times.
✗ Branch 3 (11→110) not taken.
✓ Branch 4 (12→13) taken 7 times.
✗ Branch 5 (12→110) not taken.
✓ Branch 6 (13→14) taken 2 times.
✓ Branch 7 (13→15) taken 5 times.
✓ Branch 8 (16→17) taken 2 times.
✓ Branch 9 (16→18) taken 619 times.
|
621 | if (!spiceStruct->used && !spiceStruct->entry->getQualType().isPublic()) |
479 | 2 | continue; | |
480 | |||
481 | // Change scope to struct scope, specific to substantiation | ||
482 | 619 | currentScope = spiceStruct->scope; | |
483 |
1/2✗ Branch 0 (18→19) not taken.
✓ Branch 1 (18→20) taken 619 times.
|
619 | assert(currentScope); |
484 | |||
485 | // Set LLVM type to the struct entry | ||
486 | 619 | const SymbolTableEntry *structEntry = spiceStruct->entry; | |
487 |
1/2✗ Branch 0 (20→21) not taken.
✓ Branch 1 (20→22) taken 619 times.
|
619 | assert(structEntry != nullptr); |
488 | |||
489 | // Generate VTable if required | ||
490 |
2/2✓ Branch 0 (22→23) taken 155 times.
✓ Branch 1 (22→26) taken 464 times.
|
619 | if (node->emitVTable) { |
491 |
1/2✓ Branch 0 (23→24) taken 155 times.
✗ Branch 1 (23→110) not taken.
|
155 | generateVTable(spiceStruct); |
492 |
1/2✓ Branch 0 (24→25) taken 155 times.
✗ Branch 1 (24→76) not taken.
|
310 | deferredVTableInitializations.emplace_back([=, this]() { generateVTableInitializer(spiceStruct); }, false); |
493 | } | ||
494 | |||
495 | // Generate default ctor if required | ||
496 |
1/2✓ Branch 0 (26→27) taken 619 times.
✗ Branch 1 (26→110) not taken.
|
619 | const QualType &thisType = structEntry->getQualType(); |
497 |
2/4✓ Branch 0 (30→31) taken 619 times.
✗ Branch 1 (30→80) not taken.
✓ Branch 2 (31→32) taken 619 times.
✗ Branch 3 (31→78) not taken.
|
1857 | const Function *ctorFunc = FunctionManager::lookup(currentScope, CTOR_FUNCTION_NAME, thisType, {}, true); |
498 |
4/4✓ Branch 0 (35→36) taken 255 times.
✓ Branch 1 (35→38) taken 364 times.
✓ Branch 2 (36→37) taken 29 times.
✓ Branch 3 (36→38) taken 226 times.
|
619 | if (ctorFunc != nullptr && ctorFunc->implicitDefault) |
499 |
1/2✓ Branch 0 (37→38) taken 29 times.
✗ Branch 1 (37→110) not taken.
|
29 | generateDefaultCtor(ctorFunc); |
500 | |||
501 | // Generate default copy ctor if required | ||
502 |
2/4✓ Branch 0 (38→39) taken 619 times.
✗ Branch 1 (38→91) not taken.
✓ Branch 2 (42→43) taken 619 times.
✗ Branch 3 (42→87) not taken.
|
1857 | const ArgList args = {{thisType.toConstRef(node), false /* always non-temporary */}}; |
503 |
2/4✓ Branch 0 (46→47) taken 619 times.
✗ Branch 1 (46→95) not taken.
✓ Branch 2 (47→48) taken 619 times.
✗ Branch 3 (47→93) not taken.
|
619 | const Function *copyCtorFunc = FunctionManager::lookup(currentScope, CTOR_FUNCTION_NAME, thisType, args, true); |
504 |
4/4✓ Branch 0 (50→51) taken 184 times.
✓ Branch 1 (50→53) taken 435 times.
✓ Branch 2 (51→52) taken 87 times.
✓ Branch 3 (51→53) taken 97 times.
|
619 | if (copyCtorFunc != nullptr && copyCtorFunc->implicitDefault) |
505 |
1/2✓ Branch 0 (52→53) taken 87 times.
✗ Branch 1 (52→108) not taken.
|
87 | generateDefaultCopyCtor(copyCtorFunc); |
506 | |||
507 | // Generate default dtor if required | ||
508 |
2/4✓ Branch 0 (56→57) taken 619 times.
✗ Branch 1 (56→101) not taken.
✓ Branch 2 (57→58) taken 619 times.
✗ Branch 3 (57→99) not taken.
|
1857 | const Function *dtorFunc = FunctionManager::lookup(currentScope, DTOR_FUNCTION_NAME, thisType, {}, true); |
509 |
4/4✓ Branch 0 (61→62) taken 183 times.
✓ Branch 1 (61→64) taken 436 times.
✓ Branch 2 (62→63) taken 91 times.
✓ Branch 3 (62→64) taken 92 times.
|
619 | if (dtorFunc != nullptr && dtorFunc->implicitDefault) |
510 |
1/2✓ Branch 0 (63→64) taken 91 times.
✗ Branch 1 (63→108) not taken.
|
91 | generateDefaultDtor(dtorFunc); |
511 | |||
512 | // Return to root scope | ||
513 | 619 | currentScope = rootScope; | |
514 |
1/2✗ Branch 0 (64→65) not taken.
✓ Branch 1 (64→66) taken 619 times.
|
619 | assert(currentScope); |
515 | 619 | } | |
516 | |||
517 |
1/2✓ Branch 0 (72→73) taken 498 times.
✗ Branch 1 (72→112) not taken.
|
996 | return nullptr; |
518 | 498 | } | |
519 | |||
520 | 66 | std::any IRGenerator::visitInterfaceDef(const InterfaceDefNode *node) { | |
521 | // Get all substantiated structs which result from this struct def | ||
522 |
1/2✓ Branch 0 (2→3) taken 66 times.
✗ Branch 1 (2→34) not taken.
|
66 | std::vector<Interface *> manifestations = node->interfaceManifestations; |
523 | |||
524 | // Sort the manifestations to prevent generating the struct types in the wrong order (in case of dependencies between structs) | ||
525 | 216 | const auto comp = [](const Interface *lhs, const Interface *rhs) { return lhs->manifestationIndex < rhs->manifestationIndex; }; | |
526 |
1/2✓ Branch 0 (3→4) taken 66 times.
✗ Branch 1 (3→32) not taken.
|
66 | std::ranges::sort(manifestations, comp); |
527 | |||
528 |
2/2✓ Branch 0 (23→6) taken 174 times.
✓ Branch 1 (23→24) taken 66 times.
|
240 | for (Interface *spiceInterface : manifestations) { |
529 | // Skip interfaces, that are not fully substantiated | ||
530 |
3/4✓ Branch 0 (7→8) taken 174 times.
✗ Branch 1 (7→30) not taken.
✓ Branch 2 (8→9) taken 53 times.
✓ Branch 3 (8→10) taken 121 times.
|
174 | if (!spiceInterface->isFullySubstantiated()) |
531 | 53 | continue; | |
532 | |||
533 | // Do not generate this interface if it is private and used by nobody | ||
534 |
8/10✓ Branch 0 (10→11) taken 5 times.
✓ Branch 1 (10→15) taken 116 times.
✓ Branch 2 (11→12) taken 5 times.
✗ Branch 3 (11→30) not taken.
✓ Branch 4 (12→13) taken 5 times.
✗ Branch 5 (12→30) not taken.
✓ Branch 6 (13→14) taken 1 times.
✓ Branch 7 (13→15) taken 4 times.
✓ Branch 8 (16→17) taken 1 times.
✓ Branch 9 (16→18) taken 120 times.
|
121 | if (!spiceInterface->used && !spiceInterface->entry->getQualType().isPublic()) |
535 | 1 | continue; | |
536 | |||
537 | // Generate VTable information | ||
538 |
1/2✓ Branch 0 (18→19) taken 120 times.
✗ Branch 1 (18→30) not taken.
|
120 | generateVTable(spiceInterface); |
539 |
1/2✓ Branch 0 (19→20) taken 120 times.
✗ Branch 1 (19→28) not taken.
|
240 | deferredVTableInitializations.emplace_back([=, this]() { generateVTableInitializer(spiceInterface); }, false); |
540 | } | ||
541 | |||
542 |
1/2✓ Branch 0 (24→25) taken 66 times.
✗ Branch 1 (24→31) not taken.
|
132 | return nullptr; |
543 | 66 | } | |
544 | |||
545 | 62 | std::any IRGenerator::visitEnumDef(const EnumDefNode *node) { | |
546 |
1/2✓ Branch 0 (2→3) taken 62 times.
✗ Branch 1 (2→5) not taken.
|
62 | return nullptr; // Noop (enums are high-level semantic-only structures) |
547 | } | ||
548 | |||
549 | 684 | std::any IRGenerator::visitGenericTypeDef(const GenericTypeDefNode *node) { | |
550 |
1/2✓ Branch 0 (2→3) taken 684 times.
✗ Branch 1 (2→5) not taken.
|
684 | return nullptr; // Noop (generic types are high-level semantic-only structures) |
551 | } | ||
552 | |||
553 | 44 | std::any IRGenerator::visitAliasDef(const AliasDefNode *node) { | |
554 |
1/2✓ Branch 0 (2→3) taken 44 times.
✗ Branch 1 (2→5) not taken.
|
44 | return nullptr; // Noop (alias definitions are high-level semantic-only structures) |
555 | } | ||
556 | |||
557 | 735 | std::any IRGenerator::visitGlobalVarDef(const GlobalVarDefNode *node) { | |
558 | // Retrieve some information about the variable | ||
559 |
1/2✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→4) taken 735 times.
|
735 | assert(node->entry != nullptr); |
560 | 735 | const QualType &entryType = node->entry->getQualType(); | |
561 | 735 | const bool isPublic = entryType.isPublic(); | |
562 | 735 | const bool isConst = entryType.isConst(); | |
563 | |||
564 | // Get correct type and linkage type | ||
565 |
2/4✓ Branch 0 (7→8) taken 735 times.
✗ Branch 1 (7→35) not taken.
✓ Branch 2 (8→9) taken 735 times.
✗ Branch 3 (8→33) not taken.
|
735 | const auto varType = std::any_cast<llvm::Type *>(visit(node->dataType)); |
566 |
2/2✓ Branch 0 (10→11) taken 258 times.
✓ Branch 1 (10→12) taken 477 times.
|
735 | const auto linkage = isPublic ? llvm::GlobalValue::ExternalLinkage : llvm::GlobalValue::PrivateLinkage; |
567 | |||
568 | // Create global var | ||
569 |
1/2✓ Branch 0 (14→15) taken 735 times.
✗ Branch 1 (14→36) not taken.
|
735 | llvm::Value *varAddress = module->getOrInsertGlobal(node->varName, varType); |
570 |
1/2✓ Branch 0 (16→17) taken 735 times.
✗ Branch 1 (16→37) not taken.
|
735 | llvm::GlobalVariable *var = module->getNamedGlobal(node->varName); |
571 | // Set some attributes, based on the given information | ||
572 | 735 | var->setLinkage(linkage); | |
573 | 735 | var->setConstant(isConst); | |
574 | |||
575 | // Set initializer | ||
576 |
1/2✓ Branch 0 (19→20) taken 735 times.
✗ Branch 1 (19→24) not taken.
|
735 | if (node->hasValue) { // Set the constant value as variable initializer |
577 |
2/4✓ Branch 0 (20→21) taken 735 times.
✗ Branch 1 (20→40) not taken.
✓ Branch 2 (21→22) taken 735 times.
✗ Branch 3 (21→38) not taken.
|
735 | const auto constantValue = std::any_cast<llvm::Constant *>(visit(node->constant)); |
578 | 735 | var->setInitializer(constantValue); | |
579 | ✗ | } else if (cliOptions.buildMode == DEBUG) { // Set the default value as variable initializer | |
580 | ✗ | llvm::Constant *constantValue = getDefaultValueForSymbolType(node->entry->getQualType()); | |
581 | ✗ | var->setInitializer(constantValue); | |
582 | } | ||
583 | |||
584 | 735 | node->entry->updateAddress(varAddress); | |
585 | |||
586 | // Add debug info | ||
587 | 735 | diGenerator.generateGlobalVarDebugInfo(var, node->entry); | |
588 | |||
589 |
1/2✓ Branch 0 (30→31) taken 735 times.
✗ Branch 1 (30→41) not taken.
|
735 | return nullptr; |
590 | } | ||
591 | |||
592 | 817 | std::any IRGenerator::visitExtDecl(const ExtDeclNode *node) { | |
593 | // Get return type | ||
594 | 817 | const Function *spiceFunc = node->extFunction; | |
595 |
1/2✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→4) taken 817 times.
|
817 | assert(spiceFunc != nullptr); |
596 |
1/2✓ Branch 0 (4→5) taken 817 times.
✗ Branch 1 (4→87) not taken.
|
817 | llvm::Type *returnType = builder.getVoidTy(); |
597 |
3/4✓ Branch 0 (5→6) taken 817 times.
✗ Branch 1 (5→87) not taken.
✓ Branch 2 (6→7) taken 535 times.
✓ Branch 3 (6→9) taken 282 times.
|
817 | if (!spiceFunc->returnType.is(TY_DYN)) |
598 |
1/2✓ Branch 0 (7→8) taken 535 times.
✗ Branch 1 (7→87) not taken.
|
535 | returnType = spiceFunc->returnType.toLLVMType(sourceFile); |
599 | |||
600 | // Get arg types | ||
601 | 817 | std::vector<llvm::Type *> argTypes; | |
602 |
1/2✓ Branch 0 (10→11) taken 817 times.
✗ Branch 1 (10→85) not taken.
|
817 | argTypes.reserve(spiceFunc->paramList.size()); |
603 |
3/4✓ Branch 0 (11→12) taken 817 times.
✗ Branch 1 (11→63) not taken.
✓ Branch 2 (19→14) taken 1608 times.
✓ Branch 3 (19→20) taken 817 times.
|
2425 | for (const QualType ¶mType : spiceFunc->getParamTypes()) |
604 |
2/4✓ Branch 0 (15→16) taken 1608 times.
✗ Branch 1 (15→60) not taken.
✓ Branch 2 (16→17) taken 1608 times.
✗ Branch 3 (16→60) not taken.
|
2425 | argTypes.push_back(paramType.toLLVMType(sourceFile)); |
605 | |||
606 | // Declare function | ||
607 |
1/2✓ Branch 0 (22→23) taken 817 times.
✗ Branch 1 (22→64) not taken.
|
817 | llvm::FunctionType *functionType = llvm::FunctionType::get(returnType, argTypes, node->isVarArg); |
608 |
1/2✓ Branch 0 (23→24) taken 817 times.
✗ Branch 1 (23→85) not taken.
|
817 | const std::string mangledName = spiceFunc->getMangledName(); |
609 |
1/2✓ Branch 0 (25→26) taken 817 times.
✗ Branch 1 (25→65) not taken.
|
817 | module->getOrInsertFunction(mangledName, functionType); |
610 |
1/2✓ Branch 0 (27→28) taken 817 times.
✗ Branch 1 (27→66) not taken.
|
817 | llvm::Function *fct = module->getFunction(mangledName); |
611 | |||
612 | // Add noundef attribute to all parameters | ||
613 |
2/2✓ Branch 0 (32→29) taken 1608 times.
✓ Branch 1 (32→33) taken 817 times.
|
2425 | for (size_t i = 0; i < argTypes.size(); i++) |
614 |
1/2✓ Branch 0 (29→30) taken 1608 times.
✗ Branch 1 (29→83) not taken.
|
1608 | fct->addParamAttr(i, llvm::Attribute::NoUndef); |
615 | |||
616 | // If the function should be imported as dll, add the dll attribute | ||
617 |
10/18✓ Branch 0 (33→34) taken 1 times.
✓ Branch 1 (33→40) taken 816 times.
✓ Branch 2 (36→37) taken 1 times.
✗ Branch 3 (36→67) not taken.
✓ Branch 4 (37→38) taken 1 times.
✗ Branch 5 (37→67) not taken.
✗ Branch 6 (38→39) not taken.
✓ Branch 7 (38→40) taken 1 times.
✓ Branch 8 (41→42) taken 1 times.
✓ Branch 9 (41→43) taken 816 times.
✓ Branch 10 (43→44) taken 1 times.
✓ Branch 11 (43→46) taken 816 times.
✗ Branch 12 (46→47) not taken.
✓ Branch 13 (46→55) taken 817 times.
✗ Branch 14 (67→68) not taken.
✗ Branch 15 (67→69) not taken.
✗ Branch 16 (71→72) not taken.
✗ Branch 17 (71→74) not taken.
|
819 | if (node->attrs && node->attrs->attrLst->hasAttr(ATTR_CORE_LINKER_DLL)) |
618 | ✗ | if (node->attrs->attrLst->getAttrValueByName(ATTR_CORE_LINKER_DLL)->boolValue) | |
619 | ✗ | fct->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); | |
620 | |||
621 |
1/2✓ Branch 0 (55→56) taken 817 times.
✗ Branch 1 (55→82) not taken.
|
1634 | return nullptr; |
622 | 817 | } | |
623 | |||
624 | } // namespace spice::compiler | ||
625 |