Path: blob/main_old/src/tests/compiler_tests/IntermNode_test.cpp
1693 views
//1// Copyright 2015 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// IntermNode_test.cpp:6// Unit tests for the AST node classes.7//89#include "compiler/translator/IntermNode.h"10#include "angle_gl.h"11#include "compiler/translator/InfoSink.h"12#include "compiler/translator/PoolAlloc.h"13#include "compiler/translator/StaticType.h"14#include "compiler/translator/SymbolTable.h"15#include "gtest/gtest.h"1617using namespace sh;1819class IntermNodeTest : public testing::Test20{21public:22IntermNodeTest() : mUniqueIndex(0) {}2324protected:25void SetUp() override26{27allocator.push();28SetGlobalPoolAllocator(&allocator);29}3031void TearDown() override32{33SetGlobalPoolAllocator(nullptr);34allocator.pop();35}3637TIntermSymbol *createTestSymbol(const TType &type)38{39std::stringstream symbolNameOut;40symbolNameOut << "test" << mUniqueIndex;41ImmutableString symbolName(symbolNameOut.str());42++mUniqueIndex;4344// We're using a mock symbol table here, don't need to assign proper symbol ids to these45// nodes.46TSymbolTable symbolTable;47TType *variableType = new TType(type);48variableType->setQualifier(EvqTemporary);49TVariable *variable =50new TVariable(&symbolTable, symbolName, variableType, SymbolType::AngleInternal);51TIntermSymbol *node = new TIntermSymbol(variable);52node->setLine(createUniqueSourceLoc());53return node;54}5556TIntermSymbol *createTestSymbol()57{58TType type(EbtFloat, EbpHigh);59return createTestSymbol(type);60}6162TFunction *createTestFunction(const TType &returnType, const TIntermSequence &args)63{64// We're using a mock symbol table similarly as for creating symbol nodes.65const ImmutableString name("testFunc");66TSymbolTable symbolTable;67TFunction *func = new TFunction(&symbolTable, name, SymbolType::UserDefined,68new TType(returnType), false);69for (TIntermNode *arg : args)70{71const TType *type = new TType(arg->getAsTyped()->getType());72func->addParameter(new TVariable(&symbolTable, ImmutableString("param"), type,73SymbolType::UserDefined));74}75return func;76}7778void checkTypeEqualWithQualifiers(const TType &original, const TType ©)79{80ASSERT_EQ(original, copy);81ASSERT_EQ(original.getPrecision(), copy.getPrecision());82ASSERT_EQ(original.getQualifier(), copy.getQualifier());83}8485void checkSymbolCopy(TIntermNode *aOriginal, TIntermNode *aCopy)86{87ASSERT_NE(aOriginal, aCopy);88TIntermSymbol *copy = aCopy->getAsSymbolNode();89TIntermSymbol *original = aOriginal->getAsSymbolNode();90ASSERT_NE(nullptr, copy);91ASSERT_NE(nullptr, original);92ASSERT_NE(original, copy);93ASSERT_EQ(&original->variable(), ©->variable());94ASSERT_EQ(original->uniqueId(), copy->uniqueId());95ASSERT_EQ(original->getName(), copy->getName());96checkTypeEqualWithQualifiers(original->getType(), copy->getType());97ASSERT_EQ(original->getLine().first_file, copy->getLine().first_file);98ASSERT_EQ(original->getLine().first_line, copy->getLine().first_line);99ASSERT_EQ(original->getLine().last_file, copy->getLine().last_file);100ASSERT_EQ(original->getLine().last_line, copy->getLine().last_line);101}102103TSourceLoc createUniqueSourceLoc()104{105TSourceLoc loc;106loc.first_file = mUniqueIndex;107loc.first_line = mUniqueIndex + 1;108loc.last_file = mUniqueIndex + 2;109loc.last_line = mUniqueIndex + 3;110++mUniqueIndex;111return loc;112}113114static TSourceLoc getTestSourceLoc()115{116TSourceLoc loc;117loc.first_file = 1;118loc.first_line = 2;119loc.last_file = 3;120loc.last_line = 4;121return loc;122}123124static void checkTestSourceLoc(const TSourceLoc &loc)125{126ASSERT_EQ(1, loc.first_file);127ASSERT_EQ(2, loc.first_line);128ASSERT_EQ(3, loc.last_file);129ASSERT_EQ(4, loc.last_line);130}131132private:133angle::PoolAllocator allocator;134int mUniqueIndex;135};136137// Check that the deep copy of a symbol node is an actual copy with the same attributes as the138// original.139TEST_F(IntermNodeTest, DeepCopySymbolNode)140{141const TType *type = StaticType::Get<EbtInt, EbpHigh, EvqTemporary, 1, 1>();142143// We're using a mock symbol table here, don't need to assign proper symbol ids to these nodes.144TSymbolTable symbolTable;145146TVariable *variable =147new TVariable(&symbolTable, ImmutableString("name"), type, SymbolType::AngleInternal);148TIntermSymbol *original = new TIntermSymbol(variable);149original->setLine(getTestSourceLoc());150TIntermTyped *copy = original->deepCopy();151checkSymbolCopy(original, copy);152checkTestSourceLoc(copy->getLine());153}154155// Check that the deep copy of a constant union node is an actual copy with the same attributes as156// the original.157TEST_F(IntermNodeTest, DeepCopyConstantUnionNode)158{159TType type(EbtInt, EbpHigh);160TConstantUnion *constValue = new TConstantUnion[1];161constValue[0].setIConst(101);162TIntermConstantUnion *original = new TIntermConstantUnion(constValue, type);163original->setLine(getTestSourceLoc());164TIntermTyped *copyTyped = original->deepCopy();165TIntermConstantUnion *copy = copyTyped->getAsConstantUnion();166ASSERT_NE(nullptr, copy);167ASSERT_NE(original, copy);168checkTestSourceLoc(copy->getLine());169checkTypeEqualWithQualifiers(original->getType(), copy->getType());170ASSERT_EQ(101, copy->getIConst(0));171}172173// Check that the deep copy of a binary node is an actual copy with the same attributes as the174// original. Child nodes also need to be copies with the same attributes as the original children.175TEST_F(IntermNodeTest, DeepCopyBinaryNode)176{177TType type(EbtFloat, EbpHigh);178179TIntermBinary *original = new TIntermBinary(EOpAdd, createTestSymbol(), createTestSymbol());180original->setLine(getTestSourceLoc());181TIntermTyped *copyTyped = original->deepCopy();182TIntermBinary *copy = copyTyped->getAsBinaryNode();183ASSERT_NE(nullptr, copy);184ASSERT_NE(original, copy);185checkTestSourceLoc(copy->getLine());186checkTypeEqualWithQualifiers(original->getType(), copy->getType());187188checkSymbolCopy(original->getLeft(), copy->getLeft());189checkSymbolCopy(original->getRight(), copy->getRight());190}191192// Check that the deep copy of a unary node is an actual copy with the same attributes as the193// original. The child node also needs to be a copy with the same attributes as the original child.194TEST_F(IntermNodeTest, DeepCopyUnaryNode)195{196TType type(EbtFloat, EbpHigh);197198TIntermUnary *original = new TIntermUnary(EOpPreIncrement, createTestSymbol(), nullptr);199original->setLine(getTestSourceLoc());200TIntermTyped *copyTyped = original->deepCopy();201TIntermUnary *copy = copyTyped->getAsUnaryNode();202ASSERT_NE(nullptr, copy);203ASSERT_NE(original, copy);204checkTestSourceLoc(copy->getLine());205checkTypeEqualWithQualifiers(original->getType(), copy->getType());206207checkSymbolCopy(original->getOperand(), copy->getOperand());208}209210// Check that the deep copy of an aggregate node is an actual copy with the same attributes as the211// original. Child nodes also need to be copies with the same attributes as the original children.212TEST_F(IntermNodeTest, DeepCopyAggregateNode)213{214TIntermSequence *originalSeq = new TIntermSequence();215originalSeq->push_back(createTestSymbol());216originalSeq->push_back(createTestSymbol());217originalSeq->push_back(createTestSymbol());218219TFunction *testFunc =220createTestFunction(originalSeq->back()->getAsTyped()->getType(), *originalSeq);221222TIntermAggregate *original = TIntermAggregate::CreateFunctionCall(*testFunc, originalSeq);223original->setLine(getTestSourceLoc());224225TIntermTyped *copyTyped = original->deepCopy();226TIntermAggregate *copy = copyTyped->getAsAggregate();227ASSERT_NE(nullptr, copy);228ASSERT_NE(original, copy);229checkTestSourceLoc(copy->getLine());230checkTypeEqualWithQualifiers(original->getType(), copy->getType());231232ASSERT_EQ(original->getSequence()->size(), copy->getSequence()->size());233TIntermSequence::size_type i = 0;234for (auto *copyChild : *copy->getSequence())235{236TIntermNode *originalChild = original->getSequence()->at(i);237checkSymbolCopy(originalChild, copyChild);238++i;239}240}241242// Check that the deep copy of a ternary node is an actual copy with the same attributes as the243// original. Child nodes also need to be copies with the same attributes as the original children.244TEST_F(IntermNodeTest, DeepCopyTernaryNode)245{246TType type(EbtFloat, EbpHigh);247248TIntermTernary *original = new TIntermTernary(createTestSymbol(TType(EbtBool, EbpUndefined)),249createTestSymbol(), createTestSymbol());250original->setLine(getTestSourceLoc());251TIntermTyped *copyTyped = original->deepCopy();252TIntermTernary *copy = copyTyped->getAsTernaryNode();253ASSERT_NE(nullptr, copy);254ASSERT_NE(original, copy);255checkTestSourceLoc(copy->getLine());256checkTypeEqualWithQualifiers(original->getType(), copy->getType());257258checkSymbolCopy(original->getCondition(), copy->getCondition());259checkSymbolCopy(original->getTrueExpression(), copy->getTrueExpression());260checkSymbolCopy(original->getFalseExpression(), copy->getFalseExpression());261}262263264