GCC Code Coverage Report


Directory: ../
File: src/symboltablebuilder/Scope.h
Date: 2025-02-05 01:09:36
Exec Total Coverage
Lines: 7 7 100.0%
Functions: 1 1 100.0%
Branches: 40 78 51.3%

Line Branch Exec Source
1 // Copyright (c) 2021-2025 ChilliBits. All rights reserved.
2
3 #pragma once
4
5 #include <model/Interface.h>
6 #include <model/Struct.h>
7 #include <symboltablebuilder/SymbolTable.h>
8 #include <typechecker/FunctionManager.h>
9 #include <typechecker/InterfaceManager.h>
10 #include <typechecker/StructManager.h>
11 #include <util/CompilerWarning.h>
12
13 namespace spice::compiler {
14
15 // Forward declarations
16 class FctDefNode;
17 class ProcDefNode;
18 class SourceFile;
19
20 enum class ScopeType : uint8_t {
21 GLOBAL,
22 FUNC_PROC_BODY,
23 LAMBDA_BODY,
24 STRUCT,
25 INTERFACE,
26 ENUM,
27 IF_ELSE_BODY,
28 WHILE_BODY,
29 FOR_BODY,
30 FOREACH_BODY,
31 CASE_BODY,
32 DEFAULT_BODY,
33 UNSAFE_BODY,
34 ANONYMOUS_BLOCK_BODY
35 };
36
37 /**
38 * Represents an enclosed group of instructions, which are semantically separated from other scopes.
39 * In the source code, scopes usually are written as curly braces.
40 *
41 * Following language structures use scopes:
42 * - global scope
43 * - functions/procedures
44 * - structs
45 * - enums
46 * - interfaces
47 * - thread blocks
48 * - unsafe blocks
49 * - for loops
50 * - foreach loops
51 * - while loops
52 * - if statements
53 * - anonymous scopes
54 */
55 class Scope {
56 public:
57 // Constructors
58 19644 Scope(Scope *parent, SourceFile *sourceFile, ScopeType scopeType, const CodeLoc *codeLoc)
59
2/2
✓ Branch 0 (3→4) taken 18630 times.
✓ Branch 1 (3→5) taken 1014 times.
19644 : parent(parent), sourceFile(sourceFile), codeLoc(codeLoc), type(scopeType) {}
60
61 // Friend classes
62 friend class FunctionManager;
63 friend class StructManager;
64 friend class InterfaceManager;
65
66 // Public methods
67 // Scope management
68 Scope *createChildScope(const std::string &scopeName, ScopeType scopeType, const CodeLoc *declCodeLoc);
69 void renameChildScope(const std::string &oldName, const std::string &newName);
70 Scope *copyChildScope(const std::string &oldName, const std::string &newName);
71 std::shared_ptr<Scope> deepCopyScope();
72 [[nodiscard]] Scope *getChildScope(const std::string &scopeName) const;
73 [[nodiscard]] std::vector<SymbolTableEntry *> getVarsGoingOutOfScope();
74
75 // Generic types
76 void insertGenericType(const std::string &typeName, const GenericType &genericType);
77 GenericType *lookupGenericType(const std::string &typeName);
78
79 // Util
80 void collectWarnings(std::vector<CompilerWarning> &warnings) const;
81 void ensureSuccessfulTypeInference() const;
82 [[nodiscard]] size_t getFieldCount() const;
83 [[nodiscard]] std::vector<Function *> getVirtualMethods();
84 [[nodiscard]] std::vector<const Struct *> getAllStructManifestationsInDeclarationOrder() const;
85 [[nodiscard]] bool hasRefFields();
86 [[nodiscard]] unsigned int getLoopNestingDepth() const;
87 [[nodiscard]] bool isInCaseBranch() const;
88 [[nodiscard]] bool isInAsyncScope() const;
89 [[nodiscard]] bool doesAllowUnsafeOperations() const;
90 [[nodiscard]] bool isImportedBy(const Scope *askingScope) const;
91 [[nodiscard]] nlohmann::json getSymbolTableJSON() const;
92
93 // Wrapper methods for symbol table
94 ALWAYS_INLINE SymbolTableEntry *insert(const std::string &name, ASTNode *declNode) {
95
12/24
✓ Branch 0 (30→31) taken 764 times.
✗ Branch 1 (30→62) not taken.
✓ Branch 2 (13→14) taken 1017 times.
✗ Branch 3 (13→41) not taken.
✓ Branch 4 (31→32) taken 46 times.
✗ Branch 5 (31→65) not taken.
✓ Branch 6 (36→37) taken 46 times.
✗ Branch 7 (36→63) not taken.
✓ Branch 8 (26→27) taken 93 times.
✗ Branch 9 (26→74) not taken.
✓ Branch 10 (57→58) taken 2457 times.
✗ Branch 11 (57→111) not taken.
✓ Branch 12 (70→71) taken 2952 times.
✗ Branch 13 (70→119) not taken.
✓ Branch 14 (52→53) taken 2673 times.
✗ Branch 15 (52→112) not taken.
✓ Branch 16 (61→62) taken 6007 times.
✗ Branch 17 (61→118) not taken.
✓ Branch 18 (73→74) taken 6007 times.
✗ Branch 19 (73→126) not taken.
✓ Branch 20 (26→27) taken 370 times.
✗ Branch 21 (26→67) not taken.
✓ Branch 22 (36→37) taken 370 times.
✗ Branch 23 (36→73) not taken.
43240 return symbolTable.insert(name, declNode);
96 }
97
3/6
✓ Branch 0 (28→29) taken 25649 times.
✗ Branch 1 (28→547) not taken.
✓ Branch 2 (22→23) taken 44389 times.
✗ Branch 3 (22→243) not taken.
✓ Branch 4 (5→6) taken 7862 times.
✗ Branch 5 (5→66) not taken.
77930 ALWAYS_INLINE SymbolTableEntry *lookup(const std::string &symbolName) { return symbolTable.lookup(symbolName); }
98
11/22
✓ Branch 0 (35→36) taken 14588 times.
✗ Branch 1 (35→74) not taken.
✓ Branch 2 (77→78) taken 3585 times.
✗ Branch 3 (77→227) not taken.
✓ Branch 4 (123→124) taken 5554 times.
✗ Branch 5 (123→254) not taken.
✓ Branch 6 (51→52) taken 9648 times.
✗ Branch 7 (51→271) not taken.
✓ Branch 8 (72→73) taken 8624 times.
✗ Branch 9 (72→202) not taken.
✓ Branch 10 (114→115) taken 4114 times.
✗ Branch 11 (114→229) not taken.
✓ Branch 12 (56→57) taken 16022 times.
✗ Branch 13 (56→374) not taken.
✓ Branch 14 (77→78) taken 2672 times.
✗ Branch 15 (77→265) not taken.
✓ Branch 16 (145→146) taken 32862 times.
✗ Branch 17 (145→309) not taken.
✓ Branch 18 (7→8) taken 441 times.
✗ Branch 19 (7→45) not taken.
✓ Branch 20 (33→34) taken 354 times.
✗ Branch 21 (33→59) not taken.
120358 ALWAYS_INLINE SymbolTableEntry *lookupStrict(const std::string &symbolName) { return symbolTable.lookupStrict(symbolName); }
99 ALWAYS_INLINE SymbolTableEntry *lookupField(unsigned int n) {
100
6/12
✗ Branch 0 (6→7) not taken.
✓ Branch 1 (6→8) taken 21345 times.
✗ Branch 2 (6→7) not taken.
✓ Branch 3 (6→8) taken 1216 times.
✗ Branch 4 (6→7) not taken.
✓ Branch 5 (6→8) taken 5899 times.
✗ Branch 6 (16→17) not taken.
✓ Branch 7 (16→18) taken 1076 times.
✗ Branch 8 (30→31) not taken.
✓ Branch 9 (30→32) taken 992 times.
✗ Branch 10 (23→24) not taken.
✓ Branch 11 (23→25) taken 302 times.
30830 assert(type == ScopeType::STRUCT);
101
6/12
✓ Branch 0 (8→9) taken 5083 times.
✗ Branch 1 (8→59) not taken.
✓ Branch 2 (8→9) taken 3898 times.
✗ Branch 3 (8→76) not taken.
✓ Branch 4 (8→9) taken 3099 times.
✗ Branch 5 (8→64) not taken.
✓ Branch 6 (18→19) taken 1076 times.
✗ Branch 7 (18→141) not taken.
✓ Branch 8 (32→33) taken 992 times.
✗ Branch 9 (32→151) not taken.
✓ Branch 10 (25→26) taken 302 times.
✗ Branch 11 (25→114) not taken.
30830 return symbolTable.lookupStrictByIndex(n);
102 }
103
104 // Public members
105 Scope *parent;
106 SourceFile *sourceFile;
107 std::unordered_map<std::string, std::shared_ptr<Scope>> children;
108 SymbolTable symbolTable = SymbolTable(parent == nullptr ? nullptr : &parent->symbolTable, this);
109 const CodeLoc *codeLoc = nullptr;
110 const ScopeType type;
111 bool isGenericScope = false;
112 bool isAsyncScope = false;
113 bool isDtorScope = false;
114
115 private:
116 // Private members
117 FunctionRegistry functions;
118 StructRegistry structs;
119 InterfaceRegistry interfaces;
120 std::unordered_map<std::string, GenericType> genericTypes;
121 };
122
123 } // namespace spice::compiler
124