From ff5ba4a40fa13c0987272d463ba0edc57bc10fa6 Mon Sep 17 00:00:00 2001
From: Dimitri van Heesch <doxygen@gmail.com>
Date: Fri, 22 May 2020 16:08:39 +0200
Subject: Refactoring: Removed creation of MemberDef's for macro definitions
 from pre.l

---
 src/CMakeLists.txt |  1 -
 src/define.cpp     | 54 --------------------------------------------
 src/define.h       | 32 +++++++++-----------------
 src/doxygen.cpp    | 35 +++++++++++++++++++++++++++++
 src/doxygen.h      |  3 ++-
 src/pre.l          | 66 +++++++++++++++++++++++-------------------------------
 6 files changed, 76 insertions(+), 115 deletions(-)
 delete mode 100644 src/define.cpp

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fec251e..e880722 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -204,7 +204,6 @@ add_library(doxymain STATIC
     context.cpp
     cppvalue.cpp
     defgen.cpp
-    define.cpp
     definition.cpp
     dia.cpp
     diagram.cpp
diff --git a/src/define.cpp b/src/define.cpp
deleted file mode 100644
index b5d9170..0000000
--- a/src/define.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/******************************************************************************
- *
- * 
- *
- * Copyright (C) 1997-2015 by Dimitri van Heesch.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation under the terms of the GNU General Public License is hereby 
- * granted. No representations are made about the suitability of this software 
- * for any purpose. It is provided "as is" without express or implied warranty.
- * See the GNU General Public License for more details.
- *
- * Documents produced by Doxygen are derivative works derived from the
- * input used in their production; they are not affected by this license.
- *
- */
-
-#include "define.h"
-#include "config.h"
-
-Define::Define()
-{ 
-  fileDef=0; 
-  lineNr=1;
-  columnNr=1;
-  nargs=-1;
-  undef=FALSE; 
-  varArgs=FALSE;
-  isPredefined=FALSE;
-  nonRecursive=FALSE;
-}
-
-Define::Define(const Define &d)
-      : name(d.name),definition(d.definition),fileName(d.fileName)
-{ 
-  //name=d.name; definition=d.definition; fileName=d.fileName; 
-  lineNr=d.lineNr; 
-  columnNr=d.columnNr;
-  nargs=d.nargs; 
-  undef=d.undef; 
-  varArgs=d.varArgs;
-  isPredefined=d.isPredefined;
-  nonRecursive=d.nonRecursive;
-  fileDef=0;
-}
-
-Define::~Define()
-{
-}
-
-bool Define::hasDocumentation()
-{
-  return definition && (doc || Config_getBool(EXTRACT_ALL));
-}
diff --git a/src/define.h b/src/define.h
index 3627140..0a3d62c 100644
--- a/src/define.h
+++ b/src/define.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright (C) 1997-2015 by Dimitri van Heesch.
+ * Copyright (C) 1997-2020 by Dimitri van Heesch.
  *
  * Permission to use, copy, modify, and distribute this software and its
  * documentation under the terms of the GNU General Public License is hereby
@@ -28,31 +28,21 @@ class FileDef;
 class Define
 {
   public:
-    Define();
-    Define(const Define &d);
-   ~Define();
-    bool hasDocumentation();
     QCString name;
     QCString definition;
     QCString fileName;
-    QCString doc;
-    QCString brief;
     QCString args;
-    QCString anchor;
-    FileDef *fileDef;
-    int lineNr;
-    int columnNr;
-    int nargs;
-    bool undef;
-    bool varArgs;
-    bool isPredefined;
-    bool nonRecursive;
+    FileDef *fileDef = 0;
+    int lineNr = 1;
+    int columnNr = 1;
+    int nargs = -1;
+    bool undef = FALSE;
+    bool varArgs = FALSE;
+    bool isPredefined = FALSE;
+    bool nonRecursive = FALSE;
 };
 
-/** A dictionary of references to Define objects. */
-typedef std::map< std::string,Define* > DefineMapRef;
-
-/** A dictionary of managed Define objects. */
-typedef std::map< std::string,std::unique_ptr<Define> > DefineMapOwning;
+/** List of all macro definitions */
+using DefineList = std::vector< std::unique_ptr<Define> >;
 
 #endif
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 5f324fd..c7c9b45 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -160,6 +160,7 @@ bool             Doxygen::generatingXmlOutput = FALSE;
 bool             Doxygen::markdownSupport = TRUE;
 GenericsSDict   *Doxygen::genericsDict;
 Preprocessor    *Doxygen::preprocessor = 0;
+DefineList       Doxygen::macroDefinitions;
 
 // locally accessible globals
 static std::unordered_map< std::string, const Entry* > g_classEntries;
@@ -7698,6 +7699,36 @@ static void addSourceReferences()
 
 //----------------------------------------------------------------------------
 
+// add the macro definitions found during preprocessing as file members
+static void buildDefineList()
+{
+  for (const auto &def : Doxygen::macroDefinitions)
+  {
+    std::unique_ptr<MemberDef> md { createMemberDef(
+      def->fileName,def->lineNr,def->columnNr,
+      "#define",def->name,def->args,0,
+      Public,Normal,FALSE,Member,MemberType_Define,
+      ArgumentList(),ArgumentList(),"") };
+
+    if (!def->args.isEmpty())
+    {
+      md->moveArgumentList(stringToArgumentList(SrcLangExt_Cpp, def->args));
+    }
+    md->setInitializer(def->definition);
+    md->setFileDef(def->fileDef);
+    md->setDefinition("#define "+def->name);
+
+    MemberName *mn=Doxygen::functionNameLinkedMap->add(def->name);
+    if (def->fileDef)
+    {
+      def->fileDef->insertMember(md.get());
+    }
+    mn->push_back(std::move(md));
+  }
+}
+
+//----------------------------------------------------------------------------
+
 static void sortMemberLists()
 {
   // sort class member lists
@@ -10876,6 +10907,10 @@ void parseInput()
    *             Gather information                                         *
    **************************************************************************/
 
+  g_s.begin("Building macro definition list...\n");
+  buildDefineList();
+  g_s.end();
+
   g_s.begin("Building group list...\n");
   buildGroupList(root.get());
   organizeSubGroups(root.get());
diff --git a/src/doxygen.h b/src/doxygen.h
index d8cd1fc..b824b54 100644
--- a/src/doxygen.h
+++ b/src/doxygen.h
@@ -28,6 +28,7 @@
 #include "membergroup.h"
 #include "dirdef.h"
 #include "memberlist.h"
+#include "define.h"
 
 class RefList;
 class PageSList;
@@ -107,7 +108,6 @@ class Doxygen
     static FileNameLinkedMap        *diaFileNameLinkedMap;
     static MemberNameLinkedMap      *memberNameLinkedMap;
     static MemberNameLinkedMap      *functionNameLinkedMap;
-    static QStrList                  tagfileList;
     static StringUnorderedMap        namespaceAliasMap;
     static GroupSDict               *groupSDict;
     static NamespaceSDict           *namespaceSDict;
@@ -139,6 +139,7 @@ class Doxygen
     static bool                      markdownSupport;
     static GenericsSDict            *genericsDict;
     static Preprocessor             *preprocessor;
+    static DefineList                macroDefinitions;
 };
 
 void initDoxygen();
diff --git a/src/pre.l b/src/pre.l
index da67db5..ef97f0a 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -57,8 +57,6 @@
 #include "condparser.h"
 #include "config.h"
 #include "filedef.h"
-#include "memberdef.h"
-#include "membername.h"
 
 #define YY_NO_UNISTD_H 1
 
@@ -93,6 +91,12 @@ struct FileState
   QCString fileName;
 };
 
