//
// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
// Copyright (C) 2013 LunarG, Inc.
// Copyright (C) 2015-2018 Google, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//    Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
//    Redistributions in binary form must reproduce the above
//    copyright notice, this list of conditions and the following
//    disclaimer in the documentation and/or other materials provided
//    with the distribution.
//
//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//

#ifndef _SYMBOL_TABLE_INCLUDED_
#define _SYMBOL_TABLE_INCLUDED_

//
// Symbol table for parsing.  Has these design characteristics:
//
// * Same symbol table can be used to compile many shaders, to preserve
//   effort of creating and loading with the large numbers of built-in
//   symbols.
//
// -->  This requires a copy mechanism, so initial pools used to create
//   the shared information can be popped.  Done through "clone"
//   methods.
//
// * Name mangling will be used to give each function a unique name
//   so that symbol table lookups are never ambiguous.  This allows
//   a simpler symbol table structure.
//
// * Pushing and popping of scope, so symbol table will really be a stack
//   of symbol tables.  Searched from the top, with new inserts going into
//   the top.
//
// * Constants:  Compile time constant symbols will keep their values
//   in the symbol table.  The parser can substitute constants at parse
//   time, including doing constant folding and constant propagation.
//
// * No temporaries:  Temporaries made from operations (+, --, .xy, etc.)
//   are tracked in the intermediate representation, not the symbol table.
//

#include "../Include/Common.h"
#include "../Include/intermediate.h"
#include "../Include/InfoSink.h"

namespace glslang {

//
// Symbol base class.  (Can build functions or variables out of these...)
//

class TVariable;
class TFunction;
class TAnonMember;

typedef TVector<const char*> TExtensionList;

class TSymbol {
public:
    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
    explicit TSymbol(const TString *n) :  name(n), extensions(0), writable(true) { }
    virtual TSymbol* clone() const = 0;
    virtual ~TSymbol() { }  // rely on all symbol owned memory coming from the pool

    virtual const TString& getName() const { return *name; }
    virtual void changeName(const TString* newName) { name = newName; }
    virtual void addPrefix(const char* prefix)
    {
        TString newName(prefix);
        newName.append(*name);
        changeName(NewPoolTString(newName.c_str()));
    }
    virtual const TString& getMangledName() const { return getName(); }
    virtual TFunction* getAsFunction() { return 0; }
    virtual const TFunction* getAsFunction() const { return 0; }
    virtual TVariable* getAsVariable() { return 0; }
    virtual const TVariable* getAsVariable() const { return 0; }
    virtual const TAnonMember* getAsAnonMember() const { return 0; }
    virtual const TType& getType() const = 0;
    virtual TType& getWritableType() = 0;
    virtual void setUniqueId(long long id) { uniqueId = id; }
    virtual long long getUniqueId() const { return uniqueId; }
    virtual void setExtensions(int numExts, const char* const exts[])
    {
        assert(extensions == 0);
        assert(numExts > 0);
        extensions = NewPoolObject(extensions);
        for (int e = 0; e < numExts; ++e)
            extensions->push_back(exts[e]);
    }
    virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); }
    virtual const char** getExtensions() const { return extensions->data(); }

#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
    virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0;
    void dumpExtensions(TInfoSink& infoSink) const;
#endif

    virtual bool isReadOnly() const { return ! writable; }
    virtual void makeReadOnly() { writable = false; }

protected:
    explicit TSymbol(const TSymbol&);
    TSymbol& operator=(const TSymbol&);

    const TString *name;
    unsigned long long uniqueId;      // For cross-scope comparing during code generation

    // For tracking what extensions must be present
    // (don't use if correct version/profile is present).
    TExtensionList* extensions; // an array of pointers to existing constant char strings

    //
    // N.B.: Non-const functions that will be generally used should assert on this,
    // to avoid overwriting shared symbol-table information.
    //
    bool writable;
};

//
// Variable class, meaning a symbol that's not a function.
//
// There could be a separate class hierarchy for Constant variables;
// Only one of int, bool, or float, (or none) is correct for
// any particular use, but it's easy to do this way, and doesn't
// seem worth having separate classes, and "getConst" can't simply return
// different values for different types polymorphically, so this is
// just simple and pragmatic.
//
class TVariable : public TSymbol {
public:
    TVariable(const TString *name, const TType& t, bool uT = false )
        : TSymbol(name),
          userType(uT),
          constSubtree(nullptr),
          memberExtensions(nullptr),
          anonId(-1)
        { type.shallowCopy(t); }
    virtual TVariable* clone() const;
    virtual ~TVariable() { }

