Commit 6c0c2987 by Jamie Madill

Make TParseContext a class, with private data.

BUG=angleproject:995 Change-Id: Ie077e3a4f0fd5ef840aa35edeb41d15a98b7c0ff Reviewed-on: https://chromium-review.googlesource.com/270628Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 06145236
......@@ -202,7 +202,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[],
shaderType, shaderSpec, compileOptions, true,
infoSink, debugShaderPrecision);
parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
parseContext.setFragmentPrecisionHigh(fragmentPrecisionHigh);
SetGlobalParseContext(&parseContext);
// We preserve symbols at the built-in level from compile-to-compile.
......@@ -211,8 +211,8 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[],
// Parse shader.
bool success =
(PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) &&
(parseContext.treeRoot != NULL);
(PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr, &parseContext) == 0) &&
(parseContext.getTreeRoot() != nullptr);
shaderVersion = parseContext.getShaderVersion();
if (success && MapSpecToShaderVersion(shaderSpec) < shaderVersion)
......@@ -222,7 +222,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[],
success = false;
}
TIntermNode *root = NULL;
TIntermNode *root = nullptr;
if (success)
{
......@@ -232,7 +232,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[],
symbolTable.setGlobalInvariant();
}
root = parseContext.treeRoot;
root = parseContext.getTreeRoot();
success = intermediate.postProcess(root);
// Disallow expressions deemed too complex.
......
......@@ -10,7 +10,7 @@
bool InitializeParseContextIndex();
void FreeParseContextIndex();
struct TParseContext;
class TParseContext;
extern void SetGlobalParseContext(TParseContext* context);
extern TParseContext* GetGlobalParseContext();
......
......@@ -25,8 +25,9 @@ struct TMatrixFields
// The following are extra variables needed during parsing, grouped together so
// they can be passed to the parser without needing a global.
//
struct TParseContext : angle::NonCopyable
class TParseContext : angle::NonCopyable
{
public:
TParseContext(TSymbolTable &symt,
TExtensionBehavior &ext,
TIntermediate &interm,
......@@ -38,58 +39,73 @@ struct TParseContext : angle::NonCopyable
bool debugShaderPrecisionSupported)
: intermediate(interm),
symbolTable(symt),
shaderType(type),
shaderSpec(spec),
compileOptions(options),
treeRoot(nullptr),
mShaderType(type),
mShaderSpec(spec),
mCompileOptions(options),
mTreeRoot(nullptr),
mLoopNestingLevel(0),
structNestingLevel(0),
mStructNestingLevel(0),
mSwitchNestingLevel(0),
currentFunctionType(nullptr),
mCurrentFunctionType(nullptr),
mFunctionReturnsValue(false),
checksPrecisionErrors(checksPrecErrors),
fragmentPrecisionHigh(false),
defaultMatrixPacking(EmpColumnMajor),
defaultBlockStorage(EbsShared),
diagnostics(is),
shaderVersion(100),
directiveHandler(ext, diagnostics, shaderVersion, debugShaderPrecisionSupported),
preprocessor(&diagnostics, &directiveHandler),
scanner(nullptr),
mChecksPrecisionErrors(checksPrecErrors),
mFragmentPrecisionHigh(false),
mDefaultMatrixPacking(EmpColumnMajor),
mDefaultBlockStorage(EbsShared),
mDiagnostics(is),
mShaderVersion(100),
mDirectiveHandler(ext, mDiagnostics, mShaderVersion, debugShaderPrecisionSupported),
mPreprocessor(&mDiagnostics, &mDirectiveHandler),
mScanner(nullptr),
mDeferredSingleDeclarationErrorCheck(false)
{
}
TIntermediate &intermediate; // to hold and build a parse tree
TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed
sh::GLenum shaderType; // vertex or fragment language (future: pack or unpack)
ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
int shaderVersion;
int compileOptions;
TIntermNode *treeRoot; // root of parse tree being created
int mLoopNestingLevel; // 0 if outside all loops
int structNestingLevel; // incremented while parsing a struct declaration
int mSwitchNestingLevel; // 0 if outside all switch statements
const TType *currentFunctionType; // the return type of the function that's currently being parsed
bool mFunctionReturnsValue; // true if a non-void function has a return
bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
bool fragmentPrecisionHigh; // true if highp precision is supported in the fragment language.
TLayoutMatrixPacking defaultMatrixPacking;
TLayoutBlockStorage defaultBlockStorage;
TString HashErrMsg;
TDiagnostics diagnostics;
TDirectiveHandler directiveHandler;
pp::Preprocessor preprocessor;
void *scanner;
int getShaderVersion() const { return shaderVersion; }
int numErrors() const { return diagnostics.numErrors(); }
TInfoSink &infoSink() { return diagnostics.infoSink(); }
const pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
pp::Preprocessor &getPreprocessor() { return mPreprocessor; }
void *getScanner() const { return mScanner; }
void setScanner(void *scanner) { mScanner = scanner; }
int getShaderVersion() const { return mShaderVersion; }
sh::GLenum getShaderType() const { return mShaderType; }
ShShaderSpec getShaderSpec() const { return mShaderSpec; }
int numErrors() const { return mDiagnostics.numErrors(); }
TInfoSink &infoSink() { return mDiagnostics.infoSink(); }
void error(const TSourceLoc &loc, const char *reason, const char *token,
const char *extraInfo="");
void warning(const TSourceLoc &loc, const char *reason, const char *token,
const char *extraInfo="");
void recover();
TIntermNode *getTreeRoot() const { return mTreeRoot; }
void setTreeRoot(TIntermNode *treeRoot) { mTreeRoot = treeRoot; }
bool getFragmentPrecisionHigh() const { return mFragmentPrecisionHigh; }
void setFragmentPrecisionHigh(bool fragmentPrecisionHigh)
{
mFragmentPrecisionHigh = fragmentPrecisionHigh;
}
bool getFunctionReturnsValue() const { return mFunctionReturnsValue; }
void setFunctionReturnsValue(bool functionReturnsValue)
{
mFunctionReturnsValue = functionReturnsValue;
}
void setLoopNestingLevel(int loopNestintLevel)
{
mLoopNestingLevel = loopNestintLevel;
}
const TType *getCurrentFunctionType() const { return mCurrentFunctionType; }
void setCurrentFunctionType(const TType *currentFunctionType)
{
mCurrentFunctionType = currentFunctionType;
}
void incrLoopNestingLevel() { ++mLoopNestingLevel; }
void decrLoopNestingLevel() { --mLoopNestingLevel; }
void incrSwitchNestingLevel() { ++mSwitchNestingLevel; }
void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
// This method is guaranteed to succeed, even if no variable with 'name' exists.
const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol);
......@@ -123,8 +139,8 @@ struct TParseContext : angle::NonCopyable
bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
void es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation);
const TPragma &pragma() const { return directiveHandler.pragma(); }
const TExtensionBehavior &extensionBehavior() const { return directiveHandler.extensionBehavior(); }
const TPragma &pragma() const { return mDirectiveHandler.pragma(); }
const TExtensionBehavior &extensionBehavior() const { return mDirectiveHandler.extensionBehavior(); }
bool supportsExtension(const char *extension);
bool isExtensionEnabled(const char *extension) const;
void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior);
......@@ -281,6 +297,10 @@ struct TParseContext : angle::NonCopyable
TIntermTyped *addTernarySelection(
TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &line);
// TODO(jmadill): make these private
TIntermediate &intermediate; // to hold and build a parse tree
TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed
private:
bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable);
......@@ -301,6 +321,26 @@ struct TParseContext : angle::NonCopyable
// Set to true when the last/current declarator list was started with an empty declaration.
bool mDeferredSingleDeclarationErrorCheck;
sh::GLenum mShaderType; // vertex or fragment language (future: pack or unpack)
ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
int mShaderVersion;
int mCompileOptions;
TIntermNode *mTreeRoot; // root of parse tree being created
int mLoopNestingLevel; // 0 if outside all loops
int mStructNestingLevel; // incremented while parsing a struct declaration
int mSwitchNestingLevel; // 0 if outside all switch statements
const TType *mCurrentFunctionType; // the return type of the function that's currently being parsed
bool mFunctionReturnsValue; // true if a non-void function has a return
bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
bool mFragmentPrecisionHigh; // true if highp precision is supported in the fragment language.
TLayoutMatrixPacking mDefaultMatrixPacking;
TLayoutBlockStorage mDefaultBlockStorage;
TString mHashErrMsg;
TDiagnostics mDiagnostics;
TDirectiveHandler mDirectiveHandler;
pp::Preprocessor mPreprocessor;
void *mScanner;
};
int PaParseStrings(
......
......@@ -389,7 +389,7 @@ bool ValidateLimitations::validateFunctionCall(TIntermAggregate *node)
bool valid = true;
TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable;
TSymbol* symbol = symbolTable.find(node->getName(), GetGlobalParseContext()->shaderVersion);
TSymbol* symbol = symbolTable.find(node->getName(), GetGlobalParseContext()->getShaderVersion());
ASSERT(symbol && symbol->isFunction());
TFunction *function = static_cast<TFunction *>(symbol);
for (ParamIndex::const_iterator i = pIndex.begin();
......
......@@ -9,7 +9,7 @@
#include "compiler/translator/IntermNode.h"
struct TParseContext;
class TParseContext;
class ValidateSwitch : public TIntermTraverser
{
......
......@@ -7,7 +7,7 @@
#ifndef COMPILER_TRANSLATOR_GLSLANG_H_
#define COMPILER_TRANSLATOR_GLSLANG_H_
struct TParseContext;
class TParseContext;
extern int glslang_initialize(TParseContext* context);
extern int glslang_finalize(TParseContext* context);
......
......@@ -246,7 +246,7 @@ O [0-7]
"sampler2DMSArray" |
"isampler2DMSArray" |
"usampler2DMSArray" {
if (context->shaderVersion < 300) {
if (context->getShaderVersion() < 300) {
yylval->lex.string = NewPoolTString(yytext);
return check_type(yyscanner);
}
......@@ -255,7 +255,7 @@ O [0-7]
/* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */
"packed" {
if (context->shaderVersion >= 300)
if (context->getShaderVersion() >= 300)
{
yylval->lex.string = NewPoolTString(yytext);
return check_type(yyscanner);
......@@ -399,7 +399,7 @@ O [0-7]
yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
pp::Token token;
yyget_extra(yyscanner)->preprocessor.lex(&token);
yyget_extra(yyscanner)->getPreprocessor().lex(&token);
yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
if (len < max_size)
memcpy(buf, token.text.c_str(), len);
......@@ -417,7 +417,7 @@ int check_type(yyscan_t yyscanner) {
struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
int token = IDENTIFIER;
TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->shaderVersion);
TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion());
if (symbol && symbol->isVariable()) {
TVariable* variable = static_cast<TVariable*>(symbol);
if (variable->isUserType()) {
......@@ -438,9 +438,9 @@ int reserved_word(yyscan_t yyscanner) {
int ES2_reserved_ES3_keyword(TParseContext *context, int token)
{
yyscan_t yyscanner = (yyscan_t) context->scanner;
yyscan_t yyscanner = (yyscan_t) context->getScanner();
if (context->shaderVersion < 300)
if (context->getShaderVersion() < 300)
{
return reserved_word(yyscanner);
}
......@@ -450,9 +450,9 @@ int ES2_reserved_ES3_keyword(TParseContext *context, int token)
int ES2_keyword_ES3_reserved(TParseContext *context, int token)
{
yyscan_t yyscanner = (yyscan_t) context->scanner;
yyscan_t yyscanner = (yyscan_t) context->getScanner();
if (context->shaderVersion >= 300)
if (context->getShaderVersion() >= 300)
{
return reserved_word(yyscanner);
}
......@@ -462,11 +462,11 @@ int ES2_keyword_ES3_reserved(TParseContext *context, int token)
int ES2_ident_ES3_keyword(TParseContext *context, int token)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
yyscan_t yyscanner = (yyscan_t) context->scanner;
struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
yyscan_t yyscanner = (yyscan_t) context->getScanner();
// not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
if (context->shaderVersion < 300)
if (context->getShaderVersion() < 300)
{
yylval->lex.string = NewPoolTString(yytext);
return check_type(yyscanner);
......@@ -477,10 +477,10 @@ int ES2_ident_ES3_keyword(TParseContext *context, int token)
int uint_constant(TParseContext *context)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
yyscan_t yyscanner = (yyscan_t) context->scanner;
struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
yyscan_t yyscanner = (yyscan_t) context->getScanner();
if (context->shaderVersion < 300)
if (context->getShaderVersion() < 300)
{
context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, "");
context->recover();
......@@ -495,9 +495,9 @@ int uint_constant(TParseContext *context)
int floatsuffix_check(TParseContext* context)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
if (context->shaderVersion < 300)
if (context->getShaderVersion() < 300)
{
context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext);
context->recover();
......@@ -536,15 +536,15 @@ int glslang_initialize(TParseContext* context) {
if (yylex_init_extra(context, &scanner))
return 1;
context->scanner = scanner;
context->setScanner(scanner);
return 0;
}
int glslang_finalize(TParseContext* context) {
yyscan_t scanner = context->scanner;
yyscan_t scanner = context->getScanner();
if (scanner == NULL) return 0;
context->scanner = NULL;
context->setScanner(NULL);
yylex_destroy(scanner);
return 0;
......@@ -552,24 +552,26 @@ int glslang_finalize(TParseContext* context) {
int glslang_scan(size_t count, const char* const string[], const int length[],
TParseContext* context) {
yyrestart(NULL, context->scanner);
yyset_column(0, context->scanner);
yyset_lineno(1, context->scanner);
yyrestart(NULL, context->getScanner());
yyset_column(0, context->getScanner());
yyset_lineno(1, context->getScanner());
// Initialize preprocessor.
if (!context->preprocessor.init(count, string, length))
pp::Preprocessor *preprocessor = &context->getPreprocessor();
if (!preprocessor->init(count, string, length))
return 1;
// Define extension macros.
const TExtensionBehavior& extBehavior = context->extensionBehavior();
for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
iter != extBehavior.end(); ++iter) {
context->preprocessor.predefineMacro(iter->first.c_str(), 1);
preprocessor->predefineMacro(iter->first.c_str(), 1);
}
if (context->fragmentPrecisionHigh)
context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
if (context->getFragmentPrecisionHigh())
preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
context->preprocessor.setMaxTokenSize(GetGlobalMaxTokenSize(context->shaderSpec));
preprocessor->setMaxTokenSize(GetGlobalMaxTokenSize(context->getShaderSpec()));
return 0;
}
......
......@@ -1759,7 +1759,7 @@ case 133:
case 134:
YY_RULE_SETUP
{
if (context->shaderVersion < 300) {
if (context->getShaderVersion() < 300) {
yylval->lex.string = NewPoolTString(yytext);
return check_type(yyscanner);
}
......@@ -1770,7 +1770,7 @@ YY_RULE_SETUP
case 135:
YY_RULE_SETUP
{
if (context->shaderVersion >= 300)
if (context->getShaderVersion() >= 300)
{
yylval->lex.string = NewPoolTString(yytext);
return check_type(yyscanner);
......@@ -3234,7 +3234,7 @@ void yyfree (void * ptr , yyscan_t yyscanner)
yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
pp::Token token;
yyget_extra(yyscanner)->preprocessor.lex(&token);
yyget_extra(yyscanner)->getPreprocessor().lex(&token);
yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
if (len < max_size)
memcpy(buf, token.text.c_str(), len);
......@@ -3252,7 +3252,7 @@ int check_type(yyscan_t yyscanner) {
struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
int token = IDENTIFIER;
TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->shaderVersion);
TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion());
if (symbol && symbol->isVariable()) {
TVariable* variable = static_cast<TVariable*>(symbol);
if (variable->isUserType()) {
......@@ -3273,9 +3273,9 @@ int reserved_word(yyscan_t yyscanner) {
int ES2_reserved_ES3_keyword(TParseContext *context, int token)
{
yyscan_t yyscanner = (yyscan_t) context->scanner;
yyscan_t yyscanner = (yyscan_t) context->getScanner();
if (context->shaderVersion < 300)
if (context->getShaderVersion() < 300)
{
return reserved_word(yyscanner);
}
......@@ -3285,9 +3285,9 @@ int ES2_reserved_ES3_keyword(TParseContext *context, int token)
int ES2_keyword_ES3_reserved(TParseContext *context, int token)
{
yyscan_t yyscanner = (yyscan_t) context->scanner;
yyscan_t yyscanner = (yyscan_t) context->getScanner();
if (context->shaderVersion >= 300)
if (context->getShaderVersion() >= 300)
{
return reserved_word(yyscanner);
}
......@@ -3297,11 +3297,11 @@ int ES2_keyword_ES3_reserved(TParseContext *context, int token)
int ES2_ident_ES3_keyword(TParseContext *context, int token)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
yyscan_t yyscanner = (yyscan_t) context->scanner;
struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
yyscan_t yyscanner = (yyscan_t) context->getScanner();
// not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
if (context->shaderVersion < 300)
if (context->getShaderVersion() < 300)
{
yylval->lex.string = NewPoolTString(yytext);
return check_type(yyscanner);
......@@ -3312,10 +3312,10 @@ int ES2_ident_ES3_keyword(TParseContext *context, int token)
int uint_constant(TParseContext *context)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
yyscan_t yyscanner = (yyscan_t) context->scanner;
struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
yyscan_t yyscanner = (yyscan_t) context->getScanner();
if (context->shaderVersion < 300)
if (context->getShaderVersion() < 300)
{
context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, "");
context->recover();
......@@ -3330,9 +3330,9 @@ int uint_constant(TParseContext *context)
int floatsuffix_check(TParseContext* context)
{
struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner();
if (context->shaderVersion < 300)
if (context->getShaderVersion() < 300)
{
context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext);
context->recover();
......@@ -3371,15 +3371,15 @@ int glslang_initialize(TParseContext* context) {
if (yylex_init_extra(context,&scanner))
return 1;
context->scanner = scanner;
context->setScanner(scanner);
return 0;
}
int glslang_finalize(TParseContext* context) {
yyscan_t scanner = context->scanner;
yyscan_t scanner = context->getScanner();
if (scanner == NULL) return 0;
context->scanner = NULL;
context->setScanner(NULL);
yylex_destroy(scanner);
return 0;
......@@ -3387,24 +3387,26 @@ int glslang_finalize(TParseContext* context) {
int glslang_scan(size_t count, const char* const string[], const int length[],
TParseContext* context) {
yyrestart(NULL,context->scanner);
yyset_column(0,context->scanner);
yyset_lineno(1,context->scanner);
yyrestart(NULL,context->getScanner());
yyset_column(0,context->getScanner());
yyset_lineno(1,context->getScanner());
// Initialize preprocessor.
if (!context->preprocessor.init(count, string, length))
pp::Preprocessor *preprocessor = &context->getPreprocessor();
if (!preprocessor->init(count, string, length))
return 1;
// Define extension macros.
const TExtensionBehavior& extBehavior = context->extensionBehavior();
for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
iter != extBehavior.end(); ++iter) {
context->preprocessor.predefineMacro(iter->first.c_str(), 1);
preprocessor->predefineMacro(iter->first.c_str(), 1);
}
if (context->fragmentPrecisionHigh)
context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
if (context->getFragmentPrecisionHigh())
preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
context->preprocessor.setMaxTokenSize(GetGlobalMaxTokenSize(context->shaderSpec));
preprocessor->setMaxTokenSize(GetGlobalMaxTokenSize(context->getShaderSpec()));
return 0;
}
......
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