Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
glslsemantic.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5
7#include "glslengine_p.h"
8#include "glslparser_p.h"
10#include "glsltypes_p.h"
11#include <QDebug>
12
13QT_BEGIN_NAMESPACE
14
15using namespace GLSL;
16
17Semantic::Semantic()
18 : _engine(nullptr)
19 , _scope(nullptr)
20 , _type(nullptr)
21{
22}
23
24Semantic::~Semantic()
25{
26}
27
28Engine *Semantic::switchEngine(Engine *engine)
29{
30 Engine *previousEngine = _engine;
31 _engine = engine;
32 return previousEngine;
33}
34
35Scope *Semantic::switchScope(Scope *scope)
36{
37 Scope *previousScope = _scope;
38 _scope = scope;
39 return previousScope;
40}
41
42Semantic::ExprResult Semantic::expression(ExpressionAST *ast)
43{
44 Semantic::ExprResult r(_engine->undefinedType());
45 std::swap(_expr, r);
46 accept(ast);
47 std::swap(_expr, r);
48 return r;
49}
50
51void Semantic::statement(StatementAST *ast)
52{
53 accept(ast);
54}
55
56const Type *Semantic::type(TypeAST *ast)
57{
58 const Type *t = _engine->undefinedType();
59 std::swap(_type, t);
60 accept(ast);
61 std::swap(_type, t);
62 return t;
63}
64
65void Semantic::declaration(DeclarationAST *ast)
66{
67 accept(ast);
68}
69
70void Semantic::translationUnit(TranslationUnitAST *ast, Scope *globalScope, Engine *engine)
71{
72 Engine *previousEngine = switchEngine(engine);
73 Scope *previousScope = switchScope(globalScope);
74 if (ast) {
75 for (List<DeclarationAST *> *it = ast->declarations; it; it = it->next) {
76 DeclarationAST *decl = it->value;
77 declaration(decl);
78 }
79 }
80 (void) switchScope(previousScope);
81 (void) switchEngine(previousEngine);
82}
83
84Semantic::ExprResult Semantic::expression(ExpressionAST *ast, Scope *scope, Engine *engine)
85{
86 ExprResult result(engine->undefinedType());
87 if (ast && scope) {
88 Engine *previousEngine = switchEngine(engine);
89 Scope *previousScope = switchScope(scope);
90 result = expression(ast);
91 (void) switchScope(previousScope);
92 (void) switchEngine(previousEngine);
93 }
94 return result;
95}
96
97Semantic::ExprResult Semantic::functionIdentifier(FunctionIdentifierAST *ast)
98{
99 ExprResult result;
100 if (ast) {
101 if (ast->name) {
102 if (Symbol *s = _scope->lookup(*ast->name)) {
103 if (s->asOverloadSet() != nullptr || s->asFunction() != nullptr)
104 result.type = s->type();
105 else
106 _engine->error(ast->lineno, QString::fromLatin1("`%1' cannot be used as a function").arg(*ast->name));
107 } else {
108 _engine->error(ast->lineno, QString::fromLatin1("`%1' was not declared in this scope").arg(*ast->name));
109 }
110 } else if (ast->type) {
111 const Type *ty = type(ast->type);
112 result.type = ty;
113 }
114 }
115
116 return result;
117}
118
119Symbol *Semantic::field(StructTypeAST::Field *ast)
120{
121 // ast->name
122 const Type *ty = type(ast->type);
123 QString name;
124 if (ast->name)
125 name = *ast->name;
126 return _engine->newVariable(_scope, name, ty);
127}
128
129void Semantic::parameterDeclaration(ParameterDeclarationAST *ast, Function *fun)
130{
131 const Type *ty = type(ast->type);
132 QString name;
133 if (ast->name)
134 name = *ast->name;
135 Argument *arg = _engine->newArgument(fun, name, ty);
136 fun->addArgument(arg);
137}
138
139bool Semantic::visit(TranslationUnitAST *ast)
140{
141 Q_UNUSED(ast)
142 Q_ASSERT(!"unreachable");
143 return false;
144}
145
146bool Semantic::visit(FunctionIdentifierAST *ast)
147{
148 Q_UNUSED(ast)
149 Q_ASSERT(!"unreachable");
150 return false;
151}
152
153bool Semantic::visit(StructTypeAST::Field *ast)
154{
155 Q_UNUSED(ast)
156 Q_ASSERT(!"unreachable");
157 return false;
158}
159
160
161// expressions
162bool Semantic::visit(IdentifierExpressionAST *ast)
163{
164 if (ast->name) {
165 if (Symbol *s = _scope->lookup(*ast->name))
166 _expr.type = s->type();
167 else
168 _engine->error(ast->lineno, QString::fromLatin1("`%1' was not declared in this scope").arg(*ast->name));
169 }
170 return false;
171}
172
173bool Semantic::visit(LiteralExpressionAST *ast)
174{
175 if (ast->value) {
176 _expr.isConstant = true;
177
178 if (ast->value->at(0) == QLatin1Char('t') && *ast->value == QLatin1String("true"))
179 _expr.type = _engine->boolType();
180 else if (ast->value->at(0) == QLatin1Char('f') && *ast->value == QLatin1String("false"))
181 _expr.type = _engine->boolType();
182 else if (ast->value->endsWith(QLatin1Char('u')) || ast->value->endsWith(QLatin1Char('U')))
183 _expr.type = _engine->uintType();
184 else if (ast->value->endsWith(QLatin1String("lf")) || ast->value->endsWith(QLatin1String("LF")))
185 _expr.type = _engine->doubleType();
186 else if (ast->value->endsWith(QLatin1Char('f')) || ast->value->endsWith(QLatin1Char('F')) || ast->value->contains(QLatin1Char('.')))
187 _expr.type = _engine->floatType();
188 else
189 _expr.type = _engine->intType();
190 }
191 return false;
192}
193
194bool Semantic::visit(BinaryExpressionAST *ast)
195{
196 ExprResult left = expression(ast->left);
197 ExprResult right = expression(ast->right);
198 _expr.isConstant = left.isConstant && right.isConstant;
199 switch (ast->kind) {
200 case AST::Kind_ArrayAccess:
201 if (left.type) {
202 if (const IndexType *idxType = left.type->asIndexType())
203 _expr = idxType->indexElementType();
204 else
205 _engine->error(ast->lineno, QString::fromLatin1("Invalid type `%1' for array subscript").arg(left.type->toString()));
206 }
207 break;
208
209 case AST::Kind_Modulus:
210 case AST::Kind_Multiply:
211 case AST::Kind_Divide:
212 case AST::Kind_Plus:
213 case AST::Kind_Minus:
214 case AST::Kind_ShiftLeft:
215 case AST::Kind_ShiftRight:
216 _expr.type = left.type; // ### not exactly
217 break;
218
219 case AST::Kind_LessThan:
220 case AST::Kind_GreaterThan:
221 case AST::Kind_LessEqual:
222 case AST::Kind_GreaterEqual:
223 case AST::Kind_Equal:
224 case AST::Kind_NotEqual:
225 case AST::Kind_BitwiseAnd:
226 case AST::Kind_BitwiseXor:
227 case AST::Kind_BitwiseOr:
228 case AST::Kind_LogicalAnd:
229 case AST::Kind_LogicalXor:
230 case AST::Kind_LogicalOr:
231 _expr.type = _engine->boolType();
232 break;
233
234 case AST::Kind_Comma:
235 _expr = right;
236 break;
237 }
238
239 return false;
240}
241
242bool Semantic::visit(UnaryExpressionAST *ast)
243{
244 ExprResult expr = expression(ast->expr);
245 _expr = expr;
246 return false;
247}
248
249bool Semantic::visit(TernaryExpressionAST *ast)
250{
251 ExprResult first = expression(ast->first);
252 ExprResult second = expression(ast->second);
253 ExprResult third = expression(ast->third);
254 _expr.isConstant = first.isConstant && second.isConstant && third.isConstant;
255 _expr.type = second.type;
256 return false;
257}
258
259bool Semantic::visit(AssignmentExpressionAST *ast)
260{
261 ExprResult variable = expression(ast->variable);
262 ExprResult value = expression(ast->value);
263 return false;
264}
265
266bool Semantic::visit(MemberAccessExpressionAST *ast)
267{
268 ExprResult expr = expression(ast->expr);
269 if (expr.type && ast->field) {
270 if (const VectorType *vecTy = expr.type->asVectorType()) {
271 if (Symbol *s = vecTy->find(*ast->field))
272 _expr.type = s->type();
273 else
274 _engine->error(ast->lineno, QString::fromLatin1("`%1' has no member named `%2'").arg(vecTy->name()).arg(*ast->field));
275 } else if (const Struct *structTy = expr.type->asStructType()) {
276 if (Symbol *s = structTy->find(*ast->field))
277 _expr.type = s->type();
278 else
279 _engine->error(ast->lineno, QString::fromLatin1("`%1' has no member named `%2'").arg(structTy->name()).arg(*ast->field));
280 } else {
281 _engine->error(ast->lineno, QString::fromLatin1("Requested for member `%1', in a non class or vec instance").arg(*ast->field));
282 }
283 }
284 return false;
285}
286
287bool Semantic::implicitCast(const Type *type, const Type *target) const
288{
289 if (! (type && target)) {
290 return false;
291 } else if (type->isEqualTo(target)) {
292 return true;
293 } else if (target->asUIntType() != nullptr) {
294 return type->asIntType() != nullptr;
295 } else if (target->asFloatType() != nullptr) {
296 return type->asIntType() != nullptr ||
297 type->asUIntType() != nullptr;
298 } else if (target->asDoubleType() != nullptr) {
299 return type->asIntType() != nullptr ||
300 type->asUIntType() != nullptr ||
301 type->asFloatType() != nullptr;
302 } else if (const VectorType *targetVecTy = target->asVectorType()) {
303 if (const VectorType *vecTy = type->asVectorType()) {
304 if (targetVecTy->dimension() == vecTy->dimension()) {
305 const Type *targetElementType = targetVecTy->elementType();
306 const Type *elementType = vecTy->elementType();
307
308 if (targetElementType->asUIntType() != nullptr) {
309 // uvec* -> ivec*
310 return elementType->asIntType() != nullptr;
311 } else if (targetElementType->asFloatType() != nullptr) {
312 // vec* -> ivec* | uvec*
313 return elementType->asIntType() != nullptr ||
314 elementType->asUIntType() != nullptr;
315 } else if (targetElementType->asDoubleType() != nullptr) {
316 // dvec* -> ivec* | uvec* | fvec*
317 return elementType->asIntType() != nullptr ||
318 elementType->asUIntType() != nullptr ||
319 elementType->asFloatType() != nullptr;
320 }
321 }
322 }
323 } else if (const MatrixType *targetMatTy = target->asMatrixType()) {
324 if (const MatrixType *matTy = type->asMatrixType()) {
325 if (targetMatTy->columns() == matTy->columns() &&
326 targetMatTy->rows() == matTy->rows()) {
327 const Type *targetElementType = targetMatTy->elementType();
328 const Type *elementType = matTy->elementType();
329
330 if (targetElementType->asDoubleType() != nullptr) {
331 // dmat* -> mat*
332 return elementType->asFloatType() != nullptr;
333 }
334 }
335 }
336 }
337
338 return false;
339}
340
341bool Semantic::visit(FunctionCallExpressionAST *ast)
342{
343 ExprResult expr = expression(ast->expr);
344 ExprResult id = functionIdentifier(ast->id);
345 QVector<ExprResult> actuals;
346 for (List<ExpressionAST *> *it = ast->arguments; it; it = it->next) {
347 ExprResult arg = expression(it->value);
348 actuals.append(arg);
349 }
350 if (id.isValid()) {
351 if (const Function *funTy = id.type->asFunctionType()) {
352 if (actuals.size() < funTy->argumentCount())
353 _engine->error(ast->lineno, QString::fromLatin1("not enough arguments"));
354 else if (actuals.size() > funTy->argumentCount())
355 _engine->error(ast->lineno, QString::fromLatin1("too many arguments"));
356 _expr.type = funTy->returnType();
357 } else if (const OverloadSet *overloads = id.type->asOverloadSetType()) {
358 QVector<Function *> candidates;
359 const auto functions = overloads->functions();
360 for (Function *f : functions) {
361 if (f->argumentCount() == actuals.size()) {
362 int argc = 0;
363 for (; argc < actuals.size(); ++argc) {
364 const Type *actualTy = actuals.at(argc).type;
365 const Type *argumentTy = f->argumentAt(argc)->type();
366 if (! implicitCast(actualTy, argumentTy))
367 break;
368 }
369
370 if (argc == actuals.size())
371 candidates.append(f);
372 }
373 }
374
375 if (candidates.isEmpty()) {
376 // ### error, unresolved call.
377 Q_ASSERT(!functions.isEmpty());
378
379 _expr.type = functions.front()->returnType();
380 } else {
381 _expr.type = candidates.constFirst()->returnType();
382
383 if (candidates.size() != 1) {
384 // ### error, ambiguous call
385 }
386 }
387 } else {
388 // called as constructor, e.g. vec2(a, b)
389 _expr.type = id.type;
390 }
391 }
392
393 return false;
394}
395
396bool Semantic::visit(DeclarationExpressionAST *ast)
397{
398 const Type *ty = type(ast->type);
399 Q_UNUSED(ty)
400 // ast->name
401 ExprResult initializer = expression(ast->initializer);
402 return false;
403}
404
405
406// statements
407bool Semantic::visit(ExpressionStatementAST *ast)
408{
409 ExprResult expr = expression(ast->expr);
410 return false;
411}
412
413bool Semantic::visit(CompoundStatementAST *ast)
414{
415 Block *block = _engine->newBlock(_scope);
416 Scope *previousScope = switchScope(block);
417 ast->symbol = block;
418 for (List<StatementAST *> *it = ast->statements; it; it = it->next) {
419 StatementAST *stmt = it->value;
420 statement(stmt);
421 }
422 (void) switchScope(previousScope);
423 return false;
424}
425
426bool Semantic::visit(IfStatementAST *ast)
427{
428 ExprResult condition = expression(ast->condition);
429 statement(ast->thenClause);
430 statement(ast->elseClause);
431 return false;
432}
433
434bool Semantic::visit(WhileStatementAST *ast)
435{
436 ExprResult condition = expression(ast->condition);
437 statement(ast->body);
438 return false;
439}
440
441bool Semantic::visit(DoStatementAST *ast)
442{
443 statement(ast->body);
444 ExprResult condition = expression(ast->condition);
445 return false;
446}
447
448bool Semantic::visit(ForStatementAST *ast)
449{
450 statement(ast->init);
451 ExprResult condition = expression(ast->condition);
452 ExprResult increment = expression(ast->increment);
453 statement(ast->body);
454 return false;
455}
456
457bool Semantic::visit(JumpStatementAST *ast)
458{
459 Q_UNUSED(ast)
460 return false;
461}
462
463bool Semantic::visit(ReturnStatementAST *ast)
464{
465 ExprResult expr = expression(ast->expr);
466 return false;
467}
468
469bool Semantic::visit(SwitchStatementAST *ast)
470{
471 ExprResult expr = expression(ast->expr);
472 statement(ast->body);
473 return false;
474}
475
476bool Semantic::visit(CaseLabelStatementAST *ast)
477{
478 ExprResult expr = expression(ast->expr);
479 return false;
480}
481
482bool Semantic::visit(DeclarationStatementAST *ast)
483{
484 declaration(ast->decl);
485 return false;
486}
487
488
489// types
490bool Semantic::visit(BasicTypeAST *ast)
491{
492 switch (ast->token) {
493 case Parser::T_VOID:
494 _type = _engine->voidType();
495 break;
496
497 case Parser::T_BOOL:
498 _type = _engine->boolType();
499 break;
500
501 case Parser::T_INT:
502 _type = _engine->intType();
503 break;
504
505 case Parser::T_UINT:
506 _type = _engine->uintType();
507 break;
508
509 case Parser::T_FLOAT:
510 _type = _engine->floatType();
511 break;
512
513 case Parser::T_DOUBLE:
514 _type = _engine->doubleType();
515 break;
516
517 // bvec
518 case Parser::T_BVEC2:
519 _type = _engine->vectorType(_engine->boolType(), 2);
520 break;
521
522 case Parser::T_BVEC3:
523 _type = _engine->vectorType(_engine->boolType(), 3);
524 break;
525
526 case Parser::T_BVEC4:
527 _type = _engine->vectorType(_engine->boolType(), 4);
528 break;
529
530 // ivec
531 case Parser::T_IVEC2:
532 _type = _engine->vectorType(_engine->intType(), 2);
533 break;
534
535 case Parser::T_IVEC3:
536 _type = _engine->vectorType(_engine->intType(), 3);
537 break;
538
539 case Parser::T_IVEC4:
540 _type = _engine->vectorType(_engine->intType(), 4);
541 break;
542
543 // uvec
544 case Parser::T_UVEC2:
545 _type = _engine->vectorType(_engine->uintType(), 2);
546 break;
547
548 case Parser::T_UVEC3:
549 _type = _engine->vectorType(_engine->uintType(), 3);
550 break;
551
552 case Parser::T_UVEC4:
553 _type = _engine->vectorType(_engine->uintType(), 4);
554 break;
555
556 // vec
557 case Parser::T_VEC2:
558 _type = _engine->vectorType(_engine->floatType(), 2);
559 break;
560
561 case Parser::T_VEC3:
562 _type = _engine->vectorType(_engine->floatType(), 3);
563 break;
564
565 case Parser::T_VEC4:
566 _type = _engine->vectorType(_engine->floatType(), 4);
567 break;
568
569 // dvec
570 case Parser::T_DVEC2:
571 _type = _engine->vectorType(_engine->doubleType(), 2);
572 break;
573
574 case Parser::T_DVEC3:
575 _type = _engine->vectorType(_engine->doubleType(), 3);
576 break;
577
578 case Parser::T_DVEC4:
579 _type = _engine->vectorType(_engine->doubleType(), 4);
580 break;
581
582 // mat2
583 case Parser::T_MAT2:
584 case Parser::T_MAT2X2:
585 _type = _engine->matrixType(_engine->floatType(), 2, 2);
586 break;
587
588 case Parser::T_MAT2X3:
589 _type = _engine->matrixType(_engine->floatType(), 2, 3);
590 break;
591
592 case Parser::T_MAT2X4:
593 _type = _engine->matrixType(_engine->floatType(), 2, 4);
594 break;
595
596 // mat3
597 case Parser::T_MAT3X2:
598 _type = _engine->matrixType(_engine->floatType(), 3, 2);
599 break;
600
601 case Parser::T_MAT3:
602 case Parser::T_MAT3X3:
603 _type = _engine->matrixType(_engine->floatType(), 3, 3);
604 break;
605
606 case Parser::T_MAT3X4:
607 _type = _engine->matrixType(_engine->floatType(), 3, 4);
608 break;
609
610 // mat4
611 case Parser::T_MAT4X2:
612 _type = _engine->matrixType(_engine->floatType(), 4, 2);
613 break;
614
615 case Parser::T_MAT4X3:
616 _type = _engine->matrixType(_engine->floatType(), 4, 3);
617 break;
618
619 case Parser::T_MAT4:
620 case Parser::T_MAT4X4:
621 _type = _engine->matrixType(_engine->floatType(), 4, 4);
622 break;
623
624
625 // dmat2
626 case Parser::T_DMAT2:
627 case Parser::T_DMAT2X2:
628 _type = _engine->matrixType(_engine->doubleType(), 2, 2);
629 break;
630
631 case Parser::T_DMAT2X3:
632 _type = _engine->matrixType(_engine->doubleType(), 2, 3);
633 break;
634
635 case Parser::T_DMAT2X4:
636 _type = _engine->matrixType(_engine->doubleType(), 2, 4);
637 break;
638
639 // dmat3
640 case Parser::T_DMAT3X2:
641 _type = _engine->matrixType(_engine->doubleType(), 3, 2);
642 break;
643
644 case Parser::T_DMAT3:
645 case Parser::T_DMAT3X3:
646 _type = _engine->matrixType(_engine->doubleType(), 3, 3);
647 break;
648
649 case Parser::T_DMAT3X4:
650 _type = _engine->matrixType(_engine->doubleType(), 3, 4);
651 break;
652
653 // dmat4
654 case Parser::T_DMAT4X2:
655 _type = _engine->matrixType(_engine->doubleType(), 4, 2);
656 break;
657
658 case Parser::T_DMAT4X3:
659 _type = _engine->matrixType(_engine->doubleType(), 4, 3);
660 break;
661
662 case Parser::T_DMAT4:
663 case Parser::T_DMAT4X4:
664 _type = _engine->matrixType(_engine->doubleType(), 4, 4);
665 break;
666
667 // samplers
668 case Parser::T_SAMPLER1D:
669 case Parser::T_SAMPLER2D:
670 case Parser::T_SAMPLER3D:
671 case Parser::T_SAMPLERCUBE:
672 case Parser::T_SAMPLER1DSHADOW:
673 case Parser::T_SAMPLER2DSHADOW:
674 case Parser::T_SAMPLERCUBESHADOW:
675 case Parser::T_SAMPLER1DARRAY:
676 case Parser::T_SAMPLER2DARRAY:
677 case Parser::T_SAMPLER1DARRAYSHADOW:
678 case Parser::T_SAMPLER2DARRAYSHADOW:
679 case Parser::T_SAMPLERCUBEARRAY:
680 case Parser::T_SAMPLERCUBEARRAYSHADOW:
681 case Parser::T_SAMPLER2DRECT:
682 case Parser::T_SAMPLER2DRECTSHADOW:
683 case Parser::T_SAMPLERBUFFER:
684 case Parser::T_SAMPLER2DMS:
685 case Parser::T_SAMPLER2DMSARRAY:
686 case Parser::T_ISAMPLER1D:
687 case Parser::T_ISAMPLER2D:
688 case Parser::T_ISAMPLER3D:
689 case Parser::T_ISAMPLERCUBE:
690 case Parser::T_ISAMPLER1DARRAY:
691 case Parser::T_ISAMPLER2DARRAY:
692 case Parser::T_ISAMPLERCUBEARRAY:
693 case Parser::T_ISAMPLER2DRECT:
694 case Parser::T_ISAMPLERBUFFER:
695 case Parser::T_ISAMPLER2DMS:
696 case Parser::T_ISAMPLER2DMSARRAY:
697 case Parser::T_USAMPLER1D:
698 case Parser::T_USAMPLER2D:
699 case Parser::T_USAMPLER3D:
700 case Parser::T_USAMPLERCUBE:
701 case Parser::T_USAMPLER1DARRAY:
702 case Parser::T_USAMPLER2DARRAY:
703 case Parser::T_USAMPLERCUBEARRAY:
704 case Parser::T_USAMPLER2DRECT:
705 case Parser::T_USAMPLERBUFFER:
706 case Parser::T_USAMPLER2DMS:
707 case Parser::T_USAMPLER2DMSARRAY:
708 _type = _engine->samplerType(ast->token);
709 break;
710
711 default:
712 _engine->error(ast->lineno, QString::fromLatin1("Unknown type `%1'").arg(QLatin1String(GLSLParserTable::spell[ast->token])));
713 }
714
715 return false;
716}
717
718bool Semantic::visit(NamedTypeAST *ast)
719{
720 if (ast->name) {
721 if (Symbol *s = _scope->lookup(*ast->name)) {
722 if (Struct *ty = s->asStruct()) {
723 _type = ty;
724 return false;
725 }
726 }
727 _engine->error(ast->lineno, QString::fromLatin1("Undefined type `%1'").arg(*ast->name));
728 }
729
730 return false;
731}
732
733bool Semantic::visit(ArrayTypeAST *ast)
734{
735 const Type *elementType = type(ast->elementType);
736 Q_UNUSED(elementType)
737 ExprResult size = expression(ast->size);
738 _type = _engine->arrayType(elementType); // ### ignore the size for now
739 return false;
740}
741
742bool Semantic::visit(StructTypeAST *ast)
743{
744 Struct *s = _engine->newStruct(_scope);
745 if (ast->name)
746 s->setName(*ast->name);
747 if (Scope *e = s->scope())
748 e->add(s);
749 Scope *previousScope = switchScope(s);
750 for (List<StructTypeAST::Field *> *it = ast->fields; it; it = it->next) {
751 StructTypeAST::Field *f = it->value;
752 if (Symbol *member = field(f))
753 s->add(member);
754 }
755 (void) switchScope(previousScope);
756 return false;
757}
758
759bool Semantic::visit(QualifiedTypeAST *ast)
760{
761 _type = type(ast->type);
762 for (List<LayoutQualifierAST *> *it = ast->layout_list; it; it = it->next) {
763 LayoutQualifierAST *q = it->value;
764 // q->name;
765 // q->number;
766 Q_UNUSED(q)
767 }
768 return false;
769}
770
771
772// declarations
773bool Semantic::visit(PrecisionDeclarationAST *ast)
774{
775 const Type *ty = type(ast->type);
776 Q_UNUSED(ty)
777 return false;
778}
779
780bool Semantic::visit(ParameterDeclarationAST *ast)
781{
782 Q_UNUSED(ast)
783 Q_ASSERT(!"unreachable");
784 return false;
785}
786
787bool Semantic::visit(VariableDeclarationAST *ast)
788{
789 if (!ast->type)
790 return false;
791
792 const Type *ty = type(ast->type);
793 ExprResult initializer = expression(ast->initializer);
794 if (ast->name) {
795 QualifiedTypeAST *qtype = ast->type->asQualifiedType();
796 int qualifiers = 0;
797 if (qtype)
798 qualifiers = qtype->qualifiers;
799 Variable *var = _engine->newVariable(_scope, *ast->name, ty, qualifiers);
800 _scope->add(var);
801 }
802 return false;
803}
804
805bool Semantic::visit(TypeDeclarationAST *ast)
806{
807 const Type *ty = type(ast->type);
808 Q_UNUSED(ty)
809 return false;
810}
811
812bool Semantic::visit(TypeAndVariableDeclarationAST *ast)
813{
814 declaration(ast->typeDecl);
815 declaration(ast->varDecl);
816 return false;
817}
818
819bool Semantic::visit(InvariantDeclarationAST *ast)
820{
821 Q_UNUSED(ast)
822 return false;
823}
824
825bool Semantic::visit(InitDeclarationAST *ast)
826{
827 for (List<DeclarationAST *> *it = ast->decls; it; it = it->next) {
828 DeclarationAST *decl = it->value;
829 declaration(decl);
830 }
831 return false;
832}
833
834bool Semantic::visit(FunctionDeclarationAST *ast)
835{
836 Function *fun = _engine->newFunction(_scope);
837 if (ast->name)
838 fun->setName(*ast->name);
839
840 fun->setReturnType(type(ast->returnType));
841
842 for (List<ParameterDeclarationAST *> *it = ast->params; it; it = it->next) {
843 ParameterDeclarationAST *decl = it->value;
844 parameterDeclaration(decl, fun);
845 }
846
847 if (Scope *enclosingScope = fun->scope())
848 enclosingScope->add(fun);
849
850 Scope *previousScope = switchScope(fun);
851 statement(ast->body);
852 (void) switchScope(previousScope);
853 return false;
854}
855
856QT_END_NAMESPACE