Doxygen
Loading...
Searching...
No Matches
doxygen.cpp File Reference
#include "doxygen.h"
#include <algorithm>
#include <cerrno>
#include <chrono>
#include <cinttypes>
#include <clocale>
#include <cstdio>
#include <cstdlib>
#include <locale>
#include <memory>
#include <sys/stat.h>
#include <unordered_map>
#include "aliases.h"
#include "arguments.h"
#include "cite.h"
#include "clangparser.h"
#include "classlist.h"
#include "cmdmapper.h"
#include "code.h"
#include "commentcnv.h"
#include "conceptdef.h"
#include "config.h"
#include "debug.h"
#include "declinfo.h"
#include "defargs.h"
#include "defgen.h"
#include "dir.h"
#include "dirdef.h"
#include "docbookgen.h"
#include "docparser.h"
#include "docsets.h"
#include "dot.h"
#include "eclipsehelp.h"
#include "emoji.h"
#include "entry.h"
#include "fileinfo.h"
#include "filename.h"
#include "fileparser.h"
#include "formula.h"
#include "fortrancode.h"
#include "fortranscanner.h"
#include "ftvhelp.h"
#include "groupdef.h"
#include "htags.h"
#include "htmlgen.h"
#include "htmlhelp.h"
#include "index.h"
#include "indexlist.h"
#include "language.h"
#include "latexgen.h"
#include "layout.h"
#include "lexcode.h"
#include "lexscanner.h"
#include "mangen.h"
#include "markdown.h"
#include "membergroup.h"
#include "memberlist.h"
#include "membername.h"
#include "mermaid.h"
#include "message.h"
#include "moduledef.h"
#include "msc.h"
#include "namespacedef.h"
#include "outputlist.h"
#include "pagedef.h"
#include "parserintf.h"
#include "perlmodgen.h"
#include "plantuml.h"
#include "portable.h"
#include "pre.h"
#include "pycode.h"
#include "pyscanner.h"
#include "qhp.h"
#include "reflist.h"
#include "regex.h"
#include "requirement.h"
#include "rtfgen.h"
#include "scanner.h"
#include "searchindex_js.h"
#include "settings.h"
#include "singlecomment.h"
#include "sitemap.h"
#include "sqlcode.h"
#include "sqlite3gen.h"
#include "stlsupport.h"
#include "stringutil.h"
#include "symbolresolver.h"
#include "tagreader.h"
#include "threadpool.h"
#include "trace.h"
#include "util.h"
#include "version.h"
#include "vhdlcode.h"
#include "vhdldocgen.h"
#include "vhdljjparser.h"
#include "xmlcode.h"
#include "xmlgen.h"
#include <sqlite3.h>
#include <signal.h>
Include dependency graph for doxygen.cpp:

Go to the source code of this file.

Classes

class  Statistics
struct  Statistics::stat
class  NullOutlineParser
 /dev/null outline parser More...

Macros

#define HAS_SIGNALS

Enumerations

enum  FindBaseClassRelation_Mode { TemplateInstances , DocumentedOnly , Undocumented }

Functions

void initResources ()
void clearAll ()
static void addMemberDocs (const Entry *root, MemberDefMutable *md, const DString &funcDecl, const ArgumentList *al, bool over_load, TypeSpecifier spec)
static void findMember (const Entry *root, const DString &relates, const DString &type, const DString &args, DString funcDecl, bool overloaded, bool isFunc)
static bool findClassRelation (const Entry *root, Definition *context, ClassDefMutable *cd, const BaseInfo *bi, const TemplateNameMap &templateNames, FindBaseClassRelation_Mode mode, bool isArtificial)
template<class Def>
static void addIncludeFile (Def *def, FileDef *ifd, const Entry *root)
static Definition * findScopeFromQualifiedName (NamespaceDefMutable *startScope, const DString &n, FileDef *fileScope, const TagInfo *tagInfo)
static void resolveTemplateInstanceInType (const Entry *root, const Definition *scope, const MemberDef *md)
static void addPageToContext (PageDef *pd, Entry *root)
static void addRelatedPage (Entry *root)
static void buildGroupListFiltered (const Entry *root, bool additional, bool includeExternal)
static void buildGroupList (const Entry *root)
static void findGroupScope (const Entry *root)
static void organizeSubGroupsFiltered (const Entry *root, bool additional)
static void organizeSubGroups (const Entry *root)
static void buildFileList (const Entry *root)
DString stripTemplateSpecifiers (const DString &s)
static Definition * buildScopeFromQualifiedName (const DString &name_, SrcLangExt lang, const TagInfo *tagInfo)
std::unique_ptr< ArgumentList > getTemplateArgumentsFromName (const DString &name, const ArgumentLists &tArgLists)
static ClassDef::CompoundType convertToCompoundType (EntryType section, TypeSpecifier specifier)
static void addClassToContext (const Entry *root)
static void buildClassList (const Entry *root)
static void buildClassDocList (const Entry *root)
static void addConceptToContext (const Entry *root)
static void findModuleDocumentation (const Entry *root)
static void buildConceptList (const Entry *root)
static void buildConceptDocList (const Entry *root)
static void distributeConceptGroups ()
static void resolveClassNestingRelations ()
void distributeClassGroupRelations ()
template<typename Container>
static void associateVariableWithAnonymousEnumType (const MemberDef *md, const Container *cd, const MemberDef *enumTypeMember, MemberListType mlFilter)
static ClassDefMutable * createTagLessInstance (const Definition *root, const ClassDef *templ, const DString &fieldName, bool hasNamedVariable)
template<typename Container, typename TagContainer>
static void processTagLessClasses (const Definition *root, const Container *def, const TagContainer *tagParent, MemberListType varFilter, MemberListType typeFilter, const DString &prefix, int count)
 Look through the members of class cd and its public members.
template<typename Container, typename TagContainer>
static void processTagLessClassesForList (const Definition *root, const Container *def, const TagContainer *tagParent, MemberListType varFilter, MemberListType typeFilter, const DString &prefix, int count)
template<typename Container>
static void findTagLessClasses (std::set< const Definition * > &candidates, const Container *cd)
static void findTagLessClasses ()
static void buildNamespaceList (const Entry *root)
static NamespaceDef * findUsedNamespace (const LinkedRefMap< NamespaceDef > &unl, const DString &name)
static void findUsingDirectives (const Entry *root)
static void buildListOfUsingDecls (const Entry *root)
static void findUsingDeclarations (const Entry *root, bool filterPythonPackages)
static void applyMemberOverrideOptions (const Entry *root, MemberDefMutable *md)
static void createUsingMemberImportForClass (const Entry *root, ClassDefMutable *cd, const MemberDef *md, const DString &fileName, const DString &memName)
static void findUsingDeclImports (const Entry *root)
static void findIncludedUsingDirectives ()
static MemberDef * addVariableToClass (const Entry *root, ClassDefMutable *cd, MemberType mtype, const DString &type, const DString &name, const DString &args, Protection prot, Relationship related)
static MemberDef * addVariableToFile (const Entry *root, MemberType mtype, const DString &scope, const DString &type, const DString &name, const DString &args)
static int findFunctionPtr (const std::string &type, SrcLangExt lang, int *pLength=nullptr)
static bool isVarWithConstructor (const Entry *root)
static int findEndOfTemplate (const DString &s, size_t startPos)
static void addVariable (const Entry *root, int isFuncPtr=-1)
static void buildTypedefList (const Entry *root)
static void buildSequenceList (const Entry *root)
static void buildDictionaryList (const Entry *root)
static void buildVarList (const Entry *root)
static void addInterfaceOrServiceToServiceOrSingleton (const Entry *root, ClassDefMutable *cd, DString const &rname)
static void buildInterfaceAndServiceList (const Entry *root)
static void addMethodToClass (const Entry *root, ClassDefMutable *cd, const DString &rtype, const DString &rname, const DString &rargs, bool isFriend, Protection protection, bool stat, Specifier virt, TypeSpecifier spec, const DString &relates)
static void addGlobalFunction (const Entry *root, const DString &rname, const DString &sc)
static void buildFunctionList (const Entry *root)
static void findFriends ()
static void transferFunctionDocumentation ()
static void transferFunctionReferences ()
static void transferRelatedFunctionDocumentation ()
void transferStaticInstanceInitializers ()
static TemplateNameMap getTemplateArgumentsInName (const ArgumentList &templateArguments, const std::string &name)
static ClassDef * findClassWithinClassContext (Definition *context, ClassDef *cd, const DString &name)
static void findUsedClassesForClass (const Entry *root, Definition *context, ClassDefMutable *masterCd, ClassDefMutable *instanceCd, bool isArtificial, const ArgumentList *actualArgs=nullptr, const TemplateNameMap &templateNames=TemplateNameMap())
static void findBaseClassesForClass (const Entry *root, Definition *context, ClassDefMutable *masterCd, ClassDefMutable *instanceCd, FindBaseClassRelation_Mode mode, bool isArtificial, const ArgumentList *actualArgs=nullptr, const TemplateNameMap &templateNames=TemplateNameMap())
static void findTemplateInstanceRelation (const Entry *root, Definition *context, ClassDefMutable *templateClass, const DString &templSpec, const TemplateNameMap &templateNames, bool isArtificial)
static bool isRecursiveBaseClass (const DString &scope, const DString &name)
static int findTemplateSpecializationPosition (const DString &name)
static bool isClassSection (const Entry *root)
static void findClassEntries (const Entry *root)
static DString extractClassName (const Entry *root)
static void findInheritedTemplateInstances ()
static void makeTemplateInstanceRelation (const Entry *root, ClassDefMutable *cd)
static void findUsedTemplateInstances ()
static void warnUndocumentedNamespaces ()
static void computeClassRelations ()
static void computeTemplateClassRelations ()
static void computeMemberReferences ()
template<typename Func>
static void applyToAllDefinitions (Func func)
static void addRequirementReferences ()
static void addListReferences ()
static void generateXRefPages ()
static const ClassDef * findClassDefinition (FileDef *fd, NamespaceDef *nd, const DString &scopeName)
static bool isEntryInGroupOfMember (const Entry *root, const MemberDef *md, bool allowNoGroup=false)
static bool findGlobalMember (const Entry *root, const DString &namespaceName, const DString &type, const DString &name, const DString &tempArg, const DString &, const DString &decl, TypeSpecifier)
static bool isSpecialization (const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists)
static bool scopeIsTemplate (const Definition *d)
static DString substituteTemplatesInString (const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const std::string &src)
static void substituteTemplatesInArgList (const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const ArgumentList &src, ArgumentList &dst)
static void addLocalObjCMethod (const Entry *root, const DString &scopeName, const DString &funcType, const DString &funcName, const DString &funcArgs, const DString &exceptions, const DString &funcDecl, TypeSpecifier spec)
static void addMemberFunction (const Entry *root, MemberName *mn, const DString &scopeName, const DString &namespaceName, const DString &className, const DString &funcTyp, const DString &funcName, const DString &funcArgs, const DString &funcTempList, const DString &exceptions, const DString &type, const DString &args, bool isFriend, TypeSpecifier spec, const DString &relates, const DString &funcDecl, bool overloaded, bool isFunc)
static void addMemberSpecialization (const Entry *root, MemberName *mn, ClassDefMutable *cd, const DString &funcType, const DString &funcName, const DString &funcArgs, const DString &funcDecl, const DString &exceptions, TypeSpecifier spec)
static void addOverloaded (const Entry *root, MemberName *mn, const DString &funcType, const DString &funcName, const DString &funcArgs, const DString &funcDecl, const DString &exceptions, TypeSpecifier spec)
static void insertMemberAlias (Definition *outerScope, const MemberDef *md)
static void filterMemberDocumentation (const Entry *root, const DString &relates)
static void findMemberDocumentation (const Entry *root)
static void findObjCMethodDefinitions (const Entry *root)
static void findEnums (const Entry *root)
static void addEnumValuesToEnums (const Entry *root)
static void addEnumDocs (const Entry *root, MemberDefMutable *md)
static bool tryAddEnumDocsToGroupMember (const Entry *root, const DString &name)
static void findEnumDocumentation (const Entry *root)
static void findDEV (const MemberNameLinkedMap &mnsd)
static void findDocumentedEnumValues ()
static void addMembersToIndex ()
static void addToIndices ()
static void vhdlCorrectMemberProperties ()
static void computeMemberRelationsForBaseClass (const ClassDef *cd, const BaseClassDef *bcd, const ArgumentList *actualArgs)
static void computeMemberRelations ()
static void createTemplateInstanceMembers ()
static void mergeCategories ()
static void buildCompleteMemberLists ()
static void generateFileSources ()
static void generateFileDocs ()
static void addSourceReferences ()
static void buildDefineList ()
static void sortMemberLists ()
static bool isSymbolHidden (const Definition *d)
static void computeTooltipTexts ()
static void setAnonymousEnumType ()
static void countMembers ()
static void generateDocsForClassList (const std::vector< ClassDefMutable * > &classList)
static void addClassAndNestedClasses (std::vector< ClassDefMutable * > &list, ClassDefMutable *cd)
static void generateClassDocs ()
static void generateConceptDocs ()
static void inheritDocumentation ()
static void combineUsingRelations ()
static void addMembersToMemberGroup ()
static void distributeMemberGroupDocumentation ()
static void findSectionsInDocumentation ()
static void flushCachedTemplateRelations ()
static void flushUnresolvedRelations ()
static bool haveEqualFileNames (const Entry *root, const MemberDef *md)
static void addDefineDoc (const Entry *root, MemberDefMutable *md)
static void findDefineDocumentation (Entry *root)
static void findDirDocumentation (const Entry *root)
static void buildRequirementsList (Entry *root)
static void buildPageList (Entry *root)
static void findMainPage (Entry *root)
static void findMainPageTagFiles (Entry *root)
static void computePageRelations (Entry *root)
static void checkPageRelations ()
static void resolveUserReferences ()
static void generatePageDocs ()
static void buildExampleList (Entry *root)
void printNavTree (Entry *root, int indent)
void printSectionsTree ()
static void generateExampleDocs ()
static void generateGroupDocs ()
static void generateNamespaceClassDocs (const ClassLinkedRefMap &classList)
static void generateNamespaceConceptDocs (const ConceptLinkedRefMap &conceptList)
static void generateNamespaceDocs ()
static void runHtmlHelpCompiler ()
static void runQHelpGenerator ()
static void computeVerifiedDotPath ()
static void generateConfigFile (const DString &configFile, bool shortList, bool updateOnly=false)
static void compareDoxyfile (Config::CompareMode diffList)
static void readTagFile (const std::shared_ptr< Entry > &root, const DString &tagLine)
static void copyLatexStyleSheet ()
static void copyStyleSheet ()
static void copyLogo (const DString &outputOption, bool toIndex)
static void copyIcon (const DString &outputOption, bool toIndex)
static void copyExtraFiles (StringVector files, const DString &filesOption, const DString &outputOption, bool toIndex)
static void generateDiskNames ()
static std::unique_ptr< OutlineParserInterface > getParserForFile (const DString &fn)
static std::shared_ptr< Entry > parseFile (OutlineParserInterface &parser, FileDef *fd, const DString &fn, ClangTUParser *clangParser, bool newTU)
static void parseFilesMultiThreading (const std::shared_ptr< Entry > &root)
 parse the list of input files
static void parseFilesSingleThreading (const std::shared_ptr< Entry > &root)
 parse the list of input files
static std::string resolveSymlink (const std::string &path)
static StringUnorderedSet g_pathsVisited (1009)
static void readDir (FileInfo *fi, FileNameLinkedMap *fnMap, StringUnorderedSet *exclSet, const StringVector *patList, const StringVector *exclPatList, StringVector *resultList, StringUnorderedSet *resultSet, bool errorIfNotExist, bool recursive, StringUnorderedSet *killSet, StringUnorderedSet *paths)
void readFileOrDirectory (const DString &s, FileNameLinkedMap *fnMap, StringUnorderedSet *exclSet, const StringVector *patList, const StringVector *exclPatList, StringVector *resultList, StringUnorderedSet *resultSet, bool recursive, bool errorIfNotExist, StringUnorderedSet *killSet, StringUnorderedSet *paths)
static void dumpSymbol (TextStream &t, Definition *d)
static void dumpSymbolMap ()
static void devUsage ()
static void version (const bool extended)
static void usage (const DString &name, const DString &versionString)
static const char * getArg (int argc, char **argv, int &optInd)
template<class T>
std::function< std::unique_ptr< T >() > make_parser_factory ()
void initDoxygen ()
void cleanUpDoxygen ()
void readConfiguration (int argc, char **argv)
void checkConfiguration ()
 check and resolve config options
void adjustConfiguration ()
 adjust globals that depend on configuration settings.
static void stopDoxygen (int)
static void writeTagFile ()
static void exitDoxygen () noexcept
static DString createOutputDirectory (const DString &baseDirName, const DString &formatDirName, const char *defaultDirName)
void searchInputFiles ()
static void checkMarkdownMainfile ()
void parseInput ()
void generateOutput ()

Variables

static std::multimap< std::string, const Entry * > g_classEntries
static StringVector g_inputFiles
static OutputList * g_outputList = nullptr
static StringSet g_usingDeclarations
static bool g_successfulRun = false
static bool g_dumpSymbolMap = false
static DString g_commentFileName
static bool g_singleComment =false
static const StringUnorderedSet g_compoundKeywords
class Statistics g_s
static std::unordered_map< std::string, std::vector< ClassDefMutable * > > g_usingClassMap

Macro Definition Documentation

◆ HAS_SIGNALS

#define HAS_SIGNALS

Definition at line 137 of file doxygen.cpp.

Enumeration Type Documentation

◆ FindBaseClassRelation_Mode

Enumerator
TemplateInstances 
DocumentedOnly 
Undocumented 

Definition at line 289 of file doxygen.cpp.

290{
294};
@ Undocumented
Definition doxygen.cpp:293
@ TemplateInstances
Definition doxygen.cpp:291
@ DocumentedOnly
Definition doxygen.cpp:292

Function Documentation

◆ addClassAndNestedClasses()

void addClassAndNestedClasses ( std::vector< ClassDefMutable * > & list,
ClassDefMutable * cd )
static

Definition at line 9471 of file doxygen.cpp.

9472{
9473 list.push_back(cd);
9474 for (const auto &innerCdi : cd->getClasses())
9475 {
9476 ClassDefMutable *innerCd = toClassDefMutable(innerCdi);
9477 if (innerCd)
9478 {
9479 AUTO_TRACE("innerCd={} isLinkable={} isImplicitTemplateInstance={} protectLevelVisible={} embeddedInOuterScope={}",
9480 innerCd->name(),innerCd->isLinkableInProject(),innerCd->isImplicitTemplateInstance(),protectionLevelVisible(innerCd->protection()),
9481 innerCd->isEmbeddedInOuterScope());
9482 }
9483 if (innerCd && innerCd->isLinkableInProject() && !innerCd->isImplicitTemplateInstance() &&
9484 protectionLevelVisible(innerCd->protection()) &&
9485 !innerCd->isEmbeddedInOuterScope()
9486 )
9487 {
9488 list.push_back(innerCd);
9489 addClassAndNestedClasses(list,innerCd);
9490 }
9491 }
9492}
virtual Protection protection() const =0
Return the protection level (Public,Protected,Private) in which this compound was found.
virtual bool isEmbeddedInOuterScope() const =0
virtual bool isImplicitTemplateInstance() const =0
virtual ClassLinkedRefMap getClasses() const =0
returns the classes nested into this class
virtual const DString & name() const =0
virtual bool isLinkableInProject() const =0
ClassDefMutable * toClassDefMutable(Definition *d)
#define AUTO_TRACE(...)
Definition docnode.cpp:53
static void addClassAndNestedClasses(std::vector< ClassDefMutable * > &list, ClassDefMutable *cd)
Definition doxygen.cpp:9471
bool protectionLevelVisible(Protection prot)
Definition util.cpp:4681

References addClassAndNestedClasses(), AUTO_TRACE, ClassDef::getClasses(), ClassDef::isEmbeddedInOuterScope(), ClassDef::isImplicitTemplateInstance(), Definition::isLinkableInProject(), Definition::name(), ClassDef::protection(), protectionLevelVisible(), and toClassDefMutable().

Referenced by addClassAndNestedClasses(), and generateClassDocs().

◆ addClassToContext()

void addClassToContext ( const Entry * root)
static

Definition at line 950 of file doxygen.cpp.

951{
952 AUTO_TRACE("name={}",root->name);
953 FileDef *fd = root->fileDef();
954
955 DString scName;
956 if (root->parent()->section.isScope())
957 {
958 scName=root->parent()->name;
959 }
960 // name without parent's scope
961 DString fullName = root->name;
962
963 // strip off any template parameters (but not those for specializations)
964 if (size_t idx=fullName.find('>'); idx!=DString::npos && root->lang==SrcLangExt::CSharp) // mangle A<S,T>::N as A-2-g::N
965 {
966 fullName = mangleCSharpGenericName(fullName.left(idx+1))+fullName.mid(idx+1);
967 }
968 fullName=stripTemplateSpecifiersFromScope(fullName);
969
970 // name with scope (if not present already)
971 DString qualifiedName = fullName;
972 if (!scName.empty() && !leftScopeMatch(scName,fullName))
973 {
974 qualifiedName.prepend(scName+"::");
975 }
976
977 // see if we already found the class before
978 ClassDefMutable *cd = getClassMutable(qualifiedName);
979
980 AUTO_TRACE_ADD("Found class with name '{}', qualifiedName '{}'", cd ? cd->name() : root->name, qualifiedName);
981
982 if (cd)
983 {
984 fullName=cd->name();
985 AUTO_TRACE_ADD("Existing class '{}'",cd->name());
986 //if (cd->templateArguments()==0)
987 //{
988 // //printf("existing ClassDef tempArgList=%p specScope=%s\n",root->tArgList,qPrint(root->scopeSpec));
989 // cd->setTemplateArguments(tArgList);
990 //}
991
992 cd->setDocumentation(root->doc,root->docFile,root->docLine);
993 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
994 root->commandOverrides.apply_collaborationGraph([&](bool b ) { cd->overrideCollaborationGraph(b); });
995 root->commandOverrides.apply_inheritanceGraph ([&](CLASS_GRAPH_t gt) { cd->overrideInheritanceGraph(gt); });
996
997 if (!root->spec.isForwardDecl() && cd->isForwardDeclared())
998 {
999 cd->setDefFile(root->fileName,root->startLine,root->startColumn);
1000 if (root->bodyLine!=-1)
1001 {
1002 cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1003 cd->setBodyDef(fd);
1004 }
1005 }
1006
1007 if (cd->templateArguments().empty() || (cd->isForwardDeclared() && !root->spec.isForwardDecl()))
1008 {
1009 // this happens if a template class declared with @class is found
1010 // before the actual definition or if a forward declaration has different template
1011 // parameter names.
1012 std::unique_ptr<ArgumentList> tArgList = getTemplateArgumentsFromName(cd->name(),root->tArgLists);
1013 if (tArgList)
1014 {
1015 cd->setTemplateArguments(*tArgList);
1016 }
1017 }
1018 if (cd->requiresClause().empty() && !root->req.empty())
1019 {
1020 cd->setRequiresClause(root->req);
1021 }
1022
1024
1025 cd->setMetaData(root->metaData);
1026 }
1027 else // new class
1028 {
1030
1031 DString className;
1032 DString namespaceName;
1033 extractNamespaceName(fullName,className,namespaceName);
1034
1035 AUTO_TRACE_ADD("New class: fullname '{}' namespace '{}' name='{}' brief='{}' docs='{}'",
1036 fullName, namespaceName, className, Trace::trunc(root->brief), Trace::trunc(root->doc));
1037
1038 DString tagName;
1039 DString refFileName;
1040 const TagInfo *tagInfo = root->tagInfo();
1041 if (tagInfo)
1042 {
1043 tagName = tagInfo->tagName;
1044 refFileName = tagInfo->fileName;
1045 if (fullName.find("::")!=DString::npos)
1046 // symbols imported via tag files may come without the parent scope,
1047 // so we artificially create it here
1048 {
1049 buildScopeFromQualifiedName(fullName,root->lang,tagInfo);
1050 }
1051 }
1052 std::unique_ptr<ArgumentList> tArgList;
1053 size_t i=0;
1054 if ((root->lang==SrcLangExt::CSharp || root->lang==SrcLangExt::Java) &&
1055 (i=fullName.find('<'))!=DString::npos)
1056 {
1057 // a Java/C# generic class looks like a C++ specialization, so we need to split the
1058 // name and template arguments here
1059 tArgList = stringToArgumentList(root->lang,fullName.mid(i));
1060 if (i!=DString::npos && root->lang==SrcLangExt::CSharp) // in C# A, A<T>, and A<T,S> are different classes, so we need some way to disguish them using this name mangling
1061 // A -> A
1062 // A<T> -> A-1-g
1063 // A<T,S> -> A-2-g
1064 {
1065 fullName=mangleCSharpGenericName(fullName);
1066 }
1067 else
1068 {
1069 fullName=fullName.left(i);
1070 }
1071 }
1072 else
1073 {
1074 tArgList = getTemplateArgumentsFromName(fullName,root->tArgLists);
1075 }
1076 // add class to the list
1077 cd = toClassDefMutable(
1078 Doxygen::classLinkedMap->add(fullName,
1079 createClassDef(tagInfo?tagName:root->fileName,root->startLine,root->startColumn,
1080 fullName,sec,tagName,refFileName,true,root->spec.isEnum()) ));
1081 if (cd)
1082 {
1083 AUTO_TRACE_ADD("New class '{}' type={} #tArgLists={} tagInfo={} hidden={} artificial={}",
1084 fullName,cd->compoundTypeString(),root->tArgLists.size(),
1085 fmt::ptr(tagInfo),root->hidden,root->artificial);
1086 cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1087 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1088 cd->setLanguage(root->lang);
1089 cd->setId(root->id);
1090 cd->setHidden(root->hidden);
1091 cd->setArtificial(root->artificial);
1092 cd->setClassSpecifier(root->spec);
1093 if (root->lang==SrcLangExt::CSharp && !root->args.empty())
1094 {
1096 }
1097 cd->addQualifiers(root->qualifiers);
1098 cd->setTypeConstraints(root->typeConstr);
1099 root->commandOverrides.apply_collaborationGraph([&](bool b ) { cd->overrideCollaborationGraph(b); });
1100 root->commandOverrides.apply_inheritanceGraph ([&](CLASS_GRAPH_t gt) { cd->overrideInheritanceGraph(gt); });
1101
1102 if (tArgList)
1103 {
1104 cd->setTemplateArguments(*tArgList);
1105 }
1106 cd->setRequiresClause(root->req);
1107 cd->setProtection(root->protection);
1108 cd->setIsStatic(root->isStatic);
1109
1110 // file definition containing the class cd
1111 cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1112 cd->setBodyDef(fd);
1113
1114 cd->setMetaData(root->metaData);
1115
1116 cd->insertUsedFile(fd);
1117 }
1118 else
1119 {
1120 AUTO_TRACE_ADD("Class {} not added, already exists as alias", fullName);
1121 }
1122 }
1123
1124 if (cd)
1125 {
1127 if (!root->subGrouping) cd->setSubGrouping(false);
1128 if (!root->spec.isForwardDecl())
1129 {
1130 if (cd->hasDocumentation())
1131 {
1132 addIncludeFile(cd,fd,root);
1133 }
1134 if (fd && root->section.isCompound())
1135 {
1136 AUTO_TRACE_ADD("Inserting class {} in file {} (root->fileName='{}')", cd->name(), fd->name(), root->fileName);
1137 cd->setFileDef(fd);
1138 fd->insertClass(cd);
1139 }
1140 }
1141 addClassToGroups(root,cd);
1143 cd->setRefItems(root->sli);
1144 cd->setRequirementReferences(root->rqli);
1145 }
1146}
bool empty() const
Definition arguments.h:100
virtual DString requiresClause() const =0
virtual const ArgumentList & templateArguments() const =0
Returns the template arguments of this class.
virtual DString compoundTypeString() const =0
Returns the type of compound as a string.
virtual bool isForwardDeclared() const =0
Returns true if this class represents a forward declaration of a template class.
CompoundType
The various compound types.
Definition classdef.h:105
virtual void overrideCollaborationGraph(bool e)=0
virtual void setPrimaryConstructorParams(const ArgumentList &list)=0
virtual void setFileDef(FileDef *fd)=0
virtual void setTemplateArguments(const ArgumentList &al)=0
virtual void addQualifiers(const StringVector &qualifiers)=0
virtual void setClassSpecifier(TypeSpecifier spec)=0
virtual void insertUsedFile(const FileDef *)=0
virtual void setProtection(Protection p)=0
virtual void setTypeConstraints(const ArgumentList &al)=0
virtual void overrideInheritanceGraph(CLASS_GRAPH_t e)=0
virtual void setCompoundType(CompoundType t)=0
virtual void setMetaData(const DString &md)=0
virtual void setIsStatic(bool b)=0
virtual void setSubGrouping(bool enabled)=0
virtual void setRequiresClause(const DString &req)=0
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:84
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:318
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:148
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
Definition dstring.h:178
DString & prepend(const char *s)
Definition dstring.h:515
size_t find(char c, size_t pos=0) const
Definition dstring.h:239
DString left(size_t len) const
Definition dstring.h:306
virtual bool hasDocumentation() const =0
virtual void setBodySegment(int defLine, int bls, int ble)=0
virtual void setHidden(bool b)=0
virtual void setDocumentation(const DString &d, const DString &docFile, int docLine, bool stripWhiteSpace=true)=0
virtual void setDefFile(const DString &df, int defLine, size_t defColumn)=0
virtual void addSectionsToDefinition(const std::vector< const SectionInfo * > &anchorList)=0
virtual void setLanguage(SrcLangExt lang)=0
virtual void setArtificial(bool b)=0
virtual void setBriefDescription(const DString &b, const DString &briefFile, int briefLine)=0
virtual void setBodyDef(const FileDef *fd)=0
virtual void setRequirementReferences(const RequirementRefs &rqli)=0
virtual void setId(const DString &name)=0
virtual void setRefItems(const RefItemVector &sli)=0
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:88
bool subGrouping
automatically group class members?
Definition entry.h:187
RequirementRefs rqli
references to requirements
Definition entry.h:227
int docLine
line number at which the documentation was found
Definition entry.h:201
ArgumentList typeConstr
where clause (C#) for type constraints
Definition entry.h:215
int endBodyLine
line number where the definition ends
Definition entry.h:218
const TagInfo * tagInfo() const
Definition entry.h:176
DString fileName
file this entry was extracted from
Definition entry.h:223
ArgumentLists tArgLists
template argument declarations
Definition entry.h:195
DString docFile
file in which the documentation was found
Definition entry.h:202
DString args
member argument string
Definition entry.h:191
SrcLangExt lang
programming language in which this entry was found
Definition entry.h:228
Entry * parent() const
Definition entry.h:133
DString doc
documentation block (partly parsed)
Definition entry.h:200
DString req
C++20 requires clause.
Definition entry.h:235
DString brief
brief description (doc block)
Definition entry.h:203
std::vector< const SectionInfo * > anchors
list of anchors defined in this entry
Definition entry.h:222
CommandOverrides commandOverrides
store info for commands whose default can be overridden
Definition entry.h:189
int startLine
start line of entry in the source
Definition entry.h:224
size_t startColumn
start column of entry in the source
Definition entry.h:225
EntryType section
entry type (see Sections);
Definition entry.h:171
int bodyLine
line number of the body in the source
Definition entry.h:216
DString metaData
Slice metadata.
Definition entry.h:234
std::vector< std::string > qualifiers
qualifiers specified with the qualifier command
Definition entry.h:236
DString name
member name
Definition entry.h:173
RefItemVector sli
special lists (test/todo/bug/deprecated/..) this entry is in
Definition entry.h:226
Protection protection
class protection
Definition entry.h:179
bool artificial
Artificially introduced item.
Definition entry.h:230
bool hidden
does this represent an entity that is hidden from the output
Definition entry.h:229
int briefLine
line number at which the brief desc. was found
Definition entry.h:204
FileDef * fileDef() const
Definition entry.h:168
DString id
libclang id
Definition entry.h:232
bool isStatic
static ?
Definition entry.h:184
TypeSpecifier spec
class/member specifiers
Definition entry.h:181
DString briefFile
file in which the brief desc. was found
Definition entry.h:205
ENTRY_TYPES constexpr bool isCompound() const noexcept
Definition types.h:863
constexpr bool isScope() const noexcept
Definition types.h:864
A model of a file symbol.
Definition filedef.h:97
virtual void insertClass(ClassDef *cd)=0
static ModuleManager & instance()
void addClassToModule(const Entry *root, ClassDef *cd)
This struct is used to capture the tag file information for an Entry.
Definition entry.h:101
DString tagName
Definition entry.h:103
DString fileName
Definition entry.h:104
std::unique_ptr< ClassDef > createClassDef(const DString &fileName, int startLine, size_t startColumn, const DString &name, ClassDef::CompoundType ct, const DString &ref, const DString &fName, bool isSymbol, bool isJavaEnum)
Factory method to create a new ClassDef object.
Definition classdef.cpp:583
ClassDefMutable * getClassMutable(const DString &key)
Definition classdef.h:468
std::unique_ptr< ArgumentList > stringToArgumentList(SrcLangExt lang, const DString &argsString, DString *extraTypeChars=nullptr)
Definition defargs.l:821
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:54
static Definition * buildScopeFromQualifiedName(const DString &name_, SrcLangExt lang, const TagInfo *tagInfo)
Definition doxygen.cpp:724
static void addIncludeFile(Def *def, FileDef *ifd, const Entry *root)
Definition doxygen.cpp:311
static ClassDef::CompoundType convertToCompoundType(EntryType section, TypeSpecifier specifier)
Definition doxygen.cpp:908
std::unique_ptr< ArgumentList > getTemplateArgumentsFromName(const DString &name, const ArgumentLists &tArgLists)
Definition doxygen.cpp:878
void addClassToGroups(const Entry *root, ClassDef *cd)
DString trunc(const DString &s, size_t numChars=15)
Definition trace.h:56
bool leftScopeMatch(const DString &scope, const DString &name)
Definition util.cpp:745
void extractNamespaceName(const DString &scopeName, DString &className, DString &namespaceName, bool allowEmptyClass)
Definition util.cpp:3032
DString stripTemplateSpecifiersFromScope(const DString &fullName, bool parentOnly, DString *pLastScopeStripped, DString scopeName, bool allowArtificial)
Definition util.cpp:3692
DString mangleCSharpGenericName(const DString &name)
Definition util.cpp:5351

References addClassToGroups(), ModuleManager::addClassToModule(), addIncludeFile(), ClassDefMutable::addQualifiers(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, Entry::args, Entry::artificial, AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, buildScopeFromQualifiedName(), Doxygen::classLinkedMap, Entry::commandOverrides, ClassDef::compoundTypeString(), convertToCompoundType(), createClassDef(), Entry::doc, Entry::docFile, Entry::docLine, ArgumentList::empty(), DString::empty(), Entry::endBodyLine, extractNamespaceName(), Entry::fileDef(), Entry::fileName, TagInfo::fileName, DString::find(), getClassMutable(), getTemplateArgumentsFromName(), Definition::hasDocumentation(), Entry::hidden, Entry::id, FileDef::insertClass(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), EntryType::isCompound(), ClassDef::isForwardDeclared(), EntryType::isScope(), Entry::isStatic, Entry::lang, DString::left(), leftScopeMatch(), mangleCSharpGenericName(), Entry::metaData, DString::mid(), Definition::name(), Entry::name, DString::npos, ClassDefMutable::overrideCollaborationGraph(), ClassDefMutable::overrideInheritanceGraph(), Entry::parent(), DString::prepend(), Entry::protection, Entry::qualifiers, Entry::req, ClassDef::requiresClause(), Entry::rqli, Entry::section, DefinitionMutable::setArtificial(), DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), ClassDefMutable::setClassSpecifier(), ClassDefMutable::setCompoundType(), DefinitionMutable::setDefFile(), DefinitionMutable::setDocumentation(), ClassDefMutable::setFileDef(), DefinitionMutable::setHidden(), DefinitionMutable::setId(), ClassDefMutable::setIsStatic(), DefinitionMutable::setLanguage(), ClassDefMutable::setMetaData(), ClassDefMutable::setPrimaryConstructorParams(), ClassDefMutable::setProtection(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), ClassDefMutable::setRequiresClause(), ClassDefMutable::setSubGrouping(), ClassDefMutable::setTemplateArguments(), ClassDefMutable::setTypeConstraints(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, stringToArgumentList(), stripTemplateSpecifiersFromScope(), Entry::subGrouping, Entry::tagInfo(), TagInfo::tagName, Entry::tArgLists, ClassDef::templateArguments(), toClassDefMutable(), Trace::trunc(), and Entry::typeConstr.

Referenced by buildClassDocList(), and buildClassList().

◆ addConceptToContext()

void addConceptToContext ( const Entry * root)
static

Definition at line 1175 of file doxygen.cpp.

1176{
1177 AUTO_TRACE();
1178 FileDef *fd = root->fileDef();
1179
1180 DString scName;
1181 if (root->parent()->section.isScope())
1182 {
1183 scName=root->parent()->name;
1184 }
1185
1186 // name with scope (if not present already)
1187 DString qualifiedName = root->name;
1188 if (!scName.empty() && !leftScopeMatch(qualifiedName,scName))
1189 {
1190 qualifiedName.prepend(scName+"::");
1191 }
1192
1193 // see if we already found the concept before
1194 ConceptDefMutable *cd = getConceptMutable(qualifiedName);
1195
1196 AUTO_TRACE_ADD("Found concept with name '{}' (qualifiedName='{}')", cd ? cd->name() : root->name, qualifiedName);
1197
1198 if (cd)
1199 {
1200 qualifiedName=cd->name();
1201 AUTO_TRACE_ADD("Existing concept '{}'",cd->name());
1202
1203 cd->setDocumentation(root->doc,root->docFile,root->docLine);
1204 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1205
1206 addIncludeFile(cd,fd,root);
1207 }
1208 else // new concept
1209 {
1210 DString className;
1211 DString namespaceName;
1212 extractNamespaceName(qualifiedName,className,namespaceName);
1213
1214 AUTO_TRACE_ADD("New concept: fullname '{}' namespace '{}' name='{}' brief='{}' docs='{}'",
1215 qualifiedName,namespaceName,className,root->brief,root->doc);
1216
1217 DString tagName;
1218 DString refFileName;
1219 const TagInfo *tagInfo = root->tagInfo();
1220 if (tagInfo)
1221 {
1222 tagName = tagInfo->tagName;
1223 refFileName = tagInfo->fileName;
1224 if (qualifiedName.find("::")!=DString::npos)
1225 // symbols imported via tag files may come without the parent scope,
1226 // so we artificially create it here
1227 {
1228 buildScopeFromQualifiedName(qualifiedName,root->lang,tagInfo);
1229 }
1230 }
1231 std::unique_ptr<ArgumentList> tArgList = getTemplateArgumentsFromName(qualifiedName,root->tArgLists);
1232 // add concept to the list
1234 Doxygen::conceptLinkedMap->add(qualifiedName,
1235 createConceptDef(tagInfo?tagName:root->fileName,root->startLine,root->startColumn,
1236 qualifiedName,tagName,refFileName)));
1237 if (cd)
1238 {
1239 AUTO_TRACE_ADD("New concept '{}' #tArgLists={} tagInfo={}",
1240 qualifiedName,root->tArgLists.size(),fmt::ptr(tagInfo));
1241 cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1242 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1243 cd->setLanguage(root->lang);
1244 cd->setId(root->id);
1245 cd->setHidden(root->hidden);
1246 cd->setGroupId(root->mGrpId);
1247 if (tArgList)
1248 {
1249 cd->setTemplateArguments(*tArgList);
1250 }
1251 cd->setInitializer(root->initializer.str());
1252 // file definition containing the class cd
1253 cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1254 cd->setBodyDef(fd);
1256 cd->setRefItems(root->sli);
1257 cd->setRequirementReferences(root->rqli);
1258 addIncludeFile(cd,fd,root);
1259
1260 // also add namespace to the correct structural context
1261 Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,qualifiedName,nullptr,tagInfo);
1263 {
1265 if (dm)
1266 {
1267 dm->addInnerCompound(cd);
1268 }
1269 cd->setOuterScope(d);
1270 }
1271 for (const auto &ce : root->children())
1272 {
1273 //printf("Concept %s has child %s\n",qPrint(root->name),qPrint(ce->section.to_string()));
1274 if (ce->section.isConceptDocPart())
1275 {
1276 cd->addSectionsToDefinition(ce->anchors);
1277 cd->setRefItems(ce->sli);
1278 cd->setRequirementReferences(ce->rqli);
1279 if (!ce->brief.empty())
1280 {
1281 cd->addDocPart(ce->brief,ce->startLine,ce->startColumn);
1282 //printf(" brief=[[\n%s\n]] line=%d,col=%d\n",qPrint(ce->brief),ce->startLine,ce->startColumn);
1283 }
1284 if (!ce->doc.empty())
1285 {
1286 cd->addDocPart(ce->doc,ce->startLine,ce->startColumn);
1287 //printf(" doc=[[\n%s\n]] line=%d,col=%d\n",qPrint(ce->doc),ce->startLine,ce->startColumn);
1288 }
1289 }
1290 else if (ce->section.isConceptCodePart())
1291 {
1292 cd->addCodePart(ce->initializer.str(),ce->startLine,ce->startColumn);
1293 //printf(" code=[[\n%s\n]] line=%d,col=%d\n",qPrint(ce->initializer.str()),ce->startLine,ce->startColumn);
1294 }
1295 }
1296 }
1297 else
1298 {
1299 AUTO_TRACE_ADD("Concept '{}' not added, already exists (as alias)", qualifiedName);
1300 }
1301 }
1302
1303 if (cd)
1304 {
1306 for (const auto &ce : root->children())
1307 {
1308 if (ce->section.isConceptDocPart())
1309 {
1310 cd->addSectionsToDefinition(ce->anchors);
1311 }
1312 }
1313 if (fd)
1314 {
1315 AUTO_TRACE_ADD("Inserting concept '{}' in file '{}' (root->fileName='{}')", cd->name(), fd->name(), root->fileName);
1316 cd->setFileDef(fd);
1317 fd->insertConcept(cd);
1318 }
1319 addConceptToGroups(root,cd);
1321 cd->setRefItems(root->sli);
1322 cd->setRequirementReferences(root->rqli);
1323 }
1324}
virtual void addDocPart(const DString &doc, int lineNr, size_t colNr)=0
virtual void addCodePart(const DString &code, int lineNr, size_t colNr)=0
virtual void setFileDef(FileDef *fd)=0
virtual void setGroupId(int id)=0
virtual void setInitializer(const DString &init)=0
virtual void setTemplateArguments(const ArgumentList &al)=0
The common base class of all entity definitions found in the sources.
Definition definition.h:77
virtual DefType definitionType() const =0
virtual void addInnerCompound(Definition *d)=0
virtual void setOuterScope(Definition *d)=0
static ConceptLinkedMap * conceptLinkedMap
Definition doxygen.h:90
static NamespaceDefMutable * globalScope
Definition doxygen.h:114
TextStream initializer
initial value (for variables)
Definition entry.h:197
const std::vector< std::shared_ptr< Entry > > & children() const
Definition entry.h:138
int mGrpId
member group id
Definition entry.h:219
virtual void insertConcept(ConceptDef *cd)=0
void addConceptToModule(const Entry *root, ConceptDef *cd)
std::string str() const
Return the contents of the buffer as a std::string object.
Definition textstream.h:232
ConceptDefMutable * toConceptDefMutable(Definition *d)
std::unique_ptr< ConceptDef > createConceptDef(const DString &fileName, int startLine, size_t startColumn, const DString &name, const DString &tagRef, const DString &tagFile)
ConceptDefMutable * getConceptMutable(const DString &key)
Definition conceptdef.h:106
DefinitionMutable * toDefinitionMutable(Definition *d)
static Definition * findScopeFromQualifiedName(NamespaceDefMutable *startScope, const DString &n, FileDef *fileScope, const TagInfo *tagInfo)
Definition doxygen.cpp:793
void addConceptToGroups(const Entry *root, ConceptDef *cd)

References ConceptDefMutable::addCodePart(), addConceptToGroups(), ModuleManager::addConceptToModule(), ConceptDefMutable::addDocPart(), addIncludeFile(), DefinitionMutable::addInnerCompound(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, buildScopeFromQualifiedName(), Entry::children(), Doxygen::conceptLinkedMap, createConceptDef(), Definition::definitionType(), Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), Entry::endBodyLine, extractNamespaceName(), Entry::fileDef(), Entry::fileName, TagInfo::fileName, DString::find(), findScopeFromQualifiedName(), getConceptMutable(), getTemplateArgumentsFromName(), Doxygen::globalScope, Entry::hidden, Entry::id, Entry::initializer, FileDef::insertConcept(), ModuleManager::instance(), EntryType::isScope(), Entry::lang, leftScopeMatch(), Entry::mGrpId, Definition::name(), Entry::name, DString::npos, Entry::parent(), DString::prepend(), Entry::rqli, Entry::section, DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), ConceptDefMutable::setFileDef(), ConceptDefMutable::setGroupId(), DefinitionMutable::setHidden(), DefinitionMutable::setId(), ConceptDefMutable::setInitializer(), DefinitionMutable::setLanguage(), DefinitionMutable::setOuterScope(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), ConceptDefMutable::setTemplateArguments(), Entry::sli, Entry::startColumn, Entry::startLine, TextStream::str(), Entry::tagInfo(), TagInfo::tagName, Entry::tArgLists, toConceptDefMutable(), toDefinitionMutable(), and Definition::TypeNamespace.

Referenced by buildConceptDocList(), and buildConceptList().

◆ addDefineDoc()

void addDefineDoc ( const Entry * root,
MemberDefMutable * md )
static

Definition at line 9822 of file doxygen.cpp.

9823{
9824 md->setDocumentation(root->doc,root->docFile,root->docLine);
9825 md->setDocsForDefinition(!root->proto);
9826 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9827 if (md->inbodyDocumentation().empty())
9828 {
9830 }
9831 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
9832 {
9833 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
9834 md->setBodyDef(root->fileDef());
9835 }
9837 md->setMaxInitLines(root->initLines);
9839 md->setRefItems(root->sli);
9840 md->setRequirementReferences(root->rqli);
9841 md->addQualifiers(root->qualifiers);
9842 if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
9843 addMemberToGroups(root,md);
9845}
virtual DString inbodyDocumentation() const =0
virtual int getStartBodyLine() const =0
virtual void setInbodyDocumentation(const DString &d, const DString &docFile, int docLine)=0
bool proto
prototype ?
Definition entry.h:186
int inbodyLine
line number at which the body doc was found
Definition entry.h:207
DString inbodyFile
file in which the body doc was found
Definition entry.h:208
DString inbodyDocs
documentation inside the body of a function
Definition entry.h:206
int initLines
define/variable initializer lines to show
Definition entry.h:183
virtual void setMemberGroupId(int id)=0
virtual void setMaxInitLines(int lines)=0
virtual void setDocsForDefinition(bool b)=0
virtual void addQualifiers(const StringVector &qualifiers)=0
void addMemberToModule(const Entry *root, MemberDef *md)
static void applyMemberOverrideOptions(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:2418
void addMemberToGroups(const Entry *root, MemberDef *md)

References addMemberToGroups(), ModuleManager::addMemberToModule(), MemberDefMutable::addQualifiers(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, applyMemberOverrideOptions(), Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), Entry::endBodyLine, Entry::fileDef(), Definition::getStartBodyLine(), Entry::inbodyDocs, Definition::inbodyDocumentation(), Entry::inbodyFile, Entry::inbodyLine, Entry::initLines, ModuleManager::instance(), Entry::mGrpId, Entry::proto, Entry::qualifiers, Entry::rqli, DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setMaxInitLines(), MemberDefMutable::setMemberGroupId(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), Entry::sli, and Entry::startLine.

Referenced by findDefineDocumentation().

◆ addEnumDocs()

void addEnumDocs ( const Entry * root,
MemberDefMutable * md )
static

Definition at line 8251 of file doxygen.cpp.

8252{
8253 AUTO_TRACE();
8254 // documentation outside a compound overrides the documentation inside it
8255 {
8256 md->setDocumentation(root->doc,root->docFile,root->docLine);
8257 md->setDocsForDefinition(!root->proto);
8258 }
8259
8260 // brief descriptions inside a compound override the documentation
8261 // outside it
8262 {
8263 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
8264 }
8265
8266 if (md->inbodyDocumentation().empty() || !root->parent()->name.empty())
8267 {
8269 }
8270
8271 if (root->mGrpId!=-1 && md->getMemberGroupId()==-1)
8272 {
8273 md->setMemberGroupId(root->mGrpId);
8274 }
8275
8277 md->setRefItems(root->sli);
8278 md->setRequirementReferences(root->rqli);
8279
8280 const GroupDef *gd=md->getGroupDef();
8281 if (gd==nullptr && !root->groups.empty()) // member not grouped but out-of-line documentation is
8282 {
8283 addMemberToGroups(root,md);
8284 }
8286}
std::vector< Grouping > groups
list of groups this entry belongs to
Definition entry.h:221
A model of a group of symbols.
Definition groupdef.h:48
virtual GroupDef * getGroupDef()=0
virtual int getMemberGroupId() const =0

References addMemberToGroups(), ModuleManager::addMemberToModule(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, AUTO_TRACE, Entry::brief, Entry::briefFile, Entry::briefLine, Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), MemberDef::getGroupDef(), MemberDef::getMemberGroupId(), Entry::groups, Entry::inbodyDocs, Definition::inbodyDocumentation(), Entry::inbodyFile, Entry::inbodyLine, ModuleManager::instance(), Entry::mGrpId, Entry::name, Entry::parent(), Entry::proto, Entry::rqli, DefinitionMutable::setBriefDescription(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setMemberGroupId(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), and Entry::sli.

Referenced by findEnumDocumentation(), and tryAddEnumDocsToGroupMember().

◆ addEnumValuesToEnums()

void addEnumValuesToEnums ( const Entry * root)
static

Definition at line 8003 of file doxygen.cpp.

8004{
8005 if (root->section.isEnum())
8006 // non anonymous enumeration
8007 {
8008 AUTO_TRACE("name={}",root->name);
8009 ClassDefMutable *cd = nullptr;
8010 FileDef *fd = nullptr;
8011 NamespaceDefMutable *nd = nullptr;
8012 MemberNameLinkedMap *mnsd = nullptr;
8013 bool isGlobal = false;
8014 bool isRelated = false;
8015 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
8016
8017 DString name;
8018 DString scope;
8019
8020 if (size_t i = root->name.rfind("::"); i!=DString::npos) // scope is specified
8021 {
8022 scope=root->name.left(i); // extract scope
8023 if (root->lang==SrcLangExt::CSharp)
8024 {
8025 scope = mangleCSharpGenericName(scope);
8026 }
8027 name=root->name.right(root->name.length()-i-2); // extract name
8028 if ((cd=getClassMutable(scope))==nullptr)
8029 {
8031 }
8032 }
8033 else // no scope, check the scope in which the docs where found
8034 {
8035 if (root->parent()->section.isScope() && !root->parent()->name.empty()) // found enum docs inside a compound
8036 {
8037 scope=root->parent()->name;
8038 if (root->lang==SrcLangExt::CSharp)
8039 {
8040 scope = mangleCSharpGenericName(scope);
8041 }
8042 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
8043 }
8044 name=root->name;
8045 }
8046
8047 if (!root->relates.empty())
8048 { // related member, prefix user specified scope
8049 isRelated=true;
8050 if (getClassMutable(root->relates)==nullptr && !scope.empty())
8051 scope=mergeScopes(scope,root->relates);
8052 else
8053 scope=root->relates;
8054 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
8055 }
8056
8057 if (cd && !name.empty()) // found a enum inside a compound
8058 {
8059 //printf("Enum in class '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
8060 fd=nullptr;
8062 isGlobal=false;
8063 }
8064 else if (nd && !nd->isAnonymous()) // found enum inside namespace
8065 {
8066 //printf("Enum in namespace '%s'::'%s'\n",qPrint(nd->name()),qPrint(name));
8068 isGlobal=true;
8069 }
8070 else // found a global enum
8071 {
8072 fd=root->fileDef();
8073 //printf("Enum in file '%s': '%s'\n",qPrint(fd->name()),qPrint(name));
8075 isGlobal=true;
8076 }
8077
8078 if (!name.empty())
8079 {
8080 //printf("** name=%s\n",qPrint(name));
8081 MemberName *mn = mnsd->find(name); // for all members with this name
8082 if (mn)
8083 {
8084 struct EnumValueInfo
8085 {
8086 EnumValueInfo(const DString &n,std::unique_ptr<MemberDef> &&md) :
8087 name(n), member(std::move(md)) {}
8088 DString name;
8089 std::unique_ptr<MemberDef> member;
8090 };
8091 std::vector< EnumValueInfo > extraMembers;
8092 // for each enum in this list
8093 for (const auto &imd : *mn)
8094 {
8095 MemberDefMutable *md = toMemberDefMutable(imd.get());
8096 // use raw pointer in this loop, since we modify mn and can then invalidate mdp.
8097 if (md && md->isEnumerate() && !root->children().empty())
8098 {
8099 AUTO_TRACE_ADD("enum {} with {} children",md->name(),root->children().size());
8100 for (const auto &e : root->children())
8101 {
8102 SrcLangExt sle = root->lang;
8103 bool isJavaLike = sle==SrcLangExt::CSharp || sle==SrcLangExt::Java || sle==SrcLangExt::XML;
8104 if ( isJavaLike || root->spec.isStrong())
8105 {
8106 if (sle == SrcLangExt::Cpp && e->section.isDefine()) continue;
8107 // Unlike classic C/C++ enums, for C++11, C# & Java enum
8108 // values are only visible inside the enum scope, so we must create
8109 // them here and only add them to the enum
8110 //printf("md->qualifiedName()=%s e->name=%s tagInfo=%p name=%s\n",
8111 // qPrint(md->qualifiedName()),qPrint(e->name),(void*)e->tagInfo(),qPrint(e->name));
8112 DString qualifiedName = root->name;
8113 if (size_t i = qualifiedName.rfind("::"); i!=DString::npos && sle==SrcLangExt::CSharp)
8114 {
8115 qualifiedName = mangleCSharpGenericName(qualifiedName.left(i))+qualifiedName.mid(i);
8116 }
8117 if (isJavaLike)
8118 {
8119 qualifiedName=substitute(qualifiedName,"::",".");
8120 }
8121 if (md->qualifiedName()==qualifiedName) // enum value scope matches that of the enum
8122 {
8123 DString fileName = e->fileName;
8124 if (fileName.empty() && e->tagInfo())
8125 {
8126 fileName = e->tagInfo()->tagName;
8127 }
8128 AUTO_TRACE_ADD("strong enum value {}",e->name);
8129 auto fmd = createMemberDef(
8130 fileName,e->startLine,e->startColumn,
8131 e->type,e->name,e->args,DString(),
8132 e->protection, Specifier::Normal,e->isStatic,Relationship::Member,
8133 MemberType::EnumValue,ArgumentList(),ArgumentList(),e->metaData);
8134 auto fmmd = toMemberDefMutable(fmd.get());
8135 NamespaceDef *mnd = md->getNamespaceDef();
8136 if (md->getClassDef())
8137 fmmd->setMemberClass(md->getClassDef());
8138 else if (mnd && (mnd->isLinkable() || mnd->isAnonymous()))
8139 fmmd->setNamespace(mnd);
8140 else if (md->getFileDef())
8141 fmmd->setFileDef(md->getFileDef());
8142 fmmd->setOuterScope(md->getOuterScope());
8143 fmmd->setTagInfo(e->tagInfo());
8144 fmmd->setLanguage(e->lang);
8145 fmmd->setBodySegment(e->startLine,e->bodyLine,e->endBodyLine);
8146 fmmd->setBodyDef(e->fileDef());
8147 fmmd->setId(e->id);
8148 fmmd->setDocumentation(e->doc,e->docFile,e->docLine);
8149 fmmd->setBriefDescription(e->brief,e->briefFile,e->briefLine);
8150 fmmd->addSectionsToDefinition(e->anchors);
8151 fmmd->setInitializer(e->initializer.str());
8152 fmmd->setMaxInitLines(e->initLines);
8153 fmmd->setMemberGroupId(e->mGrpId);
8154 fmmd->setExplicitExternal(e->explicitExternal,fileName,e->startLine,e->startColumn);
8155 fmmd->setRefItems(e->sli);
8156 fmmd->setRequirementReferences(e->rqli);
8157 fmmd->setAnchor();
8158 md->insertEnumField(fmd.get());
8159 fmmd->setEnumScope(md,true);
8160 extraMembers.emplace_back(e->name,std::move(fmd));
8161 }
8162 }
8163 else
8164 {
8165 AUTO_TRACE_ADD("enum value {}",e->name);
8166 //printf("e->name=%s isRelated=%d\n",qPrint(e->name),isRelated);
8167 MemberName *fmn=nullptr;
8168 MemberNameLinkedMap *emnsd = isRelated ? Doxygen::functionNameLinkedMap : mnsd;
8169 if (!e->name.empty() && (fmn=emnsd->find(e->name)))
8170 // get list of members with the same name as the field
8171 {
8172 for (const auto &ifmd : *fmn)
8173 {
8174 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
8175 if (fmd && fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope
8176 {
8177 //printf("found enum value with same name %s in scope %s\n",
8178 // qPrint(fmd->name()),qPrint(fmd->getOuterScope()->name()));
8179 if (nd && !nd->isAnonymous())
8180 {
8181 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
8182 {
8183 const NamespaceDef *fnd=fmd->getNamespaceDef();
8184 if (fnd==nd) // enum value is inside a namespace
8185 {
8186 md->insertEnumField(fmd);
8187 fmd->setEnumScope(md);
8188 }
8189 }
8190 }
8191 else if (isGlobal)
8192 {
8193 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
8194 {
8195 const FileDef *ffd=fmd->getFileDef();
8196 if (ffd==fd && ffd==md->getFileDef()) // enum value has file scope
8197 {
8198 md->insertEnumField(fmd);
8199 fmd->setEnumScope(md);
8200 }
8201 }
8202 }
8203 else if (isRelated && cd) // reparent enum value to
8204 // match the enum's scope
8205 {
8206 md->insertEnumField(fmd); // add field def to list
8207 fmd->setEnumScope(md); // cross ref with enum name
8208 fmd->setEnumClassScope(cd); // cross ref with enum name
8209 fmd->setOuterScope(cd);
8210 fmd->makeRelated();
8211 cd->insertMember(fmd);
8212 }
8213 else
8214 {
8215 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
8216 {
8217 const ClassDef *fcd=fmd->getClassDef();
8218 if (fcd==cd) // enum value is inside a class
8219 {
8220 //printf("Inserting enum field %s in enum scope %s\n",
8221 // qPrint(fmd->name()),qPrint(md->name()));
8222 md->insertEnumField(fmd); // add field def to list
8223 fmd->setEnumScope(md); // cross ref with enum name
8224 }
8225 }
8226 }
8227 }
8228 }
8229 }
8230 }
8231 }
8232 }
8233 }
8234 // move the newly added members into mn
8235 for (auto &e : extraMembers)
8236 {
8237 MemberName *emn=mnsd->add(e.name);
8238 emn->push_back(std::move(e.member));
8239 }
8240 }
8241 }
8242 }
8243 else
8244 {
8245 for (const auto &e : root->children()) addEnumValuesToEnums(e.get());
8246 }
8247}
This class represents an function or template argument list.
Definition arguments.h:66
A abstract class representing of a compound symbol.
Definition classdef.h:100
virtual void insertMember(MemberDef *)=0
size_t rfind(char c, size_t pos=npos) const
Definition dstring.h:244
DString right(size_t len) const
Definition dstring.h:311
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:151
virtual bool isLinkable() const =0
virtual bool isAnonymous() const =0
virtual DString qualifiedName() const =0
virtual Definition * getOuterScope() const =0
static MemberNameLinkedMap * functionNameLinkedMap
Definition doxygen.h:105
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:104
DString relates
related class (doc block)
Definition entry.h:209
T * add(const char *k, Args &&... args)
Definition linkedmap.h:90
const T * find(const std::string &key) const
Definition linkedmap.h:47
virtual const ClassDef * getClassDef() const =0
virtual const FileDef * getFileDef() const =0
virtual bool isStrongEnumValue() const =0
virtual const NamespaceDef * getNamespaceDef() const =0
virtual bool isEnumerate() const =0
virtual bool isEnumValue() const =0
virtual void setEnumScope(MemberDef *md, bool livesInsideEnum=false)=0
virtual void setEnumClassScope(ClassDef *cd)=0
virtual void insertEnumField(MemberDef *md)=0
virtual void makeRelated()=0
void push_back(Ptr &&p)
Definition membername.h:52
Ordered dictionary of MemberName objects.
Definition membername.h:61
An abstract interface of a namespace symbol.
static void addEnumValuesToEnums(const Entry *root)
Definition doxygen.cpp:8003
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
Definition dstring.cpp:485
std::unique_ptr< MemberDef > createMemberDef(const DString &defFileName, int defLine, size_t defColumn, const DString &type, const DString &name, const DString &args, const DString &excp, Protection prot, Specifier virt, bool stat, Relationship related, MemberType t, const ArgumentList &tal, const ArgumentList &al, const DString &metaData)
Factory method to create a new instance of a MemberDef.
MemberDefMutable * toMemberDefMutable(Definition *d)
const char * name(int level)
Definition latexgen.h:368
NamespaceDefMutable * toNamespaceDefMutable(Definition *d)
NamespaceDefMutable * getResolvedNamespaceMutable(const DString &key)
SrcLangExt
Definition types.h:207
DString mergeScopes(const DString &leftScope, const DString &rightScope)
Definition util.cpp:3759

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addEnumValuesToEnums(), AUTO_TRACE, AUTO_TRACE_ADD, buildScopeFromQualifiedName(), Entry::children(), createMemberDef(), DString::empty(), Entry::fileDef(), LinkedMap< T, Hash, KeyEqual, Map >::find(), Doxygen::functionNameLinkedMap, MemberDef::getClassDef(), getClassMutable(), MemberDef::getFileDef(), MemberDef::getNamespaceDef(), Definition::getOuterScope(), getResolvedNamespaceMutable(), MemberDefMutable::insertEnumField(), ClassDefMutable::insertMember(), Definition::isAnonymous(), MemberDef::isEnumerate(), MemberDef::isEnumValue(), Definition::isLinkable(), EntryType::isScope(), MemberDef::isStrongEnumValue(), Entry::lang, DString::left(), DString::length(), MemberDefMutable::makeRelated(), mangleCSharpGenericName(), Doxygen::memberNameLinkedMap, mergeScopes(), DString::mid(), Definition::name(), Entry::name, DString::npos, Entry::parent(), MemberName::push_back(), Definition::qualifiedName(), Entry::relates, DString::rfind(), DString::right(), Entry::section, MemberDefMutable::setEnumClassScope(), MemberDefMutable::setEnumScope(), DefinitionMutable::setOuterScope(), Entry::spec, substitute(), Entry::tagInfo(), toMemberDefMutable(), and toNamespaceDefMutable().

Referenced by addEnumValuesToEnums(), and parseInput().

◆ addGlobalFunction()

void addGlobalFunction ( const Entry * root,
const DString & rname,
const DString & sc )
static

Definition at line 4084 of file doxygen.cpp.

4085{
4086 DString scope = sc;
4087
4088 // new global function
4090 auto md = createMemberDef(
4091 root->fileName,root->startLine,root->startColumn,
4092 root->type,name,root->args,root->exception,
4093 root->protection,root->virt,root->isStatic,Relationship::Member,
4094 MemberType::Function,
4095 !root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
4096 root->argList,root->metaData);
4097 auto mmd = toMemberDefMutable(md.get());
4098 mmd->setTagInfo(root->tagInfo());
4099 mmd->setLanguage(root->lang);
4100 mmd->setId(root->id);
4101 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
4102 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
4103 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
4104 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
4105 mmd->setDocsForDefinition(!root->proto);
4106 mmd->setTypeConstraints(root->typeConstr);
4107 //md->setBody(root->body);
4108 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
4109 FileDef *fd=root->fileDef();
4110 mmd->setBodyDef(fd);
4111 mmd->addSectionsToDefinition(root->anchors);
4112 mmd->setMemberSpecifiers(root->spec);
4113 mmd->setVhdlSpecifiers(root->vhdlSpec);
4114 mmd->setMemberGroupId(root->mGrpId);
4115 mmd->setRequiresClause(root->req);
4116 mmd->setExplicitExternal(root->explicitExternal,root->fileName,root->startLine,root->startColumn);
4117 addIncludeFile(mmd,fd,root);
4118
4119 NamespaceDefMutable *nd = nullptr;
4120 // see if the function is inside a namespace that was not part of
4121 // the name already (in that case nd should be non-zero already)
4122 if (root->parent()->section.isNamespace())
4123 {
4124 //DString nscope=removeAnonymousScopes(root->parent()->name);
4125 DString nscope=root->parent()->name;
4126 if (!nscope.empty())
4127 {
4128 nd = getResolvedNamespaceMutable(nscope);
4129 }
4130 }
4131 else if (root->parent()->section.isGroupDoc() && !scope.empty())
4132 {
4134 }
4135
4136 if (!scope.empty())
4137 {
4139 if (sep!="::")
4140 {
4141 scope = substitute(scope,"::",sep);
4142 }
4143 scope+=sep;
4144 }
4145
4146 if (Config_getBool(HIDE_SCOPE_NAMES) || root->lang==SrcLangExt::Python) scope = "";
4147 DString def;
4148 //DString optArgs = root->argList.empty() ? DString() : root->args;
4149 if (!root->type.empty())
4150 {
4151 def=root->type+" "+scope+name; //+optArgs;
4152 }
4153 else
4154 {
4155 def=scope+name; //+optArgs;
4156 }
4157 AUTO_TRACE("new non-member function type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
4158 root->type,scope,rname,root->args,root->proto,def);
4159 mmd->setDefinition(def);
4161 mmd->addQualifiers(root->qualifiers);
4162
4163 mmd->setRefItems(root->sli);
4164 mmd->setRequirementReferences(root->rqli);
4165 if (nd && !nd->name().empty() && nd->name().at(0)!='@')
4166 {
4167 // add member to namespace
4168 mmd->setNamespace(nd);
4169 nd->insertMember(md.get());
4170 }
4171 if (fd)
4172 {
4173 // add member to the file (we do this even if we have already
4174 // inserted it into the namespace)
4175 mmd->setFileDef(fd);
4176 fd->insertMember(md.get());
4177 }
4178
4179 addMemberToGroups(root,md.get());
4181 if (root->relatesType == RelatesType::Simple) // if this is a relatesalso command,
4182 // allow find Member to pick it up
4183 {
4184 root->markAsProcessed(); // Otherwise we have finished with this entry.
4185 }
4186
4187 // add member to the list of file members
4189 mn->push_back(std::move(md));
4190}
char & at(size_t i)
Returns a reference to the character at index i.
Definition dstring.h:686
VhdlSpecifier vhdlSpec
VHDL specifiers.
Definition entry.h:182
void markAsProcessed() const
Definition entry.h:166
bool explicitExternal
explicitly defined as external?
Definition entry.h:185
RelatesType relatesType
how relates is handled
Definition entry.h:210
ArgumentList argList
member arguments as a list
Definition entry.h:194
DString type
member type
Definition entry.h:172
DString exception
throw specification
Definition entry.h:214
Specifier virt
virtualness of the entry
Definition entry.h:190
virtual void insertMember(MemberDef *md)=0
virtual void insertMember(MemberDef *md)=0
#define Config_getBool(name)
Definition config.h:33
DString removeRedundantWhiteSpace(const DString &s)
Definition util.cpp:427
DString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Definition util.cpp:4639

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addIncludeFile(), addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, Entry::args, DString::at(), AUTO_TRACE, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), Entry::endBodyLine, Entry::exception, Entry::explicitExternal, Entry::fileDef(), Entry::fileName, Doxygen::functionNameLinkedMap, getLanguageSpecificSeparator(), getResolvedNamespaceMutable(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, FileDef::insertMember(), NamespaceDefMutable::insertMember(), ModuleManager::instance(), Entry::isStatic, Entry::lang, Entry::markAsProcessed(), Entry::metaData, Entry::mGrpId, Definition::name(), Entry::name, Entry::parent(), Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, Entry::relatesType, removeRedundantWhiteSpace(), Entry::req, Entry::rqli, Entry::section, DefinitionMutable::setBodyDef(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, substitute(), Entry::tagInfo(), Entry::tArgLists, toMemberDefMutable(), Entry::type, Entry::typeConstr, Entry::vhdlSpec, and Entry::virt.

Referenced by buildFunctionList().

◆ addIncludeFile()

template<class Def>
void addIncludeFile ( Def * def,
FileDef * ifd,
const Entry * root )
static

Definition at line 311 of file doxygen.cpp.

312{
313 AUTO_TRACE();
314 if (
315 (!root->doc.stripWhiteSpace().empty() ||
316 !root->brief.stripWhiteSpace().empty() ||
317 Config_getBool(EXTRACT_ALL)
318 ) && root->protection!=Protection::Private
319 )
320 {
321 AUTO_TRACE_ADD("includefile={}",root->includeFile);
322 //printf(">>>>>> includeFile=%s\n",qPrint(root->includeFile));
323
324 bool local=Config_getBool(FORCE_LOCAL_INCLUDES);
325 DString includeFile = root->includeFile;
326 if (!includeFile.empty() && includeFile.at(0)=='"')
327 {
328 local = true;
329 includeFile=includeFile.mid(1,includeFile.length()-2);
330 }
331 else if (!includeFile.empty() && includeFile.at(0)=='<')
332 {
333 local = false;
334 includeFile=includeFile.mid(1,includeFile.length()-2);
335 }
336
337 bool ambig = false;
338 FileDef *fd=nullptr;
339 // see if we need to include a verbatim copy of the header file
340 //printf("root->includeFile=%s\n",qPrint(root->includeFile));
341 if (!includeFile.empty() &&
342 (fd=Doxygen::inputNameLinkedMap->findFileDef(includeFile,ambig))==nullptr
343 )
344 { // explicit request
345 DString text;
346 text.sprintf("the name '%s' supplied as "
347 "the argument of the \\class, \\struct, \\union, or \\headerfile command ",
348 qPrint(includeFile)
349 );
350 if (ambig) // name is ambiguous
351 {
352 text+="matches the following input files:\n";
354 text+="\n";
355 text+="Please use a more specific name by "
356 "including a (larger) part of the path!";
357 }
358 else // name is not an input file
359 {
360 text+="is not an input file";
361 }
362 warn(root->fileName,root->startLine, "{}", text);
363 }
364 else if (includeFile.empty() && ifd &&
365 // see if the file extension makes sense
366 EntryType::guessSection(ifd->name()).isHeader())
367 { // implicit assumption
368 fd=ifd;
369 }
370
371 // if a file is found, we mark it as a source file.
372 if (fd)
373 {
374 DString iName = !root->includeName.empty() ?
375 root->includeName : includeFile;
376 if (!iName.empty()) // user specified include file
377 {
378 if (iName.at(0)=='<') local=false; // explicit override
379 else if (iName.at(0)=='"') local=true;
380 if (iName.at(0)=='"' || iName.at(0)=='<')
381 {
382 iName=iName.mid(1,iName.length()-2); // strip quotes or brackets
383 }
384 if (iName.empty())
385 {
386 iName=fd->name();
387 }
388 }
389 else if (!Config_getList(STRIP_FROM_INC_PATH).empty())
390 {
392 }
393 else // use name of the file containing the class definition
394 {
395 iName=fd->name();
396 }
397 AUTO_TRACE_ADD("iName={}",iName);
398 if (fd->generateSourceFile()) // generate code for header
399 {
400 def->setIncludeFile(fd,iName,local,!root->includeName.empty());
401 }
402 else // put #include in the class documentation without link
403 {
404 def->setIncludeFile(nullptr,iName,local,true);
405 }
406 }
407 }
408}
DString & sprintf(const char *format,...)
Definition dstring.cpp:34
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition dstring.h:337
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:97
DString includeName
include name (3 arg of \class)
Definition entry.h:199
DString includeFile
include file (2 arg of \class, must be unique)
Definition entry.h:198
static EntryType guessSection(const DString &name)
Definition types.cpp:22
virtual bool generateSourceFile() const =0
virtual DString absFilePath() const =0
DString showFileDefMatches(const DString &n) const
Returns a list of file definitions in fnMap that match the file name n.
Definition filename.cpp:131
FileDef * findFileDef(const DString &n, bool &ambig) const
Returns the file definition in fnMap that matches the file name n.
Definition filename.cpp:38
#define Config_getList(name)
Definition config.h:38
const char * qPrint(const char *s)
Definition dstring.h:783
#define warn(file, line, fmt,...)
Definition message.h:97
DString stripFromIncludePath(const DString &path)
Definition util.cpp:227

References FileDef::absFilePath(), DString::at(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::brief, Config_getBool, Config_getList, Entry::doc, DString::empty(), Entry::fileName, FileNameLinkedMap::findFileDef(), FileDef::generateSourceFile(), EntryType::guessSection(), Entry::includeFile, Entry::includeName, Doxygen::inputNameLinkedMap, DString::length(), DString::mid(), Definition::name(), Entry::protection, qPrint(), FileNameLinkedMap::showFileDefMatches(), DString::sprintf(), Entry::startLine, stripFromIncludePath(), DString::stripWhiteSpace(), and warn.

Referenced by addClassToContext(), addConceptToContext(), addGlobalFunction(), addInterfaceOrServiceToServiceOrSingleton(), addLocalObjCMethod(), addMemberDocs(), addMemberSpecialization(), addMethodToClass(), addOverloaded(), addVariableToClass(), addVariableToFile(), buildFileList(), buildGroupListFiltered(), buildNamespaceList(), findEnums(), and findMember().

◆ addInterfaceOrServiceToServiceOrSingleton()

void addInterfaceOrServiceToServiceOrSingleton ( const Entry * root,
ClassDefMutable * cd,
DString const & rname )
static

Definition at line 3831 of file doxygen.cpp.

3835{
3836 FileDef *fd = root->fileDef();
3837 enum MemberType type = root->section.isExportedInterface() ? MemberType::Interface : MemberType::Service;
3838 DString fileName = root->fileName;
3839 if (fileName.empty() && root->tagInfo())
3840 {
3841 fileName = root->tagInfo()->tagName;
3842 }
3843 auto md = createMemberDef(
3844 fileName, root->startLine, root->startColumn, root->type, rname,
3845 "", "", root->protection, root->virt, root->isStatic, Relationship::Member,
3846 type, ArgumentList(), root->argList, root->metaData);
3847 auto mmd = toMemberDefMutable(md.get());
3848 mmd->setTagInfo(root->tagInfo());
3849 mmd->setMemberClass(cd);
3850 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3851 mmd->setDocsForDefinition(false);
3852 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3853 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3854 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3855 mmd->setMemberSpecifiers(root->spec);
3856 mmd->setVhdlSpecifiers(root->vhdlSpec);
3857 mmd->setMemberGroupId(root->mGrpId);
3858 mmd->setTypeConstraints(root->typeConstr);
3859 mmd->setLanguage(root->lang);
3860 mmd->setBodyDef(fd);
3861 mmd->setFileDef(fd);
3862 mmd->addSectionsToDefinition(root->anchors);
3863 DString const def = root->type + " " + rname;
3864 mmd->setDefinition(def);
3866 mmd->addQualifiers(root->qualifiers);
3867 addIncludeFile(mmd,fd,root);
3868
3869 AUTO_TRACE("Interface member: fileName='{}' type='{}' name='{}' mtype='{}' prot={} virt={} state={} proto={} def='{}'",
3870 fileName,root->type,rname,type,root->protection,root->virt,root->isStatic,root->proto,def);
3871
3872 // add member to the class cd
3873 cd->insertMember(md.get());
3874 // also add the member as a "base" (to get nicer diagrams)
3875 // "optional" interface/service get Protected which turns into dashed line
3876 BaseInfo base(rname,
3877 root->spec.isOptional() ? Protection::Protected : Protection::Public, Specifier::Normal);
3878 TemplateNameMap templateNames;
3879 findClassRelation(root,cd,cd,&base,templateNames,DocumentedOnly,true) ||
3880 findClassRelation(root,cd,cd,&base,templateNames,Undocumented,true);
3881 // add file to list of used files
3882 cd->insertUsedFile(fd);
3883
3884 addMemberToGroups(root,md.get());
3886 root->markAsProcessed();
3887 mmd->setRefItems(root->sli);
3888 mmd->setRequirementReferences(root->rqli);
3889
3890 // add member to the global list of all members
3892 mn->push_back(std::move(md));
3893}
std::map< std::string, int > TemplateNameMap
Definition classdef.h:89
static bool findClassRelation(const Entry *root, Definition *context, ClassDefMutable *cd, const BaseInfo *bi, const TemplateNameMap &templateNames, FindBaseClassRelation_Mode mode, bool isArtificial)
Definition doxygen.cpp:5154
This class stores information about an inheritance relation.
Definition entry.h:88
MemberType
Definition types.h:569

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addIncludeFile(), addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, AUTO_TRACE, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, DocumentedOnly, DString::empty(), Entry::endBodyLine, Entry::fileDef(), Entry::fileName, findClassRelation(), Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), Entry::isStatic, Entry::lang, Entry::markAsProcessed(), Doxygen::memberNameLinkedMap, Entry::metaData, Entry::mGrpId, Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, Entry::rqli, Entry::section, Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, Entry::tagInfo(), TagInfo::tagName, toMemberDefMutable(), Entry::type, Entry::typeConstr, Undocumented, Entry::vhdlSpec, and Entry::virt.

Referenced by buildInterfaceAndServiceList().

◆ addListReferences()

void addListReferences ( )
static

Definition at line 5817 of file doxygen.cpp.

5818{
5819 AUTO_TRACE();
5820 applyToAllDefinitions([](auto* obj) { obj->addListReferences(); });
5821}
static void applyToAllDefinitions(Func func)
Definition doxygen.cpp:5752

References applyToAllDefinitions(), and AUTO_TRACE.

Referenced by parseInput().

◆ addLocalObjCMethod()

void addLocalObjCMethod ( const Entry * root,
const DString & scopeName,
const DString & funcType,
const DString & funcName,
const DString & funcArgs,
const DString & exceptions,
const DString & funcDecl,
TypeSpecifier spec )
static

Definition at line 6397 of file doxygen.cpp.

6402{
6403 AUTO_TRACE();
6404 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
6405 ClassDefMutable *cd=nullptr;
6406 if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClassMutable(scopeName)))
6407 {
6408 AUTO_TRACE_ADD("Local objective C method '{}' scopeName='{}'",root->name,scopeName);
6409 auto md = createMemberDef(
6410 root->fileName,root->startLine,root->startColumn,
6411 funcType,funcName,funcArgs,exceptions,
6412 root->protection,root->virt,root->isStatic,Relationship::Member,
6413 MemberType::Function,ArgumentList(),root->argList,root->metaData);
6414 auto mmd = toMemberDefMutable(md.get());
6415 mmd->setTagInfo(root->tagInfo());
6416 mmd->setLanguage(root->lang);
6417 mmd->setId(root->id);
6418 mmd->makeImplementationDetail();
6419 mmd->setMemberClass(cd);
6420 mmd->setDefinition(funcDecl);
6422 mmd->addQualifiers(root->qualifiers);
6423 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6424 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6425 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6426 mmd->setDocsForDefinition(!root->proto);
6427 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6428 mmd->addSectionsToDefinition(root->anchors);
6429 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6430 FileDef *fd=root->fileDef();
6431 mmd->setBodyDef(fd);
6432 mmd->setMemberSpecifiers(spec);
6433 mmd->setVhdlSpecifiers(root->vhdlSpec);
6434 mmd->setMemberGroupId(root->mGrpId);
6435 cd->insertMember(md.get());
6436 cd->insertUsedFile(fd);
6437 mmd->setRefItems(root->sli);
6438 mmd->setRequirementReferences(root->rqli);
6439 addIncludeFile(mmd,fd,root);
6440
6442 mn->push_back(std::move(md));
6443 }
6444 else
6445 {
6446 // local objective C method found for class without interface
6447 }
6448}

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addIncludeFile(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Entry::fileDef(), Entry::fileName, getClassMutable(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), Entry::isStatic, Entry::lang, Doxygen::memberNameLinkedMap, Entry::metaData, Entry::mGrpId, Entry::name, Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, Entry::rqli, DefinitionMutable::setBodyDef(), Entry::sli, Entry::startColumn, Entry::startLine, Entry::tagInfo(), toMemberDefMutable(), Entry::vhdlSpec, and Entry::virt.

Referenced by addMemberFunction(), and findMember().

◆ addMemberDocs()

void addMemberDocs ( const Entry * root,
MemberDefMutable * md,
const DString & funcDecl,
const ArgumentList * al,
bool over_load,
TypeSpecifier spec )
static

Definition at line 5840 of file doxygen.cpp.

5846{
5847 if (md==nullptr) return;
5848 AUTO_TRACE("scope='{}' name='{}' args='{}' funcDecl='{}' mSpec={}",
5849 root->parent()->name,md->name(),md->argsString(),funcDecl,spec);
5850 if (!root->section.isDoc()) // @fn or @var does not need to specify the complete definition, so don't overwrite it
5851 {
5852 DString fDecl=funcDecl;
5853 // strip extern specifier
5854 fDecl.stripPrefix("extern ");
5855 md->setDefinition(fDecl);
5856 }
5858 md->addQualifiers(root->qualifiers);
5860 const NamespaceDef *nd=md->getNamespaceDef();
5861 DString fullName;
5862 if (cd)
5863 fullName = cd->name();
5864 else if (nd)
5865 fullName = nd->name();
5866
5867 if (!fullName.empty()) fullName+="::";
5868 fullName+=md->name();
5869 FileDef *rfd=root->fileDef();
5870
5871 // TODO determine scope based on root not md
5872 Definition *rscope = md->getOuterScope();
5873
5874 const ArgumentList &mdAl = md->argumentList();
5875 if (al)
5876 {
5877 ArgumentList mergedAl = *al;
5878 //printf("merging arguments (1) docs=%d\n",root->doc.empty());
5879 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedAl,!root->doc.empty());
5880 }
5881 else
5882 {
5883 if (
5884 matchArguments2( md->getOuterScope(), md->getFileDef(),md->typeString(),const_cast<ArgumentList*>(&mdAl),
5885 rscope,rfd,root->type,&root->argList,
5886 true, root->lang
5887 )
5888 )
5889 {
5890 //printf("merging arguments (2)\n");
5891 ArgumentList mergedArgList = root->argList;
5892 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.empty());
5893 }
5894 }
5895 if (over_load) // the \overload keyword was used
5896 {
5898 if (!root->doc.empty())
5899 {
5900 doc+="<p>";
5901 doc+=root->doc;
5902 }
5903 md->setDocumentation(doc,root->docFile,root->docLine);
5905 md->setDocsForDefinition(!root->proto);
5906 }
5907 else
5908 {
5909 //printf("overwrite!\n");
5910 md->setDocumentation(root->doc,root->docFile,root->docLine);
5911 md->setDocsForDefinition(!root->proto);
5912
5913 //printf("overwrite!\n");
5914 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
5915
5916 if (
5917 (md->inbodyDocumentation().empty() ||
5918 !root->parent()->name.empty()
5919 ) && !root->inbodyDocs.empty()
5920 )
5921 {
5923 }
5924 }
5925
5926 //printf("initializer: '%s'(isEmpty=%d) '%s'(isEmpty=%d)\n",
5927 // qPrint(md->initializer()),md->initializer().empty(),
5928 // qPrint(root->initializer),root->initializer.empty()
5929 // );
5930 std::string rootInit = root->initializer.str();
5931 if (md->initializer().empty() && !rootInit.empty())
5932 {
5933 //printf("setInitializer\n");
5934 md->setInitializer(rootInit);
5935 }
5936 if (md->requiresClause().empty() && !root->req.empty())
5937 {
5938 md->setRequiresClause(root->req);
5939 }
5940
5941 md->setMaxInitLines(root->initLines);
5942
5943 if (rfd)
5944 {
5945 if ((md->getStartBodyLine()==-1 && root->bodyLine!=-1)
5946 )
5947 {
5948 //printf("Setting new body segment [%d,%d]\n",root->bodyLine,root->endBodyLine);
5949 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
5950 md->setBodyDef(rfd);
5951 }
5952
5953 md->setRefItems(root->sli);
5954 md->setRequirementReferences(root->rqli);
5955 }
5956
5958 md->addQualifiers(root->qualifiers);
5959
5960 md->mergeMemberSpecifiers(spec);
5962 addMemberToGroups(root,md);
5963 addIncludeFile(md,rfd,root);
5965 if (cd) cd->insertUsedFile(rfd);
5966 //printf("root->mGrpId=%d\n",root->mGrpId);
5967 if (root->mGrpId!=-1)
5968 {
5969 if (md->getMemberGroupId()!=-1)
5970 {
5971 if (md->getMemberGroupId()!=root->mGrpId)
5972 {
5973 warn(root->fileName,root->startLine,
5974 "member {} belongs to two different groups. The second one found here will be ignored.",
5975 md->name()
5976 );
5977 }
5978 }
5979 else // set group id
5980 {
5981 //printf("setMemberGroupId=%d md=%s\n",root->mGrpId,qPrint(md->name()));
5982 md->setMemberGroupId(root->mGrpId);
5983 }
5984 }
5985 md->addQualifiers(root->qualifiers);
5986}
bool stripPrefix(const DString &prefix)
Definition dstring.h:290
constexpr bool isDoc() const noexcept
Definition types.h:867
virtual DString requiresClause() const =0
virtual DString argsString() const =0
virtual const DString & initializer() const =0
virtual const ArgumentList & argumentList() const =0
virtual DString typeString() const =0
virtual void setRequiresClause(const DString &req)=0
virtual void setDefinition(const DString &d)=0
virtual ClassDefMutable * getClassDefMutable()=0
virtual void setInitializer(const DString &i)=0
virtual void mergeMemberSpecifiers(TypeSpecifier s)=0
virtual DString trOverloadText()=0
Translator * theTranslator
Definition language.cpp:76
bool matchArguments2(const Definition *srcScope, const FileDef *srcFileScope, const DString &srcReturnType, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const DString &dstReturnType, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
Definition util.cpp:1594
void mergeArguments(ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
Definition util.cpp:1694

References addIncludeFile(), addMemberToGroups(), ModuleManager::addMemberToModule(), MemberDefMutable::addQualifiers(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, MemberDef::argsString(), MemberDef::argumentList(), AUTO_TRACE, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), Entry::endBodyLine, Entry::fileDef(), Entry::fileName, MemberDefMutable::getClassDefMutable(), MemberDef::getFileDef(), MemberDef::getMemberGroupId(), MemberDef::getNamespaceDef(), Definition::getOuterScope(), Definition::getStartBodyLine(), Entry::inbodyDocs, Definition::inbodyDocumentation(), Entry::inbodyFile, Entry::inbodyLine, Entry::initializer, MemberDef::initializer(), Entry::initLines, ClassDefMutable::insertUsedFile(), ModuleManager::instance(), EntryType::isDoc(), Entry::lang, matchArguments2(), mergeArguments(), MemberDefMutable::mergeMemberSpecifiers(), Entry::mGrpId, Definition::name(), Entry::name, Entry::parent(), Entry::proto, Entry::qualifiers, Entry::req, MemberDef::requiresClause(), Entry::rqli, Entry::section, DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), MemberDefMutable::setDefinition(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setInitializer(), MemberDefMutable::setMaxInitLines(), MemberDefMutable::setMemberGroupId(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), MemberDefMutable::setRequiresClause(), Entry::sli, Entry::startLine, TextStream::str(), DString::stripPrefix(), theTranslator, Translator::trOverloadText(), Entry::type, MemberDef::typeString(), and warn.

Referenced by addMemberFunction(), addVariableToClass(), addVariableToFile(), findGlobalMember(), and findMember().

◆ addMemberFunction()

void addMemberFunction ( const Entry * root,
MemberName * mn,
const DString & scopeName,
const DString & namespaceName,
const DString & className,
const DString & funcTyp,
const DString & funcName,
const DString & funcArgs,
const DString & funcTempList,
const DString & exceptions,
const DString & type,
const DString & args,
bool isFriend,
TypeSpecifier spec,
const DString & relates,
const DString & funcDecl,
bool overloaded,
bool isFunc )
static

Definition at line 6452 of file doxygen.cpp.

6470{
6471 AUTO_TRACE();
6472 DString funcType = funcTyp;
6473 int count=0;
6474 int noMatchCount=0;
6475 bool memFound=false;
6476 for (const auto &imd : *mn)
6477 {
6478 MemberDefMutable *md = toMemberDefMutable(imd.get());
6479 if (md==nullptr) continue;
6481 if (cd==nullptr) continue;
6482 //AUTO_TRACE_ADD("member definition found, scope needed='{}' scope='{}' args='{}' fileName='{}'",
6483 // scopeName, cd->name(), md->argsString(), root->fileName);
6484 FileDef *fd=root->fileDef();
6485 NamespaceDef *nd=nullptr;
6486 if (!namespaceName.empty()) nd=getResolvedNamespace(namespaceName);
6487
6488 //printf("scopeName %s->%s\n",qPrint(scopeName),
6489 // qPrint(stripTemplateSpecifiersFromScope(scopeName,false)));
6490
6491 // if the member we are searching for is an enum value that is part of
6492 // a "strong" enum, we need to look into the fields of the enum for a match
6493 size_t enumNamePos=0;
6494 if (md->isEnumValue() && (enumNamePos=className.rfind("::"))!=DString::npos)
6495 {
6496 DString enumName = className.mid(enumNamePos+2);
6497 DString fullScope = className.left(enumNamePos);
6498 if (!namespaceName.empty()) fullScope.prepend(namespaceName+"::");
6499 if (fullScope==cd->name())
6500 {
6501 MemberName *enumMn=Doxygen::memberNameLinkedMap->find(enumName);
6502 //printf("enumMn(%s)=%p\n",qPrint(className),(void*)enumMn);
6503 if (enumMn)
6504 {
6505 for (const auto &emd : *enumMn)
6506 {
6507 memFound = emd->isStrong() && md->getEnumScope()==emd.get();
6508 if (memFound)
6509 {
6510 addMemberDocs(root,md,funcDecl,nullptr,overloaded,spec);
6511 count++;
6512 }
6513 if (memFound) break;
6514 }
6515 }
6516 }
6517 }
6518 if (memFound) break;
6519
6520 const ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
6521 if (tcd==nullptr && cd && stripAnonymousNamespaceScope(cd->name())==scopeName)
6522 {
6523 // don't be fooled by anonymous scopes
6524 tcd=cd;
6525 }
6526 //printf("Looking for %s inside nd=%s result=%s cd=%s\n",
6527 // qPrint(scopeName),nd?qPrint(nd->name()):"<none>",tcd?qPrint(tcd->name()):"",qPrint(cd->name()));
6528
6529 if (cd && tcd==cd) // member's classes match
6530 {
6531 AUTO_TRACE_ADD("class definition '{}' found",cd->name());
6532
6533 // get the template parameter lists found at the member declaration
6534 ArgumentLists declTemplArgs = cd->getTemplateParameterLists();
6535 const ArgumentList &templAl = md->templateArguments();
6536 if (!templAl.empty())
6537 {
6538 declTemplArgs.push_back(templAl);
6539 }
6540
6541 // get the template parameter lists found at the member definition
6542 const ArgumentLists &defTemplArgs = root->tArgLists;
6543 //printf("defTemplArgs=%p\n",defTemplArgs);
6544
6545 // do we replace the decl argument lists with the def argument lists?
6546 bool substDone=false;
6547 ArgumentList argList;
6548
6549 /* substitute the occurrences of class template names in the
6550 * argument list before matching
6551 */
6552 const ArgumentList &mdAl = md->argumentList();
6553 if (declTemplArgs.size()>0 && declTemplArgs.size()==defTemplArgs.size())
6554 {
6555 /* the function definition has template arguments
6556 * and the class definition also has template arguments, so
6557 * we must substitute the template names of the class by that
6558 * of the function definition before matching.
6559 */
6560 substituteTemplatesInArgList(declTemplArgs,defTemplArgs,mdAl,argList);
6561
6562 substDone=true;
6563 }
6564 else /* no template arguments, compare argument lists directly */
6565 {
6566 argList = mdAl;
6567 }
6568
6569 bool matching=
6570 md->isVariable() || md->isTypedef() || // needed for function pointers
6572 md->getClassDef(),md->getFileDef(),md->typeString(),&argList,
6573 cd,fd,root->type,&root->argList,
6574 true,root->lang);
6575
6576 AUTO_TRACE_ADD("matching '{}'<=>'{}' className='{}' namespaceName='{}' result={}",
6577 argListToString(argList,true),argListToString(root->argList,true),className,namespaceName,matching);
6578
6579 if (md->getLanguage()==SrcLangExt::ObjC && md->isVariable() && root->section.isFunction())
6580 {
6581 matching = false; // don't match methods and attributes with the same name
6582 }
6583
6584 // for template member we also need to check the return type
6585 if (!md->templateArguments().empty() && !root->tArgLists.empty())
6586 {
6587 DString memType = md->typeString();
6588 memType.stripPrefix("static "); // see bug700696
6589 // a member defined outside its namespace may use the namespace-qualified
6590 // name for its return type ("N::C" instead of "C"), while the in-class
6591 // declaration uses the unqualified name, so strip the leading namespace
6592 // before comparing the return types, see issue #12379
6593 funcType=substitute(stripTemplateSpecifiersFromScope(funcType,true),
6594 className+"::",""); // see bug700693 & bug732594
6595 memType=substitute(stripTemplateSpecifiersFromScope(memType,true),
6596 className+"::",""); // see bug758900
6597 if (!namespaceName.empty())
6598 {
6599 funcType.stripPrefix(namespaceName+"::");
6600 memType.stripPrefix(namespaceName+"::");
6601 }
6602 if (memType=="auto" && !argList.trailingReturnType().empty())
6603 {
6604 memType = argList.trailingReturnType();
6605 memType.stripPrefix(" -> ");
6606 }
6607 if (funcType=="auto" && !root->argList.trailingReturnType().empty())
6608 {
6609 funcType = root->argList.trailingReturnType();
6610 funcType.stripPrefix(" -> ");
6612 substDone=true;
6613 }
6614 AUTO_TRACE_ADD("Comparing return types '{}'<->'{}' #args {}<->{}",
6615 memType,funcType,md->templateArguments().size(),root->tArgLists.back().size());
6616 if (md->templateArguments().size()!=root->tArgLists.back().size() || memType!=funcType)
6617 {
6618 //printf(" ---> no matching\n");
6619 matching = false;
6620 }
6621 }
6622 else if (defTemplArgs.size()>declTemplArgs.size())
6623 {
6624 AUTO_TRACE_ADD("Different number of template arguments {} vs {}",defTemplArgs.size(),declTemplArgs.size());
6625 // avoid matching a non-template function in a template class against a
6626 // template function with the same name and parameters, see issue #10184
6627 substDone = false;
6628 matching = false;
6629 }
6630 bool rootIsUserDoc = root->section.isMemberDoc();
6631 bool classIsTemplate = scopeIsTemplate(md->getClassDef());
6632 bool mdIsTemplate = md->templateArguments().hasParameters();
6633 bool classOrMdIsTemplate = mdIsTemplate || classIsTemplate;
6634 bool rootIsTemplate = !root->tArgLists.empty();
6635 //printf("classIsTemplate=%d mdIsTemplate=%d rootIsTemplate=%d\n",classIsTemplate,mdIsTemplate,rootIsTemplate);
6636 if (!rootIsUserDoc && // don't check out-of-line @fn references, see bug722457
6637 (mdIsTemplate || rootIsTemplate) && // either md or root is a template
6638 ((classOrMdIsTemplate && !rootIsTemplate) || (!classOrMdIsTemplate && rootIsTemplate))
6639 )
6640 {
6641 // Method with template return type does not match method without return type
6642 // even if the parameters are the same. See also bug709052
6643 AUTO_TRACE_ADD("Comparing return types: template v.s. non-template");
6644 matching = false;
6645 }
6646
6647 AUTO_TRACE_ADD("Match results of matchArguments2='{}' substDone='{}'",matching,substDone);
6648
6649 if (substDone) // found a new argument list
6650 {
6651 if (matching) // replace member's argument list
6652 {
6654 md->moveArgumentList(std::make_unique<ArgumentList>(argList));
6655 }
6656 else // no match
6657 {
6658 if (!funcTempList.empty() &&
6659 isSpecialization(declTemplArgs,defTemplArgs))
6660 {
6661 // check if we are dealing with a partial template
6662 // specialization. In this case we add it to the class
6663 // even though the member arguments do not match.
6664
6665 addMethodToClass(root,cd,type,md->name(),args,isFriend,
6666 md->protection(),md->isStatic(),md->virtualness(),spec,relates);
6667 return;
6668 }
6669 }
6670 }
6671 if (matching)
6672 {
6673 addMemberDocs(root,md,funcDecl,nullptr,overloaded,spec);
6674 count++;
6675 memFound=true;
6676 }
6677 }
6678 else if (cd && cd!=tcd) // we did find a class with the same name as cd
6679 // but in a different namespace
6680 {
6681 noMatchCount++;
6682 }
6683
6684 if (memFound) break;
6685 }
6686 if (count==0 && root->parent() && root->parent()->section.isObjcImpl())
6687 {
6688 addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec);
6689 return;
6690 }
6691 if (count==0 && !(isFriend && funcType=="class"))
6692 {
6693 int candidates=0;
6694 const ClassDef *ecd = nullptr, *ucd = nullptr;
6695 MemberDef *emd = nullptr, *umd = nullptr;
6696 //printf("Assume template class\n");
6697 for (const auto &md : *mn)
6698 {
6699 MemberDef *cmd=md.get();
6701 ClassDefMutable *ccd=cdmdm ? cdmdm->getClassDefMutable() : nullptr;
6702 //printf("ccd->name()==%s className=%s\n",qPrint(ccd->name()),qPrint(className));
6703 if (ccd!=nullptr && rightScopeMatch(ccd->name(),className))
6704 {
6705 const ArgumentList &templAl = md->templateArguments();
6706 if (!root->tArgLists.empty() && !templAl.empty() &&
6707 root->tArgLists.back().size()<=templAl.size())
6708 {
6709 AUTO_TRACE_ADD("add template specialization");
6710 addMethodToClass(root,ccd,type,md->name(),args,isFriend,
6711 root->protection,root->isStatic,root->virt,spec,relates);
6712 return;
6713 }
6714 if (argListToString(md->argumentList(),false,false) ==
6715 argListToString(root->argList,false,false))
6716 { // exact argument list match -> remember
6717 ucd = ecd = ccd;
6718 umd = emd = cmd;
6719 AUTO_TRACE_ADD("new candidate className='{}' scope='{}' args='{}': exact match",
6720 className,ccd->name(),md->argsString());
6721 }
6722 else // arguments do not match, but member name and scope do -> remember
6723 {
6724 ucd = ccd;
6725 umd = cmd;
6726 AUTO_TRACE_ADD("new candidate className='{}' scope='{}' args='{}': no match",
6727 className,ccd->name(),md->argsString());
6728 }
6729 candidates++;
6730 }
6731 }
6732 bool strictProtoMatching = Config_getBool(STRICT_PROTO_MATCHING);
6733 if (!strictProtoMatching)
6734 {
6735 if (candidates==1 && ucd && umd)
6736 {
6737 // we didn't find an actual match on argument lists, but there is only 1 member with this
6738 // name in the same scope, so that has to be the one.
6739 addMemberDocs(root,toMemberDefMutable(umd),funcDecl,nullptr,overloaded,spec);
6740 return;
6741 }
6742 else if (candidates>1 && ecd && emd)
6743 {
6744 // we didn't find a unique match using type resolution,
6745 // but one of the matches has the exact same signature so
6746 // we take that one.
6747 addMemberDocs(root,toMemberDefMutable(emd),funcDecl,nullptr,overloaded,spec);
6748 return;
6749 }
6750 }
6751
6752 DString warnMsg = "no ";
6753 if (noMatchCount>1) warnMsg+="uniquely ";
6754 warnMsg+="matching class member found for \n";
6755
6756 for (const ArgumentList &al : root->tArgLists)
6757 {
6758 warnMsg+=" template ";
6759 warnMsg+=tempArgListToString(al,root->lang);
6760 warnMsg+='\n';
6761 }
6762
6763 DString fullFuncDecl=funcDecl;
6764 if (isFunc) fullFuncDecl+=argListToString(root->argList,true);
6765
6766 warnMsg+=" ";
6767 warnMsg+=fullFuncDecl;
6768
6769 if (candidates>0 || noMatchCount>=1)
6770 {
6771 warnMsg+="\nPossible candidates:";
6772
6773 NamespaceDef *nd=nullptr;
6774 if (!namespaceName.empty()) nd=getResolvedNamespace(namespaceName);
6775 FileDef *fd=root->fileDef();
6776
6777 for (const auto &md : *mn)
6778 {
6779 const ClassDef *cd=md->getClassDef();
6780 const ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
6781 if (tcd==nullptr && cd && stripAnonymousNamespaceScope(cd->name())==scopeName)
6782 {
6783 // don't be fooled by anonymous scopes
6784 tcd=cd;
6785 }
6786 if (cd!=nullptr && (rightScopeMatch(cd->name(),className) || (cd!=tcd)))
6787 {
6788 warnMsg+='\n';
6789 const ArgumentList &templAl = md->templateArguments();
6790 warnMsg+=" '";
6791 if (templAl.hasParameters())
6792 {
6793 warnMsg+="template ";
6794 warnMsg+=tempArgListToString(templAl,root->lang);
6795 warnMsg+='\n';
6796 warnMsg+=" ";
6797 }
6798 if (!md->typeString().empty())
6799 {
6800 warnMsg+=md->typeString();
6801 warnMsg+=' ';
6802 }
6804 if (!qScope.empty())
6805 warnMsg+=qScope+"::"+md->name();
6806 warnMsg+=md->argsString();
6807 warnMsg+="' " + warn_line(md->getDefFileName(),md->getDefLine());
6808 }
6809 }
6810 }
6811 warn(root->fileName,root->startLine,"{}",warnMsg);
6812 }
6813}
bool hasParameters() const
Definition arguments.h:77
DString trailingReturnType() const
Definition arguments.h:115
size_t size() const
Definition arguments.h:101
void setTrailingReturnType(const DString &s)
Definition arguments.cpp:40
virtual ArgumentLists getTemplateParameterLists() const =0
Returns the template parameter lists that form the template declaration of this class.
virtual DString qualifiedNameWithTemplateParameters(const ArgumentLists *actualParams=nullptr, uint32_t *actualParamIndex=nullptr) const =0
virtual SrcLangExt getLanguage() const =0
Returns the programming language this definition was written in.
virtual DString getDefFileName() const =0
virtual int getDefLine() const =0
A model of a class/file/namespace member symbol.
Definition memberdef.h:45
virtual const ArgumentList & templateArguments() const =0
virtual bool isTypedef() const =0
virtual bool isStatic() const =0
virtual Protection protection() const =0
virtual bool isVariable() const =0
virtual Specifier virtualness(int count=0) const =0
virtual const MemberDef * getEnumScope() const =0
virtual void setDefinitionTemplateParameterLists(const ArgumentLists &lists)=0
virtual void moveArgumentList(std::unique_ptr< ArgumentList > al)=0
static bool isSpecialization(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists)
Definition doxygen.cpp:6239
static void substituteTemplatesInArgList(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const ArgumentList &src, ArgumentList &dst)
Definition doxygen.cpp:6353
static void addLocalObjCMethod(const Entry *root, const DString &scopeName, const DString &funcType, const DString &funcName, const DString &funcArgs, const DString &exceptions, const DString &funcDecl, TypeSpecifier spec)
Definition doxygen.cpp:6397
static void addMemberDocs(const Entry *root, MemberDefMutable *md, const DString &funcDecl, const ArgumentList *al, bool over_load, TypeSpecifier spec)
Definition doxygen.cpp:5840
static void addMethodToClass(const Entry *root, ClassDefMutable *cd, const DString &rtype, const DString &rname, const DString &rargs, bool isFriend, Protection protection, bool stat, Specifier virt, TypeSpecifier spec, const DString &relates)
Definition doxygen.cpp:3947
static bool scopeIsTemplate(const Definition *d)
Definition doxygen.cpp:6255
static const ClassDef * findClassDefinition(FileDef *fd, NamespaceDef *nd, const DString &scopeName)
Definition doxygen.cpp:5992
DString warn_line(const DString &file, int line)
Definition message.cpp:211
NamespaceDef * getResolvedNamespace(const DString &name)
bool rightScopeMatch(const DString &scope, const DString &name)
Definition util.cpp:734
DString replaceAnonymousScopes(const DString &s, const DString &replacement)
Definition util.cpp:155
DString tempArgListToString(const ArgumentList &al, SrcLangExt lang, bool includeDefault)
Definition util.cpp:908
DString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:864
DString stripAnonymousNamespaceScope(const DString &s)
Definition util.cpp:167

References addLocalObjCMethod(), addMemberDocs(), addMethodToClass(), Entry::argList, argListToString(), MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, Config_getBool, ArgumentList::empty(), DString::empty(), Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), findClassDefinition(), MemberDef::getClassDef(), MemberDefMutable::getClassDefMutable(), MemberDef::getEnumScope(), MemberDef::getFileDef(), Definition::getLanguage(), getResolvedNamespace(), ClassDef::getTemplateParameterLists(), ArgumentList::hasParameters(), MemberDef::isEnumValue(), isSpecialization(), Entry::isStatic, MemberDef::isStatic(), MemberDef::isTypedef(), MemberDef::isVariable(), Entry::lang, DString::left(), matchArguments2(), Doxygen::memberNameLinkedMap, DString::mid(), MemberDefMutable::moveArgumentList(), Definition::name(), DString::npos, Entry::parent(), DString::prepend(), Entry::protection, MemberDef::protection(), ClassDef::qualifiedNameWithTemplateParameters(), replaceAnonymousScopes(), DString::rfind(), rightScopeMatch(), scopeIsTemplate(), Entry::section, MemberDefMutable::setDefinitionTemplateParameterLists(), ArgumentList::setTrailingReturnType(), ArgumentList::size(), Entry::startLine, stripAnonymousNamespaceScope(), DString::stripPrefix(), stripTemplateSpecifiersFromScope(), substitute(), substituteTemplatesInArgList(), Entry::tArgLists, tempArgListToString(), MemberDef::templateArguments(), toMemberDefMutable(), ArgumentList::trailingReturnType(), Entry::type, MemberDef::typeString(), Entry::virt, MemberDef::virtualness(), warn, and warn_line().

Referenced by findMember().

◆ addMemberSpecialization()

void addMemberSpecialization ( const Entry * root,
MemberName * mn,
ClassDefMutable * cd,
const DString & funcType,
const DString & funcName,
const DString & funcArgs,
const DString & funcDecl,
const DString & exceptions,
TypeSpecifier spec )
static

Definition at line 6817 of file doxygen.cpp.

6827{
6828 AUTO_TRACE("funcType={} funcName={} funcArgs={} funcDecl={} spec={}",funcType,funcName,funcArgs,funcDecl,spec);
6829 MemberDef *declMd=nullptr;
6830 for (const auto &md : *mn)
6831 {
6832 if (md->getClassDef()==cd)
6833 {
6834 // TODO: we should probably also check for matching arguments
6835 declMd = md.get();
6836 break;
6837 }
6838 }
6839 MemberType mtype=MemberType::Function;
6840 ArgumentList tArgList;
6841 // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6842 auto md = createMemberDef(
6843 root->fileName,root->startLine,root->startColumn,
6844 funcType,funcName,funcArgs,exceptions,
6845 declMd ? declMd->protection() : root->protection,
6846 root->virt,root->isStatic,Relationship::Member,
6847 mtype,tArgList,root->argList,root->metaData);
6848 auto mmd = toMemberDefMutable(md.get());
6849 //printf("new specialized member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6850 mmd->setTagInfo(root->tagInfo());
6851 mmd->setLanguage(root->lang);
6852 mmd->setId(root->id);
6853 mmd->setMemberClass(cd);
6854 mmd->setTemplateSpecialization(true);
6855 mmd->setTypeConstraints(root->typeConstr);
6856 mmd->setDefinition(funcDecl);
6858 mmd->addQualifiers(root->qualifiers);
6859 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6860 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6861 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6862 mmd->setDocsForDefinition(!root->proto);
6863 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6864 mmd->addSectionsToDefinition(root->anchors);
6865 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6866 FileDef *fd=root->fileDef();
6867 mmd->setBodyDef(fd);
6868 mmd->setMemberSpecifiers(spec);
6869 mmd->setVhdlSpecifiers(root->vhdlSpec);
6870 mmd->setMemberGroupId(root->mGrpId);
6871 cd->insertMember(md.get());
6872 mmd->setRefItems(root->sli);
6873 mmd->setRequirementReferences(root->rqli);
6874 addIncludeFile(mmd,fd,root);
6875
6876 mn->push_back(std::move(md));
6877}

References addIncludeFile(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, AUTO_TRACE, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Entry::fileDef(), Entry::fileName, Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), Entry::isStatic, Entry::lang, Entry::metaData, Entry::mGrpId, Entry::protection, MemberDef::protection(), Entry::proto, MemberName::push_back(), Entry::qualifiers, Entry::rqli, DefinitionMutable::setBodyDef(), Entry::sli, Entry::startColumn, Entry::startLine, Entry::tagInfo(), toMemberDefMutable(), Entry::typeConstr, Entry::vhdlSpec, and Entry::virt.

Referenced by findMember().

◆ addMembersToIndex()

void addMembersToIndex ( )
static

Definition at line 8445 of file doxygen.cpp.

8446{
8447 auto &index = Index::instance();
8448 // for each class member name
8449 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8450 {
8451 // for each member definition
8452 for (const auto &md : *mn)
8453 {
8454 index.addClassMemberNameToIndex(md.get());
8455 if (md->getModuleDef())
8456 {
8457 index.addModuleMemberNameToIndex(md.get());
8458 }
8459 }
8460 }
8461 // for each file/namespace function name
8462 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8463 {
8464 // for each member definition
8465 for (const auto &md : *mn)
8466 {
8467 if (md->getNamespaceDef())
8468 {
8469 index.addNamespaceMemberNameToIndex(md.get());
8470 }
8471 else
8472 {
8473 index.addFileMemberNameToIndex(md.get());
8474 }
8475 if (md->getModuleDef())
8476 {
8477 index.addModuleMemberNameToIndex(md.get());
8478 }
8479 }
8480 }
8481
8482 index.sortMemberIndexLists();
8483}
static Index & instance()
Definition index.cpp:110

References Doxygen::functionNameLinkedMap, Index::instance(), and Doxygen::memberNameLinkedMap.

Referenced by parseInput().

◆ addMembersToMemberGroup()

void addMembersToMemberGroup ( )
static

Definition at line 9601 of file doxygen.cpp.

9602{
9603 // for each class
9604 for (const auto &cd : *Doxygen::classLinkedMap)
9605 {
9606 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9607 if (cdm)
9608 {
9610 }
9611 }
9612 // for each file
9613 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9614 {
9615 for (const auto &fd : *fn)
9616 {
9617 fd->addMembersToMemberGroup();
9618 }
9619 }
9620 // for each namespace
9621 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9622 {
9624 if (ndm)
9625 {
9627 }
9628 }
9629 // for each group
9630 for (const auto &gd : *Doxygen::groupLinkedMap)
9631 {
9632 gd->addMembersToMemberGroup();
9633 }
9635}
virtual void addMembersToMemberGroup()=0
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:108
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:107
void addMembersToMemberGroup()
virtual void addMembersToMemberGroup()=0

References ClassDefMutable::addMembersToMemberGroup(), ModuleManager::addMembersToMemberGroup(), NamespaceDefMutable::addMembersToMemberGroup(), Doxygen::classLinkedMap, Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), Doxygen::namespaceLinkedMap, toClassDefMutable(), and toNamespaceDefMutable().

Referenced by parseInput().

◆ addMethodToClass()

void addMethodToClass ( const Entry * root,
ClassDefMutable * cd,
const DString & rtype,
const DString & rname,
const DString & rargs,
bool isFriend,
Protection protection,
bool stat,
Specifier virt,
TypeSpecifier spec,
const DString & relates )
static

Definition at line 3947 of file doxygen.cpp.

3953{
3954 FileDef *fd=root->fileDef();
3955
3956 DString type = rtype;
3957 DString args = rargs;
3958
3960 name.stripPrefix("::");
3961
3962 MemberType mtype = MemberType::Function;
3963 if (isFriend) mtype=MemberType::Friend;
3964 else if (root->mtype==MethodTypes::Signal) mtype=MemberType::Signal;
3965 else if (root->mtype==MethodTypes::Slot) mtype=MemberType::Slot;
3966 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType::DCOP;
3967
3968 // strip redundant template specifier for constructors
3969 size_t i = DString::npos;
3970 size_t j = DString::npos;
3971 if ((fd==nullptr || fd->getLanguage()==SrcLangExt::Cpp) &&
3972 !name.startsWith("operator ") && // not operator
3973 (i=name.find('<'))!=DString::npos && // containing <
3974 (j=name.find('>'))!=DString::npos && // or >
3975 (j!=i+2 || name.at(i+1)!='=') // but not the C++20 spaceship operator <=>
3976 )
3977 {
3978 name=name.left(i);
3979 }
3980
3981 DString fileName = root->fileName;
3982 if (fileName.empty() && root->tagInfo())
3983 {
3984 fileName = root->tagInfo()->tagName;
3985 }
3986
3987 //printf("root->name='%s; args='%s' root->argList='%s'\n",
3988 // qPrint(root->name),qPrint(args),qPrint(argListToString(root->argList))
3989 // );
3990
3991 // adding class member
3992 Relationship relationship = relates.empty() ? Relationship::Member :
3993 root->relatesType==RelatesType::MemberOf ? Relationship::Foreign :
3994 Relationship::Related ;
3995 auto md = createMemberDef(
3996 fileName,root->startLine,root->startColumn,
3997 type,name,args,root->exception,
3998 protection,virt,
3999 stat && root->relatesType!=RelatesType::MemberOf,
4000 relationship,
4001 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
4002 root->argList, root->metaData);
4003 auto mmd = toMemberDefMutable(md.get());
4004 mmd->setTagInfo(root->tagInfo());
4005 mmd->setMemberClass(cd);
4006 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
4007 mmd->setDocsForDefinition(!root->proto);
4008 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
4009 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
4010 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
4011 mmd->setMemberSpecifiers(spec);
4012 mmd->setVhdlSpecifiers(root->vhdlSpec);
4013 mmd->setMemberGroupId(root->mGrpId);
4014 mmd->setTypeConstraints(root->typeConstr);
4015 mmd->setLanguage(root->lang);
4016 mmd->setRequiresClause(root->req);
4017 mmd->setId(root->id);
4018 mmd->setBodyDef(fd);
4019 mmd->setFileDef(fd);
4020 mmd->addSectionsToDefinition(root->anchors);
4021 addIncludeFile(mmd,fd,root);
4022 DString def;
4024 SrcLangExt lang = cd->getLanguage();
4025 DString scopeSeparator=getLanguageSpecificSeparator(lang);
4026 if (scopeSeparator!="::")
4027 {
4028 qualScope = substitute(qualScope,"::",scopeSeparator);
4029 }
4030 if (lang==SrcLangExt::PHP)
4031 {
4032 // for PHP we use Class::method and Namespace\method
4033 scopeSeparator="::";
4034 }
4035 if (!relates.empty() || isFriend || Config_getBool(HIDE_SCOPE_NAMES))
4036 {
4037 if (!type.empty())
4038 {
4039 def=type+" "+name; //+optArgs;
4040 }
4041 else
4042 {
4043 def=name; //+optArgs;
4044 }
4045 }
4046 else
4047 {
4048 if (!type.empty())
4049 {
4050 def=type+" "+qualScope+scopeSeparator+name; //+optArgs;
4051 }
4052 else
4053 {
4054 def=qualScope+scopeSeparator+name; //+optArgs;
4055 }
4056 }
4057 def.stripPrefix("friend ");
4058 mmd->setDefinition(def);
4060 mmd->addQualifiers(root->qualifiers);
4061
4062 AUTO_TRACE("function member: type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
4063 type, qualScope, rname, args, root->proto, def);
4064
4065 // add member to the class cd
4066 cd->insertMember(md.get());
4067 // add file to list of used files
4068 cd->insertUsedFile(fd);
4069
4070 addMemberToGroups(root,md.get());
4072 root->markAsProcessed();
4073 mmd->setRefItems(root->sli);
4074 mmd->setRequirementReferences(root->rqli);
4075
4076 // add member to the global list of all members
4077 //printf("Adding member=%s class=%s\n",qPrint(md->name()),qPrint(cd->name()));
4079 mn->push_back(std::move(md));
4080}
MethodTypes mtype
signal, slot, (dcop) method, or property?
Definition entry.h:180
Relationship
Definition types.h:167

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addIncludeFile(), addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, AUTO_TRACE, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), Entry::endBodyLine, Entry::exception, Entry::fileDef(), Entry::fileName, Definition::getLanguage(), getLanguageSpecificSeparator(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), Entry::lang, Entry::markAsProcessed(), Doxygen::memberNameLinkedMap, Entry::metaData, Entry::mGrpId, Entry::mtype, DString::npos, Entry::proto, MemberName::push_back(), ClassDef::qualifiedNameWithTemplateParameters(), Entry::qualifiers, Entry::relatesType, removeRedundantWhiteSpace(), Entry::req, Entry::rqli, Entry::sli, Entry::startColumn, Entry::startLine, DString::stripPrefix(), substitute(), Entry::tagInfo(), TagInfo::tagName, Entry::tArgLists, toMemberDefMutable(), Entry::typeConstr, and Entry::vhdlSpec.

Referenced by addMemberFunction(), and buildFunctionList().

◆ addOverloaded()

void addOverloaded ( const Entry * root,
MemberName * mn,
const DString & funcType,
const DString & funcName,
const DString & funcArgs,
const DString & funcDecl,
const DString & exceptions,
TypeSpecifier spec )
static

Definition at line 6881 of file doxygen.cpp.

6884{
6885 // for unique overloaded member we allow the class to be
6886 // omitted, this is to be Qt compatible. Using this should
6887 // however be avoided, because it is error prone
6888 bool sameClass=false;
6889 if (mn->size()>0)
6890 {
6891 // check if all members with the same name are also in the same class
6892 sameClass = std::equal(mn->begin()+1,mn->end(),mn->begin(),
6893 [](const auto &md1,const auto &md2)
6894 { return md1->getClassDef()->name()==md2->getClassDef()->name(); });
6895 }
6896 if (sameClass)
6897 {
6898 MemberDefMutable *mdm = toMemberDefMutable(mn->front().get());
6899 ClassDefMutable *cd = mdm ? mdm->getClassDefMutable() : nullptr;
6900 if (cd==nullptr) return;
6901
6902 MemberType mtype = MemberType::Function;
6903 if (root->mtype==MethodTypes::Signal) mtype=MemberType::Signal;
6904 else if (root->mtype==MethodTypes::Slot) mtype=MemberType::Slot;
6905 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType::DCOP;
6906
6907 // new overloaded member function
6908 std::unique_ptr<ArgumentList> tArgList =
6909 getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6910 //printf("new related member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6911 auto md = createMemberDef(
6912 root->fileName,root->startLine,root->startColumn,
6913 funcType,funcName,funcArgs,exceptions,
6914 root->protection,root->virt,root->isStatic,Relationship::Related,
6915 mtype,tArgList ? *tArgList : ArgumentList(),root->argList,root->metaData);
6916 auto mmd = toMemberDefMutable(md.get());
6917 mmd->setTagInfo(root->tagInfo());
6918 mmd->setLanguage(root->lang);
6919 mmd->setId(root->id);
6920 mmd->setTypeConstraints(root->typeConstr);
6921 mmd->setMemberClass(cd);
6922 mmd->setDefinition(funcDecl);
6924 mmd->addQualifiers(root->qualifiers);
6926 doc+="<p>";
6927 doc+=root->doc;
6928 mmd->setDocumentation(doc,root->docFile,root->docLine);
6929 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6930 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6931 mmd->setDocsForDefinition(!root->proto);
6932 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6933 mmd->addSectionsToDefinition(root->anchors);
6934 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6935 FileDef *fd=root->fileDef();
6936 mmd->setBodyDef(fd);
6937 mmd->setMemberSpecifiers(spec);
6938 mmd->setVhdlSpecifiers(root->vhdlSpec);
6939 mmd->setMemberGroupId(root->mGrpId);
6940 cd->insertMember(md.get());
6941 cd->insertUsedFile(fd);
6942 mmd->setRefItems(root->sli);
6943 mmd->setRequirementReferences(root->rqli);
6944 addIncludeFile(mmd,fd,root);
6945
6946 mn->push_back(std::move(md));
6947 }
6948}
Ptr & front()
Definition membername.h:49
size_t size() const
Definition membername.h:46
iterator begin()
Definition membername.h:35
iterator end()
Definition membername.h:36

References addIncludeFile(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, MemberName::begin(), Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, MemberName::end(), Entry::endBodyLine, Entry::fileDef(), Entry::fileName, MemberName::front(), MemberDefMutable::getClassDefMutable(), getTemplateArgumentsFromName(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), Entry::isStatic, Entry::lang, Entry::metaData, Entry::mGrpId, Entry::mtype, Definition::name(), Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, Entry::rqli, DefinitionMutable::setBodyDef(), MemberName::size(), Entry::sli, Entry::startColumn, Entry::startLine, Entry::tagInfo(), Entry::tArgLists, theTranslator, toMemberDefMutable(), Translator::trOverloadText(), Entry::typeConstr, Entry::vhdlSpec, and Entry::virt.

Referenced by findMember().

◆ addPageToContext()

void addPageToContext ( PageDef * pd,
Entry * root )
static

Definition at line 417 of file doxygen.cpp.

418{
419 if (root->parent()) // add the page to it's scope
420 {
421 DString scope = root->parent()->name;
422 if (root->parent()->section.isPackageDoc())
423 {
424 scope=substitute(scope,".","::");
425 }
426 scope = stripAnonymousNamespaceScope(scope);
427 scope+="::"+pd->name();
429 if (d)
430 {
431 pd->setPageScope(d);
432 }
433 }
434}
virtual void setPageScope(Definition *)=0

References findScopeFromQualifiedName(), Doxygen::globalScope, Definition::name(), Entry::name, Entry::parent(), Entry::section, PageDef::setPageScope(), stripAnonymousNamespaceScope(), substitute(), and Entry::tagInfo().

Referenced by addRelatedPage(), and findMainPage().

◆ addRelatedPage()

void addRelatedPage ( Entry * root)
static

Definition at line 436 of file doxygen.cpp.

437{
438 GroupDef *gd=nullptr;
439 for (const Grouping &g : root->groups)
440 {
441 if (!g.groupname.empty() && (gd=Doxygen::groupLinkedMap->find(g.groupname))) break;
442 }
443 //printf("---> addRelatedPage() %s gd=%p\n",qPrint(root->name),gd);
444 DString doc=root->doc+root->inbodyDocs;
445
446 PageDef *pd = addRelatedPage(root->name, // name
447 root->args, // ptitle
448 doc, // doc
449 root->docFile, // fileName
450 root->docLine, // docLine
451 root->startLine, // startLine
452 root->sli, // sli
453 gd, // gd
454 root->tagInfo(), // tagInfo
455 false, // xref
456 root->lang // lang
457 );
458 if (pd)
459 {
460 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
462 pd->setLocalToc(root->localToc);
463 addPageToContext(pd,root);
464 }
465}
LocalToc localToc
Definition entry.h:233
A model of a page symbol.
Definition pagedef.h:27
virtual void setLocalToc(const LocalToc &tl)=0
static void addRelatedPage(Entry *root)
Definition doxygen.cpp:436
static void addPageToContext(PageDef *pd, Entry *root)
Definition doxygen.cpp:417
Grouping info.
Definition types.h:227
DString groupname
name of the group
Definition types.h:257

References addPageToContext(), addRelatedPage(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, Entry::args, Entry::brief, Entry::briefFile, Entry::briefLine, Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), LinkedMap< T, Hash, KeyEqual, Map >::find(), Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, Entry::inbodyDocs, Entry::lang, Entry::localToc, Entry::name, DefinitionMutable::setBriefDescription(), PageDef::setLocalToc(), Entry::sli, Entry::startLine, and Entry::tagInfo().

Referenced by addRelatedPage(), and buildPageList().

◆ addRequirementReferences()

void addRequirementReferences ( )
static

Definition at line 5809 of file doxygen.cpp.

5810{
5811 AUTO_TRACE();
5812 applyToAllDefinitions([](auto* obj) { obj->addRequirementReferences(); });
5813}

References applyToAllDefinitions(), and AUTO_TRACE.

Referenced by parseInput().

◆ addSourceReferences()

void addSourceReferences ( )
static

Definition at line 9119 of file doxygen.cpp.

9120{
9121 // add source references for class definitions
9122 for (const auto &cd : *Doxygen::classLinkedMap)
9123 {
9124 const FileDef *fd=cd->getBodyDef();
9125 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
9126 {
9127 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
9128 }
9129 }
9130 // add source references for concept definitions
9131 for (const auto &cd : *Doxygen::conceptLinkedMap)
9132 {
9133 const FileDef *fd=cd->getBodyDef();
9134 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
9135 {
9136 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
9137 }
9138 }
9139 // add source references for namespace definitions
9140 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9141 {
9142 const FileDef *fd=nd->getBodyDef();
9143 if (fd && nd->isLinkableInProject() && nd->getStartDefLine()!=-1)
9144 {
9145 const_cast<FileDef*>(fd)->addSourceRef(nd->getStartDefLine(),nd.get(),nullptr);
9146 }
9147 }
9148
9149 // add source references for member names
9150 for (const auto &mn : *Doxygen::memberNameLinkedMap)
9151 {
9152 for (const auto &md : *mn)
9153 {
9154 //printf("class member %s: def=%s body=%d link?=%d\n",
9155 // qPrint(md->name()),
9156 // md->getBodyDef()?qPrint(md->getBodyDef()->name()):"<none>",
9157 // md->getStartBodyLine(),md->isLinkableInProject());
9158 const FileDef *fd=md->getBodyDef();
9159 if (fd &&
9160 md->getStartDefLine()!=-1 &&
9161 md->isLinkableInProject() &&
9163 )
9164 {
9165 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
9166 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
9167 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
9168 }
9169 }
9170 }
9171 for (const auto &mn : *Doxygen::functionNameLinkedMap)
9172 {
9173 for (const auto &md : *mn)
9174 {
9175 const FileDef *fd=md->getBodyDef();
9176 //printf("member %s body=[%d,%d] fd=%p link=%d parseSources=%d\n",
9177 // qPrint(md->name()),
9178 // md->getStartBodyLine(),md->getEndBodyLine(),fd,
9179 // md->isLinkableInProject(),
9180 // Doxygen::parseSourcesNeeded);
9181 if (fd &&
9182 md->getStartDefLine()!=-1 &&
9183 md->isLinkableInProject() &&
9185 )
9186 {
9187 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
9188 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
9189 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
9190 }
9191 }
9192 }
9193}
virtual const FileDef * getBodyDef() const =0
static bool parseSourcesNeeded
Definition doxygen.h:116

References Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Doxygen::functionNameLinkedMap, FileDef::generateSourceFile(), Definition::getBodyDef(), Definition::getStartDefLine(), Definition::isLinkableInProject(), Doxygen::memberNameLinkedMap, Doxygen::namespaceLinkedMap, and Doxygen::parseSourcesNeeded.

Referenced by parseInput().

◆ addToIndices()

void addToIndices ( )
static

Definition at line 8487 of file doxygen.cpp.

8488{
8489 for (const auto &cd : *Doxygen::classLinkedMap)
8490 {
8491 if (cd->isLinkableInProject())
8492 {
8493 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8494 if (Doxygen::searchIndex.enabled())
8495 {
8496 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),false);
8497 Doxygen::searchIndex.addWord(cd->localName(),true);
8498 }
8499 }
8500 }
8501
8502 for (const auto &cd : *Doxygen::conceptLinkedMap)
8503 {
8504 if (cd->isLinkableInProject())
8505 {
8506 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8507 if (Doxygen::searchIndex.enabled())
8508 {
8509 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),false);
8510 Doxygen::searchIndex.addWord(cd->localName(),true);
8511 }
8512 }
8513 }
8514
8515 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8516 {
8517 if (nd->isLinkableInProject())
8518 {
8519 Doxygen::indexList->addIndexItem(nd.get(),nullptr);
8520 if (Doxygen::searchIndex.enabled())
8521 {
8522 Doxygen::searchIndex.setCurrentDoc(nd.get(),nd->anchor(),false);
8523 Doxygen::searchIndex.addWord(nd->localName(),true);
8524 }
8525 }
8526 }
8527
8528 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8529 {
8530 for (const auto &fd : *fn)
8531 {
8532 if (Doxygen::searchIndex.enabled() && fd->isLinkableInProject())
8533 {
8534 Doxygen::searchIndex.setCurrentDoc(fd.get(),fd->anchor(),false);
8535 Doxygen::searchIndex.addWord(fd->localName(),true);
8536 }
8537 }
8538 }
8539
8540 auto addWordsForTitle = [](const Definition *d,const DString &anchor,const DString &title)
8541 {
8543 if (Doxygen::searchIndex.enabled())
8544 {
8545 Doxygen::searchIndex.setCurrentDoc(d,anchor,false);
8546 std::string s = title.str();
8547 static const reg::Ex re(R"(\a[\w-]*)");
8548 reg::Iterator it(s,re);
8550 for (; it!=end ; ++it)
8551 {
8552 const auto &match = *it;
8553 std::string matchStr = match.str();
8554 Doxygen::searchIndex.addWord(matchStr,true);
8555 }
8556 }
8557 };
8558
8559 for (const auto &gd : *Doxygen::groupLinkedMap)
8560 {
8561 if (gd->isLinkableInProject())
8562 {
8563 addWordsForTitle(gd.get(),gd->anchor(),gd->groupTitle());
8564 }
8565 }
8566
8567 for (const auto &pd : *Doxygen::pageLinkedMap)
8568 {
8569 if (pd->isLinkableInProject())
8570 {
8571 addWordsForTitle(pd.get(),pd->anchor(),pd->title());
8572 }
8573 }
8574
8576 {
8577 addWordsForTitle(Doxygen::mainPage.get(),Doxygen::mainPage->anchor(),Doxygen::mainPage->title());
8578 }
8579
8580 auto addMemberToSearchIndex = [](const MemberDef *md)
8581 {
8582 if (Doxygen::searchIndex.enabled())
8583 {
8584 Doxygen::searchIndex.setCurrentDoc(md,md->anchor(),false);
8585 DString ln=md->localName();
8586 DString qn=md->qualifiedName();
8588 if (ln!=qn)
8589 {
8591 if (md->getClassDef())
8592 {
8593 Doxygen::searchIndex.addWord(md->getClassDef()->displayName(),true);
8594 }
8595 if (md->getNamespaceDef())
8596 {
8597 Doxygen::searchIndex.addWord(md->getNamespaceDef()->displayName(),true);
8598 }
8599 }
8600 }
8601 };
8602
8603 auto getScope = [](const MemberDef *md)
8604 {
8605 const Definition *scope = nullptr;
8606 if (md->getGroupDef()) scope = md->getGroupDef();
8607 else if (md->getClassDef()) scope = md->getClassDef();
8608 else if (md->getNamespaceDef()) scope = md->getNamespaceDef();
8609 else if (md->getFileDef()) scope = md->getFileDef();
8610 return scope;
8611 };
8612
8613 auto addMemberToIndices = [addMemberToSearchIndex,getScope](const MemberDef *md)
8614 {
8615 if (md->isLinkableInProject())
8616 {
8617 if (!(md->isEnumerate() && md->isAnonymous()))
8618 {
8619 Doxygen::indexList->addIndexItem(getScope(md),md);
8620 addMemberToSearchIndex(md);
8621 }
8622 if (md->isEnumerate())
8623 {
8624 for (const auto &fmd : md->enumFieldList())
8625 {
8626 Doxygen::indexList->addIndexItem(getScope(fmd),fmd);
8627 addMemberToSearchIndex(fmd);
8628 }
8629 }
8630 }
8631 };
8632
8633 // for each class member name
8634 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8635 {
8636 // for each member definition
8637 for (const auto &md : *mn)
8638 {
8639 addMemberToIndices(md.get());
8640 }
8641 }
8642 // for each file/namespace function name
8643 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8644 {
8645 // for each member definition
8646 for (const auto &md : *mn)
8647 {
8648 addMemberToIndices(md.get());
8649 }
8650 }
8651}
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:93
static IndexList * indexList
Definition doxygen.h:125
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:92
static SearchIndexIntf searchIndex
Definition doxygen.h:117
void addIndexItem(const Definition *context, const MemberDef *md, const DString &sectionAnchor=DString(), const DString &title=DString())
Definition indexlist.h:118
void addWord(const DString &word, bool hiPriority)
void setCurrentDoc(const Definition *ctx, const DString &anchor, bool isSourceFile)
Class representing a regular expression.
Definition regex.h:39
Class to iterate through matches.
Definition regex.h:245
DirIterator end(const DirIterator &) noexcept
Definition dir.cpp:181
bool match(std::string_view str, Match &match, const Ex &re)
Matches a given string str for a match against regular expression re.
Definition regex.cpp:861
DString filterTitle(const DString &title)
Definition util.cpp:4464

References IndexList::addIndexItem(), SearchIndexIntf::addWord(), Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, end(), filterTitle(), Doxygen::functionNameLinkedMap, Doxygen::groupLinkedMap, Doxygen::indexList, Doxygen::inputNameLinkedMap, Doxygen::mainPage, Doxygen::memberNameLinkedMap, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, Doxygen::searchIndex, and SearchIndexIntf::setCurrentDoc().

Referenced by parseInput().

◆ addVariable()

void addVariable ( const Entry * root,
int isFuncPtr = -1 )
static

Definition at line 3441 of file doxygen.cpp.

3442{
3443 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
3444
3445 AUTO_TRACE("VARIABLE_SEC: type='{}' name='{}' args='{}' bodyLine={} endBodyLine={} mGrpId={} relates='{}'",
3446 root->type, root->name, root->args, root->bodyLine, root->endBodyLine, root->mGrpId, root->relates);
3447 //printf("root->parent->name=%s\n",qPrint(root->parent->name));
3448
3449 DString type = root->type;
3450 DString name = root->name;
3451 DString args = root->args;
3452 if (type.empty() && name.find("operator")==DString::npos &&
3453 (name.find('*')!=DString::npos || name.find('&')!=DString::npos))
3454 {
3455 // recover from parse error caused by redundant braces
3456 // like in "int *(var[10]);", which is parsed as
3457 // type="" name="int *" args="(var[10])"
3458
3459 type=name;
3460 std::string sargs = args.str();
3461 static const reg::Ex reName(R"(\a\w*)");
3463 if (reg::search(sargs,match,reName))
3464 {
3465 name = match.str(); // e.g. 'var' in '(var[10])'
3466 sargs = match.suffix().str(); // e.g. '[10]) in '(var[10])'
3467 size_t j = sargs.find(')');
3468 if (j!=std::string::npos) args=sargs.substr(0,j); // extract, e.g '[10]' from '[10])'
3469 }
3470 }
3471 else
3472 {
3473 int i=isFuncPtr;
3474 if (i==-1 && (root->spec.isAlias())==0) i=findFunctionPtr(type.str(),root->lang); // for typedefs isFuncPtr is not yet set
3475 AUTO_TRACE_ADD("functionPtr={}",i!=-1?"yes":"no");
3476 if (i>=0) // function pointer
3477 {
3478 size_t ii = i;
3479 size_t ai = type.find('[',ii);
3480 if (ai!=DString::npos && ai>ii) // function pointer array
3481 {
3482 args.prepend(type.mid(ai));
3483 type=type.left(ai);
3484 }
3485 else if (type.find(')',ii)!=DString::npos) // function ptr, not variable like "int (*bla)[10]"
3486 {
3487 type=type.left(type.length()-1);
3488 args.prepend(") ");
3489 }
3490 }
3491 }
3492 AUTO_TRACE_ADD("after correction: type='{}' name='{}' args='{}'",type,name,args);
3493
3494 DString scope;
3496
3497 // find the scope of this variable
3498 int index = computeQualifiedIndex(name);
3499 // grouped members are stored with full scope
3500 bool qualifiedGroupMember = index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo();
3501 // A specialization of a variable template that lives in a namespace, i.e.
3502 // `template<class T> constexpr bool std::ranges::enable_view<MyView<T>> = true;`.
3503 // Its scope has to be spelled out, so it must not be mistaken for the definition of a static
3504 // data member, which is declared in its class as well and is therefore picked up from there.
3505 bool variableTemplateSpecialization = index!=-1 && !root->tArgLists.empty() &&
3506 name.mid(index+2).find('<')!=DString::npos &&
3507 getClass(name.left(index))==nullptr;
3508 if (qualifiedGroupMember || variableTemplateSpecialization)
3509 {
3510 Definition *d = buildScopeFromQualifiedName(name.left(index+2),root->lang,root->tagInfo());
3511 if (variableTemplateSpecialization)
3512 // the scope may have been made up for this specialization, but it holds a documented member
3513 // now, which is only reachable through a page of its own
3514 {
3515 for (Definition *s=d; s && s!=Doxygen::globalScope; s=s->getOuterScope())
3516 {
3518 if (ndm && ndm->isArtificial()) ndm->setArtificial(false);
3519 }
3520 }
3521 scope=name.left(index);
3522 name=name.mid(index+2);
3523 }
3524 else
3525 {
3526 Entry *p = root->parent();
3527 while (p->section.isScope())
3528 {
3529 DString scopeName = p->name;
3530 if (!scopeName.empty())
3531 {
3532 scope.prepend(scopeName);
3533 break;
3534 }
3535 p=p->parent();
3536 }
3537 }
3538
3539 DString type_s = type;
3540 type=type.stripWhiteSpace();
3541 ClassDefMutable *cd=nullptr;
3542 bool isRelated=false;
3543 bool isMemberOf=false;
3544
3545 DString classScope=stripAnonymousNamespaceScope(scope);
3546 if (root->lang==SrcLangExt::CSharp)
3547 {
3548 classScope=mangleCSharpGenericName(classScope);
3549 }
3550 else
3551 {
3552 classScope=stripTemplateSpecifiersFromScope(classScope,false);
3553 }
3554 DString annScopePrefix=scope.left(scope.length()-classScope.length());
3555
3556
3557 // Look for last :: not part of template specifier
3558 int p=-1;
3559 for (size_t i=0;i<name.length()-1;i++)
3560 {
3561 if (name[i]==':' && name[i+1]==':')
3562 {
3563 p=static_cast<int>(i);
3564 }
3565 else if (name[i]=='<') // skip over template parts,
3566 // i.e. A::B<C::D> => p=1 and
3567 // A<B::C>::D => p=8
3568 {
3569 int e = findEndOfTemplate(name,i+1);
3570 if (e!=-1) i=static_cast<int>(e);
3571 }
3572 }
3573
3574 if (p!=-1) // found it
3575 {
3576 if (isTypeAClassFriend(type))
3577 {
3578 cd=getClassMutable(scope);
3579 if (cd)
3580 {
3581 addVariableToClass(root, // entry
3582 cd, // class to add member to
3583 MemberType::Friend, // type of member
3584 type, // type value as string
3585 name, // name of the member
3586 args, // arguments as string
3587 Protection::Public, // protection
3588 Relationship::Member // related to a class
3589 );
3590 }
3591 }
3592 if (root->bodyLine!=-1 && root->endBodyLine!=-1) // store the body location for later use
3593 {
3594 Doxygen::staticInitMap.emplace(name.str(),BodyInfo{root->startLine,root->bodyLine,root->endBodyLine});
3595 }
3596
3597
3598 AUTO_TRACE_ADD("static variable {} body=[{}..{}]",name,root->bodyLine,root->endBodyLine);
3599 return; /* skip this member, because it is a
3600 * static variable definition (always?), which will be
3601 * found in a class scope as well, but then we know the
3602 * correct protection level, so only then it will be
3603 * inserted in the correct list!
3604 */
3605 }
3606
3607 MemberType mtype = MemberType::Variable;
3608 if (type=="@")
3609 mtype=MemberType::EnumValue;
3610 else if (type_s.startsWith("typedef "))
3611 mtype=MemberType::Typedef;
3612 else if (type_s.startsWith("friend ") || type_s=="friend")
3613 mtype=MemberType::Friend;
3614 else if (root->mtype==MethodTypes::Property)
3615 mtype=MemberType::Property;
3616 else if (root->mtype==MethodTypes::Event)
3617 mtype=MemberType::Event;
3618 else if (type.find("sequence<") != DString::npos)
3619 mtype=sliceOpt ? MemberType::Sequence : MemberType::Typedef;
3620 else if (type.find("dictionary<") != DString::npos)
3621 mtype=sliceOpt ? MemberType::Dictionary : MemberType::Typedef;
3622
3623 if (!root->relates.empty()) // related variable
3624 {
3625 isRelated=true;
3626 isMemberOf=(root->relatesType==RelatesType::MemberOf);
3627 if (getClass(root->relates)==nullptr && !scope.empty())
3628 scope=mergeScopes(scope,root->relates);
3629 else
3630 scope=root->relates;
3631 }
3632
3633 cd=getClassMutable(scope);
3634 if (cd==nullptr && classScope!=scope) cd=getClassMutable(classScope);
3635 if (cd)
3636 {
3637 Relationship relationship = isMemberOf ? Relationship::Foreign :
3638 isRelated ? Relationship::Related :
3639 Relationship::Member ;
3640
3641 addVariableToClass(root, // entry
3642 cd, // class to add member to
3643 mtype, // member type
3644 type, // type value as string
3645 name, // name of the member
3646 args, // arguments as string
3647 root->protection,
3648 relationship
3649 );
3650
3651 }
3652 else if (!name.empty()) // global variable
3653 {
3654 addVariableToFile(root,mtype,scope,type,name,args);
3655 }
3656
3657}
DString substr(size_t pos=0, size_t count=npos) const
Returns a substring of length count starting at pos.
Definition dstring.h:223
const std::string & str() const
Definition dstring.h:645
bool startsWith(const char *s) const
Definition dstring.h:600
virtual bool isArtificial() const =0
static StaticInitMap staticInitMap
Definition doxygen.h:134
Represents an unstructured piece of information, about an entity found in the sources.
Definition entry.h:115
ClassDef * getClass(const DString &n)
Object representing the matching results.
Definition regex.h:160
static int findFunctionPtr(const std::string &type, SrcLangExt lang, int *pLength=nullptr)
Definition doxygen.cpp:3170
static MemberDef * addVariableToFile(const Entry *root, MemberType mtype, const DString &scope, const DString &type, const DString &name, const DString &args)
Definition doxygen.cpp:2917
static int findEndOfTemplate(const DString &s, size_t startPos)
Definition doxygen.cpp:3373
static MemberDef * addVariableToClass(const Entry *root, ClassDefMutable *cd, MemberType mtype, const DString &type, const DString &name, const DString &args, Protection prot, Relationship related)
Definition doxygen.cpp:2746
bool search(std::string_view str, Match &match, const Ex &re, size_t pos)
Search in a given string str starting at position pos for a match against regular expression re.
Definition regex.cpp:850
Data associated with description found in the body.
Definition definition.h:64
bool isTypeAClassFriend(const DString &type)
Definition types.h:920
int computeQualifiedIndex(const DString &name)
Return the index of the last :: in the string name that is still before the first <.
Definition util.cpp:5309

References addVariableToClass(), addVariableToFile(), Entry::args, AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, buildScopeFromQualifiedName(), computeQualifiedIndex(), Config_getBool, DString::empty(), Entry::endBodyLine, DString::find(), findEndOfTemplate(), findFunctionPtr(), getClass(), getClassMutable(), Definition::getOuterScope(), Doxygen::globalScope, Definition::isArtificial(), EntryType::isScope(), isTypeAClassFriend(), Entry::lang, DString::left(), DString::length(), mangleCSharpGenericName(), mergeScopes(), Entry::mGrpId, DString::mid(), Entry::mtype, Entry::name, DString::npos, Entry::parent(), DString::prepend(), Entry::protection, Entry::relates, Entry::relatesType, removeRedundantWhiteSpace(), reg::search(), Entry::section, DefinitionMutable::setArtificial(), Entry::spec, DString::startsWith(), Doxygen::staticInitMap, DString::str(), stripAnonymousNamespaceScope(), stripTemplateSpecifiersFromScope(), DString::stripWhiteSpace(), DString::substr(), Entry::tagInfo(), Entry::tArgLists, toNamespaceDefMutable(), and Entry::type.

Referenced by buildDictionaryList(), buildSequenceList(), buildTypedefList(), and buildVarList().

◆ addVariableToClass()

MemberDef * addVariableToClass ( const Entry * root,
ClassDefMutable * cd,
MemberType mtype,
const DString & type,
const DString & name,
const DString & args,
Protection prot,
Relationship related )
static

Definition at line 2746 of file doxygen.cpp.

2755{
2757 DString scopeSeparator="::";
2758 SrcLangExt lang = cd->getLanguage();
2759 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
2760 {
2761 qualScope = substitute(qualScope,"::",".");
2762 scopeSeparator=".";
2763 }
2764 AUTO_TRACE("class variable: file='{}' type='{}' scope='{}' name='{}' args='{}' prot={} mtype={} lang={} init='{}'",
2765 root->fileName, type, qualScope, name, args, root->protection, mtype, lang, root->initializer.str());
2766
2767 DString def;
2768 if (!type.empty())
2769 {
2770 if (related!=Relationship::Member || mtype==MemberType::Friend || Config_getBool(HIDE_SCOPE_NAMES))
2771 {
2772 if (root->spec.isAlias()) // turn 'typedef B A' into 'using A'
2773 {
2774 if (lang==SrcLangExt::Python)
2775 {
2776 def="type "+name+args;
2777 }
2778 else
2779 {
2780 def="using "+name;
2781 }
2782 }
2783 else
2784 {
2785 def=type+" "+name+args;
2786 }
2787 }
2788 else
2789 {
2790 if (root->spec.isAlias()) // turn 'typedef B C::A' into 'using C::A'
2791 {
2792 if (lang==SrcLangExt::Python)
2793 {
2794 def="type "+qualScope+scopeSeparator+name+args;
2795 }
2796 else
2797 {
2798 def="using "+qualScope+scopeSeparator+name;
2799 }
2800 }
2801 else
2802 {
2803 def=type+" "+qualScope+scopeSeparator+name+args;
2804 }
2805 }
2806 }
2807 else
2808 {
2809 if (Config_getBool(HIDE_SCOPE_NAMES))
2810 {
2811 def=name+args;
2812 }
2813 else
2814 {
2815 def=qualScope+scopeSeparator+name+args;
2816 }
2817 }
2818 def.stripPrefix("static ");
2819
2820 // see if the member is already found in the same scope
2821 // (this may be the case for a static member that is initialized
2822 // outside the class)
2824 if (mn)
2825 {
2826 for (const auto &imd : *mn)
2827 {
2828 //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n",
2829 // md->getClassDef(),cd,qPrint(type),md->typeString());
2830 MemberDefMutable *md = toMemberDefMutable(imd.get());
2831 if (md &&
2832 md->getClassDef()==cd &&
2833 ((lang==SrcLangExt::Python && type.empty() && !md->typeString().empty()) ||
2835 // member already in the scope
2836 {
2837
2838 if (root->lang==SrcLangExt::ObjC &&
2839 root->mtype==MethodTypes::Property &&
2840 md->memberType()==MemberType::Variable)
2841 { // Objective-C 2.0 property
2842 // turn variable into a property
2843 md->setProtection(root->protection);
2844 cd->reclassifyMember(md,MemberType::Property);
2845 }
2846 addMemberDocs(root,md,def,nullptr,false,root->spec);
2847 AUTO_TRACE_ADD("Member already found!");
2848 return md;
2849 }
2850 }
2851 }
2852
2853 DString fileName = root->fileName;
2854 if (fileName.empty() && root->tagInfo())
2855 {
2856 fileName = root->tagInfo()->tagName;
2857 }
2858
2859 // new member variable, typedef or enum value
2860 auto md = createMemberDef(
2861 fileName,root->startLine,root->startColumn,
2862 type,name,args,root->exception,
2863 prot,Specifier::Normal,root->isStatic,related,
2864 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
2865 ArgumentList(), root->metaData);
2866 auto mmd = toMemberDefMutable(md.get());
2867 mmd->setTagInfo(root->tagInfo());
2868 mmd->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope())
2869 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
2870 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2871 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2872 mmd->setDefinition(def);
2873 mmd->setBitfields(root->bitfields);
2874 mmd->addSectionsToDefinition(root->anchors);
2875 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2876 mmd->setInitializer(root->initializer.str());
2877 mmd->setMaxInitLines(root->initLines);
2878 mmd->setMemberGroupId(root->mGrpId);
2879 mmd->setMemberSpecifiers(root->spec);
2880 mmd->setVhdlSpecifiers(root->vhdlSpec);
2881 mmd->setReadAccessor(root->read);
2882 mmd->setWriteAccessor(root->write);
2884 mmd->setHidden(root->hidden);
2885 mmd->setArtificial(root->artificial);
2886 mmd->setLanguage(root->lang);
2887 mmd->setId(root->id);
2888 addMemberToGroups(root,md.get());
2890 mmd->setBodyDef(root->fileDef());
2891 mmd->addQualifiers(root->qualifiers);
2892 addIncludeFile(mmd,root->fileDef(),root);
2893
2894 AUTO_TRACE_ADD("Adding new member '{}' to class '{}'",name,cd->name());
2895 cd->insertMember(md.get());
2896 mmd->setRefItems(root->sli);
2897 mmd->setRequirementReferences(root->rqli);
2898
2899 cd->insertUsedFile(root->fileDef());
2900 root->markAsProcessed();
2901
2902 if (mtype==MemberType::Typedef)
2903 {
2904 resolveTemplateInstanceInType(root,cd,md.get());
2905 }
2906
2907 // add the member to the global list
2908 MemberDef *result = md.get();
2910 mn->push_back(std::move(md));
2911
2912 return result;
2913}
virtual void reclassifyMember(MemberDefMutable *md, MemberType t)=0
DString bitfields
member's bit fields
Definition entry.h:192
DString write
property write accessor
Definition entry.h:212
DString read
property read accessor
Definition entry.h:211
virtual MemberType memberType() const =0
virtual void setProtection(Protection p)=0
static void resolveTemplateInstanceInType(const Entry *root, const Definition *scope, const MemberDef *md)
Definition doxygen.cpp:5084

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addIncludeFile(), addMemberDocs(), addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::artificial, AUTO_TRACE, AUTO_TRACE_ADD, Entry::bitfields, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), Entry::endBodyLine, Entry::exception, Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), MemberDef::getClassDef(), Definition::getLanguage(), Entry::hidden, Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, Entry::initializer, Entry::initLines, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), Entry::isStatic, Entry::lang, Entry::markAsProcessed(), Doxygen::memberNameLinkedMap, MemberDef::memberType(), Entry::metaData, Entry::mGrpId, Entry::mtype, Definition::name(), Entry::protection, MemberName::push_back(), ClassDef::qualifiedNameWithTemplateParameters(), Entry::qualifiers, Entry::read, ClassDefMutable::reclassifyMember(), removeRedundantWhiteSpace(), resolveTemplateInstanceInType(), Entry::rqli, MemberDefMutable::setProtection(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, TextStream::str(), DString::stripPrefix(), substitute(), Entry::tagInfo(), TagInfo::tagName, Entry::tArgLists, toMemberDefMutable(), MemberDef::typeString(), Entry::vhdlSpec, and Entry::write.

Referenced by addVariable().

◆ addVariableToFile()

MemberDef * addVariableToFile ( const Entry * root,
MemberType mtype,
const DString & scope,
const DString & type,
const DString & name,
const DString & args )
static

Definition at line 2917 of file doxygen.cpp.

2924{
2925 AUTO_TRACE("global variable: file='{}' type='{}' scope='{}' name='{}' args='{}' prot={} mtype={} lang={} init='{}'",
2926 root->fileName, type, scope, name, args, root->protection, mtype, root->lang, root->initializer.str());
2927
2928 FileDef *fd = root->fileDef();
2929
2930 // see if we have a typedef that should hide a struct or union
2931 if (mtype==MemberType::Typedef && Config_getBool(TYPEDEF_HIDES_STRUCT))
2932 {
2933 DString ttype = type;
2934 ttype.stripPrefix("typedef ");
2935 if (ttype.stripPrefix("struct ") || ttype.stripPrefix("union "))
2936 {
2937 static const reg::Ex re(R"(\a\w*)");
2939 const std::string &typ = ttype.str();
2940 if (reg::search(typ,match,re))
2941 {
2942 DString typeValue = match.str();
2943 ClassDefMutable *cd = getClassMutable(typeValue);
2944 if (cd)
2945 {
2946 // this typedef should hide compound name cd, so we
2947 // change the name that is displayed from cd.
2948 cd->setClassName(name);
2949 cd->setDocumentation(root->doc,root->docFile,root->docLine);
2950 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2951 return nullptr;
2952 }
2953 }
2954 }
2955 }
2956
2957 // see if the function is inside a namespace
2958 NamespaceDefMutable *nd = nullptr;
2959 if (!scope.empty())
2960 {
2961 if (scope.find('@')!=DString::npos) return nullptr; // anonymous scope!
2962 nd = getResolvedNamespaceMutable(scope);
2963 }
2964 DString def;
2965
2966 // determine the definition of the global variable
2967 if (nd && !nd->isAnonymous() &&
2968 !Config_getBool(HIDE_SCOPE_NAMES)
2969 )
2970 // variable is inside a namespace, so put the scope before the name
2971 {
2972 SrcLangExt lang = nd->getLanguage();
2974
2975 if (!type.empty())
2976 {
2977 if (root->spec.isAlias()) // turn 'typedef B NS::A' into 'using NS::A'
2978 {
2979 if (lang==SrcLangExt::Python)
2980 {
2981 def="type "+nd->name()+sep+name+args;
2982 }
2983 else
2984 {
2985 def="using "+nd->name()+sep+name;
2986 }
2987 }
2988 else // normal member
2989 {
2990 def=type+" "+nd->name()+sep+name+args;
2991 }
2992 }
2993 else
2994 {
2995 def=nd->name()+sep+name+args;
2996 }
2997 }
2998 else
2999 {
3000 if (!type.empty() && !root->name.empty())
3001 {
3002 if (name.at(0)=='@') // dummy variable representing anonymous union
3003 {
3004 def=type;
3005 }
3006 else
3007 {
3008 if (root->spec.isAlias()) // turn 'typedef B A' into 'using A'
3009 {
3010 if (root->lang==SrcLangExt::Python)
3011 {
3012 def="type "+root->name+args;
3013 }
3014 else
3015 {
3016 def="using "+root->name;
3017 }
3018 }
3019 else // normal member
3020 {
3021 def=type+" "+name+args;
3022 }
3023 }
3024 }
3025 else
3026 {
3027 def=name+args;
3028 }
3029 }
3030 def.stripPrefix("static ");
3031
3033 if (mn)
3034 {
3035 //DString nscope=removeAnonymousScopes(scope);
3036 //NamespaceDef *nd=nullptr;
3037 //if (!nscope.empty())
3038 if (!scope.empty())
3039 {
3040 nd = getResolvedNamespaceMutable(scope);
3041 }
3042 for (const auto &imd : *mn)
3043 {
3044 MemberDefMutable *md = toMemberDefMutable(imd.get());
3045 if (md &&
3046 ((nd==nullptr && md->getNamespaceDef()==nullptr && md->getFileDef() &&
3047 root->fileName==md->getFileDef()->absFilePath()
3048 ) // both variable names in the same file
3049 || (nd!=nullptr && md->getNamespaceDef()==nd) // both in same namespace
3050 )
3051 && !md->isDefine() // function style #define's can be "overloaded" by typedefs or variables
3052 && !md->isEnumerate() // in C# an enum value and enum can have the same name
3053 )
3054 // variable already in the scope
3055 {
3056 bool isPHPArray = md->getLanguage()==SrcLangExt::PHP &&
3057 md->argsString()!=args &&
3058 args.find('[')!=DString::npos;
3059 bool staticsInDifferentFiles =
3060 root->isStatic && md->isStatic() &&
3061 root->fileName!=md->getDefFileName();
3062
3063 if (md->getFileDef() &&
3064 !isPHPArray && // not a php array
3065 !staticsInDifferentFiles
3066 )
3067 // not a php array variable
3068 {
3069 AUTO_TRACE_ADD("variable already found: scope='{}'",md->getOuterScope()->name());
3070 addMemberDocs(root,md,def,nullptr,false,root->spec);
3071 md->setRefItems(root->sli);
3072 md->setRequirementReferences(root->rqli);
3073 // if md is a variable forward declaration and root is the definition that
3074 // turn md into the definition
3075 if (!root->explicitExternal && md->isExternal())
3076 {
3077 md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn());
3078 md->setExplicitExternal(false,root->fileName,root->startLine,root->startColumn);
3079 }
3080 // if md is the definition and root point at a declaration, then add the
3081 // declaration info
3082 else if (root->explicitExternal && !md->isExternal())
3083 {
3084 md->setDeclFile(root->fileName,root->startLine,root->startColumn);
3085 }
3086 return md;
3087 }
3088 }
3089 }
3090 }
3091
3092 DString fileName = root->fileName;
3093 if (fileName.empty() && root->tagInfo())
3094 {
3095 fileName = root->tagInfo()->tagName;
3096 }
3097
3098 AUTO_TRACE_ADD("new variable, namespace='{}'",nd?nd->name():DString("<global>"));
3099 // new global variable, enum value or typedef
3100 auto md = createMemberDef(
3101 fileName,root->startLine,root->startColumn,
3102 type,name,args,DString(),
3103 root->protection, Specifier::Normal,root->isStatic,Relationship::Member,
3104 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
3105 root->argList, root->metaData);
3106 auto mmd = toMemberDefMutable(md.get());
3107 mmd->setTagInfo(root->tagInfo());
3108 mmd->setMemberSpecifiers(root->spec);
3109 mmd->setVhdlSpecifiers(root->vhdlSpec);
3110 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3111 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3112 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3113 mmd->addSectionsToDefinition(root->anchors);
3114 mmd->setInitializer(root->initializer.str());
3115 mmd->setMaxInitLines(root->initLines);
3116 mmd->setMemberGroupId(root->mGrpId);
3117 mmd->setDefinition(def);
3118 mmd->setLanguage(root->lang);
3119 mmd->setId(root->id);
3121 mmd->setExplicitExternal(root->explicitExternal,fileName,root->startLine,root->startColumn);
3122 mmd->addQualifiers(root->qualifiers);
3123 //md->setOuterScope(fd);
3124 if (!root->explicitExternal)
3125 {
3126 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3127 mmd->setBodyDef(fd);
3128 }
3129 addMemberToGroups(root,md.get());
3130 addIncludeFile(mmd,fd,root);
3132
3133 mmd->setRefItems(root->sli);
3134 mmd->setRequirementReferences(root->rqli);
3135 if (nd && !nd->isAnonymous())
3136 {
3137 mmd->setNamespace(nd);
3138 nd->insertMember(md.get());
3139 }
3140
3141 // add member to the file (we do this even if we have already inserted
3142 // it into the namespace.
3143 if (fd)
3144 {
3145 mmd->setFileDef(fd);
3146 fd->insertMember(md.get());
3147 }
3148
3149 root->markAsProcessed();
3150
3151 if (mtype==MemberType::Typedef)
3152 {
3153 resolveTemplateInstanceInType(root,nd,md.get());
3154 }
3155
3156 // add member definition to the list of globals
3157 MemberDef *result = md.get();
3159 mn->push_back(std::move(md));
3160
3161
3162
3163 return result;
3164}
virtual void setClassName(const DString &name)=0
virtual size_t getDefColumn() const =0
virtual bool isExternal() const =0
virtual bool isDefine() const =0
virtual void setExplicitExternal(bool b, const DString &df, int line, size_t column)=0
virtual void setDeclFile(const DString &df, int line, size_t column)=0

References FileDef::absFilePath(), LinkedMap< T, Hash, KeyEqual, Map >::add(), addIncludeFile(), addMemberDocs(), addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, MemberDef::argsString(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), Entry::endBodyLine, Entry::explicitExternal, Entry::fileDef(), Entry::fileName, DString::find(), LinkedMap< T, Hash, KeyEqual, Map >::find(), Doxygen::functionNameLinkedMap, getClassMutable(), Definition::getDefColumn(), Definition::getDefFileName(), Definition::getDefLine(), MemberDef::getFileDef(), Definition::getLanguage(), getLanguageSpecificSeparator(), MemberDef::getNamespaceDef(), Definition::getOuterScope(), getResolvedNamespaceMutable(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, Entry::initializer, Entry::initLines, FileDef::insertMember(), NamespaceDefMutable::insertMember(), ModuleManager::instance(), Definition::isAnonymous(), MemberDef::isDefine(), MemberDef::isEnumerate(), MemberDef::isExternal(), Entry::isStatic, MemberDef::isStatic(), Entry::lang, Entry::markAsProcessed(), Entry::metaData, Entry::mGrpId, Definition::name(), Entry::name, DString::npos, Entry::protection, MemberName::push_back(), Entry::qualifiers, resolveTemplateInstanceInType(), Entry::rqli, reg::search(), DefinitionMutable::setBriefDescription(), ClassDefMutable::setClassName(), MemberDefMutable::setDeclFile(), DefinitionMutable::setDocumentation(), MemberDefMutable::setExplicitExternal(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, DString::str(), TextStream::str(), DString::stripPrefix(), Entry::tagInfo(), TagInfo::tagName, Entry::tArgLists, toMemberDefMutable(), and Entry::vhdlSpec.

Referenced by addVariable().

◆ adjustConfiguration()

void adjustConfiguration ( )

adjust globals that depend on configuration settings.

Definition at line 12250 of file doxygen.cpp.

12251{
12252 AUTO_TRACE();
12253 Doxygen::globalNamespaceDef = createNamespaceDef("<globalScope>",1,1,"<globalScope>");
12264
12265 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
12266
12267 /* Set the global html file extension. */
12268 Doxygen::htmlFileExtension = Config_getString(HTML_FILE_EXTENSION);
12269
12270
12272 Config_getBool(CALLER_GRAPH) ||
12273 Config_getBool(REFERENCES_RELATION) ||
12274 Config_getBool(REFERENCED_BY_RELATION);
12275
12276 /**************************************************************************
12277 * Add custom extension mappings
12278 **************************************************************************/
12279
12280 StringVector extMaps = Config_getList(EXTENSION_MAPPING);
12281 for (const auto &mapping : extMaps)
12282 {
12283 DString mapStr = mapping;
12284 if (size_t i=mapStr.find('='); i==DString::npos)
12285 {
12286 continue;
12287 }
12288 else
12289 {
12290 DString ext = mapStr.left(i).stripWhiteSpace().lower();
12291 DString language = mapStr.mid(i+1).stripWhiteSpace().lower();
12292 if (ext.empty() || language.empty())
12293 {
12294 continue;
12295 }
12296
12297 if (!updateLanguageMapping(ext,language))
12298 {
12299 err("Failed to map file extension '{}' to unsupported language '{}'.\n"
12300 "Check the EXTENSION_MAPPING setting in the config file.\n",
12301 ext,language);
12302 }
12303 else
12304 {
12305 msg("Adding custom extension mapping: '{}' will be treated as language '{}'\n",
12306 ext,language);
12307 }
12308 }
12309 }
12310 // create input file exncodings
12311
12312 // check INPUT_ENCODING
12313 void *cd = portable_iconv_open("UTF-8",Config_getString(INPUT_ENCODING).data());
12314 if (cd==reinterpret_cast<void *>(-1))
12315 {
12316 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
12317 "Check the 'INPUT_ENCODING' setting in the config file!\n",
12318 Config_getString(INPUT_ENCODING),strerror(errno));
12319 }
12320 else
12321 {
12323 }
12324
12325 // check and split INPUT_FILE_ENCODING
12326 StringVector fileEncod = Config_getList(INPUT_FILE_ENCODING);
12327 for (const auto &mapping : fileEncod)
12328 {
12329 DString mapStr = mapping;
12330 if (size_t i=mapStr.find('='); i==DString::npos)
12331 {
12332 continue;
12333 }
12334 else
12335 {
12336 DString pattern = mapStr.left(i).stripWhiteSpace().lower();
12337 DString encoding = mapStr.mid(i+1).stripWhiteSpace().lower();
12338 if (pattern.empty() || encoding.empty())
12339 {
12340 continue;
12341 }
12342 cd = portable_iconv_open("UTF-8",encoding.data());
12343 if (cd==reinterpret_cast<void *>(-1))
12344 {
12345 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
12346 "Check the 'INPUT_FILE_ENCODING' setting in the config file!\n",
12347 encoding,strerror(errno));
12348 }
12349 else
12350 {
12352 }
12353
12354 Doxygen::inputFileEncodingList.emplace_back(pattern, encoding);
12355 }
12356 }
12357
12358 // add predefined macro name to a dictionary
12359 StringVector expandAsDefinedList = Config_getList(EXPAND_AS_DEFINED);
12360 for (const auto &s : expandAsDefinedList)
12361 {
12363 }
12364
12365 // read aliases and store them in a dictionary
12366 readAliases();
12367
12368 // store number of spaces in a tab into Doxygen::spaces
12369 int tabSize = Config_getInt(TAB_SIZE);
12370 Doxygen::spaces.resize(tabSize);
12371 for (int sp=0; sp<tabSize; sp++) Doxygen::spaces.at(sp)=' ';
12372 Doxygen::spaces.at(tabSize)='\0';
12373}
void readAliases()
Definition aliases.cpp:162
void resize(size_t newlen)
Definition dstring.h:209
DString lower() const
Definition dstring.h:326
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition dstring.h:157
static FileNameLinkedMap * plantUmlFileNameLinkedMap
Definition doxygen.h:102
static StringUnorderedSet expandAsDefinedSet
Definition doxygen.h:112
static InputFileEncodingList inputFileEncodingList
Definition doxygen.h:131
static FileNameLinkedMap * dotFileNameLinkedMap
Definition doxygen.h:99
static FileNameLinkedMap * imageNameLinkedMap
Definition doxygen.h:98
static FileNameLinkedMap * mscFileNameLinkedMap
Definition doxygen.h:100
static FileNameLinkedMap * mermaidFileNameLinkedMap
Definition doxygen.h:103
static FileNameLinkedMap * diaFileNameLinkedMap
Definition doxygen.h:101
static DString spaces
Definition doxygen.h:126
static std::unique_ptr< NamespaceDef > globalNamespaceDef
Definition doxygen.h:113
static DString htmlFileExtension
Definition doxygen.h:115
static FileNameLinkedMap * includeNameLinkedMap
Definition doxygen.h:94
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:95
Ordered dictionary of FileName objects.
Definition filename.h:70
#define Config_getInt(name)
Definition config.h:34
#define Config_getString(name)
Definition config.h:32
#define Config_getEnum(name)
Definition config.h:35
std::vector< std::string > StringVector
Definition containers.h:33
void setTranslator(OUTPUT_LANGUAGE_t langName)
Definition language.cpp:78
#define msg(fmt,...)
Definition message.h:94
#define err(fmt,...)
Definition message.h:127
#define term(fmt,...)
Definition message.h:137
std::unique_ptr< NamespaceDef > createNamespaceDef(const DString &defFileName, int defLine, size_t defColumn, const DString &name, const DString &ref, const DString &refFile, const DString &type, bool isPublished)
Factory method to create new NamespaceDef instance.
int portable_iconv_close(void *cd)
void * portable_iconv_open(const char *tocode, const char *fromcode)
bool updateLanguageMapping(const DString &extension, const DString &language)
Definition util.cpp:4069

References DString::at(), AUTO_TRACE, Config_getBool, Config_getEnum, Config_getInt, Config_getList, Config_getString, createNamespaceDef(), DString::data(), Doxygen::diaFileNameLinkedMap, Doxygen::dotFileNameLinkedMap, DString::empty(), err, Doxygen::exampleNameLinkedMap, Doxygen::expandAsDefinedSet, DString::find(), Doxygen::globalNamespaceDef, Doxygen::globalScope, Doxygen::htmlFileExtension, Doxygen::imageNameLinkedMap, Doxygen::includeNameLinkedMap, Doxygen::inputFileEncodingList, Doxygen::inputNameLinkedMap, DString::left(), DString::lower(), Doxygen::mermaidFileNameLinkedMap, DString::mid(), Doxygen::mscFileNameLinkedMap, msg, DString::npos, Doxygen::parseSourcesNeeded, Doxygen::plantUmlFileNameLinkedMap, portable_iconv_close(), portable_iconv_open(), readAliases(), DString::resize(), setTranslator(), Doxygen::spaces, DString::stripWhiteSpace(), term, toNamespaceDefMutable(), and updateLanguageMapping().

Referenced by main().

◆ applyMemberOverrideOptions()

void applyMemberOverrideOptions ( const Entry * root,
MemberDefMutable * md )
static

Definition at line 2418 of file doxygen.cpp.

2419{
2420 root->commandOverrides.apply_callGraph ([&](bool b) { md->overrideCallGraph(b); });
2421 root->commandOverrides.apply_callerGraph ([&](bool b) { md->overrideCallerGraph(b); });
2422 root->commandOverrides.apply_referencedByRelation([&](bool b) { md->overrideReferencedByRelation(b); });
2423 root->commandOverrides.apply_referencesRelation ([&](bool b) { md->overrideReferencesRelation(b); });
2424 root->commandOverrides.apply_inlineSource ([&](bool b) { md->overrideInlineSource(b); });
2425 root->commandOverrides.apply_enumValues ([&](bool b) { md->overrideEnumValues(b); });
2426}
virtual void overrideReferencesRelation(bool e)=0
virtual void overrideReferencedByRelation(bool e)=0
virtual void overrideCallGraph(bool e)=0
virtual void overrideInlineSource(bool e)=0
virtual void overrideEnumValues(bool e)=0
virtual void overrideCallerGraph(bool e)=0

References Entry::commandOverrides, MemberDefMutable::overrideCallerGraph(), MemberDefMutable::overrideCallGraph(), MemberDefMutable::overrideEnumValues(), MemberDefMutable::overrideInlineSource(), MemberDefMutable::overrideReferencedByRelation(), and MemberDefMutable::overrideReferencesRelation().

Referenced by addDefineDoc(), addGlobalFunction(), addInterfaceOrServiceToServiceOrSingleton(), addLocalObjCMethod(), addMemberDocs(), addMemberSpecialization(), addMethodToClass(), addOverloaded(), addVariableToClass(), addVariableToFile(), buildFunctionList(), createUsingMemberImportForClass(), findEnums(), findMember(), and findUsingDeclImports().

◆ applyToAllDefinitions()

template<typename Func>
void applyToAllDefinitions ( Func func)
static

Definition at line 5752 of file doxygen.cpp.

5753{
5754 for (const auto &cd : *Doxygen::classLinkedMap)
5755 {
5756 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5757 if (cdm)
5758 {
5759 func(cdm);
5760 }
5761 }
5762
5763 for (const auto &cd : *Doxygen::conceptLinkedMap)
5764 {
5765 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
5766 if (cdm)
5767 {
5768 func(cdm);
5769 }
5770 }
5771
5772 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5773 {
5774 for (const auto &fd : *fn)
5775 {
5776 func(fd.get());
5777 }
5778 }
5779
5780 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5781 {
5783 if (ndm)
5784 {
5785 func(ndm);
5786 }
5787 }
5788
5789 for (const auto &gd : *Doxygen::groupLinkedMap)
5790 {
5791 func(gd.get());
5792 }
5793
5794 for (const auto &pd : *Doxygen::pageLinkedMap)
5795 {
5796 func(pd.get());
5797 }
5798
5799 for (const auto &dd : *Doxygen::dirLinkedMap)
5800 {
5801 func(dd.get());
5802 }
5803
5804 func(&ModuleManager::instance());
5805}
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:120

References Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Doxygen::dirLinkedMap, Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, toClassDefMutable(), toConceptDefMutable(), and toNamespaceDefMutable().

Referenced by addListReferences(), and addRequirementReferences().

◆ associateVariableWithAnonymousEnumType()

template<typename Container>
void associateVariableWithAnonymousEnumType ( const MemberDef * md,
const Container * cd,
const MemberDef * enumTypeMember,
MemberListType mlFilter )
static

Definition at line 1545 of file doxygen.cpp.

1549{
1550 if (md && md->isEnumerate() && md->name().startsWith("@")) // anonymous enum type
1551 {
1552 MemberList *eiml = cd->getMemberList(mlFilter);
1553 if (eiml)
1554 {
1555 for (const auto &eimd : *eiml)
1556 {
1557 DString vtype = eimd->typeString();
1558 if (vtype.find(md->name())!=DString::npos)
1559 {
1561 if (mimd)
1562 {
1563 mimd->setAnonymousEnumType(enumTypeMember);
1564 break;
1565 }
1566 }
1567 }
1568 }
1569 }
1570}
virtual void setAnonymousEnumType(const MemberDef *md)=0
A list of MemberDef objects as shown in documentation sections.
Definition memberlist.h:126

References DString::find(), MemberDef::isEnumerate(), Definition::name(), DString::npos, MemberDefMutable::setAnonymousEnumType(), DString::startsWith(), and toMemberDefMutable().

Referenced by createTagLessInstance(), and processTagLessClassesForList().

◆ buildClassDocList()

void buildClassDocList ( const Entry * root)
static

Definition at line 1161 of file doxygen.cpp.

1162{
1163 if ((root->section.isCompoundDoc()) && !root->name.empty())
1164 {
1165 AUTO_TRACE();
1166 addClassToContext(root);
1167 }
1168 for (const auto &e : root->children()) buildClassDocList(e.get());
1169}
constexpr bool isCompoundDoc() const noexcept
Definition types.h:866
static void addClassToContext(const Entry *root)
Definition doxygen.cpp:950
static void buildClassDocList(const Entry *root)
Definition doxygen.cpp:1161

References addClassToContext(), AUTO_TRACE, buildClassDocList(), Entry::children(), DString::empty(), EntryType::isCompoundDoc(), Entry::name, and Entry::section.

Referenced by buildClassDocList(), and parseInput().

◆ buildClassList()

void buildClassList ( const Entry * root)
static

Definition at line 1151 of file doxygen.cpp.

1152{
1153 if ((root->section.isCompound() || root->section.isObjcImpl()) && !root->name.empty())
1154 {
1155 AUTO_TRACE();
1156 addClassToContext(root);
1157 }
1158 for (const auto &e : root->children()) buildClassList(e.get());
1159}
static void buildClassList(const Entry *root)
Definition doxygen.cpp:1151

References addClassToContext(), AUTO_TRACE, buildClassList(), Entry::children(), DString::empty(), EntryType::isCompound(), Entry::name, and Entry::section.

Referenced by buildClassList(), and parseInput().

◆ buildCompleteMemberLists()

void buildCompleteMemberLists ( )
static

Definition at line 8863 of file doxygen.cpp.

8864{
8865 // merge the member list of base classes into the inherited classes.
8866 for (const auto &cd : *Doxygen::classLinkedMap)
8867 {
8868 if (// !cd->isReference() && // not an external class
8869 cd->subClasses().empty() && // is a root of the hierarchy
8870 !cd->baseClasses().empty()) // and has at least one base class
8871 {
8872 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8873 if (cdm)
8874 {
8875 //printf("*** merging members for %s\n",qPrint(cd->name()));
8876 cdm->mergeMembers();
8877 }
8878 }
8879 }
8880 // now sort the member list of all members for all classes.
8881 for (const auto &cd : *Doxygen::classLinkedMap)
8882 {
8883 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8884 if (cdm)
8885 {
8886 cdm->sortAllMembersList();
8887 }
8888 }
8889}
virtual void sortAllMembersList()=0
virtual void mergeMembers()=0

References Doxygen::classLinkedMap, ClassDefMutable::mergeMembers(), ClassDefMutable::sortAllMembersList(), and toClassDefMutable().

Referenced by parseInput().

◆ buildConceptDocList()

void buildConceptDocList ( const Entry * root)
static

Definition at line 1346 of file doxygen.cpp.

1347{
1348 if (root->section.isConceptDoc())
1349 {
1350 AUTO_TRACE();
1351 addConceptToContext(root);
1352 }
1353 for (const auto &e : root->children()) buildConceptDocList(e.get());
1354}
static void addConceptToContext(const Entry *root)
Definition doxygen.cpp:1175
static void buildConceptDocList(const Entry *root)
Definition doxygen.cpp:1346

References addConceptToContext(), AUTO_TRACE, buildConceptDocList(), Entry::children(), and Entry::section.

Referenced by buildConceptDocList(), and parseInput().

◆ buildConceptList()

void buildConceptList ( const Entry * root)
static

Definition at line 1336 of file doxygen.cpp.

1337{
1338 if (root->section.isConcept())
1339 {
1340 AUTO_TRACE();
1341 addConceptToContext(root);
1342 }
1343 for (const auto &e : root->children()) buildConceptList(e.get());
1344}
static void buildConceptList(const Entry *root)
Definition doxygen.cpp:1336

References addConceptToContext(), AUTO_TRACE, buildConceptList(), Entry::children(), and Entry::section.

Referenced by buildConceptList(), and parseInput().

◆ buildDefineList()

void buildDefineList ( )
static

Definition at line 9198 of file doxygen.cpp.

9199{
9200 AUTO_TRACE();
9201 for (const auto &s : g_inputFiles)
9202 {
9203 auto it = Doxygen::macroDefinitions.find(s);
9205 {
9206 for (const auto &def : it->second)
9207 {
9208 auto md = createMemberDef(
9209 def.fileName,def.lineNr,def.columnNr,
9210 "#define",def.name,def.args,DString(),
9211 Protection::Public,Specifier::Normal,false,Relationship::Member,MemberType::Define,
9212 ArgumentList(),ArgumentList(),"");
9213 auto mmd = toMemberDefMutable(md.get());
9214
9215 if (!def.args.empty())
9216 {
9217 mmd->moveArgumentList(stringToArgumentList(SrcLangExt::Cpp, def.args));
9218 }
9219 mmd->setInitializer(def.definition);
9220 mmd->setFileDef(def.fileDef);
9221 mmd->setDefinition("#define "+def.name);
9222
9224 if (def.fileDef)
9225 {
9226 const MemberList *defMl = def.fileDef->getMemberList(MemberListType::DocDefineMembers());
9227 if (defMl)
9228 {
9229 const MemberDef *defMd = defMl->findRev(def.name);
9230 if (defMd) // definition already stored
9231 {
9232 mmd->setRedefineCount(defMd->redefineCount()+1);
9233 }
9234 }
9235 def.fileDef->insertMember(md.get());
9236 }
9237 AUTO_TRACE_ADD("adding macro {} with definition {}",def.name,def.definition);
9238 mn->push_back(std::move(md));
9239 }
9240 }
9241 }
9242}
static DefinesPerFileList macroDefinitions
Definition doxygen.h:128
virtual int redefineCount() const =0
const MemberDef * findRev(const DString &name) const
Definition memberlist.h:107
static StringVector g_inputFiles
Definition doxygen.cpp:191

References LinkedMap< T, Hash, KeyEqual, Map >::add(), AUTO_TRACE, AUTO_TRACE_ADD, createMemberDef(), end(), MemberVector::findRev(), Doxygen::functionNameLinkedMap, g_inputFiles, Doxygen::macroDefinitions, MemberName::push_back(), MemberDef::redefineCount(), stringToArgumentList(), and toMemberDefMutable().

Referenced by parseInput().

◆ buildDictionaryList()

void buildDictionaryList ( const Entry * root)
static

Definition at line 3780 of file doxygen.cpp.

3781{
3782 if (!root->name.empty() &&
3783 root->section.isVariable() &&
3784 root->type.find("dictionary<")!=DString::npos // it's a dictionary
3785 )
3786 {
3787 AUTO_TRACE();
3788 addVariable(root);
3789 }
3790 for (const auto &e : root->children())
3791 if (!e->section.isEnum())
3792 buildDictionaryList(e.get());
3793}
static void buildDictionaryList(const Entry *root)
Definition doxygen.cpp:3780
static void addVariable(const Entry *root, int isFuncPtr=-1)
Definition doxygen.cpp:3441

References addVariable(), AUTO_TRACE, buildDictionaryList(), Entry::children(), DString::empty(), DString::find(), Entry::name, DString::npos, Entry::section, and Entry::type.

Referenced by buildDictionaryList(), and parseInput().

◆ buildExampleList()

void buildExampleList ( Entry * root)
static

Definition at line 10252 of file doxygen.cpp.

10253{
10254 if ((root->section.isExample() || root->section.isExampleLineno()) && !root->name.empty())
10255 {
10256 if (Doxygen::exampleLinkedMap->find(root->name))
10257 {
10258 warn(root->fileName,root->startLine,"Example {} was already documented. Ignoring documentation found here.",root->name);
10259 }
10260 else
10261 {
10263 createPageDef(root->fileName,root->startLine,
10264 root->name,root->brief+root->doc+root->inbodyDocs,root->args));
10265 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
10266 pd->setFileName(convertNameToFile(pd->name()+"-example",false,true));
10268 pd->setLanguage(root->lang);
10269 pd->setShowLineNo(root->section.isExampleLineno());
10270
10271 //we don't add example to groups
10272 //addExampleToGroups(root,pd);
10273 }
10274 }
10275 for (const auto &e : root->children()) buildExampleList(e.get());
10276}
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:91
virtual void setFileName(const DString &name)=0
virtual void setShowLineNo(bool)=0
static void buildExampleList(Entry *root)
std::unique_ptr< PageDef > createPageDef(const DString &f, int l, const DString &n, const DString &d, const DString &t)
Definition pagedef.cpp:89
DString convertNameToFile(const DString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:2869

References LinkedMap< T, Hash, KeyEqual, Map >::add(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, Entry::args, Entry::brief, Entry::briefFile, Entry::briefLine, buildExampleList(), Entry::children(), convertNameToFile(), createPageDef(), Entry::doc, DString::empty(), Doxygen::exampleLinkedMap, Entry::fileName, Entry::inbodyDocs, Entry::lang, Definition::name(), Entry::name, Entry::section, DefinitionMutable::setBriefDescription(), PageDef::setFileName(), DefinitionMutable::setLanguage(), PageDef::setShowLineNo(), Entry::startLine, and warn.

Referenced by buildExampleList(), and parseInput().

◆ buildFileList()

void buildFileList ( const Entry * root)
static

Definition at line 611 of file doxygen.cpp.

612{
613 if ((root->section.isFileDoc() || (root->section.isFile() && Config_getBool(EXTRACT_ALL))) &&
614 !root->name.empty() && !root->tagInfo() // skip any file coming from tag files
615 )
616 {
617 bool ambig = false;
619 if (!fd || ambig)
620 {
621 bool save_ambig = ambig;
622 // use the directory of the file to see if the described file is in the same
623 // directory as the describing file.
624 DString fn = root->fileName;
625 size_t newIndex=fn.rfind('/');
626 if (newIndex==DString::npos)
627 {
628 fn = root->name;
629 }
630 else
631 {
632 fn = fn.left(newIndex)+"/"+root->name;
633 }
635 if (!fd) ambig = save_ambig;
636 }
637 //printf("**************** root->name=%s fd=%p\n",qPrint(root->name),(void*)fd);
638 if (fd && !ambig)
639 {
640 //printf("Adding documentation!\n");
641 // using false in setDocumentation is small hack to make sure a file
642 // is documented even if a \file command is used without further
643 // documentation
644 fd->setDocumentation(root->doc,root->docFile,root->docLine,false);
645 fd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
647 fd->setRefItems(root->sli);
649 addIncludeFile(fd,fd,root);
650 root->commandOverrides.apply_includeGraph ([&](bool b) { fd->overrideIncludeGraph(b); });
651 root->commandOverrides.apply_includedByGraph([&](bool b) { fd->overrideIncludedByGraph(b); });
652 for (const Grouping &g : root->groups)
653 {
654 GroupDef *gd=nullptr;
656 {
657 if (!gd->containsFile(fd))
658 {
659 gd->addFile(fd);
660 fd->makePartOfGroup(gd);
661 //printf("File %s: in group %s\n",qPrint(fd->name()),qPrint(gd->name()));
662 }
663 }
664 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
665 {
666 warn(root->fileName, root->startLine,
667 "Found non-existing group '{}' for the command '{}', ignoring command",
669 );
670 }
671 }
672 }
673 else
674 {
675 DString text(4096, DString::ExplicitSize);
676 text.sprintf("the name '%s' supplied as "
677 "the argument in the \\file statement ",
678 qPrint(root->name));
679 if (ambig) // name is ambiguous
680 {
681 text+="matches the following input files:\n";
683 text+="\n";
684 text+="Please use a more specific name by "
685 "including a (larger) part of the path!";
686 }
687 else // name is not an input file
688 {
689 text+="is not an input file";
690 }
691 warn(root->fileName,root->startLine,"{}", text);
692 }
693 }
694 for (const auto &e : root->children()) buildFileList(e.get());
695}
@ ExplicitSize
Definition dstring.h:131
virtual void makePartOfGroup(GroupDef *gd)=0
constexpr bool isFile() const noexcept
Definition types.h:865
virtual void overrideIncludeGraph(bool e)=0
virtual void overrideIncludedByGraph(bool e)=0
virtual bool containsFile(const FileDef *def) const =0
virtual void addFile(FileDef *def)=0
static void buildFileList(const Entry *root)
Definition doxygen.cpp:611
static constexpr const char * getGroupPriName(GroupPri_t priority) noexcept
Definition types.h:240
@ GROUPING_INGROUP
membership in group was defined by @ingroup
Definition types.h:236
GroupPri_t pri
priority of this definition
Definition types.h:258

References GroupDef::addFile(), addIncludeFile(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, Entry::brief, Entry::briefFile, Entry::briefLine, buildFileList(), Entry::children(), Entry::commandOverrides, Config_getBool, GroupDef::containsFile(), Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), DString::ExplicitSize, Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), FileNameLinkedMap::findFileDef(), Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, Doxygen::inputNameLinkedMap, EntryType::isFile(), DString::left(), DefinitionMutable::makePartOfGroup(), Entry::name, DString::npos, FileDef::overrideIncludedByGraph(), FileDef::overrideIncludeGraph(), Grouping::pri, qPrint(), DString::rfind(), Entry::rqli, Entry::section, DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), FileNameLinkedMap::showFileDefMatches(), Entry::sli, DString::sprintf(), Entry::startLine, Entry::tagInfo(), and warn.

Referenced by buildFileList(), and parseInput().

◆ buildFunctionList()

void buildFunctionList ( const Entry * root)
static

Definition at line 4194 of file doxygen.cpp.

4195{
4196 if (root->section.isFunction())
4197 {
4198 AUTO_TRACE("member function: type='{}' scope='{}' name='{}' args='{}' relates='{}' relatesType='{}'"
4199 " file='{}' line={} bodyLine={} #tArgLists={} mGrpId={}"
4200 " spec={} proto={} docFile='{}'",
4201 root->type, root->parent()->name, root->name, root->args, root->relates, root->relatesType,
4202 root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(), root->mGrpId,
4203 root->spec, root->proto, root->docFile);
4204
4205 bool isFriend=root->type=="friend" || root->type.find("friend ")!=DString::npos;
4206 DString rname = removeRedundantWhiteSpace(root->name);
4207 //printf("rname=%s\n",qPrint(rname));
4208
4209 DString scope;
4210 int index = computeQualifiedIndex(rname);
4211 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
4212 // grouped members are stored with full scope
4213 {
4214 buildScopeFromQualifiedName(rname.left(index+2),root->lang,root->tagInfo());
4215 scope=rname.left(index);
4216 rname=rname.mid(index+2);
4217 }
4218 else
4219 {
4220 scope=root->parent()->name; //stripAnonymousNamespaceScope(root->parent->name);
4221 }
4222 if (!rname.empty() && scope.find('@')==DString::npos)
4223 {
4224 // check if this function's parent is a class
4225 if (root->lang==SrcLangExt::CSharp)
4226 {
4227 scope=mangleCSharpGenericName(scope);
4228 }
4229 else
4230 {
4231 scope=stripTemplateSpecifiersFromScope(scope,false);
4232 }
4233
4234 FileDef *rfd=root->fileDef();
4235
4236 size_t memIndex=rname.rfind("::");
4237
4239 if (cd && scope+"::"==rname.left(scope.length()+2)) // found A::f inside A
4240 {
4241 // strip scope from name
4242 rname=rname.mid(root->parent()->name.length()+2);
4243 }
4244
4245 bool isMember=false;
4246 if (memIndex!=DString::npos)
4247 {
4248 size_t ts=rname.find('<');
4249 size_t te=rname.find('>');
4250 if (memIndex>0 && (ts==DString::npos || te==DString::npos))
4251 {
4252 // note: the following code was replaced by inMember=true to deal with a
4253 // function rname='X::foo' of class X inside a namespace also called X...
4254 // bug id 548175
4255 //nd = Doxygen::namespaceLinkedMap->find(rname.left(memIndex));
4256 //isMember = nd==nullptr;
4257 //if (nd)
4258 //{
4259 // // strip namespace scope from name
4260 // scope=rname.left(memIndex);
4261 // rname=rname.mid(memIndex+2);
4262 //}
4263 isMember = true;
4264 }
4265 else
4266 {
4267 isMember=memIndex<ts || memIndex>te;
4268 }
4269 }
4270
4271 if (!root->parent()->name.empty() && root->parent()->section.isCompound() && cd)
4272 {
4273 AUTO_TRACE_ADD("member '{}' of class '{}'", rname,cd->name());
4274 addMethodToClass(root,cd,root->type,rname,root->args,isFriend,
4275 root->protection,root->isStatic,root->virt,root->spec,root->relates);
4276 }
4277 else if (root->parent()->section.isObjcImpl() && cd)
4278 {
4279 const MemberDef *md = cd->getMemberByName(rname);
4280 if (md)
4281 {
4282 MemberDefMutable *mdm = toMemberDefMutable(const_cast<MemberDef*>(md));
4283 if (mdm)
4284 {
4285 mdm->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
4286 mdm->setBodyDef(root->fileDef());
4287 }
4288 }
4289 }
4290 else if (!root->parent()->section.isCompound() && !root->parent()->section.isObjcImpl() &&
4291 !isMember &&
4292 (root->relates.empty() || root->relatesType==RelatesType::Duplicate) &&
4293 !root->type.startsWith("extern ") && !root->type.startsWith("typedef ")
4294 )
4295 // no member => unrelated function
4296 {
4297 /* check the uniqueness of the function name in the file.
4298 * A file could contain a function prototype and a function definition
4299 * or even multiple function prototypes.
4300 */
4301 bool found=false;
4302 MemberDef *md_found=nullptr;
4304 if (mn)
4305 {
4306 AUTO_TRACE_ADD("function '{}' already found",rname);
4307 for (const auto &imd : *mn)
4308 {
4309 MemberDefMutable *md = toMemberDefMutable(imd.get());
4310 if (md)
4311 {
4312 const NamespaceDef *mnd = md->getNamespaceDef();
4313 NamespaceDef *rnd = nullptr;
4314 //printf("root namespace=%s\n",qPrint(rootNav->parent()->name()));
4315 DString fullScope = scope;
4316 DString parentScope = root->parent()->name;
4317 if (!parentScope.empty() && !leftScopeMatch(parentScope,scope))
4318 {
4319 if (!scope.empty()) fullScope.prepend("::");
4320 fullScope.prepend(parentScope);
4321 }
4322 //printf("fullScope=%s\n",qPrint(fullScope));
4323 rnd = getResolvedNamespace(fullScope);
4324 const FileDef *mfd = md->getFileDef();
4325 DString nsName,rnsName;
4326 if (mnd) nsName = mnd->name();
4327 if (rnd) rnsName = rnd->name();
4328 //printf("matching arguments for %s%s %s%s\n",
4329 // qPrint(md->name()),md->argsString(),qPrint(rname),qPrint(argListToString(root->argList)));
4330 const ArgumentList &mdAl = md->argumentList();
4331 const ArgumentList &mdTempl = md->templateArguments();
4332
4333 // in case of template functions, we need to check if the
4334 // functions have the same number of template parameters
4335 bool sameTemplateArgs = true;
4336 bool matchingReturnTypes = true;
4337 bool sameRequiresClause = true;
4338 if (!mdTempl.empty() && !root->tArgLists.empty())
4339 {
4340 sameTemplateArgs = matchTemplateArguments(mdTempl,root->tArgLists.back());
4341 if (md->typeString()!=removeRedundantWhiteSpace(root->type))
4342 {
4343 matchingReturnTypes = false;
4344 }
4345 if (md->requiresClause()!=root->req)
4346 {
4347 sameRequiresClause = false;
4348 }
4349 }
4350 else if (!mdTempl.empty() || !root->tArgLists.empty())
4351 { // if one has template parameters and the other doesn't then that also counts as a
4352 // difference
4353 sameTemplateArgs = false;
4354 }
4355
4356 bool staticsInDifferentFiles =
4357 root->isStatic && md->isStatic() && root->fileName!=md->getDefFileName();
4358
4359 if (sameTemplateArgs &&
4360 matchingReturnTypes &&
4361 sameRequiresClause &&
4362 !staticsInDifferentFiles &&
4363 matchArguments2(md->getOuterScope(),mfd,md->typeString(),&mdAl,
4364 rnd ? rnd : Doxygen::globalScope,rfd,root->type,&root->argList,
4365 false,root->lang)
4366 )
4367 {
4368 GroupDef *gd=nullptr;
4369 if (!root->groups.empty() && !root->groups.front().groupname.empty())
4370 {
4371 gd = Doxygen::groupLinkedMap->find(root->groups.front().groupname);
4372 }
4373 //printf("match!\n");
4374 //printf("mnd=%p rnd=%p nsName=%s rnsName=%s\n",mnd,rnd,qPrint(nsName),qPrint(rnsName));
4375 // see if we need to create a new member
4376 found=(mnd && rnd && nsName==rnsName) || // members are in the same namespace
4377 ((mnd==nullptr && rnd==nullptr && mfd!=nullptr && // no external reference and
4378 mfd->absFilePath()==root->fileName // prototype in the same file
4379 )
4380 );
4381 // otherwise, allow a duplicate global member with the same argument list
4382 if (!found && gd && gd==md->getGroupDef() && nsName==rnsName)
4383 {
4384 // member is already in the group, so we don't want to add it again.
4385 found=true;
4386 }
4387
4388 AUTO_TRACE_ADD("combining function with prototype found={} in namespace '{}'",found,nsName);
4389
4390 if (found)
4391 {
4392 // merge argument lists
4393 ArgumentList mergedArgList = root->argList;
4394 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.empty());
4395 // merge documentation
4396 if (md->documentation().empty() && !root->doc.empty())
4397 {
4398 if (root->proto)
4399 {
4401 }
4402 else
4403 {
4405 }
4406 }
4407
4408 md->setDocumentation(root->doc,root->docFile,root->docLine);
4410 md->setDocsForDefinition(!root->proto);
4411 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
4412 {
4413 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
4414 md->setBodyDef(rfd);
4415 }
4416
4417 if (md->briefDescription().empty() && !root->brief.empty())
4418 {
4419 md->setArgsString(root->args);
4420 }
4421 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
4422
4424
4426 md->addQualifiers(root->qualifiers);
4427
4428 // merge ingroup specifiers
4429 if (md->getGroupDef()==nullptr && !root->groups.empty())
4430 {
4431 addMemberToGroups(root,md);
4432 }
4433 else if (md->getGroupDef()!=nullptr && root->groups.empty())
4434 {
4435 //printf("existing member is grouped, new member not\n");
4436 }
4437 else if (md->getGroupDef()!=nullptr && !root->groups.empty())
4438 {
4439 //printf("both members are grouped\n");
4440 }
4442
4443 // if md is a declaration and root is the corresponding
4444 // definition, then turn md into a definition.
4445 if (md->isPrototype() && !root->proto)
4446 {
4447 md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn());
4448 md->setPrototype(false,root->fileName,root->startLine,root->startColumn);
4449 }
4450 // if md is already the definition, then add the declaration info
4451 else if (!md->isPrototype() && root->proto)
4452 {
4453 md->setDeclFile(root->fileName,root->startLine,root->startColumn);
4454 }
4455 }
4456 }
4457 }
4458 if (found)
4459 {
4460 md_found = md;
4461 break;
4462 }
4463 }
4464 }
4465 if (!found) /* global function is unique with respect to the file */
4466 {
4467 addGlobalFunction(root,rname,scope);
4468 }
4469 else
4470 {
4471 FileDef *fd=root->fileDef();
4472 if (fd)
4473 {
4474 // add member to the file (we do this even if we have already
4475 // inserted it into the namespace)
4476 fd->insertMember(md_found);
4477 }
4478 }
4479
4480 AUTO_TRACE_ADD("unrelated function type='{}' name='{}' args='{}'",root->type,rname,root->args);
4481 }
4482 else
4483 {
4484 AUTO_TRACE_ADD("function '{}' is not processed",rname);
4485 }
4486 }
4487 else if (rname.empty())
4488 {
4489 warn(root->fileName,root->startLine,
4490 "Illegal member name found."
4491 );
4492 }
4493 }
4494 for (const auto &e : root->children()) buildFunctionList(e.get());
4495}
virtual const MemberDef * getMemberByName(const DString &) const =0
Returns the member with the given name.
virtual DString briefDescription(bool abbreviate=false) const =0
virtual DString documentation() const =0
virtual bool isPrototype() const =0
virtual void setArgsString(const DString &as)=0
virtual void setPrototype(bool p, const DString &df, int line, size_t column)=0
virtual void moveDeclArgumentList(std::unique_ptr< ArgumentList > al)=0
static void buildFunctionList(const Entry *root)
Definition doxygen.cpp:4194
static void addGlobalFunction(const Entry *root, const DString &rname, const DString &sc)
Definition doxygen.cpp:4084
bool matchTemplateArguments(const ArgumentList &srcAl, const ArgumentList &dstAl)
Definition util.cpp:1838

References FileDef::absFilePath(), addGlobalFunction(), addMemberToGroups(), ModuleManager::addMemberToModule(), addMethodToClass(), MemberDefMutable::addQualifiers(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, Entry::args, MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Definition::briefDescription(), Entry::briefFile, Entry::briefLine, buildFunctionList(), buildScopeFromQualifiedName(), Entry::children(), computeQualifiedIndex(), Entry::doc, Entry::docFile, Entry::docLine, Definition::documentation(), ArgumentList::empty(), DString::empty(), Entry::endBodyLine, Entry::fileDef(), Entry::fileName, DString::find(), LinkedMap< T, Hash, KeyEqual, Map >::find(), Doxygen::functionNameLinkedMap, getClassMutable(), Definition::getDefColumn(), Definition::getDefFileName(), Definition::getDefLine(), MemberDef::getFileDef(), MemberDef::getGroupDef(), ClassDef::getMemberByName(), MemberDef::getNamespaceDef(), Definition::getOuterScope(), getResolvedNamespace(), Definition::getStartBodyLine(), Doxygen::globalScope, Doxygen::groupLinkedMap, Entry::groups, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, FileDef::insertMember(), ModuleManager::instance(), EntryType::isCompound(), MemberDef::isPrototype(), Entry::isStatic, MemberDef::isStatic(), Entry::lang, DString::left(), leftScopeMatch(), DString::length(), mangleCSharpGenericName(), matchArguments2(), matchTemplateArguments(), mergeArguments(), Entry::mGrpId, DString::mid(), MemberDefMutable::moveArgumentList(), MemberDefMutable::moveDeclArgumentList(), Definition::name(), Entry::name, DString::npos, Entry::parent(), DString::prepend(), Entry::protection, Entry::proto, Entry::qualifiers, Entry::relates, Entry::relatesType, removeRedundantWhiteSpace(), Entry::req, MemberDef::requiresClause(), DString::rfind(), Entry::section, MemberDefMutable::setArgsString(), DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), MemberDefMutable::setDeclFile(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setPrototype(), Entry::spec, Entry::startColumn, Entry::startLine, DString::startsWith(), stringToArgumentList(), stripTemplateSpecifiersFromScope(), Entry::tagInfo(), Entry::tArgLists, MemberDef::templateArguments(), toMemberDefMutable(), Entry::type, MemberDef::typeString(), Entry::virt, and warn.

Referenced by buildFunctionList(), and parseInput().

◆ buildGroupList()

void buildGroupList ( const Entry * root)
static

Definition at line 540 of file doxygen.cpp.

541{
542 // --- first process only local groups
543 // first process the @defgroups blocks
544 buildGroupListFiltered(root,false,false);
545 // then process the @addtogroup, @weakgroup blocks
546 buildGroupListFiltered(root,true,false);
547
548 // --- then also process external groups
549 // first process the @defgroups blocks
550 buildGroupListFiltered(root,false,true);
551 // then process the @addtogroup, @weakgroup blocks
552 buildGroupListFiltered(root,true,true);
553}
static void buildGroupListFiltered(const Entry *root, bool additional, bool includeExternal)
Definition doxygen.cpp:467

References buildGroupListFiltered().

Referenced by parseInput().

◆ buildGroupListFiltered()

void buildGroupListFiltered ( const Entry * root,
bool additional,
bool includeExternal )
static

Definition at line 467 of file doxygen.cpp.

468{
469 if (root->section.isGroupDoc() && !root->name.empty() &&
470 ((!includeExternal && root->tagInfo()==nullptr) ||
471 ( includeExternal && root->tagInfo()!=nullptr))
472 )
473 {
474 AUTO_TRACE("additional={} includeExternal={}",additional,includeExternal);
475 if ((root->groupDocType==Entry::GROUPDOC_NORMAL && !additional) ||
476 (root->groupDocType!=Entry::GROUPDOC_NORMAL && additional))
477 {
479 AUTO_TRACE_ADD("Processing group '{}':'{}' gd={}", root->type,root->name,(void*)gd);
480
481 if (gd)
482 {
483 if ( !gd->hasGroupTitle() )
484 {
485 gd->setGroupTitle( root->type );
486 }
487 else if ( root->type.length() > 0 && root->name != root->type && gd->groupTitle() != root->type )
488 {
489 warn( root->fileName,root->startLine,
490 "group {}: ignoring title \"{}\" that does not match old title \"{}\"",
491 root->name, root->type, gd->groupTitle() );
492 }
493 gd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
494 gd->setDocumentation( root->doc, root->docFile, root->docLine );
495 gd->setInbodyDocumentation( root->inbodyDocs, root->inbodyFile, root->inbodyLine );
497 gd->setRefItems(root->sli);
499 gd->setLanguage(root->lang);
501 {
502 root->commandOverrides.apply_groupGraph([&](bool b) { gd->overrideGroupGraph(b); });
503 }
504 addIncludeFile(gd,nullptr,root);
505 }
506 else
507 {
508 if (root->tagInfo())
509 {
510 gd = Doxygen::groupLinkedMap->add(root->name,
511 std::unique_ptr<GroupDef>(
512 createGroupDef(root->fileName,root->startLine,root->name,root->type,root->tagInfo()->fileName)));
513 gd->setReference(root->tagInfo()->tagName);
514 }
515 else
516 {
517 gd = Doxygen::groupLinkedMap->add(root->name,
518 std::unique_ptr<GroupDef>(
519 createGroupDef(root->fileName,root->startLine,root->name,root->type)));
520 }
521 gd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
522 // allow empty docs for group
523 gd->setDocumentation(!root->doc.empty() ? root->doc : DString(" "),root->docFile,root->docLine,false);
524 gd->setInbodyDocumentation( root->inbodyDocs, root->inbodyFile, root->inbodyLine );
526 gd->setRefItems(root->sli);
528 gd->setLanguage(root->lang);
529 addIncludeFile(gd,nullptr,root);
531 {
532 root->commandOverrides.apply_groupGraph([&](bool b) { gd->overrideGroupGraph(b); });
533 }
534 }
535 }
536 }
537 for (const auto &e : root->children()) buildGroupListFiltered(e.get(),additional,includeExternal);
538}
virtual void setReference(const DString &r)=0
GroupDocType groupDocType
Definition entry.h:231
@ GROUPDOC_NORMAL
defgroup
Definition entry.h:120
virtual DString groupTitle() const =0
virtual void overrideGroupGraph(bool e)=0
virtual void setGroupTitle(const DString &newtitle)=0
virtual bool hasGroupTitle() const =0
std::unique_ptr< GroupDef > createGroupDef(const DString &fileName, int line, const DString &name, const DString &title, const DString &refFileName)
Definition groupdef.cpp:184

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addIncludeFile(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, AUTO_TRACE, AUTO_TRACE_ADD, Entry::brief, Entry::briefFile, Entry::briefLine, buildGroupListFiltered(), Entry::children(), Entry::commandOverrides, createGroupDef(), Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), Entry::fileName, TagInfo::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), Entry::GROUPDOC_NORMAL, Entry::groupDocType, Doxygen::groupLinkedMap, GroupDef::groupTitle(), GroupDef::hasGroupTitle(), Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, Entry::lang, DString::length(), Entry::name, GroupDef::overrideGroupGraph(), Entry::rqli, Entry::section, DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), GroupDef::setGroupTitle(), DefinitionMutable::setInbodyDocumentation(), DefinitionMutable::setLanguage(), DefinitionMutable::setReference(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), Entry::sli, Entry::startLine, Entry::tagInfo(), TagInfo::tagName, Entry::type, and warn.

Referenced by buildGroupList(), and buildGroupListFiltered().

◆ buildInterfaceAndServiceList()

void buildInterfaceAndServiceList ( const Entry * root)
static

Definition at line 3895 of file doxygen.cpp.

3896{
3897 if (root->section.isExportedInterface() || root->section.isIncludedService())
3898 {
3899 AUTO_TRACE("Exported interface/included service: type='{}' scope='{}' name='{}' args='{}'"
3900 " relates='{}' relatesType='{}' file='{}' line={} bodyLine={} #tArgLists={}"
3901 " mGrpId={} spec={} proto={} docFile='{}'",
3902 root->type, root->parent()->name, root->name, root->args,
3903 root->relates, root->relatesType, root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(),
3904 root->mGrpId, root->spec, root->proto, root->docFile);
3905
3906 DString rname = removeRedundantWhiteSpace(root->name);
3907
3908 if (!rname.empty())
3909 {
3910 DString scope = root->parent()->name;
3911 ClassDefMutable *cd = getClassMutable(scope);
3912 ASSERT(cd);
3913 if (cd && ((ClassDef::Interface == cd->compoundType()) ||
3914 (ClassDef::Service == cd->compoundType()) ||
3916 {
3918 }
3919 else
3920 {
3921 ASSERT(false); // was checked by scanner.l
3922 }
3923 }
3924 else if (rname.empty())
3925 {
3926 warn(root->fileName,root->startLine,
3927 "Illegal member name found.");
3928 }
3929 }
3930 // can only have these in IDL anyway
3931 switch (root->lang)
3932 {
3933 case SrcLangExt::Unknown: // fall through (root node always is Unknown)
3934 case SrcLangExt::IDL:
3935 for (const auto &e : root->children()) buildInterfaceAndServiceList(e.get());
3936 break;
3937 default:
3938 return; // nothing to do here
3939 }
3940}
@ Singleton
Definition classdef.h:113
@ Interface
Definition classdef.h:108
virtual CompoundType compoundType() const =0
Returns the type of compound this is, i.e. class/struct/union/...
static void addInterfaceOrServiceToServiceOrSingleton(const Entry *root, ClassDefMutable *cd, DString const &rname)
Definition doxygen.cpp:3831
static void buildInterfaceAndServiceList(const Entry *root)
Definition doxygen.cpp:3895
#define ASSERT(x)
Definition message.h:142

References addInterfaceOrServiceToServiceOrSingleton(), Entry::args, ASSERT, AUTO_TRACE, Entry::bodyLine, buildInterfaceAndServiceList(), Entry::children(), ClassDef::compoundType(), Entry::docFile, DString::empty(), Entry::fileName, getClassMutable(), ClassDef::Interface, Entry::lang, Entry::mGrpId, Entry::name, Entry::parent(), Entry::proto, Entry::relates, Entry::relatesType, removeRedundantWhiteSpace(), Entry::section, ClassDef::Service, ClassDef::Singleton, Entry::spec, Entry::startLine, Entry::tArgLists, Entry::type, and warn.

Referenced by buildInterfaceAndServiceList(), and parseInput().

◆ buildListOfUsingDecls()

void buildListOfUsingDecls ( const Entry * root)
static

Definition at line 2313 of file doxygen.cpp.

2314{
2315 if (root->section.isUsingDecl() &&
2316 !root->parent()->section.isCompound() // not a class/struct member
2317 )
2318 {
2319 DString name = substitute(root->name,".","::");
2320 g_usingDeclarations.insert(name.str());
2321 }
2322 for (const auto &e : root->children()) buildListOfUsingDecls(e.get());
2323}
static StringSet g_usingDeclarations
Definition doxygen.cpp:193
static void buildListOfUsingDecls(const Entry *root)
Definition doxygen.cpp:2313

References buildListOfUsingDecls(), Entry::children(), g_usingDeclarations, EntryType::isCompound(), Entry::name, Entry::parent(), Entry::section, and substitute().

Referenced by buildListOfUsingDecls(), and parseInput().

◆ buildNamespaceList()

void buildNamespaceList ( const Entry * root)
static

Definition at line 1985 of file doxygen.cpp.

1986{
1987 if (
1988 (root->section.isNamespace() ||
1989 root->section.isNamespaceDoc() ||
1990 root->section.isPackageDoc()
1991 ) &&
1992 !root->name.empty()
1993 )
1994 {
1995 AUTO_TRACE("name={}",root->name);
1996
1997 DString fName = root->name;
1998 if (root->section.isPackageDoc())
1999 {
2000 fName=substitute(fName,".","::");
2001 }
2002
2003 DString fullName = stripAnonymousNamespaceScope(fName);
2004 if (!fullName.empty())
2005 {
2006 AUTO_TRACE_ADD("Found namespace {} in {} at line {}",root->name,root->fileName,root->startLine);
2008 if (ndi) // existing namespace
2009 {
2011 if (nd) // non-inline namespace
2012 {
2013 AUTO_TRACE_ADD("Existing namespace");
2014 nd->setDocumentation(root->doc,root->docFile,root->docLine);
2015 nd->setName(fullName); // change name to match docs
2017 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2018 if (nd->getLanguage()==SrcLangExt::Unknown)
2019 {
2020 nd->setLanguage(root->lang);
2021 }
2022 if (root->tagInfo()==nullptr && nd->isReference() && !(root->doc.empty() && root->brief.empty()))
2023 // if we previously found namespace nd in a tag file and now we find a
2024 // documented namespace with the same name in the project, then remove
2025 // the tag file reference
2026 {
2027 nd->setReference("");
2028 nd->setFileName(fullName);
2029 }
2030 nd->setMetaData(root->metaData);
2031
2032 // file definition containing the namespace nd
2033 FileDef *fd=root->fileDef();
2034 if (nd->isArtificial())
2035 {
2036 nd->setArtificial(false); // found namespace explicitly, so cannot be artificial
2037 nd->setDefFile(root->fileName,root->startLine,root->startColumn);
2038 }
2039 // insert the namespace in the file definition
2040 if (fd) fd->insertNamespace(nd);
2041 addNamespaceToGroups(root,nd);
2042 nd->setRefItems(root->sli);
2043 nd->setRequirementReferences(root->rqli);
2044 addIncludeFile(nd,fd,root);
2045 }
2046 }
2047 else // fresh namespace
2048 {
2049 DString tagName;
2050 DString tagFileName;
2051 const TagInfo *tagInfo = root->tagInfo();
2052 if (tagInfo)
2053 {
2054 tagName = tagInfo->tagName;
2055 tagFileName = tagInfo->fileName;
2056 }
2057 AUTO_TRACE_ADD("new namespace {} lang={} tagName={}",fullName,root->lang,tagName);
2058 // add namespace to the list
2060 Doxygen::namespaceLinkedMap->add(fullName,
2061 createNamespaceDef(tagInfo?tagName:root->fileName,root->startLine,
2062 root->startColumn,fullName,tagName,tagFileName,
2063 root->type,root->spec.isPublished())));
2064 if (nd)
2065 {
2066 nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
2067 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2069 nd->setHidden(root->hidden);
2070 nd->setArtificial(root->artificial);
2071 nd->setLanguage(root->lang);
2072 nd->setId(root->id);
2073 nd->setMetaData(root->metaData);
2074 nd->setInline(root->spec.isInline());
2075 nd->setExported(root->exported);
2076
2077 addNamespaceToGroups(root,nd);
2078 nd->setRefItems(root->sli);
2079 nd->setRequirementReferences(root->rqli);
2080
2081 // file definition containing the namespace nd
2082 FileDef *fd=root->fileDef();
2083 // insert the namespace in the file definition
2084 if (fd) fd->insertNamespace(nd);
2085
2086 // the empty string test is needed for extract all case
2087 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2088 nd->insertUsedFile(fd);
2089 nd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2090 nd->setBodyDef(fd);
2091 addIncludeFile(nd,fd,root);
2092
2093 // also add namespace to the correct structural context
2094 Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName,nullptr,tagInfo);
2095 AUTO_TRACE_ADD("adding namespace {} to context {}",nd->name(),d ? d->name() : DString("<none>"));
2096 if (d==nullptr) // we didn't find anything, create the scope artificially
2097 // anyway, so we can at least relate scopes properly.
2098 {
2099 d = buildScopeFromQualifiedName(fullName,nd->getLanguage(),tagInfo);
2101 if (dm)
2102 {
2103 dm->addInnerCompound(nd);
2104 }
2105 nd->setOuterScope(d);
2106 // TODO: Due to the order in which the tag file is written
2107 // a nested class can be found before its parent!
2108 }
2109 else
2110 {
2112 if (dm)
2113 {
2114 dm->addInnerCompound(nd);
2115 }
2116 nd->setOuterScope(d);
2117 // in case of d is an inline namespace, alias insert nd in the part scope of d.
2119 {
2120 NamespaceDef *pnd = toNamespaceDef(d);
2121 if (pnd && pnd->isInline())
2122 {
2123 d = d->getOuterScope();
2124 if (d)
2125 {
2126 dm = toDefinitionMutable(d);
2127 if (dm)
2128 {
2129 auto aliasNd = createNamespaceDefAlias(d,nd);
2130 dm->addInnerCompound(aliasNd.get());
2131 DString aliasName = aliasNd->name();
2132 AUTO_TRACE_ADD("adding alias {} to {}",aliasName,d->name());
2133 Doxygen::namespaceLinkedMap->add(aliasName,std::move(aliasNd));
2134 }
2135 }
2136 else
2137 {
2138 break;
2139 }
2140 }
2141 else
2142 {
2143 break;
2144 }
2145 }
2146 }
2147 }
2148 }
2149 }
2150 }
2151 for (const auto &e : root->children()) buildNamespaceList(e.get());
2152}
virtual bool isReference() const =0
virtual void setName(const DString &name)=0
virtual void setExported(bool b)=0
bool exported
is the symbol exported from a C++20 module
Definition entry.h:188
virtual void insertNamespace(NamespaceDef *nd)=0
virtual bool isInline() const =0
virtual void insertUsedFile(FileDef *fd)=0
virtual void setFileName(const DString &fn)=0
virtual void setMetaData(const DString &m)=0
virtual void setInline(bool isInline)=0
static void buildNamespaceList(const Entry *root)
Definition doxygen.cpp:1985
void addNamespaceToGroups(const Entry *root, NamespaceDef *nd)
std::unique_ptr< NamespaceDef > createNamespaceDefAlias(const Definition *newScope, const NamespaceDef *nd)
Factory method to create an alias of an existing namespace.
NamespaceDef * toNamespaceDef(Definition *d)

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addIncludeFile(), DefinitionMutable::addInnerCompound(), addNamespaceToGroups(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, Entry::artificial, AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, buildNamespaceList(), buildScopeFromQualifiedName(), Entry::children(), createNamespaceDef(), createNamespaceDefAlias(), Definition::definitionType(), Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), Entry::endBodyLine, Entry::exported, Entry::fileDef(), Entry::fileName, TagInfo::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), findScopeFromQualifiedName(), Definition::getLanguage(), Definition::getOuterScope(), Doxygen::globalScope, Entry::hidden, Entry::id, FileDef::insertNamespace(), NamespaceDefMutable::insertUsedFile(), Definition::isArtificial(), NamespaceDef::isInline(), Definition::isReference(), Entry::lang, Entry::metaData, Definition::name(), Entry::name, Doxygen::namespaceLinkedMap, Entry::rqli, Entry::section, DefinitionMutable::setArtificial(), DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), DefinitionMutable::setDefFile(), DefinitionMutable::setDocumentation(), DefinitionMutable::setExported(), NamespaceDefMutable::setFileName(), DefinitionMutable::setHidden(), DefinitionMutable::setId(), NamespaceDefMutable::setInline(), DefinitionMutable::setLanguage(), NamespaceDefMutable::setMetaData(), DefinitionMutable::setName(), DefinitionMutable::setOuterScope(), DefinitionMutable::setReference(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, stripAnonymousNamespaceScope(), substitute(), Entry::tagInfo(), TagInfo::tagName, toDefinitionMutable(), toNamespaceDef(), toNamespaceDefMutable(), Entry::type, and Definition::TypeNamespace.

Referenced by buildNamespaceList(), and parseInput().

◆ buildPageList()

void buildPageList ( Entry * root)
static

Definition at line 10008 of file doxygen.cpp.

10009{
10010 if (root->section.isPageDoc())
10011 {
10012 if (!root->name.empty())
10013 {
10014 addRelatedPage(root);
10015 }
10016 }
10017 else if (root->section.isMainpageDoc())
10018 {
10019 DString title=root->args.stripWhiteSpace();
10020 if (title.empty()) title=theTranslator->trMainPage();
10021 //DString name = Config_getBool(GENERATE_TREEVIEW)?"main":"index";
10022 DString name = "index";
10023 addRefItem(root->sli,
10024 name,
10025 theTranslator->trPage(true,true),
10026 name,
10027 title,
10028 DString(),nullptr
10029 );
10030 }
10031 for (const auto &e : root->children()) buildPageList(e.get());
10032}
virtual DString trPage(bool first_capital, bool singular)=0
virtual DString trMainPage()=0
static void buildPageList(Entry *root)
void addRefItem(const RefItemVector &sli, const DString &key, const DString &prefix, const DString &name, const DString &title, const DString &args, const Definition *scope)
Definition reflist.h:136

References addRefItem(), addRelatedPage(), Entry::args, buildPageList(), Entry::children(), DString::empty(), Entry::name, Entry::section, Entry::sli, DString::stripWhiteSpace(), theTranslator, Translator::trMainPage(), and Translator::trPage().

Referenced by buildPageList(), and parseInput().

◆ buildRequirementsList()

void buildRequirementsList ( Entry * root)
static

Definition at line 9996 of file doxygen.cpp.

9997{
9998 if (root->section.isRequirementDoc())
9999 {
10001 }
10002 for (const auto &e : root->children()) buildRequirementsList(e.get());
10003}
static RequirementManager & instance()
void addRequirement(Entry *e)
static void buildRequirementsList(Entry *root)
Definition doxygen.cpp:9996

References RequirementManager::addRequirement(), buildRequirementsList(), Entry::children(), RequirementManager::instance(), and Entry::section.

Referenced by buildRequirementsList(), and parseInput().

◆ buildScopeFromQualifiedName()

Definition * buildScopeFromQualifiedName ( const DString & name_,
SrcLangExt lang,
const TagInfo * tagInfo )
static

returns the Definition object belonging to the first level levels of full qualified name name. Creates an artificial scope if the scope is not found and set the parent/child scope relation if the scope is found.

Definition at line 724 of file doxygen.cpp.

725{
727 name.stripPrefix("::");
728 int level = name.contains("::");
729 //printf("buildScopeFromQualifiedName(%s) level=%d\n",qPrint(name),level);
730 int i=0, p=0, l=0;
732 DString fullScope;
733 while (i<level)
734 {
735 int idx=getScopeFragment(name,p,&l);
736 if (idx==-1) return prevScope;
737 DString nsName = name.mid(idx,l);
738 if (nsName.empty()) return prevScope;
739 if (!fullScope.empty()) fullScope+="::";
740 fullScope+=nsName;
742 DefinitionMutable *innerScope = toDefinitionMutable(nd);
743 ClassDef *cd=nullptr;
744 if (nd==nullptr) cd = getClass(fullScope);
745 if (nd==nullptr && cd) // scope is a class
746 {
747 innerScope = toDefinitionMutable(cd);
748 }
749 else if (nd==nullptr && cd==nullptr && fullScope.find('<')==DString::npos) // scope is not known and could be a namespace!
750 {
751 // introduce bogus namespace
752 //printf("++ adding dummy namespace %s to %s tagInfo=%p\n",qPrint(nsName),qPrint(prevScope->name()),(void*)tagInfo);
753 NamespaceDefMutable *newNd=
755 Doxygen::namespaceLinkedMap->add(fullScope,
757 "[generated]",1,1,fullScope,
758 tagInfo?tagInfo->tagName:DString(),
759 tagInfo?tagInfo->fileName:DString())));
760 if (newNd)
761 {
762 newNd->setLanguage(lang);
763 newNd->setArtificial(true);
764 // add namespace to the list
765 innerScope = newNd;
766 }
767 }
768 else // scope is a namespace
769 {
770 }
771 if (innerScope)
772 {
773 // make the parent/child scope relation
774 DefinitionMutable *prevScopeMutable = toDefinitionMutable(prevScope);
775 if (prevScopeMutable)
776 {
777 prevScopeMutable->addInnerCompound(toDefinition(innerScope));
778 }
779 innerScope->setOuterScope(prevScope);
780 }
781 else // current scope is a class, so return only the namespace part...
782 {
783 return prevScope;
784 }
785 // proceed to the next scope fragment
786 p=idx+l+2;
787 prevScope=toDefinition(innerScope);
788 i++;
789 }
790 return prevScope;
791}
Definition * toDefinition(DefinitionMutable *dm)
DString stripTemplateSpecifiers(const DString &s)
Definition doxygen.cpp:697
int getScopeFragment(const DString &s, int p, int *l)
Definition util.cpp:3804

References DefinitionMutable::addInnerCompound(), createNamespaceDef(), DString::empty(), TagInfo::fileName, DString::find(), LinkedMap< T, Hash, KeyEqual, Map >::find(), getClass(), getScopeFragment(), Doxygen::globalScope, Doxygen::namespaceLinkedMap, DString::npos, DefinitionMutable::setArtificial(), DefinitionMutable::setLanguage(), DefinitionMutable::setOuterScope(), stripTemplateSpecifiers(), TagInfo::tagName, toDefinition(), toDefinitionMutable(), and toNamespaceDefMutable().

Referenced by addClassToContext(), addConceptToContext(), addEnumValuesToEnums(), addVariable(), buildFunctionList(), buildNamespaceList(), buildTypedefList(), findClassRelation(), findEnums(), findScopeFromQualifiedName(), and resolveClassNestingRelations().

◆ buildSequenceList()

void buildSequenceList ( const Entry * root)
static

Definition at line 3762 of file doxygen.cpp.

3763{
3764 if (!root->name.empty() &&
3765 root->section.isVariable() &&
3766 root->type.find("sequence<")!=DString::npos // it's a sequence
3767 )
3768 {
3769 AUTO_TRACE();
3770 addVariable(root);
3771 }
3772 for (const auto &e : root->children())
3773 if (!e->section.isEnum())
3774 buildSequenceList(e.get());
3775}
static void buildSequenceList(const Entry *root)
Definition doxygen.cpp:3762

References addVariable(), AUTO_TRACE, buildSequenceList(), Entry::children(), DString::empty(), DString::find(), Entry::name, DString::npos, Entry::section, and Entry::type.

Referenced by buildSequenceList(), and parseInput().

◆ buildTypedefList()

void buildTypedefList ( const Entry * root)
static

Definition at line 3662 of file doxygen.cpp.

3663{
3664 //printf("buildVarList(%s)\n",qPrint(rootNav->name()));
3665 if (!root->name.empty() &&
3666 root->section.isVariable() &&
3667 root->type.find("typedef ")!=DString::npos // its a typedef
3668 )
3669 {
3670 AUTO_TRACE();
3671 DString rname = removeRedundantWhiteSpace(root->name);
3672 DString scope;
3673 int index = computeQualifiedIndex(rname);
3674 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
3675 // grouped members are stored with full scope
3676 {
3677 buildScopeFromQualifiedName(rname.left(index+2),root->lang,root->tagInfo());
3678 scope=rname.left(index);
3679 rname=rname.mid(index+2);
3680 }
3681 else
3682 {
3683 scope=root->parent()->name; //stripAnonymousNamespaceScope(root->parent->name);
3684 }
3688 bool found=false;
3689 if (mn) // symbol with the same name already found
3690 {
3691 for (auto &imd : *mn)
3692 {
3693 if (!imd->isTypedef())
3694 continue;
3695
3696 DString rtype = root->type;
3697 rtype.stripPrefix("typedef ");
3698
3699 // merge the typedefs only if they're not both grouped, and both are
3700 // either part of the same class, part of the same namespace, or both
3701 // are global (i.e., neither in a class or a namespace)
3702 bool notBothGrouped = root->groups.empty() || imd->getGroupDef()==nullptr; // see example #100
3703 bool bothSameScope = (!cd && !nd) || (cd && imd->getClassDef() == cd) || (nd && imd->getNamespaceDef() == nd);
3704 //printf("imd->isTypedef()=%d imd->typeString()=%s root->type=%s\n",imd->isTypedef(),
3705 // qPrint(imd->typeString()),qPrint(root->type));
3706 if (notBothGrouped && bothSameScope && imd->typeString()==rtype)
3707 {
3708 MemberDefMutable *md = toMemberDefMutable(imd.get());
3709 if (md)
3710 {
3711 md->setDocumentation(root->doc,root->docFile,root->docLine);
3713 md->setDocsForDefinition(!root->proto);
3714 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3716 md->setRefItems(root->sli);
3717 md->setRequirementReferences(root->rqli);
3718 md->addQualifiers(root->qualifiers);
3719
3720 // merge ingroup specifiers
3721 if (md->getGroupDef()==nullptr && !root->groups.empty())
3722 {
3723 addMemberToGroups(root,md);
3724 }
3725 else if (md->getGroupDef()!=nullptr && root->groups.empty())
3726 {
3727 //printf("existing member is grouped, new member not\n");
3728 }
3729 else if (md->getGroupDef()!=nullptr && !root->groups.empty())
3730 {
3731 //printf("both members are grouped\n");
3732 }
3733 found=true;
3734 break;
3735 }
3736 }
3737 }
3738 }
3739 if (found)
3740 {
3741 AUTO_TRACE_ADD("typedef '{}' already found",rname);
3742 // mark the entry as processed, as we copied everything from it elsewhere
3743 // also, otherwise, due to containing `typedef` it may later get treated
3744 // as a function typedef in filterMemberDocumentation, which is incorrect
3745 root->markAsProcessed();
3746 }
3747 else
3748 {
3749 AUTO_TRACE_ADD("new typedef '{}'",rname);
3750 addVariable(root);
3751 }
3752
3753 }
3754 for (const auto &e : root->children())
3755 if (!e->section.isEnum())
3756 buildTypedefList(e.get());
3757}
static void buildTypedefList(const Entry *root)
Definition doxygen.cpp:3662

References addMemberToGroups(), MemberDefMutable::addQualifiers(), DefinitionMutable::addSectionsToDefinition(), addVariable(), Entry::anchors, AUTO_TRACE, AUTO_TRACE_ADD, Entry::brief, Entry::briefFile, Entry::briefLine, buildScopeFromQualifiedName(), buildTypedefList(), Entry::children(), computeQualifiedIndex(), Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), DString::find(), LinkedMap< T, Hash, KeyEqual, Map >::find(), Doxygen::functionNameLinkedMap, getClassMutable(), MemberDef::getGroupDef(), getResolvedNamespace(), Entry::groups, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, Entry::lang, DString::left(), Entry::markAsProcessed(), DString::mid(), Entry::name, DString::npos, Entry::parent(), Entry::proto, Entry::qualifiers, removeRedundantWhiteSpace(), Entry::rqli, Entry::section, DefinitionMutable::setBriefDescription(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setInbodyDocumentation(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), Entry::sli, DString::stripPrefix(), Entry::tagInfo(), toMemberDefMutable(), and Entry::type.

Referenced by buildTypedefList(), and parseInput().

◆ buildVarList()

void buildVarList ( const Entry * root)
static

Definition at line 3799 of file doxygen.cpp.

3800{
3801 //printf("buildVarList(%s) section=%08x\n",qPrint(rootNav->name()),rootNav->section());
3802 int isFuncPtr=-1;
3803 if (!root->name.empty() &&
3804 (root->type.empty() || g_compoundKeywords.find(root->type.str())==g_compoundKeywords.end()) &&
3805 (
3806 (root->section.isVariable() && // it's a variable
3807 root->type.find("typedef ")==DString::npos // and not a typedef
3808 ) ||
3809 (root->section.isFunction() && // or maybe a function pointer variable
3810 (isFuncPtr=findFunctionPtr(root->type.str(),root->lang))!=-1
3811 ) ||
3812 (root->section.isFunction() && // class variable initialized by constructor
3814 )
3815 )
3816 ) // documented variable
3817 {
3818 AUTO_TRACE();
3819 addVariable(root,isFuncPtr);
3820 }
3821 for (const auto &e : root->children())
3822 if (!e->section.isEnum())
3823 buildVarList(e.get());
3824}
static void buildVarList(const Entry *root)
Definition doxygen.cpp:3799
static bool isVarWithConstructor(const Entry *root)
Definition doxygen.cpp:3230
static const StringUnorderedSet g_compoundKeywords
Definition doxygen.cpp:202

References addVariable(), AUTO_TRACE, buildVarList(), Entry::children(), DString::empty(), DString::find(), findFunctionPtr(), g_compoundKeywords, isVarWithConstructor(), Entry::lang, Entry::name, DString::npos, Entry::section, DString::str(), and Entry::type.

Referenced by buildVarList(), and parseInput().

◆ checkConfiguration()

void checkConfiguration ( )

check and resolve config options

Definition at line 12239 of file doxygen.cpp.

12240{
12241 AUTO_TRACE();
12242
12243 Config::postProcess(false);
12247}
void initWarningFormat()
Definition message.cpp:233
void postProcess(bool clearHeaderAndFooter, CompareMode compareMode=CompareMode::Full)
void checkAndCorrect(bool quiet, const bool check)
void updateObsolete()

References AUTO_TRACE, Config::checkAndCorrect(), Config_getBool, initWarningFormat(), Config::postProcess(), and Config::updateObsolete().

Referenced by main().

◆ checkMarkdownMainfile()

void checkMarkdownMainfile ( )
static

Definition at line 12741 of file doxygen.cpp.

12742{
12743 if (Config_getBool(MARKDOWN_SUPPORT))
12744 {
12745 DString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
12746 if (mdfileAsMainPage.empty()) return;
12747 FileInfo fi(mdfileAsMainPage.data());
12748 if (!fi.exists())
12749 {
12750 warn_uncond("Specified markdown mainpage '{}' does not exist\n",mdfileAsMainPage);
12751 return;
12752 }
12753 bool ambig = false;
12754 if (Doxygen::inputNameLinkedMap->findFileDef(fi.absFilePath(),ambig)==nullptr)
12755 {
12756 warn_uncond("Specified markdown mainpage '{}' has not been defined as input file\n",mdfileAsMainPage);
12757 return;
12758 }
12759 }
12760}
Minimal replacement for QFileInfo.
Definition fileinfo.h:26
#define warn_uncond(fmt,...)
Definition message.h:122

References FileInfo::absFilePath(), Config_getBool, Config_getString, DString::data(), DString::empty(), FileInfo::exists(), Doxygen::inputNameLinkedMap, and warn_uncond.

Referenced by parseInput().

◆ checkPageRelations()

void checkPageRelations ( )
static

Definition at line 10147 of file doxygen.cpp.

10148{
10149 for (const auto &pd : *Doxygen::pageLinkedMap)
10150 {
10151 Definition *ppd = pd->getOuterScope();
10152 while (ppd)
10153 {
10154 if (ppd==pd.get())
10155 {
10156 term("page defined {} with label {} is a subpage "
10157 "of itself! Please remove this cyclic dependency.\n",
10158 warn_line(pd->docFile(),pd->docLine()),pd->name());
10159 }
10160 ppd=ppd->getOuterScope();
10161 }
10162 }
10163}

References Definition::getOuterScope(), Doxygen::pageLinkedMap, term, and warn_line().

Referenced by parseInput().

◆ cleanUpDoxygen()

void cleanUpDoxygen ( )

Definition at line 11776 of file doxygen.cpp.

11777{
11781
11782 delete Doxygen::indexList;
11792 Doxygen::mainPage.reset();
11796 Doxygen::globalScope = nullptr;
11798 delete theTranslator;
11799 delete g_outputList;
11800
11805 delete Doxygen::dirLinkedMap;
11806 delete Doxygen::symbolMap;
11807}
static ParserManager * parserManager
Definition doxygen.h:122
static SymbolMap< Definition > * symbolMap
Definition doxygen.h:118
static FormulaManager & instance()
Definition formula.cpp:54
void clear()
Definition linkedmap.h:212
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:179
static OutputList * g_outputList
Definition doxygen.cpp:192

References FormulaManager::clear(), LinkedMap< T, Hash, KeyEqual, Map >::clear(), ModuleManager::clear(), Doxygen::diaFileNameLinkedMap, Doxygen::dirLinkedMap, Doxygen::dotFileNameLinkedMap, Doxygen::exampleLinkedMap, Doxygen::exampleNameLinkedMap, Doxygen::functionNameLinkedMap, g_outputList, Doxygen::globalNamespaceDef, Doxygen::globalScope, Doxygen::groupLinkedMap, Doxygen::imageNameLinkedMap, Doxygen::includeNameLinkedMap, Doxygen::indexList, Doxygen::inputNameLinkedMap, FormulaManager::instance(), ModuleManager::instance(), SectionManager::instance(), Doxygen::mainPage, Doxygen::memberNameLinkedMap, Doxygen::mermaidFileNameLinkedMap, Doxygen::mscFileNameLinkedMap, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, Doxygen::parserManager, Doxygen::plantUmlFileNameLinkedMap, Doxygen::symbolMap, and theTranslator.

Referenced by generateOutput(), parseInput(), readConfiguration(), and stopDoxygen().

◆ clearAll()

void clearAll ( )

Definition at line 205 of file doxygen.cpp.

References Doxygen::classLinkedMap, CitationManager::clear(), FormulaManager::clear(), LinkedMap< T, Hash, KeyEqual, Map >::clear(), Doxygen::conceptLinkedMap, Doxygen::diaFileNameLinkedMap, Doxygen::dotFileNameLinkedMap, Doxygen::exampleLinkedMap, Doxygen::exampleNameLinkedMap, g_inputFiles, Doxygen::hiddenClassLinkedMap, Doxygen::imageNameLinkedMap, Doxygen::includeNameLinkedMap, Doxygen::inputNameLinkedMap, CitationManager::instance(), FormulaManager::instance(), SectionManager::instance(), Doxygen::mainPage, Doxygen::mermaidFileNameLinkedMap, Doxygen::mscFileNameLinkedMap, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, Doxygen::plantUmlFileNameLinkedMap, and Doxygen::tagDestinationMap.

◆ combineUsingRelations()

void combineUsingRelations ( )
static

Definition at line 9576 of file doxygen.cpp.

9577{
9578 // for each file
9579 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9580 {
9581 for (const auto &fd : *fn)
9582 {
9583 fd->combineUsingRelations();
9584 }
9585 }
9586
9587 // for each namespace
9588 NamespaceDefSet visitedNamespaces;
9589 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9590 {
9592 if (ndm)
9593 {
9594 ndm->combineUsingRelations(visitedNamespaces);
9595 }
9596 }
9597}
virtual void combineUsingRelations(NamespaceDefSet &visitedNamespace)=0
std::unordered_set< const NamespaceDef * > NamespaceDefSet

References NamespaceDefMutable::combineUsingRelations(), Doxygen::inputNameLinkedMap, Doxygen::namespaceLinkedMap, and toNamespaceDefMutable().

Referenced by parseInput().

◆ compareDoxyfile()

void compareDoxyfile ( Config::CompareMode diffList)
static

Definition at line 10650 of file doxygen.cpp.

10651{
10652 std::ofstream f;
10653 bool fileOpened=openOutputFile("-",f);
10654 if (fileOpened)
10655 {
10656 TextStream t(&f);
10657 Config::compareDoxyfile(t,diffList);
10658 }
10659 else
10660 {
10661 term("Cannot open stdout for writing\n");
10662 }
10663}
Text streaming class that buffers data.
Definition textstream.h:36
void compareDoxyfile(TextStream &t, CompareMode compareMode)
bool openOutputFile(const DString &outFile, std::ofstream &f)
Definition util.cpp:4996

References Config::compareDoxyfile(), openOutputFile(), and term.

Referenced by readConfiguration().

◆ computeClassRelations()

void computeClassRelations ( )
static

Definition at line 5622 of file doxygen.cpp.

5623{
5624 AUTO_TRACE();
5625 for (const auto &[name,root] : g_classEntries)
5626 {
5627 DString bName = extractClassName(root);
5628 ClassDefMutable *cd = getClassMutable(bName);
5629 if (cd)
5630 {
5631 findBaseClassesForClass(root,cd,cd,cd,DocumentedOnly,false);
5632 }
5633 size_t numMembers = cd ? cd->memberNameInfoLinkedMap().size() : 0;
5634 if ((cd==nullptr || (!cd->hasDocumentation() && !cd->isReference())) && numMembers>0 && !bName.endsWith("::"))
5635 {
5636 if (!root->name.empty() && root->name.find('@')==DString::npos && // normal name
5637 (EntryType::guessSection(root->fileName).isHeader() ||
5638 Config_getBool(EXTRACT_LOCAL_CLASSES)) && // not defined in source file
5639 protectionLevelVisible(root->protection) && // hidden by protection
5640 !Config_getBool(HIDE_UNDOC_CLASSES) // undocumented class are visible
5641 )
5642 warn_undoc(root->fileName,root->startLine, "Compound {} is not documented.", root->name);
5643 }
5644 }
5645}
virtual const MemberNameInfoLinkedMap & memberNameInfoLinkedMap() const =0
Returns a dictionary of all members.
bool endsWith(const char *s) const
Definition dstring.h:617
size_t size() const
Definition linkedmap.h:210
static DString extractClassName(const Entry *root)
Definition doxygen.cpp:5527
static void findBaseClassesForClass(const Entry *root, Definition *context, ClassDefMutable *masterCd, ClassDefMutable *instanceCd, FindBaseClassRelation_Mode mode, bool isArtificial, const ArgumentList *actualArgs=nullptr, const TemplateNameMap &templateNames=TemplateNameMap())
Definition doxygen.cpp:4982
static std::multimap< std::string, const Entry * > g_classEntries
Definition doxygen.cpp:190
#define warn_undoc(file, line, fmt,...)
Definition message.h:102

References AUTO_TRACE, Config_getBool, DocumentedOnly, DString::empty(), DString::endsWith(), extractClassName(), Entry::fileName, DString::find(), findBaseClassesForClass(), g_classEntries, getClassMutable(), EntryType::guessSection(), Definition::hasDocumentation(), Definition::isReference(), ClassDef::memberNameInfoLinkedMap(), Entry::name, DString::npos, Entry::protection, protectionLevelVisible(), LinkedMap< T, Hash, KeyEqual, Map >::size(), Entry::startLine, and warn_undoc.

Referenced by parseInput().

◆ computeMemberReferences()

void computeMemberReferences ( )
static

Definition at line 5716 of file doxygen.cpp.

5717{
5718 AUTO_TRACE();
5719 for (const auto &cd : *Doxygen::classLinkedMap)
5720 {
5721 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5722 if (cdm)
5723 {
5724 cdm->computeAnchors();
5725 }
5726 }
5727 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5728 {
5729 for (const auto &fd : *fn)
5730 {
5731 fd->computeAnchors();
5732 }
5733 }
5734 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5735 {
5737 if (ndm)
5738 {
5739 ndm->computeAnchors();
5740 }
5741 }
5742 for (const auto &gd : *Doxygen::groupLinkedMap)
5743 {
5744 gd->computeAnchors();
5745 }
5746}
virtual void computeAnchors()=0
virtual void computeAnchors()=0

References AUTO_TRACE, Doxygen::classLinkedMap, ClassDefMutable::computeAnchors(), NamespaceDefMutable::computeAnchors(), Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, Doxygen::namespaceLinkedMap, toClassDefMutable(), and toNamespaceDefMutable().

Referenced by parseInput().

◆ computeMemberRelations()

void computeMemberRelations ( )
static

Definition at line 8806 of file doxygen.cpp.

8807{
8808 for (const auto &cd : *Doxygen::classLinkedMap)
8809 {
8810 if (cd->isLinkable())
8811 {
8812 for (const auto &bcd : cd->baseClasses())
8813 {
8814 auto actualArgs = stringToArgumentList(cd->getLanguage(),bcd.templSpecifiers);
8815 computeMemberRelationsForBaseClass(cd.get(),&bcd,actualArgs.get());
8816 }
8817 }
8818 }
8819}
static void computeMemberRelationsForBaseClass(const ClassDef *cd, const BaseClassDef *bcd, const ArgumentList *actualArgs)
Definition doxygen.cpp:8687

References Doxygen::classLinkedMap, computeMemberRelationsForBaseClass(), and stringToArgumentList().

Referenced by parseInput().

◆ computeMemberRelationsForBaseClass()

void computeMemberRelationsForBaseClass ( const ClassDef * cd,
const BaseClassDef * bcd,
const ArgumentList * actualArgs )
static

Definition at line 8687 of file doxygen.cpp.

8688{
8689 for (const auto &mn : cd->memberNameInfoLinkedMap()) // for each member in class cd with a unique name
8690 {
8691 for (const auto &imd : *mn) // for each member with a given name
8692 {
8693 MemberDefMutable *md = toMemberDefMutable(imd->memberDef());
8694 if (md && (md->isFunction() || md->isCSharpProperty())) // filter on reimplementable members
8695 {
8696 ClassDef *mbcd = bcd->classDef;
8697 if (mbcd && mbcd->isLinkable()) // filter on linkable classes
8698 {
8699 const auto &bmn = mbcd->memberNameInfoLinkedMap();
8700 const auto &bmni = bmn.find(mn->memberName());
8701 if (bmni) // there are base class members with the same name
8702 {
8703 for (const auto &ibmd : *bmni) // for base class member with that name
8704 {
8705 MemberDefMutable *bmd = toMemberDefMutable(ibmd->memberDef());
8706 if (bmd) // not part of an inline namespace
8707 {
8708 auto lang = bmd->getLanguage();
8709 auto compType = mbcd->compoundType();
8710 if (bmd->virtualness()!=Specifier::Normal ||
8711 lang==SrcLangExt::Python ||
8712 lang==SrcLangExt::Java ||
8713 lang==SrcLangExt::PHP ||
8714 compType==ClassDef::Interface ||
8715 compType==ClassDef::Protocol)
8716 {
8717 const ArgumentList &bmdAl = bmd->argumentList();
8718 const ArgumentList &mdAl = md->argumentList();
8719 const ClassDef *baseClass = bcd->classDef;
8720 const ClassDef *baseTemplate = baseClass->templateMaster() ? baseClass->templateMaster() : baseClass;
8721 const ClassDef *memberClass = bmd->getClassDef();
8722 bool instantiateBaseMember = actualArgs &&
8723 (memberClass==baseClass || memberClass==baseTemplate) &&
8724 !baseTemplate->templateArguments().empty();
8725 bool useDerivedScope = false;
8726 ArgumentList instantiatedBmdAl;
8727 DString instantiatedBmdType = bmd->typeString();
8728 if (instantiateBaseMember)
8729 {
8730 instantiatedBmdAl = bmdAl;
8731 for (Argument &arg : instantiatedBmdAl)
8732 {
8734 arg.type,baseTemplate->templateArguments(),actualArgs);
8735 useDerivedScope = useDerivedScope || substitutedType!=arg.type;
8736 arg.type = substitutedType;
8737 }
8738 DString substitutedTrailingReturnType = substituteTemplateArgumentsInString(
8739 instantiatedBmdAl.trailingReturnType(),baseTemplate->templateArguments(),actualArgs);
8740 useDerivedScope = useDerivedScope ||
8741 substitutedTrailingReturnType!=instantiatedBmdAl.trailingReturnType();
8742 instantiatedBmdAl.setTrailingReturnType(substitutedTrailingReturnType);
8744 instantiatedBmdType,baseTemplate->templateArguments(),actualArgs);
8745 useDerivedScope = useDerivedScope || substitutedType!=instantiatedBmdType;
8746 instantiatedBmdType = substitutedType;
8747 }
8748 //printf(" Base argList='%s'\n Super argList='%s'\n",
8749 // qPrint(argListToString(bmdAl)),
8750 // qPrint(argListToString(mdAl))
8751 // );
8752 if (
8753 lang==SrcLangExt::Python ||
8754 matchArguments2(useDerivedScope ? cd : bmd->getOuterScope(),
8755 useDerivedScope ? cd->getFileDef() : bmd->getFileDef(),
8756 instantiatedBmdType,instantiateBaseMember ? &instantiatedBmdAl : &bmdAl,
8757 md->getOuterScope(), md->getFileDef(), md->typeString(),&mdAl,
8758 true,lang
8759 )
8760 )
8761 {
8762 if (lang==SrcLangExt::Python && md->name().startsWith("__")) continue; // private members do not reimplement
8763 //printf("match!\n");
8764 const MemberDef *rmd = md->reimplements();
8765 if (rmd==nullptr) // not already assigned
8766 {
8767 //printf("%s: setting (new) reimplements member %s\n",qPrint(md->qualifiedName()),qPrint(bmd->qualifiedName()));
8768 md->setReimplements(bmd);
8769 }
8770 //printf("%s: add reimplementedBy member %s\n",qPrint(bmd->qualifiedName()),qPrint(md->qualifiedName()));
8771 bmd->insertReimplementedBy(md);
8772 }
8773 else
8774 {
8775 //printf("no match!\n");
8776 }
8777 }
8778 }
8779 }
8780 }
8781 }
8782 }
8783 }
8784 }
8785
8786 // do also for indirect base classes
8787 for (const auto &bbcd : bcd->classDef->baseClasses())
8788 {
8789 DString templSpec = bbcd.templSpecifiers;
8790 const ClassDef *baseClass = bcd->classDef;
8791 const ClassDef *baseTemplate = baseClass->templateMaster() ? baseClass->templateMaster() : baseClass;
8792 if (actualArgs)
8793 {
8794 templSpec = substituteTemplateArgumentsInString(templSpec,baseTemplate->templateArguments(),actualArgs);
8795 }
8796 auto nextActualArgs = stringToArgumentList(baseClass->getLanguage(),templSpec);
8797 computeMemberRelationsForBaseClass(cd,&bbcd,nextActualArgs.get());
8798 }
8799}
This class contains the information about the argument of a function or template.
Definition arguments.h:27
virtual const BaseClassList & baseClasses() const =0
Returns the list of base classes from which this class directly inherits.
virtual const ClassDef * templateMaster() const =0
Returns the template master of which this class is an instance.
virtual FileDef * getFileDef() const =0
Returns the file in which this compound's definition can be found.
virtual bool isCSharpProperty() const =0
virtual bool isFunction() const =0
virtual const MemberDef * reimplements() const =0
virtual void setReimplements(MemberDef *md)=0
virtual void insertReimplementedBy(MemberDef *md)=0
ClassDef * classDef
Class definition that this relation inherits from.
Definition classdef.h:56
DString substituteTemplateArgumentsInString(const DString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
Definition util.cpp:3530

References MemberDef::argumentList(), ClassDef::baseClasses(), BaseClassDef::classDef, ClassDef::compoundType(), computeMemberRelationsForBaseClass(), ArgumentList::empty(), LinkedMap< T, Hash, KeyEqual, Map >::find(), MemberDef::getClassDef(), ClassDef::getFileDef(), MemberDef::getFileDef(), Definition::getLanguage(), Definition::getOuterScope(), MemberDefMutable::insertReimplementedBy(), ClassDef::Interface, MemberDef::isCSharpProperty(), MemberDef::isFunction(), Definition::isLinkable(), matchArguments2(), ClassDef::memberNameInfoLinkedMap(), Definition::name(), ClassDef::Protocol, MemberDef::reimplements(), MemberDefMutable::setReimplements(), DString::startsWith(), stringToArgumentList(), substituteTemplateArgumentsInString(), ClassDef::templateArguments(), ClassDef::templateMaster(), toMemberDefMutable(), MemberDef::typeString(), and MemberDef::virtualness().

Referenced by computeMemberRelations(), and computeMemberRelationsForBaseClass().

◆ computePageRelations()

void computePageRelations ( Entry * root)
static

Definition at line 10117 of file doxygen.cpp.

10118{
10119 if ((root->section.isPageDoc() || root->section.isMainpageDoc()) && !root->name.empty())
10120 {
10121 PageDef *pd = root->section.isPageDoc() ?
10123 Doxygen::mainPage.get();
10124 if (pd)
10125 {
10126 for (const BaseInfo &bi : root->extends)
10127 {
10129 if (pd==subPd)
10130 {
10131 term("page defined {} with label {} is a direct "
10132 "subpage of itself! Please remove this cyclic dependency.\n",
10133 warn_line(pd->docFile(),pd->docLine()),pd->name());
10134 }
10135 else if (subPd)
10136 {
10137 pd->addInnerCompound(subPd);
10138 //printf("*** Added subpage relation: %s->%s\n",
10139 // qPrint(pd->name()),qPrint(subPd->name()));
10140 }
10141 }
10142 }
10143 }
10144 for (const auto &e : root->children()) computePageRelations(e.get());
10145}
virtual int docLine() const =0
virtual DString docFile() const =0
std::vector< BaseInfo > extends
list of base classes
Definition entry.h:220
static void computePageRelations(Entry *root)
DString name
the name of the base class
Definition entry.h:92

References DefinitionMutable::addInnerCompound(), Entry::children(), computePageRelations(), Definition::docFile(), Definition::docLine(), DString::empty(), Entry::extends, LinkedMap< T, Hash, KeyEqual, Map >::find(), Doxygen::mainPage, BaseInfo::name, Definition::name(), Entry::name, Doxygen::pageLinkedMap, Entry::section, term, and warn_line().

Referenced by computePageRelations(), and parseInput().

◆ computeTemplateClassRelations()

void computeTemplateClassRelations ( )
static

Definition at line 5647 of file doxygen.cpp.

5648{
5649 AUTO_TRACE();
5650 for (const auto &[name,root] : g_classEntries)
5651 {
5652 DString bName=stripAnonymousNamespaceScope(root->name);
5655 // strip any anonymous scopes first
5656 if (cd && !cd->getTemplateInstances().empty())
5657 {
5658 AUTO_TRACE_ADD("Template class '{}'",cd->name());
5659 for (const auto &ti : cd->getTemplateInstances()) // for each template instance
5660 {
5661 ClassDefMutable *tcd=toClassDefMutable(ti.classDef);
5662 if (tcd && tcd->isImplicitTemplateInstance()) // (partial) specializations have their own base classes
5663 {
5664 AUTO_TRACE_ADD("Template instance '{}'",tcd->name());
5665 DString templSpec = ti.templSpec;
5666 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(tcd->getLanguage(),templSpec);
5667 for (const BaseInfo &bi : root->extends)
5668 {
5669 // check if the base class is a template argument
5670 BaseInfo tbi = bi;
5671 const ArgumentList &tl = cd->templateArguments();
5672 if (!tl.empty())
5673 {
5674 TemplateNameMap baseClassNames = tcd->getTemplateBaseClassNames();
5675 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,bi.name.str());
5676 // for each template name that we inherit from we need to
5677 // substitute the formal with the actual arguments
5678 TemplateNameMap actualTemplateNames;
5679 for (const auto &tn_kv : templateNames)
5680 {
5681 size_t templIndex = tn_kv.second;
5682 Argument actArg;
5683 bool hasActArg=false;
5684 if (templIndex<templArgs->size())
5685 {
5686 actArg=templArgs->at(templIndex);
5687 hasActArg=true;
5688 }
5689 if (hasActArg &&
5690 baseClassNames.find(actArg.type.str())!=baseClassNames.end() &&
5691 actualTemplateNames.find(actArg.type.str())==actualTemplateNames.end()
5692 )
5693 {
5694 actualTemplateNames.emplace(actArg.type.str(),static_cast<int>(templIndex));
5695 }
5696 }
5697
5698 tbi.name = substituteTemplateArgumentsInString(bi.name,tl,templArgs.get());
5699 // find a documented base class in the correct scope
5700 if (!findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,false))
5701 {
5702 // no documented base class -> try to find an undocumented one
5703 findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,Undocumented,true);
5704 }
5705 }
5706 }
5707 }
5708 }
5709 }
5710 }
5711}
DString type
Definition arguments.h:43
virtual const TemplateInstanceList & getTemplateInstances() const =0
Returns a sorted dictionary with all template instances found for this template class.
virtual const TemplateNameMap & getTemplateBaseClassNames() const =0
static TemplateNameMap getTemplateArgumentsInName(const ArgumentList &templateArguments, const std::string &name)
Definition doxygen.cpp:4763

References AUTO_TRACE, AUTO_TRACE_ADD, DocumentedOnly, ArgumentList::empty(), Entry::extends, findClassRelation(), g_classEntries, getClassMutable(), Definition::getLanguage(), getTemplateArgumentsInName(), ClassDef::getTemplateBaseClassNames(), ClassDef::getTemplateInstances(), ClassDef::isImplicitTemplateInstance(), BaseInfo::name, Definition::name(), Entry::name, DString::str(), stringToArgumentList(), stripAnonymousNamespaceScope(), stripTemplateSpecifiersFromScope(), substituteTemplateArgumentsInString(), ClassDef::templateArguments(), toClassDefMutable(), Argument::type, and Undocumented.

Referenced by parseInput().

◆ computeTooltipTexts()

void computeTooltipTexts ( )
static

Definition at line 9295 of file doxygen.cpp.

9296{
9297 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
9298 if (numThreads>1)
9299 {
9300 ThreadPool threadPool(numThreads);
9301 std::vector < std::future< void > > results;
9302 // queue the work
9303 for (const auto &[name,symList] : *Doxygen::symbolMap)
9304 {
9305 for (const auto &def : symList)
9306 {
9308 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
9309 {
9310 auto processTooltip = [dm]() {
9311 dm->computeTooltip();
9312 };
9313 results.emplace_back(threadPool.queue(processTooltip));
9314 }
9315 }
9316 }
9317 // wait for the results
9318 for (auto &f : results)
9319 {
9320 f.get();
9321 }
9322 }
9323 else
9324 {
9325 for (const auto &[name,symList] : *Doxygen::symbolMap)
9326 {
9327 for (const auto &def : symList)
9328 {
9330 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
9331 {
9332 dm->computeTooltip();
9333 }
9334 }
9335 }
9336 }
9337}
virtual void computeTooltip()=0
Class managing a pool of worker threads.
Definition threadpool.h:48
static bool isSymbolHidden(const Definition *d)
Definition doxygen.cpp:9288

References DefinitionMutable::computeTooltip(), Config_getInt, isSymbolHidden(), ThreadPool::queue(), Doxygen::symbolMap, and toDefinitionMutable().

Referenced by parseInput().

◆ computeVerifiedDotPath()

void computeVerifiedDotPath ( )
static

Definition at line 10574 of file doxygen.cpp.

10575{
10576 // check dot path
10577 DString dotPath = Config_getString(DOT_PATH);
10578 if (!dotPath.empty())
10579 {
10580 FileInfo fi(dotPath.str());
10581 if (!(fi.exists() && fi.isFile()) )// not an existing user specified path + exec
10582 {
10583 dotPath = dotPath+"/dot"+Portable::commandExtension();
10584 FileInfo dp(dotPath.str());
10585 if (!dp.exists() || !dp.isFile())
10586 {
10587 warn_uncond("the dot tool could not be found as '{}'\n",dotPath);
10588 dotPath = "dot";
10589 dotPath += Portable::commandExtension();
10590 }
10591 else if (dp.isRelative())
10592 {
10593 dotPath = fi.dirPath() + "/" + dotPath;
10594 }
10595 }
10596#if defined(_WIN32) // convert slashes
10597 size_t l=dotPath.length();
10598 for (size_t i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\';
10599#endif
10600 }
10601 else
10602 {
10603 dotPath = "dot";
10604 dotPath += Portable::commandExtension();
10605 }
10606 Doxygen::verifiedDotPath = dotPath;
10608}
static DString verifiedDotPath
Definition doxygen.h:130
const char * commandExtension()
Definition portable.cpp:477
#define TRACE(...)
Definition trace.h:77

References DString::at(), Portable::commandExtension(), Config_getString, FileInfo::dirPath(), DString::empty(), FileInfo::exists(), FileInfo::isFile(), FileInfo::isRelative(), DString::length(), DString::str(), TRACE, Doxygen::verifiedDotPath, and warn_uncond.

Referenced by parseInput().

◆ convertToCompoundType()

ClassDef::CompoundType convertToCompoundType ( EntryType section,
TypeSpecifier specifier )
static

Definition at line 908 of file doxygen.cpp.

909{
911
912 if (specifier.isStruct())
914 else if (specifier.isUnion())
915 sec=ClassDef::Union;
916 else if (specifier.isCategory())
918 else if (specifier.isInterface())
920 else if (specifier.isProtocol())
922 else if (specifier.isException())
924 else if (specifier.isService())
926 else if (specifier.isSingleton())
928
929 if (section.isUnionDoc())
930 sec=ClassDef::Union;
931 else if (section.isStructDoc())
933 else if (section.isInterfaceDoc())
935 else if (section.isProtocolDoc())
937 else if (section.isCategoryDoc())
939 else if (section.isExceptionDoc())
941 else if (section.isServiceDoc())
943 else if (section.isSingletonDoc())
945
946 return sec;
947}
@ Exception
Definition classdef.h:111

References ClassDef::Category, ClassDef::Class, ClassDef::Exception, ClassDef::Interface, ClassDef::Protocol, ClassDef::Service, ClassDef::Singleton, ClassDef::Struct, and ClassDef::Union.

Referenced by addClassToContext().

◆ copyExtraFiles()

void copyExtraFiles ( StringVector files,
const DString & filesOption,
const DString & outputOption,
bool toIndex )
inlinestatic

Definition at line 10843 of file doxygen.cpp.

10844{
10845 for (const auto &fileName : files)
10846 {
10847 if (!fileName.empty())
10848 {
10849 FileInfo fi(fileName);
10850 if (!fi.exists())
10851 {
10852 err("Extra file '{}' specified in {} does not exist!\n", fileName,filesOption);
10853 }
10854 else if (fi.isDir())
10855 {
10856 err("Extra file '{}' specified in {} is a directory, it has to be a file!\n", fileName,filesOption);
10857 }
10858 else
10859 {
10860 DString destFileName = outputOption+"/"+fi.fileName();
10861 copyFile(fileName, destFileName);
10862 if (toIndex) Doxygen::indexList->addImageFile(fi.fileName());
10863 }
10864 }
10865 }
10866}
void addImageFile(const DString &name)
Definition indexlist.h:124
bool copyFile(const DString &src, const DString &dest)
Copies the contents of file with name src to the newly created file with name dest.
Definition util.cpp:4629

References IndexList::addImageFile(), copyFile(), err, FileInfo::exists(), FileInfo::fileName(), Doxygen::indexList, and FileInfo::isDir().

Referenced by generateOutput().

◆ copyIcon()

void copyIcon ( const DString & outputOption,
bool toIndex )
static

Definition at line 10818 of file doxygen.cpp.

10819{
10820 DString projectIcon = Config_getString(PROJECT_ICON);
10821 if (!projectIcon.empty())
10822 {
10823 FileInfo fi(projectIcon.str());
10824 if (!fi.exists())
10825 {
10826 err("Project icon '{}' specified by PROJECT_ICON does not exist!\n",projectIcon);
10827 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10828 }
10829 else if (fi.isDir())
10830 {
10831 err("Project icon '{}' specified by PROJECT_ICON is a directory, it has to be a file!\n",projectIcon);
10832 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10833 }
10834 else
10835 {
10836 DString destFileName = outputOption+"/"+fi.fileName();
10837 copyFile(projectIcon,destFileName);
10838 if (toIndex) Doxygen::indexList->addImageFile(fi.fileName());
10839 }
10840 }
10841}
#define Config_updateString(name, value)
Definition config.h:39

References IndexList::addImageFile(), Config_getString, Config_updateString, copyFile(), DString::empty(), err, FileInfo::exists(), FileInfo::fileName(), Doxygen::indexList, FileInfo::isDir(), and DString::str().

Referenced by generateOutput().

◆ copyLatexStyleSheet()

void copyLatexStyleSheet ( )
static

Definition at line 10709 of file doxygen.cpp.

10710{
10711 StringVector latexExtraStyleSheet = Config_getList(LATEX_EXTRA_STYLESHEET);
10712 for (const auto &sheet : latexExtraStyleSheet)
10713 {
10714 std::string fileName = sheet;
10715 if (!fileName.empty())
10716 {
10717 FileInfo fi(fileName);
10718 if (!fi.exists())
10719 {
10720 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET does not exist!\n",fileName);
10721 }
10722 else if (fi.isDir())
10723 {
10724 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET is a directory, it has to be a file!\n", fileName);
10725 }
10726 else
10727 {
10728 DString destFileName = Config_getString(LATEX_OUTPUT)+"/"+fi.fileName();
10729 if (!checkExtension(fi.fileName(), LATEX_STYLE_EXTENSION))
10730 {
10731 destFileName += LATEX_STYLE_EXTENSION;
10732 }
10733 copyFile(fileName, destFileName);
10734 }
10735 }
10736 }
10737}
#define LATEX_STYLE_EXTENSION
Definition latexgen.h:24
bool checkExtension(const DString &fName, const DString &ext)
Definition util.cpp:3932

References checkExtension(), Config_getList, Config_getString, copyFile(), err, FileInfo::exists(), FileInfo::fileName(), FileInfo::isDir(), and LATEX_STYLE_EXTENSION.

Referenced by generateOutput().

◆ copyLogo()

void copyLogo ( const DString & outputOption,
bool toIndex )
static

Definition at line 10793 of file doxygen.cpp.

10794{
10795 DString projectLogo = projectLogoFile();
10796 if (!projectLogo.empty())
10797 {
10798 FileInfo fi(projectLogo.str());
10799 if (!fi.exists())
10800 {
10801 err("Project logo '{}' specified by PROJECT_LOGO does not exist!\n",projectLogo);
10802 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10803 }
10804 else if (fi.isDir())
10805 {
10806 err("Project logo '{}' specified by PROJECT_LOGO is a directory, it has to be a file!\n",projectLogo);
10807 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10808 }
10809 else
10810 {
10811 DString destFileName = outputOption+"/"+fi.fileName();
10812 copyFile(projectLogo,destFileName);
10813 if (toIndex) Doxygen::indexList->addImageFile(fi.fileName());
10814 }
10815 }
10816}
DString projectLogoFile()
Definition util.cpp:2586

References IndexList::addImageFile(), Config_updateString, copyFile(), DString::empty(), err, FileInfo::exists(), FileInfo::fileName(), Doxygen::indexList, FileInfo::isDir(), projectLogoFile(), and DString::str().

Referenced by generateOutput().

◆ copyStyleSheet()

void copyStyleSheet ( )
static

Definition at line 10740 of file doxygen.cpp.

10741{
10742 DString htmlStyleSheet = Config_getString(HTML_STYLESHEET);
10743 if (!htmlStyleSheet.empty())
10744 {
10745 if (!htmlStyleSheet.startsWith("http:") && !htmlStyleSheet.startsWith("https:"))
10746 {
10747 FileInfo fi(htmlStyleSheet.str());
10748 if (!fi.exists())
10749 {
10750 err("Style sheet '{}' specified by HTML_STYLESHEET does not exist!\n",htmlStyleSheet);
10751 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10752 }
10753 else if (fi.isDir())
10754 {
10755 err("Style sheet '{}' specified by HTML_STYLESHEET is a directory, it has to be a file!\n",htmlStyleSheet);
10756 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10757 }
10758 else
10759 {
10760 DString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10761 copyFile(htmlStyleSheet,destFileName);
10762 }
10763 }
10764 }
10765 StringVector htmlExtraStyleSheet = Config_getList(HTML_EXTRA_STYLESHEET);
10766 for (const auto &sheet : htmlExtraStyleSheet)
10767 {
10768 DString fileName(sheet);
10769 if (!fileName.empty() && !fileName.startsWith("http:") && !fileName.startsWith("https:"))
10770 {
10771 FileInfo fi(fileName.str());
10772 if (!fi.exists())
10773 {
10774 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET does not exist!\n",fileName);
10775 }
10776 else if (fi.fileName()=="doxygen.css" || fi.fileName()=="tabs.css" || fi.fileName()=="navtree.css")
10777 {
10778 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is already a built-in stylesheet. Please use a different name\n",fi.fileName());
10779 }
10780 else if (fi.isDir())
10781 {
10782 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is a directory, it has to be a file!\n",fileName);
10783 }
10784 else
10785 {
10786 DString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10787 copyFile(fileName, destFileName);
10788 }
10789 }
10790 }
10791}

References Config_getList, Config_getString, Config_updateString, copyFile(), DString::empty(), err, FileInfo::exists(), FileInfo::fileName(), FileInfo::isDir(), DString::startsWith(), and DString::str().

Referenced by generateOutput().

◆ countMembers()

void countMembers ( )
static

Definition at line 9355 of file doxygen.cpp.

9356{
9357 for (const auto &cd : *Doxygen::classLinkedMap)
9358 {
9359 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9360 if (cdm)
9361 {
9362 cdm->countMembers();
9363 }
9364 }
9365
9366 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9367 {
9369 if (ndm)
9370 {
9371 ndm->countMembers();
9372 }
9373 }
9374
9375 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9376 {
9377 for (const auto &fd : *fn)
9378 {
9379 fd->countMembers();
9380 }
9381 }
9382
9383 for (const auto &gd : *Doxygen::groupLinkedMap)
9384 {
9385 gd->countMembers();
9386 }
9387
9388 auto &mm = ModuleManager::instance();
9389 mm.countMembers();
9390}
virtual void countMembers()=0
virtual void countMembers()=0

References Doxygen::classLinkedMap, ClassDefMutable::countMembers(), NamespaceDefMutable::countMembers(), Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), Doxygen::namespaceLinkedMap, toClassDefMutable(), and toNamespaceDefMutable().

Referenced by generateOutput().

◆ createOutputDirectory()

DString createOutputDirectory ( const DString & baseDirName,
const DString & formatDirName,
const char * defaultDirName )
static

Definition at line 12488 of file doxygen.cpp.

12491{
12492 DString result = formatDirName;
12493 if (result.empty())
12494 {
12495 result = baseDirName + defaultDirName;
12496 }
12497 else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':'))
12498 {
12499 result.prepend(baseDirName+"/");
12500 }
12501 Dir formatDir(result.str());
12502 if (!formatDir.exists() && !formatDir.mkdir(result.str()))
12503 {
12504 term("Could not create output directory {}\n", result);
12505 }
12506 return result;
12507}
Class representing a directory in the file system.
Definition dir.h:73

References DString::empty(), Dir::exists(), DString::length(), Dir::mkdir(), DString::prepend(), DString::str(), and term.

Referenced by parseInput().

◆ createTagLessInstance()

ClassDefMutable * createTagLessInstance ( const Definition * root,
const ClassDef * templ,
const DString & fieldName,
bool hasNamedVariable )
static

Definition at line 1572 of file doxygen.cpp.

1573{
1574 DString fullName;
1575 if (Config_getEnum(TAGLESS_NAMESTYLE)==TAGLESS_NAMESTYLE_t::flat)
1576 {
1577 // "flat" style: refer to the anonymous compound via its flattened scope and
1578 // member names, e.g. 'struct A { struct { int x; } y; };' yields 'A.y'.
1579 // This matches the pre-1.18 naming and is friendlier for consumers of the
1580 // XML output that cannot handle type names starting with '[' (e.g. mkdoxy).
1581 fullName = removeAnonymousScopes(templ->name());
1582 if (fullName.endsWith("::")) fullName = fullName.left(fullName.length()-2);
1583 // add the field name as a suffix to make the name unique again; the
1584 // separator is only added when there is a flattened scope left (a
1585 // file-scope anonymous compound has none and would otherwise get a
1586 // leading '.').
1587 if (!fullName.empty()) fullName += ".";
1588 fullName += fieldName;
1589 }
1590 else // "marker" style (the default)
1591 {
1592 DString n = templ->name();
1593 // replace e.g. X::@1343:@4343::Y -> X::[struct]::Y
1594 if (size_t sn = n.find('@'); sn!=DString::npos)
1595 {
1596 const char *p = n.data()+sn;
1597 char c;
1598 while ((c=*p))
1599 {
1600 if (!isdigit(c) && c!='@' && c!=':') break;
1601 p++;
1602 }
1603 n = n.left(sn)+"["+templ->compoundTypeString().str()+"]"+p;
1604 }
1605 // add field name to the class name to make it unique again, e.g. X::[struct]::Y.m
1606 fullName = n+"."+fieldName;
1607 }
1608
1609 //printf("** adding class %s based on %s in %s\n",qPrint(fullName),qPrint(templ->name()),qPrint(root->name()));
1611 Doxygen::classLinkedMap->add(fullName,
1613 templ->getDefLine(),
1614 templ->getDefColumn(),
1615 fullName,
1616 templ->compoundType())));
1617 if (cd)
1618 {
1619 //printf("cd->name()=%s displayName=%s\n",qPrint(cd->name()),qPrint(cd->displayName()));
1620 cd->setDocumentation(templ->documentation(),templ->docFile(),templ->docLine()); // copy docs to definition
1621 cd->setBriefDescription(templ->briefDescription(),templ->briefFile(),templ->briefLine());
1622 cd->setLanguage(templ->getLanguage());
1623 cd->setBodySegment(templ->getDefLine(),templ->getStartBodyLine(),templ->getEndBodyLine());
1624 cd->setBodyDef(templ->getBodyDef());
1625
1626 if (hasNamedVariable)
1627 {
1628 cd->setHasNamedVariable(true);
1629 if (root!=Doxygen::globalScope)
1630 {
1631 DefinitionMutable *outerScope = toDefinitionMutable(const_cast<Definition*>(root));
1632 if (root && root->definitionType()==Definition::TypeFile)
1633 {
1634 FileDef *fd = toFileDef(const_cast<Definition*>(root));
1635 fd->insertClass(cd);
1636 cd->setFileDef(fd);
1638 }
1639 else if (outerScope)
1640 {
1641 outerScope->addInnerCompound(cd);
1642 cd->setOuterScope(const_cast<Definition*>(root));
1643 }
1644 }
1645 }
1646 else
1647 {
1648 cd->setArtificial(true);
1649 }
1650
1651 for (auto &gd : root->partOfGroups())
1652 {
1653 cd->makePartOfGroup(gd);
1654 gd->addClass(cd);
1655 }
1656
1657 auto addMember = [&](const MemberDef *md) -> MemberDefMutable*
1658 {
1659 auto newMd = createMemberDef(md->getDefFileName(),md->getDefLine(),md->getDefColumn(),
1660 md->typeString(),md->name(),md->argsString(),md->excpString(),
1661 md->protection(),md->virtualness(),md->isStatic(),Relationship::Member,
1662 md->memberType(),
1663 ArgumentList(),ArgumentList(),"");
1664 MemberDefMutable *imd = toMemberDefMutable(newMd.get());
1665 imd->setDefinition(md->definition());
1666 imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
1667 imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
1668 imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
1669 imd->setMemberSpecifiers(md->getMemberSpecifiers());
1670 imd->setId(md->id());
1671 imd->addQualifiers(md->getQualifiers());
1672 imd->setVhdlSpecifiers(md->getVhdlSpecifiers());
1673 imd->setMemberGroupId(md->getMemberGroupId());
1674 imd->setInitializer(md->initializer());
1675 imd->setRequiresClause(md->requiresClause());
1676 imd->setMaxInitLines(md->initializerLines());
1677 imd->setBitfields(md->bitfieldString());
1678 imd->setLanguage(md->getLanguage());
1679 imd->setAnchor();
1680 MemberName *mn = Doxygen::memberNameLinkedMap->add(md->name());
1681 mn->push_back(std::move(newMd));
1682 return imd;
1683 };
1684
1685 static auto memberListPairs = std::array<std::pair<MemberListType,MemberListType>,3>{{
1686 { MemberListType::PubAttribs(), MemberListType::PubTypes() },
1687 { MemberListType::ProAttribs(), MemberListType::ProTypes() },
1688 { MemberListType::PriAttribs(), MemberListType::PriTypes() }
1689 }};
1690 for (auto [attribs,types] : memberListPairs)
1691 {
1692 MemberList *ml = templ->getMemberList(attribs);
1693 if (ml)
1694 {
1695 for (const auto &md : *ml)
1696 {
1697 //printf(" Member attribute %s def=%s\n",qPrint(md->name()),qPrint(md->definition()));
1698 MemberDefMutable *imd = addMember(md);
1699 if (!hasNamedVariable && root) // we have an anonymous struct/union without associated member variable,
1700 // so we also need to create a new member to show in the outer scope's detailed section.
1701 // e.g. struct S { union { int a; int b; }; }; needs S::a and S::b as members
1702 {
1703 MemberDefMutable *dimd = addMember(md);
1704 // link the detailed member to the original member
1707 if (root && root->definitionType()==Definition::TypeClass && dimd)
1708 {
1709 ClassDefMutable *cm = toClassDefMutable(const_cast<Definition*>(root));
1710 if (cm)
1711 {
1712 //printf(" Member attribute %s added to class %s\n",qPrint(md->name()),qPrint(cm->name()));
1713 dimd->setMemberClass(cm);
1714 cm->insertMember(dimd);
1715 associateVariableWithAnonymousEnumType(md,cm,dimd,attribs);
1716 }
1717 }
1718 else if (root && root->definitionType()==Definition::TypeFile && dimd)
1719 {
1720 FileDef *fd = toFileDef(const_cast<Definition*>(root));
1721 if (fd)
1722 {
1723 //printf(" Member attribute %s added to file %s\n",qPrint(md->name()),qPrint(fd->name()));
1724 dimd->setOuterScope(fd);
1725 dimd->setFileDef(fd);
1726 fd->insertMember(dimd);
1727 associateVariableWithAnonymousEnumType(md,fd,dimd,attribs);
1728 }
1729 }
1730 else if (root && root->definitionType()==Definition::TypeNamespace && dimd)
1731 {
1732 NamespaceDefMutable *ndm = toNamespaceDefMutable(const_cast<Definition*>(root));
1733 if (ndm)
1734 {
1735 //printf(" Member attribute %s added to namespace %s\n",qPrint(md->name()),qPrint(ndm->name()));
1736 dimd->setOuterScope(ndm);
1737 dimd->setNamespace(ndm);
1738 ndm->insertMember(dimd);
1739 associateVariableWithAnonymousEnumType(md,ndm,dimd,attribs);
1740 }
1741 }
1742 }
1743
1744 imd->setMemberClass(cd);
1745 cd->insertMember(imd);
1746 associateVariableWithAnonymousEnumType(md,cd,imd,attribs);
1747 }
1748 }
1749 ml = templ->getMemberList(types);
1750 if (ml)
1751 {
1752 for (const auto &md : *ml)
1753 {
1754 //printf(" Member type %s def=%s\n",qPrint(md->name()),qPrint(md->definition()));
1755 MemberDefMutable *mdm = addMember(md);
1756 mdm->setMemberClass(cd);
1757 cd->insertMember(mdm);
1759 associateVariableWithAnonymousEnumType(md,cd,mdm,attribs);
1760 if (md->isEnumerate() && md->name().startsWith("@")) // anonymous enum type
1761 {
1762 for (const auto &emd : md->enumFieldList())
1763 {
1764 //printf(" enum field %s\n",qPrint(emd->name()));
1765 MemberDefMutable *emdm = addMember(emd);
1766 mdm->insertEnumField(emdm);
1767 emdm->setEnumScope(md);
1768 emdm->setMemberClass(cd);
1769 cd->insertMember(emdm);
1771 associateVariableWithAnonymousEnumType(md,cd,emdm,attribs);
1772 }
1773 }
1774 }
1775 }
1776 }
1777 }
1778 return cd;
1779}
virtual MemberList * getMemberList(MemberListType lt) const =0
Returns the members in the list identified by lt.
virtual void setHasNamedVariable(bool b)=0
virtual int getEndBodyLine() const =0
virtual DString briefFile() const =0
virtual int briefLine() const =0
virtual const GroupList & partOfGroups() const =0
virtual void setClassDefOfAnonymousType(const ClassDef *cd)=0
virtual void setMemberClass(ClassDef *cd)=0
virtual void setMemberSpecifiers(TypeSpecifier s)=0
virtual void setVhdlSpecifiers(VhdlSpecifier s)=0
virtual void setFileDef(FileDef *fd)=0
virtual void setAnonymousMemberForDeclaration(const MemberDef *md)=0
virtual void setAnonymousMemberForDetails(const MemberDef *md)=0
virtual void setBitfields(const DString &s)=0
virtual void setNamespace(NamespaceDef *nd)=0
virtual void setAnchor()=0
static void associateVariableWithAnonymousEnumType(const MemberDef *md, const Container *cd, const MemberDef *enumTypeMember, MemberListType mlFilter)
Definition doxygen.cpp:1545
FileDef * toFileDef(Definition *d)
Definition filedef.cpp:2033
DString removeAnonymousScopes(const DString &str)
Definition util.cpp:98

References LinkedMap< T, Hash, KeyEqual, Map >::add(), DefinitionMutable::addInnerCompound(), MemberDefMutable::addQualifiers(), associateVariableWithAnonymousEnumType(), Definition::briefDescription(), Definition::briefFile(), Definition::briefLine(), Doxygen::classLinkedMap, ClassDef::compoundType(), ClassDef::compoundTypeString(), Config_getEnum, createClassDef(), createMemberDef(), DString::data(), Definition::definitionType(), Definition::docFile(), Definition::docLine(), Definition::documentation(), DString::empty(), DString::endsWith(), DString::find(), Definition::getBodyDef(), Definition::getDefColumn(), Definition::getDefFileName(), Definition::getDefLine(), Definition::getEndBodyLine(), Definition::getLanguage(), ClassDef::getMemberList(), Definition::getStartBodyLine(), Doxygen::globalScope, FileDef::insertClass(), MemberDefMutable::insertEnumField(), ClassDefMutable::insertMember(), FileDef::insertMember(), NamespaceDefMutable::insertMember(), DString::left(), DString::length(), DefinitionMutable::makePartOfGroup(), Doxygen::memberNameLinkedMap, Definition::name(), DString::npos, Definition::partOfGroups(), MemberName::push_back(), removeAnonymousScopes(), MemberDefMutable::setAnchor(), MemberDefMutable::setAnonymousMemberForDeclaration(), MemberDefMutable::setAnonymousMemberForDetails(), DefinitionMutable::setArtificial(), MemberDefMutable::setBitfields(), DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), MemberDefMutable::setClassDefOfAnonymousType(), MemberDefMutable::setDefinition(), DefinitionMutable::setDocumentation(), MemberDefMutable::setEnumScope(), ClassDefMutable::setFileDef(), MemberDefMutable::setFileDef(), ClassDefMutable::setHasNamedVariable(), DefinitionMutable::setId(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setInitializer(), DefinitionMutable::setLanguage(), MemberDefMutable::setMaxInitLines(), MemberDefMutable::setMemberClass(), MemberDefMutable::setMemberGroupId(), MemberDefMutable::setMemberSpecifiers(), MemberDefMutable::setNamespace(), DefinitionMutable::setOuterScope(), MemberDefMutable::setRequiresClause(), MemberDefMutable::setVhdlSpecifiers(), DString::str(), toClassDefMutable(), toDefinitionMutable(), toFileDef(), toMemberDefMutable(), toNamespaceDefMutable(), Definition::TypeClass, Definition::TypeFile, and Definition::TypeNamespace.

Referenced by processTagLessClassesForList().

◆ createTemplateInstanceMembers()

void createTemplateInstanceMembers ( )
static

Definition at line 8823 of file doxygen.cpp.

8824{
8825 // for each class
8826 for (const auto &cd : *Doxygen::classLinkedMap)
8827 {
8828 // that is a template
8829 for (const auto &ti : cd->getTemplateInstances())
8830 {
8831 ClassDefMutable *tcdm = toClassDefMutable(ti.classDef);
8832 if (tcdm && tcdm->isImplicitTemplateInstance()) // (partial) specializations have their own members
8833 {
8834 tcdm->addMembersToTemplateInstance(cd.get(),cd->templateArguments(),ti.templSpec);
8835 }
8836 }
8837 }
8838}
virtual void addMembersToTemplateInstance(const ClassDef *cd, const ArgumentList &templateArguments, const DString &templSpec)=0

References ClassDefMutable::addMembersToTemplateInstance(), Doxygen::classLinkedMap, ClassDef::isImplicitTemplateInstance(), and toClassDefMutable().

Referenced by parseInput().

◆ createUsingMemberImportForClass()

void createUsingMemberImportForClass ( const Entry * root,
ClassDefMutable * cd,
const MemberDef * md,
const DString & fileName,
const DString & memName )
static

Definition at line 2430 of file doxygen.cpp.

2432{
2433 AUTO_TRACE("creating new member {} for class {}",memName,cd->name());
2434 const ArgumentList &templAl = md->templateArguments();
2435 const ArgumentList &al = md->argumentList();
2436 auto newMd = createMemberDef(
2437 fileName,root->startLine,root->startColumn,
2438 md->typeString(),memName,md->argsString(),
2439 md->excpString(),root->protection,root->virt,
2440 md->isStatic(),Relationship::Member,md->memberType(),
2441 templAl,al,root->metaData
2442 );
2443 auto newMmd = toMemberDefMutable(newMd.get());
2444 newMmd->setMemberClass(cd);
2445 cd->insertMember(newMd.get());
2446 if (!root->doc.empty() || !root->brief.empty())
2447 {
2448 newMmd->setDocumentation(root->doc,root->docFile,root->docLine);
2449 newMmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2450 newMmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2451 }
2452 else
2453 {
2454 newMmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
2455 newMmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
2456 newMmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
2457 }
2458 newMmd->setDefinition(md->definition());
2459 applyMemberOverrideOptions(root,newMmd);
2460 newMmd->addQualifiers(root->qualifiers);
2461 newMmd->setBitfields(md->bitfieldString());
2462 newMmd->addSectionsToDefinition(root->anchors);
2463 newMmd->setBodySegment(md->getDefLine(),md->getStartBodyLine(),md->getEndBodyLine());
2464 newMmd->setBodyDef(md->getBodyDef());
2465 newMmd->setInitializer(md->initializer());
2466 newMmd->setRequiresClause(md->requiresClause());
2467 newMmd->setMaxInitLines(md->initializerLines());
2468 newMmd->setMemberGroupId(root->mGrpId);
2469 newMmd->setMemberSpecifiers(md->getMemberSpecifiers());
2470 newMmd->setVhdlSpecifiers(md->getVhdlSpecifiers());
2471 newMmd->setLanguage(root->lang);
2472 newMmd->setId(root->id);
2474 mn->push_back(std::move(newMd));
2475}
virtual DString inbodyFile() const =0
virtual int inbodyLine() const =0
virtual DString definition() const =0
virtual DString excpString() const =0
virtual VhdlSpecifier getVhdlSpecifiers() const =0
virtual DString bitfieldString() const =0
virtual TypeSpecifier getMemberSpecifiers() const =0
virtual int initializerLines() const =0

References LinkedMap< T, Hash, KeyEqual, Map >::add(), Entry::anchors, applyMemberOverrideOptions(), MemberDef::argsString(), MemberDef::argumentList(), AUTO_TRACE, MemberDef::bitfieldString(), Entry::brief, Definition::briefDescription(), Definition::briefFile(), Entry::briefFile, Definition::briefLine(), Entry::briefLine, createMemberDef(), MemberDef::definition(), Entry::doc, Definition::docFile(), Entry::docFile, Definition::docLine(), Entry::docLine, Definition::documentation(), DString::empty(), MemberDef::excpString(), Definition::getBodyDef(), Definition::getDefLine(), Definition::getEndBodyLine(), MemberDef::getMemberSpecifiers(), Definition::getStartBodyLine(), MemberDef::getVhdlSpecifiers(), Entry::id, Entry::inbodyDocs, Definition::inbodyDocumentation(), Definition::inbodyFile(), Entry::inbodyFile, Definition::inbodyLine(), Entry::inbodyLine, MemberDef::initializer(), MemberDef::initializerLines(), ClassDefMutable::insertMember(), MemberDef::isStatic(), Entry::lang, Doxygen::memberNameLinkedMap, MemberDef::memberType(), Entry::metaData, Entry::mGrpId, Definition::name(), Entry::protection, MemberName::push_back(), Entry::qualifiers, MemberDef::requiresClause(), Entry::startColumn, Entry::startLine, MemberDef::templateArguments(), toMemberDefMutable(), MemberDef::typeString(), and Entry::virt.

Referenced by findUsingDeclImports().

◆ devUsage()

void devUsage ( )
static

Definition at line 11584 of file doxygen.cpp.

11585{
11587 msg("Developer parameters:\n");
11588 msg(" -m dump symbol map\n");
11589 msg(" -b making messages output unbuffered\n");
11590 msg(" -c <file> process input file as a comment block and produce HTML output\n");
11591#if ENABLE_TRACING
11592 msg(" -t [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout)\n");
11593 msg(" -t_time [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout),\n"
11594 " and include time and thread information\n");
11595#endif
11596 msg(" -d <level> enable a debug level, such as (multiple invocations of -d are possible):\n");
11598}
@ Time
Definition debug.h:36
static void printFlags()
Definition debug.cpp:137
static void clearFlag(const DebugMask mask)
Definition debug.cpp:122

References Debug::clearFlag(), msg, Debug::printFlags(), and Debug::Time.

Referenced by readConfiguration().

◆ distributeClassGroupRelations()

void distributeClassGroupRelations ( )

Definition at line 1511 of file doxygen.cpp.

1512{
1513 //bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
1514 //if (!inlineGroupedClasses) return;
1515 //printf("** distributeClassGroupRelations()\n");
1516
1517 ClassDefSet visitedClasses;
1518 for (const auto &cd : *Doxygen::classLinkedMap)
1519 {
1520 //printf("Checking %s\n",qPrint(cd->name()));
1521 // distribute the group to nested classes as well
1522 if (visitedClasses.find(cd.get())==visitedClasses.end() && !cd->partOfGroups().empty())
1523 {
1524 //printf(" Candidate for merging\n");
1525 GroupDef *gd = cd->partOfGroups().front();
1526 for (auto &ncd : cd->getClasses())
1527 {
1529 if (ncdm && ncdm->partOfGroups().empty())
1530 {
1531 //printf(" Adding %s to group '%s'\n",qPrint(ncd->name()),
1532 // gd->groupTitle());
1533 ncdm->makePartOfGroup(gd);
1534 gd->addClass(ncdm);
1535 }
1536 }
1537 visitedClasses.insert(cd.get()); // only visit every class once
1538 }
1539 }
1540}
virtual bool addClass(ClassDef *def)=0
std::unordered_set< const ClassDef * > ClassDefSet
Definition classdef.h:91

References GroupDef::addClass(), Doxygen::classLinkedMap, DefinitionMutable::makePartOfGroup(), Definition::partOfGroups(), and toClassDefMutable().

◆ distributeConceptGroups()

void distributeConceptGroups ( )
static

Definition at line 1358 of file doxygen.cpp.

1359{
1360 AUTO_TRACE();
1361 for (const auto &cd : *Doxygen::conceptLinkedMap)
1362 {
1363 if (cd->groupId()!=DOX_NOGROUP)
1364 {
1365 for (const auto &ocd : *Doxygen::conceptLinkedMap)
1366 {
1367 if (cd!=ocd && cd->groupId()==ocd->groupId() &&
1368 !cd->partOfGroups().empty() && ocd->partOfGroups().empty())
1369 {
1370 ConceptDefMutable *ocdm = toConceptDefMutable(ocd.get());
1371 if (ocdm)
1372 {
1373 for (const auto &gd : cd->partOfGroups())
1374 {
1375 if (gd)
1376 {
1377 AUTO_TRACE_ADD("making concept '{}' part of group '{}'",ocdm->name(),gd->name());
1378 ocdm->makePartOfGroup(gd);
1379 gd->addConcept(ocd.get());
1380 }
1381 }
1382 }
1383 }
1384 }
1385 }
1386 }
1387}
#define DOX_NOGROUP
Definition membergroup.h:26

References AUTO_TRACE, AUTO_TRACE_ADD, Doxygen::conceptLinkedMap, DOX_NOGROUP, DefinitionMutable::makePartOfGroup(), Definition::name(), and toConceptDefMutable().

Referenced by parseInput().

◆ distributeMemberGroupDocumentation()

void distributeMemberGroupDocumentation ( )
static

Definition at line 9639 of file doxygen.cpp.

9640{
9641 // for each class
9642 for (const auto &cd : *Doxygen::classLinkedMap)
9643 {
9644 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9645 if (cdm)
9646 {
9648 }
9649 }
9650 // for each file
9651 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9652 {
9653 for (const auto &fd : *fn)
9654 {
9655 fd->distributeMemberGroupDocumentation();
9656 }
9657 }
9658 // for each namespace
9659 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9660 {
9662 if (ndm)
9663 {
9665 }
9666 }
9667 // for each group
9668 for (const auto &gd : *Doxygen::groupLinkedMap)
9669 {
9670 gd->distributeMemberGroupDocumentation();
9671 }
9673}
virtual void distributeMemberGroupDocumentation()=0
void distributeMemberGroupDocumentation()
virtual void distributeMemberGroupDocumentation()=0

References Doxygen::classLinkedMap, ClassDefMutable::distributeMemberGroupDocumentation(), ModuleManager::distributeMemberGroupDocumentation(), NamespaceDefMutable::distributeMemberGroupDocumentation(), Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), Doxygen::namespaceLinkedMap, toClassDefMutable(), and toNamespaceDefMutable().

Referenced by parseInput().

◆ dumpSymbol()

void dumpSymbol ( TextStream & t,
Definition * d )
static

Definition at line 11543 of file doxygen.cpp.

11544{
11545 DString anchor;
11547 {
11548 MemberDef *md = toMemberDef(d);
11549 anchor=":"+md->anchor();
11550 }
11551 DString scope;
11552 DString fn = d->getOutputFileBase();
11555 {
11556 scope = fn;
11557 }
11558 t << "REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
11559 << fn+anchor << "','"
11560 << scope << "','"
11561 << d->name() << "','"
11562 << d->getDefFileName() << "','"
11563 << d->getDefLine()
11564 << "');\n";
11565}
virtual DString anchor() const =0
virtual DString getOutputFileBase() const =0
MemberDef * toMemberDef(Definition *d)
void addHtmlExtensionIfMissing(DString &fName)
Definition util.cpp:3937

References addHtmlExtensionIfMissing(), Definition::anchor(), Definition::definitionType(), Definition::getDefFileName(), Definition::getDefLine(), Definition::getOuterScope(), Definition::getOutputFileBase(), Doxygen::globalScope, Definition::name(), toMemberDef(), and Definition::TypeMember.

Referenced by dumpSymbolMap().

◆ dumpSymbolMap()

void dumpSymbolMap ( )
static

Definition at line 11567 of file doxygen.cpp.

11568{
11569 std::ofstream f = Portable::openOutputStream("symbols.sql");
11570 if (f.is_open())
11571 {
11572 TextStream t(&f);
11573 for (const auto &[name,symList] : *Doxygen::symbolMap)
11574 {
11575 for (const auto &def : symList)
11576 {
11577 dumpSymbol(t,def);
11578 }
11579 }
11580 }
11581}
static void dumpSymbol(TextStream &t, Definition *d)
std::ofstream openOutputStream(const DString &name, bool append=false)
Definition portable.cpp:681

References dumpSymbol(), Portable::openOutputStream(), and Doxygen::symbolMap.

Referenced by generateOutput().

◆ exitDoxygen()

void exitDoxygen ( )
staticnoexcept

Definition at line 12475 of file doxygen.cpp.

12476{
12477 if (!g_successfulRun) // premature exit
12478 {
12479 Dir thisDir;
12480 msg("Exiting...\n");
12481 if (!Doxygen::filterDBFileName.empty())
12482 {
12483 thisDir.remove(Doxygen::filterDBFileName.str());
12484 }
12485 }
12486}
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:320
static DString filterDBFileName
Definition doxygen.h:124
static bool g_successfulRun
Definition doxygen.cpp:194

References Doxygen::filterDBFileName, g_successfulRun, msg, and Dir::remove().

Referenced by parseInput().

◆ extractClassName()

DString extractClassName ( const Entry * root)
static

Definition at line 5527 of file doxygen.cpp.

5528{
5529 // strip any anonymous scopes first
5532 if (size_t i=bName.find('<'); (root->lang==SrcLangExt::CSharp || root->lang==SrcLangExt::Java) && i!=DString::npos)
5533 {
5534 // a Java/C# generic class looks like a C++ specialization, so we need to strip the
5535 // template part before looking for matches
5536 if (root->lang==SrcLangExt::CSharp)
5537 {
5538 bName = mangleCSharpGenericName(root->name);
5539 }
5540 else
5541 {
5542 bName = bName.left(i);
5543 }
5544 }
5545 return bName;
5546}

References DString::find(), Entry::lang, DString::left(), mangleCSharpGenericName(), Entry::name, DString::npos, stripAnonymousNamespaceScope(), and stripTemplateSpecifiersFromScope().

Referenced by computeClassRelations(), findInheritedTemplateInstances(), and findUsedTemplateInstances().

◆ filterMemberDocumentation()

void filterMemberDocumentation ( const Entry * root,
const DString & relates )
static

Definition at line 7620 of file doxygen.cpp.

7621{
7622 AUTO_TRACE("root->type='{}' root->inside='{}' root->name='{}' root->args='{}' section={} root->spec={} root->mGrpId={}",
7623 root->type,root->inside,root->name,root->args,root->section,root->spec,root->mGrpId);
7624 //printf("root->parent()->name=%s\n",qPrint(root->parent()->name));
7625 bool isFunc=true;
7626
7627 DString type = root->type;
7628 DString args = root->args;
7629 int i=-1, l=0;
7630 if ( // detect func variable/typedef to func ptr
7631 (i=findFunctionPtr(type.str(),root->lang,&l))!=-1
7632 )
7633 {
7634 //printf("Fixing function pointer!\n");
7635 // fix type and argument
7636 args.prepend(type.mid(i+l));
7637 type=type.left(i+l);
7638 //printf("Results type=%s,name=%s,args=%s\n",qPrint(type),qPrint(root->name),qPrint(args));
7639 isFunc=false;
7640 }
7641 else if ((type.startsWith("typedef ") && args.find('(')!=DString::npos))
7642 // detect function types marked as functions
7643 {
7644 isFunc=false;
7645 }
7646
7647 //printf("Member %s isFunc=%d\n",qPrint(root->name),isFunc);
7648 if (root->section.isMemberDoc())
7649 {
7650 //printf("Documentation for inline member '%s' found args='%s'\n",
7651 // qPrint(root->name),qPrint(args));
7652 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7653 if (type.empty())
7654 {
7655 findMember(root,
7656 relates,
7657 type,
7658 args,
7659 root->name + args + root->exception,
7660 false,
7661 isFunc);
7662 }
7663 else
7664 {
7665 findMember(root,
7666 relates,
7667 type,
7668 args,
7669 type + " " + root->name + args + root->exception,
7670 false,
7671 isFunc);
7672 }
7673 }
7674 else if (root->section.isOverloadDoc())
7675 {
7676 //printf("Overloaded member %s found\n",qPrint(root->name));
7677 findMember(root,
7678 relates,
7679 type,
7680 args,
7681 root->name,
7682 true,
7683 isFunc);
7684 }
7685 else if
7686 ((root->section.isFunction() // function
7687 ||
7688 (root->section.isVariable() && // variable
7689 !type.empty() && // with a type
7690 g_compoundKeywords.find(type.str())==g_compoundKeywords.end() // that is not a keyword
7691 // (to skip forward declaration of class etc.)
7692 )
7693 )
7694 )
7695 {
7696 //printf("Documentation for member '%s' found args='%s' excp='%s'\n",
7697 // qPrint(root->name),qPrint(args),qPrint(root->exception));
7698 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7699 //printf("Inside=%s\n Relates=%s\n",qPrint(root->inside),qPrint(relates));
7700 if (isTypeAClassFriend(type))
7701 {
7702 findMember(root,
7703 relates,
7704 type,
7705 args,
7706 type+" "+root->name,
7707 false,false);
7708
7709 }
7710 else if (!type.empty())
7711 {
7712 findMember(root,
7713 relates,
7714 type,
7715 args,
7716 type+" "+ root->inside + root->name + args + root->exception,
7717 false,isFunc);
7718 }
7719 else
7720 {
7721 findMember(root,
7722 relates,
7723 type,
7724 args,
7725 root->inside + root->name + args + root->exception,
7726 false,isFunc);
7727 }
7728 }
7729 else if (root->section.isDefine() && !relates.empty())
7730 {
7731 findMember(root,
7732 relates,
7733 type,
7734 args,
7735 root->name + args,
7736 false,
7737 !args.empty());
7738 }
7739 else if (root->section.isVariableDoc())
7740 {
7741 //printf("Documentation for variable %s found\n",qPrint(root->name));
7742 //if (!relates.empty()) printf(" Relates %s\n",qPrint(relates));
7743 findMember(root,
7744 relates,
7745 type,
7746 args,
7747 root->name,
7748 false,
7749 false);
7750 }
7751 else if (root->section.isExportedInterface() ||
7752 root->section.isIncludedService())
7753 {
7754 findMember(root,
7755 relates,
7756 type,
7757 args,
7758 type + " " + root->name,
7759 false,
7760 false);
7761 }
7762 else
7763 {
7764 // skip section
7765 //printf("skip section\n");
7766 }
7767}
DString inside
name of the class in which documents are found
Definition entry.h:213
static void findMember(const Entry *root, const DString &relates, const DString &type, const DString &args, DString funcDecl, bool overloaded, bool isFunc)
Definition doxygen.cpp:6993

References Entry::args, AUTO_TRACE, DString::empty(), Entry::exception, DString::find(), findFunctionPtr(), findMember(), g_compoundKeywords, Entry::inside, isTypeAClassFriend(), Entry::lang, DString::left(), Entry::mGrpId, DString::mid(), Entry::name, DString::npos, DString::prepend(), Entry::section, Entry::spec, DString::startsWith(), DString::str(), and Entry::type.

Referenced by findMemberDocumentation().

◆ findBaseClassesForClass()

void findBaseClassesForClass ( const Entry * root,
Definition * context,
ClassDefMutable * masterCd,
ClassDefMutable * instanceCd,
FindBaseClassRelation_Mode mode,
bool isArtificial,
const ArgumentList * actualArgs = nullptr,
const TemplateNameMap & templateNames = TemplateNameMap() )
static

Definition at line 4982 of file doxygen.cpp.

4992{
4993 AUTO_TRACE("name={}",root->name);
4994 // The base class could ofcouse also be a non-nested class
4995 const ArgumentList &formalArgs = masterCd->templateArguments();
4996 for (const BaseInfo &bi : root->extends)
4997 {
4998 //printf("masterCd=%s bi.name='%s' #actualArgs=%d\n",
4999 // qPrint(masterCd->localName()),qPrint(bi.name),actualArgs ? (int)actualArgs->size() : -1);
5000 TemplateNameMap formTemplateNames;
5001 if (templateNames.empty())
5002 {
5003 formTemplateNames = getTemplateArgumentsInName(formalArgs,bi.name.str());
5004 }
5005 BaseInfo tbi = bi;
5006 tbi.name = substituteTemplateArgumentsInString(bi.name,formalArgs,actualArgs);
5007 //printf("masterCd=%p instanceCd=%p bi->name=%s tbi.name=%s\n",(void*)masterCd,(void*)instanceCd,qPrint(bi.name),qPrint(tbi.name));
5008
5009 if (mode==DocumentedOnly)
5010 {
5011 // find a documented base class in the correct scope
5012 if (!findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,DocumentedOnly,isArtificial))
5013 {
5014 // 1.8.2: decided to show inheritance relations even if not documented,
5015 // we do make them artificial, so they do not appear in the index
5016 //if (!Config_getBool(HIDE_UNDOC_RELATIONS))
5017 bool b = Config_getBool(HIDE_UNDOC_RELATIONS) ? true : isArtificial;
5018 //{
5019 // no documented base class -> try to find an undocumented one
5020 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,Undocumented,b);
5021 //}
5022 }
5023 }
5024 else if (mode==TemplateInstances)
5025 {
5026 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,TemplateInstances,isArtificial);
5027 }
5028 }
5029}

References AUTO_TRACE, Config_getBool, DocumentedOnly, Entry::extends, findClassRelation(), getTemplateArgumentsInName(), BaseInfo::name, Entry::name, DString::str(), substituteTemplateArgumentsInString(), ClassDef::templateArguments(), TemplateInstances, and Undocumented.

Referenced by computeClassRelations(), findInheritedTemplateInstances(), and findTemplateInstanceRelation().

◆ findClassDefinition()

const ClassDef * findClassDefinition ( FileDef * fd,
NamespaceDef * nd,
const DString & scopeName )
static

Definition at line 5992 of file doxygen.cpp.

5994{
5995 SymbolResolver resolver(fd);
5996 const ClassDef *tcd = resolver.resolveClass(nd,scopeName,true,true);
5997 //printf("findClassDefinition(fd=%s,ns=%s,scopeName=%s)='%s'\n",
5998 // qPrint(fd?fd->name():""),qPrint(nd?nd->name():""),
5999 // qPrint(scopeName),qPrint(tcd?tcd->name():""));
6000 return tcd;
6001}

References SymbolResolver::resolveClass().

Referenced by addMemberFunction().

◆ findClassEntries()

void findClassEntries ( const Entry * root)
static

Builds a dictionary of all entry nodes in the tree starting with root

Definition at line 5518 of file doxygen.cpp.

5519{
5520 if (isClassSection(root))
5521 {
5522 g_classEntries.emplace(root->name.str(),root);
5523 }
5524 for (const auto &e : root->children()) findClassEntries(e.get());
5525}
static void findClassEntries(const Entry *root)
Definition doxygen.cpp:5518
static bool isClassSection(const Entry *root)
Definition doxygen.cpp:5496

References Entry::children(), findClassEntries(), g_classEntries, isClassSection(), Entry::name, and DString::str().

Referenced by findClassEntries(), and parseInput().

◆ findClassRelation()

bool findClassRelation ( const Entry * root,
Definition * context,
ClassDefMutable * cd,
const BaseInfo * bi,
const TemplateNameMap & templateNames,
FindBaseClassRelation_Mode mode,
bool isArtificial )
static

Definition at line 5154 of file doxygen.cpp.

5163{
5164 AUTO_TRACE("name={} base={} isArtificial={} mode={}",cd->name(),bi->name,isArtificial,(int)mode);
5165
5166 DString biName=bi->name;
5167 bool explicitGlobalScope=false;
5168 if (biName.startsWith("::")) // explicit global scope
5169 {
5170 biName=biName.mid(2);
5171 explicitGlobalScope=true;
5172 }
5173
5174 Entry *parentNode=root->parent();
5175 bool lastParent=false;
5176 do // for each parent scope, starting with the largest scope
5177 // (in case of nested classes)
5178 {
5179 DString scopeName= parentNode ? parentNode->name : DString();
5180 int scopeOffset=explicitGlobalScope ? 0 : static_cast<int>(scopeName.length());
5181 do // try all parent scope prefixes, starting with the largest scope
5182 {
5183 //printf("scopePrefix='%s' biName='%s'\n",
5184 // qPrint(scopeName.left(scopeOffset)),qPrint(biName));
5185
5186 DString baseClassName=biName;
5187 if (scopeOffset>0)
5188 {
5189 baseClassName.prepend(scopeName.left(scopeOffset)+"::");
5190 }
5191 if (root->lang==SrcLangExt::CSharp)
5192 {
5193 baseClassName = mangleCSharpGenericName(baseClassName);
5194 }
5195 AUTO_TRACE_ADD("cd='{}' baseClassName='{}'",cd->name(),baseClassName);
5196 SymbolResolver resolver(cd->getFileDef());
5197 ClassDefMutable *baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
5198 baseClassName,
5199 mode==Undocumented,
5200 true
5201 );
5202 const MemberDef *baseClassTypeDef = resolver.getTypedef();
5203 DString templSpec = resolver.getTemplateSpec();
5204 //printf("baseClassName=%s baseClass=%p cd=%p explicitGlobalScope=%d\n",
5205 // qPrint(baseClassName),baseClass,cd,explicitGlobalScope);
5206 //printf(" scope='%s' baseClassName='%s' baseClass=%s templSpec=%s\n",
5207 // cd ? qPrint(cd->name()):"<none>",
5208 // qPrint(baseClassName),
5209 // baseClass?qPrint(baseClass->name()):"<none>",
5210 // qPrint(templSpec)
5211 // );
5212 //if (baseClassName.left(root->name.length())!=root->name ||
5213 // baseClassName.at(root->name.length())!='<'
5214 // ) // Check for base class with the same name.
5215 // // If found then look in the outer scope for a match
5216 // // and prevent recursion.
5217 if (!isRecursiveBaseClass(root->name,baseClassName)
5218 || explicitGlobalScope
5219 // sadly isRecursiveBaseClass always true for UNO IDL ifc/svc members
5220 // (i.e. this is needed for addInterfaceOrServiceToServiceOrSingleton)
5221 || (root->lang==SrcLangExt::IDL &&
5222 (root->section.isExportedInterface() ||
5223 root->section.isIncludedService()))
5224 )
5225 {
5226 AUTO_TRACE_ADD("class relation '{}' inherited/used by '{}' found prot={} virt={} templSpec='{}'",
5227 baseClassName, root->name, bi->prot, bi->virt, templSpec);
5228
5229 int i=findTemplateSpecializationPosition(baseClassName);
5230 size_t si=baseClassName.rfind("::",i);
5231 if (si==DString::npos) si=0;
5232 if (baseClass==nullptr && static_cast<size_t>(i)!=baseClassName.length())
5233 // base class has template specifiers
5234 {
5235 // TODO: here we should try to find the correct template specialization
5236 // but for now, we only look for the unspecialized base class.
5237 int e=findEndOfTemplate(baseClassName,i+1);
5238 //printf("baseClass==0 i=%d e=%d\n",i,e);
5239 if (e!=-1) // end of template was found at e
5240 {
5241 templSpec = removeRedundantWhiteSpace(baseClassName.mid(i,e-i));
5242 baseClassName = baseClassName.left(i)+baseClassName.mid(e);
5243 baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
5244 baseClassName,
5245 mode==Undocumented,
5246 true
5247 );
5248 baseClassTypeDef = resolver.getTypedef();
5249 //printf("baseClass=%p -> baseClass=%s templSpec=%s\n",
5250 // baseClass,qPrint(baseClassName),qPrint(templSpec));
5251 }
5252 }
5253 else if (baseClass && !templSpec.empty()) // we have a known class, but also
5254 // know it is a template, so see if
5255 // we can also link to the explicit
5256 // instance (for instance if a class
5257 // derived from a template argument)
5258 {
5259 //printf("baseClass=%s templSpec=%s\n",qPrint(baseClass->name()),qPrint(templSpec));
5260 ClassDefMutable *templClass=getClassMutable(baseClass->name()+templSpec);
5261 if (templClass)
5262 {
5263 // use the template instance instead of the template base.
5264 baseClass = templClass;
5265 templSpec.clear();
5266 }
5267 }
5268
5269 //printf("cd=%p baseClass=%p\n",cd,baseClass);
5270 bool found=baseClass!=nullptr && (baseClass!=cd || mode==TemplateInstances);
5271 AUTO_TRACE_ADD("1. found={}",found);
5272 if (!found && si!=DString::npos)
5273 {
5274 // replace any namespace aliases
5275 replaceNamespaceAliases(baseClassName);
5276 baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
5277 baseClassName,
5278 mode==Undocumented,
5279 true
5280 );
5281 baseClassTypeDef = resolver.getTypedef();
5282 found=baseClass!=nullptr && baseClass!=cd;
5283 if (found) templSpec = resolver.getTemplateSpec();
5284 }
5285 AUTO_TRACE_ADD("2. found={}",found);
5286
5287 if (!found)
5288 {
5289 baseClass=toClassDefMutable(findClassWithinClassContext(context,cd,baseClassName));
5290 //printf("findClassWithinClassContext(%s,%s)=%p\n",
5291 // qPrint(cd->name()),qPrint(baseClassName),baseClass);
5292 found = baseClass!=nullptr && baseClass!=cd;
5293
5294 }
5295 AUTO_TRACE_ADD("3. found={}",found);
5296 if (!found)
5297 {
5298 // for PHP the "use A\B as C" construct map class C to A::B, so we lookup
5299 // the class name also in the alias mapping.
5300 auto it = Doxygen::namespaceAliasMap.find(baseClassName.str());
5301 if (it!=Doxygen::namespaceAliasMap.end()) // see if it is indeed a class.
5302 {
5303 baseClass=getClassMutable(it->second.alias);
5304 found = baseClass!=nullptr && baseClass!=cd;
5305 }
5306 }
5307 bool isATemplateArgument = templateNames.find(biName.str())!=templateNames.end();
5308
5309 AUTO_TRACE_ADD("4. found={}",found);
5310 if (found)
5311 {
5312 AUTO_TRACE_ADD("Documented base class '{}' templSpec='{}'",biName,templSpec);
5313 // add base class to this class
5314
5315 // if templSpec is not empty then we should "instantiate"
5316 // the template baseClass. A new ClassDef should be created
5317 // to represent the instance. To be able to add the (instantiated)
5318 // members and documentation of a template class
5319 // (inserted in that template class at a later stage),
5320 // the template should know about its instances.
5321 // the instantiation process, should be done in a recursive way,
5322 // since instantiating a template may introduce new inheritance
5323 // relations.
5324 if (!templSpec.empty() && mode==TemplateInstances)
5325 {
5326 // if baseClass is actually a typedef then we should not
5327 // instantiate it, since typedefs are in a different namespace
5328 // see bug531637 for an example where this would otherwise hang
5329 // Doxygen
5330 if (baseClassTypeDef==nullptr)
5331 {
5332 //printf(" => findTemplateInstanceRelation: %s\n",qPrint(baseClass->name()));
5333 findTemplateInstanceRelation(root,context,baseClass,templSpec,templateNames,baseClass->isArtificial());
5334 }
5335 }
5336 else if (mode==DocumentedOnly || mode==Undocumented)
5337 {
5338 //printf(" => insert base class\n");
5339 DString usedName;
5340 if (baseClassTypeDef)
5341 {
5342 usedName=biName;
5343 //printf("***** usedName=%s templSpec=%s\n",qPrint(usedName),qPrint(templSpec));
5344 }
5345 Protection prot = bi->prot;
5346 if (Config_getBool(SIP_SUPPORT)) prot=Protection::Public;
5347 if (cd!=baseClass && !cd->isSubClass(baseClass) && baseClass->isBaseClass(cd,true,templSpec)==0) // check for recursion, see bug690787
5348 {
5349 AUTO_TRACE_ADD("insertBaseClass name={} prot={} virt={} templSpec={}",usedName,prot,bi->virt,templSpec);
5350 cd->insertBaseClass(baseClass,usedName,prot,bi->virt,templSpec);
5351 // add this class as super class to the base class
5352 baseClass->insertSubClass(cd,prot,bi->virt,templSpec);
5353 }
5354 else
5355 {
5356 warn(root->fileName,root->startLine,
5357 "Detected potential recursive class relation "
5358 "between class {} and base class {}!",
5359 cd->name(),baseClass->name()
5360 );
5361 }
5362 }
5363 return true;
5364 }
5365 else if (mode==Undocumented && (scopeOffset==0 || isATemplateArgument))
5366 {
5367 AUTO_TRACE_ADD("New undocumented base class '{}' baseClassName='{}' templSpec='{}' isArtificial={}",
5368 biName,baseClassName,templSpec,isArtificial);
5369 baseClass=nullptr;
5370 if (isATemplateArgument)
5371 {
5372 baseClass = toClassDefMutable(Doxygen::hiddenClassLinkedMap->find(baseClassName));
5373 if (baseClass==nullptr) // not found (or alias)
5374 {
5375 baseClass= toClassDefMutable(
5376 Doxygen::hiddenClassLinkedMap->add(baseClassName,
5377 createClassDef(root->fileName,root->startLine,root->startColumn,
5378 baseClassName,
5379 ClassDef::Class)));
5380 if (baseClass) // really added (not alias)
5381 {
5382 if (isArtificial) baseClass->setArtificial(true);
5383 baseClass->setLanguage(root->lang);
5384 }
5385 }
5386 }
5387 else
5388 {
5389 baseClass = toClassDefMutable(Doxygen::classLinkedMap->find(baseClassName));
5390 //printf("*** classDDict->find(%s)=%p biName=%s templSpec=%s\n",
5391 // qPrint(baseClassName),baseClass,qPrint(biName),qPrint(templSpec));
5392 if (baseClass==nullptr) // not found (or alias)
5393 {
5394 baseClass = toClassDefMutable(
5395 Doxygen::classLinkedMap->add(baseClassName,
5396 createClassDef(root->fileName,root->startLine,root->startColumn,
5397 baseClassName,
5398 ClassDef::Class)));
5399 if (baseClass) // really added (not alias)
5400 {
5401 if (isArtificial) baseClass->setArtificial(true);
5402 baseClass->setLanguage(root->lang);
5403 si = baseClassName.rfind("::");
5404 if (si!=DString::npos) // class is nested
5405 {
5406 Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),nullptr,root->tagInfo());
5407 if (sd==nullptr || sd==Doxygen::globalScope) // outer scope not found
5408 {
5409 baseClass->setArtificial(true); // see bug678139
5410 }
5411 }
5412 }
5413 }
5414 }
5415 if (baseClass)
5416 {
5417 if (biName.endsWith("-p"))
5418 {
5419 biName="<"+biName.left(biName.length()-2)+">";
5420 }
5421 if (!cd->isSubClass(baseClass) && cd!=baseClass && cd->isBaseClass(baseClass,true,templSpec)==0) // check for recursion
5422 {
5423 AUTO_TRACE_ADD("insertBaseClass name={} prot={} virt={} templSpec={}",biName,bi->prot,bi->virt,templSpec);
5424 // add base class to this class
5425 cd->insertBaseClass(baseClass,biName,bi->prot,bi->virt,templSpec);
5426 // add this class as super class to the base class
5427 baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
5428 }
5429 // the undocumented base was found in this file
5430 baseClass->insertUsedFile(root->fileDef());
5431
5432 Definition *scope = buildScopeFromQualifiedName(baseClass->name(),root->lang,nullptr);
5433 if (scope!=baseClass)
5434 {
5435 baseClass->setOuterScope(scope);
5436 }
5437
5438 if (baseClassName.endsWith("-p"))
5439 {
5441 }
5442 return true;
5443 }
5444 else
5445 {
5446 AUTO_TRACE_ADD("Base class '{}' not created (alias?)",biName);
5447 }
5448 }
5449 else
5450 {
5451 AUTO_TRACE_ADD("Base class '{}' not found",biName);
5452 }
5453 }
5454 else
5455 {
5456 if (mode!=TemplateInstances)
5457 {
5458 warn(root->fileName,root->startLine,
5459 "Detected potential recursive class relation "
5460 "between class {} and base class {}!",
5461 root->name,baseClassName
5462 );
5463 }
5464 // for mode==TemplateInstance this case is quite common and
5465 // indicates a relation between a template class and a template
5466 // instance with the same name.
5467 }
5468 if (scopeOffset==0)
5469 {
5470 scopeOffset=-1;
5471 }
5472 else
5473 {
5474 size_t o = scopeName.rfind("::",scopeOffset-1);
5475 scopeOffset = o!=DString::npos ? static_cast<int>(o) : 0;
5476 }
5477 //printf("new scopeOffset='%d'",scopeOffset);
5478 } while (scopeOffset>=0);
5479
5480 if (parentNode==nullptr)
5481 {
5482 lastParent=true;
5483 }
5484 else
5485 {
5486 parentNode=parentNode->parent();
5487 }
5488 } while (lastParent);
5489
5490 return false;
5491}
virtual int isBaseClass(const ClassDef *bcd, bool followInstances, const DString &templSpec=DString()) const =0
Returns true iff bcd is a direct or indirect base class of this class.
virtual bool isSubClass(ClassDef *bcd, int level=0) const =0
Returns true iff bcd is a direct or indirect sub class of this class.
virtual void insertSubClass(ClassDef *, Protection p, Specifier s, const DString &t=DString())=0
virtual void insertBaseClass(ClassDef *, const DString &name, Protection p, Specifier s, const DString &t=DString())=0
void clear()
Definition dstring.h:214
static NamespaceAliasInfoMap namespaceAliasMap
Definition doxygen.h:106
static int findTemplateSpecializationPosition(const DString &name)
Definition doxygen.cpp:5124
static ClassDef * findClassWithinClassContext(Definition *context, ClassDef *cd, const DString &name)
Definition doxygen.cpp:4791
static void findTemplateInstanceRelation(const Entry *root, Definition *context, ClassDefMutable *templateClass, const DString &templSpec, const TemplateNameMap &templateNames, bool isArtificial)
Definition doxygen.cpp:5033
static bool isRecursiveBaseClass(const DString &scope, const DString &name)
Definition doxygen.cpp:5113
void replaceNamespaceAliases(DString &name)
Protection prot
inheritance type
Definition entry.h:93
Specifier virt
virtualness
Definition entry.h:94
Protection
Definition types.h:32

References AUTO_TRACE, AUTO_TRACE_ADD, buildScopeFromQualifiedName(), ClassDef::Class, Doxygen::classLinkedMap, DString::clear(), Config_getBool, createClassDef(), DocumentedOnly, DString::empty(), end(), DString::endsWith(), Entry::fileDef(), Entry::fileName, findClassWithinClassContext(), findEndOfTemplate(), findScopeFromQualifiedName(), findTemplateInstanceRelation(), findTemplateSpecializationPosition(), getClassMutable(), ClassDef::getFileDef(), SymbolResolver::getTemplateSpec(), SymbolResolver::getTypedef(), Doxygen::globalScope, Doxygen::hiddenClassLinkedMap, ClassDefMutable::insertBaseClass(), ClassDefMutable::insertSubClass(), ClassDefMutable::insertUsedFile(), Definition::isArtificial(), ClassDef::isBaseClass(), isRecursiveBaseClass(), ClassDef::isSubClass(), Entry::lang, DString::left(), DString::length(), mangleCSharpGenericName(), DString::mid(), BaseInfo::name, Definition::name(), Entry::name, Doxygen::namespaceAliasMap, DString::npos, Entry::parent(), DString::prepend(), BaseInfo::prot, ClassDef::Protocol, removeRedundantWhiteSpace(), replaceNamespaceAliases(), SymbolResolver::resolveClassMutable(), DString::rfind(), Entry::section, DefinitionMutable::setArtificial(), ClassDefMutable::setCompoundType(), DefinitionMutable::setLanguage(), DefinitionMutable::setOuterScope(), Entry::startColumn, Entry::startLine, DString::startsWith(), DString::str(), Entry::tagInfo(), TemplateInstances, toClassDefMutable(), Undocumented, BaseInfo::virt, and warn.

Referenced by addInterfaceOrServiceToServiceOrSingleton(), computeTemplateClassRelations(), findBaseClassesForClass(), and findUsedClassesForClass().

◆ findClassWithinClassContext()

ClassDef * findClassWithinClassContext ( Definition * context,
ClassDef * cd,
const DString & name )
static

Searches a class from within context and cd and returns its definition if found (otherwise nullptr is returned).

Definition at line 4791 of file doxygen.cpp.

4792{
4793 ClassDef *result=nullptr;
4794 if (cd==nullptr)
4795 {
4796 return result;
4797 }
4798 FileDef *fd=cd->getFileDef();
4799 SymbolResolver resolver(fd);
4800 if (context && cd!=context)
4801 {
4802 result = const_cast<ClassDef*>(resolver.resolveClass(context,name,true,true));
4803 }
4804 //printf("1. result=%p\n",result);
4805 if (result==nullptr)
4806 {
4807 result = const_cast<ClassDef*>(resolver.resolveClass(cd,name,true,true));
4808 }
4809 //printf("2. result=%p\n",result);
4810 if (result==nullptr) // try direct class, needed for namespaced classes imported via tag files (see bug624095)
4811 {
4812 result = getClass(name);
4813 }
4814 //printf("3. result=%p\n",result);
4815 //printf("** Trying to find %s within context %s class %s result=%s lookup=%p\n",
4816 // qPrint(name),
4817 // context ? qPrint(context->name()) : "<none>",
4818 // cd ? qPrint(cd->name()) : "<none>",
4819 // result ? qPrint(result->name()) : "<none>",
4820 // Doxygen::classLinkedMap->find(name)
4821 // );
4822 return result;
4823}

References getClass(), ClassDef::getFileDef(), and SymbolResolver::resolveClass().

Referenced by findClassRelation(), and findUsedClassesForClass().

◆ findDefineDocumentation()

void findDefineDocumentation ( Entry * root)
static

Definition at line 9849 of file doxygen.cpp.

9850{
9851 if ((root->section.isDefineDoc() || root->section.isDefine()) && !root->name.empty())
9852 {
9853 //printf("found define '%s' '%s' brief='%s' doc='%s'\n",
9854 // qPrint(root->name),qPrint(root->args),qPrint(root->brief),qPrint(root->doc));
9855
9856 if (root->tagInfo() && !root->name.empty()) // define read from a tag file
9857 {
9858 auto md = createMemberDef(root->tagInfo()->tagName,1,1,
9859 "#define",root->name,root->args,DString(),
9860 Protection::Public,Specifier::Normal,false,Relationship::Member,MemberType::Define,
9861 ArgumentList(),ArgumentList(),"");
9862 auto mmd = toMemberDefMutable(md.get());
9863 mmd->setTagInfo(root->tagInfo());
9864 mmd->setLanguage(root->lang);
9865 mmd->addQualifiers(root->qualifiers);
9866 //printf("Searching for '%s' fd=%p\n",qPrint(filePathName),fd);
9867 mmd->setFileDef(root->parent()->fileDef());
9868 //printf("Adding member=%s\n",qPrint(md->name()));
9870 mn->push_back(std::move(md));
9871 }
9873 if (mn)
9874 {
9875 int count=0;
9876 for (const auto &md : *mn)
9877 {
9878 if (md->memberType()==MemberType::Define) count++;
9879 }
9880 if (count==1)
9881 {
9882 for (const auto &imd : *mn)
9883 {
9884 MemberDefMutable *md = toMemberDefMutable(imd.get());
9885 if (md && md->memberType()==MemberType::Define)
9886 {
9887 addDefineDoc(root,md);
9888 }
9889 }
9890 }
9891 else if (count>1 &&
9892 (!root->doc.empty() ||
9893 !root->brief.empty() ||
9894 root->bodyLine!=-1
9895 )
9896 )
9897 // multiple defines don't know where to add docs
9898 // but maybe they are in different files together with their documentation
9899 {
9900 for (const auto &imd : *mn)
9901 {
9902 MemberDefMutable *md = toMemberDefMutable(imd.get());
9903 if (md && md->memberType()==MemberType::Define)
9904 {
9905 if (haveEqualFileNames(root, md) || isEntryInGroupOfMember(root, md))
9906 // doc and define in the same file or group assume they belong together.
9907 {
9908 addDefineDoc(root,md);
9909 }
9910 }
9911 }
9912 //warn("define {} found in the following files:\n",root->name);
9913 //warn("Cannot determine where to add the documentation found "
9914 // "at line {} of file {}. \n",
9915 // root->startLine,root->fileName);
9916 }
9917 }
9918 else if (!root->doc.empty() || !root->brief.empty()) // define not found
9919 {
9920 bool preEnabled = Config_getBool(ENABLE_PREPROCESSING);
9921 if (preEnabled)
9922 {
9923 warn(root->fileName,root->startLine,"documentation for unknown define {} found.",root->name);
9924 }
9925 else
9926 {
9927 warn(root->fileName,root->startLine, "found documented #define {} but ignoring it because ENABLE_PREPROCESSING is NO.", root->name);
9928 }
9929 }
9930 }
9931 for (const auto &e : root->children()) findDefineDocumentation(e.get());
9932}
static void findDefineDocumentation(Entry *root)
Definition doxygen.cpp:9849
static void addDefineDoc(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:9822
static bool haveEqualFileNames(const Entry *root, const MemberDef *md)
Definition doxygen.cpp:9811
static bool isEntryInGroupOfMember(const Entry *root, const MemberDef *md, bool allowNoGroup=false)
Definition doxygen.cpp:6007

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addDefineDoc(), Entry::args, Entry::bodyLine, Entry::brief, Entry::children(), Config_getBool, createMemberDef(), Entry::doc, DString::empty(), Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), findDefineDocumentation(), Doxygen::functionNameLinkedMap, haveEqualFileNames(), isEntryInGroupOfMember(), Entry::lang, MemberDef::memberType(), Entry::name, Entry::parent(), MemberName::push_back(), Entry::qualifiers, Entry::section, Entry::startLine, Entry::tagInfo(), TagInfo::tagName, toMemberDefMutable(), and warn.

Referenced by findDefineDocumentation(), and parseInput().

◆ findDEV()

void findDEV ( const MemberNameLinkedMap & mnsd)
static

Definition at line 8411 of file doxygen.cpp.

8412{
8413 // for each member name
8414 for (const auto &mn : mnsd)
8415 {
8416 // for each member definition
8417 for (const auto &imd : *mn)
8418 {
8419 MemberDefMutable *md = toMemberDefMutable(imd.get());
8420 if (md && md->isEnumerate()) // member is an enum
8421 {
8422 int documentedEnumValues=0;
8423 // for each enum value
8424 for (const auto &fmd : md->enumFieldList())
8425 {
8426 if (fmd->isLinkableInProject()) documentedEnumValues++;
8427 }
8428 // at least one enum value is documented
8429 if (documentedEnumValues>0) md->setDocumentedEnumValues(true);
8430 }
8431 }
8432 }
8433}
virtual const MemberVector & enumFieldList() const =0
virtual void setDocumentedEnumValues(bool value)=0

References MemberDef::enumFieldList(), MemberDef::isEnumerate(), MemberDefMutable::setDocumentedEnumValues(), and toMemberDefMutable().

Referenced by findDocumentedEnumValues().

◆ findDirDocumentation()

void findDirDocumentation ( const Entry * root)
static

Definition at line 9936 of file doxygen.cpp.

9937{
9938 if (root->section.isDirDoc())
9939 {
9940 DString normalizedName = root->name;
9941 normalizedName = substitute(normalizedName,"\\","/");
9942 //printf("root->docFile=%s normalizedName=%s\n",
9943 // qPrint(root->docFile),qPrint(normalizedName));
9944 if (root->docFile==normalizedName) // current dir?
9945 {
9946 if (size_t lastSlashPos=normalizedName.rfind('/'); lastSlashPos!=DString::npos) // strip file name
9947 {
9948 normalizedName=normalizedName.left(lastSlashPos);
9949 }
9950 }
9951 if (normalizedName.at(normalizedName.length()-1)!='/')
9952 {
9953 normalizedName+='/';
9954 }
9955 DirDef *matchingDir=nullptr;
9956 for (const auto &dir : *Doxygen::dirLinkedMap)
9957 {
9958 //printf("Dir: %s<->%s\n",qPrint(dir->name()),qPrint(normalizedName));
9959 if (dir->name().right(normalizedName.length())==normalizedName)
9960 {
9961 if (matchingDir)
9962 {
9963 warn(root->fileName,root->startLine,
9964 "\\dir command matches multiple directories.\n"
9965 " Applying the command for directory {}\n"
9966 " Ignoring the command for directory {}",
9967 matchingDir->name(),dir->name()
9968 );
9969 }
9970 else
9971 {
9972 matchingDir=dir.get();
9973 }
9974 }
9975 }
9976 if (matchingDir)
9977 {
9978 //printf("Match for with dir %s #anchor=%zu\n",qPrint(matchingDir->name()),root->anchors.size());
9979 matchingDir->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9980 matchingDir->setDocumentation(root->doc,root->docFile,root->docLine);
9981 matchingDir->setRefItems(root->sli);
9982 matchingDir->setRequirementReferences(root->rqli);
9983 matchingDir->addSectionsToDefinition(root->anchors);
9984 root->commandOverrides.apply_directoryGraph([&](bool b) { matchingDir->overrideDirectoryGraph(b); });
9985 addDirToGroups(root,matchingDir);
9986 }
9987 else
9988 {
9989 warn(root->fileName,root->startLine,"No matching directory found for command \\dir {}",normalizedName);
9990 }
9991 }
9992 for (const auto &e : root->children()) findDirDocumentation(e.get());
9993}
A model of a directory symbol.
Definition dirdef.h:108
virtual void overrideDirectoryGraph(bool e)=0
static void findDirDocumentation(const Entry *root)
Definition doxygen.cpp:9936
void addDirToGroups(const Entry *root, DirDef *dd)

References addDirToGroups(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, DString::at(), Entry::brief, Entry::briefFile, Entry::briefLine, Entry::children(), Entry::commandOverrides, Doxygen::dirLinkedMap, Entry::doc, Entry::docFile, Entry::docLine, Entry::fileName, findDirDocumentation(), DString::left(), DString::length(), Definition::name(), Entry::name, DString::npos, DirDef::overrideDirectoryGraph(), DString::rfind(), Entry::rqli, Entry::section, DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), Entry::sli, Entry::startLine, substitute(), and warn.

Referenced by findDirDocumentation(), and parseInput().

◆ findDocumentedEnumValues()

void findDocumentedEnumValues ( )
static

Definition at line 8437 of file doxygen.cpp.

8438{
8441}
static void findDEV(const MemberNameLinkedMap &mnsd)
Definition doxygen.cpp:8411

References findDEV(), Doxygen::functionNameLinkedMap, and Doxygen::memberNameLinkedMap.

Referenced by parseInput().

◆ findEndOfTemplate()

int findEndOfTemplate ( const DString & s,
size_t startPos )
static

Searches for the end of a template in prototype s starting from character position startPos. If the end was found the position of the closing > is returned, otherwise -1 is returned.

Handles exotic cases such as

Class<(id<0)>
Class<bits<<2>
Class<"<">
Class<'<'>
Class<(")<")>

Definition at line 3373 of file doxygen.cpp.

3374{
3375 // locate end of template
3376 size_t e=startPos;
3377 int brCount=1;
3378 int roundCount=0;
3379 size_t len = s.length();
3380 bool insideString=false;
3381 bool insideChar=false;
3382 char pc = 0;
3383 while (e<len && brCount!=0)
3384 {
3385 char c=s.at(e);
3386 switch(c)
3387 {
3388 case '<':
3389 if (!insideString && !insideChar)
3390 {
3391 if (e<len-1 && s.at(e+1)=='<')
3392 e++;
3393 else if (roundCount==0)
3394 brCount++;
3395 }
3396 break;
3397 case '>':
3398 if (!insideString && !insideChar)
3399 {
3400 if (e<len-1 && s.at(e+1)=='>')
3401 e++;
3402 else if (roundCount==0)
3403 brCount--;
3404 }
3405 break;
3406 case '(':
3407 if (!insideString && !insideChar)
3408 roundCount++;
3409 break;
3410 case ')':
3411 if (!insideString && !insideChar)
3412 roundCount--;
3413 break;
3414 case '"':
3415 if (!insideChar)
3416 {
3417 if (insideString && pc!='\\')
3418 insideString=false;
3419 else
3420 insideString=true;
3421 }
3422 break;
3423 case '\'':
3424 if (!insideString)
3425 {
3426 if (insideChar && pc!='\\')
3427 insideChar=false;
3428 else
3429 insideChar=true;
3430 }
3431 break;
3432 }
3433 pc = c;
3434 e++;
3435 }
3436 return brCount==0 ? static_cast<int>(e) : -1;
3437}

References DString::at(), and DString::length().

Referenced by addVariable(), and findClassRelation().

◆ findEnumDocumentation()

void findEnumDocumentation ( const Entry * root)
static

Definition at line 8326 of file doxygen.cpp.

8327{
8328 if (root->section.isEnumDoc() &&
8329 !root->name.empty() &&
8330 root->name.at(0)!='@' // skip anonymous enums
8331 )
8332 {
8333 DString name;
8334 DString scope;
8335 if (size_t i = root->name.rfind("::"); i!=DString::npos) // scope is specified as part of the name
8336 {
8337 name=root->name.mid(i+2); // extract name
8338 scope=root->name.left(i); // extract scope
8339 //printf("Scope='%s' Name='%s'\n",qPrint(scope),qPrint(name));
8340 }
8341 else // just the name
8342 {
8343 name=root->name;
8344 }
8345 if (root->parent()->section.isScope() && !root->parent()->name.empty()) // found enum docs inside a compound
8346 {
8347 if (!scope.empty()) scope.prepend("::");
8348 scope.prepend(root->parent()->name);
8349 }
8350 const ClassDef *cd = getClass(scope);
8352 const FileDef *fd = root->fileDef();
8353 AUTO_TRACE("Found docs for enum with name '{}' and scope '{}' in context '{}' cd='{}', nd='{}' fd='{}'",
8354 name,scope,root->parent()->name,
8355 cd ? cd->name() : DString("<none>"),
8356 nd ? nd->name() : DString("<none>"),
8357 fd ? fd->name() : DString("<none>"));
8358
8359 if (!name.empty())
8360 {
8361 bool found = tryAddEnumDocsToGroupMember(root, name);
8362 if (!found)
8363 {
8365 if (mn)
8366 {
8367 for (const auto &imd : *mn)
8368 {
8369 MemberDefMutable *md = toMemberDefMutable(imd.get());
8370 if (md && md->isEnumerate())
8371 {
8372 const ClassDef *mcd = md->getClassDef();
8373 const NamespaceDef *mnd = md->getNamespaceDef();
8374 const FileDef *mfd = md->getFileDef();
8375 if (cd && mcd==cd)
8376 {
8377 AUTO_TRACE_ADD("Match found for class scope");
8378 addEnumDocs(root,md);
8379 found = true;
8380 break;
8381 }
8382 else if (cd==nullptr && mcd==nullptr && nd!=nullptr && mnd==nd)
8383 {
8384 AUTO_TRACE_ADD("Match found for namespace scope");
8385 addEnumDocs(root,md);
8386 found = true;
8387 break;
8388 }
8389 else if (cd==nullptr && nd==nullptr && mcd==nullptr && mnd==nullptr && fd==mfd)
8390 {
8391 AUTO_TRACE_ADD("Match found for global scope");
8392 addEnumDocs(root,md);
8393 found = true;
8394 break;
8395 }
8396 }
8397 }
8398 }
8399 }
8400 if (!found)
8401 {
8402 warn(root->fileName,root->startLine, "Documentation for undefined enum '{}' found.", name);
8403 }
8404 }
8405 }
8406 for (const auto &e : root->children()) findEnumDocumentation(e.get());
8407}
static void addEnumDocs(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:8251
static bool tryAddEnumDocsToGroupMember(const Entry *root, const DString &name)
Definition doxygen.cpp:8293
static void findEnumDocumentation(const Entry *root)
Definition doxygen.cpp:8326

References addEnumDocs(), DString::at(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::children(), DString::empty(), Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), findEnumDocumentation(), Doxygen::functionNameLinkedMap, getClass(), MemberDef::getClassDef(), MemberDef::getFileDef(), MemberDef::getNamespaceDef(), MemberDef::isEnumerate(), EntryType::isScope(), DString::left(), Doxygen::memberNameLinkedMap, DString::mid(), Definition::name(), Entry::name, Doxygen::namespaceLinkedMap, DString::npos, Entry::parent(), DString::prepend(), DString::rfind(), Entry::section, Entry::startLine, toMemberDefMutable(), tryAddEnumDocsToGroupMember(), and warn.

Referenced by findEnumDocumentation(), and parseInput().

◆ findEnums()

void findEnums ( const Entry * root)
static

Definition at line 7827 of file doxygen.cpp.

7828{
7829 if (root->section.isEnum())
7830 {
7831 AUTO_TRACE("name={}",root->name);
7832 ClassDefMutable *cd = nullptr;
7833 FileDef *fd = nullptr;
7834 NamespaceDefMutable *nd = nullptr;
7835 MemberNameLinkedMap *mnsd = nullptr;
7836 bool isGlobal = false;
7837 bool isRelated = false;
7838 bool isMemberOf = false;
7839 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
7840
7841 DString name;
7842 DString scope;
7843
7844 if (size_t i = root->name.rfind("::"); i!=DString::npos) // scope is specified
7845 {
7846 scope=root->name.left(i); // extract scope
7847 if (root->lang==SrcLangExt::CSharp)
7848 {
7849 scope = mangleCSharpGenericName(scope);
7850 }
7851 name=root->name.right(root->name.length()-i-2); // extract name
7852 if ((cd=getClassMutable(scope))==nullptr)
7853 {
7855 }
7856 }
7857 else // no scope, check the scope in which the docs where found
7858 {
7859 if (root->parent()->section.isScope() && !root->parent()->name.empty()) // found enum docs inside a compound
7860 {
7861 scope=root->parent()->name;
7862 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7863 }
7864 name=root->name;
7865 }
7866
7867 if (!root->relates.empty())
7868 { // related member, prefix user specified scope
7869 isRelated=true;
7870 isMemberOf=(root->relatesType==RelatesType::MemberOf);
7871 if (getClass(root->relates)==nullptr && !scope.empty())
7872 scope=mergeScopes(scope,root->relates);
7873 else
7874 scope=root->relates;
7875 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7876 }
7877
7878 if (cd && !name.empty()) // found a enum inside a compound
7879 {
7880 //printf("Enum '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
7881 fd=nullptr;
7883 isGlobal=false;
7884 }
7885 else if (nd) // found enum inside namespace
7886 {
7888 isGlobal=true;
7889 }
7890 else // found a global enum
7891 {
7892 fd=root->fileDef();
7894 isGlobal=true;
7895 }
7896
7897 if (!name.empty())
7898 {
7899 // new enum type
7900 AUTO_TRACE_ADD("new enum {} at line {} of {}",name,root->bodyLine,root->fileName);
7901 auto md = createMemberDef(
7902 root->fileName,root->startLine,root->startColumn,
7903 DString(),name,DString(),DString(),
7904 root->protection,Specifier::Normal,false,
7905 isMemberOf ? Relationship::Foreign : isRelated ? Relationship::Related : Relationship::Member,
7906 MemberType::Enumeration,
7908 auto mmd = toMemberDefMutable(md.get());
7909 mmd->setTagInfo(root->tagInfo());
7910 mmd->setLanguage(root->lang);
7911 mmd->setId(root->id);
7912 if (!isGlobal) mmd->setMemberClass(cd); else mmd->setFileDef(fd);
7913 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
7914 mmd->setBodyDef(root->fileDef());
7915 mmd->setMemberSpecifiers(root->spec);
7916 mmd->setVhdlSpecifiers(root->vhdlSpec);
7917 mmd->setEnumBaseType(root->args);
7918 //printf("Enum %s definition at line %d of %s: protection=%d scope=%s\n",
7919 // qPrint(root->name),root->bodyLine,qPrint(root->fileName),root->protection,cd?qPrint(cd->name()):"<none>");
7920 mmd->addSectionsToDefinition(root->anchors);
7921 mmd->setMemberGroupId(root->mGrpId);
7923 mmd->addQualifiers(root->qualifiers);
7924 //printf("%s::setRefItems(%zu)\n",qPrint(md->name()),root->sli.size());
7925 mmd->setRefItems(root->sli);
7926 mmd->setRequirementReferences(root->rqli);
7927 //printf("found enum %s nd=%p\n",qPrint(md->name()),nd);
7928 bool defSet=false;
7929 addIncludeFile(mmd,root->fileDef(),root);
7930
7931 DString baseType = root->args;
7932 if (!baseType.empty())
7933 {
7934 baseType.prepend(" : ");
7935 }
7936
7937 if (nd)
7938 {
7939 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES) || root->lang==SrcLangExt::Python)
7940 {
7941 mmd->setDefinition(name+baseType);
7942 }
7943 else
7944 {
7945 mmd->setDefinition(nd->name()+"::"+name+baseType);
7946 }
7947 //printf("definition=%s\n",md->definition());
7948 defSet=true;
7949 mmd->setNamespace(nd);
7950 nd->insertMember(md.get());
7951 }
7952
7953 // even if we have already added the enum to a namespace, we still
7954 // also want to add it to other appropriate places such as file
7955 // or class.
7956 if (isGlobal && (nd==nullptr || !nd->isAnonymous()))
7957 {
7958 if (!defSet) mmd->setDefinition(name+baseType);
7959 if (fd==nullptr && root->parent())
7960 {
7961 fd=root->parent()->fileDef();
7962 }
7963 if (fd)
7964 {
7965 mmd->setFileDef(fd);
7966 fd->insertMember(md.get());
7967 }
7968 }
7969 else if (cd)
7970 {
7971 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES) || root->lang==SrcLangExt::Python)
7972 {
7973 mmd->setDefinition(name+baseType);
7974 }
7975 else
7976 {
7977 mmd->setDefinition(cd->name()+"::"+name+baseType);
7978 }
7979 cd->insertMember(md.get());
7980 cd->insertUsedFile(fd);
7981 }
7982 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
7983 mmd->setDocsForDefinition(!root->proto);
7984 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7985 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
7986
7987 //printf("Adding member=%s\n",qPrint(md->name()));
7988 addMemberToGroups(root,md.get());
7990
7991 MemberName *mn = mnsd->add(name);
7992 mn->push_back(std::move(md));
7993 }
7994 }
7995 else
7996 {
7997 for (const auto &e : root->children()) findEnums(e.get());
7998 }
7999}
static void findEnums(const Entry *root)
Definition doxygen.cpp:7827

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addIncludeFile(), addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::args, AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, buildScopeFromQualifiedName(), Entry::children(), Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), Entry::endBodyLine, Entry::fileDef(), Entry::fileName, findEnums(), Doxygen::functionNameLinkedMap, getClass(), getClassMutable(), getResolvedNamespaceMutable(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), FileDef::insertMember(), NamespaceDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), Definition::isAnonymous(), EntryType::isScope(), Entry::lang, DString::left(), DString::length(), mangleCSharpGenericName(), Doxygen::memberNameLinkedMap, mergeScopes(), Entry::metaData, Entry::mGrpId, Definition::name(), Entry::name, DString::npos, Entry::parent(), DString::prepend(), Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, Entry::relates, Entry::relatesType, DString::rfind(), DString::right(), Entry::rqli, Entry::section, Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, Entry::tagInfo(), toMemberDefMutable(), toNamespaceDefMutable(), and Entry::vhdlSpec.

Referenced by findEnums(), and parseInput().

◆ findFriends()

void findFriends ( )
static

Definition at line 4499 of file doxygen.cpp.

4500{
4501 AUTO_TRACE();
4502 for (const auto &fn : *Doxygen::functionNameLinkedMap) // for each global function name
4503 {
4504 MemberName *mn = Doxygen::memberNameLinkedMap->find(fn->memberName());
4505 if (mn)
4506 { // there are members with the same name
4507 // for each function with that name
4508 for (const auto &ifmd : *fn)
4509 {
4510 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
4511 // for each member with that name
4512 for (const auto &immd : *mn)
4513 {
4514 MemberDefMutable *mmd = toMemberDefMutable(immd.get());
4515 //printf("Checking for matching arguments
4516 // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n",
4517 // mmd->isRelated(),mmd->isFriend(),mmd->isFunction());
4518 if (fmd && mmd &&
4519 (mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) &&
4520 matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), mmd->typeString(), &mmd->argumentList(),
4521 fmd->getOuterScope(), fmd->getFileDef(), fmd->typeString(), &fmd->argumentList(),
4522 true,mmd->getLanguage()
4523 )
4524
4525 ) // if the member is related and the arguments match then the
4526 // function is actually a friend.
4527 {
4528 AUTO_TRACE_ADD("Merging related global and member '{}' isFriend={} isRelated={} isFunction={}",
4529 mmd->name(),mmd->isFriend(),mmd->isRelated(),mmd->isFunction());
4530 const ArgumentList &mmdAl = mmd->argumentList();
4531 const ArgumentList &fmdAl = fmd->argumentList();
4532 mergeArguments(const_cast<ArgumentList&>(fmdAl),const_cast<ArgumentList&>(mmdAl));
4533
4534 // reset argument lists to add missing default parameters
4535 DString mmdAlStr = argListToString(mmdAl);
4536 DString fmdAlStr = argListToString(fmdAl);
4537 mmd->setArgsString(mmdAlStr);
4538 fmd->setArgsString(fmdAlStr);
4539 mmd->moveDeclArgumentList(std::make_unique<ArgumentList>(mmdAl));
4540 fmd->moveDeclArgumentList(std::make_unique<ArgumentList>(fmdAl));
4541 AUTO_TRACE_ADD("friend args='{}' member args='{}'",argListToString(fmd->argumentList()),argListToString(mmd->argumentList()));
4542
4543 if (!fmd->documentation().empty())
4544 {
4545 mmd->setDocumentation(fmd->documentation(),fmd->docFile(),fmd->docLine());
4546 }
4547 else if (!mmd->documentation().empty())
4548 {
4549 fmd->setDocumentation(mmd->documentation(),mmd->docFile(),mmd->docLine());
4550 }
4551 if (mmd->briefDescription().empty() && !fmd->briefDescription().empty())
4552 {
4553 mmd->setBriefDescription(fmd->briefDescription(),fmd->briefFile(),fmd->briefLine());
4554 }
4555 else if (!mmd->briefDescription().empty() && !fmd->briefDescription().empty())
4556 {
4557 fmd->setBriefDescription(mmd->briefDescription(),mmd->briefFile(),mmd->briefLine());
4558 }
4559 if (!fmd->inbodyDocumentation().empty())
4560 {
4562 }
4563 else if (!mmd->inbodyDocumentation().empty())
4564 {
4566 }
4567 //printf("body mmd %d fmd %d\n",mmd->getStartBodyLine(),fmd->getStartBodyLine());
4568 if (mmd->getStartBodyLine()==-1 && fmd->getStartBodyLine()!=-1)
4569 {
4570 mmd->setBodySegment(fmd->getDefLine(),fmd->getStartBodyLine(),fmd->getEndBodyLine());
4571 mmd->setBodyDef(fmd->getBodyDef());
4572 //mmd->setBodyMember(fmd);
4573 }
4574 else if (mmd->getStartBodyLine()!=-1 && fmd->getStartBodyLine()==-1)
4575 {
4576 fmd->setBodySegment(mmd->getDefLine(),mmd->getStartBodyLine(),mmd->getEndBodyLine());
4577 fmd->setBodyDef(mmd->getBodyDef());
4578 //fmd->setBodyMember(mmd);
4579 }
4581
4583
4584 mmd->addQualifiers(fmd->getQualifiers());
4585 fmd->addQualifiers(mmd->getQualifiers());
4586
4587 }
4588 }
4589 }
4590 }
4591 }
4592}
virtual bool isFriend() const =0
virtual bool isRelated() const =0
virtual StringVector getQualifiers() const =0
virtual bool isDocsForDefinition() const =0
void mergeMemberOverrideOptions(MemberDefMutable *md1, MemberDefMutable *md2)

References MemberDefMutable::addQualifiers(), argListToString(), MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, Definition::briefDescription(), Definition::briefFile(), Definition::briefLine(), Definition::docFile(), Definition::docLine(), Definition::documentation(), DString::empty(), LinkedMap< T, Hash, KeyEqual, Map >::find(), Doxygen::functionNameLinkedMap, Definition::getBodyDef(), Definition::getDefLine(), Definition::getEndBodyLine(), MemberDef::getFileDef(), Definition::getLanguage(), Definition::getOuterScope(), MemberDef::getQualifiers(), Definition::getStartBodyLine(), Definition::inbodyDocumentation(), Definition::inbodyFile(), Definition::inbodyLine(), MemberDef::isDocsForDefinition(), MemberDef::isFriend(), MemberDef::isFunction(), MemberDef::isRelated(), matchArguments2(), Doxygen::memberNameLinkedMap, mergeArguments(), mergeMemberOverrideOptions(), MemberDefMutable::moveDeclArgumentList(), Definition::name(), MemberDefMutable::setArgsString(), DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setInbodyDocumentation(), toMemberDefMutable(), and MemberDef::typeString().

Referenced by parseInput().

◆ findFunctionPtr()

int findFunctionPtr ( const std::string & type,
SrcLangExt lang,
int * pLength = nullptr )
static

See if the return type string type is that of a function pointer

Returns
-1 if this is not a function pointer variable or the index at which the closing brace of (...*name) was found.

Definition at line 3170 of file doxygen.cpp.

3171{
3172 AUTO_TRACE("type='{}' lang={}",type,lang);
3173 if (lang == SrcLangExt::Fortran || lang == SrcLangExt::VHDL)
3174 {
3175 return -1; // Fortran and VHDL do not have function pointers
3176 }
3177
3178 static const reg::Ex re(R"(\‍([^)]*[*&^][^)]*\))");
3180 size_t i=std::string::npos;
3181 size_t l=0;
3182 if (reg::search(type,match,re)) // contains (...*...) or (...&...) or (...^...)
3183 {
3184 i = match.position();
3185 l = match.length();
3186 }
3187 if (i!=std::string::npos)
3188 {
3189 size_t di = type.find("decltype(");
3190 if (di!=std::string::npos && di<i)
3191 {
3192 i = std::string::npos;
3193 }
3194 }
3195 size_t bb=type.find('<');
3196 size_t be=type.rfind('>');
3197 bool templFp = false;
3198 if (be!=std::string::npos) {
3199 size_t cc_ast = type.find("::*");
3200 size_t cc_amp = type.find("::&");
3201 templFp = (cc_ast != std::string::npos && cc_ast>be) || (cc_amp != std::string::npos && cc_amp>be); // hack to find, e.g 'B<X>(A<int>::*)'
3202 }
3203
3204 if (!type.empty() && // return type is non-empty
3205 i!=std::string::npos && // contains (...*...)
3206 type.find("operator")==std::string::npos && // not an operator
3207 (type.find(")(")==std::string::npos || type.find("typedef ")!=std::string::npos) &&
3208 // not a function pointer return type
3209 (!((bb!=std::string::npos && bb<i) && (be!=std::string::npos && i<be)) || templFp) // bug665855: avoid treating "typedef A<void (T*)> type" as a function pointer
3210 )
3211 {
3212 if (pLength) *pLength=static_cast<int>(l);
3213 //printf("findFunctionPtr=%d\n",(int)i);
3214 AUTO_TRACE_EXIT("result={}",i);
3215 return static_cast<int>(i);
3216 }
3217 else
3218 {
3219 //printf("findFunctionPtr=%d\n",-1);
3220 AUTO_TRACE_EXIT("result=-1");
3221 return -1;
3222 }
3223}
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:55

References AUTO_TRACE, AUTO_TRACE_EXIT, and reg::search().

Referenced by addVariable(), buildVarList(), and filterMemberDocumentation().

◆ findGlobalMember()

bool findGlobalMember ( const Entry * root,
const DString & namespaceName,
const DString & type,
const DString & name,
const DString & tempArg,
const DString & ,
const DString & decl,
TypeSpecifier  )
static

Definition at line 6031 of file doxygen.cpp.

6039{
6040 AUTO_TRACE("namespace='{}' type='{}' name='{}' tempArg='{}' decl='{}'",namespaceName,type,name,tempArg,decl);
6041 DString n=name;
6042 if (n.empty()) return false;
6043 if (n.find("::")!=DString::npos) return false; // skip undefined class members
6044 MemberName *mn=Doxygen::functionNameLinkedMap->find(n+tempArg); // look in function dictionary
6045 if (mn==nullptr)
6046 {
6047 mn=Doxygen::functionNameLinkedMap->find(n); // try without template arguments
6048 }
6049 if (mn) // function name defined
6050 {
6051 AUTO_TRACE_ADD("Found symbol name");
6052 //int count=0;
6053 bool found=false;
6054 for (const auto &md : *mn)
6055 {
6056 // If the entry has groups, then restrict the search to members which are
6057 // in one of the groups of the entry. If md is not associated with a group yet,
6058 // allow this documentation entry to add the group info.
6059 if (!root->groups.empty() && !isEntryInGroupOfMember(root, md.get(), true))
6060 {
6061 continue;
6062 }
6063
6064 const NamespaceDef *nd=nullptr;
6065 if (md->isAlias() && md->getOuterScope() &&
6066 md->getOuterScope()->definitionType()==Definition::TypeNamespace)
6067 {
6068 nd = toNamespaceDef(md->getOuterScope());
6069 }
6070 else
6071 {
6072 nd = md->getNamespaceDef();
6073 }
6074
6075 // special case for strong enums
6076 size_t enumNamePos=0;
6077 if (nd && md->isEnumValue() && (enumNamePos=namespaceName.rfind("::"))!=DString::npos)
6078 { // md part of a strong enum in a namespace?
6079 DString enumName = namespaceName.mid(enumNamePos+2);
6080 if (namespaceName.left(enumNamePos)==nd->name())
6081 {
6083 if (enumMn)
6084 {
6085 for (const auto &emd : *enumMn)
6086 {
6087 found = emd->isStrong() && md->getEnumScope()==emd.get();
6088 if (found)
6089 {
6090 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,nullptr,false,root->spec);
6091 break;
6092 }
6093 }
6094 }
6095 }
6096 if (found)
6097 {
6098 break;
6099 }
6100 }
6101 else if (nd==nullptr && md->isEnumValue()) // md part of global strong enum?
6102 {
6103 MemberName *enumMn=Doxygen::functionNameLinkedMap->find(namespaceName);
6104 if (enumMn)
6105 {
6106 for (const auto &emd : *enumMn)
6107 {
6108 found = emd->isStrong() && md->getEnumScope()==emd.get();
6109 if (found)
6110 {
6111 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,nullptr,false,root->spec);
6112 break;
6113 }
6114 }
6115 }
6116 }
6117
6118 const FileDef *fd=root->fileDef();
6119 //printf("File %s\n",fd ? qPrint(fd->name()) : "<none>");
6121 if (fd)
6122 {
6123 nl = fd->getUsedNamespaces();
6124 }
6125 //printf("NamespaceList %p\n",nl);
6126
6127 // search in the list of namespaces that are imported via a
6128 // using declaration
6129 bool viaUsingDirective = nd && nl.find(nd->qualifiedName())!=nullptr;
6130
6131 if ((namespaceName.empty() && nd==nullptr) || // not in a namespace
6132 (nd && nd->name()==namespaceName) || // or in the same namespace
6133 viaUsingDirective // member in 'using' namespace
6134 )
6135 {
6136 AUTO_TRACE_ADD("Try to add member '{}' to scope '{}'",md->name(),namespaceName);
6137
6138 NamespaceDef *rnd = nullptr;
6139 if (!namespaceName.empty()) rnd = Doxygen::namespaceLinkedMap->find(namespaceName);
6140
6141 const ArgumentList &mdAl = md.get()->argumentList();
6142 bool matching=
6143 (mdAl.empty() && root->argList.empty()) ||
6144 md->isVariable() || md->isTypedef() || /* in case of function pointers */
6145 matchArguments2(md->getOuterScope(),md->getFileDef(),md->typeString(),&mdAl,
6146 rnd ? rnd : Doxygen::globalScope,fd,root->type,&root->argList,
6147 false,root->lang);
6148
6149 // for template members we need to check if the number of
6150 // template arguments is the same, otherwise we are dealing with
6151 // different functions.
6152 if (matching && !root->tArgLists.empty())
6153 {
6154 const ArgumentList &mdTempl = md->templateArguments();
6155 if (root->tArgLists.back().size()!=mdTempl.size())
6156 {
6157 matching=false;
6158 }
6159 }
6160
6161 //printf("%s<->%s\n",
6162 // qPrint(argListToString(md->argumentList())),
6163 // qPrint(argListToString(root->argList)));
6164
6165 // For static members we also check if the comment block was found in
6166 // the same file. This is needed because static members with the same
6167 // name can be in different files. Thus it would be wrong to just
6168 // put the comment block at the first syntactically matching member. If
6169 // the comment block belongs to a group of the static member, then add
6170 // the documentation even if it is in a different file.
6171 if (matching && md->isStatic() &&
6172 md->getDefFileName()!=root->fileName &&
6173 mn->size()>1 &&
6174 !isEntryInGroupOfMember(root,md.get()))
6175 {
6176 matching = false;
6177 }
6178
6179 // for template member we also need to check the return type and requires
6180 if (!md->templateArguments().empty() && !root->tArgLists.empty())
6181 {
6182 //printf("Comparing return types '%s'<->'%s'\n",
6183 // md->typeString(),type);
6184 //printf("%s: Comparing '%s'<=>'%s'\n",qPrint(md->name()),qPrint(md->requiresClause()),qPrint(root->req));
6185 if (md->templateArguments().size()!=root->tArgLists.back().size() ||
6186 md->typeString()!=type ||
6187 md->requiresClause()!=root->req)
6188 {
6189 //printf(" ---> no matching\n");
6190 matching = false;
6191 }
6192 }
6193
6194 if (matching) // add docs to the member
6195 {
6196 AUTO_TRACE_ADD("Match found");
6197 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,&root->argList,false,root->spec);
6198 found=true;
6199 break;
6200 }
6201 }
6202 }
6203 if (!found && root->relatesType!=RelatesType::Duplicate && root->section.isFunction()) // no match
6204 {
6205 DString fullFuncDecl=decl;
6206 if (!root->argList.empty()) fullFuncDecl+=argListToString(root->argList,true);
6207 DString warnMsg = "no matching file member found for \n"+fullFuncDecl;
6208 if (mn->size()>0)
6209 {
6210 warnMsg+="\nPossible candidates:";
6211 for (const auto &md : *mn)
6212 {
6213 warnMsg+="\n '";
6214 warnMsg+=replaceAnonymousScopes(md->declaration());
6215 warnMsg+="' " + warn_line(md->getDefFileName(),md->getDefLine());
6216 }
6217 }
6218 warn(root->fileName,root->startLine, "{}", qPrint(warnMsg));
6219 }
6220 }
6221 else // got docs for an undefined member!
6222 {
6223 if (root->type!="friend class" &&
6224 root->type!="friend struct" &&
6225 root->type!="friend union" &&
6226 root->type!="friend" &&
6227 (!Config_getBool(TYPEDEF_HIDES_STRUCT) ||
6228 root->type.find("typedef ")==DString::npos)
6229 )
6230 {
6231 warn(root->fileName,root->startLine,
6232 "documented symbol '{}' was not declared or defined.",qPrint(decl)
6233 );
6234 }
6235 }
6236 return true;
6237}
size_t size() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:154
virtual const LinkedRefMap< NamespaceDef > & getUsedNamespaces() const =0
Container class representing a vector of objects with keys.
Definition linkedmap.h:232
const T * find(const std::string &key) const
Definition linkedmap.h:243

References addMemberDocs(), Entry::argList, argListToString(), AUTO_TRACE, AUTO_TRACE_ADD, Config_getBool, ArgumentList::empty(), DString::empty(), Entry::fileDef(), Entry::fileName, DString::find(), LinkedMap< T, Hash, KeyEqual, Map >::find(), LinkedRefMap< T, Hash, KeyEqual, Map >::find(), Doxygen::functionNameLinkedMap, FileDef::getUsedNamespaces(), Doxygen::globalScope, Entry::groups, isEntryInGroupOfMember(), Entry::lang, DString::left(), matchArguments2(), DString::mid(), Definition::name(), Doxygen::namespaceLinkedMap, DString::npos, qPrint(), Definition::qualifiedName(), Entry::relatesType, replaceAnonymousScopes(), Entry::req, DString::rfind(), Entry::section, ArgumentList::size(), DString::size(), Entry::spec, Entry::startLine, Entry::tArgLists, toMemberDefMutable(), toNamespaceDef(), Entry::type, Definition::TypeNamespace, warn, and warn_line().

Referenced by findMember().

◆ findGroupScope()

void findGroupScope ( const Entry * root)
static

Definition at line 555 of file doxygen.cpp.

556{
557 if (root->section.isGroupDoc() && !root->name.empty() &&
558 root->parent() && !root->parent()->name.empty())
559 {
561 if (gd)
562 {
563 DString scope = root->parent()->name;
564 if (root->parent()->section.isPackageDoc())
565 {
566 scope=substitute(scope,".","::");
567 }
568 scope = stripAnonymousNamespaceScope(scope);
569 scope+="::"+gd->name();
571 if (d)
572 {
573 gd->setGroupScope(d);
574 }
575 }
576 }
577 for (const auto &e : root->children()) findGroupScope(e.get());
578}
virtual void setGroupScope(Definition *d)=0
static void findGroupScope(const Entry *root)
Definition doxygen.cpp:555

References Entry::children(), DString::empty(), LinkedMap< T, Hash, KeyEqual, Map >::find(), findGroupScope(), findScopeFromQualifiedName(), Doxygen::globalScope, Doxygen::groupLinkedMap, Definition::name(), Entry::name, Entry::parent(), Entry::section, GroupDef::setGroupScope(), stripAnonymousNamespaceScope(), substitute(), and Entry::tagInfo().

Referenced by findGroupScope(), and parseInput().

◆ findIncludedUsingDirectives()

void findIncludedUsingDirectives ( )
static

Definition at line 2729 of file doxygen.cpp.

2730{
2731 FileDefSet visitedFiles;
2732 // then recursively add using directives found in #include files
2733 // to files that have not been visited.
2734 for (const auto &fn : *Doxygen::inputNameLinkedMap)
2735 {
2736 for (const auto &fd : *fn)
2737 {
2738 //printf("----- adding using directives for file %s\n",qPrint(fd->name()));
2739 fd->addIncludedUsingDirectives(visitedFiles);
2740 }
2741 }
2742}
std::unordered_set< const FileDef * > FileDefSet
Definition filedef.h:41

References Doxygen::inputNameLinkedMap.

Referenced by parseInput().

◆ findInheritedTemplateInstances()

void findInheritedTemplateInstances ( )
static

Using the dictionary build by findClassEntries(), this function will look for additional template specialization that exists as inheritance relations only. These instances will be added to the template they are derived from.

Definition at line 5553 of file doxygen.cpp.

5554{
5555 AUTO_TRACE();
5556 ClassDefSet visitedClasses;
5557 for (const auto &[name,root] : g_classEntries)
5558 {
5559 DString bName = extractClassName(root);
5560 ClassDefMutable *cdm = getClassMutable(bName);
5561 if (cdm)
5562 {
5563 findBaseClassesForClass(root,cdm,cdm,cdm,TemplateInstances,false);
5564 }
5565 }
5566}

References AUTO_TRACE, extractClassName(), findBaseClassesForClass(), g_classEntries, getClassMutable(), and TemplateInstances.

Referenced by parseInput().

◆ findMainPage()

void findMainPage ( Entry * root)
static

Definition at line 10035 of file doxygen.cpp.

10036{
10037 if (root->section.isMainpageDoc())
10038 {
10039 if (Doxygen::mainPage==nullptr && root->tagInfo()==nullptr)
10040 {
10041 //printf("mainpage: docLine=%d startLine=%d\n",root->docLine,root->startLine);
10042 //printf("Found main page! \n======\n%s\n=======\n",qPrint(root->doc));
10043 DString title=root->args.stripWhiteSpace();
10044 if (title.empty()) title = Config_getString(PROJECT_NAME);
10045 //DString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
10046 DString indexName="index";
10048 indexName, root->brief+root->doc+root->inbodyDocs,title);
10049 //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
10050 Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
10051 Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1);
10052 Doxygen::mainPage->setFileName(indexName);
10053 Doxygen::mainPage->setLocalToc(root->localToc);
10055
10057 if (si)
10058 {
10059 if (!si->ref().empty()) // we are from a tag file
10060 {
10061 // a page name is a label as well! but should no be double either
10064 indexName,
10065 root->startLine,
10066 Doxygen::mainPage->title(),
10068 0); // level 0
10069 }
10070 else if (si->lineNr() != -1)
10071 {
10072 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {}, line {})",
10073 Doxygen::mainPage->name(),si->fileName(),si->lineNr());
10074 }
10075 else
10076 {
10077 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {})",
10078 Doxygen::mainPage->name(),si->fileName());
10079 }
10080 }
10081 else
10082 {
10083 // a page name is a label as well! but should no be double either
10086 indexName,
10087 root->startLine,
10088 Doxygen::mainPage->title(),
10090 0); // level 0
10091 }
10092 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
10093 }
10094 else if (root->tagInfo()==nullptr)
10095 {
10096 warn(root->fileName,root->startLine,
10097 "found more than one \\mainpage comment block! (first occurrence: {}, line {}), Skipping current block!",
10098 Doxygen::mainPage->docFile(),Doxygen::mainPage->getStartBodyLine());
10099 }
10100 }
10101 for (const auto &e : root->children()) findMainPage(e.get());
10102}
class that provide information about a section.
Definition section.h:58
DString fileName() const
Definition section.h:74
int lineNr() const
Definition section.h:73
DString ref() const
Definition section.h:72
SectionInfo * replace(const DString &label, const DString &fileName, int lineNr, const DString &title, SectionType type, int level, const DString &ref=DString())
Definition section.h:157
SectionInfo * add(const SectionInfo &si)
Definition section.h:139
static constexpr int Page
Definition section.h:31
static void findMainPage(Entry *root)

References SectionManager::add(), addPageToContext(), Entry::anchors, Entry::args, Entry::brief, Entry::briefFile, Entry::briefLine, Entry::children(), Config_getString, createPageDef(), Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), Entry::fileName, SectionInfo::fileName(), LinkedMap< T, Hash, KeyEqual, Map >::find(), findMainPage(), Entry::inbodyDocs, SectionManager::instance(), SectionInfo::lineNr(), Entry::localToc, Doxygen::mainPage, SectionType::Page, SectionInfo::ref(), SectionManager::replace(), Entry::section, Entry::startLine, DString::stripWhiteSpace(), Entry::tagInfo(), and warn.

Referenced by findMainPage(), and parseInput().

◆ findMainPageTagFiles()

void findMainPageTagFiles ( Entry * root)
static

Definition at line 10105 of file doxygen.cpp.

10106{
10107 if (root->section.isMainpageDoc())
10108 {
10109 if (Doxygen::mainPage && root->tagInfo())
10110 {
10111 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
10112 }
10113 }
10114 for (const auto &e : root->children()) findMainPageTagFiles(e.get());
10115}
static void findMainPageTagFiles(Entry *root)

References Entry::anchors, Entry::children(), findMainPageTagFiles(), Doxygen::mainPage, Entry::section, and Entry::tagInfo().

Referenced by findMainPageTagFiles(), and parseInput().

◆ findMember()

void findMember ( const Entry * root,
const DString & relates,
const DString & type,
const DString & args,
DString funcDecl,
bool overloaded,
bool isFunc )
static

This function tries to find a member (in a documented class/file/namespace) that corresponds to the function/variable declaration given in funcDecl.

The boolean overloaded is used to specify whether or not a standard overload documentation line should be generated.

The boolean isFunc is a hint that indicates that this is a function instead of a variable or typedef.

Definition at line 6993 of file doxygen.cpp.

7001{
7002 AUTO_TRACE("root='{}' funcDecl='{}' related='{}' overload={} isFunc={} mGrpId={} #tArgList={} spec={} lang={}",
7003 root->name, funcDecl, relates, overloaded, isFunc, root->mGrpId, root->tArgLists.size(),
7004 root->spec, root->lang);
7005
7006 DString scopeName;
7007 DString className;
7008 DString namespaceName;
7009 DString funcType;
7010 DString funcName;
7011 DString funcArgs;
7012 DString funcTempList;
7013 DString exceptions;
7014 DString funcSpec;
7015 bool isRelated=false;
7016 bool isMemberOf=false;
7017 bool isFriend=false;
7018 bool done=false;
7019 TypeSpecifier spec = root->spec;
7020 while (!done)
7021 {
7022 done=true;
7023 if (funcDecl.stripPrefix("friend ")) // treat friends as related members
7024 {
7025 isFriend=true;
7026 done=false;
7027 }
7028 if (funcDecl.stripPrefix("inline "))
7029 {
7030 spec.setInline(true);
7031 done=false;
7032 }
7033 if (funcDecl.stripPrefix("explicit "))
7034 {
7035 spec.setExplicit(true);
7036 done=false;
7037 }
7038 if (funcDecl.stripPrefix("mutable "))
7039 {
7040 spec.setMutable(true);
7041 done=false;
7042 }
7043 if (funcDecl.stripPrefix("thread_local "))
7044 {
7045 spec.setThreadLocal(true);
7046 done=false;
7047 }
7048 if (funcDecl.stripPrefix("virtual "))
7049 {
7050 done=false;
7051 }
7052 }
7053
7054 // delete any ; from the function declaration
7055 size_t sep=0;
7056 while ((sep=funcDecl.find(';'))!=DString::npos)
7057 {
7058 funcDecl=(funcDecl.left(sep)+funcDecl.mid(sep+1)).stripWhiteSpace();
7059 }
7060
7061 // make sure the first character is a space to simplify searching.
7062 if (!funcDecl.empty() && funcDecl[0]!=' ') funcDecl.prepend(" ");
7063
7064 // remove some superfluous spaces
7065 funcDecl= substitute(
7066 substitute(
7067 substitute(funcDecl,"~ ","~"),
7068 ":: ","::"
7069 ),
7070 " ::","::"
7071 ).stripWhiteSpace();
7072
7073 //printf("funcDecl='%s'\n",qPrint(funcDecl));
7074 if (isFriend && funcDecl.startsWith("class "))
7075 {
7076 //printf("friend class\n");
7077 funcDecl=funcDecl.mid(6);
7078 funcName = funcDecl;
7079 }
7080 else if (isFriend && funcDecl.startsWith("struct "))
7081 {
7082 funcDecl=funcDecl.mid(7);
7083 funcName = funcDecl;
7084 }
7085 else
7086 {
7087 // extract information from the declarations
7088 parseFuncDecl(funcDecl,root->lang,scopeName,funcType,funcName,
7089 funcArgs,funcTempList,exceptions
7090 );
7091 }
7092
7093 // the class name can also be a namespace name, we decide this later.
7094 // if a related class name is specified and the class name could
7095 // not be derived from the function declaration, then use the
7096 // related field.
7097 AUTO_TRACE_ADD("scopeName='{}' className='{}' namespaceName='{}' funcType='{}' funcName='{}' funcArgs='{}'",
7098 scopeName,className,namespaceName,funcType,funcName,funcArgs);
7099 if (!relates.empty())
7100 { // related member, prefix user specified scope
7101 isRelated=true;
7102 isMemberOf=(root->relatesType == RelatesType::MemberOf);
7103 if (getClass(relates)==nullptr && !scopeName.empty())
7104 {
7105 scopeName= mergeScopes(scopeName,relates);
7106 }
7107 else
7108 {
7109 scopeName = relates;
7110 }
7111 }
7112
7113 if (relates.empty() && root->parent() &&
7114 (root->parent()->section.isScope() || root->parent()->section.isObjcImpl()) &&
7115 !root->parent()->name.empty()) // see if we can combine scopeName
7116 // with the scope in which it was found
7117 {
7118 DString joinedName = root->parent()->name+"::"+scopeName;
7119 if (!scopeName.empty() &&
7120 (getClass(joinedName) || Doxygen::namespaceLinkedMap->find(joinedName)))
7121 {
7122 scopeName = joinedName;
7123 }
7124 else
7125 {
7126 scopeName = mergeScopes(root->parent()->name,scopeName);
7127 }
7128 }
7129 else // see if we can prefix a namespace or class that is used from the file
7130 {
7131 FileDef *fd=root->fileDef();
7132 if (fd)
7133 {
7134 for (const auto &fnd : fd->getUsedNamespaces())
7135 {
7136 DString joinedName = fnd->name()+"::"+scopeName;
7137 if (Doxygen::namespaceLinkedMap->find(joinedName))
7138 {
7139 scopeName=joinedName;
7140 break;
7141 }
7142 }
7143 }
7144 }
7146 removeRedundantWhiteSpace(scopeName),false,&funcSpec,DString(),false);
7147
7148 // funcSpec contains the last template specifiers of the given scope.
7149 // If this method does not have any template arguments or they are
7150 // empty while funcSpec is not empty we assume this is a
7151 // specialization of a method. If not, we clear the funcSpec and treat
7152 // this as a normal method of a template class.
7153 if (!(root->tArgLists.size()>0 &&
7154 root->tArgLists.front().size()==0
7155 )
7156 )
7157 {
7158 funcSpec.clear();
7159 }
7160
7161 //namespaceName=removeAnonymousScopes(namespaceName);
7162 if (!Config_getBool(EXTRACT_ANON_NSPACES) && scopeName.find('@')!=DString::npos) return; // skip stuff in anonymous namespace...
7163
7164 // split scope into a namespace and a class part
7165 extractNamespaceName(scopeName,className,namespaceName,true);
7166 AUTO_TRACE_ADD("scopeName='{}' className='{}' namespaceName='{}'",scopeName,className,namespaceName);
7167
7168 //printf("namespaceName='%s' className='%s'\n",qPrint(namespaceName),qPrint(className));
7169 // merge class and namespace scopes again
7170 scopeName.clear();
7171 if (!namespaceName.empty())
7172 {
7173 if (className.empty())
7174 {
7175 scopeName=namespaceName;
7176 }
7177 else if (!relates.empty() || // relates command with explicit scope
7178 !getClass(className)) // class name only exists in a namespace
7179 {
7180 scopeName=namespaceName+"::"+className;
7181 }
7182 else
7183 {
7184 scopeName=className;
7185 }
7186 }
7187 else if (!className.empty())
7188 {
7189 scopeName=className;
7190 }
7191 //printf("new scope='%s'\n",qPrint(scopeName));
7192
7193 DString tempScopeName=scopeName;
7194 ClassDefMutable *cd=getClassMutable(scopeName);
7195 if (cd)
7196 {
7197 if (funcSpec.empty())
7198 {
7199 uint32_t argListIndex=0;
7200 tempScopeName=cd->qualifiedNameWithTemplateParameters(&root->tArgLists,&argListIndex);
7201 }
7202 else
7203 {
7204 tempScopeName=scopeName+funcSpec;
7205 }
7206 }
7207 //printf("scopeName=%s cd=%p root->tArgLists=%p result=%s\n",
7208 // qPrint(scopeName),cd,root->tArgLists,qPrint(tempScopeName));
7209
7210 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
7211 // rebuild the function declaration (needed to get the scope right).
7212 if (!scopeName.empty() && !isRelated && !isFriend && !Config_getBool(HIDE_SCOPE_NAMES) && root->lang!=SrcLangExt::Python)
7213 {
7214 if (!funcType.empty())
7215 {
7216 if (isFunc) // a function -> we use argList for the arguments
7217 {
7218 funcDecl=funcType+" "+tempScopeName+"::"+funcName+funcTempList;
7219 }
7220 else
7221 {
7222 funcDecl=funcType+" "+tempScopeName+"::"+funcName+funcArgs;
7223 }
7224 }
7225 else
7226 {
7227 if (isFunc) // a function => we use argList for the arguments
7228 {
7229 funcDecl=tempScopeName+"::"+funcName+funcTempList;
7230 }
7231 else // variable => add 'argument' list
7232 {
7233 funcDecl=tempScopeName+"::"+funcName+funcArgs;
7234 }
7235 }
7236 }
7237 else // build declaration without scope
7238 {
7239 if (!funcType.empty()) // but with a type
7240 {
7241 if (isFunc) // function => omit argument list
7242 {
7243 funcDecl=funcType+" "+funcName+funcTempList;
7244 }
7245 else // variable => add 'argument' list
7246 {
7247 funcDecl=funcType+" "+funcName+funcArgs;
7248 }
7249 }
7250 else // no type
7251 {
7252 if (isFunc)
7253 {
7254 funcDecl=funcName+funcTempList;
7255 }
7256 else
7257 {
7258 funcDecl=funcName+funcArgs;
7259 }
7260 }
7261 }
7262
7263 if (funcType=="template class" && !funcTempList.empty())
7264 return; // ignore explicit template instantiations
7265
7266 AUTO_TRACE_ADD("Parse results: namespaceName='{}' className=`{}` funcType='{}' funcSpec='{}' "
7267 " funcName='{}' funcArgs='{}' funcTempList='{}' funcDecl='{}' relates='{}'"
7268 " exceptions='{}' isRelated={} isMemberOf={} isFriend={} isFunc={}",
7269 namespaceName, className, funcType, funcSpec,
7270 funcName, funcArgs, funcTempList, funcDecl, relates,
7271 exceptions, isRelated, isMemberOf, isFriend, isFunc);
7272
7273 if (!funcName.empty()) // function name is valid
7274 {
7275 // check if 'className' is actually a scoped enum, in which case we need to
7276 // process it as a global, see issue #6471
7277 bool strongEnum = false;
7278 MemberName *mn=nullptr;
7279 if (!className.empty() && (mn=Doxygen::functionNameLinkedMap->find(className)))
7280 {
7281 for (const auto &imd : *mn)
7282 {
7283 MemberDefMutable *md = toMemberDefMutable(imd.get());
7284 Definition *mdScope = nullptr;
7285 if (md && md->isEnumerate() && md->isStrong() && (mdScope=md->getOuterScope()) &&
7286 // need filter for the correct scope, see issue #9668
7287 ((namespaceName.empty() && mdScope==Doxygen::globalScope) || (mdScope->name()==namespaceName)))
7288 {
7289 AUTO_TRACE_ADD("'{}' is a strong enum! (namespace={} md->getOuterScope()->name()={})",md->name(),namespaceName,md->getOuterScope()->name());
7290 strongEnum = true;
7291 // pass the scope name name as a 'namespace' to the findGlobalMember function
7292 if (!namespaceName.empty())
7293 {
7294 namespaceName+="::"+className;
7295 }
7296 else
7297 {
7298 namespaceName=className;
7299 }
7300 }
7301 }
7302 }
7303
7304 if (funcName.startsWith("operator ")) // strip class scope from cast operator
7305 {
7306 funcName = substitute(funcName,className+"::","");
7307 }
7308 mn = nullptr;
7309 if (!funcTempList.empty()) // try with member specialization
7310 {
7311 mn=Doxygen::memberNameLinkedMap->find(funcName+funcTempList);
7312 }
7313 if (mn==nullptr) // try without specialization
7314 {
7315 mn=Doxygen::memberNameLinkedMap->find(funcName);
7316 }
7317 if (!isRelated && !strongEnum && mn) // function name already found
7318 {
7319 AUTO_TRACE_ADD("member name exists ({} members with this name)",mn->size());
7320 if (!className.empty()) // class name is valid
7321 {
7322 if (funcSpec.empty()) // not a member specialization
7323 {
7324 addMemberFunction(root,mn,scopeName,namespaceName,className,funcType,funcName,
7325 funcArgs,funcTempList,exceptions,
7326 type,args,isFriend,spec,relates,funcDecl,overloaded,isFunc);
7327 }
7328 else if (cd) // member specialization
7329 {
7330 addMemberSpecialization(root,mn,cd,funcType,funcName,funcArgs,funcDecl,exceptions,spec);
7331 }
7332 else
7333 {
7334 //printf("*** Specialized member %s of unknown scope %s%s found!\n",
7335 // qPrint(scopeName),qPrint(funcName),qPrint(funcArgs));
7336 }
7337 }
7338 else if (overloaded) // check if the function belongs to only one class
7339 {
7340 addOverloaded(root,mn,funcType,funcName,funcArgs,funcDecl,exceptions,spec);
7341 }
7342 else // unrelated function with the same name as a member
7343 {
7344 if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec))
7345 {
7346 DString fullFuncDecl=funcDecl;
7347 if (isFunc) fullFuncDecl+=argListToString(root->argList,true);
7348 warn(root->fileName,root->startLine,
7349 "Cannot determine class for function\n{}",
7350 fullFuncDecl
7351 );
7352 }
7353 }
7354 }
7355 else if (isRelated && !relates.empty())
7356 {
7357 AUTO_TRACE_ADD("related function scopeName='{}' className='{}'",scopeName,className);
7358 if (className.empty()) className=relates;
7359 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
7360 if ((cd=getClassMutable(scopeName)))
7361 {
7362 bool newMember=true; // assume we have a new member
7363 MemberDefMutable *mdDefine=nullptr;
7364 {
7365 mn = Doxygen::functionNameLinkedMap->find(funcName);
7366 if (mn)
7367 {
7368 for (const auto &imd : *mn)
7369 {
7370 MemberDefMutable *md = toMemberDefMutable(imd.get());
7371 if (md && md->isDefine())
7372 {
7373 mdDefine = md;
7374 break;
7375 }
7376 }
7377 }
7378 }
7379
7380 if (mdDefine) // macro definition is already created by the preprocessor and inserted as a file member
7381 {
7382 //printf("moving #define %s into class %s\n",qPrint(mdDefine->name()),qPrint(cd->name()));
7383
7384 // take mdDefine from the Doxygen::functionNameLinkedMap (without deleting the data)
7385 auto mdDefineTaken = Doxygen::functionNameLinkedMap->take(funcName,mdDefine);
7386 // insert it as a class member
7387 if ((mn=Doxygen::memberNameLinkedMap->find(funcName))==nullptr)
7388 {
7389 mn=Doxygen::memberNameLinkedMap->add(funcName);
7390 }
7391
7392 if (mdDefine->getFileDef())
7393 {
7394 mdDefine->getFileDef()->removeMember(mdDefine);
7395 }
7396 mdDefine->makeRelated();
7397 mdDefine->setMemberClass(cd);
7398 mdDefine->moveTo(cd);
7399 cd->insertMember(mdDefine);
7400 // also insert the member as an alias in the parent's scope, so it can be referenced also without cd's scope
7401 insertMemberAlias(cd->getOuterScope(),mdDefine);
7402 mn->push_back(std::move(mdDefineTaken));
7403 }
7404 else // normal member, needs to be created and added to the class
7405 {
7406 FileDef *fd=root->fileDef();
7407
7408 if ((mn=Doxygen::memberNameLinkedMap->find(funcName))==nullptr)
7409 {
7410 mn=Doxygen::memberNameLinkedMap->add(funcName);
7411 }
7412 else
7413 {
7414 // see if we got another member with matching arguments
7415 MemberDefMutable *rmd_found = nullptr;
7416 for (const auto &irmd : *mn)
7417 {
7418 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
7419 if (rmd)
7420 {
7421 const ArgumentList &rmdAl = rmd->argumentList();
7422
7423 newMember=
7424 className!=rmd->getOuterScope()->name() ||
7425 !matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmd->typeString(),&rmdAl,
7426 cd,fd,root->type,&root->argList,
7427 true,root->lang);
7428 if (!newMember)
7429 {
7430 rmd_found = rmd;
7431 }
7432 }
7433 }
7434 if (rmd_found) // member already exists as rmd -> add docs
7435 {
7436 AUTO_TRACE_ADD("addMemberDocs for related member {}",root->name);
7437 addMemberDocs(root,rmd_found,funcDecl,nullptr,overloaded,spec);
7438 newMember=false;
7439 }
7440 }
7441
7442 if (newMember) // need to create a new member
7443 {
7444 MemberType mtype = MemberType::Function;
7445 switch (root->mtype)
7446 {
7447 case MethodTypes::Method: mtype = MemberType::Function; break;
7448 case MethodTypes::Signal: mtype = MemberType::Signal; break;
7449 case MethodTypes::Slot: mtype = MemberType::Slot; break;
7450 case MethodTypes::DCOP: mtype = MemberType::DCOP; break;
7451 case MethodTypes::Property: mtype = MemberType::Property; break;
7452 case MethodTypes::Event: mtype = MemberType::Event; break;
7453 }
7454
7455 //printf("New related name '%s' '%d'\n",qPrint(funcName),
7456 // root->argList ? (int)root->argList->count() : -1);
7457
7458 // first note that we pass:
7459 // (root->tArgLists ? root->tArgLists->last() : nullptr)
7460 // for the template arguments for the new "member."
7461 // this accurately reflects the template arguments of
7462 // the related function, which don't have to do with
7463 // those of the related class.
7464 auto md = createMemberDef(
7465 root->fileName,root->startLine,root->startColumn,
7466 funcType,funcName,funcArgs,exceptions,
7467 root->protection,root->virt,
7468 root->isStatic,
7469 isMemberOf ? Relationship::Foreign : Relationship::Related,
7470 mtype,
7471 (!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList()),
7472 funcArgs.empty() ? ArgumentList() : root->argList,
7473 root->metaData);
7474 auto mmd = toMemberDefMutable(md.get());
7475
7476 // also insert the member as an alias in the parent's scope, so it can be referenced also without cd's scope
7477 insertMemberAlias(cd->getOuterScope(),md.get());
7478
7479 // we still have the problem that
7480 // MemberDef::writeDocumentation() in memberdef.cpp
7481 // writes the template argument list for the class,
7482 // as if this member is a member of the class.
7483 // fortunately, MemberDef::writeDocumentation() has
7484 // a special mechanism that allows us to totally
7485 // override the set of template argument lists that
7486 // are printed. We use that and set it to the
7487 // template argument lists of the related function.
7488 //
7489 mmd->setDefinitionTemplateParameterLists(root->tArgLists);
7490
7491 mmd->setTagInfo(root->tagInfo());
7492
7493 addIncludeFile(mmd,root->fileDef(),root);
7494 //printf("Related member name='%s' decl='%s' bodyLine='%d'\n",
7495 // qPrint(funcName),qPrint(funcDecl),root->bodyLine);
7496
7497 // try to find the matching line number of the body from the
7498 // global function list
7499 bool found=false;
7500 if (root->bodyLine==-1)
7501 {
7503 if (rmn)
7504 {
7505 const MemberDefMutable *rmd_found=nullptr;
7506 for (const auto &irmd : *rmn)
7507 {
7508 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
7509 if (rmd)
7510 {
7511 const ArgumentList &rmdAl = rmd->argumentList();
7512 // check for matching argument lists
7513 if (
7514 matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmd->typeString(),&rmdAl,
7515 cd,fd,root->type,&root->argList,
7516 true,root->lang)
7517 )
7518 {
7519 found=true;
7520 rmd_found = rmd;
7521 break;
7522 }
7523 }
7524 }
7525 if (rmd_found) // member found -> copy line number info
7526 {
7527 mmd->setBodySegment(rmd_found->getDefLine(),rmd_found->getStartBodyLine(),rmd_found->getEndBodyLine());
7528 mmd->setBodyDef(rmd_found->getBodyDef());
7529 //md->setBodyMember(rmd);
7530 }
7531 }
7532 }
7533 if (!found) // line number could not be found or is available in this
7534 // entry
7535 {
7536 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
7537 mmd->setBodyDef(fd);
7538 }
7539
7540 //if (root->mGrpId!=-1)
7541 //{
7542 // md->setMemberGroup(memberGroupDict[root->mGrpId]);
7543 //}
7544 mmd->setMemberClass(cd);
7545 mmd->setMemberSpecifiers(spec);
7546 mmd->setVhdlSpecifiers(root->vhdlSpec);
7547 mmd->setDefinition(funcDecl);
7549 mmd->addQualifiers(root->qualifiers);
7550 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
7551 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
7552 mmd->setDocsForDefinition(!root->proto);
7553 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
7554 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7555 mmd->addSectionsToDefinition(root->anchors);
7556 mmd->setMemberGroupId(root->mGrpId);
7557 mmd->setLanguage(root->lang);
7558 mmd->setId(root->id);
7559 //md->setMemberDefTemplateArguments(root->mtArgList);
7560 cd->insertMember(md.get());
7561 cd->insertUsedFile(fd);
7562 mmd->setRefItems(root->sli);
7563 mmd->setRequirementReferences(root->rqli);
7564 if (root->relatesType==RelatesType::Duplicate) mmd->setRelatedAlso(cd);
7565 addMemberToGroups(root,md.get());
7567 //printf("Adding member=%s\n",qPrint(md->name()));
7568 mn->push_back(std::move(md));
7569 }
7570 if (root->relatesType==RelatesType::Duplicate)
7571 {
7572 if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec))
7573 {
7574 DString fullFuncDecl=funcDecl;
7575 if (isFunc) fullFuncDecl+=argListToString(root->argList,true);
7576 warn(root->fileName,root->startLine,
7577 "Cannot determine file/namespace for relatedalso function\n{}",
7578 fullFuncDecl
7579 );
7580 }
7581 }
7582 }
7583 }
7584 else
7585 {
7586 warn_undoc(root->fileName,root->startLine, "class '{}' for related function '{}' is not documented.", className,funcName);
7587 }
7588 }
7589 else if (root->parent() && root->parent()->section.isObjcImpl())
7590 {
7591 addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec);
7592 }
7593 else // unrelated not overloaded member found
7594 {
7595 bool globMem = findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec);
7596 if (className.empty() && !globMem)
7597 {
7598 warn(root->fileName,root->startLine, "class for member '{}' cannot be found.", funcName);
7599 }
7600 else if (!className.empty() && !globMem)
7601 {
7602 warn(root->fileName,root->startLine,
7603 "member '{}' of class '{}' cannot be found",
7604 funcName,className);
7605 }
7606 }
7607 }
7608 else
7609 {
7610 // this should not be called
7611 warn(root->fileName,root->startLine,"member with no name found.");
7612 }
7613 return;
7614}
virtual void removeMember(MemberDef *md)=0
virtual void moveTo(Definition *)=0
virtual bool isStrong() const =0
MemberName::Ptr take(const DString &key, const MemberDef *value)
Definition membername.h:63
Wrapper class for a number of boolean properties.
Definition types.h:694
void parseFuncDecl(const DString &decl, const SrcLangExt lang, DString &clName, DString &type, DString &name, DString &args, DString &funcTempList, DString &exceptions)
Definition declinfo.l:329
static void insertMemberAlias(Definition *outerScope, const MemberDef *md)
Definition doxygen.cpp:6950
static void addMemberSpecialization(const Entry *root, MemberName *mn, ClassDefMutable *cd, const DString &funcType, const DString &funcName, const DString &funcArgs, const DString &funcDecl, const DString &exceptions, TypeSpecifier spec)
Definition doxygen.cpp:6817
static void addMemberFunction(const Entry *root, MemberName *mn, const DString &scopeName, const DString &namespaceName, const DString &className, const DString &funcTyp, const DString &funcName, const DString &funcArgs, const DString &funcTempList, const DString &exceptions, const DString &type, const DString &args, bool isFriend, TypeSpecifier spec, const DString &relates, const DString &funcDecl, bool overloaded, bool isFunc)
Definition doxygen.cpp:6452
static void addOverloaded(const Entry *root, MemberName *mn, const DString &funcType, const DString &funcName, const DString &funcArgs, const DString &funcDecl, const DString &exceptions, TypeSpecifier spec)
Definition doxygen.cpp:6881
static bool findGlobalMember(const Entry *root, const DString &namespaceName, const DString &type, const DString &name, const DString &tempArg, const DString &, const DString &decl, TypeSpecifier)
Definition doxygen.cpp:6031

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addIncludeFile(), addLocalObjCMethod(), addMemberDocs(), addMemberFunction(), addMemberSpecialization(), addMemberToGroups(), ModuleManager::addMemberToModule(), addOverloaded(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, argListToString(), MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, DString::clear(), Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), Entry::endBodyLine, extractNamespaceName(), Entry::fileDef(), Entry::fileName, DString::find(), LinkedMap< T, Hash, KeyEqual, Map >::find(), findGlobalMember(), Doxygen::functionNameLinkedMap, Definition::getBodyDef(), getClass(), getClassMutable(), Definition::getDefLine(), Definition::getEndBodyLine(), MemberDef::getFileDef(), Definition::getOuterScope(), Definition::getStartBodyLine(), FileDef::getUsedNamespaces(), Doxygen::globalScope, Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), insertMemberAlias(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), MemberDef::isDefine(), MemberDef::isEnumerate(), EntryType::isScope(), Entry::isStatic, MemberDef::isStrong(), Entry::lang, DString::left(), MemberDefMutable::makeRelated(), matchArguments2(), Doxygen::memberNameLinkedMap, mergeScopes(), Entry::metaData, Entry::mGrpId, DString::mid(), MemberDef::moveTo(), Entry::mtype, Definition::name(), Entry::name, Doxygen::namespaceLinkedMap, DString::npos, Entry::parent(), parseFuncDecl(), DString::prepend(), Entry::protection, Entry::proto, MemberName::push_back(), ClassDef::qualifiedNameWithTemplateParameters(), Entry::qualifiers, Entry::relatesType, FileDef::removeMember(), removeRedundantWhiteSpace(), Entry::rqli, Entry::section, MemberDefMutable::setMemberClass(), MemberName::size(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, DString::startsWith(), DString::stripPrefix(), stripTemplateSpecifiersFromScope(), DString::stripWhiteSpace(), substitute(), Entry::tagInfo(), MemberNameLinkedMap::take(), Entry::tArgLists, toMemberDefMutable(), Entry::type, MemberDef::typeString(), Entry::vhdlSpec, Entry::virt, warn, and warn_undoc.

Referenced by filterMemberDocumentation(), and findObjCMethodDefinitions().

◆ findMemberDocumentation()

void findMemberDocumentation ( const Entry * root)
static

Definition at line 7769 of file doxygen.cpp.

7770{
7771 if (root->section.isMemberDoc() ||
7772 root->section.isOverloadDoc() ||
7773 root->section.isFunction() ||
7774 root->section.isVariable() ||
7775 root->section.isVariableDoc() ||
7776 root->section.isDefine() ||
7777 root->section.isIncludedService() ||
7778 root->section.isExportedInterface()
7779 )
7780 {
7781 AUTO_TRACE();
7782 if (root->relatesType==RelatesType::Duplicate && !root->relates.empty())
7783 {
7785 }
7787 }
7788 for (const auto &e : root->children())
7789 {
7790 if (!e->section.isEnum())
7791 {
7792 findMemberDocumentation(e.get());
7793 }
7794 }
7795}
static void findMemberDocumentation(const Entry *root)
Definition doxygen.cpp:7769
static void filterMemberDocumentation(const Entry *root, const DString &relates)
Definition doxygen.cpp:7620

References AUTO_TRACE, Entry::children(), DString::empty(), filterMemberDocumentation(), findMemberDocumentation(), Entry::relates, Entry::relatesType, and Entry::section.

Referenced by findMemberDocumentation(), and parseInput().

◆ findModuleDocumentation()

void findModuleDocumentation ( const Entry * root)
static

Definition at line 1326 of file doxygen.cpp.

1327{
1328 if (root->section.isModuleDoc())
1329 {
1330 AUTO_TRACE();
1332 }
1333 for (const auto &e : root->children()) findModuleDocumentation(e.get());
1334}
void addDocs(const Entry *root)
static void findModuleDocumentation(const Entry *root)
Definition doxygen.cpp:1326

References ModuleManager::addDocs(), AUTO_TRACE, Entry::children(), findModuleDocumentation(), ModuleManager::instance(), and Entry::section.

Referenced by findModuleDocumentation(), and parseInput().

◆ findObjCMethodDefinitions()

void findObjCMethodDefinitions ( const Entry * root)
static

Definition at line 7799 of file doxygen.cpp.

7800{
7801 AUTO_TRACE();
7802 for (const auto &objCImpl : root->children())
7803 {
7804 if (objCImpl->section.isObjcImpl())
7805 {
7806 for (const auto &objCMethod : objCImpl->children())
7807 {
7808 if (objCMethod->section.isFunction())
7809 {
7810 //printf(" Found ObjC method definition %s\n",qPrint(objCMethod->name));
7811 findMember(objCMethod.get(),
7812 objCMethod->relates,
7813 objCMethod->type,
7814 objCMethod->args,
7815 objCMethod->type+" "+objCImpl->name+"::"+objCMethod->name+" "+objCMethod->args,
7816 false,true);
7817 objCMethod->section=EntryType::makeEmpty();
7818 }
7819 }
7820 }
7821 }
7822}

References AUTO_TRACE, Entry::children(), and findMember().

Referenced by parseInput().

◆ findScopeFromQualifiedName()

Definition * findScopeFromQualifiedName ( NamespaceDefMutable * startScope,
const DString & n,
FileDef * fileScope,
const TagInfo * tagInfo )
static

Definition at line 793 of file doxygen.cpp.

795{
796 //printf("<findScopeFromQualifiedName(%s,%s)\n",startScope ? qPrint(startScope->name()) : 0, qPrint(n));
797 Definition *resultScope=toDefinition(startScope);
798 if (resultScope==nullptr) resultScope=Doxygen::globalScope;
800 int l1 = 0;
801 int i1 = getScopeFragment(scope,0,&l1);
802 if (i1==-1)
803 {
804 //printf(">no fragments!\n");
805 return resultScope;
806 }
807 int p=i1+l1,l2=0,i2=0;
808 while ((i2=getScopeFragment(scope,p,&l2))!=-1)
809 {
810 DString nestedNameSpecifier = scope.mid(i1,l1);
811 Definition *orgScope = resultScope;
812 //printf(" nestedNameSpecifier=%s\n",qPrint(nestedNameSpecifier));
813 resultScope = const_cast<Definition*>(resultScope->findInnerCompound(nestedNameSpecifier));
814 //printf(" resultScope=%p\n",resultScope);
815 if (resultScope==nullptr)
816 {
817 if (orgScope==Doxygen::globalScope && fileScope && !fileScope->getUsedNamespaces().empty())
818 // also search for used namespaces
819 {
820 for (const auto &nd : fileScope->getUsedNamespaces())
821 {
823 if (mnd)
824 {
825 resultScope = findScopeFromQualifiedName(toNamespaceDefMutable(nd),n,fileScope,tagInfo);
826 if (resultScope!=nullptr) break;
827 }
828 }
829 if (resultScope)
830 {
831 // for a nested class A::I in used namespace N, we get
832 // N::A::I while looking for A, so we should compare
833 // resultScope->name() against scope.left(i2+l2)
834 //printf(" -> result=%s scope=%s\n",qPrint(resultScope->name()),qPrint(scope));
835 if (rightScopeMatch(resultScope->name(),scope.left(i2+l2)))
836 {
837 break;
838 }
839 goto nextFragment;
840 }
841 }
842
843 // also search for used classes. Complication: we haven't been able
844 // to put them in the right scope yet, because we are still resolving
845 // the scope relations!
846 // Therefore loop through all used classes and see if there is a right
847 // scope match between the used class and nestedNameSpecifier.
848 for (const auto &usedName : g_usingDeclarations)
849 {
850 //printf("Checking using class %s\n",qPrint(usedName));
851 if (rightScopeMatch(usedName,nestedNameSpecifier))
852 {
853 // ui.currentKey() is the fully qualified name of nestedNameSpecifier
854 // so use this instead.
855 DString fqn = usedName + scope.mid(p);
856 resultScope = buildScopeFromQualifiedName(fqn,startScope->getLanguage(),nullptr);
857 //printf("Creating scope from fqn=%s result %p\n",qPrint(fqn),resultScope);
858 if (resultScope)
859 {
860 //printf("> Match! resultScope=%s\n",qPrint(resultScope->name()));
861 return resultScope;
862 }
863 }
864 }
865
866 //printf("> name %s not found in scope %s\n",qPrint(nestedNameSpecifier),qPrint(orgScope->name()));
867 return nullptr;
868 }
869 nextFragment:
870 i1=i2;
871 l1=l2;
872 p=i2+l2;
873 }
874 //printf(">findScopeFromQualifiedName scope %s\n",qPrint(resultScope->name()));
875 return resultScope;
876}
virtual const Definition * findInnerCompound(const DString &name) const =0
bool empty() const
Definition linkedmap.h:374

References buildScopeFromQualifiedName(), LinkedRefMap< T, Hash, KeyEqual, Map >::empty(), Definition::findInnerCompound(), findScopeFromQualifiedName(), g_usingDeclarations, Definition::getLanguage(), getScopeFragment(), FileDef::getUsedNamespaces(), Doxygen::globalScope, DString::left(), DString::mid(), Definition::name(), rightScopeMatch(), stripTemplateSpecifiersFromScope(), toDefinition(), and toNamespaceDefMutable().

Referenced by addConceptToContext(), addPageToContext(), buildNamespaceList(), findClassRelation(), findGroupScope(), findScopeFromQualifiedName(), and resolveClassNestingRelations().

◆ findSectionsInDocumentation()

void findSectionsInDocumentation ( )
static

Definition at line 9677 of file doxygen.cpp.

9678{
9679 // for each class
9680 for (const auto &cd : *Doxygen::classLinkedMap)
9681 {
9682 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9683 if (cdm)
9684 {
9686 }
9687 }
9688 // for each concept
9689 for (const auto &cd : *Doxygen::conceptLinkedMap)
9690 {
9691 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
9692 if (cdm)
9693 {
9695 }
9696 }
9697 // for each file
9698 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9699 {
9700 for (const auto &fd : *fn)
9701 {
9702 fd->findSectionsInDocumentation();
9703 }
9704 }
9705 // for each namespace
9706 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9707 {
9709 if (ndm)
9710 {
9712 }
9713 }
9714 // for each group
9715 for (const auto &gd : *Doxygen::groupLinkedMap)
9716 {
9717 gd->findSectionsInDocumentation();
9718 }
9719 // for each page
9720 for (const auto &pd : *Doxygen::pageLinkedMap)
9721 {
9722 pd->findSectionsInDocumentation();
9723 }
9724 // for each directory
9725 for (const auto &dd : *Doxygen::dirLinkedMap)
9726 {
9727 dd->findSectionsInDocumentation();
9728 }
9730 if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
9731}
virtual void findSectionsInDocumentation()=0
virtual void findSectionsInDocumentation()=0
void findSectionsInDocumentation()
virtual void findSectionsInDocumentation()=0

References Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Doxygen::dirLinkedMap, ClassDefMutable::findSectionsInDocumentation(), ConceptDefMutable::findSectionsInDocumentation(), ModuleManager::findSectionsInDocumentation(), NamespaceDefMutable::findSectionsInDocumentation(), Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), Doxygen::mainPage, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, toClassDefMutable(), toConceptDefMutable(), and toNamespaceDefMutable().

Referenced by parseInput().

◆ findTagLessClasses() [1/2]

void findTagLessClasses ( )
static

Definition at line 1932 of file doxygen.cpp.

1933{
1934 std::set<const Definition *> candidates;
1935 for (auto &cd : *Doxygen::classLinkedMap)
1936 {
1937 if (cd->isAlias()) continue;
1938 Definition *scope = cd->getOuterScope();
1939 //printf(" scope=%s for class %s\n",qPrint(scope?scope->name():"<null>"),qPrint(cd->name()));
1940 if (scope && scope->definitionType()==Definition::TypeNamespace) // class that is not nested
1941 {
1942 const NamespaceDef *nd = toNamespaceDef(scope);
1943 if (nd && nd==Doxygen::globalScope) // class at global namespace
1944 {
1945 const FileDef *fd = cd->getFileDef();
1946 if (fd)
1947 {
1948 findTagLessClasses(candidates,fd);
1949 }
1950 }
1951 else if (nd) // class in a namespace
1952 {
1953 findTagLessClasses(candidates,nd);
1954 }
1955 }
1956 }
1957
1958 // since processTagLessClasses is potentially adding classes to Doxygen::classLinkedMap
1959 // we need to call it outside of the loop above, otherwise the iterator gets invalidated!
1960 for (const auto &d : candidates)
1961 {
1962 //printf("------ processing tag-less classes for %s\n",qPrint(d->name()));
1963 if (d->definitionType()==Definition::TypeNamespace)
1964 {
1965 const NamespaceDef *nd = toNamespaceDef(d);
1966 processTagLessClasses(nd,nd,nd,MemberListType::DecVarMembers(),MemberListType::DecEnumMembers(),"",0);
1967 }
1968 else if (d->definitionType()==Definition::TypeFile)
1969 {
1970 const FileDef *fd = toFileDef(d);
1971 processTagLessClasses(fd,fd,fd,MemberListType::DecVarMembers(),MemberListType::DecEnumMembers(),"",0);
1972 }
1973 else if (d->definitionType()==Definition::TypeClass)
1974 {
1975 const ClassDef *cd = toClassDef(d);
1976 processTagLessClasses(cd,cd,cd,MemberListType::PubAttribs(),MemberListType::PubTypes(),"",0);
1977 }
1978 }
1979}
ClassDef * toClassDef(Definition *d)
static void processTagLessClasses(const Definition *root, const Container *def, const TagContainer *tagParent, MemberListType varFilter, MemberListType typeFilter, const DString &prefix, int count)
Look through the members of class cd and its public members.
Definition doxygen.cpp:1897
static void findTagLessClasses()
Definition doxygen.cpp:1932

References Doxygen::classLinkedMap, Definition::definitionType(), findTagLessClasses(), Definition::getOuterScope(), Doxygen::globalScope, processTagLessClasses(), toClassDef(), toFileDef(), toNamespaceDef(), Definition::TypeClass, Definition::TypeFile, and Definition::TypeNamespace.

Referenced by findTagLessClasses(), findTagLessClasses(), and parseInput().

◆ findTagLessClasses() [2/2]

template<typename Container>
void findTagLessClasses ( std::set< const Definition * > & candidates,
const Container * cd )
static

Definition at line 1917 of file doxygen.cpp.

1918{
1919 for (const auto &icd : cd->getClasses())
1920 {
1921 // process all non-anonymous inner classes, but skip aliases (e.g. from inline namespaces),
1922 // as these share the members of the aliased class, which is processed already
1923 if (!icd->isAlias() && icd->name().find('@')==DString::npos)
1924 {
1925 findTagLessClasses(candidates,icd);
1926 }
1927 }
1928
1929 candidates.insert(cd);
1930}

References findTagLessClasses(), and DString::npos.

◆ findTemplateInstanceRelation()

void findTemplateInstanceRelation ( const Entry * root,
Definition * context,
ClassDefMutable * templateClass,
const DString & templSpec,
const TemplateNameMap & templateNames,
bool isArtificial )
static

Definition at line 5033 of file doxygen.cpp.

5038{
5039 AUTO_TRACE("Derived from template '{}' with parameters '{}' isArtificial={}",
5040 templateClass->name(),templSpec,isArtificial);
5041
5042 DString tempArgsStr = tempArgListToString(templateClass->templateArguments(),root->lang,false);
5043 bool existingClass = templSpec==tempArgsStr;
5044 if (existingClass) return; // avoid recursion
5045
5046 bool freshInstance=false;
5047 ClassDefMutable *instanceClass = toClassDefMutable(
5048 templateClass->insertTemplateInstance(
5049 root->fileName,root->startLine,root->startColumn,templSpec,freshInstance));
5050 if (instanceClass)
5051 {
5052 if (freshInstance)
5053 {
5054 instanceClass->setArtificial(true);
5055 instanceClass->setLanguage(root->lang);
5056
5057 AUTO_TRACE_ADD("found fresh instance '{}'",instanceClass->name());
5058 instanceClass->setTemplateBaseClassNames(templateNames);
5059
5060 // search for new template instances caused by base classes of
5061 // instanceClass
5062 auto it_pair = g_classEntries.equal_range(templateClass->name().str());
5063 for (auto it=it_pair.first ; it!=it_pair.second ; ++it)
5064 {
5065 const Entry *templateRoot = it->second;
5066 AUTO_TRACE_ADD("template root found '{}' templSpec='{}'",templateRoot->name,templSpec);
5067 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(root->lang,templSpec);
5068 findBaseClassesForClass(templateRoot,context,templateClass,instanceClass,
5069 TemplateInstances,isArtificial,templArgs.get(),templateNames);
5070
5071 findUsedClassesForClass(templateRoot,context,templateClass,instanceClass,
5072 isArtificial,templArgs.get(),templateNames);
5073 }
5074 }
5075 else
5076 {
5077 AUTO_TRACE_ADD("instance already exists");
5078 }
5079 }
5080}
virtual void setTemplateBaseClassNames(const TemplateNameMap &templateNames)=0
virtual ClassDef * insertTemplateInstance(const DString &fileName, int startLine, size_t startColumn, const DString &templSpec, bool &freshInstance)=0
static void findUsedClassesForClass(const Entry *root, Definition *context, ClassDefMutable *masterCd, ClassDefMutable *instanceCd, bool isArtificial, const ArgumentList *actualArgs=nullptr, const TemplateNameMap &templateNames=TemplateNameMap())
Definition doxygen.cpp:4826

References AUTO_TRACE, AUTO_TRACE_ADD, Entry::fileName, findBaseClassesForClass(), findUsedClassesForClass(), g_classEntries, ClassDefMutable::insertTemplateInstance(), Entry::lang, Definition::name(), Entry::name, DefinitionMutable::setArtificial(), DefinitionMutable::setLanguage(), ClassDefMutable::setTemplateBaseClassNames(), Entry::startColumn, Entry::startLine, DString::str(), stringToArgumentList(), tempArgListToString(), ClassDef::templateArguments(), TemplateInstances, and toClassDefMutable().

Referenced by findClassRelation(), and resolveTemplateInstanceInType().

◆ findTemplateSpecializationPosition()

int findTemplateSpecializationPosition ( const DString & name)
static

Definition at line 5124 of file doxygen.cpp.

5125{
5126 if (name.empty()) return 0;
5127 int l = static_cast<int>(name.length());
5128 if (name[l-1]=='>') // search backward to find the matching <, allowing nested <...> and strings.
5129 {
5130 int count=1;
5131 int i=l-2;
5132 char insideQuote=0;
5133 while (count>0 && i>=0)
5134 {
5135 char c = name[i--];
5136 switch (c)
5137 {
5138 case '>': if (!insideQuote) count++; break;
5139 case '<': if (!insideQuote) count--; break;
5140 case '\'': if (!insideQuote) insideQuote=c;
5141 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
5142 break;
5143 case '"': if (!insideQuote) insideQuote=c;
5144 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
5145 break;
5146 default: break;
5147 }
5148 }
5149 if (i>=0) l=i+1;
5150 }
5151 return l;
5152}

Referenced by findClassRelation().

◆ findUsedClassesForClass()

void findUsedClassesForClass ( const Entry * root,
Definition * context,
ClassDefMutable * masterCd,
ClassDefMutable * instanceCd,
bool isArtificial,
const ArgumentList * actualArgs = nullptr,
const TemplateNameMap & templateNames = TemplateNameMap() )
static

Definition at line 4826 of file doxygen.cpp.

4834{
4835 AUTO_TRACE();
4836 const ArgumentList &formalArgs = masterCd->templateArguments();
4837 for (auto &mni : masterCd->memberNameInfoLinkedMap())
4838 {
4839 for (auto &mi : *mni)
4840 {
4841 const MemberDef *md=mi->memberDef();
4842 if (md->isVariable() || md->isObjCProperty()) // for each member variable in this class
4843 {
4844 AUTO_TRACE_ADD("Found variable '{}' in class '{}'",md->name(),masterCd->name());
4845 DString type = normalizeNonTemplateArgumentsInString(md->typeString(),masterCd,formalArgs);
4846 DString typedefValue = md->getLanguage()==SrcLangExt::Java ? type : resolveTypeDef(masterCd,type);
4847 if (!typedefValue.empty())
4848 {
4849 type = typedefValue;
4850 }
4851 int pos=0;
4852 DString usedClassName;
4853 DString templSpec;
4854 bool found=false;
4855 // the type can contain template variables, replace them if present
4856 type = substituteTemplateArgumentsInString(type,formalArgs,actualArgs);
4857
4858 //printf(" template substitution gives=%s\n",qPrint(type));
4859 while (!found && extractClassNameFromType(type,pos,usedClassName,templSpec,root->lang)!=-1)
4860 {
4861 // find the type (if any) that matches usedClassName
4862 SymbolResolver resolver(masterCd->getFileDef());
4863 const ClassDefMutable *typeCd = resolver.resolveClassMutable(masterCd,usedClassName,false,true);
4864 //printf("====> usedClassName=%s -> typeCd=%s\n",
4865 // qPrint(usedClassName),typeCd?qPrint(typeCd->name()):"<none>");
4866 if (typeCd)
4867 {
4868 usedClassName = typeCd->name();
4869 }
4870
4871 // replace any namespace aliases
4872 replaceNamespaceAliases(usedClassName);
4873 // add any template arguments to the class
4874 DString usedName = removeRedundantWhiteSpace(usedClassName+templSpec);
4875 //printf(" usedName=%s usedClassName=%s templSpec=%s\n",qPrint(usedName),qPrint(usedClassName),qPrint(templSpec));
4876
4877 TemplateNameMap formTemplateNames;
4878 if (templateNames.empty())
4879 {
4880 formTemplateNames = getTemplateArgumentsInName(formalArgs,usedName.str());
4881 }
4882 BaseInfo bi(usedName,Protection::Public,Specifier::Normal);
4883 findClassRelation(root,context,instanceCd,&bi,formTemplateNames,TemplateInstances,isArtificial);
4884
4885 for (const Argument &arg : masterCd->templateArguments())
4886 {
4887 if (arg.name==usedName) // type is a template argument
4888 {
4889 ClassDef *usedCd = Doxygen::hiddenClassLinkedMap->find(usedName);
4890 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4891 if (usedCd==nullptr)
4892 {
4893 usedCdm = toClassDefMutable(
4894 Doxygen::hiddenClassLinkedMap->add(usedName,
4896 masterCd->getDefFileName(),masterCd->getDefLine(),
4897 masterCd->getDefColumn(),
4898 usedName,
4899 ClassDef::Class)));
4900 if (usedCdm)
4901 {
4902 //printf("making %s a template argument!!!\n",qPrint(usedCd->name()));
4903 usedCdm->makeTemplateArgument();
4904 usedCdm->setUsedOnly(true);
4905 usedCdm->setLanguage(masterCd->getLanguage());
4906 usedCd = usedCdm;
4907 }
4908 }
4909 if (usedCd)
4910 {
4911 found=true;
4912 AUTO_TRACE_ADD("case 1: adding used class '{}'", usedCd->name());
4913 instanceCd->addUsedClass(usedCd,md->name(),md->protection());
4914 if (usedCdm)
4915 {
4916 if (isArtificial) usedCdm->setArtificial(true);
4917 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4918 }
4919 }
4920 }
4921 }
4922
4923 if (!found)
4924 {
4925 ClassDef *usedCd=findClassWithinClassContext(context,masterCd,usedName);
4926 //printf("Looking for used class %s: result=%s master=%s\n",
4927 // qPrint(usedName),usedCd?qPrint(usedCd->name()):"<none>",masterCd?qPrint(masterCd->name()):"<none>");
4928
4929 if (usedCd)
4930 {
4931 found=true;
4932 AUTO_TRACE_ADD("case 2: adding used class '{}'", usedCd->name());
4933 instanceCd->addUsedClass(usedCd,md->name(),md->protection()); // class exists
4934 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4935 if (usedCdm)
4936 {
4937 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4938 }
4939 }
4940 }
4941 }
4942 if (!found && !type.empty()) // used class is not documented in any scope
4943 {
4945 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4946 if (usedCd==nullptr && !Config_getBool(HIDE_UNDOC_RELATIONS))
4947 {
4948 if (type.endsWith("(*") || type.endsWith("(^")) // type is a function pointer
4949 {
4950 type+=md->argsString();
4951 }
4952 AUTO_TRACE_ADD("New undocumented used class '{}'", type);
4953 usedCdm = toClassDefMutable(
4956 masterCd->getDefFileName(),masterCd->getDefLine(),
4957 masterCd->getDefColumn(),
4958 type,ClassDef::Class)));
4959 if (usedCdm)
4960 {
4961 usedCdm->setUsedOnly(true);
4962 usedCdm->setLanguage(masterCd->getLanguage());
4963 usedCd = usedCdm;
4964 }
4965 }
4966 if (usedCd)
4967 {
4968 AUTO_TRACE_ADD("case 3: adding used class '{}'", usedCd->name());
4969 instanceCd->addUsedClass(usedCd,md->name(),md->protection());
4970 if (usedCdm)
4971 {
4972 if (isArtificial) usedCdm->setArtificial(true);
4973 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4974 }
4975 }
4976 }
4977 }
4978 }
4979 }
4980}
virtual void addUsedClass(ClassDef *cd, const DString &accessName, Protection prot)=0
virtual void makeTemplateArgument(bool b=true)=0
virtual void setUsedOnly(bool b)=0
virtual void addUsedByClass(ClassDef *cd, const DString &accessName, Protection prot)=0
virtual bool isObjCProperty() const =0
DString resolveTypeDef(const Definition *context, const DString &qualifiedName, const Definition **typedefContext)
Definition util.cpp:232
DString normalizeNonTemplateArgumentsInString(const DString &name, const Definition *context, const ArgumentList &formalArgs)
Definition util.cpp:3471
int extractClassNameFromType(const DString &type, int &pos, DString &name, DString &templSpec, SrcLangExt lang)
Definition util.cpp:3386

References ClassDefMutable::addUsedByClass(), ClassDefMutable::addUsedClass(), MemberDef::argsString(), AUTO_TRACE, AUTO_TRACE_ADD, ClassDef::Class, Config_getBool, createClassDef(), DString::empty(), DString::endsWith(), extractClassNameFromType(), LinkedMap< T, Hash, KeyEqual, Map >::find(), findClassRelation(), findClassWithinClassContext(), Definition::getDefColumn(), Definition::getDefFileName(), Definition::getDefLine(), ClassDef::getFileDef(), Definition::getLanguage(), getTemplateArgumentsInName(), Doxygen::hiddenClassLinkedMap, MemberDef::isObjCProperty(), MemberDef::isVariable(), Entry::lang, ClassDefMutable::makeTemplateArgument(), ClassDef::memberNameInfoLinkedMap(), Definition::name(), normalizeNonTemplateArgumentsInString(), MemberDef::protection(), removeRedundantWhiteSpace(), replaceNamespaceAliases(), SymbolResolver::resolveClassMutable(), resolveTypeDef(), DefinitionMutable::setArtificial(), DefinitionMutable::setLanguage(), ClassDefMutable::setUsedOnly(), DString::str(), substituteTemplateArgumentsInString(), ClassDef::templateArguments(), TemplateInstances, toClassDefMutable(), and MemberDef::typeString().

Referenced by findTemplateInstanceRelation(), and findUsedTemplateInstances().

◆ findUsedNamespace()

NamespaceDef * findUsedNamespace ( const LinkedRefMap< NamespaceDef > & unl,
const DString & name )
static

Definition at line 2156 of file doxygen.cpp.

2158{
2159 NamespaceDef *usingNd =nullptr;
2160 for (auto &und : unl)
2161 {
2162 DString uScope=und->name()+"::";
2163 usingNd = getResolvedNamespace(uScope+name);
2164 if (usingNd!=nullptr) break;
2165 }
2166 return usingNd;
2167}

References getResolvedNamespace().

Referenced by findUsingDirectives().

◆ findUsedTemplateInstances()

void findUsedTemplateInstances ( )
static

Definition at line 5586 of file doxygen.cpp.

5587{
5588 AUTO_TRACE();
5589 for (const auto &[name,root] : g_classEntries)
5590 {
5591 DString bName = extractClassName(root);
5592 ClassDefMutable *cdm = getClassMutable(bName);
5593 if (cdm)
5594 {
5595 findUsedClassesForClass(root,cdm,cdm,cdm,true);
5597 cdm->addTypeConstraints();
5598 }
5599 }
5600}
virtual void addTypeConstraints()=0
static void makeTemplateInstanceRelation(const Entry *root, ClassDefMutable *cd)
Definition doxygen.cpp:5568

References ClassDefMutable::addTypeConstraints(), AUTO_TRACE, extractClassName(), findUsedClassesForClass(), g_classEntries, getClassMutable(), and makeTemplateInstanceRelation().

Referenced by parseInput().

◆ findUsingDeclarations()

void findUsingDeclarations ( const Entry * root,
bool filterPythonPackages )
static

Definition at line 2326 of file doxygen.cpp.

2327{
2328 if (root->section.isUsingDecl() &&
2329 !root->parent()->section.isCompound() && // not a class/struct member
2330 (!filterPythonPackages || (root->lang==SrcLangExt::Python && root->fileName.endsWith("__init__.py")))
2331 )
2332 {
2333 AUTO_TRACE("Found using declaration '{}' at line {} of {} inside section {}",
2334 root->name,root->startLine,root->fileName,root->parent()->section);
2335 if (!root->name.empty())
2336 {
2337 const Definition *usingDef = nullptr;
2338 NamespaceDefMutable *nd = nullptr;
2339 FileDef *fd = root->fileDef();
2340 DString scName;
2341
2342 // see if the using statement was found inside a namespace or inside
2343 // the global file scope.
2344 if (root->parent()->section.isNamespace())
2345 {
2346 scName=root->parent()->name;
2347 if (!scName.empty())
2348 {
2349 nd = getResolvedNamespaceMutable(scName);
2350 }
2351 }
2352
2353 // Assume the using statement was used to import a class.
2354 // Find the scope in which the 'using' namespace is defined by prepending
2355 // the possible scopes in which the using statement was found, starting
2356 // with the most inner scope and going to the most outer scope (i.e.
2357 // file scope).
2358
2359 DString name = substitute(root->name,".","::"); //Java/C# scope->internal
2360
2361 SymbolResolver resolver;
2362 const Definition *scope = nd;
2363 if (nd==nullptr) scope = fd;
2364 usingDef = resolver.resolveSymbol(scope,name);
2365
2366 //printf("usingDef(scope=%s,name=%s)=%s\n",qPrint(nd?nd->qualifiedName():""),qPrint(name),usingDef?qPrint(usingDef->qualifiedName()):"nullptr");
2367
2368 if (!usingDef)
2369 {
2370 usingDef = getClass(name); // try direct lookup, this is needed to get
2371 // builtin STL classes to properly resolve, e.g.
2372 // vector -> std::vector
2373 }
2374 if (!usingDef)
2375 {
2376 usingDef = Doxygen::hiddenClassLinkedMap->find(name); // check if it is already hidden
2377 }
2378#if 0
2379 if (!usingDef)
2380 {
2381 AUTO_TRACE_ADD("New using class '{}' (sec={})! #tArgLists={}",
2382 name,root->section,root->tArgLists.size());
2385 createClassDef( "<using>",1,1, name, ClassDef::Class)));
2386 if (usingCd)
2387 {
2388 usingCd->setArtificial(true);
2389 usingCd->setLanguage(root->lang);
2390 usingDef = usingCd;
2391 }
2392 }
2393#endif
2394 else
2395 {
2396 AUTO_TRACE_ADD("Found used type '{}' in scope='{}'",
2397 usingDef->name(), nd ? nd->name(): fd ? fd->name() : DString("<unknown>"));
2398 }
2399
2400 if (usingDef)
2401 {
2402 if (nd)
2403 {
2404 nd->addUsingDeclaration(usingDef);
2405 }
2406 else if (fd)
2407 {
2408 fd->addUsingDeclaration(usingDef);
2409 }
2410 }
2411 }
2412 }
2413 for (const auto &e : root->children()) findUsingDeclarations(e.get(),filterPythonPackages);
2414}
virtual void addUsingDeclaration(const Definition *d)=0
virtual void addUsingDeclaration(const Definition *d)=0
const Definition * resolveSymbol(const Definition *scope, const DString &name, const DString &args=DString(), bool checkCV=false, bool insideCode=false, bool onlyLinkable=false)
Find the symbool definition matching name within the scope set.
static void findUsingDeclarations(const Entry *root, bool filterPythonPackages)
Definition doxygen.cpp:2326

References FileDef::addUsingDeclaration(), NamespaceDefMutable::addUsingDeclaration(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::children(), ClassDef::Class, createClassDef(), DString::empty(), DString::endsWith(), Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), findUsingDeclarations(), getClass(), getResolvedNamespaceMutable(), Doxygen::hiddenClassLinkedMap, EntryType::isCompound(), Entry::lang, Definition::name(), Entry::name, Entry::parent(), SymbolResolver::resolveSymbol(), Entry::section, DefinitionMutable::setArtificial(), DefinitionMutable::setLanguage(), Entry::startLine, substitute(), Entry::tArgLists, and toClassDefMutable().

Referenced by findUsingDeclarations(), and parseInput().

◆ findUsingDeclImports()

void findUsingDeclImports ( const Entry * root)
static

Definition at line 2479 of file doxygen.cpp.

2480{
2481 if (root->section.isUsingDecl() &&
2482 root->parent()->section.isCompound() // in a class/struct member
2483 )
2484 {
2485 AUTO_TRACE("Found using declaration '{}' inside section {}", root->name, root->parent()->section);
2486 DString fullName=removeRedundantWhiteSpace(root->parent()->name);
2487 fullName=stripAnonymousNamespaceScope(fullName);
2488 fullName=stripTemplateSpecifiersFromScope(fullName);
2489 ClassDefMutable *cd = getClassMutable(fullName);
2490 if (cd)
2491 {
2492 AUTO_TRACE_ADD("found class '{}'",cd->name());
2493 size_t i=root->name.rfind("::");
2494 if (i!=DString::npos)
2495 {
2496 DString scope=root->name.left(i);
2497 DString memName=root->name.mid(i+2);
2498 SymbolResolver resolver;
2499 const ClassDef *bcd = resolver.resolveClass(cd,scope); // todo: file in fileScope parameter
2500 AUTO_TRACE_ADD("name={} scope={} bcd={}",scope,cd?cd->name():"<none>",bcd?bcd->name():"<none>");
2501 if (bcd && bcd!=cd)
2502 {
2503 AUTO_TRACE_ADD("found class '{}' memName='{}'",bcd->name(),memName);
2505 const MemberNameInfo *mni = mnlm.find(memName);
2506 if (mni)
2507 {
2508 for (auto &mi : *mni)
2509 {
2510 const MemberDef *md = mi->memberDef();
2511 if (md && md->protection()!=Protection::Private)
2512 {
2513 AUTO_TRACE_ADD("found member '{}'",mni->memberName());
2514 DString fileName = root->fileName;
2515 if (fileName.empty() && root->tagInfo())
2516 {
2517 fileName = root->tagInfo()->tagName;
2518 }
2519 if (!cd->containsOverload(md))
2520 {
2521 createUsingMemberImportForClass(root,cd,md,fileName,memName);
2522 // also insert the member into copies of the class
2523 auto it = g_usingClassMap.find(cd->qualifiedName().str());
2524 if (it != g_usingClassMap.end())
2525 {
2526 for (const auto &copyCd : it->second)
2527 {
2528 createUsingMemberImportForClass(root,copyCd,md,fileName,memName);
2529 }
2530 }
2531 }
2532 }
2533 }
2534 }
2535 }
2536 }
2537 }
2538 }
2539 else if (root->section.isUsingDecl() &&
2540 (root->parent()->section.isNamespace() || root->parent()->section.isEmpty()) && // namespace or global member
2541 root->lang==SrcLangExt::Cpp // do we also want this for e.g. Fortran? (see test case 095)
2542 )
2543 {
2544 AUTO_TRACE("Found using declaration '{}' inside section {}", root->name, root->parent()->section);
2545 Definition *scope = nullptr;
2546 NamespaceDefMutable *nd = nullptr;
2547 FileDef *fd = root->parent()->fileDef();
2548 if (!root->parent()->name.empty())
2549 {
2550 DString fullName=removeRedundantWhiteSpace(root->parent()->name);
2551 fullName=stripAnonymousNamespaceScope(fullName);
2553 scope = nd;
2554 }
2555 else
2556 {
2557 scope = fd;
2558 }
2559 if (scope)
2560 {
2561 AUTO_TRACE_ADD("found scope '{}'",scope->name());
2562 SymbolResolver resolver;
2563 const Definition *def = resolver.resolveSymbol(root->name.startsWith("::") ? nullptr : scope,root->name);
2564 if (def && def->definitionType()==Definition::TypeMember)
2565 {
2566 size_t i=root->name.rfind("::");
2567 DString memName;
2568 if (i!=DString::npos)
2569 {
2570 memName = root->name.right(root->name.length()-i-2);
2571 }
2572 else
2573 {
2574 memName = root->name;
2575 }
2576 const MemberDef *md = toMemberDef(def);
2577 AUTO_TRACE_ADD("found member '{}' for name '{}'",md->qualifiedName(),root->name);
2578 DString fileName = root->fileName;
2579 if (fileName.empty() && root->tagInfo())
2580 {
2581 fileName = root->tagInfo()->tagName;
2582 }
2583 const ArgumentList &templAl = md->templateArguments();
2584 const ArgumentList &al = md->argumentList();
2585
2586 auto newMd = createMemberDef(
2587 fileName,root->startLine,root->startColumn,
2588 md->typeString(),memName,md->argsString(),
2589 md->excpString(),root->protection,root->virt,
2590 md->isStatic(),Relationship::Member,md->memberType(),
2591 templAl,al,root->metaData
2592 );
2593 auto newMmd = toMemberDefMutable(newMd.get());
2594 if (nd)
2595 {
2596 newMmd->setNamespace(nd);
2597 nd->insertMember(newMd.get());
2598 }
2599 if (fd)
2600 {
2601 newMmd->setFileDef(fd);
2602 fd->insertMember(newMd.get());
2603 }
2604 if (!root->doc.empty() || !root->brief.empty())
2605 {
2606 newMmd->setDocumentation(root->doc,root->docFile,root->docLine);
2607 newMmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2608 newMmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2609 }
2610 else
2611 {
2612 newMmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
2613 newMmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
2614 newMmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
2615 }
2616 newMmd->setDefinition(md->definition());
2617 applyMemberOverrideOptions(root,newMmd);
2618 newMmd->addQualifiers(root->qualifiers);
2619 newMmd->setBitfields(md->bitfieldString());
2620 newMmd->addSectionsToDefinition(root->anchors);
2621 newMmd->setBodySegment(md->getDefLine(),md->getStartBodyLine(),md->getEndBodyLine());
2622 newMmd->setBodyDef(md->getBodyDef());
2623 newMmd->setInitializer(md->initializer());
2624 newMmd->setRequiresClause(md->requiresClause());
2625 newMmd->setMaxInitLines(md->initializerLines());
2626 newMmd->setMemberGroupId(root->mGrpId);
2627 newMmd->setMemberSpecifiers(md->getMemberSpecifiers());
2628 newMmd->setVhdlSpecifiers(md->getVhdlSpecifiers());
2629 newMmd->setLanguage(root->lang);
2630 newMmd->setId(root->id);
2632 mn->push_back(std::move(newMd));
2633#if 0 // insert an alias instead of a copy
2634 const MemberDef *md = toMemberDef(def);
2635 AUTO_TRACE_ADD("found member '{}' for name '{}'",md->qualifiedName(),root->name);
2636 auto aliasMd = createMemberDefAlias(nd,md);
2637 DString aliasFullName = nd->qualifiedName()+"::"+aliasMd->localName();
2638 if (nd && aliasMd.get())
2639 {
2640 nd->insertMember(aliasMd.get());
2641 }
2642 if (fd && aliasMd.get())
2643 {
2644 fd->insertMember(aliasMd.get());
2645 }
2646 MemberName *mn = Doxygen::memberNameLinkedMap->add(aliasFullName);
2647 mn->push_back(std::move(aliasMd));
2648#endif
2649 }
2650 else if (def && def->definitionType()==Definition::TypeClass)
2651 {
2652 const ClassDef *cd = toClassDef(def);
2653 DString copyFullName;
2654 if (nd==nullptr)
2655 {
2656 copyFullName = cd->localName();
2657 }
2658 else
2659 {
2660 copyFullName = nd->qualifiedName()+"::"+cd->localName();
2661 }
2662 if (Doxygen::classLinkedMap->find(copyFullName)==nullptr)
2663 {
2665 Doxygen::classLinkedMap->add(copyFullName,
2666 cd->deepCopy(copyFullName)));
2667 AUTO_TRACE_ADD("found class '{}' for name '{}' copy '{}' obj={}",cd->qualifiedName(),root->name,copyFullName,(void*)ncdm);
2668 g_usingClassMap[cd->qualifiedName().str()].push_back(ncdm);
2669 if (ncdm)
2670 {
2671 if (nd) ncdm->moveTo(nd);
2672 if ((!root->doc.empty() || !root->brief.empty())) // use docs at using statement
2673 {
2674 ncdm->setDocumentation(root->doc,root->docFile,root->docLine);
2675 ncdm->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2676 }
2677 else // use docs from used class
2678 {
2679 ncdm->setDocumentation(cd->documentation(),cd->docFile(),cd->docLine());
2681 }
2682 if (nd)
2683 {
2684 nd->addInnerCompound(ncdm);
2685 nd->addUsingDeclaration(ncdm);
2686 }
2687 if (fd)
2688 {
2689 if (ncdm) ncdm->setFileDef(fd);
2690 fd->insertClass(ncdm);
2691 fd->addUsingDeclaration(ncdm);
2692 }
2693 }
2694 }
2695#if 0 // insert an alias instead of a copy
2696 auto aliasCd = createClassDefAlias(nd,cd);
2697 DString aliasFullName;
2698 if (nd==nullptr)
2699 {
2700 aliasFullName = aliasCd->localName();
2701 }
2702 else
2703 {
2704 aliasFullName = nd->qualifiedName()+"::"+aliasCd->localName();
2705 }
2706 AUTO_TRACE_ADD("found class '{}' for name '{}' aliasFullName='{}'",cd->qualifiedName(),root->name,aliasFullName);
2707 auto acd = Doxygen::classLinkedMap->add(aliasFullName,std::move(aliasCd));
2708 if (nd && acd)
2709 {
2710 nd->addInnerCompound(acd);
2711 }
2712 if (fd && acd)
2713 {
2714 fd->insertClass(acd);
2715 }
2716#endif
2717 }
2718 else if (scope)
2719 {
2720 AUTO_TRACE_ADD("no symbol with name '{}' in scope {}",root->name,scope->name());
2721 }
2722 }
2723 }
2724 for (const auto &e : root->children()) findUsingDeclImports(e.get());
2725}
virtual std::unique_ptr< ClassDef > deepCopy(const DString &name) const =0
virtual void moveTo(Definition *)=0
virtual bool containsOverload(const MemberDef *md) const =0
virtual const DString & localName() const =0
const ClassDef * resolveClass(const Definition *scope, const DString &name, bool maybeUnlinkable=false, bool mayBeHidden=false)
Find the class definition matching name within the scope set.
std::unique_ptr< ClassDef > createClassDefAlias(const Definition *newScope, const ClassDef *cd)
Definition classdef.cpp:816
static void findUsingDeclImports(const Entry *root)
Definition doxygen.cpp:2479
static void createUsingMemberImportForClass(const Entry *root, ClassDefMutable *cd, const MemberDef *md, const DString &fileName, const DString &memName)
Definition doxygen.cpp:2430
static std::unordered_map< std::string, std::vector< ClassDefMutable * > > g_usingClassMap
Definition doxygen.cpp:2477
std::unique_ptr< MemberDef > createMemberDefAlias(const Definition *newScope, const MemberDef *aliasMd)

References LinkedMap< T, Hash, KeyEqual, Map >::add(), DefinitionMutable::addInnerCompound(), FileDef::addUsingDeclaration(), NamespaceDefMutable::addUsingDeclaration(), Entry::anchors, applyMemberOverrideOptions(), MemberDef::argsString(), MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, MemberDef::bitfieldString(), Entry::brief, Definition::briefDescription(), Definition::briefFile(), Entry::briefFile, Definition::briefLine(), Entry::briefLine, Entry::children(), Doxygen::classLinkedMap, ClassDef::containsOverload(), createClassDefAlias(), createMemberDef(), createMemberDefAlias(), createUsingMemberImportForClass(), ClassDef::deepCopy(), MemberDef::definition(), Definition::definitionType(), Entry::doc, Definition::docFile(), Entry::docFile, Definition::docLine(), Entry::docLine, Definition::documentation(), DString::empty(), MemberDef::excpString(), Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), findUsingDeclImports(), Doxygen::functionNameLinkedMap, g_usingClassMap, Definition::getBodyDef(), getClassMutable(), Definition::getDefLine(), Definition::getEndBodyLine(), MemberDef::getMemberSpecifiers(), getResolvedNamespace(), Definition::getStartBodyLine(), MemberDef::getVhdlSpecifiers(), Entry::id, Entry::inbodyDocs, Definition::inbodyDocumentation(), Definition::inbodyFile(), Entry::inbodyFile, Definition::inbodyLine(), Entry::inbodyLine, MemberDef::initializer(), MemberDef::initializerLines(), FileDef::insertClass(), FileDef::insertMember(), NamespaceDefMutable::insertMember(), EntryType::isCompound(), MemberDef::isStatic(), Entry::lang, DString::left(), DString::length(), Definition::localName(), ClassDef::memberNameInfoLinkedMap(), Doxygen::memberNameLinkedMap, MemberDef::memberType(), Entry::metaData, Entry::mGrpId, DString::mid(), ClassDef::moveTo(), Definition::name(), Entry::name, DString::npos, Entry::parent(), Entry::protection, MemberDef::protection(), MemberName::push_back(), Definition::qualifiedName(), Entry::qualifiers, removeRedundantWhiteSpace(), MemberDef::requiresClause(), SymbolResolver::resolveClass(), SymbolResolver::resolveSymbol(), DString::rfind(), DString::right(), Entry::section, DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), ClassDefMutable::setFileDef(), Entry::startColumn, Entry::startLine, DString::startsWith(), DString::str(), stripAnonymousNamespaceScope(), stripTemplateSpecifiersFromScope(), Entry::tagInfo(), TagInfo::tagName, MemberDef::templateArguments(), toClassDef(), toClassDefMutable(), toMemberDef(), toMemberDefMutable(), toNamespaceDefMutable(), Definition::TypeClass, Definition::TypeMember, MemberDef::typeString(), and Entry::virt.

Referenced by findUsingDeclImports(), and parseInput().

◆ findUsingDirectives()

void findUsingDirectives ( const Entry * root)
static

Definition at line 2169 of file doxygen.cpp.

2170{
2171 if (root->section.isUsingDir())
2172 {
2173 AUTO_TRACE("Found using directive {} at line {} of {}",root->name,root->startLine,root->fileName);
2174 DString name=substitute(root->name,".","::");
2175 if (name.endsWith("::"))
2176 {
2177 name=name.left(name.length()-2);
2178 }
2179 if (!name.empty())
2180 {
2181 NamespaceDef *usingNd = nullptr;
2182 NamespaceDefMutable *nd = nullptr;
2183 FileDef *fd = root->fileDef();
2184 DString nsName;
2185
2186 // see if the using statement was found inside a namespace or inside
2187 // the global file scope.
2188 if (root->parent() && root->parent()->section.isNamespace() &&
2189 (fd==nullptr || fd->getLanguage()!=SrcLangExt::Java) // not a .java file
2190 )
2191 {
2192 nsName=stripAnonymousNamespaceScope(root->parent()->name);
2193 if (!nsName.empty())
2194 {
2195 nd = getResolvedNamespaceMutable(nsName);
2196 }
2197 }
2198
2199 // find the scope in which the 'using' namespace is defined by prepending
2200 // the possible scopes in which the using statement was found, starting
2201 // with the most inner scope and going to the most outer scope (i.e.
2202 // file scope).
2203 int scopeOffset = static_cast<int>(nsName.length());
2204 do
2205 {
2206 DString scope=scopeOffset>0 ?
2207 nsName.left(scopeOffset)+"::" : DString();
2208 usingNd = getResolvedNamespace(scope+name);
2209 //printf("Trying with scope='%s' usingNd=%p\n",(scope+qPrint(name)),usingNd);
2210 if (scopeOffset==0)
2211 {
2212 scopeOffset=-1;
2213 }
2214 else
2215 {
2216 size_t o = nsName.rfind("::",scopeOffset-1);
2217 scopeOffset = o!=DString::npos ? static_cast<int>(o) : 0;
2218 }
2219 } while (scopeOffset>=0 && usingNd==nullptr);
2220
2221 if (usingNd==nullptr && nd) // not found, try used namespaces in this scope
2222 // or in one of the parent namespace scopes
2223 {
2224 const NamespaceDefMutable *pnd = nd;
2225 while (pnd && usingNd==nullptr)
2226 {
2227 // also try with one of the used namespaces found earlier
2229
2230 // goto the parent
2231 Definition *s = pnd->getOuterScope();
2233 {
2235 }
2236 else
2237 {
2238 pnd = nullptr;
2239 }
2240 }
2241 }
2242 if (usingNd==nullptr && fd) // still nothing, also try used namespace in the
2243 // global scope
2244 {
2245 usingNd = findUsedNamespace(fd->getUsedNamespaces(),name);
2246 }
2247
2248 //printf("%s -> %s\n",qPrint(name),usingNd?qPrint(usingNd->name()):"<none>");
2249
2250 // add the namespace the correct scope
2251 if (usingNd)
2252 {
2253 //printf("using fd=%p nd=%p\n",fd,nd);
2254 if (nd)
2255 {
2256 //printf("Inside namespace %s\n",qPrint(nd->name()));
2257 nd->addUsingDirective(usingNd);
2258 }
2259 else if (fd)
2260 {
2261 //printf("Inside file %s\n",qPrint(fd->name()));
2262 fd->addUsingDirective(usingNd);
2263 }
2264 }
2265 else // unknown namespace, but add it anyway.
2266 {
2267 AUTO_TRACE_ADD("new unknown namespace {} lang={} hidden={}",name,root->lang,root->hidden);
2268 // add namespace to the list
2271 createNamespaceDef(root->fileName,root->startLine,root->startColumn,name)));
2272 if (nd)
2273 {
2274 nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
2275 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2277 nd->setHidden(root->hidden);
2278 nd->setArtificial(true);
2279 nd->setLanguage(root->lang);
2280 nd->setId(root->id);
2281 nd->setMetaData(root->metaData);
2282 nd->setInline(root->spec.isInline());
2283 nd->setExported(root->exported);
2284
2285 for (const Grouping &g : root->groups)
2286 {
2287 GroupDef *gd=nullptr;
2289 gd->addNamespace(nd);
2290 }
2291
2292 // insert the namespace in the file definition
2293 if (fd)
2294 {
2295 fd->insertNamespace(nd);
2296 fd->addUsingDirective(nd);
2297 }
2298
2299 // the empty string test is needed for extract all case
2300 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2301 nd->insertUsedFile(fd);
2302 nd->setRefItems(root->sli);
2303 nd->setRequirementReferences(root->rqli);
2304 }
2305 }
2306 }
2307 }
2308 for (const auto &e : root->children()) findUsingDirectives(e.get());
2309}
virtual void addUsingDirective(NamespaceDef *nd)=0
virtual bool addNamespace(NamespaceDef *def)=0
virtual const LinkedRefMap< NamespaceDef > & getUsedNamespaces() const =0
virtual void addUsingDirective(NamespaceDef *nd)=0
static NamespaceDef * findUsedNamespace(const LinkedRefMap< NamespaceDef > &unl, const DString &name)
Definition doxygen.cpp:2156
static void findUsingDirectives(const Entry *root)
Definition doxygen.cpp:2169

References GroupDef::addNamespace(), DefinitionMutable::addSectionsToDefinition(), FileDef::addUsingDirective(), NamespaceDefMutable::addUsingDirective(), Entry::anchors, AUTO_TRACE, AUTO_TRACE_ADD, Entry::brief, Entry::briefFile, Entry::briefLine, Entry::children(), createNamespaceDef(), Definition::definitionType(), Entry::doc, Entry::docFile, Entry::docLine, DString::empty(), Entry::exported, Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), findUsedNamespace(), findUsingDirectives(), Definition::getLanguage(), Definition::getOuterScope(), getResolvedNamespace(), getResolvedNamespaceMutable(), FileDef::getUsedNamespaces(), NamespaceDef::getUsedNamespaces(), Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, Entry::hidden, Entry::id, FileDef::insertNamespace(), NamespaceDefMutable::insertUsedFile(), Entry::lang, DString::left(), DString::length(), Entry::metaData, Entry::name, Doxygen::namespaceLinkedMap, DString::npos, Entry::parent(), DString::rfind(), Entry::rqli, Entry::section, DefinitionMutable::setArtificial(), DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), DefinitionMutable::setExported(), DefinitionMutable::setHidden(), DefinitionMutable::setId(), NamespaceDefMutable::setInline(), DefinitionMutable::setLanguage(), NamespaceDefMutable::setMetaData(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, stripAnonymousNamespaceScope(), substitute(), toNamespaceDef(), toNamespaceDefMutable(), and Definition::TypeNamespace.

Referenced by findUsingDirectives(), and parseInput().

◆ flushCachedTemplateRelations()

void flushCachedTemplateRelations ( )
static

Definition at line 9736 of file doxygen.cpp.

9737{
9738 // remove all references to classes from the cache
9739 // as there can be new template instances in the inheritance path
9740 // to this class. Optimization: only remove those classes that
9741 // have inheritance instances as direct or indirect sub classes.
9743
9744 // remove all cached typedef resolutions whose target is a
9745 // template class as this may now be a template instance
9746 // for each global function name
9747 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9748 {
9749 // for each function with that name
9750 for (const auto &ifmd : *fn)
9751 {
9752 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9753 if (fmd && fmd->isTypedefValCached())
9754 {
9755 const ClassDef *cd = fmd->getCachedTypedefVal();
9756 if (cd->isTemplate()) fmd->invalidateTypedefValCache();
9757 }
9758 }
9759 }
9760 // for each class method name
9761 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9762 {
9763 // for each function with that name
9764 for (const auto &imd : *nm)
9765 {
9766 MemberDefMutable *md = toMemberDefMutable(imd.get());
9767 if (md && md->isTypedefValCached())
9768 {
9769 const ClassDef *cd = md->getCachedTypedefVal();
9770 if (cd->isTemplate()) md->invalidateTypedefValCache();
9771 }
9772 }
9773 }
9774}
virtual bool isTemplate() const =0
Returns true if this class is a template.
virtual const ClassDef * getCachedTypedefVal() const =0
virtual bool isTypedefValCached() const =0
virtual void invalidateTypedefValCache()=0
static void clearTypeLookupCache(ClearScope scope)

References SymbolResolver::Classes, SymbolResolver::clearTypeLookupCache(), Doxygen::functionNameLinkedMap, MemberDef::getCachedTypedefVal(), MemberDefMutable::invalidateTypedefValCache(), ClassDef::isTemplate(), MemberDef::isTypedefValCached(), Doxygen::memberNameLinkedMap, and toMemberDefMutable().

Referenced by parseInput().

◆ flushUnresolvedRelations()

void flushUnresolvedRelations ( )
static

Definition at line 9778 of file doxygen.cpp.

9779{
9780 // Remove all unresolved references to classes from the cache.
9781 // This is needed before resolving the inheritance relations, since
9782 // it would otherwise not find the inheritance relation
9783 // for C in the example below, as B::I was already found to be unresolvable
9784 // (which is correct if you ignore the inheritance relation between A and B).
9785 //
9786 // class A { class I {} };
9787 // class B : public A {};
9788 // class C : public B::I {};
9790
9791 // for each class method name
9792 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9793 {
9794 // for each function with that name
9795 for (const auto &imd : *nm)
9796 {
9797 MemberDefMutable *md = toMemberDefMutable(imd.get());
9798 if (md)
9799 {
9801 }
9802 }
9803 }
9804
9805}
virtual void invalidateCachedArgumentTypes()=0

References SymbolResolver::clearTypeLookupCache(), MemberDefMutable::invalidateCachedArgumentTypes(), Doxygen::memberNameLinkedMap, toMemberDefMutable(), and SymbolResolver::Unresolved.

Referenced by parseInput().

◆ g_pathsVisited()

StringUnorderedSet g_pathsVisited ( 1009 )
static

Referenced by readDir(), and readFileOrDirectory().

◆ generateClassDocs()

void generateClassDocs ( )
static

Definition at line 9494 of file doxygen.cpp.

9495{
9496 std::vector<ClassDefMutable*> classList;
9497 for (const auto &cdi : *Doxygen::classLinkedMap)
9498 {
9499 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9500 if (cd && (cd->getOuterScope()==nullptr ||
9502 {
9503 addClassAndNestedClasses(classList,cd);
9504 }
9505 }
9506 for (const auto &cdi : *Doxygen::hiddenClassLinkedMap)
9507 {
9508 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9509 if (cd && (cd->getOuterScope()==nullptr ||
9511 {
9512 addClassAndNestedClasses(classList,cd);
9513 }
9514 }
9515 generateDocsForClassList(classList);
9516}
static void generateDocsForClassList(const std::vector< ClassDefMutable * > &classList)
Definition doxygen.cpp:9396

References addClassAndNestedClasses(), Doxygen::classLinkedMap, Definition::definitionType(), generateDocsForClassList(), Definition::getOuterScope(), Doxygen::hiddenClassLinkedMap, toClassDefMutable(), and Definition::TypeClass.

Referenced by generateOutput().

◆ generateConceptDocs()

void generateConceptDocs ( )
static

Definition at line 9520 of file doxygen.cpp.

9521{
9522 for (const auto &cdi : *Doxygen::conceptLinkedMap)
9523 {
9525
9526 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9527 if (cd &&
9528 (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9529 cd->getOuterScope()==Doxygen::globalScope // only look at global concepts
9530 ) && !cd->isHidden() && cd->isLinkableInProject()
9531 )
9532 {
9533 msg("Generating docs for concept {}...\n",cd->displayName());
9535 }
9536 }
9537}
virtual void writeDocumentation(OutputList &ol)=0
virtual DString displayName(bool includeScope=true) const =0
virtual bool isHidden() const =0

References Doxygen::conceptLinkedMap, Definition::displayName(), g_outputList, Definition::getOuterScope(), Doxygen::globalScope, Definition::isHidden(), Definition::isLinkableInProject(), msg, toConceptDefMutable(), and ConceptDefMutable::writeDocumentation().

Referenced by generateOutput().

◆ generateConfigFile()

void generateConfigFile ( const DString & configFile,
bool shortList,
bool updateOnly = false )
static

Generate a template version of the configuration file. If the shortList parameter is true a configuration file without comments will be generated.

Definition at line 10616 of file doxygen.cpp.

10618{
10619 std::ofstream f;
10620 bool fileOpened=openOutputFile(configFile,f);
10621 bool writeToStdout=configFile=="-";
10622 if (fileOpened)
10623 {
10624 TextStream t(&f);
10625 Config::writeTemplate(t,shortList,updateOnly);
10626 if (!writeToStdout)
10627 {
10628 if (!updateOnly)
10629 {
10630 msg("\n\nConfiguration file '{}' created.\n\n",configFile);
10631 msg("Now edit the configuration file and enter\n\n");
10632 if (configFile!="Doxyfile" && configFile!="doxyfile")
10633 msg(" doxygen {}\n\n",configFile);
10634 else
10635 msg(" doxygen\n\n");
10636 msg("to generate the documentation for your project\n\n");
10637 }
10638 else
10639 {
10640 msg("\n\nConfiguration file '{}' updated.\n\n",configFile);
10641 }
10642 }
10643 }
10644 else
10645 {
10646 term("Cannot open file {} for writing\n",configFile);
10647 }
10648}
void writeTemplate(TextStream &t, bool shortList, bool updateOnly=false)

References msg, openOutputFile(), term, and Config::writeTemplate().

Referenced by readConfiguration().

◆ generateDiskNames()

void generateDiskNames ( )
static

Definition at line 10870 of file doxygen.cpp.

10871{
10872 for (const auto &fn : *Doxygen::inputNameLinkedMap)
10873 {
10874 struct FileEntry
10875 {
10876 FileEntry(const DString &p,FileDef *fd) : path(p), fileDef(fd) {}
10877 DString path;
10878 FileDef *fileDef;
10879 };
10880
10881 // collect the entry for which to compute the longest common prefix (LCP) of the path
10882 std::vector<FileEntry> fileEntries;
10883 for (const auto &fd : *fn)
10884 {
10885 if (!fd->isReference()) // skip external references
10886 {
10887 fileEntries.emplace_back(fd->getPath(),fd.get());
10888 }
10889 }
10890
10891 size_t size = fileEntries.size();
10892
10893 if (size==1) // name if unique, so diskname is simply the name
10894 {
10895 FileDef *fd = fileEntries[0].fileDef;
10896 fd->setDiskName(fn->fileName());
10897 }
10898 else if (size>1) // multiple occurrences of the same file name
10899 {
10900 // sort the array
10901 std::stable_sort(fileEntries.begin(),
10902 fileEntries.end(),
10903 [](const FileEntry &fe1,const FileEntry &fe2)
10904 { return dstricmp_sort(fe1.path,fe2.path)<0; }
10905 );
10906
10907 // since the entries are sorted, the common prefix of the whole array is same
10908 // as the common prefix between the first and last entry
10909 const FileEntry &first = fileEntries[0];
10910 const FileEntry &last = fileEntries[size-1];
10911 int first_path_size = static_cast<int>(first.path.size())-1; // -1 to skip trailing slash
10912 int last_path_size = static_cast<int>(last.path.size())-1; // -1 to skip trailing slash
10913 int j=0;
10914 int i=0;
10915 for (i=0;i<first_path_size && i<last_path_size;i++)
10916 {
10917 if (first.path[i]=='/') j=i;
10918 if (first.path[i]!=last.path[i]) break;
10919 }
10920 if (i==first_path_size && i<last_path_size && last.path[i]=='/')
10921 {
10922 // case first='some/path' and last='some/path/more' => match is 'some/path'
10923 j=first_path_size;
10924 }
10925 else if (i==last_path_size && i<first_path_size && first.path[i]=='/')
10926 {
10927 // case first='some/path/more' and last='some/path' => match is 'some/path'
10928 j=last_path_size;
10929 }
10930
10931 // add non-common part of the path to the name
10932 for (auto &fileEntry : fileEntries)
10933 {
10934 DString prefix = fileEntry.path.right(fileEntry.path.length()-j-1);
10935 fileEntry.fileDef->setName(prefix+fn->fileName());
10936 //printf("!!!!!!!! non unique disk name=%s:%s\n",qPrint(prefix),fn->fileName());
10937 fileEntry.fileDef->setDiskName(prefix+fn->fileName());
10938 }
10939 }
10940 }
10941}
constexpr auto prefix
Definition anchor.cpp:47
virtual void setDiskName(const DString &name)=0

References Doxygen::inputNameLinkedMap, prefix, and FileDef::setDiskName().

Referenced by parseInput().

◆ generateDocsForClassList()

void generateDocsForClassList ( const std::vector< ClassDefMutable * > & classList)
static

Definition at line 9396 of file doxygen.cpp.

9397{
9398 AUTO_TRACE();
9399 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
9400 if (numThreads>1) // multi threaded processing
9401 {
9402 struct DocContext
9403 {
9404 DocContext(ClassDefMutable *cd_,const OutputList &ol_)
9405 : cd(cd_), ol(ol_) {}
9406 ClassDefMutable *cd;
9407 OutputList ol;
9408 };
9409 ThreadPool threadPool(numThreads);
9410 std::vector< std::future< std::shared_ptr<DocContext> > > results;
9411 for (const auto &cd : classList)
9412 {
9413 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9414 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9415 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9416 )
9417 {
9418 auto ctx = std::make_shared<DocContext>(cd,*g_outputList);
9419 auto processFile = [ctx]()
9420 {
9421 msg("Generating docs for compound {}...\n",ctx->cd->displayName());
9422
9423 // skip external references, anonymous compounds and
9424 // template instances
9425 if (!ctx->cd->isHidden() && !ctx->cd->isEmbeddedInOuterScope() &&
9426 ctx->cd->isLinkableInProject() && !ctx->cd->isImplicitTemplateInstance())
9427 {
9428 ctx->cd->writeDocumentation(ctx->ol);
9429 ctx->cd->writeMemberList(ctx->ol);
9430 }
9431
9432 // even for undocumented classes, the inner classes can be documented.
9433 ctx->cd->writeDocumentationForInnerClasses(ctx->ol);
9434 return ctx;
9435 };
9436 results.emplace_back(threadPool.queue(processFile));
9437 }
9438 }
9439 for (auto &f : results)
9440 {
9441 auto ctx = f.get();
9442 }
9443 }
9444 else // single threaded processing
9445 {
9446 for (const auto &cd : classList)
9447 {
9448 //printf("cd=%s getOuterScope=%p global=%p hidden=%d embeddedInOuterScope=%d\n",
9449 // qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope,cd->isHidden(),cd->isEmbeddedInOuterScope());
9450 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9451 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9452 )
9453 {
9454 // skip external references, anonymous compounds and
9455 // template instances
9456 if ( !cd->isHidden() && !cd->isEmbeddedInOuterScope() &&
9457 cd->isLinkableInProject() && !cd->isImplicitTemplateInstance())
9458 {
9459 msg("Generating docs for compound {}...\n",cd->displayName());
9460
9461 cd->writeDocumentation(*g_outputList);
9462 cd->writeMemberList(*g_outputList);
9463 }
9464 // even for undocumented classes, the inner classes can be documented.
9465 cd->writeDocumentationForInnerClasses(*g_outputList);
9466 }
9467 }
9468 }
9469}

References AUTO_TRACE, Config_getInt, g_outputList, Doxygen::globalScope, msg, and ThreadPool::queue().

Referenced by generateClassDocs().

◆ generateExampleDocs()

void generateExampleDocs ( )
static

Definition at line 10320 of file doxygen.cpp.

10321{
10323 for (const auto &pd : *Doxygen::exampleLinkedMap)
10324 {
10325 msg("Generating docs for example {}...\n",pd->name());
10326 SrcLangExt lang = getLanguageFromFileName(pd->name(), SrcLangExt::Unknown);
10327 if (lang != SrcLangExt::Unknown)
10328 {
10329 DString ext = getFileNameExtension(pd->name());
10330 auto intf = Doxygen::parserManager->getCodeParser(ext);
10331 intf->resetCodeParserState();
10332 }
10333 DString n=pd->getOutputFileBase();
10334 startFile(*g_outputList,n,false,n,pd->name());
10336 g_outputList->docify(pd->name());
10339 DString lineNoOptStr;
10340 if (pd->showLineNo())
10341 {
10342 lineNoOptStr="{lineno}";
10343 }
10344 g_outputList->generateDoc(pd->docFile(), // file
10345 pd->docLine(), // startLine
10346 pd.get(), // context
10347 nullptr, // memberDef
10348 (pd->briefDescription().empty()?"":pd->briefDescription()+"\n\n")+
10349 pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
10350 DocOptions()
10351 .setIndexWords(true)
10352 .setExample(pd->name()));
10353 endFile(*g_outputList); // contains g_outputList->endContents()
10354 }
10356}
void disable(OutputType o)
void enable(OutputType o)
void docify(const DString &s)
Definition outputlist.h:433
void generateDoc(const DString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const DString &docStr, const DocOptions &options)
void startContents()
Definition outputlist.h:614
std::unique_ptr< CodeParserInterface > getCodeParser(const DString &extension)
Gets the interface to the parser associated with a given extension.
Definition parserintf.h:253
void endTitle(OutputList &ol, const DString &fileName, const DString &name)
Definition index.cpp:398
void endFile(OutputList &ol, bool skipNavIndex, bool skipEndContents, const DString &navPath)
Definition index.cpp:431
void startTitle(OutputList &ol, const DString &fileName, const DefinitionMutable *def)
Definition index.cpp:388
void startFile(OutputList &ol, const DString &name, bool isSource, const DString &manName, const DString &title, HighlightedItem hli, bool additionalIndices, const DString &altSidebarName, int hierarchyLevel, const DString &allMembersFile)
Definition index.cpp:405
Helper class to pass options when calling OutputList::generateDoc().
Definition docoptions.h:24
DString getFileNameExtension(const DString &fn)
Definition util.cpp:4216
SrcLangExt getLanguageFromFileName(const DString &fileName, SrcLangExt defLang)
Definition util.cpp:4174

References OutputList::disable(), OutputList::docify(), OutputList::enable(), endFile(), endTitle(), Doxygen::exampleLinkedMap, g_outputList, OutputList::generateDoc(), ParserManager::getCodeParser(), getFileNameExtension(), getLanguageFromFileName(), Man, msg, Doxygen::parserManager, OutputList::startContents(), startFile(), and startTitle().

Referenced by generateOutput().

◆ generateFileDocs()

void generateFileDocs ( )
static

Definition at line 9059 of file doxygen.cpp.

9060{
9061 if (Index::instance().numDocumentedFiles()==0) return;
9062
9063 if (!Doxygen::inputNameLinkedMap->empty())
9064 {
9065 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
9066 if (numThreads>1) // multi threaded processing
9067 {
9068 struct DocContext
9069 {
9070 DocContext(FileDef *fd_,const OutputList &ol_)
9071 : fd(fd_), ol(ol_) {}
9072 FileDef *fd;
9073 OutputList ol;
9074 };
9075 ThreadPool threadPool(numThreads);
9076 std::vector< std::future< std::shared_ptr<DocContext> > > results;
9077 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9078 {
9079 for (const auto &fd : *fn)
9080 {
9081 bool doc = fd->isLinkableInProject();
9082 if (doc)
9083 {
9084 auto ctx = std::make_shared<DocContext>(fd.get(),*g_outputList);
9085 auto processFile = [ctx]() {
9086 msg("Generating docs for file {}...\n",ctx->fd->docName());
9087 ctx->fd->writeDocumentation(ctx->ol);
9088 return ctx;
9089 };
9090 results.emplace_back(threadPool.queue(processFile));
9091 }
9092 }
9093 }
9094 for (auto &f : results)
9095 {
9096 auto ctx = f.get();
9097 }
9098 }
9099 else // single threaded processing
9100 {
9101 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9102 {
9103 for (const auto &fd : *fn)
9104 {
9105 bool doc = fd->isLinkableInProject();
9106 if (doc)
9107 {
9108 msg("Generating docs for file {}...\n",fd->docName());
9109 fd->writeDocumentation(*g_outputList);
9110 }
9111 }
9112 }
9113 }
9114 }
9115}

References Config_getInt, g_outputList, Doxygen::inputNameLinkedMap, Index::instance(), msg, and ThreadPool::queue().

Referenced by generateOutput().

◆ generateFileSources()

void generateFileSources ( )
static

Definition at line 8893 of file doxygen.cpp.

8894{
8895 auto processSourceFile = [](FileDef *fd,OutputList &ol,ClangTUParser *parser)
8896 {
8897 bool showSources = fd->generateSourceFile() && !Htags::useHtags; // sources need to be shown in the output
8898 bool parseSources = !fd->isReference() && Doxygen::parseSourcesNeeded; // we needed to parse the sources even if we do not show them
8899 if (showSources)
8900 {
8901 msg("Generating code for file {}...\n",fd->docName());
8902 fd->writeSourceHeader(ol);
8903 fd->writeSourceBody(ol,parser);
8904 fd->writeSourceFooter(ol);
8905 }
8906 else if (parseSources)
8907 {
8908 msg("Parsing code for file {}...\n",fd->docName());
8909 fd->parseSource(parser);
8910 }
8911 };
8912 if (!Doxygen::inputNameLinkedMap->empty())
8913 {
8914#if USE_LIBCLANG
8916 {
8917 StringUnorderedSet processedFiles;
8918
8919 // create a dictionary with files to process
8920 StringUnorderedSet filesToProcess;
8921
8922 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8923 {
8924 for (const auto &fd : *fn)
8925 {
8926 filesToProcess.insert(fd->absFilePath().str());
8927 }
8928 }
8929 // process source files (and their include dependencies)
8930 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8931 {
8932 for (const auto &fd : *fn)
8933 {
8934 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp &&
8935 (fd->generateSourceFile() ||
8937 )
8938 )
8939 {
8940 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8941 clangParser->parse();
8942 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8943
8944 for (auto incFile : clangParser->filesInSameTU())
8945 {
8946 if (filesToProcess.find(incFile)!=filesToProcess.end() && // part of input
8947 fd->absFilePath()!=incFile && // not same file
8948 processedFiles.find(incFile)==processedFiles.end()) // not yet marked as processed
8949 {
8950 StringVector moreFiles;
8951 bool ambig = false;
8952 FileDef *ifd=Doxygen::inputNameLinkedMap->findFileDef(incFile,ambig);
8953 if (ifd && !ifd->isReference())
8954 {
8955 processSourceFile(ifd,*g_outputList,clangParser.get());
8956 processedFiles.insert(incFile);
8957 }
8958 }
8959 }
8960 processedFiles.insert(fd->absFilePath().str());
8961 }
8962 }
8963 }
8964 // process remaining files
8965 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8966 {
8967 for (const auto &fd : *fn)
8968 {
8969 if (processedFiles.find(fd->absFilePath().str())==processedFiles.end()) // not yet processed
8970 {
8971 if (fd->getLanguage()==SrcLangExt::Cpp) // C/C++ file, use clang parser
8972 {
8973 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8974 clangParser->parse();
8975 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8976 }
8977 else // non C/C++ file, use built-in parser
8978 {
8979 processSourceFile(fd.get(),*g_outputList,nullptr);
8980 }
8981 }
8982 }
8983 }
8984 }
8985 else
8986#endif
8987 {
8988 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8989 if (numThreads>1)
8990 {
8991 msg("Generating code files using {} threads.\n",numThreads);
8992 struct SourceContext
8993 {
8994 SourceContext(FileDef *fd_,bool gen_,const OutputList &ol_)
8995 : fd(fd_), generateSourceFile(gen_), ol(ol_) {}
8996 FileDef *fd;
8997 bool generateSourceFile;
8998 OutputList ol;
8999 };
9000 ThreadPool threadPool(numThreads);
9001 std::vector< std::future< std::shared_ptr<SourceContext> > > results;
9002 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9003 {
9004 for (const auto &fd : *fn)
9005 {
9006 bool generateSourceFile = fd->generateSourceFile() && !Htags::useHtags;
9007 auto ctx = std::make_shared<SourceContext>(fd.get(),generateSourceFile,*g_outputList);
9008 auto processFile = [ctx]()
9009 {
9010 if (ctx->generateSourceFile)
9011 {
9012 msg("Generating code for file {}...\n",ctx->fd->docName());
9013 }
9014 else
9015 {
9016 msg("Parsing code for file {}...\n",ctx->fd->docName());
9017 }
9018 StringVector filesInSameTu;
9019 ctx->fd->getAllIncludeFilesRecursively(filesInSameTu);
9020 if (ctx->generateSourceFile) // sources need to be shown in the output
9021 {
9022 ctx->fd->writeSourceHeader(ctx->ol);
9023 ctx->fd->writeSourceBody(ctx->ol,nullptr);
9024 ctx->fd->writeSourceFooter(ctx->ol);
9025 }
9026 else if (!ctx->fd->isReference() && Doxygen::parseSourcesNeeded)
9027 // we needed to parse the sources even if we do not show them
9028 {
9029 ctx->fd->parseSource(nullptr);
9030 }
9031 return ctx;
9032 };
9033 results.emplace_back(threadPool.queue(processFile));
9034 }
9035 }
9036 for (auto &f : results)
9037 {
9038 auto ctx = f.get();
9039 }
9040 }
9041 else // single threaded version
9042 {
9043 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9044 {
9045 for (const auto &fd : *fn)
9046 {
9047 StringVector filesInSameTu;
9048 fd->getAllIncludeFilesRecursively(filesInSameTu);
9049 processSourceFile(fd.get(),*g_outputList,nullptr);
9050 }
9051 }
9052 }
9053 }
9054 }
9055}
std::unique_ptr< ClangTUParser > createTUParser(const FileDef *fd) const
static ClangParser * instance()
Returns the one and only instance of the class.
Clang parser object for a single translation unit, which consists of a source file and the directly o...
Definition clangparser.h:25
static bool clangAssistedParsing
Definition doxygen.h:129
virtual void writeSourceHeader(OutputList &ol)=0
virtual const DString & docName() const =0
virtual bool isSource() const =0
virtual void parseSource(ClangTUParser *clangParser)=0
virtual void getAllIncludeFilesRecursively(StringVector &incFiles) const =0
virtual void writeSourceFooter(OutputList &ol)=0
virtual void writeSourceBody(OutputList &ol, ClangTUParser *clangParser)=0
Class representing a list of output generators that are written to in parallel.
Definition outputlist.h:311
std::unordered_set< std::string > StringUnorderedSet
Definition containers.h:29
static bool useHtags
Definition htags.h:23

References FileDef::absFilePath(), Doxygen::clangAssistedParsing, Config_getInt, ClangParser::createTUParser(), FileDef::docName(), DString::find(), FileNameLinkedMap::findFileDef(), g_outputList, FileDef::generateSourceFile(), FileDef::getAllIncludeFilesRecursively(), Definition::getLanguage(), Doxygen::inputNameLinkedMap, ClangParser::instance(), Definition::isReference(), FileDef::isSource(), msg, FileDef::parseSource(), Doxygen::parseSourcesNeeded, ThreadPool::queue(), DString::str(), Htags::useHtags, FileDef::writeSourceBody(), FileDef::writeSourceFooter(), and FileDef::writeSourceHeader().

Referenced by generateOutput().

◆ generateGroupDocs()

void generateGroupDocs ( )
static

Definition at line 10361 of file doxygen.cpp.

10362{
10363 for (const auto &gd : *Doxygen::groupLinkedMap)
10364 {
10365 if (!gd->isReference())
10366 {
10367 gd->writeDocumentation(*g_outputList);
10368 }
10369 }
10370}

References g_outputList, and Doxygen::groupLinkedMap.

Referenced by generateOutput().

◆ generateNamespaceClassDocs()

void generateNamespaceClassDocs ( const ClassLinkedRefMap & classList)
static

Definition at line 10375 of file doxygen.cpp.

10376{
10377 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10378 if (numThreads>1) // multi threaded processing
10379 {
10380 struct DocContext
10381 {
10382 DocContext(ClassDefMutable *cdm_,const OutputList &ol_)
10383 : cdm(cdm_), ol(ol_) {}
10384 ClassDefMutable *cdm;
10385 OutputList ol;
10386 };
10387 ThreadPool threadPool(numThreads);
10388 std::vector< std::future< std::shared_ptr<DocContext> > > results;
10389 // for each class in the namespace...
10390 for (const auto &cd : classList)
10391 {
10393 if (cdm)
10394 {
10395 auto ctx = std::make_shared<DocContext>(cdm,*g_outputList);
10396 auto processFile = [ctx]()
10397 {
10398 if ( ( ctx->cdm->isLinkableInProject() &&
10399 !ctx->cdm->isImplicitTemplateInstance()
10400 ) // skip external references, anonymous compounds and
10401 // template instances and nested classes
10402 && !ctx->cdm->isHidden() && !ctx->cdm->isEmbeddedInOuterScope()
10403 )
10404 {
10405 msg("Generating docs for compound {}...\n",ctx->cdm->displayName());
10406 ctx->cdm->writeDocumentation(ctx->ol);
10407 ctx->cdm->writeMemberList(ctx->ol);
10408 }
10409 ctx->cdm->writeDocumentationForInnerClasses(ctx->ol);
10410 return ctx;
10411 };
10412 results.emplace_back(threadPool.queue(processFile));
10413 }
10414 }
10415 // wait for the results
10416 for (auto &f : results)
10417 {
10418 auto ctx = f.get();
10419 }
10420 }
10421 else // single threaded processing
10422 {
10423 // for each class in the namespace...
10424 for (const auto &cd : classList)
10425 {
10427 if (cdm)
10428 {
10429 if ( ( cd->isLinkableInProject() &&
10430 !cd->isImplicitTemplateInstance()
10431 ) // skip external references, anonymous compounds and
10432 // template instances and nested classes
10433 && !cd->isHidden() && !cd->isEmbeddedInOuterScope()
10434 )
10435 {
10436 msg("Generating docs for compound {}...\n",cd->displayName());
10437
10440 }
10442 }
10443 }
10444 }
10445}
virtual void writeDocumentation(OutputList &ol) const =0
virtual void writeMemberList(OutputList &ol) const =0
virtual void writeDocumentationForInnerClasses(OutputList &ol) const =0

References Config_getInt, g_outputList, msg, ThreadPool::queue(), toClassDefMutable(), ClassDef::writeDocumentation(), ClassDef::writeDocumentationForInnerClasses(), and ClassDef::writeMemberList().

Referenced by generateNamespaceDocs().

◆ generateNamespaceConceptDocs()

void generateNamespaceConceptDocs ( const ConceptLinkedRefMap & conceptList)
static

Definition at line 10447 of file doxygen.cpp.

10448{
10449 // for each concept in the namespace...
10450 for (const auto &cd : conceptList)
10451 {
10453 if ( cdm && cd->isLinkableInProject() && !cd->isHidden())
10454 {
10455 msg("Generating docs for concept {}...\n",cd->name());
10457 }
10458 }
10459}

References g_outputList, Definition::isLinkableInProject(), msg, toConceptDefMutable(), and ConceptDefMutable::writeDocumentation().

Referenced by generateNamespaceDocs().

◆ generateNamespaceDocs()

void generateNamespaceDocs ( )
static

Definition at line 10461 of file doxygen.cpp.

10462{
10463 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
10464
10465 //writeNamespaceIndex(*g_outputList);
10466
10467 // for each namespace...
10468 for (const auto &nd : *Doxygen::namespaceLinkedMap)
10469 {
10470 if (nd->isLinkableInProject())
10471 {
10473 if (ndm)
10474 {
10475 msg("Generating docs for namespace {}\n",nd->displayName());
10477 }
10478 }
10479
10480 generateNamespaceClassDocs(nd->getClasses());
10481 if (sliceOpt)
10482 {
10483 generateNamespaceClassDocs(nd->getInterfaces());
10484 generateNamespaceClassDocs(nd->getStructs());
10485 generateNamespaceClassDocs(nd->getExceptions());
10486 }
10487 generateNamespaceConceptDocs(nd->getConcepts());
10488 }
10489}
virtual void writeDocumentation(OutputList &ol)=0
static void generateNamespaceConceptDocs(const ConceptLinkedRefMap &conceptList)
static void generateNamespaceClassDocs(const ClassLinkedRefMap &classList)

References Config_getBool, g_outputList, generateNamespaceClassDocs(), generateNamespaceConceptDocs(), msg, Doxygen::namespaceLinkedMap, toNamespaceDefMutable(), and NamespaceDefMutable::writeDocumentation().

Referenced by generateOutput().

◆ generateOutput()

void generateOutput ( )

add extra languages for which we can only produce syntax highlighted code

Definition at line 13431 of file doxygen.cpp.

13432{
13433 AUTO_TRACE();
13434 /**************************************************************************
13435 * Initialize output generators *
13436 **************************************************************************/
13437
13438 /// add extra languages for which we can only produce syntax highlighted code
13440
13441 //// dump all symbols
13442 if (g_dumpSymbolMap)
13443 {
13444 dumpSymbolMap();
13445 exit(0);
13446 }
13447
13448 bool generateHtml = Config_getBool(GENERATE_HTML);
13449 bool generateLatex = Config_getBool(GENERATE_LATEX);
13450 bool generateMan = Config_getBool(GENERATE_MAN);
13451 bool generateRtf = Config_getBool(GENERATE_RTF);
13452 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
13453
13454
13456 if (generateHtml)
13457 {
13461 }
13462 if (generateLatex)
13463 {
13466 }
13467 if (generateDocbook)
13468 {
13471 }
13472 if (generateMan)
13473 {
13476 }
13477 if (generateRtf)
13478 {
13481 }
13482 if (Config_getBool(USE_HTAGS))
13483 {
13484 Htags::useHtags = true;
13485 DString htmldir = Config_getString(HTML_OUTPUT);
13486 if (!Htags::execute(htmldir))
13487 err("USE_HTAGS is YES but htags(1) failed. \n");
13488 else if (!Htags::loadFilemap(htmldir))
13489 err("htags(1) ended normally but failed to load the filemap. \n");
13490 }
13491
13492 /**************************************************************************
13493 * Generate documentation *
13494 **************************************************************************/
13495
13496 g_s.begin("Generating style sheet...\n");
13497 //printf("writing style info\n");
13498 g_outputList->writeStyleInfo(0); // write first part
13499 g_s.end();
13500
13501 bool searchEngine = Config_getBool(SEARCHENGINE);
13502 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
13503
13504 g_s.begin("Generating search indices...\n");
13505 if (searchEngine && !serverBasedSearch && generateHtml)
13506 {
13508 }
13509
13510 // generate search indices (need to do this before writing other HTML
13511 // pages as these contain a drop down menu with options depending on
13512 // what categories we find in this function.
13513 if (generateHtml && searchEngine)
13514 {
13515 DString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
13516 Dir searchDir(searchDirName.str());
13517 if (!searchDir.exists() && !searchDir.mkdir(searchDirName.str()))
13518 {
13519 term("Could not create search results directory '{}' $PWD='{}'\n",
13520 searchDirName,Dir::currentDirPath());
13521 }
13522 HtmlGenerator::writeSearchData(searchDirName);
13523 if (!serverBasedSearch) // client side search index
13524 {
13526 }
13527 }
13528 g_s.end();
13529
13530 // copy static stuff
13531 if (generateHtml)
13532 {
13534 copyLogo(Config_getString(HTML_OUTPUT),true);
13535 copyIcon(Config_getString(HTML_OUTPUT),true);
13536 copyExtraFiles(Config_getList(HTML_EXTRA_FILES),"HTML_EXTRA_FILES",Config_getString(HTML_OUTPUT),true);
13537 }
13538 if (generateLatex)
13539 {
13541 copyLogo(Config_getString(LATEX_OUTPUT),false);
13542 copyIcon(Config_getString(LATEX_OUTPUT),false);
13543 copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT),false);
13544 }
13545 if (generateDocbook)
13546 {
13547 copyLogo(Config_getString(DOCBOOK_OUTPUT),false);
13548 copyIcon(Config_getString(DOCBOOK_OUTPUT),false);
13549 }
13550 if (generateRtf)
13551 {
13552 copyLogo(Config_getString(RTF_OUTPUT),false);
13553 copyIcon(Config_getString(RTF_OUTPUT),false);
13554 copyExtraFiles(Config_getList(RTF_EXTRA_FILES),"RTF_EXTRA_FILES",Config_getString(RTF_OUTPUT),false);
13555 }
13556
13558 if (fm.hasFormulas() && generateHtml
13559 && !Config_getBool(USE_MATHJAX))
13560 {
13561 g_s.begin("Generating images for formulas in HTML...\n");
13562 fm.generateImages(Config_getString(HTML_OUTPUT), true, Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg ?
13564 g_s.end();
13565 }
13566 if (fm.hasFormulas() && generateRtf)
13567 {
13568 g_s.begin("Generating images for formulas in RTF...\n");
13570 g_s.end();
13571 }
13572
13573 if (fm.hasFormulas() && generateDocbook)
13574 {
13575 g_s.begin("Generating images for formulas in Docbook...\n");
13577 g_s.end();
13578 }
13579
13580 g_s.begin("Generating example documentation...\n");
13582 g_s.end();
13583
13584 g_s.begin("Generating file sources...\n");
13586 g_s.end();
13587
13588 g_s.begin("Counting members...\n");
13589 // needs to be done after generating the sources
13590 // but before generating the compound documentation, see bug #12233
13591 countMembers();
13592 g_s.end();
13593
13594 g_s.begin("Generating file documentation...\n");
13596 g_s.end();
13597
13598 g_s.begin("Generating page documentation...\n");
13600 g_s.end();
13601
13602 g_s.begin("Generating group documentation...\n");
13604 g_s.end();
13605
13606 g_s.begin("Generating class documentation...\n");
13608 g_s.end();
13609
13610 g_s.begin("Generating concept documentation...\n");
13612 g_s.end();
13613
13614 g_s.begin("Generating module documentation...\n");
13616 g_s.end();
13617
13618 g_s.begin("Generating namespace documentation...\n");
13620 g_s.end();
13621
13622 if (Config_getBool(GENERATE_LEGEND))
13623 {
13624 g_s.begin("Generating graph info page...\n");
13626 g_s.end();
13627 }
13628
13629 g_s.begin("Generating directory documentation...\n");
13631 g_s.end();
13632
13633 if (g_outputList->size()>0)
13634 {
13636 }
13637
13638 g_s.begin("finalizing index lists...\n");
13640 g_s.end();
13641
13642 g_s.begin("writing tag file...\n");
13643 writeTagFile();
13644 g_s.end();
13645
13646 if (Config_getBool(GENERATE_XML))
13647 {
13648 g_s.begin("Generating XML output...\n");
13650 generateXML();
13652 g_s.end();
13653 }
13654 if (Config_getBool(GENERATE_SQLITE3))
13655 {
13656 g_s.begin("Generating SQLITE3 output...\n");
13658 g_s.end();
13659 }
13660
13661 if (Config_getBool(GENERATE_AUTOGEN_DEF))
13662 {
13663 g_s.begin("Generating AutoGen DEF output...\n");
13664 generateDEF();
13665 g_s.end();
13666 }
13667 if (Config_getBool(GENERATE_PERLMOD))
13668 {
13669 g_s.begin("Generating Perl module output...\n");
13671 g_s.end();
13672 }
13673 if (generateHtml && searchEngine && serverBasedSearch)
13674 {
13675 g_s.begin("Generating search index\n");
13676 if (Doxygen::searchIndex.kind()==SearchIndexIntf::Internal) // write own search index
13677 {
13679 Doxygen::searchIndex.write(Config_getString(HTML_OUTPUT)+"/search/search.idx");
13680 }
13681 else // write data for external search index
13682 {
13684 DString searchDataFile = Config_getString(SEARCHDATA_FILE);
13685 if (searchDataFile.empty())
13686 {
13687 searchDataFile="searchdata.xml";
13688 }
13689 if (!Portable::isAbsolutePath(searchDataFile.data()))
13690 {
13691 searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/");
13692 }
13693 Doxygen::searchIndex.write(searchDataFile);
13694 }
13695 g_s.end();
13696 }
13697
13698 if (generateRtf)
13699 {
13700 g_s.begin("Combining RTF output...\n");
13701 if (!RTFGenerator::preProcessFileInplace(Config_getString(RTF_OUTPUT),"refman.rtf"))
13702 {
13703 err("An error occurred during post-processing the RTF files!\n");
13704 }
13705 g_s.end();
13706 }
13707
13708 if (PlantumlManager::instance().needToRun())
13709 {
13710 g_s.begin("Running plantuml with JAVA...\n");
13712 g_s.end();
13713 }
13714
13715 if (MermaidManager::instance().needToRun())
13716 {
13717 g_s.begin("Running mermaid (mmdc)...\n");
13719 g_s.end();
13720 }
13721
13722 if (Config_getBool(HAVE_DOT) && DotManager::instance()->needToRun())
13723 {
13724 g_s.begin("Running dot...\n");
13726 g_s.end();
13727 }
13728
13729 if (generateHtml &&
13730 Config_getBool(GENERATE_HTMLHELP) &&
13731 !Config_getString(HHC_LOCATION).empty())
13732 {
13733 g_s.begin("Running html help compiler...\n");
13735 g_s.end();
13736 }
13737
13738 if ( generateHtml &&
13739 Config_getBool(GENERATE_QHP) &&
13740 !Config_getString(QHG_LOCATION).empty())
13741 {
13742 g_s.begin("Running qhelpgenerator...\n");
13744 g_s.end();
13745 }
13746
13749
13751
13753 {
13754
13755 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
13756 if (numThreads<1) numThreads=1;
13757 msg("Total elapsed time: {:.6f} seconds\n(of which an average of {:.6f} seconds per thread waiting for external tools to finish)\n",
13758 (static_cast<double>(Debug::elapsedTime())),
13759 Portable::getSysElapsedTime()/static_cast<double>(numThreads)
13760 );
13761 g_s.print();
13762
13764 msg("finished...\n");
13766 }
13767 else
13768 {
13769 msg("finished...\n");
13770 }
13771
13772
13773 /**************************************************************************
13774 * Start cleaning up *
13775 **************************************************************************/
13776
13778
13780 Dir thisDir;
13781 thisDir.remove(Doxygen::filterDBFileName.str());
13783 exitTracing();
13785 delete Doxygen::clangUsrMap;
13786 g_successfulRun=true;
13787
13788 //dumpDocNodeSizes();
13789}
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
static double elapsedTime()
Definition debug.cpp:200
static void setFlag(const DebugMask mask)
Definition debug.cpp:117
static std::string currentDirPath()
Definition dir.cpp:348
static void init()
bool run()
Definition dot.cpp:119
static DotManager * instance()
Definition dot.cpp:78
static bool generatingXmlOutput
Definition doxygen.h:127
static ClangUsrMap * clangUsrMap
Definition doxygen.h:119
bool hasFormulas() const
Definition formula.cpp:720
void generateImages(const DString &outputDir, bool toIndex, Format format, HighDPI hd=HighDPI::Off)
Definition formula.cpp:635
Generator for HTML output.
Definition htmlgen.h:93
static void writeSearchData(const DString &dir)
Definition htmlgen.cpp:1461
static void init()
Definition htmlgen.cpp:1281
static void writeSearchPage()
Definition htmlgen.cpp:3284
static void writeTabData()
Additional initialization after indices have been created.
Definition htmlgen.cpp:1445
static void writeExternalSearchPage()
Definition htmlgen.cpp:3383
void finalize()
Definition indexlist.h:104
Generator for LaTeX output.
Definition latexgen.h:96
static void init()
Definition latexgen.cpp:632
Generator for Man page output.
Definition mangen.h:69
static void init()
Definition mangen.cpp:275
void run()
Run mmdc tool for all collected diagrams.
Definition mermaid.cpp:255
static MermaidManager & instance()
Definition mermaid.cpp:38
void writeDocumentation(OutputList &ol)
void add()
Definition outputlist.h:348
size_t size() const
Definition outputlist.h:357
void writeStyleInfo(int part)
Definition outputlist.h:391
void cleanup()
Definition outputlist.h:748
static PlantumlManager & instance()
Definition plantuml.cpp:236
void run()
Run plant UML tool for all images.
Definition plantuml.cpp:432
Generator for RTF output.
Definition rtfgen.h:80
static void init()
Definition rtfgen.cpp:464
static bool preProcessFileInplace(const DString &path, const DString &name)
This is an API to a VERY brittle RTF preprocessor that combines nested RTF files.
Definition rtfgen.cpp:2468
void write(const DString &file)
void print()
Definition doxygen.cpp:250
void begin(const char *name)
Definition doxygen.cpp:237
void end()
Definition doxygen.cpp:243
static void showCacheUsage()
Show usage of the type lookup cache.
void generateDEF()
Definition defgen.cpp:463
void generateDirDocs(OutputList &ol)
Definition dirdef.cpp:1188
static void copyLatexStyleSheet()
static void runQHelpGenerator()
class Statistics g_s
static void copyStyleSheet()
static void generateGroupDocs()
static void generateExampleDocs()
static void copyLogo(const DString &outputOption, bool toIndex)
static void dumpSymbolMap()
static void generateFileDocs()
Definition doxygen.cpp:9059
static void generatePageDocs()
static void copyIcon(const DString &outputOption, bool toIndex)
static void generateFileSources()
Definition doxygen.cpp:8893
static void copyExtraFiles(StringVector files, const DString &filesOption, const DString &outputOption, bool toIndex)
static void generateClassDocs()
Definition doxygen.cpp:9494
static void countMembers()
Definition doxygen.cpp:9355
static void runHtmlHelpCompiler()
static bool g_dumpSymbolMap
Definition doxygen.cpp:195
static void generateNamespaceDocs()
static void writeTagFile()
void cleanUpDoxygen()
static void generateConceptDocs()
Definition doxygen.cpp:9520
void writeGraphInfo(OutputList &ol)
Definition index.cpp:4097
void writeIndexHierarchy(OutputList &ol)
Definition index.cpp:5812
void finishWarnExit()
Definition message.cpp:291
void deinit()
double getSysElapsedTime()
Definition portable.cpp:113
bool isAbsolutePath(const DString &fileName)
Definition portable.cpp:513
void generatePerlMod()
void finalizeSearchIndexer()
void createJavaScriptSearchIndex()
void writeJavaScriptSearchIndex()
void generateSqlite3()
static bool execute(const DString &htmldir)
Definition htags.cpp:41
static bool loadFilemap(const DString &htmldir)
Definition htags.cpp:110
void exitTracing()
Definition trace.cpp:55
void addCodeOnlyMappings()
Definition util.cpp:4168
void cleanupInlineGraphs()
Definition util.cpp:5432
void generateXML()
Definition xmlgen.cpp:2357

References OutputList::add(), addCodeOnlyMappings(), AUTO_TRACE, Statistics::begin(), FormulaManager::Bitmap, Doxygen::clangUsrMap, OutputList::cleanup(), cleanUpDoxygen(), cleanupInlineGraphs(), Debug::clearFlag(), Config_getBool, Config_getEnum, Config_getInt, Config_getList, Config_getString, copyExtraFiles(), copyIcon(), copyLatexStyleSheet(), copyLogo(), copyStyleSheet(), countMembers(), createJavaScriptSearchIndex(), Dir::currentDirPath(), DString::data(), Config::deinit(), dumpSymbolMap(), Debug::elapsedTime(), DString::empty(), Statistics::end(), err, Htags::execute(), Dir::exists(), exitTracing(), Doxygen::filterDBFileName, IndexList::finalize(), finalizeSearchIndexer(), finishWarnExit(), g_dumpSymbolMap, g_outputList, g_s, g_successfulRun, generateClassDocs(), generateConceptDocs(), generateDEF(), generateDirDocs(), generateExampleDocs(), generateFileDocs(), generateFileSources(), generateGroupDocs(), FormulaManager::generateImages(), generateNamespaceDocs(), generatePageDocs(), generatePerlMod(), generateSqlite3(), generateXML(), Doxygen::generatingXmlOutput, Portable::getSysElapsedTime(), FormulaManager::hasFormulas(), Doxygen::indexList, DocbookGenerator::init(), HtmlGenerator::init(), LatexGenerator::init(), ManGenerator::init(), RTFGenerator::init(), DotManager::instance(), FormulaManager::instance(), MermaidManager::instance(), ModuleManager::instance(), PlantumlManager::instance(), SearchIndexIntf::Internal, Portable::isAbsolutePath(), Debug::isFlagSet(), Htags::loadFilemap(), Dir::mkdir(), msg, FormulaManager::On, DString::prepend(), RTFGenerator::preProcessFileInplace(), Statistics::print(), Dir::remove(), DotManager::run(), MermaidManager::run(), PlantumlManager::run(), runHtmlHelpCompiler(), runQHelpGenerator(), Doxygen::searchIndex, Debug::setFlag(), SymbolResolver::showCacheUsage(), OutputList::size(), DString::str(), term, Debug::Time, Htags::useHtags, FormulaManager::Vector, SearchIndexIntf::write(), ModuleManager::writeDocumentation(), HtmlGenerator::writeExternalSearchPage(), writeGraphInfo(), writeIndexHierarchy(), writeJavaScriptSearchIndex(), HtmlGenerator::writeSearchData(), HtmlGenerator::writeSearchPage(), OutputList::writeStyleInfo(), HtmlGenerator::writeTabData(), and writeTagFile().

Referenced by main().

◆ generatePageDocs()

void generatePageDocs ( )
static

Definition at line 10235 of file doxygen.cpp.

10236{
10237 //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageLinkedMap->count());
10238 if (Index::instance().numDocumentedPages()==0) return;
10239 for (const auto &pd : *Doxygen::pageLinkedMap)
10240 {
10241 if (!pd->getGroupDef() && !pd->isReference())
10242 {
10243 msg("Generating docs for page {}...\n",pd->name());
10244 pd->writeDocumentation(*g_outputList);
10245 }
10246 }
10247}

References g_outputList, Index::instance(), msg, and Doxygen::pageLinkedMap.

Referenced by generateOutput().

◆ generateXRefPages()

void generateXRefPages ( )
static

Definition at line 5826 of file doxygen.cpp.

5827{
5828 AUTO_TRACE();
5830 {
5831 rl->generatePage();
5832 }
5833}
std::unique_ptr< RefList > Ptr
Definition linkedmap.h:38
static RefListManager & instance()
Definition reflist.h:122

References AUTO_TRACE, and RefListManager::instance().

Referenced by parseInput().

◆ getArg()

const char * getArg ( int argc,
char ** argv,
int & optInd )
static

Definition at line 11679 of file doxygen.cpp.

11680{
11681 char *s=nullptr;
11682 if (dstrlen(&argv[optInd][2])>0)
11683 s=&argv[optInd][2];
11684 else if (optInd+1<argc && argv[optInd+1][0]!='-')
11685 s=argv[++optInd];
11686 return s;
11687}
uint32_t dstrlen(const char *str)
Returns the length of string str, or 0 if a null pointer is passed.
Definition dstring.h:39

References dstrlen().

Referenced by readConfiguration().

◆ getParserForFile()

std::unique_ptr< OutlineParserInterface > getParserForFile ( const DString & fn)
static

Definition at line 10947 of file doxygen.cpp.

10948{
10949 DString fileName=fn;
10950 DString extension;
10951 size_t sep = fileName.rfind('/');
10952 size_t ei = fileName.rfind('.');
10953 if (ei!=DString::npos && (sep==DString::npos || ei>sep)) // matches dir/file.ext but not dir.1/file
10954 {
10955 extension=fileName.mid(ei);
10956 }
10957 else
10958 {
10959 extension = ".no_extension";
10960 }
10961
10962 return Doxygen::parserManager->getOutlineParser(extension);
10963}
std::unique_ptr< OutlineParserInterface > getOutlineParser(const DString &extension)
Gets the interface to the parser associated with a given extension.
Definition parserintf.h:244

References ParserManager::getOutlineParser(), DString::mid(), DString::npos, Doxygen::parserManager, and DString::rfind().

Referenced by parseFilesMultiThreading(), and parseFilesSingleThreading().

◆ getTemplateArgumentsFromName()

std::unique_ptr< ArgumentList > getTemplateArgumentsFromName ( const DString & name,
const ArgumentLists & tArgLists )

Definition at line 878 of file doxygen.cpp.

881{
882 // for each scope fragment, check if it is a template and advance through
883 // the list if so.
884 size_t i=0, p=0;
885 auto alIt = tArgLists.begin();
886 while ((i=name.find("::",p))!=DString::npos && alIt!=tArgLists.end())
887 {
889 if (nd==nullptr)
890 {
891 ClassDef *cd = getClass(name.left(i));
892 if (cd)
893 {
894 if (!cd->templateArguments().empty())
895 {
896 ++alIt;
897 }
898 }
899 }
900 p=i+2;
901 }
902 return alIt!=tArgLists.end() ?
903 std::make_unique<ArgumentList>(*alIt) :
904 std::unique_ptr<ArgumentList>();
905}
Definition dstring.h:913

References ArgumentList::empty(), LinkedMap< T, Hash, KeyEqual, Map >::find(), getClass(), Doxygen::namespaceLinkedMap, DString::npos, and ClassDef::templateArguments().

Referenced by addClassToContext(), addConceptToContext(), and addOverloaded().

◆ getTemplateArgumentsInName()

TemplateNameMap getTemplateArgumentsInName ( const ArgumentList & templateArguments,
const std::string & name )
static

make a dictionary of all template arguments of class cd that are part of the base class name. Example: A template class A with template arguments <R,S,T> that inherits from B<T,T,S> will have T and S in the dictionary.

Definition at line 4763 of file doxygen.cpp.

4764{
4765 std::map<std::string,int> templateNames;
4766 int count=0;
4767 for (const Argument &arg : templateArguments)
4768 {
4769 static const reg::Ex re(R"(\a[\w:]*)");
4770 reg::Iterator it(name,re);
4772 for (; it!=end ; ++it)
4773 {
4774 const auto &match = *it;
4775 std::string n = match.str();
4776 if (n==arg.name.str())
4777 {
4778 if (templateNames.find(n)==templateNames.end())
4779 {
4780 templateNames.emplace(n,count);
4781 }
4782 }
4783 }
4784 }
4785 return templateNames;
4786}

References end().

Referenced by computeTemplateClassRelations(), findBaseClassesForClass(), findUsedClassesForClass(), and resolveTemplateInstanceInType().

◆ haveEqualFileNames()

bool haveEqualFileNames ( const Entry * root,
const MemberDef * md )
static

Definition at line 9811 of file doxygen.cpp.

9812{
9813 if (const FileDef *fd = md->getFileDef())
9814 {
9815 return fd->absFilePath() == root->fileName;
9816 }
9817 return false;
9818}

References Entry::fileName, and MemberDef::getFileDef().

Referenced by findDefineDocumentation().

◆ inheritDocumentation()

void inheritDocumentation ( )
static

Definition at line 9541 of file doxygen.cpp.

9542{
9543 for (const auto &mn : *Doxygen::memberNameLinkedMap)
9544 {
9545 for (const auto &imd : *mn)
9546 {
9547 MemberDefMutable *md = toMemberDefMutable(imd.get());
9548 //static int count=0;
9549 //printf("%04d Member '%s'\n",count++,qPrint(md->qualifiedName()));
9550 if (md && md->documentation().empty() && md->briefDescription().empty())
9551 { // no documentation yet
9552 const MemberDef *bmd = md->reimplements();
9553 while (bmd && bmd->documentation().empty() &&
9554 bmd->briefDescription().empty()
9555 )
9556 { // search up the inheritance tree for a documentation member
9557 //printf("bmd=%s class=%s\n",qPrint(bmd->name()),qPrint(bmd->getClassDef()->name()));
9558 bmd = bmd->reimplements();
9559 }
9560 if (bmd) // copy the documentation from the reimplemented member
9561 {
9562 md->setInheritsDocsFrom(bmd);
9563 md->setDocumentation(bmd->documentation(),bmd->docFile(),bmd->docLine());
9565 md->setBriefDescription(bmd->briefDescription(),bmd->briefFile(),bmd->briefLine());
9566 md->copyArgumentNames(bmd);
9568 }
9569 }
9570 }
9571 }
9572}
virtual void setInheritsDocsFrom(const MemberDef *md)=0
virtual void copyArgumentNames(const MemberDef *bmd)=0

References Definition::briefDescription(), Definition::briefFile(), Definition::briefLine(), MemberDefMutable::copyArgumentNames(), Definition::docFile(), Definition::docLine(), Definition::documentation(), DString::empty(), Definition::inbodyDocumentation(), Definition::inbodyFile(), Definition::inbodyLine(), MemberDef::isDocsForDefinition(), Doxygen::memberNameLinkedMap, MemberDef::reimplements(), DefinitionMutable::setBriefDescription(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setInheritsDocsFrom(), and toMemberDefMutable().

Referenced by parseInput().

◆ initDoxygen()

void initDoxygen ( )

Definition at line 11706 of file doxygen.cpp.

11707{
11708 initResources();
11709 DString lang = Portable::getenv("LC_ALL");
11710 if (!lang.empty()) Portable::setenv("LANG",lang);
11711 std::setlocale(LC_ALL,"");
11712 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
11713 std::setlocale(LC_NUMERIC,"C");
11714
11716
11740
11741 // register any additional parsers here...
11742
11744
11745#if USE_LIBCLANG
11747#endif
11756 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
11757 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
11758 //Doxygen::tagDestinationDict.setAutoDelete(true);
11760
11761 // initialization of these globals depends on
11762 // configuration switches so we need to postpone these
11763 Doxygen::globalScope = nullptr;
11773
11774}
static void startTimer()
Definition debug.cpp:195
A linked map of directories.
Definition dirdef.h:173
A list of index interfaces.
Definition indexlist.h:65
Manages programming language parsers.
Definition parserintf.h:182
void registerParser(const DString &name, const OutlineParserFactory &outlineParserFactory, const CodeParserFactory &codeParserFactory)
Registers an additional parser.
Definition parserintf.h:215
std::function< std::unique_ptr< T >() > make_parser_factory()
void initResources()
std::unordered_map< std::string, const Definition * > ClangUsrMap
Definition doxygen.h:75
void setenv(const DString &variable, const DString &value)
Definition portable.cpp:302
DString getenv(const DString &variable)
Definition portable.cpp:337
void initDefaultExtensionMapping()
Definition util.cpp:4101

References Doxygen::clangUsrMap, Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Doxygen::diaFileNameLinkedMap, Doxygen::dirLinkedMap, Doxygen::dotFileNameLinkedMap, DString::empty(), Doxygen::exampleLinkedMap, Doxygen::exampleNameLinkedMap, Doxygen::functionNameLinkedMap, Portable::getenv(), Doxygen::globalScope, Doxygen::groupLinkedMap, Doxygen::hiddenClassLinkedMap, Doxygen::imageNameLinkedMap, Doxygen::includeNameLinkedMap, Doxygen::indexList, initDefaultExtensionMapping(), initResources(), Doxygen::inputNameLinkedMap, make_parser_factory(), Doxygen::memberNameLinkedMap, Doxygen::mermaidFileNameLinkedMap, Doxygen::mscFileNameLinkedMap, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, Doxygen::parserManager, Doxygen::plantUmlFileNameLinkedMap, ParserManager::registerParser(), Portable::setenv(), Debug::startTimer(), and Doxygen::symbolMap.

Referenced by main().

◆ initResources()

void initResources ( )
extern

Referenced by initDoxygen().

◆ insertMemberAlias()

void insertMemberAlias ( Definition * outerScope,
const MemberDef * md )
static

Definition at line 6950 of file doxygen.cpp.

6951{
6952 if (outerScope && outerScope!=Doxygen::globalScope)
6953 {
6954 auto aliasMd = createMemberDefAlias(outerScope,md);
6955 if (outerScope->definitionType()==Definition::TypeClass)
6956 {
6957 ClassDefMutable *cdm = toClassDefMutable(outerScope);
6958 if (cdm)
6959 {
6960 cdm->insertMember(aliasMd.get());
6961 }
6962 }
6963 else if (outerScope->definitionType()==Definition::TypeNamespace)
6964 {
6965 NamespaceDefMutable *ndm = toNamespaceDefMutable(outerScope);
6966 if (ndm)
6967 {
6968 ndm->insertMember(aliasMd.get());
6969 }
6970 }
6971 else if (outerScope->definitionType()==Definition::TypeFile)
6972 {
6973 toFileDef(outerScope)->insertMember(aliasMd.get());
6974 }
6975 if (aliasMd)
6976 {
6977 Doxygen::functionNameLinkedMap->add(md->name())->push_back(std::move(aliasMd));
6978 }
6979 }
6980}

References LinkedMap< T, Hash, KeyEqual, Map >::add(), createMemberDefAlias(), Definition::definitionType(), Doxygen::functionNameLinkedMap, Doxygen::globalScope, ClassDefMutable::insertMember(), FileDef::insertMember(), NamespaceDefMutable::insertMember(), Definition::name(), MemberName::push_back(), toClassDefMutable(), toFileDef(), toNamespaceDefMutable(), Definition::TypeClass, Definition::TypeFile, and Definition::TypeNamespace.

Referenced by findMember().

◆ isClassSection()

bool isClassSection ( const Entry * root)
static

Definition at line 5496 of file doxygen.cpp.

5497{
5498 if ( !root->name.empty() )
5499 {
5500 if (root->section.isCompound())
5501 // is it a compound (class, struct, union, interface ...)
5502 {
5503 return true;
5504 }
5505 else if (root->section.isCompoundDoc())
5506 // is it a documentation block with inheritance info.
5507 {
5508 bool hasExtends = !root->extends.empty();
5509 if (hasExtends) return true;
5510 }
5511 }
5512 return false;
5513}

References DString::empty(), Entry::extends, EntryType::isCompound(), EntryType::isCompoundDoc(), Entry::name, and Entry::section.

Referenced by findClassEntries().

◆ isEntryInGroupOfMember()

bool isEntryInGroupOfMember ( const Entry * root,
const MemberDef * md,
bool allowNoGroup = false )
static

Definition at line 6007 of file doxygen.cpp.

6008{
6009 const GroupDef *gd = md->getGroupDef();
6010 if (!gd)
6011 {
6012 return allowNoGroup;
6013 }
6014
6015 for (const auto &g : root->groups)
6016 {
6017 if (g.groupname == gd->name())
6018 {
6019 return true; // matching group
6020 }
6021 }
6022
6023 return false;
6024}

References MemberDef::getGroupDef(), Entry::groups, and Definition::name().

Referenced by findDefineDocumentation(), and findGlobalMember().

◆ isRecursiveBaseClass()

bool isRecursiveBaseClass ( const DString & scope,
const DString & name )
static

Definition at line 5113 of file doxygen.cpp.

5114{
5115 DString n=name;
5116 if (size_t index=n.find('<'); index!=DString::npos)
5117 {
5118 n=n.left(index);
5119 }
5120 bool result = rightScopeMatch(scope,n);
5121 return result;
5122}

References DString::find(), DString::left(), DString::npos, and rightScopeMatch().

Referenced by findClassRelation().

◆ isSpecialization()

bool isSpecialization ( const ArgumentLists & srcTempArgLists,
const ArgumentLists & dstTempArgLists )
static

Definition at line 6239 of file doxygen.cpp.

6243{
6244 auto srcIt = srcTempArgLists.begin();
6245 auto dstIt = dstTempArgLists.begin();
6246 while (srcIt!=srcTempArgLists.end() && dstIt!=dstTempArgLists.end())
6247 {
6248 if ((*srcIt).size()!=(*dstIt).size()) return true;
6249 ++srcIt;
6250 ++dstIt;
6251 }
6252 return false;
6253}

Referenced by addMemberFunction().

◆ isSymbolHidden()

bool isSymbolHidden ( const Definition * d)
static

Definition at line 9288 of file doxygen.cpp.

9289{
9290 bool hidden = d->isHidden();
9291 const Definition *parent = d->getOuterScope();
9292 return parent ? hidden || isSymbolHidden(parent) : hidden;
9293}
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Definition docnode.h:1335

References Definition::getOuterScope(), Definition::isHidden(), isSymbolHidden(), and parent().

Referenced by computeTooltipTexts(), and isSymbolHidden().

◆ isVarWithConstructor()

bool isVarWithConstructor ( const Entry * root)
static

Returns true iff type is a class within scope context. Used to detect variable declarations that look like function prototypes.

Definition at line 3230 of file doxygen.cpp.

3231{
3232 bool result = false;
3233 bool typeIsClass = false;
3234 bool typePtrType = false;
3235 DString type;
3236 Definition *ctx = nullptr;
3237 FileDef *fd = root->fileDef();
3238 SymbolResolver resolver(fd);
3239
3240 AUTO_TRACE("isVarWithConstructor({})",root->name);
3241 if (root->parent()->section.isCompound())
3242 { // inside a class
3243 result=false;
3244 AUTO_TRACE_EXIT("inside class: result={}",result);
3245 return result;
3246 }
3247 else if ((fd != nullptr) && (fd->name().endsWith(".c") || fd->name().endsWith(".h")))
3248 { // inside a .c file
3249 result=false;
3250 AUTO_TRACE_EXIT("inside C file: result={}",result);
3251 return result;
3252 }
3253 if (root->type.empty())
3254 {
3255 result=false;
3256 AUTO_TRACE_EXIT("no type: result={}",result);
3257 return result;
3258 }
3259 if (!root->parent()->name.empty())
3260 {
3262 }
3263 type = root->type;
3264 // remove qualifiers
3265 type.findAndRemoveWord("const");
3266 type.findAndRemoveWord("static");
3267 type.findAndRemoveWord("volatile");
3268 typePtrType = type.find('*')!=DString::npos || type.find('&')!=DString::npos;
3269 if (!typePtrType)
3270 {
3271 typeIsClass = resolver.resolveClass(ctx,type)!=nullptr;
3272 if (size_t ti=type.find('<'); !typeIsClass && ti!=DString::npos)
3273 {
3274 typeIsClass=resolver.resolveClass(ctx,type.left(ti))!=nullptr;
3275 }
3276 }
3277 if (typeIsClass) // now we still have to check if the arguments are
3278 // types or values. Since we do not have complete type info
3279 // we need to rely on heuristics :-(
3280 {
3281 if (root->argList.empty())
3282 {
3283 result=false; // empty arg list -> function prototype.
3284 AUTO_TRACE_EXIT("empty arg list: result={}",result);
3285 return result;
3286 }
3287 for (const Argument &a : root->argList)
3288 {
3289 static const reg::Ex initChars(R"([\d"'&*!^]+)");
3291 if (!a.name.empty() || !a.defval.empty())
3292 {
3293 std::string name = a.name.str();
3294 if (reg::search(name,match,initChars) && match.position()==0)
3295 {
3296 result=true;
3297 }
3298 else
3299 {
3300 result=false; // arg has (type,name) pair -> function prototype
3301 }
3302 AUTO_TRACE_EXIT("function prototype: result={}",result);
3303 return result;
3304 }
3305 if (!a.type.empty() &&
3306 (a.type.at(a.type.length()-1)=='*' ||
3307 a.type.at(a.type.length()-1)=='&'))
3308 // type ends with * or & => pointer or reference
3309 {
3310 result=false;
3311 AUTO_TRACE_EXIT("pointer or reference: result={}",result);
3312 return result;
3313 }
3314 if (a.type.empty() || resolver.resolveClass(ctx,a.type)!=nullptr)
3315 {
3316 result=false; // arg type is a known type
3317 AUTO_TRACE_EXIT("known type: result={}",result);
3318 return result;
3319 }
3320 if (checkIfTypedef(ctx,fd,a.type))
3321 {
3322 result=false; // argument is a typedef
3323 AUTO_TRACE_EXIT("typedef: result={}",result);
3324 return result;
3325 }
3326 std::string atype = a.type.str();
3327 if (reg::search(atype,match,initChars) && match.position()==0)
3328 {
3329 result=true; // argument type starts with typical initializer char
3330 AUTO_TRACE_EXIT("argument with init char: result={}",result);
3331 return result;
3332 }
3333 std::string resType=resolveTypeDef(ctx,a.type).str();
3334 if (resType.empty()) resType=atype;
3335 static const reg::Ex idChars(R"(\a\w*)");
3336 if (reg::search(resType,match,idChars) && match.position()==0) // resType starts with identifier
3337 {
3338 resType=match.str();
3339 if (resType=="int" || resType=="long" ||
3340 resType=="float" || resType=="double" ||
3341 resType=="char" || resType=="void" ||
3342 resType=="signed" || resType=="unsigned" ||
3343 resType=="const" || resType=="volatile" )
3344 {
3345 result=false; // type keyword -> function prototype
3346 AUTO_TRACE_EXIT("type keyword: result={}",result);
3347 return result;
3348 }
3349 }
3350 }
3351 result=true;
3352 }
3353
3354 AUTO_TRACE_EXIT("end: result={}",result);
3355 return result;
3356}
DString defval
Definition arguments.h:47
DString name
Definition arguments.h:45
bool findAndRemoveWord(const char *word)
removes occurrences of whole word from this string, while keeping internal spaces and reducing multip...
Definition dstring.cpp:660
bool checkIfTypedef(const Definition *scope, const FileDef *fileScope, const DString &n)
Definition util.cpp:4277

References Entry::argList, DString::at(), AUTO_TRACE, AUTO_TRACE_EXIT, checkIfTypedef(), Argument::defval, ArgumentList::empty(), DString::empty(), DString::endsWith(), Entry::fileDef(), DString::find(), LinkedMap< T, Hash, KeyEqual, Map >::find(), DString::findAndRemoveWord(), EntryType::isCompound(), DString::left(), DString::length(), Argument::name, Definition::name(), Entry::name, Doxygen::namespaceLinkedMap, DString::npos, Entry::parent(), SymbolResolver::resolveClass(), resolveTypeDef(), reg::search(), Entry::section, DString::str(), Argument::type, and Entry::type.

Referenced by buildVarList().

◆ make_parser_factory()

template<class T>
std::function< std::unique_ptr< T >() > make_parser_factory ( )

Definition at line 11701 of file doxygen.cpp.

11702{
11703 return []() { return std::make_unique<T>(); };
11704}

Referenced by initDoxygen().

◆ makeTemplateInstanceRelation()

void makeTemplateInstanceRelation ( const Entry * root,
ClassDefMutable * cd )
static

Definition at line 5568 of file doxygen.cpp.

5569{
5570 AUTO_TRACE("root->name={} cd={}",root->name,cd->name());
5571 size_t i = root->name.find('<');
5572 size_t j = root->name.rfind('>');
5573 size_t k = j!=DString::npos ? root->name.find("::",j+1) : DString::npos; // A<T::B> => ok, A<T>::B => nok
5574 if (i!=DString::npos && j!=DString::npos && k==DString::npos && root->lang!=SrcLangExt::CSharp && root->lang!=SrcLangExt::Java)
5575 {
5576 ClassDefMutable *master = getClassMutable(root->name.left(i));
5577 if (master && master!=cd && !cd->templateMaster())
5578 {
5579 AUTO_TRACE_ADD("class={} master={}",cd->name(),cd->templateMaster()?cd->templateMaster()->name():"<none>",master->name());
5580 cd->setTemplateMaster(master);
5581 master->insertExplicitTemplateInstance(cd,root->name.mid(i));
5582 }
5583 }
5584}
virtual void insertExplicitTemplateInstance(ClassDef *instance, const DString &spec)=0
virtual void setTemplateMaster(const ClassDef *tm)=0

References AUTO_TRACE, AUTO_TRACE_ADD, DString::find(), getClassMutable(), ClassDefMutable::insertExplicitTemplateInstance(), Entry::lang, DString::left(), DString::mid(), Definition::name(), Entry::name, DString::npos, DString::rfind(), ClassDefMutable::setTemplateMaster(), and ClassDef::templateMaster().

Referenced by findUsedTemplateInstances().

◆ mergeCategories()

void mergeCategories ( )
static

Definition at line 8842 of file doxygen.cpp.

8843{
8844 AUTO_TRACE();
8845 // merge members of categories into the class they extend
8846 for (const auto &cd : *Doxygen::classLinkedMap)
8847 {
8848 if (size_t i=cd->name().find('('); i!=DString::npos) // it is an Objective-C category
8849 {
8850 DString baseName=cd->name().left(i);
8851 ClassDefMutable *baseClass=toClassDefMutable(Doxygen::classLinkedMap->find(baseName));
8852 if (baseClass)
8853 {
8854 AUTO_TRACE_ADD("merging members of category {} into {}",cd->name(),baseClass->name());
8855 baseClass->mergeCategory(cd.get());
8856 }
8857 }
8858 }
8859}
virtual void mergeCategory(ClassDef *category)=0

References AUTO_TRACE, AUTO_TRACE_ADD, Doxygen::classLinkedMap, DString::left(), ClassDefMutable::mergeCategory(), Definition::name(), DString::npos, and toClassDefMutable().

Referenced by parseInput().

◆ organizeSubGroups()

void organizeSubGroups ( const Entry * root)
static

Definition at line 599 of file doxygen.cpp.

600{
601 //printf("Defining groups\n");
602 // first process the @defgroups blocks
603 organizeSubGroupsFiltered(root,false);
604 //printf("Additional groups\n");
605 // then process the @addtogroup, @weakgroup blocks
606 organizeSubGroupsFiltered(root,true);
607}
static void organizeSubGroupsFiltered(const Entry *root, bool additional)
Definition doxygen.cpp:580

References organizeSubGroupsFiltered().

Referenced by parseInput().

◆ organizeSubGroupsFiltered()

void organizeSubGroupsFiltered ( const Entry * root,
bool additional )
static

Definition at line 580 of file doxygen.cpp.

581{
582 if (root->section.isGroupDoc() && !root->name.empty())
583 {
584 AUTO_TRACE("additional={}",additional);
585 if ((root->groupDocType==Entry::GROUPDOC_NORMAL && !additional) ||
586 (root->groupDocType!=Entry::GROUPDOC_NORMAL && additional))
587 {
589 if (gd)
590 {
591 AUTO_TRACE_ADD("adding {} to group {}",root->name,gd->name());
592 addGroupToGroups(root,gd);
593 }
594 }
595 }
596 for (const auto &e : root->children()) organizeSubGroupsFiltered(e.get(),additional);
597}
void addGroupToGroups(const Entry *root, GroupDef *subGroup)

References addGroupToGroups(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::children(), DString::empty(), LinkedMap< T, Hash, KeyEqual, Map >::find(), Entry::GROUPDOC_NORMAL, Entry::groupDocType, Doxygen::groupLinkedMap, Definition::name(), Entry::name, organizeSubGroupsFiltered(), and Entry::section.

Referenced by organizeSubGroups(), and organizeSubGroupsFiltered().

◆ parseFile()

std::shared_ptr< Entry > parseFile ( OutlineParserInterface & parser,
FileDef * fd,
const DString & fn,
ClangTUParser * clangParser,
bool newTU )
static

Definition at line 10965 of file doxygen.cpp.

10968{
10969 DString fileName=fn;
10970 AUTO_TRACE("fileName={}",fileName);
10971 DString extension;
10972 if (size_t ei = fileName.rfind('.'); ei!=DString::npos)
10973 {
10974 extension=fileName.mid(ei);
10975 }
10976 else
10977 {
10978 extension = ".no_extension";
10979 }
10980
10981 FileInfo fi(fileName.str());
10982 std::string preBuf;
10983
10984 if (Config_getBool(ENABLE_PREPROCESSING) &&
10985 parser.needsPreprocessing(extension))
10986 {
10987 Preprocessor preprocessor;
10988 StringVector includePath = Config_getList(INCLUDE_PATH);
10989 for (const auto &s : includePath)
10990 {
10991 std::string absPath = FileInfo(s).absFilePath();
10992 preprocessor.addSearchDir(absPath);
10993 }
10994 std::string inBuf;
10995 msg("Preprocessing {}...\n",fn);
10996 readInputFile(fileName,inBuf);
10997 addTerminalCharIfMissing(inBuf,'\n');
10998 preprocessor.processFile(fileName,inBuf,preBuf);
10999 }
11000 else // no preprocessing
11001 {
11002 msg("Reading {}...\n",fn);
11003 readInputFile(fileName,preBuf);
11004 addTerminalCharIfMissing(preBuf,'\n');
11005 }
11006
11007 std::string convBuf;
11008 convBuf.reserve(preBuf.size()+1024);
11009
11010 // convert multi-line C++ comments to C style comments
11011 convertCppComments(preBuf,convBuf,fileName.str());
11012
11013 std::shared_ptr<Entry> fileRoot = std::make_shared<Entry>();
11014 // use language parse to parse the file
11015 if (clangParser)
11016 {
11017 if (newTU) clangParser->parse();
11018 clangParser->switchToFile(fd);
11019 }
11020 parser.parseInput(fileName,convBuf.data(),fileRoot,clangParser);
11021 fileRoot->setFileDef(fd);
11022 return fileRoot;
11023}
void switchToFile(const FileDef *fd)
Switches to another file within the translation unit started with start().
void parse()
Parse the file given at construction time as a translation unit This file should already be preproces...
std::string absFilePath() const
Definition fileinfo.cpp:105
virtual bool needsPreprocessing(const DString &extension) const =0
Returns true if the language identified by extension needs the C preprocessor to be run before feed t...
virtual void parseInput(const DString &fileName, const char *fileBuf, const std::shared_ptr< Entry > &root, ClangTUParser *clangParser)=0
Parses a single input file with the goal to build an Entry tree.
void processFile(const DString &fileName, const std::string &input, std::string &output)
Definition pre.l:4409
void addSearchDir(const DString &dir)
Definition pre.l:4391
void convertCppComments(const std::string &inBuf, std::string &outBuf, const std::string &fn)
Converts the comments in a file.
void addTerminalCharIfMissing(std::string &s, char c)
Definition stringutil.h:87
bool readInputFile(const DString &fileName, std::string &contents, const ReadInputFileOptions &options)
read a file name fileName and optionally filter and transcode it
Definition util.cpp:4380

References FileInfo::absFilePath(), Preprocessor::addSearchDir(), addTerminalCharIfMissing(), AUTO_TRACE, Config_getBool, Config_getList, convertCppComments(), DString::data(), DString::mid(), msg, OutlineParserInterface::needsPreprocessing(), DString::npos, ClangTUParser::parse(), OutlineParserInterface::parseInput(), Preprocessor::processFile(), readInputFile(), DString::rfind(), DString::str(), and ClangTUParser::switchToFile().

Referenced by parseFilesMultiThreading(), and parseFilesSingleThreading().

◆ parseFilesMultiThreading()

void parseFilesMultiThreading ( const std::shared_ptr< Entry > & root)
static

parse the list of input files

Definition at line 11026 of file doxygen.cpp.

11027{
11028 AUTO_TRACE();
11029#if USE_LIBCLANG
11031 {
11032 StringUnorderedSet processedFiles;
11033
11034 // create a dictionary with files to process
11035 StringUnorderedSet filesToProcess;
11036 for (const auto &s : g_inputFiles)
11037 {
11038 filesToProcess.insert(s);
11039 }
11040
11041 std::mutex processedFilesLock;
11042 // process source files (and their include dependencies)
11043 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
11044 msg("Processing input using {} threads.\n",numThreads);
11045 ThreadPool threadPool(numThreads);
11046 using FutureType = std::vector< std::shared_ptr<Entry> >;
11047 std::vector< std::future< FutureType > > results;
11048 for (const auto &s : g_inputFiles)
11049 {
11050 bool ambig = false;
11051 DString qs = s;
11053 ASSERT(fd!=nullptr);
11054 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp) // this is a source file
11055 {
11056 // lambda representing the work to executed by a thread
11057 auto processFile = [qs,&filesToProcess,&processedFilesLock,&processedFiles]() {
11058 bool ambig_l = false;
11059 std::vector< std::shared_ptr<Entry> > roots;
11060 FileDef *fd_l = Doxygen::inputNameLinkedMap->findFileDef(qs,ambig_l);
11061 auto clangParser = ClangParser::instance()->createTUParser(fd_l);
11062 auto parser = getParserForFile(qs);
11063 auto fileRoot { parseFile(*parser.get(),fd_l,qs,clangParser.get(),true) };
11064 roots.push_back(fileRoot);
11065
11066 // Now process any include files in the same translation unit
11067 // first. When libclang is used this is much more efficient.
11068 for (auto incFile : clangParser->filesInSameTU())
11069 {
11070 DString qincFile = incFile;
11071 if (filesToProcess.find(incFile)!=filesToProcess.end())
11072 {
11073 bool needsToBeProcessed = false;
11074 {
11075 std::lock_guard<std::mutex> lock(processedFilesLock);
11076 needsToBeProcessed = processedFiles.find(incFile)==processedFiles.end();
11077 if (needsToBeProcessed) processedFiles.insert(incFile);
11078 }
11079 if (qincFile!=qs && needsToBeProcessed)
11080 {
11081 FileDef *ifd=Doxygen::inputNameLinkedMap->findFileDef(qincFile,ambig_l);
11082 if (ifd && !ifd->isReference())
11083 {
11084 //printf(" Processing %s in same translation unit as %s\n",incFile,qPrint(s));
11085 fileRoot = parseFile(*parser.get(),ifd,qincFile,clangParser.get(),false);
11086 roots.push_back(fileRoot);
11087 }
11088 }
11089 }
11090 }
11091 return roots;
11092 };
11093 // dispatch the work and collect the future results
11094 results.emplace_back(threadPool.queue(processFile));
11095 }
11096 }
11097 // synchronize with the Entry result lists produced and add them to the root
11098 for (auto &f : results)
11099 {
11100 auto l = f.get();
11101 for (auto &e : l)
11102 {
11103 root->moveToSubEntryAndKeep(e);
11104 }
11105 }
11106 // process remaining files
11107 results.clear();
11108 for (const auto &s : g_inputFiles)
11109 {
11110 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
11111 {
11112 // lambda representing the work to executed by a thread
11113 auto processFile = [s]() {
11114 bool ambig = false;
11115 DString qs = s;
11116 std::vector< std::shared_ptr<Entry> > roots;
11118 auto parser { getParserForFile(qs) };
11119 bool useClang = getLanguageFromFileName(qs)==SrcLangExt::Cpp;
11120 if (useClang)
11121 {
11122 auto clangParser = ClangParser::instance()->createTUParser(fd);
11123 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
11124 roots.push_back(fileRoot);
11125 }
11126 else
11127 {
11128 auto fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
11129 roots.push_back(fileRoot);
11130 }
11131 return roots;
11132 };
11133 results.emplace_back(threadPool.queue(processFile));
11134 }
11135 }
11136 // synchronize with the Entry result lists produced and add them to the root
11137 for (auto &f : results)
11138 {
11139 auto l = f.get();
11140 for (auto &e : l)
11141 {
11142 root->moveToSubEntryAndKeep(e);
11143 }
11144 }
11145 }
11146 else // normal processing
11147#endif
11148 {
11149 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
11150 msg("Processing input using {} threads.\n",numThreads);
11151 ThreadPool threadPool(numThreads);
11152 using FutureType = std::shared_ptr<Entry>;
11153 std::vector< std::future< FutureType > > results;
11154 for (const auto &s : g_inputFiles)
11155 {
11156 // lambda representing the work to executed by a thread
11157 auto processFile = [s]() {
11158 bool ambig = false;
11159 DString qs = s;
11161 auto parser = getParserForFile(qs);
11162 auto fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
11163 return fileRoot;
11164 };
11165 // dispatch the work and collect the future results
11166 results.emplace_back(threadPool.queue(processFile));
11167 }
11168 // synchronize with the Entry results produced and add them to the root
11169 for (auto &f : results)
11170 {
11171 root->moveToSubEntryAndKeep(f.get());
11172 }
11173 }
11174}
static std::shared_ptr< Entry > parseFile(OutlineParserInterface &parser, FileDef *fd, const DString &fn, ClangTUParser *clangParser, bool newTU)
static std::unique_ptr< OutlineParserInterface > getParserForFile(const DString &fn)

References ASSERT, AUTO_TRACE, Doxygen::clangAssistedParsing, Config_getInt, ClangParser::createTUParser(), FileNameLinkedMap::findFileDef(), g_inputFiles, Definition::getLanguage(), getLanguageFromFileName(), getParserForFile(), Doxygen::inputNameLinkedMap, ClangParser::instance(), Definition::isReference(), FileDef::isSource(), msg, parseFile(), and ThreadPool::queue().

Referenced by parseInput().

◆ parseFilesSingleThreading()

void parseFilesSingleThreading ( const std::shared_ptr< Entry > & root)
static

parse the list of input files

Definition at line 11177 of file doxygen.cpp.

11178{
11179 AUTO_TRACE();
11180#if USE_LIBCLANG
11182 {
11183 StringUnorderedSet processedFiles;
11184
11185 // create a dictionary with files to process
11186 StringUnorderedSet filesToProcess;
11187 for (const auto &s : g_inputFiles)
11188 {
11189 filesToProcess.insert(s);
11190 }
11191
11192 // process source files (and their include dependencies)
11193 for (const auto &s : g_inputFiles)
11194 {
11195 bool ambig = false;
11196 DString qs =s;
11198 ASSERT(fd!=nullptr);
11199 if (fd->isSource() && !fd->isReference() && getLanguageFromFileName(qs)==SrcLangExt::Cpp) // this is a source file
11200 {
11201 auto clangParser = ClangParser::instance()->createTUParser(fd);
11202 auto parser { getParserForFile(qs) };
11203 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
11204 root->moveToSubEntryAndKeep(fileRoot);
11205 processedFiles.insert(s);
11206
11207 // Now process any include files in the same translation unit
11208 // first. When libclang is used this is much more efficient.
11209 for (auto incFile : clangParser->filesInSameTU())
11210 {
11211 //printf(" file %s\n",qPrint(incFile));
11212 if (filesToProcess.find(incFile)!=filesToProcess.end() && // file need to be processed
11213 processedFiles.find(incFile)==processedFiles.end()) // and is not processed already
11214 {
11215 FileDef *ifd=Doxygen::inputNameLinkedMap->findFileDef(incFile,ambig);
11216 if (ifd && !ifd->isReference())
11217 {
11218 //printf(" Processing %s in same translation unit as %s\n",qPrint(incFile),qPrint(qs));
11219 fileRoot = parseFile(*parser.get(),ifd,incFile,clangParser.get(),false);
11220 root->moveToSubEntryAndKeep(fileRoot);
11221 processedFiles.insert(incFile);
11222 }
11223 }
11224 }
11225 }
11226 }
11227 // process remaining files
11228 for (const auto &s : g_inputFiles)
11229 {
11230 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
11231 {
11232 bool ambig = false;
11233 DString qs = s;
11235 if (getLanguageFromFileName(qs)==SrcLangExt::Cpp) // not yet processed
11236 {
11237 auto clangParser = ClangParser::instance()->createTUParser(fd);
11238 auto parser { getParserForFile(qs) };
11239 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
11240 root->moveToSubEntryAndKeep(fileRoot);
11241 }
11242 else
11243 {
11244 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
11245 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
11246 root->moveToSubEntryAndKeep(fileRoot);
11247 }
11248 processedFiles.insert(s);
11249 }
11250 }
11251 }
11252 else // normal processing
11253#endif
11254 {
11255 for (const auto &s : g_inputFiles)
11256 {
11257 bool ambig = false;
11258 DString qs = s;
11260 ASSERT(fd!=nullptr);
11261 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
11262 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
11263 root->moveToSubEntryAndKeep(std::move(fileRoot));
11264 }
11265 }
11266}

References ASSERT, AUTO_TRACE, Doxygen::clangAssistedParsing, ClangParser::createTUParser(), FileNameLinkedMap::findFileDef(), g_inputFiles, getLanguageFromFileName(), getParserForFile(), Doxygen::inputNameLinkedMap, ClangParser::instance(), Definition::isReference(), FileDef::isSource(), and parseFile().

Referenced by parseInput().

◆ parseInput()

void parseInput ( )

Definition at line 12762 of file doxygen.cpp.

12763{
12764 AUTO_TRACE();
12765 std::atexit(exitDoxygen);
12766
12767 Portable::correctPath(Config_getList(EXTERNAL_TOOL_PATH));
12768
12769#if USE_LIBCLANG
12770 Doxygen::clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
12771#endif
12772
12773 // we would like to show the versionString earlier, but we first have to handle the configuration file
12774 // to know the value of the QUIET setting.
12775 DString versionString = getFullVersion();
12776 msg("Doxygen version used: {}\n",versionString);
12777
12779
12780 /**************************************************************************
12781 * Make sure the output directory exists
12782 **************************************************************************/
12783 DString outputDirectory = Config_getString(OUTPUT_DIRECTORY);
12784 if (!g_singleComment)
12785 {
12786 if (outputDirectory.empty())
12787 {
12788 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,Dir::currentDirPath());
12789 }
12790 else
12791 {
12792 Dir dir(outputDirectory.str());
12793 if (!dir.exists())
12794 {
12795 dir.setPath(Dir::currentDirPath());
12796 if (!dir.mkdir(outputDirectory.str()))
12797 {
12798 term("tag OUTPUT_DIRECTORY: Output directory '{}' does not "
12799 "exist and cannot be created\n",outputDirectory);
12800 }
12801 else
12802 {
12803 msg("Notice: Output directory '{}' does not exist. "
12804 "I have created it for you.\n", outputDirectory);
12805 }
12806 dir.setPath(outputDirectory.str());
12807 }
12808 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,dir.absPath());
12809 }
12810 }
12811 AUTO_TRACE_ADD("outputDirectory={}",outputDirectory);
12812
12813 /**************************************************************************
12814 * Initialize global lists and dictionaries
12815 **************************************************************************/
12816
12817#ifdef HAS_SIGNALS
12818 signal(SIGINT, stopDoxygen);
12819#endif
12820
12821 uint32_t pid = Portable::pid();
12822 Doxygen::filterDBFileName.sprintf("doxygen_filterdb_%d.tmp",pid);
12823 Doxygen::filterDBFileName.prepend(outputDirectory+"/");
12824
12825 /**************************************************************************
12826 * Check/create output directories *
12827 **************************************************************************/
12828
12829 bool generateHtml = Config_getBool(GENERATE_HTML);
12830 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
12831 bool generateXml = Config_getBool(GENERATE_XML);
12832 bool generateLatex = Config_getBool(GENERATE_LATEX);
12833 bool generateRtf = Config_getBool(GENERATE_RTF);
12834 bool generateMan = Config_getBool(GENERATE_MAN);
12835 bool generateSql = Config_getBool(GENERATE_SQLITE3);
12836 DString htmlOutput;
12837 DString docbookOutput;
12838 DString xmlOutput;
12839 DString latexOutput;
12840 DString rtfOutput;
12841 DString manOutput;
12842 DString sqlOutput;
12843
12844 if (!g_singleComment)
12845 {
12846 if (generateHtml)
12847 {
12848 htmlOutput = createOutputDirectory(outputDirectory,Config_getString(HTML_OUTPUT),"/html");
12849 Config_updateString(HTML_OUTPUT,htmlOutput);
12850
12851 DString sitemapUrl = Config_getString(SITEMAP_URL);
12852 bool generateSitemap = !sitemapUrl.empty();
12853 if (generateSitemap && !sitemapUrl.endsWith("/"))
12854 {
12855 Config_updateString(SITEMAP_URL,sitemapUrl+"/");
12856 }
12857
12858 // add HTML indexers that are enabled
12859 bool generateHtmlHelp = Config_getBool(GENERATE_HTMLHELP);
12860 bool generateEclipseHelp = Config_getBool(GENERATE_ECLIPSEHELP);
12861 bool generateQhp = Config_getBool(GENERATE_QHP);
12862 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
12863 bool generateDocSet = Config_getBool(GENERATE_DOCSET);
12864 if (generateEclipseHelp) Doxygen::indexList->addIndex<EclipseHelp>();
12865 if (generateHtmlHelp) Doxygen::indexList->addIndex<HtmlHelp>();
12866 if (generateQhp) Doxygen::indexList->addIndex<Qhp>();
12867 if (generateSitemap) Doxygen::indexList->addIndex<Sitemap>();
12868 if (generateTreeView) Doxygen::indexList->addIndex<FTVHelp>(true);
12869 if (generateDocSet) Doxygen::indexList->addIndex<DocSets>();
12872 }
12873
12874 if (generateDocbook)
12875 {
12876 docbookOutput = createOutputDirectory(outputDirectory,Config_getString(DOCBOOK_OUTPUT),"/docbook");
12877 Config_updateString(DOCBOOK_OUTPUT,docbookOutput);
12878 }
12879
12880 if (generateXml)
12881 {
12882 xmlOutput = createOutputDirectory(outputDirectory,Config_getString(XML_OUTPUT),"/xml");
12883 Config_updateString(XML_OUTPUT,xmlOutput);
12884 }
12885
12886 if (generateLatex)
12887 {
12888 latexOutput = createOutputDirectory(outputDirectory,Config_getString(LATEX_OUTPUT), "/latex");
12889 Config_updateString(LATEX_OUTPUT,latexOutput);
12890 }
12891
12892 if (generateRtf)
12893 {
12894 rtfOutput = createOutputDirectory(outputDirectory,Config_getString(RTF_OUTPUT),"/rtf");
12895 Config_updateString(RTF_OUTPUT,rtfOutput);
12896 }
12897
12898 if (generateMan)
12899 {
12900 manOutput = createOutputDirectory(outputDirectory,Config_getString(MAN_OUTPUT),"/man");
12901 Config_updateString(MAN_OUTPUT,manOutput);
12902 }
12903
12904 if (generateSql)
12905 {
12906 sqlOutput = createOutputDirectory(outputDirectory,Config_getString(SQLITE3_OUTPUT),"/sqlite3");
12907 Config_updateString(SQLITE3_OUTPUT,sqlOutput);
12908 }
12909 }
12910
12911 if (Config_getBool(HAVE_DOT))
12912 {
12913 DString curFontPath = Config_getString(DOT_FONTPATH);
12914 if (curFontPath.empty())
12915 {
12916 Portable::getenv("DOTFONTPATH");
12917 DString newFontPath = ".";
12918 if (!curFontPath.empty())
12919 {
12920 newFontPath+=Portable::pathListSeparator();
12921 newFontPath+=curFontPath;
12922 }
12923 Portable::setenv("DOTFONTPATH",qPrint(newFontPath));
12924 }
12925 else
12926 {
12927 Portable::setenv("DOTFONTPATH",qPrint(curFontPath));
12928 }
12929 }
12930
12931 /**************************************************************************
12932 * Handle layout file *
12933 **************************************************************************/
12934
12936 DString layoutFileName = Config_getString(LAYOUT_FILE);
12937 bool defaultLayoutUsed = false;
12938 if (layoutFileName.empty())
12939 {
12940 layoutFileName = Config_updateString(LAYOUT_FILE,"DoxygenLayout.xml");
12941 defaultLayoutUsed = true;
12942 }
12943 AUTO_TRACE_ADD("defaultLayoutUsed={}, layoutFileName={}",defaultLayoutUsed,layoutFileName);
12944
12945 FileInfo fi(layoutFileName.str());
12946 if (fi.exists())
12947 {
12948 msg("Parsing layout file {}...\n",layoutFileName);
12949 LayoutDocManager::instance().parse(layoutFileName);
12950 }
12951 else if (!defaultLayoutUsed)
12952 {
12953 warn_uncond("failed to open layout file '{}' for reading! Using default settings.\n",layoutFileName);
12954 }
12955 printLayout();
12956
12957 /**************************************************************************
12958 * Read and preprocess input *
12959 **************************************************************************/
12960
12961 // prevent search in the output directories
12962 StringVector exclPatterns = Config_getList(EXCLUDE_PATTERNS);
12963 if (generateHtml) exclPatterns.push_back(htmlOutput.str());
12964 if (generateDocbook) exclPatterns.push_back(docbookOutput.str());
12965 if (generateXml) exclPatterns.push_back(xmlOutput.str());
12966 if (generateLatex) exclPatterns.push_back(latexOutput.str());
12967 if (generateRtf) exclPatterns.push_back(rtfOutput.str());
12968 if (generateMan) exclPatterns.push_back(manOutput.str());
12969 Config_updateList(EXCLUDE_PATTERNS,exclPatterns);
12970
12971 if (!g_singleComment)
12972 {
12974
12976 }
12977
12978 // Notice: the order of the function calls below is very important!
12979
12980 if (generateHtml && !Config_getBool(USE_MATHJAX))
12981 {
12983 }
12984 if (generateRtf)
12985 {
12987 }
12988 if (generateDocbook)
12989 {
12991 }
12992
12994
12995 /**************************************************************************
12996 * Handle Tag Files *
12997 **************************************************************************/
12998
12999 std::shared_ptr<Entry> root = std::make_shared<Entry>();
13000
13001 if (!g_singleComment)
13002 {
13003 msg("Reading and parsing tag files\n");
13004 StringVector tagFileList = Config_getList(TAGFILES);
13005 for (const auto &s : tagFileList)
13006 {
13007 readTagFile(root,s.c_str());
13008 }
13009 }
13010
13011 /**************************************************************************
13012 * Parse source files *
13013 **************************************************************************/
13014
13015 addSTLSupport(root);
13016
13017 g_s.begin("Parsing files\n");
13018 if (g_singleComment)
13019 {
13020 //printf("Parsing comment %s\n",qPrint(g_commentFileName));
13021 if (g_commentFileName=="-")
13022 {
13023 std::string text = fileToString(g_commentFileName).str();
13024 addTerminalCharIfMissing(text,'\n');
13025 generateHtmlForComment("stdin.md",text);
13026 }
13027 else if (FileInfo(g_commentFileName.str()).isFile())
13028 {
13029 std::string text;
13031 addTerminalCharIfMissing(text,'\n');
13033 }
13034 else
13035 {
13036 }
13038 exit(0);
13039 }
13040 else
13041 {
13042 if (Config_getInt(NUM_PROC_THREADS)==1)
13043 {
13045 }
13046 else
13047 {
13049 }
13050 }
13051 g_s.end();
13052
13053 /**************************************************************************
13054 * Gather information *
13055 **************************************************************************/
13056
13057 g_s.begin("Building macro definition list...\n");
13059 g_s.end();
13060
13061 g_s.begin("Building group list...\n");
13062 buildGroupList(root.get());
13063 organizeSubGroups(root.get());
13064 g_s.end();
13065
13066 g_s.begin("Building directory list...\n");
13068 findDirDocumentation(root.get());
13069 g_s.end();
13070
13071 g_s.begin("Building namespace list...\n");
13072 buildNamespaceList(root.get());
13073 findUsingDirectives(root.get());
13074 g_s.end();
13075
13076 g_s.begin("Building file list...\n");
13077 buildFileList(root.get());
13078 g_s.end();
13079
13080 g_s.begin("Building class list...\n");
13081 buildClassList(root.get());
13082 g_s.end();
13083
13084 g_s.begin("Building concept list...\n");
13085 buildConceptList(root.get());
13086 g_s.end();
13087
13088 // build list of using declarations here (global list)
13089 buildListOfUsingDecls(root.get());
13090 g_s.end();
13091
13092 g_s.begin("Computing nesting relations for classes...\n");
13094 g_s.end();
13095 // 1.8.2-20121111: no longer add nested classes to the group as well
13096 //distributeClassGroupRelations();
13097
13098 // calling buildClassList may result in cached relations that
13099 // become invalid after resolveClassNestingRelations(), that's why
13100 // we need to clear the cache here
13102 // we don't need the list of using declaration anymore
13103 g_usingDeclarations.clear();
13104
13105 g_s.begin("Associating documentation with classes...\n");
13106 buildClassDocList(root.get());
13107 g_s.end();
13108
13109 g_s.begin("Associating documentation with concepts...\n");
13110 buildConceptDocList(root.get());
13112 g_s.end();
13113
13114 g_s.begin("Associating documentation with modules...\n");
13115 findModuleDocumentation(root.get());
13116 g_s.end();
13117
13118 g_s.begin("Building example list...\n");
13119 buildExampleList(root.get());
13120 g_s.end();
13121
13122 g_s.begin("Searching for enumerations...\n");
13123 findEnums(root.get());
13124 g_s.end();
13125
13126 // Since buildVarList calls isVarWithConstructor
13127 // and this calls getResolvedClass we need to process
13128 // typedefs first so the relations between classes via typedefs
13129 // are properly resolved. See bug 536385 for an example.
13130 g_s.begin("Searching for documented typedefs...\n");
13131 buildTypedefList(root.get());
13132 g_s.end();
13133
13134 if (Config_getBool(OPTIMIZE_OUTPUT_SLICE))
13135 {
13136 g_s.begin("Searching for documented sequences...\n");
13137 buildSequenceList(root.get());
13138 g_s.end();
13139
13140 g_s.begin("Searching for documented dictionaries...\n");
13141 buildDictionaryList(root.get());
13142 g_s.end();
13143 }
13144
13145 g_s.begin("Searching for members imported via using declarations...\n");
13146 // this should be after buildTypedefList in order to properly import
13147 // used typedefs
13148 findUsingDeclarations(root.get(),true); // do for python packages first
13149 findUsingDeclarations(root.get(),false); // then the rest
13150 g_s.end();
13151
13152 g_s.begin("Searching for included using directives...\n");
13154 g_s.end();
13155
13156 g_s.begin("Searching for documented variables...\n");
13157 buildVarList(root.get());
13158 g_s.end();
13159
13160 g_s.begin("Building interface member list...\n");
13161 buildInterfaceAndServiceList(root.get()); // UNO IDL
13162
13163 g_s.begin("Building member list...\n"); // using class info only !
13164 buildFunctionList(root.get());
13165 g_s.end();
13166
13167 g_s.begin("Searching for friends...\n");
13168 findFriends();
13169 g_s.end();
13170
13171 g_s.begin("Searching for documented defines...\n");
13172 findDefineDocumentation(root.get());
13173 g_s.end();
13174
13175 g_s.begin("Computing class inheritance relations...\n");
13176 findClassEntries(root.get());
13178 g_s.end();
13179
13180 g_s.begin("Computing class usage relations...\n");
13182 g_s.end();
13183
13184 g_s.begin("Flushing cached template relations that have become invalid...\n");
13186 g_s.end();
13187
13188 g_s.begin("Warn for undocumented namespaces...\n");
13190 g_s.end();
13191
13192 g_s.begin("Computing class relations...\n");
13195 if (Config_getBool(OPTIMIZE_OUTPUT_VHDL))
13196 {
13198 }
13200 g_classEntries.clear();
13201 g_s.end();
13202
13203 g_s.begin("Add enum values to enums...\n");
13204 addEnumValuesToEnums(root.get());
13205 findEnumDocumentation(root.get());
13206 g_s.end();
13207
13208 g_s.begin("Searching for member function documentation...\n");
13209 findObjCMethodDefinitions(root.get());
13210 findMemberDocumentation(root.get()); // may introduce new members !
13211 findUsingDeclImports(root.get()); // may introduce new members !
13212 g_usingClassMap.clear();
13216 g_s.end();
13217
13218 // moved to after finding and copying documentation,
13219 // as this introduces new members see bug 722654
13220 g_s.begin("Creating members for template instances...\n");
13222 g_s.end();
13223
13224 g_s.begin("Searching for tag less structs...\n");
13226 g_s.end();
13227
13228 g_s.begin("Building page list...\n");
13229 buildPageList(root.get());
13230 g_s.end();
13231
13232 g_s.begin("Building requirements list...\n");
13233 buildRequirementsList(root.get());
13234 g_s.end();
13235
13236 g_s.begin("Search for main page...\n");
13237 findMainPage(root.get());
13238 findMainPageTagFiles(root.get());
13239 g_s.end();
13240
13241 g_s.begin("Computing page relations...\n");
13242 computePageRelations(root.get());
13244 g_s.end();
13245
13246 g_s.begin("Determining the scope of groups...\n");
13247 findGroupScope(root.get());
13248 g_s.end();
13249
13250 g_s.begin("Computing module relations...\n");
13251 auto &mm = ModuleManager::instance();
13252 mm.resolvePartitions();
13253 mm.resolveImports();
13254 mm.collectExportedSymbols();
13255 g_s.end();
13256
13257 auto memberNameComp = [](const MemberNameLinkedMap::Ptr &n1,const MemberNameLinkedMap::Ptr &n2)
13258 {
13259 return dstricmp_sort(n1->memberName().data()+getPrefixIndex(n1->memberName()),
13260 n2->memberName().data()+getPrefixIndex(n2->memberName())
13261 )<0;
13262 };
13263
13264 auto classComp = [](const ClassLinkedMap::Ptr &c1,const ClassLinkedMap::Ptr &c2)
13265 {
13266 if (Config_getBool(SORT_BY_SCOPE_NAME))
13267 {
13268 return dstricmp_sort(c1->name(), c2->name())<0;
13269 }
13270 else
13271 {
13272 int i = dstricmp_sort(c1->className(), c2->className());
13273 return i==0 ? dstricmp_sort(c1->name(), c2->name())<0 : i<0;
13274 }
13275 };
13276
13277 auto namespaceComp = [](const NamespaceLinkedMap::Ptr &n1,const NamespaceLinkedMap::Ptr &n2)
13278 {
13279 return dstricmp_sort(n1->name(),n2->name())<0;
13280 };
13281
13282 auto conceptComp = [](const ConceptLinkedMap::Ptr &c1,const ConceptLinkedMap::Ptr &c2)
13283 {
13284 return dstricmp_sort(c1->name(),c2->name())<0;
13285 };
13286
13287 g_s.begin("Sorting lists...\n");
13288 std::stable_sort(Doxygen::memberNameLinkedMap->begin(),
13290 memberNameComp);
13291 std::stable_sort(Doxygen::functionNameLinkedMap->begin(),
13293 memberNameComp);
13294 std::stable_sort(Doxygen::hiddenClassLinkedMap->begin(),
13296 classComp);
13297 std::stable_sort(Doxygen::classLinkedMap->begin(),
13299 classComp);
13300 std::stable_sort(Doxygen::conceptLinkedMap->begin(),
13302 conceptComp);
13303 std::stable_sort(Doxygen::namespaceLinkedMap->begin(),
13305 namespaceComp);
13306 g_s.end();
13307
13308 g_s.begin("Determining which enums are documented\n");
13310 g_s.end();
13311
13312 g_s.begin("Computing member relations...\n");
13315 g_s.end();
13316
13317 g_s.begin("Building full member lists recursively...\n");
13319 g_s.end();
13320
13321 g_s.begin("Adding members to member groups.\n");
13323 g_s.end();
13324
13325 if (Config_getBool(DISTRIBUTE_GROUP_DOC))
13326 {
13327 g_s.begin("Distributing member group documentation.\n");
13329 g_s.end();
13330 }
13331
13332 g_s.begin("Computing member references...\n");
13334 g_s.end();
13335
13336 if (Config_getBool(INHERIT_DOCS))
13337 {
13338 g_s.begin("Inheriting documentation...\n");
13340 g_s.end();
13341 }
13342
13343
13344 // compute the shortest possible names of all files
13345 // without losing the uniqueness of the file names.
13346 g_s.begin("Generating disk names...\n");
13348 g_s.end();
13349
13350 g_s.begin("Adding source references...\n");
13352 g_s.end();
13353
13354 g_s.begin("Adding xrefitems...\n");
13357 g_s.end();
13358
13359 g_s.begin("Adding requirements...\n");
13362 g_s.end();
13363
13364 g_s.begin("Sorting member lists...\n");
13366 g_s.end();
13367
13368 g_s.begin("Setting anonymous enum type...\n");
13370 g_s.end();
13371
13372 g_s.begin("Computing dependencies between directories...\n");
13374 g_s.end();
13375
13376 g_s.begin("Generating citations page...\n");
13378 g_s.end();
13379
13380 g_s.begin("Counting data structures...\n");
13382 g_s.end();
13383
13384 g_s.begin("Resolving user defined references...\n");
13386 g_s.end();
13387
13388 g_s.begin("Finding anchors and sections in the documentation...\n");
13390 g_s.end();
13391
13392 g_s.begin("Transferring function references...\n");
13394 g_s.end();
13395
13396 g_s.begin("Combining using relations...\n");
13398 g_s.end();
13399
13401 g_s.begin("Adding members to index pages...\n");
13403 addToIndices();
13404 g_s.end();
13405
13406 g_s.begin("Correcting members for VHDL...\n");
13408 g_s.end();
13409
13410 g_s.begin("Computing tooltip texts...\n");
13412 g_s.end();
13413
13414 if (Config_getBool(SORT_GROUP_NAMES))
13415 {
13416 std::stable_sort(Doxygen::groupLinkedMap->begin(),
13418 [](const auto &g1,const auto &g2)
13419 { return g1->groupTitle() < g2->groupTitle(); });
13420
13421 for (const auto &gd : *Doxygen::groupLinkedMap)
13422 {
13423 gd->sortSubGroups();
13424 }
13425 }
13426
13427 printNavTree(root.get(),0);
13429}
void generatePage()
Generate the citations page.
Definition cite.cpp:336
A class that generates docset files.
Definition docsets.h:35
Generator for Eclipse help files.
Definition eclipsehelp.h:42
A class that generates a dynamic tree view side panel.
Definition ftvhelp.h:41
bool isFile() const
Definition fileinfo.cpp:67
void initFromRepository(const DString &dir)
Definition formula.cpp:60
void checkRepositories()
Definition formula.cpp:173
A class that generated the HTML Help specific files.
Definition htmlhelp.h:37
void countDataStructures()
Definition index.cpp:266
void initialize()
Definition indexlist.h:101
void addIndex(As &&... args)
Add an index generator to the list, using a syntax similar to std::make_unique<T>().
Definition indexlist.h:98
void parse(const DString &fileName, const char *data=nullptr)
Parses a user provided layout.
Definition layout.cpp:1482
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition layout.cpp:1449
Definition qhp.h:29
static void computeVhdlComponentRelations()
#define Config_updateList(name,...)
Definition config.h:43
DirIterator begin(DirIterator it) noexcept
Definition dir.cpp:176
void buildDirectories()
Definition dirdef.cpp:1097
void computeDirDependencies()
Definition dirdef.cpp:1171
static void findInheritedTemplateInstances()
Definition doxygen.cpp:5553
void printNavTree(Entry *root, int indent)
static void buildGroupList(const Entry *root)
Definition doxygen.cpp:540
static void flushCachedTemplateRelations()
Definition doxygen.cpp:9736
static void computeTemplateClassRelations()
Definition doxygen.cpp:5647
void printSectionsTree()
static void generateXRefPages()
Definition doxygen.cpp:5826
static void warnUndocumentedNamespaces()
Definition doxygen.cpp:5602
static void resolveClassNestingRelations()
Definition doxygen.cpp:1391
static void vhdlCorrectMemberProperties()
Definition doxygen.cpp:8655
static void stopDoxygen(int)
static void computeMemberReferences()
Definition doxygen.cpp:5716
static void transferRelatedFunctionDocumentation()
Definition doxygen.cpp:4677
static void addMembersToMemberGroup()
Definition doxygen.cpp:9601
static void distributeConceptGroups()
Definition doxygen.cpp:1358
static void transferFunctionDocumentation()
Definition doxygen.cpp:4596
static void setAnonymousEnumType()
Definition doxygen.cpp:9341
static void sortMemberLists()
Definition doxygen.cpp:9246
static void createTemplateInstanceMembers()
Definition doxygen.cpp:8823
void transferStaticInstanceInitializers()
Definition doxygen.cpp:4726
static void findObjCMethodDefinitions(const Entry *root)
Definition doxygen.cpp:7799
static void distributeMemberGroupDocumentation()
Definition doxygen.cpp:9639
static void resolveUserReferences()
static void findIncludedUsingDirectives()
Definition doxygen.cpp:2729
static void organizeSubGroups(const Entry *root)
Definition doxygen.cpp:599
void searchInputFiles()
static void findFriends()
Definition doxygen.cpp:4499
static DString g_commentFileName
Definition doxygen.cpp:196
static void addListReferences()
Definition doxygen.cpp:5817
static void exitDoxygen() noexcept
static void addMembersToIndex()
Definition doxygen.cpp:8445
static void addSourceReferences()
Definition doxygen.cpp:9119
static void inheritDocumentation()
Definition doxygen.cpp:9541
static void flushUnresolvedRelations()
Definition doxygen.cpp:9778
static void findDocumentedEnumValues()
Definition doxygen.cpp:8437
static void generateDiskNames()
static void addToIndices()
Definition doxygen.cpp:8487
static void computeClassRelations()
Definition doxygen.cpp:5622
static void checkPageRelations()
static void readTagFile(const std::shared_ptr< Entry > &root, const DString &tagLine)
static void addRequirementReferences()
Definition doxygen.cpp:5809
static void computeVerifiedDotPath()
static bool g_singleComment
Definition doxygen.cpp:197
static void findSectionsInDocumentation()
Definition doxygen.cpp:9677
static void mergeCategories()
Definition doxygen.cpp:8842
static void findUsedTemplateInstances()
Definition doxygen.cpp:5586
static void computeTooltipTexts()
Definition doxygen.cpp:9295
static void parseFilesSingleThreading(const std::shared_ptr< Entry > &root)
parse the list of input files
static void buildCompleteMemberLists()
Definition doxygen.cpp:8863
static void combineUsingRelations()
Definition doxygen.cpp:9576
static void checkMarkdownMainfile()
static void parseFilesMultiThreading(const std::shared_ptr< Entry > &root)
parse the list of input files
static DString createOutputDirectory(const DString &baseDirName, const DString &formatDirName, const char *defaultDirName)
static void transferFunctionReferences()
Definition doxygen.cpp:4629
static void buildDefineList()
Definition doxygen.cpp:9198
static void computeMemberRelations()
Definition doxygen.cpp:8806
int dstricmp_sort(const char *str1, const char *str2)
Definition dstring.h:67
void printLayout()
Definition layout.cpp:1834
void correctPath(const StringVector &list)
Correct a possible wrong PATH variable.
Definition portable.cpp:532
uint32_t pid()
Definition portable.cpp:264
DString pathListSeparator()
Definition portable.cpp:399
void initSearchIndexer()
void generateHtmlForComment(const std::string &fn, const std::string &text)
Helper for implemented the -c option of doxygen, which produces HTML output for a given doxygen forma...
void addSTLSupport(std::shared_ptr< Entry > &root)
Add stub entries for the most used classes in the standard template library.
DString fileToString(const DString &name, bool filter, bool isSourceCode)
Definition util.cpp:1058
int getPrefixIndex(const DString &name)
Definition util.cpp:2657

References Dir::absPath(), addEnumValuesToEnums(), IndexList::addIndex(), addListReferences(), addMembersToIndex(), addMembersToMemberGroup(), addRequirementReferences(), addSourceReferences(), addSTLSupport(), addTerminalCharIfMissing(), addToIndices(), SymbolResolver::All, AUTO_TRACE, AUTO_TRACE_ADD, begin(), Statistics::begin(), buildClassDocList(), buildClassList(), buildCompleteMemberLists(), buildConceptDocList(), buildConceptList(), buildDefineList(), buildDictionaryList(), buildDirectories(), buildExampleList(), buildFileList(), buildFunctionList(), buildGroupList(), buildInterfaceAndServiceList(), buildListOfUsingDecls(), buildNamespaceList(), buildPageList(), buildRequirementsList(), buildSequenceList(), buildTypedefList(), buildVarList(), checkMarkdownMainfile(), checkPageRelations(), FormulaManager::checkRepositories(), Doxygen::clangAssistedParsing, Doxygen::classLinkedMap, cleanUpDoxygen(), SymbolResolver::clearTypeLookupCache(), combineUsingRelations(), computeClassRelations(), computeDirDependencies(), computeMemberReferences(), computeMemberRelations(), computePageRelations(), computeTemplateClassRelations(), computeTooltipTexts(), computeVerifiedDotPath(), VhdlDocGen::computeVhdlComponentRelations(), Doxygen::conceptLinkedMap, Config_getBool, Config_getInt, Config_getList, Config_getString, Config_updateList, Config_updateString, Portable::correctPath(), Index::countDataStructures(), createOutputDirectory(), createTemplateInstanceMembers(), Dir::currentDirPath(), distributeConceptGroups(), distributeMemberGroupDocumentation(), dstricmp_sort(), DString::empty(), end(), Statistics::end(), DString::endsWith(), Dir::exists(), FileInfo::exists(), exitDoxygen(), fileToString(), Doxygen::filterDBFileName, findClassEntries(), findDefineDocumentation(), findDirDocumentation(), findDocumentedEnumValues(), findEnumDocumentation(), findEnums(), findFriends(), findGroupScope(), findIncludedUsingDirectives(), findInheritedTemplateInstances(), findMainPage(), findMainPageTagFiles(), findMemberDocumentation(), findModuleDocumentation(), findObjCMethodDefinitions(), findSectionsInDocumentation(), findTagLessClasses(), findUsedTemplateInstances(), findUsingDeclarations(), findUsingDeclImports(), findUsingDirectives(), flushCachedTemplateRelations(), flushUnresolvedRelations(), Doxygen::functionNameLinkedMap, g_classEntries, g_commentFileName, g_s, g_singleComment, g_usingClassMap, g_usingDeclarations, generateDiskNames(), generateHtmlForComment(), CitationManager::generatePage(), RequirementManager::generatePage(), generateXRefPages(), Portable::getenv(), getPrefixIndex(), Doxygen::groupLinkedMap, Doxygen::hiddenClassLinkedMap, Doxygen::indexList, inheritDocumentation(), LayoutDocManager::init(), FormulaManager::initFromRepository(), IndexList::initialize(), initSearchIndexer(), CitationManager::instance(), FormulaManager::instance(), Index::instance(), LayoutDocManager::instance(), ModuleManager::instance(), RequirementManager::instance(), FileInfo::isFile(), Doxygen::memberNameLinkedMap, mergeCategories(), Dir::mkdir(), msg, Doxygen::namespaceLinkedMap, organizeSubGroups(), LayoutDocManager::parse(), parseFilesMultiThreading(), parseFilesSingleThreading(), Portable::pathListSeparator(), Portable::pid(), DString::prepend(), printLayout(), printNavTree(), printSectionsTree(), qPrint(), readInputFile(), readTagFile(), resolveClassNestingRelations(), resolveUserReferences(), searchInputFiles(), setAnonymousEnumType(), Portable::setenv(), Dir::setPath(), sortMemberLists(), DString::sprintf(), stopDoxygen(), DString::str(), term, transferFunctionDocumentation(), transferFunctionReferences(), transferRelatedFunctionDocumentation(), transferStaticInstanceInitializers(), vhdlCorrectMemberProperties(), warn_uncond, and warnUndocumentedNamespaces().

Referenced by main().

◆ printNavTree()

void printNavTree ( Entry * root,
int indent )

Definition at line 10281 of file doxygen.cpp.

10282{
10284 {
10285 DString indentStr;
10286 indentStr.fill(' ',indent);
10287 Debug::print(Debug::Entries,0,"{}{} at {}:{} (sec={}, spec={})\n",
10288 indentStr.empty()?"":indentStr,
10289 root->name.empty()?"<empty>":root->name,
10290 root->fileName,root->startLine,
10291 root->section.to_string(),
10292 root->spec.to_string());
10293 for (const auto &e : root->children())
10294 {
10295 printNavTree(e.get(),indent+2);
10296 }
10297 }
10298}
DString fill(char c, size_t len)
Fills a string with a predefined character.
Definition dstring.h:278
@ Entries
Definition debug.h:48
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
Definition debug.h:78
std::string to_string() const
Definition types.h:868
std::string to_string() const
Definition types.h:738

References Entry::children(), DString::empty(), Debug::Entries, Entry::fileName, DString::fill(), Debug::isFlagSet(), Entry::name, Debug::print(), printNavTree(), Entry::section, Entry::spec, Entry::startLine, EntryType::to_string(), and TypeSpecifier::to_string().

Referenced by parseInput(), and printNavTree().

◆ printSectionsTree()

void printSectionsTree ( )

Definition at line 10304 of file doxygen.cpp.

10305{
10307 {
10308 for (const auto &si : SectionManager::instance())
10309 {
10310 Debug::print(Debug::Sections,0,"Section = {}, file = {}, title = {}, type = {}, ref = {}\n",
10311 si->label(),si->fileName(),si->title(),si->type().level(),si->ref());
10312 }
10313 }
10314}
@ Sections
Definition debug.h:49

References SectionManager::instance(), Debug::isFlagSet(), Debug::print(), and Debug::Sections.

Referenced by parseInput().

◆ processTagLessClasses()

template<typename Container, typename TagContainer>
void processTagLessClasses ( const Definition * root,
const Container * def,
const TagContainer * tagParent,
MemberListType varFilter,
MemberListType typeFilter,
const DString & prefix,
int count )
static

Look through the members of class cd and its public members.

If there is a member m of a tag less struct/union, then we create a duplicate of the struct/union with the name of the member to identify it. So if cd has name S, then the tag less struct/union will get name S.m Since tag less structs can be nested we need to call this function recursively. Later on we need to patch the member types so we keep track of the hierarchy of classes we create.

Definition at line 1897 of file doxygen.cpp.

1903{
1904 if (varFilter==MemberListType::PubAttribs()) // also handle protected and private members
1905 {
1906 processTagLessClassesForList(root,def,tagParent,MemberListType::PubAttribs(),MemberListType::PubTypes(),prefix,count);
1907 processTagLessClassesForList(root,def,tagParent,MemberListType::ProAttribs(),MemberListType::ProTypes(),prefix,count);
1908 processTagLessClassesForList(root,def,tagParent,MemberListType::PriAttribs(),MemberListType::PriTypes(),prefix,count);
1909 }
1910 else
1911 {
1912 processTagLessClassesForList(root,def,tagParent,varFilter,typeFilter,prefix,count);
1913 }
1914}
static void processTagLessClassesForList(const Definition *root, const Container *def, const TagContainer *tagParent, MemberListType varFilter, MemberListType typeFilter, const DString &prefix, int count)
Definition doxygen.cpp:1790

References prefix, and processTagLessClassesForList().

Referenced by findTagLessClasses(), and processTagLessClassesForList().

◆ processTagLessClassesForList()

template<typename Container, typename TagContainer>
void processTagLessClassesForList ( const Definition * root,
const Container * def,
const TagContainer * tagParent,
MemberListType varFilter,
MemberListType typeFilter,
const DString & prefix,
int count )
static

Definition at line 1790 of file doxygen.cpp.

1796{
1797 AUTO_TRACE("count={} name={}\n",count,def->name());
1798 if (tagParent)
1799 {
1800 MemberList *ml = def->getMemberList(varFilter);
1801 if (ml)
1802 {
1803 int pos=0;
1804 // make a copy of the member list, since we may add new members to the list while iterating over it
1805 std::vector<MemberDef *> members;
1806 for (const auto &md : *ml)
1807 {
1808 members.push_back(md);
1809 }
1810 for (const auto &md : members)
1811 {
1812 MemberDefMutable *pmdm = nullptr;
1813 if (tagParent!=def)
1814 {
1815 // associate the variable of the anonymous type with the type member
1816 MemberList *pml = tagParent->getMemberList(varFilter);
1817 if (pml)
1818 {
1819 for (const auto &pmd : *pml)
1820 {
1821 if (pmd->name()==md->name())
1822 {
1823 pmdm = toMemberDefMutable(pmd);
1824 }
1825 }
1826 }
1827 }
1828 else
1829 {
1830 pmdm = toMemberDefMutable(md);
1831 }
1832 bool hasNamedVariable = pmdm==nullptr || !pmdm->isAnonymous();
1833
1834 DString type = md->typeString();
1835 //printf(" member %s: type='%s' outerScope='%s'\n",qPrint(md->name()),qPrint(type),qPrint(md->getOuterScope()?md->getOuterScope()->name():"<null>"));
1836 if ((def->definitionType()!=Definition::TypeFile || md->getOuterScope()==Doxygen::globalScope) && // parse namespace members only if def is a namespace
1837 (type.find("::@")!=DString::npos || type.find(" @")!=DString::npos)) // member of tag less struct/union
1838 {
1839 // make a copy of the class list, since we may add new members to the list while iterating over it
1840 std::vector<const ClassDef *> candidates;
1841 for (const auto &icd : def->getClasses())
1842 {
1843 candidates.push_back(icd);
1844 }
1845 for (const auto &icd : candidates)
1846 {
1847 //printf(" comparing '%s'<->'%s'\n",qPrint(type),qPrint(icd->name()));
1848 if (type.find(icd->name())!=DString::npos) // matching tag less struct/union
1849 {
1850 DString name = md->name();
1851 if (md->isAnonymous()) name = "__unnamed" + DString().setNum(pos++)+"__"; // TODO: remove dead code
1852 if (!prefix.empty()) name.prepend(prefix+".");
1853 //printf(" found %s in scope %s\n",qPrint(name),qPrint(def->name()));
1854 ClassDefMutable *ncd = createTagLessInstance(root,icd,name,hasNamedVariable);
1855 if (ncd)
1856 {
1857 processTagLessClasses(ncd,icd,ncd,MemberListType::PubAttribs(),MemberListType::PubTypes(),name,count+1);
1858 //printf(" addTagged %s to %s\n",qPrint(ncd->name()),qPrint(tagParent->name()));
1859 ncd->setTaglessParent(icd);
1860 if (pmdm)
1861 {
1862 pmdm->setClassDefOfAnonymousType(ncd);
1863 }
1864 }
1865 }
1866 else
1867 {
1868 //printf(" no match for %s in %s\n",qPrint(icd->name()),qPrint(type));
1869 }
1870 }
1871 }
1872 }
1873 }
1874 // associate the variable of the anonymous enum type with the type member
1875 ml = def->getMemberList(typeFilter);
1876 if (ml)
1877 {
1878 for (const auto &md : *ml)
1879 {
1880 MemberListType mlFilter = def->definitionType()==Definition::TypeClass ? varFilter : MemberListType::DecVarMembers();
1881 associateVariableWithAnonymousEnumType(md,def,md,mlFilter);
1882 }
1883 }
1884 }
1885}
virtual void setTaglessParent(const ClassDef *cd)=0
DString & setNum(short n)
Definition dstring.h:552
Wrapper class for the MemberListType type.
Definition types.h:346
static ClassDefMutable * createTagLessInstance(const Definition *root, const ClassDef *templ, const DString &fieldName, bool hasNamedVariable)
Definition doxygen.cpp:1572

References associateVariableWithAnonymousEnumType(), AUTO_TRACE, createTagLessInstance(), DString::find(), Doxygen::globalScope, Definition::isAnonymous(), DString::npos, prefix, processTagLessClasses(), MemberDefMutable::setClassDefOfAnonymousType(), DString::setNum(), ClassDefMutable::setTaglessParent(), toMemberDefMutable(), Definition::TypeClass, and Definition::TypeFile.

Referenced by processTagLessClasses().

◆ readConfiguration()

void readConfiguration ( int argc,
char ** argv )

Definition at line 11809 of file doxygen.cpp.

11810{
11811 DString versionString = getFullVersion();
11812
11813 // helper that calls \a func to write to file \a fileName via a TextStream
11814 auto writeFile = [](const char *fileName,std::function<void(TextStream&)> func) -> bool
11815 {
11816 std::ofstream f;
11817 if (openOutputFile(fileName,f))
11818 {
11819 TextStream t(&f);
11820 func(t);
11821 return true;
11822 }
11823 return false;
11824 };
11825
11826
11827 /**************************************************************************
11828 * Handle arguments *
11829 **************************************************************************/
11830
11831 int optInd=1;
11832 DString configName;
11833 DString traceName;
11834 bool genConfig=false;
11835 bool shortList=false;
11836 bool traceTiming=false;
11838 bool updateConfig=false;
11839 bool quiet = false;
11840 while (optInd<argc && argv[optInd][0]=='-' &&
11841 (isalpha(argv[optInd][1]) || argv[optInd][1]=='?' ||
11842 argv[optInd][1]=='-')
11843 )
11844 {
11845 switch(argv[optInd][1])
11846 {
11847 case 'g':
11848 {
11849 genConfig=true;
11850 }
11851 break;
11852 case 'l':
11853 {
11854 DString layoutName;
11855 if (optInd+1>=argc)
11856 {
11857 layoutName="DoxygenLayout.xml";
11858 }
11859 else
11860 {
11861 layoutName=argv[optInd+1];
11862 }
11863 writeDefaultLayoutFile(layoutName);
11865 exit(0);
11866 }
11867 break;
11868 case 'c':
11869 if (optInd+1>=argc) // no file name given
11870 {
11871 msg("option \"-c\" is missing the file name to read\n");
11872 devUsage();
11874 exit(1);
11875 }
11876 else
11877 {
11878 g_commentFileName=argv[optInd+1];
11879 optInd++;
11880 }
11881 g_singleComment=true;
11882 quiet=true;
11883 break;
11884 case 'd':
11885 {
11886 DString debugLabel=getArg(argc,argv,optInd);
11887 if (debugLabel.empty())
11888 {
11889 devUsage();
11891 exit(0);
11892 }
11893 int retVal = Debug::setFlagStr(debugLabel);
11894 if (!retVal)
11895 {
11896 msg("option \"-d\" has unknown debug specifier: \"{}\".\n",debugLabel);
11897 devUsage();
11899 exit(1);
11900 }
11901 }
11902 break;
11903 case 't':
11904 {
11905#if ENABLE_TRACING
11906 if (!strcmp(argv[optInd]+1,"t_time"))
11907 {
11908 traceTiming = true;
11909 }
11910 else if (!strcmp(argv[optInd]+1,"t"))
11911 {
11912 traceTiming = false;
11913 }
11914 else
11915 {
11916 err("option should be \"-t\" or \"-t_time\", found: \"{}\".\n",argv[optInd]);
11918 exit(1);
11919 }
11920 if (optInd+1>=argc || argv[optInd+1][0] == '-') // no file name given
11921 {
11922 traceName="stdout";
11923 }
11924 else
11925 {
11926 traceName=argv[optInd+1];
11927 optInd++;
11928 }
11929#else
11930 err("support for option \"-t\" has not been compiled in (use a debug build or a release build with tracing enabled).\n");
11932 exit(1);
11933#endif
11934 }
11935 break;
11936 case 'x':
11937 if (!strcmp(argv[optInd]+1,"x_noenv")) diffList=Config::CompareMode::CompressedNoEnv;
11938 else if (!strcmp(argv[optInd]+1,"x")) diffList=Config::CompareMode::Compressed;
11939 else
11940 {
11941 err("option should be \"-x\" or \"-x_noenv\", found: \"{}\".\n",argv[optInd]);
11943 exit(1);
11944 }
11945 break;
11946 case 's':
11947 shortList=true;
11948 break;
11949 case 'u':
11950 updateConfig=true;
11951 break;
11952 case 'e':
11953 {
11954 DString formatName=getArg(argc,argv,optInd);
11955 if (formatName.empty())
11956 {
11957 err("option \"-e\" is missing format specifier rtf.\n");
11959 exit(1);
11960 }
11961 if (dstricmp(formatName.data(),"rtf")==0)
11962 {
11963 if (optInd+1>=argc)
11964 {
11965 err("option \"-e rtf\" is missing an extensions file name\n");
11967 exit(1);
11968 }
11969 writeFile(argv[optInd+1],RTFGenerator::writeExtensionsFile);
11971 exit(0);
11972 }
11973 err("option \"-e\" has invalid format specifier.\n");
11975 exit(1);
11976 }
11977 break;
11978 case 'f':
11979 {
11980 DString listName=getArg(argc,argv,optInd);
11981 if (listName.empty())
11982 {
11983 err("option \"-f\" is missing list specifier.\n");
11985 exit(1);
11986 }
11987 if (dstricmp(listName.data(),"emoji")==0)
11988 {
11989 if (optInd+1>=argc)
11990 {
11991 err("option \"-f emoji\" is missing an output file name\n");
11993 exit(1);
11994 }
11995 writeFile(argv[optInd+1],[](TextStream &t) { EmojiEntityMapper::instance().writeEmojiFile(t); });
11997 exit(0);
11998 }
11999 err("option \"-f\" has invalid list specifier.\n");
12001 exit(1);
12002 }
12003 break;
12004 case 'w':
12005 {
12006 DString formatName=getArg(argc,argv,optInd);
12007 if (formatName.empty())
12008 {
12009 err("option \"-w\" is missing format specifier rtf, html or latex\n");
12011 exit(1);
12012 }
12013 if (dstricmp(formatName.data(),"rtf")==0)
12014 {
12015 if (optInd+1>=argc)
12016 {
12017 err("option \"-w rtf\" is missing a style sheet file name\n");
12019 exit(1);
12020 }
12021 if (!writeFile(argv[optInd+1],RTFGenerator::writeStyleSheetFile))
12022 {
12023 err("error opening RTF style sheet file {}!\n",argv[optInd+1]);
12025 exit(1);
12026 }
12028 exit(0);
12029 }
12030 else if (dstricmp(formatName.data(),"html")==0)
12031 {
12032 Config::init();
12033 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
12034 // explicit config file mentioned or default found on disk
12035 {
12036 DString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? DString("Doxyfile") : DString("doxyfile"));
12037 if (!Config::parse(df)) // parse the config file
12038 {
12039 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
12041 exit(1);
12042 }
12043 }
12044 if (optInd+3>=argc)
12045 {
12046 err("option \"-w html\" does not have enough arguments\n");
12048 exit(1);
12049 }
12050 Config::postProcess(true);
12053 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
12054 writeFile(argv[optInd+1],[&](TextStream &t) { HtmlGenerator::writeHeaderFile(t,argv[optInd+3]); });
12055 writeFile(argv[optInd+2],HtmlGenerator::writeFooterFile);
12056 writeFile(argv[optInd+3],HtmlGenerator::writeStyleSheetFile);
12058 exit(0);
12059 }
12060 else if (dstricmp(formatName.data(),"latex")==0)
12061 {
12062 Config::init();
12063 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
12064 {
12065 DString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? DString("Doxyfile") : DString("doxyfile"));
12066 if (!Config::parse(df))
12067 {
12068 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
12070 exit(1);
12071 }
12072 }
12073 if (optInd+3>=argc)
12074 {
12075 err("option \"-w latex\" does not have enough arguments\n");
12077 exit(1);
12078 }
12079 Config::postProcess(true);
12082 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
12083 writeFile(argv[optInd+1],LatexGenerator::writeHeaderFile);
12084 writeFile(argv[optInd+2],LatexGenerator::writeFooterFile);
12085 writeFile(argv[optInd+3],LatexGenerator::writeStyleSheetFile);
12087 exit(0);
12088 }
12089 else
12090 {
12091 err("Illegal format specifier \"{}\": should be one of rtf, html or latex\n",formatName);
12093 exit(1);
12094 }
12095 }
12096 break;
12097 case 'm':
12098 g_dumpSymbolMap = true;
12099 break;
12100 case 'v':
12101 version(false);
12103 exit(0);
12104 break;
12105 case 'V':
12106 version(true);
12108 exit(0);
12109 break;
12110 case '-':
12111 if (dstrcmp(&argv[optInd][2],"help")==0)
12112 {
12113 usage(argv[0],versionString);
12114 exit(0);
12115 }
12116 else if (dstrcmp(&argv[optInd][2],"version")==0)
12117 {
12118 version(false);
12120 exit(0);
12121 }
12122 else if ((dstrcmp(&argv[optInd][2],"Version")==0) ||
12123 (dstrcmp(&argv[optInd][2],"VERSION")==0))
12124 {
12125 version(true);
12127 exit(0);
12128 }
12129 else
12130 {
12131 err("Unknown option \"-{}\"\n",&argv[optInd][1]);
12132 usage(argv[0],versionString);
12133 exit(1);
12134 }
12135 break;
12136 case 'b':
12137 setvbuf(stdout,nullptr,_IONBF,0);
12138 break;
12139 case 'q':
12140 quiet = true;
12141 break;
12142 case 'h':
12143 case '?':
12144 usage(argv[0],versionString);
12145 exit(0);
12146 break;
12147 default:
12148 err("Unknown option \"-{:c}\"\n",argv[optInd][1]);
12149 usage(argv[0],versionString);
12150 exit(1);
12151 }
12152 optInd++;
12153 }
12154
12155 /**************************************************************************
12156 * Parse or generate the config file *
12157 **************************************************************************/
12158
12159 initTracing(traceName.data(),traceTiming);
12160 TRACE("Doxygen version used: {}",getFullVersion());
12161 Config::init();
12162
12163 FileInfo configFileInfo1("Doxyfile"),configFileInfo2("doxyfile");
12164 if (optInd>=argc)
12165 {
12166 if (configFileInfo1.exists())
12167 {
12168 configName="Doxyfile";
12169 }
12170 else if (configFileInfo2.exists())
12171 {
12172 configName="doxyfile";
12173 }
12174 else if (genConfig)
12175 {
12176 configName="Doxyfile";
12177 }
12178 else
12179 {
12180 err("Doxyfile not found and no input file specified!\n");
12181 usage(argv[0],versionString);
12182 exit(1);
12183 }
12184 }
12185 else
12186 {
12187 FileInfo fi(argv[optInd]);
12188 if (fi.exists() || dstrcmp(argv[optInd],"-")==0 || genConfig)
12189 {
12190 configName=argv[optInd];
12191 }
12192 else
12193 {
12194 err("configuration file {} not found!\n",argv[optInd]);
12195 usage(argv[0],versionString);
12196 exit(1);
12197 }
12198 }
12199
12200 if (genConfig)
12201 {
12202 generateConfigFile(configName,shortList);
12204 exit(0);
12205 }
12206
12207 if (!Config::parse(configName,updateConfig,diffList))
12208 {
12209 err("could not open or read configuration file {}!\n",configName);
12211 exit(1);
12212 }
12213
12214 if (diffList!=Config::CompareMode::Full)
12215 {
12217 compareDoxyfile(diffList);
12219 exit(0);
12220 }
12221
12222 if (updateConfig)
12223 {
12225 generateConfigFile(configName,shortList,true);
12227 exit(0);
12228 }
12229
12230 /* Perlmod wants to know the path to the config file.*/
12231 FileInfo configFileInfo(configName.str());
12232 setPerlModDoxyfile(configFileInfo.absFilePath());
12233
12234 /* handle -q option */
12235 if (quiet) Config_updateBool(QUIET,true);
12236}
static bool setFlagStr(const DString &label)
Definition debug.cpp:103
static EmojiEntityMapper & instance()
Returns the one and only instance of the Emoji entity mapper.
Definition emoji.cpp:1981
void writeEmojiFile(TextStream &t)
Writes the list of supported emojis to the given file.
Definition emoji.cpp:2002
bool exists() const
Definition fileinfo.cpp:34
static void writeHeaderFile(TextStream &t, const DString &cssname)
Definition htmlgen.cpp:1629
static void writeFooterFile(TextStream &t)
Definition htmlgen.cpp:1635
static void writeStyleSheetFile(TextStream &t)
Definition htmlgen.cpp:1623
static void writeFooterFile(TextStream &t)
Definition latexgen.cpp:696
static void writeStyleSheetFile(TextStream &t)
Definition latexgen.cpp:702
static void writeHeaderFile(TextStream &t)
Definition latexgen.cpp:690
static void writeStyleSheetFile(TextStream &t)
Definition rtfgen.cpp:397
static void writeExtensionsFile(TextStream &t)
Definition rtfgen.cpp:412
#define Config_updateBool(name, value)
Definition config.h:40
static void compareDoxyfile(Config::CompareMode diffList)
static void devUsage()
static void generateConfigFile(const DString &configFile, bool shortList, bool updateOnly=false)
static void version(const bool extended)
static void usage(const DString &name, const DString &versionString)
static const char * getArg(int argc, char **argv, int &optInd)
int dstricmp(const char *s1, const char *s2)
Definition dstring.cpp:444
int dstrcmp(const char *str1, const char *str2)
Definition dstring.h:50
void writeDefaultLayoutFile(const DString &fileName)
Definition layout.cpp:1746
CompareMode
Definition config.h:54
void init()
bool parse(const DString &fileName, bool update=false, CompareMode compareMode=CompareMode::Full)
void setPerlModDoxyfile(const DString &qs)
void initTracing(const DString &logFile, bool timing)
Definition trace.cpp:25

References FileInfo::absFilePath(), Config::checkAndCorrect(), cleanUpDoxygen(), compareDoxyfile(), Config::Compressed, Config::CompressedNoEnv, Config_getBool, Config_getEnum, Config_updateBool, DString::data(), devUsage(), dstrcmp(), dstricmp(), DString::empty(), err, FileInfo::exists(), Config::Full, g_commentFileName, g_dumpSymbolMap, g_singleComment, generateConfigFile(), getArg(), Config::init(), initTracing(), EmojiEntityMapper::instance(), msg, openOutputFile(), Config::parse(), Config::postProcess(), Debug::setFlagStr(), setPerlModDoxyfile(), setTranslator(), DString::str(), TRACE, Config::updateObsolete(), usage(), version(), writeDefaultLayoutFile(), EmojiEntityMapper::writeEmojiFile(), RTFGenerator::writeExtensionsFile(), HtmlGenerator::writeFooterFile(), LatexGenerator::writeFooterFile(), HtmlGenerator::writeHeaderFile(), LatexGenerator::writeHeaderFile(), HtmlGenerator::writeStyleSheetFile(), LatexGenerator::writeStyleSheetFile(), and RTFGenerator::writeStyleSheetFile().

Referenced by main().

◆ readDir()

void readDir ( FileInfo * fi,
FileNameLinkedMap * fnMap,
StringUnorderedSet * exclSet,
const StringVector * patList,
const StringVector * exclPatList,
StringVector * resultList,
StringUnorderedSet * resultSet,
bool errorIfNotExist,
bool recursive,
StringUnorderedSet * killSet,
StringUnorderedSet * paths )
static

Definition at line 11342 of file doxygen.cpp.

11354{
11355 std::string dirName = fi->absFilePath();
11356 if (paths && !dirName.empty())
11357 {
11358 paths->insert(dirName);
11359 }
11360 //printf("%s isSymLink()=%d\n",qPrint(dirName),fi->isSymLink());
11361 if (fi->isSymLink())
11362 {
11363 dirName = resolveSymlink(dirName);
11364 if (dirName.empty())
11365 {
11366 //printf("RECURSIVE SYMLINK: %s\n",qPrint(dirName));
11367 return; // recursive symlink
11368 }
11369 }
11370
11371 if (g_pathsVisited.find(dirName)!=g_pathsVisited.end())
11372 {
11373 //printf("PATH ALREADY VISITED: %s\n",qPrint(dirName));
11374 return; // already visited path
11375 }
11376 g_pathsVisited.insert(dirName);
11377
11378 Dir dir(dirName);
11379 msg("Searching for files in directory {}\n", fi->absFilePath());
11380 //printf("killSet=%p count=%d\n",killSet,killSet ? (int)killSet->count() : -1);
11381
11382 StringVector dirResultList;
11383
11384 bool caseSenseNames = useCaseSenseNames();
11385
11386 // Process the entries in a fixed order, so that the order in which FileDefs
11387 // are created (which e.g. determines the SHORT_NAMES numbering) and in which
11388 // subdirectories are visited does not depend on the file system.
11389 StringVector entries;
11390 for (const auto &dirEntry : dir.iterator())
11391 {
11392 entries.push_back(dirEntry.path());
11393 }
11394 std::sort(entries.begin(),entries.end());
11395
11396 for (const auto &entryPath : entries)
11397 {
11398 FileInfo cfi(entryPath);
11399 auto checkPatterns = [&]() -> bool
11400 {
11401 return (patList==nullptr || cfi.match(*patList,caseSenseNames)) &&
11402 (exclPatList==nullptr || !cfi.match(*exclPatList,caseSenseNames)) &&
11403 (killSet==nullptr || killSet->find(cfi.absFilePath())==killSet->end());
11404 };
11405
11406 if (exclSet==nullptr || exclSet->find(cfi.absFilePath())==exclSet->end())
11407 { // file should not be excluded
11408 //printf("killSet->find(%s)\n",qPrint(cfi->absFilePath()));
11409 if (Config_getBool(EXCLUDE_SYMLINKS) && cfi.isSymLink())
11410 {
11411 }
11412 else if (!cfi.exists() || !cfi.isReadable())
11413 {
11414 if (errorIfNotExist && checkPatterns())
11415 {
11416 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",cfi.absFilePath());
11417 }
11418 }
11419 else if (cfi.isFile() && checkPatterns())
11420 {
11421 std::string name=cfi.fileName();
11422 std::string path=cfi.dirPath()+"/";
11423 std::string fullName=path+name;
11424 if (fnMap)
11425 {
11426 auto fd = createFileDef(path,name);
11427 FileName *fn=nullptr;
11428 if (!name.empty())
11429 {
11430 fn = fnMap->add(name);
11431 fn->push_back(std::move(fd));
11432 }
11433 }
11434 dirResultList.push_back(fullName);
11435 if (resultSet) resultSet->insert(fullName);
11436 if (killSet) killSet->insert(fullName);
11437 }
11438 else if (recursive &&
11439 cfi.isDir() &&
11440 (exclPatList==nullptr || !cfi.match(*exclPatList,caseSenseNames)) &&
11441 cfi.fileName().at(0)!='.') // skip "." ".." and ".dir"
11442 {
11443 FileInfo acfi(cfi.absFilePath());
11444 readDir(&acfi,fnMap,exclSet,
11445 patList,exclPatList,&dirResultList,resultSet,errorIfNotExist,
11446 recursive,killSet,paths);
11447 }
11448 }
11449 }
11450 if (resultList && !dirResultList.empty())
11451 {
11452 // sort the resulting list to make the order platform independent.
11453 std::stable_sort(dirResultList.begin(),
11454 dirResultList.end(),
11455 [](const auto &f1,const auto &f2) { return dstricmp_sort(f1.c_str(),f2.c_str())<0; });
11456
11457 // append the sorted results to resultList
11458 resultList->insert(resultList->end(), dirResultList.begin(), dirResultList.end());
11459 }
11460}
bool isSymLink() const
Definition fileinfo.cpp:81
Class representing all files with a certain base name.
Definition filename.h:31
static StringUnorderedSet g_pathsVisited(1009)
static std::string resolveSymlink(const std::string &path)
static void readDir(FileInfo *fi, FileNameLinkedMap *fnMap, StringUnorderedSet *exclSet, const StringVector *patList, const StringVector *exclPatList, StringVector *resultList, StringUnorderedSet *resultSet, bool errorIfNotExist, bool recursive, StringUnorderedSet *killSet, StringUnorderedSet *paths)
std::unique_ptr< FileDef > createFileDef(const DString &p, const DString &n, const DString &ref, const DString &dn)
Definition filedef.cpp:269
bool useCaseSenseNames()
Returns true if the names of the symbols can be case sensitive.
Definition util.cpp:2685

References FileInfo::absFilePath(), LinkedMap< T, Hash, KeyEqual, Map >::add(), Config_getBool, createFileDef(), FileInfo::dirPath(), FileInfo::exists(), FileInfo::fileName(), g_pathsVisited(), FileInfo::isDir(), FileInfo::isFile(), FileInfo::isReadable(), FileInfo::isSymLink(), Dir::iterator(), FileInfo::match(), msg, readDir(), resolveSymlink(), useCaseSenseNames(), and warn_uncond.

Referenced by readDir(), and readFileOrDirectory().

◆ readFileOrDirectory()

void readFileOrDirectory ( const DString & s,
FileNameLinkedMap * fnMap,
StringUnorderedSet * exclSet,
const StringVector * patList,
const StringVector * exclPatList,
StringVector * resultList,
StringUnorderedSet * resultSet,
bool recursive,
bool errorIfNotExist,
StringUnorderedSet * killSet,
StringUnorderedSet * paths )

Definition at line 11467 of file doxygen.cpp.

11479{
11480 //printf("killSet count=%d\n",killSet ? (int)killSet->size() : -1);
11481 // strip trailing slashes
11482 if (s.empty()) return;
11483
11484 g_pathsVisited.clear();
11485
11486 FileInfo fi(s.str());
11487 //printf("readFileOrDirectory(%s)\n",s);
11488 {
11489 if (exclSet==nullptr || exclSet->find(fi.absFilePath())==exclSet->end())
11490 {
11491 if (Config_getBool(EXCLUDE_SYMLINKS) && fi.isSymLink())
11492 {
11493 }
11494 else if (!fi.exists() || !fi.isReadable())
11495 {
11496 if (errorIfNotExist)
11497 {
11498 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",s);
11499 }
11500 }
11501 else if (fi.isFile())
11502 {
11503 std::string dirPath = fi.dirPath(true);
11504 std::string filePath = fi.absFilePath();
11505 if (paths && !dirPath.empty())
11506 {
11507 paths->insert(dirPath);
11508 }
11509 //printf("killSet.find(%s)=%d\n",qPrint(fi.absFilePath()),killSet.find(fi.absFilePath())!=killSet.end());
11510 if (killSet==nullptr || killSet->find(filePath)==killSet->end())
11511 {
11512 std::string name=fi.fileName();
11513 if (fnMap)
11514 {
11515 auto fd = createFileDef(dirPath+"/",name);
11516 if (!name.empty())
11517 {
11518 FileName *fn = fnMap->add(name);
11519 fn->push_back(std::move(fd));
11520 }
11521 }
11522 if (resultList || resultSet)
11523 {
11524 if (resultList) resultList->push_back(filePath);
11525 if (resultSet) resultSet->insert(filePath);
11526 }
11527
11528 if (killSet) killSet->insert(fi.absFilePath());
11529 }
11530 }
11531 else if (fi.isDir()) // readable dir
11532 {
11533 readDir(&fi,fnMap,exclSet,patList,
11534 exclPatList,resultList,resultSet,errorIfNotExist,
11535 recursive,killSet,paths);
11536 }
11537 }
11538 }
11539}

References FileInfo::absFilePath(), LinkedMap< T, Hash, KeyEqual, Map >::add(), Config_getBool, createFileDef(), FileInfo::dirPath(), DString::empty(), FileInfo::exists(), FileInfo::fileName(), g_pathsVisited(), FileInfo::isDir(), FileInfo::isFile(), FileInfo::isReadable(), FileInfo::isSymLink(), readDir(), DString::str(), and warn_uncond.

Referenced by searchInputFiles().

◆ readTagFile()

void readTagFile ( const std::shared_ptr< Entry > & root,
const DString & tagLine )
static

Definition at line 10668 of file doxygen.cpp.

10669{
10670 DString fileName;
10671 DString destName;
10672 if (size_t eqPos = tagLine.find('='); eqPos!=DString::npos) // tag command contains a destination
10673 {
10674 fileName = tagLine.left(eqPos).stripWhiteSpace();
10675 destName = tagLine.mid(eqPos+1).stripWhiteSpace();
10676 if (fileName.empty() || destName.empty()) return;
10677 //printf("insert tagDestination %s->%s\n",qPrint(fi.fileName()),qPrint(destName));
10678 }
10679 else
10680 {
10681 fileName = tagLine;
10682 }
10683
10684 FileInfo fi(fileName.str());
10685 if (!fi.exists() || !fi.isFile())
10686 {
10687 err("Tag file '{}' does not exist or is not a file. Skipping it...\n",fileName);
10688 return;
10689 }
10690
10691 if (Doxygen::tagFileSet.find(fi.absFilePath()) != Doxygen::tagFileSet.end()) return;
10692
10693 Doxygen::tagFileSet.emplace(fi.absFilePath());
10694
10695 if (!destName.empty())
10696 {
10697 Doxygen::tagDestinationMap.emplace(fi.absFilePath(), destName.str());
10698 msg("Reading tag file '{}', location '{}'...\n",fileName,destName);
10699 }
10700 else
10701 {
10702 msg("Reading tag file '{}'...\n",fileName);
10703 }
10704
10705 parseTagFile(root,fi.absFilePath().c_str());
10706}
static StringUnorderedSet tagFileSet
Definition doxygen.h:110
void parseTagFile(const std::shared_ptr< Entry > &root, const char *fullName)

References FileInfo::absFilePath(), DString::empty(), err, FileInfo::exists(), DString::find(), FileInfo::isFile(), DString::left(), DString::mid(), msg, DString::npos, parseTagFile(), DString::str(), DString::stripWhiteSpace(), Doxygen::tagDestinationMap, and Doxygen::tagFileSet.

Referenced by parseInput().

◆ resolveClassNestingRelations()

void resolveClassNestingRelations ( )
static

create the scope artificially

Definition at line 1391 of file doxygen.cpp.

1392{
1393 ClassDefSet visitedClasses;
1394
1395 bool done=false;
1396 //int iteration=0;
1397 while (!done)
1398 {
1399 done=true;
1400 //++iteration;
1401 struct ClassAlias
1402 {
1403 ClassAlias(const DString &name,std::unique_ptr<ClassDef> cd,DefinitionMutable *ctx) :
1404 aliasFullName(name),aliasCd(std::move(cd)), aliasContext(ctx) {}
1405 DString aliasFullName;
1406 std::unique_ptr<ClassDef> aliasCd;
1407 DefinitionMutable *aliasContext;
1408 };
1409 std::vector<ClassAlias> aliases;
1410 for (const auto &icd : *Doxygen::classLinkedMap)
1411 {
1412 ClassDefMutable *cd = toClassDefMutable(icd.get());
1413 if (cd && visitedClasses.find(icd.get())==visitedClasses.end())
1414 {
1416 //printf("processing=%s, iteration=%d\n",qPrint(cd->name()),iteration);
1417 // also add class to the correct structural context
1419 name,icd->getFileDef(),nullptr);
1420 if (d)
1421 {
1422 //printf("****** adding %s to scope %s in iteration %d\n",qPrint(cd->name()),qPrint(d->name()),iteration);
1424 if (dm)
1425 {
1426 dm->addInnerCompound(cd);
1427 }
1428 cd->setOuterScope(d);
1429
1430 // for inline namespace add an alias of the class to the outer scope
1432 {
1434 //printf("nd->isInline()=%d\n",nd->isInline());
1435 if (nd && nd->isInline())
1436 {
1437 d = d->getOuterScope();
1438 if (d)
1439 {
1440 dm = toDefinitionMutable(d);
1441 if (dm)
1442 {
1443 auto aliasCd = createClassDefAlias(d,cd);
1444 DString aliasFullName = d->qualifiedName()+"::"+aliasCd->localName();
1445 aliases.emplace_back(aliasFullName,std::move(aliasCd),dm);
1446 //printf("adding %s to %s as %s\n",qPrint(aliasCd->name()),qPrint(d->name()),qPrint(aliasFullName));
1447 }
1448 }
1449 }
1450 else
1451 {
1452 break;
1453 }
1454 }
1455
1456 visitedClasses.insert(icd.get());
1457 done=false;
1458 }
1459 //else
1460 //{
1461 // printf("****** ignoring %s: scope not (yet) found in iteration %d\n",qPrint(cd->name()),iteration);
1462 //}
1463 }
1464 }
1465 // add aliases
1466 for (auto &alias : aliases)
1467 {
1468 ClassDef *aliasCd = Doxygen::classLinkedMap->add(alias.aliasFullName,std::move(alias.aliasCd));
1469 if (aliasCd)
1470 {
1471 alias.aliasContext->addInnerCompound(aliasCd);
1472 }
1473 }
1474 }
1475
1476 //give warnings for unresolved compounds
1477 for (const auto &icd : *Doxygen::classLinkedMap)
1478 {
1479 ClassDefMutable *cd = toClassDefMutable(icd.get());
1480 if (cd && visitedClasses.find(icd.get())==visitedClasses.end())
1481 {
1483 /// create the scope artificially
1484 // anyway, so we can at least relate scopes properly.
1485 Definition *d = buildScopeFromQualifiedName(name,cd->getLanguage(),nullptr);
1486 if (d && d!=cd && !cd->getDefFileName().empty())
1487 // avoid recursion in case of redundant scopes, i.e: namespace N { class N::C {}; }
1488 // for this case doxygen assumes the existence of a namespace N::N in which C is to be found!
1489 // also avoid warning for stuff imported via a tagfile.
1490 {
1492 if (dm)
1493 {
1494 dm->addInnerCompound(cd);
1495 }
1496 cd->setOuterScope(d);
1497 // A specialization can only be written for a template that has been declared before, so a missing
1498 // scope means that declaration is outside the input - e.g. `template<> struct std::hash<MyClass>`.
1499 if (cd->localName().find('<')==DString::npos)
1500 {
1501 warn(cd->getDefFileName(),cd->getDefLine(),
1502 "Incomplete input: scope for class {} not found!{}",name,
1503 name.startsWith("std::") ? " Try enabling BUILTIN_STL_SUPPORT." : ""
1504 );
1505 }
1506 }
1507 }
1508 }
1509}

References LinkedMap< T, Hash, KeyEqual, Map >::add(), DefinitionMutable::addInnerCompound(), buildScopeFromQualifiedName(), Doxygen::classLinkedMap, createClassDefAlias(), Definition::definitionType(), DString::empty(), DString::find(), findScopeFromQualifiedName(), Definition::getDefFileName(), Definition::getDefLine(), Definition::getLanguage(), Definition::getOuterScope(), Doxygen::globalScope, NamespaceDef::isInline(), Definition::localName(), Definition::name(), DString::npos, Definition::qualifiedName(), DefinitionMutable::setOuterScope(), stripAnonymousNamespaceScope(), toClassDefMutable(), toDefinitionMutable(), toNamespaceDef(), Definition::TypeNamespace, and warn.

Referenced by parseInput().

◆ resolveSymlink()

std::string resolveSymlink ( const std::string & path)
static

Definition at line 11270 of file doxygen.cpp.

11271{
11272 size_t sepPos=0;
11273 size_t oldPos=0;
11274 StringUnorderedSet nonSymlinks;
11275 StringUnorderedSet known;
11276 DString result(path);
11277 DString oldPrefix = "/";
11278 do
11279 {
11280#if defined(_WIN32)
11281 // UNC path, skip server and share name
11282 if (sepPos==0 && (result.startsWith("//") || result.startsWith("\\\\")))
11283 sepPos = result.find('/',2);
11284 if (sepPos!=DString::npos)
11285 sepPos = result.find('/',sepPos+1);
11286#else
11287 sepPos = result.find('/',sepPos+1);
11288#endif
11289 DString prefix = sepPos==DString::npos ? result : result.left(sepPos);
11290 if (nonSymlinks.find(prefix.str())==nonSymlinks.end())
11291 {
11292 FileInfo fi(prefix.str());
11293 if (fi.isSymLink())
11294 {
11295 DString target = fi.readLink();
11296 bool isRelative = FileInfo(target.str()).isRelative();
11297 if (isRelative)
11298 {
11299 target = Dir::cleanDirPath(oldPrefix.str()+"/"+target.str());
11300 }
11301 if (sepPos!=DString::npos)
11302 {
11303 if (fi.isDir() && !target.empty() && target.at(target.length()-1)!='/')
11304 {
11305 target+='/';
11306 }
11307 target+=result.mid(sepPos);
11308 }
11309 result = Dir::cleanDirPath(target.str());
11310 if (known.find(result.str())!=known.end()) return std::string(); // recursive symlink!
11311 known.insert(result.str());
11312 if (isRelative)
11313 {
11314 sepPos = oldPos;
11315 }
11316 else // link to absolute path
11317 {
11318 sepPos = 0;
11319 oldPrefix = "/";
11320 }
11321 }
11322 else
11323 {
11324 nonSymlinks.insert(prefix.str());
11325 oldPrefix = prefix;
11326 }
11327 oldPos = sepPos;
11328 }
11329 }
11330 while (sepPos!=DString::npos);
11331 return Dir::cleanDirPath(result.str());
11332}
static std::string cleanDirPath(const std::string &path)
Definition dir.cpp:363
bool isRelative() const
Definition fileinfo.cpp:62

References DString::at(), Dir::cleanDirPath(), DString::empty(), DString::find(), FileInfo::isDir(), FileInfo::isRelative(), FileInfo::isSymLink(), DString::left(), DString::length(), DString::mid(), DString::npos, prefix, FileInfo::readLink(), DString::startsWith(), and DString::str().

Referenced by readDir().

◆ resolveTemplateInstanceInType()

void resolveTemplateInstanceInType ( const Entry * root,
const Definition * scope,
const MemberDef * md )
static

Definition at line 5084 of file doxygen.cpp.

5085{
5086 // For a statement like 'using X = T<A>', add a template instance 'T<A>' as a symbol, so it can
5087 // be used to match arguments (see issue #11111)
5088 AUTO_TRACE();
5089 DString ttype = md->typeString();
5090 ttype.stripPrefix("typedef ");
5091 if (size_t ti=ttype.find('<'); ti!=DString::npos)
5092 {
5093 DString templateClassName = ttype.left(ti);
5094 SymbolResolver resolver(root->fileDef());
5095 ClassDefMutable *baseClass = resolver.resolveClassMutable(scope ? scope : Doxygen::globalScope,
5096 templateClassName, true, true);
5097 AUTO_TRACE_ADD("templateClassName={} baseClass={}",templateClassName,baseClass?baseClass->name():"<none>");
5098 if (baseClass)
5099 {
5100 const ArgumentList &tl = baseClass->templateArguments();
5101 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,templateClassName.str());
5103 baseClass,
5104 ttype.mid(ti),
5105 templateNames,
5106 baseClass->isArtificial());
5107 }
5108 }
5109}

References AUTO_TRACE, AUTO_TRACE_ADD, Entry::fileDef(), DString::find(), findTemplateInstanceRelation(), Definition::getOuterScope(), getTemplateArgumentsInName(), Doxygen::globalScope, Definition::isArtificial(), DString::left(), DString::mid(), Definition::name(), DString::npos, SymbolResolver::resolveClassMutable(), DString::str(), DString::stripPrefix(), ClassDef::templateArguments(), and MemberDef::typeString().

Referenced by addVariableToClass(), and addVariableToFile().

◆ resolveUserReferences()

void resolveUserReferences ( )
static

Definition at line 10167 of file doxygen.cpp.

10168{
10169 for (const auto &si : SectionManager::instance())
10170 {
10171 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
10172 // qPrint(si->label),si->definition?qPrint(si->definition->name()):"<none>",
10173 // qPrint(si->fileName));
10174 PageDef *pd=nullptr;
10175
10176 // hack: the items of a todo/test/bug/deprecated list are all fragments from
10177 // different files, so the resulting section's all have the wrong file
10178 // name (not from the todo/test/bug/deprecated list, but from the file in
10179 // which they are defined). We correct this here by looking at the
10180 // generated section labels!
10182 {
10183 DString label="_"+rl->listName(); // "_todo", "_test", ...
10184 if (si->label().left(label.length())==label)
10185 {
10186 si->setFileName(rl->listName());
10187 si->setGenerated(true);
10188 break;
10189 }
10190 }
10191
10192 //printf("start: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
10193 if (!si->generated())
10194 {
10195 // if this section is in a page and the page is in a group, then we
10196 // have to adjust the link file name to point to the group.
10197 if (!si->fileName().empty() &&
10198 (pd=Doxygen::pageLinkedMap->find(si->fileName())) &&
10199 pd->getGroupDef())
10200 {
10201 si->setFileName(pd->getGroupDef()->getOutputFileBase());
10202 }
10203
10204 if (si->definition())
10205 {
10206 // TODO: there should be one function in Definition that returns
10207 // the file to link to, so we can avoid the following tests.
10208 const GroupDef *gd=nullptr;
10209 if (si->definition()->definitionType()==Definition::TypeMember)
10210 {
10211 gd = (toMemberDef(si->definition()))->getGroupDef();
10212 }
10213
10214 if (gd)
10215 {
10216 si->setFileName(gd->getOutputFileBase());
10217 }
10218 else
10219 {
10220 //si->fileName=si->definition->getOutputFileBase();
10221 //printf("Setting si->fileName to %s\n",qPrint(si->fileName));
10222 }
10223 }
10224 }
10225 //printf("end: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
10226 }
10227}
virtual const GroupDef * getGroupDef() const =0

References LinkedMap< T, Hash, KeyEqual, Map >::find(), PageDef::getGroupDef(), Definition::getOutputFileBase(), RefListManager::instance(), SectionManager::instance(), DString::length(), Doxygen::pageLinkedMap, toMemberDef(), and Definition::TypeMember.

Referenced by parseInput().

◆ runHtmlHelpCompiler()

void runHtmlHelpCompiler ( )
static

Definition at line 10491 of file doxygen.cpp.

10492{
10493 std::string oldDir = Dir::currentDirPath();
10494 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10497 {
10498 err("failed to run html help compiler on {}\n", HtmlHelp::hhpFileName);
10499 }
10500 Dir::setCurrent(oldDir);
10501}
@ ExtCmd
Definition debug.h:37
static bool setCurrent(const std::string &path)
Definition dir.cpp:356
static const DString hhpFileName
Definition htmlhelp.h:90
int system(const DString &command, const DString &args, bool commandHasConsole=true)
Definition portable.cpp:121
void setShortDir()
Definition portable.cpp:569

References Config_getString, Dir::currentDirPath(), err, Debug::ExtCmd, HtmlHelp::hhpFileName, Debug::isFlagSet(), qPrint(), Dir::setCurrent(), Portable::setShortDir(), and Portable::system().

Referenced by generateOutput().

◆ runQHelpGenerator()

void runQHelpGenerator ( )
static

Definition at line 10503 of file doxygen.cpp.

10504{
10505 DString args = Qhp::qhpFileName + " -o \"" + Qhp::getQchFileName() + "\"";
10506 std::string oldDir = Dir::currentDirPath();
10507 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10508
10509 DString qhgLocation=Config_getString(QHG_LOCATION);
10510 if (Debug::isFlagSet(Debug::Qhp)) // produce info for debugging
10511 {
10512 // run qhelpgenerator -v and extract the Qt version used
10513 DString cmd=qhgLocation+ " -v 2>&1";
10514 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10515 FILE *f=Portable::popen(cmd,"r");
10516 if (!f)
10517 {
10518 err("could not execute {}\n",qhgLocation);
10519 }
10520 else
10521 {
10522 const size_t bufSize = 1024;
10523 char inBuf[bufSize+1];
10524 size_t numRead=fread(inBuf,1,bufSize,f);
10525 inBuf[numRead] = '\0';
10526 Debug::print(Debug::Qhp,0,"{}",inBuf);
10528
10529 int qtVersion=0;
10530 static const reg::Ex versionReg(R"(Qt (\d+)\.(\d+)\.(\d+))");
10532 std::string s = inBuf;
10533 if (reg::search(s,match,versionReg))
10534 {
10535 qtVersion = 10000*DString(match[1].str()).toInt() +
10536 100*DString(match[2].str()).toInt() +
10537 DString(match[3].str()).toInt();
10538 }
10539 if (qtVersion>0 && (qtVersion<60000 || qtVersion >= 60205))
10540 {
10541 // dump the output of qhelpgenerator -c file.qhp
10542 // Qt<6 or Qt>=6.2.5 or higher, see https://bugreports.qt.io/browse/QTBUG-101070
10543 cmd=qhgLocation+ " -c " + Qhp::qhpFileName + " 2>&1";
10544 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10545 f=Portable::popen(cmd,"r");
10546 if (!f)
10547 {
10548 err("could not execute {}\n",qhgLocation);
10549 }
10550 else
10551 {
10552 std::string output;
10553 while ((numRead=fread(inBuf,1,bufSize,f))>0)
10554 {
10555 inBuf[numRead] = '\0';
10556 output += inBuf;
10557 }
10559 Debug::print(Debug::Qhp,0,"{}",output);
10560 }
10561 }
10562 }
10563 }
10564
10565 if (Portable::system(qhgLocation, args, false))
10566 {
10567 err("failed to run qhelpgenerator on {}\n",Qhp::qhpFileName);
10568 }
10569 Dir::setCurrent(oldDir);
10570}
int toInt(bool *ok=nullptr, int base=10) const
Definition dstring.cpp:191
@ Qhp
Definition debug.h:45
static DString getQchFileName()
Definition qhp.cpp:430
static const DString qhpFileName
Definition qhp.h:49
FILE * popen(const DString &name, const DString &type)
Definition portable.cpp:495
int pclose(FILE *stream)
Definition portable.cpp:504

References Config_getString, Dir::currentDirPath(), err, Debug::ExtCmd, Qhp::getQchFileName(), Debug::isFlagSet(), Portable::pclose(), Portable::popen(), Debug::print(), Debug::Qhp, Qhp::qhpFileName, reg::search(), Dir::setCurrent(), Portable::system(), and DString::toInt().

Referenced by generateOutput().

◆ scopeIsTemplate()

bool scopeIsTemplate ( const Definition * d)
static

Definition at line 6255 of file doxygen.cpp.

6256{
6257 bool result=false;
6258 //printf("> scopeIsTemplate(%s)\n",qPrint(d?d->name():"null"));
6260 {
6261 auto cd = toClassDef(d);
6262 result = cd->templateArguments().hasParameters() || cd->templateMaster()!=nullptr ||
6264 }
6265 //printf("< scopeIsTemplate=%d\n",result);
6266 return result;
6267}

References Definition::definitionType(), Definition::getOuterScope(), scopeIsTemplate(), toClassDef(), and Definition::TypeClass.

Referenced by addMemberFunction(), and scopeIsTemplate().

◆ searchInputFiles()

void searchInputFiles ( )

Definition at line 12509 of file doxygen.cpp.

12510{
12511 StringUnorderedSet killSet;
12512
12513 StringVector exclPatterns = Config_getList(EXCLUDE_PATTERNS);
12514 bool alwaysRecursive = Config_getBool(RECURSIVE);
12515 StringUnorderedSet excludeNameSet;
12516
12517 // gather names of all files in the include path
12518 g_s.begin("Searching for include files...\n");
12519 killSet.clear();
12520 StringVector includePathList = Config_getList(INCLUDE_PATH);
12521 for (const auto &s : includePathList)
12522 {
12523 size_t plSize = Config_getList(INCLUDE_FILE_PATTERNS).size();
12524 StringVector pl = plSize==0 ? Config_getList(FILE_PATTERNS) :
12525 Config_getList(INCLUDE_FILE_PATTERNS);
12526 readFileOrDirectory(s, // s
12528 nullptr, // exclSet
12529 &pl, // patList
12530 &exclPatterns, // exclPatList
12531 nullptr, // resultList
12532 nullptr, // resultSet
12533 false, // INCLUDE_PATH isn't recursive
12534 true, // errorIfNotExist
12535 &killSet); // killSet
12536 }
12537 g_s.end();
12538
12539 g_s.begin("Searching for example files...\n");
12540 killSet.clear();
12541 StringVector examplePathList = Config_getList(EXAMPLE_PATH);
12542 for (const auto &s : examplePathList)
12543 {
12544 StringVector patterns = Config_getList(EXAMPLE_PATTERNS);
12545 readFileOrDirectory(s, // s
12547 nullptr, // exclSet
12548 &patterns, // patList
12549 nullptr, // exclPatList
12550 nullptr, // resultList
12551 nullptr, // resultSet
12552 (alwaysRecursive || Config_getBool(EXAMPLE_RECURSIVE)), // recursive
12553 true, // errorIfNotExist
12554 &killSet); // killSet
12555 }
12556 g_s.end();
12557
12558 g_s.begin("Searching for images...\n");
12559 killSet.clear();
12560 StringVector imagePathList=Config_getList(IMAGE_PATH);
12561 for (const auto &s : imagePathList)
12562 {
12563 readFileOrDirectory(s, // s
12565 nullptr, // exclSet
12566 nullptr, // patList
12567 nullptr, // exclPatList
12568 nullptr, // resultList
12569 nullptr, // resultSet
12570 alwaysRecursive, // recursive
12571 true, // errorIfNotExist
12572 &killSet); // killSet
12573 }
12574 g_s.end();
12575
12576 g_s.begin("Searching for dot files...\n");
12577 killSet.clear();
12578 StringVector dotFileList=Config_getList(DOTFILE_DIRS);
12579 for (const auto &s : dotFileList)
12580 {
12581 readFileOrDirectory(s, // s
12583 nullptr, // exclSet
12584 nullptr, // patList
12585 nullptr, // exclPatList
12586 nullptr, // resultList
12587 nullptr, // resultSet
12588 alwaysRecursive, // recursive
12589 true, // errorIfNotExist
12590 &killSet); // killSet
12591 }
12592 g_s.end();
12593
12594 g_s.begin("Searching for msc files...\n");
12595 killSet.clear();
12596 StringVector mscFileList=Config_getList(MSCFILE_DIRS);
12597 for (const auto &s : mscFileList)
12598 {
12599 readFileOrDirectory(s, // s
12601 nullptr, // exclSet
12602 nullptr, // patList
12603 nullptr, // exclPatList
12604 nullptr, // resultList
12605 nullptr, // resultSet
12606 alwaysRecursive, // recursive
12607 true, // errorIfNotExist
12608 &killSet); // killSet
12609 }
12610 g_s.end();
12611
12612 g_s.begin("Searching for dia files...\n");
12613 killSet.clear();
12614 StringVector diaFileList=Config_getList(DIAFILE_DIRS);
12615 for (const auto &s : diaFileList)
12616 {
12617 readFileOrDirectory(s, // s
12619 nullptr, // exclSet
12620 nullptr, // patList
12621 nullptr, // exclPatList
12622 nullptr, // resultList
12623 nullptr, // resultSet
12624 alwaysRecursive, // recursive
12625 true, // errorIfNotExist
12626 &killSet); // killSet
12627 }
12628 g_s.end();
12629
12630 g_s.begin("Searching for plantuml files...\n");
12631 killSet.clear();
12632 StringVector plantUmlFileList=Config_getList(PLANTUMLFILE_DIRS);
12633 for (const auto &s : plantUmlFileList)
12634 {
12635 readFileOrDirectory(s, // s
12637 nullptr, // exclSet
12638 nullptr, // patList
12639 nullptr, // exclPatList
12640 nullptr, // resultList
12641 nullptr, // resultSet
12642 alwaysRecursive, // recursive
12643 true, // errorIfNotExist
12644 &killSet); // killSet
12645 }
12646 g_s.end();
12647
12648 g_s.begin("Searching for mermaid files...\n");
12649 killSet.clear();
12650 StringVector mermaidFileList=Config_getList(MERMAIDFILE_DIRS);
12651 for (const auto &s : mermaidFileList)
12652 {
12653 readFileOrDirectory(s, // s
12655 nullptr, // exclSet
12656 nullptr, // patList
12657 nullptr, // exclPatList
12658 nullptr, // resultList
12659 nullptr, // resultSet
12660 alwaysRecursive, // recursive
12661 true, // errorIfNotExist
12662 &killSet); // killSet
12663 }
12664 g_s.end();
12665
12666 g_s.begin("Searching for files to exclude\n");
12667 StringVector excludeList = Config_getList(EXCLUDE);
12668 for (const auto &s : excludeList)
12669 {
12670 StringVector filePatterns = Config_getList(FILE_PATTERNS);
12671 readFileOrDirectory(s, // s
12672 nullptr, // fnDict
12673 nullptr, // exclSet
12674 &filePatterns, // patList
12675 nullptr, // exclPatList
12676 nullptr, // resultList
12677 &excludeNameSet, // resultSet
12678 alwaysRecursive, // recursive
12679 false); // errorIfNotExist
12680 }
12681 g_s.end();
12682
12683 /**************************************************************************
12684 * Determine Input Files *
12685 **************************************************************************/
12686
12687 g_s.begin("Searching INPUT for files to process...\n");
12688 killSet.clear();
12689 Doxygen::inputPaths.clear();
12690 StringVector inputList=Config_getList(INPUT);
12691 for (const auto &s : inputList)
12692 {
12693 DString path = s;
12694 size_t l = path.length();
12695 if (l>0)
12696 {
12697 // strip trailing slashes
12698 if (path.at(l-1)=='\\' || path.at(l-1)=='/') path=path.left(l-1);
12699
12700 StringVector filePatterns = Config_getList(FILE_PATTERNS);
12702 path, // s
12704 &excludeNameSet, // exclSet
12705 &filePatterns, // patList
12706 &exclPatterns, // exclPatList
12707 &g_inputFiles, // resultList
12708 nullptr, // resultSet
12709 alwaysRecursive, // recursive
12710 true, // errorIfNotExist
12711 &killSet, // killSet
12712 &Doxygen::inputPaths); // paths
12713 }
12714 }
12715
12716 // Sort the FileDef objects by full path to get a predictable ordering over multiple runs
12717 for (auto &fileName : *Doxygen::inputNameLinkedMap)
12718 {
12719 if (fileName->size()>1)
12720 {
12721 std::stable_sort(fileName->begin(),fileName->end(),[](const auto &f1,const auto &f2)
12722 {
12723 return dstricmp_sort(f1->absFilePath(),f2->absFilePath())<0;
12724 });
12725 }
12726 }
12727 std::stable_sort(Doxygen::inputNameLinkedMap->begin(),
12729 [](const auto &f1,const auto &f2)
12730 {
12731 return dstricmp_sort(f1->front()->absFilePath(),f2->front()->absFilePath())<0;
12732 });
12733 if (Doxygen::inputNameLinkedMap->empty())
12734 {
12735 warn_uncond("No files to be processed, please check your settings, in particular INPUT, FILE_PATTERNS, and RECURSIVE\n");
12736 }
12737 g_s.end();
12738}
static StringUnorderedSet inputPaths
Definition doxygen.h:96
void readFileOrDirectory(const DString &s, FileNameLinkedMap *fnMap, StringUnorderedSet *exclSet, const StringVector *patList, const StringVector *exclPatList, StringVector *resultList, StringUnorderedSet *resultSet, bool recursive, bool errorIfNotExist, StringUnorderedSet *killSet, StringUnorderedSet *paths)

References DString::at(), begin(), Statistics::begin(), Config_getBool, Config_getList, Doxygen::diaFileNameLinkedMap, Doxygen::dotFileNameLinkedMap, dstricmp_sort(), end(), Statistics::end(), Doxygen::exampleNameLinkedMap, g_inputFiles, g_s, Doxygen::imageNameLinkedMap, Doxygen::includeNameLinkedMap, Doxygen::inputNameLinkedMap, Doxygen::inputPaths, DString::left(), DString::length(), Doxygen::mermaidFileNameLinkedMap, Doxygen::mscFileNameLinkedMap, Doxygen::plantUmlFileNameLinkedMap, readFileOrDirectory(), and warn_uncond.

Referenced by parseInput().

◆ setAnonymousEnumType()

void setAnonymousEnumType ( )
static

Definition at line 9341 of file doxygen.cpp.

9342{
9343 for (const auto &cd : *Doxygen::classLinkedMap)
9344 {
9345 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9346 if (cdm)
9347 {
9348 cdm->setAnonymousEnumType();
9349 }
9350 }
9351}
virtual void setAnonymousEnumType()=0

References Doxygen::classLinkedMap, ClassDefMutable::setAnonymousEnumType(), and toClassDefMutable().

Referenced by parseInput().

◆ sortMemberLists()

void sortMemberLists ( )
static

Definition at line 9246 of file doxygen.cpp.

9247{
9248 // sort class member lists
9249 for (const auto &cd : *Doxygen::classLinkedMap)
9250 {
9251 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9252 if (cdm)
9253 {
9254 cdm->sortMemberLists();
9255 }
9256 }
9257
9258 // sort namespace member lists
9259 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9260 {
9262 if (ndm)
9263 {
9264 ndm->sortMemberLists();
9265 }
9266 }
9267
9268 // sort file member lists
9269 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9270 {
9271 for (const auto &fd : *fn)
9272 {
9273 fd->sortMemberLists();
9274 }
9275 }
9276
9277 // sort group member lists
9278 for (const auto &gd : *Doxygen::groupLinkedMap)
9279 {
9280 gd->sortMemberLists();
9281 }
9282
9284}
virtual void sortMemberLists()=0
void sortMemberLists()
virtual void sortMemberLists()=0

References Doxygen::classLinkedMap, Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), Doxygen::namespaceLinkedMap, ClassDefMutable::sortMemberLists(), ModuleManager::sortMemberLists(), NamespaceDefMutable::sortMemberLists(), toClassDefMutable(), and toNamespaceDefMutable().

Referenced by parseInput().

◆ stopDoxygen()

void stopDoxygen ( int )
static

Definition at line 12376 of file doxygen.cpp.

12377{
12378 signal(SIGINT,SIG_DFL); // Re-register signal handler for default action
12379 Dir thisDir;
12380 msg("Cleaning up...\n");
12381 if (!Doxygen::filterDBFileName.empty())
12382 {
12383 thisDir.remove(Doxygen::filterDBFileName.str());
12384 }
12385 killpg(0,SIGINT);
12387 exitTracing();
12388 exit(1);
12389}

References cleanUpDoxygen(), exitTracing(), Doxygen::filterDBFileName, msg, and Dir::remove().

Referenced by parseInput().

◆ stripTemplateSpecifiers()

DString stripTemplateSpecifiers ( const DString & s)

Definition at line 697 of file doxygen.cpp.

698{
699 size_t l = s.length();
700 int count=0;
701 int round=0;
702 DString result;
703 for (size_t i=0;i<l;i++)
704 {
705 char c=s.at(i);
706 if (c=='(') round++;
707 else if (c==')' && round>0) round--;
708 else if (c=='<' && round==0) count++;
709 if (count==0)
710 {
711 result+=c;
712 }
713 if (c=='>' && round==0 && count>0) count--;
714 }
715 //printf("stripTemplateSpecifiers(%s)=%s\n",qPrint(s),qPrint(result));
716 return result;
717}

References DString::at(), and DString::length().

Referenced by buildScopeFromQualifiedName().

◆ substituteTemplatesInArgList()

void substituteTemplatesInArgList ( const ArgumentLists & srcTempArgLists,
const ArgumentLists & dstTempArgLists,
const ArgumentList & src,
ArgumentList & dst )
static

Definition at line 6353 of file doxygen.cpp.

6359{
6360 auto dstIt = dst.begin();
6361 for (const Argument &sa : src)
6362 {
6363 DString dstType = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.type.str());
6364 DString dstArray = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.array.str());
6365 if (dstIt == dst.end())
6366 {
6367 Argument da = sa;
6368 da.type = dstType;
6369 da.array = dstArray;
6370 dst.push_back(da);
6371 dstIt = dst.end();
6372 }
6373 else
6374 {
6375 Argument da = *dstIt;
6376 da.type = dstType;
6377 da.array = dstArray;
6378 ++dstIt;
6379 }
6380 }
6381 dst.setConstSpecifier(src.constSpecifier());
6382 dst.setVolatileSpecifier(src.volatileSpecifier());
6383 dst.setPureSpecifier(src.pureSpecifier());
6385 srcTempArgLists,dstTempArgLists,
6386 src.trailingReturnType().str()));
6387 dst.setIsDeleted(src.isDeleted());
6388 dst.setRefQualifier(src.refQualifier());
6389 dst.setNoParameters(src.noParameters());
6390 //printf("substituteTemplatesInArgList: replacing %s with %s\n",
6391 // qPrint(argListToString(src)),qPrint(argListToString(dst))
6392 // );
6393}
DString array
Definition arguments.h:46
iterator end()
Definition arguments.h:95
void setPureSpecifier(bool b)
Definition arguments.h:122
void push_back(const Argument &a)
Definition arguments.h:103
void setConstSpecifier(bool b)
Definition arguments.h:120
void setRefQualifier(RefQualifierType t)
Definition arguments.h:127
void setIsDeleted(bool b)
Definition arguments.h:126
iterator begin()
Definition arguments.h:94
void setNoParameters(bool b)
Definition arguments.h:128
void setVolatileSpecifier(bool b)
Definition arguments.h:121
static DString substituteTemplatesInString(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const std::string &src)
Definition doxygen.cpp:6269

References Argument::array, ArgumentList::begin(), ArgumentList::constSpecifier(), ArgumentList::end(), ArgumentList::isDeleted(), ArgumentList::noParameters(), ArgumentList::pureSpecifier(), ArgumentList::push_back(), ArgumentList::refQualifier(), ArgumentList::setConstSpecifier(), ArgumentList::setIsDeleted(), ArgumentList::setNoParameters(), ArgumentList::setPureSpecifier(), ArgumentList::setRefQualifier(), ArgumentList::setTrailingReturnType(), ArgumentList::setVolatileSpecifier(), DString::str(), substituteTemplatesInString(), ArgumentList::trailingReturnType(), Argument::type, and ArgumentList::volatileSpecifier().

Referenced by addMemberFunction().

◆ substituteTemplatesInString()

DString substituteTemplatesInString ( const ArgumentLists & srcTempArgLists,
const ArgumentLists & dstTempArgLists,
const std::string & src )
static

Definition at line 6269 of file doxygen.cpp.

6274{
6275 std::string dst;
6276 static const reg::Ex re(R"(\a\w*)");
6277 reg::Iterator it(src,re);
6279 //printf("type=%s\n",qPrint(sa->type));
6280 size_t p=0;
6281 for (; it!=end ; ++it) // for each word in srcType
6282 {
6283 const auto &match = *it;
6284 size_t i = match.position();
6285 size_t l = match.length();
6286 bool found=false;
6287 dst+=src.substr(p,i-p);
6288 std::string name=match.str();
6289
6290 auto srcIt = srcTempArgLists.begin();
6291 auto dstIt = dstTempArgLists.begin();
6292 while (srcIt!=srcTempArgLists.end() && !found)
6293 {
6294 const ArgumentList *tdAli = nullptr;
6295 std::vector<Argument>::const_iterator tdaIt;
6296 if (dstIt!=dstTempArgLists.end())
6297 {
6298 tdAli = &(*dstIt);
6299 tdaIt = tdAli->begin();
6300 ++dstIt;
6301 }
6302
6303 const ArgumentList &tsaLi = *srcIt;
6304 for (auto tsaIt = tsaLi.begin(); tsaIt!=tsaLi.end() && !found; ++tsaIt)
6305 {
6306 Argument tsa = *tsaIt;
6307 const Argument *tda = nullptr;
6308 if (tdAli && tdaIt!=tdAli->end())
6309 {
6310 tda = &(*tdaIt);
6311 ++tdaIt;
6312 }
6313 //if (tda) printf("tsa=%s|%s tda=%s|%s\n",
6314 // qPrint(tsa.type),qPrint(tsa.name),
6315 // qPrint(tda->type),qPrint(tda->name));
6316 if (name==tsa.name.str())
6317 {
6318 if (tda && tda->name.empty())
6319 {
6320 DString tdaName = tda->name;
6321 DString tdaType = tda->type;
6322 int vc=0;
6323 if (tdaType.startsWith("class ")) vc=6;
6324 else if (tdaType.startsWith("typename ")) vc=9;
6325 if (vc>0) // convert type=="class T" to type=="class" name=="T"
6326 {
6327 tdaName = tdaType.mid(vc);
6328 }
6329 if (!tdaName.empty())
6330 {
6331 name=tdaName.str(); // substitute
6332 found=true;
6333 }
6334 }
6335 }
6336 }
6337
6338 //printf(" srcList='%s' dstList='%s faList='%s'\n",
6339 // qPrint(argListToString(srclali.current())),
6340 // qPrint(argListToString(dstlali.current())),
6341 // funcTempArgList ? qPrint(argListToString(funcTempArgList)) : "<none>");
6342 ++srcIt;
6343 }
6344 dst+=name;
6345 p=i+l;
6346 }
6347 dst+=src.substr(p);
6348 //printf(" substituteTemplatesInString(%s)=%s\n",
6349 // qPrint(src),qPrint(dst));
6350 return dst;
6351}

References ArgumentList::begin(), DString::empty(), ArgumentList::end(), end(), DString::mid(), Argument::name, DString::startsWith(), DString::str(), and Argument::type.

Referenced by substituteTemplatesInArgList().

◆ transferFunctionDocumentation()

void transferFunctionDocumentation ( )
static

Definition at line 4596 of file doxygen.cpp.

4597{
4598 AUTO_TRACE();
4599
4600 // find matching function declaration and definitions.
4601 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4602 {
4603 //printf("memberName=%s count=%zu\n",qPrint(mn->memberName()),mn->size());
4604 /* find a matching function declaration and definition for this function */
4605 for (const auto &imdec : *mn)
4606 {
4607 MemberDefMutable *mdec = toMemberDefMutable(imdec.get());
4608 if (mdec &&
4609 (mdec->isPrototype() ||
4610 (mdec->isVariable() && mdec->isExternal())
4611 ))
4612 {
4613 for (const auto &imdef : *mn)
4614 {
4615 MemberDefMutable *mdef = toMemberDefMutable(imdef.get());
4616 if (mdef && mdec!=mdef &&
4617 mdec->getNamespaceDef()==mdef->getNamespaceDef())
4618 {
4620 }
4621 }
4622 }
4623 }
4624 }
4625}
void combineDeclarationAndDefinition(MemberDefMutable *mdec, MemberDefMutable *mdef)

References AUTO_TRACE, combineDeclarationAndDefinition(), Doxygen::functionNameLinkedMap, MemberDef::getNamespaceDef(), MemberDef::isExternal(), MemberDef::isPrototype(), MemberDef::isVariable(), and toMemberDefMutable().

Referenced by parseInput().

◆ transferFunctionReferences()

void transferFunctionReferences ( )
static

Definition at line 4629 of file doxygen.cpp.

4630{
4631 AUTO_TRACE();
4632 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4633 {
4634 MemberDefMutable *mdef=nullptr,*mdec=nullptr;
4635 /* find a matching function declaration and definition for this function */
4636 for (const auto &imd : *mn)
4637 {
4638 MemberDefMutable *md = toMemberDefMutable(imd.get());
4639 if (md)
4640 {
4641 if (md->isPrototype())
4642 mdec=md;
4643 else if (md->isVariable() && md->isExternal())
4644 mdec=md;
4645
4646 if (md->isFunction() && !md->isStatic() && !md->isPrototype())
4647 mdef=md;
4648 else if (md->isVariable() && !md->isExternal() && !md->isStatic())
4649 mdef=md;
4650 }
4651
4652 if (mdef && mdec) break;
4653 }
4654 if (mdef && mdec)
4655 {
4656 const ArgumentList &mdefAl = mdef->argumentList();
4657 const ArgumentList &mdecAl = mdec->argumentList();
4658 if (
4659 matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdef->typeString(),const_cast<ArgumentList*>(&mdefAl),
4660 mdec->getOuterScope(),mdec->getFileDef(),mdec->typeString(),const_cast<ArgumentList*>(&mdecAl),
4661 true,mdef->getLanguage()
4662 )
4663 ) /* match found */
4664 {
4665 AUTO_TRACE_ADD("merging references for mdec={} mdef={}",mdec->name(),mdef->name());
4666 mdef->mergeReferences(mdec);
4667 mdec->mergeReferences(mdef);
4668 mdef->mergeReferencedBy(mdec);
4669 mdec->mergeReferencedBy(mdef);
4670 }
4671 }
4672 }
4673}
virtual void mergeReferencedBy(const Definition *other)=0
virtual void mergeReferences(const Definition *other)=0

References MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, Doxygen::functionNameLinkedMap, MemberDef::getFileDef(), Definition::getLanguage(), Definition::getOuterScope(), MemberDef::isExternal(), MemberDef::isFunction(), MemberDef::isPrototype(), MemberDef::isStatic(), MemberDef::isVariable(), matchArguments2(), DefinitionMutable::mergeReferencedBy(), DefinitionMutable::mergeReferences(), Definition::name(), toMemberDefMutable(), and MemberDef::typeString().

Referenced by parseInput().

◆ transferRelatedFunctionDocumentation()

void transferRelatedFunctionDocumentation ( )
static

Definition at line 4677 of file doxygen.cpp.

4678{
4679 AUTO_TRACE();
4680 // find match between function declaration and definition for
4681 // related functions
4682 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4683 {
4684 /* find a matching function declaration and definition for this function */
4685 // for each global function
4686 for (const auto &imd : *mn)
4687 {
4688 MemberDefMutable *md = toMemberDefMutable(imd.get());
4689 if (md)
4690 {
4691 //printf(" Function '%s'\n",qPrint(md->name()));
4693 if (rmn) // check if there is a member with the same name
4694 {
4695 //printf(" Member name found\n");
4696 // for each member with the same name
4697 for (const auto &irmd : *rmn)
4698 {
4699 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
4700 //printf(" Member found: related='%d'\n",rmd->isRelated());
4701 if (rmd &&
4702 (rmd->isRelated() || rmd->isForeign()) && // related function
4703 matchArguments2( md->getOuterScope(), md->getFileDef(), md->typeString(), &md->argumentList(),
4704 rmd->getOuterScope(),rmd->getFileDef(),rmd->typeString(),&rmd->argumentList(),
4705 true,md->getLanguage()
4706 )
4707 )
4708 {
4709 AUTO_TRACE_ADD("Found related member '{}'",md->name());
4710 if (rmd->relatedAlso())
4711 md->setRelatedAlso(rmd->relatedAlso());
4712 else if (rmd->isForeign())
4713 md->makeForeign();
4714 else
4715 md->makeRelated();
4716 }
4717 }
4718 }
4719 }
4720 }
4721 }
4722}
virtual bool isForeign() const =0
virtual ClassDef * relatedAlso() const =0
virtual void setRelatedAlso(ClassDef *cd)=0
virtual void makeForeign()=0

References MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, LinkedMap< T, Hash, KeyEqual, Map >::find(), Doxygen::functionNameLinkedMap, MemberDef::getFileDef(), Definition::getLanguage(), Definition::getOuterScope(), MemberDef::isForeign(), MemberDef::isRelated(), MemberDefMutable::makeForeign(), MemberDefMutable::makeRelated(), matchArguments2(), Doxygen::memberNameLinkedMap, Definition::name(), MemberDef::relatedAlso(), MemberDefMutable::setRelatedAlso(), toMemberDefMutable(), and MemberDef::typeString().

Referenced by parseInput().

◆ transferStaticInstanceInitializers()

void transferStaticInstanceInitializers ( )

Definition at line 4726 of file doxygen.cpp.

4727{
4728 AUTO_TRACE();
4729 for (const auto &[qualifiedName,bodyInfo] : Doxygen::staticInitMap)
4730 {
4731 size_t i=qualifiedName.rfind("::");
4732 if (i!=std::string::npos)
4733 {
4734 DString scope = qualifiedName.substr(0,i);
4735 DString name = qualifiedName.substr(i+2);
4737 if (mn)
4738 {
4739 for (const auto &imd : *mn)
4740 {
4741 MemberDefMutable *md = toMemberDefMutable(imd.get());
4742 if (md && md->qualifiedName().str()==qualifiedName && md->isVariable())
4743 {
4744 AUTO_TRACE_ADD("found static member {} body [{}..{}]\n",
4745 md->qualifiedName(),bodyInfo.startLine,bodyInfo.endLine);
4746 md->setBodySegment(bodyInfo.defLine,
4747 bodyInfo.startLine,
4748 bodyInfo.endLine);
4749 }
4750 }
4751 }
4752 }
4753 }
4754}

References AUTO_TRACE, AUTO_TRACE_ADD, LinkedMap< T, Hash, KeyEqual, Map >::find(), MemberDef::isVariable(), Doxygen::memberNameLinkedMap, Definition::qualifiedName(), DefinitionMutable::setBodySegment(), Doxygen::staticInitMap, DString::str(), DString::substr(), and toMemberDefMutable().

Referenced by parseInput().

◆ tryAddEnumDocsToGroupMember()

bool tryAddEnumDocsToGroupMember ( const Entry * root,
const DString & name )
static

Definition at line 8293 of file doxygen.cpp.

8294{
8295 for (const auto &g : root->groups)
8296 {
8297 const GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
8298 if (gd)
8299 {
8300 MemberList *ml = gd->getMemberList(MemberListType::DecEnumMembers());
8301 if (ml)
8302 {
8303 MemberDefMutable *md = toMemberDefMutable(ml->find(name));
8304 if (md)
8305 {
8306 addEnumDocs(root,md);
8307 return true;
8308 }
8309 }
8310 }
8311 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
8312 {
8313 warn(root->fileName, root->startLine,
8314 "Found non-existing group '{}' for the command '{}', ignoring command",
8315 g.groupname, Grouping::getGroupPriName( g.pri )
8316 );
8317 }
8318 }
8319
8320 return false;
8321}
virtual MemberList * getMemberList(MemberListType lt) const =0
const MemberDef * find(const DString &name) const
Definition memberlist.h:94

References addEnumDocs(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), MemberVector::find(), Grouping::getGroupPriName(), GroupDef::getMemberList(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Entry::groups, Entry::startLine, toMemberDefMutable(), and warn.

Referenced by findEnumDocumentation().

◆ usage()

void usage ( const DString & name,
const DString & versionString )
static

Definition at line 11634 of file doxygen.cpp.

11635{
11637 msg("Doxygen version {0}\nCopyright Dimitri van Heesch 1997-2025\n\n"
11638 "You can use Doxygen in a number of ways:\n\n"
11639 "1) Use Doxygen to generate a template configuration file*:\n"
11640 " {1} [-s] -g [configName]\n\n"
11641 "2) Use Doxygen to update an old configuration file*:\n"
11642 " {1} [-s] -u [configName]\n\n"
11643 "3) Use Doxygen to generate documentation using an existing "
11644 "configuration file*:\n"
11645 " {1} [configName]\n\n"
11646 "4) Use Doxygen to generate a template file controlling the layout of the\n"
11647 " generated documentation:\n"
11648 " {1} -l [layoutFileName]\n\n"
11649 " In case layoutFileName is omitted DoxygenLayout.xml will be used as filename.\n"
11650 " If - is used for layoutFileName Doxygen will write to standard output.\n\n"
11651 "5) Use Doxygen to generate a template style sheet file for RTF, HTML or Latex.\n"
11652 " RTF: {1} -w rtf styleSheetFile\n"
11653 " HTML: {1} -w html headerFile footerFile styleSheetFile [configFile]\n"
11654 " LaTeX: {1} -w latex headerFile footerFile styleSheetFile [configFile]\n\n"
11655 "6) Use Doxygen to generate a rtf extensions file\n"
11656 " {1} -e rtf extensionsFile\n\n"
11657 " If - is used for extensionsFile Doxygen will write to standard output.\n\n"
11658 "7) Use Doxygen to compare the used configuration file with the template configuration file\n"
11659 " {1} -x [configFile]\n\n"
11660 " Use Doxygen to compare the used configuration file with the template configuration file\n"
11661 " without replacing the environment variables or CMake type replacement variables\n"
11662 " {1} -x_noenv [configFile]\n\n"
11663 "8) Use Doxygen to show a list of built-in emojis.\n"
11664 " {1} -f emoji outputFileName\n\n"
11665 " If - is used for outputFileName Doxygen will write to standard output.\n\n"
11666 "*) If -s is specified the comments of the configuration items in the config file will be omitted.\n"
11667 " If configName is omitted 'Doxyfile' will be used as a default.\n"
11668 " If - is used for configFile Doxygen will write / read the configuration to /from standard output / input.\n\n"
11669 "If -q is used for a Doxygen documentation run, Doxygen will see this as if QUIET=YES has been set.\n\n"
11670 "-v print version string, -V print extended version information\n"
11671 "-h,-? prints usage help information\n"
11672 "{1} -d prints additional usage flags for debugging purposes\n",versionString,name);
11673}

References Debug::clearFlag(), msg, and Debug::Time.

Referenced by readConfiguration().

◆ version()

void version ( const bool extended)
static

Definition at line 11604 of file doxygen.cpp.

11605{
11607 DString versionString = getFullVersion();
11608 msg("{}\n",versionString);
11609 if (extended)
11610 {
11611 DString extVers;
11612 if (!extVers.empty()) extVers+= ", ";
11613 extVers += "sqlite3 ";
11614 extVers += sqlite3_libversion();
11615#if USE_LIBCLANG
11616 if (!extVers.empty()) extVers+= ", ";
11617 extVers += "clang support ";
11618 extVers += CLANG_VERSION_STRING;
11619#endif
11620 if (!extVers.empty())
11621 {
11622 if (size_t lastComma = extVers.rfind(','); lastComma != DString::npos)
11623 {
11624 extVers = extVers.replace(lastComma,1," and");
11625 }
11626 msg(" with {}.\n",extVers);
11627 }
11628 }
11629}
DString & replace(size_t index, size_t len, const char *s)
Definition dstring.cpp:154

References Debug::clearFlag(), DString::empty(), msg, DString::npos, DString::replace(), DString::rfind(), and Debug::Time.

Referenced by readConfiguration().

◆ vhdlCorrectMemberProperties()

void vhdlCorrectMemberProperties ( )
static

Definition at line 8655 of file doxygen.cpp.

8656{
8657 // for each member name
8658 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8659 {
8660 // for each member definition
8661 for (const auto &imd : *mn)
8662 {
8663 MemberDefMutable *md = toMemberDefMutable(imd.get());
8664 if (md)
8665 {
8667 }
8668 }
8669 }
8670 // for each member name
8671 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8672 {
8673 // for each member definition
8674 for (const auto &imd : *mn)
8675 {
8676 MemberDefMutable *md = toMemberDefMutable(imd.get());
8677 if (md)
8678 {
8680 }
8681 }
8682 }
8683}
static void correctMemberProperties(MemberDefMutable *md)

References VhdlDocGen::correctMemberProperties(), Doxygen::functionNameLinkedMap, Doxygen::memberNameLinkedMap, and toMemberDefMutable().

Referenced by parseInput().

◆ warnUndocumentedNamespaces()

void warnUndocumentedNamespaces ( )
static

Definition at line 5602 of file doxygen.cpp.

5603{
5604 AUTO_TRACE();
5605 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5606 {
5607 if (!nd->hasDocumentation())
5608 {
5609 if ((EntryType::guessSection(nd->getDefFileName()).isHeader() ||
5610 nd->getLanguage() == SrcLangExt::Fortran) && // Fortran doesn't have header files.
5611 !Config_getBool(HIDE_UNDOC_NAMESPACES) // undocumented namespaces are visible
5612 )
5613 {
5614 warn_undoc(nd->getDefFileName(),nd->getDefLine(), "{} {} is not documented.",
5615 nd->getLanguage() == SrcLangExt::Fortran ? "Module" : "Namespace",
5616 nd->name());
5617 }
5618 }
5619 }
5620}

References AUTO_TRACE, Config_getBool, EntryType::guessSection(), Doxygen::namespaceLinkedMap, and warn_undoc.

Referenced by parseInput().

◆ writeTagFile()

void writeTagFile ( )
static

Definition at line 12392 of file doxygen.cpp.

12393{
12394 DString generateTagFile = Config_getString(GENERATE_TAGFILE);
12395 if (generateTagFile.empty()) return;
12396
12397 std::ofstream f = Portable::openOutputStream(generateTagFile);
12398 if (!f.is_open())
12399 {
12400 err("cannot open tag file {} for writing\n", generateTagFile);
12401 return;
12402 }
12403 TextStream tagFile(&f);
12404 tagFile << "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>\n";
12405 tagFile << "<tagfile doxygen_version=\"" << getDoxygenVersion() << "\"";
12406 std::string gitVersion = getGitVersion();
12407 if (!gitVersion.empty())
12408 {
12409 tagFile << " doxygen_gitid=\"" << gitVersion << "\"";
12410 }
12411 tagFile << ">\n";
12412
12413 // for each file
12414 for (const auto &fn : *Doxygen::inputNameLinkedMap)
12415 {
12416 for (const auto &fd : *fn)
12417 {
12418 if (fd->isLinkableInProject()) fd->writeTagFile(tagFile);
12419 }
12420 }
12421 // for each class
12422 for (const auto &cd : *Doxygen::classLinkedMap)
12423 {
12424 ClassDefMutable *cdm = toClassDefMutable(cd.get());
12425 if (cdm && cdm->isLinkableInProject())
12426 {
12427 cdm->writeTagFile(tagFile);
12428 }
12429 }
12430 // for each concept
12431 for (const auto &cd : *Doxygen::conceptLinkedMap)
12432 {
12433 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
12434 if (cdm && cdm->isLinkableInProject())
12435 {
12436 cdm->writeTagFile(tagFile);
12437 }
12438 }
12439 // for each namespace
12440 for (const auto &nd : *Doxygen::namespaceLinkedMap)
12441 {
12443 if (ndm && nd->isLinkableInProject())
12444 {
12445 ndm->writeTagFile(tagFile);
12446 }
12447 }
12448 // for each group
12449 for (const auto &gd : *Doxygen::groupLinkedMap)
12450 {
12451 if (gd->isLinkableInProject()) gd->writeTagFile(tagFile);
12452 }
12453 // for each module
12454 for (const auto &mod : ModuleManager::instance().modules())
12455 {
12456 if (mod->isLinkableInProject()) mod->writeTagFile(tagFile);
12457 }
12458 // for each page
12459 for (const auto &pd : *Doxygen::pageLinkedMap)
12460 {
12461 if (pd->isLinkableInProject()) pd->writeTagFile(tagFile);
12462 }
12463 // for requirements
12465 // for each directory
12466 for (const auto &dd : *Doxygen::dirLinkedMap)
12467 {
12468 if (dd->isLinkableInProject()) dd->writeTagFile(tagFile);
12469 }
12470 if (Doxygen::mainPage) Doxygen::mainPage->writeTagFile(tagFile);
12471
12472 tagFile << "</tagfile>\n";
12473}
virtual void writeTagFile(TextStream &) const =0
virtual void writeTagFile(TextStream &)=0
virtual void writeTagFile(TextStream &)=0
void writeTagFile(TextStream &tagFile)

References Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Config_getString, Doxygen::dirLinkedMap, DString::empty(), err, Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), RequirementManager::instance(), Definition::isLinkableInProject(), Doxygen::mainPage, Doxygen::namespaceLinkedMap, Portable::openOutputStream(), Doxygen::pageLinkedMap, toClassDefMutable(), toConceptDefMutable(), toNamespaceDefMutable(), ClassDef::writeTagFile(), ConceptDefMutable::writeTagFile(), NamespaceDefMutable::writeTagFile(), and RequirementManager::writeTagFile().

Referenced by generateOutput().

Variable Documentation

◆ g_classEntries

◆ g_commentFileName

DString g_commentFileName
static

Definition at line 196 of file doxygen.cpp.

Referenced by parseInput(), and readConfiguration().

◆ g_compoundKeywords

const StringUnorderedSet g_compoundKeywords
static
Initial value:
=
{ "template class", "template struct", "class", "struct", "union", "interface", "exception" }

Definition at line 202 of file doxygen.cpp.

Referenced by buildVarList(), and filterMemberDocumentation().

◆ g_dumpSymbolMap

bool g_dumpSymbolMap = false
static

Definition at line 195 of file doxygen.cpp.

Referenced by generateOutput(), and readConfiguration().

◆ g_inputFiles

◆ g_outputList

◆ g_s

◆ g_singleComment

bool g_singleComment =false
static

Definition at line 197 of file doxygen.cpp.

Referenced by parseInput(), and readConfiguration().

◆ g_successfulRun

bool g_successfulRun = false
static

Definition at line 194 of file doxygen.cpp.

Referenced by exitDoxygen(), and generateOutput().

◆ g_usingClassMap

std::unordered_map<std::string,std::vector<ClassDefMutable*> > g_usingClassMap
static

Definition at line 2477 of file doxygen.cpp.

Referenced by findUsingDeclImports(), and parseInput().

◆ g_usingDeclarations

StringSet g_usingDeclarations
static

Definition at line 193 of file doxygen.cpp.

Referenced by buildListOfUsingDecls(), findScopeFromQualifiedName(), and parseInput().