Enforce fragment precision qualifier requirement
TRAC #12156
The fragment shader has no default precision qualifier for floating-point types,
so compilation should fail when it's not set explicitly globally or per declaration.
Signed-off-by: Shannon Woods
Signed-off-by: Daniel Koch

Author:    Nicolas Capens

git-svn-id: https://angleproject.googlecode.com/svn/trunk@293 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/SymbolTable.h b/src/compiler/SymbolTable.h
index f58cdb8..fa6e64d 100644
--- a/src/compiler/SymbolTable.h
+++ b/src/compiler/SymbolTable.h
@@ -129,7 +129,7 @@
 public:
     TFunction(TOperator o) :
         TSymbol(0),
-        returnType(TType(EbtVoid)),
+        returnType(TType(EbtVoid, EbpUndefined)),
         op(o),
         defined(false) { }
     TFunction(const TString *name, TType& retType, TOperator tOp = EOpNull) : 
@@ -241,6 +241,7 @@
     TSymbolTable(TSymbolTable& symTable)
     {
         table.push_back(symTable.table[0]);
+        precisionStack.push_back( symTable.precisionStack[0] );
         uniqueId = symTable.uniqueId;
     }
 
@@ -263,12 +264,14 @@
     void push()
     { 
         table.push_back(new TSymbolTableLevel);
+        precisionStack.push_back( PrecisionStackLevel() );
     }
 
     void pop()
     { 
         delete table[currentLevel()]; 
         table.pop_back(); 
+        precisionStack.pop_back();
     }
 
     bool insert(TSymbol& symbol)
@@ -299,11 +302,37 @@
     void dump(TInfoSink &infoSink) const;
     void copyTable(const TSymbolTable& copyOf);
 
+    void setDefaultPrecision( TBasicType type, TPrecision prec ){
+        if( type != EbtFloat && type != EbtInt ) return; // Only set default precision for int/float
+        int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
+        precisionStack[indexOfLastElement][type] = prec; // Uses map operator [], overwrites the current value
+    }
+
+    // Searches down the precisionStack for a precision qualifier for the specified TBasicType
+    TPrecision getDefaultPrecision( TBasicType type){
+        if( type != EbtFloat && type != EbtInt ) return EbpUndefined;
+        int level = static_cast<int>(precisionStack.size()) - 1;
+        assert( level >= 0); // Just to be safe. Should not happen.
+        PrecisionStackLevel::iterator it;
+        TPrecision prec = EbpUndefined; // If we dont find anything we return this. Should we error check this?
+        while( level >= 0 ){
+            it = precisionStack[level].find( type );
+            if( it != precisionStack[level].end() ){
+                prec = (*it).second;
+                break;
+            }
+            level--;
+        }
+        return prec;
+    }
+
 protected:    
     int currentLevel() const { return static_cast<int>(table.size()) - 1; }
     bool atDynamicBuiltInLevel() { return table.size() == 2; }
 
     std::vector<TSymbolTableLevel*> table;
+    typedef std::map< TBasicType, TPrecision > PrecisionStackLevel;
+    std::vector< PrecisionStackLevel > precisionStack;
     int uniqueId;     // for unique identification in code generation
 };