<commit_before>//
// Copyright (c) 2013 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.
//
// ValidateOutputs validates fragment shader outputs. It checks for conflicting locations,
// out-of-range locations, that locations are specified when using multiple outputs, and YUV output
// validity.

#include "compiler/translator/ValidateOutputs.h"

#include <set>

#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/ParseContext.h"

namespace sh
{

namespace
{
void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
{
    diagnostics->error(symbol.getLine(), reason, symbol.getSymbol().c_str());
}

class ValidateOutputsTraverser : public TIntermTraverser
{
  public:
    ValidateOutputsTraverser(const TExtensionBehavior &extBehavior, int maxDrawBuffers);

    void validate(TDiagnostics *diagnostics) const;

    void visitSymbol(TIntermSymbol *) override;

  private:
    int mMaxDrawBuffers;
    bool mAllowUnspecifiedOutputLocationResolution;
    bool mUsesFragDepth;

    typedef std::vector<TIntermSymbol *> OutputVector;
    OutputVector mOutputs;
    OutputVector mUnspecifiedLocationOutputs;
    OutputVector mYuvOutputs;
    std::set<std::string> mVisitedSymbols;
};

ValidateOutputsTraverser::ValidateOutputsTraverser(const TExtensionBehavior &extBehavior,
                                                   int maxDrawBuffers)
    : TIntermTraverser(true, false, false),
      mMaxDrawBuffers(maxDrawBuffers),
      mAllowUnspecifiedOutputLocationResolution(
          IsExtensionEnabled(extBehavior, TExtension::EXT_blend_func_extended)),
      mUsesFragDepth(false)
{
}

void ValidateOutputsTraverser::visitSymbol(TIntermSymbol *symbol)
{
    TString name         = symbol->getSymbol();
    TQualifier qualifier = symbol->getQualifier();

    if (mVisitedSymbols.count(name.c_str()) == 1)
        return;

    mVisitedSymbols.insert(name.c_str());

    if (qualifier == EvqFragmentOut)
    {
        if (symbol->getType().getLayoutQualifier().location != -1)
        {
            mOutputs.push_back(symbol);
        }
        else if (symbol->getType().getLayoutQualifier().yuv == true)
        {
            mYuvOutputs.push_back(symbol);
        }
        else
        {
            mUnspecifiedLocationOutputs.push_back(symbol);
        }
    }
    else if (qualifier == EvqFragDepth || qualifier == EvqFragDepthEXT)
    {
        mUsesFragDepth = true;
    }
}
<commit_msg>Index symbols by id in ValidateOutputs<commit_after>//
// Copyright (c) 2013 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.
//
// ValidateOutputs validates fragment shader outputs. It checks for conflicting locations,
// out-of-range locations, that locations are specified when using multiple outputs, and YUV output
// validity.

#include "compiler/translator/ValidateOutputs.h"

#include <set>

#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/ParseContext.h"

namespace sh
{

namespace
{
void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
{
    diagnostics->error(symbol.getLine(), reason, symbol.getSymbol().c_str());
}

class ValidateOutputsTraverser : public TIntermTraverser
{
  public:
    ValidateOutputsTraverser(const TExtensionBehavior &extBehavior, int maxDrawBuffers);

    void validate(TDiagnostics *diagnostics) const;

    void visitSymbol(TIntermSymbol *) override;

  private:
    int mMaxDrawBuffers;
    bool mAllowUnspecifiedOutputLocationResolution;
    bool mUsesFragDepth;

    typedef std::vector<TIntermSymbol *> OutputVector;
    OutputVector mOutputs;
    OutputVector mUnspecifiedLocationOutputs;
    OutputVector mYuvOutputs;
    std::set<int> mVisitedSymbols;  // Visited symbol ids.
};

ValidateOutputsTraverser::ValidateOutputsTraverser(const TExtensionBehavior &extBehavior,
                                                   int maxDrawBuffers)
    : TIntermTraverser(true, false, false),
      mMaxDrawBuffers(maxDrawBuffers),
      mAllowUnspecifiedOutputLocationResolution(
          IsExtensionEnabled(extBehavior, TExtension::EXT_blend_func_extended)),
      mUsesFragDepth(false)
{
}

void ValidateOutputsTraverser::visitSymbol(TIntermSymbol *symbol)
{
    if (symbol->variable().symbolType() == SymbolType::Empty)
        return;

    if (mVisitedSymbols.count(symbol->uniqueId().get()) == 1)
        return;

    mVisitedSymbols.insert(symbol->uniqueId().get());

    TQualifier qualifier = symbol->getQualifier();
    if (qualifier == EvqFragmentOut)
    {
        if (symbol->getType().getLayoutQualifier().location != -1)
        {
            mOutputs.push_back(symbol);
        }
        else if (symbol->getType().getLayoutQualifier().yuv == true)
        {
            mYuvOutputs.push_back(symbol);
        }
        else
        {
            mUnspecifiedLocationOutputs.push_back(symbol);
        }
    }
    else if (qualifier == EvqFragDepth || qualifier == EvqFragDepthEXT)
    {
        mUsesFragDepth = true;
    }
}

{'fraction_non_alphanumeric': 0.09744560075685904, 'fraction_numerical': 0.002270577105014191, 'mean_word_length': 3.472081218274112, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4032061', 'n_tokens_mistral': 1572, 'n_tokens_neox': 1564, 'n_words': 335}