1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
33 #include "glsltypes.h"
34 #include "glslsymbols.h"
35 #include "glslengine.h"
36 #include "glslparser.h"
40 bool UndefinedType::isEqualTo(const Type *other) const
42 if (other && other->asUndefinedType() != 0)
47 bool UndefinedType::isLessThan(const Type *other) const
51 Q_ASSERT(other->asUndefinedType() != 0);
55 bool VoidType::isEqualTo(const Type *other) const
57 if (other && other->asVoidType() != 0)
62 bool VoidType::isLessThan(const Type *other) const
66 Q_ASSERT(other->asVoidType() != 0);
70 bool BoolType::isEqualTo(const Type *other) const
72 if (other && other->asBoolType() != 0)
77 bool BoolType::isLessThan(const Type *other) const
81 Q_ASSERT(other->asBoolType() != 0);
85 bool IntType::isEqualTo(const Type *other) const
87 if (other && other->asIntType() != 0)
92 bool IntType::isLessThan(const Type *other) const
96 Q_ASSERT(other->asIntType() != 0);
100 bool UIntType::isEqualTo(const Type *other) const
102 if (other && other->asUIntType() != 0)
107 bool UIntType::isLessThan(const Type *other) const
110 Q_ASSERT(other != 0);
111 Q_ASSERT(other->asUIntType() != 0);
115 bool FloatType::isEqualTo(const Type *other) const
117 if (other && other->asFloatType() != 0)
122 bool FloatType::isLessThan(const Type *other) const
125 Q_ASSERT(other != 0);
126 Q_ASSERT(other->asFloatType() != 0);
130 bool DoubleType::isEqualTo(const Type *other) const
132 if (other && other->asDoubleType() != 0)
137 bool DoubleType::isLessThan(const Type *other) const
140 Q_ASSERT(other != 0);
141 Q_ASSERT(other->asDoubleType() != 0);
145 QString VectorType::toString() const
147 const char *prefix = "";
148 if (elementType()->asBoolType() != 0)
150 else if (elementType()->asIntType() != 0)
152 else if (elementType()->asUIntType() != 0)
154 else if (elementType()->asDoubleType() != 0)
156 return QString("%1vec%2").arg(QLatin1String(prefix)).arg(_dimension);
159 void VectorType::add(Symbol *symbol)
161 _members.insert(symbol->name(), symbol);
164 Symbol *VectorType::find(const QString &name) const
166 return _members.value(name);
169 void VectorType::populateMembers(Engine *engine)
171 if (_members.isEmpty()) {
172 populateMembers(engine, "xyzw");
173 populateMembers(engine, "rgba");
174 populateMembers(engine, "stpq");
178 void VectorType::populateMembers(Engine *engine, const char *components)
180 // Single component swizzles.
181 for (int x = 0; x < _dimension; ++x) {
182 const QString *name = engine->identifier(components + x, 1);
183 add(engine->newVariable(this, *name, elementType()));
186 // Two component swizzles.
187 const Type *vec2Type;
191 vec2Type = engine->vectorType(elementType(), 2);
192 for (int x = 0; x < _dimension; ++x) {
193 for (int y = 0; y < _dimension; ++y) {
195 name += QLatin1Char(components[x]);
196 name += QLatin1Char(components[y]);
197 add(engine->newVariable
198 (this, *engine->identifier(name), vec2Type));
202 // Three component swizzles.
203 const Type *vec3Type;
206 else if (_dimension < 3)
209 vec3Type = engine->vectorType(elementType(), 3);
210 for (int x = 0; x < _dimension; ++x) {
211 for (int y = 0; y < _dimension; ++y) {
212 for (int z = 0; z < _dimension; ++z) {
214 name += QLatin1Char(components[x]);
215 name += QLatin1Char(components[y]);
216 name += QLatin1Char(components[z]);
217 add(engine->newVariable
218 (this, *engine->identifier(name), vec3Type));
223 // Four component swizzles.
226 for (int x = 0; x < _dimension; ++x) {
227 for (int y = 0; y < _dimension; ++y) {
228 for (int z = 0; z < _dimension; ++z) {
229 for (int w = 0; w < _dimension; ++w) {
231 name += QLatin1Char(components[x]);
232 name += QLatin1Char(components[y]);
233 name += QLatin1Char(components[z]);
234 name += QLatin1Char(components[w]);
235 add(engine->newVariable
236 (this, *engine->identifier(name), this));
243 bool VectorType::isEqualTo(const Type *other) const
246 if (const VectorType *v = other->asVectorType()) {
247 if (_dimension != v->dimension())
249 else if (elementType() != v->elementType())
257 bool VectorType::isLessThan(const Type *other) const
259 Q_ASSERT(other != 0);
260 const VectorType *vec = other->asVectorType();
262 if (_dimension < vec->dimension())
264 else if (_dimension == vec->dimension() && elementType() < vec->elementType())
269 QString MatrixType::toString() const
271 const char *prefix = "";
272 if (elementType()->asBoolType() != 0)
274 else if (elementType()->asIntType() != 0)
276 else if (elementType()->asUIntType() != 0)
278 else if (elementType()->asDoubleType() != 0)
280 return QString("%1mat%2x%3").arg(QLatin1String(prefix)).arg(_columns).arg(_rows);
283 bool MatrixType::isEqualTo(const Type *other) const
286 if (const MatrixType *v = other->asMatrixType()) {
287 if (_columns != v->columns())
289 else if (_rows != v->rows())
291 else if (_elementType != v->elementType())
299 bool MatrixType::isLessThan(const Type *other) const
301 Q_ASSERT(other != 0);
302 const MatrixType *mat = other->asMatrixType();
304 if (_columns < mat->columns())
306 else if (_columns == mat->columns()) {
307 if (_rows < mat->rows())
309 else if (_rows == mat->rows() && _elementType < mat->elementType())
315 QString ArrayType::toString() const
317 return elementType()->toString() + QLatin1String("[]");
320 bool ArrayType::isEqualTo(const Type *other) const
323 if (const ArrayType *array = other->asArrayType())
324 return elementType()->isEqualTo(array->elementType());
329 bool ArrayType::isLessThan(const Type *other) const
331 Q_ASSERT(other != 0);
332 const ArrayType *array = other->asArrayType();
333 Q_ASSERT(array != 0);
334 return elementType() < array->elementType();
337 QList<Symbol *> Struct::members() const
340 foreach (Symbol *s, _members) {
341 if (! s->name().isEmpty())
347 void Struct::add(Symbol *member)
349 _members.append(member);
352 Symbol *Struct::find(const QString &name) const
354 foreach (Symbol *s, _members) {
355 if (s->name() == name)
361 bool Struct::isEqualTo(const Type *other) const
367 bool Struct::isLessThan(const Type *other) const
374 QString Function::toString() const
376 return prettyPrint(-1);
379 QString Function::prettyPrint(int currentArgument) const
382 proto += _returnType->toString();
383 proto += QLatin1Char(' ');
385 proto += QLatin1Char('(');
386 for (int i = 0; i < _arguments.size(); ++i) {
388 proto += QLatin1String(", ");
389 if (currentArgument == i)
390 proto += QLatin1String("<b>");
391 Argument *arg = _arguments.at(i);
392 proto += arg->type()->toString();
393 proto += QLatin1Char(' ');
394 proto += arg->name();
395 if (currentArgument == i)
396 proto += QLatin1String("</b>");
398 proto += QLatin1Char(')');
402 const Type *Function::returnType() const
407 void Function::setReturnType(const Type *returnType)
409 _returnType = returnType;
412 QVector<Argument *> Function::arguments() const
417 void Function::addArgument(Argument *arg)
419 _arguments.append(arg);
422 int Function::argumentCount() const
424 return _arguments.size();
427 Argument *Function::argumentAt(int index) const
429 return _arguments.at(index);
432 bool Function::isEqualTo(const Type *other) const
438 bool Function::isLessThan(const Type *other) const
444 QList<Symbol *> Function::members() const
447 foreach (Argument *arg, _arguments) {
448 if (! arg->name().isEmpty())
454 Symbol *Function::find(const QString &name) const
456 foreach (Argument *arg, _arguments) {
457 if (arg->name() == name)
463 QString SamplerType::toString() const
465 return QLatin1String(Parser::spell[_kind]);
468 bool SamplerType::isEqualTo(const Type *other) const
471 if (const SamplerType *samp = other->asSamplerType())
472 return _kind == samp->kind();
477 bool SamplerType::isLessThan(const Type *other) const
479 Q_ASSERT(other != 0);
480 const SamplerType *samp = other->asSamplerType();
482 return _kind < samp->kind();
485 OverloadSet::OverloadSet(Scope *enclosingScope)
486 : Scope(enclosingScope)
490 QVector<Function *> OverloadSet::functions() const
495 void OverloadSet::addFunction(Function *function)
497 _functions.append(function);
500 const Type *OverloadSet::type() const
505 Symbol *OverloadSet::find(const QString &) const
510 void OverloadSet::add(Symbol *symbol)
513 if (Function *fun = symbol->asFunction())
518 bool OverloadSet::isEqualTo(const Type *other) const
524 bool OverloadSet::isLessThan(const Type *other) const