summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/context.cpp38
-rw-r--r--src/definition.cpp62
-rw-r--r--src/definition.h61
-rw-r--r--src/doxygen.cpp101
-rw-r--r--src/doxygen.h6
-rw-r--r--src/index.cpp2
-rw-r--r--src/markdown.cpp14
-rw-r--r--src/pycode.l18
-rw-r--r--src/scopedtypevariant.h18
-rw-r--r--src/symbolmap.h79
-rw-r--r--src/util.cpp144
11 files changed, 200 insertions, 343 deletions
diff --git a/src/context.cpp b/src/context.cpp
index 394e857..59889ce 100644
--- a/src/context.cpp
+++ b/src/context.cpp
@@ -1554,16 +1554,14 @@ class DefinitionContext
QCString result = "unspecified";
switch (m_def->definitionType())
{
- case DefinitionIntf::TypeClass: result="class"; break;
- case DefinitionIntf::TypeFile: result="file"; break;
- case DefinitionIntf::TypeNamespace: result="namespace"; break;
- case DefinitionIntf::TypeGroup: result="module"; break;
- case DefinitionIntf::TypePackage: result="package"; break;
- case DefinitionIntf::TypePage: result="page"; break;
- case DefinitionIntf::TypeDir: result="dir"; break;
- case DefinitionIntf::TypeMember: // fall through
- case DefinitionIntf::TypeSymbolList:
- break;
+ case Definition::TypeClass: result="class"; break;
+ case Definition::TypeFile: result="file"; break;
+ case Definition::TypeNamespace: result="namespace"; break;
+ case Definition::TypeGroup: result="module"; break;
+ case Definition::TypePackage: result="package"; break;
+ case Definition::TypePage: result="page"; break;
+ case Definition::TypeDir: result="dir"; break;
+ case Definition::TypeMember: break;
}
return result;
}
@@ -10309,25 +10307,9 @@ void generateOutputViaTemplate()
}
// clear all cached data in Definition objects.
- QDictIterator<DefinitionIntf> di(*Doxygen::symbolMap);
- const DefinitionIntf *intf;
- for (;(intf=di.current());++di)
+ for (const auto &kv : Doxygen::symbolMap)
{
- if (intf->definitionType()==DefinitionIntf::TypeSymbolList) // list of symbols
- {
- DefinitionListIterator dli(*dynamic_cast<const DefinitionList*>(intf));
- const Definition *d;
- // for each symbol
- for (dli.toFirst();(d=dli.current());++dli)
- {
- d->setCookie(0);
- }
- }
- else // single symbol
- {
- const Definition *d = dynamic_cast<const Definition *>(intf);
- d->setCookie(0);
- }
+ kv.second->setCookie(0);
}
e.destroyContext(ctx);
diff --git a/src/definition.cpp b/src/definition.cpp
index 355ef82..8f0b5a1 100644
--- a/src/definition.cpp
+++ b/src/definition.cpp
@@ -224,40 +224,7 @@ static void addToMap(const char *name,Definition *d)
if (!vhdlOpt && index!=-1) symbolName=symbolName.mid(index+2);
if (!symbolName.isEmpty())
{
- //printf("******* adding symbol '%s' (%p)\n",symbolName.data(),d);
- DefinitionIntf *di=Doxygen::symbolMap->find(symbolName);
- //printf(" addToMap(%p): looking for symbol %s: %p\n",d,symbolName.data(),di);
- if (di==0) // new Symbol
- {
- //printf(" new symbol!\n");
- Doxygen::symbolMap->insert(symbolName,d);
- }
- else // existing symbol
- {
- //printf(" existing symbol: ");
- if (di->definitionType()==DefinitionIntf::TypeSymbolList) // already multiple symbols
- {
- //printf("adding to exiting list\n");
- DefinitionList *dl = (DefinitionList*)di;
- dl->append(d);
- }
- else // going from one to two symbols
- {
- Doxygen::symbolMap->take(symbolName);
- DefinitionList *dl = new DefinitionList;
- //printf("replacing symbol by list %p with elements %p and %p\n",dl,di,d);
- dl->append((Definition*)di);
- dl->append(d);
- Doxygen::symbolMap->insert(symbolName,dl);
- }
- }
-
- // auto resize if needed
- static int sizeIndex=9;
- if (Doxygen::symbolMap->size()>SDict_primes[sizeIndex])
- {
- Doxygen::symbolMap->resize(SDict_primes[++sizeIndex]);
- }
+ Doxygen::symbolMap.add(symbolName,d);
d->_setSymbolName(symbolName);
}
@@ -265,32 +232,7 @@ static void addToMap(const char *name,Definition *d)
static void removeFromMap(Definition *d)
{
- QCString symbolName = d->_symbolName();
- if (!symbolName.isEmpty())
- {
- //printf("******* removing symbol '%s' (%p)\n",symbolName.data(),d);
- DefinitionIntf *di=Doxygen::symbolMap->find(symbolName);
- if (di)
- {
- if (di!=d) // symbolName not unique
- {
- //printf(" removing from list: %p!\n",di);
- DefinitionList *dl = (DefinitionList*)di;
- bool b = dl->removeRef(d);
- ASSERT(b==TRUE);
- if (dl->isEmpty())
- {
- Doxygen::symbolMap->take(symbolName);
- delete dl;
- }
- }
- else // symbolName unique
- {
- //printf(" removing symbol %p\n",di);
- Doxygen::symbolMap->take(symbolName);
- }
- }
- }
+ Doxygen::symbolMap.remove(d->_symbolName(),d);
}
DefinitionImpl::DefinitionImpl(const char *df,int dl,int dc,
diff --git a/src/definition.h b/src/definition.h
index b3d7853..9b31f2f 100644
--- a/src/definition.h
+++ b/src/definition.h
@@ -68,12 +68,19 @@ struct BodyInfo
FileDef *fileDef; //!< file definition containing the function body
};
-/** Abstract interface for a Definition or DefinitionList */
-class DefinitionIntf
+/** The common base class of all entity definitions found in the sources.
+ *
+ * This can be a class or a member function, or a file, or a namespace, etc.
+ * Use definitionType() to find which type of definition this is.
+ */
+class Definition
{
public:
- DefinitionIntf() {}
- virtual ~DefinitionIntf() {}
+ struct Cookie
+ {
+ virtual ~Cookie() {}
+ };
+
/*! Types of derived classes */
enum DefType
{
@@ -84,29 +91,16 @@ class DefinitionIntf
TypeGroup = 4,
TypePackage = 5,
TypePage = 6,
- TypeDir = 7,
- TypeSymbolList = 8
- };
- /*! Use this for dynamic inspection of the type of the derived class */
- virtual DefType definitionType() const = 0;
-};
-
-/** The common base class of all entity definitions found in the sources.
- *
- * This can be a class or a member function, or a file, or a namespace, etc.
- * Use definitionType() to find which type of definition this is.
- */
-class Definition : public DefinitionIntf
-{
- public:
- struct Cookie
- {
- virtual ~Cookie() {}
+ TypeDir = 7
};
//-----------------------------------------------------------------------------------
// ---- getters -----
//-----------------------------------------------------------------------------------
+
+ /*! Use this for dynamic inspection of the type of the derived class */
+ virtual DefType definitionType() const = 0;
+
/*! Returns TRUE if this is an alias of another definition */
virtual bool isAlias() const = 0;
@@ -375,28 +369,9 @@ class Definition : public DefinitionIntf
//-----------------------------------------------------------------------------------
virtual void _setSymbolName(const QCString &name) = 0;
virtual QCString _symbolName() const = 0;
-};
-
-/** A list of Definition objects. */
-class DefinitionList : public QList<Definition>, public DefinitionIntf
-{
- public:
- ~DefinitionList() {}
- DefType definitionType() const { return TypeSymbolList; }
- int compareValues(const Definition *item1,const Definition *item2) const
- {
- return qstricmp(item1->name(),item2->name());
- }
-};
-
-/** An iterator for Definition objects in a DefinitionList. */
-class DefinitionListIterator : public QListIterator<Definition>
-{
- public:
- DefinitionListIterator(const DefinitionList &l) :
- QListIterator<Definition>(l) {}
- ~DefinitionListIterator() {}
+ // ---------------------------------
+ virtual ~Definition() = default;
};
/** Reads a fragment from file \a fileName starting with line \a startLine
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 1a70e61..988b308 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -142,7 +142,7 @@ bool Doxygen::insideMainPage = FALSE; // are we generating docs for
NamespaceDef *Doxygen::globalScope = 0;
bool Doxygen::parseSourcesNeeded = FALSE;
SearchIndexIntf *Doxygen::searchIndex=0;
-QDict<DefinitionIntf> *Doxygen::symbolMap = 0;
+SymbolMap<Definition> Doxygen::symbolMap;
QDict<Definition> *Doxygen::clangUsrMap = 0;
bool Doxygen::outputToWizard=FALSE;
QDict<int> * Doxygen::htmlDirMap = 0;
@@ -1177,7 +1177,7 @@ static void resolveClassNestingRelations()
cd->setOuterScope(d);
// for inline namespace add an alias of the class to the outer scope
- while (d->definitionType()==DefinitionIntf::TypeNamespace)
+ while (d->definitionType()==Definition::TypeNamespace)
{
NamespaceDef *nd = dynamic_cast<NamespaceDef*>(d);
//printf("d->isInline()=%d\n",nd->isInline());
@@ -1565,7 +1565,7 @@ static void buildNamespaceList(const Entry *root)
d->addInnerCompound(nd);
nd->setOuterScope(d);
// in case of d is an inline namespace, alias insert nd in the part scope of d.
- while (d->definitionType()==DefinitionIntf::TypeNamespace)
+ while (d->definitionType()==Definition::TypeNamespace)
{
NamespaceDef *pnd = dynamic_cast<NamespaceDef*>(d);
if (pnd->isInline())
@@ -2429,7 +2429,8 @@ static bool isVarWithConstructor(const Entry *root)
static QRegExp initChars("[0-9\"'&*!^]+");
static QRegExp idChars("[a-z_A-Z][a-z_A-Z0-9]*");
bool result=FALSE;
- bool typeIsClass;
+ bool typeIsClass = false;
+ bool typePtrType = false;
QCString type;
Definition *ctx = 0;
FileDef *fd = 0;
@@ -2462,11 +2463,15 @@ static bool isVarWithConstructor(const Entry *root)
findAndRemoveWord(type,"const");
findAndRemoveWord(type,"static");
findAndRemoveWord(type,"volatile");
+ typePtrType = type.find('*')!=-1 || type.find('&')!=-1;
//if (type.left(6)=="const ") type=type.right(type.length()-6);
- typeIsClass=getResolvedClass(ctx,fd,type)!=0;
- if (!typeIsClass && (ti=type.find('<'))!=-1)
+ if (!typePtrType)
{
- typeIsClass=getResolvedClass(ctx,fd,type.left(ti))!=0;
+ typeIsClass = getResolvedClass(ctx,fd,type)!=0;
+ if (!typeIsClass && (ti=type.find('<'))!=-1)
+ {
+ typeIsClass=getResolvedClass(ctx,fd,type.left(ti))!=0;
+ }
}
if (typeIsClass) // now we still have to check if the arguments are
// types or values. Since we do not have complete type info
@@ -2492,6 +2497,14 @@ static bool isVarWithConstructor(const Entry *root)
}
goto done;
}
+ if (!a.type.isEmpty() &&
+ (a.type.at(a.type.length()-1)=='*' ||
+ a.type.at(a.type.length()-1)=='&'))
+ // type ends with * or & => pointer or reference
+ {
+ result=FALSE;
+ goto done;
+ }
if (a.type.isEmpty() || getResolvedClass(ctx,fd,a.type)!=0)
{
result=FALSE; // arg type is a known type
@@ -2503,13 +2516,6 @@ static bool isVarWithConstructor(const Entry *root)
result=FALSE; // argument is a typedef
goto done;
}
- if (a.type.at(a.type.length()-1)=='*' ||
- a.type.at(a.type.length()-1)=='&')
- // type ends with * or & => pointer or reference
- {
- result=FALSE;
- goto done;
- }
if (a.type.find(initChars)==0)
{
result=TRUE; // argument type starts with typical initializer char
@@ -7812,25 +7818,9 @@ static void sortMemberLists()
void computeTooltipTexts()
{
- QDictIterator<DefinitionIntf> di(*Doxygen::symbolMap);
- DefinitionIntf *intf;
- for (;(intf=di.current());++di)
+ for (const auto &kv : Doxygen::symbolMap)
{
- if (intf->definitionType()==DefinitionIntf::TypeSymbolList) // list of symbols
- {
- DefinitionListIterator dli(*(DefinitionList*)intf);
- Definition *d;
- // for each symbol
- for (dli.toFirst();(d=dli.current());++dli)
- {
- d->computeTooltip();
- }
- }
- else // single symbol
- {
- Definition *d = (Definition *)intf;
- if (d!=Doxygen::globalScope) d->computeTooltip();
- }
+ kv.second->computeTooltip();
}
}
@@ -9796,25 +9786,9 @@ static void dumpSymbolMap()
if (f.open(IO_WriteOnly))
{
FTextStream t(&f);
- QDictIterator<DefinitionIntf> di(*Doxygen::symbolMap);
- DefinitionIntf *intf;
- for (;(intf=di.current());++di)
+ for (const auto &kv : Doxygen::symbolMap)
{
- if (intf->definitionType()==DefinitionIntf::TypeSymbolList) // list of symbols
- {
- DefinitionListIterator dli(*(DefinitionList*)intf);
- Definition *d;
- // for each symbol
- for (dli.toFirst();(d=dli.current());++dli)
- {
- dumpSymbol(t,d);
- }
- }
- else // single symbol
- {
- Definition *d = (Definition *)intf;
- if (d!=Doxygen::globalScope) dumpSymbol(t,d);
- }
+ dumpSymbol(t,kv.second);
}
}
}
@@ -9939,7 +9913,6 @@ void initDoxygen()
initNamespaceMemberIndices();
initFileMemberIndices();
- Doxygen::symbolMap = new QDict<DefinitionIntf>(50177);
#ifdef USE_LIBCLANG
Doxygen::clangUsrMap = new QDict<Definition>(50177);
#endif
@@ -10012,26 +9985,6 @@ void cleanUpDoxygen()
delete g_outputList;
Mappers::freeMappers();
- if (Doxygen::symbolMap)
- {
- // iterate through Doxygen::symbolMap and delete all
- // DefinitionList objects, since they have no owner
- QDictIterator<DefinitionIntf> dli(*Doxygen::symbolMap);
- DefinitionIntf *di;
- for (dli.toFirst();(di=dli.current());)
- {
- if (di->definitionType()==DefinitionIntf::TypeSymbolList)
- {
- DefinitionIntf *tmp = Doxygen::symbolMap->take(dli.currentKey());
- delete (DefinitionList *)tmp;
- }
- else
- {
- ++dli;
- }
- }
- }
-
delete Doxygen::memberNameLinkedMap;
delete Doxygen::functionNameLinkedMap;
delete Doxygen::groupSDict;
@@ -10041,11 +9994,6 @@ void cleanUpDoxygen()
delete Doxygen::directories;
DotManager::deleteInstance();
-
- //delete Doxygen::symbolMap; <- we cannot do this unless all static lists
- // (such as Doxygen::namespaceSDict)
- // with objects based on Definition are made
- // dynamic first
}
static int computeIdealCacheParam(uint v)
@@ -11811,7 +11759,6 @@ void generateOutput()
thisDir.remove(Doxygen::filterDBFileName);
Config::deinit();
QTextCodec::deleteAllCodecs();
- delete Doxygen::symbolMap;
delete Doxygen::clangUsrMap;
g_successfulRun=TRUE;
}
diff --git a/src/doxygen.h b/src/doxygen.h
index f2b7dda..b48a92c 100644
--- a/src/doxygen.h
+++ b/src/doxygen.h
@@ -29,6 +29,7 @@
#include "memberlist.h"
#include "define.h"
#include "cache.h"
+#include "symbolmap.h"
#define THREAD_LOCAL thread_local
#define AtomicInt std::atomic_int
@@ -54,7 +55,6 @@ class MemberNameLinkedMap;
class FileNameLinkedMap;
class NamespaceSDict;
class NamespaceDef;
-class DefinitionIntf;
class DirSDict;
class DirRelation;
class IndexList;
@@ -66,8 +66,6 @@ struct MemberGroupInfo;
typedef QList<QCString> StringList;
typedef QListIterator<QCString> StringListIterator;
-//typedef QDict<FileDef> FileDict;
-//typedef QDict<GroupDef> GroupDict;
class StringDict : public QDict<QCString>
{
@@ -123,7 +121,7 @@ class Doxygen
static QCString htmlFileExtension;
static bool parseSourcesNeeded;
static SearchIndexIntf *searchIndex;
- static QDict<DefinitionIntf> *symbolMap;
+ static SymbolMap<Definition> symbolMap;
static QDict<Definition> *clangUsrMap;
static bool outputToWizard;
static QDict<int> *htmlDirMap;
diff --git a/src/index.cpp b/src/index.cpp
index c4fda05..e9619ad 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -2762,7 +2762,7 @@ static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char
static void writeMemberList(OutputList &ol,bool useSections,int page,
const LetterToIndexMap<MemberIndexList> &memberLists,
- DefinitionIntf::DefType type)
+ Definition::DefType type)
{
int index = (int)type;
ASSERT(index<3);
diff --git a/src/markdown.cpp b/src/markdown.cpp
index 7f6dc9b..68f13c1 100644
--- a/src/markdown.cpp
+++ b/src/markdown.cpp
@@ -1933,16 +1933,16 @@ int Markdown::writeTableBlock(const char *data,int size)
{
if (row % 2)
{
- m_out.addStr("<tr class=\"markdownTableRowOdd\">");
+ m_out.addStr("\n<tr class=\"markdownTableRowOdd\">");
}
else
{
- m_out.addStr("<tr class=\"markdownTableRowEven\">");
+ m_out.addStr("\n<tr class=\"markdownTableRowEven\">");
}
}
else
{
- m_out.addStr(" <tr class=\"markdownTableHead\">");
+ m_out.addStr("\n <tr class=\"markdownTableHead\">");
}
for (int c = 0; c < columns; c++)
{
@@ -2000,7 +2000,7 @@ int Markdown::writeTableBlock(const char *data,int size)
}
cellTag = "td";
cellClass = "class=\"markdownTableBody";
- m_out.addStr(" </tr>\n");
+ m_out.addStr(" </tr>");
}
m_out.addStr("</table>\n");
@@ -2114,14 +2114,14 @@ int Markdown::writeBlockQuote(const char *data,int size)
{
for (l=curLevel;l<level;l++)
{
- m_out.addStr("<blockquote>\n");
+ m_out.addStr("<blockquote>");
}
}
else if (level<curLevel) // quote level decreased => add end markers
{
for (l=level;l<curLevel;l++)
{
- m_out.addStr("</blockquote>\n");
+ m_out.addStr("</blockquote>");
}
}
curLevel=level;
@@ -2134,7 +2134,7 @@ int Markdown::writeBlockQuote(const char *data,int size)
// end of comment within blockquote => add end markers
for (l=0;l<curLevel;l++)
{
- m_out.addStr("</blockquote>\n");
+ m_out.addStr("</blockquote>");
}
return i;
}
diff --git a/src/pycode.l b/src/pycode.l
index dcba4dd..7fb4184 100644
--- a/src/pycode.l
+++ b/src/pycode.l
@@ -1490,22 +1490,10 @@ static void findMemberLink(yyscan_t yyscanner,
// );
if (yyextra->currentDefinition)
{
- DefinitionIntf *di = Doxygen::symbolMap->find(symName);
- if (di)
+ auto range = Doxygen::symbolMap.find(symName);
+ for (auto it = range.first; it!=range.second; ++it)
{
- if (di->definitionType()==DefinitionIntf::TypeSymbolList) // multiple symbols
- {
- DefinitionListIterator dli(*(DefinitionList*)di);
- Definition *sym;
- for (dli.toFirst();(sym=dli.current());++dli)
- {
- if (findMemberLink(yyscanner,ol,sym,symName)) return;
- }
- }
- else // single symbol
- {
- if (findMemberLink(yyscanner,ol,(Definition*)di,symName)) return;
- }
+ findMemberLink(yyscanner,ol,it->second,symName);
}
}
//printf("sym %s not found\n",&yytext[5]);
diff --git a/src/scopedtypevariant.h b/src/scopedtypevariant.h
index 2648a3a..d544434 100644
--- a/src/scopedtypevariant.h
+++ b/src/scopedtypevariant.h
@@ -26,7 +26,7 @@
class LocalDef
{
public:
- void insertBaseClass(QCString name) { m_baseClasses.push_back(name); }
+ void insertBaseClass(const QCString &name) { m_baseClasses.push_back(name); }
std::vector<QCString> baseClasses() const { return m_baseClasses; }
private:
std::vector<QCString> m_baseClasses;
@@ -72,7 +72,7 @@ class ScopedTypeVariant
}
}
//! constructor for creating a variant of type Local
- explicit ScopedTypeVariant(QCString name)
+ explicit ScopedTypeVariant(const QCString &name)
{
m_name = name;
m_variant = Local;
@@ -93,7 +93,7 @@ class ScopedTypeVariant
}
}
//! move constructor
- ScopedTypeVariant(ScopedTypeVariant && stv) noexcept : ScopedTypeVariant()
+ ScopedTypeVariant(ScopedTypeVariant &&stv) noexcept : ScopedTypeVariant()
{
swap(*this,stv);
}
@@ -131,7 +131,7 @@ class ScopedTypeVariant
m_u.globalDef = def;
}
//! Turn the variant into a Local type
- LocalDef *setLocal(QCString name)
+ LocalDef *setLocal(const QCString &name)
{
if (m_variant==Local)
{
@@ -200,12 +200,12 @@ class VariableContext
{
m_scopes.clear();
}
- void addVariable(QCString name,ScopedTypeVariant stv)
+ void addVariable(const QCString &name,ScopedTypeVariant stv)
{
Scope *scope = m_scopes.empty() ? &m_globalScope : &m_scopes.back();
scope->emplace(std::make_pair(name.str(),std::move(stv))); // add it to a list
}
- const ScopedTypeVariant *findVariable(QCString name)
+ const ScopedTypeVariant *findVariable(const QCString &name)
{
const ScopedTypeVariant *result = 0;
if (name.isEmpty()) return result;
@@ -245,7 +245,7 @@ class CallContext
public:
struct Ctx
{
- Ctx(QCString name_,QCString type_) : name(name_), type(type_) {}
+ Ctx(const QCString &name_,const QCString &type_) : name(name_), type(type_) {}
QCString name;
QCString type;
ScopedTypeVariant stv;
@@ -255,12 +255,12 @@ class CallContext
{
clear();
}
- void setScope(ScopedTypeVariant stv)
+ void setScope(const ScopedTypeVariant &stv)
{
Ctx &ctx = m_stvList.back();
ctx.stv=std::move(stv);
}
- void pushScope(const QCString &name_,const QCString type_)
+ void pushScope(const QCString &name_,const QCString &type_)
{
m_stvList.push_back(Ctx(name_,type_));
}
diff --git a/src/symbolmap.h b/src/symbolmap.h
new file mode 100644
index 0000000..0f837d4
--- /dev/null
+++ b/src/symbolmap.h
@@ -0,0 +1,79 @@
+/******************************************************************************
+ *
+ * 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
+ * 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.
+ *
+ */
+
+#ifndef SYMBOLMAP_H
+#define SYMBOLMAP_H
+
+#include <algorithm>
+#include <map>
+#include <vector>
+#include <string>
+#include <utility>
+
+//! Class implementing a symbol map that maps symbol names to objects.
+//! Symbol names do not have to be unique.
+//! Supports adding symbols with add(), removing symbols with remove(), and
+//! finding symbols with find().
+template<class T>
+class SymbolMap
+{
+ public:
+ using Ptr = T *;
+ using Map = std::multimap<std::string,Ptr>;
+ using iterator = typename Map::iterator;
+ using const_iterator = typename Map::const_iterator;
+
+ //! Add a symbol \a def into the map under key \a name
+ void add(const char *name,Ptr def)
+ {
+ m_map.insert({std::string(name),def});
+ }
+
+ //! Remove a symbol \a def from the map that was stored under key \a name
+ void remove(const char *name,Ptr def)
+ {
+ auto range = find(name);
+ for (auto it=range.first; it!=range.second; )
+ {
+ if (it->second==def) it = m_map.erase(it); else ++it;
+ }
+ }
+
+ //! Find the list of symbols stored under key \a name
+ //! Returns a pair of iterators pointing to the start and end of the range of matching symbols
+ std::pair<const_iterator,const_iterator> find(const char *name) const
+ {
+ return m_map.equal_range(name ? name : "");
+ }
+
+ //! Find the list of symbols stored under key \a name
+ //! Returns a pair of iterators pointing to the start and end of the range of matching symbols
+ std::pair<iterator,iterator> find(const char *name)
+ {
+ return m_map.equal_range(name ? name : "");
+ }
+
+ iterator begin() { return m_map.begin(); }
+ iterator end() { return m_map.end(); }
+ const_iterator begin() const { return m_map.cbegin(); }
+ const_iterator end() const { return m_map.cend(); }
+ bool empty() const { return m_map.empty(); }
+ size_t size() const { return m_map.size(); }
+
+ private:
+ Map m_map;
+};
+
+#endif
diff --git a/src/util.cpp b/src/util.cpp
index dd25284..f518491 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -663,57 +663,37 @@ static QCString substTypedef(const Definition *scope,const FileDef *fileScope,co
QCString result=name;
if (name.isEmpty()) return result;
- // lookup scope fragment in the symbol map
- DefinitionIntf *di = Doxygen::symbolMap->find(name);
- if (di==0) return result; // no matches
+ auto range = Doxygen::symbolMap.find(name);
+ if (range.first==range.second)
+ return result; // no matches
MemberDef *bestMatch=0;
- if (di->definitionType()==DefinitionIntf::TypeSymbolList) // multi symbols
+ int minDistance=10000; // init at "infinite"
+
+ for (auto it = range.first; it!=range.second; ++it)
{
- // search for the best match
- DefinitionListIterator dli(*(DefinitionList*)di);
- Definition *d;
- int minDistance=10000; // init at "infinite"
- for (dli.toFirst();(d=dli.current());++dli) // foreach definition
+ Definition *d = it->second;
+ // only look at members
+ if (d->definitionType()==Definition::TypeMember)
{
- // only look at members
- if (d->definitionType()==Definition::TypeMember)
+ // that are also typedefs
+ MemberDef *md = dynamic_cast<MemberDef *>(d);
+ if (md->isTypedef()) // d is a typedef
{
- // that are also typedefs
- MemberDef *md = dynamic_cast<MemberDef *>(d);
- if (md->isTypedef()) // d is a typedef
+ VisitedNamespaces visitedNamespaces;
+ AccessStack accessStack;
+ // test accessibility of typedef within scope.
+ int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,"");
+ if (distance!=-1 && distance<minDistance)
+ // definition is accessible and a better match
{
- VisitedNamespaces visitedNamespaces;
- AccessStack accessStack;
- // test accessibility of typedef within scope.
- int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,"");
- if (distance!=-1 && distance<minDistance)
- // definition is accessible and a better match
- {
- minDistance=distance;
- bestMatch = md;
- }
+ minDistance=distance;
+ bestMatch = md;
}
}
}
}
- else if (di->definitionType()==DefinitionIntf::TypeMember) // single symbol
- {
- Definition *d = (Definition*)di;
- // that are also typedefs
- MemberDef *md = dynamic_cast<MemberDef *>(di);
- if (md->isTypedef()) // d is a typedef
- {
- // test accessibility of typedef within scope.
- VisitedNamespaces visitedNamespaces;
- AccessStack accessStack;
- int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,"");
- if (distance!=-1) // definition is accessible
- {
- bestMatch = md;
- }
- }
- }
+
if (bestMatch)
{
result = bestMatch->typeString();
@@ -1311,8 +1291,9 @@ static const ClassDef *getResolvedClassRec(const Definition *scope,
QCString *pResolvedType
)
{
- //printf("[getResolvedClassRec(%s,%s)\n",scope?scope->name().data():"<global>",n);
if (n==0 || *n=='\0') return 0;
+ //static int level=0;
+ //printf("%d [getResolvedClassRec(%s,%s)\n",level++,scope?scope->name().data():"<global>",n);
QCString name;
QCString explicitScopePart;
QCString strippedTemplateParams;
@@ -1338,20 +1319,20 @@ static const ClassDef *getResolvedClassRec(const Definition *scope,
if (name.isEmpty())
{
- //printf("] empty name\n");
+ //printf("%d ] empty name\n",--level);
return 0; // empty name
}
//printf("Looking for symbol %s\n",name.data());
- const DefinitionIntf *di = Doxygen::symbolMap->find(name);
+ auto range = Doxygen::symbolMap.find(name);
// the -g (for C# generics) and -p (for ObjC protocols) are now already
// stripped from the key used in the symbolMap, so that is not needed here.
- if (di==0)
+ if (range.first==range.second)
{
- di = Doxygen::symbolMap->find(name+"-p");
- if (di==0)
+ range = Doxygen::symbolMap.find(name+"-p");
+ if (range.first==range.second)
{
- //printf("no such symbol!\n");
+ //printf("%d ] no such symbol!\n",--level);
return 0;
}
}
@@ -1413,7 +1394,7 @@ static const ClassDef *getResolvedClassRec(const Definition *scope,
if (pTemplSpec) *pTemplSpec=pval->templSpec;
if (pTypeDef) *pTypeDef=pval->typeDef;
if (pResolvedType) *pResolvedType=pval->resolvedType;
- //printf("] cachedMatch=%s\n",
+ //printf("%d ] cachedMatch=%s\n",--level,
// pval->classDef?pval->classDef->name().data():"<none>");
//if (pTemplSpec)
// printf("templSpec=%s\n",pTemplSpec->data());
@@ -1432,23 +1413,9 @@ static const ClassDef *getResolvedClassRec(const Definition *scope,
QCString bestResolvedType;
int minDistance=10000; // init at "infinite"
- if (di->definitionType()==DefinitionIntf::TypeSymbolList) // not a unique name
+ for (auto it=range.first ; it!=range.second; ++it)
{
- //printf(" name is not unique\n");
- DefinitionListIterator dli(*(DefinitionList*)di);
- Definition *d;
- int count=0;
- for (dli.toFirst();(d=dli.current());++dli,++count) // foreach definition
- {
- getResolvedSymbol(scope,fileScope,d,explicitScopePart,actTemplParams,
- minDistance,bestMatch,bestTypedef,bestTemplSpec,
- bestResolvedType);
- }
- }
- else // unique name
- {
- //printf(" name is unique\n");
- Definition *d = (Definition *)di;
+ Definition *d = it->second;
getResolvedSymbol(scope,fileScope,d,explicitScopePart,actTemplParams,
minDistance,bestMatch,bestTypedef,bestTemplSpec,
bestResolvedType);
@@ -1477,7 +1444,7 @@ static const ClassDef *getResolvedClassRec(const Definition *scope,
pval->templSpec = bestTemplSpec;
pval->resolvedType = bestResolvedType;
}
- //printf("] bestMatch=%s distance=%d\n",
+ //printf("%d ] bestMatch=%s distance=%d\n",--level,
// bestMatch?bestMatch->name().data():"<none>",minDistance);
//if (pTemplSpec)
// printf("templSpec=%s\n",pTemplSpec->data());
@@ -2804,7 +2771,6 @@ static QCString getCanonicalTypeForIdentifier(
if (count>10) return word; // oops recursion
QCString symName,result,templSpec,tmpName;
- //DefinitionList *defList=0;
if (tSpec && !tSpec->isEmpty())
templSpec = stripDeclKeywords(getCanonicalTemplateSpec(d,fs,*tSpec));
@@ -6750,8 +6716,8 @@ MemberDef *getMemberFromSymbol(const Definition *scope,const FileDef *fileScope,
if (name.isEmpty())
return 0; // no name was given
- DefinitionIntf *di = Doxygen::symbolMap->find(name);
- if (di==0)
+ auto range = Doxygen::symbolMap.find(name);
+ if (range.first==range.second)
return 0; // could not find any matching symbols
// mostly copied from getResolvedClassRec()
@@ -6768,42 +6734,22 @@ MemberDef *getMemberFromSymbol(const Definition *scope,const FileDef *fileScope,
int minDistance = 10000;
MemberDef *bestMatch = 0;
- if (di->definitionType()==DefinitionIntf::TypeSymbolList)
+ for (auto it=range.first; it!=range.second; ++it)
{
- //printf("multiple matches!\n");
- // find the closest closest matching definition
- DefinitionListIterator dli(*(DefinitionList*)di);
- Definition *d;
- for (dli.toFirst();(d=dli.current());++dli)
+ Definition *d = it->second;
+ if (d->definitionType()==Definition::TypeMember)
{
- if (d->definitionType()==Definition::TypeMember)
+ VisitedNamespaces visitedNamespaces;
+ AccessStack accessStack;
+ int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,explicitScopePart);
+ if (distance!=-1 && distance<minDistance)
{
- VisitedNamespaces visitedNamespaces;
- AccessStack accessStack;
- int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,explicitScopePart);
- if (distance!=-1 && distance<minDistance)
- {
- minDistance = distance;
- bestMatch = dynamic_cast<MemberDef *>(d);
- //printf("new best match %s distance=%d\n",bestMatch->qualifiedName().data(),distance);
- }
+ minDistance = distance;
+ bestMatch = dynamic_cast<MemberDef *>(d);
+ //printf("new best match %s distance=%d\n",bestMatch->qualifiedName().data(),distance);
}
}
}
- else if (di->definitionType()==Definition::TypeMember)
- {
- //printf("unique match!\n");
- Definition *d = (Definition *)di;
- VisitedNamespaces visitedNamespaces;
- AccessStack accessStack;
- int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,explicitScopePart);
- if (distance!=-1 && distance<minDistance)
- {
- minDistance = distance;
- bestMatch = dynamic_cast<MemberDef *>(d);
- //printf("new best match %s distance=%d\n",bestMatch->qualifiedName().data(),distance);
- }
- }
return bestMatch;
}