    virtual TVariable* getAsVariable() { return this; }
    virtual const TVariable* getAsVariable() const { return this; }
    virtual const TType& getType() const { return type; }
    virtual TType& getWritableType() { assert(writable); return type; }
    virtual bool isUserType() const { return userType; }
    virtual const TConstUnionArray& getConstArray() const { return constArray; }
    virtual TConstUnionArray& getWritableConstArray() { assert(writable); return constArray; }
    virtual void setConstArray(const TConstUnionArray& array) { constArray = array; }
    virtual void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
    virtual TIntermTyped* getConstSubtree() const { return constSubtree; }
    virtual void setAnonId(int i) { anonId = i; }
    virtual int getAnonId() const { return anonId; }

    virtual void setMemberExtensions(int member, int numExts, const char* const exts[])
    {
        assert(type.isStruct());
        assert(numExts > 0);
        if (memberExtensions == nullptr) {
            memberExtensions = NewPoolObject(memberExtensions);
            memberExtensions->resize(type.getStruct()->size());
        }
        for (int e = 0; e < numExts; ++e)
            (*memberExtensions)[member].push_back(exts[e]);
    }
    virtual bool hasMemberExtensions() const { return memberExtensions != nullptr; }
    virtual int getNumMemberExtensions(int member) const 
    {
        return memberExtensions == nullptr ? 0 : (int)(*memberExtensions)[member].size();
    }
    virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); }

#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
    virtual void dump(TInfoSink& infoSink, bool complete = false) const;
#endif

protected:
    explicit TVariable(const TVariable&);
    TVariable& operator=(const TVariable&);

    TType type;
    bool userType;

    // we are assuming that Pool Allocator will free the memory allocated to unionArray
    // when this object is destroyed

    TConstUnionArray constArray;               // for compile-time constant value
    TIntermTyped* constSubtree;                // for specialization constant computation
    TVector<TExtensionList>* memberExtensions; // per-member extension list, allocated only when needed
    int anonId; // the ID used for anonymous blocks: TODO: see if uniqueId could serve a dual purpose
};

//
// The function sub-class of symbols and the parser will need to
// share this definition of a function parameter.
//
struct TParameter {
    TString *name;
    TType* type;
    TIntermTyped* defaultValue;
    void copyParam(const TParameter& param)
    {
        if (param.name)
            name = NewPoolTString(param.name->c_str());
        else
            name = 0;
        type = param.type->clone();
        defaultValue = param.defaultValue;
    }
    TBuiltInVariable getDeclaredBuiltIn() const { return type->getQualifier().declaredBuiltIn; }
};

