Edit

kc3-lang/angle/src/compiler/preprocessor/MacroExpander.h

Branch :

  • Show log

    Commit

  • Author : Olli Etuaho
    Date : 2015-09-18 10:34:31
    Hash : 261f5379
    Message : Support parsing defined operator generated by macro expansion dEQP tests enforce that the defined operator should be parsed even when it is generated as a result of macro expansion, even though this is undefined according to the C++ preprocessor spec. Implement support for this by putting the parsing for the defined operator inside MacroExpander. The operator gets processed right after it is generated by macro expansion. Parsing the defined operator is toggled with a boolean according to the context where MacroExpander is used. BUG=angleproject:989 TEST=angle_unittests, dEQP-GLES3.functional.shaders.preprocessor.* - 2 tests start passing: dEQP-GLES3.functional.shaders.preprocessor.conditional_inclusion.basic_2* Change-Id: I780e63bd4558253657d898685d62339017564a06 Reviewed-on: https://chromium-review.googlesource.com/300970 Reviewed-by: Jamie Madill <jmadill@chromium.org> Tested-by: Olli Etuaho <oetuaho@nvidia.com>

  • src/compiler/preprocessor/MacroExpander.h
  • //
    // Copyright (c) 2012 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_PREPROCESSOR_MACROEXPANDER_H_
    #define COMPILER_PREPROCESSOR_MACROEXPANDER_H_
    
    #include <cassert>
    #include <memory>
    #include <vector>
    
    #include "Lexer.h"
    #include "Macro.h"
    #include "pp_utils.h"
    
    namespace pp
    {
    
    class Diagnostics;
    struct SourceLocation;
    
    class MacroExpander : public Lexer
    {
      public:
        MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics, bool parseDefined);
        ~MacroExpander() override;
    
        void lex(Token *token) override;
    
      private:
        PP_DISALLOW_COPY_AND_ASSIGN(MacroExpander);
    
        void getToken(Token *token);
        void ungetToken(const Token &token);
        bool isNextTokenLeftParen();
    
        bool pushMacro(const Macro &macro, const Token &identifier);
        void popMacro();
    
        bool expandMacro(const Macro &macro,
                         const Token &identifier,
                         std::vector<Token> *replacements);
    
        typedef std::vector<Token> MacroArg;
        bool collectMacroArgs(const Macro &macro,
                              const Token &identifier,
                              std::vector<MacroArg> *args,
                              SourceLocation *closingParenthesisLocation);
        void replaceMacroParams(const Macro &macro,
                                const std::vector<MacroArg> &args,
                                std::vector<Token> *replacements);
    
        struct MacroContext
        {
            const Macro *macro;
            std::size_t index;
            std::vector<Token> replacements;
    
            MacroContext()
                : macro(0),
                  index(0)
            {
            }
            bool empty() const
            {
                return index == replacements.size();
            }
            const Token &get()
            {
                return replacements[index++];
            }
            void unget()
            {
                assert(index > 0);
                --index;
            }
        };
    
        Lexer *mLexer;
        MacroSet *mMacroSet;
        Diagnostics *mDiagnostics;
        bool mParseDefined;
    
        std::auto_ptr<Token> mReserveToken;
        std::vector<MacroContext *> mContextStack;
    };
    
    }  // namespace pp
    
    #endif  // COMPILER_PREPROCESSOR_MACROEXPANDER_H_