• 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 · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc