1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "Preprocessor.h" 16 17 #include <cassert> 18 19 #include "DiagnosticsBase.h" 20 #include "DirectiveParser.h" 21 #include "Macro.h" 22 #include "MacroExpander.h" 23 #include "Token.h" 24 #include "Tokenizer.h" 25 26 namespace pp 27 { 28 29 struct PreprocessorImpl 30 { 31 Diagnostics *diagnostics; 32 MacroSet macroSet; 33 Tokenizer tokenizer; 34 DirectiveParser directiveParser; 35 MacroExpander macroExpander; 36 37 PreprocessorImpl(Diagnostics *diag, 38 DirectiveHandler *directiveHandler, 39 const PreprocessorSettings &settings) 40 : diagnostics(diag), 41 tokenizer(diag), 42 directiveParser(&tokenizer, ¯oSet, diag, directiveHandler, settings.maxMacroExpansionDepth), 43 macroExpander(&directiveParser, ¯oSet, diag, false, settings.maxMacroExpansionDepth) 44 { 45 } 46 }; 47 48 Preprocessor::Preprocessor(Diagnostics *diagnostics, 49 DirectiveHandler *directiveHandler, 50 const PreprocessorSettings &settings) 51 { 52 mImpl = new PreprocessorImpl(diagnostics, directiveHandler, settings); 53 } 54 55 Preprocessor::~Preprocessor() 56 { 57 delete mImpl; 58 } 59 60 bool Preprocessor::init(size_t count, const char *const string[], const int length[]) 61 { 62 static const int kDefaultGLSLVersion = 100; 63 64 // Add standard pre-defined macros. 65 predefineMacro("__LINE__", 0); 66 predefineMacro("__FILE__", 0); 67 predefineMacro("__VERSION__", kDefaultGLSLVersion); 68 predefineMacro("GL_ES", 1); 69 70 return mImpl->tokenizer.init(count, string, length); 71 } 72 73 void Preprocessor::predefineMacro(const char *name, int value) 74 { 75 PredefineMacro(&mImpl->macroSet, name, value); 76 } 77 78 void Preprocessor::lex(Token *token) 79 { 80 bool validToken = false; 81 while (!validToken) 82 { 83 mImpl->macroExpander.lex(token); 84 switch (token->type) 85 { 86 // We should not be returning internal preprocessing tokens. 87 // Convert preprocessing tokens to compiler tokens or report 88 // diagnostics. 89 case Token::PP_HASH: 90 assert(false); 91 break; 92 case Token::PP_NUMBER: 93 mImpl->diagnostics->report(Diagnostics::PP_INVALID_NUMBER, 94 token->location, token->text); 95 break; 96 case Token::PP_OTHER: 97 mImpl->diagnostics->report(Diagnostics::PP_INVALID_CHARACTER, 98 token->location, token->text); 99 break; 100 default: 101 validToken = true; 102 break; 103 } 104 } 105 } 106 107 void Preprocessor::setMaxTokenSize(size_t maxTokenSize) 108 { 109 mImpl->tokenizer.setMaxTokenSize(maxTokenSize); 110 } 111 112 } // namespace pp 113