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
PreprocessorImplpp::PreprocessorImpl37 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
Preprocessor(Diagnostics * diagnostics,DirectiveHandler * directiveHandler,const PreprocessorSettings & settings)48 Preprocessor::Preprocessor(Diagnostics *diagnostics,
49 DirectiveHandler *directiveHandler,
50 const PreprocessorSettings &settings)
51 {
52 mImpl = new PreprocessorImpl(diagnostics, directiveHandler, settings);
53 }
54
~Preprocessor()55 Preprocessor::~Preprocessor()
56 {
57 delete mImpl;
58 }
59
init(size_t count,const char * const string[],const int length[])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
predefineMacro(const char * name,int value)73 void Preprocessor::predefineMacro(const char *name, int value)
74 {
75 PredefineMacro(&mImpl->macroSet, name, value);
76 }
77
lex(Token * token)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
setMaxTokenSize(size_t maxTokenSize)107 void Preprocessor::setMaxTokenSize(size_t maxTokenSize)
108 {
109 mImpl->tokenizer.setMaxTokenSize(maxTokenSize);
110 }
111
112 } // namespace pp
113