GCC Code Coverage Report


src/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
46 / 56
82.1%
Branches:
10 / 14, 4 excl
71.4%
Functions:
11 / 11
100.0%

symboltablebuilder/symbol-table-entry.spice
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 // Std imports
4 import "std/text/json/json-value";
5
6 // Own imports
7 import "@/ast/ast-nodes";
8 import "@/symboltablebuilder/scope";
9 import "@/symboltablebuilder/super-type";
10 import "@/symboltablebuilder/qual-type";
11 import "@/symboltablebuilder/lifecycle";
12 import "@/reader/code-loc";
13 import "@/util/common-util";
14 import "@/exception/compiler-error";
15
16 // Reserved function names for implicitly generated struct constructors/destructors
17 public const string CTOR_FUNCTION_NAME = "ctor";
18 public const string DTOR_FUNCTION_NAME = "dtor";
19
20 // Reserved variable names
21 public const string THIS_VARIABLE_NAME = "this";
22 public const string RETURN_VARIABLE_NAME = "result";
23
24 959959 public type SymbolTableEntry struct {
25 // Public fields
26 public String name
27 public Scope* scope
28 public ASTNode* declNode
29 public unsigned long orderIndex
30 public bool global
31 228906 public bool isVolatile = false
32 228906 public bool isParam = false
33 228906 public bool anonymous = false
34 228906 public bool used = false
35 228906 public bool isImplicitField = false
36 // Private fields
37 QualType qualType
38 Lifecycle lifecycle
39 }
40
41 228906 public p SymbolTableEntry.ctor(const String& name, const QualType& qualType, Scope* scope, ASTNode* declNode, unsigned long orderIndex, bool global) {
42 228906 this.name = name;
43 228906 this.qualType = qualType;
44 228906 this.scope = scope;
45 228906 this.declNode = declNode;
46 228906 this.orderIndex = orderIndex;
47 228906 this.global = global;
48 228906 }
49
50 /**
51 * Retrieve the qualified type of this symbol
52 *
53 * @return Qualified type of this symbol
54 */
55 8473650 public f<const QualType&> SymbolTableEntry.getQualType() {
56 8473650 return this.qualType;
57 }
58
59 /**
60 * Update the type of this symbol.
61 *
62 * @param newType New type of the current symbol
63 * @param overwriteExistingType Overwrites the existing type without throwing an error
64 */
65 306452 public p SymbolTableEntry.updateType(const QualType& newType, bool overwriteExistingType) {
66 306452 const dyn options = [SuperType::TY_INVALID, SuperType::TY_DYN];
67 306452 assert overwriteExistingType || this.qualType.isOneOf(options, len(options));
68 306452 this.qualType = newType;
69 306452 }
70
71 /**
72 * Update the state of the current symbol
73 *
74 * @throws CompilerError When the state change is not valid
75 *
76 * @param newState New state of the current symbol
77 */
78 473348 public p SymbolTableEntry.updateState(const LifecycleState& newState) {
79 473348 const LifecycleState oldState = this.lifecycle.getCurrentState();
80
2/4
✓ Branch 0 taken 473348 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 473348 times.
✗ Branch 3 not taken.
473348 if newState == LifecycleState::DEAD && oldState == LifecycleState::DECLARED {
81 ✗ const String message = "Cannot destroy uninitialized variable '" + this.name + "'";
82 ✗ const CompilerError error = CompilerError(CompilerErrorType::INTERNAL_ERROR, message.getRaw());
83 ✗ const String& errorMessage = error.getMessage();
84 ✗ panic(Error(errorMessage.getRaw()));
85 ✗ }
86
2/4
✓ Branch 0 taken 473348 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 473348 times.
✗ Branch 3 not taken.
473348 if newState == LifecycleState::DEAD && oldState == LifecycleState::DEAD {
87 ✗ const String message = "Cannot destroy already destroyed variable '" + this.name + "'";
88 ✗ const CompilerError error = CompilerError(CompilerErrorType::INTERNAL_ERROR, message.getRaw());
89 ✗ const String& errorMessage = error.getMessage();
90 ✗ panic(Error(errorMessage.getRaw()));
91 ✗ }
92 473348 this.lifecycle.addEvent(LifecycleEvent{newState});
93 473348 }
94
95 /**
96 * Retrieve the code location where the symbol was declared
97 *
98 * @return Declaration code location
99 */
100 212 public f<const CodeLoc &> SymbolTableEntry.getDeclCodeLoc() {
101 212 return this.declNode.codeLoc;
102 }
103
104 /**
105 * Retrieve the lifecycle of this symbol
106 *
107 * @return Lifecycle
108 */
109 4397 public f<const Lifecycle&> SymbolTableEntry.getLifecycle() {
110 4397 return this.lifecycle;
111 }
112
113 /**
114 * Check if this symbol is initialized
115 *
116 * @return Initialized or not
117 */
118 88208 public f<bool> SymbolTableEntry.isInitialized() {
119 88208 return this.lifecycle.isInitialized();
120 }
121
122 /**
123 * Check if this symbol is a struct field
124 *
125 * @return Struct field or not
126 */
127 112402 public f<bool> SymbolTableEntry.isField() {
128 112402 const ScopeType scopeType = this.scope.getScopeType();
129
6/6
✓ Branch 0 taken 91967 times.
✓ Branch 1 taken 20435 times.
✓ Branch 2 taken 92124 times.
✓ Branch 3 taken 20278 times.
✓ Branch 4 taken 152 times.
✓ Branch 5 taken 91972 times.
112402 return (scopeType == ScopeType::STRUCT || scopeType == ScopeType::UNION) && this.orderIndex < this.scope.getFieldCount() && !this.anonymous;
130 }
131
132 /**
133 * Stringify the current symbol to a human-readable form. Used to dump whole symbol tables with their contents.
134 * The returned heap-allocated JSON value is owned by the caller.
135 *
136 * Example:
137 * {
138 * "name": "testIden",
139 * "type": "int[]*",
140 * "orderIndex": 4,
141 * "state": "initialized",
142 * "qualifiers: [
143 * "const": true,
144 * "signed": false
145 * ],
146 * "isGlobal": false,
147 * "isVolatile": false
148 * }
149 *
150 * @return Symbol table entry as a JSON object
151 */
152 375876 public f<JsonValue*> SymbolTableEntry.toJSON() {
153 375876 result = __new<JsonValue>(JsonValueKind::JSON_OBJECT);
154 375876 setJsonField(result, String("name"), __new<JsonValue>(this.name));
155 375876 setJsonField(result, String("type"), __new<JsonValue>(this.qualType.getName(true)));
156 375876 setJsonField(result, String("codeLoc"), __new<JsonValue>(this.declNode.codeLoc.toString()));
157 375876 setJsonField(result, String("orderIndex"), __new<JsonValue>(this.orderIndex));
158 375876 setJsonField(result, String("state"), __new<JsonValue>(String(this.lifecycle.getCurrentStateName())));
159 375876 setJsonField(result, String("isGlobal"), __new<JsonValue>(this.global));
160 375876 setJsonField(result, String("isVolatile"), __new<JsonValue>(this.isVolatile));
161 375876 }
162