//
// Copyright 2002 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.
//

//
// Definition of the in-memory high-level intermediate representation
// of shaders.  This is a tree that parser creates.
//
// Nodes in the tree are defined as a hierarchy of classes derived from
// TIntermNode. Each is a node in a tree.  There is no preset branching factor;
// each node can have it's own type of list of children.
//

#ifndef COMPILER_TRANSLATOR_INTERMNODE_H_
#define COMPILER_TRANSLATOR_INTERMNODE_H_

#include "GLSLANG/ShaderLang.h"

#include <algorithm>
#include <queue>

#include "common/angleutils.h"
#include "compiler/translator/Common.h"
#include "compiler/translator/ConstantUnion.h"
#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/Operator.h"
#include "compiler/translator/SymbolUniqueId.h"
#include "compiler/translator/Types.h"
#include "compiler/translator/tree_util/Visit.h"

namespace sh
{

class TDiagnostics;

class TIntermTraverser;
class TIntermAggregate;
class TIntermBlock;
class TIntermInvariantDeclaration;
class TIntermDeclaration;
class TIntermFunctionPrototype;
class TIntermFunctionDefinition;
class TIntermSwizzle;
class TIntermBinary;
class TIntermUnary;
class TIntermConstantUnion;
class TIntermTernary;
class TIntermIfElse;
class TIntermSwitch;
class TIntermCase;
class TIntermTyped;
class TIntermSymbol;
class TIntermLoop;
class TInfoSink;
class TInfoSinkBase;
class TIntermBranch;
class TIntermPreprocessorDirective;

class TSymbolTable;
class TFunction;
class TVariable;

//
// Base class for the tree nodes
//
class TIntermNode : angle::NonCopyable
{
  public:
    POOL_ALLOCATOR_NEW_DELETE
    TIntermNode()
    {
        // TODO: Move this to TSourceLoc constructor
        // after getting rid of TPublicType.
        mLine.first_file = mLine.last_file = 0;
        mLine.first_line = mLine.last_line = 0;
    }
    virtual ~TIntermNode() {}

    const TSourceLoc &getLine() const { return mLine; }
    void setLine(const TSourceLoc &l) { mLine = l; }

    virtual void traverse(TIntermTraverser *it);
    virtual bool visit(Visit visit, TIntermTraverser *it) = 0;

    virtual TIntermTyped *getAsTyped() { return nullptr; }
    virtual TIntermConstantUnion *getAsConstantUnion() { return nullptr; }
    virtual TIntermFunctionDefinition *getAsFunctionDefinition() { return nullptr; }
    virtual TIntermAggregate *getAsAggregate() { return nullptr; }
    virtual TIntermBlock *getAsBlock() { return nullptr; }
    virtual TIntermFunctionPrototype *getAsFunctionPrototypeNode() { return nullptr; }
    virtual TIntermInvariantDeclaration *getAsInvariantDeclarationNode() { return nullptr; }
    virtual TIntermDeclaration *getAsDeclarationNode() { return nullptr; }
    virtual TIntermSwizzle *getAsSwizzleNode() { return nullptr; }
    virtual TIntermBinary *getAsBinaryNode() { return nullptr; }
    virtual TIntermUnary *getAsUnaryNode() { return nullptr; }
    virtual TIntermTernary *getAsTernaryNode() { return nullptr; }
    virtual TIntermIfElse *getAsIfElseNode() { return nullptr; }
    virtual TIntermSwitch *getAsSwitchNode() { return nullptr; }
    virtual TIntermCase *getAsCaseNode() { return nullptr; }
    virtual TIntermSymbol *getAsSymbolNode() { return nullptr; }
    virtual TIntermLoop *getAsLoopNode() { return nullptr; }
    virtual TIntermBranch *getAsBranchNode() { return nullptr; }
    virtual TIntermPreprocessorDirective *getAsPreprocessorDirective() { return nullptr; }

    virtual TIntermNode *deepCopy() const = 0;

    virtual size_t getChildCount() const                  = 0;
    virtual TIntermNode *getChildNode(size_t index) const = 0;
    // Replace a child node. Return true if |original| is a child
    // node and it is replaced; otherwise, return false.
    virtual bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) = 0;

  protected:
    TSourceLoc mLine;
};

