1 | // |
2 | // Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. |
3 | // Use of this source code is governed by a BSD-style license that can be |
4 | // found in the LICENSE file. |
5 | // |
6 | |
7 | #include "compiler/preprocessor/Preprocessor.h" |
8 | |
9 | #include "common/debug.h" |
10 | #include "compiler/preprocessor/DiagnosticsBase.h" |
11 | #include "compiler/preprocessor/DirectiveParser.h" |
12 | #include "compiler/preprocessor/Macro.h" |
13 | #include "compiler/preprocessor/MacroExpander.h" |
14 | #include "compiler/preprocessor/Token.h" |
15 | #include "compiler/preprocessor/Tokenizer.h" |
16 | |
17 | namespace angle |
18 | { |
19 | |
20 | namespace pp |
21 | { |
22 | |
23 | struct PreprocessorImpl |
24 | { |
25 | Diagnostics *diagnostics; |
26 | MacroSet macroSet; |
27 | Tokenizer tokenizer; |
28 | DirectiveParser directiveParser; |
29 | MacroExpander macroExpander; |
30 | |
31 | PreprocessorImpl(Diagnostics *diag, |
32 | DirectiveHandler *directiveHandler, |
33 | const PreprocessorSettings &settings) |
34 | : diagnostics(diag), |
35 | tokenizer(diag), |
36 | directiveParser(&tokenizer, ¯oSet, diag, directiveHandler, settings), |
37 | macroExpander(&directiveParser, ¯oSet, diag, settings, false) |
38 | {} |
39 | }; |
40 | |
41 | Preprocessor::Preprocessor(Diagnostics *diagnostics, |
42 | DirectiveHandler *directiveHandler, |
43 | const PreprocessorSettings &settings) |
44 | { |
45 | mImpl = new PreprocessorImpl(diagnostics, directiveHandler, settings); |
46 | } |
47 | |
48 | Preprocessor::~Preprocessor() |
49 | { |
50 | delete mImpl; |
51 | } |
52 | |
53 | bool Preprocessor::init(size_t count, const char *const string[], const int length[]) |
54 | { |
55 | static const int kDefaultGLSLVersion = 100; |
56 | |
57 | // Add standard pre-defined macros. |
58 | predefineMacro("__LINE__" , 0); |
59 | predefineMacro("__FILE__" , 0); |
60 | predefineMacro("__VERSION__" , kDefaultGLSLVersion); |
61 | predefineMacro("GL_ES" , 1); |
62 | |
63 | return mImpl->tokenizer.init(count, string, length); |
64 | } |
65 | |
66 | void Preprocessor::predefineMacro(const char *name, int value) |
67 | { |
68 | PredefineMacro(&mImpl->macroSet, name, value); |
69 | } |
70 | |
71 | void Preprocessor::lex(Token *token) |
72 | { |
73 | bool validToken = false; |
74 | while (!validToken) |
75 | { |
76 | mImpl->macroExpander.lex(token); |
77 | switch (token->type) |
78 | { |
79 | // We should not be returning internal preprocessing tokens. |
80 | // Convert preprocessing tokens to compiler tokens or report |
81 | // diagnostics. |
82 | case Token::PP_HASH: |
83 | UNREACHABLE(); |
84 | break; |
85 | case Token::PP_NUMBER: |
86 | mImpl->diagnostics->report(Diagnostics::PP_INVALID_NUMBER, token->location, |
87 | token->text); |
88 | break; |
89 | case Token::PP_OTHER: |
90 | mImpl->diagnostics->report(Diagnostics::PP_INVALID_CHARACTER, token->location, |
91 | token->text); |
92 | break; |
93 | default: |
94 | validToken = true; |
95 | break; |
96 | } |
97 | } |
98 | } |
99 | |
100 | void Preprocessor::setMaxTokenSize(size_t maxTokenSize) |
101 | { |
102 | mImpl->tokenizer.setMaxTokenSize(maxTokenSize); |
103 | } |
104 | |
105 | } // namespace pp |
106 | |
107 | } // namespace angle |
108 | |