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

rieske / trans / 28461496314

30 Jun 2026 04:55PM UTC coverage: 90.13% (-0.4%) from 90.53%
28461496314

Pull #44

github

rieske
Support multi-word struct pass/return and expand struct tests

Pass multi-word structs on the stack with correct SP adjustments when
pushing words; copy aggregates word-wise on assign. Return up to two
words in RAX/RDX and restore them on retrieve. Use the real function
return type from declaration specs (fixes void calls and struct
returns). Expand StructsTest for by-value/by-address args in different
positions, mutation, return by value/pointer, assign, and chains.
Pull Request #44: Implement C structs with member access

329 of 404 new or added lines in 13 files covered. (81.44%)

5415 of 6008 relevant lines covered (90.13%)

240586.41 hits per line

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

80.54
/src/ast/AbstractSyntaxTreeBuilderContext.cpp
1
#include "AbstractSyntaxTreeBuilderContext.h"
2

3
namespace ast {
4

5
AbstractSyntaxTreeBuilderContext::AbstractSyntaxTreeBuilderContext() {
412 ✔
6
}
412 ✔
7

8
void AbstractSyntaxTreeBuilderContext::pushTerminal(TerminalSymbol terminal) {
19,380 ✔
9
    terminalSymbols.push(terminal);
19,380 ✔
10
}
19,380 ✔
11

12
TerminalSymbol AbstractSyntaxTreeBuilderContext::popTerminal() {
19,310 ✔
13
    auto terminal = terminalSymbols.top();
19,310 ✔
14
    terminalSymbols.pop();
19,310 ✔
15
    return terminal;
19,310 ✔
16
}
17

18
void AbstractSyntaxTreeBuilderContext::pushTypeSpecifier(TypeSpecifier typeSpecifier) {
1,370 ✔
19
    typeSpecifiers.push(typeSpecifier);
1,370 ✔
20
}
1,370 ✔
21

22
TypeSpecifier AbstractSyntaxTreeBuilderContext::popTypeSpecifier() {
1,370 ✔
23
    auto typeSpecifier = typeSpecifiers.top();
1,370 ✔
24
    typeSpecifiers.pop();
1,370 ✔
25
    return typeSpecifier;
1,370 ✔
26
}
27

28
void AbstractSyntaxTreeBuilderContext::pushStorageSpecifier(StorageSpecifier storageSpecifier) {
×
29
    storageSpecifiers.push(storageSpecifier);
×
30
}
×
31

32
StorageSpecifier AbstractSyntaxTreeBuilderContext::popStorageSpecifier() {
×
33
    auto storageSpecifier = storageSpecifiers.top();
×
34
    storageSpecifiers.pop();
×
35
    return storageSpecifier;
×
36
}
37

38
void AbstractSyntaxTreeBuilderContext::pushTypeQualifier(type::Qualifier typeQualifier) {
×
39
    typeQualifiers.push(typeQualifier);
×
40
}
×
41

42
type::Qualifier AbstractSyntaxTreeBuilderContext::popTypeQualifier() {
×
43
    auto typeQualifier = typeQualifiers.top();
×
44
    typeQualifiers.pop();
×
45
    return typeQualifier;
×
46
}
47

48
void AbstractSyntaxTreeBuilderContext::pushConstant(Constant constant) {
1,374 ✔
49
    constants.push(constant);
1,374 ✔
50
}
1,374 ✔
51

52
Constant AbstractSyntaxTreeBuilderContext::popConstant() {
1,374 ✔
53
    auto constant = constants.top();
1,374 ✔
54
    constants.pop();
1,374 ✔
55
    return constant;
1,374 ✔
56
}
57

58
void AbstractSyntaxTreeBuilderContext::pushExpression(std::unique_ptr<Expression> expression) {
7,832 ✔
59
    expressionStack.push(std::move(expression));
7,832 ✔
60
}
7,832 ✔
61

62
std::unique_ptr<Expression> AbstractSyntaxTreeBuilderContext::popExpression() {
7,830 ✔
63
    auto expression = std::move(expressionStack.top());
7,830 ✔
64
    expressionStack.pop();
7,830 ✔
65
    return expression;
7,830 ✔
66
}
67

68
void AbstractSyntaxTreeBuilderContext::newActualArgumentsList(std::unique_ptr<Expression> argument) {
932 ✔
69
    std::vector<std::unique_ptr<Expression>> arguments;
932 ✔
70
    arguments.push_back(std::move(argument));
932 ✔
71
    actualArgumentLists.push(std::move(arguments));
932 ✔
72
}
932 ✔
73

74
void AbstractSyntaxTreeBuilderContext::addToActualArgumentsList(std::unique_ptr<Expression> argument) {
1,148 ✔
75
    actualArgumentLists.top().push_back(std::move(argument));
1,148 ✔
76
}
1,148 ✔
77

78
std::vector<std::unique_ptr<Expression>> AbstractSyntaxTreeBuilderContext::popActualArgumentsList() {
932 ✔
79
    auto arguments = std::move(actualArgumentLists.top());
932 ✔
80
    actualArgumentLists.pop();
932 ✔
81
    return arguments;
932 ✔
82
}
83

84
void AbstractSyntaxTreeBuilderContext::newPointer(Pointer pointer) {
84 ✔
85
    pointerStack.push(std::vector<Pointer> { pointer });
252 ✔
86
}
168 ✔
87

88
void AbstractSyntaxTreeBuilderContext::pointerToPointer(Pointer pointer) {
×
89
    pointerStack.top().push_back(pointer);
×
90
}
×
91

92
std::vector<Pointer> AbstractSyntaxTreeBuilderContext::popPointers() {
84 ✔
93
    auto pointers = pointerStack.top();
84 ✔
94
    pointerStack.pop();
84 ✔
95
    return pointers;
84 ✔
96
}
97

98
void AbstractSyntaxTreeBuilderContext::pushStatement(std::unique_ptr<AbstractSyntaxTreeNode> statement) {
3,204 ✔
99
    statementStack.push(std::move(statement));
3,204 ✔
100
}
3,204 ✔
101

102
std::unique_ptr<AbstractSyntaxTreeNode> AbstractSyntaxTreeBuilderContext::popStatement() {
3,204 ✔
103
    auto statement = std::move(statementStack.top());
3,204 ✔
104
    statementStack.pop();
3,204 ✔
105
    return statement;
3,204 ✔
106
}
107

108
void AbstractSyntaxTreeBuilderContext::pushDirectDeclarator(std::unique_ptr<DirectDeclarator> declarator) {
1,976 ✔
109
    directDeclarators.push(std::move(declarator));
1,976 ✔
110
}
1,976 ✔
111

112
std::unique_ptr<DirectDeclarator> AbstractSyntaxTreeBuilderContext::popDirectDeclarator() {
1,976 ✔
113
    auto declarator = std::move(directDeclarators.top());
1,976 ✔
114
    directDeclarators.pop();
1,976 ✔
115
    return declarator;
1,976 ✔
116
}
117

118
void AbstractSyntaxTreeBuilderContext::pushDeclarator(std::unique_ptr<Declarator> declarator) {
1,452 ✔
119
    declarators.push(std::move(declarator));
1,452 ✔
120
}
1,452 ✔
121

122
std::unique_ptr<Declarator> AbstractSyntaxTreeBuilderContext::popDeclarator() {
1,450 ✔
123
    auto declarator = std::move(declarators.top());
1,450 ✔
124
    declarators.pop();
1,450 ✔
125
    return declarator;
1,450 ✔
126
}
127

128
void AbstractSyntaxTreeBuilderContext::pushInitializedDeclarator(std::unique_ptr<InitializedDeclarator> initializedDeclarator) {
662 ✔
129
    initializedDeclarators.push(std::move(initializedDeclarator));
662 ✔
130
}
662 ✔
131

132
std::unique_ptr<InitializedDeclarator> AbstractSyntaxTreeBuilderContext::popInitializedDeclarator() {
662 ✔
133
    auto initializedDeclarator = std::move(initializedDeclarators.top());
662 ✔
134
    initializedDeclarators.pop();
662 ✔
135
    return initializedDeclarator;
662 ✔
136
}
137

138
void AbstractSyntaxTreeBuilderContext::pushInitializedDeclarators(std::vector<std::unique_ptr<InitializedDeclarator> > declarators) {
662 ✔
139
    initializedDeclaratorLists.push(std::move(declarators));
662 ✔
140
}
662 ✔
141

142
std::vector<std::unique_ptr<InitializedDeclarator> > AbstractSyntaxTreeBuilderContext::popInitializedDeclarators() {
662 ✔
143
    auto declarators = std::move(initializedDeclaratorLists.top());
662 ✔
144
    initializedDeclaratorLists.pop();
662 ✔
145
    return declarators;
662 ✔
146
}
147

148
void AbstractSyntaxTreeBuilderContext::pushDeclarationList(std::vector<std::unique_ptr<Declaration>> declarationList) {
422 ✔
149
    declarationLists.push(std::move(declarationList));
422 ✔
150
}
422 ✔
151

152
std::vector<std::unique_ptr<Declaration>> AbstractSyntaxTreeBuilderContext::popDeclarationList() {
422 ✔
153
    auto declarationList = std::move(declarationLists.top());
422 ✔
154
    declarationLists.pop();
422 ✔
155
    return declarationList;
422 ✔
156
}
157

158
void AbstractSyntaxTreeBuilderContext::pushFormalArgument(FormalArgument formalArgument) {
202 ✔
159
    formalArguments.push(std::move(formalArgument));
202 ✔
160
}
202 ✔
161

162
FormalArgument AbstractSyntaxTreeBuilderContext::popFormalArgument() {
202 ✔
163
    auto parameter = std::move(formalArguments.top());
202 ✔
164
    formalArguments.pop();
202 ✔
165
    return parameter;
202 ✔
166
}
167

168
void AbstractSyntaxTreeBuilderContext::pushFormalArguments(FormalArguments formalArguments) {
202 ✔
169
    formalArgumentLists.push(std::move(formalArguments));
202 ✔
170
}
202 ✔
171

172
FormalArguments AbstractSyntaxTreeBuilderContext::popFormalArguments() {
202 ✔
173
    auto formalArguments = std::move(formalArgumentLists.top());
202 ✔
174
    formalArgumentLists.pop();
202 ✔
175
    return formalArguments;
202 ✔
176
}
177

178
void AbstractSyntaxTreeBuilderContext::pushArgumentsDeclaration(std::pair<FormalArguments, bool> argumentsDeclaration) {
90 ✔
179
    argumentsDeclarations.push(std::move(argumentsDeclaration));
90 ✔
180
}
90 ✔
181

182
std::pair<FormalArguments, bool> AbstractSyntaxTreeBuilderContext::popArgumentsDeclaration() {
90 ✔
183
    auto argumentsDeclaration = std::move(argumentsDeclarations.top());
90 ✔
184
    argumentsDeclarations.pop();
90 ✔
185
    return argumentsDeclaration;
90 ✔
186
}
187

188
void AbstractSyntaxTreeBuilderContext::pushDeclarationSpecifiers(DeclarationSpecifiers declarationSpecifiers) {
1,300 ✔
189
    declarationSpecifiersStack.push(std::move(declarationSpecifiers));
1,300 ✔
190
}
1,300 ✔
191

192
DeclarationSpecifiers AbstractSyntaxTreeBuilderContext::popDeclarationSpecifiers() {
1,298 ✔
193
    auto declarationSpecifiers = std::move(declarationSpecifiersStack.top());
1,298 ✔
194
    declarationSpecifiersStack.pop();
1,298 ✔
195
    return declarationSpecifiers;
1,298 ✔
196
}
197

198
void AbstractSyntaxTreeBuilderContext::pushDeclaration(std::unique_ptr<Declaration> declaration) {
574 ✔
199
    declarations.push(std::move(declaration));
574 ✔
200
}
574 ✔
201

202
void AbstractSyntaxTreeBuilderContext::newTypeQualifierList(type::Qualifier qualifier) {
×
203
    typeQualifierLists.push( { qualifier });
×
204
}
×
205

206
void AbstractSyntaxTreeBuilderContext::addToTypeQualifierList(type::Qualifier qualifier) {
×
207
    typeQualifierLists.top().push_back(qualifier);
×
208
}
×
209

210
std::vector<type::Qualifier> AbstractSyntaxTreeBuilderContext::popTypeQualifierList() {
×
211
    auto qualifiers = typeQualifierLists.top();
×
212
    typeQualifierLists.pop();
×
213
    return qualifiers;
×
214
}
215

216
std::unique_ptr<Declaration> AbstractSyntaxTreeBuilderContext::popDeclaration() {
574 ✔
217
    auto declaration = std::move(declarations.top());
574 ✔
218
    declarations.pop();
574 ✔
219
    return declaration;
574 ✔
220
}
221

222
void AbstractSyntaxTreeBuilderContext::newStatementList(std::unique_ptr<AbstractSyntaxTreeNode> statement) {
622 ✔
223
    std::vector<std::unique_ptr<AbstractSyntaxTreeNode>> statements;
622 ✔
224
    statements.push_back(std::move(statement));
622 ✔
225
    statementLists.push(std::move(statements));
622 ✔
226
}
622 ✔
227

228
void AbstractSyntaxTreeBuilderContext::addToStatementList(std::unique_ptr<AbstractSyntaxTreeNode> statement) {
1,436 ✔
229
    statementLists.top().push_back(std::move(statement));
1,436 ✔
230
}
1,436 ✔
231

232
std::vector<std::unique_ptr<AbstractSyntaxTreeNode>> AbstractSyntaxTreeBuilderContext::popStatementList() {
622 ✔
233
    auto statements = std::move(statementLists.top());
622 ✔
234
    statementLists.pop();
622 ✔
235
    return statements;
622 ✔
236
}
237

238
void AbstractSyntaxTreeBuilderContext::pushExternalDeclaration(std::unique_ptr<AbstractSyntaxTreeNode> externalDeclaration) {
674 ✔
239
    externalDeclarations.push(std::move(externalDeclaration));
674 ✔
240
}
674 ✔
241

242
std::unique_ptr<AbstractSyntaxTreeNode> AbstractSyntaxTreeBuilderContext::popExternalDeclaration() {
674 ✔
243
    auto externalDeclaration = std::move(externalDeclarations.top());
674 ✔
244
    externalDeclarations.pop();
674 ✔
245
    return externalDeclaration;
674 ✔
246
}
247

248
void AbstractSyntaxTreeBuilderContext::addToTranslationUnit(std::unique_ptr<AbstractSyntaxTreeNode> externalDeclaration) {
674 ✔
249
    translationUnit.push_back(std::move(externalDeclaration));
674 ✔
250
}
674 ✔
251

252
std::vector<std::unique_ptr<AbstractSyntaxTreeNode> > AbstractSyntaxTreeBuilderContext::popTranslationUnit() {
410 ✔
253
    return std::move(translationUnit);
410 ✔
254
}
255

NEW
256
void AbstractSyntaxTreeBuilderContext::newStructMemberList() {
×
NEW
257
    structMemberLists.push({});
×
NEW
258
}
×
259

260
void AbstractSyntaxTreeBuilderContext::addStructMember(std::string name, type::Type type) {
70 ✔
261
    if (structMemberLists.empty()) {
70 ✔
262
        structMemberLists.push({});
34 ✔
263
    }
264
    structMemberLists.top().emplace_back(std::move(name), std::move(type));
70 ✔
265
}
70 ✔
266

NEW
267
void AbstractSyntaxTreeBuilderContext::addStructMembersFromList(std::vector<std::pair<std::string, type::Type>> members) {
×
NEW
268
    for (auto& m : members) {
×
NEW
269
        structMemberLists.top().push_back(std::move(m));
×
270
    }
NEW
271
}
×
272

273
std::vector<std::pair<std::string, type::Type>> AbstractSyntaxTreeBuilderContext::popStructMemberList() {
34 ✔
274
    auto list = std::move(structMemberLists.top());
34 ✔
275
    structMemberLists.pop();
34 ✔
276
    return list;
34 ✔
277
}
278

NEW
279
void AbstractSyntaxTreeBuilderContext::pushStructMemberList(std::vector<std::pair<std::string, type::Type>> members) {
×
NEW
280
    structMemberLists.push(std::move(members));
×
NEW
281
}
×
282

283

284

NEW
285
std::optional<type::Type> AbstractSyntaxTreeBuilderContext::lookupStructTag(const std::string& tag) const {
×
NEW
286
    auto it = structTags.find(tag);
×
NEW
287
    if (it == structTags.end()) {
×
NEW
288
        return std::nullopt;
×
289
    }
NEW
290
    return it->second;
×
291
}
292

293

294
void AbstractSyntaxTreeBuilderContext::addStructDeclarator(std::unique_ptr<Declarator> declarator) {
70 ✔
295
    if (structDeclaratorLists.empty()) {
70 ✔
296
        structDeclaratorLists.push({});
70 ✔
297
    }
298
    structDeclaratorLists.top().push_back(std::move(declarator));
70 ✔
299
}
70 ✔
300

301
std::vector<std::unique_ptr<Declarator>> AbstractSyntaxTreeBuilderContext::popStructDeclarators() {
70 ✔
302
    if (structDeclaratorLists.empty()) {
70 ✔
NEW
303
        return {};
×
304
    }
305
    auto list = std::move(structDeclaratorLists.top());
70 ✔
306
    structDeclaratorLists.pop();
70 ✔
307
    return list;
70 ✔
308
}
70 ✔
309

310
type::Type AbstractSyntaxTreeBuilderContext::ensureStructTag(const std::string& tag) {
106 ✔
311
    auto it = structTags.find(tag);
106 ✔
312
    if (it != structTags.end()) {
106 ✔
313
        return it->second;
72 ✔
314
    }
315
    type::Type incomplete = type::incompleteStructure();
34 ✔
316
    structTags.insert_or_assign(tag, incomplete);
34 ✔
317
    return incomplete;
34 ✔
318
}
34 ✔
319

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

© 2026 Coveralls, Inc