Edit

kc3-lang/angle/src/compiler/preprocessor/Preprocessor.cpp

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/Preprocessor.cpp
  • //
    // Copyright (c) 2011 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.
    //
    
    #include "Preprocessor.h"
    
    #include <cassert>
    
    #include "DiagnosticsBase.h"
    #include "DirectiveParser.h"
    #include "Macro.h"
    #include "MacroExpander.h"
    #include "Token.h"
    #include "Tokenizer.h"
    
    namespace pp
    {
    
    struct PreprocessorImpl
    {
        Diagnostics *diagnostics;
        MacroSet macroSet;
        Tokenizer tokenizer;
        DirectiveParser directiveParser;
        MacroExpander macroExpander;
    
        PreprocessorImpl(Diagnostics *diag, DirectiveHandler *directiveHandler)
            : diagnostics(diag),
              tokenizer(diag),
              directiveParser(&tokenizer, &macroSet, diag, directiveHandler),
              macroExpander(&directiveParser, &macroSet, diag, false)
        {
        }
    };
    
    Preprocessor::Preprocessor(Diagnostics *diagnostics,
                               DirectiveHandler *directiveHandler)
    {
        mImpl = new PreprocessorImpl(diagnostics, directiveHandler);
    }
    
    Preprocessor::~Preprocessor()
    {
        delete mImpl;
    }
    
    bool Preprocessor::init(size_t count,
                            const char * const string[],
                            const int length[])
    {
        static const int kDefaultGLSLVersion = 100;
    
        // Add standard pre-defined macros.
        predefineMacro("__LINE__", 0);
        predefineMacro("__FILE__", 0);
        predefineMacro("__VERSION__", kDefaultGLSLVersion);
        predefineMacro("GL_ES", 1);
    
        return mImpl->tokenizer.init(count, string, length);
    }
    
    void Preprocessor::predefineMacro(const char *name, int value)
    {
        PredefineMacro(&mImpl->macroSet, name, value);
    }
    
    void Preprocessor::lex(Token *token)
    {
        bool validToken = false;
        while (!validToken)
        {
            mImpl->macroExpander.lex(token);
            switch (token->type)
            {
              // We should not be returning internal preprocessing tokens.
              // Convert preprocessing tokens to compiler tokens or report
              // diagnostics.
              case Token::PP_HASH:
                assert(false);
                break;
              case Token::PP_NUMBER:
                mImpl->diagnostics->report(Diagnostics::PP_INVALID_NUMBER,
                                           token->location, token->text);
                break;
              case Token::PP_OTHER:
                mImpl->diagnostics->report(Diagnostics::PP_INVALID_CHARACTER,
                                           token->location, token->text);
                break;
              default:
                validToken = true;
                break;
            }
        }
    }
    
    void Preprocessor::setMaxTokenSize(size_t maxTokenSize)
    {
        mImpl->tokenizer.setMaxTokenSize(maxTokenSize);
    }
    
    }  // namespace pp