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, ¯oSet, diag, directiveHandler), 1.38 + macroExpander(&directiveParser, ¯oSet, 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 +