gfx/angle/src/compiler/preprocessor/Preprocessor.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/angle/src/compiler/preprocessor/Preprocessor.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,142 @@
     1.4 +//
     1.5 +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.
     1.6 +// Use of this source code is governed by a BSD-style license that can be
     1.7 +// found in the LICENSE file.
     1.8 +//
     1.9 +
    1.10 +#include "Preprocessor.h"
    1.11 +
    1.12 +#include <cassert>
    1.13 +#include <sstream>
    1.14 +
    1.15 +#include "DiagnosticsBase.h"
    1.16 +#include "DirectiveParser.h"
    1.17 +#include "Macro.h"
    1.18 +#include "MacroExpander.h"
    1.19 +#include "Token.h"
    1.20 +#include "Tokenizer.h"
    1.21 +
    1.22 +namespace pp
    1.23 +{
    1.24 +
    1.25 +struct PreprocessorImpl
    1.26 +{
    1.27 +    Diagnostics* diagnostics;
    1.28 +    MacroSet macroSet;
    1.29 +    Tokenizer tokenizer;
    1.30 +    DirectiveParser directiveParser;
    1.31 +    MacroExpander macroExpander;
    1.32 +
    1.33 +    PreprocessorImpl(Diagnostics* diag,
    1.34 +                     DirectiveHandler* directiveHandler) :
    1.35 +        diagnostics(diag),
    1.36 +        tokenizer(diag),
    1.37 +        directiveParser(&tokenizer, &macroSet, diag, directiveHandler),
    1.38 +        macroExpander(&directiveParser, &macroSet, diag)
    1.39 +    {
    1.40 +    }
    1.41 +};
    1.42 +
    1.43 +Preprocessor::Preprocessor(Diagnostics* diagnostics,
    1.44 +                           DirectiveHandler* directiveHandler)
    1.45 +{
    1.46 +    mImpl = new PreprocessorImpl(diagnostics, directiveHandler);
    1.47 +}
    1.48 +
    1.49 +Preprocessor::~Preprocessor()
    1.50 +{
    1.51 +    delete mImpl;
    1.52 +}
    1.53 +
    1.54 +bool Preprocessor::init(size_t count,
    1.55 +                        const char* const string[],
    1.56 +                        const int length[])
    1.57 +{
    1.58 +    static const int kGLSLVersion = 100;
    1.59 +
    1.60 +    // Add standard pre-defined macros.
    1.61 +    predefineMacro("__LINE__", 0);
    1.62 +    predefineMacro("__FILE__", 0);
    1.63 +    predefineMacro("__VERSION__", kGLSLVersion);
    1.64 +    predefineMacro("GL_ES", 1);
    1.65 +
    1.66 +    return mImpl->tokenizer.init(count, string, length);
    1.67 +}
    1.68 +
    1.69 +void Preprocessor::predefineMacro(const char* name, int value)
    1.70 +{
    1.71 +    std::ostringstream stream;
    1.72 +    stream << value;
    1.73 +
    1.74 +    Token token;
    1.75 +    token.type = Token::CONST_INT;
    1.76 +    token.text = stream.str();
    1.77 +
    1.78 +    Macro macro;
    1.79 +    macro.predefined = true;
    1.80 +    macro.type = Macro::kTypeObj;
    1.81 +    macro.name = name;
    1.82 +    macro.replacements.push_back(token);
    1.83 +
    1.84 +    mImpl->macroSet[name] = macro;
    1.85 +}
    1.86 +
    1.87 +void Preprocessor::lex(Token* token)
    1.88 +{
    1.89 +    bool validToken = false;
    1.90 +    while (!validToken)
    1.91 +    {
    1.92 +        mImpl->macroExpander.lex(token);
    1.93 +        switch (token->type)
    1.94 +        {
    1.95 +          // We should not be returning internal preprocessing tokens.
    1.96 +          // Convert preprocessing tokens to compiler tokens or report
    1.97 +          // diagnostics.
    1.98 +          case Token::PP_HASH:
    1.99 +            assert(false);
   1.100 +            break;
   1.101 +          case Token::CONST_INT:
   1.102 +          {
   1.103 +            int val = 0;
   1.104 +            if (!token->iValue(&val))
   1.105 +            {
   1.106 +                // Do not mark the token as invalid.
   1.107 +                // Just emit the diagnostic and reset value to 0.
   1.108 +                mImpl->diagnostics->report(Diagnostics::INTEGER_OVERFLOW,
   1.109 +                                           token->location, token->text);
   1.110 +                token->text.assign("0");
   1.111 +            }
   1.112 +            validToken = true;
   1.113 +            break;
   1.114 +          }
   1.115 +          case Token::CONST_FLOAT:
   1.116 +          {
   1.117 +            float val = 0;
   1.118 +            if (!token->fValue(&val))
   1.119 +            {
   1.120 +                // Do not mark the token as invalid.
   1.121 +                // Just emit the diagnostic and reset value to 0.0.
   1.122 +                mImpl->diagnostics->report(Diagnostics::FLOAT_OVERFLOW,
   1.123 +                                           token->location, token->text);
   1.124 +                token->text.assign("0.0");
   1.125 +            }
   1.126 +            validToken = true;
   1.127 +            break;
   1.128 +          }
   1.129 +          case Token::PP_NUMBER:
   1.130 +            mImpl->diagnostics->report(Diagnostics::INVALID_NUMBER,
   1.131 +                                       token->location, token->text);
   1.132 +            break;
   1.133 +          case Token::PP_OTHER:
   1.134 +            mImpl->diagnostics->report(Diagnostics::INVALID_CHARACTER,
   1.135 +                                       token->location, token->text);
   1.136 +            break;
   1.137 +          default:
   1.138 +            validToken = true;
   1.139 +            break;
   1.140 +        }
   1.141 +    }
   1.142 +}
   1.143 +
   1.144 +}  // namespace pp
   1.145 +

mercurial