Edit

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

Branch :

  • Show log

    Commit

  • Author : shannon.woods@transgaming.com
    Date : 2013-02-28 23:19:26
    Hash : d64b3dab
    Message : Fixed 64-bit integer truncation issues in shader translator. This is an incompatible API change, but one which is necessary in order to improve correctness of the code. The API version in ShaderLang.h is updated and, unfortunately, the define renamed to something less ambiguous due to conflicts on some Android buildbots. Temporary patches in Chromium and WebKit will be landed separately to support this upgrade. BUG=403,404,405,406,407,408,409 Review URL: https://codereview.appspot.com/7300058 Conflicts: include/GLSLANG/ShaderLang.h git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1960 736b8ea6-26fd-11df-bfd4-992fa37f6226

  • 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 <sstream>
    
    #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)
        {
        }
    };
    
    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 kGLSLVersion = 100;
    
        // Add standard pre-defined macros.
        predefineMacro("__LINE__", 0);
        predefineMacro("__FILE__", 0);
        predefineMacro("__VERSION__", kGLSLVersion);
        predefineMacro("GL_ES", 1);
    
        return mImpl->tokenizer.init(count, string, length);
    }
    
    void Preprocessor::predefineMacro(const char* name, int value)
    {
        std::ostringstream stream;
        stream << value;
    
        Token token;
        token.type = Token::CONST_INT;
        token.text = stream.str();
    
        Macro macro;
        macro.predefined = true;
        macro.type = Macro::kTypeObj;
        macro.name = name;
        macro.replacements.push_back(token);
    
        mImpl->macroSet[name] = macro;
    }
    
    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::CONST_INT:
              {
                int val = 0;
                if (!token->iValue(&val))
                {
                    // Do not mark the token as invalid.
                    // Just emit the diagnostic and reset value to 0.
                    mImpl->diagnostics->report(Diagnostics::INTEGER_OVERFLOW,
                                               token->location, token->text);
                    token->text.assign("0");
                }
                validToken = true;
                break;
              }
              case Token::CONST_FLOAT:
              {
                float val = 0;
                if (!token->fValue(&val))
                {
                    // Do not mark the token as invalid.
                    // Just emit the diagnostic and reset value to 0.0.
                    mImpl->diagnostics->report(Diagnostics::FLOAT_OVERFLOW,
                                               token->location, token->text);
                    token->text.assign("0.0");
                }
                validToken = true;
                break;
              }
              case Token::PP_NUMBER:
                mImpl->diagnostics->report(Diagnostics::INVALID_NUMBER,
                                           token->location, token->text);
                break;
              case Token::PP_OTHER:
                mImpl->diagnostics->report(Diagnostics::INVALID_CHARACTER,
                                           token->location, token->text);
                break;
              default:
                validToken = true;
                break;
            }
        }
    }
    
    }  // namespace pp