//
// This is just to help yacc.
//
struct TIntermNodePair
{
    TIntermNode *node1;
    TIntermNode *node2;
};

//
// Intermediate class for nodes that have a type.
//
class TIntermTyped : public TIntermNode
{
  public:
    TIntermTyped() {}

    virtual TIntermTyped *deepCopy() const override = 0;

    TIntermTyped *getAsTyped() override { return this; }

    virtual TIntermTyped *fold(TDiagnostics *diagnostics) { return this; }

    // getConstantValue() returns the constant value that this node represents, if any. It
    // should only be used after nodes have been replaced with their folded versions returned
    // from fold(). hasConstantValue() returns true if getConstantValue() will return a value.
    virtual bool hasConstantValue() const;
    virtual const TConstantUnion *getConstantValue() const;

    // True if executing the expression represented by this node affects state, like values of
    // variables. False if the executing the expression only computes its return value without
    // affecting state. May return true conservatively.
    virtual bool hasSideEffects() const = 0;

    virtual const TType &getType() const = 0;

    TBasicType getBasicType() const { return getType().getBasicType(); }
    TQualifier getQualifier() const { return getType().getQualifier(); }
    TPrecision getPrecision() const { return getType().getPrecision(); }
    TMemoryQualifier getMemoryQualifier() const { return getType().getMemoryQualifier(); }
    int getCols() const { return getType().getCols(); }
    int getRows() const { return getType().getRows(); }
    int getNominalSize() const { return getType().getNominalSize(); }
    int getSecondarySize() const { return getType().getSecondarySize(); }

    bool isInterfaceBlock() const { return getType().isInterfaceBlock(); }
    bool isMatrix() const { return getType().isMatrix(); }
    bool isArray() const { return getType().isArray(); }
    bool isVector() const { return getType().isVector(); }
    bool isScalar() const { return getType().isScalar(); }
    bool isScalarInt() const { return getType().isScalarInt(); }
    const char *getBasicString() const { return getType().getBasicString(); }

    unsigned int getOutermostArraySize() const { return getType().getOutermostArraySize(); }

  protected:
    TIntermTyped(const TIntermTyped &node);
};

//
// Handle for, do-while, and while loops.
//
enum TLoopType
{
    ELoopFor,
    ELoopWhile,
    ELoopDoWhile
};

class TIntermLoop : public TIntermNode
{
  public:
    TIntermLoop(TLoopType type,
                TIntermNode *init,
                TIntermTyped *cond,
                TIntermTyped *expr,
                TIntermBlock *body);

    TIntermLoop *getAsLoopNode() override { return this; }
    void traverse(TIntermTraverser *it) final;
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    TLoopType getType() const { return mType; }
    TIntermNode *getInit() { return mInit; }
    TIntermTyped *getCondition() { return mCond; }
    TIntermTyped *getExpression() { return mExpr; }
    TIntermBlock *getBody() { return mBody; }

    void setInit(TIntermNode *init) { mInit = init; }
    void setCondition(TIntermTyped *condition) { mCond = condition; }
    void setExpression(TIntermTyped *expression) { mExpr = expression; }
    void setBody(TIntermBlock *body) { mBody = body; }

    virtual TIntermLoop *deepCopy() const override { return new TIntermLoop(*this); }

  protected:
    TLoopType mType;
    TIntermNode *mInit;   // for-loop initialization
    TIntermTyped *mCond;  // loop exit condition
    TIntermTyped *mExpr;  // for-loop expression
    TIntermBlock *mBody;  // loop body

  private:
    TIntermLoop(const TIntermLoop &);
};

//
// Handle break, continue, return, and kill.
//
class TIntermBranch : public TIntermNode
{
  public:
    TIntermBranch(TOperator op, TIntermTyped *e) : mFlowOp(op), mExpression(e) {}

    TIntermBranch *getAsBranchNode() override { return this; }
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    TOperator getFlowOp() { return mFlowOp; }
    TIntermTyped *getExpression() { return mExpression; }

    virtual TIntermBranch *deepCopy() const override { return new TIntermBranch(*this); }

  protected:
    TOperator mFlowOp;
    TIntermTyped *mExpression;  // zero except for "return exp;" statements

