Edit

kc3-lang/angle/src/tests/test_utils/compiler_test.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2018-11-27 11:34:27
    Hash : b980c563
    Message : Reformat all cpp and h files. This applies git cl format --full to all ANGLE sources. Bug: angleproject:2986 Change-Id: Ib504e618c1589332a37e97696cdc3515d739308f Reviewed-on: https://chromium-review.googlesource.com/c/1351367 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>

  • src/tests/test_utils/compiler_test.cpp
  • //
    // Copyright (c) 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.
    //
    // compiler_test.cpp:
    //     utilities for compiler unit tests.
    
    #include "tests/test_utils/compiler_test.h"
    
    #include "angle_gl.h"
    #include "compiler/translator/Compiler.h"
    #include "compiler/translator/FunctionLookup.h"
    #include "compiler/translator/tree_util/IntermTraverse.h"
    
    namespace sh
    {
    
    namespace
    {
    
    ImmutableString GetSymbolTableMangledName(TIntermAggregate *node)
    {
        ASSERT(!node->isConstructor());
        switch (node->getOp())
        {
            case EOpCallInternalRawFunction:
            case EOpCallBuiltInFunction:
            case EOpCallFunctionInAST:
                return TFunctionLookup::GetMangledName(node->getFunction()->name().data(),
                                                       *node->getSequence());
            default:
                const char *opString = GetOperatorString(node->getOp());
                return TFunctionLookup::GetMangledName(opString, *node->getSequence());
        }
    }
    
    class FunctionCallFinder : public TIntermTraverser
    {
      public:
        FunctionCallFinder(const char *functionMangledName)
            : TIntermTraverser(true, false, false),
              mFunctionMangledName(functionMangledName),
              mNodeFound(nullptr)
        {}
    
        bool visitAggregate(Visit visit, TIntermAggregate *node) override
        {
            if (node->isFunctionCall() && GetSymbolTableMangledName(node) == mFunctionMangledName)
            {
                mNodeFound = node;
                return false;
            }
            return true;
        }
    
        bool isFound() const { return mNodeFound != nullptr; }
        const TIntermAggregate *getNode() const { return mNodeFound; }
    
      private:
        const char *mFunctionMangledName;
        TIntermAggregate *mNodeFound;
    };
    
    }  // anonymous namespace
    
    bool compileTestShader(GLenum type,
                           ShShaderSpec spec,
                           ShShaderOutput output,
                           const std::string &shaderString,
                           ShBuiltInResources *resources,
                           ShCompileOptions compileOptions,
                           std::string *translatedCode,
                           std::string *infoLog)
    {
        sh::TCompiler *translator = sh::ConstructCompiler(type, spec, output);
        if (!translator->Init(*resources))
        {
            SafeDelete(translator);
            return false;
        }
    
        const char *shaderStrings[] = {shaderString.c_str()};
    
        bool compilationSuccess =
            translator->compile(shaderStrings, 1, SH_OBJECT_CODE | compileOptions);
        TInfoSink &infoSink = translator->getInfoSink();
        if (translatedCode)
            *translatedCode = infoSink.obj.c_str();
        if (infoLog)
            *infoLog = infoSink.info.c_str();
        SafeDelete(translator);
        return compilationSuccess;
    }
    
    bool compileTestShader(GLenum type,
                           ShShaderSpec spec,
                           ShShaderOutput output,
                           const std::string &shaderString,
                           ShCompileOptions compileOptions,
                           std::string *translatedCode,
                           std::string *infoLog)
    {
        ShBuiltInResources resources;
        sh::InitBuiltInResources(&resources);
        return compileTestShader(type, spec, output, shaderString, &resources, compileOptions,
                                 translatedCode, infoLog);
    }
    
    MatchOutputCodeTest::MatchOutputCodeTest(GLenum shaderType,
                                             ShCompileOptions defaultCompileOptions,
                                             ShShaderOutput outputType)
        : mShaderType(shaderType), mDefaultCompileOptions(defaultCompileOptions)
    {
        sh::InitBuiltInResources(&mResources);
        mOutputCode[outputType] = std::string();
    }
    
    void MatchOutputCodeTest::addOutputType(const ShShaderOutput outputType)
    {
        mOutputCode[outputType] = std::string();
    }
    
    ShBuiltInResources *MatchOutputCodeTest::getResources()
    {
        return &mResources;
    }
    
    void MatchOutputCodeTest::compile(const std::string &shaderString)
    {
        compile(shaderString, mDefaultCompileOptions);
    }
    
    void MatchOutputCodeTest::compile(const std::string &shaderString,
                                      const ShCompileOptions compileOptions)
    {
        std::string infoLog;
        for (auto &code : mOutputCode)
        {
            bool compilationSuccess =
                compileWithSettings(code.first, shaderString, compileOptions, &code.second, &infoLog);
            if (!compilationSuccess)
            {
                FAIL() << "Shader compilation failed:\n" << infoLog;
            }
        }
    }
    
    bool MatchOutputCodeTest::compileWithSettings(ShShaderOutput output,
                                                  const std::string &shaderString,
                                                  const ShCompileOptions compileOptions,
                                                  std::string *translatedCode,
                                                  std::string *infoLog)
    {
        return compileTestShader(mShaderType, SH_GLES3_1_SPEC, output, shaderString, &mResources,
                                 compileOptions, translatedCode, infoLog);
    }
    
    bool MatchOutputCodeTest::foundInCode(ShShaderOutput output, const char *stringToFind) const
    {
        const auto code = mOutputCode.find(output);
        EXPECT_NE(mOutputCode.end(), code);
        if (code == mOutputCode.end())
        {
            return std::string::npos;
        }
        return code->second.find(stringToFind) != std::string::npos;
    }
    
    bool MatchOutputCodeTest::foundInCodeInOrder(ShShaderOutput output,
                                                 std::vector<const char *> stringsToFind)
    {
        const auto code = mOutputCode.find(output);
        EXPECT_NE(mOutputCode.end(), code);
        if (code == mOutputCode.end())
        {
            return false;
        }
    
        size_t currentPos = 0;
        for (const char *stringToFind : stringsToFind)
        {
            auto position = code->second.find(stringToFind, currentPos);
            if (position == std::string::npos)
            {
                return false;
            }
            currentPos = position + strlen(stringToFind);
        }
        return true;
    }
    
    bool MatchOutputCodeTest::foundInCode(ShShaderOutput output,
                                          const char *stringToFind,
                                          const int expectedOccurrences) const
    {
        const auto code = mOutputCode.find(output);
        EXPECT_NE(mOutputCode.end(), code);
        if (code == mOutputCode.end())
        {
            return false;
        }
    
        size_t currentPos  = 0;
        int occurencesLeft = expectedOccurrences;
    
        const size_t searchStringLength = strlen(stringToFind);
    
        while (occurencesLeft-- > 0)
        {
            auto position = code->second.find(stringToFind, currentPos);
            if (position == std::string::npos)
            {
                return false;
            }
            // Search strings should not overlap.
            currentPos = position + searchStringLength;
        }
        // Make sure that there aren't extra occurrences.
        return code->second.find(stringToFind, currentPos) == std::string::npos;
    }
    
    bool MatchOutputCodeTest::foundInCode(const char *stringToFind) const
    {
        for (auto &code : mOutputCode)
        {
            if (!foundInCode(code.first, stringToFind))
            {
                return false;
            }
        }
        return true;
    }
    
    bool MatchOutputCodeTest::foundInCode(const char *stringToFind, const int expectedOccurrences) const
    {
        for (auto &code : mOutputCode)
        {
            if (!foundInCode(code.first, stringToFind, expectedOccurrences))
            {
                return false;
            }
        }
        return true;
    }
    
    bool MatchOutputCodeTest::foundInCodeInOrder(std::vector<const char *> stringsToFind)
    {
        for (auto &code : mOutputCode)
        {
            if (!foundInCodeInOrder(code.first, stringsToFind))
            {
                return false;
            }
        }
        return true;
    }
    
    bool MatchOutputCodeTest::notFoundInCode(const char *stringToFind) const
    {
        for (auto &code : mOutputCode)
        {
            if (foundInCode(code.first, stringToFind))
            {
                return false;
            }
        }
        return true;
    }
    
    const TIntermAggregate *FindFunctionCallNode(TIntermNode *root, const TString &functionMangledName)
    {
        FunctionCallFinder finder(functionMangledName.c_str());
        root->traverse(&finder);
        return finder.getNode();
    }
    
    }  // namespace sh