+/** A dictionary of references to Define objects. */
+typedef std::map< std::string,Define* > DefineMapRef;
+
+/** A dictionary of managed Define objects. */
+typedef std::map< std::string,std::unique_ptr<Define> > DefineMapOwning;
+
 /** @brief Singleton that manages the defines available while 
  *  preprocessing files. 
  */
@@ -415,7 +419,7 @@ static bool      otherCaseDone(yyscan_t yyscanner);
 static bool  computeExpression(yyscan_t yyscanner,const QCString &expr);
 static void   startCondSection(yyscan_t yyscanner,const char *sectId);
 static void     endCondSection(yyscan_t yyscanner);
-static void          addDefine(yyscan_t yyscanner);
+static void addMacroDefinition(yyscan_t yyscanner);
 static std::unique_ptr<Define> newDefine(yyscan_t yyscanner);
 static void        setFileName(yyscan_t yyscanner,const char *name);
 static yy_size_t        yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size);
@@ -1540,7 +1544,7 @@ CHARLIT   (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
 					  //printf("Define name='%s' text='%s' litTexti='%s'\n",yyextra->defName.data(),yyextra->defText.data(),yyextra->defLitText.data());
 					  if (yyextra->includeStack.empty() || yyextra->curlyCount>0) 
 					  {
-					    addDefine(yyscanner);
+					    addMacroDefinition(yyscanner);
 					  }
 					  def=g_defineManager.isDefined(yyextra->defName);
 					  if (def==0) // new define
@@ -2787,60 +2791,46 @@ static std::unique_ptr<Define> newDefine(yyscan_t yyscanner)
   return def;
 }
 
