]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/generate.cpp
Rearrange expression node replacement
[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)
588 {
589         TraversingVisitor::visit(binary);
590
591         /* Binary operators are only defined for basic types (not for image or
592         structure types). */
593         BasicTypeDeclaration *basic_left = dynamic_cast<BasicTypeDeclaration *>(binary.left->type);
594         BasicTypeDeclaration *basic_right = dynamic_cast<BasicTypeDeclaration *>(binary.right->type);
595         if(!basic_left || !basic_right)
596                 return;
597
598         char oper = binary.oper->token[0];
599         if(oper=='[')
600         {
601                 /* Subscripting operates on vectors, matrices and arrays, and the right
602                 operand must be an integer. */
603                 if((!is_vector_or_matrix(*basic_left) && basic_left->kind!=BasicTypeDeclaration::ARRAY) || basic_right->kind!=BasicTypeDeclaration::INT)
604                         return;
605
606                 resolve(binary, basic_left->base_type, binary.left->lvalue);
607                 return;
608         }
609         else if(basic_left->kind==BasicTypeDeclaration::ARRAY || basic_right->kind==BasicTypeDeclaration::ARRAY)
610                 // No other binary operator can be used with arrays.
611                 return;
612
613         BasicTypeDeclaration *elem_left = get_element_type(*basic_left);
614         BasicTypeDeclaration *elem_right = get_element_type(*basic_right);
615         if(!elem_left || !elem_right)
616                 return;
617
618         Compatibility compat = get_compatibility(*basic_left, *basic_right);
619         Compatibility elem_compat = get_compatibility(*elem_left, *elem_right);
620         if(elem_compat==NOT_COMPATIBLE)
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 only apply to integers.
661                 if(basic_left->kind!=BasicTypeDeclaration::INT || basic_right->kind!=BasicTypeDeclaration::INT)
662                         return;
663
664                 type = basic_left;
665         }
666         else if(oper=='+' || oper=='-' || oper=='*' || oper=='/')
667         {
668                 // Arithmetic operators require scalar elements.
669                 if(!is_scalar(*elem_left) || !is_scalar(*elem_right))
670                         return;
671
672                 if(oper=='*' && is_vector_or_matrix(*basic_left) && is_vector_or_matrix(*basic_right) &&
673                         (basic_left->kind==BasicTypeDeclaration::MATRIX || basic_right->kind==BasicTypeDeclaration::MATRIX))
674                 {
675                         /* Multiplication has special rules when at least one operand is a
676                         matrix and the other is a vector or a matrix. */
677                         unsigned left_columns = basic_left->size&0xFFFF;
678                         unsigned right_rows = basic_right->size;
679                         if(basic_right->kind==BasicTypeDeclaration::MATRIX)
680                                 right_rows >>= 16;
681                         if(left_columns!=right_rows)
682                                 return;
683
684                         BasicTypeDeclaration *elem_result = (elem_compat==LEFT_CONVERTIBLE ? elem_right : elem_left);
685
686                         if(basic_left->kind==BasicTypeDeclaration::VECTOR)
687                                 type = find_type(*elem_result, BasicTypeDeclaration::VECTOR, basic_right->size&0xFFFF);
688                         else if(basic_right->kind==BasicTypeDeclaration::VECTOR)
689                                 type = find_type(*elem_result, BasicTypeDeclaration::VECTOR, basic_left->size>>16);
690                         else
691                                 type = find_type(*elem_result, BasicTypeDeclaration::MATRIX, (basic_left->size&0xFFFF0000)|(basic_right->size&0xFFFF));
692                 }
693                 else if(compat==NOT_COMPATIBLE)
694                 {
695                         // Arithmetic between scalars and matrices or vectors is supported.
696                         if(is_scalar(*basic_left) && is_vector_or_matrix(*basic_right))
697                                 type = (elem_compat==RIGHT_CONVERTIBLE ? find_type(*elem_left, basic_right->kind, basic_right->size) : basic_right);
698                         else if(is_vector_or_matrix(*basic_left) && is_scalar(*basic_right))
699                                 type = (elem_compat==LEFT_CONVERTIBLE ? find_type(*elem_right, basic_left->kind, basic_left->size) : basic_left);
700                         else
701                                 return;
702                 }
703                 else if(compat==LEFT_CONVERTIBLE)
704                         type = basic_right;
705                 else
706                         type = basic_left;
707         }
708         else
709                 return;
710
711         bool converted = true;
712         if(compat==LEFT_CONVERTIBLE)
713                 convert_to(binary.left, *basic_right);
714         else if(compat==RIGHT_CONVERTIBLE)
715                 convert_to(binary.right, *basic_left);
716         else if(elem_compat==LEFT_CONVERTIBLE)
717                 converted = convert_to_element(binary.left, *elem_right);
718         else if(elem_compat==RIGHT_CONVERTIBLE)
719                 converted = convert_to_element(binary.right, *elem_left);
720
721         if(!converted)
722                 type = 0;
723
724         resolve(binary, type, false);
725 }
726
727 void ExpressionResolver::visit(Assignment &assign)
728 {
729         TraversingVisitor::visit(assign);
730         resolve(assign, assign.left->type, true);
731 }
732
733 void ExpressionResolver::visit(FunctionCall &call)
734 {
735         TraversingVisitor::visit(call);
736
737         TypeDeclaration *type = 0;
738         if(call.declaration)
739                 type = call.declaration->return_type_declaration;
740         else if(call.constructor)
741         {
742                 map<string, TypeDeclaration *>::const_iterator i=stage->types.find(call.name);
743                 type = (i!=stage->types.end() ? i->second : 0);
744         }
745         resolve(call, type, false);
746 }
747
748 void ExpressionResolver::visit(BasicTypeDeclaration &type)
749 {
750         basic_types.push_back(&type);
751 }
752
753 void ExpressionResolver::visit(VariableDeclaration &var)
754 {
755         TraversingVisitor::visit(var);
756         if(!var.init_expression)
757                 return;
758
759         BasicTypeDeclaration *var_basic = dynamic_cast<BasicTypeDeclaration *>(var.type_declaration);
760         BasicTypeDeclaration *init_basic = dynamic_cast<BasicTypeDeclaration *>(var.init_expression->type);
761         if(!var_basic || !init_basic)
762                 return;
763
764         Compatibility compat = get_compatibility(*var_basic, *init_basic);
765         if(compat==RIGHT_CONVERTIBLE)
766                 convert_to(var.init_expression, *var_basic);
767 }
768
769
770 void FunctionResolver::apply(Stage &s)
771 {
772         stage = &s;
773         s.functions.clear();
774         s.content.visit(*this);
775 }
776
777 void FunctionResolver::visit(FunctionCall &call)
778 {
779         map<string, FunctionDeclaration *>::iterator i = stage->functions.find(call.name);
780         if(i!=stage->functions.end())
781                 call.declaration = i->second;
782
783         TraversingVisitor::visit(call);
784 }
785
786 void FunctionResolver::visit(FunctionDeclaration &func)
787 {
788         FunctionDeclaration *&stage_decl = stage->functions[func.name];
789         vector<FunctionDeclaration *> &decls = declarations[func.name];
790         if(func.definition==&func)
791         {
792                 stage_decl = &func;
793
794                 // Set all previous declarations to use this definition.
795                 for(vector<FunctionDeclaration *>::iterator i=decls.begin(); i!=decls.end(); ++i)
796                 {
797                         (*i)->definition = func.definition;
798                         (*i)->body.body.clear();
799                 }
800         }
801         else
802         {
803                 func.definition = 0;
804                 if(!stage_decl)
805                         stage_decl = &func;
806                 else
807                         func.definition = stage_decl->definition;
808         }
809         decls.push_back(&func);
810
811         TraversingVisitor::visit(func);
812 }
813
814
815 InterfaceGenerator::InterfaceGenerator():
816         stage(0),
817         function_scope(false),
818         iface_block(0),
819         copy_block(false),
820         iface_target_block(0)
821 { }
822
823 string InterfaceGenerator::get_out_prefix(Stage::Type type)
824 {
825         if(type==Stage::VERTEX)
826                 return "_vs_out_";
827         else if(type==Stage::GEOMETRY)
828                 return "_gs_out_";
829         else
830                 return string();
831 }
832
833 void InterfaceGenerator::apply(Stage &s)
834 {
835         stage = &s;
836         iface_target_block = &stage->content;
837         if(stage->previous)
838                 in_prefix = get_out_prefix(stage->previous->type);
839         out_prefix = get_out_prefix(stage->type);
840         s.content.visit(*this);
841         NodeRemover().apply(s, nodes_to_remove);
842 }
843
844 void InterfaceGenerator::visit(Block &block)
845 {
846         SetForScope<Block *> set_block(current_block, &block);
847         for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
848         {
849                 assignment_insert_point = i;
850                 if(&block==&stage->content)
851                         iface_insert_point = i;
852
853                 (*i)->visit(*this);
854         }
855 }
856
857 string InterfaceGenerator::change_prefix(const string &name, const string &prefix) const
858 {
859         unsigned offset = (name.compare(0, in_prefix.size(), in_prefix) ? 0 : in_prefix.size());
860         return prefix+name.substr(offset);
861 }
862
863 VariableDeclaration *InterfaceGenerator::generate_interface(VariableDeclaration &var, const string &iface, const string &name)
864 {
865         if(stage->content.variables.count(name))
866                 return 0;
867
868         VariableDeclaration* iface_var = new VariableDeclaration;
869         iface_var->sampling = var.sampling;
870         iface_var->interface = iface;
871         iface_var->type = var.type;
872         iface_var->name = name;
873         /* Geometry shader inputs are always arrays.  But if we're bringing in an
874         entire block, the array is on the block and not individual variables. */
875         if(stage->type==Stage::GEOMETRY && !copy_block)
876                 iface_var->array = ((var.array && var.interface!="in") || iface=="in");
877         else
878                 iface_var->array = var.array;
879         if(iface_var->array)
880                 iface_var->array_size = var.array_size;
881         if(iface=="in")
882         {
883                 iface_var->layout = var.layout;
884                 iface_var->linked_declaration = &var;
885                 var.linked_declaration = iface_var;
886         }
887
888         iface_target_block->body.insert(iface_insert_point, iface_var);
889         iface_target_block->variables.insert(make_pair(name, iface_var));
890
891         return iface_var;
892 }
893
894 InterfaceBlock *InterfaceGenerator::generate_interface(InterfaceBlock &out_block)
895 {
896         if(stage->interface_blocks.count("in"+out_block.name))
897                 return 0;
898
899         InterfaceBlock *in_block = new InterfaceBlock;
900         in_block->interface = "in";
901         in_block->name = out_block.name;
902         in_block->instance_name = out_block.instance_name;
903         if(stage->type==Stage::GEOMETRY)
904                 in_block->array = true;
905         else
906                 in_block->array = out_block.array;
907         in_block->linked_block = &out_block;
908         out_block.linked_block = in_block;
909
910         {
911                 SetFlag set_copy(copy_block, true);
912                 SetForScope<Block *> set_target(iface_target_block, &in_block->members);
913                 SetForScope<NodeList<Statement>::iterator> set_ins_pt(iface_insert_point, in_block->members.body.end());
914                 out_block.members.visit(*this);
915         }
916
917         iface_target_block->body.insert(iface_insert_point, in_block);
918         stage->interface_blocks.insert(make_pair("in"+in_block->name, in_block));
919         if(!in_block->instance_name.empty())
920                 stage->interface_blocks.insert(make_pair("_"+in_block->instance_name, in_block));
921
922         SetFlag set_scope(function_scope, false);
923         SetForScope<Block *> set_block(current_block, &stage->content);
924         in_block->visit(*this);
925
926         return in_block;
927 }
928
929 ExpressionStatement &InterfaceGenerator::insert_assignment(const string &left, Expression *right)
930 {
931         Assignment *assign = new Assignment;
932         VariableReference *ref = new VariableReference;
933         ref->name = left;
934         assign->left = ref;
935         assign->oper = &Operator::get_operator("=", Operator::BINARY);
936         assign->right = right;
937
938         ExpressionStatement *stmt = new ExpressionStatement;
939         stmt->expression = assign;
940         current_block->body.insert(assignment_insert_point, stmt);
941         stmt->visit(*this);
942
943         return *stmt;
944 }
945
946 void InterfaceGenerator::visit(VariableReference &var)
947 {
948         if(var.declaration || !stage->previous)
949                 return;
950         /* Don't pull a variable from previous stage if we just generated an output
951         interface in this stage */
952         if(stage->content.variables.count(var.name))
953                 return;
954
955         const map<string, VariableDeclaration *> &prev_vars = stage->previous->content.variables;
956         map<string, VariableDeclaration *>::const_iterator i = prev_vars.find(var.name);
957         if(i==prev_vars.end() || i->second->interface!="out")
958                 i = prev_vars.find(in_prefix+var.name);
959         if(i!=prev_vars.end() && i->second->interface=="out")
960         {
961                 generate_interface(*i->second, "in", i->second->name);
962                 var.name = i->second->name;
963                 return;
964         }
965
966         const map<string, InterfaceBlock *> &prev_blocks = stage->previous->interface_blocks;
967         map<string, InterfaceBlock *>::const_iterator j = prev_blocks.find("_"+var.name);
968         if(j!=prev_blocks.end() && j->second->interface=="out")
969         {
970                 generate_interface(*j->second);
971                 /* Let VariableResolver convert the variable reference into an interface
972                 block reference. */
973                 return;
974         }
975
976         for(j=prev_blocks.begin(); j!=prev_blocks.end(); ++j)
977                 if(j->second->instance_name.empty())
978                 {
979                         i = j->second->members.variables.find(var.name);
980                         if(i!=j->second->members.variables.end())
981                         {
982                                 generate_interface(*j->second);
983                                 return;
984                         }
985                 }
986 }
987
988 void InterfaceGenerator::visit(VariableDeclaration &var)
989 {
990         if(copy_block)
991         {
992                 generate_interface(var, "in", var.name);
993                 return;
994         }
995
996         if(iface_block)
997         {
998                 if(iface_block->linked_block)
999                 {
1000                         // Link all variables to their counterparts in the linked block.
1001                         const map<string, VariableDeclaration *> &linked_vars = iface_block->linked_block->members.variables;
1002                         map<string, VariableDeclaration *>::const_iterator i = linked_vars.find(var.name);
1003                         if(i!=linked_vars.end())
1004                         {
1005                                 var.linked_declaration = i->second;
1006                                 var.linked_declaration->linked_declaration = &var;
1007                         }
1008                 }
1009                 return;
1010         }
1011
1012         if(var.interface=="out")
1013         {
1014                 /* For output variables in function scope, generate a global interface
1015                 and replace the local declaration with an assignment. */
1016                 VariableDeclaration *out_var = 0;
1017                 if(function_scope && (out_var=generate_interface(var, "out", var.name)))
1018                 {
1019                         out_var->source = var.source;
1020                         out_var->line = var.line;
1021                         nodes_to_remove.insert(&var);
1022                         if(var.init_expression)
1023                         {
1024                                 ExpressionStatement &stmt = insert_assignment(var.name, var.init_expression->clone());
1025                                 stmt.source = var.source;
1026                                 stmt.line = var.line;
1027                                 return;
1028                         }
1029                 }
1030         }
1031         else if(var.interface=="in")
1032         {
1033                 /* Try to link input variables in global scope with output variables from
1034                 previous stage. */
1035                 if(current_block==&stage->content && !var.linked_declaration && stage->previous)
1036                 {
1037                         const map<string, VariableDeclaration *> &prev_vars = stage->previous->content.variables;
1038                         map<string, VariableDeclaration *>::const_iterator i = prev_vars.find(var.name);
1039                         if(i!=prev_vars.end() && i->second->interface=="out")
1040                         {
1041                                 var.linked_declaration = i->second;
1042                                 i->second->linked_declaration = &var;
1043                         }
1044                 }
1045         }
1046
1047         TraversingVisitor::visit(var);
1048 }
1049
1050 void InterfaceGenerator::visit(InterfaceBlock &iface)
1051 {
1052         if(iface.interface=="in")
1053         {
1054                 /* Try to link input blocks with output blocks sharing the same block
1055                 name from previous stage. */
1056                 if(!iface.linked_block && stage->previous)
1057                 {
1058                         const map<string, InterfaceBlock *> &prev_blocks = stage->previous->interface_blocks;
1059                         map<string, InterfaceBlock *>::const_iterator i = prev_blocks.find("out"+iface.name);
1060                         if(i!=prev_blocks.end())
1061                         {
1062                                 iface.linked_block = i->second;
1063                                 i->second->linked_block = &iface;
1064                         }
1065                 }
1066         }
1067
1068         SetForScope<InterfaceBlock *> set_iface(iface_block, &iface);
1069         TraversingVisitor::visit(iface);
1070 }
1071
1072 void InterfaceGenerator::visit(FunctionDeclaration &func)
1073 {
1074         SetFlag set_scope(function_scope, true);
1075         // Skip parameters because they're not useful here
1076         func.body.visit(*this);
1077 }
1078
1079 void InterfaceGenerator::visit(Passthrough &pass)
1080 {
1081         vector<VariableDeclaration *> pass_vars;
1082
1083         // Pass through all input variables of this stage.
1084         for(map<string, VariableDeclaration *>::const_iterator i=stage->content.variables.begin(); i!=stage->content.variables.end(); ++i)
1085                 if(i->second->interface=="in")
1086                         pass_vars.push_back(i->second);
1087
1088         if(stage->previous)
1089         {
1090                 const map<string, VariableDeclaration *> &prev_vars = stage->previous->content.variables;
1091                 for(map<string, VariableDeclaration *>::const_iterator i=prev_vars.begin(); i!=prev_vars.end(); ++i)
1092                 {
1093                         if(i->second->interface!="out")
1094                                 continue;
1095
1096                         /* Pass through output variables from the previous stage, but only
1097                         those which are not already linked to an input here. */
1098                         if(!i->second->linked_declaration && generate_interface(*i->second, "in", i->second->name))
1099                                 pass_vars.push_back(i->second);
1100                 }
1101         }
1102
1103         if(stage->type==Stage::GEOMETRY)
1104         {
1105                 /* Special case for geometry shader: copy gl_Position from input to
1106                 output. */
1107                 InterfaceBlockReference *ref = new InterfaceBlockReference;
1108                 ref->name = "gl_in";
1109
1110                 BinaryExpression *subscript = new BinaryExpression;
1111                 subscript->left = ref;
1112                 subscript->oper = &Operator::get_operator("[", Operator::BINARY);
1113                 subscript->right = pass.subscript;
1114
1115                 MemberAccess *memacc = new MemberAccess;
1116                 memacc->left = subscript;
1117                 memacc->member = "gl_Position";
1118
1119                 insert_assignment("gl_Position", memacc);
1120         }
1121
1122         for(vector<VariableDeclaration *>::const_iterator i=pass_vars.begin(); i!=pass_vars.end(); ++i)
1123         {
1124                 string out_name = change_prefix((*i)->name, out_prefix);
1125                 generate_interface(**i, "out", out_name);
1126
1127                 VariableReference *ref = new VariableReference;
1128                 ref->name = (*i)->name;
1129                 if(pass.subscript)
1130                 {
1131                         BinaryExpression *subscript = new BinaryExpression;
1132                         subscript->left = ref;
1133                         subscript->oper = &Operator::get_operator("[", Operator::BINARY);
1134                         subscript->right = pass.subscript;
1135                         insert_assignment(out_name, subscript);
1136                 }
1137                 else
1138                         insert_assignment(out_name, ref);
1139         }
1140
1141         nodes_to_remove.insert(&pass);
1142 }
1143
1144 } // namespace SL
1145 } // namespace GL
1146 } // namespace Msp