  private:
    TIntermBranch(const TIntermBranch &);
};

// Nodes that correspond to variable symbols in the source code. These may be regular variables or
// interface block instances. In declarations that only declare a struct type but no variables, a
// TIntermSymbol node with an empty variable is used to store the type.
class TIntermSymbol : public TIntermTyped
{
  public:
    TIntermSymbol(const TVariable *variable);

    TIntermTyped *deepCopy() const override { return new TIntermSymbol(*this); }

    bool hasConstantValue() const override;
    const TConstantUnion *getConstantValue() const override;

    bool hasSideEffects() const override { return false; }

    const TType &getType() const override;

    const TSymbolUniqueId &uniqueId() const;
    ImmutableString getName() const;
    const TVariable &variable() const { return *mVariable; }

    TIntermSymbol *getAsSymbolNode() override { return this; }
    void traverse(TIntermTraverser *it) final;
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; }

  private:
    TIntermSymbol(const TIntermSymbol &) = default;  // Note: not deleted, just private!

    const TVariable *const mVariable;  // Guaranteed to be non-null
};

// A typed expression that is not just representing a symbol table symbol.
class TIntermExpression : public TIntermTyped
{
  public:
    TIntermExpression(const TType &t);

    const TType &getType() const override { return mType; }

  protected:
    TType *getTypePointer() { return &mType; }
    void setType(const TType &t) { mType = t; }
    void setTypePreservePrecision(const TType &t);

    TIntermExpression(const TIntermExpression &node) = default;

    TType mType;
};

// Constant folded node.
// Note that nodes may be constant folded and not be constant expressions with the EvqConst
// qualifier. This happens for example when the following expression is processed:
// "true ? 1.0 : non_constant"
// Other nodes than TIntermConstantUnion may also be constant expressions.
//
class TIntermConstantUnion : public TIntermExpression
{
  public:
    TIntermConstantUnion(const TConstantUnion *unionPointer, const TType &type)
        : TIntermExpression(type), mUnionArrayPointer(unionPointer)
    {
        ASSERT(unionPointer);
    }

    TIntermTyped *deepCopy() const override { return new TIntermConstantUnion(*this); }

    bool hasConstantValue() const override;
    const TConstantUnion *getConstantValue() const override;

    bool hasSideEffects() const override { return false; }

    int getIConst(size_t index) const
    {
        return mUnionArrayPointer ? mUnionArrayPointer[index].getIConst() : 0;
    }
    unsigned int getUConst(size_t index) const
    {
        return mUnionArrayPointer ? mUnionArrayPointer[index].getUConst() : 0;
    }
    float getFConst(size_t index) const
    {
        return mUnionArrayPointer ? mUnionArrayPointer[index].getFConst() : 0.0f;
    }
    bool getBConst(size_t index) const
    {
        return mUnionArrayPointer ? mUnionArrayPointer[index].getBConst() : false;
    }
    bool isZero(size_t index) const
    {
        return mUnionArrayPointer ? mUnionArrayPointer[index].isZero() : false;
    }

    TIntermConstantUnion *getAsConstantUnion() override { return this; }
    void traverse(TIntermTraverser *it) final;
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; }

    TConstantUnion *foldUnaryNonComponentWise(TOperator op);
    TConstantUnion *foldUnaryComponentWise(TOperator op, TDiagnostics *diagnostics);

    static const TConstantUnion *FoldBinary(TOperator op,
                                            const TConstantUnion *leftArray,
                                            const TType &leftType,
                                            const TConstantUnion *rightArray,
                                            const TType &rightType,
                                            TDiagnostics *diagnostics,
                                            const TSourceLoc &line);

    static const TConstantUnion *FoldIndexing(const TType &type,
                                              const TConstantUnion *constArray,
                                              int index);
    static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate,
                                                TDiagnostics *diagnostics);
    static bool IsFloatDivision(TBasicType t1, TBasicType t2);

  protected:
    // Same data may be shared between multiple constant unions, so it can't be modified.
    const TConstantUnion *mUnionArrayPointer;

  private:
    typedef float (*FloatTypeUnaryFunc)(float);
    void foldFloatTypeUnary(const TConstantUnion &parameter,
                            FloatTypeUnaryFunc builtinFunc,
                            TConstantUnion *result) const;

    TIntermConstantUnion(const TIntermConstantUnion &node);  // Note: not deleted, just private!
};

