Edit

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

Branch :

  • Show log

    Commit

  • Author : Olli Etuaho
    Date : 2015-09-08 14:21:38
    Hash : e6432c85
    Message : Fix preprocessor macro replacement list location According to the dEQP tests, a macro replacement list generated by a function-like macro invocation should get its location from the closing parenthesis of the invocation. The tests check this by using __LINE__ in a macro with a multi-line invocation. It's not quite clear from the spec that the enforced behavior is expected as opposed to the replacement list getting its location from the macro name, but a minor correction to the preprocessor makes the dEQP tests pass. Newlines in the preprocessor unit tests are generated according to the source locations in the token list produced by the preprocessor, so the expectations of a few tests also need to be updated. BUG=angleproject:989 TEST=dEQP-GLES3.functional.shaders.preprocessor.predefined_macros.* (2 start passing with this change), angle_unittests Change-Id: I4cc9da09bd0985310a05ebf6def680916a46308a Reviewed-on: https://chromium-review.googlesource.com/297990 Tested-by: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Zhenyao Mo <zmo@chromium.org>

  • 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);
        ~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;
    
        std::auto_ptr<Token> mReserveToken;
        std::vector<MacroContext *> mContextStack;
    };
    
    }  // namespace pp
    
    #endif  // COMPILER_PREPROCESSOR_MACROEXPANDER_H_