After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 608921 - Preprocessor regression: Macro that are not used in file affect the file
Preprocessor regression: Macro that are not used in file affect the file
Status: RESOLVED INCOMPLETE
Product: doxygen
Classification: Other
Component: general
1.6.2
Other All
: Normal critical
: ---
Assigned To: Dimitri van Heesch
Dimitri van Heesch
Depends on:
Blocks:
 
 
Reported: 2010-02-03 20:08 UTC by Gilles
Modified: 2010-11-22 15:58 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Example 1 (67.01 KB, application/x-zip-compressed)
2010-02-03 20:08 UTC, Gilles
Details
Example 2 (65.30 KB, application/x-zip-compressed)
2010-02-03 20:09 UTC, Gilles
Details
Example for the wrong link (47.84 KB, application/zip)
2010-02-16 14:06 UTC, Gilles
Details

Description Gilles 2010-02-03 20:08:40 UTC
Created attachment 152961 [details]
Example 1

in newer version of doxygen, all files are preprocessor only once, and already defined macro remain active throughout the run.
The attached file DoxyPre.zip demonstrates that a macro not visible in file2.cpp
so badly polutes the signatures that Doxygen cannot document a method-

The attached file DoxyPre2.zip demonstrattes that a macro not visible in file2.cpp
mask the correct method
Comment 1 Gilles 2010-02-03 20:09:27 UTC
Created attachment 152962 [details]
Example 2
Comment 2 Gilles 2010-02-03 20:11:43 UTC
The issue originate in the fact that g_fileDefineDict->clear(); at the begin of preprocessFile() has been commented, and in the fact that readIncludeFile skips all files that are already known

Kind Regards
Gilles
Comment 3 Gilles 2010-02-09 19:09:06 UTC
Describing the issue via zip files is cumbersome for the reader.
Therefore is a description of issue 1:
Doxyfile contains:
INPUT                  = header1.hpp file1.cpp file2.cpp 
ENABLE_PREPROCESSING   = YES
MACRO_EXPANSION        = YES
EXPAND_ONLY_PREDEF     = YES
SEARCH_INCLUDES        = YES
INCLUDE_PATH           =
INCLUDE_FILE_PATTERNS  =
PREDEFINED             = "UNUSED(par)=par"
EXPAND_AS_DEFINED      =
SKIP_FUNCTION_MACROS   = YES

header1.hpp contains:
/**
 * \file header1.hpp
 * define some usefull macros
 */

/**
 * \brief Decorate unused parameters in function/method declaration.
 *
 * The macro masks the parameter name from real compiler so that the compiler
 * does not produce warning about the unused paramter.
 * The doxy configuration file contains the definition
 * \verbatim PREDEFINED            += "UNUSED(p)=p" \endverbatim
 * so that the parameters are visible to doxygen. This makes it possible to
 * document them
 */
#define UNUSED(par) 

File1.cpp contains:
/**
 * \file file1.cpp
 * include 1 headers and pollute prepocessor
 */
#include "header1.hpp"

/// \brief polute pre.l
#define cat 42

File2.cpp contains:

/**
 * \file file2.cpp
 * include 1 headers, and some code
 */
#include "header1.hpp"


/**
 * \brief a test class
 */
class CTest
{
  public:
    void methOk(int UNUSED(baz), CTest* UNUSED(foo), char* UNUSED(bar)) ;
    void methBroken(int UNUSED(cat), CTest* UNUSED(foo), char* UNUSED(bar)) ;
};


/**
 *  \brief demonstrate a working usage of the macro UNUSED.
 *
 *  \param baz The BAZ param
 *  \param foo The FOO param
 *  \param bar The BAR param
 */
void CTest::methOk(int UNUSED(baz), CTest* UNUSED(foo), char* UNUSED(bar))
{
}
  
/**
 *  \brief demonstrate a broken usage of the macro UNUSED.
 *
 *  \param cat The CAT param.  Alas because Doxygen already read 
 *             the file file1.cpp it already kows a macro "cat" defined as "42"
 *             The problem is that Doxgen does no longer reset the dictionary of known macro
 *             g_fileDefineDict->clear(); at the begin of preprocessFile()
 *  \param foo The FOO param
 *  \param bar The BAR param
 */
void CTest::methBroken(int UNUSED(cat), CTest* UNUSED(foo), char* UNUSED(bar))
{
}


Doxygen runs write to stdout
C:/usr/gilbert/doxygen/DoxyPre/file2.cpp:30: Warning: argument 'cat' of command
@param is not found in the argument list of CTest::methBroken(int 42, CTest *foo
, char *bar)
C:/usr/gilbert/doxygen/DoxyPre/file2.cpp:30: Warning: The following parameters o
f CTest::methBroken(int 42, CTest *foo, char *bar) are not documented:
  parameter '42'

The generated documentations says:
void CTest::methBroken  ( int  42,  
  CTest *  foo,  
  char *  bar   
 )    

demonstrate a broken usage of the macro UNUSED. 
...