//
// Intermediate class for node types that hold operators.
//
class TIntermOperator : public TIntermExpression
{
  public:
    TOperator getOp() const { return mOp; }

    bool isAssignment() const;
    bool isMultiplication() const;
    bool isConstructor() const;

    // Returns true for calls mapped to EOpCall*, false for built-ins that have their own specific
    // ops.
    bool isFunctionCall() const;

    bool hasSideEffects() const override { return isAssignment(); }

  protected:
    TIntermOperator(TOperator op) : TIntermExpression(TType(EbtFloat, EbpUndefined)), mOp(op) {}
    TIntermOperator(TOperator op, const TType &type) : TIntermExpression(type), mOp(op) {}

    TIntermOperator(const TIntermOperator &) = default;

    const TOperator mOp;
};

// Node for vector swizzles.
class TIntermSwizzle : public TIntermExpression
{
  public:
    // This constructor determines the type of the node based on the operand.
    TIntermSwizzle(TIntermTyped *operand, const TVector<int> &swizzleOffsets);

    TIntermTyped *deepCopy() const override { return new TIntermSwizzle(*this); }

    TIntermSwizzle *getAsSwizzleNode() override { return this; }
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    bool hasSideEffects() const override { return mOperand->hasSideEffects(); }

    TIntermTyped *getOperand() { return mOperand; }
    void writeOffsetsAsXYZW(TInfoSinkBase *out) const;

    const TVector<int> &getSwizzleOffsets() { return mSwizzleOffsets; }

    bool hasDuplicateOffsets() const;
    void setHasFoldedDuplicateOffsets(bool hasFoldedDuplicateOffsets);
    bool offsetsMatch(int offset) const;

    TIntermTyped *fold(TDiagnostics *diagnostics) override;

  protected:
    TIntermTyped *mOperand;
    TVector<int> mSwizzleOffsets;
    bool mHasFoldedDuplicateOffsets;

  private:
    void promote();

    TIntermSwizzle(const TIntermSwizzle &node);  // Note: not deleted, just private!
};

//
// Nodes for all the basic binary math operators.
//
class TIntermBinary : public TIntermOperator
{
  public:
    // This constructor determines the type of the binary node based on the operands and op.
    TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right);
    // Comma qualifier depends on the shader version, so use this to create comma nodes:
    static TIntermBinary *CreateComma(TIntermTyped *left, TIntermTyped *right, int shaderVersion);

    TIntermTyped *deepCopy() const override { return new TIntermBinary(*this); }

    bool hasConstantValue() const override;
    const TConstantUnion *getConstantValue() const override;

    static TOperator GetMulOpBasedOnOperands(const TType &left, const TType &right);
    static TOperator GetMulAssignOpBasedOnOperands(const TType &left, const TType &right);

    TIntermBinary *getAsBinaryNode() override { return this; }
    void traverse(TIntermTraverser *it) final;
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    bool hasSideEffects() const override
    {
        return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects();
    }

    TIntermTyped *getLeft() const { return mLeft; }
    TIntermTyped *getRight() const { return mRight; }
    TIntermTyped *fold(TDiagnostics *diagnostics) override;

    void setAddIndexClamp() { mAddIndexClamp = true; }
    bool getAddIndexClamp() const { return mAddIndexClamp; }

    // This method is only valid for EOpIndexDirectStruct. It returns the name of the field.
    const ImmutableString &getIndexStructFieldName() const;

  protected:
    TIntermTyped *mLeft;
    TIntermTyped *mRight;

    // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
    bool mAddIndexClamp;

  private:
    void promote();

    static TQualifier GetCommaQualifier(int shaderVersion,
                                        const TIntermTyped *left,
                                        const TIntermTyped *right);

    TIntermBinary(const TIntermBinary &node);  // Note: not deleted, just private!
};

//
// Nodes for unary math operators.
//
class TIntermUnary : public TIntermOperator
{
  public:
    TIntermUnary(TOperator op, TIntermTyped *operand, const TFunction *function);

    TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); }

    TIntermUnary *getAsUnaryNode() override { return this; }
    void traverse(TIntermTraverser *it) final;
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    bool hasSideEffects() const override { return isAssignment() || mOperand->hasSideEffects(); }

    TIntermTyped *getOperand() { return mOperand; }
    TIntermTyped *fold(TDiagnostics *diagnostics) override;

    const TFunction *getFunction() const { return mFunction; }

    void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
    bool getUseEmulatedFunction() { return mUseEmulatedFunction; }

  protected:
    TIntermTyped *mOperand;

    // If set to true, replace the built-in function call with an emulated one
    // to work around driver bugs.
    bool mUseEmulatedFunction;

    const TFunction *const mFunction;

  private:
    void promote();

    TIntermUnary(const TIntermUnary &node);  // note: not deleted, just private!
};

typedef TVector<TIntermNode *> TIntermSequence;
typedef TVector<int> TQualifierList;

// Interface for node classes that have an arbitrarily sized set of children.
class TIntermAggregateBase
{
  public:
    virtual ~TIntermAggregateBase() {}

    virtual TIntermSequence *getSequence()             = 0;
    virtual const TIntermSequence *getSequence() const = 0;

    bool replaceChildNodeWithMultiple(TIntermNode *original, const TIntermSequence &replacements);
    bool insertChildNodes(TIntermSequence::size_type position, const TIntermSequence &insertions);

  protected:
    TIntermAggregateBase() {}

    bool replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement);
};

//
// Nodes that operate on an arbitrary sized set of children.
//
class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
{
  public:
    static TIntermAggregate *CreateFunctionCall(const TFunction &func, TIntermSequence *arguments);

    static TIntermAggregate *CreateRawFunctionCall(const TFunction &func,
                                                   TIntermSequence *arguments);

    // This covers all built-in function calls - whether they are associated with an op or not.
    static TIntermAggregate *CreateBuiltInFunctionCall(const TFunction &func,
                                                       TIntermSequence *arguments);
    static TIntermAggregate *CreateConstructor(const TType &type, TIntermSequence *arguments);
    ~TIntermAggregate() override {}

    // Note: only supported for nodes that can be a part of an expression.
    TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); }

    TIntermAggregate *shallowCopy() const;

    bool hasConstantValue() const override;
    const TConstantUnion *getConstantValue() const override;

    TIntermAggregate *getAsAggregate() override { return this; }
    void traverse(TIntermTraverser *it) final;
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    bool hasSideEffects() const override;

    TIntermTyped *fold(TDiagnostics *diagnostics) override;

    TIntermSequence *getSequence() override { return &mArguments; }
    const TIntermSequence *getSequence() const override { return &mArguments; }

    void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
    bool getUseEmulatedFunction() { return mUseEmulatedFunction; }

    // Returns true if changing parameter precision may affect the return value.
    bool gotPrecisionFromChildren() const { return mGotPrecisionFromChildren; }

    const TFunction *getFunction() const { return mFunction; }

    // Get the function name to display to the user in an error message.
    const char *functionName() const;

  protected:
    TIntermSequence mArguments;

    // If set to true, replace the built-in function call with an emulated one
    // to work around driver bugs. Only for calls mapped to ops other than EOpCall*.
    bool mUseEmulatedFunction;

    bool mGotPrecisionFromChildren;

    const TFunction *const mFunction;

  private:
    TIntermAggregate(const TFunction *func,
                     const TType &type,
                     TOperator op,
                     TIntermSequence *arguments);

    TIntermAggregate(const TIntermAggregate &node);  // note: not deleted, just private!

    void setPrecisionAndQualifier();

    bool areChildrenConstQualified();

    void setPrecisionFromChildren();

    void setPrecisionForBuiltInOp();

    // Returns true if precision was set according to special rules for this built-in.
    bool setPrecisionForSpecialBuiltInOp();

    // Used for built-in functions under EOpCallBuiltInFunction. The function name in the symbol
    // info needs to be set before calling this.
    void setBuiltInFunctionPrecision();
};

// A list of statements. Either the root node which contains declarations and function definitions,
// or a block that can be marked with curly braces {}.
class TIntermBlock : public TIntermNode, public TIntermAggregateBase
{
  public:
    TIntermBlock() : TIntermNode() {}
    ~TIntermBlock() override {}