-static void addDefine(yyscan_t yyscanner)
+static void addMacroDefinition(yyscan_t yyscanner)
 {
   YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
   if (state->skip) return; // do not add this define as it is inside a 
                       // conditional section (cond command) that is disabled.
 
-  //printf("addDefine '%s' '%s'\n",state->defName.data(),state->defArgsStr.data());
-  //ArgumentList *al = new ArgumentList;
-  //stringToArgumentList(state->defArgsStr,al);
-  std::unique_ptr<MemberDef> md { createMemberDef(
-      state->yyFileName,state->yyLineNr-state->yyMLines,state->yyColNr,
-      "#define",state->defName,state->defArgsStr,0,
-      Public,Normal,FALSE,Member,MemberType_Define,ArgumentList(),ArgumentList(),"") };
-  if (!state->defArgsStr.isEmpty())
-  {
-    //printf("addDefine() state->defName='%s' state->defArgsStr='%s'\n",state->defName.data(),state->defArgsStr.data());
-    md->moveArgumentList(stringToArgumentList(SrcLangExt_Cpp, state->defArgsStr));
-  }
-  //printf("Setting initializer for '%s' to '%s'\n",state->defName.data(),state->defText.data());
-  int l=state->defLitText.find('\n');
-  if (l>0 && state->defLitText.left(l).stripWhiteSpace()=="\\")
+  auto define = std::make_unique<Define>();
+  define->fileName = state->yyFileName;
+  define->lineNr   = state->yyLineNr - state->yyMLines;
+  define->columnNr = state->yyColNr;
+  define->name     = state->defName;
+  define->args     = state->defArgsStr;
+  define->fileDef  = state->inputFileDef;
+
+  QCString litText = state->defLitText;
+  int l=litText.find('\n');
+  if (l>0 && litText.left(l).stripWhiteSpace()=="\\")
   {
     // strip first line if it only contains a slash
-    state->defLitText = state->defLitText.right(state->defLitText.length()-l-1);
+    litText = litText.right(litText.length()-l-1);
   }
   else if (l>0)
   {
     // align the items on the first line with the items on the second line
     int k=l+1;
-    const char *p=state->defLitText.data()+k;
+    const char *p=litText.data()+k;
     char c;
     while ((c=*p++) && (c==' ' || c=='\t')) k++;
-    state->defLitText=state->defLitText.mid(l+1,k-l-1)+state->defLitText.stripWhiteSpace();
+    litText=litText.mid(l+1,k-l-1)+litText.stripWhiteSpace();
   }
-  QCString defLitTextStripped = state->defLitText.stripWhiteSpace();
-  if (defLitTextStripped.contains('\n')>=1)
+  QCString litTextStripped = state->defLitText.stripWhiteSpace();
+  if (litTextStripped.contains('\n')>=1)
   {
-    md->setInitializer(state->defLitText);
+    define->definition = litText;
   }
   else
   {
-    md->setInitializer(defLitTextStripped);
-  }
-
-  //printf("pre.l: md->setFileDef(%p)\n",state->inputFileDef);
-  md->setFileDef(state->inputFileDef);
-  md->setDefinition("#define "+state->defName);
-
-  MemberName *mn=Doxygen::functionNameLinkedMap->add(state->defName);
-  if (state->yyFileDef) 
-  {
-    state->yyFileDef->insertMember(md.get());
+    define->definition = litTextStripped;
   }
-  mn->push_back(std::move(md));
+  Doxygen::macroDefinitions.push_back(std::move(define));
 }
 
 static inline void outputChar(yyscan_t yyscanner,char c)
-- 
cgit v0.12

