//
// Copyright 2017 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.
//
// Symbol.h: Symbols representing variables, functions, structures and interface blocks.
//

#ifndef COMPILER_TRANSLATOR_SYMBOL_H_
#define COMPILER_TRANSLATOR_SYMBOL_H_

#include "common/angleutils.h"
#include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolUniqueId.h"

namespace sh
{

class TSymbolTable;

// Symbol base class. (Can build functions or variables out of these...)
class TSymbol : angle::NonCopyable
{
  public:
    POOL_ALLOCATOR_NEW_DELETE
    TSymbol(TSymbolTable *symbolTable,
            const ImmutableString &name,
            SymbolType symbolType,
            SymbolClass symbolClass,
            TExtension extension = TExtension::UNDEFINED);

    TSymbol(TSymbolTable *symbolTable,
            const ImmutableString &name,
            SymbolType symbolType,
            SymbolClass symbolClass,
            const std::array<TExtension, 3u> &extensions);

    // Note that we can't have a virtual destructor in order to support constexpr symbols. Data is
    // either statically allocated or pool allocated.
    ~TSymbol() = default;

    // Calling name() for empty symbols (symbolType == SymbolType::Empty) generates a similar name
    // as for internal variables.
    ImmutableString name() const;
    // Don't call getMangledName() for empty symbols (symbolType == SymbolType::Empty).
    ImmutableString getMangledName() const;

    bool isFunction() const { return mSymbolClass == SymbolClass::Function; }
    bool isVariable() const { return mSymbolClass == SymbolClass::Variable; }
    bool isStruct() const { return mSymbolClass == SymbolClass::Struct; }
    bool isInterfaceBlock() const { return mSymbolClass == SymbolClass::InterfaceBlock; }

    const TSymbolUniqueId &uniqueId() const { return mUniqueId; }
    SymbolType symbolType() const { return mSymbolType; }
    const std::array<TExtension, 3u> extensions() const { return mExtensions; }

    template <size_t ExtensionCount>
    constexpr const std::array<TExtension, 3u> CreateExtensionList(
        const std::array<TExtension, ExtensionCount> &extensions)
    {
        switch (extensions.size())
        {
            case 1:
                return std::array<TExtension, 3u>{
                    {extensions[0], TExtension::UNDEFINED, TExtension::UNDEFINED}};
            case 2:
                return std::array<TExtension, 3u>{
                    {extensions[0], extensions[1], TExtension::UNDEFINED}};
            case 3:
                return std::array<TExtension, 3u>{{extensions[0], extensions[1], extensions[2]}};
            default:
                UNREACHABLE();
                return std::array<TExtension, 3u>{
                    {TExtension::UNDEFINED, TExtension::UNDEFINED, TExtension::UNDEFINED}};
        }
    }

  protected:
    template <size_t ExtensionCount>
    constexpr TSymbol(const TSymbolUniqueId &id,
                      const ImmutableString &name,
                      SymbolType symbolType,
                      const std::array<TExtension, ExtensionCount> &extensions,
                      SymbolClass symbolClass)
        : mName(name),
          mUniqueId(id),
          mExtensions(CreateExtensionList(extensions)),
          mSymbolType(symbolType),
          mSymbolClass(symbolClass)
    {}

    const ImmutableString mName;

  private:
    const TSymbolUniqueId mUniqueId;
    const std::array<TExtension, 3u> mExtensions;
    const SymbolType mSymbolType : 4;

    // We use this instead of having virtual functions for querying the class in order to support
    // constexpr symbols.
    const SymbolClass mSymbolClass : 4;
};

static_assert(sizeof(TSymbol) <= 24, "Size check failed");

// Variable.
// May store the value of a constant variable of any type (float, int, bool or struct).
class TVariable : public TSymbol
{
  public:
    TVariable(TSymbolTable *symbolTable,
              const ImmutableString &name,
              const TType *type,
              SymbolType symbolType,
              TExtension ext = TExtension::UNDEFINED);

    TVariable(TSymbolTable *symbolTable,
              const ImmutableString &name,
              const TType *type,
              SymbolType symbolType,
              const std::array<TExtension, 3u> &extensions);

    const TType &getType() const { return *mType; }

    const TConstantUnion *getConstPointer() const { return unionArray; }

    void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }

    // Note: only to be used for built-in variables with autogenerated ids!
    constexpr TVariable(const TSymbolUniqueId &id,
                        const ImmutableString &name,
                        SymbolType symbolType,
                        TExtension extension,
                        const TType *type)
        : TSymbol(id,
                  name,
                  symbolType,
                  std::array<TExtension, 1u>{{extension}},
                  SymbolClass::Variable),
          mType(type),
          unionArray(nullptr)
    {}

    template <size_t ExtensionCount>
    constexpr TVariable(const TSymbolUniqueId &id,
                        const ImmutableString &name,
                        SymbolType symbolType,
                        const std::array<TExtension, ExtensionCount> &extensions,
                        const TType *type)
        : TSymbol(id, name, symbolType, extensions, SymbolClass::Variable),
          mType(type),
          unionArray(nullptr)
    {}

  private:
    const TType *mType;
    const TConstantUnion *unionArray;
};

// Struct type.
class TStructure : public TSymbol, public TFieldListCollection
{
  public:
    TStructure(TSymbolTable *symbolTable,
               const ImmutableString &name,
               const TFieldList *fields,
               SymbolType symbolType);

    // The char arrays passed in must be pool allocated or static.
    void createSamplerSymbols(const char *namePrefix,
                              const TString &apiNamePrefix,
                              TVector<const TVariable *> *outputSymbols,
                              TMap<const TVariable *, TString> *outputSymbolsToAPINames,
                              TSymbolTable *symbolTable) const;

    void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; }
    bool atGlobalScope() const { return mAtGlobalScope; }

  private:
    friend class TSymbolTable;
    // For creating built-in structs.
    TStructure(const TSymbolUniqueId &id,
               const ImmutableString &name,
               TExtension extension,
               const TFieldList *fields)
        : TSymbol(id,
                  name,
                  SymbolType::BuiltIn,
                  std::array<TExtension, 1u>{{extension}},
                  SymbolClass::Struct),
          TFieldListCollection(fields)
    {}

    template <size_t ExtensionCount>
    TStructure(const TSymbolUniqueId &id,
               const ImmutableString &name,
               const std::array<TExtension, ExtensionCount> &extensions,
               const TFieldList *fields)
        : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::Struct),
          TFieldListCollection(fields)
    {}

    // TODO(zmo): Find a way to get rid of the const_cast in function
    // setName().  At the moment keep this function private so only
    // friend class RegenerateStructNames may call it.
    friend class RegenerateStructNamesTraverser;
    void setName(const ImmutableString &name);

    bool mAtGlobalScope;
};

// Interface block. Note that this contains the block name, not the instance name. Interface block
// instances are stored as TVariable.
class TInterfaceBlock : public TSymbol, public TFieldListCollection
{
  public:
    TInterfaceBlock(TSymbolTable *symbolTable,
                    const ImmutableString &name,
                    const TFieldList *fields,
                    const TLayoutQualifier &layoutQualifier,
                    SymbolType symbolType,
                    TExtension extension = TExtension::UNDEFINED);

    TInterfaceBlock(TSymbolTable *symbolTable,
                    const ImmutableString &name,
                    const TFieldList *fields,
                    const TLayoutQualifier &layoutQualifier,
                    SymbolType symbolType,
                    const std::array<TExtension, 3u> &extensions);

    TLayoutBlockStorage blockStorage() const { return mBlockStorage; }
    int blockBinding() const { return mBinding; }

  private:
    friend class TSymbolTable;
    // For creating built-in interface blocks.
    TInterfaceBlock(const TSymbolUniqueId &id,
                    const ImmutableString &name,
                    TExtension extension,
                    const TFieldList *fields)
        : TSymbol(id,
                  name,
                  SymbolType::BuiltIn,
                  std::array<TExtension, 1u>{{extension}},
                  SymbolClass::InterfaceBlock),
          TFieldListCollection(fields),
          mBlockStorage(EbsUnspecified),
          mBinding(0)
    {}

    template <size_t ExtensionCount>
    TInterfaceBlock(const TSymbolUniqueId &id,
                    const ImmutableString &name,
                    const std::array<TExtension, ExtensionCount> &extensions,
                    const TFieldList *fields)
        : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::InterfaceBlock),
          TFieldListCollection(fields),
          mBlockStorage(EbsUnspecified),
          mBinding(0)
    {}

    TLayoutBlockStorage mBlockStorage;
    int mBinding;

    // Note that we only record matrix packing on a per-field granularity.
};

// Parameter class used for parsing user-defined function parameters.
struct TParameter
{
    // Destructively converts to TVariable.
    // This method resets name and type to nullptrs to make sure
    // their content cannot be modified after the call.
    const TVariable *createVariable(TSymbolTable *symbolTable)
    {
        const ImmutableString constName(name);
        const TType *constType = new TType(type);
        name                   = nullptr;
        return new TVariable(symbolTable, constName, constType,
                             constName.empty() ? SymbolType::Empty : SymbolType::UserDefined);
    }

    const char *name;  // either pool allocated or static.
    TPublicType type;
};

// The function sub-class of a symbol.
class TFunction : public TSymbol
{
  public:
    // User-defined function
    TFunction(TSymbolTable *symbolTable,
              const ImmutableString &name,
              SymbolType symbolType,
              const TType *retType,
              bool knownToNotHaveSideEffects);

    void addParameter(const TVariable *p);
    void shareParameters(const TFunction &parametersSource);

    ImmutableString getFunctionMangledName() const
    {
        ASSERT(symbolType() != SymbolType::BuiltIn);
        if (mMangledName.empty())
        {
            mMangledName = buildMangledName();
        }
        return mMangledName;
    }

    const TType &getReturnType() const { return *returnType; }

    TOperator getBuiltInOp() const { return mOp; }

    void setDefined() { defined = true; }
    bool isDefined() const { return defined; }
    void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; }
    bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; }
    void setHasVoidParameter() { mHasVoidParameter = true; }
    bool hasVoidParameter() const { return mHasVoidParameter; }

    size_t getParamCount() const { return mParamCount; }
    const TVariable *getParam(size_t i) const { return mParameters[i]; }

    bool isKnownToNotHaveSideEffects() const { return mKnownToNotHaveSideEffects; }

    bool isMain() const;
    bool isImageFunction() const;
    bool isAtomicCounterFunction() const;

    // Note: Only to be used for static built-in functions!
    constexpr TFunction(const TSymbolUniqueId &id,
                        const ImmutableString &name,
                        TExtension extension,
                        const TVariable *const *parameters,
                        size_t paramCount,
                        const TType *retType,
                        TOperator op,
                        bool knownToNotHaveSideEffects)
        : TSymbol(id,
                  name,
                  SymbolType::BuiltIn,
                  std::array<TExtension, 1u>{{extension}},
                  SymbolClass::Function),
          mParametersVector(nullptr),
          mParameters(parameters),
          returnType(retType),
          mMangledName(nullptr),
          mParamCount(paramCount),
          mOp(op),
          defined(false),
          mHasPrototypeDeclaration(false),
          mKnownToNotHaveSideEffects(knownToNotHaveSideEffects),
          mHasVoidParameter(false)
    {}

    template <size_t ExtensionCount>
    constexpr TFunction(const TSymbolUniqueId &id,
                        const ImmutableString &name,
                        const std::array<TExtension, ExtensionCount> &extensions,
                        const TVariable *const *parameters,
                        size_t paramCount,
                        const TType *retType,
                        TOperator op,
                        bool knownToNotHaveSideEffects)
        : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::Function),
          mParametersVector(nullptr),
          mParameters(parameters),
          returnType(retType),
          mMangledName(nullptr),
          mParamCount(paramCount),
          mOp(op),
          defined(false),
          mHasPrototypeDeclaration(false),
          mKnownToNotHaveSideEffects(knownToNotHaveSideEffects),
          mHasVoidParameter(false)
    {}

  private:
    ImmutableString buildMangledName() const;

    typedef TVector<const TVariable *> TParamVector;
    TParamVector *mParametersVector;
    const TVariable *const *mParameters;
    const TType *const returnType;
    mutable ImmutableString mMangledName;
    size_t mParamCount : 32;
    const TOperator mOp;  // Only set for built-ins
    bool defined : 1;
    bool mHasPrototypeDeclaration : 1;
    bool mKnownToNotHaveSideEffects : 1;
    // Whether the parameter list of the function starts with void.  This is used to generate an
    // error if any other parameter follows.
    bool mHasVoidParameter : 1;
};

}  // namespace sh

#endif  // COMPILER_TRANSLATOR_SYMBOL_H_