    TIntermBlock *getAsBlock() override { return this; }
    void traverse(TIntermTraverser *it) final;
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    // Only intended for initially building the block.
    void appendStatement(TIntermNode *statement);
    void insertStatement(size_t insertPosition, TIntermNode *statement);

    TIntermSequence *getSequence() override { return &mStatements; }
    const TIntermSequence *getSequence() const override { return &mStatements; }

    TIntermBlock *deepCopy() const override { return new TIntermBlock(*this); }

  protected:
    TIntermSequence mStatements;

  private:
    TIntermBlock(const TIntermBlock &);
};

// Function prototype. May be in the AST either as a function prototype declaration or as a part of
// a function definition. The type of the node is the function return type.
class TIntermFunctionPrototype : public TIntermTyped
{
  public:
    TIntermFunctionPrototype(const TFunction *function);
    ~TIntermFunctionPrototype() override {}

    TIntermFunctionPrototype *getAsFunctionPrototypeNode() override { return this; }
    void traverse(TIntermTraverser *it) final;
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    const TType &getType() const override;

    TIntermTyped *deepCopy() const override
    {
        UNREACHABLE();
        return nullptr;
    }
    bool hasSideEffects() const override
    {
        UNREACHABLE();
        return true;
    }

    const TFunction *getFunction() const { return mFunction; }

  protected:
    const TFunction *const mFunction;
};

// Node for function definitions. The prototype child node stores the function header including
// parameters, and the body child node stores the function body.
class TIntermFunctionDefinition : public TIntermNode
{
  public:
    TIntermFunctionDefinition(TIntermFunctionPrototype *prototype, TIntermBlock *body)
        : TIntermNode(), mPrototype(prototype), mBody(body)
    {
        ASSERT(prototype != nullptr);
        ASSERT(body != nullptr);
    }

    TIntermFunctionDefinition *getAsFunctionDefinition() override { return this; }
    void traverse(TIntermTraverser *it) final;
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    TIntermFunctionPrototype *getFunctionPrototype() const { return mPrototype; }
    TIntermBlock *getBody() const { return mBody; }

    const TFunction *getFunction() const { return mPrototype->getFunction(); }

    TIntermNode *deepCopy() const override
    {
        UNREACHABLE();
        return nullptr;
    }

  private:
    TIntermFunctionPrototype *mPrototype;
    TIntermBlock *mBody;
};

// Struct, interface block or variable declaration. Can contain multiple variable declarators.
class TIntermDeclaration : public TIntermNode, public TIntermAggregateBase
{
  public:
    TIntermDeclaration() : TIntermNode() {}
    ~TIntermDeclaration() override {}

    TIntermDeclaration *getAsDeclarationNode() override { return this; }
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    // Only intended for initially building the declaration.
    // The declarator node should be either TIntermSymbol or TIntermBinary with op set to
    // EOpInitialize.
    void appendDeclarator(TIntermTyped *declarator);

    TIntermSequence *getSequence() override { return &mDeclarators; }
    const TIntermSequence *getSequence() const override { return &mDeclarators; }

    TIntermNode *deepCopy() const override
    {
        UNREACHABLE();
        return nullptr;
    }

  protected:
    TIntermSequence mDeclarators;
};

// Specialized declarations for attributing invariance.
class TIntermInvariantDeclaration : public TIntermNode
{
  public:
    TIntermInvariantDeclaration(TIntermSymbol *symbol, const TSourceLoc &line);

    virtual TIntermInvariantDeclaration *getAsInvariantDeclarationNode() override { return this; }
    bool visit(Visit visit, TIntermTraverser *it) final;

    TIntermSymbol *getSymbol() { return mSymbol; }

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    TIntermInvariantDeclaration *deepCopy() const override
    {
        return new TIntermInvariantDeclaration(*this);
    }

  private:
    TIntermSymbol *mSymbol;

    TIntermInvariantDeclaration(const TIntermInvariantDeclaration &);
};

// For ternary operators like a ? b : c.
class TIntermTernary : public TIntermExpression
{
  public:
    TIntermTernary(TIntermTyped *cond, TIntermTyped *trueExpression, TIntermTyped *falseExpression);

