Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
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
12
13using namespace GLSL;
14
16 : _engine(nullptr)
17 , _scope(nullptr)
18 , _type(nullptr)
19{
20}
21
25
27{
28 Engine *previousEngine = _engine;
29 _engine = engine;
30 return previousEngine;
31}
32
34{
35 Scope *previousScope = _scope;
36 _scope = scope;
37 return previousScope;
38}
39
41{
43 std::swap(_expr, r);
44 accept(ast);
45 std::swap(_expr, r);
46 return r;
47}
48
50{
51 accept(ast);
52}
53
55{
56 const Type *t = _engine->undefinedType();
57 std::swap(_type, t);
58 accept(ast);
59 std::swap(_type, t);
60 return t;
61}
62
64{
65 accept(ast);
66}
67
69{
70 Engine *previousEngine = switchEngine(engine);
71 Scope *previousScope = switchScope(globalScope);
72 if (ast) {
73 for (List<DeclarationAST *> *it = ast->declarations; it; it = it->next) {
74 DeclarationAST *decl = it->value;
75 declaration(decl);
76 }
77 }
78 (void) switchScope(previousScope);
79 (void) switchEngine(previousEngine);
80}
81
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(previousScope);
90 (void) switchEngine(previousEngine);
91 }
92 return result;
93}
94
96{
98 if (ast) {
99 if (ast->name) {
100 if (Symbol *s = _scope->lookup(*ast->name)) {
101 if (s->asOverloadSet() != nullptr || s->asFunction() != nullptr)
102 result.type = s->type();
103 else
104 _engine->error(ast->lineno, QString::fromLatin1("`%1' cannot be used as a function").arg(*ast->name));
105 } else {
106 _engine->error(ast->lineno, QString::fromLatin1("`%1' was not declared in this scope").arg(*ast->name));
107 }
108 } else if (ast->type) {
109 const Type *ty = type(ast->type);
110 result.type = ty;
111 }
112 }
113
114 return result;
115}
116
118{
119 // ast->name
120 const Type *ty = type(ast->type);
122 if (ast->name)
123 name = *ast->name;
124 return _engine->newVariable(_scope, name, ty);
125}
126
128{
129 const Type *ty = type(ast->type);
131 if (ast->name)
132 name = *ast->name;
133 Argument *arg = _engine->newArgument(fun, name, ty);
134 fun->addArgument(arg);
135}
136
138{
139 Q_UNUSED(ast)
140 Q_ASSERT(!"unreachable");
141 return false;
142}
143
145{
146 Q_UNUSED(ast)
147 Q_ASSERT(!"unreachable");
148 return false;
149}
150
152{
153 Q_UNUSED(ast)
154 Q_ASSERT(!"unreachable");
155 return false;
156}
157
158
159// expressions
161{
162 if (ast->name) {
163 if (Symbol *s = _scope->lookup(*ast->name))
164 _expr.type = s->type();
165 else
166 _engine->error(ast->lineno, QString::fromLatin1("`%1' was not declared in this scope").arg(*ast->name));
167 }
168 return false;
169}
170
172{
173 if (ast->value) {
174 _expr.isConstant = true;
175
176 if (ast->value->at(0) == QLatin1Char('t') && *ast->value == QLatin1String("true"))
177 _expr.type = _engine->boolType();
178 else if (ast->value->at(0) == QLatin1Char('f') && *ast->value == QLatin1String("false"))
179 _expr.type = _engine->boolType();
180 else if (ast->value->endsWith(QLatin1Char('u')) || ast->value->endsWith(QLatin1Char('U')))
181 _expr.type = _engine->uintType();
182 else if (ast->value->endsWith(QLatin1String("lf")) || ast->value->endsWith(QLatin1String("LF")))
183 _expr.type = _engine->doubleType();
184 else if (ast->value->endsWith(QLatin1Char('f')) || ast->value->endsWith(QLatin1Char('F')) || ast->value->contains(QLatin1Char('.')))
185 _expr.type = _engine->floatType();
186 else
187 _expr.type = _engine->intType();
188 }
189 return false;
190}
191
193{
196 _expr.isConstant = left.isConstant && right.isConstant;
197 switch (ast->kind) {
199 if (left.type) {
200 if (const IndexType *idxType = left.type->asIndexType())
201 _expr = idxType->indexElementType();
202 else
203 _engine->error(ast->lineno, QString::fromLatin1("Invalid type `%1' for array subscript").arg(left.type->toString()));
204 }
205 break;
206
209 case AST::Kind_Divide:
210 case AST::Kind_Plus:
211 case AST::Kind_Minus:
214 _expr.type = left.type; // ### not exactly
215 break;
216
221 case AST::Kind_Equal:
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
241{
242 ExprResult expr = expression(ast->expr);
243 _expr = expr;
244 return false;
245}
246
248{
250 ExprResult second = expression(ast->second);
251 ExprResult third = expression(ast->third);
252 _expr.isConstant = first.isConstant && second.isConstant && third.isConstant;
253 _expr.type = second.type;
254 return false;
255}
256
258{
261 return false;
262}
263
265{
266 ExprResult expr = expression(ast->expr);
267 if (expr.type && ast->field) {
268 if (const VectorType *vecTy = expr.type->asVectorType()) {
269 if (Symbol *s = vecTy->find(*ast->field))
270 _expr.type = s->type();
271 else
272 _engine->error(ast->lineno, QString::fromLatin1("`%1' has no member named `%2'").arg(vecTy->name()).arg(*ast->field));
273 } else if (const Struct *structTy = expr.type->asStructType()) {
274 if (Symbol *s = structTy->find(*ast->field))
275 _expr.type = s->type();
276 else
277 _engine->error(ast->lineno, QString::fromLatin1("`%1' has no member named `%2'").arg(structTy->name()).arg(*ast->field));
278 } else {
279 _engine->error(ast->lineno, QString::fromLatin1("Requested for member `%1', in a non class or vec instance").arg(*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(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
340{
341 ExprResult expr = expression(ast->expr);
343 QVector<ExprResult> actuals;
344 for (List<ExpressionAST *> *it = ast->arguments; it; it = it->next) {
345 ExprResult arg = expression(it->value);
346 actuals.append(arg);
347 }
348 if (id.isValid()) {
349 if (const Function *funTy = id.type->asFunctionType()) {
350 if (actuals.size() < funTy->argumentCount())
351 _engine->error(ast->lineno, QString::fromLatin1("not enough arguments"));
352 else if (actuals.size() > funTy->argumentCount())
353 _engine->error(ast->lineno, QString::fromLatin1("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(argc).type;
363 const Type *argumentTy = f->argumentAt(argc)->type();
364 if (! implicitCast(actualTy, argumentTy))
365 break;
366 }
367
368 if (argc == actuals.size())
369 candidates.append(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
395{
396 const Type *ty = type(ast->type);
397 Q_UNUSED(ty)
398 // ast->name
399 ExprResult initializer = expression(ast->initializer);
400 return false;
401}
402
403
404// statements
406{
407 ExprResult expr = expression(ast->expr);
408 return false;
409}
410
412{
413 Block *block = _engine->newBlock(_scope);
414 Scope *previousScope = switchScope(block);
415 ast->symbol = block;
416 for (List<StatementAST *> *it = ast->statements; it; it = it->next) {
417 StatementAST *stmt = it->value;
418 statement(stmt);
419 }
420 (void) switchScope(previousScope);
421 return false;
422}
423
425{
427 statement(ast->thenClause);
428 statement(ast->elseClause);
429 return false;
430}
431
433{
435 statement(ast->body);
436 return false;
437}
438
440{
441 statement(ast->body);
443 return false;
444}
445
447{
448 statement(ast->init);
451 statement(ast->body);
452 return false;
453}
454
456{
457 Q_UNUSED(ast)
458 return false;
459}
460
462{
463 ExprResult expr = expression(ast->expr);
464 return false;
465}
466
468{
469 ExprResult expr = expression(ast->expr);
470 statement(ast->body);
471 return false;
472}
473
475{
476 ExprResult expr = expression(ast->expr);
477 return false;
478}
479
481{
482 declaration(ast->decl);
483 return false;
484}
485
486
487// types
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(_engine->boolType(), 2);
518 break;
519
520 case Parser::T_BVEC3:
521 _type = _engine->vectorType(_engine->boolType(), 3);
522 break;
523
524 case Parser::T_BVEC4:
525 _type = _engine->vectorType(_engine->boolType(), 4);
526 break;
527
528 // ivec
529 case Parser::T_IVEC2:
530 _type = _engine->vectorType(_engine->intType(), 2);
531 break;
532
533 case Parser::T_IVEC3:
534 _type = _engine->vectorType(_engine->intType(), 3);
535 break;
536
537 case Parser::T_IVEC4:
538 _type = _engine->vectorType(_engine->intType(), 4);
539 break;
540
541 // uvec
542 case Parser::T_UVEC2:
543 _type = _engine->vectorType(_engine->uintType(), 2);
544 break;
545
546 case Parser::T_UVEC3:
547 _type = _engine->vectorType(_engine->uintType(), 3);
548 break;
549
550 case Parser::T_UVEC4:
551 _type = _engine->vectorType(_engine->uintType(), 4);
552 break;
553
554 // vec
555 case Parser::T_VEC2:
556 _type = _engine->vectorType(_engine->floatType(), 2);
557 break;
558
559 case Parser::T_VEC3:
560 _type = _engine->vectorType(_engine->floatType(), 3);
561 break;
562
563 case Parser::T_VEC4:
564 _type = _engine->vectorType(_engine->floatType(), 4);
565 break;
566
567 // dvec
568 case Parser::T_DVEC2:
569 _type = _engine->vectorType(_engine->doubleType(), 2);
570 break;
571
572 case Parser::T_DVEC3:
573 _type = _engine->vectorType(_engine->doubleType(), 3);
574 break;
575
576 case Parser::T_DVEC4:
577 _type = _engine->vectorType(_engine->doubleType(), 4);
578 break;
579
580 // mat2
581 case Parser::T_MAT2:
582 case Parser::T_MAT2X2:
583 _type = _engine->matrixType(_engine->floatType(), 2, 2);
584 break;
585
586 case Parser::T_MAT2X3:
587 _type = _engine->matrixType(_engine->floatType(), 2, 3);
588 break;
589
590 case Parser::T_MAT2X4:
591 _type = _engine->matrixType(_engine->floatType(), 2, 4);
592 break;
593
594 // mat3
595 case Parser::T_MAT3X2:
596 _type = _engine->matrixType(_engine->floatType(), 3, 2);
597 break;
598
599 case Parser::T_MAT3:
600 case Parser::T_MAT3X3:
601 _type = _engine->matrixType(_engine->floatType(), 3, 3);
602 break;
603
604 case Parser::T_MAT3X4:
605 _type = _engine->matrixType(_engine->floatType(), 3, 4);
606 break;
607
608 // mat4
609 case Parser::T_MAT4X2:
610 _type = _engine->matrixType(_engine->floatType(), 4, 2);
611 break;
612
613 case Parser::T_MAT4X3:
614 _type = _engine->matrixType(_engine->floatType(), 4, 3);
615 break;
616
617 case Parser::T_MAT4:
618 case Parser::T_MAT4X4:
619 _type = _engine->matrixType(_engine->floatType(), 4, 4);
620 break;
621
622
623 // dmat2
624 case Parser::T_DMAT2:
626 _type = _engine->matrixType(_engine->doubleType(), 2, 2);
627 break;
628
630 _type = _engine->matrixType(_engine->doubleType(), 2, 3);
631 break;
632
634 _type = _engine->matrixType(_engine->doubleType(), 2, 4);
635 break;
636
637 // dmat3
639 _type = _engine->matrixType(_engine->doubleType(), 3, 2);
640 break;
641
642 case Parser::T_DMAT3:
644 _type = _engine->matrixType(_engine->doubleType(), 3, 3);
645 break;
646
648 _type = _engine->matrixType(_engine->doubleType(), 3, 4);
649 break;
650
651 // dmat4
653 _type = _engine->matrixType(_engine->doubleType(), 4, 2);
654 break;
655
657 _type = _engine->matrixType(_engine->doubleType(), 4, 3);
658 break;
659
660 case Parser::T_DMAT4:
662 _type = _engine->matrixType(_engine->doubleType(), 4, 4);
663 break;
664
665 // samplers
706 _type = _engine->samplerType(ast->token);
707 break;
708
709 default:
710 _engine->error(ast->lineno, QString::fromLatin1("Unknown type `%1'").arg(QLatin1String(GLSLParserTable::spell[ast->token])));
711 }
712
713 return false;
714}
715
717{
718 if (ast->name) {
719 if (Symbol *s = _scope->lookup(*ast->name)) {
720 if (Struct *ty = s->asStruct()) {
721 _type = ty;
722 return false;
723 }
724 }
725 _engine->error(ast->lineno, QString::fromLatin1("Undefined type `%1'").arg(*ast->name));
726 }
727
728 return false;
729}
730
732{
733 const Type *elementType = type(ast->elementType);
734 Q_UNUSED(elementType)
736 _type = _engine->arrayType(elementType); // ### ignore the size for now
737 return false;
738}
739
741{
742 Struct *s = _engine->newStruct(_scope);
743 if (ast->name)
744 s->setName(*ast->name);
745 if (Scope *e = s->scope())
746 e->add(s);
747 Scope *previousScope = switchScope(s);
748 for (List<StructTypeAST::Field *> *it = ast->fields; it; it = it->next) {
749 StructTypeAST::Field *f = it->value;
750 if (Symbol *member = field(f))
751 s->add(member);
752 }
753 (void) switchScope(previousScope);
754 return false;
755}
756
758{
759 _type = type(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
772{
773 const Type *ty = type(ast->type);
774 Q_UNUSED(ty)
775 return false;
776}
777
779{
780 Q_UNUSED(ast)
781 Q_ASSERT(!"unreachable");
782 return false;
783}
784
786{
787 if (!ast->type)
788 return false;
789
790 const Type *ty = type(ast->type);
791 ExprResult initializer = expression(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, *ast->name, ty, qualifiers);
798 _scope->add(var);
799 }
800 return false;
801}
802
804{
805 const Type *ty = type(ast->type);
806 Q_UNUSED(ty)
807 return false;
808}
809
811{
812 declaration(ast->typeDecl);
813 declaration(ast->varDecl);
814 return false;
815}
816
818{
819 Q_UNUSED(ast)
820 return false;
821}
822
824{
825 for (List<DeclarationAST *> *it = ast->decls; it; it = it->next) {
826 DeclarationAST *decl = it->value;
827 declaration(decl);
828 }
829 return false;
830}
831
833{
834 Function *fun = _engine->newFunction(_scope);
835 if (ast->name)
836 fun->setName(*ast->name);
837
838 fun->setReturnType(type(ast->returnType));
839
840 for (List<ParameterDeclarationAST *> *it = ast->params; it; it = it->next) {
841 ParameterDeclarationAST *decl = it->value;
843 }
844
845 if (Scope *enclosingScope = fun->scope())
846 enclosingScope->add(fun);
847
848 Scope *previousScope = switchScope(fun);
849 statement(ast->body);
850 (void) switchScope(previousScope);
851 return false;
852}
853
static const char *const spell[]
virtual QualifiedTypeAST * asQualifiedType()
Definition glslast_p.h:248
@ Kind_BitwiseAnd
Definition glslast_p.h:150
@ Kind_GreaterThan
Definition glslast_p.h:145
@ Kind_LessThan
Definition glslast_p.h:143
@ Kind_GreaterEqual
Definition glslast_p.h:146
@ Kind_ArrayAccess
Definition glslast_p.h:154
@ Kind_ShiftLeft
Definition glslast_p.h:139
@ Kind_LessEqual
Definition glslast_p.h:144
@ Kind_BitwiseOr
Definition glslast_p.h:151
@ Kind_LogicalOr
Definition glslast_p.h:148
@ Kind_ShiftRight
Definition glslast_p.h:140
@ Kind_LogicalXor
Definition glslast_p.h:149
@ Kind_Multiply
Definition glslast_p.h:136
@ Kind_LogicalAnd
Definition glslast_p.h:147
@ Kind_BitwiseXor
Definition glslast_p.h:152
@ Kind_NotEqual
Definition glslast_p.h:142
ExpressionAST * size
Definition glslast_p.h:728
TypeAST * elementType
Definition glslast_p.h:727
ExpressionAST * left
Definition glslast_p.h:354
ExpressionAST * right
Definition glslast_p.h:355
List< StatementAST * > * statements
Definition glslast_p.h:513
ExpressionAST * condition
Definition glslast_p.h:563
StatementAST * body
Definition glslast_p.h:562
const UndefinedType * undefinedType()
const UIntType * uintType()
Struct * newStruct(Scope *scope=nullptr)
const MatrixType * matrixType(const Type *elementType, int columns, int rows)
const BoolType * boolType()
const ArrayType * arrayType(const Type *elementType)
const VoidType * voidType()
const IntType * intType()
const SamplerType * samplerType(int kind)
void error(int line, const QString &message)
const VectorType * vectorType(const Type *elementType, int dimension)
const DoubleType * doubleType()
Variable * newVariable(Scope *scope, const QString &name, const Type *type, int qualifiers=0)
Argument * newArgument(Function *function, const QString &name, const Type *type)
Block * newBlock(Scope *scope=nullptr)
const FloatType * floatType()
Function * newFunction(Scope *scope=nullptr)
StatementAST * body
Definition glslast_p.h:580
StatementAST * init
Definition glslast_p.h:577
ExpressionAST * condition
Definition glslast_p.h:578
ExpressionAST * increment
Definition glslast_p.h:579
List< ExpressionAST * > * arguments
Definition glslast_p.h:437
FunctionIdentifierAST * id
Definition glslast_p.h:436
List< ParameterDeclarationAST * > * params
Definition glslast_p.h:981
const Function * asFunctionType() const override
StatementAST * elseClause
Definition glslast_p.h:533
StatementAST * thenClause
Definition glslast_p.h:532
ExpressionAST * condition
Definition glslast_p.h:531
const IndexType * asIndexType() const override
List< DeclarationAST * > * decls
Definition glslast_p.h:960
const QString * value
Definition glslast_p.h:340
const MatrixType * asMatrixType() const override
const QString * name
Definition glslast_p.h:708
const OverloadSet * asOverloadSetType() const override
List< LayoutQualifierAST * > * layout_list
Definition glslast_p.h:832
ExpressionAST * expr
Definition glslast_p.h:605
virtual void add(Symbol *symbol)=0
Symbol * lookup(const QString &name) const
void parameterDeclaration(ParameterDeclarationAST *ast, Function *fun)
Symbol * field(StructTypeAST::Field *ast)
const Type * type(TypeAST *ast)
void declaration(DeclarationAST *ast)
void translationUnit(TranslationUnitAST *ast, Scope *globalScope, Engine *engine)
Scope * switchScope(Scope *scope)
void statement(StatementAST *ast)
Engine * switchEngine(Engine *engine)
~Semantic() override
ExprResult expression(ExpressionAST *ast, Scope *scope, Engine *engine)
bool visit(TranslationUnitAST *ast) override
ExprResult functionIdentifier(FunctionIdentifierAST *ast)
bool implicitCast(const Type *type, const Type *target) const
List< Field * > * fields
Definition glslast_p.h:772
const QString * name
Definition glslast_p.h:771
Struct * asStruct() override
StatementAST * body
Definition glslast_p.h:620
ExpressionAST * expr
Definition glslast_p.h:619
Scope * scope() const
void setName(const QString &name)
ExpressionAST * first
Definition glslast_p.h:383
ExpressionAST * second
Definition glslast_p.h:384
ExpressionAST * third
Definition glslast_p.h:385
List< DeclarationAST * > * declarations
Definition glslast_p.h:303
VariableDeclarationAST * varDecl
Definition glslast_p.h:932
TypeDeclarationAST * typeDecl
Definition glslast_p.h:931
virtual const VectorType * asVectorType() const
Definition glsltype_p.h:41
virtual const IntType * asIntType() const
Definition glsltype_p.h:35
virtual const Struct * asStructType() const
Definition glsltype_p.h:47
virtual const UIntType * asUIntType() const
Definition glsltype_p.h:36
virtual const FloatType * asFloatType() const
Definition glsltype_p.h:37
ExpressionAST * expr
Definition glslast_p.h:369
ExpressionAST * initializer
Definition glslast_p.h:901
const VectorType * asVectorType() const override
void accept(AST *ast)
StatementAST * body
Definition glslast_p.h:548
ExpressionAST * condition
Definition glslast_p.h:547
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1226
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition qstring.cpp:5506
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.h:1369
QSet< QString >::iterator it
Definition glsl_p.h:22
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum condition
GLboolean r
[2]
GLdouble GLdouble right
GLfloat GLfloat f
GLint left
GLenum type
GLenum target
GLuint name
GLint first
GLdouble s
[6]
Definition qopenglext.h:235
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
GLenum GLenum variable
GLbyte ty
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
SSL_CTX int void * arg
#define Q_UNUSED(x)
QtConcurrent::task([]{ qDebug("Hello, world!");}).spawn(FutureResult void increment(QPromise< int > &promise, int i)
[10]
QObject::connect nullptr
QJSValue fun
[0]
QJSEngine engine
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18