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

source code of qtquick3d/src/glslparser/glslsemantic.cpp