    TIntermTernary *getAsTernaryNode() override { return this; }
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    TIntermTyped *getCondition() const { return mCondition; }
    TIntermTyped *getTrueExpression() const { return mTrueExpression; }
    TIntermTyped *getFalseExpression() const { return mFalseExpression; }

    TIntermTyped *deepCopy() const override { return new TIntermTernary(*this); }

    bool hasSideEffects() const override
    {
        return mCondition->hasSideEffects() || mTrueExpression->hasSideEffects() ||
               mFalseExpression->hasSideEffects();
    }

    TIntermTyped *fold(TDiagnostics *diagnostics) override;

  private:
    TIntermTernary(const TIntermTernary &node);  // Note: not deleted, just private!

    static TQualifier DetermineQualifier(TIntermTyped *cond,
                                         TIntermTyped *trueExpression,
                                         TIntermTyped *falseExpression);

    TIntermTyped *mCondition;
    TIntermTyped *mTrueExpression;
    TIntermTyped *mFalseExpression;
};

class TIntermIfElse : public TIntermNode
{
  public:
    TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB);

    TIntermIfElse *getAsIfElseNode() override { return this; }
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    TIntermTyped *getCondition() const { return mCondition; }
    TIntermBlock *getTrueBlock() const { return mTrueBlock; }
    TIntermBlock *getFalseBlock() const { return mFalseBlock; }

    TIntermIfElse *deepCopy() const override { return new TIntermIfElse(*this); }

  protected:
    TIntermTyped *mCondition;
    TIntermBlock *mTrueBlock;
    TIntermBlock *mFalseBlock;

  private:
    TIntermIfElse(const TIntermIfElse &);
};

//
// Switch statement.
//
class TIntermSwitch : public TIntermNode
{
  public:
    TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList);

    TIntermSwitch *getAsSwitchNode() override { return this; }
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    TIntermTyped *getInit() { return mInit; }
    TIntermBlock *getStatementList() { return mStatementList; }

    // Must be called with a non-null statementList.
    void setStatementList(TIntermBlock *statementList);

    TIntermSwitch *deepCopy() const override { return new TIntermSwitch(*this); }

  protected:
    TIntermTyped *mInit;
    TIntermBlock *mStatementList;

  private:
    TIntermSwitch(const TIntermSwitch &);
};

//
// Case label.
//
class TIntermCase : public TIntermNode
{
  public:
    TIntermCase(TIntermTyped *condition) : TIntermNode(), mCondition(condition) {}

    TIntermCase *getAsCaseNode() override { return this; }
    bool visit(Visit visit, TIntermTraverser *it) final;

    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;
    bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;

    bool hasCondition() const { return mCondition != nullptr; }
    TIntermTyped *getCondition() const { return mCondition; }

    TIntermCase *deepCopy() const override { return new TIntermCase(*this); }

  protected:
    TIntermTyped *mCondition;

  private:
    TIntermCase(const TIntermCase &);
};

//
// Preprocessor Directive.
//  #ifdef, #define, #if, #endif, etc.
//

enum class PreprocessorDirective
{
    Define,
    Ifdef,
    If,
    Endif,
};

class TIntermPreprocessorDirective final : public TIntermNode
{
  public:
    // This could also take an ImmutableString as an argument.
    TIntermPreprocessorDirective(PreprocessorDirective directive, ImmutableString command);
    ~TIntermPreprocessorDirective() final;

    void traverse(TIntermTraverser *it) final;
    bool visit(Visit visit, TIntermTraverser *it) final;
    bool replaceChildNode(TIntermNode *, TIntermNode *) final { return false; }

    TIntermPreprocessorDirective *getAsPreprocessorDirective() final { return this; }
    size_t getChildCount() const final;
    TIntermNode *getChildNode(size_t index) const final;

    PreprocessorDirective getDirective() const { return mDirective; }
    const ImmutableString &getCommand() const { return mCommand; }

    TIntermPreprocessorDirective *deepCopy() const override
    {
        return new TIntermPreprocessorDirective(*this);
    }

  private:
    PreprocessorDirective mDirective;
    ImmutableString mCommand;

    TIntermPreprocessorDirective(const TIntermPreprocessorDirective &);
};

}  // namespace sh

#endif  // COMPILER_TRANSLATOR_INTERMNODE_H_
