Collect AST transform utilities to a separate file

Collect static functions that are used to create nodes in AST
transformations into a single file.

BUG=angleproject:1490
TEST=angle_unittests

Change-Id: I6f87422988fa088f2f4b48986e378a2909705cb7
diff --git a/src/compiler/translator/AddDefaultReturnStatements.cpp b/src/compiler/translator/AddDefaultReturnStatements.cpp
index 55442e8..4dfe60c 100644
--- a/src/compiler/translator/AddDefaultReturnStatements.cpp
+++ b/src/compiler/translator/AddDefaultReturnStatements.cpp
@@ -10,6 +10,7 @@
 #include "compiler/translator/AddDefaultReturnStatements.h"
 
 #include "compiler/translator/IntermNode.h"
+#include "compiler/translator/IntermNode_util.h"
 #include "compiler/translator/util.h"
 
 namespace sh
@@ -46,8 +47,7 @@
         TIntermFunctionDefinition *definition = node->getAsFunctionDefinition();
         if (definition != nullptr && NeedsReturnStatement(definition, &returnType))
         {
-            TIntermBranch *branch =
-                new TIntermBranch(EOpReturn, TIntermTyped::CreateZero(returnType));
+            TIntermBranch *branch = new TIntermBranch(EOpReturn, CreateZeroNode(returnType));
 
             TIntermBlock *bodyNode = definition->getBody();
             bodyNode->getSequence()->push_back(branch);
diff --git a/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp b/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp
index ff78de8..d6a1e02 100644
--- a/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp
+++ b/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp
@@ -10,6 +10,7 @@
 
 #include "BreakVariableAliasingInInnerLoops.h"
 
+#include "compiler/translator/IntermNode_util.h"
 #include "compiler/translator/IntermTraverse.h"
 
 // A HLSL compiler developer gave us more details on the root cause and the workaround needed:
@@ -68,7 +69,7 @@
         // to
         //    A = (B + typeof<B>(0));
 
-        TIntermBinary *bPlusZero = new TIntermBinary(EOpAdd, B, TIntermTyped::CreateZero(type));
+        TIntermBinary *bPlusZero = new TIntermBinary(EOpAdd, B, CreateZeroNode(type));
         bPlusZero->setLine(B->getLine());
 
         binary->replaceChildNode(B, bPlusZero);
diff --git a/src/compiler/translator/EmulateGLFragColorBroadcast.cpp b/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
index 4e61b37..55ab980 100644
--- a/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
+++ b/src/compiler/translator/EmulateGLFragColorBroadcast.cpp
@@ -14,6 +14,7 @@
 #include "compiler/translator/EmulateGLFragColorBroadcast.h"
 
 #include "compiler/translator/FindMain.h"
+#include "compiler/translator/IntermNode_util.h"
 #include "compiler/translator/IntermTraverse.h"
 
 namespace sh
@@ -53,7 +54,7 @@
     gl_FragDataType.setArraySize(mMaxDrawBuffers);
 
     TIntermSymbol *symbol   = new TIntermSymbol(0, "gl_FragData", gl_FragDataType);
-    TIntermTyped *indexNode = TIntermTyped::CreateIndexNode(index);
+    TIntermTyped *indexNode = CreateIndexNode(index);
 
     TIntermBinary *binary = new TIntermBinary(EOpIndexDirect, symbol, indexNode);
     return binary;
diff --git a/src/compiler/translator/InitializeVariables.cpp b/src/compiler/translator/InitializeVariables.cpp
index 988427c..22c1cab 100644
--- a/src/compiler/translator/InitializeVariables.cpp
+++ b/src/compiler/translator/InitializeVariables.cpp
@@ -9,6 +9,7 @@
 #include "angle_gl.h"
 #include "common/debug.h"
 #include "compiler/translator/FindMain.h"
+#include "compiler/translator/IntermNode_util.h"
 #include "compiler/translator/IntermTraverse.h"
 #include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/util.h"
@@ -29,7 +30,7 @@
 
 TIntermBinary *CreateZeroInitAssignment(const TIntermTyped *initializedNode)
 {
-    TIntermTyped *zero = TIntermTyped::CreateZero(initializedNode->getType());
+    TIntermTyped *zero = CreateZeroNode(initializedNode->getType());
     return new TIntermBinary(EOpAssign, initializedNode->deepCopy(), zero);
 }
 
@@ -40,8 +41,8 @@
     TStructure *structType = initializedNode->getType().getStruct();
     for (int i = 0; i < static_cast<int>(structType->fields().size()); ++i)
     {
-        TIntermBinary *element = new TIntermBinary(
-            EOpIndexDirectStruct, initializedNode->deepCopy(), TIntermTyped::CreateIndexNode(i));
+        TIntermBinary *element = new TIntermBinary(EOpIndexDirectStruct,
+                                                   initializedNode->deepCopy(), CreateIndexNode(i));
         if (element->isArray())
         {
             AddArrayZeroInitSequence(element, initSequenceOut);
@@ -69,8 +70,8 @@
     // http://crbug.com/709317
     for (unsigned int i = 0; i < initializedNode->getArraySize(); ++i)
     {
-        TIntermBinary *element = new TIntermBinary(EOpIndexDirect, initializedNode->deepCopy(),
-                                                   TIntermTyped::CreateIndexNode(i));
+        TIntermBinary *element =
+            new TIntermBinary(EOpIndexDirect, initializedNode->deepCopy(), CreateIndexNode(i));
         if (element->getType().isStructureContainingArrays())
         {
             AddStructZeroInitSequence(element, initSequenceOut);
@@ -175,8 +176,8 @@
                 }
                 else
                 {
-                    TIntermBinary *init = new TIntermBinary(
-                        EOpInitialize, symbol, TIntermTyped::CreateZero(symbol->getType()));
+                    TIntermBinary *init =
+                        new TIntermBinary(EOpInitialize, symbol, CreateZeroNode(symbol->getType()));
                     queueReplacementWithParent(node, symbol, init, OriginalNode::BECOMES_CHILD);
                 }
             }
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index aac5c25..1d842cd 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -558,105 +558,6 @@
     return true;
 }
 
-// static
-TIntermTyped *TIntermTyped::CreateIndexNode(int index)
-{
-    TConstantUnion *u = new TConstantUnion[1];
-    u[0].setIConst(index);
-
-    TType type(EbtInt, EbpUndefined, EvqConst, 1);
-    TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
-    return node;
-}
-
-// static
-TIntermTyped *TIntermTyped::CreateZero(const TType &type)
-{
-    TType constType(type);
-    constType.setQualifier(EvqConst);
-
-    if (!type.isArray() && type.getBasicType() != EbtStruct)
-    {
-        size_t size       = constType.getObjectSize();
-        TConstantUnion *u = new TConstantUnion[size];
-        for (size_t i = 0; i < size; ++i)
-        {
-            switch (type.getBasicType())
-            {
-                case EbtFloat:
-                    u[i].setFConst(0.0f);
-                    break;
-                case EbtInt:
-                    u[i].setIConst(0);
-                    break;
-                case EbtUInt:
-                    u[i].setUConst(0u);
-                    break;
-                case EbtBool:
-                    u[i].setBConst(false);
-                    break;
-                default:
-                    // CreateZero is called by ParseContext that keeps parsing even when an error
-                    // occurs, so it is possible for CreateZero to be called with non-basic types.
-                    // This happens only on error condition but CreateZero needs to return a value
-                    // with the correct type to continue the typecheck. That's why we handle
-                    // non-basic type by setting whatever value, we just need the type to be right.
-                    u[i].setIConst(42);
-                    break;
-            }
-        }
-
-        TIntermConstantUnion *node = new TIntermConstantUnion(u, constType);
-        return node;
-    }
-
-    if (type.getBasicType() == EbtVoid)
-    {
-        // Void array. This happens only on error condition, similarly to the case above. We don't
-        // have a constructor operator for void, so this needs special handling. We'll end up with a
-        // value without the array type, but that should not be a problem.
-        constType.clearArrayness();
-        return CreateZero(constType);
-    }
-
-    TIntermSequence *arguments = new TIntermSequence();
-
-    if (type.isArray())
-    {
-        TType elementType(type);
-        elementType.clearArrayness();
-
-        size_t arraySize = type.getArraySize();
-        for (size_t i = 0; i < arraySize; ++i)
-        {
-            arguments->push_back(CreateZero(elementType));
-        }
-    }
-    else
-    {
-        ASSERT(type.getBasicType() == EbtStruct);
-
-        TStructure *structure = type.getStruct();
-        for (const auto &field : structure->fields())
-        {
-            arguments->push_back(CreateZero(*field->type()));
-        }
-    }
-
-    return TIntermAggregate::CreateConstructor(constType, arguments);
-}
-
-// static
-TIntermTyped *TIntermTyped::CreateBool(bool value)
-{
-    TConstantUnion *u = new TConstantUnion[1];
-    u[0].setBConst(value);
-
-    TType type(EbtBool, EbpUndefined, EvqConst, 1);
-    TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
-    return node;
-}
-
 TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node) : TIntermTyped(node)
 {
     mUnionArrayPointer = node.mUnionArrayPointer;
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index 19bab3d..dff7e24 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -180,10 +180,6 @@
 
     bool isConstructorWithOnlyConstantUnionParameters();
 
-    static TIntermTyped *CreateIndexNode(int index);
-    static TIntermTyped *CreateZero(const TType &type);
-    static TIntermTyped *CreateBool(bool value);
-
   protected:
     TType mType;
 
diff --git a/src/compiler/translator/IntermNode_util.cpp b/src/compiler/translator/IntermNode_util.cpp
new file mode 100644
index 0000000..2b7a330
--- /dev/null
+++ b/src/compiler/translator/IntermNode_util.cpp
@@ -0,0 +1,167 @@
+//
+// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// IntermNode_util.cpp: High-level utilities for creating AST nodes and node hierarchies. Mostly
+// meant to be used in AST transforms.
+
+#include "compiler/translator/IntermNode_util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+TName GetInternalFunctionName(const char *name)
+{
+    TString nameStr(name);
+    TName nameObj(nameStr);
+    nameObj.setInternal(true);
+    return nameObj;
+}
+
+}  // anonymous namespace
+
+TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TType &returnType,
+                                                              const char *name,
+                                                              const TSymbolUniqueId &functionId)
+{
+    TIntermFunctionPrototype *functionNode = new TIntermFunctionPrototype(returnType, functionId);
+    functionNode->getFunctionSymbolInfo()->setNameObj(GetInternalFunctionName(name));
+    return functionNode;
+}
+
+TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TType &returnType,
+                                                                const char *name,
+                                                                TIntermBlock *functionBody,
+                                                                const TSymbolUniqueId &functionId)
+{
+    TIntermFunctionPrototype *prototypeNode =
+        CreateInternalFunctionPrototypeNode(returnType, name, functionId);
+    return new TIntermFunctionDefinition(prototypeNode, functionBody);
+}
+
+TIntermAggregate *CreateInternalFunctionCallNode(const TType &returnType,
+                                                 const char *name,
+                                                 const TSymbolUniqueId &functionId,
+                                                 TIntermSequence *arguments)
+{
+    TIntermAggregate *functionNode = TIntermAggregate::CreateFunctionCall(
+        returnType, functionId, GetInternalFunctionName(name), arguments);
+    return functionNode;
+}
+
+TIntermTyped *CreateZeroNode(const TType &type)
+{
+    TType constType(type);
+    constType.setQualifier(EvqConst);
+
+    if (!type.isArray() && type.getBasicType() != EbtStruct)
+    {
+        size_t size       = constType.getObjectSize();
+        TConstantUnion *u = new TConstantUnion[size];
+        for (size_t i = 0; i < size; ++i)
+        {
+            switch (type.getBasicType())
+            {
+                case EbtFloat:
+                    u[i].setFConst(0.0f);
+                    break;
+                case EbtInt:
+                    u[i].setIConst(0);
+                    break;
+                case EbtUInt:
+                    u[i].setUConst(0u);
+                    break;
+                case EbtBool:
+                    u[i].setBConst(false);
+                    break;
+                default:
+                    // CreateZeroNode is called by ParseContext that keeps parsing even when an
+                    // error occurs, so it is possible for CreateZeroNode to be called with
+                    // non-basic types. This happens only on error condition but CreateZeroNode
+                    // needs to return a value with the correct type to continue the typecheck.
+                    // That's why we handle non-basic type by setting whatever value, we just need
+                    // the type to be right.
+                    u[i].setIConst(42);
+                    break;
+            }
+        }
+
+        TIntermConstantUnion *node = new TIntermConstantUnion(u, constType);
+        return node;
+    }
+
+    if (type.getBasicType() == EbtVoid)
+    {
+        // Void array. This happens only on error condition, similarly to the case above. We don't
+        // have a constructor operator for void, so this needs special handling. We'll end up with a
+        // value without the array type, but that should not be a problem.
+        constType.clearArrayness();
+        return CreateZeroNode(constType);
+    }
+
+    TIntermSequence *arguments = new TIntermSequence();
+
+    if (type.isArray())
+    {
+        TType elementType(type);
+        elementType.clearArrayness();
+
+        size_t arraySize = type.getArraySize();
+        for (size_t i = 0; i < arraySize; ++i)
+        {
+            arguments->push_back(CreateZeroNode(elementType));
+        }
+    }
+    else
+    {
+        ASSERT(type.getBasicType() == EbtStruct);
+
+        TStructure *structure = type.getStruct();
+        for (const auto &field : structure->fields())
+        {
+            arguments->push_back(CreateZeroNode(*field->type()));
+        }
+    }
+
+    return TIntermAggregate::CreateConstructor(constType, arguments);
+}
+
+TIntermConstantUnion *CreateIndexNode(int index)
+{
+    TConstantUnion *u = new TConstantUnion[1];
+    u[0].setIConst(index);
+
+    TType type(EbtInt, EbpUndefined, EvqConst, 1);
+    TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
+    return node;
+}
+
+TIntermConstantUnion *CreateBoolNode(bool value)
+{
+    TConstantUnion *u = new TConstantUnion[1];
+    u[0].setBConst(value);
+
+    TType type(EbtBool, EbpUndefined, EvqConst, 1);
+    TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
+    return node;
+}
+
+TIntermBlock *EnsureBlock(TIntermNode *node)
+{
+    if (node == nullptr)
+        return nullptr;
+    TIntermBlock *blockNode = node->getAsBlock();
+    if (blockNode != nullptr)
+        return blockNode;
+
+    blockNode = new TIntermBlock();
+    blockNode->setLine(node->getLine());
+    blockNode->appendStatement(node);
+    return blockNode;
+}
+
+}  // namespace sh
diff --git a/src/compiler/translator/IntermNode_util.h b/src/compiler/translator/IntermNode_util.h
new file mode 100644
index 0000000..b7d2b09
--- /dev/null
+++ b/src/compiler/translator/IntermNode_util.h
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// IntermNode_util.h: High-level utilities for creating AST nodes and node hierarchies. Mostly meant
+// to be used in AST transforms.
+
+#ifndef COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
+#define COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
+
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+
+TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TType &returnType,
+                                                              const char *name,
+                                                              const TSymbolUniqueId &functionId);
+TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TType &returnType,
+                                                                const char *name,
+                                                                TIntermBlock *functionBody,
+                                                                const TSymbolUniqueId &functionId);
+TIntermAggregate *CreateInternalFunctionCallNode(const TType &returnType,
+                                                 const char *name,
+                                                 const TSymbolUniqueId &functionId,
+                                                 TIntermSequence *arguments);
+
+TIntermTyped *CreateZeroNode(const TType &type);
+TIntermConstantUnion *CreateIndexNode(int index);
+TIntermConstantUnion *CreateBoolNode(bool value);
+
+// If the input node is nullptr, return nullptr.
+// If the input node is a block node, return it.
+// If the input node is not a block node, put it inside a block node and return that.
+TIntermBlock *EnsureBlock(TIntermNode *node);
+
+}  // namespace sh
+
+#endif  // COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
\ No newline at end of file
diff --git a/src/compiler/translator/IntermTraverse.cpp b/src/compiler/translator/IntermTraverse.cpp
index f918443..e200552 100644
--- a/src/compiler/translator/IntermTraverse.cpp
+++ b/src/compiler/translator/IntermTraverse.cpp
@@ -713,46 +713,6 @@
     mReplacements.push_back(NodeUpdateEntry(parent, original, replacement, originalBecomesChild));
 }
 
-TName TIntermTraverser::GetInternalFunctionName(const char *name)
-{
-    TString nameStr(name);
-    TName nameObj(nameStr);
-    nameObj.setInternal(true);
-    return nameObj;
-}
-
-TIntermFunctionPrototype *TIntermTraverser::CreateInternalFunctionPrototypeNode(
-    const TType &returnType,
-    const char *name,
-    const TSymbolUniqueId &functionId)
-{
-    TIntermFunctionPrototype *functionNode = new TIntermFunctionPrototype(returnType, functionId);
-    functionNode->getFunctionSymbolInfo()->setNameObj(GetInternalFunctionName(name));
-    return functionNode;
-}
-
-TIntermFunctionDefinition *TIntermTraverser::CreateInternalFunctionDefinitionNode(
-    const TType &returnType,
-    const char *name,
-    TIntermBlock *functionBody,
-    const TSymbolUniqueId &functionId)
-{
-    TIntermFunctionPrototype *prototypeNode =
-        CreateInternalFunctionPrototypeNode(returnType, name, functionId);
-    return new TIntermFunctionDefinition(prototypeNode, functionBody);
-}
-
-TIntermAggregate *TIntermTraverser::CreateInternalFunctionCallNode(
-    const TType &returnType,
-    const char *name,
-    const TSymbolUniqueId &functionId,
-    TIntermSequence *arguments)
-{
-    TIntermAggregate *functionNode = TIntermAggregate::CreateFunctionCall(
-        returnType, functionId, GetInternalFunctionName(name), arguments);
-    return functionNode;
-}
-
 TLValueTrackingTraverser::TLValueTrackingTraverser(bool preVisit,
                                                    bool inVisit,
                                                    bool postVisit,
diff --git a/src/compiler/translator/IntermTraverse.h b/src/compiler/translator/IntermTraverse.h
index 51c13dc..85b5aea 100644
--- a/src/compiler/translator/IntermTraverse.h
+++ b/src/compiler/translator/IntermTraverse.h
@@ -102,20 +102,6 @@
     // Start creating temporary symbols from the given temporary symbol index + 1.
     void useTemporaryId(TSymbolUniqueId *temporaryId);
 
-    static TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(
-        const TType &returnType,
-        const char *name,
-        const TSymbolUniqueId &functionId);
-    static TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(
-        const TType &returnType,
-        const char *name,
-        TIntermBlock *functionBody,
-        const TSymbolUniqueId &functionId);
-    static TIntermAggregate *CreateInternalFunctionCallNode(const TType &returnType,
-                                                            const char *name,
-                                                            const TSymbolUniqueId &functionId,
-                                                            TIntermSequence *arguments);
-
   protected:
     // Should only be called from traverse*() functions
     void incrementDepth(TIntermNode *current)
@@ -261,8 +247,6 @@
     std::vector<NodeInsertMultipleEntry> mInsertions;
 
   private:
-    static TName GetInternalFunctionName(const char *name);
-
     static bool CompareInsertion(const NodeInsertMultipleEntry &a,
                                  const NodeInsertMultipleEntry &b);
 
diff --git a/src/compiler/translator/Intermediate.cpp b/src/compiler/translator/Intermediate.cpp
deleted file mode 100644
index 5be61fd..0000000
--- a/src/compiler/translator/Intermediate.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-//
-// Build the intermediate representation.
-//
-
-#include <float.h>
-#include <limits.h>
-#include <algorithm>
-
-#include "compiler/translator/Intermediate.h"
-#include "compiler/translator/SymbolTable.h"
-
-namespace sh
-{
-
-////////////////////////////////////////////////////////////////////////////
-//
-// First set of functions are to help build the intermediate representation.
-// These functions are not member functions of the nodes.
-// They are called from parser productions.
-//
-/////////////////////////////////////////////////////////////////////////////
-
-// If the input node is nullptr, return nullptr.
-// If the input node is a block node, return it.
-// If the input node is not a block node, put it inside a block node and return that.
-TIntermBlock *TIntermediate::EnsureBlock(TIntermNode *node)
-{
-    if (node == nullptr)
-        return nullptr;
-    TIntermBlock *blockNode = node->getAsBlock();
-    if (blockNode != nullptr)
-        return blockNode;
-
-    blockNode = new TIntermBlock();
-    blockNode->setLine(node->getLine());
-    blockNode->appendStatement(node);
-    return blockNode;
-}
-
-}  // namespace sh
diff --git a/src/compiler/translator/Intermediate.h b/src/compiler/translator/Intermediate.h
deleted file mode 100644
index 98706dc..0000000
--- a/src/compiler/translator/Intermediate.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#ifndef COMPILER_TRANSLATOR_INTERMEDIATE_H_
-#define COMPILER_TRANSLATOR_INTERMEDIATE_H_
-
-#include "compiler/translator/IntermNode.h"
-
-namespace sh
-{
-
-//
-// Set of helper functions to help build the tree.
-// TODO(oetuaho@nvidia.com): Clean this up, it doesn't need to be a class.
-//
-class TIntermediate
-{
-  public:
-    static TIntermBlock *EnsureBlock(TIntermNode *node);
-
-  private:
-    TIntermediate(){};
-};
-
-}  // namespace sh
-
-#endif  // COMPILER_TRANSLATOR_INTERMEDIATE_H_
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 0d5559a..af722ce 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -12,6 +12,7 @@
 #include "common/mathutil.h"
 #include "compiler/preprocessor/SourceLocation.h"
 #include "compiler/translator/Cache.h"
+#include "compiler/translator/IntermNode_util.h"
 #include "compiler/translator/ValidateGlobalInitializer.h"
 #include "compiler/translator/ValidateSwitch.h"
 #include "compiler/translator/glslang.h"
@@ -1875,7 +1876,7 @@
                (typedCond->getBasicType() == EbtBool && !typedCond->isArray() &&
                 !typedCond->isVector()));
 
