]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/generate.cpp
Additional rules for bit shift operators
[libs/gl.git] / source / glsl / generate.cpp
1 #include <msp/core/hash.h>
2 #include <msp/core/raii.h>
3 #include <msp/strings/lexicalcast.h>
4 #include "builtin.h"
5 #include "generate.h"
6
7 using namespace std;
8
9 namespace Msp {
10 namespace GL {
11 namespace SL {
12
13 void DeclarationCombiner::apply(Stage &stage)
14 {
15         stage.content.visit(*this);
16         NodeRemover().apply(stage, nodes_to_remove);
17 }
18
19 void DeclarationCombiner::visit(Block &block)
20 {
21         if(current_block)
22                 return;
23
24         TraversingVisitor::visit(block);
25 }
26
27 void DeclarationCombiner::visit(VariableDeclaration &var)
28 {
29         VariableDeclaration *&ptr = variables[var.name];
30         if(ptr)
31         {
32                 ptr->type = var.type;
33                 if(var.init_expression)
34                         ptr->init_expression = var.init_expression;
35                 if(var.layout)
36                 {
37                         if(ptr->layout)
38                         {
39                                 for(vector<Layout::Qualifier>::iterator i=var.layout->qualifiers.begin(); i!=var.layout->qualifiers.end(); ++i)
40                                 {
41                                         bool found = false;
42                                         for(vector<Layout::Qualifier>::iterator j=ptr->layout->qualifiers.begin(); (!found && j!=ptr->layout->qualifiers.end()); ++j)
43                                                 if(j->name==i->name)
44                                                 {
45                                                         j->has_value = i->value;
46                                                         j->value = i->value;
47                                                         found = true;
48                                                 }
49
50                                         if(!found)
51                                                 ptr->layout->qualifiers.push_back(*i);
52                                 }
53                         }
54                         else
55                                 ptr->layout = var.layout;
56                 }
57                 nodes_to_remove.insert(&var);
58         }
59         else
60                 ptr = &var;
61 }
62
63
64 ConstantSpecializer::ConstantSpecializer():
65         values(0)
66 { }
67
68 void ConstantSpecializer::apply(Stage &stage, const map<string, int> *v)
69 {
70         values = v;
71         stage.content.visit(*this);
72 }
73
74 void ConstantSpecializer::visit(VariableDeclaration &var)
75 {
76         bool specializable = false;
77         if(var.layout)
78         {
79                 vector<Layout::Qualifier> &qualifiers = var.layout->qualifiers;
80                 for(vector<Layout::Qualifier>::iterator i=qualifiers.begin(); i!=qualifiers.end(); ++i)
81                         if(i->name=="constant_id")
82                         {
83                                 specializable = true;
84                                 if(values)
85                                         qualifiers.erase(i);
86                                 else if(i->value==-1)
87                                         i->value = hash32(var.name)&0x7FFFFFFF;
88                                 break;
89                         }
90
91                 if(qualifiers.empty())
92                         var.layout = 0;
93         }
94
95         if(specializable && values)
96         {
97                 map<string, int>::const_iterator i = values->find(var.name);
98                 if(i!=values->end())
99                 {
100                         RefPtr<Literal> literal = new Literal;
101                         if(var.type=="bool")
102                         {
103                                 literal->token = (i->second ? "true" : "false");
104                                 literal->value = static_cast<bool>(i->second);
105                         }
106                         else if(var.type=="int")
107                         {
108                                 literal->token = lexical_cast<string>(i->second);
109                                 literal->value = i->second;
110                         }
111                         var.init_expression = literal;
112                 }
113         }
114 }
115
116
117 void BlockHierarchyResolver::enter(Block &block)
118 {
119         block.parent = current_block;
120 }
121
122
123 TypeResolver::TypeResolver():
124         stage(0)
125 { }
126
127 void TypeResolver::apply(Stage &s)
128 {
129         stage = &s;
130         s.types.clear();
131         s.content.visit(*this);
132 }
133
134 TypeDeclaration *TypeResolver::resolve_type(const string &name)
135 {
136         map<string, TypeDeclaration *>::iterator i = stage->types.find(name);
137         if(i!=stage->types.end())
138         {
139                 map<TypeDeclaration *, TypeDeclaration *>::iterator j = alias_map.find(i->second);
140                 return (j!=alias_map.end() ? j->second : i->second);
141         }
142         else
143                 return 0;
144 }
145
146 void TypeResolver::visit(Block &block)
147 {
148         for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
149         {
150                 if(!block.parent)
151                         type_insert_point = i;
152                 (*i)->visit(*this);
153         }
154 }
155
156 void TypeResolver::visit(BasicTypeDeclaration &type)
157 {
158         type.base_type = resolve_type(type.base);
159
160         if(type.kind==BasicTypeDeclaration::VECTOR && type.base_type)
161                 if(BasicTypeDeclaration *basic_base = dynamic_cast<BasicTypeDeclaration *>(type.base_type))
162                         if(basic_base->kind==BasicTypeDeclaration::VECTOR)
163                         {
164                                 type.kind = BasicTypeDeclaration::MATRIX;
165                                 type.size |= basic_base->size<<16;
166                         }
167
168         if(type.kind==BasicTypeDeclaration::ALIAS && type.base_type)
169                 alias_map[&type] = type.base_type;
170         else if(type.kind==BasicTypeDeclaration::ARRAY && type.base_type)
171                 array_types[type.base_type] = &type;
172
173         stage->types.insert(make_pair(type.name, &type));
174 }
175
176 void TypeResolver::visit(ImageTypeDeclaration &type)
177 {
178         type.base_type = resolve_type(type.base);
179         stage->types.insert(make_pair(type.name, &type));
180 }
181
182 void TypeResolver::visit(StructDeclaration &strct)
183 {
184         stage->types.insert(make_pair(strct.name, &strct));
185         TraversingVisitor::visit(strct);
186 }
187
188 void TypeResolver::visit(VariableDeclaration &var)
189 {
190         TypeDeclaration *type = resolve_type(var.type);
191         if(var.array && type)
192         {
193                 map<TypeDeclaration *, TypeDeclaration *>::iterator i = array_types.find(type);
194                 if(i==array_types.end())
195                 {
196                         BasicTypeDeclaration *array = new BasicTypeDeclaration;
197                         array->source = BUILTIN_SOURCE;
198                         array->name = type->name+"[]";
199                         array->kind = BasicTypeDeclaration::ARRAY;
200                         array->base = type->name;
201                         array->base_type = type;
202                         stage->content.body.insert(type_insert_point, array);
203                         array->visit(*this);
204                         type = array;
205                 }
206                 else
207                         type = i->second;
208         }
209         var.type_declaration = type;
210 }
211
212 void TypeResolver::visit(FunctionDeclaration &func)
213 {
214         func.return_type_declaration = resolve_type(func.return_type);
215         TraversingVisitor::visit(func);
216 }
217
218
219 VariableResolver::VariableResolver():
220         stage(0),
221         r_any_resolved(false),
222         record_target(false),
223         r_self_referencing(false),
224         r_assignment_target(0)
225 { }
226
227 bool VariableResolver::apply(Stage &s)
228 {
229         stage = &s;
230         s.interface_blocks.clear();
231         r_any_resolved = false;
232         s.content.visit(*this);
233         return r_any_resolved;
234 }
235
236 void VariableResolver::enter(Block &block)
237 {
238         block.variables.clear();
239 }
240
241 void VariableResolver::visit_and_replace(RefPtr<Expression> &expr)
242 {
243         r_replacement_expr = 0;
244         expr->visit(*this);
245         if(r_replacement_expr)
246                 expr = r_replacement_expr;
247         r_replacement_expr = 0;
248 }
249
250 void VariableResolver::visit(VariableReference &var)
251 {
252         VariableDeclaration *declaration = 0;
253
254         /* Look for variable declarations in the block hierarchy first.  Interface
255         blocks are always defined in the top level so we can't accidentally skip
256         one. */
257         for(Block *block=current_block; (!declaration && block); block=block->parent)
258         {
259                 map<string, VariableDeclaration *>::iterator i = block->variables.find(var.name);
260                 if(i!=block->variables.end())
261                         declaration = i->second;
262         }
263
264         if(!declaration)
265         {
266                 const map<string, InterfaceBlock *> &blocks = stage->interface_blocks;
267                 map<string, InterfaceBlock *>::const_iterator i = blocks.find("_"+var.name);
268                 if(i!=blocks.end())
269                 {
270                         /* The name refers to an interface block with an instance name rather
271                         than a variable.  Prepare a new syntax tree node accordingly. */
272                         InterfaceBlockReference *iface_ref = new InterfaceBlockReference;
273                         iface_ref->source = var.source;
274                         iface_ref->line = var.line;
275                         iface_ref->name = var.name;
276                         iface_ref->declaration = i->second;
277                         r_replacement_expr = iface_ref;
278                 }
279                 else
280                 {
281                         // Look for the variable in anonymous interface blocks.
282                         for(i=blocks.begin(); (!declaration && i!=blocks.end()); ++i)
283                                 if(i->second->instance_name.empty())
284                                 {
285                                         map<string, VariableDeclaration *>::iterator j = i->second->members.variables.find(var.name);
286                                         if(j!=i->second->members.variables.end())
287                                                 declaration = j->second;
288                                 }
289                 }
290         }
291
292         r_any_resolved |= (declaration!=var.declaration);
293         var.declaration = declaration;
294
295         if(record_target)
296         {
297                 if(r_assignment_target)
298                 {
299                         /* More than one variable reference found in assignment target.
300                         Unable to determine what the primary target is. */
301                         record_target = false;
302                         r_assignment_target = 0;
303                 }
304                 else
305                         r_assignment_target = var.declaration;
306         }
307         else if(var.declaration && var.declaration==r_assignment_target)
308                 r_self_referencing = true;
309 }
310
311 void VariableResolver::visit(InterfaceBlockReference &iface)
312 {
313         map<string, InterfaceBlock *>::iterator i = stage->interface_blocks.find("_"+iface.name);
314         InterfaceBlock *declaration = (i!=stage->interface_blocks.end() ? i->second : 0);
315         r_any_resolved |= (declaration!=iface.declaration);
316         iface.declaration = declaration;
317 }
318
319 void VariableResolver::visit(MemberAccess &memacc)
320 {
321         visit_and_replace(memacc.left);
322
323         map<string, VariableDeclaration *> *members = 0;
324         if(StructDeclaration *strct = dynamic_cast<StructDeclaration *>(memacc.left->type))
325                 members = &strct->members.variables;
326         else if(InterfaceBlockReference *iface_ref = dynamic_cast<InterfaceBlockReference *>(memacc.left.get()))
327         {
328                 if(iface_ref->declaration)
329                         members = &iface_ref->declaration->members.variables;
330         }
331
332         VariableDeclaration *declaration = 0;
333         if(members)
334         {
335                 map<string, VariableDeclaration *>::iterator i = members->find(memacc.member);
336                 if(i!=members->end())
337                         declaration = i->second;
338         }
339
340         r_any_resolved |= (declaration!=memacc.declaration);
341         memacc.declaration = declaration;
342 }
343
344 void VariableResolver::visit(UnaryExpression &unary)
345 {
346         visit_and_replace(unary.expression);
347 }
348
349 void VariableResolver::visit(BinaryExpression &binary)
350 {
351         if(binary.oper->token[0]=='[')
352         {
353                 {
354                         /* The subscript expression is not a part of the primary assignment
355                         target. */
356                         SetFlag set(record_target, false);
357                         visit_and_replace(binary.right);
358                 }
359                 visit_and_replace(binary.left);
360         }
361         else
362         {
363                 visit_and_replace(binary.left);
364                 visit_and_replace(binary.right);
365         }
366 }
367
368 void VariableResolver::visit(Assignment &assign)
369 {
370         {
371                 SetFlag set(record_target);
372                 r_assignment_target = 0;
373                 visit_and_replace(assign.left);
374                 r_any_resolved |= (r_assignment_target!=assign.target_declaration);
375                 assign.target_declaration = r_assignment_target;
376         }
377
378         r_self_referencing = false;
379         visit_and_replace(assign.right);
380         assign.self_referencing = (r_self_referencing || assign.oper->token[0]!='=');
381 }
382
383 void VariableResolver::visit(FunctionCall &call)
384 {
385         for(NodeArray<Expression>::iterator i=call.arguments.begin(); i!=call.arguments.end(); ++i)
386                 visit_and_replace(*i);
387 }
388
389 void VariableResolver::visit(VariableDeclaration &var)
390 {
391         if(!block_interface.empty() && var.interface.empty())
392                 var.interface = block_interface;
393
394         TraversingVisitor::visit(var);
395         current_block->variables.insert(make_pair(var.name, &var));
396 }
397
398 void VariableResolver::visit(InterfaceBlock &iface)
399 {
400         /* Block names can be reused in different interfaces.  Prefix the name with
401         the first character of the interface to avoid conflicts. */
402         stage->interface_blocks.insert(make_pair(iface.interface+iface.name, &iface));
403         if(!iface.instance_name.empty())
404                 stage->interface_blocks.insert(make_pair("_"+iface.instance_name, &iface));
405
406         SetForScope<string> set_iface(block_interface, iface.interface);
407         TraversingVisitor::visit(iface);
408 }
409
410
411 ExpressionResolver::ExpressionResolver():
412         stage(0),
413         r_any_resolved(false)
414 { }
415
416 bool ExpressionResolver::apply(Stage &s)
417 {
418         stage = &s;
419         r_any_resolved = false;
420         s.content.visit(*this);
421         return r_any_resolved;
422 }
423
424 bool ExpressionResolver::is_scalar(BasicTypeDeclaration &type)
425 {
426         return (type.kind==BasicTypeDeclaration::INT || type.kind==BasicTypeDeclaration::FLOAT);
427 }
428
429 bool ExpressionResolver::is_vector_or_matrix(BasicTypeDeclaration &type)
430 {
431         return (type.kind==BasicTypeDeclaration::VECTOR || type.kind==BasicTypeDeclaration::MATRIX);
432 }
433
434 BasicTypeDeclaration *ExpressionResolver::get_element_type(BasicTypeDeclaration &type)
435 {
436         if(is_vector_or_matrix(type) || type.kind==BasicTypeDeclaration::ARRAY)
437         {
438                 BasicTypeDeclaration *basic_base = dynamic_cast<BasicTypeDeclaration *>(type.base_type);
439                 return (basic_base ? get_element_type(*basic_base) : 0);
440         }
441         else
442                 return &type;
443 }
444
445 bool ExpressionResolver::can_convert(BasicTypeDeclaration &from, BasicTypeDeclaration &to)
446 {
447         if(from.kind==BasicTypeDeclaration::INT && to.kind==BasicTypeDeclaration::FLOAT)
448                 return from.size<=to.size;
449         else if(from.kind!=to.kind)
450                 return false;
451         else if((from.kind==BasicTypeDeclaration::VECTOR || from.kind==BasicTypeDeclaration::MATRIX) && from.size==to.size)
452         {
453                 BasicTypeDeclaration *from_base = dynamic_cast<BasicTypeDeclaration *>(from.base_type);
454                 BasicTypeDeclaration *to_base = dynamic_cast<BasicTypeDeclaration *>(to.base_type);
455                 return (from_base && to_base && can_convert(*from_base, *to_base));
456         }
457         else
458                 return false;
459 }
460
461 ExpressionResolver::Compatibility ExpressionResolver::get_compatibility(BasicTypeDeclaration &left, BasicTypeDeclaration &right)
462 {
463         if(&left==&right)
464                 return SAME_TYPE;
465         else if(can_convert(left, right))
466                 return LEFT_CONVERTIBLE;
467         else if(can_convert(right, left))
468                 return RIGHT_CONVERTIBLE;
469         else
470                 return NOT_COMPATIBLE;
471 }
472
473 BasicTypeDeclaration *ExpressionResolver::find_type(BasicTypeDeclaration::Kind kind, unsigned size)
474 {
475         for(vector<BasicTypeDeclaration *>::const_iterator i=basic_types.begin(); i!=basic_types.end(); ++i)
476                 if((*i)->kind==kind && (*i)->size==size)
477                         return *i;
478         return 0;
479 }
480
481 BasicTypeDeclaration *ExpressionResolver::find_type(BasicTypeDeclaration &elem_type, BasicTypeDeclaration::Kind kind, unsigned size)
482 {
483         for(vector<BasicTypeDeclaration *>::const_iterator i=basic_types.begin(); i!=basic_types.end(); ++i)
484                 if(get_element_type(**i)==&elem_type && (*i)->kind==kind && (*i)->size==size)
485                         return *i;
486         return 0;
487 }
488
489 void ExpressionResolver::convert_to(RefPtr<Expression> &expr, BasicTypeDeclaration &type)
490 {
491         RefPtr<FunctionCall> call = new FunctionCall;
492         call->name = type.name;
493         call->constructor = true;
494         call->arguments.push_back(0);
495         call->arguments.back() = expr;
496         call->type = &type;
497         expr = call;
498 }
499
500 bool ExpressionResolver::convert_to_element(RefPtr<Expression> &expr, BasicTypeDeclaration &elem_type)
501 {
502         if(BasicTypeDeclaration *expr_type = dynamic_cast<BasicTypeDeclaration *>(expr->type))
503         {
504                 BasicTypeDeclaration *to_type = &elem_type;
505                 if(is_vector_or_matrix(*expr_type))
506                         to_type = find_type(elem_type, expr_type->kind, expr_type->size);
507                 if(to_type)
508                 {
509                         convert_to(expr, *to_type);
510                         return true;
511                 }
512         }
513
514         return false;
515 }
516
517 void ExpressionResolver::resolve(Expression &expr, TypeDeclaration *type, bool lvalue)
518 {
519         r_any_resolved |= (type!=expr.type || lvalue!=expr.lvalue);
520         expr.type = type;
521         expr.lvalue = lvalue;
522 }
523
524 void ExpressionResolver::visit(Literal &literal)
525 {
526         if(literal.value.check_type<bool>())
527                 resolve(literal, find_type(BasicTypeDeclaration::BOOL, 1), false);
528         else if(literal.value.check_type<int>())
529                 resolve(literal, find_type(BasicTypeDeclaration::INT, 32), false);
530         else if(literal.value.check_type<float>())
531                 resolve(literal, find_type(BasicTypeDeclaration::FLOAT, 32), false);
532 }
533
534 void ExpressionResolver::visit(ParenthesizedExpression &parexpr)
535 {
536         TraversingVisitor::visit(parexpr);
537         resolve(parexpr, parexpr.expression->type, parexpr.expression->lvalue);
538 }
539
540 void ExpressionResolver::visit(VariableReference &var)
541 {
542         if(var.declaration)
543                 resolve(var, var.declaration->type_declaration, true);
544 }
545
546 void ExpressionResolver::visit(InterfaceBlockReference &iface)
547 {
548         resolve(iface, 0, true);
549 }
550
551 void ExpressionResolver::visit(MemberAccess &memacc)
552 {
553         TraversingVisitor::visit(memacc);
554
555         if(memacc.declaration)
556                 resolve(memacc, memacc.declaration->type_declaration, memacc.left->lvalue);
557 }
558
559 void ExpressionResolver::visit(UnaryExpression &unary)
560 {
561         TraversingVisitor::visit(unary);
562
563         BasicTypeDeclaration *basic = dynamic_cast<BasicTypeDeclaration *>(unary.expression->type);
564         if(!basic)
565                 return;
566
567         char oper = unary.oper->token[0];
568         if(oper=='!')
569         {
570                 if(basic->kind!=BasicTypeDeclaration::BOOL)
571                         return;
572         }
573         else if(oper=='~')
574         {
575                 if(basic->kind!=BasicTypeDeclaration::INT)
576                         return;
577         }
578         else if(oper=='+' || oper=='-')
579         {
580                 BasicTypeDeclaration *elem = get_element_type(*basic);
581                 if(!elem || !is_scalar(*elem))
582                         return;
583         }
584         resolve(unary, basic, unary.expression->lvalue);
585 }
586
587 void ExpressionResolver::visit(BinaryExpression &binary, bool assign)
588 {
589         /* Binary operators are only defined for basic types (not for image or
590         structure types). */
591         BasicTypeDeclaration *basic_left = dynamic_cast<BasicTypeDeclaration *>(binary.left->type);
592         BasicTypeDeclaration *basic_right = dynamic_cast<BasicTypeDeclaration *>(binary.right->type);
593         if(!basic_left || !basic_right)
594                 return;
595
596         char oper = binary.oper->token[0];
597         if(oper=='[')
598         {
599                 /* Subscripting operates on vectors, matrices and arrays, and the right
600                 operand must be an integer. */
601                 if((!is_vector_or_matrix(*basic_left) && basic_left->kind!=BasicTypeDeclaration::ARRAY) || basic_right->kind!=BasicTypeDeclaration::INT)
602                         return;
603
604                 resolve(binary, basic_left->base_type, binary.left->lvalue);
605                 return;
606         }
607         else if(basic_left->kind==BasicTypeDeclaration::ARRAY || basic_right->kind==BasicTypeDeclaration::ARRAY)
608                 // No other binary operator can be used with arrays.
609                 return;
610
611         BasicTypeDeclaration *elem_left = get_element_type(*basic_left);
612         BasicTypeDeclaration *elem_right = get_element_type(*basic_right);
613         if(!elem_left || !elem_right)
614                 return;
615
616         Compatibility compat = get_compatibility(*basic_left, *basic_right);
617         Compatibility elem_compat = get_compatibility(*elem_left, *elem_right);
618         if(elem_compat==NOT_COMPATIBLE)
619                 return;
620         if(assign && (compat==LEFT_CONVERTIBLE || elem_compat==LEFT_CONVERTIBLE))
621                 return;
622
623         TypeDeclaration *type = 0;
624         char oper2 = binary.oper->token[1];
625         if((oper=='<' && oper2!='<') || (oper=='>' && oper2!='>'))
626         {
627                 /* Relational operators compare two scalar integer or floating-point
628                 values. */
629                 if(!is_scalar(*elem_left) || !is_scalar(*elem_right) || compat==NOT_COMPATIBLE)
630                         return;
631
632                 type = find_type(BasicTypeDeclaration::BOOL, 1);
633         }
634         else if((oper=='=' || oper=='!') && oper2=='=')
635         {
636                 // Equality comparison can be done on any compatible types.
637                 if(compat==NOT_COMPATIBLE)
638                         return;
639
640                 type = find_type(BasicTypeDeclaration::BOOL, 1);
641         }
642         else if(oper2=='&' || oper2=='|' || oper2=='^')
643         {
644                 // Logical operators can only be applied to booleans.
645                 if(basic_left->kind!=BasicTypeDeclaration::BOOL || basic_right->kind!=BasicTypeDeclaration::BOOL)
646                         return;
647
648                 type = basic_left;
649         }
650         else if((oper=='&' || oper=='|' || oper=='^' || oper=='%') && !oper2)
651         {
652                 // Bitwise operators and modulo can only be applied to integers.
653                 if(basic_left->kind!=BasicTypeDeclaration::INT || basic_right->kind!=BasicTypeDeclaration::INT)
654                         return;
655
656                 type = (compat==LEFT_CONVERTIBLE ? basic_right : basic_left);
657         }
658         else if((oper=='<' || oper=='>') && oper2==oper)
659         {
660                 // Shifts apply to integer scalars and vectors, with some restrictions.
661                 if(elem_left->kind!=BasicTypeDeclaration::INT || elem_right->kind!=BasicTypeDeclaration::INT)
662                         return;
663                 unsigned left_size = (basic_left->kind==BasicTypeDeclaration::INT ? 1 : basic_left->kind==BasicTypeDeclaration::VECTOR ? basic_left->size : 0);
664                 unsigned right_size = (basic_right->kind==BasicTypeDeclaration::INT ? 1 : basic_right->kind==BasicTypeDeclaration::VECTOR ? basic_right->size : 0);
665                 if(!left_size || (left_size==1 && right_size!=1) || (left_size>1 && right_size!=1 && right_size!=left_size))
666                         return;
667
668                 type = basic_left;
669                 // Don't perform conversion even if the operands are of different sizes.
670                 compat = SAME_TYPE;
671         }
672         else if(oper=='+' || oper=='-' || oper=='*' || oper=='/')
673         {
674                 // Arithmetic operators require scalar elements.
675                 if(!is_scalar(*elem_left) || !is_scalar(*elem_right))
676                         return;
677
678                 if(oper=='*' && is_vector_or_matrix(*basic_left) && is_vector_or_matrix(*basic_right) &&
679                         (basic_left->kind==BasicTypeDeclaration::MATRIX || basic_right->kind==BasicTypeDeclaration::MATRIX))
680                 {
681                         /* Multiplication has special rules when at least one operand is a
682                         matrix and the other is a vector or a matrix. */
683                         unsigned left_columns = basic_left->size&0xFFFF;
684                         unsigned right_rows = basic_right->size;
685                         if(basic_right->kind==BasicTypeDeclaration::MATRIX)
686                                 right_rows >>= 16;
687                         if(left_columns!=right_rows)
688                                 return;
689
690                         BasicTypeDeclaration *elem_result = (elem_compat==LEFT_CONVERTIBLE ? elem_right : elem_left);
691
692                         if(basic_left->kind==BasicTypeDeclaration::VECTOR)
693                                 type = find_type(*elem_result, BasicTypeDeclaration::VECTOR, basic_right->size&0xFFFF);
694                         else if(basic_right->kind==BasicTypeDeclaration::VECTOR)
695                                 type = find_type(*elem_result, BasicTypeDeclaration::VECTOR, basic_left->size>>16);
696                         else
697                                 type = find_type(*elem_result, BasicTypeDeclaration::MATRIX, (basic_left->size&0xFFFF0000)|(basic_right->size&0xFFFF));
698                 }
699                 else if(compat==NOT_COMPATIBLE)
700                 {
701                         // Arithmetic between scalars and matrices or vectors is supported.
702                         if(is_scalar(*basic_left) && is_vector_or_matrix(*basic_right))
703                                 type = (elem_compat==RIGHT_CONVERTIBLE ? find_type(*elem_left, basic_right->kind, basic_right->size) : basic_right);
704                         else if(is_vector_or_matrix(*basic_left) && is_scalar(*basic_right))
705                                 type = (elem_compat==LEFT_CONVERTIBLE ? find_type(*elem_right, basic_left->kind, basic_left->size) : basic_left);
706                         else
707                                 return;
708                 }
709                 else if(compat==LEFT_CONVERTIBLE)
710                         type = basic_right;
711                 else
712                         type = basic_left;
713         }
714         else
715                 return;
716
717         if(assign && type!=basic_left)
718                 return;
719
720         bool converted = true;
721         if(compat==LEFT_CONVERTIBLE)
722                 convert_to(binary.left, *basic_right);
723         else if(compat==RIGHT_CONVERTIBLE)
724                 convert_to(binary.right, *basic_left);
725         else if(elem_compat==LEFT_CONVERTIBLE)
726                 converted = convert_to_element(binary.left, *elem_right);
727         else if(elem_compat==RIGHT_CONVERTIBLE)
728                 converted = convert_to_element(binary.right, *elem_left);
729
730         if(!converted)
731                 type = 0;
732
733         resolve(binary, type, assign);
734 }
735
736 void ExpressionResolver::visit(BinaryExpression &binary)
737 {
738         TraversingVisitor::visit(binary);
739         visit(binary, false);
740 }
741
742 void ExpressionResolver::visit(Assignment &assign)
743 {
744         TraversingVisitor::visit(assign);
745
746         if(assign.oper->token[0]!='=')
747                 return visit(assign, true);
748         else if(assign.left->type!=assign.right->type)
749         {
750                 BasicTypeDeclaration *basic_left = dynamic_cast<BasicTypeDeclaration *>(assign.left->type);
751                 BasicTypeDeclaration *basic_right = dynamic_cast<BasicTypeDeclaration *>(assign.right->type);
752                 if(!basic_left || !basic_right)
753                         return;
754
755                 Compatibility compat = get_compatibility(*basic_left, *basic_right);
756                 if(compat==RIGHT_CONVERTIBLE)
757                         convert_to(assign.right, *basic_left);
758                 else if(compat!=SAME_TYPE)
759                         return;
760         }
761
762         resolve(assign, assign.left->type, true);
763 }
764
765 void ExpressionResolver::visit(FunctionCall &call)
766 {
767         TraversingVisitor::visit(call);
768
769         TypeDeclaration *type = 0;
770         if(call.declaration)
771                 type = call.declaration->return_type_declaration;
772         else if(call.constructor)
773         {
774                 map<string, TypeDeclaration *>::const_iterator i=stage->types.find(call.name);
775                 type = (i!=stage->types.end() ? i->second : 0);
776         }
777         resolve(call, type, false);
778 }
779
780 void ExpressionResolver::visit(BasicTypeDeclaration &type)
781 {
782         basic_types.push_back(&type);
783 }
784
785 void ExpressionResolver::visit(VariableDeclaration &var)
786 {
787         TraversingVisitor::visit(var);
788         if(!var.init_expression)
789                 return;
790
791         BasicTypeDeclaration *var_basic = dynamic_cast<BasicTypeDeclaration *>(var.type_declaration);
792         BasicTypeDeclaration *init_basic = dynamic_cast<BasicTypeDeclaration *>(var.init_expression->type);
793         if(!var_basic || !init_basic)
794                 return;
795
796         Compatibility compat = get_compatibility(*var_basic, *init_basic);
797         if(compat==RIGHT_CONVERTIBLE)
798                 convert_to(var.init_expression, *var_basic);
799 }
800
801
802 void FunctionResolver::apply(Stage &s)
803 {
804         stage = &s;
805         s.functions.clear();
806         s.content.visit(*this);
807 }
808
809 void FunctionResolver::visit(FunctionCall &call)
810 {
811         map<string, FunctionDeclaration *>::iterator i = stage->functions.find(call.name);
812         if(i!=stage->functions.end())
813                 call.declaration = i->second;
814
815         TraversingVisitor::visit(call);
816 }
817
818 void FunctionResolver::visit(FunctionDeclaration &func)
819 {
820         FunctionDeclaration *&stage_decl = stage->functions[func.name];
821         vector<FunctionDeclaration *> &decls = declarations[func.name];
822         if(func.definition==&func)
823         {
824                 stage_decl = &func;
825
826                 // Set all previous declarations to use this definition.
827                 for(vector<FunctionDeclaration *>::iterator i=decls.begin(); i!=decls.end(); ++i)
828                 {
829                         (*i)->definition = func.definition;
830                         (*i)->body.body.clear();
831                 }
832         }
833         else
834         {
835                 func.definition = 0;
836                 if(!stage_decl)
837                         stage_decl = &func;
838                 else
839                         func.definition = stage_decl->definition;
840         }
841         decls.push_back(&func);
842
843         TraversingVisitor::visit(func);
844 }
845
846
847 InterfaceGenerator::InterfaceGenerator():
848         stage(0),
849         function_scope(false),
850         iface_block(0),
851         copy_block(false),
852         iface_target_block(0)
853 { }
854
855 string InterfaceGenerator::get_out_prefix(Stage::Type type)
856 {
857         if(type==Stage::VERTEX)
858                 return "_vs_out_";
859         else if(type==Stage::GEOMETRY)
860                 return "_gs_out_";
861         else
862                 return string();
863 }
864
865 void InterfaceGenerator::apply(Stage &s)
866 {
867         stage = &s;
868         iface_target_block = &stage->content;
869         if(stage->previous)
870                 in_prefix = get_out_prefix(stage->previous->type);
871         out_prefix = get_out_prefix(stage->type);
872         s.content.visit(*this);
873         NodeRemover().apply(s, nodes_to_remove);
874 }
875
876 void InterfaceGenerator::visit(Block &block)
877 {
878         SetForScope<Block *> set_block(current_block, &block);
879         for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
880         {
881                 assignment_insert_point = i;
882                 if(&block==&stage->content)
883                         iface_insert_point = i;
884
885                 (*i)->visit(*this);
886         }
887 }
888
889 string InterfaceGenerator::change_prefix(const string &name, const string &prefix) const
890 {
891         unsigned offset = (name.compare(0, in_prefix.size(), in_prefix) ? 0 : in_prefix.size());
892         return prefix+name.substr(offset);
893 }
894
895 VariableDeclaration *InterfaceGenerator::generate_interface(VariableDeclaration &var, const string &iface, const string &name)
896 {
897         if(stage->content.variables.count(name))
898                 return 0;
899
900         VariableDeclaration* iface_var = new VariableDeclaration;
901         iface_var->sampling = var.sampling;
902         iface_var->interface = iface;
903         iface_var->type = var.type;
904         iface_var->name = name;
905         /* Geometry shader inputs are always arrays.  But if we're bringing in an
906         entire block, the array is on the block and not individual variables. */
907         if(stage->type==Stage::GEOMETRY && !copy_block)
908                 iface_var->array = ((var.array && var.interface!="in") || iface=="in");
909         else
910                 iface_var->array = var.array;
911         if(iface_var->array)
912                 iface_var->array_size = var.array_size;
913         if(iface=="in")
914         {
915                 iface_var->layout = var.layout;
916                 iface_var->linked_declaration = &var;
917                 var.linked_declaration = iface_var;
918         }
919
920         iface_target_block->body.insert(iface_insert_point, iface_var);
921         iface_target_block->variables.insert(make_pair(name, iface_var));
922
923         return iface_var;
924 }
925
926 InterfaceBlock *InterfaceGenerator::generate_interface(InterfaceBlock &out_block)
927 {
928         if(stage->interface_blocks.count("in"+out_block.name))
929                 return 0;
930
931         InterfaceBlock *in_block = new InterfaceBlock;
932         in_block->interface = "in";
933         in_block->name = out_block.name;
934         in_block->instance_name = out_block.instance_name;
935         if(stage->type==Stage::GEOMETRY)
936                 in_block->array = true;
937         else
938                 in_block->array = out_block.array;
939         in_block->linked_block = &out_block;
940         out_block.linked_block = in_block;
941
942         {
943                 SetFlag set_copy(copy_block, true);
944                 SetForScope<Block *> set_target(iface_target_block, &in_block->members);
945                 SetForScope<NodeList<Statement>::iterator> set_ins_pt(iface_insert_point, in_block->members.body.end());
946                 out_block.members.visit(*this);
947         }
948
949         iface_target_block->body.insert(iface_insert_point, in_block);
950         stage->interface_blocks.insert(make_pair("in"+in_block->name, in_block));
951         if(!in_block->instance_name.empty())
952                 stage->interface_blocks.insert(make_pair("_"+in_block->instance_name, in_block));
953
954         SetFlag set_scope(function_scope, false);
955         SetForScope<Block *> set_block(current_block, &stage->content);
956         in_block->visit(*this);
957
958         return in_block;
959 }
960
961 ExpressionStatement &InterfaceGenerator::insert_assignment(const string &left, Expression *right)
962 {
963         Assignment *assign = new Assignment;
964         VariableReference *ref = new VariableReference;
965         ref->name = left;
966         assign->left = ref;
967         assign->oper = &Operator::get_operator("=", Operator::BINARY);
968         assign->right = right;
969
970         ExpressionStatement *stmt = new ExpressionStatement;
971         stmt->expression = assign;
972         current_block->body.insert(assignment_insert_point, stmt);
973         stmt->visit(*this);
974
975         return *stmt;
976 }
977
978 void InterfaceGenerator::visit(VariableReference &var)
979 {
980         if(var.declaration || !stage->previous)
981                 return;
982         /* Don't pull a variable from previous stage if we just generated an output
983         interface in this stage */
984         if(stage->content.variables.count(var.name))
985                 return;
986
987         const map<string, VariableDeclaration *> &prev_vars = stage->previous->content.variables;
988         map<string, VariableDeclaration *>::const_iterator i = prev_vars.find(var.name);
989         if(i==prev_vars.end() || i->second->interface!="out")
990                 i = prev_vars.find(in_prefix+var.name);
991         if(i!=prev_vars.end() && i->second->interface=="out")
992         {
993                 generate_interface(*i->second, "in", i->second->name);
994                 var.name = i->second->name;
995                 return;
996         }
997
998         const map<string, InterfaceBlock *> &prev_blocks = stage->previous->interface_blocks;
999         map<string, InterfaceBlock *>::const_iterator j = prev_blocks.find("_"+var.name);
1000         if(j!=prev_blocks.end() && j->second->interface=="out")
1001         {
1002                 generate_interface(*j->second);
1003                 /* Let VariableResolver convert the variable reference into an interface
1004                 block reference. */
1005                 return;
1006         }
1007
1008         for(j=prev_blocks.begin(); j!=prev_blocks.end(); ++j)
1009                 if(j->second->instance_name.empty())
1010                 {
1011                         i = j->second->members.variables.find(var.name);
1012                         if(i!=j->second->members.variables.end())
1013                         {
1014                                 generate_interface(*j->second);
1015                                 return;
1016                         }
1017                 }
1018 }
1019
1020 void InterfaceGenerator::visit(VariableDeclaration &var)
1021 {
1022         if(copy_block)
1023         {
1024                 generate_interface(var, "in", var.name);
1025                 return;
1026         }
1027
1028         if(iface_block)
1029         {
1030                 if(iface_block->linked_block)
1031                 {
1032                         // Link all variables to their counterparts in the linked block.
1033                         const map<string, VariableDeclaration *> &linked_vars = iface_block->linked_block->members.variables;
1034                         map<string, VariableDeclaration *>::const_iterator i = linked_vars.find(var.name);
1035                         if(i!=linked_vars.end())
1036                         {
1037                                 var.linked_declaration = i->second;
1038                                 var.linked_declaration->linked_declaration = &var;
1039                         }
1040                 }
1041                 return;
1042         }
1043
1044         if(var.interface=="out")
1045         {
1046                 /* For output variables in function scope, generate a global interface
1047                 and replace the local declaration with an assignment. */
1048                 VariableDeclaration *out_var = 0;
1049                 if(function_scope && (out_var=generate_interface(var, "out", var.name)))
1050                 {
1051                         out_var->source = var.source;
1052                         out_var->line = var.line;
1053                         nodes_to_remove.insert(&var);
1054                         if(var.init_expression)
1055                         {
1056                                 ExpressionStatement &stmt = insert_assignment(var.name, var.init_expression->clone());
1057                                 stmt.source = var.source;
1058                                 stmt.line = var.line;
1059                                 return;
1060                         }
1061                 }
1062         }
1063         else if(var.interface=="in")
1064         {
1065                 /* Try to link input variables in global scope with output variables from
1066                 previous stage. */
1067                 if(current_block==&stage->content && !var.linked_declaration && stage->previous)
1068                 {
1069                         const map<string, VariableDeclaration *> &prev_vars = stage->previous->content.variables;
1070                         map<string, VariableDeclaration *>::const_iterator i = prev_vars.find(var.name);
1071                         if(i!=prev_vars.end() && i->second->interface=="out")
1072                         {
1073                                 var.linked_declaration = i->second;
1074                                 i->second->linked_declaration = &var;
1075                         }
1076                 }
1077         }
1078
1079         TraversingVisitor::visit(var);
1080 }
1081
1082 void InterfaceGenerator::visit(InterfaceBlock &iface)
1083 {
1084         if(iface.interface=="in")
1085         {
1086                 /* Try to link input blocks with output blocks sharing the same block
1087                 name from previous stage. */
1088                 if(!iface.linked_block && stage->previous)
1089                 {
1090                         const map<string, InterfaceBlock *> &prev_blocks = stage->previous->interface_blocks;
1091                         map<string, InterfaceBlock *>::const_iterator i = prev_blocks.find("out"+iface.name);
1092                         if(i!=prev_blocks.end())
1093                         {
1094                                 iface.linked_block = i->second;
1095                                 i->second->linked_block = &iface;
1096                         }
1097                 }
1098         }
1099
1100         SetForScope<InterfaceBlock *> set_iface(iface_block, &iface);
1101         TraversingVisitor::visit(iface);
1102 }
1103
1104 void InterfaceGenerator::visit(FunctionDeclaration &func)
1105 {
1106         SetFlag set_scope(function_scope, true);
1107         // Skip parameters because they're not useful here
1108         func.body.visit(*this);
1109 }
1110
1111 void InterfaceGenerator::visit(Passthrough &pass)
1112 {
1113         vector<VariableDeclaration *> pass_vars;
1114
1115         // Pass through all input variables of this stage.
1116         for(map<string, VariableDeclaration *>::const_iterator i=stage->content.variables.begin(); i!=stage->content.variables.end(); ++i)
1117                 if(i->second->interface=="in")
1118                         pass_vars.push_back(i->second);
1119
1120         if(stage->previous)
1121         {
1122                 const map<string, VariableDeclaration *> &prev_vars = stage->previous->content.variables;
1123                 for(map<string, VariableDeclaration *>::const_iterator i=prev_vars.begin(); i!=prev_vars.end(); ++i)
1124                 {
1125                         if(i->second->interface!="out")
1126                                 continue;
1127
1128                         /* Pass through output variables from the previous stage, but only
1129                         those which are not already linked to an input here. */
1130                         if(!i->second->linked_declaration && generate_interface(*i->second, "in", i->second->name))
1131                                 pass_vars.push_back(i->second);
1132                 }
1133         }
1134
1135         if(stage->type==Stage::GEOMETRY)
1136         {
1137                 /* Special case for geometry shader: copy gl_Position from input to
1138                 output. */
1139                 InterfaceBlockReference *ref = new InterfaceBlockReference;
1140                 ref->name = "gl_in";
1141
1142                 BinaryExpression *subscript = new BinaryExpression;
1143                 subscript->left = ref;
1144                 subscript->oper = &Operator::get_operator("[", Operator::BINARY);
1145                 subscript->right = pass.subscript;
1146
1147                 MemberAccess *memacc = new MemberAccess;
1148                 memacc->left = subscript;
1149                 memacc->member = "gl_Position";
1150
1151                 insert_assignment("gl_Position", memacc);
1152         }
1153
1154         for(vector<VariableDeclaration *>::const_iterator i=pass_vars.begin(); i!=pass_vars.end(); ++i)
1155         {
1156                 string out_name = change_prefix((*i)->name, out_prefix);
1157                 generate_interface(**i, "out", out_name);
1158
1159                 VariableReference *ref = new VariableReference;
1160                 ref->name = (*i)->name;
1161                 if(pass.subscript)
1162                 {
1163                         BinaryExpression *subscript = new BinaryExpression;
1164                         subscript->left = ref;
1165                         subscript->oper = &Operator::get_operator("[", Operator::BINARY);
1166                         subscript->right = pass.subscript;
1167                         insert_assignment(out_name, subscript);
1168                 }
1169                 else
1170                         insert_assignment(out_name, ref);
1171         }
1172
1173         nodes_to_remove.insert(&pass);
1174 }
1175
1176 } // namespace SL
1177 } // namespace GL
1178 } // namespace Msp