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

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 //
michael@0 2 // Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.
michael@0 3 // Use of this source code is governed by a BSD-style license that can be
michael@0 4 // found in the LICENSE file.
michael@0 5 //
michael@0 6
michael@0 7 #include "Preprocessor.h"
michael@0 8
michael@0 9 #include <cassert>
michael@0 10 #include <sstream>
michael@0 11
michael@0 12 #include "DiagnosticsBase.h"
michael@0 13 #include "DirectiveParser.h"
michael@0 14 #include "Macro.h"
michael@0 15 #include "MacroExpander.h"
michael@0 16 #include "Token.h"
michael@0 17 #include "Tokenizer.h"
michael@0 18
michael@0 19 namespace pp
michael@0 20 {
michael@0 21
michael@0 22 struct PreprocessorImpl
michael@0 23 {
michael@0 24 Diagnostics* diagnostics;
michael@0 25 MacroSet macroSet;
michael@0 26 Tokenizer tokenizer;
michael@0 27 DirectiveParser directiveParser;
michael@0 28 MacroExpander macroExpander;
michael@0 29
michael@0 30 PreprocessorImpl(Diagnostics* diag,
michael@0 31 DirectiveHandler* directiveHandler) :
michael@0 32 diagnostics(diag),
michael@0 33 tokenizer(diag),
michael@0 34 directiveParser(&tokenizer, &macroSet, diag, directiveHandler),
michael@0 35 macroExpander(&directiveParser, &macroSet, diag)
michael@0 36 {
michael@0 37 }
michael@0 38 };
michael@0 39
michael@0 40 Preprocessor::Preprocessor(Diagnostics* diagnostics,
michael@0 41 DirectiveHandler* directiveHandler)
michael@0 42 {
michael@0 43 mImpl = new PreprocessorImpl(diagnostics, directiveHandler);
michael@0 44 }
michael@0 45
michael@0 46 Preprocessor::~Preprocessor()
michael@0 47 {
michael@0 48 delete mImpl;
michael@0 49 }
michael@0 50
michael@0 51 bool Preprocessor::init(size_t count,
michael@0 52 const char* const string[],
michael@0 53 const int length[])
michael@0 54 {
michael@0 55 static const int kGLSLVersion = 100;
michael@0 56
michael@0 57 // Add standard pre-defined macros.
michael@0 58 predefineMacro("__LINE__", 0);
michael@0 59 predefineMacro("__FILE__", 0);
michael@0 60 predefineMacro("__VERSION__", kGLSLVersion);
michael@0 61 predefineMacro("GL_ES", 1);
michael@0 62
michael@0 63 return mImpl->tokenizer.init(count, string, length);
michael@0 64 }
michael@0 65
michael@0 66 void Preprocessor::predefineMacro(const char* name, int value)
michael@0 67 {
michael@0 68 std::ostringstream stream;
michael@0 69 stream << value;
michael@0 70
michael@0 71 Token token;
michael@0 72 token.type = Token::CONST_INT;
michael@0 73 token.text = stream.str();
michael@0 74
michael@0 75 Macro macro;
michael@0 76 macro.predefined = true;
michael@0 77 macro.type = Macro::kTypeObj;
michael@0 78 macro.name = name;
michael@0 79 macro.replacements.push_back(token);
michael@0 80
michael@0 81 mImpl->macroSet[name] = macro;
michael@0 82 }
michael@0 83
michael@0 84 void Preprocessor::lex(Token* token)
michael@0 85 {
michael@0 86 bool validToken = false;
michael@0 87 while (!validToken)
michael@0 88 {
michael@0 89 mImpl->macroExpander.lex(token);
michael@0 90 switch (token->type)
michael@0 91 {
michael@0 92 // We should not be returning internal preprocessing tokens.
michael@0 93 // Convert preprocessing tokens to compiler tokens or report
michael@0 94 // diagnostics.
michael@0 95 case Token::PP_HASH:
michael@0 96 assert(false);
michael@0 97 break;
michael@0 98 case Token::CONST_INT:
michael@0 99 {
michael@0 100 int val = 0;
michael@0 101 if (!token->iValue(&val))
michael@0 102 {
michael@0 103 // Do not mark the token as invalid.
michael@0 104 // Just emit the diagnostic and reset value to 0.
michael@0 105 mImpl->diagnostics->report(Diagnostics::INTEGER_OVERFLOW,
michael@0 106 token->location, token->text);
michael@0 107 token->text.assign("0");
michael@0 108 }
michael@0 109 validToken = true;
michael@0 110 break;
michael@0 111 }
michael@0 112 case Token::CONST_FLOAT:
michael@0 113 {
michael@0 114 float val = 0;
michael@0 115 if (!token->fValue(&val))
michael@0 116 {
michael@0 117 // Do not mark the token as invalid.
michael@0 118 // Just emit the diagnostic and reset value to 0.0.
michael@0 119 mImpl->diagnostics->report(Diagnostics::FLOAT_OVERFLOW,
michael@0 120 token->location, token->text);
michael@0 121 token->text.assign("0.0");
michael@0 122 }
michael@0 123 validToken = true;
michael@0 124 break;
michael@0 125 }
michael@0 126 case Token::PP_NUMBER:
michael@0 127 mImpl->diagnostics->report(Diagnostics::INVALID_NUMBER,
michael@0 128 token->location, token->text);
michael@0 129 break;
michael@0 130 case Token::PP_OTHER:
michael@0 131 mImpl->diagnostics->report(Diagnostics::INVALID_CHARACTER,
michael@0 132 token->location, token->text);
michael@0 133 break;
michael@0 134 default:
michael@0 135 validToken = true;
michael@0 136 break;
michael@0 137 }
michael@0 138 }
michael@0 139 }
michael@0 140
michael@0 141 } // namespace pp
michael@0 142

mercurial