//
// The function sub-class of a symbol.
//
class TFunction : public TSymbol {
public:
    explicit TFunction(TOperator o) :
        TSymbol(0),
        op(o),
        defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0) { }
    TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
        TSymbol(name),
        mangledName(*name + '('),
        op(tOp),
        defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0)
    {
        returnType.shallowCopy(retType);
        declaredBuiltIn = retType.getQualifier().builtIn;
    }
    virtual TFunction* clone() const override;
    virtual ~TFunction();

    virtual TFunction* getAsFunction() override { return this; }
    virtual const TFunction* getAsFunction() const override { return this; }

    // Install 'p' as the (non-'this') last parameter.
    // Non-'this' parameters are reflected in both the list of parameters and the
    // mangled name.
    virtual void addParameter(TParameter& p)
    {
        assert(writable);
        parameters.push_back(p);
        p.type->appendMangledName(mangledName);

        if (p.defaultValue != nullptr)
            defaultParamCount++;
    }

    // Install 'this' as the first parameter.
    // 'this' is reflected in the list of parameters, but not the mangled name.
    virtual void addThisParameter(TType& type, const char* name)
    {
        TParameter p = { NewPoolTString(name), new TType, nullptr };
        p.type->shallowCopy(type);
        parameters.insert(parameters.begin(), p);
    }

    virtual void addPrefix(const char* prefix) override
    {
        TSymbol::addPrefix(prefix);
        mangledName.insert(0, prefix);
    }

    virtual void removePrefix(const TString& prefix)
    {
        assert(mangledName.compare(0, prefix.size(), prefix) == 0);
        mangledName.erase(0, prefix.size());
    }

    virtual const TString& getMangledName() const override { return mangledName; }
    virtual const TType& getType() const override { return returnType; }
    virtual TBuiltInVariable getDeclaredBuiltInType() const { return declaredBuiltIn; }
    virtual TType& getWritableType() override { return returnType; }
    virtual void relateToOperator(TOperator o) { assert(writable); op = o; }
    virtual TOperator getBuiltInOp() const { return op; }
    virtual void setDefined() { assert(writable); defined = true; }
    virtual bool isDefined() const { return defined; }
    virtual void setPrototyped() { assert(writable); prototyped = true; }
    virtual bool isPrototyped() const { return prototyped; }
    virtual void setImplicitThis() { assert(writable); implicitThis = true; }
    virtual bool hasImplicitThis() const { return implicitThis; }
    virtual void setIllegalImplicitThis() { assert(writable); illegalImplicitThis = true; }
    virtual bool hasIllegalImplicitThis() const { return illegalImplicitThis; }

    // Return total number of parameters
    virtual int getParamCount() const { return static_cast<int>(parameters.size()); }
    // Return number of parameters with default values.
    virtual int getDefaultParamCount() const { return defaultParamCount; }
    // Return number of fixed parameters (without default values)
    virtual int getFixedParamCount() const { return getParamCount() - getDefaultParamCount(); }

    virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
    virtual const TParameter& operator[](int i) const { return parameters[i]; }

#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
    virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
#endif

protected:
    explicit TFunction(const TFunction&);
    TFunction& operator=(const TFunction&);

    typedef TVector<TParameter> TParamList;
    TParamList parameters;
    TType returnType;
    TBuiltInVariable declaredBuiltIn;

    TString mangledName;
    TOperator op;
    bool defined;
    bool prototyped;
    bool implicitThis;         // True if this function is allowed to see all members of 'this'
    bool illegalImplicitThis;  // True if this function is not supposed to have access to dynamic members of 'this',
                               // even if it finds member variables in the symbol table.
                               // This is important for a static member function that has member variables in scope,
                               // but is not allowed to use them, or see hidden symbols instead.
    int  defaultParamCount;
};

//
// Members of anonymous blocks are a kind of TSymbol.  They are not hidden in
// the symbol table behind a container; rather they are visible and point to
// their anonymous container.  (The anonymous container is found through the
// member, not the other way around.)
//
class TAnonMember : public TSymbol {
public:
    TAnonMember(const TString* n, unsigned int m, TVariable& a, int an) : TSymbol(n), anonContainer(a), memberNumber(m), anonId(an) { }
    virtual TAnonMember* clone() const override;
    virtual ~TAnonMember() { }

    virtual const TAnonMember* getAsAnonMember() const override { return this; }
    virtual const TVariable& getAnonContainer() const { return anonContainer; }
    virtual unsigned int getMemberNumber() const { return memberNumber; }

    virtual const TType& getType() const override
    {
        const TTypeList& types = *anonContainer.getType().getStruct();
        return *types[memberNumber].type;
    }

    virtual TType& getWritableType() override
    {
        assert(writable);
        const TTypeList& types = *anonContainer.getType().getStruct();
        return *types[memberNumber].type;
    }

    virtual void setExtensions(int numExts, const char* const exts[]) override
    {
        anonContainer.setMemberExtensions(memberNumber, numExts, exts);
    }
    virtual int getNumExtensions() const override { return anonContainer.getNumMemberExtensions(memberNumber); }
    virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); }

    virtual int getAnonId() const { return anonId; }
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
    virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
#endif

protected:
    explicit TAnonMember(const TAnonMember&);
    TAnonMember& operator=(const TAnonMember&);

    TVariable& anonContainer;
    unsigned int memberNumber;
    int anonId;
};

class TSymbolTableLevel {
public:
    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
    TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { }
    ~TSymbolTableLevel();

