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 const auto functions = overloads->functions();
358 for (Function *f : functions) {
359 if (f->argumentCount() == actuals.size()) {
360 int argc = 0;
361 for (; argc < actuals.size(); ++argc) {
362 const Type *actualTy = actuals.at(i: argc).type;
363 const Type *argumentTy = f->argumentAt(index: argc)->type();
364 if (! implicitCast(type: actualTy, target: argumentTy))
365 break;
366 }
367
368 if (argc == actuals.size())
369 candidates.append(t: f);
370 }
371 }
372
373 if (candidates.isEmpty()) {
374 // ### error, unresolved call.
375 Q_ASSERT(!functions.isEmpty());
376
377 _expr.type = functions.front()->returnType();
378 } else {
379 _expr.type = candidates.constFirst()->returnType();
380
381 if (candidates.size() != 1) {
382 // ### error, ambiguous call
383 }
384 }
385 } else {
386 // called as constructor, e.g. vec2(a, b)
387 _expr.type = id.type;
388 }
389 }
390
391 return false;
392}
393
394bool Semantic::visit(DeclarationExpressionAST *ast)
395{
396 const Type *ty = type(ast: ast->type);
397 Q_UNUSED(ty)
398 // ast->name
399 ExprResult initializer = expression(ast: ast->initializer);
400 return false;
401}
402
403
404// statements
405bool Semantic::visit(ExpressionStatementAST *ast)
406{
407 ExprResult expr = expression(ast: ast->expr);
408 return false;
409}
410
411bool Semantic::visit(CompoundStatementAST *ast)
412{
413 Block *block = _engine->newBlock(scope: _scope);
414 Scope *previousScope = switchScope(scope: block);
415 ast->symbol = block;
416 for (List<StatementAST *> *it = ast->statements; it; it = it->next) {
417 StatementAST *stmt = it->value;
418 statement(ast: stmt);
419 }
420 (void) switchScope(scope: previousScope);
421 return false;
422}
423
424bool Semantic::visit(IfStatementAST *ast)
425{
426 ExprResult condition = expression(ast: ast->condition);
427 statement(ast: ast->thenClause);
428 statement(ast: ast->elseClause);
429 return false;
430}
431
432bool Semantic::visit(WhileStatementAST *ast)
433{
434 ExprResult condition = expression(ast: ast->condition);
435 statement(ast: ast->body);
436 return false;
437}
438
439bool Semantic::visit(DoStatementAST *ast)
440{
441 statement(ast: ast->body);
442 ExprResult condition = expression(ast: ast->condition);
443 return false;
444}
445
446bool Semantic::visit(ForStatementAST *ast)
447{
448 statement(ast: ast->init);
449 ExprResult condition = expression(ast: ast->condition);
450 ExprResult increment = expression(ast: ast->increment);
451 statement(ast: ast->body);
452 return false;
453}
454
455bool Semantic::visit(JumpStatementAST *ast)
456{
457 Q_UNUSED(ast)
458 return false;
459}
460
461bool Semantic::visit(ReturnStatementAST *ast)
462{
463 ExprResult expr = expression(ast: ast->expr);
464 return false;
465}
466
467bool Semantic::visit(SwitchStatementAST *ast)
468{
469 ExprResult expr = expression(ast: ast->expr);
470 statement(ast: ast->body);
471 return false;
472}
473
474bool Semantic::visit(CaseLabelStatementAST *ast)
475{
476 ExprResult expr = expression(ast: ast->expr);
477 return false;
478}
479
480bool Semantic::visit(DeclarationStatementAST *ast)
481{
482 declaration(ast: ast->decl);
483 return false;
484}
485
486
487// types
488bool Semantic::visit(BasicTypeAST *ast)
489{
490 switch (ast->token) {
491 case Parser::T_VOID:
492 _type = _engine->voidType();
493 break;
494
495 case Parser::T_BOOL:
496 _type = _engine->boolType();
497 break;
498
499 case Parser::T_INT:
500 _type = _engine->intType();
501 break;
502
503 case Parser::T_UINT:
504 _type = _engine->uintType();
505 break;
506
507 case Parser::T_FLOAT:
508 _type = _engine->floatType();
509 break;
510
511 case Parser::T_DOUBLE:
512 _type = _engine->doubleType();
513 break;
514
515 // bvec
516 case Parser::T_BVEC2:
517 _type = _engine->vectorType(elementType: _engine->boolType(), dimension: 2);
518 break;
519
520 case Parser::T_BVEC3:
521 _type = _engine->vectorType(elementType: _engine->boolType(), dimension: 3);
522 break;
523
524 case Parser::T_BVEC4:
525 _type = _engine->vectorType(elementType: _engine->boolType(), dimension: 4);
526 break;
527
528 // ivec
529 case Parser::T_IVEC2:
530 _type = _engine->vectorType(elementType: _engine->intType(), dimension: 2);
531 break;
532
533 case Parser::T_IVEC3:
534 _type = _engine->vectorType(elementType: _engine->intType(), dimension: 3);
535 break;
536
537 case Parser::T_IVEC4:
538 _type = _engine->vectorType(elementType: _engine->intType(), dimension: 4);
539 break;
540
541 // uvec
542 case Parser::T_UVEC2:
543 _type = _engine->vectorType(elementType: _engine->uintType(), dimension: 2);
544 break;
545
546 case Parser::T_UVEC3:
547 _type = _engine->vectorType(elementType: _engine->uintType(), dimension: 3);
548 break;
549
550 case Parser::T_UVEC4:
551 _type = _engine->vectorType(elementType: _engine->uintType(), dimension: 4);
552 break;
553
554 // vec
555 case Parser::T_VEC2:
556 _type = _engine->vectorType(elementType: _engine->floatType(), dimension: 2);
557 break;
558
559 case Parser::T_VEC3:
560 _type = _engine->vectorType(elementType: _engine->floatType(), dimension: 3);
561 break;
562
563 case Parser::T_VEC4:
564 _type = _engine->vectorType(elementType: _engine->floatType(), dimension: 4);
565 break;
566
567 // dvec
568 case Parser::T_DVEC2:
569 _type = _engine->vectorType(elementType: _engine->doubleType(), dimension: 2);
570 break;
571
572 case Parser::T_DVEC3:
573 _type = _engine->vectorType(elementType: _engine->doubleType(), dimension: 3);
574 break;
575
576 case Parser::T_DVEC4:
577 _type = _engine->vectorType(elementType: _engine->doubleType(), dimension: 4);
578 break;
579
580 // mat2
581 case Parser::T_MAT2:
582 case Parser::T_MAT2X2:
583 _type = _engine->matrixType(elementType: _engine->floatType(), columns: 2, rows: 2);
584 break;
585
586 case Parser::T_MAT2X3:
587 _type = _engine->matrixType(elementType: _engine->floatType(), columns: 2, rows: 3);
588 break;
589
590 case Parser::T_MAT2X4:
591 _type = _engine->matrixType(elementType: _engine->floatType(), columns: 2, rows: 4);
592 break;
593
594 // mat3
595 case Parser::T_MAT3X2:
596 _type = _engine->matrixType(elementType: _engine->floatType(), columns: 3, rows: 2);
597 break;
598
599 case Parser::T_MAT3:
600 case Parser::T_MAT3X3:
601 _type = _engine->matrixType(elementType: _engine->floatType(), columns: 3, rows: 3);
602 break;
603
604 case Parser::T_MAT3X4:
605 _type = _engine->matrixType(elementType: _engine->floatType(), columns: 3, rows: 4);
606 break;
607
608 // mat4
609 case Parser::T_MAT4X2:
610 _type = _engine->matrixType(elementType: _engine->floatType(), columns: 4, rows: 2);
611 break;
612
613 case Parser::T_MAT4X3:
614 _type = _engine->matrixType(elementType: _engine->floatType(), columns: 4, rows: 3);
615 break;
616
617 case Parser::T_MAT4:
618 case Parser::T_MAT4X4:
619 _type = _engine->matrixType(elementType: _engine->floatType(), columns: 4, rows: 4);
620 break;
621
622
623 // dmat2
624 case Parser::T_DMAT2:
625 case Parser::T_DMAT2X2:
626 _type = _engine->matrixType(elementType: _engine->doubleType(), columns: 2, rows: 2);
627 break;
628
629 case Parser::T_DMAT2X3:
630 _type = _engine->matrixType(elementType: _engine->doubleType(), columns: 2, rows: 3);
631 break;
632
633 case Parser::T_DMAT2X4:
634 _type = _engine->matrixType(elementType: _engine->doubleType(), columns: 2, rows: 4);
635 break;
636
637 // dmat3
638 case Parser::T_DMAT3X2:
639 _type = _engine->matrixType(elementType: _engine->doubleType(), columns: 3, rows: 2);
640 break;
641
642 case Parser::T_DMAT3:
643 case Parser::T_DMAT3X3:
644 _type = _engine->matrixType(elementType: _engine->doubleType(), columns: 3, rows: 3);
645 break;
646
647 case Parser::T_DMAT3X4:
648 _type = _engine->matrixType(elementType: _engine->doubleType(), columns: 3, rows: 4);
649 break;
650
651 // dmat4
652 case Parser::T_DMAT4X2:
653 _type = _engine->matrixType(elementType: _engine->doubleType(), columns: 4, rows: 2);
654 break;
655
656 case Parser::T_DMAT4X3:
657 _type = _engine->matrixType(elementType: _engine->doubleType(), columns: 4, rows: 3);
658 break;
659
660 case Parser::T_DMAT4:
661 case Parser::T_DMAT4X4:
662 _type = _engine->matrixType(elementType: _engine->doubleType(), columns: 4, rows: 4);
663 break;
664
665 // samplers
666 case Parser::T_SAMPLER1D:
667 case Parser::T_SAMPLER2D:
668 case Parser::T_SAMPLER3D:
669 case Parser::T_SAMPLERCUBE:
670 case Parser::T_SAMPLER1DSHADOW:
671 case Parser::T_SAMPLER2DSHADOW:
672 case Parser::T_SAMPLERCUBESHADOW:
673 case Parser::T_SAMPLER1DARRAY:
674 case Parser::T_SAMPLER2DARRAY:
675 case Parser::T_SAMPLER1DARRAYSHADOW:
676 case Parser::T_SAMPLER2DARRAYSHADOW:
677 case Parser::T_SAMPLERCUBEARRAY:
678 case Parser::T_SAMPLERCUBEARRAYSHADOW:
679 case Parser::T_SAMPLER2DRECT:
680 case Parser::T_SAMPLER2DRECTSHADOW:
681 case Parser::T_SAMPLERBUFFER:
682 case Parser::T_SAMPLER2DMS:
683 case Parser::T_SAMPLER2DMSARRAY:
684 case Parser::T_ISAMPLER1D:
685 case Parser::T_ISAMPLER2D:
686 case Parser::T_ISAMPLER3D:
687 case Parser::T_ISAMPLERCUBE:
688 case Parser::T_ISAMPLER1DARRAY:
689 case Parser::T_ISAMPLER2DARRAY:
690 case Parser::T_ISAMPLERCUBEARRAY:
691 case Parser::T_ISAMPLER2DRECT:
692 case Parser::T_ISAMPLERBUFFER:
693 case Parser::T_ISAMPLER2DMS:
694 case Parser::T_ISAMPLER2DMSARRAY:
695 case Parser::T_USAMPLER1D:
696 case Parser::T_USAMPLER2D:
697 case Parser::T_USAMPLER3D:
698 case Parser::T_USAMPLERCUBE:
699 case Parser::T_USAMPLER1DARRAY:
700 case Parser::T_USAMPLER2DARRAY:
701 case Parser::T_USAMPLERCUBEARRAY:
702 case Parser::T_USAMPLER2DRECT:
703 case Parser::T_USAMPLERBUFFER:
704 case Parser::T_USAMPLER2DMS:
705 case Parser::T_USAMPLER2DMSARRAY:
706 _type = _engine->samplerType(kind: ast->token);
707 break;
708
709 default:
710 _engine->error(line: ast->lineno, message: QString::fromLatin1(ba: "Unknown type `%1'").arg(a: QLatin1String(GLSLParserTable::spell[ast->token])));
711 }
712
713 return false;
714}
715
716bool Semantic::visit(NamedTypeAST *ast)
717{
718 if (ast->name) {
719 if (Symbol *s = _scope->lookup(name: *ast->name)) {
720 if (Struct *ty = s->asStruct()) {
721 _type = ty;
722 return false;
723 }
724 }
725 _engine->error(line: ast->lineno, message: QString::fromLatin1(ba: "Undefined type `%1'").arg(a: *ast->name));
726 }
727
728 return false;
729}
730
731bool Semantic::visit(ArrayTypeAST *ast)
732{
733 const Type *elementType = type(ast: ast->elementType);
734 Q_UNUSED(elementType)
735 ExprResult size = expression(ast: ast->size);
736 _type = _engine->arrayType(elementType); // ### ignore the size for now
737 return false;
738}
739
740bool Semantic::visit(StructTypeAST *ast)
741{
742 Struct *s = _engine->newStruct(scope: _scope);
743 if (ast->name)
744 s->setName(*ast->name);
745 if (Scope *e = s->scope())
746 e->add(symbol: s);
747 Scope *previousScope = switchScope(scope: s);
748 for (List<StructTypeAST::Field *> *it = ast->fields; it; it = it->next) {
749 StructTypeAST::Field *f = it->value;
750 if (Symbol *member = field(ast: f))
751 s->add(member);
752 }
753 (void) switchScope(scope: previousScope);
754 return false;
755}
756
757bool Semantic::visit(QualifiedTypeAST *ast)
758{
759 _type = type(ast: ast->type);
760 for (List<LayoutQualifierAST *> *it = ast->layout_list; it; it = it->next) {
761 LayoutQualifierAST *q = it->value;
762 // q->name;
763 // q->number;
764 Q_UNUSED(q)
765 }
766 return false;
767}
768
769
770// declarations
771bool Semantic::visit(PrecisionDeclarationAST *ast)
772{
773 const Type *ty = type(ast: ast->type);
774 Q_UNUSED(ty)
775 return false;
776}
777
778bool Semantic::visit(ParameterDeclarationAST *ast)
779{
780 Q_UNUSED(ast)
781 Q_ASSERT(!"unreachable");
782 return false;
783}
784
785bool Semantic::visit(VariableDeclarationAST *ast)
786{
787 if (!ast->type)
788 return false;
789
790 const Type *ty = type(ast: ast->type);
791 ExprResult initializer = expression(ast: ast->initializer);
792 if (ast->name) {
793 QualifiedTypeAST *qtype = ast->type->asQualifiedType();
794 int qualifiers = 0;
795 if (qtype)
796 qualifiers = qtype->qualifiers;
797 Variable *var = _engine->newVariable(scope: _scope, name: *ast->name, type: ty, qualifiers);
798 _scope->add(symbol: var);
799 }
800 return false;
801}
802
803bool Semantic::visit(TypeDeclarationAST *ast)
804{
805 const Type *ty = type(ast: ast->type);
806 Q_UNUSED(ty)
807 return false;
808}
809
810bool Semantic::visit(TypeAndVariableDeclarationAST *ast)
811{
812 declaration(ast: ast->typeDecl);
813 declaration(ast: ast->varDecl);
814 return false;
815}
816
817bool Semantic::visit(InvariantDeclarationAST *ast)
818{
819 Q_UNUSED(ast)
820 return false;
821}
822
823bool Semantic::visit(InitDeclarationAST *ast)
824{
825 for (List<DeclarationAST *> *it = ast->decls; it; it = it->next) {
826 DeclarationAST *decl = it->value;
827 declaration(ast: decl);
828 }
829 return false;
830}
831
832bool Semantic::visit(FunctionDeclarationAST *ast)
833{
834 Function *fun = _engine->newFunction(scope: _scope);
835 if (ast->name)
836 fun->setName(*ast->name);
837
838 fun->setReturnType(type(ast: ast->returnType));
839
840 for (List<ParameterDeclarationAST *> *it = ast->params; it; it = it->next) {
841 ParameterDeclarationAST *decl = it->value;
842 parameterDeclaration(ast: decl, fun);
843 }
844
845 if (Scope *enclosingScope = fun->scope())
846 enclosingScope->add(symbol: fun);
847
848 Scope *previousScope = switchScope(scope: fun);
849 statement(ast: ast->body);
850 (void) switchScope(scope: previousScope);
851 return false;
852}
853
854QT_END_NAMESPACE
855

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

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