Implemented validation for loop and indexing limitations specified by GLSL ES spec 1.0 Appendix A Section 4 and 5.
A couple of things to note:
- This CL only validates the "form" of loop and indexing. It does not detect number-of-iterations or out-of-bound access. This will require more involved analysis/heuristics.
- I haved combined SH_VALIDATE_CONTROL_FLOW and SH_VALIDATE_INDEXING into one flag - SH_VALIDATE_LOOP_INDEXING. Validating both together is much easier.
BUG=48
Review URL: http://codereview.appspot.com/3225041

git-svn-id: https://angleproject.googlecode.com/svn/trunk@491 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/Intermediate.cpp b/src/compiler/Intermediate.cpp
index 4591cfb..ea71234 100644
--- a/src/compiler/Intermediate.cpp
+++ b/src/compiler/Intermediate.cpp
@@ -22,6 +22,101 @@
     return left > right ? left : right;
 }
 
+const char* getOperatorString(TOperator op) {
+    switch (op) {
+      case EOpInitialize: return "=";
+      case EOpAssign: return "=";
+      case EOpAddAssign: return "+=";
+      case EOpSubAssign: return "-=";
+      case EOpDivAssign: return "/=";
+
+      // Fall-through.
+      case EOpMulAssign: 
+      case EOpVectorTimesMatrixAssign:
+      case EOpVectorTimesScalarAssign:
+      case EOpMatrixTimesScalarAssign:
+      case EOpMatrixTimesMatrixAssign: return "*=";
+
+      // Fall-through.
+      case EOpIndexDirect:
+      case EOpIndexIndirect: return "[]";
+
+      case EOpIndexDirectStruct: return ".";
+      case EOpVectorSwizzle: return ".";
+      case EOpAdd: return "+";
+      case EOpSub: return "-";
+      case EOpMul: return "*";
+      case EOpDiv: return "/";
+      case EOpMod: UNIMPLEMENTED(); break;
+      case EOpEqual: return "==";
+      case EOpNotEqual: return "!=";
+      case EOpLessThan: return "<";
+      case EOpGreaterThan: return ">";
+      case EOpLessThanEqual: return "<=";
+      case EOpGreaterThanEqual: return ">=";
+
+      // Fall-through.
+      case EOpVectorTimesScalar:
+      case EOpVectorTimesMatrix:
+      case EOpMatrixTimesVector:
+      case EOpMatrixTimesScalar:
+      case EOpMatrixTimesMatrix: return "*";
+
+      case EOpLogicalOr: return "||";
+      case EOpLogicalXor: return "^^";
+      case EOpLogicalAnd: return "&&";
+      case EOpNegative: return "-";
+      case EOpVectorLogicalNot: return "not";
+      case EOpLogicalNot: return "!";
+      case EOpPostIncrement: return "++";
+      case EOpPostDecrement: return "--";
+      case EOpPreIncrement: return "++";
+      case EOpPreDecrement: return "--";
+
+      // Fall-through.
+      case EOpConvIntToBool:
+      case EOpConvFloatToBool: return "bool";
+ 
+      // Fall-through.
+      case EOpConvBoolToFloat:
+      case EOpConvIntToFloat: return "float";
+ 
+      // Fall-through.
+      case EOpConvFloatToInt:
+      case EOpConvBoolToInt: return "int";
+
+      case EOpRadians: return "radians";
+      case EOpDegrees: return "degrees";
+      case EOpSin: return "sin";
+      case EOpCos: return "cos";
+      case EOpTan: return "tan";
+      case EOpAsin: return "asin";
+      case EOpAcos: return "acos";
+      case EOpAtan: return "atan";
+      case EOpExp: return "exp";
+      case EOpLog: return "log";
+      case EOpExp2: return "exp2";
+      case EOpLog2: return "log2";
+      case EOpSqrt: return "sqrt";
+      case EOpInverseSqrt: return "inversesqrt";
+      case EOpAbs: return "abs";
+      case EOpSign: return "sign";
+      case EOpFloor: return "floor";
+      case EOpCeil: return "ceil";
+      case EOpFract: return "fract";
+      case EOpLength: return "length";
+      case EOpNormalize: return "normalize";
+      case EOpDFdx: return "dFdx";
+      case EOpDFdy: return "dFdy";
+      case EOpFwidth: return "fwidth";
+      case EOpAny: return "any";
+      case EOpAll: return "all";
+
+      default: break;
+    }
+    return "";
+}
+
 ////////////////////////////////////////////////////////////////////////////
 //
 // First set of functions are to help build the intermediate representation.