diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 9ead5dcabaa26f6e907f36a645ac2e1dc02adbff..3b0bc4e34267ef75a606354af10976b490451ead 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -70,7 +70,7 @@ void TParseContext::setVersion(int newVersion)
 			defaultPrecision[EbtFloat] = EpqHigh;
 			defaultPrecision[EbtSampler2D] = EpqLow;
 			defaultPrecision[EbtSamplerCube] = EpqLow;
-        }
+}
 
         if (language == EShLangFragment)  {
 			defaultPrecision[EbtInt] = EpqMedium;
@@ -728,7 +728,6 @@ bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType
 
 void TParseContext::setDefaultPrecision(int line, TBasicType type, TPrecisionQualifier qualifier)
 {
-    // TODO: push and pop for nested scopes
     if (IsSampler(type) || type == EbtInt || type == EbtFloat) {
         defaultPrecision[type] = qualifier;
     } else {
@@ -772,7 +771,12 @@ bool TParseContext::insertBuiltInArrayAtGlobalLevel()
         error(0, "INTERNAL ERROR finding symbol", name->c_str(), "");
         return true;
     }
-    TVariable* variable = static_cast<TVariable*>(symbol);
+    TVariable* variable = symbol->getAsVariable();
+
+    if (! variable) {
+        error(0, "INTERNAL ERROR, variable expected", name->c_str(), "");
+        return true;
+    }
 
     TVariable* newVariable = new TVariable(name, variable->getType());
 
@@ -785,8 +789,6 @@ bool TParseContext::insertBuiltInArrayAtGlobalLevel()
     return false;
 }
 
-
-
 //
 // Do size checking for an array type's size.
 //
@@ -877,12 +879,13 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t
             return true;
         }
     } else {
-        if (! symbol->isVariable()) {
-            error(line, "variable expected", identifier.c_str(), "");
+        variable = symbol->getAsVariable();
+
+        if (! variable) {
+            error(line, "array variable name expected", identifier.c_str(), "");
             return true;
         }
 
-        variable = static_cast<TVariable*>(symbol);
         if (! variable->getType().isArray()) {
             error(line, "redeclaring non-array as array", identifier.c_str(), "");
             return true;
@@ -924,7 +927,12 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size,
         error(line, " undeclared identifier", node->getSymbol().c_str(), "");
         return true;
     }
-    TVariable* variable = static_cast<TVariable*>(symbol);
+
+    TVariable* variable = symbol->getAsVariable();
+    if (! variable) {
+        error(0, "array variable name expected", node->getSymbol().c_str(), "");
+        return true;
+    }
 
     type->setArrayInformationType(variable->getArrayInformationType());
     variable->updateArrayInformationType(type);
@@ -933,12 +941,12 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size,
     // its an error
     if (node->getSymbol() == "gl_TexCoord") {
         TSymbol* texCoord = symbolTable.find("gl_MaxTextureCoords", &builtIn);
-        if (texCoord == 0) {
+        if (! texCoord || ! texCoord->getAsVariable()) {
             infoSink.info.message(EPrefixInternalError, "gl_MaxTextureCoords not defined", line);
             return true;
         }
 
-        int texCoordValue = static_cast<TVariable*>(texCoord)->getConstPointer()[0].getIConst();
+        int texCoordValue = texCoord->getAsVariable()->getConstUnionPointer()[0].getIConst();
         if (texCoordValue <= size) {
             error(line, "", "[", "gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords", "");
             return true;
@@ -1042,20 +1050,21 @@ bool TParseContext::paramErrorCheck(int line, TStorageQualifier qualifier, TType
 //
 const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
 {
-    const TSymbol* symbol = symbolTable.find(call->getMangledName(), builtIn);
+    TSymbol* symbol = symbolTable.find(call->getMangledName(), builtIn);
 
     if (symbol == 0) {        
         error(line, "no matching overloaded function found", call->getName().c_str(), "");
+
         return 0;
     }
-
-    if (! symbol->isFunction()) {
+    
+    const TFunction* function = symbol->getAsFunction();
+    if (! function) {
         error(line, "function name expected", call->getName().c_str(), "");
+
         return 0;
     }
     
-    const TFunction* function = static_cast<const TFunction*>(symbol);
-    
     return function;
 }
 
@@ -1117,7 +1126,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
             return true;
         }
         if (initializer->getAsConstantUnion()) { 
-            constUnion* unionArray = variable->getConstPointer();
+            constUnion* unionArray = variable->getConstUnionPointer();
 
             if (type.getObjectSize() == 1 && type.getBasicType() != EbtStruct) {
 	            *unionArray = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0];
@@ -1125,11 +1134,14 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
                 variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
             }
         } else if (initializer->getAsSymbolNode()) {
-            const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol());
-            const TVariable* tVar = static_cast<const TVariable*>(symbol);
-
-            constUnion* constArray = tVar->getConstPointer();
-            variable->shareConstPointer(constArray);
+            TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol());
+            if (TVariable* tVar = symbol->getAsVariable()) {
+                constUnion* constArray = tVar->getConstUnionPointer();
+                variable->shareConstPointer(constArray);
+            } else {
+                error(line, "expected variable", initializer->getAsSymbolNode()->getSymbol().c_str(), "");
+                return true;
+            }
         } else {
             error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str());
             variable->getType().getQualifier().storage = EvqTemporary;
diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp
index 280881faf874569fcfcfe3a6b5dd1174aba08295..6e731c6d7e87e83d4c6c9820bf246f61ea4b8395 100644
--- a/glslang/MachineIndependent/SymbolTable.cpp
+++ b/glslang/MachineIndependent/SymbolTable.cpp
@@ -35,7 +35,7 @@
 //
 
 //
-// Symbol table for parsing.  Most functionaliy and main ideas 
+// Symbol table for parsing.  Most functionaliy and main ideas
 // are documented in the header file.
 //
 
@@ -76,7 +76,7 @@ void TType::buildMangledName(TString& mangledName)
             mangledName += '-';
             (*structure)[i].type->buildMangledName(mangledName);
         }
-    default: 
+    default:
         break;
     }
 
@@ -98,7 +98,7 @@ void TType::buildMangledName(TString& mangledName)
 }
 
 int TType::getStructSize() const
-{ 
+{
     if (!getStruct()) {
         assert(false && "Not a struct");
         return 0;
@@ -107,7 +107,7 @@ int TType::getStructSize() const
     if (structureSize == 0)
         for (TTypeList::iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
             structureSize += ((*tl).type)->getObjectSize();
-        
+
     return structureSize;
 }
 
@@ -115,7 +115,7 @@ int TType::getStructSize() const
 // Dump functions.
 //
 
-void TVariable::dump(TInfoSink& infoSink) const 
+void TVariable::dump(TInfoSink& infoSink) const
 {
     infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " " << type.getBasicString();
     if (type.isArray()) {
@@ -129,7 +129,7 @@ void TFunction::dump(TInfoSink &infoSink) const
     infoSink.debug << getName().c_str() << ": " <<  returnType.getBasicString() << " " << getMangledName().c_str() << "\n";
 }
 
-void TSymbolTableLevel::dump(TInfoSink &infoSink) const 
+void TSymbolTableLevel::dump(TInfoSink &infoSink) const
 {
     tLevel::const_iterator it;
     for (it = level.begin(); it != level.end(); ++it)
@@ -170,18 +170,17 @@ TSymbolTableLevel::~TSymbolTableLevel()
 // performance operation, and only intended for symbol tables that
 // live across a large number of compiles.
 //
-void TSymbolTableLevel::relateToOperator(const char* name, TOperator op) 
+void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
 {
     tLevel::iterator it;
     for (it = level.begin(); it != level.end(); ++it) {
-        if ((*it).second->isFunction()) {
-            TFunction* function = static_cast<TFunction*>((*it).second);
+        TFunction* function = (*it).second->getAsFunction();
+        if (function) {
             if (function->getName() == name)
                 function->relateToOperator(op);
         }
     }
-}    
-
+}
 
 TSymbol::TSymbol(const TSymbol& copyOf)
 {
@@ -194,11 +193,11 @@ TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol
 	type.copyType(copyOf.type, remapper);
 	userType = copyOf.userType;
 	// for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL
-	assert(copyOf.arrayInformationType == 0); 
+	assert(copyOf.arrayInformationType == 0);
 	arrayInformationType = 0;
 
 	if (copyOf.unionArray) {		
-		assert(!copyOf.type.getStruct()); 
+		assert(!copyOf.type.getStruct());
 		assert(copyOf.type.getObjectSize() == 1);
 		unionArray = new constUnion[1];
         unionArray[0] = copyOf.unionArray[0];
@@ -206,7 +205,7 @@ TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol
 		unionArray = 0;
 }
 
-TVariable* TVariable::clone(TStructureMap& remapper) 
+TVariable* TVariable::clone(TStructureMap& remapper)
 {
 	TVariable *variable = new TVariable(*this, remapper);
 
@@ -227,7 +226,7 @@ TFunction::TFunction(const TFunction& copyOf, const TStructureMap& remapper) : T
 	defined = copyOf.defined;
 }
 
-TFunction* TFunction::clone(TStructureMap& remapper) 
+TFunction* TFunction::clone(TStructureMap& remapper)
 {
 	TFunction *function = new TFunction(*this, remapper);
 
diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h
index efad7b41be3abb381b4aa4e05838ba994da09c17..de956a59ce694d42564d7ec1c7a131c1ed5f22a0 100644
--- a/glslang/MachineIndependent/SymbolTable.h
+++ b/glslang/MachineIndependent/SymbolTable.h
@@ -65,6 +65,8 @@
 //
 // Symbol base class.  (Can build functions or variables out of these...)
 //
+class TVariable;
+class TFunction;
 class TSymbol {
 public:
     POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
@@ -72,8 +74,8 @@ public:
     virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
     const TString& getName() const { return *name; }
     virtual const TString& getMangledName() const { return getName(); }
-    virtual bool isFunction() const { return false; }
-    virtual bool isVariable() const { return false; }
+    virtual TFunction* getAsFunction() { return 0; }
+    virtual TVariable* getAsVariable() { return 0; }
     void setUniqueId(int id) { uniqueId = id; }
     int getUniqueId() const { return uniqueId; }
     virtual void dump(TInfoSink &infoSink) const = 0;	
@@ -99,7 +101,7 @@ class TVariable : public TSymbol {
 public:
     TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0), arrayInformationType(0) { }
     virtual ~TVariable() { }
-    virtual bool isVariable() const { return true; }
+    virtual TVariable* getAsVariable() { return this; }
     TType& getType() { return type; }
     const TType& getType() const { return type; }
     bool isUserType() const { return userType; }
@@ -109,14 +111,14 @@ public:
 
     virtual void dump(TInfoSink &infoSink) const;
 
-    constUnion* getConstPointer() {
+    constUnion* getConstUnionPointer() {
         if (!unionArray)
             unionArray = new constUnion[type.getObjectSize()];
 
         return unionArray;
     }
 
-    constUnion* getConstPointer() const { return unionArray; }
+    constUnion* getConstUnionPointer() const { return unionArray; }
 
     void shareConstPointer( constUnion *constArray)
     {
@@ -166,7 +168,7 @@ public:
         defined(false) { }
 	TFunction(const TFunction&, const TStructureMap& remapper);
 	virtual ~TFunction();
-    virtual bool isFunction() const { return true; }
+    virtual TFunction* getAsFunction() { return this; }
 
     void addParameter(TParameter& p)
     {
diff --git a/glslang/MachineIndependent/glslang.l b/glslang/MachineIndependent/glslang.l
index 351e29f06867402d8f51a5fb004e427dd2106616..8efe677707c026850680aacda0e43269b5d7b9f9 100644
--- a/glslang/MachineIndependent/glslang.l
+++ b/glslang/MachineIndependent/glslang.l
@@ -541,11 +541,12 @@ int PaReservedWord()
 int PaIdentOrType(TString& id, TParseContext& parseContextLocal, TSymbol*& symbol)
 {
     symbol = parseContextLocal.symbolTable.find(id);
-    if (parseContextLocal.lexAfterType == false && symbol && symbol->isVariable()) {
-        TVariable* variable = static_cast<TVariable*>(symbol);
-        if (variable->isUserType()) {
-            parseContextLocal.lexAfterType = true;
-            return TYPE_NAME;
+    if (parseContextLocal.lexAfterType == false && symbol) {
+        if (TVariable* variable = symbol->getAsVariable()) {
+            if (variable->isUserType()) {
+                parseContextLocal.lexAfterType = true;
+                return TYPE_NAME;
+            }
         }
     }
 
diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y
index 8d3a47f18ad6e5c61ae54bc4776ca3cbbf105517..ecc856b8ac499513e4e1bd5713f54e3f51f9f83d 100644
--- a/glslang/MachineIndependent/glslang.y
+++ b/glslang/MachineIndependent/glslang.y
@@ -217,26 +217,24 @@ Jutta Degener, 1995
 
 variable_identifier
     : IDENTIFIER {
-        // The symbol table search was done in the lexical phase
-        const TSymbol* symbol = $1.symbol;
-        const TVariable* variable;
-        if (symbol == 0) {
-            TVariable* fakeVariable = new TVariable($1.string, TType(EbtVoid));
-            variable = fakeVariable;
-        } else {
-            // This identifier can only be a variable type symbol
-            if (! symbol->isVariable()) {
-                parseContext.error($1.line, "variable expected", $1.string->c_str(), "");
-                parseContext.recover();
-            }
-            variable = static_cast<const TVariable*>(symbol);
+        // The symbol table search was done in the lexical phase, but
+        // if this is a new symbol, it won't find it, which is okay at this
+        // point in the grammar.
+        TSymbol* symbol = $1.symbol;
+        const TVariable* variable = symbol ? symbol->getAsVariable() : 0;
+        if (symbol && ! variable) {
+            parseContext.error($1.line, "variable name expected", $1.string->c_str(), "");
+            parseContext.recover();
         }
 
+        if (! variable)
+            variable = new TVariable($1.string, TType(EbtVoid));
+
         // don't delete $1.string, it's used by error recovery, and the pool
         // pop will reclaim the memory
 
         if (variable->getType().getQualifier().storage == EvqConst ) {
-            constUnion* constArray = variable->getConstPointer();
+            constUnion* constArray = variable->getConstUnionPointer();
             TType t(variable->getType());
             $$ = parseContext.intermediate.addConstantUnion(constArray, t, $1.line);
         } else
@@ -1201,7 +1199,8 @@ function_prototype
         //
         // Redeclarations are allowed.  But, return types and parameter qualifiers must match.
         //
-        TFunction* prevDec = static_cast<TFunction*>(parseContext.symbolTable.find($1->getMangledName()));
+        TSymbol* symbol = parseContext.symbolTable.find($1->getMangledName());
+        TFunction* prevDec = symbol ? symbol->getAsFunction() : 0;
         if (prevDec) {
             if (prevDec->getReturnType() != $1->getReturnType()) {
                 parseContext.error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString(), "");
@@ -2460,10 +2459,15 @@ type_specifier_nonarray
         // This is for user defined type names.  The lexical phase looked up the
         // type.
         //
-        const TType& structure = static_cast<const TVariable*>($1.symbol)->getType();
-        $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
-        $$.type = EbtStruct;
-        $$.userDef = &structure;
+        if (TVariable* variable = ($1.symbol)->getAsVariable()) { 
+            const TType& structure = variable->getType();
+            $$.init($1.line, parseContext.symbolTable.atGlobalLevel());
+            $$.type = EbtStruct;
+            $$.userDef = &structure;
+        } else {
+            parseContext.error($1.line, "expected type name", $1.string->c_str(), "");
+            parseContext.recover();
+        }
     }
     ;
 
@@ -2876,20 +2880,35 @@ external_declaration
 function_definition
     : function_prototype {
         TFunction& function = *($1.function);
-        TFunction* prevDec = static_cast<TFunction*>(parseContext.symbolTable.find(function.getMangledName()));
+        TSymbol* symbol = parseContext.symbolTable.find(function.getMangledName());
+        TFunction* prevDec = symbol ? symbol->getAsFunction() : 0;
+
+        if (! prevDec) {
+            parseContext.error($1.line, "can't find function name", function.getName().c_str(), "");
+            parseContext.recover();
+        }
+
         //
         // Note:  'prevDec' could be 'function' if this is the first time we've seen function
         // as it would have just been put in the symbol table.  Otherwise, we're looking up
         // an earlier occurance.
         //
-        if (prevDec->isDefined()) {
+        if (prevDec && prevDec->isDefined()) {
             //
             // Then this function already has a body.
             //
             parseContext.error($1.line, "function already has a body", function.getName().c_str(), "");
             parseContext.recover();
         }
-        prevDec->setDefined();
+        if (prevDec) {
+            prevDec->setDefined();
+            //
+            // Remember the return type for later checking for RETURN statements.
+            //
+            parseContext.currentFunctionType = &(prevDec->getReturnType());
+        } else 
+             parseContext.currentFunctionType = new TType(EbtVoid);
+        parseContext.functionReturnsValue = false;
 
         //
         // Raise error message if main function takes any parameters or return anything other than void
@@ -2910,12 +2929,6 @@ function_definition
         //
         parseContext.symbolTable.push();
 
-        //
-        // Remember the return type for later checking for RETURN statements.
-        //
-        parseContext.currentFunctionType = &(prevDec->getReturnType());
-        parseContext.functionReturnsValue = false;
-
         //
         // Insert parameters into the symbol table.
         // If the parameter has no name, it's not an error, just don't insert it