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
glsltypes.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
6#include "glsltypes_p.h"
8#include "glslengine_p.h"
9#include "glslparser_p.h"
10
11QT_BEGIN_NAMESPACE
12
13using namespace GLSL;
14
15bool UndefinedType::isEqualTo(const Type *other) const
16{
17 if (other && other->asUndefinedType() != nullptr)
18 return true;
19 return false;
20}
21
22bool UndefinedType::isLessThan(const Type *other) const
23{
24 Q_UNUSED(other)
25 Q_ASSERT(other != nullptr);
26 Q_ASSERT(other->asUndefinedType() != nullptr);
27 return false;
28}
29
30bool VoidType::isEqualTo(const Type *other) const
31{
32 if (other && other->asVoidType() != nullptr)
33 return true;
34 return false;
35}
36
37bool VoidType::isLessThan(const Type *other) const
38{
39 Q_UNUSED(other)
40 Q_ASSERT(other != nullptr);
41 Q_ASSERT(other->asVoidType() != nullptr);
42 return false;
43}
44
45bool BoolType::isEqualTo(const Type *other) const
46{
47 if (other && other->asBoolType() != nullptr)
48 return true;
49 return false;
50}
51
52bool BoolType::isLessThan(const Type *other) const
53{
54 Q_UNUSED(other)
55 Q_ASSERT(other != nullptr);
56 Q_ASSERT(other->asBoolType() != nullptr);
57 return false;
58}
59
60bool IntType::isEqualTo(const Type *other) const
61{
62 if (other && other->asIntType() != nullptr)
63 return true;
64 return false;
65}
66
67bool IntType::isLessThan(const Type *other) const
68{
69 Q_UNUSED(other)
70 Q_ASSERT(other != nullptr);
71 Q_ASSERT(other->asIntType() != nullptr);
72 return false;
73}
74
75bool UIntType::isEqualTo(const Type *other) const
76{
77 if (other && other->asUIntType() != nullptr)
78 return true;
79 return false;
80}
81
82bool UIntType::isLessThan(const Type *other) const
83{
84 Q_UNUSED(other)
85 Q_ASSERT(other != nullptr);
86 Q_ASSERT(other->asUIntType() != nullptr);
87 return false;
88}
89
90bool FloatType::isEqualTo(const Type *other) const
91{
92 if (other && other->asFloatType() != nullptr)
93 return true;
94 return false;
95}
96
97bool FloatType::isLessThan(const Type *other) const
98{
99 Q_UNUSED(other)
100 Q_ASSERT(other != nullptr);
101 Q_ASSERT(other->asFloatType() != nullptr);
102 return false;
103}
104
105bool DoubleType::isEqualTo(const Type *other) const
106{
107 if (other && other->asDoubleType() != nullptr)
108 return true;
109 return false;
110}
111
112bool DoubleType::isLessThan(const Type *other) const
113{
114 Q_UNUSED(other)
115 Q_ASSERT(other != nullptr);
116 Q_ASSERT(other->asDoubleType() != nullptr);
117 return false;
118}
119
120QString VectorType::toString() const
121{
122 const char *prefix = "";
123 if (elementType()->asBoolType() != nullptr)
124 prefix = "b";
125 else if (elementType()->asIntType() != nullptr)
126 prefix = "i'";
127 else if (elementType()->asUIntType() != nullptr)
128 prefix = "u";
129 else if (elementType()->asDoubleType() != nullptr)
130 prefix = "d";
131 return QString::fromLatin1("%1vec%2").arg(QLatin1String(prefix)).arg(_dimension);
132}
133
134void VectorType::add(Symbol *symbol)
135{
136 _members.insert(symbol->name(), symbol);
137}
138
139Symbol *VectorType::find(const QString &name) const
140{
141 return _members.value(name);
142}
143
144void VectorType::populateMembers(Engine *engine)
145{
146 if (_members.isEmpty()) {
147 populateMembers(engine, "xyzw");
148 populateMembers(engine, "rgba");
149 populateMembers(engine, "stpq");
150 }
151}
152
153void VectorType::populateMembers(Engine *engine, const char *components)
154{
155 // Single component swizzles.
156 for (int x = 0; x < _dimension; ++x) {
157 const QString *name = engine->identifier(components + x, 1);
158 add(engine->newVariable(this, *name, elementType()));
159 }
160
161 // Two component swizzles.
162 const Type *vec2Type;
163 if (_dimension == 2)
164 vec2Type = this;
165 else
166 vec2Type = engine->vectorType(elementType(), 2);
167 for (int x = 0; x < _dimension; ++x) {
168 for (int y = 0; y < _dimension; ++y) {
169 QString name;
170 name += QLatin1Char(components[x]);
171 name += QLatin1Char(components[y]);
172 add(engine->newVariable
173 (this, *engine->identifier(name), vec2Type));
174 }
175 }
176
177 // Three component swizzles.
178 const Type *vec3Type;
179 if (_dimension == 3)
180 vec3Type = this;
181 else if (_dimension < 3)
182 return;
183 else
184 vec3Type = engine->vectorType(elementType(), 3);
185 for (int x = 0; x < _dimension; ++x) {
186 for (int y = 0; y < _dimension; ++y) {
187 for (int z = 0; z < _dimension; ++z) {
188 QString name;
189 name += QLatin1Char(components[x]);
190 name += QLatin1Char(components[y]);
191 name += QLatin1Char(components[z]);
192 add(engine->newVariable
193 (this, *engine->identifier(name), vec3Type));
194 }
195 }
196 }
197
198 // Four component swizzles.
199 if (_dimension != 4)
200 return;
201 for (int x = 0; x < _dimension; ++x) {
202 for (int y = 0; y < _dimension; ++y) {
203 for (int z = 0; z < _dimension; ++z) {
204 for (int w = 0; w < _dimension; ++w) {
205 QString name;
206 name += QLatin1Char(components[x]);
207 name += QLatin1Char(components[y]);
208 name += QLatin1Char(components[z]);
209 name += QLatin1Char(components[w]);
210 add(engine->newVariable
211 (this, *engine->identifier(name), this));
212 }
213 }
214 }
215 }
216}
217
218bool VectorType::isEqualTo(const Type *other) const
219{
220 if (other) {
221 if (const VectorType *v = other->asVectorType()) {
222 if (_dimension != v->dimension())
223 return false;
224 else if (elementType() != v->elementType())
225 return false;
226 return true;
227 }
228 }
229 return false;
230}
231
232bool VectorType::isLessThan(const Type *other) const
233{
234 Q_ASSERT(other != nullptr);
235 const VectorType *vec = other->asVectorType();
236 Q_ASSERT(vec != nullptr);
237 if (_dimension < vec->dimension())
238 return true;
239 else if (_dimension == vec->dimension() && elementType() < vec->elementType())
240 return true;
241 return false;
242}
243
244QString MatrixType::toString() const
245{
246 const char *prefix = "";
247 if (elementType()->asBoolType() != nullptr)
248 prefix = "b";
249 else if (elementType()->asIntType() != nullptr)
250 prefix = "i";
251 else if (elementType()->asUIntType() != nullptr)
252 prefix = "u";
253 else if (elementType()->asDoubleType() != nullptr)
254 prefix = "d";
255 return QString::fromLatin1("%1mat%2x%3").arg(QLatin1String(prefix)).arg(_columns).arg(_rows);
256}
257
258bool MatrixType::isEqualTo(const Type *other) const
259{
260 if (other) {
261 if (const MatrixType *v = other->asMatrixType()) {
262 if (_columns != v->columns())
263 return false;
264 else if (_rows != v->rows())
265 return false;
266 else if (_elementType != v->elementType())
267 return false;
268 return true;
269 }
270 }
271 return false;
272}
273
274bool MatrixType::isLessThan(const Type *other) const
275{
276 Q_ASSERT(other != nullptr);
277 const MatrixType *mat = other->asMatrixType();
278 Q_ASSERT(mat != nullptr);
279 if (_columns < mat->columns()) {
280 return true;
281 } else if (_columns == mat->columns()) {
282 if (_rows < mat->rows())
283 return true;
284 else if (_rows == mat->rows() && _elementType < mat->elementType())
285 return true;
286 }
287 return false;
288}
289
290QString ArrayType::toString() const
291{
292 return elementType()->toString() + QLatin1String("[]");
293}
294
295bool ArrayType::isEqualTo(const Type *other) const
296{
297 if (other) {
298 if (const ArrayType *array = other->asArrayType())
299 return elementType()->isEqualTo(array->elementType());
300 }
301 return false;
302}
303
304bool ArrayType::isLessThan(const Type *other) const
305{
306 Q_ASSERT(other != nullptr);
307 const ArrayType *array = other->asArrayType();
308 Q_ASSERT(array != nullptr);
309 return elementType() < array->elementType();
310}
311
312QList<Symbol *> Struct::members() const
313{
314 QList<Symbol *> m;
315 for (Symbol *s : _members) {
316 if (! s->name().isEmpty())
317 m.append(s);
318 }
319 return m;
320}
321
322void Struct::add(Symbol *member)
323{
324 _members.append(member);
325}
326
327Symbol *Struct::find(const QString &name) const
328{
329 for (Symbol *s : _members) {
330 if (s->name() == name)
331 return s;
332 }
333 return nullptr;
334}
335
336bool Struct::isEqualTo(const Type *other) const
337{
338 Q_UNUSED(other)
339 return false;
340}
341
342bool Struct::isLessThan(const Type *other) const
343{
344 Q_UNUSED(other)
345 return false;
346}
347
348
349QString Function::toString() const
350{
351 return prettyPrint();
352}
353
354QString Function::prettyPrint() const
355{
356 QString proto;
357 proto += _returnType->toString();
358 proto += QLatin1Char(' ');
359 proto += name();
360 proto += QLatin1Char('(');
361 for (int i = 0; i < _arguments.size(); ++i) {
362 if (i != 0)
363 proto += QLatin1String(", ");
364 Argument *arg = _arguments.at(i);
365 proto += arg->type()->toString();
366 proto += QLatin1Char(' ');
367 proto += arg->name();
368 }
369 proto += QLatin1Char(')');
370 return proto;
371}
372
373const Type *Function::returnType() const
374{
375 return _returnType;
376}
377
378void Function::setReturnType(const Type *returnType)
379{
380 _returnType = returnType;
381}
382
383QVector<Argument *> Function::arguments() const
384{
385 return _arguments;
386}
387
388void Function::addArgument(Argument *arg)
389{
390 _arguments.append(arg);
391}
392
393int Function::argumentCount() const
394{
395 return _arguments.size();
396}
397
398Argument *Function::argumentAt(int index) const
399{
400 return _arguments.at(index);
401}
402
403bool Function::isEqualTo(const Type *other) const
404{
405 Q_UNUSED(other)
406 return false;
407}
408
409bool Function::isLessThan(const Type *other) const
410{
411 Q_UNUSED(other)
412 return false;
413}
414
415QList<Symbol *> Function::members() const
416{
417 QList<Symbol *> m;
418 for (Argument *arg : _arguments) {
419 if (! arg->name().isEmpty())
420 m.append(arg);
421 }
422 return m;
423}
424
425Symbol *Function::find(const QString &name) const
426{
427 for (Argument *arg : _arguments) {
428 if (arg->name() == name)
429 return arg;
430 }
431 return nullptr;
432}
433
434QString SamplerType::toString() const
435{
436 return QLatin1String(Parser::spell[_kind]);
437}
438
439bool SamplerType::isEqualTo(const Type *other) const
440{
441 if (other) {
442 if (const SamplerType *samp = other->asSamplerType())
443 return _kind == samp->kind();
444 }
445 return false;
446}
447
448bool SamplerType::isLessThan(const Type *other) const
449{
450 Q_ASSERT(other != nullptr);
451 const SamplerType *samp = other->asSamplerType();
452 Q_ASSERT(samp != nullptr);
453 return _kind < samp->kind();
454}
455
456OverloadSet::OverloadSet(Scope *enclosingScope)
457 : Scope(enclosingScope)
458{
459}
460
461QVector<Function *> OverloadSet::functions() const
462{
463 return _functions;
464}
465
466void OverloadSet::addFunction(Function *function)
467{
468 _functions.append(function);
469}
470
471const Type *OverloadSet::type() const
472{
473 return this;
474}
475
476Symbol *OverloadSet::find(const QString &) const
477{
478 return nullptr;
479}
480
481void OverloadSet::add(Symbol *symbol)
482{
483 if (symbol) {
484 if (Function *fun = symbol->asFunction())
485 addFunction(fun);
486 }
487}
488
489bool OverloadSet::isEqualTo(const Type *other) const
490{
491 Q_UNUSED(other)
492 return false;
493}
494
495bool OverloadSet::isLessThan(const Type *other) const
496{
497 Q_UNUSED(other)
498 return false;
499}
500
501QT_END_NAMESPACE