-        node = new TIntermLoop(type, init, typedCond, expr, TIntermediate::EnsureBlock(body));
+        node = new TIntermLoop(type, init, typedCond, expr, EnsureBlock(body));
         node->setLine(line);
         return node;
     }
@@ -1898,8 +1899,7 @@
 
     TIntermBinary *conditionInit = new TIntermBinary(EOpAssign, declarator->getLeft()->deepCopy(),
                                                      declarator->getRight()->deepCopy());
-    TIntermLoop *loop =
-        new TIntermLoop(type, init, conditionInit, expr, TIntermediate::EnsureBlock(body));
+    TIntermLoop *loop = new TIntermLoop(type, init, conditionInit, expr, EnsureBlock(body));
     block->appendStatement(loop);
     loop->setLine(line);
     block->setLine(line);
@@ -1917,16 +1917,15 @@
     {
         if (cond->getAsConstantUnion()->getBConst(0) == true)
         {
-            return TIntermediate::EnsureBlock(code.node1);
+            return EnsureBlock(code.node1);
         }
         else
         {
-            return TIntermediate::EnsureBlock(code.node2);
+            return EnsureBlock(code.node2);
         }
     }
 
-    TIntermIfElse *node = new TIntermIfElse(cond, TIntermediate::EnsureBlock(code.node1),
-                                            TIntermediate::EnsureBlock(code.node2));
+    TIntermIfElse *node = new TIntermIfElse(cond, EnsureBlock(code.node1), EnsureBlock(code.node2));
     node->setLine(loc);
 
     return node;
