• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rieske / trans / 28323069258

28 Jun 2026 01:01PM UTC coverage: 90.637% (+0.006%) from 90.631%
28323069258

Pull #38

github

rieske
Implement C-like block scopes and shadowing

Use a monotonic scope-id stack for nested and sibling blocks. Share one
scope between parameters and the function body (visit body children
without entering a new scope). Reject redeclaring parameters as locals.
Add tests for nested/sibling shadowing and parameter scope rules.
Pull Request #38: Implement C-like block scopes and shadowing

37 of 38 new or added lines in 4 files covered. (97.37%)

6 existing lines in 1 file now uncovered.

4937 of 5447 relevant lines covered (90.64%)

228243.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.11
/src/semantic_analyzer/ValueScope.cpp
1
#include "ValueScope.h"
2

3
#include <iostream>
4
#include <algorithm>
5

6
#include "translation_unit/Context.h"
7

8
const std::string TEMP_PREFIX = "$t";
9

10
namespace {
11

12
unsigned nextTemp { 0 };
13

14
std::string generateTempName() {
3,380✔
15
    return TEMP_PREFIX + std::to_string(++nextTemp);
3,380✔
16
}
17

18
class EntryWithSameNameExists {
19
public:
20
    EntryWithSameNameExists(std::string name) :
4,084✔
21
            name { name }
4,084✔
22
    {
23
    }
4,084✔
24
    bool operator()(const semantic_analyzer::ValueEntry& entry) {
5,790✔
25
        return entry.getName() == name;
5,790✔
26
    }
27

28
private:
29
    std::string name;
30
};
31

32
} // namespace
33

34
namespace semantic_analyzer {
35

36
bool ValueScope::insertSymbol(std::string name, const type::Type& type, translation_unit::Context context) {
1,470✔
37
    if (localSymbols.find(name) != localSymbols.end()) {
1,470✔
38
        return false;
×
39
    }
40
    // Parameters live in `arguments` but share block scope with the function body (C).
41
    auto existingArgument = std::find_if(arguments.begin(), arguments.end(), EntryWithSameNameExists { name });
1,470✔
42
    if (existingArgument != arguments.end()) {
1,470✔
43
        return false;
2✔
44
    }
45
    ValueEntry entry { name, type, false, context, static_cast<int>(localSymbols.size()) };
1,468✔
46
    localSymbols.insert(std::make_pair(name, entry));
1,468✔
47
    return true;
1,468✔
48
}
1,468✔
49

50
void ValueScope::insertFunctionArgument(std::string name, const type::Type& type, translation_unit::Context context) {
164✔
51
    auto existingArgument = std::find_if(arguments.begin(), arguments.end(), EntryWithSameNameExists { name });
164✔
52
    if (existingArgument == arguments.end()) {
164✔
53
        ValueEntry entry { name, type, false, context, static_cast<int>(arguments.size()) };
164✔
54
        arguments.push_back(entry);
164✔
55
    }
164✔
56
}
164✔
57

UNCOV
58
bool ValueScope::isSymbolDefined(std::string symbolName) const {
×
59
    try {
UNCOV
60
        lookup(symbolName);
×
UNCOV
61
        return true;
×
UNCOV
62
    } catch (std::out_of_range &ex) {
×
UNCOV
63
        return false;
×
UNCOV
64
    }
×
65
}
66

67
ValueEntry ValueScope::lookup(std::string name) const {
7,132✔
68
    if (localSymbols.find(name) == localSymbols.end()) {
7,132✔
69
        auto existingArgument = std::find_if(arguments.begin(), arguments.end(), EntryWithSameNameExists { name });
2,450✔
70
        if (existingArgument == arguments.end()) {
2,450✔
71
            throw std::out_of_range("symbol not found: " + name);
2,060✔
72
        }
73
        return *existingArgument;
390✔
74
    }
75
    return localSymbols.at(name);
4,682✔
76
}
77

78
ValueEntry ValueScope::createTemporarySymbol(type::Type type) {
3,380✔
79
    std::string tempName = generateTempName();
3,380✔
80
// FIXME:
81
    ValueEntry temp { tempName, type, true, translation_unit::Context { "", 0 }, static_cast<int>(localSymbols.size()) };
10,140✔
82
    localSymbols.insert(std::make_pair(tempName, temp));
3,380✔
83
    return temp;
6,760✔
84
}
3,380✔
85

86
std::map<std::string, ValueEntry> ValueScope::getSymbols() const {
720✔
87
    return localSymbols;
720✔
88
}
89

90
std::vector<ValueEntry> ValueScope::getArguments() const {
720✔
91
    return arguments;
720✔
92
}
93

94
} // namespace semantic_analyzer
95

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc