Line data Source code
1 : /*=============================================================================
2 : Boost.Wave: A Standard compliant C++ preprocessor library
3 : http://www.boost.org/
4 :
5 : Copyright (c) 2001-2005 Hartmut Kaiser. Distributed under the Boost
6 : Software License, Version 1.0. (See accompanying file
7 : LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 : =============================================================================*/
9 :
10 : #if !defined(BOOST_WAVE_ADVANCED_PREPROCESSING_HOOKS_INCLUDED)
11 : #define BOOST_WAVE_ADVANCED_PREPROCESSING_HOOKS_INCLUDED
12 :
13 : // ROSE standard include files
14 :
15 : #include <cstdio>
16 : #include <ostream>
17 : #include <string>
18 :
19 : #include <boost/assert.hpp>
20 : #include <boost/config.hpp>
21 :
22 : #include <boost/wave/token_ids.hpp>
23 : #include <boost/wave/util/macro_helpers.hpp>
24 : #include <boost/wave/preprocessing_hooks.hpp>
25 :
26 : #include "attributeListMap.h"
27 :
28 : #define ROSE_WAVE_PSEUDO_FILE "<rose wave fix>"
29 :
30 : #if 0
31 : namespace {
32 :
33 : char const *get_directivename(boost::wave::token_id id)
34 : {
35 : using namespace boost::wave;
36 : switch (static_cast<unsigned int>(id)) {
37 : case T_PP_IFDEF: return "#ifdef";
38 : case T_PP_IFNDEF: return "#ifndef";
39 : case T_PP_IF: return "#if";
40 : case T_PP_ELSE: return "#else";
41 : case T_PP_ELIF: return "#elif";
42 : case T_PP_ENDIF: return "#endif";
43 : default:
44 : return "#unknown directive";
45 : }
46 : }
47 : }
48 :
49 : #endif
50 :
51 : ///////////////////////////////////////////////////////////////////////////////
52 : //
53 : // The advanced_preprocessing_hooks policy class is used to register some
54 : // of the more advanced (and probably more rarely used hooks with the Wave
55 : // library.
56 : //
57 : // This policy type is used as a template parameter to the boost::wave::context<>
58 : // object.
59 : //
60 : ///////////////////////////////////////////////////////////////////////////////
61 : //template<typename ContextT>
62 : class advanced_preprocessing_hooks
63 : : public boost::wave::context_policies::default_preprocessing_hooks
64 : {
65 :
66 : public:
67 : AttributeListMap* attributeListMap;
68 : std::list< token_type > tokens;
69 :
70 : token_type lastPreprocDirective;
71 : int numberOfIfs;
72 :
73 : std::string includeDirective;
74 : token_type includeDirectiveToken;
75 : bool skipping;
76 : bool updatingLastToken;
77 : token_type last_token;
78 0 : advanced_preprocessing_hooks()
79 0 : : attributeListMap(NULL)
80 : , tokens()
81 : , lastPreprocDirective()
82 : , numberOfIfs(0)
83 : , includeDirective()
84 : , skipping(false)
85 0 : , updatingLastToken(false)
86 : { }
87 :
88 :
89 :
90 : ////////////////////////////////////////////////////////////////////
91 : //
92 : //Note from AS:
93 : //The typename ContainerT is often equivalent to list<TokenT>.
94 : //TokentT is often equivalent to boost::wave::cpplexer::lex_token<>
95 : //found in boost_1_33_0/boost/wave/cpplexer/cpp_lex_token.hpp.
96 : //
97 : ///////////////////////////////////////////////////////////////////
98 :
99 :
100 :
101 :
102 : ///////////////////////////////////////////////////////////////////////////
103 : //
104 : // The function 'expanding_function_like_macro' is called, whenever a
105 : // function-like macro is to be expanded.
106 : //
107 : // The macroname parameter marks the position, where the macro to expand
108 : // is defined.
109 : // The formal_args parameter holds the formal arguments used during the
110 : // definition of the macro.
111 : // The definition parameter holds the macro definition for the macro to
112 : // trace.
113 : //
114 : // The macro call parameter marks the position, where this macro invoked.
115 : // The arguments parameter holds the macro arguments used during the
116 : // invocation of the macro
117 : //
118 : ///////////////////////////////////////////////////////////////////////////
119 :
120 : template <typename ContextT, typename TokenT, typename ContainerT, typename IteratorT>
121 0 : bool expanding_function_like_macro(ContextT const& ctx,
122 : TokenT const& macrodef, std::vector<TokenT> const& formal_args,
123 : ContainerT const& definition,
124 : TokenT const& macrocall, std::vector<ContainerT> const& arguments,
125 : IteratorT const& seqstart, IteratorT const& seqend)
126 : {
127 : ////////////////////////////////////////////////////////////////////
128 : //
129 : //Note from AS:
130 : //The typename ContainerT is often equivalent to list<TokenT>.
131 : //TokentT is often equivalent to boost::wave::cpplexer::lex_token<>
132 : //found in boost_1_33_0/boost/wave/cpplexer/cpp_lex_token.hpp.
133 : //
134 : ///////////////////////////////////////////////////////////////////
135 :
136 0 : attributeListMap->expanding_function_like_macro(macrodef, formal_args, definition, macrocall, arguments);
137 :
138 : return false;
139 : }
140 :
141 : ///////////////////////////////////////////////////////////////////////////
142 : //
143 : // The function 'expanding_object_like_macro' is called, whenever a
144 : // object-like macro is to be expanded .
145 : //
146 : // The macroname parameter marks the position, where the macro to expand
147 : // is defined.
148 : // The definition parameter holds the macro definition for the macro to
149 : // trace.
150 : //
151 : // The macro call parameter marks the position, where this macro invoked.
152 : //
153 : ///////////////////////////////////////////////////////////////////////////
154 :
155 : template <typename ContextT, typename TokenT, typename ContainerT>
156 0 : bool expanding_object_like_macro(ContextT const& ctx, TokenT const& macro,
157 : ContainerT const& definition, TokenT const& macrocall)
158 : {
159 0 : attributeListMap->expanding_object_like_macro(macro, definition, macrocall);
160 : return false;
161 : }
162 :
163 : ///////////////////////////////////////////////////////////////////////////
164 : //
165 : // The function 'expanded_macro' is called, whenever the expansion of a
166 : // macro is finished but before the rescanning process starts.
167 : //
168 : // The parameter 'result' contains the token sequence generated as the
169 : // result of the macro expansion.
170 : //
171 : ///////////////////////////////////////////////////////////////////////////
172 : template <typename ContextT, typename ContainerT>
173 0 : void expanded_macro(ContextT const& ctx, ContainerT const& result)
174 : {
175 0 : attributeListMap->expanded_macro(result);
176 : }
177 :
178 : ///////////////////////////////////////////////////////////////////////////
179 : //
180 : // The function 'rescanned_macro' is called, whenever the rescanning of a
181 : // macro is finished.
182 : //
183 : // The parameter 'result' contains the token sequence generated as the
184 : // result of the rescanning.
185 : //
186 : ///////////////////////////////////////////////////////////////////////////
187 : template <typename ContextT, typename ContainerT>
188 0 : void rescanned_macro(ContextT const& ctx, ContainerT const& result)
189 : {
190 0 : attributeListMap->rescanned_macro(result);
191 0 : }
192 :
193 : ///////////////////////////////////////////////////////////////////////////
194 : //
195 : // The function 'found_include_directive' is called, whenever a #include
196 : // directive was located.
197 : //
198 : // The parameter 'filename' contains the (expanded) file name found after
199 : // the #include directive. This has the format '<file>', '"file"' or
200 : // 'file'.
201 : // The formats '<file>' or '"file"' are used for #include directives found
202 : // in the preprocessed token stream, the format 'file' is used for files
203 : // specified through the --force_include command line argument.
204 : //
205 : // The parameter 'include_next' is set to true if the found directive was
206 : // a #include_next directive and the BOOST_WAVE_SUPPORT_INCLUDE_NEXT
207 : // preprocessing constant was defined to something != 0.
208 : //
209 : ///////////////////////////////////////////////////////////////////////////
210 :
211 : template <typename ContextT>
212 : bool
213 0 : found_include_directive(ContextT const& ctx, std::string const& filename,
214 : bool include_next)
215 : {
216 0 : if(SgProject::get_verbose() >= 1)
217 0 : std::cout << "Found include directive: " << filename << std::endl;
218 :
219 0 : includeDirective = filename;
220 0 : return false;
221 : }
222 :
223 : ///////////////////////////////////////////////////////////////////////////
224 : //
225 : // The function 'opened_include_file' is called, whenever a file referred
226 : // by an #include directive was successfully located and opened.
227 : //
228 : // The parameter 'filename' contains the file system path of the
229 : // opened file (this is relative to the directory of the currently
230 : // processed file or a absolute path depending on the paths given as the
231 : // include search paths).
232 : //
233 : // The include_depth parameter contains the current include file depth.
234 : //
235 : // The is_system_include parameter denotes, whether the given file was
236 : // found as a result of a #include <...> directive.
237 : //
238 : ///////////////////////////////////////////////////////////////////////////
239 : template <typename ContextT>
240 : void
241 0 : opened_include_file(ContextT const& ctx, std::string const& relname,
242 : std::string const& absname, bool is_system_include)
243 : {
244 :
245 0 : if(SgProject::get_verbose() >= 1){
246 0 : std::cout << "openend include file relname: " << relname << " absname: " << absname << std::endl;
247 0 : std::cout << "it is connected to : " << includeDirective << std::endl;
248 : }
249 0 : attributeListMap->found_include_directive(includeDirectiveToken, relname, absname);
250 0 : }
251 :
252 : ///////////////////////////////////////////////////////////////////////////
253 : //
254 : // The function 'returning_from_include_file' is called, whenever an
255 : // included file is about to be closed after it's processing is complete.
256 : //
257 : ///////////////////////////////////////////////////////////////////////////
258 : // new signature
259 : template <typename ContextT>
260 : void
261 0 : returning_from_include_file(ContextT const& ctx)
262 : {}
263 :
264 : ///////////////////////////////////////////////////////////////////////////
265 : //
266 : // The function 'interpret_pragma' is called, whenever a #pragma wave
267 : // directive is found, which isn't known to the core Wave library.
268 : //
269 : // The parameter 'ctx' is a reference to the context object used for
270 : // instantiating the preprocessing iterators by the user.
271 : //
272 : // The parameter 'pending' may be used to push tokens back into the input
273 : // stream, which are to be used as the replacement text for the whole
274 : // #pragma wave() directive.
275 : //
276 : // The parameter 'option' contains the name of the interpreted pragma.
277 : //
278 : // The parameter 'values' holds the values of the parameter provided to
279 : // the pragma operator.
280 : //
281 : // The parameter 'act_token' contains the actual #pragma token, which may
282 : // be used for error output.
283 : //
284 : // If the return value is 'false', the whole #pragma directive is
285 : // interpreted as unknown and a corresponding error message is issued. A
286 : // return value of 'true' signs a successful interpretation of the given
287 : // #pragma.
288 : //
289 : ///////////////////////////////////////////////////////////////////////////
290 : template <typename ContextT, typename ContainerT>
291 : bool
292 0 : interpret_pragma(ContextT const &ctx, ContainerT &pending,
293 : typename ContextT::token_type const &option, ContainerT const &values,
294 : typename ContextT::token_type const &act_token)
295 : {
296 : return false;
297 : }
298 :
299 : ///////////////////////////////////////////////////////////////////////////
300 : //
301 : // The function 'defined_macro' is called, whenever a macro was defined
302 : // successfully.
303 : //
304 : // The parameter 'name' is a reference to the token holding the macro name.
305 : //
306 : // The parameter 'is_functionlike' is set to true, whenever the newly
307 : // defined macro is defined as a function like macro.
308 : //
309 : // The parameter 'parameters' holds the parameter tokens for the macro
310 : // definition. If the macro has no parameters or if it is a object like
311 : // macro, then this container is empty.
312 : //
313 : // The parameter 'definition' contains the token sequence given as the
314 : // replacement sequence (definition part) of the newly defined macro.
315 : //
316 : // The parameter 'is_predefined' is set to true for all macros predefined
317 : // during the initialisation phase of the library.
318 : //
319 : ///////////////////////////////////////////////////////////////////////////
320 : template <typename ContextT, typename TokenT, typename ParametersT,
321 : typename DefinitionT>
322 : void
323 0 : defined_macro(ContextT const& ctx, TokenT const& macro_name,
324 : bool is_functionlike, ParametersT const& parameters,
325 : DefinitionT const& definition, bool is_predefined)
326 : {
327 : #if 0
328 : // The "#if 0" was already here, but I also commented these lines out because '{' and '}' do not balance otherwise. The
329 : // unbalanced braces cause some problems for some tools (indenting, automatic enum detection, etc) [RPM 2010-10-11]
330 : // string name(macro_name.get_value().c_str());
331 : // //add all macros which is not a builtin macro to ROSE attribute
332 : // if(! (name.substr(0,2)=="__")
333 : // //&&(name.substr(name.length()-2,name.length())=="__"))
334 : // ){
335 : // //AS(041906) Filter out macros defined on the commandline as they are not
336 : // //part of a file and is therefore not interesting for macro-rewrapping.
337 : #endif
338 : //if(is_predefined!=true)
339 0 : if( macro_name.get_position().get_file().size()!=0 )
340 : {
341 0 : if( (macro_name.get_position().get_file()!="<built-in>") )
342 : {
343 0 : attributeListMap->defined_macro(macro_name, is_functionlike, parameters, definition, is_predefined);
344 :
345 : }
346 : }
347 : else
348 : {
349 0 : attributeListMap->defined_macro(macro_name, is_functionlike, parameters, definition, is_predefined);
350 : }
351 :
352 :
353 0 : token_type space = token_type(boost::wave::T_SPACE, " ", boost::wave::util::file_position_type(BOOST_WAVE_STRINGTYPE(ROSE_WAVE_PSEUDO_FILE), 0, 0));
354 0 : tokens.push_back(space);
355 0 : tokens.push_back(macro_name);
356 :
357 0 : boost::wave::util::file_position_type filepos;
358 : if (
359 0 : macro_name.get_position().get_file().find("<default>") == std::string::npos &&
360 0 : macro_name.get_position().get_file().find("<built-in>") == std::string::npos &&
361 0 : macro_name.get_position().get_file().find("<command line>") == std::string::npos &&
362 0 : macro_name.get_position().get_file().find("rose_edg_required_macros_and_functions") == std::string::npos)
363 0 : filepos = boost::wave::util::file_position_type(BOOST_WAVE_STRINGTYPE(ROSE_WAVE_PSEUDO_FILE), 0, 0);
364 : else
365 0 : filepos = boost::wave::util::file_position_type(macro_name.get_position().get_file(), 0, 0);
366 :
367 0 : if (is_functionlike)
368 : {
369 0 : token_type left = token_type(boost::wave::T_LEFTPAREN, "(", filepos);
370 0 : tokens.push_back(left);
371 0 : bool first = true;
372 0 : for (typename ParametersT::const_iterator i = parameters.begin(); i != parameters.end(); ++i)
373 : {
374 0 : if (!first)
375 : {
376 0 : token_type comma = token_type(boost::wave::T_COMMA, ",", filepos);
377 0 : tokens.push_back(comma);
378 : }
379 0 : tokens.push_back(*i);
380 0 : first = false;
381 : }
382 0 : token_type right = token_type(boost::wave::T_RIGHTPAREN, ")", filepos);
383 0 : tokens.push_back(right);
384 : }
385 0 : token_type space2 = token_type(boost::wave::T_SPACE, " ", filepos);
386 0 : tokens.push_back(space2);
387 0 : for (typename DefinitionT::const_iterator i = definition.begin(); i != definition.end(); ++i)
388 : {
389 0 : token_type space = token_type(boost::wave::T_SPACE, " ", filepos);
390 0 : tokens.push_back(space);
391 0 : tokens.push_back(*i);
392 : }
393 :
394 0 : }
395 :
396 :
397 : ///////////////////////////////////////////////////////////////////////////
398 : //
399 : // The function 'found_directive' is called, whenever a preprocessor
400 : // directive was encountered, but before the corresponding action is
401 : // executed.
402 : //
403 : // The parameter 'directive' is a reference to the token holding the
404 : // preprocessing directive.
405 : //
406 : ///////////////////////////////////////////////////////////////////////////
407 : template <typename ContextT, typename TokenT>
408 : bool
409 0 : found_directive(ContextT const& ctx, TokenT const& directive)
410 : {
411 0 : if(SgProject::get_verbose() >= 1)
412 0 : std::cout << "found_directive!" << std::endl;
413 :
414 0 : skipping = false;
415 0 : lastPreprocDirective = directive;
416 : // print the commented conditional directives
417 : using namespace boost::wave;
418 0 : token_id id = token_id(directive);
419 :
420 0 : bool record = true;
421 0 : switch(id)
422 : {
423 : case T_PP_LINE: //#line
424 : case T_PP_UNDEF: //#undef
425 : case T_PP_WARNING: //#warning
426 : case T_PP_DEFINE: //#define
427 : record = false;
428 : break; // handled via lastPreprocDirective in their own methods
429 : case T_PP_IF: //#if
430 : case T_PP_IFDEF: //#ifdef
431 : case T_PP_IFNDEF: //#ifndef
432 : case T_PP_ELSE: //#else
433 : case T_PP_ELIF: //#elif
434 : break; // appended too as necessary in skipped_token and evaluated_conditional_expression
435 : case T_PP_ENDIF: //#endif
436 : case T_PP_ERROR: //#error
437 : case T_PP_PRAGMA: //#pragma
438 : case T_PP_INCLUDE: //#include \"...\"
439 : break;
440 : case T_PP_QHEADER: //#include <...>
441 : case T_PP_HHEADER: //#include ...
442 : break;
443 : default: //<something else (" << directive.get_value() << ")>
444 : break;
445 : }
446 : if (record)
447 0 : attributeListMap->found_directive(directive);
448 :
449 0 : attributeListMap->flush_token_stream();
450 0 : updatingLastToken = true;
451 :
452 0 : if(SgProject::get_verbose() >= 1)
453 : {
454 0 : switch(id)
455 : {
456 0 : case T_PP_DEFINE: std::cout << "Directive is: #define\n"; break;
457 0 : case T_PP_IF: std::cout << "Directive is: #if\n"; break;
458 0 : case T_PP_IFDEF: std::cout << "Directive is: #ifdef\n"; break;
459 0 : case T_PP_IFNDEF: std::cout << "Directive is: #ifndef\n"; break;
460 0 : case T_PP_ELSE: std::cout << "Directive is: #else\n"; break;
461 0 : case T_PP_ELIF: std::cout << "Directive is: #elif\n"; break;
462 0 : case T_PP_ENDIF: std::cout << "Directive is: #endif\n"; break;
463 0 : case T_PP_ERROR: std::cout << "Directive is: #error\n"; break;
464 0 : case T_PP_LINE: std::cout << "Directive is: #line\n"; break;
465 0 : case T_PP_PRAGMA: std::cout << "Directive is: #pragma\n"; break;
466 0 : case T_PP_UNDEF: std::cout << "Directive is: #undef\n"; break;
467 0 : case T_PP_WARNING: std::cout << "Directive is: #warning\n"; break;
468 0 : case T_PP_INCLUDE: std::cout << "Directive is: #include \"...\"\n"; break;
469 0 : case T_PP_QHEADER: std::cout << "Directive is: #include <...>\n"; break;
470 0 : case T_PP_HHEADER: std::cout << "Directive is: #include ...\n"; break;
471 0 : default: std::cout << "Directive is: <something else>\n"; break;
472 : }
473 : }
474 :
475 0 : last_token = directive;
476 0 : tokens.push_back(directive);
477 0 : return false;
478 : }
479 :
480 : ///////////////////////////////////////////////////////////////////////////
481 : //
482 : // The function 'generated_token' is called, whenever a token is about
483 : // to be returned from the library
484 : //
485 : ///////////////////////////////////////////////////////////////////////////
486 : template <typename ContextT, typename TokenT>
487 0 : TokenT const& generated_token(ContextT const& ctx, TokenT const& token)
488 : {
489 0 : if(SgProject::get_verbose() >= 1)
490 0 : std::cout << "Generating token: ";
491 :
492 : using namespace boost::wave;
493 0 : token_id id = token_id(token);
494 :
495 0 : if(SgProject::get_verbose() >= 1)
496 : {
497 0 : switch(id)
498 : {
499 0 : case T_PP_DEFINE: std::cout << "#define: "; break;
500 0 : case T_PP_IF: std::cout << "#if: "; break;
501 0 : case T_PP_IFDEF: std::cout << "#ifdef: "; break;
502 0 : case T_PP_IFNDEF: std::cout << "#ifndef: "; break;
503 0 : case T_PP_ELSE: std::cout << "#else: "; break;
504 0 : case T_PP_ELIF: std::cout << "#elif: "; break;
505 0 : case T_PP_ENDIF: std::cout << "#endif: "; break;
506 0 : case T_PP_ERROR: std::cout << "#error: "; break;
507 0 : case T_PP_LINE: std::cout << "#line: "; break;
508 0 : case T_PP_PRAGMA: std::cout << "#pragma: "; break;
509 0 : case T_PP_UNDEF: std::cout << "#undef: "; break;
510 0 : case T_PP_WARNING: std::cout << "#warning: "; break;
511 0 : case T_PP_INCLUDE: std::cout << "#include \"...\": "; break;
512 0 : case T_PP_QHEADER: std::cout << "#include <...>: "; break;
513 0 : case T_PP_HHEADER: std::cout << "#include ...: "; break;
514 0 : default: std::cout << "<something else (" << id << ")>: "; break;
515 : }
516 : // std::cout << boost::wave::util::impl::as_string(token).c_str() << std::endl;
517 0 : if (token != token_type())
518 0 : std::cout << token.get_value().c_str() << std::endl;
519 : }
520 0 : return token;
521 : }
522 :
523 : ///////////////////////////////////////////////////////////////////////////
524 : //
525 : // The function 'evaluated_conditional_expression' is called, whenever a
526 : // conditional preprocessing expression was evaluated (the expression
527 : // given to a #if, #ifdef or #ifndef directive)
528 : //
529 : // The parameter 'expression' holds the non-expanded token sequence
530 : // comprising the evaluated expression.
531 : //
532 : // The parameter expression_value contains the result of the evaluation of
533 : // the expression in the current preprocessing context.
534 : //
535 : ///////////////////////////////////////////////////////////////////////////
536 : template <typename ContextT, typename TokenT, typename ContainerT>
537 : bool
538 0 : evaluated_conditional_expression(ContextT const& ctx, TokenT const& directive, ContainerT const& expression, bool expression_value)
539 : {
540 : using namespace boost::wave;
541 0 : token_id id = token_id(directive);
542 :
543 0 : ROSE_ASSERT(directive == lastPreprocDirective);
544 :
545 0 : if(SgProject::get_verbose() >= 1)
546 : {
547 0 : std::cout << "Conditional: ";
548 0 : switch(id)
549 : {
550 0 : case T_PP_DEFINE: std::cout << "#define: "; break;
551 0 : case T_PP_IF: std::cout << "#if: "; break;
552 0 : case T_PP_IFDEF: std::cout << "#ifdef: "; break;
553 0 : case T_PP_IFNDEF: std::cout << "#ifndef: "; break;
554 0 : case T_PP_ELSE: std::cout << "#else: "; break;
555 0 : case T_PP_ELIF: std::cout << "#elif: "; break;
556 0 : case T_PP_ENDIF: std::cout << "#endif: "; break;
557 0 : case T_PP_ERROR: std::cout << "#error: "; break;
558 0 : case T_PP_LINE: std::cout << "#line: "; break;
559 0 : case T_PP_PRAGMA: std::cout << "#pragma: "; break;
560 0 : case T_PP_UNDEF: std::cout << "#undef: "; break;
561 0 : case T_PP_WARNING: std::cout << "#warning: "; break;
562 0 : case T_PP_INCLUDE: std::cout << "#include \"...\": "; break;
563 0 : case T_PP_QHEADER: std::cout << "#include <...>: "; break;
564 0 : case T_PP_HHEADER: std::cout << "#include ...: "; break;
565 0 : default: std::cout << "<something else (" << id << ")>: "; break;
566 : }
567 : // std::cout << boost::wave::util::impl::as_string(token).c_str() << std::endl;
568 0 : std::cout << directive.get_value().c_str() << std::endl;
569 : }
570 0 : token_type space = token_type(boost::wave::T_SPACE, " ", boost::wave::util::file_position_type(BOOST_WAVE_STRINGTYPE(ROSE_WAVE_PSEUDO_FILE), 0, 0));
571 0 : token_container whitespace;
572 0 : whitespace.push_back(space);
573 : // directive was already given up in found_directive. here we add to the expression
574 0 : attributeListMap->update_token(lastPreprocDirective, whitespace, expression_value);
575 0 : attributeListMap->update_token(lastPreprocDirective, expression, expression_value);
576 :
577 : // tokens.push_back(space);
578 0 : for (typename ContainerT::const_iterator i = expression.begin(); i != expression.end(); ++i)
579 : {
580 0 : token_type space = token_type(boost::wave::T_SPACE, " ", boost::wave::util::file_position_type(BOOST_WAVE_STRINGTYPE(ROSE_WAVE_PSEUDO_FILE), 0, 0));
581 0 : tokens.push_back(space);
582 0 : tokens.push_back(*i);
583 : }
584 :
585 0 : token_type newline = token_type(boost::wave::T_NEWLINE, "\n", boost::wave::util::file_position_type(BOOST_WAVE_STRINGTYPE(ROSE_WAVE_PSEUDO_FILE), 0, 0));
586 0 : token_container whitespace2;
587 0 : whitespace2.push_back(newline);
588 0 : attributeListMap->update_token(lastPreprocDirective, whitespace2, expression_value);
589 :
590 : // King84 (2010.09.09):
591 : // Tell later guys to update the previous token as soon as we start skipping
592 : // This is important to associate conditions with skipped #elif directives
593 0 : updatingLastToken = true;
594 :
595 0 : last_token = directive;
596 0 : return false; // ok to continue, do not re-evaluate expression
597 : }
598 :
599 : ///////////////////////////////////////////////////////////////////////////
600 : //
601 : // The function 'skipped_token' is called, whenever a token is about to be
602 : // skipped due to a false preprocessor condition (code fragments to be
603 : // skipped inside the not evaluated conditional #if/#else/#endif branches).
604 : //
605 : // The parameter 'token' refers to the token to be skipped.
606 : //
607 : //
608 : ///////////////////////////////////////////////////////////////////////////
609 : template <typename ContextT, typename TokenT>
610 : void
611 0 : skipped_token(ContextT const& ctx, TokenT const& token)
612 : {
613 : using namespace boost::wave;
614 : //Process all tokens to be skipped except the ones without a filename,
615 : //e.g macro definitions from the commandline
616 0 : if (token.get_position().get_file().size() == 0)
617 : return;
618 0 : if (token == last_token && token.get_position() == last_token.get_position())
619 : return;
620 :
621 0 : token_id id = token_id(token);
622 0 : token_id lastid = token_id(lastPreprocDirective);
623 0 : if (lastPreprocDirective == token_type())
624 : {
625 0 : attributeListMap->skipped_token(token);
626 : }
627 0 : else if (token != lastPreprocDirective)
628 : {
629 0 : tokens.push_back(token);
630 :
631 0 : if (id == T_NEWLINE) // if it's a newline, it's the end of the previous token not that trailing-slash linesare already taken into account by wave
632 0 : updatingLastToken = false;
633 :
634 : // This is if we have to associated skipped tokens with a previous token. We do this for the last directive until we get a newline
635 0 : if (updatingLastToken)
636 : {
637 0 : token_container tc;
638 0 : tc.push_back(token);
639 0 : if(SgProject::get_verbose() >= 1)
640 0 : std::cout << "Updating previous token (" << lastPreprocDirective.get_value().c_str() << ") with token " << token.get_value().c_str() << std::endl;
641 0 : attributeListMap->update_token(lastPreprocDirective, tc, false);
642 : }
643 0 : else if (skipping || (lastid != T_PP_IF && lastid != T_PP_IFDEF && lastid != T_PP_IFNDEF && lastid != T_PP_ELIF)) // if we skipped the first newline
644 : {
645 0 : attributeListMap->skipped_token(token);
646 : }
647 : }
648 :
649 0 : switch(id)
650 : {
651 0 : case T_PP_DEFINE:
652 : case T_PP_IF:
653 : case T_PP_IFDEF:
654 : case T_PP_IFNDEF:
655 : case T_PP_ELSE:
656 : case T_PP_ELIF:
657 : case T_PP_ENDIF:
658 : case T_PP_ERROR:
659 : case T_PP_LINE:
660 : case T_PP_PRAGMA:
661 : case T_PP_UNDEF:
662 : case T_PP_WARNING:
663 : case T_PP_INCLUDE:
664 : case T_PP_QHEADER:
665 : case T_PP_HHEADER:
666 0 : lastPreprocDirective = token; // since found_directive doesn't get called
667 0 : break;
668 : default:
669 : break;
670 : }
671 :
672 0 : if(SgProject::get_verbose() >= 1)
673 : {
674 0 : switch(id)
675 : {
676 0 : case T_PP_DEFINE: std::cout << "Skipped: #define\n"; break;
677 0 : case T_PP_IF: std::cout << "Skipped: #if\n"; break;
678 0 : case T_PP_IFDEF: std::cout << "Skipped: #ifdef\n"; break;
679 0 : case T_PP_IFNDEF: std::cout << "Skipped: #ifndef\n"; break;
680 0 : case T_PP_ELSE: std::cout << "Skipped: #else\n"; break;
681 0 : case T_PP_ELIF: std::cout << "Skipped: #elif\n"; break;
682 0 : case T_PP_ENDIF: std::cout << "Skipped: #endif\n"; break;
683 0 : case T_PP_ERROR: std::cout << "Skipped: #error\n"; break;
684 0 : case T_PP_LINE: std::cout << "Skipped: #line\n"; break;
685 0 : case T_PP_PRAGMA: std::cout << "Skipped: #pragma\n"; break;
686 0 : case T_PP_UNDEF: std::cout << "Skipped: #undef\n"; break;
687 0 : case T_PP_WARNING: std::cout << "Skipped: #warning\n"; break;
688 0 : case T_PP_INCLUDE: std::cout << "Skipped: #include \"...\"\n"; break;
689 0 : case T_PP_QHEADER: std::cout << "Skipped: #include <...>\n"; break;
690 0 : case T_PP_HHEADER: std::cout << "Skipped: #include ...\n"; break;
691 0 : default: std::cout << "Skipped: <something else (" << token.get_value().c_str() << ")>\n"; break;
692 : }
693 0 : if (lastPreprocDirective != token_type())
694 0 : std::cout << "\tskipping is " << skipping << "\tupdatingLastToken is " << updatingLastToken << "\tlastPreprocDirective is " << lastPreprocDirective.get_value().c_str() << std::endl;
695 : }
696 0 : skipping = true; // skipping lets us skip the extra newline that shows up after #if statements
697 0 : last_token = token;
698 : }
699 :
700 : ///////////////////////////////////////////////////////////////////////////
701 : //
702 : // The function 'undefined_macro' is called, whenever a macro definition
703 : // was removed successfully.
704 : //
705 : // The parameter 'name' holds the name of the macro, which definition was
706 : // removed.
707 : //
708 : ///////////////////////////////////////////////////////////////////////////
709 : template <typename ContextT, typename TokenT>
710 : void
711 0 : undefined_macro(ContextT const& ctx, TokenT const& macro_name)
712 : {
713 0 : token_list_container tokListCont;
714 0 : tokListCont.push_back(macro_name);
715 0 : attributeListMap->found_directive(lastPreprocDirective,tokListCont, false);
716 :
717 0 : token_type space = token_type(boost::wave::T_SPACE, " ", boost::wave::util::file_position_type(BOOST_WAVE_STRINGTYPE(ROSE_WAVE_PSEUDO_FILE), 0, 0));
718 0 : tokens.push_back(space);
719 0 : tokens.push_back(macro_name);
720 0 : }
721 :
722 : #if 0
723 : template <typename ContainerT>
724 : void
725 : on_warning(ContainerT const& tokenStream)
726 : {
727 : attributeListMap->found_directive(lastPreprocDirective,tokenStream, false);
728 :
729 : std::cout << "ON TOKEN WARNING: " << boost::wave::util::impl::as_string(tokenStream) << std::endl;
730 : }
731 : #endif
732 :
733 : ///////////////////////////////////////////////////////////////////////////
734 : //
735 : // The function 'found_warning_directive' is called, will be called by the
736 : // library, whenever a #warning directive is found.
737 : //
738 : // The parameter 'ctx' is a reference to the context object used for
739 : // instantiating the preprocessing iterators by the user.
740 : //
741 : // The parameter 'message' references the argument token sequence of the
742 : // encountered #warning directive.
743 : //
744 : ///////////////////////////////////////////////////////////////////////////
745 : template <typename ContextT, typename ContainerT>
746 : bool
747 0 : found_warning_directive(ContextT const& ctx, ContainerT const& message)
748 : {
749 0 : attributeListMap->found_directive(lastPreprocDirective,message, false);
750 :
751 0 : if(SgProject::get_verbose() >= 1)
752 0 : std::cout << "ON TOKEN WARNING: " << boost::wave::util::impl::as_string(message) << std::endl;
753 :
754 : //Do not throw warning message
755 0 : return true;
756 : }
757 :
758 :
759 : ///////////////////////////////////////////////////////////////////////////
760 : //
761 : // The function 'found_line_directive' will be called by the library
762 : // whenever a #line directive is found.
763 : //
764 : // The parameter 'ctx' is a reference to the context object used for
765 : // instantiating the preprocessing iterators by the user.
766 : //
767 : // The parameter 'arguments' references the argument token sequence of the
768 : // encountered #line directive.
769 : //
770 : // The parameter 'line' contains the recognized line number from the #line
771 : // directive.
772 : //
773 : // The parameter 'filename' references the recognized file name from the
774 : // #line directive (if there was one given).
775 : //
776 : ///////////////////////////////////////////////////////////////////////////
777 : template <typename ContextT, typename ContainerT>
778 : void
779 0 : found_line_directive(ContextT const& ctx, ContainerT const& arguments, unsigned int line, std::string const& filename)
780 : {
781 0 : std::string filenameString(filename.c_str());
782 :
783 0 : if (SgProject::get_verbose() >= 1)
784 0 : std::cout << "On line found" << std::endl;
785 : /*
786 : token_list_container toexpand;
787 : std::copy(first, make_ref_transform_iterator(end, boost::wave::util::get_value),
788 : std::inserter(toexpand, toexpand.end()));
789 : */
790 :
791 0 : attributeListMap->found_directive(lastPreprocDirective,arguments, false);
792 :
793 0 : token_type space = token_type(boost::wave::T_SPACE, " ", boost::wave::util::file_position_type(BOOST_WAVE_STRINGTYPE(ROSE_WAVE_PSEUDO_FILE), 0, 0));
794 0 : token_container whitespace;
795 0 : whitespace.push_back(space);
796 : // directive was already given up in found_directive. here we add to it the arguments
797 0 : attributeListMap->update_token(lastPreprocDirective, whitespace, false);
798 0 : attributeListMap->update_token(lastPreprocDirective, arguments, false);
799 :
800 : // tokens.push_back(space);
801 0 : for (typename ContainerT::const_iterator i = arguments.begin(); i != arguments.end(); ++i)
802 : {
803 0 : token_type space = token_type(boost::wave::T_SPACE, " ", boost::wave::util::file_position_type(BOOST_WAVE_STRINGTYPE(ROSE_WAVE_PSEUDO_FILE), 0, 0));
804 0 : tokens.push_back(space);
805 0 : tokens.push_back(*i);
806 : }
807 0 : }
808 :
809 :
810 : template <typename ContextT, typename TokenT>
811 : bool
812 0 : may_skip_whitespace(ContextT const& ctx, TokenT& token, bool& skipped_newline)
813 : {
814 0 : if (token == lastPreprocDirective && token.get_position() == lastPreprocDirective.get_position())
815 : return false;
816 0 : if (token == last_token && token.get_position() == last_token.get_position())
817 : return false;
818 0 : if (SgProject::get_verbose() >= 1)
819 0 : if (token != TokenT())
820 0 : std::cout << "MAX_SKIP_WHITESPACE: " << token.get_value().c_str() << std::endl;
821 :
822 : using namespace boost::wave;
823 0 : token_id id = token_id(token);
824 0 : if (id != T_EOF && id != T_EOI)
825 0 : tokens.push_back(token);
826 0 : if (id != T_EOF && id != T_EOI && id != T_NEWLINE)
827 : {
828 0 : if (SgProject::get_verbose() >= 1)
829 0 : std::cout << "Normal reported" << std::endl;
830 0 : attributeListMap->may_skip_whitespace(ctx, token, skipped_newline);
831 : }
832 0 : else if (skipping) // then we need to flush tokens
833 : {
834 0 : if (SgProject::get_verbose() >= 1)
835 0 : std::cout << "Skip leads to flushing" << std::endl;
836 0 : attributeListMap->flush_token_stream();
837 : }
838 : else
839 : {
840 0 : if (SgProject::get_verbose() >= 1)
841 0 : std::cout << "EOF or newline leads to flushing" << std::endl;
842 0 : attributeListMap->flush_token_stream();
843 : }
844 : return false;
845 : }
846 :
847 : template <typename ContextT, typename ExceptionT>
848 : void throw_exception(ContextT const &ctx, ExceptionT const& e)
849 : {
850 : if (SgProject::get_verbose() >= 1)
851 : std::cout << "THROW_EXCEPTION" << std::endl;
852 : }
853 :
854 : template <typename ContextT>
855 0 : void detected_include_guard(ContextT const &ctx, std::string const& filename, std::string const& include_guard)
856 : {
857 0 : if (SgProject::get_verbose() >= 1)
858 0 : std::cout << "DETECTED_INCLUDE_GUARD" << include_guard << " in file " << filename << std::endl;
859 0 : }
860 :
861 : template <typename ContextT, typename TokenT>
862 0 : void detected_pragma_once(ContextT const &ctx, TokenT const& pragma_token, std::string const& filename)
863 : {
864 0 : if (SgProject::get_verbose() >= 1)
865 0 : std::cout << "DETECTED_PRAGMA_ONCE " << pragma_token.get_value() << " in file " << filename << std::endl;
866 0 : }
867 :
868 : template <typename ContextT, typename ContainerT>
869 : bool found_error_directive(ContextT const &ctx, ContainerT const &message)
870 : {
871 : if (SgProject::get_verbose() >= 1)
872 : std::cout << "FOUND_ERROR_DIRECTIVE" << std::endl;
873 : return false;
874 : }
875 :
876 :
877 : #if 0
878 : bool need_comment;
879 : #endif
880 : };
881 :
882 : #endif // !defined(BOOST_WAVE_ADVANCED_PREPROCESSING_HOOKS_INCLUDED)
883 :
|