OSDN Git Service

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