// // Change all function entries in the table with the non-mangled name // to be related to the provided built-in extension. This is a low // performance operation, and only intended for symbol tables that // live across a large number of compiles. // void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext) { for (tLevel::iterator it = level.begin(); it != level.end(); ++it) { TSymbol* symbol = it->second; if (symbol->getName() == name) symbol->relateToExtension(ext); } }
// Return a writable version of the variable 'name'. // // Return nullptr if 'name' is not found. This should mean // something is seriously wrong (e.g., compiler asking self for // built-in that doesn't exist). TVariable* TParseContextBase::getEditableVariable(const char* name) { bool builtIn; TSymbol* symbol = symbolTable.find(name, &builtIn); assert(symbol != nullptr); if (symbol == nullptr) return nullptr; if (builtIn) makeEditable(symbol); return symbol->getAsVariable(); }
// Make all function overloads of the given name require an extension(s). // Should only be used for a version/profile that actually needs the extension(s). void TSymbolTableLevel::setFunctionExtensions(const char* name, int num, const char* const extensions[]) { tLevel::const_iterator candidate = level.lower_bound(name); while (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) { TSymbol* symbol = candidate->second; symbol->setExtensions(num, extensions); } else break; ++candidate; } }
bool ValidateLimitations::validateFunctionCall(TIntermAggregate *node) { ASSERT(node->getOp() == EOpFunctionCall); // If not within loop body, there is nothing to check. if (!withinLoopBody()) return true; // List of param indices for which loop indices are used as argument. typedef std::vector<size_t> ParamIndex; ParamIndex pIndex; TIntermSequence *params = node->getSequence(); for (TIntermSequence::size_type i = 0; i < params->size(); ++i) { TIntermSymbol *symbol = (*params)[i]->getAsSymbolNode(); if (symbol && isLoopIndex(symbol)) pIndex.push_back(i); } // If none of the loop indices are used as arguments, // there is nothing to check. if (pIndex.empty()) return true; bool valid = true; TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable; TSymbol *symbol = symbolTable.find(node->getFunctionSymbolInfo()->getName(), GetGlobalParseContext()->getShaderVersion()); ASSERT(symbol && symbol->isFunction()); TFunction *function = static_cast<TFunction *>(symbol); for (ParamIndex::const_iterator i = pIndex.begin(); i != pIndex.end(); ++i) { const TConstParameter ¶m = function->getParam(*i); TQualifier qual = param.type->getQualifier(); if ((qual == EvqOut) || (qual == EvqInOut)) { error((*params)[*i]->getLine(), "Loop index cannot be used as argument to a function out or inout parameter", (*params)[*i]->getAsSymbolNode()->getSymbol().c_str()); valid = false; } } return valid; }
/* AddSymbol() - add a symbol to a symbol. * * Every symbol has an associated vector of zero or more other symbols. * nonterminal - vector of rule names * rule - vector of heterogenous production symbols * terminal - <empty> */ void TSymbolAtom::AddSymbol(TSymbol Symbol, TTokenIndex TokenId) { auto SymbolName = Symbol->Name(); printf("Add symbol '%s' to '%s'\n", Symbol->Name_.c_str(), Name_.c_str()); // either every symbol should be getting token IDs or none of them... // assert(Derives.size() == TokenIds.size() || TokenId < 0); Derives.push_back(Symbol); // if(TokenId >= 0) // TokenIds.push_back(TokenId); printf(" count(Derives) = %d\n", (int)Derives.size()); }
bool Halyard::operator==(const TSymbol &inS1, const TSymbol &inS2) { return inS1.GetName() == inS2.GetName(); }
// // Do all the semantic checking for declaring an array, with and // without a size, and make the right changes to the symbol table. // // size == 0 means no specified size. // // Returns true if there was an error. // bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable) { // // Don't check for reserved word use until after we know it's not in the symbol table, // because reserved arrays can be redeclared. // bool builtIn = false; bool sameScope = false; TSymbol* symbol = symbolTable.find(identifier, &builtIn, &sameScope); if (symbol == 0 || !sameScope) { if (reservedErrorCheck(line, identifier)) return true; variable = new TVariable(&identifier, TType(type)); if (type.arraySize) variable->getType().setArraySize(type.arraySize); if (! symbolTable.insert(*variable)) { delete variable; error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str(), ""); return true; } } else { if (! symbol->isVariable()) { error(line, "variable expected", identifier.c_str(), ""); return true; } variable = static_cast<TVariable*>(symbol); if (! variable->getType().isArray()) { error(line, "redeclaring non-array as array", identifier.c_str(), ""); return true; } if (variable->getType().getArraySize() > 0) { error(line, "redeclaration of array with size", identifier.c_str(), ""); return true; } if (! variable->getType().sameElementType(TType(type))) { error(line, "redeclaration of array with a different type", identifier.c_str(), ""); return true; } TType* t = variable->getArrayInformationType(); while (t != 0) { if (t->getMaxArraySize() > type.arraySize) { error(line, "higher index value already used for the array", identifier.c_str(), ""); return true; } t->setArraySize(type.arraySize); t = t->getArrayInformationType(); } if (type.arraySize) variable->getType().setArraySize(type.arraySize); } if (voidErrorCheck(line, identifier, type)) return true; return false; }
void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node) { bool visit = true; TIntermSequence *sequence = node->getSequence(); if (node->getOp() == EOpPrototype) { addToFunctionMap(node->getFunctionSymbolInfo()->getNameObj(), sequence); } if (preVisit) visit = visitAggregate(PreVisit, node); if (visit) { bool inFunctionMap = false; if (node->getOp() == EOpFunctionCall) { inFunctionMap = isInFunctionMap(node); if (!inFunctionMap) { // The function is not user-defined - it is likely built-in texture function. // Assume that those do not have out parameters. setInFunctionCallOutParameter(false); } } incrementDepth(node); if (inFunctionMap) { TIntermSequence *params = getFunctionParameters(node); TIntermSequence::iterator paramIter = params->begin(); for (auto *child : *sequence) { ASSERT(paramIter != params->end()); TQualifier qualifier = (*paramIter)->getAsTyped()->getQualifier(); setInFunctionCallOutParameter(qualifier == EvqOut || qualifier == EvqInOut); child->traverse(this); if (visit && inVisit) { if (child != sequence->back()) visit = visitAggregate(InVisit, node); } ++paramIter; } setInFunctionCallOutParameter(false); } else { // Find the built-in function corresponding to this op so that we can determine the // in/out qualifiers of its parameters. TFunction *builtInFunc = nullptr; TString opString = GetOperatorString(node->getOp()); if (!node->isConstructor() && !opString.empty()) { // The return type doesn't affect the mangled name of the function, which is used // to look it up from the symbol table. TType dummyReturnType; TFunction call(&opString, &dummyReturnType, node->getOp()); for (auto *child : *sequence) { TType *paramType = child->getAsTyped()->getTypePointer(); TConstParameter p(paramType); call.addParameter(p); } TSymbol *sym = mSymbolTable.findBuiltIn(call.getMangledName(), mShaderVersion); if (sym != nullptr && sym->isFunction()) { builtInFunc = static_cast<TFunction *>(sym); ASSERT(builtInFunc->getParamCount() == sequence->size()); } } size_t paramIndex = 0; for (auto *child : *sequence) { TQualifier qualifier = EvqIn; if (builtInFunc != nullptr) qualifier = builtInFunc->getParam(paramIndex).type->getQualifier(); setInFunctionCallOutParameter(qualifier == EvqOut || qualifier == EvqInOut); child->traverse(this); if (visit && inVisit) { if (child != sequence->back()) visit = visitAggregate(InVisit, node); } ++paramIndex; } setInFunctionCallOutParameter(false); } decrementDepth(); } if (visit && postVisit) visitAggregate(PostVisit, node); }
TRefSys::TRefSys(const TSymbol& symbol, ValueType value ) :TComplex(TSymbol{symbol.GetScope(), symbol.GetName(), TSymbol::TYPE_COMPLEX,TypeName()}) { MakeCommonValue(value); m_valueNames = { "a", "b", "c", "x", "y", "z" }; }
TBool::TBool(const TSymbol& symbol, ValueType value) :TVariate(TSymbol{ symbol.GetScope(), symbol.GetName(), TSymbol::BOOL,TypeName() }) , m_value(value) { }