Path: blob/main_old/src/tests/test_utils/compiler_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// compiler_test.cpp:6// utilities for compiler unit tests.78#include "tests/test_utils/compiler_test.h"910#include "angle_gl.h"11#include "compiler/translator/Compiler.h"12#include "compiler/translator/FunctionLookup.h"13#include "compiler/translator/tree_util/IntermTraverse.h"1415namespace sh16{1718namespace19{20constexpr char kBinaryBlob[] = "<binary blob>";21bool IsBinaryBlob(const std::string &code)22{23return code == kBinaryBlob;24}2526ImmutableString GetSymbolTableMangledName(TIntermAggregate *node)27{28ASSERT(!node->isConstructor());29return TFunctionLookup::GetMangledName(node->getFunction()->name().data(),30*node->getSequence());31}3233class FunctionCallFinder : public TIntermTraverser34{35public:36FunctionCallFinder(const char *functionMangledName)37: TIntermTraverser(true, false, false),38mFunctionMangledName(functionMangledName),39mNodeFound(nullptr)40{}4142bool visitAggregate(Visit visit, TIntermAggregate *node) override43{44if (!node->isConstructor() && GetSymbolTableMangledName(node) == mFunctionMangledName)45{46mNodeFound = node;47return false;48}49return true;50}5152bool isFound() const { return mNodeFound != nullptr; }53const TIntermAggregate *getNode() const { return mNodeFound; }5455private:56const char *mFunctionMangledName;57TIntermAggregate *mNodeFound;58};5960} // anonymous namespace6162bool compileTestShader(GLenum type,63ShShaderSpec spec,64ShShaderOutput output,65const std::string &shaderString,66ShBuiltInResources *resources,67ShCompileOptions compileOptions,68std::string *translatedCode,69std::string *infoLog)70{71sh::TCompiler *translator = sh::ConstructCompiler(type, spec, output);72if (!translator->Init(*resources))73{74SafeDelete(translator);75return false;76}7778const char *shaderStrings[] = {shaderString.c_str()};7980bool compilationSuccess =81translator->compile(shaderStrings, 1, SH_OBJECT_CODE | compileOptions);82TInfoSink &infoSink = translator->getInfoSink();83if (translatedCode)84{85*translatedCode = infoSink.obj.isBinary() ? kBinaryBlob : infoSink.obj.c_str();86}87if (infoLog)88{89*infoLog = infoSink.info.c_str();90}91SafeDelete(translator);92return compilationSuccess;93}9495bool compileTestShader(GLenum type,96ShShaderSpec spec,97ShShaderOutput output,98const std::string &shaderString,99ShCompileOptions compileOptions,100std::string *translatedCode,101std::string *infoLog)102{103ShBuiltInResources resources;104sh::InitBuiltInResources(&resources);105resources.FragmentPrecisionHigh = 1;106return compileTestShader(type, spec, output, shaderString, &resources, compileOptions,107translatedCode, infoLog);108}109110MatchOutputCodeTest::MatchOutputCodeTest(GLenum shaderType,111ShCompileOptions defaultCompileOptions,112ShShaderOutput outputType)113: mShaderType(shaderType), mDefaultCompileOptions(defaultCompileOptions)114{115sh::InitBuiltInResources(&mResources);116mResources.FragmentPrecisionHigh = 1;117mOutputCode[outputType] = std::string();118}119120void MatchOutputCodeTest::addOutputType(const ShShaderOutput outputType)121{122mOutputCode[outputType] = std::string();123}124125ShBuiltInResources *MatchOutputCodeTest::getResources()126{127return &mResources;128}129130void MatchOutputCodeTest::compile(const std::string &shaderString)131{132compile(shaderString, mDefaultCompileOptions);133}134135void MatchOutputCodeTest::compile(const std::string &shaderString,136const ShCompileOptions compileOptions)137{138std::string infoLog;139for (auto &code : mOutputCode)140{141bool compilationSuccess =142compileWithSettings(code.first, shaderString, compileOptions, &code.second, &infoLog);143if (!compilationSuccess)144{145FAIL() << "Shader compilation failed:\n" << infoLog;146}147}148}149150bool MatchOutputCodeTest::compileWithSettings(ShShaderOutput output,151const std::string &shaderString,152const ShCompileOptions compileOptions,153std::string *translatedCode,154std::string *infoLog)155{156return compileTestShader(mShaderType, SH_GLES3_1_SPEC, output, shaderString, &mResources,157compileOptions, translatedCode, infoLog);158}159160bool MatchOutputCodeTest::foundInCodeRegex(ShShaderOutput output,161const std::regex ®exToFind,162std::smatch *match) const163{164const auto code = mOutputCode.find(output);165EXPECT_NE(mOutputCode.end(), code);166if (code == mOutputCode.end())167{168return std::string::npos;169}170171// No meaningful check for binary blobs172if (IsBinaryBlob(code->second))173{174return true;175}176177if (match)178{179return std::regex_search(code->second, *match, regexToFind);180}181else182{183return std::regex_search(code->second, regexToFind);184}185}186187bool MatchOutputCodeTest::foundInCode(ShShaderOutput output, const char *stringToFind) const188{189const auto code = mOutputCode.find(output);190EXPECT_NE(mOutputCode.end(), code);191if (code == mOutputCode.end())192{193return std::string::npos;194}195196// No meaningful check for binary blobs197if (IsBinaryBlob(code->second))198{199return true;200}201202return code->second.find(stringToFind) != std::string::npos;203}204205bool MatchOutputCodeTest::foundInCodeInOrder(ShShaderOutput output,206std::vector<const char *> stringsToFind)207{208const auto code = mOutputCode.find(output);209EXPECT_NE(mOutputCode.end(), code);210if (code == mOutputCode.end())211{212return false;213}214215// No meaningful check for binary blobs216if (IsBinaryBlob(code->second))217{218return true;219}220221size_t currentPos = 0;222for (const char *stringToFind : stringsToFind)223{224auto position = code->second.find(stringToFind, currentPos);225if (position == std::string::npos)226{227return false;228}229currentPos = position + strlen(stringToFind);230}231return true;232}233234bool MatchOutputCodeTest::foundInCode(ShShaderOutput output,235const char *stringToFind,236const int expectedOccurrences) const237{238const auto code = mOutputCode.find(output);239EXPECT_NE(mOutputCode.end(), code);240if (code == mOutputCode.end())241{242return false;243}244245// No meaningful check for binary blobs246if (IsBinaryBlob(code->second))247{248return true;249}250251size_t currentPos = 0;252int occurencesLeft = expectedOccurrences;253254const size_t searchStringLength = strlen(stringToFind);255256while (occurencesLeft-- > 0)257{258auto position = code->second.find(stringToFind, currentPos);259if (position == std::string::npos)260{261return false;262}263// Search strings should not overlap.264currentPos = position + searchStringLength;265}266// Make sure that there aren't extra occurrences.267return code->second.find(stringToFind, currentPos) == std::string::npos;268}269270bool MatchOutputCodeTest::foundInCode(const char *stringToFind) const271{272for (auto &code : mOutputCode)273{274if (!foundInCode(code.first, stringToFind))275{276return false;277}278}279return true;280}281282bool MatchOutputCodeTest::foundInCodeRegex(const std::regex ®exToFind, std::smatch *match) const283{284for (auto &code : mOutputCode)285{286if (!foundInCodeRegex(code.first, regexToFind, match))287{288return false;289}290}291return true;292}293294bool MatchOutputCodeTest::foundInCode(const char *stringToFind, const int expectedOccurrences) const295{296for (auto &code : mOutputCode)297{298if (!foundInCode(code.first, stringToFind, expectedOccurrences))299{300return false;301}302}303return true;304}305306bool MatchOutputCodeTest::foundInCodeInOrder(std::vector<const char *> stringsToFind)307{308for (auto &code : mOutputCode)309{310if (!foundInCodeInOrder(code.first, stringsToFind))311{312return false;313}314}315return true;316}317318bool MatchOutputCodeTest::notFoundInCode(const char *stringToFind) const319{320for (auto &code : mOutputCode)321{322// No meaningful check for binary blobs323if (IsBinaryBlob(code.second))324{325continue;326}327328if (foundInCode(code.first, stringToFind))329{330return false;331}332}333return true;334}335336const TIntermAggregate *FindFunctionCallNode(TIntermNode *root, const TString &functionMangledName)337{338FunctionCallFinder finder(functionMangledName.c_str());339root->traverse(&finder);340return finder.getNode();341}342343} // namespace sh344345346