    bool insert(TSymbol& symbol, bool separateNameSpaces)
    {
        //
        // returning true means symbol was added to the table with no semantic errors
        //
        const TString& name = symbol.getName();
        if (name == "") {
            symbol.getAsVariable()->setAnonId(anonId++);
            // An empty name means an anonymous container, exposing its members to the external scope.
            // Give it a name and insert its members in the symbol table, pointing to the container.
            char buf[20];
            snprintf(buf, 20, "%s%d", AnonymousPrefix, symbol.getAsVariable()->getAnonId());
            symbol.changeName(NewPoolTString(buf));

            return insertAnonymousMembers(symbol, 0);
        } else {
            // Check for redefinition errors:
            // - STL itself will tell us if there is a direct name collision, with name mangling, at this level
            // - additionally, check for function-redefining-variable name collisions
            const TString& insertName = symbol.getMangledName();
            if (symbol.getAsFunction()) {
                // make sure there isn't a variable of this name
                if (! separateNameSpaces && level.find(name) != level.end())
                    return false;

                // insert, and whatever happens is okay
                level.insert(tLevelPair(insertName, &symbol));

                return true;
            } else
                return level.insert(tLevelPair(insertName, &symbol)).second;
        }
    }

    // Add more members to an already inserted aggregate object
    bool amend(TSymbol& symbol, int firstNewMember)
    {
        // See insert() for comments on basic explanation of insert.
        // This operates similarly, but more simply.
        // Only supporting amend of anonymous blocks so far.
        if (IsAnonymous(symbol.getName()))
            return insertAnonymousMembers(symbol, firstNewMember);
        else
            return false;
    }

    bool insertAnonymousMembers(TSymbol& symbol, int firstMember)
    {
        const TTypeList& types = *symbol.getAsVariable()->getType().getStruct();
        for (unsigned int m = firstMember; m < types.size(); ++m) {
            TAnonMember* member = new TAnonMember(&types[m].type->getFieldName(), m, *symbol.getAsVariable(), symbol.getAsVariable()->getAnonId());
            if (! level.insert(tLevelPair(member->getMangledName(), member)).second)
                return false;
        }

        return true;
    }

    TSymbol* find(const TString& name) const
    {
        tLevel::const_iterator it = level.find(name);
        if (it == level.end())
            return 0;
        else
            return (*it).second;
    }

    void findFunctionNameList(const TString& name, TVector<const TFunction*>& list)
    {
        size_t parenAt = name.find_first_of('(');
        TString base(name, 0, parenAt + 1);

        tLevel::const_iterator begin = level.lower_bound(base);
        base[parenAt] = ')';  // assume ')' is lexically after '('
        tLevel::const_iterator end = level.upper_bound(base);
        for (tLevel::const_iterator it = begin; it != end; ++it)
            list.push_back(it->second->getAsFunction());
    }

    // See if there is already a function in the table having the given non-function-style name.
    bool hasFunctionName(const TString& name) const
    {
        tLevel::const_iterator candidate = level.lower_bound(name);
        if (candidate != level.end()) {
            const TString& candidateName = (*candidate).first;
            TString::size_type parenAt = candidateName.find_first_of('(');
            if (parenAt != candidateName.npos && candidateName.compare(0, parenAt, name) == 0)

                return true;
        }

        return false;
    }

    // See if there is a variable at this level having the given non-function-style name.
    // Return true if name is found, and set variable to true if the name was a variable.
    bool findFunctionVariableName(const TString& name, bool& variable) const
    {
        tLevel::const_iterator candidate = level.lower_bound(name);
        if (candidate != level.end()) {
            const TString& candidateName = (*candidate).first;
            TString::size_type parenAt = candidateName.find_first_of('(');
            if (parenAt == candidateName.npos) {
                // not a mangled name
                if (candidateName == name) {
                    // found a variable name match
                    variable = true;
                    return true;
                }
            } else {
                // a mangled name
                if (candidateName.compare(0, parenAt, name) == 0) {
                    // found a function name match
                    variable = false;
                    return true;
                }
            }
        }

        return false;
    }

