[PATCH] [2/2] prototype mistaken as class constructor: recognize typedef names

Dave Dodge <[email protected]>
Newsgroups gmane.text.doxygen.devel
Message-ID <20051219230800.GF23243@basmati>
Symptom: Some function prototypes end up being treated as constructor calls.

Example:

  /** \brief something */
  typedef struct { int x; } t1;
  /** \brief something */
  typedef int t2;
  extern t1 foo(t2);                   // declaration

  /** \brief something */
  t1 foo(t2 x)                         // definition

Doxygen thinks that the declaration is actually a variable being
created with a call to a constructor for type t.  It ends up putting
it in the "Variables" section.

This patch adds a check to the arguments being passed to the function
that might be a constructor.  If any argument consists entirely of a
typedef name, it must be a bare type with no parameter name and
therefore this must be a function prototype instead of a constructor
call.

Index: doxygen-1.4.5/src/doxygen.cpp
===================================================================
--- doxygen-1.4.5.orig/src/doxygen.cpp	2005-11-11 12:20:37.000000000 -0500
+++ doxygen-1.4.5/src/doxygen.cpp	2005-11-11 12:25:40.000000000 -0500
@@ -1972,6 +1972,13 @@
         result=FALSE; // arg type is a known type
         goto done;
       }
+      // If the parameter is just a typedef, then this is a function prototype.
+      if(checkIfTypedef(ctx,fd,a->type))
+      {
+        //printf("%s:%d: false (arg is typedef)\n",__FILE__,__LINE__);
+        result=FALSE; // argument is a typedef
+        goto done;
+      }
       // If the argument is a pointer type, then this is a function prototype.
       if (a->type.find('*',a->type.length()-1)!=-1)
       {
Index: doxygen-1.4.5/src/util.h
===================================================================
--- doxygen-1.4.5.orig/src/util.h	2005-11-11 12:06:59.000000000 -0500
+++ doxygen-1.4.5/src/util.h	2005-11-11 12:25:40.000000000 -0500
@@ -153,6 +153,7 @@
                            QCString *pTemplSpec=0,
                            bool mayBeUnlinkable=FALSE,
                            bool mayBeHidden=FALSE);
+bool checkIfTypedef(Definition *scope,FileDef *fileScope,const char *n);
 NamespaceDef *getResolvedNamespace(const char *key);
 FileDef *findFileDef(const FileNameDict *fnDict,const char *n,
                 bool &ambig);
Index: doxygen-1.4.5/src/util.cpp
===================================================================
--- doxygen-1.4.5.orig/src/util.cpp	2005-11-11 12:15:24.000000000 -0500
+++ doxygen-1.4.5/src/util.cpp	2005-11-11 12:25:40.000000000 -0500
@@ -1310,6 +1310,61 @@
   return result;
 }
 
+/*! Returns true iff the given name string appears to be a typedef in scope. */
+bool checkIfTypedef(Definition *scope,FileDef *fileScope,const char *n)
+{
+  if (scope==0 ||
+      (scope->definitionType()!=Definition::TypeClass &&
+       scope->definitionType()!=Definition::TypeNamespace
+      )
+     )
+  {
+    scope=Doxygen::globalScope;
+  }
+
+  QCString name = n;
+  if (name.isEmpty())
+    return false; // no name was given
+
+  DefinitionList *dl = Doxygen::symbolMap->find(name);
+  if (dl==0)
+    return false; // could not find any matching symbols
+
+  // mostly copied from getResolvedClassRec()
+  QCString explicitScopePart;
+  int qualifierIndex = computeQualifiedIndex(name);
+  if (qualifierIndex!=-1)
+  {
+    explicitScopePart = name.left(qualifierIndex);
+    replaceNamespaceAliases(explicitScopePart,explicitScopePart.length());
+    name = name.mid(qualifierIndex+2);
+  }
+
+  // find the closest closest matching definition
+  DefinitionListIterator dli(*dl);
+  Definition *d;
+  int minDistance = 10000;
+  MemberDef *bestMatch = 0;
+  for (dli.toFirst();(d=dli.current());++dli)
+  {
+    if (d->definitionType()==Definition::TypeMember)
+    {
+      g_visitedNamespaces.clear();
+      int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart);
+      if (distance!=-1 && distance<minDistance)
+      {
+        minDistance = distance;
+        bestMatch = (MemberDef *)d;
+      }
+    }
+  }
+
+  if (bestMatch && bestMatch->isTypedef())
+    return true; // closest matching symbol is a typedef
+  else
+    return false;
+}
+
 //-------------------------------------------------------------------------
 //-------------------------------------------------------------------------
 //-------------------------------------------------------------------------


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.