2009-03-20 14:57:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/**************************************************************************
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* *  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								* *  This  file  is  part  of  Qt  Creator  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* *  
						 
					
						
							
								
									
										
										
										
											2012-01-26 18:33:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								* *  Copyright  ( c )  2012  Nokia  Corporation  and / or  its  subsidiary ( - ies ) .  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								* *  
						 
					
						
							
								
									
										
										
										
											2012-07-19 12:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								* *  Contact :  http : //www.qt-project.org/
  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								* *  
						 
					
						
							
								
									
										
										
										
											2008-12-02 14:17:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								* *  
						 
					
						
							
								
									
										
										
										
											2009-02-25 09:15:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								* *  GNU  Lesser  General  Public  License  Usage  
						 
					
						
							
								
									
										
										
										
											2008-12-02 14:17:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								* *  
						 
					
						
							
								
									
										
										
										
											2011-04-13 08:42:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								* *  This  file  may  be  used  under  the  terms  of  the  GNU  Lesser  General  Public  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* *  License  version  2.1  as  published  by  the  Free  Software  Foundation  and  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* *  appearing  in  the  file  LICENSE . LGPL  included  in  the  packaging  of  this  file .  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* *  Please  review  the  following  information  to  ensure  the  GNU  Lesser  General  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* *  Public  License  version  2.1  requirements  will  be  met :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* *  http : //www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  
						 
					
						
							
								
									
										
										
										
											2008-12-02 14:17:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								* *  
						 
					
						
							
								
									
										
										
										
											2010-12-17 16:01:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								* *  In  addition ,  as  a  special  exception ,  Nokia  gives  you  certain  additional  
						 
					
						
							
								
									
										
										
										
											2011-04-13 08:42:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								* *  rights .  These  rights  are  described  in  the  Nokia  Qt  LGPL  Exception  
						 
					
						
							
								
									
										
										
										
											2010-12-17 16:01:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								* *  version  1.1 ,  included  in  the  file  LGPL_EXCEPTION . txt  in  this  package .  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* *  
						 
					
						
							
								
									
										
										
										
											2011-04-13 08:42:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								* *  Other  Usage  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* *  Alternatively ,  this  file  may  be  used  in  accordance  with  the  terms  and  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* *  conditions  contained  in  a  signed  written  agreement  between  you  and  Nokia .  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* *  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								* *  
						 
					
						
							
								
									
										
										
										
											2009-02-25 09:15:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Copyright  2005  Roberto  Raggi  < roberto @ kdevelop . org > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Permission  to  use ,  copy ,  modify ,  distribute ,  and  sell  this  software  and  its 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  documentation  for  any  purpose  is  hereby  granted  without  fee ,  provided  that 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  the  above  copyright  notice  appear  in  all  copies  and  that  both  that 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  copyright  notice  and  this  permission  notice  appear  in  supporting 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  documentation . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  The  above  copyright  notice  and  this  permission  notice  shall  be  included  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  all  copies  or  substantial  portions  of  the  Software . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  THE  SOFTWARE  IS  PROVIDED  " AS IS " ,  WITHOUT  WARRANTY  OF  ANY  KIND ,  EXPRESS  OR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  IMPLIED ,  INCLUDING  BUT  NOT  LIMITED  TO  THE  WARRANTIES  OF  MERCHANTABILITY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  FITNESS  FOR  A  PARTICULAR  PURPOSE  AND  NONINFRINGEMENT .   IN  NO  EVENT  SHALL  THE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  KDEVELOP  TEAM  BE  LIABLE  FOR  ANY  CLAIM ,  DAMAGES  OR  OTHER  LIABILITY ,  WHETHER  IN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  AN  ACTION  OF  CONTRACT ,  TORT  OR  OTHERWISE ,  ARISING  FROM ,  OUT  OF  OR  IN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  CONNECTION  WITH  THE  SOFTWARE  OR  THE  USE  OR  OTHER  DEALINGS  IN  THE  SOFTWARE . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "pp.h" 
  
						 
					
						
							
								
									
										
										
										
											2009-05-15 16:01:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "pp-cctype.h" 
  
						 
					
						
							
								
									
										
										
										
											2008-12-02 15:08:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <Control.h> 
  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <Lexer.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <Token.h> 
  
						 
					
						
							
								
									
										
										
										
											2009-03-02 19:03:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <Literals.h> 
  
						 
					
						
							
								
									
										
										
										
											2009-03-19 18:15:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <cctype> 
  
						 
					
						
							
								
									
										
										
										
											2009-03-02 19:03:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <QtDebug> 
  
						 
					
						
							
								
									
										
										
										
											2012-02-15 10:42:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <QList> 
  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <QDate> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <QTime> 
  
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <QPair> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <list> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <algorithm> 
  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define NO_DEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef NO_DEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#   include <iostream> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif  // NO_DEBUG
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 18:11:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <deque> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								namespace  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								enum  {  
						 
					
						
							
								
									
										
										
										
											2012-03-30 14:21:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    MAX_TOKEN_EXPANSION_COUNT  =  5000 , 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-20 21:11:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    MAX_TOKEN_BUFFER_DEPTH  =  16000  // for when macros are using some kind of right-folding, this is the list of "delayed" buffers waiting to be expanded after the current one.
 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								template < typename  _T >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  ScopedSwap  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    _T  oldValue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    _T  & ref ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								public :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ScopedSwap ( _T  & var ,  _T  newValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        :  oldValue ( newValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ,  ref ( var ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        std : : swap ( ref ,  oldValue ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ~ ScopedSwap ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        std : : swap ( ref ,  oldValue ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								typedef  ScopedSwap < bool >  ScopedBoolSwap ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								typedef  ScopedSwap < unsigned >  ScopedUnsignedSwap ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  // anonymous namespace
  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 10:41:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								namespace  CPlusPlus  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								namespace  Internal  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  TokenBuffer  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-04-18 18:11:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    std : : deque < PPToken >  tokens ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  Macro  * macro ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TokenBuffer  * next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-30 14:21:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TokenBuffer ( const  PPToken  * start ,  const  PPToken  * end ,  const  Macro  * macro ,  TokenBuffer  * next ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        :  tokens ( start ,  end ) ,  macro ( macro ) ,  next ( next ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-30 14:21:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bool  isBlocked ( const  Macro  * macro )  const  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! macro ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( const  TokenBuffer  * it  =  this ;  it ;  it  =  it - > next ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-30 14:21:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( it - > macro  = =  macro  & &  it - > macro - > name ( )  = =  macro - > name ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 10:41:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								struct  Value  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    enum  Kind  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Kind_Long , 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 21:47:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Kind_ULong 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 10:41:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Kind  kind ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    union  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        long  l ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        unsigned  long  ul ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Value ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        :  kind ( Kind_Long ) ,  l ( 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    {  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  bool  is_ulong  ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    {  return  kind  = =  Kind_ULong ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  void  set_ulong  ( unsigned  long  v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ul  =  v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        kind  =  Kind_ULong ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  void  set_long  ( long  v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        l  =  v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        kind  =  Kind_Long ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  bool  is_zero  ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    {  return  l  = =  0 ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define PP_DEFINE_BIN_OP(name, op) \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  Value  operator  op ( const  Value  & other )  const  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    {  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Value  v  =  * this ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( v . is_ulong  ( )  | |  other . is_ulong  ( ) )  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            v . set_ulong  ( v . ul  op  other . ul ) ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            v . set_long  ( v . l  op  other . l ) ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  v ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_add ,  + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_sub ,  - ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_mult ,  * ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_div ,  / ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_mod ,  % ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_lhs ,  < < ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_rhs ,  > > ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_lt ,  < ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_gt ,  > ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_le ,  < = ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_ge ,  > = ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_eq ,  = = ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_ne ,  ! = ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_bit_and ,  & ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_bit_or ,  | ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_bit_xor ,  ^ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_and ,  & & ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PP_DEFINE_BIN_OP ( op_or ,  | | ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef PP_DEFINE_BIN_OP 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  // namespace Internal
  
						 
					
						
							
								
									
										
										
										
											2011-02-04 09:52:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  // namespace CPlusPlus
  
						 
					
						
							
								
									
										
										
										
											2009-03-03 10:41:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								using  namespace  CPlusPlus ;  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								using  namespace  CPlusPlus : : Internal ;  
						 
					
						
							
								
									
										
										
										
											2009-03-03 10:41:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								namespace  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								inline  bool  isContinuationToken ( const  PPToken  & tk )  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  tk . isNot ( T_EOF_SYMBOL )  & &  ( !  tk . newline ( )  | |  tk . joined ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Macro  * macroDefinition ( const  ByteArrayRef  & name ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       unsigned  offset , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       unsigned  line , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       Environment  * env , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       Client  * client ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 16:00:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Macro  * m  =  env - > resolve ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( client )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            client - > passedMacroDefinitionCheck ( offset ,  line ,  * m ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 16:00:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            client - > failedMacroDefinitionCheck ( offset ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-12 15:24:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  m ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 16:00:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								class  RangeLexer  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  Token  * first ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  Token  * last ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Token  trivial ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								public :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  RangeLexer ( const  Token  * first ,  const  Token  * last ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        :  first ( first ) ,  last ( last ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // WARN: `last' must be a valid iterator.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        trivial . offset  =  last - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  operator  bool ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    {  return  first  ! =  last ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  bool  isValid ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    {  return  first  ! =  last ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  int  size ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    {  return  std : : distance ( first ,  last ) ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  const  Token  * dot ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    {  return  first ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  const  Token  & operator * ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( first  ! =  last ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  * first ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  trivial ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  const  Token  * operator - > ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( first  ! =  last ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  first ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  & trivial ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  RangeLexer  & operator + + ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        + + first ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  * this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  ExpressionEvaluator  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ExpressionEvaluator ( const  ExpressionEvaluator  & other ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    void  operator  =  ( const  ExpressionEvaluator  & other ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								public :  
						 
					
						
							
								
									
										
										
										
											2009-09-25 16:00:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ExpressionEvaluator ( Client  * client ,  Environment  * env ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        :  client ( client ) ,  env ( env ) ,  _lex ( 0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    {  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Value  operator ( ) ( const  Token  * firstToken ,  const  Token  * lastToken , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                     const  QByteArray  & source ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this - > source  =  source ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  Value  previousValue  =  switchValue ( Value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        RangeLexer  tmp ( firstToken ,  lastToken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        RangeLexer  * previousLex  =  _lex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        _lex  =  & tmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        process_expression ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        _lex  =  previousLex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  switchValue ( previousValue ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								protected :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Value  switchValue ( const  Value  & value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        Value  previousValue  =  _value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        _value  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  previousValue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  isTokenDefined ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ( * _lex ) - > isNot ( T_IDENTIFIER ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 17:28:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  ByteArrayRef  spell  =  tokenSpell ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        if  ( spell . size ( )  ! =  7 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  spell  = =  " defined " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 17:10:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  char  * tokenPosition ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  source . constData ( )  +  ( * _lex ) - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  tokenLength ( )  const 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  ( * _lex ) - > f . length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 17:28:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ByteArrayRef  tokenSpell ( )  const 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 17:28:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  ByteArrayRef ( tokenPosition ( ) ,  tokenLength ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    inline  void  process_expression ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    {  process_constant_expression ( ) ;  } 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    void  process_primary ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-10 15:44:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ( * _lex ) - > is ( T_NUMERIC_LITERAL ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 17:10:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  char  * spell  =  tokenPosition ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            int  len  =  tokenLength ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            while  ( len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  char  ch  =  spell [ len  -  1 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 12:33:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 17:10:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( !  ( ch  = =  ' u '  | |  ch  = =  ' U '  | |  ch  = =  ' l '  | |  ch  = =  ' L ' ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 12:33:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 17:10:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                - - len ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 12:33:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 17:10:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  char  * end  =  spell  +  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            char  * vend  =  const_cast < char  * > ( end ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _value . set_long ( strtol ( spell ,  & vend ,  0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( isTokenDefined ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ( * _lex ) - > is ( T_IDENTIFIER ) )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                _value . set_long ( macroDefinition ( tokenSpell ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                ( * _lex ) - > offset , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                ( * _lex ) - > lineno ,  env ,  client ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                ! =  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( ( * _lex ) - > is ( T_LPAREN ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ( * _lex ) - > is ( T_IDENTIFIER ) )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    _value . set_long ( macroDefinition ( tokenSpell ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                    ( * _lex ) - > offset , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                    ( * _lex ) - > lineno , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                    env ,  client ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    ! =  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                    + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( ( * _lex ) - > is ( T_RPAREN ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( ( * _lex ) - > is ( T_IDENTIFIER ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _value . set_long ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( ( * _lex ) - > is ( T_MINUS ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            process_primary ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _value . set_long ( -  _value . l ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( ( * _lex ) - > is ( T_PLUS ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            process_primary ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-27 09:55:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( ( * _lex ) - > is ( T_TILDE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            process_primary ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _value . set_long ( ~  _value . l ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( ( * _lex ) - > is ( T_EXCLAIM ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            process_primary ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _value . set_long ( _value . is_zero ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( ( * _lex ) - > is ( T_LPAREN ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            process_expression ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ( * _lex ) - > is ( T_RPAREN ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Value  process_expression_with_operator_precedence ( const  Value  & lhs ,  int  minPrecedence ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Value  result  =  lhs ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        while  ( precedence ( ( * _lex ) - > kind ( ) )  > =  minPrecedence )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  int  oper  =  ( * _lex ) - > kind ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  int  operPrecedence  =  precedence ( oper ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            process_primary ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            Value  rhs  =  _value ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            for  ( int  LA_token_kind  =  ( * _lex ) - > kind ( ) ,  LA_precedence  =  precedence ( LA_token_kind ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 17:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    LA_precedence  >  operPrecedence  & &  isBinaryOperator ( LA_token_kind ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    LA_token_kind  =  ( * _lex ) - > kind ( ) ,  LA_precedence  =  precedence ( LA_token_kind ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                rhs  =  process_expression_with_operator_precedence ( rhs ,  LA_precedence ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            result  =  evaluate_expression ( oper ,  result ,  rhs ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    void  process_constant_expression ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        process_primary ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        _value  =  process_expression_with_operator_precedence ( _value ,  precedence ( T_PIPE_PIPE ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ( * _lex ) - > is ( T_QUESTION ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  Value  cond  =  _value ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            + + ( * _lex ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            process_constant_expression ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Value  left  =  _value ,  right ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ( * _lex ) - > is ( T_COLON ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                + + ( * _lex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                process_constant_expression ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                right  =  _value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            _value  =  !  cond . is_zero ( )  ?  left  :  right ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								private :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    inline  int  precedence ( int  tokenKind )  const 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        switch  ( tokenKind )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_PIPE_PIPE :        return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_AMPER_AMPER :      return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_PIPE :             return  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_CARET :            return  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_AMPER :            return  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_EQUAL_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_EXCLAIM_EQUAL :    return  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_GREATER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_LESS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_LESS_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_GREATER_EQUAL :    return  6 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_LESS_LESS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_GREATER_GREATER :  return  7 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_PLUS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_MINUS :            return  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_STAR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_SLASH : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_PERCENT :          return  9 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  inline  bool  isBinaryOperator ( int  tokenKind ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        switch  ( tokenKind )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_PIPE_PIPE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_AMPER_AMPER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_PIPE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_CARET : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_AMPER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_EQUAL_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_EXCLAIM_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_GREATER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_LESS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_LESS_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_GREATER_EQUAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_LESS_LESS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_GREATER_GREATER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_PLUS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_MINUS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_STAR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_SLASH : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_PERCENT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  inline  Value  evaluate_expression ( int  tokenKind ,  const  Value  & lhs ,  const  Value  & rhs ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-28 15:22:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        switch  ( tokenKind )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_PIPE_PIPE :        return  lhs  | |  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_AMPER_AMPER :      return  lhs  & &  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_PIPE :             return  lhs  |  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_CARET :            return  lhs  ^  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_AMPER :            return  lhs  &  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_EQUAL_EQUAL :      return  lhs  = =  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_EXCLAIM_EQUAL :    return  lhs  ! =  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_GREATER :          return  lhs  >  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_LESS :             return  lhs  <  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_LESS_EQUAL :       return  lhs  < =  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_GREATER_EQUAL :    return  lhs  > =  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_LESS_LESS :        return  lhs  < <  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_GREATER_GREATER :  return  lhs  > >  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_PLUS :             return  lhs  +  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_MINUS :            return  lhs  -  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_STAR :             return  lhs  *  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_SLASH :            return  rhs . is_zero ( )  ?  Value ( )  :  lhs  /  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  T_PERCENT :          return  rhs . is_zero ( )  ?  Value ( )  :  lhs  %  rhs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								private :  
						 
					
						
							
								
									
										
										
										
											2009-09-25 16:00:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Client  * client ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    Environment  * env ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    QByteArray  source ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RangeLexer  * _lex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Value  _value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  // end of anonymous namespace
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Preprocessor : : State : : State ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :  m_lexer ( 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_skipping ( MAX_LEVEL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_trueTest ( MAX_LEVEL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_ifLevel ( 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_tokenBuffer ( 0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-30 14:21:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ,  m_tokenBufferDepth ( 0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ,  m_inPreprocessorDirective ( false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_result ( 0 ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ,  m_markExpandedTokens ( true ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ,  m_noLines ( false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_inCondition ( false ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ,  m_offsetRef ( 0 ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ,  m_lineRef ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_expansionStatus ( NotExpanding ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_skipping [ m_ifLevel ]  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_trueTest [ m_ifLevel ]  =  false ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_expansionResult . reserve ( 256 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-22 15:45:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//#define COMPRESS_TOKEN_BUFFER
  
						 
					
						
							
								
									
										
										
										
											2012-03-30 14:21:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : State : : pushTokenBuffer ( const  PPToken  * start ,  const  PPToken  * end ,  const  Macro  * macro )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_tokenBufferDepth  < =  MAX_TOKEN_BUFFER_DEPTH )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef COMPRESS_TOKEN_BUFFER 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // This does not work correctly for boost's preprocessor library, or that library exposes a bug in the code.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( macro  | |  ! m_tokenBuffer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_tokenBuffer  =  new  TokenBuffer ( start ,  end ,  macro ,  m_tokenBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + m_tokenBufferDepth ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_tokenBuffer - > tokens . insert ( m_tokenBuffer - > tokens . begin ( ) ,  start ,  end ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-22 15:45:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        unsigned  tkCount  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( TokenBuffer  * it  =  m_tokenBuffer ;  it ;  it  =  m_tokenBuffer - > next ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tkCount  + =  it - > tokens . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        qDebug ( ) < < " New depth: "  < <  m_tokenBufferDepth  < <  " with total token count: "  < <  tkCount ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-30 14:21:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_tokenBuffer  =  new  TokenBuffer ( start ,  end ,  macro ,  m_tokenBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        + + m_tokenBufferDepth ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Preprocessor : : State : : popTokenBuffer ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TokenBuffer  * r  =  m_tokenBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_tokenBuffer  =  m_tokenBuffer - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    delete  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_tokenBufferDepth ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        - - m_tokenBufferDepth ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Preprocessor : : Preprocessor ( Client  * client ,  Environment  * env )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    :  m_client ( client ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_env ( env ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_expandMacros ( true ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  m_keepComments ( false ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-19 10:35:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								QByteArray  Preprocessor : : run ( const  QString  & fileName ,  const  QString  & source )  
						 
					
						
							
								
									
										
										
										
											2009-06-15 15:38:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-04-19 10:35:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  run ( fileName ,  source . toLatin1 ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-15 15:38:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-19 10:35:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								QByteArray  Preprocessor : : run ( const  QString  & fileName ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                             const  QByteArray  & source , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                             bool  noLines , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                             bool  markGeneratedTokens ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-02 11:30:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_scratchBuffer . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-02 11:30:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    QByteArray  preprocessed ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    preprocess ( fileName ,  source ,  & preprocessed ,  noLines ,  markGeneratedTokens ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-02 11:30:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  preprocessed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-04 20:54:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Preprocessor : : expandMacros ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  m_expandMacros ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-04 20:54:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Preprocessor : : setExpandMacros ( bool  expandMacros )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_expandMacros  =  expandMacros ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-04 20:54:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-23 14:05:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Preprocessor : : keepComments ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  m_keepComments ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-23 14:05:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Preprocessor : : setKeepComments ( bool  keepComments )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_keepComments  =  keepComments ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-23 14:05:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : generateOutputLineMarker ( unsigned  lineno )  
						 
					
						
							
								
									
										
										
										
											2012-03-30 13:01:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    maybeStartOutputLine ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    QByteArray  marker ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    marker . reserve ( 64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    marker . append ( " #  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    marker . append ( QByteArray : : number ( lineno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    marker . append ( "   \" " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    marker . append ( m_env - > currentFileUtf8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    marker . append ( " \" \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    writeOutput ( marker ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-30 13:01:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : handleDefined ( PPToken  * tk )  
						 
					
						
							
								
									
										
										
										
											2009-03-03 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-04-19 17:30:03 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ScopedBoolSwap  s ( m_state . m_inPreprocessorDirective ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    unsigned  lineno  =  tk - > lineno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    lex ( tk ) ;  // consume "defined" token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  lparenSeen  =  tk - > is ( T_LPAREN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( lparenSeen ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lex ( tk ) ;  // consume "(" token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( tk - > isNot ( T_IDENTIFIER ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //### TODO: generate error message
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    PPToken  idToken  =  * tk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lex ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( tk - > isNot ( T_POUND_POUND ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lex ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( tk - > is ( T_IDENTIFIER ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            idToken  =  generateConcatenated ( idToken ,  * tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  while  ( isContinuationToken ( * tk ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-24 18:50:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 14:33:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( lparenSeen  & &  tk - > is ( T_RPAREN ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lex ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pushToken ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    QByteArray  result ( 1 ,  ' 0 ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_env - > resolve ( idToken . asByteArrayRef ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        result [ 0 ]  =  ' 1 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 11:34:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    * tk  =  generateToken ( T_NUMERIC_LITERAL ,  result . constData ( ) ,  result . size ( ) ,  lineno ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : pushToken ( Preprocessor : : PPToken  * tk )  
						 
					
						
							
								
									
										
										
										
											2009-03-03 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  PPToken  currentTokenBuffer [ ]  =  {  * tk  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-30 14:21:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_state . pushTokenBuffer ( currentTokenBuffer ,  currentTokenBuffer  +  1 ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-03-03 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : lex ( PPToken  * tk )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								_Lagain :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_state . m_tokenBuffer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . m_tokenBuffer - > tokens . empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-30 14:21:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_state . popTokenBuffer ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            goto  _Lagain ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        * tk  =  m_state . m_tokenBuffer - > tokens . front ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . m_tokenBuffer - > tokens . pop_front ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tk - > setSource ( m_state . m_source ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . m_lexer - > scan ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Adjust token's line number in order to take into account the environment reference.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tk - > lineno  + =  m_state . m_lineRef  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								_Lclassify :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( !  m_state . m_inPreprocessorDirective )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( tk - > newline ( )  & &  tk - > is ( T_POUND ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            handlePreprocessorDirective ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            goto  _Lclassify ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( tk - > newline ( )  & &  skipping ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ScopedBoolSwap  s ( m_state . m_inPreprocessorDirective ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                lex ( tk ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  while  ( isContinuationToken ( * tk ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            goto  _Lclassify ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( tk - > is ( T_IDENTIFIER )  & &  ! isQtReservedWord ( tk - > asByteArrayRef ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 12:37:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( m_state . m_inCondition  & &  tk - > asByteArrayRef ( )  = =  " defined " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                handleDefined ( tk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 12:37:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                synchronizeOutputLines ( * tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( handleIdentifier ( tk ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 12:37:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    goto  _Lagain ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 10:27:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : skipPreprocesorDirective ( PPToken  * tk )  
						 
					
						
							
								
									
										
										
										
											2012-03-16 15:16:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ScopedBoolSwap  s ( m_state . m_inPreprocessorDirective ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( isContinuationToken ( * tk ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        lex ( tk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-16 15:16:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Preprocessor : : handleIdentifier ( PPToken  * tk )  
						 
					
						
							
								
									
										
										
										
											2009-03-04 14:00:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! expandMacros ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ScopedBoolSwap  s ( m_state . m_inPreprocessorDirective ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppLine ( " __LINE__ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppFile ( " __FILE__ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppDate ( " __DATE__ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppTime ( " __TIME__ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ByteArrayRef  macroNameRef  =  tk - > asByteArrayRef ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( macroNameRef . size ( )  = =  8 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            & &  macroNameRef [ 0 ]  = =  ' _ ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            & &  macroNameRef [ 1 ]  = =  ' _ ' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        PPToken  newTk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( macroNameRef  = =  ppLine )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            QByteArray  txt  =  QByteArray : : number ( tk - > lineno ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 11:34:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            newTk  =  generateToken ( T_STRING_LITERAL ,  txt . constData ( ) ,  txt . size ( ) ,  tk - > lineno ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( macroNameRef  = =  ppFile )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            QByteArray  txt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            txt . append ( ' " ' ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            txt . append ( m_env - > currentFileUtf8 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            txt . append ( ' " ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 11:34:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            newTk  =  generateToken ( T_STRING_LITERAL ,  txt . constData ( ) ,  txt . size ( ) ,  tk - > lineno ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( macroNameRef  = =  ppDate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            QByteArray  txt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            txt . append ( ' " ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            txt . append ( QDate : : currentDate ( ) . toString ( ) . toUtf8 ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            txt . append ( ' " ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 11:34:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            newTk  =  generateToken ( T_STRING_LITERAL ,  txt . constData ( ) ,  txt . size ( ) ,  tk - > lineno ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( macroNameRef  = =  ppTime )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            QByteArray  txt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            txt . append ( ' " ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            txt . append ( QTime : : currentTime ( ) . toString ( ) . toUtf8 ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            txt . append ( ' " ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 11:34:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            newTk  =  generateToken ( T_STRING_LITERAL ,  txt . constData ( ) ,  txt . size ( ) ,  tk - > lineno ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-04 14:00:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( newTk . hasSource ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            newTk . f . newline  =  tk - > newline ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            newTk . f . whitespace  =  tk - > whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            * tk  =  newTk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-04 14:00:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 17:44:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Macro  * macro  =  m_env - > resolve ( macroNameRef ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! macro 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            | |  ( tk - > expanded ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                & &  m_state . m_tokenBuffer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                & &  m_state . m_tokenBuffer - > isBlocked ( macro ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-30 14:21:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//    qDebug() << "expanding" << macro->name() << "on line" << tk->lineno;
  
						 
					
						
							
								
									
										
										
										
											2010-03-03 14:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Keep track the of the macro identifier token.
 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    PPToken  idTk  =  * tk ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Expanded tokens which are not generated ones preserve the original line number from
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // their corresponding argument in macro substitution. For expanded tokens which are
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // generated, this information must be taken from somewhere else. What we do is to keep
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // a "reference" line initialize set to the line where expansion happens.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    unsigned  baseLine  =  idTk . lineno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    QVector < PPToken >  body  =  macro - > definitionTokens ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-03 14:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Withing nested expansion we might reach a previously added marker token. In this case,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // we need to move it from its current possition to outside the nesting.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PPToken  oldMarkerTk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( macro - > isFunctionLike ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Collect individual tokens that form the macro arguments.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        QVector < QVector < PPToken >  >  allArgTks ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-12 15:59:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bool  hasArgs  =  collectActualArguments ( tk ,  & allArgTks ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Check whether collecting arguments failed due to a previously added marker
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // that goot nested in a sequence of expansions. If so, store it and try again.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! hasArgs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                & &  ! tk - > hasSource ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                & &  m_state . m_markExpandedTokens 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                & &  ( m_state . m_expansionStatus  = =  Expanding 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    | |  m_state . m_expansionStatus  = =  ReadyForExpansion ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            oldMarkerTk  =  * tk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            hasArgs  =  collectActualArguments ( tk ,  & allArgTks ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-06-12 15:59:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Check for matching parameter/argument count.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  hasMatchingArgs  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( hasArgs )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  int  expectedArgCount  =  macro - > formals ( ) . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  int  actualArgCount  =  allArgTks . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( expectedArgCount  = =  actualArgCount 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    | |  ( macro - > isVariadic ( )  & &  actualArgCount  >  expectedArgCount  -  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Handle '#define foo()' when invoked as 'foo()'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    | |  ( expectedArgCount  = =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        & &  actualArgCount  = =  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        & &  allArgTks . at ( 0 ) . isEmpty ( ) ) )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                hasMatchingArgs  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-12 15:59:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! hasArgs  | |  ! hasMatchingArgs )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //### TODO: error message
 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            pushToken ( tk ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // If a previous marker was found, make sure to put it back.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( oldMarkerTk . f . length ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                pushToken ( & oldMarkerTk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            * tk  =  idTk ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-02 08:46:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-03 14:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_client  & &  ! idTk . generated ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Bundle each token sequence into a macro argument "reference" for notification.
 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-12 14:51:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Even empty ones, which are not necessarily important on its own, but for the matter
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // of couting their number - such as in foo(,)
 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            QVector < MacroArgumentReference >  argRefs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( int  i  =  0 ;  i  <  allArgTks . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  QVector < PPToken >  & argTks  =  allArgTks . at ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-12 14:51:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( argTks . isEmpty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    argRefs . push_back ( MacroArgumentReference ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    argRefs . push_back ( MacroArgumentReference ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                          m_state . m_offsetRef  +  argTks . first ( ) . begin ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                          argTks . last ( ) . begin ( )  +  argTks . last ( ) . length ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                            -  argTks . first ( ) . begin ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_client - > startExpandingMacro ( m_state . m_offsetRef  +  idTk . offset , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                          idTk . lineno , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                          * macro , 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 12:37:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                          argRefs ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! handleFunctionLikeMacro ( tk ,  macro ,  body ,  allArgTks ,  baseLine ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( m_client  & &  ! idTk . expanded ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                m_client - > stopExpandingMacro ( idTk . offset ,  * macro ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( m_client  & &  ! idTk . generated ( ) )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_client - > startExpandingMacro ( m_state . m_offsetRef  +  idTk . offset ,  idTk . lineno ,  * macro ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-30 14:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( body . isEmpty ( ) )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_state . m_markExpandedTokens 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                & &  ( m_state . m_expansionStatus  = =  NotExpanding 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    | |  m_state . m_expansionStatus  = =  JustFinishedExpansion ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // This is not the most beautiful approach but it's quite reasonable. What we do here
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // is to create a fake identifier token which is only composed by whitespaces. It's
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // also not marked as expanded so it it can be treated as a regular token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            QByteArray  content ( idTk . f . length  +  computeDistance ( idTk ) ,  '   ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            PPToken  fakeIdentifier  =  generateToken ( T_IDENTIFIER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                   content . constData ( ) ,  content . length ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                   idTk . lineno ,  false ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fakeIdentifier . f . whitespace  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fakeIdentifier . f . expanded  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fakeIdentifier . f . generated  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            body . push_back ( fakeIdentifier ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-30 14:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // The first body token replaces the macro invocation so its whitespace and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // newline info is replicated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        PPToken  & bodyTk  =  body [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bodyTk . f . whitespace  =  idTk . f . whitespace ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bodyTk . f . newline  =  idTk . f . newline ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Expansions are tracked from a "top-level" basis. This means that each expansion
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // section in the output corresponds to a direct use of a macro (either object-like
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // or function-like) in the source code and all its recurring expansions - they are
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // surrounded by two marker tokens, one at the begin and the other at the end.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // For instance, the following code will generate 3 expansions in total, but the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // output will aggregate the tokens in only 2 expansion sections.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //  - The first corresponds to BAR expanding to FOO and then FOO expanding to T o;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //  - The second corresponds to FOO expanding to T o;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // #define FOO(T, o) T o;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // #define BAR(T, o) FOO(T, o)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // BAR(Test, x) FOO(Test, y)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . m_markExpandedTokens )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( m_state . m_expansionStatus  = =  NotExpanding 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    | |  m_state . m_expansionStatus  = =  JustFinishedExpansion )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                PPToken  marker ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                marker . f . expanded  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                marker . f . length  =  idTk . f . length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                marker . offset  =  idTk . offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                marker . lineno  =  idTk . lineno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                body . prepend ( marker ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                body . append ( marker ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_state . m_expansionStatus  =  ReadyForExpansion ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( oldMarkerTk . f . length 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                       & &  ( m_state . m_expansionStatus  = =  ReadyForExpansion 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                           | |  m_state . m_expansionStatus  = =  Expanding ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                body . append ( oldMarkerTk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-30 14:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-30 14:21:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_state . pushTokenBuffer ( body . begin ( ) ,  body . end ( ) ,  macro ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-30 14:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_client  & &  ! idTk . generated ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_client - > stopExpandingMacro ( idTk . offset ,  * macro ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-30 14:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Preprocessor : : handleFunctionLikeMacro ( PPToken  * tk ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                           const  Macro  * macro , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                           QVector < PPToken >  & body , 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                           const  QVector < QVector < PPToken >  >  & actuals , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                           unsigned  baseLine ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    QVector < PPToken >  expanded ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 13:03:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    expanded . reserve ( MAX_TOKEN_EXPANSION_COUNT ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  size_t  bodySize  =  body . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( size_t  i  =  0 ;  i  <  bodySize  & &  expanded . size ( )  <  MAX_TOKEN_EXPANSION_COUNT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        int  expandedSize  =  expanded . size ( ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        PPToken  bodyTk  =  body . at ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( bodyTk . is ( T_IDENTIFIER ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  ByteArrayRef  id  =  bodyTk . asByteArrayRef ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  QVector < QByteArray >  & formals  =  macro - > formals ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            int  j  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( ;  j  <  formals . size ( )  & &  expanded . size ( )  <  MAX_TOKEN_EXPANSION_COUNT ;  + + j )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( formals [ j ]  = =  id )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 13:03:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    QVector < PPToken >  actualsForThisParam  =  actuals . at ( j ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    unsigned  lineno  =  baseLine ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Collect variadic arguments
 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 11:54:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    if  ( id  = =  " __VA_ARGS__ "  | |  ( macro - > isVariadic ( )  & &  j  +  1  = =  formals . size ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        for  ( int  k  =  j  +  1 ;  k  <  actuals . size ( ) ;  + + k )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            actualsForThisParam . append ( generateToken ( T_COMMA ,  " , " ,  1 ,  lineno ,  true ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            actualsForThisParam  + =  actuals . at ( k ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-22 13:11:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 10:41:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    const  int  actualsSize  =  actualsForThisParam . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( i  >  0  & &  body [ i  -  1 ] . is ( T_POUND ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        QByteArray  enclosedString ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        enclosedString . reserve ( 256 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        for  ( int  i  =  0 ;  i  <  actualsSize ;  + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            const  PPToken  & t  =  actualsForThisParam . at ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( i  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                lineno  =  t . lineno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            else  if  ( t . whitespace ( ) ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                enclosedString . append ( '   ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            enclosedString . append ( t . tokenStart ( ) ,  t . length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        enclosedString . replace ( " \\ " ,  " \\ \\ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        enclosedString . replace ( " \" " ,  " \\ \" " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        expanded . push_back ( generateToken ( T_STRING_LITERAL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                         enclosedString . constData ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                         enclosedString . size ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                         lineno ,  true ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        for  ( int  k  =  0 ;  k  <  actualsSize ;  + + k )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            // Mark the actual tokens (which are the replaced version of the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            // body's one) as expanded. For the first token we replicate the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            // body's whitespace info.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            PPToken  actual  =  actualsForThisParam . at ( k ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            actual . f . expanded  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( k  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                actual . f . whitespace  =  bodyTk . whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            expanded  + =  actual ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( k  = =  actualsSize  -  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                lineno  =  actual . lineno ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 17:06:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Get a better (more up-to-date) value for the base line.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    baseLine  =  lineno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 17:18:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( j  = =  formals . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // No formal macro parameter for this identifier in the body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                bodyTk . f . generated  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                bodyTk . lineno  =  baseLine ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expanded . push_back ( bodyTk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( bodyTk . isNot ( T_POUND )  & &  bodyTk . isNot ( T_POUND_POUND ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bodyTk . f . generated  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bodyTk . lineno  =  baseLine ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expanded . push_back ( bodyTk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 09:58:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( i  >  1  & &  body [ i  -  1 ] . is ( T_POUND_POUND ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( expandedSize  <  1  | |  expanded . size ( )  = =  expandedSize )  //### TODO: [cpp.concat] placemarkers
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  PPToken  & leftTk  =  expanded [ expandedSize  -  1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  PPToken  & rightTk  =  expanded [ expandedSize ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expanded [ expandedSize  -  1 ]  =  generateConcatenated ( leftTk ,  rightTk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            expanded . remove ( expandedSize ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-09 16:01:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // The "new" body.
 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    body  =  expanded ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 13:03:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    body . squeeze ( ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Next token to be lexed after the expansion.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pushToken ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : trackExpansionCycles ( PPToken  * tk )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_state . m_markExpandedTokens )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Identify a macro expansion section. The format is as follows:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // # expansion begin x,y ~g l:c
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // ...
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // # expansion end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // The x and y correspond, respectively, to the offset where the macro invocation happens
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // and the macro name's length. Following that there might be an unlimited number of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // token marks which are directly mapped to each token that appears in the expansion.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Something like ~g indicates that the following g tokens are all generated. While
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // something like l:c indicates that the following token is expanded but not generated
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // and is positioned on line l and column c. Example:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // #define FOO(X) int f(X = 0)  // line 1
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // FOO(int
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //     a);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Output would be:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // # expansion begin 8,3 ~3 2:4 3:4 ~3
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // int f(int a = 0)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // # expansion end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // # 3 filename
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //       ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( tk - > expanded ( )  & &  ! tk - > hasSource ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( m_state . m_expansionStatus  = =  ReadyForExpansion )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_state . m_expansionStatus  =  Expanding ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_state . m_expansionResult . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_state . m_expandedTokensInfo . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( m_state . m_expansionStatus  = =  Expanding )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_state . m_expansionStatus  =  JustFinishedExpansion ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                maybeStartOutputLine ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                writeOutput ( " # expansion begin  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                QByteArray  expansionInfo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expansionInfo . reserve ( m_state . m_expandedTokensInfo . size ( )  *  2 ) ;  // Rough estimate
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Offset and length of the macro invocation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expansionInfo . append ( QByteArray : : number ( tk - > offset ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expansionInfo . append ( ' , ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expansionInfo . append ( QByteArray : : number ( tk - > length ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Expanded tokens
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                unsigned  generatedCount  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                for  ( int  i  =  0 ;  i  <  m_state . m_expandedTokensInfo . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  QPair < unsigned ,  unsigned >  & p  =  m_state . m_expandedTokensInfo . at ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( p . first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( generatedCount )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            expansionInfo . append ( "  ~ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            expansionInfo . append ( QByteArray : : number ( generatedCount ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            generatedCount  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        expansionInfo . append ( '   ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        expansionInfo . append ( QByteArray : : number ( p . first ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        expansionInfo . append ( ' : ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        expansionInfo . append ( QByteArray : : number ( p . second ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        + + generatedCount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( generatedCount )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    expansionInfo . append ( "  ~ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    expansionInfo . append ( QByteArray : : number ( generatedCount ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                expansionInfo . append ( ' \n ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                writeOutput ( expansionInfo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                writeOutput ( m_state . m_expansionResult ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                maybeStartOutputLine ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                writeOutput ( " # expansion end \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            lex ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( tk - > expanded ( )  & &  ! tk - > hasSource ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                trackExpansionCycles ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Preprocessor : : synchronizeOutputLines ( const  PPToken  & tk ,  bool  forceLine )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_state . m_expansionStatus  ! =  NotExpanding 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            | |  ( ! forceLine  & &  m_env - > currentLine  = =  tk . lineno ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( forceLine  | |  m_env - > currentLine  >  tk . lineno  | |  tk . lineno  -  m_env - > currentLine  > =  9 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . m_noLines )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! m_state . m_markExpandedTokens ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                writeOutput ( '   ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generateOutputLineMarker ( tk . lineno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( unsigned  i  =  m_env - > currentLine ;  i  <  tk . lineno ;  + + i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            writeOutput ( ' \n ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_env - > currentLine  =  tk . lineno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( tk . is ( T_COMMENT )  | |  tk . is ( T_DOXY_COMMENT ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_env - > currentLine  + =  tk . asByteArrayRef ( ) . count ( ' \n ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Preprocessor : : removeTrailingOutputLines ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    QByteArray  * buffer  =  currentOutputBuffer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( buffer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        int  i  =  buffer - > size ( )  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( i  > =  0  & &  buffer - > at ( i )  = =  ' \n ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            - - i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  int  mightChop  =  buffer - > size ( )  -  i  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( mightChop  >  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Keep one new line at end.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            buffer - > chop ( mightChop  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								std : : size_t  Preprocessor : : computeDistance ( const  Preprocessor : : PPToken  & tk ,  bool  forceTillLine )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Find previous non-space character or line begin.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  char  * buffer  =  tk . bufferStart ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  char  * tokenBegin  =  tk . tokenStart ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  char  * it  =  tokenBegin  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( ;  it  > =  buffer ;  - - it )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( * it  = =  ' \n ' | |  ( ! pp_isspace ( * it )  & &  ! forceTillLine ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    + + it ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  tokenBegin  -  it ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Preprocessor : : enforceSpacing ( const  Preprocessor : : PPToken  & tk ,  bool  forceSpacing )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( tk . whitespace ( )  | |  forceSpacing )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // For expanded tokens we simply add a whitespace, if necessary - the exact amount of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // whitespaces is irrelevant within an expansion section. For real tokens we must be
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // more specific and get the information from the original source.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( tk . expanded ( )  & &  ! atStartOfOutputLine ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            writeOutput ( '   ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  std : : size_t  spacing  =  computeDistance ( tk ,  forceSpacing ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  char  * tokenBegin  =  tk . tokenStart ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  char  * it  =  tokenBegin  -  spacing ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Reproduce the content as in the original line.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( ;  it  ! =  tokenBegin ;  + + it )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( pp_isspace ( * it ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    writeOutput ( * it ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    writeOutput ( '   ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/// invalid pp-tokens are used as markers to force whitespace checks.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Preprocessor : : preprocess ( const  QString  & fileName ,  const  QByteArray  & source ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                              QByteArray  * result ,  bool  noLines , 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                              bool  markGeneratedTokens ,  bool  inCondition , 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                              unsigned  offsetRef ,  unsigned  lineRef ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:59:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( source . isEmpty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-04 11:47:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 17:06:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-19 10:25:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  State  savedState  =  m_state ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-19 11:54:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_state  =  State ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . m_currentFileName  =  fileName ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . m_source  =  source ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . m_lexer  =  new  Lexer ( source . constBegin ( ) ,  source . constEnd ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . m_lexer - > setScanKeywords ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . m_lexer - > setScanAngleStringLiteralTokens ( false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_keepComments ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . m_lexer - > setScanCommentTokens ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . m_result  =  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . m_noLines  =  noLines ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_state . m_markExpandedTokens  =  markGeneratedTokens ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-19 11:54:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_state . m_inCondition  =  inCondition ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 12:37:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_state . m_offsetRef  =  offsetRef ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_state . m_lineRef  =  lineRef ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:59:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  QString  previousFileName  =  m_env - > currentFile ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_env - > currentFile  =  fileName ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_env - > currentFileUtf8  =  fileName . toUtf8 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-04 11:47:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  unsigned  previousCurrentLine  =  m_env - > currentLine ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-30 13:01:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_env - > currentLine  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:59:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-30 13:01:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( ! m_state . m_noLines ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        generateOutputLineMarker ( 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-04 11:47:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    PPToken  tk ( m_state . m_source ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lex ( & tk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-04 11:47:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Track the start and end of macro expansion cycles.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        trackExpansionCycles ( & tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  macroExpanded  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . m_expansionStatus  = =  Expanding )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Collect the line and column from the tokens undergoing expansion. Those will
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // be available in the expansion section for further referencing about their real
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // location.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            unsigned  trackedLine  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            unsigned  trackedColumn  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( tk . expanded ( )  & &  ! tk . generated ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                trackedLine  =  tk . lineno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                trackedColumn  =  computeDistance ( tk ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-04 11:47:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            m_state . m_expandedTokensInfo . append ( qMakePair ( trackedLine ,  trackedColumn ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( m_state . m_expansionStatus  = =  JustFinishedExpansion )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_state . m_expansionStatus  =  NotExpanding ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            macroExpanded  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-04 11:47:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:59:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Update environment line information.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        synchronizeOutputLines ( tk ,  macroExpanded ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:56:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Make sure spacing between tokens is handled properly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        enforceSpacing ( tk ,  macroExpanded ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Finally output the token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        writeOutput ( tk . asByteArrayRef ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  while  ( tk . isNot ( T_EOF_SYMBOL ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:56:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    removeTrailingOutputLines ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-19 10:25:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    delete  m_state . m_lexer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state  =  savedState ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:56:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_env - > currentFile  =  previousFileName ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_env - > currentFileUtf8  =  previousFileName . toUtf8 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_env - > currentLine  =  previousCurrentLine ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:56:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Preprocessor : : collectActualArguments ( PPToken  * tk ,  QVector < QVector < PPToken >  >  * actuals )  
						 
					
						
							
								
									
										
										
										
											2009-03-03 17:18:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Q_ASSERT ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Q_ASSERT ( actuals ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 17:18:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    lex ( tk ) ;  // consume the identifier
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:46:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( tk - > isNot ( T_LPAREN ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //### TODO: error message
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:46:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    QVector < PPToken >  tokens ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    lex ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    scanActualArgument ( tk ,  & tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:46:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    actuals - > append ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:19:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( tk - > is ( T_COMMA ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lex ( tk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:19:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        QVector < PPToken >  tokens ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        scanActualArgument ( tk ,  & tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        actuals - > append ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:19:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( tk - > is ( T_RPAREN ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lex ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //###TODO: else error message
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : scanActualArgument ( PPToken  * tk ,  QVector < PPToken >  * tokens )  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    Q_ASSERT ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    int  count  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( tk - > isNot ( T_EOF_SYMBOL ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( tk - > is ( T_LPAREN ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            + + count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( tk - > is ( T_RPAREN ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( !  count ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            - - count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( !  count  & &  tk - > is ( T_COMMA ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        tokens - > append ( * tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lex ( tk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : handlePreprocessorDirective ( PPToken  * tk )  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ScopedBoolSwap  s ( m_state . m_inPreprocessorDirective ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 09:52:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    PPToken  poundToken  =  * tk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    lex ( tk ) ;  // scan the directive
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 09:52:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( tk - > newline ( )  & &  !  tk - > joined ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ;  // nothing to do.
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  const  QByteArray  ppDefine ( " define " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppIf ( " if " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppIfDef ( " ifdef " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppIfNDef ( " ifndef " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppEndIf ( " endif " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppElse ( " else " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppUndef ( " undef " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppElif ( " elif " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppInclude ( " include " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppIncludeNext ( " include_next " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  const  QByteArray  ppImport ( " import " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //### TODO:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // line
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // error
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // pragma
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( tk - > is ( T_IDENTIFIER ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  ByteArrayRef  directive  =  tk - > asByteArrayRef ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! skipping ( )  & &  directive  = =  ppDefine ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            handleDefineDirective ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( ! skipping ( )  & &  directive  = =  ppUndef ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            handleUndefDirective ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( ! skipping ( )  & &  ( directive  = =  ppInclude 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                 | |  directive  = =  ppIncludeNext 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                 | |  directive  = =  ppImport ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            handleIncludeDirective ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( directive  = =  ppIf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            handleIfDirective ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( directive  = =  ppIfDef ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            handleIfDefDirective ( false ,  tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( directive  = =  ppIfNDef ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            handleIfDefDirective ( true ,  tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( directive  = =  ppEndIf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            handleEndIfDirective ( tk ,  poundToken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( directive  = =  ppElse ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            handleElseDirective ( tk ,  poundToken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else  if  ( directive  = =  ppElif ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            handleElifDirective ( tk ,  poundToken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        skipPreprocesorDirective ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-03-03 09:52:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : handleIncludeDirective ( PPToken  * tk )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . m_lexer - > setScanAngleStringLiteralTokens ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    lex ( tk ) ;  // consume "include" token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . m_lexer - > setScanAngleStringLiteralTokens ( false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-29 17:14:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  unsigned  line  =  tk - > lineno ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    QByteArray  included ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( tk - > is ( T_STRING_LITERAL )  | |  tk - > is ( T_ANGLE_STRING_LITERAL ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        included  =  tk - > asByteArrayRef ( ) . toByteArray ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-29 17:14:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        lex ( tk ) ;  // consume string token
 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        included  =  expand ( tk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    included  =  included . trimmed ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-30 13:34:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( included . isEmpty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //### TODO: error message
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//    qDebug("include [[%s]]", included.toUtf8().constData());
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Client : : IncludeType  mode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( included . at ( 0 )  = =  ' " ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        mode  =  Client : : IncludeLocal ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( included . at ( 0 )  = =  ' < ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        mode  =  Client : : IncludeGlobal ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ;  //### TODO: add error message?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-17 13:21:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_client )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        QString  inc  =  QString : : fromUtf8 ( included . constData ( )  +  1 ,  included . size ( )  -  2 ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        m_client - > sourceNeeded ( line ,  inc ,  mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-17 13:21:47 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : handleDefineDirective ( PPToken  * tk )  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  unsigned  defineOffset  =  tk - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    lex ( tk ) ;  // consume "define" token
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( tk - > isNot ( T_IDENTIFIER ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    Macro  macro ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    macro . setFileName ( m_env - > currentFile ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-02 14:57:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    macro . setLine ( tk - > lineno ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    QByteArray  macroName  =  tk - > asByteArrayRef ( ) . toByteArray ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    macro . setName ( macroName ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    macro . setOffset ( tk - > offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    lex ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( isContinuationToken ( * tk )  & &  tk - > is ( T_LPAREN )  & &  !  tk - > whitespace ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-22 13:55:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        macro . setFunctionLike ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        lex ( tk ) ;  // skip `('
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bool  hasIdentifier  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( isContinuationToken ( * tk )  & &  tk - > is ( T_IDENTIFIER ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-16 14:06:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            hasIdentifier  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            macro . addFormal ( tk - > asByteArrayRef ( ) . toByteArray ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            lex ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            while  ( isContinuationToken ( * tk )  & &  tk - > is ( T_COMMA ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                lex ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( isContinuationToken ( * tk )  & &  tk - > is ( T_IDENTIFIER ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    macro . addFormal ( tk - > asByteArrayRef ( ) . toByteArray ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    lex ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-16 14:06:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    hasIdentifier  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( tk - > is ( T_DOT_DOT_DOT ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-22 13:55:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            macro . setVariadic ( true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-16 14:06:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! hasIdentifier ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                macro . addFormal ( " __VA_ARGS__ " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            lex ( tk ) ;  // consume elipsis token
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( isContinuationToken ( * tk )  & &  tk - > is ( T_RPAREN ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            lex ( tk ) ;  // consume ")" token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    QVector < PPToken >  bodyTokens ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    unsigned  previousOffset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    unsigned  previousLine  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Macro  * macroReference  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( isContinuationToken ( * tk ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Macro tokens are always marked as expanded. However, only for object-like macros
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // we mark them as generated too. For function-like macros we postpone it until the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // formals are identified in the bodies.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tk - > f . expanded  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! macro . isFunctionLike ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tk - > f . generated  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Identifiers must not be eagerly expanded inside defines, but we should still notify
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // in the case they are macros.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( tk - > is ( T_IDENTIFIER )  & &  m_client )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            macroReference  =  m_env - > resolve ( tk - > asByteArrayRef ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( macroReference )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! macroReference - > isFunctionLike ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    m_client - > notifyMacroReference ( tk - > offset ,  tk - > lineno ,  * macroReference ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    macroReference  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 15:27:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 12:37:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( macroReference )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( tk - > is ( T_LPAREN ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_client - > notifyMacroReference ( previousOffset ,  previousLine ,  * macroReference ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            macroReference  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 15:27:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        previousOffset  =  tk - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        previousLine  =  tk - > lineno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 15:27:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bodyTokens . push_back ( * tk ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-29 15:27:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        lex ( tk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( isQtReservedWord ( ByteArrayRef ( & macroName ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-22 13:55:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        QByteArray  macroId  =  macro . name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( macro . isFunctionLike ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            macroId  + =  ' ( ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bool  fst  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-19 15:42:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            foreach  ( const  QByteArray  & formal ,  macro . formals ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-22 13:55:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( !  fst ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    macroId  + =  " ,  " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                fst  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                macroId  + =  formal ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            macroId  + =  ' ) ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bodyTokens . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        macro . setDefinition ( macroId ,  bodyTokens ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  if  ( ! bodyTokens . isEmpty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        PPToken  & firstBodyToken  =  bodyTokens [ 0 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        int  start  =  firstBodyToken . offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        int  len  =  tk - > offset  -  start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        QByteArray  bodyText  =  firstBodyToken . source ( ) . mid ( start ,  len ) . trimmed ( ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  int  bodySize  =  bodyTokens . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( int  i  =  0 ;  i  <  bodySize ;  + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            PPToken  & t  =  bodyTokens [ i ] ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( t . hasSource ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                t . squeezeSource ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-06 11:50:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        macro . setDefinition ( bodyText ,  bodyTokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    macro . setLength ( tk - > offset  -  defineOffset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_env - > bind ( macro ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    qDebug() << "adding macro" << macro.name() << "defined at" << macro.fileName() << ":"<<macro.line();
  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_client ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_client - > macroAdded ( macro ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								QByteArray  Preprocessor : : expand ( PPToken  * tk ,  PPToken  * lastConditionToken )  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    unsigned  line  =  tk - > lineno ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    unsigned  begin  =  tk - > begin ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PPToken  lastTk ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    while  ( isContinuationToken ( * tk ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        lastTk  =  * tk ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        lex ( tk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // Gather the exact spelling of the content in the source.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    QByteArray  condition ( m_state . m_source . mid ( begin ,  lastTk . begin ( )  +  lastTk . length ( )  -  begin ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//    qDebug("*** Condition before: [%s]", condition.constData());
  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    QByteArray  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    result . reserve ( 256 ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    preprocess ( m_state . m_currentFileName ,  condition ,  & result ,  true ,  false ,  true ,  begin ,  line ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    result . squeeze ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    qDebug("*** Condition after: [%s]", result.constData());
  
						 
					
						
							
								
									
										
										
										
											2012-05-22 12:27:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( lastConditionToken ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        * lastConditionToken  =  lastTk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  PPToken  Preprocessor : : evalExpression ( PPToken  * tk ,  Value  & result )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    PPToken  lastConditionToken ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  QByteArray  expanded  =  expand ( tk ,  & lastConditionToken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Lexer  lexer ( expanded . constData ( ) ,  expanded . constData ( )  +  expanded . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : vector < Token >  buf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Token  t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lexer . scan ( & t ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        buf . push_back ( t ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  while  ( t . isNot ( T_EOF_SYMBOL ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ExpressionEvaluator  eval ( m_client ,  m_env ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    result  =  eval ( & buf [ 0 ] ,  & buf [ buf . size ( )  -  1 ] ,  expanded ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  lastConditionToken ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : handleIfDirective ( PPToken  * tk )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    lex ( tk ) ;  // consume "if" token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Value  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  PPToken  lastExpressionToken  =  evalExpression ( tk ,  result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  bool  value  =  ! result . is_zero ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  bool  wasSkipping  =  m_state . m_skipping [ m_state . m_ifLevel ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    + + m_state . m_ifLevel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_state . m_trueTest [ m_state . m_ifLevel ]  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( wasSkipping )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . m_skipping [ m_state . m_ifLevel ]  =  wasSkipping ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  startSkipping  =  ! value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . m_skipping [ m_state . m_ifLevel ]  =  startSkipping ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( startSkipping  & &  m_client ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            startSkippingBlocks ( lastExpressionToken ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : handleElifDirective ( PPToken  * tk ,  const  PPToken  & poundToken )  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . m_ifLevel  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//        std::cerr << "*** WARNING #elif without #if" << std::endl;
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        handleIfDirective ( tk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        lex ( tk ) ;  // consume "elif" token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . m_skipping [ m_state . m_ifLevel  -  1 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // we keep on skipping because we are nested in a skipped block
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_state . m_skipping [ m_state . m_ifLevel ]  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( m_state . m_trueTest [ m_state . m_ifLevel ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! m_state . m_skipping [ m_state . m_ifLevel ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // start skipping because the preceeding then-part was not skipped
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_state . m_skipping [ m_state . m_ifLevel ]  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( m_client ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    startSkippingBlocks ( poundToken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // preceeding then-part was skipped, so calculate if we should start
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // skipping, depending on the condition
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Value  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            evalExpression ( tk ,  result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bool  startSkipping  =  result . is_zero ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_state . m_trueTest [ m_state . m_ifLevel ]  =  ! startSkipping ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_state . m_skipping [ m_state . m_ifLevel ]  =  startSkipping ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( m_client  & &  ! startSkipping ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_client - > stopSkippingBlocks ( poundToken . offset  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : handleElseDirective ( PPToken  * tk ,  const  PPToken  & poundToken )  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    lex ( tk ) ;  // consume "else" token
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-19 20:06:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . m_ifLevel  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_state . m_skipping [ m_state . m_ifLevel  -  1 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // we keep on skipping because we are nested in a skipped block
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_state . m_skipping [ m_state . m_ifLevel ]  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bool  wasSkipping  =  m_state . m_skipping [ m_state . m_ifLevel ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bool  startSkipping  =  m_state . m_trueTest [ m_state . m_ifLevel ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_state . m_skipping [ m_state . m_ifLevel ]  =  startSkipping ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( m_client  & &  wasSkipping  & &  ! startSkipping ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                m_client - > stopSkippingBlocks ( poundToken . offset  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else  if  ( m_client  & &  ! wasSkipping  & &  startSkipping ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                startSkippingBlocks ( poundToken ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef NO_DEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        std : : cerr  < <  " *** WARNING #else without #if "  < <  std : : endl ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif  // NO_DEBUG
  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : handleEndIfDirective ( PPToken  * tk ,  const  PPToken  & poundToken )  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( m_state . m_ifLevel  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef NO_DEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        std : : cerr  < <  " *** WARNING #endif without #if " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! tk - > generated ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            std : : cerr  < <  "  on line  "  < <  tk - > lineno  < <  "  of file  "  < <  m_state . m_currentFileName . toUtf8 ( ) . constData ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        std : : cerr  < <  std : : endl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif  // NO_DEBUG
  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bool  wasSkipping  =  m_state . m_skipping [ m_state . m_ifLevel ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . m_skipping [ m_state . m_ifLevel ]  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . m_trueTest [ m_state . m_ifLevel ]  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        - - m_state . m_ifLevel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( m_client  & &  wasSkipping  & &  ! m_state . m_skipping [ m_state . m_ifLevel ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_client - > stopSkippingBlocks ( poundToken . offset  -  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    lex ( tk ) ;  // consume "endif" token
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : handleIfDefDirective ( bool  checkUndefined ,  PPToken  * tk )  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  const  QByteArray  qCreatorRun ( " Q_CREATOR_RUN " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-12 15:24:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    lex ( tk ) ;  // consume "ifdef" token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( tk - > is ( T_IDENTIFIER ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  value  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  ByteArrayRef  macroName  =  tk - > asByteArrayRef ( ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( Macro  * macro  =  macroDefinition ( macroName ,  tk - > offset ,  tk - > lineno ,  m_env ,  m_client ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            value  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-12 15:24:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // the macro is a feature constraint(e.g. QT_NO_XXX)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( checkUndefined  & &  macroName . startsWith ( " QT_NO_ " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( macro - > fileName ( )  = =  QLatin1String ( " <configuration> " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // and it' defined in a pro file (e.g. DEFINES += QT_NO_QOBJECT)
 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-12 15:24:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    value  =  false ;  // take the branch
 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-12 15:24:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  else  if  ( m_env - > isBuiltinMacro ( macroName ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            value  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  if  ( macroName  = =  qCreatorRun )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            value  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( checkUndefined ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            value  =  ! value ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  bool  wasSkipping  =  m_state . m_skipping [ m_state . m_ifLevel ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        + + m_state . m_ifLevel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . m_trueTest [ m_state . m_ifLevel ]  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_state . m_skipping [ m_state . m_ifLevel ]  =  wasSkipping  ?  wasSkipping  :  ! value ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_client  & &  ! wasSkipping  & &  ! value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            startSkippingBlocks ( * tk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        lex ( tk ) ;  // consume the identifier
 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifndef NO_DEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        std : : cerr  < <  " *** WARNING #ifdef without identifier "  < <  std : : endl ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif  // NO_DEBUG
  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  Preprocessor : : handleUndefDirective ( PPToken  * tk )  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    lex ( tk ) ;  // consume "undef" token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( tk - > is ( T_IDENTIFIER ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  ByteArrayRef  macroName  =  tk - > asByteArrayRef ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-18 17:44:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  Macro  * macro  =  m_env - > remove ( macroName ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( m_client  & &  macro ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_client - > macroAdded ( * macro ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lex ( tk ) ;  // consume macro name
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef NO_DEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        std : : cerr  < <  " *** WARNING #undef without identifier "  < <  std : : endl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif  // NO_DEBUG
  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  Preprocessor : : isQtReservedWord ( const  ByteArrayRef  & macroId )  
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  int  size  =  macroId . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if       ( size  = =  9  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_SIGNALS " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-03 09:11:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( size  = =  9  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_FOREACH " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    else  if  ( size  = =  7  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_SLOTS " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-25 11:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( size  = =  8  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_SIGNAL " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( size  = =  6  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_SLOT " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-30 16:30:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( size  = =  3  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_D " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( size  = =  3  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_Q " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-22 13:11:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( size  = =  10  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_PROPERTY " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-08 15:08:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( size  = =  18  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_PRIVATE_PROPERTY " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-22 13:11:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( size  = =  7  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_ENUMS " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( size  = =  7  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_FLAGS " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-16 17:29:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( size  = =  12  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_INTERFACES " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-03 15:40:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( size  = =  11  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_INVOKABLE " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    else  if  ( size  = =  6  & &  macroId . at ( 0 )  = =  ' S '  & &  macroId  = =  " SIGNAL " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( size  = =  4  & &  macroId . at ( 0 )  = =  ' S '  & &  macroId  = =  " SLOT " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( size  = =  7  & &  macroId . at ( 0 )  = =  ' s '  & &  macroId  = =  " signals " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-03 11:00:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( size  = =  7  & &  macroId . at ( 0 )  = =  ' f '  & &  macroId  = =  " foreach " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    else  if  ( size  = =  5  & &  macroId . at ( 0 )  = =  ' s '  & &  macroId  = =  " slots " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-28 10:55:51 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( size  = =  4  & &  macroId . at ( 0 )  = =  ' e '  & &  macroId  = =  " emit " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else  if  ( size  = =  6  & &  macroId . at ( 0 )  = =  ' Q '  & &  macroId  = =  " Q_EMIT " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-02 12:01:29 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-06-15 15:38:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								PPToken  Preprocessor : : generateToken ( enum  Kind  kind ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    const  char  * content ,  int  length , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    unsigned  lineno , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    bool  addQuotes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    bool  addToControl ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-04-22 12:04:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // When the token is a generated token, the column position cannot be
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // reconstructed, but we also have to prevent it from searching the whole
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // scratch buffer. So inserting a newline before the new token will give
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // an indent width of 0 (zero).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    m_scratchBuffer . append ( ' \n ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    const  size_t  pos  =  m_scratchBuffer . size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( kind  = =  T_STRING_LITERAL  & &  addQuotes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_scratchBuffer . append ( ' " ' ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    m_scratchBuffer . append ( content ,  length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( kind  = =  T_STRING_LITERAL  & &  addQuotes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        m_scratchBuffer . append ( ' " ' ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        length  + =  2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    PPToken  tk ( m_scratchBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tk . f . kind  =  kind ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_state . m_lexer - > control ( )  & &  addToControl )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( kind  = =  T_STRING_LITERAL ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            tk . string  =  m_state . m_lexer - > control ( ) - > stringLiteral ( m_scratchBuffer . constData ( )  +  pos ,  length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else  if  ( kind  = =  T_IDENTIFIER ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            tk . identifier  =  m_state . m_lexer - > control ( ) - > identifier ( m_scratchBuffer . constData ( )  +  pos ,  length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else  if  ( kind  = =  T_NUMERIC_LITERAL ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            tk . number  =  m_state . m_lexer - > control ( ) - > numericLiteral ( m_scratchBuffer . constData ( )  +  pos ,  length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    tk . offset  =  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tk . f . length  =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tk . f . generated  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tk . f . expanded  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tk . lineno  =  lineno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  tk ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								PPToken  Preprocessor : : generateConcatenated ( const  PPToken  & leftTk ,  const  PPToken  & rightTk )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    QByteArray  newText ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    newText . reserve ( leftTk . length ( )  +  rightTk . length ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-22 12:04:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    newText . append ( leftTk . tokenStart ( ) ,  leftTk . length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    newText . append ( rightTk . tokenStart ( ) ,  rightTk . length ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-27 17:11:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    PPToken  result  =  generateToken ( T_IDENTIFIER ,  newText . constData ( ) ,  newText . size ( ) ,  leftTk . lineno ,  true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    result . f . whitespace  =  leftTk . f . whitespace ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-26 15:18:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Preprocessor : : startSkippingBlocks ( const  Preprocessor : : PPToken  & tk )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! m_client ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  iter  =  tk . end ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  QByteArray  & txt  =  tk . source ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( ;  iter  <  txt . size ( ) ;  + + iter )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( txt . at ( iter )  = =  ' \n ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            m_client - > startSkippingBlocks ( iter  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-15 15:38:20 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
											 
										
											
												C++: Core changes in preprocessing
Summary of most relevant items:
- Preprocessor output format change. No more gen true/false. Instead
  a more intuitive and natural expansion (like from a real compiler) is
  performed directly corresponding to the macro invocation. Notice that
  information about the generated tokens is not lost, because it's now
  embedded in the expansion section header (in terms of lines and columns
  as explained in the code). In addition the location on where the macro
  expansion happens is also documented for future use.
- Fix line control directives and associated token line numbers.
  This was not detected in tests cases because some of them were
  actually wrong: Within expansions the line information was being
  considered as originally computed in the macro definition, while
  the desired and expected for Creator's reporting mechanism (just
  like regular compilers) is the line from the expanded version
  of the tokens.
- Do not allow for eager expansion. This was previously being done
  inside define directives. However, it's not allowed and might
  lead to incorrect results, since the argument substitution should
  only happen upon the macro invocation (and following nested ones).
  At least GCC and clang are consistent with that. See test case
  tst_Preprocessor:dont_eagerly_expand for a detailed explanation.
- Revive the 'expanded' token flag. This is used to mark every token
  that originates from a macro expansion. Notice, however, that
  expanded tokens are not necessarily generated tokens (although
  every generated token is a expanded token). Expanded tokens that
  are not generated are those which are still considered by our
  code model features, since they are visible on the editor. The
  translation unit is smart enough to calculate line/column position
  for such tokens based on the information from the expansion section
  header.
- How expansions are tracked has also changed. Now, we simply add
  two surrounding marker tokens to each "top-level" expansion
  sequence. There is an enumeration that control expansion states.
  Also, no "previous" token is kept around.
- Preprocessor client methods suffered a change in signature so
  they now receive the line number of the action in question as
  a paramater. Previously such line could be retrieved by the client
  implementation by accessing the environment line. However, this
  is not reliable because we try to avoid synchronization of the
  output/environment lines in order to avoid unnecessary output,
  while expanding macros or handling preprocessor directives.
- Although macros are not expanded during define directives (as
  mentioned above) the preprocessor client is now "notified"
  when it sees a macro. This is to allow usage tracking.
- Other small stuff.
This is all in one patch because the fixes are a consequence
of the change in preprocessing control.
Change-Id: I8f4c6e6366f37756ec65d0a93b79f72a3ac4ed50
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
											 
										 
										
											2012-06-20 15:22:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								template  < class  T >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Preprocessor : : writeOutput ( const  T  & t )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    QByteArray  * buffer  =  currentOutputBuffer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( buffer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        buffer - > append ( t ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Preprocessor : : writeOutput ( const  ByteArrayRef  & ref )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    QByteArray  * buffer  =  currentOutputBuffer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( buffer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        buffer - > append ( ref . start ( ) ,  ref . length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  Preprocessor : : atStartOfOutputLine ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  QByteArray  * buffer  =  currentOutputBuffer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ( buffer  & &  ! buffer - > isEmpty ( ) )  ?  * ( buffer - > end ( )  -  1 )  = =  ' \n '  :  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  Preprocessor : : maybeStartOutputLine ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    QByteArray  * buffer  =  currentOutputBuffer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( buffer  & &  ! buffer - > isEmpty ( )  & &  * ( buffer - > end ( )  -  1 )  ! =  ' \n ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        writeOutput ( ' \n ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  QByteArray  * Preprocessor : : currentOutputBuffer ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( m_state . m_expansionStatus  = =  Expanding ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  & m_state . m_expansionResult ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  m_state . m_result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								QByteArray  * Preprocessor : : currentOutputBuffer ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  const_cast < QByteArray  * > ( static_cast < const  Preprocessor  * > ( this ) - > currentOutputBuffer ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}