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