@@ -3084,14 +3083,14 @@
         {
             error(line, "implicitly sized array constructor must have at least one argument", "[]");
             type.setArraySize(1u);
-            return TIntermTyped::CreateZero(type);
+            return CreateZeroNode(type);
         }
         type.setArraySize(static_cast<unsigned int>(arguments->size()));
     }
 
     if (!checkConstructorArguments(line, arguments, type))
     {
-        return TIntermTyped::CreateZero(type);
+        return CreateZeroNode(type);
     }
 
     TIntermAggregate *constructorNode = TIntermAggregate::CreateConstructor(type, arguments);
@@ -3350,7 +3349,7 @@
             error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
         }
 
-        return TIntermTyped::CreateZero(TType(EbtFloat, EbpHigh, EvqConst));
+        return CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
     }
 
     TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
@@ -3537,7 +3536,7 @@
             }
             if (fieldFound)
             {
-                TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
+                TIntermTyped *index = CreateIndexNode(i);
                 index->setLine(fieldLocation);
                 TIntermBinary *node =
                     new TIntermBinary(EOpIndexDirectStruct, baseExpression, index);
@@ -3573,7 +3572,7 @@
             }
             if (fieldFound)
             {
-                TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
+                TIntermTyped *index = CreateIndexNode(i);
                 index->setLine(fieldLocation);
                 TIntermBinary *node =
                     new TIntermBinary(EOpIndexDirectInterfaceBlock, baseExpression, index);
@@ -4577,7 +4576,7 @@
     {
         binaryOpError(loc, GetOperatorString(op), left->getCompleteString(),
                       right->getCompleteString());
-        node = TIntermTyped::CreateZero(TType(EbtBool, EbpUndefined, EvqConst));
+        node = CreateBoolNode(false);
         node->setLine(loc);
     }
     return node;
@@ -5011,7 +5010,7 @@
     }
 
     // Error message was already written. Put on a dummy node for error recovery.
