Re: [CEDET-devel] [cedet-semantic] multiple conditions in #ifdef not parsed correctly
Brought to you by:
zappo
From: Eric M. L. <er...@si...> - 2009-11-18 23:57:31
|
Hi Brian, Your assessment is correct. The preprocessor in CEDET for C doesn't do much for complex expressions. It's been in there for a couple years, and you're the first person to notice. :) The reason is that it isn't really a very simple problem. We are deep in the lexical analyzer, and suddenly we need a lexical analyzer to solve this problem. Right now we just have a bit of a short cut for the simple case of a single expression. Ideally, we'd use the lexical analyzer and a parser to solve the problem, except we are trying to do a single pass lexical analysis, instead of the tradition 2 pass that gcc and most other compilers employ. If you'd like to take a crack at this problem in semantic-c-do-lex-if, I expect that the solution is to change the regex in semantic-lex-c-if to exclude the expression, and to extract it 'by hand' in semantic-c-do-lex-if where it could then be evaluated. If you don't have time, hopefully I can examine this more after Thanksgiving. If your patch is over 10 lines long or so, I'll also need a release so your changes can be included in Emacs. Also, if it helps, you can disable semantic-c-obey-conditional-section-parsing-flag to just go with the 'whatever' approach. :) Eric Brian J. Carlson wrote: > Thank you for such a wonderful set of tools. > > I have recently started using CEDET with boost and have narrowed down a > parsing "problem." > > The problem is that #ifdef pre-parsing is not evaluating correctly. > > An example of this type of statement is as follows: > #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) > > > I am using emacs 23: > "GNU Emacs 23.1.50.1 (x86_64-pc-linux-gnu, GTK+ Version 2.18.0) > of 2009-09-27 on crested, modified by Debian" > with CEDET from the cvs repository at cedet.cvs.sourceforge.net) > > I executed the following emacs-lisp after starting > emacs via 'emacs --no-init'): > > ,---- > | (if (not (featurep 'cedet)) > | (load-file "~/.elisp/cedet/common/cedet.elc")) > | (global-ede-mode t) > | (require 'ede-cpp-root) > | (require 'semantic-gcc) > | (ede-cpp-root-project "cedet-test" > | :file "~/src/cedet-test/test.cpp") > | (semantic-load-enable-excessive-code-helpers) > | (require 'semantic-ia) > `---- > > Here is the contents of test.cpp: > ,---- > | #undef BOOST_NO_MEMBER_TEMPLATES > | #undef BOOST_MSVC6_MEMBER_TEMPLATES > | > | > | #if defined(BOOST_NO_MEMBER_TEMPLATES) > | int mymethod(int myint) { > | return myint++; > | } > | #else > | // This is what should be recognized and it is > | int mymethod(int myint) { > | return myint + 2; > | } > | #endif > | > | > | #if !defined(BOOST_MSVC6_MEMBER_TEMPLATES) > | // This is what should be recognized an it is > | void mysecondmethod(int) { > | return; > | } > | #else > | void mysecondmethod(unsigned int) { > | return; > | } > | #endif > | > | // So BOOST_NO_MEMBER_TEMPLATES is NOT defined > | // and BOOST_MSVC6_MEMBER_TEMPLATES is NOT defined > | > | // so this is #if false && true --> > | // should yield false, but it yields true > | #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) > | // This should not be the value that is parsed but it is... > | void definedBOOST_NO_MEMBER_TEMPLATES_AND_bang_BOOST_MSVC6() > | { > | return; > | } > | #else > | // This is what should be parsed but it is not > | void not_definedBOOST_NO_MEMBER_TEMPLATES_AND_bang_BOOST_MSVC6() > | { > | return; > | } > | #endif > | > | // (senator-force-refresh) > `---- > > > At first glance (and I mean glance), it looks like the parser is evaluating > if "BOOST_MSVC6_MEMBER_TEMPLATES && !definedBOOST_NO_MEMBER_TEMPLATES_AND_bang_BOOST_MSVC6)" is defined > rather than seeing this as two separate conditions. Or the lexer is not dealing with the && or || in the > #if xxxxxxxxxx && xxxxxxxx type of pre-processing directive. > > Any help with this would be greatly appreciated. > > Thanks, > ;-Brian > |