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

daisytuner / sdfglib / 17637380013

11 Sep 2025 07:29AM UTC coverage: 59.755% (+0.6%) from 59.145%
17637380013

push

github

web-flow
New debug info (#210)

* initial draft

* update data structure and construction logic

* finalize DebugInfo draft

* fix tests

* Update serializer and fix tests

* fix append bug

* update data structure

* sdfg builder update

* const ref vectors

* update implementation and partial tests

* compiling state

* update serializer interface

* update dot test

* reset interface to debug_info in json to maintain compatibility with tools

* first review batch

* second batch of changes

* merge fixes

777 of 1111 new or added lines in 46 files covered. (69.94%)

11 existing lines in 11 files now uncovered.

9755 of 16325 relevant lines covered (59.75%)

115.06 hits per line

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

89.47
/src/debug_info.cpp
1
#include "sdfg/debug_info.h"
2

3
#include <algorithm>
4
#include <cstddef>
5
#include <string>
6
#include <vector>
7
#include "sdfg/exceptions.h"
8

9
namespace sdfg {
10

11
/***** DebugInfo *****/
12

NEW
13
DebugInfo::DebugInfo() { this->locations_ = {DebugLoc("", "", 0, 0, false)}; };
×
14

15
DebugInfo::DebugInfo(DebugLoc loc) : locations_({loc}) {};
14✔
16

NEW
17
DebugInfo::DebugInfo(DebugLoc loc, std::vector<DebugLoc> inlined_at) : locations_({loc}) {
×
NEW
18
    for (auto& debug_loc : inlined_at) {
×
NEW
19
        if (debug_loc.has) {
×
NEW
20
            this->locations_.push_back(debug_loc);
×
NEW
21
        }
×
22
    }
NEW
23
};
×
24

25
DebugInfo::DebugInfo(std::vector<DebugLoc> inlined_at) {
10✔
26
    for (auto& loc : inlined_at) {
30✔
27
        if (loc.has) {
20✔
28
            this->locations_.push_back(loc);
20✔
29
        }
20✔
30
    }
31
    if (this->locations_.empty()) {
10✔
NEW
32
        this->locations_.push_back(DebugLoc("", "", 0, 0, false));
×
NEW
33
    }
×
34
}
10✔
35

36
const std::vector<DebugLoc>& DebugInfo::locations() const { return this->locations_; }
127✔
37

38
bool DebugInfo::has() const { return this->locations_.front().has; };
56✔
39

40
std::string DebugInfo::filename() const { return this->locations_.front().filename; };
1✔
41

42
std::string DebugInfo::function() const { return this->locations_.front().function; };
1✔
43

44
size_t DebugInfo::line() const { return this->locations_.front().line; };
1✔
45

46
size_t DebugInfo::column() const { return this->locations_.front().column; };
1✔
47

48
bool DebugInfo::operator==(const DebugInfo& other) const {
13✔
49
    bool result = true;
13✔
50
    if (this->locations_.size() != other.locations_.size()) return false;
13✔
51
    for (size_t i = 0; i < this->locations_.size(); i++) {
25✔
52
        result &= (this->locations_[i] == other.locations_[i]);
14✔
53
    }
14✔
54
    return result;
11✔
55
}
13✔
56

57

58
/***** DebugInfoRegion *****/
59

60
DebugInfoRegion::DebugInfoRegion()
612✔
61
    : indices_(), filename_(""), function_(""), start_line_(0), start_column_(0), end_line_(0), end_column_(0) {
612✔
62
    this->has_ = false;
612✔
63
};
612✔
64

65
DebugInfoRegion::DebugInfoRegion(std::unordered_set<size_t> indices, const DebugInfos& all_instructions)
7,158✔
66
    : indices_(indices) {
3,579✔
67
    if (this->indices_.empty()) {
3,579✔
68
        this->has_ = false;
3,541✔
69
        return;
3,541✔
70
    }
71

72
    if (all_instructions.empty()) {
38✔
NEW
73
        this->has_ = false;
×
NEW
74
        return;
×
75
    }
76

77
    // filter instructions
78
    DebugInfos instructions;
38✔
79
    for (auto index : this->indices_) {
87✔
80
        if (index < all_instructions.size()) {
49✔
81
            auto instruction = all_instructions[index];
49✔
82
            if (instruction.has()) {
49✔
83
                instructions.push_back(instruction);
49✔
84
            }
49✔
85
        }
49✔
86
    }
87

88
    if (instructions.empty()) {
38✔
NEW
89
        this->has_ = false;
×
NEW
90
        return;
×
91
    }
92

93
    // find locations
94
    std::string filename;
38✔
95
    std::string function;
38✔
96
    size_t start_line;
97
    size_t start_column;
98
    size_t end_line;
99
    size_t end_column;
100

101

102
    bool found = false;
38✔
103
    for (auto& loc : instructions.front().locations()) {
40✔
104
        filename = loc.filename;
40✔
105
        function = loc.function;
40✔
106
        start_line = loc.line;
40✔
107
        start_column = loc.column;
40✔
108
        end_line = loc.line;
40✔
109
        end_column = loc.column;
40✔
110
        int fitting = 0;
40✔
111
        for (const auto& instruction : instructions) {
91✔
112
            found = false;
53✔
113
            for (const auto& inlined_loc : instruction.locations()) {
58✔
114
                if (fuse_ranges(inlined_loc, filename, function, start_line, start_column, end_line, end_column)) {
56✔
115
                    found = true;
51✔
116
                    break;
51✔
117
                }
118
            }
119
            if (!found) {
53✔
120
                // If no ranges were fused, we can break early
121
                break;
2✔
122
            }
123
            fitting++;
51✔
124
        }
125
        if (fitting == instructions.size()) {
40✔
126
            found = true;
38✔
127
            break; // All instructions fit the same file and function
38✔
128
        }
129
    }
130
    if (!found) {
38✔
NEW
131
        throw InvalidSDFGException("No valid debug locations found in DebugTable");
×
132
    }
133

134
    this->filename_ = filename;
38✔
135
    this->function_ = function;
38✔
136
    this->start_line_ = start_line;
38✔
137
    this->start_column_ = start_column;
38✔
138
    this->end_line_ = end_line;
38✔
139
    this->end_column_ = end_column;
38✔
140
    this->has_ = true;
38✔
141
};
3,579✔
142

143
bool DebugInfoRegion::fuse_ranges(
56✔
144
    const DebugLoc& loc,
145
    std::string& filename,
146
    std::string& function,
147
    size_t& line_start,
148
    size_t& col_start,
149
    size_t& line_end,
150
    size_t& col_end
151
) {
152
    if (loc.filename == filename && loc.function == function) {
56✔
153
        if (line_start == loc.line) {
51✔
154
            col_start = std::min(col_start, loc.column);
43✔
155
        } else if (line_start > loc.line) {
51✔
156
            col_start = loc.column;
4✔
157
        }
4✔
158
        line_start = std::min(line_start, loc.line);
51✔
159

160
        if (line_end == loc.line) {
51✔
161
            col_end = std::max(col_end, loc.column);
43✔
162
        } else if (line_end < loc.line) {
51✔
163
            col_end = loc.column;
4✔
164
        }
4✔
165
        line_end = std::max(line_end, loc.line);
51✔
166
        return true; // Same file and function, ranges fused
51✔
167
    }
168
    return false; // Different file or function, ranges not fused
5✔
169
}
56✔
170

171
std::unordered_set<size_t> DebugInfoRegion::indices() const { return this->indices_; }
378✔
172

173
DebugInfoRegion DebugInfoRegion::
174
    merge(const DebugInfoRegion& first, const DebugInfoRegion& second, const DebugInfos& all_instructions) {
26✔
175
    // Merge the two regions by combining their indices
176
    std::unordered_set<size_t> merged_indices = first.indices_;
26✔
177
    merged_indices.insert(second.indices_.begin(), second.indices_.end());
26✔
178

179
    // Create a new region with the merged indices
180
    return DebugInfoRegion(merged_indices, all_instructions);
26✔
181
}
26✔
182

183
bool DebugInfoRegion::has() const { return this->has_; }
127✔
184

185
std::string DebugInfoRegion::filename() const { return this->filename_; }
129✔
186

187
std::string DebugInfoRegion::function() const { return this->function_; }
128✔
188

189
size_t DebugInfoRegion::start_line() const { return this->start_line_; }
129✔
190
size_t DebugInfoRegion::start_column() const { return this->start_column_; }
129✔
191
size_t DebugInfoRegion::end_line() const { return this->end_line_; }
129✔
192
size_t DebugInfoRegion::end_column() const { return this->end_column_; }
129✔
193

194
/***** DebugTable *****/
195

196
const DebugInfos& DebugTable::elements() const { return this->elements_; };
3,608✔
197

198
size_t DebugTable::add_element(DebugInfo element) {
25✔
199
    auto entry = std::find(this->elements_.begin(), this->elements_.end(), element);
25✔
200
    if (entry != this->elements_.end()) {
25✔
201
        // Element already exists, return its index
202
        return std::distance(this->elements_.begin(), entry);
3✔
203
    }
204
    this->elements_.push_back(element);
22✔
205
    return this->elements_.size() - 1;
22✔
206
};
25✔
207

208
DebugInfos DebugTable::get_region(std::unordered_set<size_t> indices) const {
261✔
209
    DebugInfos elements;
261✔
210
    for (auto index : indices) {
264✔
211
        if (index < this->elements_.size()) {
3✔
212
            elements.push_back(this->elements_[index]);
3✔
213
        }
3✔
214
    }
215
    return elements;
261✔
216
};
261✔
217

218
} // namespace sdfg
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