Edit

kc3-lang/angle/src/compiler/translator/TranslatorMetalDirect/Name.cpp

Branch :

  • Show log

    Commit

  • Author : Kyle Piddington
    Date : 2021-04-26 16:56:15
    Hash : d7aa0130
    Message : Upstream Apple's direct-to-Metal backend: compile translator. This change is meant to merge the translator changes from Apple's direct-to-Metal backend. Taken from Kyle Piddington's CL: https://chromium-review.googlesource.com/c/angle/angle/+/2857366/ The goal of this CL is to merge the translator code in a state that compiles, but not to switch the Metal backend over to use this translator backend yet. Bug: angleproject:5505 Change-Id: I68a6354604498cd5fd1eb96c13fc56f3b38f2bd0 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2897536 Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Commit-Queue: Jonah Ryan-Davis <jonahr@google.com>

  • src/compiler/translator/TranslatorMetalDirect/Name.cpp
  • //
    // Copyright 2020 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.
    //
    
    #include "compiler/translator/TranslatorMetalDirect/Name.h"
    #include "common/debug.h"
    #include "compiler/translator/tree_util/IntermTraverse.h"
    
    using namespace sh;
    
    ////////////////////////////////////////////////////////////////////////////////
    
    template <typename T>
    static ImmutableString GetName(T const &object)
    {
        if (object.symbolType() == SymbolType::Empty)
        {
            return kEmptyImmutableString;
        }
        return object.name();
    }
    
    Name::Name(const TField &field) : Name(GetName(field), field.symbolType()) {}
    
    Name::Name(const TSymbol &symbol) : Name(GetName(symbol), symbol.symbolType()) {}
    
    bool Name::operator==(const Name &other) const
    {
        return mRawName == other.mRawName && mSymbolType == other.mSymbolType;
    }
    
    bool Name::operator!=(const Name &other) const
    {
        return !(*this == other);
    }
    
    bool Name::operator<(const Name &other) const
    {
        if (mRawName < other.mRawName)
        {
            return true;
        }
        if (other.mRawName < mRawName)
        {
            return false;
        }
        return mSymbolType < other.mSymbolType;
    }
    
    bool Name::empty() const
    {
        return mSymbolType == SymbolType::Empty;
    }
    
    bool Name::beginsWith(const Name &prefix) const
    {
        if (mSymbolType != prefix.mSymbolType)
        {
            return false;
        }
        return mRawName.beginsWith(prefix.mRawName);
    }
    
    void Name::emit(TInfoSinkBase &out) const
    {
        switch (mSymbolType)
        {
            case SymbolType::BuiltIn:
            case SymbolType::UserDefined:
                ASSERT(!mRawName.empty());
                out << mRawName;
                break;
    
            case SymbolType::AngleInternal:
                ASSERT(!mRawName.empty());
                if (mRawName.beginsWith(kAngleInternalPrefix))
                {
                    out << mRawName;
                }
                else if (mRawName[0] != '_')
                {
                    out << kAngleInternalPrefix << '_' << mRawName;
                }
                else
                {
                    out << kAngleInternalPrefix << mRawName;
                }
                break;
    
            case SymbolType::Empty:
                UNREACHABLE();
                break;
        }
    }
    
    ////////////////////////////////////////////////////////////////////////////////
    
    namespace
    {
    
    // NOTE: This matches more things than FindSymbolNode.
    class ExpressionContainsNameVisitor : public TIntermTraverser
    {
        Name mName;
        bool mFoundName = false;
    
      public:
        ExpressionContainsNameVisitor(const Name &name)
            : TIntermTraverser(true, false, false), mName(name)
        {}
    
        bool foundName() const { return mFoundName; }
    
        void visitSymbol(TIntermSymbol *node) override
        {
            if (Name(node->variable()) == mName)
            {
                mFoundName = true;
            }
        }
    
        bool visitSwizzle(Visit, TIntermSwizzle *) override { return !mFoundName; }
    
        bool visitBinary(Visit visit, TIntermBinary *node) override { return !mFoundName; }
    
        bool visitUnary(Visit visit, TIntermUnary *node) override { return !mFoundName; }
    
        bool visitTernary(Visit visit, TIntermTernary *node) override { return !mFoundName; }
    
        bool visitAggregate(Visit visit, TIntermAggregate *node) override
        {
            if (node->isConstructor())
            {
                const TType &type           = node->getType();
                const TStructure *structure = type.getStruct();
                if (structure && Name(*structure) == mName)
                {
                    mFoundName = true;
                }
            }
            else
            {
                const TFunction *func = node->getFunction();
                if (func && Name(*func) == mName)
                {
                    mFoundName = true;
                }
            }
            return !mFoundName;
        }
    
        bool visitIfElse(Visit visit, TIntermIfElse *node) override
        {
            UNREACHABLE();
            return false;
        }
    
        bool visitSwitch(Visit, TIntermSwitch *) override
        {
            UNREACHABLE();
            return false;
        }
        bool visitCase(Visit, TIntermCase *) override
        {
            UNREACHABLE();
            return false;
        }
    
        void visitFunctionPrototype(TIntermFunctionPrototype *) override { UNREACHABLE(); }
    
        bool visitFunctionDefinition(Visit, TIntermFunctionDefinition *) override
        {
            UNREACHABLE();
            return false;
        }
    
        bool visitBlock(Visit, TIntermBlock *) override
        {
            UNREACHABLE();
            return false;
        }
    
        bool visitGlobalQualifierDeclaration(Visit, TIntermGlobalQualifierDeclaration *) override
        {
            UNREACHABLE();
            return false;
        }
    
        bool visitDeclaration(Visit, TIntermDeclaration *) override
        {
            UNREACHABLE();
            return false;
        }
    
        bool visitLoop(Visit, TIntermLoop *) override
        {
            UNREACHABLE();
            return false;
        }
    
        bool visitBranch(Visit, TIntermBranch *) override
        {
            UNREACHABLE();
            return false;
        }
    
        void visitPreprocessorDirective(TIntermPreprocessorDirective *) override { UNREACHABLE(); }
    };
    
    }  // anonymous namespace
    
    bool sh::ExpressionContainsName(const Name &name, TIntermTyped &node)
    {
        ExpressionContainsNameVisitor visitor(name);
        node.traverse(&visitor);
        return visitor.foundName();
    }