Home | History | Annotate | Download | only in preprocessor
      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, &macroSet, diag, directiveHandler,  settings.maxMacroExpansionDepth),
     43 	      macroExpander(&directiveParser, &macroSet, 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