zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
DirectiveParser.cpp
Go to the documentation of this file.
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 "DirectiveParser.h"
8 
9 #include <cassert>
10 #include <cstdlib>
11 #include <sstream>
12 
13 #include "DiagnosticsBase.h"
14 #include "DirectiveHandlerBase.h"
15 #include "ExpressionParser.h"
16 #include "MacroExpander.h"
17 #include "Token.h"
18 #include "Tokenizer.h"
19 
20 namespace {
22 {
23  DIRECTIVE_NONE,
24  DIRECTIVE_DEFINE,
25  DIRECTIVE_UNDEF,
26  DIRECTIVE_IF,
27  DIRECTIVE_IFDEF,
28  DIRECTIVE_IFNDEF,
29  DIRECTIVE_ELSE,
30  DIRECTIVE_ELIF,
31  DIRECTIVE_ENDIF,
32  DIRECTIVE_ERROR,
33  DIRECTIVE_PRAGMA,
34  DIRECTIVE_EXTENSION,
35  DIRECTIVE_VERSION,
36  DIRECTIVE_LINE
37 };
38 } // namespace
39 
40 static DirectiveType getDirective(const pp::Token* token)
41 {
42  static const std::string kDirectiveDefine("define");
43  static const std::string kDirectiveUndef("undef");
44  static const std::string kDirectiveIf("if");
45  static const std::string kDirectiveIfdef("ifdef");
46  static const std::string kDirectiveIfndef("ifndef");
47  static const std::string kDirectiveElse("else");
48  static const std::string kDirectiveElif("elif");
49  static const std::string kDirectiveEndif("endif");
50  static const std::string kDirectiveError("error");
51  static const std::string kDirectivePragma("pragma");
52  static const std::string kDirectiveExtension("extension");
53  static const std::string kDirectiveVersion("version");
54  static const std::string kDirectiveLine("line");
55 
56  if (token->type != pp::Token::IDENTIFIER)
57  return DIRECTIVE_NONE;
58 
59  if (token->text == kDirectiveDefine)
60  return DIRECTIVE_DEFINE;
61  else if (token->text == kDirectiveUndef)
62  return DIRECTIVE_UNDEF;
63  else if (token->text == kDirectiveIf)
64  return DIRECTIVE_IF;
65  else if (token->text == kDirectiveIfdef)
66  return DIRECTIVE_IFDEF;
67  else if (token->text == kDirectiveIfndef)
68  return DIRECTIVE_IFNDEF;
69  else if (token->text == kDirectiveElse)
70  return DIRECTIVE_ELSE;
71  else if (token->text == kDirectiveElif)
72  return DIRECTIVE_ELIF;
73  else if (token->text == kDirectiveEndif)
74  return DIRECTIVE_ENDIF;
75  else if (token->text == kDirectiveError)
76  return DIRECTIVE_ERROR;
77  else if (token->text == kDirectivePragma)
78  return DIRECTIVE_PRAGMA;
79  else if (token->text == kDirectiveExtension)
80  return DIRECTIVE_EXTENSION;
81  else if (token->text == kDirectiveVersion)
82  return DIRECTIVE_VERSION;
83  else if (token->text == kDirectiveLine)
84  return DIRECTIVE_LINE;
85 
86  return DIRECTIVE_NONE;
87 }
88 
89 static bool isConditionalDirective(DirectiveType directive)
90 {
91  switch (directive)
92  {
93  case DIRECTIVE_IF:
94  case DIRECTIVE_IFDEF:
95  case DIRECTIVE_IFNDEF:
96  case DIRECTIVE_ELSE:
97  case DIRECTIVE_ELIF:
98  case DIRECTIVE_ENDIF:
99  return true;
100  default:
101  return false;
102  }
103 }
104 
105 // Returns true if the token represents End Of Directive.
106 static bool isEOD(const pp::Token* token)
107 {
108  return (token->type == '\n') || (token->type == pp::Token::LAST);
109 }
110 
111 static void skipUntilEOD(pp::Lexer* lexer, pp::Token* token)
112 {
113  while(!isEOD(token))
114  {
115  lexer->lex(token);
116  }
117 }
118 
120 {
121  // Names prefixed with "GL_" are reserved.
122  if (name.substr(0, 3) == "GL_")
123  return true;
124 
125  // Names containing two consecutive underscores are reserved.
126  if (name.find("__") != std::string::npos)
127  return true;
128 
129  return false;
130 }
131 
132 static bool isMacroPredefined(const std::string& name,
133  const pp::MacroSet& macroSet)
134 {
135  pp::MacroSet::const_iterator iter = macroSet.find(name);
136  return iter != macroSet.end() ? iter->second.predefined : false;
137 }
138 
139 namespace pp
140 {
141 
142 class DefinedParser : public Lexer
143 {
144  public:
145  DefinedParser(Lexer* lexer,
146  const MacroSet* macroSet,
147  Diagnostics* diagnostics) :
148  mLexer(lexer),
149  mMacroSet(macroSet),
150  mDiagnostics(diagnostics)
151  {
152  }
153 
154  protected:
155  virtual void lex(Token* token)
156  {
157  static const std::string kDefined("defined");
158 
159  mLexer->lex(token);
160  if (token->type != Token::IDENTIFIER)
161  return;
162  if (token->text != kDefined)
163  return;
164 
165  bool paren = false;
166  mLexer->lex(token);
167  if (token->type == '(')
168  {
169  paren = true;
170  mLexer->lex(token);
171  }
172 
173  if (token->type != Token::IDENTIFIER)
174  {
175  mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
176  token->location, token->text);
177  skipUntilEOD(mLexer, token);
178  return;
179  }
180  MacroSet::const_iterator iter = mMacroSet->find(token->text);
181  std::string expression = iter != mMacroSet->end() ? "1" : "0";
182 
183  if (paren)
184  {
185  mLexer->lex(token);
186  if (token->type != ')')
187  {
188  mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
189  token->location, token->text);
190  skipUntilEOD(mLexer, token);
191  return;
192  }
193  }
194 
195  // We have a valid defined operator.
196  // Convert the current token into a CONST_INT token.
197  token->type = Token::CONST_INT;
198  token->text = expression;
199  }
200 
201  private:
202  Lexer* mLexer;
203  const MacroSet* mMacroSet;
204  Diagnostics* mDiagnostics;
205 };
206 
208  MacroSet* macroSet,
209  Diagnostics* diagnostics,
210  DirectiveHandler* directiveHandler) :
211  mPastFirstStatement(false),
212  mTokenizer(tokenizer),
213  mMacroSet(macroSet),
214  mDiagnostics(diagnostics),
215  mDirectiveHandler(directiveHandler)
216 {
217 }
218 
220 {
221  do
222  {
223  mTokenizer->lex(token);
224 
225  if (token->type == Token::PP_HASH)
226  {
227  parseDirective(token);
228  mPastFirstStatement = true;
229  }
230 
231  if (token->type == Token::LAST)
232  {
233  if (!mConditionalStack.empty())
234  {
235  const ConditionalBlock& block = mConditionalStack.back();
237  block.location, block.type);
238  }
239  break;
240  }
241 
242  } while (skipping() || (token->type == '\n'));
243 
244  mPastFirstStatement = true;
245 }
246 
247 void DirectiveParser::parseDirective(Token* token)
248 {
249  assert(token->type == Token::PP_HASH);
250 
251  mTokenizer->lex(token);
252  if (isEOD(token))
253  {
254  // Empty Directive.
255  return;
256  }
257 
258  DirectiveType directive = getDirective(token);
259 
260  // While in an excluded conditional block/group,
261  // we only parse conditional directives.
262  if (skipping() && !isConditionalDirective(directive))
263  {
264  skipUntilEOD(mTokenizer, token);
265  return;
266  }
267 
268  switch(directive)
269  {
270  case DIRECTIVE_NONE:
272  token->location, token->text);
273  skipUntilEOD(mTokenizer, token);
274  break;
275  case DIRECTIVE_DEFINE:
276  parseDefine(token);
277  break;
278  case DIRECTIVE_UNDEF:
279  parseUndef(token);
280  break;
281  case DIRECTIVE_IF:
282  parseIf(token);
283  break;
284  case DIRECTIVE_IFDEF:
285  parseIfdef(token);
286  break;
287  case DIRECTIVE_IFNDEF:
288  parseIfndef(token);
289  break;
290  case DIRECTIVE_ELSE:
291  parseElse(token);
292  break;
293  case DIRECTIVE_ELIF:
294  parseElif(token);
295  break;
296  case DIRECTIVE_ENDIF:
297  parseEndif(token);
298  break;
299  case DIRECTIVE_ERROR:
300  parseError(token);
301  break;
302  case DIRECTIVE_PRAGMA:
303  parsePragma(token);
304  break;
305  case DIRECTIVE_EXTENSION:
306  parseExtension(token);
307  break;
308  case DIRECTIVE_VERSION:
309  parseVersion(token);
310  break;
311  case DIRECTIVE_LINE:
312  parseLine(token);
313  break;
314  default:
315  assert(false);
316  break;
317  }
318 
319  skipUntilEOD(mTokenizer, token);
320  if (token->type == Token::LAST)
321  {
323  token->location, token->text);
324  }
325 }
326 
327 void DirectiveParser::parseDefine(Token* token)
328 {
329  assert(getDirective(token) == DIRECTIVE_DEFINE);
330 
331  mTokenizer->lex(token);
332  if (token->type != Token::IDENTIFIER)
333  {
335  token->location, token->text);
336  return;
337  }
338  if (isMacroPredefined(token->text, *mMacroSet))
339  {
341  token->location, token->text);
342  return;
343  }
344  if (isMacroNameReserved(token->text))
345  {
347  token->location, token->text);
348  return;
349  }
350 
351  Macro macro;
352  macro.type = Macro::kTypeObj;
353  macro.name = token->text;
354 
355  mTokenizer->lex(token);
356  if (token->type == '(' && !token->hasLeadingSpace())
357  {
358  // Function-like macro. Collect arguments.
359  macro.type = Macro::kTypeFunc;
360  do {
361  mTokenizer->lex(token);
362  if (token->type != Token::IDENTIFIER)
363  break;
364  macro.parameters.push_back(token->text);
365 
366  mTokenizer->lex(token); // Get ','.
367  } while (token->type == ',');
368 
369  if (token->type != ')')
370  {
372  token->location,
373  token->text);
374  return;
375  }
376  mTokenizer->lex(token); // Get ')'.
377  }
378 
379  while ((token->type != '\n') && (token->type != Token::LAST))
380  {
381  // Reset the token location because it is unnecessary in replacement
382  // list. Resetting it also allows us to reuse Token::equals() to
383  // compare macros.
384  token->location = SourceLocation();
385  macro.replacements.push_back(*token);
386  mTokenizer->lex(token);
387  }
388  if (!macro.replacements.empty())
389  {
390  // Whitespace preceding the replacement list is not considered part of
391  // the replacement list for either form of macro.
392  macro.replacements.front().setHasLeadingSpace(false);
393  }
394 
395  // Check for macro redefinition.
396  MacroSet::const_iterator iter = mMacroSet->find(macro.name);
397  if (iter != mMacroSet->end() && !macro.equals(iter->second))
398  {
399  mDiagnostics->report(Diagnostics::MACRO_REDEFINED,
400  token->location,
401  macro.name);
402  return;
403  }
404  mMacroSet->insert(std::make_pair(macro.name, macro));
405 }
406 
407 void DirectiveParser::parseUndef(Token* token)
408 {
409  assert(getDirective(token) == DIRECTIVE_UNDEF);
410 
411  mTokenizer->lex(token);
412  if (token->type != Token::IDENTIFIER)
413  {
415  token->location, token->text);
416  return;
417  }
418 
419  MacroSet::iterator iter = mMacroSet->find(token->text);
420  if (iter != mMacroSet->end())
421  {
422  if (iter->second.predefined)
423  {
425  token->location, token->text);
426  }
427  else
428  {
429  mMacroSet->erase(iter);
430  }
431  }
432 
433  mTokenizer->lex(token);
434 }
435 
436 void DirectiveParser::parseIf(Token* token)
437 {
438  assert(getDirective(token) == DIRECTIVE_IF);
439  parseConditionalIf(token);
440 }
441 
442 void DirectiveParser::parseIfdef(Token* token)
443 {
444  assert(getDirective(token) == DIRECTIVE_IFDEF);
445  parseConditionalIf(token);
446 }
447 
448 void DirectiveParser::parseIfndef(Token* token)
449 {
450  assert(getDirective(token) == DIRECTIVE_IFNDEF);
451  parseConditionalIf(token);
452 }
453 
454 void DirectiveParser::parseElse(Token* token)
455 {
456  assert(getDirective(token) == DIRECTIVE_ELSE);
457 
458  if (mConditionalStack.empty())
459  {
461  token->location, token->text);
462  skipUntilEOD(mTokenizer, token);
463  return;
464  }
465 
466  ConditionalBlock& block = mConditionalStack.back();
467  if (block.skipBlock)
468  {
469  // No diagnostics. Just skip the whole line.
470  skipUntilEOD(mTokenizer, token);
471  return;
472  }
473  if (block.foundElseGroup)
474  {
476  token->location, token->text);
477  skipUntilEOD(mTokenizer, token);
478  return;
479  }
480 
481  block.foundElseGroup = true;
482  block.skipGroup = block.foundValidGroup;
483  block.foundValidGroup = true;
484 
485  // Warn if there are extra tokens after #else.
486  mTokenizer->lex(token);
487  if (!isEOD(token))
488  {
490  token->location, token->text);
491  skipUntilEOD(mTokenizer, token);
492  }
493 }
494 
495 void DirectiveParser::parseElif(Token* token)
496 {
497  assert(getDirective(token) == DIRECTIVE_ELIF);
498 
499  if (mConditionalStack.empty())
500  {
502  token->location, token->text);
503  skipUntilEOD(mTokenizer, token);
504  return;
505  }
506 
507  ConditionalBlock& block = mConditionalStack.back();
508  if (block.skipBlock)
509  {
510  // No diagnostics. Just skip the whole line.
511  skipUntilEOD(mTokenizer, token);
512  return;
513  }
514  if (block.foundElseGroup)
515  {
517  token->location, token->text);
518  skipUntilEOD(mTokenizer, token);
519  return;
520  }
521  if (block.foundValidGroup)
522  {
523  // Do not parse the expression.
524  // Also be careful not to emit a diagnostic.
525  block.skipGroup = true;
526  skipUntilEOD(mTokenizer, token);
527  return;
528  }
529 
530  int expression = parseExpressionIf(token);
531  block.skipGroup = expression == 0;
532  block.foundValidGroup = expression != 0;
533 }
534 
535 void DirectiveParser::parseEndif(Token* token)
536 {
537  assert(getDirective(token) == DIRECTIVE_ENDIF);
538 
539  if (mConditionalStack.empty())
540  {
542  token->location, token->text);
543  skipUntilEOD(mTokenizer, token);
544  return;
545  }
546 
547  mConditionalStack.pop_back();
548 
549  // Warn if there are tokens after #endif.
550  mTokenizer->lex(token);
551  if (!isEOD(token))
552  {
554  token->location, token->text);
555  skipUntilEOD(mTokenizer, token);
556  }
557 }
558 
559 void DirectiveParser::parseError(Token* token)
560 {
561  assert(getDirective(token) == DIRECTIVE_ERROR);
562 
563  std::ostringstream stream;
564  mTokenizer->lex(token);
565  while ((token->type != '\n') && (token->type != Token::LAST))
566  {
567  stream << *token;
568  mTokenizer->lex(token);
569  }
570  mDirectiveHandler->handleError(token->location, stream.str());
571 }
572 
573 // Parses pragma of form: #pragma name[(value)].
574 void DirectiveParser::parsePragma(Token* token)
575 {
576  assert(getDirective(token) == DIRECTIVE_PRAGMA);
577 
578  enum State
579  {
580  PRAGMA_NAME,
581  LEFT_PAREN,
582  PRAGMA_VALUE,
584  };
585 
586  bool valid = true;
588  int state = PRAGMA_NAME;
589 
590  mTokenizer->lex(token);
591  while ((token->type != '\n') && (token->type != Token::LAST))
592  {
593  switch(state++)
594  {
595  case PRAGMA_NAME:
596  name = token->text;
597  valid = valid && (token->type == Token::IDENTIFIER);
598  break;
599  case LEFT_PAREN:
600  valid = valid && (token->type == '(');
601  break;
602  case PRAGMA_VALUE:
603  value = token->text;
604  valid = valid && (token->type == Token::IDENTIFIER);
605  break;
606  case RIGHT_PAREN:
607  valid = valid && (token->type == ')');
608  break;
609  default:
610  valid = false;
611  break;
612  }
613  mTokenizer->lex(token);
614  }
615 
616  valid = valid && ((state == PRAGMA_NAME) || // Empty pragma.
617  (state == LEFT_PAREN) || // Without value.
618  (state == RIGHT_PAREN + 1)); // With value.
619  if (!valid)
620  {
622  token->location, name);
623  }
624  else if (state > PRAGMA_NAME) // Do not notify for empty pragma.
625  {
626  mDirectiveHandler->handlePragma(token->location, name, value);
627  }
628 }
629 
630 void DirectiveParser::parseExtension(Token* token)
631 {
632  assert(getDirective(token) == DIRECTIVE_EXTENSION);
633 
634  enum State
635  {
636  EXT_NAME,
637  COLON,
638  EXT_BEHAVIOR
639  };
640 
641  bool valid = true;
642  std::string name, behavior;
643  int state = EXT_NAME;
644 
645  mTokenizer->lex(token);
646  while ((token->type != '\n') && (token->type != Token::LAST))
647  {
648  switch (state++)
649  {
650  case EXT_NAME:
651  if (valid && (token->type != Token::IDENTIFIER))
652  {
654  token->location, token->text);
655  valid = false;
656  }
657  if (valid) name = token->text;
658  break;
659  case COLON:
660  if (valid && (token->type != ':'))
661  {
663  token->location, token->text);
664  valid = false;
665  }
666  break;
667  case EXT_BEHAVIOR:
668  if (valid && (token->type != Token::IDENTIFIER))
669  {
671  token->location, token->text);
672  valid = false;
673  }
674  if (valid) behavior = token->text;
675  break;
676  default:
677  if (valid)
678  {
680  token->location, token->text);
681  valid = false;
682  }
683  break;
684  }
685  mTokenizer->lex(token);
686  }
687  if (valid && (state != EXT_BEHAVIOR + 1))
688  {
690  token->location, token->text);
691  valid = false;
692  }
693  if (valid)
694  mDirectiveHandler->handleExtension(token->location, name, behavior);
695 }
696 
697 void DirectiveParser::parseVersion(Token* token)
698 {
699  assert(getDirective(token) == DIRECTIVE_VERSION);
700 
701  if (mPastFirstStatement)
702  {
704  token->location, token->text);
705  skipUntilEOD(mTokenizer, token);
706  return;
707  }
708 
709  enum State
710  {
711  VERSION_NUMBER
712  };
713 
714  bool valid = true;
715  int version = 0;
716  int state = VERSION_NUMBER;
717 
718  mTokenizer->lex(token);
719  while ((token->type != '\n') && (token->type != Token::LAST))
720  {
721  switch (state++)
722  {
723  case VERSION_NUMBER:
724  if (valid && (token->type != Token::CONST_INT))
725  {
727  token->location, token->text);
728  valid = false;
729  }
730  if (valid && !token->iValue(&version))
731  {
733  token->location, token->text);
734  valid = false;
735  }
736  break;
737  default:
738  if (valid)
739  {
741  token->location, token->text);
742  valid = false;
743  }
744  break;
745  }
746  mTokenizer->lex(token);
747  }
748  if (valid && (state != VERSION_NUMBER + 1))
749  {
751  token->location, token->text);
752  valid = false;
753  }
754  if (valid)
755  mDirectiveHandler->handleVersion(token->location, version);
756 }
757 
758 void DirectiveParser::parseLine(Token* token)
759 {
760  assert(getDirective(token) == DIRECTIVE_LINE);
761 
762  enum State
763  {
764  LINE_NUMBER,
765  FILE_NUMBER
766  };
767 
768  bool valid = true;
769  int line = 0, file = 0;
770  int state = LINE_NUMBER;
771 
772  MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics);
773  macroExpander.lex(token);
774  while ((token->type != '\n') && (token->type != Token::LAST))
775  {
776  switch (state++)
777  {
778  case LINE_NUMBER:
779  if (valid && (token->type != Token::CONST_INT))
780  {
782  token->location, token->text);
783  valid = false;
784  }
785  if (valid && !token->iValue(&line))
786  {
788  token->location, token->text);
789  valid = false;
790  }
791  break;
792  case FILE_NUMBER:
793  if (valid && (token->type != Token::CONST_INT))
794  {
796  token->location, token->text);
797  valid = false;
798  }
799  if (valid && !token->iValue(&file))
800  {
802  token->location, token->text);
803  valid = false;
804  }
805  break;
806  default:
807  if (valid)
808  {
810  token->location, token->text);
811  valid = false;
812  }
813  break;
814  }
815  macroExpander.lex(token);
816  }
817 
818  if (valid && (state != FILE_NUMBER) && (state != FILE_NUMBER + 1))
819  {
821  token->location, token->text);
822  valid = false;
823  }
824  if (valid)
825  {
826  mTokenizer->setLineNumber(line);
827  if (state == FILE_NUMBER + 1) mTokenizer->setFileNumber(file);
828  }
829 }
830 
831 bool DirectiveParser::skipping() const
832 {
833  if (mConditionalStack.empty()) return false;
834 
835  const ConditionalBlock& block = mConditionalStack.back();
836  return block.skipBlock || block.skipGroup;
837 }
838 
839 void DirectiveParser::parseConditionalIf(Token* token)
840 {
841  ConditionalBlock block;
842  block.type = token->text;
843  block.location = token->location;
844 
845  if (skipping())
846  {
847  // This conditional block is inside another conditional group
848  // which is skipped. As a consequence this whole block is skipped.
849  // Be careful not to parse the conditional expression that might
850  // emit a diagnostic.
851  skipUntilEOD(mTokenizer, token);
852  block.skipBlock = true;
853  }
854  else
855  {
856  DirectiveType directive = getDirective(token);
857 
858  int expression = 0;
859  switch (directive)
860  {
861  case DIRECTIVE_IF:
862  expression = parseExpressionIf(token);
863  break;
864  case DIRECTIVE_IFDEF:
865  expression = parseExpressionIfdef(token);
866  break;
867  case DIRECTIVE_IFNDEF:
868  expression = parseExpressionIfdef(token) == 0 ? 1 : 0;
869  break;
870  default:
871  assert(false);
872  break;
873  }
874  block.skipGroup = expression == 0;
875  block.foundValidGroup = expression != 0;
876  }
877  mConditionalStack.push_back(block);
878 }
879 
880 int DirectiveParser::parseExpressionIf(Token* token)
881 {
882  assert((getDirective(token) == DIRECTIVE_IF) ||
883  (getDirective(token) == DIRECTIVE_ELIF));
884 
885  DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics);
886  MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics);
887  ExpressionParser expressionParser(&macroExpander, mDiagnostics);
888 
889  int expression = 0;
890  macroExpander.lex(token);
891  expressionParser.parse(token, &expression);
892 
893  // Warn if there are tokens after #if expression.
894  if (!isEOD(token))
895  {
897  token->location, token->text);
898  skipUntilEOD(mTokenizer, token);
899  }
900 
901  return expression;
902 }
903 
904 int DirectiveParser::parseExpressionIfdef(Token* token)
905 {
906  assert((getDirective(token) == DIRECTIVE_IFDEF) ||
907  (getDirective(token) == DIRECTIVE_IFNDEF));
908 
909  mTokenizer->lex(token);
910  if (token->type != Token::IDENTIFIER)
911  {
913  token->location, token->text);
914  skipUntilEOD(mTokenizer, token);
915  return 0;
916  }
917 
918  MacroSet::const_iterator iter = mMacroSet->find(token->text);
919  int expression = iter != mMacroSet->end() ? 1 : 0;
920 
921  // Warn if there are tokens after #ifdef expression.
922  mTokenizer->lex(token);
923  if (!isEOD(token))
924  {
926  token->location, token->text);
927  skipUntilEOD(mTokenizer, token);
928  }
929  return expression;
930 }
931 
932 } // namespace pp
virtual void handleError(const SourceLocation &loc, const std::string &msg)=0
virtual void handleExtension(const SourceLocation &loc, const std::string &name, const std::string &behavior)=0
GLuint GLuint stream
Definition: glew.h:6573
png_sPLT_entryp pp
Definition: pngrutil.c:1375
FILE * file
Definition: visualinfo.c:88
int const char * version
Definition: zlib.h:813
static bool isMacroPredefined(const std::string &name, const pp::MacroSet &macroSet)
virtual void handleVersion(const SourceLocation &loc, int version)=0
EGLImageKHR EGLint * name
Definition: eglext.h:284
#define assert(x)
Definition: SDL_malloc.c:1234
void setFileNumber(int file)
Definition: Tokenizer.cpp:2315
void setLineNumber(int line)
Definition: Tokenizer.cpp:2322
static bool isConditionalDirective(DirectiveType directive)
static bool isMacroNameReserved(const std::string &name)
SourceLocation location
Definition: Token.h:89
void report(ID id, const SourceLocation &loc, const std::string &text)
enum State_ State
virtual void lex(Token *token)
Definition: Tokenizer.cpp:2327
static bool isEOD(const pp::Token *token)
std::map< std::string, Macro > MacroSet
Definition: Macro.h:41
EGLSurface EGLint void ** value
Definition: eglext.h:301
virtual void lex(Token *token)
std::string text
Definition: Token.h:90
static void skipUntilEOD(pp::Lexer *lexer, pp::Token *token)
GLsizei const GLcharARB ** string
Definition: glew.h:5638
virtual void lex(Token *token)=0
virtual void handlePragma(const SourceLocation &loc, const std::string &name, const std::string &value)=0
int type
Definition: Token.h:87
DirectiveParser(Tokenizer *tokenizer, MacroSet *macroSet, Diagnostics *diagnostics, DirectiveHandler *directiveHandler)
static DirectiveType getDirective(const pp::Token *token)
DirectiveType
#define false
Definition: ftrandom.c:50