-    return TIntermTyped::CreateZero(TType(EbtFloat, EbpMedium, EvqConst));
+    return CreateZeroNode(TType(EbtFloat, EbpMedium, EvqConst));
 }
 
 TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond,
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 557e34e..120d041 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -9,7 +9,6 @@
 #include "compiler/translator/Compiler.h"
 #include "compiler/translator/Diagnostics.h"
 #include "compiler/translator/DirectiveHandler.h"
-#include "compiler/translator/Intermediate.h"
 #include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/QualifierTypes.h"
 #include "compiler/preprocessor/Preprocessor.h"
diff --git a/src/compiler/translator/RemoveDynamicIndexing.cpp b/src/compiler/translator/RemoveDynamicIndexing.cpp
index 02b1112..06d77ca 100644
--- a/src/compiler/translator/RemoveDynamicIndexing.cpp
+++ b/src/compiler/translator/RemoveDynamicIndexing.cpp
@@ -11,6 +11,7 @@
 
 #include "compiler/translator/InfoSink.h"
 #include "compiler/translator/IntermNodePatternMatcher.h"
+#include "compiler/translator/IntermNode_util.h"
 #include "compiler/translator/IntermTraverse.h"
 #include "compiler/translator/SymbolTable.h"
 
@@ -94,7 +95,7 @@
 {
     TIntermSymbol *baseSymbol = CreateBaseSymbol(indexedType, baseQualifier);
     TIntermBinary *indexNode =
-        new TIntermBinary(EOpIndexDirect, baseSymbol, TIntermTyped::CreateIndexNode(index));
+        new TIntermBinary(EOpIndexDirect, baseSymbol, CreateIndexNode(index));
     return indexNode;
 }
 
@@ -199,8 +200,8 @@
     }
 
     std::string functionName                = GetIndexFunctionName(type, write);
-    TIntermFunctionPrototype *prototypeNode = TIntermTraverser::CreateInternalFunctionPrototypeNode(
-        returnType, functionName.c_str(), functionId);
+    TIntermFunctionPrototype *prototypeNode =
+        CreateInternalFunctionPrototypeNode(returnType, functionName.c_str(), functionId);
 
     TQualifier baseQualifier     = EvqInOut;
     if (!write)
@@ -352,8 +353,8 @@
 
     TType fieldType                = GetFieldType(node->getLeft()->getType());
     std::string functionName       = GetIndexFunctionName(node->getLeft()->getType(), false);
-    TIntermAggregate *indexingCall = TIntermTraverser::CreateInternalFunctionCallNode(
-        fieldType, functionName.c_str(), functionId, arguments);
+    TIntermAggregate *indexingCall =
+        CreateInternalFunctionCallNode(fieldType, functionName.c_str(), functionId, arguments);
     indexingCall->setLine(node->getLine());
     indexingCall->getFunctionSymbolInfo()->setKnownToNotHaveSideEffects(true);
     return indexingCall;
@@ -372,8 +373,8 @@
     arguments->push_back(writtenValue);
 
     std::string functionName           = GetIndexFunctionName(node->getLeft()->getType(), true);
-    TIntermAggregate *indexedWriteCall = TIntermTraverser::CreateInternalFunctionCallNode(
-        TType(EbtVoid), functionName.c_str(), functionId, arguments);
+    TIntermAggregate *indexedWriteCall =
+        CreateInternalFunctionCallNode(TType(EbtVoid), functionName.c_str(), functionId, arguments);
     indexedWriteCall->setLine(node->getLine());
     return indexedWriteCall;
 }
diff --git a/src/compiler/translator/RewriteElseBlocks.cpp b/src/compiler/translator/RewriteElseBlocks.cpp
index e3d58d8..2d21814 100644
--- a/src/compiler/translator/RewriteElseBlocks.cpp
+++ b/src/compiler/translator/RewriteElseBlocks.cpp
@@ -9,7 +9,7 @@
 
 #include "compiler/translator/RewriteElseBlocks.h"
 
-#include "compiler/translator/Intermediate.h"
+#include "compiler/translator/IntermNode_util.h"
 #include "compiler/translator/NodeSearch.h"
 #include "compiler/translator/SymbolTable.h"
 
@@ -84,8 +84,7 @@
         // returns (that are unreachable) we can silence this compile error.
         if (mFunctionType && mFunctionType->getBasicType() != EbtVoid)
         {
-            TIntermNode *returnNode =
-                new TIntermBranch(EOpReturn, TIntermTyped::CreateZero(*mFunctionType));
+            TIntermNode *returnNode = new TIntermBranch(EOpReturn, CreateZeroNode(*mFunctionType));
             negatedElse = new TIntermBlock();
             negatedElse->appendStatement(returnNode);
         }
@@ -94,7 +93,7 @@
         TIntermUnary *negatedCondition     = new TIntermUnary(EOpLogicalNot, conditionSymbolElse);
         TIntermIfElse *falseIfElse =
             new TIntermIfElse(negatedCondition, ifElse->getFalseBlock(), negatedElse);
-        falseBlock = TIntermediate::EnsureBlock(falseIfElse);
+        falseBlock = EnsureBlock(falseIfElse);
     }
 
     TIntermSymbol *conditionSymbolSel = createTempSymbol(boolType);
diff --git a/src/compiler/translator/RewriteTexelFetchOffset.cpp b/src/compiler/translator/RewriteTexelFetchOffset.cpp
index a71043b..3a499cc 100644
--- a/src/compiler/translator/RewriteTexelFetchOffset.cpp
+++ b/src/compiler/translator/RewriteTexelFetchOffset.cpp
@@ -9,6 +9,7 @@
 #include "compiler/translator/RewriteTexelFetchOffset.h"
 
 #include "common/angleutils.h"
+#include "compiler/translator/IntermNode_util.h"
 #include "compiler/translator/IntermTraverse.h"
 #include "compiler/translator/SymbolTable.h"
 
@@ -107,7 +108,7 @@
         TIntermSequence *constructOffsetIvecArguments = new TIntermSequence();
         constructOffsetIvecArguments->push_back(sequence->at(3)->getAsTyped());
 
-        TIntermTyped *zeroNode = TIntermTyped::CreateZero(TType(EbtInt));
+        TIntermTyped *zeroNode = CreateZeroNode(TType(EbtInt));
         constructOffsetIvecArguments->push_back(zeroNode);
 
         offsetNode = TIntermAggregate::CreateConstructor(texCoordNode->getType(),
diff --git a/src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp b/src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp
index 5534e9a..696a495 100644
--- a/src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp
+++ b/src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp
@@ -6,6 +6,7 @@
 
 #include "compiler/translator/RewriteUnaryMinusOperatorFloat.h"
 
+#include "compiler/translator/IntermNode_util.h"
 #include "compiler/translator/IntermTraverse.h"
 
 namespace sh
@@ -72,7 +73,7 @@
     }
 
     // 0.0 - float
-    TIntermTyped *zero = TIntermTyped::CreateZero(fValue->getType());
+    TIntermTyped *zero = CreateZeroNode(fValue->getType());
     zero->setLine(fValue->getLine());
     TIntermBinary *sub = new TIntermBinary(EOpSub, zero, fValue);
     sub->setLine(fValue->getLine());
diff --git a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
index db8f549..76269e3 100644
--- a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
+++ b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
@@ -15,6 +15,7 @@
 
 #include "angle_gl.h"
 #include "common/angleutils.h"
+#include "compiler/translator/IntermNode_util.h"
 #include "compiler/translator/IntermTraverse.h"
 
 namespace sh
@@ -47,15 +48,14 @@
 
 TIntermBinary *ConstructVectorIndexBinaryNode(TIntermSymbol *symbolNode, int index)
 {
-    return new TIntermBinary(EOpIndexDirect, symbolNode, TIntermTyped::CreateIndexNode(index));
+    return new TIntermBinary(EOpIndexDirect, symbolNode, CreateIndexNode(index));
 }
 
 TIntermBinary *ConstructMatrixIndexBinaryNode(TIntermSymbol *symbolNode, int colIndex, int rowIndex)
 {
     TIntermBinary *colVectorNode = ConstructVectorIndexBinaryNode(symbolNode, colIndex);
 
-    return new TIntermBinary(EOpIndexDirect, colVectorNode,
-                             TIntermTyped::CreateIndexNode(rowIndex));
+    return new TIntermBinary(EOpIndexDirect, colVectorNode, CreateIndexNode(rowIndex));
 }
 
 class ScalarizeArgsTraverser : public TIntermTraverser
diff --git a/src/compiler/translator/SimplifyLoopConditions.cpp b/src/compiler/translator/SimplifyLoopConditions.cpp
index 58112b2..c1572cb 100644
--- a/src/compiler/translator/SimplifyLoopConditions.cpp
+++ b/src/compiler/translator/SimplifyLoopConditions.cpp
@@ -11,6 +11,7 @@
 #include "compiler/translator/SimplifyLoopConditions.h"
 
 #include "compiler/translator/IntermNodePatternMatcher.h"
+#include "compiler/translator/IntermNode_util.h"
 #include "compiler/translator/IntermTraverse.h"
 
 namespace sh
@@ -19,15 +20,6 @@
 namespace
 {
 
-TIntermConstantUnion *CreateBoolConstantNode(bool value)
-{
-    TConstantUnion *u = new TConstantUnion;
-    u->setBConst(value);
-    TIntermConstantUnion *node =
-        new TIntermConstantUnion(u, TType(EbtBool, EbpUndefined, EvqConst, 1));
-    return node;
-}
-
 class SimplifyLoopConditionsTraverser : public TLValueTrackingTraverser
 {
   public:
@@ -188,7 +180,7 @@
             //     s0 = expr;
             //   } while (s0);
             TIntermSequence tempInitSeq;
-            tempInitSeq.push_back(createTempInitDeclaration(CreateBoolConstantNode(true)));
+            tempInitSeq.push_back(createTempInitDeclaration(CreateBoolNode(true)));
             insertStatementsInParentBlock(tempInitSeq);
 
             TIntermBlock *newBody = new TIntermBlock();
@@ -237,7 +229,7 @@
             }
             else
             {
-                conditionInitializer = TIntermTyped::CreateBool(true);
+                conditionInitializer = CreateBoolNode(true);
             }
             loopScopeSequence->push_back(createTempInitDeclaration(conditionInitializer));
 
diff --git a/src/compiler/translator/UseInterfaceBlockFields.cpp b/src/compiler/translator/UseInterfaceBlockFields.cpp
index 0819cab..aa98611 100644
--- a/src/compiler/translator/UseInterfaceBlockFields.cpp
+++ b/src/compiler/translator/UseInterfaceBlockFields.cpp
@@ -12,6 +12,7 @@
 
 #include "compiler/translator/FindMain.h"
 #include "compiler/translator/IntermNode.h"
+#include "compiler/translator/IntermNode_util.h"
 #include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/util.h"
 
@@ -55,8 +56,7 @@
     {
         for (unsigned int i = 0; i < var.arraySize; ++i)
         {
-            TIntermBinary *element =
-                new TIntermBinary(EOpIndexDirect, symbol, TIntermTyped::CreateIndexNode(i));
+            TIntermBinary *element = new TIntermBinary(EOpIndexDirect, symbol, CreateIndexNode(i));
             sequence->insert(sequence->begin(), element);
         }
     }
@@ -87,13 +87,12 @@
             TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, ubInfo->getType());
             for (unsigned int i = 0; i < block.arraySize; ++i)
             {
-                TIntermBinary *instanceSymbol = new TIntermBinary(EOpIndexDirect, arraySymbol,
-                                                                  TIntermTyped::CreateIndexNode(i));
+                TIntermBinary *instanceSymbol =
+                    new TIntermBinary(EOpIndexDirect, arraySymbol, CreateIndexNode(i));
                 for (unsigned int j = 0; j < block.fields.size(); ++j)
                 {
-                    TIntermBinary *element =
-                        new TIntermBinary(EOpIndexDirectInterfaceBlock, instanceSymbol,
-                                          TIntermTyped::CreateIndexNode(j));
+                    TIntermBinary *element = new TIntermBinary(EOpIndexDirectInterfaceBlock,
+                                                               instanceSymbol, CreateIndexNode(j));
                     sequence->insert(sequence->begin(), element);
                 }
             }
@@ -106,8 +105,8 @@
             TIntermSymbol *blockSymbol = new TIntermSymbol(0, name, ubInfo->getType());
             for (unsigned int i = 0; i < block.fields.size(); ++i)
             {
-                TIntermBinary *element = new TIntermBinary(
-                    EOpIndexDirectInterfaceBlock, blockSymbol, TIntermTyped::CreateIndexNode(i));
+                TIntermBinary *element = new TIntermBinary(EOpIndexDirectInterfaceBlock,
+                                                           blockSymbol, CreateIndexNode(i));
 
                 sequence->insert(sequence->begin(), element);
             }