    // Use this to do a lazy 'push' of precision defaults the first time
    // a precision statement is seen in a new scope.  Leave it at 0 for
    // when no push was needed.  Thus, it is not the current defaults,
    // it is what to restore the defaults to when popping a level.
    void setPreviousDefaultPrecisions(const TPrecisionQualifier *p)
    {
        // can call multiple times at one scope, will only latch on first call,
        // as we're tracking the previous scope's values, not the current values
        if (defaultPrecision != 0)
            return;

        defaultPrecision = new TPrecisionQualifier[EbtNumTypes];
        for (int t = 0; t < EbtNumTypes; ++t)
            defaultPrecision[t] = p[t];
    }

    void getPreviousDefaultPrecisions(TPrecisionQualifier *p)
    {
        // can be called for table level pops that didn't set the
        // defaults
        if (defaultPrecision == 0 || p == 0)
            return;

        for (int t = 0; t < EbtNumTypes; ++t)
            p[t] = defaultPrecision[t];
    }

    void relateToOperator(const char* name, TOperator op);
    void setFunctionExtensions(const char* name, int num, const char* const extensions[]);
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
    void dump(TInfoSink& infoSink, bool complete = false) const;
#endif
    TSymbolTableLevel* clone() const;
    void readOnly();

    void setThisLevel() { thisLevel = true; }
    bool isThisLevel() const { return thisLevel; }

protected:
    explicit TSymbolTableLevel(TSymbolTableLevel&);
    TSymbolTableLevel& operator=(TSymbolTableLevel&);

    typedef std::map<TString, TSymbol*, std::less<TString>, pool_allocator<std::pair<const TString, TSymbol*> > > tLevel;
    typedef const tLevel::value_type tLevelPair;
    typedef std::pair<tLevel::iterator, bool> tInsertResult;

    tLevel level;  // named mappings
    TPrecisionQualifier *defaultPrecision;
    int anonId;
    bool thisLevel;  // True if this level of the symbol table is a structure scope containing member function
                     // that are supposed to see anonymous access to member variables.
};

class TSymbolTable {
public:
    TSymbolTable() : uniqueId(0), noBuiltInRedeclarations(false), separateNameSpaces(false), adoptedLevels(0)
    {
        //
        // This symbol table cannot be used until push() is called.
        //
    }
    ~TSymbolTable()
    {
        // this can be called explicitly; safest to code it so it can be called multiple times

        // don't deallocate levels passed in from elsewhere
        while (table.size() > adoptedLevels)
            pop(0);
    }

    void adoptLevels(TSymbolTable& symTable)
    {
        for (unsigned int level = 0; level < symTable.table.size(); ++level) {
            table.push_back(symTable.table[level]);
            ++adoptedLevels;
        }
        uniqueId = symTable.uniqueId;
        noBuiltInRedeclarations = symTable.noBuiltInRedeclarations;
        separateNameSpaces = symTable.separateNameSpaces;
    }

