Commit 8815d7f2 by alokp@chromium.org

Added support for associating functions with extensions and performing…

Added support for associating functions with extensions and performing validation when those functions are used in a shader. BUG=25 Review URL: http://codereview.appspot.com/2141046 git-svn-id: https://angleproject.googlecode.com/svn/trunk@415 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent b19403a1
......@@ -601,6 +601,10 @@ void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource
symbolTable.relateToOperator("dFdx", EOpDFdx);
symbolTable.relateToOperator("dFdy", EOpDFdy);
symbolTable.relateToOperator("fwidth", EOpFwidth);
symbolTable.relateToExtension("dFdx", "GL_OES_standard_derivatives");
symbolTable.relateToExtension("dFdy", "GL_OES_standard_derivatives");
symbolTable.relateToExtension("fwidth", "GL_OES_standard_derivatives");
}
break;
default: break;
......
......@@ -884,16 +884,22 @@ bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier p
return false;
}
bool TParseContext::extensionErrorCheck(int line, const char* extension)
{
if (extensionBehavior[extension] == EBhWarn) {
infoSink.info.message(EPrefixWarning, ("extension " + TString(extension) + " is being used").c_str(), line);
return false;
bool TParseContext::extensionErrorCheck(int line, const TString& extension)
{
TExtensionBehavior::const_iterator iter = extensionBehavior.find(extension);
if (iter == extensionBehavior.end()) {
error(line, "extension", extension.c_str(), "is not supported");
return true;
}
if (extensionBehavior[extension] == EBhDisable) {
error(line, "extension", extension, "is disabled");
if (iter->second == EBhDisable) {
error(line, "extension", extension.c_str(), "is disabled");
return true;
}
if (iter->second == EBhWarn) {
TString msg = "extension " + extension + " is being used";
infoSink.info.message(EPrefixWarning, msg.c_str(), line);
return false;
}
return false;
}
......
......@@ -79,7 +79,7 @@ struct TParseContext {
bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type);
bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type);
bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
bool extensionErrorCheck(int line, const char*);
bool extensionErrorCheck(int line, const TString&);
const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
......
......@@ -140,6 +140,22 @@ void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
}
}
//
// 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) {
if (it->second->isFunction()) {
TFunction* function = static_cast<TFunction*>(it->second);
if (function->getName() == name)
function->relateToExtension(ext);
}
}
}
TSymbol::TSymbol(const TSymbol& copyOf)
{
......
......@@ -156,8 +156,13 @@ public:
const TString& getMangledName() const { return mangledName; }
const TType& getReturnType() const { return returnType; }
void relateToOperator(TOperator o) { op = o; }
TOperator getBuiltInOp() const { return op; }
void relateToExtension(const TString& ext) { extension = ext; }
const TString& getExtension() const { return extension; }
void setDefined() { defined = true; }
bool isDefined() { return defined; }
......@@ -174,6 +179,7 @@ protected:
TType returnType;
TString mangledName;
TOperator op;
TString extension;
bool defined;
};
......@@ -220,6 +226,7 @@ public:
}
void relateToOperator(const char* name, TOperator op);
void relateToExtension(const char* name, const TString& ext);
void dump(TInfoSink &infoSink) const;
TSymbolTableLevel* clone(TStructureMap& remapper);
......@@ -288,8 +295,16 @@ public:
return symbol;
}
TSymbolTableLevel* getGlobalLevel() { assert(table.size() >= 2); return table[1]; }
void relateToOperator(const char* name, TOperator op) { table[0]->relateToOperator(name, op); }
TSymbolTableLevel* getGlobalLevel() {
assert(table.size() >= 2);
return table[1];
}
void relateToOperator(const char* name, TOperator op) {
table[0]->relateToOperator(name, op);
}
void relateToExtension(const char* name, const TString& ext) {
table[0]->relateToExtension(name, ext);
}
int getMaxSymbolId() { return uniqueId; }
void dump(TInfoSink &infoSink) const;
void copyTable(const TSymbolTable& copyOf);
......
......@@ -501,9 +501,12 @@ function_call
fnCandidate = parseContext->findFunction($1.line, fnCall, &builtIn);
if (fnCandidate) {
//
// A declared function. But, it might still map to a built-in
// operation.
// A declared function.
//
if (builtIn && !fnCandidate->getExtension().empty() &&
parseContext->extensionErrorCheck($1.line, fnCandidate->getExtension())) {
parseContext->recover();
}
op = fnCandidate->getBuiltInOp();
if (builtIn && op != EOpNull) {
//
......
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