//
// 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"
#include "nb/cpp14oncpp11.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);

    // 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; }
    TExtension extension() const { return mExtension; }

  protected:
    constexpr TSymbol(const TSymbolUniqueId &id,
                      const ImmutableString &name,
                      SymbolType symbolType,
                      TExtension extension,
                      SymbolClass symbolClass)
        : mName(name),
          mUniqueId(id),
          mSymbolType(symbolType),
          mExtension(extension),
          mSymbolClass(symbolClass)
    {}

    const ImmutableString mName;

  private:
    const TSymbolUniqueId mUniqueId;
    const SymbolType mSymbolType;
    const TExtension mExtension;

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

// 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);

    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, extension, 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);

    // 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 RegenerateStructNames;
    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);

    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);

    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 = type;
        name                   = nullptr;
        type                   = nullptr;
        return new TVariable(symbolTable, constName, constType,
                             constName.empty() ? SymbolType::Empty : SymbolType::UserDefined);
    }

    const char *name;  // either pool allocated or static.
    TType *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() { return defined; }
    void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; }
    bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; }

    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;
    bool hasSamplerInStructOrArrayParams() const;
    bool hasSamplerInStructOrArrayOfArrayParams() 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, extension, SymbolClass::Function),
          mParametersVector(nullptr),
          mParameters(parameters),
          mParamCount(paramCount),
          returnType(retType),
          mMangledName(nullptr),
          mOp(op),
          defined(false),
          mHasPrototypeDeclaration(false),
          mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
    {}

  private:
    ImmutableString buildMangledName() const;

    typedef TVector<const TVariable *> TParamVector;
    TParamVector *mParametersVector;
    const TVariable *const *mParameters;
    size_t mParamCount;
    const TType *const returnType;
    mutable ImmutableString mMangledName;
    const TOperator mOp;  // Only set for built-ins
    bool defined;
    bool mHasPrototypeDeclaration;
    bool mKnownToNotHaveSideEffects;
};

}  // namespace sh

#endif  // COMPILER_TRANSLATOR_SYMBOL_H_