    //
    // While level adopting is generic, the methods below enact a the following
    // convention for levels:
    //   0: common built-ins shared across all stages, all compiles, only one copy for all symbol tables
    //   1: per-stage built-ins, shared across all compiles, but a different copy per stage
    //   2: built-ins specific to a compile, like resources that are context-dependent, or redeclared built-ins
    //   3: user-shader globals
    //
protected:
    static const uint32_t LevelFlagBitOffset = 56;
    static const int globalLevel = 3;
    static bool isSharedLevel(int level)  { return level <= 1; }            // exclude all per-compile levels
    static bool isBuiltInLevel(int level) { return level <= 2; }            // exclude user globals
    static bool isGlobalLevel(int level)  { return level <= globalLevel; }  // include user globals
public:
    bool isEmpty() { return table.size() == 0; }
    bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); }
    bool atGlobalLevel()  { return isGlobalLevel(currentLevel()); }
    static bool isBuiltInSymbol(long long uniqueId) {
        int level = static_cast<int>(uniqueId >> LevelFlagBitOffset);
        return isBuiltInLevel(level);
    }
    static constexpr uint64_t uniqueIdMask = (1LL << LevelFlagBitOffset) - 1;
    static const uint32_t MaxLevelInUniqueID = 127;
    void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; }
    void setSeparateNameSpaces() { separateNameSpaces = true; }

    void push()
    {
        table.push_back(new TSymbolTableLevel);
        updateUniqueIdLevelFlag();
    }

    // Make a new symbol-table level to represent the scope introduced by a structure
    // containing member functions, such that the member functions can find anonymous
    // references to member variables.
    //
    // 'thisSymbol' should have a name of "" to trigger anonymous structure-member
    // symbol finds.
    void pushThis(TSymbol& thisSymbol)
    {
        assert(thisSymbol.getName().size() == 0);
        table.push_back(new TSymbolTableLevel);
        updateUniqueIdLevelFlag();
        table.back()->setThisLevel();
        insert(thisSymbol);
    }

    void pop(TPrecisionQualifier *p)
    {
        table[currentLevel()]->getPreviousDefaultPrecisions(p);
        delete table.back();
        table.pop_back();
        updateUniqueIdLevelFlag();
    }

    //
    // Insert a visible symbol into the symbol table so it can
    // be found later by name.
    //
    // Returns false if the was a name collision.
    //
    bool insert(TSymbol& symbol)
    {
        symbol.setUniqueId(++uniqueId);

        // make sure there isn't a function of this variable name
        if (! separateNameSpaces && ! symbol.getAsFunction() && table[currentLevel()]->hasFunctionName(symbol.getName()))
            return false;

        // check for not overloading or redefining a built-in function
        if (noBuiltInRedeclarations) {
            if (atGlobalLevel() && currentLevel() > 0) {
                if (table[0]->hasFunctionName(symbol.getName()))
                    return false;
                if (currentLevel() > 1 && table[1]->hasFunctionName(symbol.getName()))
                    return false;
            }
        }

        return table[currentLevel()]->insert(symbol, separateNameSpaces);
    }

    // Add more members to an already inserted aggregate object
    bool amend(TSymbol& symbol, int firstNewMember)
    {
        // See insert() for comments on basic explanation of insert.
        // This operates similarly, but more simply.
        return table[currentLevel()]->amend(symbol, firstNewMember);
    }

    // Update the level info in symbol's unique ID to current level
    void amendSymbolIdLevel(TSymbol& symbol)
    {
        // clamp level to avoid overflow
        uint64_t level = currentLevel() > MaxLevelInUniqueID ? MaxLevelInUniqueID : currentLevel();
        uint64_t symbolId = symbol.getUniqueId();
        symbolId &= uniqueIdMask;
        symbolId |= (level << LevelFlagBitOffset);
        symbol.setUniqueId(symbolId);
    }
    //
    // To allocate an internal temporary, which will need to be uniquely
    // identified by the consumer of the AST, but never need to
    // found by doing a symbol table search by name, hence allowed an
    // arbitrary name in the symbol with no worry of collision.
    //
    void makeInternalVariable(TSymbol& symbol)
    {
        symbol.setUniqueId(++uniqueId);
    }

    //
    // Copy a variable or anonymous member's structure from a shared level so that
    // it can be added (soon after return) to the symbol table where it can be
    // modified without impacting other users of the shared table.
    //
    TSymbol* copyUpDeferredInsert(TSymbol* shared)
    {
        if (shared->getAsVariable()) {
            TSymbol* copy = shared->clone();
            copy->setUniqueId(shared->getUniqueId());
            return copy;
        } else {
            const TAnonMember* anon = shared->getAsAnonMember();
            assert(anon);
            TVariable* container = anon->getAnonContainer().clone();
            container->changeName(NewPoolTString(""));
            container->setUniqueId(anon->getAnonContainer().getUniqueId());
            return container;
        }
    }

    TSymbol* copyUp(TSymbol* shared)
    {
        TSymbol* copy = copyUpDeferredInsert(shared);
        table[globalLevel]->insert(*copy, separateNameSpaces);
        if (shared->getAsVariable())
            return copy;
        else {
            // return the copy of the anonymous member
            return table[globalLevel]->find(shared->getName());
        }
    }

    // Normal find of a symbol, that can optionally say whether the symbol was found
    // at a built-in level or the current top-scope level.
    TSymbol* find(const TString& name, bool* builtIn = 0, bool* currentScope = 0, int* thisDepthP = 0)
    {
        int level = currentLevel();
        TSymbol* symbol;
        int thisDepth = 0;
        do {
            if (table[level]->isThisLevel())
                ++thisDepth;
            symbol = table[level]->find(name);
            --level;
        } while (symbol == nullptr && level >= 0);
        level++;
        if (builtIn)
            *builtIn = isBuiltInLevel(level);
        if (currentScope)
            *currentScope = isGlobalLevel(currentLevel()) || level == currentLevel();  // consider shared levels as "current scope" WRT user globals
        if (thisDepthP != nullptr) {
            if (! table[level]->isThisLevel())
                thisDepth = 0;
            *thisDepthP = thisDepth;
        }

        return symbol;
    }

    // Find of a symbol that returns how many layers deep of nested
    // structures-with-member-functions ('this' scopes) deep the symbol was
    // found in.
    TSymbol* find(const TString& name, int& thisDepth)
    {
        int level = currentLevel();
        TSymbol* symbol;
        thisDepth = 0;
        do {
            if (table[level]->isThisLevel())
                ++thisDepth;
            symbol = table[level]->find(name);
            --level;
        } while (symbol == 0 && level >= 0);

        if (! table[level + 1]->isThisLevel())
            thisDepth = 0;

        return symbol;
    }

    bool isFunctionNameVariable(const TString& name) const
    {
        if (separateNameSpaces)
            return false;

        int level = currentLevel();
        do {
            bool variable;
            bool found = table[level]->findFunctionVariableName(name, variable);
            if (found)
                return variable;
            --level;
        } while (level >= 0);

        return false;
    }

    void findFunctionNameList(const TString& name, TVector<const TFunction*>& list, bool& builtIn)
    {
        // For user levels, return the set found in the first scope with a match
        builtIn = false;
        int level = currentLevel();
        do {
            table[level]->findFunctionNameList(name, list);
            --level;
        } while (list.empty() && level >= globalLevel);

        if (! list.empty())
            return;

        // Gather across all built-in levels; they don't hide each other
        builtIn = true;
        do {
            table[level]->findFunctionNameList(name, list);
            --level;
        } while (level >= 0);
    }

    void relateToOperator(const char* name, TOperator op)
    {
        for (unsigned int level = 0; level < table.size(); ++level)
            table[level]->relateToOperator(name, op);
    }

    void setFunctionExtensions(const char* name, int num, const char* const extensions[])
    {
        for (unsigned int level = 0; level < table.size(); ++level)
            table[level]->setFunctionExtensions(name, num, extensions);
    }

    void setVariableExtensions(const char* name, int numExts, const char* const extensions[])
    {
        TSymbol* symbol = find(TString(name));
        if (symbol == nullptr)
            return;

        symbol->setExtensions(numExts, extensions);
    }

    void setVariableExtensions(const char* blockName, const char* name, int numExts, const char* const extensions[])
    {
        TSymbol* symbol = find(TString(blockName));
        if (symbol == nullptr)
            return;
        TVariable* variable = symbol->getAsVariable();
        assert(variable != nullptr);

        const TTypeList& structure = *variable->getAsVariable()->getType().getStruct();
        for (int member = 0; member < (int)structure.size(); ++member) {
            if (structure[member].type->getFieldName().compare(name) == 0) {
                variable->setMemberExtensions(member, numExts, extensions);
                return;
            }
        }
    }

    long long getMaxSymbolId() { return uniqueId; }
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
    void dump(TInfoSink& infoSink, bool complete = false) const;
#endif
    void copyTable(const TSymbolTable& copyOf);

    void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); }

    void readOnly()
    {
        for (unsigned int level = 0; level < table.size(); ++level)
            table[level]->readOnly();
    }

    // Add current level in the high-bits of unique id
    void updateUniqueIdLevelFlag() {
        // clamp level to avoid overflow
        uint64_t level = currentLevel() > MaxLevelInUniqueID ? MaxLevelInUniqueID : currentLevel();
        uniqueId &= uniqueIdMask;
        uniqueId |= (level << LevelFlagBitOffset);
    }

    void overwriteUniqueId(long long id)
    {
        uniqueId = id;
        updateUniqueIdLevelFlag();
    }

protected:
    TSymbolTable(TSymbolTable&);
    TSymbolTable& operator=(TSymbolTableLevel&);

    int currentLevel() const { return static_cast<int>(table.size()) - 1; }
    std::vector<TSymbolTableLevel*> table;
    long long uniqueId;     // for unique identification in code generation
    bool noBuiltInRedeclarations;
    bool separateNameSpaces;
    unsigned int adoptedLevels;
};

} // end namespace glslang

#endif // _SYMBOL_TABLE_INCLUDED_