Version 1.5.6 did not have the issue
Comment 4 Dimitri van Heesch 2010-02-14 15:34:12 UTC
Confirmed. I'll make doxygen check if a macro definition is "in scope" before it is resolved. Should be fixed in the next subversion update.
Comment 5 Gilles 2010-02-16 14:00:12 UTC
Hi Dimitri,
I already tried to "check if a macro definition is in scope".
This is just a small change in pre.l.
I maintain a list of header that have been opened since preprocessFile() has been called.  and i compare this list with the definition place returned by isDefined().
This attempt however revealed an other flaw in the preprocessor.  This time a flaw that is also present in old Doxygen versions:
Given 
/**
 * \file file1.cpp
 *
 * defines a first version of DUMP
 */
 
 
#if defined(DEBUG) || defined(DOXYGEN_MAKE) 
/**
 * \brief Dump an integer
 *
 * \param p The integer to dump
 */
#   define DUMP(p) printf("%d\n", p)
#else
#   define DUMP(p) 
#endif //!DEBUG 

and given 
/**
 * \file file2.cpp
 *
 * define an other version of dump
 */

/// Some structure
struct Employe
{
  int     id; 
  string  name;
};

#if defined(DEBUG) || defined(DOXYGEN_MAKE) 
/**
 * \brief Dump an instance of Employe
 *
 * \param p The empoyee instance to dump
 */
#   define DUMP(p) printf("[%d] %s\n", p->id, p->name.c_str())
#else
#   define DUMP(p) 
#endif //!DEBUG 


#if defined(DEBUG) || defined(DOXYGEN_MAKE) 
/**
 * \brief Dump a list of Employe
 *
 * \param p The list
 */
#   define DUMP_LIST(p) \
          for(list<Employe> it(p.begin()), itEnd(p.end(); \
              it != itEnd;                                \
              ++it)                                       \
              DUMP(*it);
#else
#   define DUMP_LIST(p) 
#endif //!DEBUG 

Doxygen generates for file2.cpp the following documentation:
#define DUMP_LIST  ( p    )   

Value:

for(list<Employe> it(p.begin()), itEnd(p.end(); \
              it != itEnd;                                \
              ++it)                                       \
              DUMP(*it);

Where DUMP has a tooltip saying "Dump an integer", and is a link to the DUMP macro within file1.cpp


This is due to the fact that redefinition are ignored in:
def=g_fileDefineDict->find(g_defName);
if (def==0) // new define
{
  //printf("new define!\n");
  g_fileDefineDict->insert(g_defName,newDefine());
}
else if (def)// name already exists
{
  //printf("existing define!\n");
  //printf("define found\n");
  if (def->undef) // undefined name
  {
    def->undef = FALSE;
    def->name = g_defName;
    def->definition = g_defText.stripWhiteSpace();
    def->nargs = g_defArgs;
    def->fileName = g_yyFileName.copy(); 
    def->lineNr = g_yyLineNr;
  }
  else
  {
    //printf("Error: define %s is defined more than once!\n",g_defName.data());
  }
					    }
What i would like to do if my wife was granting time for it would be to replace
    //printf("Error: define %s is defined more than once!\n",g_defName.data());
with building within "def" a link list of "Define*"  and wind over this list in isDefined() (Together with the winding over the "active header" that i already added to isDefined()

Kind Regards
Gilles
Comment 6 Gilles 2010-02-16 14:06:29 UTC
Created attachment 153918 [details]
Example for the wrong link

I attached my test files that describe this further problem
The issue if that if i test def->fileName in isDefined() against the list of headers that have been seen since the begining of preprocessFile() then I find that DUMP has been dedined in file1.cpp, and thus when i process file2.cpp my "fixed" isDefined states that DUMP is not defined.   
Thus the need to have a link list of all definitions of "DUMP" in this example
Kind regards
Gilles
Comment 7 Dimitri van Heesch 2010-02-21 12:57:44 UTC
This bug was previously marked ASSIGNED, which means it should be fixed in
doxygen version 1.6.3. Please verify if this is indeed the case. Reopen the
bug if you think it is not fixed and please include any additional information 
that you think can be relevant.
Comment 8 Gilles 2010-02-21 20:02:37 UTC
Hi Dimitri
thanks for the quick resolution of the problem described in the attachment 1 [details]  and 2.  
But it seems that you over read the issue described in 
Gilles  [reporter]      2010-02-16 14:00:12 UTC 
Gilles  [reporter]      2010-02-16 14:06:29 UTC 

When I run 1.6.3 against the third attachment the link in the definition of DUMP_LIST link to the wrong definition; an the tool tip is the title of the wrong definition

Can you have a second look?
Thanks
  Gilles
Comment 9 Dimitri van Heesch 2010-06-11 21:08:08 UTC
Can you try with the latest subversion snapshot? I see the link now pointing to the right definition.
Comment 10 Felipe Besoaín Pino 2010-10-01 01:58:46 UTC
ping Gilles?
Comment 11 Fabio Durán Verdugo 2010-11-22 15:58:02 UTC
Closing this bug report as no further information has been provided. Please feel free to reopen this bug if you can provide the information asked for.
Thanks!