Edit

kc3-lang/angle/src/tests/compiler_tests/IntermNode_test.cpp

Branch :

  • Show log

    Commit

  • Author : Trevor David Black
    Date : 2020-09-07 22:09:22
    Hash : e815afbf
    Message : First pass at increasing inclusivity Link to the inclusivity rules https://source.android.com/setup/contribute/respectful-code Bug: b/162834212 Bug: chromium:1097198 Change-Id: Ied5a9e3879d72bff3f77ea6fcda9b82f30c32c2f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2396737 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Trevor Black <vantablack@google.com>

  • src/tests/compiler_tests/IntermNode_test.cpp
  • //
    // Copyright 2015 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_test.cpp:
    //   Unit tests for the AST node classes.
    //
    
    #include "compiler/translator/IntermNode.h"
    #include "angle_gl.h"
    #include "compiler/translator/InfoSink.h"
    #include "compiler/translator/PoolAlloc.h"
    #include "compiler/translator/StaticType.h"
    #include "compiler/translator/SymbolTable.h"
    #include "gtest/gtest.h"
    
    using namespace sh;
    
    class IntermNodeTest : public testing::Test
    {
      public:
        IntermNodeTest() : mUniqueIndex(0) {}
    
      protected:
        void SetUp() override
        {
            allocator.push();
            SetGlobalPoolAllocator(&allocator);
        }
    
        void TearDown() override
        {
            SetGlobalPoolAllocator(nullptr);
            allocator.pop();
        }
    
        TIntermSymbol *createTestSymbol(const TType &type)
        {
            std::stringstream symbolNameOut;
            symbolNameOut << "test" << mUniqueIndex;
            ImmutableString symbolName(symbolNameOut.str());
            ++mUniqueIndex;
    
            // We're using a mock symbol table here, don't need to assign proper symbol ids to these
            // nodes.
            TSymbolTable symbolTable;
            TType *variableType = new TType(type);
            variableType->setQualifier(EvqTemporary);
            TVariable *variable =
                new TVariable(&symbolTable, symbolName, variableType, SymbolType::AngleInternal);
            TIntermSymbol *node = new TIntermSymbol(variable);
            node->setLine(createUniqueSourceLoc());
            return node;
        }
    
        TIntermSymbol *createTestSymbol()
        {
            TType type(EbtFloat, EbpHigh);
            return createTestSymbol(type);
        }
    
        TFunction *createTestFunction(const TType &returnType, const TIntermSequence &args)
        {
            // We're using a mock symbol table similarly as for creating symbol nodes.
            const ImmutableString name("testFunc");
            TSymbolTable symbolTable;
            TFunction *func = new TFunction(&symbolTable, name, SymbolType::UserDefined,
                                            new TType(returnType), false);
            for (TIntermNode *arg : args)
            {
                const TType *type = new TType(arg->getAsTyped()->getType());
                func->addParameter(new TVariable(&symbolTable, ImmutableString("param"), type,
                                                 SymbolType::UserDefined));
            }
            return func;
        }
    
        void checkTypeEqualWithQualifiers(const TType &original, const TType &copy)
        {
            ASSERT_EQ(original, copy);
            ASSERT_EQ(original.getPrecision(), copy.getPrecision());
            ASSERT_EQ(original.getQualifier(), copy.getQualifier());
        }
    
        void checkSymbolCopy(TIntermNode *aOriginal, TIntermNode *aCopy)
        {
            ASSERT_NE(aOriginal, aCopy);
            TIntermSymbol *copy     = aCopy->getAsSymbolNode();
            TIntermSymbol *original = aOriginal->getAsSymbolNode();
            ASSERT_NE(nullptr, copy);
            ASSERT_NE(nullptr, original);
            ASSERT_NE(original, copy);
            ASSERT_EQ(&original->variable(), &copy->variable());
            ASSERT_EQ(original->uniqueId(), copy->uniqueId());
            ASSERT_EQ(original->getName(), copy->getName());
            checkTypeEqualWithQualifiers(original->getType(), copy->getType());
            ASSERT_EQ(original->getLine().first_file, copy->getLine().first_file);
            ASSERT_EQ(original->getLine().first_line, copy->getLine().first_line);
            ASSERT_EQ(original->getLine().last_file, copy->getLine().last_file);
            ASSERT_EQ(original->getLine().last_line, copy->getLine().last_line);
        }
    
        TSourceLoc createUniqueSourceLoc()
        {
            TSourceLoc loc;
            loc.first_file = mUniqueIndex;
            loc.first_line = mUniqueIndex + 1;
            loc.last_file  = mUniqueIndex + 2;
            loc.last_line  = mUniqueIndex + 3;
            ++mUniqueIndex;
            return loc;
        }
    
        static TSourceLoc getTestSourceLoc()
        {
            TSourceLoc loc;
            loc.first_file = 1;
            loc.first_line = 2;
            loc.last_file  = 3;
            loc.last_line  = 4;
            return loc;
        }
    
        static void checkTestSourceLoc(const TSourceLoc &loc)
        {
            ASSERT_EQ(1, loc.first_file);
            ASSERT_EQ(2, loc.first_line);
            ASSERT_EQ(3, loc.last_file);
            ASSERT_EQ(4, loc.last_line);
        }
    
      private:
        angle::PoolAllocator allocator;
        int mUniqueIndex;
    };
    
    // Check that the deep copy of a symbol node is an actual copy with the same attributes as the
    // original.
    TEST_F(IntermNodeTest, DeepCopySymbolNode)
    {
        const TType *type = StaticType::Get<EbtInt, EbpHigh, EvqTemporary, 1, 1>();
    
        // We're using a mock symbol table here, don't need to assign proper symbol ids to these nodes.
        TSymbolTable symbolTable;
    
        TVariable *variable =
            new TVariable(&symbolTable, ImmutableString("name"), type, SymbolType::AngleInternal);
        TIntermSymbol *original = new TIntermSymbol(variable);
        original->setLine(getTestSourceLoc());
        TIntermTyped *copy = original->deepCopy();
        checkSymbolCopy(original, copy);
        checkTestSourceLoc(copy->getLine());
    }
    
    // Check that the deep copy of a constant union node is an actual copy with the same attributes as
    // the original.
    TEST_F(IntermNodeTest, DeepCopyConstantUnionNode)
    {
        TType type(EbtInt, EbpHigh);
        TConstantUnion *constValue = new TConstantUnion[1];
        constValue[0].setIConst(101);
        TIntermConstantUnion *original = new TIntermConstantUnion(constValue, type);
        original->setLine(getTestSourceLoc());
        TIntermTyped *copyTyped    = original->deepCopy();
        TIntermConstantUnion *copy = copyTyped->getAsConstantUnion();
        ASSERT_NE(nullptr, copy);
        ASSERT_NE(original, copy);
        checkTestSourceLoc(copy->getLine());
        checkTypeEqualWithQualifiers(original->getType(), copy->getType());
        ASSERT_EQ(101, copy->getIConst(0));
    }
    
    // Check that the deep copy of a binary node is an actual copy with the same attributes as the
    // original. Child nodes also need to be copies with the same attributes as the original children.
    TEST_F(IntermNodeTest, DeepCopyBinaryNode)
    {
        TType type(EbtFloat, EbpHigh);
    
        TIntermBinary *original = new TIntermBinary(EOpAdd, createTestSymbol(), createTestSymbol());
        original->setLine(getTestSourceLoc());
        TIntermTyped *copyTyped = original->deepCopy();
        TIntermBinary *copy     = copyTyped->getAsBinaryNode();
        ASSERT_NE(nullptr, copy);
        ASSERT_NE(original, copy);
        checkTestSourceLoc(copy->getLine());
        checkTypeEqualWithQualifiers(original->getType(), copy->getType());
    
        checkSymbolCopy(original->getLeft(), copy->getLeft());
        checkSymbolCopy(original->getRight(), copy->getRight());
    }
    
    // Check that the deep copy of a unary node is an actual copy with the same attributes as the
    // original. The child node also needs to be a copy with the same attributes as the original child.
    TEST_F(IntermNodeTest, DeepCopyUnaryNode)
    {
        TType type(EbtFloat, EbpHigh);
    
        TIntermUnary *original = new TIntermUnary(EOpPreIncrement, createTestSymbol(), nullptr);
        original->setLine(getTestSourceLoc());
        TIntermTyped *copyTyped = original->deepCopy();
        TIntermUnary *copy      = copyTyped->getAsUnaryNode();
        ASSERT_NE(nullptr, copy);
        ASSERT_NE(original, copy);
        checkTestSourceLoc(copy->getLine());
        checkTypeEqualWithQualifiers(original->getType(), copy->getType());
    
        checkSymbolCopy(original->getOperand(), copy->getOperand());
    }
    
    // Check that the deep copy of an aggregate node is an actual copy with the same attributes as the
    // original. Child nodes also need to be copies with the same attributes as the original children.
    TEST_F(IntermNodeTest, DeepCopyAggregateNode)
    {
        TIntermSequence *originalSeq = new TIntermSequence();
        originalSeq->push_back(createTestSymbol());
        originalSeq->push_back(createTestSymbol());
        originalSeq->push_back(createTestSymbol());
    
        TFunction *testFunc =
            createTestFunction(originalSeq->back()->getAsTyped()->getType(), *originalSeq);
    
        TIntermAggregate *original = TIntermAggregate::CreateFunctionCall(*testFunc, originalSeq);
        original->setLine(getTestSourceLoc());
    
        TIntermTyped *copyTyped = original->deepCopy();
        TIntermAggregate *copy  = copyTyped->getAsAggregate();
        ASSERT_NE(nullptr, copy);
        ASSERT_NE(original, copy);
        checkTestSourceLoc(copy->getLine());
        checkTypeEqualWithQualifiers(original->getType(), copy->getType());
    
        ASSERT_EQ(original->getSequence()->size(), copy->getSequence()->size());
        TIntermSequence::size_type i = 0;
        for (auto *copyChild : *copy->getSequence())
        {
            TIntermNode *originalChild = original->getSequence()->at(i);
            checkSymbolCopy(originalChild, copyChild);
            ++i;
        }
    }
    
    // Check that the deep copy of a ternary node is an actual copy with the same attributes as the
    // original. Child nodes also need to be copies with the same attributes as the original children.
    TEST_F(IntermNodeTest, DeepCopyTernaryNode)
    {
        TType type(EbtFloat, EbpHigh);
    
        TIntermTernary *original = new TIntermTernary(createTestSymbol(TType(EbtBool, EbpUndefined)),
                                                      createTestSymbol(), createTestSymbol());
        original->setLine(getTestSourceLoc());
        TIntermTyped *copyTyped = original->deepCopy();
        TIntermTernary *copy    = copyTyped->getAsTernaryNode();
        ASSERT_NE(nullptr, copy);
        ASSERT_NE(original, copy);
        checkTestSourceLoc(copy->getLine());
        checkTypeEqualWithQualifiers(original->getType(), copy->getType());
    
        checkSymbolCopy(original->getCondition(), copy->getCondition());
        checkSymbolCopy(original->getTrueExpression(), copy->getTrueExpression());
        checkSymbolCopy(original->getFalseExpression(), copy->getFalseExpression());
    }