GCC Code Coverage Report


Directory: ../
File: src/symboltablebuilder/SymbolTableEntry.cpp
Date: 2025-02-05 01:09:36
Exec Total Coverage
Lines: 40 40 100.0%
Functions: 10 10 100.0%
Branches: 37 64 57.8%

Line Branch Exec Source
1 // Copyright (c) 2021-2025 ChilliBits. All rights reserved.
2
3 #include "SymbolTableEntry.h"
4
5 #include <ast/ASTNodes.h>
6 #include <exception/SemanticError.h>
7 #include <symboltablebuilder/Scope.h>
8 #include <util/CodeLoc.h>
9
10 namespace spice::compiler {
11
12 /**
13 * Retrieve the qualified type of this symbol
14 *
15 * @return Qualified type of this symbol
16 */
17 1599237 const QualType &SymbolTableEntry::getQualType() const { return qualType; }
18
19 /**
20 * Update the type of this symbol.
21 *
22 * @param newType New type of the current symbol
23 * @param overwriteExistingType Overwrites the existing type without throwing an error
24 */
25 60004 void SymbolTableEntry::updateType(const QualType &newType, [[maybe_unused]] bool overwriteExistingType) {
26
4/6
✓ Branch 0 (2→3) taken 28914 times.
✓ Branch 1 (2→6) taken 31090 times.
✓ Branch 2 (3→4) taken 28914 times.
✗ Branch 3 (3→7) not taken.
✗ Branch 4 (4→5) not taken.
✓ Branch 5 (4→6) taken 28914 times.
60004 assert(overwriteExistingType || qualType.isOneOf({TY_INVALID, TY_DYN}));
27 60004 qualType = newType;
28 60004 }
29
30 /**
31 * Update the state of the current symbol
32 *
33 * @throws CompilerError When the state of the symbol is set to initialized before a concrete type was set
34 *
35 * @param newState New state of the current symbol
36 * @param node AST node where the update takes place
37 */
38 87484 void SymbolTableEntry::updateState(const LifecycleState &newState, const ASTNode *node) {
39 87484 const LifecycleState oldState = lifecycle.getCurrentState();
40 if (newState == DEAD && oldState == DECLARED) // GCOV_EXCL_LINE
41 throw CompilerError(INTERNAL_ERROR, "Cannot destroy uninitialized variable '" + name + "'"); // GCOV_EXCL_LINE
42 if (newState == DEAD && oldState == DEAD) // GCOV_EXCL_LINE
43 throw CompilerError(INTERNAL_ERROR, "Cannot destroy already destroyed variable '" + name + "'"); // GCOV_EXCL_LINE
44
1/2
✓ Branch 0 (21→22) taken 87484 times.
✗ Branch 1 (21→41) not taken.
87484 lifecycle.addEvent({newState, node});
45 87484 }
46
47 /**
48 * Retrieve the code location where the symbol was declared
49 *
50 * @return Declaration code location
51 */
52 152 const CodeLoc &SymbolTableEntry::getDeclCodeLoc() const { return declNode->codeLoc; }
53
54 /**
55 * Retrieve the address of the assigned value
56 *
57 * @return Address of the value in memory
58 */
59
2/2
✓ Branch 0 (3→4) taken 6 times.
✓ Branch 1 (3→5) taken 55918 times.
55924 llvm::Value *SymbolTableEntry::getAddress() const { return memAddress.empty() ? nullptr : memAddress.top(); }
60
61 /**
62 * Update the address of a symbol. This is used to save the allocated address where the symbol lives.
63 *
64 * @param address Address of the symbol in memory
65 */
66 42330 void SymbolTableEntry::updateAddress(llvm::Value *address) {
67
1/2
✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→4) taken 42330 times.
42330 assert(address != nullptr);
68
1/2
✗ Branch 0 (6→7) not taken.
✓ Branch 1 (6→8) taken 42330 times.
42330 assert(address->getType()->isPointerTy());
69 // Ensure that structs fields get no addresses assigned, as the addresses are meant for the struct instances
70
5/8
✓ Branch 0 (8→9) taken 37253 times.
✓ Branch 1 (8→11) taken 5077 times.
✓ Branch 2 (9→10) taken 37253 times.
✗ Branch 3 (9→11) not taken.
✓ Branch 4 (11→12) taken 5077 times.
✗ Branch 5 (11→20) not taken.
✗ Branch 6 (12→13) not taken.
✓ Branch 7 (12→14) taken 5077 times.
42330 assert((scope->type != ScopeType::STRUCT && scope->type != ScopeType::INTERFACE) ||
71 qualType.isOneOf({TY_FUNCTION, TY_PROCEDURE}));
72
2/2
✓ Branch 0 (15→16) taken 34754 times.
✓ Branch 1 (15→17) taken 7576 times.
42330 if (memAddress.empty())
73 34754 memAddress.push(address);
74 else
75 7576 memAddress.top() = address;
76 42330 }
77
78 /**
79 * Push a new address to the stack
80 *
81 * @param address Address to push
82 */
83 24 void SymbolTableEntry::pushAddress(llvm::Value *address) {
84
1/2
✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→4) taken 24 times.
24 assert(address != nullptr);
85 24 memAddress.push(address);
86 24 }
87
88 /**
89 * Remove the last address from the stack
90 */
91 24 void SymbolTableEntry::popAddress() {
92
1/2
✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 24 times.
24 assert(!memAddress.empty());
93 24 memAddress.pop();
94 24 }
95
96 /**
97 * Check if this symbol is a struct field
98 *
99 * @return Struct field or not
100 */
101 14736 bool SymbolTableEntry::isField() const {
102
4/6
✓ Branch 0 (2→3) taken 12771 times.
✓ Branch 1 (2→7) taken 1965 times.
✓ Branch 2 (4→5) taken 12771 times.
✗ Branch 3 (4→7) not taken.
✓ Branch 4 (5→6) taken 12771 times.
✗ Branch 5 (5→7) not taken.
14736 return scope->type == ScopeType::STRUCT && orderIndex < scope->getFieldCount() && !anonymous;
103 }
104
105 /**
106 * Stringify the current symbol to a human-readable form. Used to dump whole symbol tables with their contents.
107 *
108 * Example:
109 * {
110 * "name": "testIden",
111 * "type": "int[]*",
112 * "orderIndex": 4,
113 * "state": "initialized",
114 * "qualifiers: [
115 * "const": true,
116 * "signed": false
117 * ],
118 * "isGlobal": false,
119 * "isVolatile": false
120 * }
121 *
122 * @return Symbol table entry as a JSON object
123 */
124 121961 nlohmann::ordered_json SymbolTableEntry::toJSON() const {
125 121961 nlohmann::json result;
126
2/4
✓ Branch 0 (3→4) taken 121961 times.
✗ Branch 1 (3→43) not taken.
✓ Branch 2 (4→5) taken 121961 times.
✗ Branch 3 (4→41) not taken.
121961 result["name"] = name;
127
3/6
✓ Branch 0 (7→8) taken 121961 times.
✗ Branch 1 (7→48) not taken.
✓ Branch 2 (8→9) taken 121961 times.
✗ Branch 3 (8→46) not taken.
✓ Branch 4 (9→10) taken 121961 times.
✗ Branch 5 (9→44) not taken.
121961 result["type"] = qualType.getName(true);
128
3/6
✓ Branch 0 (13→14) taken 121961 times.
✗ Branch 1 (13→54) not taken.
✓ Branch 2 (14→15) taken 121961 times.
✗ Branch 3 (14→52) not taken.
✓ Branch 4 (15→16) taken 121961 times.
✗ Branch 5 (15→50) not taken.
121961 result["codeLoc"] = declNode->codeLoc.toString();
129
1/2
✓ Branch 0 (20→21) taken 121961 times.
✗ Branch 1 (20→56) not taken.
121961 result["orderIndex"] = orderIndex;
130
3/6
✓ Branch 0 (23→24) taken 121961 times.
✗ Branch 1 (23→61) not taken.
✓ Branch 2 (24→25) taken 121961 times.
✗ Branch 3 (24→61) not taken.
✓ Branch 4 (25→26) taken 121961 times.
✗ Branch 5 (25→59) not taken.
121961 result["state"] = lifecycle.getCurrentStateName();
131
1/2
✓ Branch 0 (29→30) taken 121961 times.
✗ Branch 1 (29→63) not taken.
121961 result["isGlobal"] = global;
132
1/2
✓ Branch 0 (33→34) taken 121961 times.
✗ Branch 1 (33→66) not taken.
121961 result["isVolatile"] = isVolatile;
133
1/2
✓ Branch 0 (36→37) taken 121961 times.
✗ Branch 1 (36→69) not taken.
243922 return result;
134 121961 }
135
136 } // namespace spice::compiler
137