Commit e7d0752a by steve-lunarg

HLSL: use prefix for builtin functions names to avoid namespace collisions

It would have been possible for globally scoped user functions to collide with builtin method names. This adds a prefix to avoid polluting the namespace. Ideally this would be an invalid character to use in user identifiers, but as that requires changing the scanner, for the moment it's an unlikely yet valid prefix.
parent 4960baaf
...@@ -2785,11 +2785,13 @@ bool HlslGrammar::acceptFunctionCall(HlslToken callToken, TIntermTyped*& node, T ...@@ -2785,11 +2785,13 @@ bool HlslGrammar::acceptFunctionCall(HlslToken callToken, TIntermTyped*& node, T
{ {
// name // name
TString* functionName = nullptr; TString* functionName = nullptr;
if ((baseObject == nullptr && scope == nullptr) || if ((baseObject == nullptr && scope == nullptr)) {
parseContext.isBuiltInMethod(callToken.loc, baseObject, *callToken.string)) { functionName = callToken.string;
} else if (parseContext.isBuiltInMethod(callToken.loc, baseObject, *callToken.string)) {
// Built-in methods are not in the symbol table as methods, but as global functions // Built-in methods are not in the symbol table as methods, but as global functions
// taking an explicit 'this' as the first argument. // taking an explicit 'this' as the first argument.
functionName = callToken.string; functionName = NewPoolTString(BUILTIN_PREFIX);
functionName->append(*callToken.string);
} else { } else {
functionName = NewPoolTString(""); functionName = NewPoolTString("");
if (baseObject != nullptr) if (baseObject != nullptr)
......
...@@ -956,7 +956,7 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt ...@@ -956,7 +956,7 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
// Return true if the field should be treated as a built-in method. // Return true if the field should be treated as a built-in method.
// Return false otherwise. // Return false otherwise.
// //
bool HlslParseContext::isBuiltInMethod(const TSourceLoc& loc, TIntermTyped* base, const TString& field) bool HlslParseContext::isBuiltInMethod(const TSourceLoc&, TIntermTyped* base, const TString& field)
{ {
if (base == nullptr) if (base == nullptr)
return false; return false;
...@@ -3734,7 +3734,10 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct ...@@ -3734,7 +3734,10 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
// It will have false positives, since it doesn't check arg counts or types. // It will have false positives, since it doesn't check arg counts or types.
if (arguments && arguments->getAsAggregate()) { if (arguments && arguments->getAsAggregate()) {
if (isStructBufferType(arguments->getAsAggregate()->getSequence()[0]->getAsTyped()->getType())) { if (isStructBufferType(arguments->getAsAggregate()->getSequence()[0]->getAsTyped()->getType())) {
if (isStructBufferMethod(function->getName())) { static const int methodPrefixSize = sizeof(BUILTIN_PREFIX)-1;
if (function->getName().length() > methodPrefixSize &&
isStructBufferMethod(function->getName().substr(methodPrefixSize))) {
const TString mangle = function->getName() + "("; const TString mangle = function->getName() + "(";
TSymbol* symbol = symbolTable.find(mangle, &builtIn); TSymbol* symbol = symbolTable.find(mangle, &builtIn);
......
...@@ -390,6 +390,12 @@ protected: ...@@ -390,6 +390,12 @@ protected:
TVector<TString> currentTypePrefix; TVector<TString> currentTypePrefix;
}; };
// This is the prefix we use for builtin methods to avoid namespace collisions with
// global scope user functions.
// TODO: this would be better as a nonparseable character, but that would
// require changing the scanner.
#define BUILTIN_PREFIX "__BI_"
} // end namespace glslang } // end namespace glslang
#endif // HLSL_PARSE_INCLUDED_ #endif // HLSL_PARSE_INCLUDED_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment