Edit

kc3-lang/angle/src/compiler/translator/ParseContext.h

Branch :

  • Show log

    Commit

  • Author : Olli Etuaho
    Date : 2016-01-11 11:16:01
    Hash : 5f80d016
    Message : Disallow invariant(all) pragma in ESSL 3.00 fragment shaders ESSL 3.00.4 section 4.6.1 says that using #pragma STDGL invariant(all) in a fragment shader is an error, so make it an error. This spec language is not found in ESSL 1.00, and it's been removed in ESSL 3.10. BUG=angleproject:1276 TEST=angle_unittests Change-Id: I2022f35475f867304b55dfb142f8568f6df28830 Reviewed-on: https://chromium-review.googlesource.com/321240 Tryjob-Request: Olli Etuaho <oetuaho@nvidia.com> Tested-by: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Zhenyao Mo <zmo@chromium.org> Reviewed-by: Kenneth Russell <kbr@chromium.org>

  • src/compiler/translator/ParseContext.h
  • //
    // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    #ifndef COMPILER_TRANSLATOR_PARSECONTEXT_H_
    #define COMPILER_TRANSLATOR_PARSECONTEXT_H_
    
    #include "compiler/translator/Compiler.h"
    #include "compiler/translator/Diagnostics.h"
    #include "compiler/translator/DirectiveHandler.h"
    #include "compiler/translator/Intermediate.h"
    #include "compiler/translator/SymbolTable.h"
    #include "compiler/preprocessor/Preprocessor.h"
    
    struct TMatrixFields
    {
        bool wholeRow;
        bool wholeCol;
        int row;
        int col;
    };
    
    //
    // The following are extra variables needed during parsing, grouped together so
    // they can be passed to the parser without needing a global.
    //
    class TParseContext : angle::NonCopyable
    {
      public:
        TParseContext(TSymbolTable &symt,
                      TExtensionBehavior &ext,
                      TIntermediate &interm,
                      sh::GLenum type,
                      ShShaderSpec spec,
                      int options,
                      bool checksPrecErrors,
                      TInfoSink &is,
                      const ShBuiltInResources &resources)
            : intermediate(interm),
              symbolTable(symt),
              mDeferredSingleDeclarationErrorCheck(false),
              mShaderType(type),
              mShaderSpec(spec),
              mShaderVersion(100),
              mTreeRoot(nullptr),
              mLoopNestingLevel(0),
              mStructNestingLevel(0),
              mSwitchNestingLevel(0),
              mCurrentFunctionType(nullptr),
              mFunctionReturnsValue(false),
              mChecksPrecisionErrors(checksPrecErrors),
              mFragmentPrecisionHighOnESSL1(false),
              mDefaultMatrixPacking(EmpColumnMajor),
              mDefaultBlockStorage(EbsShared),
              mDiagnostics(is),
              mDirectiveHandler(ext,
                                mDiagnostics,
                                mShaderVersion,
                                mShaderType,
                                resources.WEBGL_debug_shader_precision == 1),
              mPreprocessor(&mDiagnostics, &mDirectiveHandler),
              mScanner(nullptr),
              mUsesFragData(false),
              mUsesFragColor(false),
              mUsesSecondaryOutputs(false),
              mMinProgramTexelOffset(resources.MinProgramTexelOffset),
              mMaxProgramTexelOffset(resources.MaxProgramTexelOffset)
        {
        }
    
        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="");
    
        // If isError is false, a warning will be reported instead.
        void outOfRangeError(bool isError,
                             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 mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300;
        }
        void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh)
        {
            mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh;
        }
    
        void setLoopNestingLevel(int loopNestintLevel)
        {
            mLoopNestingLevel = loopNestintLevel;
        }
    
        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);
        TIntermTyped *parseVariableIdentifier(const TSourceLoc &location,
                                              const TString *name,
                                              const TSymbol *symbol);
    
        bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc &line);
    
        bool reservedErrorCheck(const TSourceLoc &line, const TString &identifier);
        void assignError(const TSourceLoc &line, const char *op, TString left, TString right);
        void unaryOpError(const TSourceLoc &line, const char *op, TString operand);
        void binaryOpError(const TSourceLoc &line, const char *op, TString left, TString right);
        bool precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type);
        bool lValueErrorCheck(const TSourceLoc &line, const char *op, TIntermTyped*);
        bool constErrorCheck(TIntermTyped *node);
        bool integerErrorCheck(TIntermTyped *node, const char *token);
        bool globalErrorCheck(const TSourceLoc &line, bool global, const char *token);
        bool constructorErrorCheck(const TSourceLoc &line,
                                   TIntermNode *argumentsNode,
                                   TFunction &function,
                                   TOperator op,
                                   TType *type);
        bool arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *expr, int &size);
        bool arrayQualifierErrorCheck(const TSourceLoc &line, const TPublicType &type);
        bool arrayTypeErrorCheck(const TSourceLoc &line, const TPublicType &type);
        bool voidErrorCheck(const TSourceLoc &line, const TString &identifier, const TBasicType &type);
        bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*);
        bool boolErrorCheck(const TSourceLoc&, const TPublicType&);
        bool samplerErrorCheck(const TSourceLoc &line, const TPublicType &pType, const char *reason);
        bool locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType);
        bool parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType &type);
        bool paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType *type);
        bool extensionErrorCheck(const TSourceLoc &line, const TString&);
        bool singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation);
        bool layoutLocationErrorCheck(const TSourceLoc &location, const TLayoutQualifier &layoutQualifier);
        bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
        void es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation);
        void es3InputOutputTypeCheck(const TQualifier qualifier,
                                     const TPublicType &type,
                                     const TSourceLoc &qualifierLocation);
    
        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);
        void handlePragmaDirective(const TSourceLoc &loc, const char *name, const char *value, bool stdgl);
    
        bool containsSampler(const TType &type);
        const TFunction* findFunction(
            const TSourceLoc &line, TFunction *pfnCall, int inputShaderVersion, bool *builtIn = 0);
        bool executeInitializer(const TSourceLoc &line,
                                const TString &identifier,
                                const TPublicType &pType,
                                TIntermTyped *initializer,
                                TIntermNode **intermNode);
    
        TPublicType addFullySpecifiedType(TQualifier qualifier,
                                          bool invariant,
                                          TLayoutQualifier layoutQualifier,
                                          const TPublicType &typeSpecifier);
    
        TIntermAggregate *parseSingleDeclaration(TPublicType &publicType,
                                                 const TSourceLoc &identifierOrTypeLocation,
                                                 const TString &identifier);
        TIntermAggregate *parseSingleArrayDeclaration(TPublicType &publicType,
                                                      const TSourceLoc &identifierLocation,
                                                      const TString &identifier,
                                                      const TSourceLoc &indexLocation,
                                                      TIntermTyped *indexExpression);
        TIntermAggregate *parseSingleInitDeclaration(const TPublicType &publicType,
                                                     const TSourceLoc &identifierLocation,
                                                     const TString &identifier,
                                                     const TSourceLoc &initLocation,
                                                     TIntermTyped *initializer);
    
        // Parse a declaration like "type a[n] = initializer"
        // Note that this does not apply to declarations like "type[n] a = initializer"
        TIntermAggregate *parseSingleArrayInitDeclaration(TPublicType &publicType,
                                                          const TSourceLoc &identifierLocation,
                                                          const TString &identifier,
                                                          const TSourceLoc &indexLocation,
                                                          TIntermTyped *indexExpression,
                                                          const TSourceLoc &initLocation,
                                                          TIntermTyped *initializer);
    
        TIntermAggregate *parseInvariantDeclaration(const TSourceLoc &invariantLoc,
                                                    const TSourceLoc &identifierLoc,
                                                    const TString *identifier,
                                                    const TSymbol *symbol);
    
        TIntermAggregate *parseDeclarator(TPublicType &publicType,
                                          TIntermAggregate *aggregateDeclaration,
                                          const TSourceLoc &identifierLocation,
                                          const TString &identifier);
        TIntermAggregate *parseArrayDeclarator(TPublicType &publicType,
                                               TIntermAggregate *aggregateDeclaration,
                                               const TSourceLoc &identifierLocation,
                                               const TString &identifier,
                                               const TSourceLoc &arrayLocation,
                                               TIntermTyped *indexExpression);
        TIntermAggregate *parseInitDeclarator(const TPublicType &publicType,
                                              TIntermAggregate *aggregateDeclaration,
                                              const TSourceLoc &identifierLocation,
                                              const TString &identifier,
                                              const TSourceLoc &initLocation,
                                              TIntermTyped *initializer);
    
        // Parse a declarator like "a[n] = initializer"
        TIntermAggregate *parseArrayInitDeclarator(const TPublicType &publicType,
                                                   TIntermAggregate *aggregateDeclaration,
                                                   const TSourceLoc &identifierLocation,
                                                   const TString &identifier,
                                                   const TSourceLoc &indexLocation,
                                                   TIntermTyped *indexExpression,
                                                   const TSourceLoc &initLocation,
                                                   TIntermTyped *initializer);
    
        void parseGlobalLayoutQualifier(const TPublicType &typeQualifier);
        TIntermAggregate *addFunctionPrototypeDeclaration(const TFunction &function,
                                                          const TSourceLoc &location);
        TIntermAggregate *addFunctionDefinition(const TFunction &function,
                                                TIntermAggregate *functionPrototype,
                                                TIntermAggregate *functionBody,
                                                const TSourceLoc &location);
        void parseFunctionPrototype(const TSourceLoc &location,
                                    TFunction *function,
                                    TIntermAggregate **aggregateOut);
        TFunction *parseFunctionDeclarator(const TSourceLoc &location,
                                           TFunction *function);
        TFunction *addConstructorFunc(const TPublicType &publicType);
        TIntermTyped *addConstructor(TIntermNode *arguments,
                                     TType *type,
                                     TOperator op,
                                     TFunction *fnCall,
                                     const TSourceLoc &line);
        TIntermTyped *addConstVectorNode(TVectorFields &fields,
                                         TIntermConstantUnion *node,
                                         const TSourceLoc &line,
                                         bool outOfRangeIndexIsError);
        TIntermTyped *addConstMatrixNode(int index,
                                         TIntermConstantUnion *node,
                                         const TSourceLoc &line,
                                         bool outOfRangeIndexIsError);
        TIntermTyped *addConstArrayNode(int index,
                                        TIntermConstantUnion *node,
                                        const TSourceLoc &line,
                                        bool outOfRangeIndexIsError);
        TIntermTyped *addConstStruct(
            const TString &identifier, TIntermTyped *node, const TSourceLoc& line);
        TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
                                         const TSourceLoc& location,
                                         TIntermTyped *indexExpression);
        TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression,
                                                  const TSourceLoc &dotLocation,
                                                  const TString &fieldString,
                                                  const TSourceLoc &fieldLocation);
    
        TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList);
        TPublicType addStructure(const TSourceLoc &structLine,
                                 const TSourceLoc &nameLine,
                                 const TString *structName,
                                 TFieldList *fieldList);
    
        TIntermAggregate* addInterfaceBlock(const TPublicType &typeQualifier,
                                            const TSourceLoc &nameLine,
                                            const TString &blockName,
                                            TFieldList *fieldList,
                                            const TString *instanceName,
                                            const TSourceLoc &instanceLine,
                                            TIntermTyped *arrayIndex,
                                            const TSourceLoc& arrayIndexLine);
    
        TLayoutQualifier parseLayoutQualifier(
            const TString &qualifierType, const TSourceLoc &qualifierTypeLine);
        TLayoutQualifier parseLayoutQualifier(const TString &qualifierType,
                                              const TSourceLoc &qualifierTypeLine,
                                              const TString &intValueString,
                                              int intValue,
                                              const TSourceLoc &intValueLine);
        TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier);
        TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier,
                                                const TSourceLoc &storageLoc, TQualifier storageQualifier);
    
        // Performs an error check for embedded struct declarations.
        // Returns true if an error was raised due to the declaration of
        // this struct.
        bool enterStructDeclaration(const TSourceLoc &line, const TString &identifier);
        void exitStructDeclaration();
    
        bool structNestingErrorCheck(const TSourceLoc &line, const TField &field);
    
        TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc);
        TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
        TIntermCase *addDefault(const TSourceLoc &loc);
    
        TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
        TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
        TIntermTyped *addBinaryMath(
            TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
        TIntermTyped *addBinaryMathBooleanResult(
            TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
        TIntermTyped *addAssign(
            TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
    
        TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
    
        TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
        TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc);
    
        void checkTextureOffsetConst(TIntermAggregate *functionCall);
        TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall,
                                              TIntermNode *paramNode,
                                              TIntermNode *thisNode,
                                              const TSourceLoc &loc,
                                              bool *fatalError);
    
        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);
    
        bool nonInitErrorCheck(const TSourceLoc &line, const TString &identifier, TPublicType *type);
    
        TIntermTyped *addBinaryMathInternal(
            TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
        TIntermTyped *createAssign(
            TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
        // The funcReturnType parameter is expected to be non-null when the operation is a built-in function.
        // It is expected to be null for other unary operators.
        TIntermTyped *createUnaryMath(
            TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType);
    
        // Return true if the checks pass
        bool binaryOpCommonCheck(
            TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
    
        // 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;
        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 mFragmentPrecisionHighOnESSL1;  // true if highp precision is supported when compiling
                                             // ESSL1.
        TLayoutMatrixPacking mDefaultMatrixPacking;
        TLayoutBlockStorage mDefaultBlockStorage;
        TString mHashErrMsg;
        TDiagnostics mDiagnostics;
        TDirectiveHandler mDirectiveHandler;
        pp::Preprocessor mPreprocessor;
        void *mScanner;
        bool mUsesFragData; // track if we are using both gl_FragData and gl_FragColor
        bool mUsesFragColor;
        bool mUsesSecondaryOutputs;  // Track if we are using either gl_SecondaryFragData or
                                     // gl_Secondary FragColor or both.
        int mMinProgramTexelOffset;
        int mMaxProgramTexelOffset;
    };
    
    int PaParseStrings(
        size_t count, const char *const string[], const int length[], TParseContext *context);
    
    #endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_