//
// Copyright (c) 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.cpp: Symbols representing variables, functions, structures and interface blocks.
//

#if defined(_MSC_VER)
#    pragma warning(disable : 4718)
#endif

#include "compiler/translator/Symbol.h"

#include "compiler/translator/ImmutableStringBuilder.h"
#include "compiler/translator/SymbolTable.h"

namespace sh
{

namespace
{

constexpr const ImmutableString kMainName("main");
constexpr const ImmutableString kImageLoadName("imageLoad");
constexpr const ImmutableString kImageStoreName("imageStore");
constexpr const ImmutableString kImageSizeName("imageSize");
constexpr const ImmutableString kAtomicCounterName("atomicCounter");

static const char kFunctionMangledNameSeparator = '(';

}  // anonymous namespace

TSymbol::TSymbol(TSymbolTable *symbolTable,
                 const ImmutableString &name,
                 SymbolType symbolType,
                 SymbolClass symbolClass,
                 TExtension extension)
    : mName(name),
      mUniqueId(symbolTable->nextUniqueId()),
      mSymbolType(symbolType),
      mExtension(extension),
      mSymbolClass(symbolClass)
{
    ASSERT(mSymbolType == SymbolType::BuiltIn || mExtension == TExtension::UNDEFINED);
    ASSERT(mName != "" || mSymbolType == SymbolType::AngleInternal ||
           mSymbolType == SymbolType::Empty);
}

ImmutableString TSymbol::name() const
{
    if (!mName.empty())
    {
        return mName;
    }
    // This can be called for nameless function parameters in HLSL.
    ASSERT(mSymbolType == SymbolType::AngleInternal ||
           (mSymbolType == SymbolType::Empty && isVariable()));
    int uniqueId = mUniqueId.get();
    ImmutableStringBuilder symbolNameOut(sizeof(uniqueId) * 2u + 1u);
    symbolNameOut << 's';
    symbolNameOut.appendHex(mUniqueId.get());
    return symbolNameOut;
}

ImmutableString TSymbol::getMangledName() const
{
    if (mSymbolClass == SymbolClass::Function)
    {
        // We do this instead of using proper virtual functions so that we can better support
        // constexpr symbols.
        return static_cast<const TFunction *>(this)->getFunctionMangledName();
    }
    ASSERT(mSymbolType != SymbolType::Empty);
    return name();
}

TVariable::TVariable(TSymbolTable *symbolTable,
                     const ImmutableString &name,
                     const TType *type,
                     SymbolType symbolType,
                     TExtension extension)
    : TSymbol(symbolTable, name, symbolType, SymbolClass::Variable, extension),
      mType(type),
      unionArray(nullptr)
{
    ASSERT(mType);
    ASSERT(name.empty() || symbolType != SymbolType::Empty);
}

TStructure::TStructure(TSymbolTable *symbolTable,
                       const ImmutableString &name,
                       const TFieldList *fields,
                       SymbolType symbolType)
    : TSymbol(symbolTable, name, symbolType, SymbolClass::Struct), TFieldListCollection(fields)
{}

TStructure::TStructure(const TSymbolUniqueId &id,
                       const ImmutableString &name,
                       TExtension extension,
                       const TFieldList *fields)
    : TSymbol(id, name, SymbolType::BuiltIn, extension, SymbolClass::Struct),
      TFieldListCollection(fields)
{}

void TStructure::createSamplerSymbols(const char *namePrefix,
                                      const TString &apiNamePrefix,
                                      TVector<const TVariable *> *outputSymbols,
                                      TMap<const TVariable *, TString> *outputSymbolsToAPINames,
                                      TSymbolTable *symbolTable) const
{
    ASSERT(containsSamplers());
    for (const auto *field : *mFields)
    {
        const TType *fieldType = field->type();
        if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
        {
            std::stringstream fieldName = sh::InitializeStream<std::stringstream>();
            fieldName << namePrefix << "_" << field->name();
            TString fieldApiName = apiNamePrefix + ".";
            fieldApiName += field->name().data();
            fieldType->createSamplerSymbols(ImmutableString(fieldName.str()), fieldApiName,
                                            outputSymbols, outputSymbolsToAPINames, symbolTable);
        }
    }
}

void TStructure::setName(const ImmutableString &name)
{
    ImmutableString *mutableName = const_cast<ImmutableString *>(&mName);
    *mutableName                 = name;
}

TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
                                 const ImmutableString &name,
                                 const TFieldList *fields,
                                 const TLayoutQualifier &layoutQualifier,
                                 SymbolType symbolType,
                                 TExtension extension)
    : TSymbol(symbolTable, name, symbolType, SymbolClass::InterfaceBlock, extension),
      TFieldListCollection(fields),
      mBlockStorage(layoutQualifier.blockStorage),
      mBinding(layoutQualifier.binding)
{
    ASSERT(name != nullptr);
}

TInterfaceBlock::TInterfaceBlock(const TSymbolUniqueId &id,
                                 const ImmutableString &name,
                                 TExtension extension,
                                 const TFieldList *fields)
    : TSymbol(id, name, SymbolType::BuiltIn, extension, SymbolClass::InterfaceBlock),
      TFieldListCollection(fields),
      mBlockStorage(EbsUnspecified),
      mBinding(0)
{}

TFunction::TFunction(TSymbolTable *symbolTable,
                     const ImmutableString &name,
                     SymbolType symbolType,
                     const TType *retType,
                     bool knownToNotHaveSideEffects)
    : TSymbol(symbolTable, name, symbolType, SymbolClass::Function, TExtension::UNDEFINED),
      mParametersVector(new TParamVector()),
      mParameters(nullptr),
      mParamCount(0u),
      returnType(retType),
      mMangledName(""),
      mOp(EOpNull),
      defined(false),
      mHasPrototypeDeclaration(false),
      mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
{
    // Functions with an empty name are not allowed.
    ASSERT(symbolType != SymbolType::Empty);
    ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal);
}

void TFunction::addParameter(const TVariable *p)
{
    ASSERT(mParametersVector);
    mParametersVector->push_back(p);
    mParameters  = mParametersVector->data();
    mParamCount  = mParametersVector->size();
    mMangledName = kEmptyImmutableString;
}

void TFunction::shareParameters(const TFunction &parametersSource)
{
    mParametersVector = nullptr;
    mParameters       = parametersSource.mParameters;
    mParamCount       = parametersSource.mParamCount;
    ASSERT(parametersSource.name() == name());
    mMangledName = parametersSource.mMangledName;
}

ImmutableString TFunction::buildMangledName() const
{
    std::string newName(name().data(), name().length());
    newName += kFunctionMangledNameSeparator;

    for (size_t i = 0u; i < mParamCount; ++i)
    {
        newName += mParameters[i]->getType().getMangledName();
    }
    return ImmutableString(newName);
}

bool TFunction::isMain() const
{
    return symbolType() == SymbolType::UserDefined && name() == kMainName;
}

bool TFunction::isImageFunction() const
{
    return symbolType() == SymbolType::BuiltIn &&
           (name() == kImageSizeName || name() == kImageLoadName || name() == kImageStoreName);
}

bool TFunction::isAtomicCounterFunction() const
{
    return SymbolType() == SymbolType::BuiltIn && name().beginsWith(kAtomicCounterName);
}

bool TFunction::hasSamplerInStructParams() const
{
    for (size_t paramIndex = 0; paramIndex < mParamCount; ++paramIndex)
    {
        const TVariable *param = getParam(paramIndex);
        if (param->getType().isStructureContainingSamplers())
        {
            return true;
        }
    }

    return false;
}
}  // namespace sh
