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)
template<typename Container, typename TagContainer>
static void processTagLessClasses (const Definition *root, const Container *cd, 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>
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)
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 9288 of file doxygen.cpp.

9289{
9290 list.push_back(cd);
9291 for (const auto &innerCdi : cd->getClasses())
9292 {
9293 ClassDefMutable *innerCd = toClassDefMutable(innerCdi);
9294 if (innerCd)
9295 {
9296 AUTO_TRACE("innerCd={} isLinkable={} isImplicitTemplateInstance={} protectLevelVisible={} embeddedInOuterScope={}",
9297 innerCd->name(),innerCd->isLinkableInProject(),innerCd->isImplicitTemplateInstance(),protectionLevelVisible(innerCd->protection()),
9298 innerCd->isEmbeddedInOuterScope());
9299 }
9300 if (innerCd && innerCd->isLinkableInProject() && !innerCd->isImplicitTemplateInstance() &&
9301 protectionLevelVisible(innerCd->protection()) &&
9302 !innerCd->isEmbeddedInOuterScope()
9303 )
9304 {
9305 list.push_back(innerCd);
9306 addClassAndNestedClasses(list,innerCd);
9307 }
9308 }
9309}
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:9288
bool protectionLevelVisible(Protection prot)
Definition util.cpp:4672

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:577
ClassDefMutable * getClassMutable(const DString &key)
Definition classdef.h:461
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:740
void extractNamespaceName(const DString &scopeName, DString &className, DString &namespaceName, bool allowEmptyClass)
Definition util.cpp:3027
DString stripTemplateSpecifiersFromScope(const DString &fullName, bool parentOnly, DString *pLastScopeStripped, DString scopeName, bool allowArtificial)
Definition util.cpp:3687
DString mangleCSharpGenericName(const DString &name)
Definition util.cpp:5335

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 9639 of file doxygen.cpp.

9640{
9641 md->setDocumentation(root->doc,root->docFile,root->docLine);
9642 md->setDocsForDefinition(!root->proto);
9643 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9644 if (md->inbodyDocumentation().empty())
9645 {
9647 }
9648 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
9649 {
9650 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
9651 md->setBodyDef(root->fileDef());
9652 }
9654 md->setMaxInitLines(root->initLines);
9656 md->setRefItems(root->sli);
9657 md->setRequirementReferences(root->rqli);
9658 md->addQualifiers(root->qualifiers);
9659 if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
9660 addMemberToGroups(root,md);
9662}
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:2281
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 8108 of file doxygen.cpp.

8109{
8110 AUTO_TRACE();
8111 // documentation outside a compound overrides the documentation inside it
8112 {
8113 md->setDocumentation(root->doc,root->docFile,root->docLine);
8114 md->setDocsForDefinition(!root->proto);
8115 }
8116
8117 // brief descriptions inside a compound override the documentation
8118 // outside it
8119 {
8120 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
8121 }
8122
8123 if (md->inbodyDocumentation().empty() || !root->parent()->name.empty())
8124 {
8126 }
8127
8128 if (root->mGrpId!=-1 && md->getMemberGroupId()==-1)
8129 {
8130 md->setMemberGroupId(root->mGrpId);
8131 }
8132
8134 md->setRefItems(root->sli);
8135 md->setRequirementReferences(root->rqli);
8136
8137 const GroupDef *gd=md->getGroupDef();
8138 if (gd==nullptr && !root->groups.empty()) // member not grouped but out-of-line documentation is
8139 {
8140 addMemberToGroups(root,md);
8141 }
8143}
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 7860 of file doxygen.cpp.

7861{
7862 if (root->section.isEnum())
7863 // non anonymous enumeration
7864 {
7865 AUTO_TRACE("name={}",root->name);
7866 ClassDefMutable *cd = nullptr;
7867 FileDef *fd = nullptr;
7868 NamespaceDefMutable *nd = nullptr;
7869 MemberNameLinkedMap *mnsd = nullptr;
7870 bool isGlobal = false;
7871 bool isRelated = false;
7872 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
7873
7874 DString name;
7875 DString scope;
7876
7877 if (size_t i = root->name.rfind("::"); i!=DString::npos) // scope is specified
7878 {
7879 scope=root->name.left(i); // extract scope
7880 if (root->lang==SrcLangExt::CSharp)
7881 {
7882 scope = mangleCSharpGenericName(scope);
7883 }
7884 name=root->name.right(root->name.length()-i-2); // extract name
7885 if ((cd=getClassMutable(scope))==nullptr)
7886 {
7888 }
7889 }
7890 else // no scope, check the scope in which the docs where found
7891 {
7892 if (root->parent()->section.isScope() && !root->parent()->name.empty()) // found enum docs inside a compound
7893 {
7894 scope=root->parent()->name;
7895 if (root->lang==SrcLangExt::CSharp)
7896 {
7897 scope = mangleCSharpGenericName(scope);
7898 }
7899 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7900 }
7901 name=root->name;
7902 }
7903
7904 if (!root->relates.empty())
7905 { // related member, prefix user specified scope
7906 isRelated=true;
7907 if (getClassMutable(root->relates)==nullptr && !scope.empty())
7908 scope=mergeScopes(scope,root->relates);
7909 else
7910 scope=root->relates;
7911 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7912 }
7913
7914 if (cd && !name.empty()) // found a enum inside a compound
7915 {
7916 //printf("Enum in class '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
7917 fd=nullptr;
7919 isGlobal=false;
7920 }
7921 else if (nd && !nd->isAnonymous()) // found enum inside namespace
7922 {
7923 //printf("Enum in namespace '%s'::'%s'\n",qPrint(nd->name()),qPrint(name));
7925 isGlobal=true;
7926 }
7927 else // found a global enum
7928 {
7929 fd=root->fileDef();
7930 //printf("Enum in file '%s': '%s'\n",qPrint(fd->name()),qPrint(name));
7932 isGlobal=true;
7933 }
7934
7935 if (!name.empty())
7936 {
7937 //printf("** name=%s\n",qPrint(name));
7938 MemberName *mn = mnsd->find(name); // for all members with this name
7939 if (mn)
7940 {
7941 struct EnumValueInfo
7942 {
7943 EnumValueInfo(const DString &n,std::unique_ptr<MemberDef> &&md) :
7944 name(n), member(std::move(md)) {}
7945 DString name;
7946 std::unique_ptr<MemberDef> member;
7947 };
7948 std::vector< EnumValueInfo > extraMembers;
7949 // for each enum in this list
7950 for (const auto &imd : *mn)
7951 {
7952 MemberDefMutable *md = toMemberDefMutable(imd.get());
7953 // use raw pointer in this loop, since we modify mn and can then invalidate mdp.
7954 if (md && md->isEnumerate() && !root->children().empty())
7955 {
7956 AUTO_TRACE_ADD("enum {} with {} children",md->name(),root->children().size());
7957 for (const auto &e : root->children())
7958 {
7959 SrcLangExt sle = root->lang;
7960 bool isJavaLike = sle==SrcLangExt::CSharp || sle==SrcLangExt::Java || sle==SrcLangExt::XML;
7961 if ( isJavaLike || root->spec.isStrong())
7962 {
7963 if (sle == SrcLangExt::Cpp && e->section.isDefine()) continue;
7964 // Unlike classic C/C++ enums, for C++11, C# & Java enum
7965 // values are only visible inside the enum scope, so we must create
7966 // them here and only add them to the enum
7967 //printf("md->qualifiedName()=%s e->name=%s tagInfo=%p name=%s\n",
7968 // qPrint(md->qualifiedName()),qPrint(e->name),(void*)e->tagInfo(),qPrint(e->name));
7969 DString qualifiedName = root->name;
7970 if (size_t i = qualifiedName.rfind("::"); i!=DString::npos && sle==SrcLangExt::CSharp)
7971 {
7972 qualifiedName = mangleCSharpGenericName(qualifiedName.left(i))+qualifiedName.mid(i);
7973 }
7974 if (isJavaLike)
7975 {
7976 qualifiedName=substitute(qualifiedName,"::",".");
7977 }
7978 if (md->qualifiedName()==qualifiedName) // enum value scope matches that of the enum
7979 {
7980 DString fileName = e->fileName;
7981 if (fileName.empty() && e->tagInfo())
7982 {
7983 fileName = e->tagInfo()->tagName;
7984 }
7985 AUTO_TRACE_ADD("strong enum value {}",e->name);
7986 auto fmd = createMemberDef(
7987 fileName,e->startLine,e->startColumn,
7988 e->type,e->name,e->args,DString(),
7989 e->protection, Specifier::Normal,e->isStatic,Relationship::Member,
7990 MemberType::EnumValue,ArgumentList(),ArgumentList(),e->metaData);
7991 auto fmmd = toMemberDefMutable(fmd.get());
7992 NamespaceDef *mnd = md->getNamespaceDef();
7993 if (md->getClassDef())
7994 fmmd->setMemberClass(md->getClassDef());
7995 else if (mnd && (mnd->isLinkable() || mnd->isAnonymous()))
7996 fmmd->setNamespace(mnd);
7997 else if (md->getFileDef())
7998 fmmd->setFileDef(md->getFileDef());
7999 fmmd->setOuterScope(md->getOuterScope());
8000 fmmd->setTagInfo(e->tagInfo());
8001 fmmd->setLanguage(e->lang);
8002 fmmd->setBodySegment(e->startLine,e->bodyLine,e->endBodyLine);
8003 fmmd->setBodyDef(e->fileDef());
8004 fmmd->setId(e->id);
8005 fmmd->setDocumentation(e->doc,e->docFile,e->docLine);
8006 fmmd->setBriefDescription(e->brief,e->briefFile,e->briefLine);
8007 fmmd->addSectionsToDefinition(e->anchors);
8008 fmmd->setInitializer(e->initializer.str());
8009 fmmd->setMaxInitLines(e->initLines);
8010 fmmd->setMemberGroupId(e->mGrpId);
8011 fmmd->setExplicitExternal(e->explicitExternal,fileName,e->startLine,e->startColumn);
8012 fmmd->setRefItems(e->sli);
8013 fmmd->setRequirementReferences(e->rqli);
8014 fmmd->setAnchor();
8015 md->insertEnumField(fmd.get());
8016 fmmd->setEnumScope(md,true);
8017 extraMembers.emplace_back(e->name,std::move(fmd));
8018 }
8019 }
8020 else
8021 {
8022 AUTO_TRACE_ADD("enum value {}",e->name);
8023 //printf("e->name=%s isRelated=%d\n",qPrint(e->name),isRelated);
8024 MemberName *fmn=nullptr;
8025 MemberNameLinkedMap *emnsd = isRelated ? Doxygen::functionNameLinkedMap : mnsd;
8026 if (!e->name.empty() && (fmn=emnsd->find(e->name)))
8027 // get list of members with the same name as the field
8028 {
8029 for (const auto &ifmd : *fmn)
8030 {
8031 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
8032 if (fmd && fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope
8033 {
8034 //printf("found enum value with same name %s in scope %s\n",
8035 // qPrint(fmd->name()),qPrint(fmd->getOuterScope()->name()));
8036 if (nd && !nd->isAnonymous())
8037 {
8038 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
8039 {
8040 const NamespaceDef *fnd=fmd->getNamespaceDef();
8041 if (fnd==nd) // enum value is inside a namespace
8042 {
8043 md->insertEnumField(fmd);
8044 fmd->setEnumScope(md);
8045 }
8046 }
8047 }
8048 else if (isGlobal)
8049 {
8050 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
8051 {
8052 const FileDef *ffd=fmd->getFileDef();
8053 if (ffd==fd && ffd==md->getFileDef()) // enum value has file scope
8054 {
8055 md->insertEnumField(fmd);
8056 fmd->setEnumScope(md);
8057 }
8058 }
8059 }
8060 else if (isRelated && cd) // reparent enum value to
8061 // match the enum's scope
8062 {
8063 md->insertEnumField(fmd); // add field def to list
8064 fmd->setEnumScope(md); // cross ref with enum name
8065 fmd->setEnumClassScope(cd); // cross ref with enum name
8066 fmd->setOuterScope(cd);
8067 fmd->makeRelated();
8068 cd->insertMember(fmd);
8069 }
8070 else
8071 {
8072 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
8073 {
8074 const ClassDef *fcd=fmd->getClassDef();
8075 if (fcd==cd) // enum value is inside a class
8076 {
8077 //printf("Inserting enum field %s in enum scope %s\n",
8078 // qPrint(fmd->name()),qPrint(md->name()));
8079 md->insertEnumField(fmd); // add field def to list
8080 fmd->setEnumScope(md); // cross ref with enum name
8081 }
8082 }
8083 }
8084 }
8085 }
8086 }
8087 }
8088 }
8089 }
8090 }
8091 // move the newly added members into mn
8092 for (auto &e : extraMembers)
8093 {
8094 MemberName *emn=mnsd->add(e.name);
8095 emn->push_back(std::move(e.member));
8096 }
8097 }
8098 }
8099 }
8100 else
8101 {
8102 for (const auto &e : root->children()) addEnumValuesToEnums(e.get());
8103 }
8104}
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:7860
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)
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:3754

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 3950 of file doxygen.cpp.

3951{
3952 DString scope = sc;
3953
3954 // new global function
3956 auto md = createMemberDef(
3957 root->fileName,root->startLine,root->startColumn,
3958 root->type,name,root->args,root->exception,
3959 root->protection,root->virt,root->isStatic,Relationship::Member,
3960 MemberType::Function,
3961 !root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
3962 root->argList,root->metaData);
3963 auto mmd = toMemberDefMutable(md.get());
3964 mmd->setTagInfo(root->tagInfo());
3965 mmd->setLanguage(root->lang);
3966 mmd->setId(root->id);
3967 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3968 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3969 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3970 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
3971 mmd->setDocsForDefinition(!root->proto);
3972 mmd->setTypeConstraints(root->typeConstr);
3973 //md->setBody(root->body);
3974 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3975 FileDef *fd=root->fileDef();
3976 mmd->setBodyDef(fd);
3977 mmd->addSectionsToDefinition(root->anchors);
3978 mmd->setMemberSpecifiers(root->spec);
3979 mmd->setVhdlSpecifiers(root->vhdlSpec);
3980 mmd->setMemberGroupId(root->mGrpId);
3981 mmd->setRequiresClause(root->req);
3982 mmd->setExplicitExternal(root->explicitExternal,root->fileName,root->startLine,root->startColumn);
3983 addIncludeFile(mmd,fd,root);
3984
3985 NamespaceDefMutable *nd = nullptr;
3986 // see if the function is inside a namespace that was not part of
3987 // the name already (in that case nd should be non-zero already)
3988 if (root->parent()->section.isNamespace())
3989 {
3990 //DString nscope=removeAnonymousScopes(root->parent()->name);
3991 DString nscope=root->parent()->name;
3992 if (!nscope.empty())
3993 {
3994 nd = getResolvedNamespaceMutable(nscope);
3995 }
3996 }
3997 else if (root->parent()->section.isGroupDoc() && !scope.empty())
3998 {
4000 }
4001
4002 if (!scope.empty())
4003 {
4005 if (sep!="::")
4006 {
4007 scope = substitute(scope,"::",sep);
4008 }
4009 scope+=sep;
4010 }
4011
4012 if (Config_getBool(HIDE_SCOPE_NAMES) || root->lang==SrcLangExt::Python) scope = "";
4013 DString def;
4014 //DString optArgs = root->argList.empty() ? DString() : root->args;
4015 if (!root->type.empty())
4016 {
4017 def=root->type+" "+scope+name; //+optArgs;
4018 }
4019 else
4020 {
4021 def=scope+name; //+optArgs;
4022 }
4023 AUTO_TRACE("new non-member function type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
4024 root->type,scope,rname,root->args,root->proto,def);
4025 mmd->setDefinition(def);
4027 mmd->addQualifiers(root->qualifiers);
4028
4029 mmd->setRefItems(root->sli);
4030 mmd->setRequirementReferences(root->rqli);
4031 if (nd && !nd->name().empty() && nd->name().at(0)!='@')
4032 {
4033 // add member to namespace
4034 mmd->setNamespace(nd);
4035 nd->insertMember(md.get());
4036 }
4037 if (fd)
4038 {
4039 // add member to the file (we do this even if we have already
4040 // inserted it into the namespace)
4041 mmd->setFileDef(fd);
4042 fd->insertMember(md.get());
4043 }
4044
4045 addMemberToGroups(root,md.get());
4047 if (root->relatesType == RelatesType::Simple) // if this is a relatesalso command,
4048 // allow find Member to pick it up
4049 {
4050 root->markAsProcessed(); // Otherwise we have finished with this entry.
4051 }
4052
4053 // add member to the list of file members
4055 mn->push_back(std::move(md));
4056}
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:426
DString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Definition util.cpp:4630

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 3697 of file doxygen.cpp.

3701{
3702 FileDef *fd = root->fileDef();
3703 enum MemberType type = root->section.isExportedInterface() ? MemberType::Interface : MemberType::Service;
3704 DString fileName = root->fileName;
3705 if (fileName.empty() && root->tagInfo())
3706 {
3707 fileName = root->tagInfo()->tagName;
3708 }
3709 auto md = createMemberDef(
3710 fileName, root->startLine, root->startColumn, root->type, rname,
3711 "", "", root->protection, root->virt, root->isStatic, Relationship::Member,
3712 type, ArgumentList(), root->argList, root->metaData);
3713 auto mmd = toMemberDefMutable(md.get());
3714 mmd->setTagInfo(root->tagInfo());
3715 mmd->setMemberClass(cd);
3716 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3717 mmd->setDocsForDefinition(false);
3718 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3719 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3720 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3721 mmd->setMemberSpecifiers(root->spec);
3722 mmd->setVhdlSpecifiers(root->vhdlSpec);
3723 mmd->setMemberGroupId(root->mGrpId);
3724 mmd->setTypeConstraints(root->typeConstr);
3725 mmd->setLanguage(root->lang);
3726 mmd->setBodyDef(fd);
3727 mmd->setFileDef(fd);
3728 mmd->addSectionsToDefinition(root->anchors);
3729 DString const def = root->type + " " + rname;
3730 mmd->setDefinition(def);
3732 mmd->addQualifiers(root->qualifiers);
3733 addIncludeFile(mmd,fd,root);
3734
3735 AUTO_TRACE("Interface member: fileName='{}' type='{}' name='{}' mtype='{}' prot={} virt={} state={} proto={} def='{}'",
3736 fileName,root->type,rname,type,root->protection,root->virt,root->isStatic,root->proto,def);
3737
3738 // add member to the class cd
3739 cd->insertMember(md.get());
3740 // also add the member as a "base" (to get nicer diagrams)
3741 // "optional" interface/service get Protected which turns into dashed line
3742 BaseInfo base(rname,
3743 root->spec.isOptional() ? Protection::Protected : Protection::Public, Specifier::Normal);
3744 TemplateNameMap templateNames;
3745 findClassRelation(root,cd,cd,&base,templateNames,DocumentedOnly,true) ||
3746 findClassRelation(root,cd,cd,&base,templateNames,Undocumented,true);
3747 // add file to list of used files
3748 cd->insertUsedFile(fd);
3749
3750 addMemberToGroups(root,md.get());
3752 root->markAsProcessed();
3753 mmd->setRefItems(root->sli);
3754 mmd->setRequirementReferences(root->rqli);
3755
3756 // add member to the global list of all members
3758 mn->push_back(std::move(md));
3759}
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:5020
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 5683 of file doxygen.cpp.

5684{
5685 AUTO_TRACE();
5686 applyToAllDefinitions([](auto* obj) { obj->addListReferences(); });
5687}
static void applyToAllDefinitions(Func func)
Definition doxygen.cpp:5618

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 6263 of file doxygen.cpp.

6268{
6269 AUTO_TRACE();
6270 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
6271 ClassDefMutable *cd=nullptr;
6272 if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClassMutable(scopeName)))
6273 {
6274 AUTO_TRACE_ADD("Local objective C method '{}' scopeName='{}'",root->name,scopeName);
6275 auto md = createMemberDef(
6276 root->fileName,root->startLine,root->startColumn,
6277 funcType,funcName,funcArgs,exceptions,
6278 root->protection,root->virt,root->isStatic,Relationship::Member,
6279 MemberType::Function,ArgumentList(),root->argList,root->metaData);
6280 auto mmd = toMemberDefMutable(md.get());
6281 mmd->setTagInfo(root->tagInfo());
6282 mmd->setLanguage(root->lang);
6283 mmd->setId(root->id);
6284 mmd->makeImplementationDetail();
6285 mmd->setMemberClass(cd);
6286 mmd->setDefinition(funcDecl);
6288 mmd->addQualifiers(root->qualifiers);
6289 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6290 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6291 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6292 mmd->setDocsForDefinition(!root->proto);
6293 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6294 mmd->addSectionsToDefinition(root->anchors);
6295 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6296 FileDef *fd=root->fileDef();
6297 mmd->setBodyDef(fd);
6298 mmd->setMemberSpecifiers(spec);
6299 mmd->setVhdlSpecifiers(root->vhdlSpec);
6300 mmd->setMemberGroupId(root->mGrpId);
6301 cd->insertMember(md.get());
6302 cd->insertUsedFile(fd);
6303 mmd->setRefItems(root->sli);
6304 mmd->setRequirementReferences(root->rqli);
6305 addIncludeFile(mmd,fd,root);
6306
6308 mn->push_back(std::move(md));
6309 }
6310 else
6311 {
6312 // local objective C method found for class without interface
6313 }
6314}

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 5706 of file doxygen.cpp.

5712{
5713 if (md==nullptr) return;
5714 AUTO_TRACE("scope='{}' name='{}' args='{}' funcDecl='{}' mSpec={}",
5715 root->parent()->name,md->name(),md->argsString(),funcDecl,spec);
5716 if (!root->section.isDoc()) // @fn or @var does not need to specify the complete definition, so don't overwrite it
5717 {
5718 DString fDecl=funcDecl;
5719 // strip extern specifier
5720 fDecl.stripPrefix("extern ");
5721 md->setDefinition(fDecl);
5722 }
5724 md->addQualifiers(root->qualifiers);
5726 const NamespaceDef *nd=md->getNamespaceDef();
5727 DString fullName;
5728 if (cd)
5729 fullName = cd->name();
5730 else if (nd)
5731 fullName = nd->name();
5732
5733 if (!fullName.empty()) fullName+="::";
5734 fullName+=md->name();
5735 FileDef *rfd=root->fileDef();
5736
5737 // TODO determine scope based on root not md
5738 Definition *rscope = md->getOuterScope();
5739
5740 const ArgumentList &mdAl = md->argumentList();
5741 if (al)
5742 {
5743 ArgumentList mergedAl = *al;
5744 //printf("merging arguments (1) docs=%d\n",root->doc.empty());
5745 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedAl,!root->doc.empty());
5746 }
5747 else
5748 {
5749 if (
5750 matchArguments2( md->getOuterScope(), md->getFileDef(),md->typeString(),const_cast<ArgumentList*>(&mdAl),
5751 rscope,rfd,root->type,&root->argList,
5752 true, root->lang
5753 )
5754 )
5755 {
5756 //printf("merging arguments (2)\n");
5757 ArgumentList mergedArgList = root->argList;
5758 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.empty());
5759 }
5760 }
5761 if (over_load) // the \overload keyword was used
5762 {
5764 if (!root->doc.empty())
5765 {
5766 doc+="<p>";
5767 doc+=root->doc;
5768 }
5769 md->setDocumentation(doc,root->docFile,root->docLine);
5771 md->setDocsForDefinition(!root->proto);
5772 }
5773 else
5774 {
5775 //printf("overwrite!\n");
5776 md->setDocumentation(root->doc,root->docFile,root->docLine);
5777 md->setDocsForDefinition(!root->proto);
5778
5779 //printf("overwrite!\n");
5780 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
5781
5782 if (
5783 (md->inbodyDocumentation().empty() ||
5784 !root->parent()->name.empty()
5785 ) && !root->inbodyDocs.empty()
5786 )
5787 {
5789 }
5790 }
5791
5792 //printf("initializer: '%s'(isEmpty=%d) '%s'(isEmpty=%d)\n",
5793 // qPrint(md->initializer()),md->initializer().empty(),
5794 // qPrint(root->initializer),root->initializer.empty()
5795 // );
5796 std::string rootInit = root->initializer.str();
5797 if (md->initializer().empty() && !rootInit.empty())
5798 {
5799 //printf("setInitializer\n");
5800 md->setInitializer(rootInit);
5801 }
5802 if (md->requiresClause().empty() && !root->req.empty())
5803 {
5804 md->setRequiresClause(root->req);
5805 }
5806
5807 md->setMaxInitLines(root->initLines);
5808
5809 if (rfd)
5810 {
5811 if ((md->getStartBodyLine()==-1 && root->bodyLine!=-1)
5812 )
5813 {
5814 //printf("Setting new body segment [%d,%d]\n",root->bodyLine,root->endBodyLine);
5815 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
5816 md->setBodyDef(rfd);
5817 }
5818
5819 md->setRefItems(root->sli);
5820 md->setRequirementReferences(root->rqli);
5821 }
5822
5824 md->addQualifiers(root->qualifiers);
5825
5826 md->mergeMemberSpecifiers(spec);
5828 addMemberToGroups(root,md);
5829 addIncludeFile(md,rfd,root);
5831 if (cd) cd->insertUsedFile(rfd);
5832 //printf("root->mGrpId=%d\n",root->mGrpId);
5833 if (root->mGrpId!=-1)
5834 {
5835 if (md->getMemberGroupId()!=-1)
5836 {
5837 if (md->getMemberGroupId()!=root->mGrpId)
5838 {
5839 warn(root->fileName,root->startLine,
5840 "member {} belongs to two different groups. The second one found here will be ignored.",
5841 md->name()
5842 );
5843 }
5844 }
5845 else // set group id
5846 {
5847 //printf("setMemberGroupId=%d md=%s\n",root->mGrpId,qPrint(md->name()));
5848 md->setMemberGroupId(root->mGrpId);
5849 }
5850 }
5851 md->addQualifiers(root->qualifiers);
5852}
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:1589
void mergeArguments(ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
Definition util.cpp:1689

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 6318 of file doxygen.cpp.

6336{
6337 AUTO_TRACE();
6338 DString funcType = funcTyp;
6339 int count=0;
6340 int noMatchCount=0;
6341 bool memFound=false;
6342 for (const auto &imd : *mn)
6343 {
6344 MemberDefMutable *md = toMemberDefMutable(imd.get());
6345 if (md==nullptr) continue;
6347 if (cd==nullptr) continue;
6348 //AUTO_TRACE_ADD("member definition found, scope needed='{}' scope='{}' args='{}' fileName='{}'",
6349 // scopeName, cd->name(), md->argsString(), root->fileName);
6350 FileDef *fd=root->fileDef();
6351 NamespaceDef *nd=nullptr;
6352 if (!namespaceName.empty()) nd=getResolvedNamespace(namespaceName);
6353
6354 //printf("scopeName %s->%s\n",qPrint(scopeName),
6355 // qPrint(stripTemplateSpecifiersFromScope(scopeName,false)));
6356
6357 // if the member we are searching for is an enum value that is part of
6358 // a "strong" enum, we need to look into the fields of the enum for a match
6359 size_t enumNamePos=0;
6360 if (md->isEnumValue() && (enumNamePos=className.rfind("::"))!=DString::npos)
6361 {
6362 DString enumName = className.mid(enumNamePos+2);
6363 DString fullScope = className.left(enumNamePos);
6364 if (!namespaceName.empty()) fullScope.prepend(namespaceName+"::");
6365 if (fullScope==cd->name())
6366 {
6367 MemberName *enumMn=Doxygen::memberNameLinkedMap->find(enumName);
6368 //printf("enumMn(%s)=%p\n",qPrint(className),(void*)enumMn);
6369 if (enumMn)
6370 {
6371 for (const auto &emd : *enumMn)
6372 {
6373 memFound = emd->isStrong() && md->getEnumScope()==emd.get();
6374 if (memFound)
6375 {
6376 addMemberDocs(root,md,funcDecl,nullptr,overloaded,spec);
6377 count++;
6378 }
6379 if (memFound) break;
6380 }
6381 }
6382 }
6383 }
6384 if (memFound) break;
6385
6386 const ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
6387 if (tcd==nullptr && cd && stripAnonymousNamespaceScope(cd->name())==scopeName)
6388 {
6389 // don't be fooled by anonymous scopes
6390 tcd=cd;
6391 }
6392 //printf("Looking for %s inside nd=%s result=%s cd=%s\n",
6393 // qPrint(scopeName),nd?qPrint(nd->name()):"<none>",tcd?qPrint(tcd->name()):"",qPrint(cd->name()));
6394
6395 if (cd && tcd==cd) // member's classes match
6396 {
6397 AUTO_TRACE_ADD("class definition '{}' found",cd->name());
6398
6399 // get the template parameter lists found at the member declaration
6400 ArgumentLists declTemplArgs = cd->getTemplateParameterLists();
6401 const ArgumentList &templAl = md->templateArguments();
6402 if (!templAl.empty())
6403 {
6404 declTemplArgs.push_back(templAl);
6405 }
6406
6407 // get the template parameter lists found at the member definition
6408 const ArgumentLists &defTemplArgs = root->tArgLists;
6409 //printf("defTemplArgs=%p\n",defTemplArgs);
6410
6411 // do we replace the decl argument lists with the def argument lists?
6412 bool substDone=false;
6413 ArgumentList argList;
6414
6415 /* substitute the occurrences of class template names in the
6416 * argument list before matching
6417 */
6418 const ArgumentList &mdAl = md->argumentList();
6419 if (declTemplArgs.size()>0 && declTemplArgs.size()==defTemplArgs.size())
6420 {
6421 /* the function definition has template arguments
6422 * and the class definition also has template arguments, so
6423 * we must substitute the template names of the class by that
6424 * of the function definition before matching.
6425 */
6426 substituteTemplatesInArgList(declTemplArgs,defTemplArgs,mdAl,argList);
6427
6428 substDone=true;
6429 }
6430 else /* no template arguments, compare argument lists directly */
6431 {
6432 argList = mdAl;
6433 }
6434
6435 bool matching=
6436 md->isVariable() || md->isTypedef() || // needed for function pointers
6438 md->getClassDef(),md->getFileDef(),md->typeString(),&argList,
6439 cd,fd,root->type,&root->argList,
6440 true,root->lang);
6441
6442 AUTO_TRACE_ADD("matching '{}'<=>'{}' className='{}' namespaceName='{}' result={}",
6443 argListToString(argList,true),argListToString(root->argList,true),className,namespaceName,matching);
6444
6445 if (md->getLanguage()==SrcLangExt::ObjC && md->isVariable() && root->section.isFunction())
6446 {
6447 matching = false; // don't match methods and attributes with the same name
6448 }
6449
6450 // for template member we also need to check the return type
6451 if (!md->templateArguments().empty() && !root->tArgLists.empty())
6452 {
6453 DString memType = md->typeString();
6454 memType.stripPrefix("static "); // see bug700696
6455 funcType=substitute(stripTemplateSpecifiersFromScope(funcType,true),
6456 className+"::",""); // see bug700693 & bug732594
6457 memType=substitute(stripTemplateSpecifiersFromScope(memType,true),
6458 className+"::",""); // see bug758900
6459 if (memType=="auto" && !argList.trailingReturnType().empty())
6460 {
6461 memType = argList.trailingReturnType();
6462 memType.stripPrefix(" -> ");
6463 }
6464 if (funcType=="auto" && !root->argList.trailingReturnType().empty())
6465 {
6466 funcType = root->argList.trailingReturnType();
6467 funcType.stripPrefix(" -> ");
6469 substDone=true;
6470 }
6471 AUTO_TRACE_ADD("Comparing return types '{}'<->'{}' #args {}<->{}",
6472 memType,funcType,md->templateArguments().size(),root->tArgLists.back().size());
6473 if (md->templateArguments().size()!=root->tArgLists.back().size() || memType!=funcType)
6474 {
6475 //printf(" ---> no matching\n");
6476 matching = false;
6477 }
6478 }
6479 else if (defTemplArgs.size()>declTemplArgs.size())
6480 {
6481 AUTO_TRACE_ADD("Different number of template arguments {} vs {}",defTemplArgs.size(),declTemplArgs.size());
6482 // avoid matching a non-template function in a template class against a
6483 // template function with the same name and parameters, see issue #10184
6484 substDone = false;
6485 matching = false;
6486 }
6487 bool rootIsUserDoc = root->section.isMemberDoc();
6488 bool classIsTemplate = scopeIsTemplate(md->getClassDef());
6489 bool mdIsTemplate = md->templateArguments().hasParameters();
6490 bool classOrMdIsTemplate = mdIsTemplate || classIsTemplate;
6491 bool rootIsTemplate = !root->tArgLists.empty();
6492 //printf("classIsTemplate=%d mdIsTemplate=%d rootIsTemplate=%d\n",classIsTemplate,mdIsTemplate,rootIsTemplate);
6493 if (!rootIsUserDoc && // don't check out-of-line @fn references, see bug722457
6494 (mdIsTemplate || rootIsTemplate) && // either md or root is a template
6495 ((classOrMdIsTemplate && !rootIsTemplate) || (!classOrMdIsTemplate && rootIsTemplate))
6496 )
6497 {
6498 // Method with template return type does not match method without return type
6499 // even if the parameters are the same. See also bug709052
6500 AUTO_TRACE_ADD("Comparing return types: template v.s. non-template");
6501 matching = false;
6502 }
6503
6504 AUTO_TRACE_ADD("Match results of matchArguments2='{}' substDone='{}'",matching,substDone);
6505
6506 if (substDone) // found a new argument list
6507 {
6508 if (matching) // replace member's argument list
6509 {
6511 md->moveArgumentList(std::make_unique<ArgumentList>(argList));
6512 }
6513 else // no match
6514 {
6515 if (!funcTempList.empty() &&
6516 isSpecialization(declTemplArgs,defTemplArgs))
6517 {
6518 // check if we are dealing with a partial template
6519 // specialization. In this case we add it to the class
6520 // even though the member arguments do not match.
6521
6522 addMethodToClass(root,cd,type,md->name(),args,isFriend,
6523 md->protection(),md->isStatic(),md->virtualness(),spec,relates);
6524 return;
6525 }
6526 }
6527 }
6528 if (matching)
6529 {
6530 addMemberDocs(root,md,funcDecl,nullptr,overloaded,spec);
6531 count++;
6532 memFound=true;
6533 }
6534 }
6535 else if (cd && cd!=tcd) // we did find a class with the same name as cd
6536 // but in a different namespace
6537 {
6538 noMatchCount++;
6539 }
6540
6541 if (memFound) break;
6542 }
6543 if (count==0 && root->parent() && root->parent()->section.isObjcImpl())
6544 {
6545 addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec);
6546 return;
6547 }
6548 if (count==0 && !(isFriend && funcType=="class"))
6549 {
6550 int candidates=0;
6551 const ClassDef *ecd = nullptr, *ucd = nullptr;
6552 MemberDef *emd = nullptr, *umd = nullptr;
6553 //printf("Assume template class\n");
6554 for (const auto &md : *mn)
6555 {
6556 MemberDef *cmd=md.get();
6558 ClassDefMutable *ccd=cdmdm ? cdmdm->getClassDefMutable() : nullptr;
6559 //printf("ccd->name()==%s className=%s\n",qPrint(ccd->name()),qPrint(className));
6560 if (ccd!=nullptr && rightScopeMatch(ccd->name(),className))
6561 {
6562 const ArgumentList &templAl = md->templateArguments();
6563 if (!root->tArgLists.empty() && !templAl.empty() &&
6564 root->tArgLists.back().size()<=templAl.size())
6565 {
6566 AUTO_TRACE_ADD("add template specialization");
6567 addMethodToClass(root,ccd,type,md->name(),args,isFriend,
6568 root->protection,root->isStatic,root->virt,spec,relates);
6569 return;
6570 }
6571 if (argListToString(md->argumentList(),false,false) ==
6572 argListToString(root->argList,false,false))
6573 { // exact argument list match -> remember
6574 ucd = ecd = ccd;
6575 umd = emd = cmd;
6576 AUTO_TRACE_ADD("new candidate className='{}' scope='{}' args='{}': exact match",
6577 className,ccd->name(),md->argsString());
6578 }
6579 else // arguments do not match, but member name and scope do -> remember
6580 {
6581 ucd = ccd;
6582 umd = cmd;
6583 AUTO_TRACE_ADD("new candidate className='{}' scope='{}' args='{}': no match",
6584 className,ccd->name(),md->argsString());
6585 }
6586 candidates++;
6587 }
6588 }
6589 bool strictProtoMatching = Config_getBool(STRICT_PROTO_MATCHING);
6590 if (!strictProtoMatching)
6591 {
6592 if (candidates==1 && ucd && umd)
6593 {
6594 // we didn't find an actual match on argument lists, but there is only 1 member with this
6595 // name in the same scope, so that has to be the one.
6596 addMemberDocs(root,toMemberDefMutable(umd),funcDecl,nullptr,overloaded,spec);
6597 return;
6598 }
6599 else if (candidates>1 && ecd && emd)
6600 {
6601 // we didn't find a unique match using type resolution,
6602 // but one of the matches has the exact same signature so
6603 // we take that one.
6604 addMemberDocs(root,toMemberDefMutable(emd),funcDecl,nullptr,overloaded,spec);
6605 return;
6606 }
6607 }
6608
6609 DString warnMsg = "no ";
6610 if (noMatchCount>1) warnMsg+="uniquely ";
6611 warnMsg+="matching class member found for \n";
6612
6613 for (const ArgumentList &al : root->tArgLists)
6614 {
6615 warnMsg+=" template ";
6616 warnMsg+=tempArgListToString(al,root->lang);
6617 warnMsg+='\n';
6618 }
6619
6620 DString fullFuncDecl=funcDecl;
6621 if (isFunc) fullFuncDecl+=argListToString(root->argList,true);
6622
6623 warnMsg+=" ";
6624 warnMsg+=fullFuncDecl;
6625
6626 if (candidates>0 || noMatchCount>=1)
6627 {
6628 warnMsg+="\nPossible candidates:";
6629
6630 NamespaceDef *nd=nullptr;
6631 if (!namespaceName.empty()) nd=getResolvedNamespace(namespaceName);
6632 FileDef *fd=root->fileDef();
6633
6634 for (const auto &md : *mn)
6635 {
6636 const ClassDef *cd=md->getClassDef();
6637 const ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
6638 if (tcd==nullptr && cd && stripAnonymousNamespaceScope(cd->name())==scopeName)
6639 {
6640 // don't be fooled by anonymous scopes
6641 tcd=cd;
6642 }
6643 if (cd!=nullptr && (rightScopeMatch(cd->name(),className) || (cd!=tcd)))
6644 {
6645 warnMsg+='\n';
6646 const ArgumentList &templAl = md->templateArguments();
6647 warnMsg+=" '";
6648 if (templAl.hasParameters())
6649 {
6650 warnMsg+="template ";
6651 warnMsg+=tempArgListToString(templAl,root->lang);
6652 warnMsg+='\n';
6653 warnMsg+=" ";
6654 }
6655 if (!md->typeString().empty())
6656 {
6657 warnMsg+=md->typeString();
6658 warnMsg+=' ';
6659 }
6661 if (!qScope.empty())
6662 warnMsg+=qScope+"::"+md->name();
6663 warnMsg+=md->argsString();
6664 warnMsg+="' " + warn_line(md->getDefFileName(),md->getDefLine());
6665 }
6666 }
6667 }
6668 warn(root->fileName,root->startLine,"{}",warnMsg);
6669 }
6670}
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:6105
static void substituteTemplatesInArgList(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const ArgumentList &src, ArgumentList &dst)
Definition doxygen.cpp:6219
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:6263
static void addMemberDocs(const Entry *root, MemberDefMutable *md, const DString &funcDecl, const ArgumentList *al, bool over_load, TypeSpecifier spec)
Definition doxygen.cpp:5706
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:3813
static bool scopeIsTemplate(const Definition *d)
Definition doxygen.cpp:6121
static const ClassDef * findClassDefinition(FileDef *fd, NamespaceDef *nd, const DString &scopeName)
Definition doxygen.cpp:5858
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:729
DString replaceAnonymousScopes(const DString &s, const DString &replacement)
Definition util.cpp:155
DString tempArgListToString(const ArgumentList &al, SrcLangExt lang, bool includeDefault)
Definition util.cpp:903
DString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:859
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 6674 of file doxygen.cpp.

6684{
6685 AUTO_TRACE("funcType={} funcName={} funcArgs={} funcDecl={} spec={}",funcType,funcName,funcArgs,funcDecl,spec);
6686 MemberDef *declMd=nullptr;
6687 for (const auto &md : *mn)
6688 {
6689 if (md->getClassDef()==cd)
6690 {
6691 // TODO: we should probably also check for matching arguments
6692 declMd = md.get();
6693 break;
6694 }
6695 }
6696 MemberType mtype=MemberType::Function;
6697 ArgumentList tArgList;
6698 // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6699 auto md = createMemberDef(
6700 root->fileName,root->startLine,root->startColumn,
6701 funcType,funcName,funcArgs,exceptions,
6702 declMd ? declMd->protection() : root->protection,
6703 root->virt,root->isStatic,Relationship::Member,
6704 mtype,tArgList,root->argList,root->metaData);
6705 auto mmd = toMemberDefMutable(md.get());
6706 //printf("new specialized member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6707 mmd->setTagInfo(root->tagInfo());
6708 mmd->setLanguage(root->lang);
6709 mmd->setId(root->id);
6710 mmd->setMemberClass(cd);
6711 mmd->setTemplateSpecialization(true);
6712 mmd->setTypeConstraints(root->typeConstr);
6713 mmd->setDefinition(funcDecl);
6715 mmd->addQualifiers(root->qualifiers);
6716 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6717 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6718 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6719 mmd->setDocsForDefinition(!root->proto);
6720 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6721 mmd->addSectionsToDefinition(root->anchors);
6722 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6723 FileDef *fd=root->fileDef();
6724 mmd->setBodyDef(fd);
6725 mmd->setMemberSpecifiers(spec);
6726 mmd->setVhdlSpecifiers(root->vhdlSpec);
6727 mmd->setMemberGroupId(root->mGrpId);
6728 cd->insertMember(md.get());
6729 mmd->setRefItems(root->sli);
6730 mmd->setRequirementReferences(root->rqli);
6731 addIncludeFile(mmd,fd,root);
6732
6733 mn->push_back(std::move(md));
6734}

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 8302 of file doxygen.cpp.

8303{
8304 auto &index = Index::instance();
8305 // for each class member name
8306 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8307 {
8308 // for each member definition
8309 for (const auto &md : *mn)
8310 {
8311 index.addClassMemberNameToIndex(md.get());
8312 if (md->getModuleDef())
8313 {
8314 index.addModuleMemberNameToIndex(md.get());
8315 }
8316 }
8317 }
8318 // for each file/namespace function name
8319 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8320 {
8321 // for each member definition
8322 for (const auto &md : *mn)
8323 {
8324 if (md->getNamespaceDef())
8325 {
8326 index.addNamespaceMemberNameToIndex(md.get());
8327 }
8328 else
8329 {
8330 index.addFileMemberNameToIndex(md.get());
8331 }
8332 if (md->getModuleDef())
8333 {
8334 index.addModuleMemberNameToIndex(md.get());
8335 }
8336 }
8337 }
8338
8339 index.sortMemberIndexLists();
8340}
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 9418 of file doxygen.cpp.

9419{
9420 // for each class
9421 for (const auto &cd : *Doxygen::classLinkedMap)
9422 {
9423 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9424 if (cdm)
9425 {
9427 }
9428 }
9429 // for each file
9430 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9431 {
9432 for (const auto &fd : *fn)
9433 {
9434 fd->addMembersToMemberGroup();
9435 }
9436 }
9437 // for each namespace
9438 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9439 {
9441 if (ndm)
9442 {
9444 }
9445 }
9446 // for each group
9447 for (const auto &gd : *Doxygen::groupLinkedMap)
9448 {
9449 gd->addMembersToMemberGroup();
9450 }
9452}
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 3813 of file doxygen.cpp.

3819{
3820 FileDef *fd=root->fileDef();
3821
3822 DString type = rtype;
3823 DString args = rargs;
3824
3826 name.stripPrefix("::");
3827
3828 MemberType mtype = MemberType::Function;
3829 if (isFriend) mtype=MemberType::Friend;
3830 else if (root->mtype==MethodTypes::Signal) mtype=MemberType::Signal;
3831 else if (root->mtype==MethodTypes::Slot) mtype=MemberType::Slot;
3832 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType::DCOP;
3833
3834 // strip redundant template specifier for constructors
3835 size_t i = DString::npos;
3836 size_t j = DString::npos;
3837 if ((fd==nullptr || fd->getLanguage()==SrcLangExt::Cpp) &&
3838 !name.startsWith("operator ") && // not operator
3839 (i=name.find('<'))!=DString::npos && // containing <
3840 (j=name.find('>'))!=DString::npos && // or >
3841 (j!=i+2 || name.at(i+1)!='=') // but not the C++20 spaceship operator <=>
3842 )
3843 {
3844 name=name.left(i);
3845 }
3846
3847 DString fileName = root->fileName;
3848 if (fileName.empty() && root->tagInfo())
3849 {
3850 fileName = root->tagInfo()->tagName;
3851 }
3852
3853 //printf("root->name='%s; args='%s' root->argList='%s'\n",
3854 // qPrint(root->name),qPrint(args),qPrint(argListToString(root->argList))
3855 // );
3856
3857 // adding class member
3858 Relationship relationship = relates.empty() ? Relationship::Member :
3859 root->relatesType==RelatesType::MemberOf ? Relationship::Foreign :
3860 Relationship::Related ;
3861 auto md = createMemberDef(
3862 fileName,root->startLine,root->startColumn,
3863 type,name,args,root->exception,
3864 protection,virt,
3865 stat && root->relatesType!=RelatesType::MemberOf,
3866 relationship,
3867 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
3868 root->argList, root->metaData);
3869 auto mmd = toMemberDefMutable(md.get());
3870 mmd->setTagInfo(root->tagInfo());
3871 mmd->setMemberClass(cd);
3872 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3873 mmd->setDocsForDefinition(!root->proto);
3874 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3875 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3876 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3877 mmd->setMemberSpecifiers(spec);
3878 mmd->setVhdlSpecifiers(root->vhdlSpec);
3879 mmd->setMemberGroupId(root->mGrpId);
3880 mmd->setTypeConstraints(root->typeConstr);
3881 mmd->setLanguage(root->lang);
3882 mmd->setRequiresClause(root->req);
3883 mmd->setId(root->id);
3884 mmd->setBodyDef(fd);
3885 mmd->setFileDef(fd);
3886 mmd->addSectionsToDefinition(root->anchors);
3887 addIncludeFile(mmd,fd,root);
3888 DString def;
3890 SrcLangExt lang = cd->getLanguage();
3891 DString scopeSeparator=getLanguageSpecificSeparator(lang);
3892 if (scopeSeparator!="::")
3893 {
3894 qualScope = substitute(qualScope,"::",scopeSeparator);
3895 }
3896 if (lang==SrcLangExt::PHP)
3897 {
3898 // for PHP we use Class::method and Namespace\method
3899 scopeSeparator="::";
3900 }
3901 if (!relates.empty() || isFriend || Config_getBool(HIDE_SCOPE_NAMES))
3902 {
3903 if (!type.empty())
3904 {
3905 def=type+" "+name; //+optArgs;
3906 }
3907 else
3908 {
3909 def=name; //+optArgs;
3910 }
3911 }
3912 else
3913 {
3914 if (!type.empty())
3915 {
3916 def=type+" "+qualScope+scopeSeparator+name; //+optArgs;
3917 }
3918 else
3919 {
3920 def=qualScope+scopeSeparator+name; //+optArgs;
3921 }
3922 }
3923 def.stripPrefix("friend ");
3924 mmd->setDefinition(def);
3926 mmd->addQualifiers(root->qualifiers);
3927
3928 AUTO_TRACE("function member: type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
3929 type, qualScope, rname, args, root->proto, def);
3930
3931 // add member to the class cd
3932 cd->insertMember(md.get());
3933 // add file to list of used files
3934 cd->insertUsedFile(fd);
3935
3936 addMemberToGroups(root,md.get());
3938 root->markAsProcessed();
3939 mmd->setRefItems(root->sli);
3940 mmd->setRequirementReferences(root->rqli);
3941
3942 // add member to the global list of all members
3943 //printf("Adding member=%s class=%s\n",qPrint(md->name()),qPrint(cd->name()));
3945 mn->push_back(std::move(md));
3946}
bool startsWith(const char *s) const
Definition dstring.h:600
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, 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::fileDef(), Entry::fileName, DString::find(), Definition::getLanguage(), getLanguageSpecificSeparator(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), Entry::lang, DString::left(), 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::startsWith(), 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 6738 of file doxygen.cpp.

6741{
6742 // for unique overloaded member we allow the class to be
6743 // omitted, this is to be Qt compatible. Using this should
6744 // however be avoided, because it is error prone
6745 bool sameClass=false;
6746 if (mn->size()>0)
6747 {
6748 // check if all members with the same name are also in the same class
6749 sameClass = std::equal(mn->begin()+1,mn->end(),mn->begin(),
6750 [](const auto &md1,const auto &md2)
6751 { return md1->getClassDef()->name()==md2->getClassDef()->name(); });
6752 }
6753 if (sameClass)
6754 {
6755 MemberDefMutable *mdm = toMemberDefMutable(mn->front().get());
6756 ClassDefMutable *cd = mdm ? mdm->getClassDefMutable() : nullptr;
6757 if (cd==nullptr) return;
6758
6759 MemberType mtype = MemberType::Function;
6760 if (root->mtype==MethodTypes::Signal) mtype=MemberType::Signal;
6761 else if (root->mtype==MethodTypes::Slot) mtype=MemberType::Slot;
6762 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType::DCOP;
6763
6764 // new overloaded member function
6765 std::unique_ptr<ArgumentList> tArgList =
6766 getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6767 //printf("new related member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6768 auto md = createMemberDef(
6769 root->fileName,root->startLine,root->startColumn,
6770 funcType,funcName,funcArgs,exceptions,
6771 root->protection,root->virt,root->isStatic,Relationship::Related,
6772 mtype,tArgList ? *tArgList : ArgumentList(),root->argList,root->metaData);
6773 auto mmd = toMemberDefMutable(md.get());
6774 mmd->setTagInfo(root->tagInfo());
6775 mmd->setLanguage(root->lang);
6776 mmd->setId(root->id);
6777 mmd->setTypeConstraints(root->typeConstr);
6778 mmd->setMemberClass(cd);
6779 mmd->setDefinition(funcDecl);
6781 mmd->addQualifiers(root->qualifiers);
6783 doc+="<p>";
6784 doc+=root->doc;
6785 mmd->setDocumentation(doc,root->docFile,root->docLine);
6786 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6787 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6788 mmd->setDocsForDefinition(!root->proto);
6789 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6790 mmd->addSectionsToDefinition(root->anchors);
6791 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6792 FileDef *fd=root->fileDef();
6793 mmd->setBodyDef(fd);
6794 mmd->setMemberSpecifiers(spec);
6795 mmd->setVhdlSpecifiers(root->vhdlSpec);
6796 mmd->setMemberGroupId(root->mGrpId);
6797 cd->insertMember(md.get());
6798 cd->insertUsedFile(fd);
6799 mmd->setRefItems(root->sli);
6800 mmd->setRequirementReferences(root->rqli);
6801 addIncludeFile(mmd,fd,root);
6802
6803 mn->push_back(std::move(md));
6804 }
6805}
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 5675 of file doxygen.cpp.

5676{
5677 AUTO_TRACE();
5678 applyToAllDefinitions([](auto* obj) { obj->addRequirementReferences(); });
5679}

References applyToAllDefinitions(), and AUTO_TRACE.

Referenced by parseInput().

◆ addSourceReferences()

void addSourceReferences ( )
static

Definition at line 8936 of file doxygen.cpp.

8937{
8938 // add source references for class definitions
8939 for (const auto &cd : *Doxygen::classLinkedMap)
8940 {
8941 const FileDef *fd=cd->getBodyDef();
8942 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8943 {
8944 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8945 }
8946 }
8947 // add source references for concept definitions
8948 for (const auto &cd : *Doxygen::conceptLinkedMap)
8949 {
8950 const FileDef *fd=cd->getBodyDef();
8951 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8952 {
8953 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8954 }
8955 }
8956 // add source references for namespace definitions
8957 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8958 {
8959 const FileDef *fd=nd->getBodyDef();
8960 if (fd && nd->isLinkableInProject() && nd->getStartDefLine()!=-1)
8961 {
8962 const_cast<FileDef*>(fd)->addSourceRef(nd->getStartDefLine(),nd.get(),nullptr);
8963 }
8964 }
8965
8966 // add source references for member names
8967 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8968 {
8969 for (const auto &md : *mn)
8970 {
8971 //printf("class member %s: def=%s body=%d link?=%d\n",
8972 // qPrint(md->name()),
8973 // md->getBodyDef()?qPrint(md->getBodyDef()->name()):"<none>",
8974 // md->getStartBodyLine(),md->isLinkableInProject());
8975 const FileDef *fd=md->getBodyDef();
8976 if (fd &&
8977 md->getStartDefLine()!=-1 &&
8978 md->isLinkableInProject() &&
8980 )
8981 {
8982 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8983 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8984 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8985 }
8986 }
8987 }
8988 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8989 {
8990 for (const auto &md : *mn)
8991 {
8992 const FileDef *fd=md->getBodyDef();
8993 //printf("member %s body=[%d,%d] fd=%p link=%d parseSources=%d\n",
8994 // qPrint(md->name()),
8995 // md->getStartBodyLine(),md->getEndBodyLine(),fd,
8996 // md->isLinkableInProject(),
8997 // Doxygen::parseSourcesNeeded);
8998 if (fd &&
8999 md->getStartDefLine()!=-1 &&
9000 md->isLinkableInProject() &&
9002 )
9003 {
9004 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
9005 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
9006 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
9007 }
9008 }
9009 }
9010}
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 8344 of file doxygen.cpp.

8345{
8346 for (const auto &cd : *Doxygen::classLinkedMap)
8347 {
8348 if (cd->isLinkableInProject())
8349 {
8350 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8351 if (Doxygen::searchIndex.enabled())
8352 {
8353 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),false);
8354 Doxygen::searchIndex.addWord(cd->localName(),true);
8355 }
8356 }
8357 }
8358
8359 for (const auto &cd : *Doxygen::conceptLinkedMap)
8360 {
8361 if (cd->isLinkableInProject())
8362 {
8363 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8364 if (Doxygen::searchIndex.enabled())
8365 {
8366 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),false);
8367 Doxygen::searchIndex.addWord(cd->localName(),true);
8368 }
8369 }
8370 }
8371
8372 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8373 {
8374 if (nd->isLinkableInProject())
8375 {
8376 Doxygen::indexList->addIndexItem(nd.get(),nullptr);
8377 if (Doxygen::searchIndex.enabled())
8378 {
8379 Doxygen::searchIndex.setCurrentDoc(nd.get(),nd->anchor(),false);
8380 Doxygen::searchIndex.addWord(nd->localName(),true);
8381 }
8382 }
8383 }
8384
8385 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8386 {
8387 for (const auto &fd : *fn)
8388 {
8389 if (Doxygen::searchIndex.enabled() && fd->isLinkableInProject())
8390 {
8391 Doxygen::searchIndex.setCurrentDoc(fd.get(),fd->anchor(),false);
8392 Doxygen::searchIndex.addWord(fd->localName(),true);
8393 }
8394 }
8395 }
8396
8397 auto addWordsForTitle = [](const Definition *d,const DString &anchor,const DString &title)
8398 {
8400 if (Doxygen::searchIndex.enabled())
8401 {
8402 Doxygen::searchIndex.setCurrentDoc(d,anchor,false);
8403 std::string s = title.str();
8404 static const reg::Ex re(R"(\a[\w-]*)");
8405 reg::Iterator it(s,re);
8407 for (; it!=end ; ++it)
8408 {
8409 const auto &match = *it;
8410 std::string matchStr = match.str();
8411 Doxygen::searchIndex.addWord(matchStr,true);
8412 }
8413 }
8414 };
8415
8416 for (const auto &gd : *Doxygen::groupLinkedMap)
8417 {
8418 if (gd->isLinkableInProject())
8419 {
8420 addWordsForTitle(gd.get(),gd->anchor(),gd->groupTitle());
8421 }
8422 }
8423
8424 for (const auto &pd : *Doxygen::pageLinkedMap)
8425 {
8426 if (pd->isLinkableInProject())
8427 {
8428 addWordsForTitle(pd.get(),pd->anchor(),pd->title());
8429 }
8430 }
8431
8433 {
8434 addWordsForTitle(Doxygen::mainPage.get(),Doxygen::mainPage->anchor(),Doxygen::mainPage->title());
8435 }
8436
8437 auto addMemberToSearchIndex = [](const MemberDef *md)
8438 {
8439 if (Doxygen::searchIndex.enabled())
8440 {
8441 Doxygen::searchIndex.setCurrentDoc(md,md->anchor(),false);
8442 DString ln=md->localName();
8443 DString qn=md->qualifiedName();
8445 if (ln!=qn)
8446 {
8448 if (md->getClassDef())
8449 {
8450 Doxygen::searchIndex.addWord(md->getClassDef()->displayName(),true);
8451 }
8452 if (md->getNamespaceDef())
8453 {
8454 Doxygen::searchIndex.addWord(md->getNamespaceDef()->displayName(),true);
8455 }
8456 }
8457 }
8458 };
8459
8460 auto getScope = [](const MemberDef *md)
8461 {
8462 const Definition *scope = nullptr;
8463 if (md->getGroupDef()) scope = md->getGroupDef();
8464 else if (md->getClassDef()) scope = md->getClassDef();
8465 else if (md->getNamespaceDef()) scope = md->getNamespaceDef();
8466 else if (md->getFileDef()) scope = md->getFileDef();
8467 return scope;
8468 };
8469
8470 auto addMemberToIndices = [addMemberToSearchIndex,getScope](const MemberDef *md)
8471 {
8472 if (md->isLinkableInProject())
8473 {
8474 if (!(md->isEnumerate() && md->isAnonymous()))
8475 {
8476 Doxygen::indexList->addIndexItem(getScope(md),md);
8477 addMemberToSearchIndex(md);
8478 }
8479 if (md->isEnumerate())
8480 {
8481 for (const auto &fmd : md->enumFieldList())
8482 {
8483 Doxygen::indexList->addIndexItem(getScope(fmd),fmd);
8484 addMemberToSearchIndex(fmd);
8485 }
8486 }
8487 }
8488 };
8489
8490 // for each class member name
8491 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8492 {
8493 // for each member definition
8494 for (const auto &md : *mn)
8495 {
8496 addMemberToIndices(md.get());
8497 }
8498 }
8499 // for each file/namespace function name
8500 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8501 {
8502 // for each member definition
8503 for (const auto &md : *mn)
8504 {
8505 addMemberToIndices(md.get());
8506 }
8507 }
8508}
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:239
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:4455

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 3304 of file doxygen.cpp.

3305{
3306 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
3307
3308 AUTO_TRACE("VARIABLE_SEC: type='{}' name='{}' args='{}' bodyLine={} endBodyLine={} mGrpId={} relates='{}'",
3309 root->type, root->name, root->args, root->bodyLine, root->endBodyLine, root->mGrpId, root->relates);
3310 //printf("root->parent->name=%s\n",qPrint(root->parent->name));
3311
3312 DString type = root->type;
3313 DString name = root->name;
3314 DString args = root->args;
3315 if (type.empty() && name.find("operator")==DString::npos &&
3316 (name.find('*')!=DString::npos || name.find('&')!=DString::npos))
3317 {
3318 // recover from parse error caused by redundant braces
3319 // like in "int *(var[10]);", which is parsed as
3320 // type="" name="int *" args="(var[10])"
3321
3322 type=name;
3323 std::string sargs = args.str();
3324 static const reg::Ex reName(R"(\a\w*)");
3326 if (reg::search(sargs,match,reName))
3327 {
3328 name = match.str(); // e.g. 'var' in '(var[10])'
3329 sargs = match.suffix().str(); // e.g. '[10]) in '(var[10])'
3330 size_t j = sargs.find(')');
3331 if (j!=std::string::npos) args=sargs.substr(0,j); // extract, e.g '[10]' from '[10])'
3332 }
3333 }
3334 else
3335 {
3336 int i=isFuncPtr;
3337 if (i==-1 && (root->spec.isAlias())==0) i=findFunctionPtr(type.str(),root->lang); // for typedefs isFuncPtr is not yet set
3338 AUTO_TRACE_ADD("functionPtr={}",i!=-1?"yes":"no");
3339 if (i>=0) // function pointer
3340 {
3341 size_t ii = i;
3342 size_t ai = type.find('[',ii);
3343 if (ai!=DString::npos && ai>ii) // function pointer array
3344 {
3345 args.prepend(type.mid(ai));
3346 type=type.left(ai);
3347 }
3348 else if (type.find(')',ii)!=DString::npos) // function ptr, not variable like "int (*bla)[10]"
3349 {
3350 type=type.left(type.length()-1);
3351 args.prepend(") ");
3352 }
3353 }
3354 }
3355 AUTO_TRACE_ADD("after correction: type='{}' name='{}' args='{}'",type,name,args);
3356
3357 DString scope;
3358 name=removeRedundantWhiteSpace(name);
3359
3360 // find the scope of this variable
3361 int index = computeQualifiedIndex(name);
3362 // grouped members are stored with full scope
3363 bool qualifiedGroupMember = index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo();
3364 // A specialization of a variable template that lives in a namespace, i.e.
3365 // `template<class T> constexpr bool std::ranges::enable_view<MyView<T>> = true;`.
3366 // Its scope has to be spelled out, so it must not be mistaken for the definition of a static
3367 // data member, which is declared in its class as well and is therefore picked up from there.
3368 bool variableTemplateSpecialization = index!=-1 && !root->tArgLists.empty() &&
3369 name.mid(index+2).find('<')!=DString::npos &&
3370 getClass(name.left(index))==nullptr;
3371 if (qualifiedGroupMember || variableTemplateSpecialization)
3372 {
3373 Definition *d = buildScopeFromQualifiedName(name.left(index+2),root->lang,root->tagInfo());
3374 if (variableTemplateSpecialization)
3375 // the scope may have been made up for this specialization, but it holds a documented member
3376 // now, which is only reachable through a page of its own
3377 {
3378 for (Definition *s=d; s && s!=Doxygen::globalScope; s=s->getOuterScope())
3379 {
3381 if (ndm && ndm->isArtificial()) ndm->setArtificial(false);
3382 }
3383 }
3384 scope=name.left(index);
3385 name=name.mid(index+2);
3386 }
3387 else
3388 {
3389 Entry *p = root->parent();
3390 while (p->section.isScope())
3391 {
3392 DString scopeName = p->name;
3393 if (!scopeName.empty())
3394 {
3395 scope.prepend(scopeName);
3396 break;
3397 }
3398 p=p->parent();
3399 }
3400 }
3401
3402 DString type_s = type;
3403 type=type.stripWhiteSpace();
3404 ClassDefMutable *cd=nullptr;
3405 bool isRelated=false;
3406 bool isMemberOf=false;
3407
3408 DString classScope=stripAnonymousNamespaceScope(scope);
3409 if (root->lang==SrcLangExt::CSharp)
3410 {
3411 classScope=mangleCSharpGenericName(classScope);
3412 }
3413 else
3414 {
3415 classScope=stripTemplateSpecifiersFromScope(classScope,false);
3416 }
3417 DString annScopePrefix=scope.left(scope.length()-classScope.length());
3418
3419
3420 // Look for last :: not part of template specifier
3421 int p=-1;
3422 for (size_t i=0;i<name.length()-1;i++)
3423 {
3424 if (name[i]==':' && name[i+1]==':')
3425 {
3426 p=static_cast<int>(i);
3427 }
3428 else if (name[i]=='<') // skip over template parts,
3429 // i.e. A::B<C::D> => p=1 and
3430 // A<B::C>::D => p=8
3431 {
3432 int e = findEndOfTemplate(name,i+1);
3433 if (e!=-1) i=static_cast<int>(e);
3434 }
3435 }
3436
3437 if (p!=-1) // found it
3438 {
3439 if (isTypeAClassFriend(type))
3440 {
3441 cd=getClassMutable(scope);
3442 if (cd)
3443 {
3444 addVariableToClass(root, // entry
3445 cd, // class to add member to
3446 MemberType::Friend, // type of member
3447 type, // type value as string
3448 name, // name of the member
3449 args, // arguments as string
3450 Protection::Public, // protection
3451 Relationship::Member // related to a class
3452 );
3453 }
3454 }
3455 if (root->bodyLine!=-1 && root->endBodyLine!=-1) // store the body location for later use
3456 {
3457 Doxygen::staticInitMap.emplace(name.str(),BodyInfo{root->startLine,root->bodyLine,root->endBodyLine});
3458 }
3459
3460
3461 AUTO_TRACE_ADD("static variable {} body=[{}..{}]",name,root->bodyLine,root->endBodyLine);
3462 return; /* skip this member, because it is a
3463 * static variable definition (always?), which will be
3464 * found in a class scope as well, but then we know the
3465 * correct protection level, so only then it will be
3466 * inserted in the correct list!
3467 */
3468 }
3469
3470 MemberType mtype = MemberType::Variable;
3471 if (type=="@")
3472 mtype=MemberType::EnumValue;
3473 else if (type_s.startsWith("typedef "))
3474 mtype=MemberType::Typedef;
3475 else if (type_s.startsWith("friend ") || type_s=="friend")
3476 mtype=MemberType::Friend;
3477 else if (root->mtype==MethodTypes::Property)
3478 mtype=MemberType::Property;
3479 else if (root->mtype==MethodTypes::Event)
3480 mtype=MemberType::Event;
3481 else if (type.find("sequence<") != DString::npos)
3482 mtype=sliceOpt ? MemberType::Sequence : MemberType::Typedef;
3483 else if (type.find("dictionary<") != DString::npos)
3484 mtype=sliceOpt ? MemberType::Dictionary : MemberType::Typedef;
3485
3486 if (!root->relates.empty()) // related variable
3487 {
3488 isRelated=true;
3489 isMemberOf=(root->relatesType==RelatesType::MemberOf);
3490 if (getClass(root->relates)==nullptr && !scope.empty())
3491 scope=mergeScopes(scope,root->relates);
3492 else
3493 scope=root->relates;
3494 }
3495
3496 cd=getClassMutable(scope);
3497 if (cd==nullptr && classScope!=scope) cd=getClassMutable(classScope);
3498 if (cd)
3499 {
3500 // if cd is an anonymous (=tag less) scope we insert the member
3501 // into a non-anonymous parent scope as well. This is needed to
3502 // be able to refer to it using \var or \fn
3503
3504 Relationship relationship = isMemberOf ? Relationship::Foreign :
3505 isRelated ? Relationship::Related :
3506 Relationship::Member ;
3507
3508 addVariableToClass(root, // entry
3509 cd, // class to add member to
3510 mtype, // member type
3511 type, // type value as string
3512 name, // name of the member
3513 args, // arguments as string
3514 root->protection,
3515 relationship
3516 );
3517 }
3518 else if (!name.empty()) // global variable
3519 {
3520 addVariableToFile(root,mtype,scope,type,name,args);
3521 }
3522
3523}
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
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:154
static int findFunctionPtr(const std::string &type, SrcLangExt lang, int *pLength=nullptr)
Definition doxygen.cpp:3033
static MemberDef * addVariableToFile(const Entry *root, MemberType mtype, const DString &scope, const DString &type, const DString &name, const DString &args)
Definition doxygen.cpp:2780
static int findEndOfTemplate(const DString &s, size_t startPos)
Definition doxygen.cpp:3236
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:2609
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:5294

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 2609 of file doxygen.cpp.

2618{
2620 DString scopeSeparator="::";
2621 SrcLangExt lang = cd->getLanguage();
2622 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
2623 {
2624 qualScope = substitute(qualScope,"::",".");
2625 scopeSeparator=".";
2626 }
2627 AUTO_TRACE("class variable: file='{}' type='{}' scope='{}' name='{}' args='{}' prot={} mtype={} lang={} init='{}'",
2628 root->fileName, type, qualScope, name, args, root->protection, mtype, lang, root->initializer.str());
2629
2630 DString def;
2631 if (!type.empty())
2632 {
2633 if (related!=Relationship::Member || mtype==MemberType::Friend || Config_getBool(HIDE_SCOPE_NAMES))
2634 {
2635 if (root->spec.isAlias()) // turn 'typedef B A' into 'using A'
2636 {
2637 if (lang==SrcLangExt::Python)
2638 {
2639 def="type "+name+args;
2640 }
2641 else
2642 {
2643 def="using "+name;
2644 }
2645 }
2646 else
2647 {
2648 def=type+" "+name+args;
2649 }
2650 }
2651 else
2652 {
2653 if (root->spec.isAlias()) // turn 'typedef B C::A' into 'using C::A'
2654 {
2655 if (lang==SrcLangExt::Python)
2656 {
2657 def="type "+qualScope+scopeSeparator+name+args;
2658 }
2659 else
2660 {
2661 def="using "+qualScope+scopeSeparator+name;
2662 }
2663 }
2664 else
2665 {
2666 def=type+" "+qualScope+scopeSeparator+name+args;
2667 }
2668 }
2669 }
2670 else
2671 {
2672 if (Config_getBool(HIDE_SCOPE_NAMES))
2673 {
2674 def=name+args;
2675 }
2676 else
2677 {
2678 def=qualScope+scopeSeparator+name+args;
2679 }
2680 }
2681 def.stripPrefix("static ");
2682
2683 // see if the member is already found in the same scope
2684 // (this may be the case for a static member that is initialized
2685 // outside the class)
2687 if (mn)
2688 {
2689 for (const auto &imd : *mn)
2690 {
2691 //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n",
2692 // md->getClassDef(),cd,qPrint(type),md->typeString());
2693 MemberDefMutable *md = toMemberDefMutable(imd.get());
2694 if (md &&
2695 md->getClassDef()==cd &&
2696 ((lang==SrcLangExt::Python && type.empty() && !md->typeString().empty()) ||
2698 // member already in the scope
2699 {
2700
2701 if (root->lang==SrcLangExt::ObjC &&
2702 root->mtype==MethodTypes::Property &&
2703 md->memberType()==MemberType::Variable)
2704 { // Objective-C 2.0 property
2705 // turn variable into a property
2706 md->setProtection(root->protection);
2707 cd->reclassifyMember(md,MemberType::Property);
2708 }
2709 addMemberDocs(root,md,def,nullptr,false,root->spec);
2710 AUTO_TRACE_ADD("Member already found!");
2711 return md;
2712 }
2713 }
2714 }
2715
2716 DString fileName = root->fileName;
2717 if (fileName.empty() && root->tagInfo())
2718 {
2719 fileName = root->tagInfo()->tagName;
2720 }
2721
2722 // new member variable, typedef or enum value
2723 auto md = createMemberDef(
2724 fileName,root->startLine,root->startColumn,
2725 type,name,args,root->exception,
2726 prot,Specifier::Normal,root->isStatic,related,
2727 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
2728 ArgumentList(), root->metaData);
2729 auto mmd = toMemberDefMutable(md.get());
2730 mmd->setTagInfo(root->tagInfo());
2731 mmd->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope())
2732 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
2733 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2734 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2735 mmd->setDefinition(def);
2736 mmd->setBitfields(root->bitfields);
2737 mmd->addSectionsToDefinition(root->anchors);
2738 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2739 mmd->setInitializer(root->initializer.str());
2740 mmd->setMaxInitLines(root->initLines);
2741 mmd->setMemberGroupId(root->mGrpId);
2742 mmd->setMemberSpecifiers(root->spec);
2743 mmd->setVhdlSpecifiers(root->vhdlSpec);
2744 mmd->setReadAccessor(root->read);
2745 mmd->setWriteAccessor(root->write);
2747 mmd->setHidden(root->hidden);
2748 mmd->setArtificial(root->artificial);
2749 mmd->setLanguage(root->lang);
2750 mmd->setId(root->id);
2751 addMemberToGroups(root,md.get());
2753 mmd->setBodyDef(root->fileDef());
2754 mmd->addQualifiers(root->qualifiers);
2755 addIncludeFile(mmd,root->fileDef(),root);
2756
2757 AUTO_TRACE_ADD("Adding new member '{}' to class '{}'",name,cd->name());
2758 cd->insertMember(md.get());
2759 mmd->setRefItems(root->sli);
2760 mmd->setRequirementReferences(root->rqli);
2761
2762 cd->insertUsedFile(root->fileDef());
2763 root->markAsProcessed();
2764
2765 if (mtype==MemberType::Typedef)
2766 {
2767 resolveTemplateInstanceInType(root,cd,md.get());
2768 }
2769
2770 // add the member to the global list
2771 MemberDef *result = md.get();
2773 mn->push_back(std::move(md));
2774
2775 return result;
2776}
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:4950

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 2780 of file doxygen.cpp.

2787{
2788 AUTO_TRACE("global variable: file='{}' type='{}' scope='{}' name='{}' args='{}' prot={} mtype={} lang={} init='{}'",
2789 root->fileName, type, scope, name, args, root->protection, mtype, root->lang, root->initializer.str());
2790
2791 FileDef *fd = root->fileDef();
2792
2793 // see if we have a typedef that should hide a struct or union
2794 if (mtype==MemberType::Typedef && Config_getBool(TYPEDEF_HIDES_STRUCT))
2795 {
2796 DString ttype = type;
2797 ttype.stripPrefix("typedef ");
2798 if (ttype.stripPrefix("struct ") || ttype.stripPrefix("union "))
2799 {
2800 static const reg::Ex re(R"(\a\w*)");
2802 const std::string &typ = ttype.str();
2803 if (reg::search(typ,match,re))
2804 {
2805 DString typeValue = match.str();
2806 ClassDefMutable *cd = getClassMutable(typeValue);
2807 if (cd)
2808 {
2809 // this typedef should hide compound name cd, so we
2810 // change the name that is displayed from cd.
2811 cd->setClassName(name);
2812 cd->setDocumentation(root->doc,root->docFile,root->docLine);
2813 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2814 return nullptr;
2815 }
2816 }
2817 }
2818 }
2819
2820 // see if the function is inside a namespace
2821 NamespaceDefMutable *nd = nullptr;
2822 if (!scope.empty())
2823 {
2824 if (scope.find('@')!=DString::npos) return nullptr; // anonymous scope!
2825 nd = getResolvedNamespaceMutable(scope);
2826 }
2827 DString def;
2828
2829 // determine the definition of the global variable
2830 if (nd && !nd->isAnonymous() &&
2831 !Config_getBool(HIDE_SCOPE_NAMES)
2832 )
2833 // variable is inside a namespace, so put the scope before the name
2834 {
2835 SrcLangExt lang = nd->getLanguage();
2837
2838 if (!type.empty())
2839 {
2840 if (root->spec.isAlias()) // turn 'typedef B NS::A' into 'using NS::A'
2841 {
2842 if (lang==SrcLangExt::Python)
2843 {
2844 def="type "+nd->name()+sep+name+args;
2845 }
2846 else
2847 {
2848 def="using "+nd->name()+sep+name;
2849 }
2850 }
2851 else // normal member
2852 {
2853 def=type+" "+nd->name()+sep+name+args;
2854 }
2855 }
2856 else
2857 {
2858 def=nd->name()+sep+name+args;
2859 }
2860 }
2861 else
2862 {
2863 if (!type.empty() && !root->name.empty())
2864 {
2865 if (name.at(0)=='@') // dummy variable representing anonymous union
2866 {
2867 def=type;
2868 }
2869 else
2870 {
2871 if (root->spec.isAlias()) // turn 'typedef B A' into 'using A'
2872 {
2873 if (root->lang==SrcLangExt::Python)
2874 {
2875 def="type "+root->name+args;
2876 }
2877 else
2878 {
2879 def="using "+root->name;
2880 }
2881 }
2882 else // normal member
2883 {
2884 def=type+" "+name+args;
2885 }
2886 }
2887 }
2888 else
2889 {
2890 def=name+args;
2891 }
2892 }
2893 def.stripPrefix("static ");
2894
2896 if (mn)
2897 {
2898 //DString nscope=removeAnonymousScopes(scope);
2899 //NamespaceDef *nd=nullptr;
2900 //if (!nscope.empty())
2901 if (!scope.empty())
2902 {
2903 nd = getResolvedNamespaceMutable(scope);
2904 }
2905 for (const auto &imd : *mn)
2906 {
2907 MemberDefMutable *md = toMemberDefMutable(imd.get());
2908 if (md &&
2909 ((nd==nullptr && md->getNamespaceDef()==nullptr && md->getFileDef() &&
2910 root->fileName==md->getFileDef()->absFilePath()
2911 ) // both variable names in the same file
2912 || (nd!=nullptr && md->getNamespaceDef()==nd) // both in same namespace
2913 )
2914 && !md->isDefine() // function style #define's can be "overloaded" by typedefs or variables
2915 && !md->isEnumerate() // in C# an enum value and enum can have the same name
2916 )
2917 // variable already in the scope
2918 {
2919 bool isPHPArray = md->getLanguage()==SrcLangExt::PHP &&
2920 md->argsString()!=args &&
2921 args.find('[')!=DString::npos;
2922 bool staticsInDifferentFiles =
2923 root->isStatic && md->isStatic() &&
2924 root->fileName!=md->getDefFileName();
2925
2926 if (md->getFileDef() &&
2927 !isPHPArray && // not a php array
2928 !staticsInDifferentFiles
2929 )
2930 // not a php array variable
2931 {
2932 AUTO_TRACE_ADD("variable already found: scope='{}'",md->getOuterScope()->name());
2933 addMemberDocs(root,md,def,nullptr,false,root->spec);
2934 md->setRefItems(root->sli);
2935 md->setRequirementReferences(root->rqli);
2936 // if md is a variable forward declaration and root is the definition that
2937 // turn md into the definition
2938 if (!root->explicitExternal && md->isExternal())
2939 {
2940 md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn());
2941 md->setExplicitExternal(false,root->fileName,root->startLine,root->startColumn);
2942 }
2943 // if md is the definition and root point at a declaration, then add the
2944 // declaration info
2945 else if (root->explicitExternal && !md->isExternal())
2946 {
2947 md->setDeclFile(root->fileName,root->startLine,root->startColumn);
2948 }
2949 return md;
2950 }
2951 }
2952 }
2953 }
2954
2955 DString fileName = root->fileName;
2956 if (fileName.empty() && root->tagInfo())
2957 {
2958 fileName = root->tagInfo()->tagName;
2959 }
2960
2961 AUTO_TRACE_ADD("new variable, namespace='{}'",nd?nd->name():DString("<global>"));
2962 // new global variable, enum value or typedef
2963 auto md = createMemberDef(
2964 fileName,root->startLine,root->startColumn,
2965 type,name,args,DString(),
2966 root->protection, Specifier::Normal,root->isStatic,Relationship::Member,
2967 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
2968 root->argList, root->metaData);
2969 auto mmd = toMemberDefMutable(md.get());
2970 mmd->setTagInfo(root->tagInfo());
2971 mmd->setMemberSpecifiers(root->spec);
2972 mmd->setVhdlSpecifiers(root->vhdlSpec);
2973 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
2974 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2975 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2976 mmd->addSectionsToDefinition(root->anchors);
2977 mmd->setInitializer(root->initializer.str());
2978 mmd->setMaxInitLines(root->initLines);
2979 mmd->setMemberGroupId(root->mGrpId);
2980 mmd->setDefinition(def);
2981 mmd->setLanguage(root->lang);
2982 mmd->setId(root->id);
2984 mmd->setExplicitExternal(root->explicitExternal,fileName,root->startLine,root->startColumn);
2985 mmd->addQualifiers(root->qualifiers);
2986 //md->setOuterScope(fd);
2987 if (!root->explicitExternal)
2988 {
2989 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2990 mmd->setBodyDef(fd);
2991 }
2992 addMemberToGroups(root,md.get());
2993 addIncludeFile(mmd,fd,root);
2995
2996 mmd->setRefItems(root->sli);
2997 mmd->setRequirementReferences(root->rqli);
2998 if (nd && !nd->isAnonymous())
2999 {
3000 mmd->setNamespace(nd);
3001 nd->insertMember(md.get());
3002 }
3003
3004 // add member to the file (we do this even if we have already inserted
3005 // it into the namespace.
3006 if (fd)
3007 {
3008 mmd->setFileDef(fd);
3009 fd->insertMember(md.get());
3010 }
3011
3012 root->markAsProcessed();
3013
3014 if (mtype==MemberType::Typedef)
3015 {
3016 resolveTemplateInstanceInType(root,nd,md.get());
3017 }
3018
3019 // add member definition to the list of globals
3020 MemberDef *result = md.get();
3022 mn->push_back(std::move(md));
3023
3024
3025
3026 return result;
3027}
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(), DString::at(), 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 12057 of file doxygen.cpp.

12058{
12059 AUTO_TRACE();
12060 Doxygen::globalNamespaceDef = createNamespaceDef("<globalScope>",1,1,"<globalScope>");
12071
12072 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
12073
12074 /* Set the global html file extension. */
12075 Doxygen::htmlFileExtension = Config_getString(HTML_FILE_EXTENSION);
12076
12077
12079 Config_getBool(CALLER_GRAPH) ||
12080 Config_getBool(REFERENCES_RELATION) ||
12081 Config_getBool(REFERENCED_BY_RELATION);
12082
12083 /**************************************************************************
12084 * Add custom extension mappings
12085 **************************************************************************/
12086
12087 StringVector extMaps = Config_getList(EXTENSION_MAPPING);
12088 for (const auto &mapping : extMaps)
12089 {
12090 DString mapStr = mapping;
12091 if (size_t i=mapStr.find('='); i==DString::npos)
12092 {
12093 continue;
12094 }
12095 else
12096 {
12097 DString ext = mapStr.left(i).stripWhiteSpace().lower();
12098 DString language = mapStr.mid(i+1).stripWhiteSpace().lower();
12099 if (ext.empty() || language.empty())
12100 {
12101 continue;
12102 }
12103
12104 if (!updateLanguageMapping(ext,language))
12105 {
12106 err("Failed to map file extension '{}' to unsupported language '{}'.\n"
12107 "Check the EXTENSION_MAPPING setting in the config file.\n",
12108 ext,language);
12109 }
12110 else
12111 {
12112 msg("Adding custom extension mapping: '{}' will be treated as language '{}'\n",
12113 ext,language);
12114 }
12115 }
12116 }
12117 // create input file exncodings
12118
12119 // check INPUT_ENCODING
12120 void *cd = portable_iconv_open("UTF-8",Config_getString(INPUT_ENCODING).data());
12121 if (cd==reinterpret_cast<void *>(-1))
12122 {
12123 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
12124 "Check the 'INPUT_ENCODING' setting in the config file!\n",
12125 Config_getString(INPUT_ENCODING),strerror(errno));
12126 }
12127 else
12128 {
12130 }
12131
12132 // check and split INPUT_FILE_ENCODING
12133 StringVector fileEncod = Config_getList(INPUT_FILE_ENCODING);
12134 for (const auto &mapping : fileEncod)
12135 {
12136 DString mapStr = mapping;
12137 if (size_t i=mapStr.find('='); i==DString::npos)
12138 {
12139 continue;
12140 }
12141 else
12142 {
12143 DString pattern = mapStr.left(i).stripWhiteSpace().lower();
12144 DString encoding = mapStr.mid(i+1).stripWhiteSpace().lower();
12145 if (pattern.empty() || encoding.empty())
12146 {
12147 continue;
12148 }
12149 cd = portable_iconv_open("UTF-8",encoding.data());
12150 if (cd==reinterpret_cast<void *>(-1))
12151 {
12152 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
12153 "Check the 'INPUT_FILE_ENCODING' setting in the config file!\n",
12154 encoding,strerror(errno));
12155 }
12156 else
12157 {
12159 }
12160
12161 Doxygen::inputFileEncodingList.emplace_back(pattern, encoding);
12162 }
12163 }
12164
12165 // add predefined macro name to a dictionary
12166 StringVector expandAsDefinedList = Config_getList(EXPAND_AS_DEFINED);
12167 for (const auto &s : expandAsDefinedList)
12168 {
12170 }
12171
12172 // read aliases and store them in a dictionary
12173 readAliases();
12174
12175 // store number of spaces in a tab into Doxygen::spaces
12176 int tabSize = Config_getInt(TAB_SIZE);
12177 Doxygen::spaces.resize(tabSize);
12178 for (int sp=0; sp<tabSize; sp++) Doxygen::spaces.at(sp)=' ';
12179 Doxygen::spaces.at(tabSize)='\0';
12180}
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:4064

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 2281 of file doxygen.cpp.

2282{
2283 root->commandOverrides.apply_callGraph ([&](bool b) { md->overrideCallGraph(b); });
2284 root->commandOverrides.apply_callerGraph ([&](bool b) { md->overrideCallerGraph(b); });
2285 root->commandOverrides.apply_referencedByRelation([&](bool b) { md->overrideReferencedByRelation(b); });
2286 root->commandOverrides.apply_referencesRelation ([&](bool b) { md->overrideReferencesRelation(b); });
2287 root->commandOverrides.apply_inlineSource ([&](bool b) { md->overrideInlineSource(b); });
2288 root->commandOverrides.apply_enumValues ([&](bool b) { md->overrideEnumValues(b); });
2289}
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 5618 of file doxygen.cpp.

5619{
5620 for (const auto &cd : *Doxygen::classLinkedMap)
5621 {
5622 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5623 if (cdm)
5624 {
5625 func(cdm);
5626 }
5627 }
5628
5629 for (const auto &cd : *Doxygen::conceptLinkedMap)
5630 {
5631 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
5632 if (cdm)
5633 {
5634 func(cdm);
5635 }
5636 }
5637
5638 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5639 {
5640 for (const auto &fd : *fn)
5641 {
5642 func(fd.get());
5643 }
5644 }
5645
5646 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5647 {
5649 if (ndm)
5650 {
5651 func(ndm);
5652 }
5653 }
5654
5655 for (const auto &gd : *Doxygen::groupLinkedMap)
5656 {
5657 func(gd.get());
5658 }
5659
5660 for (const auto &pd : *Doxygen::pageLinkedMap)
5661 {
5662 func(pd.get());
5663 }
5664
5665 for (const auto &dd : *Doxygen::dirLinkedMap)
5666 {
5667 func(dd.get());
5668 }
5669
5670 func(&ModuleManager::instance());
5671}
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 processTagLessClasses().

◆ 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 8680 of file doxygen.cpp.

8681{
8682 // merge the member list of base classes into the inherited classes.
8683 for (const auto &cd : *Doxygen::classLinkedMap)
8684 {
8685 if (// !cd->isReference() && // not an external class
8686 cd->subClasses().empty() && // is a root of the hierarchy
8687 !cd->baseClasses().empty()) // and has at least one base class
8688 {
8689 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8690 if (cdm)
8691 {
8692 //printf("*** merging members for %s\n",qPrint(cd->name()));
8693 cdm->mergeMembers();
8694 }
8695 }
8696 }
8697 // now sort the member list of all members for all classes.
8698 for (const auto &cd : *Doxygen::classLinkedMap)
8699 {
8700 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8701 if (cdm)
8702 {
8703 cdm->sortAllMembersList();
8704 }
8705 }
8706}
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 9015 of file doxygen.cpp.

9016{
9017 AUTO_TRACE();
9018 for (const auto &s : g_inputFiles)
9019 {
9020 auto it = Doxygen::macroDefinitions.find(s);
9022 {
9023 for (const auto &def : it->second)
9024 {
9025 auto md = createMemberDef(
9026 def.fileName,def.lineNr,def.columnNr,
9027 "#define",def.name,def.args,DString(),
9028 Protection::Public,Specifier::Normal,false,Relationship::Member,MemberType::Define,
9029 ArgumentList(),ArgumentList(),"");
9030 auto mmd = toMemberDefMutable(md.get());
9031
9032 if (!def.args.empty())
9033 {
9034 mmd->moveArgumentList(stringToArgumentList(SrcLangExt::Cpp, def.args));
9035 }
9036 mmd->setInitializer(def.definition);
9037 mmd->setFileDef(def.fileDef);
9038 mmd->setDefinition("#define "+def.name);
9039
9041 if (def.fileDef)
9042 {
9043 const MemberList *defMl = def.fileDef->getMemberList(MemberListType::DocDefineMembers());
9044 if (defMl)
9045 {
9046 const MemberDef *defMd = defMl->findRev(def.name);
9047 if (defMd) // definition already stored
9048 {
9049 mmd->setRedefineCount(defMd->redefineCount()+1);
9050 }
9051 }
9052 def.fileDef->insertMember(md.get());
9053 }
9054 AUTO_TRACE_ADD("adding macro {} with definition {}",def.name,def.definition);
9055 mn->push_back(std::move(md));
9056 }
9057 }
9058 }
9059}
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 3646 of file doxygen.cpp.

3647{
3648 if (!root->name.empty() &&
3649 root->section.isVariable() &&
3650 root->type.find("dictionary<")!=DString::npos // it's a dictionary
3651 )
3652 {
3653 AUTO_TRACE();
3654 addVariable(root);
3655 }
3656 for (const auto &e : root->children())
3657 if (!e->section.isEnum())
3658 buildDictionaryList(e.get());
3659}
static void buildDictionaryList(const Entry *root)
Definition doxygen.cpp:3646
static void addVariable(const Entry *root, int isFuncPtr=-1)
Definition doxygen.cpp:3304

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 10069 of file doxygen.cpp.

10070{
10071 if ((root->section.isExample() || root->section.isExampleLineno()) && !root->name.empty())
10072 {
10073 if (Doxygen::exampleLinkedMap->find(root->name))
10074 {
10075 warn(root->fileName,root->startLine,"Example {} was already documented. Ignoring documentation found here.",root->name);
10076 }
10077 else
10078 {
10080 createPageDef(root->fileName,root->startLine,
10081 root->name,root->brief+root->doc+root->inbodyDocs,root->args));
10082 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
10083 pd->setFileName(convertNameToFile(pd->name()+"-example",false,true));
10085 pd->setLanguage(root->lang);
10086 pd->setShowLineNo(root->section.isExampleLineno());
10087
10088 //we don't add example to groups
10089 //addExampleToGroups(root,pd);
10090 }
10091 }
10092 for (const auto &e : root->children()) buildExampleList(e.get());
10093}
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:2864

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 4060 of file doxygen.cpp.

4061{
4062 if (root->section.isFunction())
4063 {
4064 AUTO_TRACE("member function: type='{}' scope='{}' name='{}' args='{}' relates='{}' relatesType='{}'"
4065 " file='{}' line={} bodyLine={} #tArgLists={} mGrpId={}"
4066 " spec={} proto={} docFile='{}'",
4067 root->type, root->parent()->name, root->name, root->args, root->relates, root->relatesType,
4068 root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(), root->mGrpId,
4069 root->spec, root->proto, root->docFile);
4070
4071 bool isFriend=root->type=="friend" || root->type.find("friend ")!=DString::npos;
4072 DString rname = removeRedundantWhiteSpace(root->name);
4073 //printf("rname=%s\n",qPrint(rname));
4074
4075 DString scope;
4076 int index = computeQualifiedIndex(rname);
4077 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
4078 // grouped members are stored with full scope
4079 {
4080 buildScopeFromQualifiedName(rname.left(index+2),root->lang,root->tagInfo());
4081 scope=rname.left(index);
4082 rname=rname.mid(index+2);
4083 }
4084 else
4085 {
4086 scope=root->parent()->name; //stripAnonymousNamespaceScope(root->parent->name);
4087 }
4088 if (!rname.empty() && scope.find('@')==DString::npos)
4089 {
4090 // check if this function's parent is a class
4091 if (root->lang==SrcLangExt::CSharp)
4092 {
4093 scope=mangleCSharpGenericName(scope);
4094 }
4095 else
4096 {
4097 scope=stripTemplateSpecifiersFromScope(scope,false);
4098 }
4099
4100 FileDef *rfd=root->fileDef();
4101
4102 size_t memIndex=rname.rfind("::");
4103
4105 if (cd && scope+"::"==rname.left(scope.length()+2)) // found A::f inside A
4106 {
4107 // strip scope from name
4108 rname=rname.mid(root->parent()->name.length()+2);
4109 }
4110
4111 bool isMember=false;
4112 if (memIndex!=DString::npos)
4113 {
4114 size_t ts=rname.find('<');
4115 size_t te=rname.find('>');
4116 if (memIndex>0 && (ts==DString::npos || te==DString::npos))
4117 {
4118 // note: the following code was replaced by inMember=true to deal with a
4119 // function rname='X::foo' of class X inside a namespace also called X...
4120 // bug id 548175
4121 //nd = Doxygen::namespaceLinkedMap->find(rname.left(memIndex));
4122 //isMember = nd==nullptr;
4123 //if (nd)
4124 //{
4125 // // strip namespace scope from name
4126 // scope=rname.left(memIndex);
4127 // rname=rname.mid(memIndex+2);
4128 //}
4129 isMember = true;
4130 }
4131 else
4132 {
4133 isMember=memIndex<ts || memIndex>te;
4134 }
4135 }
4136
4137 if (!root->parent()->name.empty() && root->parent()->section.isCompound() && cd)
4138 {
4139 AUTO_TRACE_ADD("member '{}' of class '{}'", rname,cd->name());
4140 addMethodToClass(root,cd,root->type,rname,root->args,isFriend,
4141 root->protection,root->isStatic,root->virt,root->spec,root->relates);
4142 }
4143 else if (root->parent()->section.isObjcImpl() && cd)
4144 {
4145 const MemberDef *md = cd->getMemberByName(rname);
4146 if (md)
4147 {
4148 MemberDefMutable *mdm = toMemberDefMutable(const_cast<MemberDef*>(md));
4149 if (mdm)
4150 {
4151 mdm->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
4152 mdm->setBodyDef(root->fileDef());
4153 }
4154 }
4155 }
4156 else if (!root->parent()->section.isCompound() && !root->parent()->section.isObjcImpl() &&
4157 !isMember &&
4158 (root->relates.empty() || root->relatesType==RelatesType::Duplicate) &&
4159 !root->type.startsWith("extern ") && !root->type.startsWith("typedef ")
4160 )
4161 // no member => unrelated function
4162 {
4163 /* check the uniqueness of the function name in the file.
4164 * A file could contain a function prototype and a function definition
4165 * or even multiple function prototypes.
4166 */
4167 bool found=false;
4168 MemberDef *md_found=nullptr;
4170 if (mn)
4171 {
4172 AUTO_TRACE_ADD("function '{}' already found",rname);
4173 for (const auto &imd : *mn)
4174 {
4175 MemberDefMutable *md = toMemberDefMutable(imd.get());
4176 if (md)
4177 {
4178 const NamespaceDef *mnd = md->getNamespaceDef();
4179 NamespaceDef *rnd = nullptr;
4180 //printf("root namespace=%s\n",qPrint(rootNav->parent()->name()));
4181 DString fullScope = scope;
4182 DString parentScope = root->parent()->name;
4183 if (!parentScope.empty() && !leftScopeMatch(parentScope,scope))
4184 {
4185 if (!scope.empty()) fullScope.prepend("::");
4186 fullScope.prepend(parentScope);
4187 }
4188 //printf("fullScope=%s\n",qPrint(fullScope));
4189 rnd = getResolvedNamespace(fullScope);
4190 const FileDef *mfd = md->getFileDef();
4191 DString nsName,rnsName;
4192 if (mnd) nsName = mnd->name();
4193 if (rnd) rnsName = rnd->name();
4194 //printf("matching arguments for %s%s %s%s\n",
4195 // qPrint(md->name()),md->argsString(),qPrint(rname),qPrint(argListToString(root->argList)));
4196 const ArgumentList &mdAl = md->argumentList();
4197 const ArgumentList &mdTempl = md->templateArguments();
4198
4199 // in case of template functions, we need to check if the
4200 // functions have the same number of template parameters
4201 bool sameTemplateArgs = true;
4202 bool matchingReturnTypes = true;
4203 bool sameRequiresClause = true;
4204 if (!mdTempl.empty() && !root->tArgLists.empty())
4205 {
4206 sameTemplateArgs = matchTemplateArguments(mdTempl,root->tArgLists.back());
4207 if (md->typeString()!=removeRedundantWhiteSpace(root->type))
4208 {
4209 matchingReturnTypes = false;
4210 }
4211 if (md->requiresClause()!=root->req)
4212 {
4213 sameRequiresClause = false;
4214 }
4215 }
4216 else if (!mdTempl.empty() || !root->tArgLists.empty())
4217 { // if one has template parameters and the other doesn't then that also counts as a
4218 // difference
4219 sameTemplateArgs = false;
4220 }
4221
4222 bool staticsInDifferentFiles =
4223 root->isStatic && md->isStatic() && root->fileName!=md->getDefFileName();
4224
4225 if (sameTemplateArgs &&
4226 matchingReturnTypes &&
4227 sameRequiresClause &&
4228 !staticsInDifferentFiles &&
4229 matchArguments2(md->getOuterScope(),mfd,md->typeString(),&mdAl,
4230 rnd ? rnd : Doxygen::globalScope,rfd,root->type,&root->argList,
4231 false,root->lang)
4232 )
4233 {
4234 GroupDef *gd=nullptr;
4235 if (!root->groups.empty() && !root->groups.front().groupname.empty())
4236 {
4237 gd = Doxygen::groupLinkedMap->find(root->groups.front().groupname);
4238 }
4239 //printf("match!\n");
4240 //printf("mnd=%p rnd=%p nsName=%s rnsName=%s\n",mnd,rnd,qPrint(nsName),qPrint(rnsName));
4241 // see if we need to create a new member
4242 found=(mnd && rnd && nsName==rnsName) || // members are in the same namespace
4243 ((mnd==nullptr && rnd==nullptr && mfd!=nullptr && // no external reference and
4244 mfd->absFilePath()==root->fileName // prototype in the same file
4245 )
4246 );
4247 // otherwise, allow a duplicate global member with the same argument list
4248 if (!found && gd && gd==md->getGroupDef() && nsName==rnsName)
4249 {
4250 // member is already in the group, so we don't want to add it again.
4251 found=true;
4252 }
4253
4254 AUTO_TRACE_ADD("combining function with prototype found={} in namespace '{}'",found,nsName);
4255
4256 if (found)
4257 {
4258 // merge argument lists
4259 ArgumentList mergedArgList = root->argList;
4260 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.empty());
4261 // merge documentation
4262 if (md->documentation().empty() && !root->doc.empty())
4263 {
4264 if (root->proto)
4265 {
4267 }
4268 else
4269 {
4271 }
4272 }
4273
4274 md->setDocumentation(root->doc,root->docFile,root->docLine);
4276 md->setDocsForDefinition(!root->proto);
4277 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
4278 {
4279 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
4280 md->setBodyDef(rfd);
4281 }
4282
4283 if (md->briefDescription().empty() && !root->brief.empty())
4284 {
4285 md->setArgsString(root->args);
4286 }
4287 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
4288
4290
4292 md->addQualifiers(root->qualifiers);
4293
4294 // merge ingroup specifiers
4295 if (md->getGroupDef()==nullptr && !root->groups.empty())
4296 {
4297 addMemberToGroups(root,md);
4298 }
4299 else if (md->getGroupDef()!=nullptr && root->groups.empty())
4300 {
4301 //printf("existing member is grouped, new member not\n");
4302 }
4303 else if (md->getGroupDef()!=nullptr && !root->groups.empty())
4304 {
4305 //printf("both members are grouped\n");
4306 }
4308
4309 // if md is a declaration and root is the corresponding
4310 // definition, then turn md into a definition.
4311 if (md->isPrototype() && !root->proto)
4312 {
4313 md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn());
4314 md->setPrototype(false,root->fileName,root->startLine,root->startColumn);
4315 }
4316 // if md is already the definition, then add the declaration info
4317 else if (!md->isPrototype() && root->proto)
4318 {
4319 md->setDeclFile(root->fileName,root->startLine,root->startColumn);
4320 }
4321 }
4322 }
4323 }
4324 if (found)
4325 {
4326 md_found = md;
4327 break;
4328 }
4329 }
4330 }
4331 if (!found) /* global function is unique with respect to the file */
4332 {
4333 addGlobalFunction(root,rname,scope);
4334 }
4335 else
4336 {
4337 FileDef *fd=root->fileDef();
4338 if (fd)
4339 {
4340 // add member to the file (we do this even if we have already
4341 // inserted it into the namespace)
4342 fd->insertMember(md_found);
4343 }
4344 }
4345
4346 AUTO_TRACE_ADD("unrelated function type='{}' name='{}' args='{}'",root->type,rname,root->args);
4347 }
4348 else
4349 {
4350 AUTO_TRACE_ADD("function '{}' is not processed",rname);
4351 }
4352 }
4353 else if (rname.empty())
4354 {
4355 warn(root->fileName,root->startLine,
4356 "Illegal member name found."
4357 );
4358 }
4359 }
4360 for (const auto &e : root->children()) buildFunctionList(e.get());
4361}
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:4060
static void addGlobalFunction(const Entry *root, const DString &rname, const DString &sc)
Definition doxygen.cpp:3950
bool matchTemplateArguments(const ArgumentList &srcAl, const ArgumentList &dstAl)
Definition util.cpp:1833

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 3761 of file doxygen.cpp.

3762{
3763 if (root->section.isExportedInterface() || root->section.isIncludedService())
3764 {
3765 AUTO_TRACE("Exported interface/included service: type='{}' scope='{}' name='{}' args='{}'"
3766 " relates='{}' relatesType='{}' file='{}' line={} bodyLine={} #tArgLists={}"
3767 " mGrpId={} spec={} proto={} docFile='{}'",
3768 root->type, root->parent()->name, root->name, root->args,
3769 root->relates, root->relatesType, root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(),
3770 root->mGrpId, root->spec, root->proto, root->docFile);
3771
3772 DString rname = removeRedundantWhiteSpace(root->name);
3773
3774 if (!rname.empty())
3775 {
3776 DString scope = root->parent()->name;
3777 ClassDefMutable *cd = getClassMutable(scope);
3778 ASSERT(cd);
3779 if (cd && ((ClassDef::Interface == cd->compoundType()) ||
3780 (ClassDef::Service == cd->compoundType()) ||
3782 {
3784 }
3785 else
3786 {
3787 ASSERT(false); // was checked by scanner.l
3788 }
3789 }
3790 else if (rname.empty())
3791 {
3792 warn(root->fileName,root->startLine,
3793 "Illegal member name found.");
3794 }
3795 }
3796 // can only have these in IDL anyway
3797 switch (root->lang)
3798 {
3799 case SrcLangExt::Unknown: // fall through (root node always is Unknown)
3800 case SrcLangExt::IDL:
3801 for (const auto &e : root->children()) buildInterfaceAndServiceList(e.get());
3802 break;
3803 default:
3804 return; // nothing to do here
3805 }
3806}
@ 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:3697
static void buildInterfaceAndServiceList(const Entry *root)
Definition doxygen.cpp:3761
#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 2176 of file doxygen.cpp.

2177{
2178 if (root->section.isUsingDecl() &&
2179 !root->parent()->section.isCompound() // not a class/struct member
2180 )
2181 {
2182 DString name = substitute(root->name,".","::");
2183 g_usingDeclarations.insert(name.str());
2184 }
2185 for (const auto &e : root->children()) buildListOfUsingDecls(e.get());
2186}
static StringSet g_usingDeclarations
Definition doxygen.cpp:193
static void buildListOfUsingDecls(const Entry *root)
Definition doxygen.cpp:2176

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

Referenced by buildListOfUsingDecls(), and parseInput().

◆ buildNamespaceList()

void buildNamespaceList ( const Entry * root)
static

Definition at line 1848 of file doxygen.cpp.

1849{
1850 if (
1851 (root->section.isNamespace() ||
1852 root->section.isNamespaceDoc() ||
1853 root->section.isPackageDoc()
1854 ) &&
1855 !root->name.empty()
1856 )
1857 {
1858 AUTO_TRACE("name={}",root->name);
1859
1860 DString fName = root->name;
1861 if (root->section.isPackageDoc())
1862 {
1863 fName=substitute(fName,".","::");
1864 }
1865
1866 DString fullName = stripAnonymousNamespaceScope(fName);
1867 if (!fullName.empty())
1868 {
1869 AUTO_TRACE_ADD("Found namespace {} in {} at line {}",root->name,root->fileName,root->startLine);
1871 if (ndi) // existing namespace
1872 {
1874 if (nd) // non-inline namespace
1875 {
1876 AUTO_TRACE_ADD("Existing namespace");
1877 nd->setDocumentation(root->doc,root->docFile,root->docLine);
1878 nd->setName(fullName); // change name to match docs
1880 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1881 if (nd->getLanguage()==SrcLangExt::Unknown)
1882 {
1883 nd->setLanguage(root->lang);
1884 }
1885 if (root->tagInfo()==nullptr && nd->isReference() && !(root->doc.empty() && root->brief.empty()))
1886 // if we previously found namespace nd in a tag file and now we find a
1887 // documented namespace with the same name in the project, then remove
1888 // the tag file reference
1889 {
1890 nd->setReference("");
1891 nd->setFileName(fullName);
1892 }
1893 nd->setMetaData(root->metaData);
1894
1895 // file definition containing the namespace nd
1896 FileDef *fd=root->fileDef();
1897 if (nd->isArtificial())
1898 {
1899 nd->setArtificial(false); // found namespace explicitly, so cannot be artificial
1900 nd->setDefFile(root->fileName,root->startLine,root->startColumn);
1901 }
1902 // insert the namespace in the file definition
1903 if (fd) fd->insertNamespace(nd);
1904 addNamespaceToGroups(root,nd);
1905 nd->setRefItems(root->sli);
1906 nd->setRequirementReferences(root->rqli);
1907 addIncludeFile(nd,fd,root);
1908 }
1909 }
1910 else // fresh namespace
1911 {
1912 DString tagName;
1913 DString tagFileName;
1914 const TagInfo *tagInfo = root->tagInfo();
1915 if (tagInfo)
1916 {
1917 tagName = tagInfo->tagName;
1918 tagFileName = tagInfo->fileName;
1919 }
1920 AUTO_TRACE_ADD("new namespace {} lang={} tagName={}",fullName,root->lang,tagName);
1921 // add namespace to the list
1923 Doxygen::namespaceLinkedMap->add(fullName,
1924 createNamespaceDef(tagInfo?tagName:root->fileName,root->startLine,
1925 root->startColumn,fullName,tagName,tagFileName,
1926 root->type,root->spec.isPublished())));
1927 if (nd)
1928 {
1929 nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1930 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1932 nd->setHidden(root->hidden);
1933 nd->setArtificial(root->artificial);
1934 nd->setLanguage(root->lang);
1935 nd->setId(root->id);
1936 nd->setMetaData(root->metaData);
1937 nd->setInline(root->spec.isInline());
1938 nd->setExported(root->exported);
1939
1940 addNamespaceToGroups(root,nd);
1941 nd->setRefItems(root->sli);
1942 nd->setRequirementReferences(root->rqli);
1943
1944 // file definition containing the namespace nd
1945 FileDef *fd=root->fileDef();
1946 // insert the namespace in the file definition
1947 if (fd) fd->insertNamespace(nd);
1948
1949 // the empty string test is needed for extract all case
1950 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1951 nd->insertUsedFile(fd);
1952 nd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1953 nd->setBodyDef(fd);
1954 addIncludeFile(nd,fd,root);
1955
1956 // also add namespace to the correct structural context
1957 Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName,nullptr,tagInfo);
1958 AUTO_TRACE_ADD("adding namespace {} to context {}",nd->name(),d ? d->name() : DString("<none>"));
1959 if (d==nullptr) // we didn't find anything, create the scope artificially
1960 // anyway, so we can at least relate scopes properly.
1961 {
1962 d = buildScopeFromQualifiedName(fullName,nd->getLanguage(),tagInfo);
1964 if (dm)
1965 {
1966 dm->addInnerCompound(nd);
1967 }
1968 nd->setOuterScope(d);
1969 // TODO: Due to the order in which the tag file is written
1970 // a nested class can be found before its parent!
1971 }
1972 else
1973 {
1975 if (dm)
1976 {
1977 dm->addInnerCompound(nd);
1978 }
1979 nd->setOuterScope(d);
1980 // in case of d is an inline namespace, alias insert nd in the part scope of d.
1982 {
1983 NamespaceDef *pnd = toNamespaceDef(d);
1984 if (pnd && pnd->isInline())
1985 {
1986 d = d->getOuterScope();
1987 if (d)
1988 {
1989 dm = toDefinitionMutable(d);
1990 if (dm)
1991 {
1992 auto aliasNd = createNamespaceDefAlias(d,nd);
1993 dm->addInnerCompound(aliasNd.get());
1994 DString aliasName = aliasNd->name();
1995 AUTO_TRACE_ADD("adding alias {} to {}",aliasName,d->name());
1996 Doxygen::namespaceLinkedMap->add(aliasName,std::move(aliasNd));
1997 }
1998 }
1999 else
2000 {
2001 break;
2002 }
2003 }
2004 else
2005 {
2006 break;
2007 }
2008 }
2009 }
2010 }
2011 }
2012 }
2013 }
2014 for (const auto &e : root->children()) buildNamespaceList(e.get());
2015}
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:1848
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 9825 of file doxygen.cpp.

9826{
9827 if (root->section.isPageDoc())
9828 {
9829 if (!root->name.empty())
9830 {
9831 addRelatedPage(root);
9832 }
9833 }
9834 else if (root->section.isMainpageDoc())
9835 {
9836 DString title=root->args.stripWhiteSpace();
9837 if (title.empty()) title=theTranslator->trMainPage();
9838 //DString name = Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9839 DString name = "index";
9840 addRefItem(root->sli,
9841 name,
9842 theTranslator->trPage(true,true),
9843 name,
9844 title,
9845 DString(),nullptr
9846 );
9847 }
9848 for (const auto &e : root->children()) buildPageList(e.get());
9849}
virtual DString trPage(bool first_capital, bool singular)=0
virtual DString trMainPage()=0
static void buildPageList(Entry *root)
Definition doxygen.cpp:9825
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 9813 of file doxygen.cpp.

9814{
9815 if (root->section.isRequirementDoc())
9816 {
9818 }
9819 for (const auto &e : root->children()) buildRequirementsList(e.get());
9820}
static RequirementManager & instance()
void addRequirement(Entry *e)
static void buildRequirementsList(Entry *root)
Definition doxygen.cpp:9813

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{
726 DString name = stripTemplateSpecifiers(name_);
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}
int contains(char c, bool cs=true) const
Definition dstring.cpp:85
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:3799

References DefinitionMutable::addInnerCompound(), DString::contains(), createNamespaceDef(), DString::empty(), TagInfo::fileName, DString::find(), LinkedMap< T, Hash, KeyEqual, Map >::find(), getClass(), getScopeFragment(), Doxygen::globalScope, DString::mid(), Doxygen::namespaceLinkedMap, DString::npos, DefinitionMutable::setArtificial(), DefinitionMutable::setLanguage(), DefinitionMutable::setOuterScope(), DString::stripPrefix(), 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 3628 of file doxygen.cpp.

3629{
3630 if (!root->name.empty() &&
3631 root->section.isVariable() &&
3632 root->type.find("sequence<")!=DString::npos // it's a sequence
3633 )
3634 {
3635 AUTO_TRACE();
3636 addVariable(root);
3637 }
3638 for (const auto &e : root->children())
3639 if (!e->section.isEnum())
3640 buildSequenceList(e.get());
3641}
static void buildSequenceList(const Entry *root)
Definition doxygen.cpp:3628

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 3528 of file doxygen.cpp.

3529{
3530 //printf("buildVarList(%s)\n",qPrint(rootNav->name()));
3531 if (!root->name.empty() &&
3532 root->section.isVariable() &&
3533 root->type.find("typedef ")!=DString::npos // its a typedef
3534 )
3535 {
3536 AUTO_TRACE();
3537 DString rname = removeRedundantWhiteSpace(root->name);
3538 DString scope;
3539 int index = computeQualifiedIndex(rname);
3540 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
3541 // grouped members are stored with full scope
3542 {
3543 buildScopeFromQualifiedName(rname.left(index+2),root->lang,root->tagInfo());
3544 scope=rname.left(index);
3545 rname=rname.mid(index+2);
3546 }
3547 else
3548 {
3549 scope=root->parent()->name; //stripAnonymousNamespaceScope(root->parent->name);
3550 }
3554 bool found=false;
3555 if (mn) // symbol with the same name already found
3556 {
3557 for (auto &imd : *mn)
3558 {
3559 if (!imd->isTypedef())
3560 continue;
3561
3562 DString rtype = root->type;
3563 rtype.stripPrefix("typedef ");
3564
3565 // merge the typedefs only if they're not both grouped, and both are
3566 // either part of the same class, part of the same namespace, or both
3567 // are global (i.e., neither in a class or a namespace)
3568 bool notBothGrouped = root->groups.empty() || imd->getGroupDef()==nullptr; // see example #100
3569 bool bothSameScope = (!cd && !nd) || (cd && imd->getClassDef() == cd) || (nd && imd->getNamespaceDef() == nd);
3570 //printf("imd->isTypedef()=%d imd->typeString()=%s root->type=%s\n",imd->isTypedef(),
3571 // qPrint(imd->typeString()),qPrint(root->type));
3572 if (notBothGrouped && bothSameScope && imd->typeString()==rtype)
3573 {
3574 MemberDefMutable *md = toMemberDefMutable(imd.get());
3575 if (md)
3576 {
3577 md->setDocumentation(root->doc,root->docFile,root->docLine);
3579 md->setDocsForDefinition(!root->proto);
3580 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3582 md->setRefItems(root->sli);
3583 md->setRequirementReferences(root->rqli);
3584 md->addQualifiers(root->qualifiers);
3585
3586 // merge ingroup specifiers
3587 if (md->getGroupDef()==nullptr && !root->groups.empty())
3588 {
3589 addMemberToGroups(root,md);
3590 }
3591 else if (md->getGroupDef()!=nullptr && root->groups.empty())
3592 {
3593 //printf("existing member is grouped, new member not\n");
3594 }
3595 else if (md->getGroupDef()!=nullptr && !root->groups.empty())
3596 {
3597 //printf("both members are grouped\n");
3598 }
3599 found=true;
3600 break;
3601 }
3602 }
3603 }
3604 }
3605 if (found)
3606 {
3607 AUTO_TRACE_ADD("typedef '{}' already found",rname);
3608 // mark the entry as processed, as we copied everything from it elsewhere
3609 // also, otherwise, due to containing `typedef` it may later get treated
3610 // as a function typedef in filterMemberDocumentation, which is incorrect
3611 root->markAsProcessed();
3612 }
3613 else
3614 {
3615 AUTO_TRACE_ADD("new typedef '{}'",rname);
3616 addVariable(root);
3617 }
3618
3619 }
3620 for (const auto &e : root->children())
3621 if (!e->section.isEnum())
3622 buildTypedefList(e.get());
3623}
static void buildTypedefList(const Entry *root)
Definition doxygen.cpp:3528

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 3665 of file doxygen.cpp.

3666{
3667 //printf("buildVarList(%s) section=%08x\n",qPrint(rootNav->name()),rootNav->section());
3668 int isFuncPtr=-1;
3669 if (!root->name.empty() &&
3670 (root->type.empty() || g_compoundKeywords.find(root->type.str())==g_compoundKeywords.end()) &&
3671 (
3672 (root->section.isVariable() && // it's a variable
3673 root->type.find("typedef ")==DString::npos // and not a typedef
3674 ) ||
3675 (root->section.isFunction() && // or maybe a function pointer variable
3676 (isFuncPtr=findFunctionPtr(root->type.str(),root->lang))!=-1
3677 ) ||
3678 (root->section.isFunction() && // class variable initialized by constructor
3680 )
3681 )
3682 ) // documented variable
3683 {
3684 AUTO_TRACE();
3685 addVariable(root,isFuncPtr);
3686 }
3687 for (const auto &e : root->children())
3688 if (!e->section.isEnum())
3689 buildVarList(e.get());
3690}
static void buildVarList(const Entry *root)
Definition doxygen.cpp:3665
static bool isVarWithConstructor(const Entry *root)
Definition doxygen.cpp:3093
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 12046 of file doxygen.cpp.

12047{
12048 AUTO_TRACE();
12049
12050 Config::postProcess(false);
12054}
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 12548 of file doxygen.cpp.

12549{
12550 if (Config_getBool(MARKDOWN_SUPPORT))
12551 {
12552 DString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
12553 if (mdfileAsMainPage.empty()) return;
12554 FileInfo fi(mdfileAsMainPage.data());
12555 if (!fi.exists())
12556 {
12557 warn_uncond("Specified markdown mainpage '{}' does not exist\n",mdfileAsMainPage);
12558 return;
12559 }
12560 bool ambig = false;
12561 if (Doxygen::inputNameLinkedMap->findFileDef(fi.absFilePath(),ambig)==nullptr)
12562 {
12563 warn_uncond("Specified markdown mainpage '{}' has not been defined as input file\n",mdfileAsMainPage);
12564 return;
12565 }
12566 }
12567}
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 9964 of file doxygen.cpp.

9965{
9966 for (const auto &pd : *Doxygen::pageLinkedMap)
9967 {
9968 Definition *ppd = pd->getOuterScope();
9969 while (ppd)
9970 {
9971 if (ppd==pd.get())
9972 {
9973 term("page defined {} with label {} is a subpage "
9974 "of itself! Please remove this cyclic dependency.\n",
9975 warn_line(pd->docFile(),pd->docLine()),pd->name());
9976 }
9977 ppd=ppd->getOuterScope();
9978 }
9979 }
9980}

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

Referenced by parseInput().

◆ cleanUpDoxygen()

void cleanUpDoxygen ( )

Definition at line 11583 of file doxygen.cpp.

11584{
11588
11589 delete Doxygen::indexList;
11599 Doxygen::mainPage.reset();
11603 Doxygen::globalScope = nullptr;
11605 delete theTranslator;
11606 delete g_outputList;
11607
11612 delete Doxygen::dirLinkedMap;
11613 delete Doxygen::symbolMap;
11614}
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 9393 of file doxygen.cpp.

9394{
9395 // for each file
9396 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9397 {
9398 for (const auto &fd : *fn)
9399 {
9400 fd->combineUsingRelations();
9401 }
9402 }
9403
9404 // for each namespace
9405 NamespaceDefSet visitedNamespaces;
9406 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9407 {
9409 if (ndm)
9410 {
9411 ndm->combineUsingRelations(visitedNamespaces);
9412 }
9413 }
9414}
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 10467 of file doxygen.cpp.

10468{
10469 std::ofstream f;
10470 bool fileOpened=openOutputFile("-",f);
10471 if (fileOpened)
10472 {
10473 TextStream t(&f);
10474 Config::compareDoxyfile(t,diffList);
10475 }
10476 else
10477 {
10478 term("Cannot open stdout for writing\n");
10479 }
10480}
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:4987

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

Referenced by readConfiguration().

◆ computeClassRelations()

void computeClassRelations ( )
static

Definition at line 5488 of file doxygen.cpp.

5489{
5490 AUTO_TRACE();
5491 for (const auto &[name,root] : g_classEntries)
5492 {
5493 DString bName = extractClassName(root);
5494 ClassDefMutable *cd = getClassMutable(bName);
5495 if (cd)
5496 {
5497 findBaseClassesForClass(root,cd,cd,cd,DocumentedOnly,false);
5498 }
5499 size_t numMembers = cd ? cd->memberNameInfoLinkedMap().size() : 0;
5500 if ((cd==nullptr || (!cd->hasDocumentation() && !cd->isReference())) && numMembers>0 && !bName.endsWith("::"))
5501 {
5502 if (!root->name.empty() && root->name.find('@')==DString::npos && // normal name
5503 (EntryType::guessSection(root->fileName).isHeader() ||
5504 Config_getBool(EXTRACT_LOCAL_CLASSES)) && // not defined in source file
5505 protectionLevelVisible(root->protection) && // hidden by protection
5506 !Config_getBool(HIDE_UNDOC_CLASSES) // undocumented class are visible
5507 )
5508 warn_undoc(root->fileName,root->startLine, "Compound {} is not documented.", root->name);
5509 }
5510 }
5511}
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:5393
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:4848
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 5582 of file doxygen.cpp.

5583{
5584 AUTO_TRACE();
5585 for (const auto &cd : *Doxygen::classLinkedMap)
5586 {
5587 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5588 if (cdm)
5589 {
5590 cdm->computeAnchors();
5591 }
5592 }
5593 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5594 {
5595 for (const auto &fd : *fn)
5596 {
5597 fd->computeAnchors();
5598 }
5599 }
5600 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5601 {
5603 if (ndm)
5604 {
5605 ndm->computeAnchors();
5606 }
5607 }
5608 for (const auto &gd : *Doxygen::groupLinkedMap)
5609 {
5610 gd->computeAnchors();
5611 }
5612}
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 8624 of file doxygen.cpp.

8625{
8626 for (const auto &cd : *Doxygen::classLinkedMap)
8627 {
8628 if (cd->isLinkable())
8629 {
8630 for (const auto &bcd : cd->baseClasses())
8631 {
8633 }
8634 }
8635 }
8636}
static void computeMemberRelationsForBaseClass(const ClassDef *cd, const BaseClassDef *bcd)
Definition doxygen.cpp:8544

References Doxygen::classLinkedMap, and computeMemberRelationsForBaseClass().

Referenced by parseInput().

◆ computeMemberRelationsForBaseClass()

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

Definition at line 8544 of file doxygen.cpp.

8545{
8546 for (const auto &mn : cd->memberNameInfoLinkedMap()) // for each member in class cd with a unique name
8547 {
8548 for (const auto &imd : *mn) // for each member with a given name
8549 {
8550 MemberDefMutable *md = toMemberDefMutable(imd->memberDef());
8551 if (md && (md->isFunction() || md->isCSharpProperty())) // filter on reimplementable members
8552 {
8553 ClassDef *mbcd = bcd->classDef;
8554 if (mbcd && mbcd->isLinkable()) // filter on linkable classes
8555 {
8556 const auto &bmn = mbcd->memberNameInfoLinkedMap();
8557 const auto &bmni = bmn.find(mn->memberName());
8558 if (bmni) // there are base class members with the same name
8559 {
8560 for (const auto &ibmd : *bmni) // for base class member with that name
8561 {
8562 MemberDefMutable *bmd = toMemberDefMutable(ibmd->memberDef());
8563 if (bmd) // not part of an inline namespace
8564 {
8565 auto lang = bmd->getLanguage();
8566 auto compType = mbcd->compoundType();
8567 if (bmd->virtualness()!=Specifier::Normal ||
8568 lang==SrcLangExt::Python ||
8569 lang==SrcLangExt::Java ||
8570 lang==SrcLangExt::PHP ||
8571 compType==ClassDef::Interface ||
8572 compType==ClassDef::Protocol)
8573 {
8574 const ArgumentList &bmdAl = bmd->argumentList();
8575 const ArgumentList &mdAl = md->argumentList();
8576 //printf(" Base argList='%s'\n Super argList='%s'\n",
8577 // qPrint(argListToString(bmdAl)),
8578 // qPrint(argListToString(mdAl))
8579 // );
8580 if (
8581 lang==SrcLangExt::Python ||
8582 matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),bmd->typeString(),&bmdAl,
8583 md->getOuterScope(), md->getFileDef(), md->typeString(),&mdAl,
8584 true,lang
8585 )
8586 )
8587 {
8588 if (lang==SrcLangExt::Python && md->name().startsWith("__")) continue; // private members do not reimplement
8589 //printf("match!\n");
8590 const MemberDef *rmd = md->reimplements();
8591 if (rmd==nullptr) // not already assigned
8592 {
8593 //printf("%s: setting (new) reimplements member %s\n",qPrint(md->qualifiedName()),qPrint(bmd->qualifiedName()));
8594 md->setReimplements(bmd);
8595 }
8596 //printf("%s: add reimplementedBy member %s\n",qPrint(bmd->qualifiedName()),qPrint(md->qualifiedName()));
8597 bmd->insertReimplementedBy(md);
8598 }
8599 else
8600 {
8601 //printf("no match!\n");
8602 }
8603 }
8604 }
8605 }
8606 }
8607 }
8608 }
8609 }
8610 }
8611
8612 // do also for indirect base classes
8613 for (const auto &bbcd : bcd->classDef->baseClasses())
8614 {
8616 }
8617}
virtual const BaseClassList & baseClasses() const =0
Returns the list of base classes from which this class directly inherits.
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

References MemberDef::argumentList(), ClassDef::baseClasses(), BaseClassDef::classDef, ClassDef::compoundType(), computeMemberRelationsForBaseClass(), LinkedMap< T, Hash, KeyEqual, Map >::find(), 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(), toMemberDefMutable(), MemberDef::typeString(), and MemberDef::virtualness().

Referenced by computeMemberRelations(), and computeMemberRelationsForBaseClass().

◆ computePageRelations()

void computePageRelations ( Entry * root)
static

Definition at line 9934 of file doxygen.cpp.

9935{
9936 if ((root->section.isPageDoc() || root->section.isMainpageDoc()) && !root->name.empty())
9937 {
9938 PageDef *pd = root->section.isPageDoc() ?
9940 Doxygen::mainPage.get();
9941 if (pd)
9942 {
9943 for (const BaseInfo &bi : root->extends)
9944 {
9946 if (pd==subPd)
9947 {
9948 term("page defined {} with label {} is a direct "
9949 "subpage of itself! Please remove this cyclic dependency.\n",
9950 warn_line(pd->docFile(),pd->docLine()),pd->name());
9951 }
9952 else if (subPd)
9953 {
9954 pd->addInnerCompound(subPd);
9955 //printf("*** Added subpage relation: %s->%s\n",
9956 // qPrint(pd->name()),qPrint(subPd->name()));
9957 }
9958 }
9959 }
9960 }
9961 for (const auto &e : root->children()) computePageRelations(e.get());
9962}
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)
Definition doxygen.cpp:9934
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 5513 of file doxygen.cpp.

5514{
5515 AUTO_TRACE();
5516 for (const auto &[name,root] : g_classEntries)
5517 {
5518 DString bName=stripAnonymousNamespaceScope(root->name);
5521 // strip any anonymous scopes first
5522 if (cd && !cd->getTemplateInstances().empty())
5523 {
5524 AUTO_TRACE_ADD("Template class '{}'",cd->name());
5525 for (const auto &ti : cd->getTemplateInstances()) // for each template instance
5526 {
5527 ClassDefMutable *tcd=toClassDefMutable(ti.classDef);
5528 if (tcd)
5529 {
5530 AUTO_TRACE_ADD("Template instance '{}'",tcd->name());
5531 DString templSpec = ti.templSpec;
5532 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(tcd->getLanguage(),templSpec);
5533 for (const BaseInfo &bi : root->extends)
5534 {
5535 // check if the base class is a template argument
5536 BaseInfo tbi = bi;
5537 const ArgumentList &tl = cd->templateArguments();
5538 if (!tl.empty())
5539 {
5540 TemplateNameMap baseClassNames = tcd->getTemplateBaseClassNames();
5541 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,bi.name.str());
5542 // for each template name that we inherit from we need to
5543 // substitute the formal with the actual arguments
5544 TemplateNameMap actualTemplateNames;
5545 for (const auto &tn_kv : templateNames)
5546 {
5547 size_t templIndex = tn_kv.second;
5548 Argument actArg;
5549 bool hasActArg=false;
5550 if (templIndex<templArgs->size())
5551 {
5552 actArg=templArgs->at(templIndex);
5553 hasActArg=true;
5554 }
5555 if (hasActArg &&
5556 baseClassNames.find(actArg.type.str())!=baseClassNames.end() &&
5557 actualTemplateNames.find(actArg.type.str())==actualTemplateNames.end()
5558 )
5559 {
5560 actualTemplateNames.emplace(actArg.type.str(),static_cast<int>(templIndex));
5561 }
5562 }
5563
5564 tbi.name = substituteTemplateArgumentsInString(bi.name,tl,templArgs.get());
5565 // find a documented base class in the correct scope
5566 if (!findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,false))
5567 {
5568 // no documented base class -> try to find an undocumented one
5569 findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,Undocumented,true);
5570 }
5571 }
5572 }
5573 }
5574 }
5575 }
5576 }
5577}
This class contains the information about the argument of a function or template.
Definition arguments.h:27
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:4629
DString substituteTemplateArgumentsInString(const DString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
Definition util.cpp:3525

References AUTO_TRACE, AUTO_TRACE_ADD, DocumentedOnly, ArgumentList::empty(), Entry::extends, findClassRelation(), g_classEntries, getClassMutable(), Definition::getLanguage(), getTemplateArgumentsInName(), ClassDef::getTemplateBaseClassNames(), ClassDef::getTemplateInstances(), 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 9112 of file doxygen.cpp.

9113{
9114 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
9115 if (numThreads>1)
9116 {
9117 ThreadPool threadPool(numThreads);
9118 std::vector < std::future< void > > results;
9119 // queue the work
9120 for (const auto &[name,symList] : *Doxygen::symbolMap)
9121 {
9122 for (const auto &def : symList)
9123 {
9125 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
9126 {
9127 auto processTooltip = [dm]() {
9128 dm->computeTooltip();
9129 };
9130 results.emplace_back(threadPool.queue(processTooltip));
9131 }
9132 }
9133 }
9134 // wait for the results
9135 for (auto &f : results)
9136 {
9137 f.get();
9138 }
9139 }
9140 else
9141 {
9142 for (const auto &[name,symList] : *Doxygen::symbolMap)
9143 {
9144 for (const auto &def : symList)
9145 {
9147 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
9148 {
9149 dm->computeTooltip();
9150 }
9151 }
9152 }
9153 }
9154}
virtual void computeTooltip()=0
Class managing a pool of worker threads.
Definition threadpool.h:48
static bool isSymbolHidden(const Definition *d)
Definition doxygen.cpp:9105

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

Referenced by parseInput().

◆ computeVerifiedDotPath()

void computeVerifiedDotPath ( )
static

Definition at line 10391 of file doxygen.cpp.

10392{
10393 // check dot path
10394 DString dotPath = Config_getString(DOT_PATH);
10395 if (!dotPath.empty())
10396 {
10397 FileInfo fi(dotPath.str());
10398 if (!(fi.exists() && fi.isFile()) )// not an existing user specified path + exec
10399 {
10400 dotPath = dotPath+"/dot"+Portable::commandExtension();
10401 FileInfo dp(dotPath.str());
10402 if (!dp.exists() || !dp.isFile())
10403 {
10404 warn_uncond("the dot tool could not be found as '{}'\n",dotPath);
10405 dotPath = "dot";
10406 dotPath += Portable::commandExtension();
10407 }
10408 else if (dp.isRelative())
10409 {
10410 dotPath = fi.dirPath() + "/" + dotPath;
10411 }
10412 }
10413#if defined(_WIN32) // convert slashes
10414 size_t l=dotPath.length();
10415 for (size_t i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\';
10416#endif
10417 }
10418 else
10419 {
10420 dotPath = "dot";
10421 dotPath += Portable::commandExtension();
10422 }
10423 Doxygen::verifiedDotPath = dotPath;
10425}
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 10660 of file doxygen.cpp.

10661{
10662 for (const auto &fileName : files)
10663 {
10664 if (!fileName.empty())
10665 {
10666 FileInfo fi(fileName);
10667 if (!fi.exists())
10668 {
10669 err("Extra file '{}' specified in {} does not exist!\n", fileName,filesOption);
10670 }
10671 else if (fi.isDir())
10672 {
10673 err("Extra file '{}' specified in {} is a directory, it has to be a file!\n", fileName,filesOption);
10674 }
10675 else
10676 {
10677 DString destFileName = outputOption+"/"+fi.fileName();
10678 copyFile(fileName, destFileName);
10679 if (toIndex) Doxygen::indexList->addImageFile(fi.fileName());
10680 }
10681 }
10682 }
10683}
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:4620

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 10635 of file doxygen.cpp.

10636{
10637 DString projectIcon = Config_getString(PROJECT_ICON);
10638 if (!projectIcon.empty())
10639 {
10640 FileInfo fi(projectIcon.str());
10641 if (!fi.exists())
10642 {
10643 err("Project icon '{}' specified by PROJECT_ICON does not exist!\n",projectIcon);
10644 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10645 }
10646 else if (fi.isDir())
10647 {
10648 err("Project icon '{}' specified by PROJECT_ICON is a directory, it has to be a file!\n",projectIcon);
10649 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10650 }
10651 else
10652 {
10653 DString destFileName = outputOption+"/"+fi.fileName();
10654 copyFile(projectIcon,destFileName);
10655 if (toIndex) Doxygen::indexList->addImageFile(fi.fileName());
10656 }
10657 }
10658}
#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 10526 of file doxygen.cpp.

10527{
10528 StringVector latexExtraStyleSheet = Config_getList(LATEX_EXTRA_STYLESHEET);
10529 for (const auto &sheet : latexExtraStyleSheet)
10530 {
10531 std::string fileName = sheet;
10532 if (!fileName.empty())
10533 {
10534 FileInfo fi(fileName);
10535 if (!fi.exists())
10536 {
10537 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET does not exist!\n",fileName);
10538 }
10539 else if (fi.isDir())
10540 {
10541 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET is a directory, it has to be a file!\n", fileName);
10542 }
10543 else
10544 {
10545 DString destFileName = Config_getString(LATEX_OUTPUT)+"/"+fi.fileName();
10546 if (!checkExtension(fi.fileName(), LATEX_STYLE_EXTENSION))
10547 {
10548 destFileName += LATEX_STYLE_EXTENSION;
10549 }
10550 copyFile(fileName, destFileName);
10551 }
10552 }
10553 }
10554}
#define LATEX_STYLE_EXTENSION
Definition latexgen.h:21
bool checkExtension(const DString &fName, const DString &ext)
Definition util.cpp:3927

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 10610 of file doxygen.cpp.

10611{
10612 DString projectLogo = projectLogoFile();
10613 if (!projectLogo.empty())
10614 {
10615 FileInfo fi(projectLogo.str());
10616 if (!fi.exists())
10617 {
10618 err("Project logo '{}' specified by PROJECT_LOGO does not exist!\n",projectLogo);
10619 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10620 }
10621 else if (fi.isDir())
10622 {
10623 err("Project logo '{}' specified by PROJECT_LOGO is a directory, it has to be a file!\n",projectLogo);
10624 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10625 }
10626 else
10627 {
10628 DString destFileName = outputOption+"/"+fi.fileName();
10629 copyFile(projectLogo,destFileName);
10630 if (toIndex) Doxygen::indexList->addImageFile(fi.fileName());
10631 }
10632 }
10633}
DString projectLogoFile()
Definition util.cpp:2581

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 10557 of file doxygen.cpp.

10558{
10559 DString htmlStyleSheet = Config_getString(HTML_STYLESHEET);
10560 if (!htmlStyleSheet.empty())
10561 {
10562 if (!htmlStyleSheet.startsWith("http:") && !htmlStyleSheet.startsWith("https:"))
10563 {
10564 FileInfo fi(htmlStyleSheet.str());
10565 if (!fi.exists())
10566 {
10567 err("Style sheet '{}' specified by HTML_STYLESHEET does not exist!\n",htmlStyleSheet);
10568 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10569 }
10570 else if (fi.isDir())
10571 {
10572 err("Style sheet '{}' specified by HTML_STYLESHEET is a directory, it has to be a file!\n",htmlStyleSheet);
10573 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10574 }
10575 else
10576 {
10577 DString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10578 copyFile(htmlStyleSheet,destFileName);
10579 }
10580 }
10581 }
10582 StringVector htmlExtraStyleSheet = Config_getList(HTML_EXTRA_STYLESHEET);
10583 for (const auto &sheet : htmlExtraStyleSheet)
10584 {
10585 DString fileName(sheet);
10586 if (!fileName.empty() && !fileName.startsWith("http:") && !fileName.startsWith("https:"))
10587 {
10588 FileInfo fi(fileName.str());
10589 if (!fi.exists())
10590 {
10591 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET does not exist!\n",fileName);
10592 }
10593 else if (fi.fileName()=="doxygen.css" || fi.fileName()=="tabs.css" || fi.fileName()=="navtree.css")
10594 {
10595 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is already a built-in stylesheet. Please use a different name\n",fi.fileName());
10596 }
10597 else if (fi.isDir())
10598 {
10599 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is a directory, it has to be a file!\n",fileName);
10600 }
10601 else
10602 {
10603 DString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10604 copyFile(fileName, destFileName);
10605 }
10606 }
10607 }
10608}

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 9172 of file doxygen.cpp.

9173{
9174 for (const auto &cd : *Doxygen::classLinkedMap)
9175 {
9176 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9177 if (cdm)
9178 {
9179 cdm->countMembers();
9180 }
9181 }
9182
9183 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9184 {
9186 if (ndm)
9187 {
9188 ndm->countMembers();
9189 }
9190 }
9191
9192 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9193 {
9194 for (const auto &fd : *fn)
9195 {
9196 fd->countMembers();
9197 }
9198 }
9199
9200 for (const auto &gd : *Doxygen::groupLinkedMap)
9201 {
9202 gd->countMembers();
9203 }
9204
9205 auto &mm = ModuleManager::instance();
9206 mm.countMembers();
9207}
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 12295 of file doxygen.cpp.

12298{
12299 DString result = formatDirName;
12300 if (result.empty())
12301 {
12302 result = baseDirName + defaultDirName;
12303 }
12304 else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':'))
12305 {
12306 result.prepend(baseDirName+"/");
12307 }
12308 Dir formatDir(result.str());
12309 if (!formatDir.exists() && !formatDir.mkdir(result.str()))
12310 {
12311 term("Could not create output directory {}\n", result);
12312 }
12313 return result;
12314}
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 )
static

Definition at line 1572 of file doxygen.cpp.

1573{
1574 DString n = templ->name();
1575 // replace e.g. X::@1343:@4343::Y -> X::[struct]::Y
1576 if (size_t sn = n.find('@'); sn!=DString::npos)
1577 {
1578 const char *p = n.data()+sn;
1579 char c;
1580 while ((c=*p))
1581 {
1582 if (!isdigit(c) && c!='@' && c!=':') break;
1583 p++;
1584 }
1585 n = n.left(sn)+"["+templ->compoundTypeString().str()+"]"+p;
1586 }
1587 // add field name to the class name to make it unique again, e.g. X::[struct]::Y.m
1588 DString fullName = n+"."+fieldName;
1589
1590 //printf("** adding class %s based on %s in %s\n",qPrint(fullName),qPrint(templ->name()),qPrint(root->name()));
1592 Doxygen::classLinkedMap->add(fullName,
1594 templ->getDefLine(),
1595 templ->getDefColumn(),
1596 fullName,
1597 templ->compoundType())));
1598 if (cd)
1599 {
1600 //printf("cd->name()=%s displayName=%s\n",qPrint(cd->name()),qPrint(cd->displayName()));
1601 cd->setDocumentation(templ->documentation(),templ->docFile(),templ->docLine()); // copy docs to definition
1602 cd->setBriefDescription(templ->briefDescription(),templ->briefFile(),templ->briefLine());
1603 cd->setLanguage(templ->getLanguage());
1604 cd->setBodySegment(templ->getDefLine(),templ->getStartBodyLine(),templ->getEndBodyLine());
1605 cd->setBodyDef(templ->getBodyDef());
1606
1607 if (root!=Doxygen::globalScope)
1608 {
1609 DefinitionMutable *outerScope = toDefinitionMutable(const_cast<Definition*>(root));
1610 if (root && root->definitionType()==Definition::TypeFile)
1611 {
1612 FileDef *fd = toFileDef(const_cast<Definition*>(root));
1613 fd->insertClass(cd);
1614 cd->setFileDef(fd);
1616 }
1617 else if (outerScope)
1618 {
1619 outerScope->addInnerCompound(cd);
1620 cd->setOuterScope(const_cast<Definition*>(root));
1621 }
1622 }
1623
1624 for (auto &gd : root->partOfGroups())
1625 {
1626 cd->makePartOfGroup(gd);
1627 gd->addClass(cd);
1628 }
1629
1630 auto addMember = [&](const MemberDef *md) -> MemberDefMutable*
1631 {
1632 auto newMd = createMemberDef(md->getDefFileName(),md->getDefLine(),md->getDefColumn(),
1633 md->typeString(),md->name(),md->argsString(),md->excpString(),
1634 md->protection(),md->virtualness(),md->isStatic(),Relationship::Member,
1635 md->memberType(),
1636 ArgumentList(),ArgumentList(),"");
1637 MemberDefMutable *imd = toMemberDefMutable(newMd.get());
1638 imd->setMemberClass(cd);
1639 imd->setDefinition(md->definition());
1640 imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
1641 imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
1642 imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
1643 imd->setMemberSpecifiers(md->getMemberSpecifiers());
1644 imd->setId(md->id());
1645 imd->addQualifiers(md->getQualifiers());
1646 imd->setVhdlSpecifiers(md->getVhdlSpecifiers());
1647 imd->setMemberGroupId(md->getMemberGroupId());
1648 imd->setInitializer(md->initializer());
1649 imd->setRequiresClause(md->requiresClause());
1650 imd->setMaxInitLines(md->initializerLines());
1651 imd->setBitfields(md->bitfieldString());
1652 imd->setLanguage(md->getLanguage());
1654 cd->insertMember(imd);
1655 associateVariableWithAnonymousEnumType(md,cd,imd,MemberListType::PubAttribs());
1656 MemberName *mn = Doxygen::memberNameLinkedMap->add(md->name());
1657 mn->push_back(std::move(newMd));
1658 return imd;
1659
1660 };
1661
1662 MemberList *ml = templ->getMemberList(MemberListType::PubAttribs());
1663 if (ml)
1664 {
1665 for (const auto &md : *ml)
1666 {
1667 //printf(" Member attribute %s def=%s\n",qPrint(md->name()),qPrint(md->definition()));
1668 addMember(md);
1669 }
1670 }
1671 ml = templ->getMemberList(MemberListType::PubTypes());
1672 if (ml)
1673 {
1674 for (const auto &md : *ml)
1675 {
1676 //printf(" Member type %s def=%s\n",qPrint(md->name()),qPrint(md->definition()));
1677 MemberDefMutable *mdm = addMember(md);
1678 if (md->isEnumerate() && md->name().startsWith("@")) // anonymous enum type
1679 {
1680 for (const auto &emd : md->enumFieldList())
1681 {
1682 //printf(" enum field %s\n",qPrint(emd->name()));
1683 MemberDefMutable *emdm = addMember(emd);
1684 mdm->insertEnumField(emdm);
1685 emdm->setEnumScope(md);
1686 }
1687 }
1688 }
1689 }
1690 }
1691 return cd;
1692}
virtual MemberList * getMemberList(MemberListType lt) const =0
Returns the members in the list identified by lt.
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 setBitfields(const DString &s)=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:2027

References LinkedMap< T, Hash, KeyEqual, Map >::add(), DefinitionMutable::addInnerCompound(), MemberDefMutable::addQualifiers(), associateVariableWithAnonymousEnumType(), Definition::briefDescription(), Definition::briefFile(), Definition::briefLine(), Doxygen::classLinkedMap, ClassDef::compoundType(), ClassDef::compoundTypeString(), createClassDef(), createMemberDef(), DString::data(), Definition::definitionType(), Definition::docFile(), Definition::docLine(), Definition::documentation(), 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(), DString::left(), DefinitionMutable::makePartOfGroup(), Doxygen::memberNameLinkedMap, Definition::name(), DString::npos, Definition::partOfGroups(), MemberName::push_back(), MemberDefMutable::setBitfields(), DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), MemberDefMutable::setClassDefOfAnonymousType(), MemberDefMutable::setDefinition(), DefinitionMutable::setDocumentation(), MemberDefMutable::setEnumScope(), ClassDefMutable::setFileDef(), DefinitionMutable::setId(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setInitializer(), DefinitionMutable::setLanguage(), MemberDefMutable::setMaxInitLines(), MemberDefMutable::setMemberClass(), MemberDefMutable::setMemberGroupId(), MemberDefMutable::setMemberSpecifiers(), DefinitionMutable::setOuterScope(), MemberDefMutable::setRequiresClause(), MemberDefMutable::setVhdlSpecifiers(), DString::str(), toClassDefMutable(), toDefinitionMutable(), toFileDef(), toMemberDefMutable(), and Definition::TypeFile.

Referenced by processTagLessClasses().

◆ createTemplateInstanceMembers()

void createTemplateInstanceMembers ( )
static

Definition at line 8640 of file doxygen.cpp.

8641{
8642 // for each class
8643 for (const auto &cd : *Doxygen::classLinkedMap)
8644 {
8645 // that is a template
8646 for (const auto &ti : cd->getTemplateInstances())
8647 {
8648 ClassDefMutable *tcdm = toClassDefMutable(ti.classDef);
8649 if (tcdm)
8650 {
8651 tcdm->addMembersToTemplateInstance(cd.get(),cd->templateArguments(),ti.templSpec);
8652 }
8653 }
8654 }
8655}
virtual void addMembersToTemplateInstance(const ClassDef *cd, const ArgumentList &templateArguments, const DString &templSpec)=0

References ClassDefMutable::addMembersToTemplateInstance(), Doxygen::classLinkedMap, 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 2293 of file doxygen.cpp.

2295{
2296 AUTO_TRACE("creating new member {} for class {}",memName,cd->name());
2297 const ArgumentList &templAl = md->templateArguments();
2298 const ArgumentList &al = md->argumentList();
2299 auto newMd = createMemberDef(
2300 fileName,root->startLine,root->startColumn,
2301 md->typeString(),memName,md->argsString(),
2302 md->excpString(),root->protection,root->virt,
2303 md->isStatic(),Relationship::Member,md->memberType(),
2304 templAl,al,root->metaData
2305 );
2306 auto newMmd = toMemberDefMutable(newMd.get());
2307 newMmd->setMemberClass(cd);
2308 cd->insertMember(newMd.get());
2309 if (!root->doc.empty() || !root->brief.empty())
2310 {
2311 newMmd->setDocumentation(root->doc,root->docFile,root->docLine);
2312 newMmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2313 newMmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2314 }
2315 else
2316 {
2317 newMmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
2318 newMmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
2319 newMmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
2320 }
2321 newMmd->setDefinition(md->definition());
2322 applyMemberOverrideOptions(root,newMmd);
2323 newMmd->addQualifiers(root->qualifiers);
2324 newMmd->setBitfields(md->bitfieldString());
2325 newMmd->addSectionsToDefinition(root->anchors);
2326 newMmd->setBodySegment(md->getDefLine(),md->getStartBodyLine(),md->getEndBodyLine());
2327 newMmd->setBodyDef(md->getBodyDef());
2328 newMmd->setInitializer(md->initializer());
2329 newMmd->setRequiresClause(md->requiresClause());
2330 newMmd->setMaxInitLines(md->initializerLines());
2331 newMmd->setMemberGroupId(root->mGrpId);
2332 newMmd->setMemberSpecifiers(md->getMemberSpecifiers());
2333 newMmd->setVhdlSpecifiers(md->getVhdlSpecifiers());
2334 newMmd->setLanguage(root->lang);
2335 newMmd->setId(root->id);
2337 mn->push_back(std::move(newMd));
2338}
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 11391 of file doxygen.cpp.

11392{
11394 msg("Developer parameters:\n");
11395 msg(" -m dump symbol map\n");
11396 msg(" -b making messages output unbuffered\n");
11397 msg(" -c <file> process input file as a comment block and produce HTML output\n");
11398#if ENABLE_TRACING
11399 msg(" -t [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout)\n");
11400 msg(" -t_time [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout),\n"
11401 " and include time and thread information\n");
11402#endif
11403 msg(" -d <level> enable a debug level, such as (multiple invocations of -d are possible):\n");
11405}
@ 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 9456 of file doxygen.cpp.

9457{
9458 // for each class
9459 for (const auto &cd : *Doxygen::classLinkedMap)
9460 {
9461 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9462 if (cdm)
9463 {
9465 }
9466 }
9467 // for each file
9468 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9469 {
9470 for (const auto &fd : *fn)
9471 {
9472 fd->distributeMemberGroupDocumentation();
9473 }
9474 }
9475 // for each namespace
9476 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9477 {
9479 if (ndm)
9480 {
9482 }
9483 }
9484 // for each group
9485 for (const auto &gd : *Doxygen::groupLinkedMap)
9486 {
9487 gd->distributeMemberGroupDocumentation();
9488 }
9490}
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 11350 of file doxygen.cpp.

11351{
11352 DString anchor;
11354 {
11355 MemberDef *md = toMemberDef(d);
11356 anchor=":"+md->anchor();
11357 }
11358 DString scope;
11359 DString fn = d->getOutputFileBase();
11362 {
11363 scope = fn;
11364 }
11365 t << "REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
11366 << fn+anchor << "','"
11367 << scope << "','"
11368 << d->name() << "','"
11369 << d->getDefFileName() << "','"
11370 << d->getDefLine()
11371 << "');\n";
11372}
virtual DString anchor() const =0
virtual DString getOutputFileBase() const =0
MemberDef * toMemberDef(Definition *d)
void addHtmlExtensionIfMissing(DString &fName)
Definition util.cpp:3932

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 11374 of file doxygen.cpp.

11375{
11376 std::ofstream f = Portable::openOutputStream("symbols.sql");
11377 if (f.is_open())
11378 {
11379 TextStream t(&f);
11380 for (const auto &[name,symList] : *Doxygen::symbolMap)
11381 {
11382 for (const auto &def : symList)
11383 {
11384 dumpSymbol(t,def);
11385 }
11386 }
11387 }
11388}
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 12282 of file doxygen.cpp.

12283{
12284 if (!g_successfulRun) // premature exit
12285 {
12286 Dir thisDir;
12287 msg("Exiting...\n");
12288 if (!Doxygen::filterDBFileName.empty())
12289 {
12290 thisDir.remove(Doxygen::filterDBFileName.str());
12291 }
12292 }
12293}
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 5393 of file doxygen.cpp.

5394{
5395 // strip any anonymous scopes first
5398 if (size_t i=bName.find('<'); (root->lang==SrcLangExt::CSharp || root->lang==SrcLangExt::Java) && i!=DString::npos)
5399 {
5400 // a Java/C# generic class looks like a C++ specialization, so we need to strip the
5401 // template part before looking for matches
5402 if (root->lang==SrcLangExt::CSharp)
5403 {
5404 bName = mangleCSharpGenericName(root->name);
5405 }
5406 else
5407 {
5408 bName = bName.left(i);
5409 }
5410 }
5411 return bName;
5412}

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 7477 of file doxygen.cpp.

7478{
7479 AUTO_TRACE("root->type='{}' root->inside='{}' root->name='{}' root->args='{}' section={} root->spec={} root->mGrpId={}",
7480 root->type,root->inside,root->name,root->args,root->section,root->spec,root->mGrpId);
7481 //printf("root->parent()->name=%s\n",qPrint(root->parent()->name));
7482 bool isFunc=true;
7483
7484 DString type = root->type;
7485 DString args = root->args;
7486 int i=-1, l=0;
7487 if ( // detect func variable/typedef to func ptr
7488 (i=findFunctionPtr(type.str(),root->lang,&l))!=-1
7489 )
7490 {
7491 //printf("Fixing function pointer!\n");
7492 // fix type and argument
7493 args.prepend(type.mid(i+l));
7494 type=type.left(i+l);
7495 //printf("Results type=%s,name=%s,args=%s\n",qPrint(type),qPrint(root->name),qPrint(args));
7496 isFunc=false;
7497 }
7498 else if ((type.startsWith("typedef ") && args.find('(')!=DString::npos))
7499 // detect function types marked as functions
7500 {
7501 isFunc=false;
7502 }
7503
7504 //printf("Member %s isFunc=%d\n",qPrint(root->name),isFunc);
7505 if (root->section.isMemberDoc())
7506 {
7507 //printf("Documentation for inline member '%s' found args='%s'\n",
7508 // qPrint(root->name),qPrint(args));
7509 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7510 if (type.empty())
7511 {
7512 findMember(root,
7513 relates,
7514 type,
7515 args,
7516 root->name + args + root->exception,
7517 false,
7518 isFunc);
7519 }
7520 else
7521 {
7522 findMember(root,
7523 relates,
7524 type,
7525 args,
7526 type + " " + root->name + args + root->exception,
7527 false,
7528 isFunc);
7529 }
7530 }
7531 else if (root->section.isOverloadDoc())
7532 {
7533 //printf("Overloaded member %s found\n",qPrint(root->name));
7534 findMember(root,
7535 relates,
7536 type,
7537 args,
7538 root->name,
7539 true,
7540 isFunc);
7541 }
7542 else if
7543 ((root->section.isFunction() // function
7544 ||
7545 (root->section.isVariable() && // variable
7546 !type.empty() && // with a type
7547 g_compoundKeywords.find(type.str())==g_compoundKeywords.end() // that is not a keyword
7548 // (to skip forward declaration of class etc.)
7549 )
7550 )
7551 )
7552 {
7553 //printf("Documentation for member '%s' found args='%s' excp='%s'\n",
7554 // qPrint(root->name),qPrint(args),qPrint(root->exception));
7555 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7556 //printf("Inside=%s\n Relates=%s\n",qPrint(root->inside),qPrint(relates));
7557 if (isTypeAClassFriend(type))
7558 {
7559 findMember(root,
7560 relates,
7561 type,
7562 args,
7563 type+" "+root->name,
7564 false,false);
7565
7566 }
7567 else if (!type.empty())
7568 {
7569 findMember(root,
7570 relates,
7571 type,
7572 args,
7573 type+" "+ root->inside + root->name + args + root->exception,
7574 false,isFunc);
7575 }
7576 else
7577 {
7578 findMember(root,
7579 relates,
7580 type,
7581 args,
7582 root->inside + root->name + args + root->exception,
7583 false,isFunc);
7584 }
7585 }
7586 else if (root->section.isDefine() && !relates.empty())
7587 {
7588 findMember(root,
7589 relates,
7590 type,
7591 args,
7592 root->name + args,
7593 false,
7594 !args.empty());
7595 }
7596 else if (root->section.isVariableDoc())
7597 {
7598 //printf("Documentation for variable %s found\n",qPrint(root->name));
7599 //if (!relates.empty()) printf(" Relates %s\n",qPrint(relates));
7600 findMember(root,
7601 relates,
7602 type,
7603 args,
7604 root->name,
7605 false,
7606 false);
7607 }
7608 else if (root->section.isExportedInterface() ||
7609 root->section.isIncludedService())
7610 {
7611 findMember(root,
7612 relates,
7613 type,
7614 args,
7615 type + " " + root->name,
7616 false,
7617 false);
7618 }
7619 else
7620 {
7621 // skip section
7622 //printf("skip section\n");
7623 }
7624}
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:6850

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 4848 of file doxygen.cpp.

4858{
4859 AUTO_TRACE("name={}",root->name);
4860 // The base class could ofcouse also be a non-nested class
4861 const ArgumentList &formalArgs = masterCd->templateArguments();
4862 for (const BaseInfo &bi : root->extends)
4863 {
4864 //printf("masterCd=%s bi.name='%s' #actualArgs=%d\n",
4865 // qPrint(masterCd->localName()),qPrint(bi.name),actualArgs ? (int)actualArgs->size() : -1);
4866 TemplateNameMap formTemplateNames;
4867 if (templateNames.empty())
4868 {
4869 formTemplateNames = getTemplateArgumentsInName(formalArgs,bi.name.str());
4870 }
4871 BaseInfo tbi = bi;
4872 tbi.name = substituteTemplateArgumentsInString(bi.name,formalArgs,actualArgs);
4873 //printf("masterCd=%p instanceCd=%p bi->name=%s tbi.name=%s\n",(void*)masterCd,(void*)instanceCd,qPrint(bi.name),qPrint(tbi.name));
4874
4875 if (mode==DocumentedOnly)
4876 {
4877 // find a documented base class in the correct scope
4878 if (!findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,DocumentedOnly,isArtificial))
4879 {
4880 // 1.8.2: decided to show inheritance relations even if not documented,
4881 // we do make them artificial, so they do not appear in the index
4882 //if (!Config_getBool(HIDE_UNDOC_RELATIONS))
4883 bool b = Config_getBool(HIDE_UNDOC_RELATIONS) ? true : isArtificial;
4884 //{
4885 // no documented base class -> try to find an undocumented one
4886 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,Undocumented,b);
4887 //}
4888 }
4889 }
4890 else if (mode==TemplateInstances)
4891 {
4892 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,TemplateInstances,isArtificial);
4893 }
4894 }
4895}

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 5858 of file doxygen.cpp.

5860{
5861 SymbolResolver resolver(fd);
5862 const ClassDef *tcd = resolver.resolveClass(nd,scopeName,true,true);
5863 //printf("findClassDefinition(fd=%s,ns=%s,scopeName=%s)='%s'\n",
5864 // qPrint(fd?fd->name():""),qPrint(nd?nd->name():""),
5865 // qPrint(scopeName),qPrint(tcd?tcd->name():""));
5866 return tcd;
5867}

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 5384 of file doxygen.cpp.

5385{
5386 if (isClassSection(root))
5387 {
5388 g_classEntries.emplace(root->name.str(),root);
5389 }
5390 for (const auto &e : root->children()) findClassEntries(e.get());
5391}
static void findClassEntries(const Entry *root)
Definition doxygen.cpp:5384
static bool isClassSection(const Entry *root)
Definition doxygen.cpp:5362

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 5020 of file doxygen.cpp.

5029{
5030 AUTO_TRACE("name={} base={} isArtificial={} mode={}",cd->name(),bi->name,isArtificial,(int)mode);
5031
5032 DString biName=bi->name;
5033 bool explicitGlobalScope=false;
5034 if (biName.startsWith("::")) // explicit global scope
5035 {
5036 biName=biName.mid(2);
5037 explicitGlobalScope=true;
5038 }
5039
5040 Entry *parentNode=root->parent();
5041 bool lastParent=false;
5042 do // for each parent scope, starting with the largest scope
5043 // (in case of nested classes)
5044 {
5045 DString scopeName= parentNode ? parentNode->name : DString();
5046 int scopeOffset=explicitGlobalScope ? 0 : static_cast<int>(scopeName.length());
5047 do // try all parent scope prefixes, starting with the largest scope
5048 {
5049 //printf("scopePrefix='%s' biName='%s'\n",
5050 // qPrint(scopeName.left(scopeOffset)),qPrint(biName));
5051
5052 DString baseClassName=biName;
5053 if (scopeOffset>0)
5054 {
5055 baseClassName.prepend(scopeName.left(scopeOffset)+"::");
5056 }
5057 if (root->lang==SrcLangExt::CSharp)
5058 {
5059 baseClassName = mangleCSharpGenericName(baseClassName);
5060 }
5061 AUTO_TRACE_ADD("cd='{}' baseClassName='{}'",cd->name(),baseClassName);
5062 SymbolResolver resolver(cd->getFileDef());
5063 ClassDefMutable *baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
5064 baseClassName,
5065 mode==Undocumented,
5066 true
5067 );
5068 const MemberDef *baseClassTypeDef = resolver.getTypedef();
5069 DString templSpec = resolver.getTemplateSpec();
5070 //printf("baseClassName=%s baseClass=%p cd=%p explicitGlobalScope=%d\n",
5071 // qPrint(baseClassName),baseClass,cd,explicitGlobalScope);
5072 //printf(" scope='%s' baseClassName='%s' baseClass=%s templSpec=%s\n",
5073 // cd ? qPrint(cd->name()):"<none>",
5074 // qPrint(baseClassName),
5075 // baseClass?qPrint(baseClass->name()):"<none>",
5076 // qPrint(templSpec)
5077 // );
5078 //if (baseClassName.left(root->name.length())!=root->name ||
5079 // baseClassName.at(root->name.length())!='<'
5080 // ) // Check for base class with the same name.
5081 // // If found then look in the outer scope for a match
5082 // // and prevent recursion.
5083 if (!isRecursiveBaseClass(root->name,baseClassName)
5084 || explicitGlobalScope
5085 // sadly isRecursiveBaseClass always true for UNO IDL ifc/svc members
5086 // (i.e. this is needed for addInterfaceOrServiceToServiceOrSingleton)
5087 || (root->lang==SrcLangExt::IDL &&
5088 (root->section.isExportedInterface() ||
5089 root->section.isIncludedService()))
5090 )
5091 {
5092 AUTO_TRACE_ADD("class relation '{}' inherited/used by '{}' found prot={} virt={} templSpec='{}'",
5093 baseClassName, root->name, bi->prot, bi->virt, templSpec);
5094
5095 int i=findTemplateSpecializationPosition(baseClassName);
5096 size_t si=baseClassName.rfind("::",i);
5097 if (si==DString::npos) si=0;
5098 if (baseClass==nullptr && static_cast<size_t>(i)!=baseClassName.length())
5099 // base class has template specifiers
5100 {
5101 // TODO: here we should try to find the correct template specialization
5102 // but for now, we only look for the unspecialized base class.
5103 int e=findEndOfTemplate(baseClassName,i+1);
5104 //printf("baseClass==0 i=%d e=%d\n",i,e);
5105 if (e!=-1) // end of template was found at e
5106 {
5107 templSpec = removeRedundantWhiteSpace(baseClassName.mid(i,e-i));
5108 baseClassName = baseClassName.left(i)+baseClassName.mid(e);
5109 baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
5110 baseClassName,
5111 mode==Undocumented,
5112 true
5113 );
5114 baseClassTypeDef = resolver.getTypedef();
5115 //printf("baseClass=%p -> baseClass=%s templSpec=%s\n",
5116 // baseClass,qPrint(baseClassName),qPrint(templSpec));
5117 }
5118 }
5119 else if (baseClass && !templSpec.empty()) // we have a known class, but also
5120 // know it is a template, so see if
5121 // we can also link to the explicit
5122 // instance (for instance if a class
5123 // derived from a template argument)
5124 {
5125 //printf("baseClass=%s templSpec=%s\n",qPrint(baseClass->name()),qPrint(templSpec));
5126 ClassDefMutable *templClass=getClassMutable(baseClass->name()+templSpec);
5127 if (templClass)
5128 {
5129 // use the template instance instead of the template base.
5130 baseClass = templClass;
5131 templSpec.clear();
5132 }
5133 }
5134
5135 //printf("cd=%p baseClass=%p\n",cd,baseClass);
5136 bool found=baseClass!=nullptr && (baseClass!=cd || mode==TemplateInstances);
5137 AUTO_TRACE_ADD("1. found={}",found);
5138 if (!found && si!=DString::npos)
5139 {
5140 // replace any namespace aliases
5141 replaceNamespaceAliases(baseClassName);
5142 baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
5143 baseClassName,
5144 mode==Undocumented,
5145 true
5146 );
5147 baseClassTypeDef = resolver.getTypedef();
5148 found=baseClass!=nullptr && baseClass!=cd;
5149 if (found) templSpec = resolver.getTemplateSpec();
5150 }
5151 AUTO_TRACE_ADD("2. found={}",found);
5152
5153 if (!found)
5154 {
5155 baseClass=toClassDefMutable(findClassWithinClassContext(context,cd,baseClassName));
5156 //printf("findClassWithinClassContext(%s,%s)=%p\n",
5157 // qPrint(cd->name()),qPrint(baseClassName),baseClass);
5158 found = baseClass!=nullptr && baseClass!=cd;
5159
5160 }
5161 AUTO_TRACE_ADD("3. found={}",found);
5162 if (!found)
5163 {
5164 // for PHP the "use A\B as C" construct map class C to A::B, so we lookup
5165 // the class name also in the alias mapping.
5166 auto it = Doxygen::namespaceAliasMap.find(baseClassName.str());
5167 if (it!=Doxygen::namespaceAliasMap.end()) // see if it is indeed a class.
5168 {
5169 baseClass=getClassMutable(it->second.alias);
5170 found = baseClass!=nullptr && baseClass!=cd;
5171 }
5172 }
5173 bool isATemplateArgument = templateNames.find(biName.str())!=templateNames.end();
5174
5175 AUTO_TRACE_ADD("4. found={}",found);
5176 if (found)
5177 {
5178 AUTO_TRACE_ADD("Documented base class '{}' templSpec='{}'",biName,templSpec);
5179 // add base class to this class
5180
5181 // if templSpec is not empty then we should "instantiate"
5182 // the template baseClass. A new ClassDef should be created
5183 // to represent the instance. To be able to add the (instantiated)
5184 // members and documentation of a template class
5185 // (inserted in that template class at a later stage),
5186 // the template should know about its instances.
5187 // the instantiation process, should be done in a recursive way,
5188 // since instantiating a template may introduce new inheritance
5189 // relations.
5190 if (!templSpec.empty() && mode==TemplateInstances)
5191 {
5192 // if baseClass is actually a typedef then we should not
5193 // instantiate it, since typedefs are in a different namespace
5194 // see bug531637 for an example where this would otherwise hang
5195 // Doxygen
5196 if (baseClassTypeDef==nullptr)
5197 {
5198 //printf(" => findTemplateInstanceRelation: %s\n",qPrint(baseClass->name()));
5199 findTemplateInstanceRelation(root,context,baseClass,templSpec,templateNames,baseClass->isArtificial());
5200 }
5201 }
5202 else if (mode==DocumentedOnly || mode==Undocumented)
5203 {
5204 //printf(" => insert base class\n");
5205 DString usedName;
5206 if (baseClassTypeDef)
5207 {
5208 usedName=biName;
5209 //printf("***** usedName=%s templSpec=%s\n",qPrint(usedName),qPrint(templSpec));
5210 }
5211 Protection prot = bi->prot;
5212 if (Config_getBool(SIP_SUPPORT)) prot=Protection::Public;
5213 if (cd!=baseClass && !cd->isSubClass(baseClass) && baseClass->isBaseClass(cd,true,templSpec)==0) // check for recursion, see bug690787
5214 {
5215 AUTO_TRACE_ADD("insertBaseClass name={} prot={} virt={} templSpec={}",usedName,prot,bi->virt,templSpec);
5216 cd->insertBaseClass(baseClass,usedName,prot,bi->virt,templSpec);
5217 // add this class as super class to the base class
5218 baseClass->insertSubClass(cd,prot,bi->virt,templSpec);
5219 }
5220 else
5221 {
5222 warn(root->fileName,root->startLine,
5223 "Detected potential recursive class relation "
5224 "between class {} and base class {}!",
5225 cd->name(),baseClass->name()
5226 );
5227 }
5228 }
5229 return true;
5230 }
5231 else if (mode==Undocumented && (scopeOffset==0 || isATemplateArgument))
5232 {
5233 AUTO_TRACE_ADD("New undocumented base class '{}' baseClassName='{}' templSpec='{}' isArtificial={}",
5234 biName,baseClassName,templSpec,isArtificial);
5235 baseClass=nullptr;
5236 if (isATemplateArgument)
5237 {
5238 baseClass = toClassDefMutable(Doxygen::hiddenClassLinkedMap->find(baseClassName));
5239 if (baseClass==nullptr) // not found (or alias)
5240 {
5241 baseClass= toClassDefMutable(
5242 Doxygen::hiddenClassLinkedMap->add(baseClassName,
5243 createClassDef(root->fileName,root->startLine,root->startColumn,
5244 baseClassName,
5245 ClassDef::Class)));
5246 if (baseClass) // really added (not alias)
5247 {
5248 if (isArtificial) baseClass->setArtificial(true);
5249 baseClass->setLanguage(root->lang);
5250 }
5251 }
5252 }
5253 else
5254 {
5255 baseClass = toClassDefMutable(Doxygen::classLinkedMap->find(baseClassName));
5256 //printf("*** classDDict->find(%s)=%p biName=%s templSpec=%s\n",
5257 // qPrint(baseClassName),baseClass,qPrint(biName),qPrint(templSpec));
5258 if (baseClass==nullptr) // not found (or alias)
5259 {
5260 baseClass = toClassDefMutable(
5261 Doxygen::classLinkedMap->add(baseClassName,
5262 createClassDef(root->fileName,root->startLine,root->startColumn,
5263 baseClassName,
5264 ClassDef::Class)));
5265 if (baseClass) // really added (not alias)
5266 {
5267 if (isArtificial) baseClass->setArtificial(true);
5268 baseClass->setLanguage(root->lang);
5269 si = baseClassName.rfind("::");
5270 if (si!=DString::npos) // class is nested
5271 {
5272 Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),nullptr,root->tagInfo());
5273 if (sd==nullptr || sd==Doxygen::globalScope) // outer scope not found
5274 {
5275 baseClass->setArtificial(true); // see bug678139
5276 }
5277 }
5278 }
5279 }
5280 }
5281 if (baseClass)
5282 {
5283 if (biName.endsWith("-p"))
5284 {
5285 biName="<"+biName.left(biName.length()-2)+">";
5286 }
5287 if (!cd->isSubClass(baseClass) && cd!=baseClass && cd->isBaseClass(baseClass,true,templSpec)==0) // check for recursion
5288 {
5289 AUTO_TRACE_ADD("insertBaseClass name={} prot={} virt={} templSpec={}",biName,bi->prot,bi->virt,templSpec);
5290 // add base class to this class
5291 cd->insertBaseClass(baseClass,biName,bi->prot,bi->virt,templSpec);
5292 // add this class as super class to the base class
5293 baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
5294 }
5295 // the undocumented base was found in this file
5296 baseClass->insertUsedFile(root->fileDef());
5297
5298 Definition *scope = buildScopeFromQualifiedName(baseClass->name(),root->lang,nullptr);
5299 if (scope!=baseClass)
5300 {
5301 baseClass->setOuterScope(scope);
5302 }
5303
5304 if (baseClassName.endsWith("-p"))
5305 {
5307 }
5308 return true;
5309 }
5310 else
5311 {
5312 AUTO_TRACE_ADD("Base class '{}' not created (alias?)",biName);
5313 }
5314 }
5315 else
5316 {
5317 AUTO_TRACE_ADD("Base class '{}' not found",biName);
5318 }
5319 }
5320 else
5321 {
5322 if (mode!=TemplateInstances)
5323 {
5324 warn(root->fileName,root->startLine,
5325 "Detected potential recursive class relation "
5326 "between class {} and base class {}!",
5327 root->name,baseClassName
5328 );
5329 }
5330 // for mode==TemplateInstance this case is quite common and
5331 // indicates a relation between a template class and a template
5332 // instance with the same name.
5333 }
5334 if (scopeOffset==0)
5335 {
5336 scopeOffset=-1;
5337 }
5338 else
5339 {
5340 size_t o = scopeName.rfind("::",scopeOffset-1);
5341 scopeOffset = o!=DString::npos ? static_cast<int>(o) : 0;
5342 }
5343 //printf("new scopeOffset='%d'",scopeOffset);
5344 } while (scopeOffset>=0);
5345
5346 if (parentNode==nullptr)
5347 {
5348 lastParent=true;
5349 }
5350 else
5351 {
5352 parentNode=parentNode->parent();
5353 }
5354 } while (lastParent);
5355
5356 return false;
5357}
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 FileDef * getFileDef() const =0
Returns the file in which this compound's definition can be found.
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:4990
static ClassDef * findClassWithinClassContext(Definition *context, ClassDef *cd, const DString &name)
Definition doxygen.cpp:4657
static void findTemplateInstanceRelation(const Entry *root, Definition *context, ClassDefMutable *templateClass, const DString &templSpec, const TemplateNameMap &templateNames, bool isArtificial)
Definition doxygen.cpp:4899
static bool isRecursiveBaseClass(const DString &scope, const DString &name)
Definition doxygen.cpp:4979
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 4657 of file doxygen.cpp.

4658{
4659 ClassDef *result=nullptr;
4660 if (cd==nullptr)
4661 {
4662 return result;
4663 }
4664 FileDef *fd=cd->getFileDef();
4665 SymbolResolver resolver(fd);
4666 if (context && cd!=context)
4667 {
4668 result = const_cast<ClassDef*>(resolver.resolveClass(context,name,true,true));
4669 }
4670 //printf("1. result=%p\n",result);
4671 if (result==nullptr)
4672 {
4673 result = const_cast<ClassDef*>(resolver.resolveClass(cd,name,true,true));
4674 }
4675 //printf("2. result=%p\n",result);
4676 if (result==nullptr) // try direct class, needed for namespaced classes imported via tag files (see bug624095)
4677 {
4678 result = getClass(name);
4679 }
4680 //printf("3. result=%p\n",result);
4681 //printf("** Trying to find %s within context %s class %s result=%s lookup=%p\n",
4682 // qPrint(name),
4683 // context ? qPrint(context->name()) : "<none>",
4684 // cd ? qPrint(cd->name()) : "<none>",
4685 // result ? qPrint(result->name()) : "<none>",
4686 // Doxygen::classLinkedMap->find(name)
4687 // );
4688 return result;
4689}

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

Referenced by findClassRelation(), and findUsedClassesForClass().

◆ findDefineDocumentation()

void findDefineDocumentation ( Entry * root)
static

Definition at line 9666 of file doxygen.cpp.

9667{
9668 if ((root->section.isDefineDoc() || root->section.isDefine()) && !root->name.empty())
9669 {
9670 //printf("found define '%s' '%s' brief='%s' doc='%s'\n",
9671 // qPrint(root->name),qPrint(root->args),qPrint(root->brief),qPrint(root->doc));
9672
9673 if (root->tagInfo() && !root->name.empty()) // define read from a tag file
9674 {
9675 auto md = createMemberDef(root->tagInfo()->tagName,1,1,
9676 "#define",root->name,root->args,DString(),
9677 Protection::Public,Specifier::Normal,false,Relationship::Member,MemberType::Define,
9678 ArgumentList(),ArgumentList(),"");
9679 auto mmd = toMemberDefMutable(md.get());
9680 mmd->setTagInfo(root->tagInfo());
9681 mmd->setLanguage(root->lang);
9682 mmd->addQualifiers(root->qualifiers);
9683 //printf("Searching for '%s' fd=%p\n",qPrint(filePathName),fd);
9684 mmd->setFileDef(root->parent()->fileDef());
9685 //printf("Adding member=%s\n",qPrint(md->name()));
9687 mn->push_back(std::move(md));
9688 }
9690 if (mn)
9691 {
9692 int count=0;
9693 for (const auto &md : *mn)
9694 {
9695 if (md->memberType()==MemberType::Define) count++;
9696 }
9697 if (count==1)
9698 {
9699 for (const auto &imd : *mn)
9700 {
9701 MemberDefMutable *md = toMemberDefMutable(imd.get());
9702 if (md && md->memberType()==MemberType::Define)
9703 {
9704 addDefineDoc(root,md);
9705 }
9706 }
9707 }
9708 else if (count>1 &&
9709 (!root->doc.empty() ||
9710 !root->brief.empty() ||
9711 root->bodyLine!=-1
9712 )
9713 )
9714 // multiple defines don't know where to add docs
9715 // but maybe they are in different files together with their documentation
9716 {
9717 for (const auto &imd : *mn)
9718 {
9719 MemberDefMutable *md = toMemberDefMutable(imd.get());
9720 if (md && md->memberType()==MemberType::Define)
9721 {
9722 if (haveEqualFileNames(root, md) || isEntryInGroupOfMember(root, md))
9723 // doc and define in the same file or group assume they belong together.
9724 {
9725 addDefineDoc(root,md);
9726 }
9727 }
9728 }
9729 //warn("define {} found in the following files:\n",root->name);
9730 //warn("Cannot determine where to add the documentation found "
9731 // "at line {} of file {}. \n",
9732 // root->startLine,root->fileName);
9733 }
9734 }
9735 else if (!root->doc.empty() || !root->brief.empty()) // define not found
9736 {
9737 bool preEnabled = Config_getBool(ENABLE_PREPROCESSING);
9738 if (preEnabled)
9739 {
9740 warn(root->fileName,root->startLine,"documentation for unknown define {} found.",root->name);
9741 }
9742 else
9743 {
9744 warn(root->fileName,root->startLine, "found documented #define {} but ignoring it because ENABLE_PREPROCESSING is NO.", root->name);
9745 }
9746 }
9747 }
9748 for (const auto &e : root->children()) findDefineDocumentation(e.get());
9749}
static void findDefineDocumentation(Entry *root)
Definition doxygen.cpp:9666
static void addDefineDoc(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:9639
static bool haveEqualFileNames(const Entry *root, const MemberDef *md)
Definition doxygen.cpp:9628
static bool isEntryInGroupOfMember(const Entry *root, const MemberDef *md, bool allowNoGroup=false)
Definition doxygen.cpp:5873

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 8268 of file doxygen.cpp.

8269{
8270 // for each member name
8271 for (const auto &mn : mnsd)
8272 {
8273 // for each member definition
8274 for (const auto &imd : *mn)
8275 {
8276 MemberDefMutable *md = toMemberDefMutable(imd.get());
8277 if (md && md->isEnumerate()) // member is an enum
8278 {
8279 int documentedEnumValues=0;
8280 // for each enum value
8281 for (const auto &fmd : md->enumFieldList())
8282 {
8283 if (fmd->isLinkableInProject()) documentedEnumValues++;
8284 }
8285 // at least one enum value is documented
8286 if (documentedEnumValues>0) md->setDocumentedEnumValues(true);
8287 }
8288 }
8289 }
8290}
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 9753 of file doxygen.cpp.

9754{
9755 if (root->section.isDirDoc())
9756 {
9757 DString normalizedName = root->name;
9758 normalizedName = substitute(normalizedName,"\\","/");
9759 //printf("root->docFile=%s normalizedName=%s\n",
9760 // qPrint(root->docFile),qPrint(normalizedName));
9761 if (root->docFile==normalizedName) // current dir?
9762 {
9763 if (size_t lastSlashPos=normalizedName.rfind('/'); lastSlashPos!=DString::npos) // strip file name
9764 {
9765 normalizedName=normalizedName.left(lastSlashPos);
9766 }
9767 }
9768 if (normalizedName.at(normalizedName.length()-1)!='/')
9769 {
9770 normalizedName+='/';
9771 }
9772 DirDef *matchingDir=nullptr;
9773 for (const auto &dir : *Doxygen::dirLinkedMap)
9774 {
9775 //printf("Dir: %s<->%s\n",qPrint(dir->name()),qPrint(normalizedName));
9776 if (dir->name().right(normalizedName.length())==normalizedName)
9777 {
9778 if (matchingDir)
9779 {
9780 warn(root->fileName,root->startLine,
9781 "\\dir command matches multiple directories.\n"
9782 " Applying the command for directory {}\n"
9783 " Ignoring the command for directory {}",
9784 matchingDir->name(),dir->name()
9785 );
9786 }
9787 else
9788 {
9789 matchingDir=dir.get();
9790 }
9791 }
9792 }
9793 if (matchingDir)
9794 {
9795 //printf("Match for with dir %s #anchor=%zu\n",qPrint(matchingDir->name()),root->anchors.size());
9796 matchingDir->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9797 matchingDir->setDocumentation(root->doc,root->docFile,root->docLine);
9798 matchingDir->setRefItems(root->sli);
9799 matchingDir->setRequirementReferences(root->rqli);
9800 matchingDir->addSectionsToDefinition(root->anchors);
9801 root->commandOverrides.apply_directoryGraph([&](bool b) { matchingDir->overrideDirectoryGraph(b); });
9802 addDirToGroups(root,matchingDir);
9803 }
9804 else
9805 {
9806 warn(root->fileName,root->startLine,"No matching directory found for command \\dir {}",normalizedName);
9807 }
9808 }
9809 for (const auto &e : root->children()) findDirDocumentation(e.get());
9810}
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:9753
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 8294 of file doxygen.cpp.

8295{
8298}
static void findDEV(const MemberNameLinkedMap &mnsd)
Definition doxygen.cpp:8268

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 3236 of file doxygen.cpp.

3237{
3238 // locate end of template
3239 size_t e=startPos;
3240 int brCount=1;
3241 int roundCount=0;
3242 size_t len = s.length();
3243 bool insideString=false;
3244 bool insideChar=false;
3245 char pc = 0;
3246 while (e<len && brCount!=0)
3247 {
3248 char c=s.at(e);
3249 switch(c)
3250 {
3251 case '<':
3252 if (!insideString && !insideChar)
3253 {
3254 if (e<len-1 && s.at(e+1)=='<')
3255 e++;
3256 else if (roundCount==0)
3257 brCount++;
3258 }
3259 break;
3260 case '>':
3261 if (!insideString && !insideChar)
3262 {
3263 if (e<len-1 && s.at(e+1)=='>')
3264 e++;
3265 else if (roundCount==0)
3266 brCount--;
3267 }
3268 break;
3269 case '(':
3270 if (!insideString && !insideChar)
3271 roundCount++;
3272 break;
3273 case ')':
3274 if (!insideString && !insideChar)
3275 roundCount--;
3276 break;
3277 case '"':
3278 if (!insideChar)
3279 {
3280 if (insideString && pc!='\\')
3281 insideString=false;
3282 else
3283 insideString=true;
3284 }
3285 break;
3286 case '\'':
3287 if (!insideString)
3288 {
3289 if (insideChar && pc!='\\')
3290 insideChar=false;
3291 else
3292 insideChar=true;
3293 }
3294 break;
3295 }
3296 pc = c;
3297 e++;
3298 }
3299 return brCount==0 ? static_cast<int>(e) : -1;
3300}

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

Referenced by addVariable(), and findClassRelation().

◆ findEnumDocumentation()

void findEnumDocumentation ( const Entry * root)
static

Definition at line 8183 of file doxygen.cpp.

8184{
8185 if (root->section.isEnumDoc() &&
8186 !root->name.empty() &&
8187 root->name.at(0)!='@' // skip anonymous enums
8188 )
8189 {
8190 DString name;
8191 DString scope;
8192 if (size_t i = root->name.rfind("::"); i!=DString::npos) // scope is specified as part of the name
8193 {
8194 name=root->name.mid(i+2); // extract name
8195 scope=root->name.left(i); // extract scope
8196 //printf("Scope='%s' Name='%s'\n",qPrint(scope),qPrint(name));
8197 }
8198 else // just the name
8199 {
8200 name=root->name;
8201 }
8202 if (root->parent()->section.isScope() && !root->parent()->name.empty()) // found enum docs inside a compound
8203 {
8204 if (!scope.empty()) scope.prepend("::");
8205 scope.prepend(root->parent()->name);
8206 }
8207 const ClassDef *cd = getClass(scope);
8209 const FileDef *fd = root->fileDef();
8210 AUTO_TRACE("Found docs for enum with name '{}' and scope '{}' in context '{}' cd='{}', nd='{}' fd='{}'",
8211 name,scope,root->parent()->name,
8212 cd ? cd->name() : DString("<none>"),
8213 nd ? nd->name() : DString("<none>"),
8214 fd ? fd->name() : DString("<none>"));
8215
8216 if (!name.empty())
8217 {
8218 bool found = tryAddEnumDocsToGroupMember(root, name);
8219 if (!found)
8220 {
8222 if (mn)
8223 {
8224 for (const auto &imd : *mn)
8225 {
8226 MemberDefMutable *md = toMemberDefMutable(imd.get());
8227 if (md && md->isEnumerate())
8228 {
8229 const ClassDef *mcd = md->getClassDef();
8230 const NamespaceDef *mnd = md->getNamespaceDef();
8231 const FileDef *mfd = md->getFileDef();
8232 if (cd && mcd==cd)
8233 {
8234 AUTO_TRACE_ADD("Match found for class scope");
8235 addEnumDocs(root,md);
8236 found = true;
8237 break;
8238 }
8239 else if (cd==nullptr && mcd==nullptr && nd!=nullptr && mnd==nd)
8240 {
8241 AUTO_TRACE_ADD("Match found for namespace scope");
8242 addEnumDocs(root,md);
8243 found = true;
8244 break;
8245 }
8246 else if (cd==nullptr && nd==nullptr && mcd==nullptr && mnd==nullptr && fd==mfd)
8247 {
8248 AUTO_TRACE_ADD("Match found for global scope");
8249 addEnumDocs(root,md);
8250 found = true;
8251 break;
8252 }
8253 }
8254 }
8255 }
8256 }
8257 if (!found)
8258 {
8259 warn(root->fileName,root->startLine, "Documentation for undefined enum '{}' found.", name);
8260 }
8261 }
8262 }
8263 for (const auto &e : root->children()) findEnumDocumentation(e.get());
8264}
static void addEnumDocs(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:8108
static bool tryAddEnumDocsToGroupMember(const Entry *root, const DString &name)
Definition doxygen.cpp:8150
static void findEnumDocumentation(const Entry *root)
Definition doxygen.cpp:8183

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 7684 of file doxygen.cpp.

7685{
7686 if (root->section.isEnum())
7687 {
7688 AUTO_TRACE("name={}",root->name);
7689 ClassDefMutable *cd = nullptr;
7690 FileDef *fd = nullptr;
7691 NamespaceDefMutable *nd = nullptr;
7692 MemberNameLinkedMap *mnsd = nullptr;
7693 bool isGlobal = false;
7694 bool isRelated = false;
7695 bool isMemberOf = false;
7696 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
7697
7698 DString name;
7699 DString scope;
7700
7701 if (size_t i = root->name.rfind("::"); i!=DString::npos) // scope is specified
7702 {
7703 scope=root->name.left(i); // extract scope
7704 if (root->lang==SrcLangExt::CSharp)
7705 {
7706 scope = mangleCSharpGenericName(scope);
7707 }
7708 name=root->name.right(root->name.length()-i-2); // extract name
7709 if ((cd=getClassMutable(scope))==nullptr)
7710 {
7712 }
7713 }
7714 else // no scope, check the scope in which the docs where found
7715 {
7716 if (root->parent()->section.isScope() && !root->parent()->name.empty()) // found enum docs inside a compound
7717 {
7718 scope=root->parent()->name;
7719 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7720 }
7721 name=root->name;
7722 }
7723
7724 if (!root->relates.empty())
7725 { // related member, prefix user specified scope
7726 isRelated=true;
7727 isMemberOf=(root->relatesType==RelatesType::MemberOf);
7728 if (getClass(root->relates)==nullptr && !scope.empty())
7729 scope=mergeScopes(scope,root->relates);
7730 else
7731 scope=root->relates;
7732 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7733 }
7734
7735 if (cd && !name.empty()) // found a enum inside a compound
7736 {
7737 //printf("Enum '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
7738 fd=nullptr;
7740 isGlobal=false;
7741 }
7742 else if (nd) // found enum inside namespace
7743 {
7745 isGlobal=true;
7746 }
7747 else // found a global enum
7748 {
7749 fd=root->fileDef();
7751 isGlobal=true;
7752 }
7753
7754 if (!name.empty())
7755 {
7756 // new enum type
7757 AUTO_TRACE_ADD("new enum {} at line {} of {}",name,root->bodyLine,root->fileName);
7758 auto md = createMemberDef(
7759 root->fileName,root->startLine,root->startColumn,
7760 DString(),name,DString(),DString(),
7761 root->protection,Specifier::Normal,false,
7762 isMemberOf ? Relationship::Foreign : isRelated ? Relationship::Related : Relationship::Member,
7763 MemberType::Enumeration,
7765 auto mmd = toMemberDefMutable(md.get());
7766 mmd->setTagInfo(root->tagInfo());
7767 mmd->setLanguage(root->lang);
7768 mmd->setId(root->id);
7769 if (!isGlobal) mmd->setMemberClass(cd); else mmd->setFileDef(fd);
7770 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
7771 mmd->setBodyDef(root->fileDef());
7772 mmd->setMemberSpecifiers(root->spec);
7773 mmd->setVhdlSpecifiers(root->vhdlSpec);
7774 mmd->setEnumBaseType(root->args);
7775 //printf("Enum %s definition at line %d of %s: protection=%d scope=%s\n",
7776 // qPrint(root->name),root->bodyLine,qPrint(root->fileName),root->protection,cd?qPrint(cd->name()):"<none>");
7777 mmd->addSectionsToDefinition(root->anchors);
7778 mmd->setMemberGroupId(root->mGrpId);
7780 mmd->addQualifiers(root->qualifiers);
7781 //printf("%s::setRefItems(%zu)\n",qPrint(md->name()),root->sli.size());
7782 mmd->setRefItems(root->sli);
7783 mmd->setRequirementReferences(root->rqli);
7784 //printf("found enum %s nd=%p\n",qPrint(md->name()),nd);
7785 bool defSet=false;
7786 addIncludeFile(mmd,root->fileDef(),root);
7787
7788 DString baseType = root->args;
7789 if (!baseType.empty())
7790 {
7791 baseType.prepend(" : ");
7792 }
7793
7794 if (nd)
7795 {
7796 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES) || root->lang==SrcLangExt::Python)
7797 {
7798 mmd->setDefinition(name+baseType);
7799 }
7800 else
7801 {
7802 mmd->setDefinition(nd->name()+"::"+name+baseType);
7803 }
7804 //printf("definition=%s\n",md->definition());
7805 defSet=true;
7806 mmd->setNamespace(nd);
7807 nd->insertMember(md.get());
7808 }
7809
7810 // even if we have already added the enum to a namespace, we still
7811 // also want to add it to other appropriate places such as file
7812 // or class.
7813 if (isGlobal && (nd==nullptr || !nd->isAnonymous()))
7814 {
7815 if (!defSet) mmd->setDefinition(name+baseType);
7816 if (fd==nullptr && root->parent())
7817 {
7818 fd=root->parent()->fileDef();
7819 }
7820 if (fd)
7821 {
7822 mmd->setFileDef(fd);
7823 fd->insertMember(md.get());
7824 }
7825 }
7826 else if (cd)
7827 {
7828 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES) || root->lang==SrcLangExt::Python)
7829 {
7830 mmd->setDefinition(name+baseType);
7831 }
7832 else
7833 {
7834 mmd->setDefinition(cd->name()+"::"+name+baseType);
7835 }
7836 cd->insertMember(md.get());
7837 cd->insertUsedFile(fd);
7838 }
7839 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
7840 mmd->setDocsForDefinition(!root->proto);
7841 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7842 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
7843
7844 //printf("Adding member=%s\n",qPrint(md->name()));
7845 addMemberToGroups(root,md.get());
7847
7848 MemberName *mn = mnsd->add(name);
7849 mn->push_back(std::move(md));
7850 }
7851 }
7852 else
7853 {
7854 for (const auto &e : root->children()) findEnums(e.get());
7855 }
7856}
static void findEnums(const Entry *root)
Definition doxygen.cpp:7684

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 4365 of file doxygen.cpp.

4366{
4367 AUTO_TRACE();
4368 for (const auto &fn : *Doxygen::functionNameLinkedMap) // for each global function name
4369 {
4370 MemberName *mn = Doxygen::memberNameLinkedMap->find(fn->memberName());
4371 if (mn)
4372 { // there are members with the same name
4373 // for each function with that name
4374 for (const auto &ifmd : *fn)
4375 {
4376 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
4377 // for each member with that name
4378 for (const auto &immd : *mn)
4379 {
4380 MemberDefMutable *mmd = toMemberDefMutable(immd.get());
4381 //printf("Checking for matching arguments
4382 // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n",
4383 // mmd->isRelated(),mmd->isFriend(),mmd->isFunction());
4384 if (fmd && mmd &&
4385 (mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) &&
4386 matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), mmd->typeString(), &mmd->argumentList(),
4387 fmd->getOuterScope(), fmd->getFileDef(), fmd->typeString(), &fmd->argumentList(),
4388 true,mmd->getLanguage()
4389 )
4390
4391 ) // if the member is related and the arguments match then the
4392 // function is actually a friend.
4393 {
4394 AUTO_TRACE_ADD("Merging related global and member '{}' isFriend={} isRelated={} isFunction={}",
4395 mmd->name(),mmd->isFriend(),mmd->isRelated(),mmd->isFunction());
4396 const ArgumentList &mmdAl = mmd->argumentList();
4397 const ArgumentList &fmdAl = fmd->argumentList();
4398 mergeArguments(const_cast<ArgumentList&>(fmdAl),const_cast<ArgumentList&>(mmdAl));
4399
4400 // reset argument lists to add missing default parameters
4401 DString mmdAlStr = argListToString(mmdAl);
4402 DString fmdAlStr = argListToString(fmdAl);
4403 mmd->setArgsString(mmdAlStr);
4404 fmd->setArgsString(fmdAlStr);
4405 mmd->moveDeclArgumentList(std::make_unique<ArgumentList>(mmdAl));
4406 fmd->moveDeclArgumentList(std::make_unique<ArgumentList>(fmdAl));
4407 AUTO_TRACE_ADD("friend args='{}' member args='{}'",argListToString(fmd->argumentList()),argListToString(mmd->argumentList()));
4408
4409 if (!fmd->documentation().empty())
4410 {
4411 mmd->setDocumentation(fmd->documentation(),fmd->docFile(),fmd->docLine());
4412 }
4413 else if (!mmd->documentation().empty())
4414 {
4415 fmd->setDocumentation(mmd->documentation(),mmd->docFile(),mmd->docLine());
4416 }
4417 if (mmd->briefDescription().empty() && !fmd->briefDescription().empty())
4418 {
4419 mmd->setBriefDescription(fmd->briefDescription(),fmd->briefFile(),fmd->briefLine());
4420 }
4421 else if (!mmd->briefDescription().empty() && !fmd->briefDescription().empty())
4422 {
4423 fmd->setBriefDescription(mmd->briefDescription(),mmd->briefFile(),mmd->briefLine());
4424 }
4425 if (!fmd->inbodyDocumentation().empty())
4426 {
4428 }
4429 else if (!mmd->inbodyDocumentation().empty())
4430 {
4432 }
4433 //printf("body mmd %d fmd %d\n",mmd->getStartBodyLine(),fmd->getStartBodyLine());
4434 if (mmd->getStartBodyLine()==-1 && fmd->getStartBodyLine()!=-1)
4435 {
4436 mmd->setBodySegment(fmd->getDefLine(),fmd->getStartBodyLine(),fmd->getEndBodyLine());
4437 mmd->setBodyDef(fmd->getBodyDef());
4438 //mmd->setBodyMember(fmd);
4439 }
4440 else if (mmd->getStartBodyLine()!=-1 && fmd->getStartBodyLine()==-1)
4441 {
4442 fmd->setBodySegment(mmd->getDefLine(),mmd->getStartBodyLine(),mmd->getEndBodyLine());
4443 fmd->setBodyDef(mmd->getBodyDef());
4444 //fmd->setBodyMember(mmd);
4445 }
4447
4449
4450 mmd->addQualifiers(fmd->getQualifiers());
4451 fmd->addQualifiers(mmd->getQualifiers());
4452
4453 }
4454 }
4455 }
4456 }
4457 }
4458}
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 3033 of file doxygen.cpp.

3034{
3035 AUTO_TRACE("type='{}' lang={}",type,lang);
3036 if (lang == SrcLangExt::Fortran || lang == SrcLangExt::VHDL)
3037 {
3038 return -1; // Fortran and VHDL do not have function pointers
3039 }
3040
3041 static const reg::Ex re(R"(\‍([^)]*[*&^][^)]*\))");
3043 size_t i=std::string::npos;
3044 size_t l=0;
3045 if (reg::search(type,match,re)) // contains (...*...) or (...&...) or (...^...)
3046 {
3047 i = match.position();
3048 l = match.length();
3049 }
3050 if (i!=std::string::npos)
3051 {
3052 size_t di = type.find("decltype(");
3053 if (di!=std::string::npos && di<i)
3054 {
3055 i = std::string::npos;
3056 }
3057 }
3058 size_t bb=type.find('<');
3059 size_t be=type.rfind('>');
3060 bool templFp = false;
3061 if (be!=std::string::npos) {
3062 size_t cc_ast = type.find("::*");
3063 size_t cc_amp = type.find("::&");
3064 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>::*)'
3065 }
3066
3067 if (!type.empty() && // return type is non-empty
3068 i!=std::string::npos && // contains (...*...)
3069 type.find("operator")==std::string::npos && // not an operator
3070 (type.find(")(")==std::string::npos || type.find("typedef ")!=std::string::npos) &&
3071 // not a function pointer return type
3072 (!((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
3073 )
3074 {
3075 if (pLength) *pLength=static_cast<int>(l);
3076 //printf("findFunctionPtr=%d\n",(int)i);
3077 AUTO_TRACE_EXIT("result={}",i);
3078 return static_cast<int>(i);
3079 }
3080 else
3081 {
3082 //printf("findFunctionPtr=%d\n",-1);
3083 AUTO_TRACE_EXIT("result=-1");
3084 return -1;
3085 }
3086}
#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 5897 of file doxygen.cpp.

5905{
5906 AUTO_TRACE("namespace='{}' type='{}' name='{}' tempArg='{}' decl='{}'",namespaceName,type,name,tempArg,decl);
5907 DString n=name;
5908 if (n.empty()) return false;
5909 if (n.find("::")!=DString::npos) return false; // skip undefined class members
5910 MemberName *mn=Doxygen::functionNameLinkedMap->find(n+tempArg); // look in function dictionary
5911 if (mn==nullptr)
5912 {
5913 mn=Doxygen::functionNameLinkedMap->find(n); // try without template arguments
5914 }
5915 if (mn) // function name defined
5916 {
5917 AUTO_TRACE_ADD("Found symbol name");
5918 //int count=0;
5919 bool found=false;
5920 for (const auto &md : *mn)
5921 {
5922 // If the entry has groups, then restrict the search to members which are
5923 // in one of the groups of the entry. If md is not associated with a group yet,
5924 // allow this documentation entry to add the group info.
5925 if (!root->groups.empty() && !isEntryInGroupOfMember(root, md.get(), true))
5926 {
5927 continue;
5928 }
5929
5930 const NamespaceDef *nd=nullptr;
5931 if (md->isAlias() && md->getOuterScope() &&
5932 md->getOuterScope()->definitionType()==Definition::TypeNamespace)
5933 {
5934 nd = toNamespaceDef(md->getOuterScope());
5935 }
5936 else
5937 {
5938 nd = md->getNamespaceDef();
5939 }
5940
5941 // special case for strong enums
5942 size_t enumNamePos=0;
5943 if (nd && md->isEnumValue() && (enumNamePos=namespaceName.rfind("::"))!=DString::npos)
5944 { // md part of a strong enum in a namespace?
5945 DString enumName = namespaceName.mid(enumNamePos+2);
5946 if (namespaceName.left(enumNamePos)==nd->name())
5947 {
5949 if (enumMn)
5950 {
5951 for (const auto &emd : *enumMn)
5952 {
5953 found = emd->isStrong() && md->getEnumScope()==emd.get();
5954 if (found)
5955 {
5956 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,nullptr,false,root->spec);
5957 break;
5958 }
5959 }
5960 }
5961 }
5962 if (found)
5963 {
5964 break;
5965 }
5966 }
5967 else if (nd==nullptr && md->isEnumValue()) // md part of global strong enum?
5968 {
5969 MemberName *enumMn=Doxygen::functionNameLinkedMap->find(namespaceName);
5970 if (enumMn)
5971 {
5972 for (const auto &emd : *enumMn)
5973 {
5974 found = emd->isStrong() && md->getEnumScope()==emd.get();
5975 if (found)
5976 {
5977 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,nullptr,false,root->spec);
5978 break;
5979 }
5980 }
5981 }
5982 }
5983
5984 const FileDef *fd=root->fileDef();
5985 //printf("File %s\n",fd ? qPrint(fd->name()) : "<none>");
5987 if (fd)
5988 {
5989 nl = fd->getUsedNamespaces();
5990 }
5991 //printf("NamespaceList %p\n",nl);
5992
5993 // search in the list of namespaces that are imported via a
5994 // using declaration
5995 bool viaUsingDirective = nd && nl.find(nd->qualifiedName())!=nullptr;
5996
5997 if ((namespaceName.empty() && nd==nullptr) || // not in a namespace
5998 (nd && nd->name()==namespaceName) || // or in the same namespace
5999 viaUsingDirective // member in 'using' namespace
6000 )
6001 {
6002 AUTO_TRACE_ADD("Try to add member '{}' to scope '{}'",md->name(),namespaceName);
6003
6004 NamespaceDef *rnd = nullptr;
6005 if (!namespaceName.empty()) rnd = Doxygen::namespaceLinkedMap->find(namespaceName);
6006
6007 const ArgumentList &mdAl = md.get()->argumentList();
6008 bool matching=
6009 (mdAl.empty() && root->argList.empty()) ||
6010 md->isVariable() || md->isTypedef() || /* in case of function pointers */
6011 matchArguments2(md->getOuterScope(),md->getFileDef(),md->typeString(),&mdAl,
6012 rnd ? rnd : Doxygen::globalScope,fd,root->type,&root->argList,
6013 false,root->lang);
6014
6015 // for template members we need to check if the number of
6016 // template arguments is the same, otherwise we are dealing with
6017 // different functions.
6018 if (matching && !root->tArgLists.empty())
6019 {
6020 const ArgumentList &mdTempl = md->templateArguments();
6021 if (root->tArgLists.back().size()!=mdTempl.size())
6022 {
6023 matching=false;
6024 }
6025 }
6026
6027 //printf("%s<->%s\n",
6028 // qPrint(argListToString(md->argumentList())),
6029 // qPrint(argListToString(root->argList)));
6030
6031 // For static members we also check if the comment block was found in
6032 // the same file. This is needed because static members with the same
6033 // name can be in different files. Thus it would be wrong to just
6034 // put the comment block at the first syntactically matching member. If
6035 // the comment block belongs to a group of the static member, then add
6036 // the documentation even if it is in a different file.
6037 if (matching && md->isStatic() &&
6038 md->getDefFileName()!=root->fileName &&
6039 mn->size()>1 &&
6040 !isEntryInGroupOfMember(root,md.get()))
6041 {
6042 matching = false;
6043 }
6044
6045 // for template member we also need to check the return type and requires
6046 if (!md->templateArguments().empty() && !root->tArgLists.empty())
6047 {
6048 //printf("Comparing return types '%s'<->'%s'\n",
6049 // md->typeString(),type);
6050 //printf("%s: Comparing '%s'<=>'%s'\n",qPrint(md->name()),qPrint(md->requiresClause()),qPrint(root->req));
6051 if (md->templateArguments().size()!=root->tArgLists.back().size() ||
6052 md->typeString()!=type ||
6053 md->requiresClause()!=root->req)
6054 {
6055 //printf(" ---> no matching\n");
6056 matching = false;
6057 }
6058 }
6059
6060 if (matching) // add docs to the member
6061 {
6062 AUTO_TRACE_ADD("Match found");
6063 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,&root->argList,false,root->spec);
6064 found=true;
6065 break;
6066 }
6067 }
6068 }
6069 if (!found && root->relatesType!=RelatesType::Duplicate && root->section.isFunction()) // no match
6070 {
6071 DString fullFuncDecl=decl;
6072 if (!root->argList.empty()) fullFuncDecl+=argListToString(root->argList,true);
6073 DString warnMsg = "no matching file member found for \n"+fullFuncDecl;
6074 if (mn->size()>0)
6075 {
6076 warnMsg+="\nPossible candidates:";
6077 for (const auto &md : *mn)
6078 {
6079 warnMsg+="\n '";
6080 warnMsg+=replaceAnonymousScopes(md->declaration());
6081 warnMsg+="' " + warn_line(md->getDefFileName(),md->getDefLine());
6082 }
6083 }
6084 warn(root->fileName,root->startLine, "{}", qPrint(warnMsg));
6085 }
6086 }
6087 else // got docs for an undefined member!
6088 {
6089 if (root->type!="friend class" &&
6090 root->type!="friend struct" &&
6091 root->type!="friend union" &&
6092 root->type!="friend" &&
6093 (!Config_getBool(TYPEDEF_HIDES_STRUCT) ||
6094 root->type.find("typedef ")==DString::npos)
6095 )
6096 {
6097 warn(root->fileName,root->startLine,
6098 "documented symbol '{}' was not declared or defined.",qPrint(decl)
6099 );
6100 }
6101 }
6102 return true;
6103}
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 2592 of file doxygen.cpp.

2593{
2594 FileDefSet visitedFiles;
2595 // then recursively add using directives found in #include files
2596 // to files that have not been visited.
2597 for (const auto &fn : *Doxygen::inputNameLinkedMap)
2598 {
2599 for (const auto &fd : *fn)
2600 {
2601 //printf("----- adding using directives for file %s\n",qPrint(fd->name()));
2602 fd->addIncludedUsingDirectives(visitedFiles);
2603 }
2604 }
2605}
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 5419 of file doxygen.cpp.

5420{
5421 AUTO_TRACE();
5422 ClassDefSet visitedClasses;
5423 for (const auto &[name,root] : g_classEntries)
5424 {
5425 DString bName = extractClassName(root);
5426 ClassDefMutable *cdm = getClassMutable(bName);
5427 if (cdm)
5428 {
5429 findBaseClassesForClass(root,cdm,cdm,cdm,TemplateInstances,false);
5430 }
5431 }
5432}

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

Referenced by parseInput().

◆ findMainPage()

void findMainPage ( Entry * root)
static

Definition at line 9852 of file doxygen.cpp.

9853{
9854 if (root->section.isMainpageDoc())
9855 {
9856 if (Doxygen::mainPage==nullptr && root->tagInfo()==nullptr)
9857 {
9858 //printf("mainpage: docLine=%d startLine=%d\n",root->docLine,root->startLine);
9859 //printf("Found main page! \n======\n%s\n=======\n",qPrint(root->doc));
9860 DString title=root->args.stripWhiteSpace();
9861 if (title.empty()) title = Config_getString(PROJECT_NAME);
9862 //DString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9863 DString indexName="index";
9865 indexName, root->brief+root->doc+root->inbodyDocs,title);
9866 //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
9867 Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9868 Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1);
9869 Doxygen::mainPage->setFileName(indexName);
9870 Doxygen::mainPage->setLocalToc(root->localToc);
9872
9874 if (si)
9875 {
9876 if (!si->ref().empty()) // we are from a tag file
9877 {
9878 // a page name is a label as well! but should no be double either
9880 Doxygen::mainPage->name(),
9881 indexName,
9882 root->startLine,
9883 Doxygen::mainPage->title(),
9885 0); // level 0
9886 }
9887 else if (si->lineNr() != -1)
9888 {
9889 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {}, line {})",
9890 Doxygen::mainPage->name(),si->fileName(),si->lineNr());
9891 }
9892 else
9893 {
9894 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {})",
9895 Doxygen::mainPage->name(),si->fileName());
9896 }
9897 }
9898 else
9899 {
9900 // a page name is a label as well! but should no be double either
9902 Doxygen::mainPage->name(),
9903 indexName,
9904 root->startLine,
9905 Doxygen::mainPage->title(),
9907 0); // level 0
9908 }
9909 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9910 }
9911 else if (root->tagInfo()==nullptr)
9912 {
9913 warn(root->fileName,root->startLine,
9914 "found more than one \\mainpage comment block! (first occurrence: {}, line {}), Skipping current block!",
9915 Doxygen::mainPage->docFile(),Doxygen::mainPage->getStartBodyLine());
9916 }
9917 }
9918 for (const auto &e : root->children()) findMainPage(e.get());
9919}
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)
Definition doxygen.cpp:9852

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 9922 of file doxygen.cpp.

9923{
9924 if (root->section.isMainpageDoc())
9925 {
9926 if (Doxygen::mainPage && root->tagInfo())
9927 {
9928 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9929 }
9930 }
9931 for (const auto &e : root->children()) findMainPageTagFiles(e.get());
9932}
static void findMainPageTagFiles(Entry *root)
Definition doxygen.cpp:9922

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 6850 of file doxygen.cpp.

6858{
6859 AUTO_TRACE("root='{}' funcDecl='{}' related='{}' overload={} isFunc={} mGrpId={} #tArgList={} spec={} lang={}",
6860 root->name, funcDecl, relates, overloaded, isFunc, root->mGrpId, root->tArgLists.size(),
6861 root->spec, root->lang);
6862
6863 DString scopeName;
6864 DString className;
6865 DString namespaceName;
6866 DString funcType;
6867 DString funcName;
6868 DString funcArgs;
6869 DString funcTempList;
6870 DString exceptions;
6871 DString funcSpec;
6872 bool isRelated=false;
6873 bool isMemberOf=false;
6874 bool isFriend=false;
6875 bool done=false;
6876 TypeSpecifier spec = root->spec;
6877 while (!done)
6878 {
6879 done=true;
6880 if (funcDecl.stripPrefix("friend ")) // treat friends as related members
6881 {
6882 isFriend=true;
6883 done=false;
6884 }
6885 if (funcDecl.stripPrefix("inline "))
6886 {
6887 spec.setInline(true);
6888 done=false;
6889 }
6890 if (funcDecl.stripPrefix("explicit "))
6891 {
6892 spec.setExplicit(true);
6893 done=false;
6894 }
6895 if (funcDecl.stripPrefix("mutable "))
6896 {
6897 spec.setMutable(true);
6898 done=false;
6899 }
6900 if (funcDecl.stripPrefix("thread_local "))
6901 {
6902 spec.setThreadLocal(true);
6903 done=false;
6904 }
6905 if (funcDecl.stripPrefix("virtual "))
6906 {
6907 done=false;
6908 }
6909 }
6910
6911 // delete any ; from the function declaration
6912 size_t sep=0;
6913 while ((sep=funcDecl.find(';'))!=DString::npos)
6914 {
6915 funcDecl=(funcDecl.left(sep)+funcDecl.mid(sep+1)).stripWhiteSpace();
6916 }
6917
6918 // make sure the first character is a space to simplify searching.
6919 if (!funcDecl.empty() && funcDecl[0]!=' ') funcDecl.prepend(" ");
6920
6921 // remove some superfluous spaces
6922 funcDecl= substitute(
6923 substitute(
6924 substitute(funcDecl,"~ ","~"),
6925 ":: ","::"
6926 ),
6927 " ::","::"
6928 ).stripWhiteSpace();
6929
6930 //printf("funcDecl='%s'\n",qPrint(funcDecl));
6931 if (isFriend && funcDecl.startsWith("class "))
6932 {
6933 //printf("friend class\n");
6934 funcDecl=funcDecl.mid(6);
6935 funcName = funcDecl;
6936 }
6937 else if (isFriend && funcDecl.startsWith("struct "))
6938 {
6939 funcDecl=funcDecl.mid(7);
6940 funcName = funcDecl;
6941 }
6942 else
6943 {
6944 // extract information from the declarations
6945 parseFuncDecl(funcDecl,root->lang,scopeName,funcType,funcName,
6946 funcArgs,funcTempList,exceptions
6947 );
6948 }
6949
6950 // the class name can also be a namespace name, we decide this later.
6951 // if a related class name is specified and the class name could
6952 // not be derived from the function declaration, then use the
6953 // related field.
6954 AUTO_TRACE_ADD("scopeName='{}' className='{}' namespaceName='{}' funcType='{}' funcName='{}' funcArgs='{}'",
6955 scopeName,className,namespaceName,funcType,funcName,funcArgs);
6956 if (!relates.empty())
6957 { // related member, prefix user specified scope
6958 isRelated=true;
6959 isMemberOf=(root->relatesType == RelatesType::MemberOf);
6960 if (getClass(relates)==nullptr && !scopeName.empty())
6961 {
6962 scopeName= mergeScopes(scopeName,relates);
6963 }
6964 else
6965 {
6966 scopeName = relates;
6967 }
6968 }
6969
6970 if (relates.empty() && root->parent() &&
6971 (root->parent()->section.isScope() || root->parent()->section.isObjcImpl()) &&
6972 !root->parent()->name.empty()) // see if we can combine scopeName
6973 // with the scope in which it was found
6974 {
6975 DString joinedName = root->parent()->name+"::"+scopeName;
6976 if (!scopeName.empty() &&
6977 (getClass(joinedName) || Doxygen::namespaceLinkedMap->find(joinedName)))
6978 {
6979 scopeName = joinedName;
6980 }
6981 else
6982 {
6983 scopeName = mergeScopes(root->parent()->name,scopeName);
6984 }
6985 }
6986 else // see if we can prefix a namespace or class that is used from the file
6987 {
6988 FileDef *fd=root->fileDef();
6989 if (fd)
6990 {
6991 for (const auto &fnd : fd->getUsedNamespaces())
6992 {
6993 DString joinedName = fnd->name()+"::"+scopeName;
6994 if (Doxygen::namespaceLinkedMap->find(joinedName))
6995 {
6996 scopeName=joinedName;
6997 break;
6998 }
6999 }
7000 }
7001 }
7003 removeRedundantWhiteSpace(scopeName),false,&funcSpec,DString(),false);
7004
7005 // funcSpec contains the last template specifiers of the given scope.
7006 // If this method does not have any template arguments or they are
7007 // empty while funcSpec is not empty we assume this is a
7008 // specialization of a method. If not, we clear the funcSpec and treat
7009 // this as a normal method of a template class.
7010 if (!(root->tArgLists.size()>0 &&
7011 root->tArgLists.front().size()==0
7012 )
7013 )
7014 {
7015 funcSpec.clear();
7016 }
7017
7018 //namespaceName=removeAnonymousScopes(namespaceName);
7019 if (!Config_getBool(EXTRACT_ANON_NSPACES) && scopeName.find('@')!=DString::npos) return; // skip stuff in anonymous namespace...
7020
7021 // split scope into a namespace and a class part
7022 extractNamespaceName(scopeName,className,namespaceName,true);
7023 AUTO_TRACE_ADD("scopeName='{}' className='{}' namespaceName='{}'",scopeName,className,namespaceName);
7024
7025 //printf("namespaceName='%s' className='%s'\n",qPrint(namespaceName),qPrint(className));
7026 // merge class and namespace scopes again
7027 scopeName.clear();
7028 if (!namespaceName.empty())
7029 {
7030 if (className.empty())
7031 {
7032 scopeName=namespaceName;
7033 }
7034 else if (!relates.empty() || // relates command with explicit scope
7035 !getClass(className)) // class name only exists in a namespace
7036 {
7037 scopeName=namespaceName+"::"+className;
7038 }
7039 else
7040 {
7041 scopeName=className;
7042 }
7043 }
7044 else if (!className.empty())
7045 {
7046 scopeName=className;
7047 }
7048 //printf("new scope='%s'\n",qPrint(scopeName));
7049
7050 DString tempScopeName=scopeName;
7051 ClassDefMutable *cd=getClassMutable(scopeName);
7052 if (cd)
7053 {
7054 if (funcSpec.empty())
7055 {
7056 uint32_t argListIndex=0;
7057 tempScopeName=cd->qualifiedNameWithTemplateParameters(&root->tArgLists,&argListIndex);
7058 }
7059 else
7060 {
7061 tempScopeName=scopeName+funcSpec;
7062 }
7063 }
7064 //printf("scopeName=%s cd=%p root->tArgLists=%p result=%s\n",
7065 // qPrint(scopeName),cd,root->tArgLists,qPrint(tempScopeName));
7066
7067 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
7068 // rebuild the function declaration (needed to get the scope right).
7069 if (!scopeName.empty() && !isRelated && !isFriend && !Config_getBool(HIDE_SCOPE_NAMES) && root->lang!=SrcLangExt::Python)
7070 {
7071 if (!funcType.empty())
7072 {
7073 if (isFunc) // a function -> we use argList for the arguments
7074 {
7075 funcDecl=funcType+" "+tempScopeName+"::"+funcName+funcTempList;
7076 }
7077 else
7078 {
7079 funcDecl=funcType+" "+tempScopeName+"::"+funcName+funcArgs;
7080 }
7081 }
7082 else
7083 {
7084 if (isFunc) // a function => we use argList for the arguments
7085 {
7086 funcDecl=tempScopeName+"::"+funcName+funcTempList;
7087 }
7088 else // variable => add 'argument' list
7089 {
7090 funcDecl=tempScopeName+"::"+funcName+funcArgs;
7091 }
7092 }
7093 }
7094 else // build declaration without scope
7095 {
7096 if (!funcType.empty()) // but with a type
7097 {
7098 if (isFunc) // function => omit argument list
7099 {
7100 funcDecl=funcType+" "+funcName+funcTempList;
7101 }
7102 else // variable => add 'argument' list
7103 {
7104 funcDecl=funcType+" "+funcName+funcArgs;
7105 }
7106 }
7107 else // no type
7108 {
7109 if (isFunc)
7110 {
7111 funcDecl=funcName+funcTempList;
7112 }
7113 else
7114 {
7115 funcDecl=funcName+funcArgs;
7116 }
7117 }
7118 }
7119
7120 if (funcType=="template class" && !funcTempList.empty())
7121 return; // ignore explicit template instantiations
7122
7123 AUTO_TRACE_ADD("Parse results: namespaceName='{}' className=`{}` funcType='{}' funcSpec='{}' "
7124 " funcName='{}' funcArgs='{}' funcTempList='{}' funcDecl='{}' relates='{}'"
7125 " exceptions='{}' isRelated={} isMemberOf={} isFriend={} isFunc={}",
7126 namespaceName, className, funcType, funcSpec,
7127 funcName, funcArgs, funcTempList, funcDecl, relates,
7128 exceptions, isRelated, isMemberOf, isFriend, isFunc);
7129
7130 if (!funcName.empty()) // function name is valid
7131 {
7132 // check if 'className' is actually a scoped enum, in which case we need to
7133 // process it as a global, see issue #6471
7134 bool strongEnum = false;
7135 MemberName *mn=nullptr;
7136 if (!className.empty() && (mn=Doxygen::functionNameLinkedMap->find(className)))
7137 {
7138 for (const auto &imd : *mn)
7139 {
7140 MemberDefMutable *md = toMemberDefMutable(imd.get());
7141 Definition *mdScope = nullptr;
7142 if (md && md->isEnumerate() && md->isStrong() && (mdScope=md->getOuterScope()) &&
7143 // need filter for the correct scope, see issue #9668
7144 ((namespaceName.empty() && mdScope==Doxygen::globalScope) || (mdScope->name()==namespaceName)))
7145 {
7146 AUTO_TRACE_ADD("'{}' is a strong enum! (namespace={} md->getOuterScope()->name()={})",md->name(),namespaceName,md->getOuterScope()->name());
7147 strongEnum = true;
7148 // pass the scope name name as a 'namespace' to the findGlobalMember function
7149 if (!namespaceName.empty())
7150 {
7151 namespaceName+="::"+className;
7152 }
7153 else
7154 {
7155 namespaceName=className;
7156 }
7157 }
7158 }
7159 }
7160
7161 if (funcName.startsWith("operator ")) // strip class scope from cast operator
7162 {
7163 funcName = substitute(funcName,className+"::","");
7164 }
7165 mn = nullptr;
7166 if (!funcTempList.empty()) // try with member specialization
7167 {
7168 mn=Doxygen::memberNameLinkedMap->find(funcName+funcTempList);
7169 }
7170 if (mn==nullptr) // try without specialization
7171 {
7172 mn=Doxygen::memberNameLinkedMap->find(funcName);
7173 }
7174 if (!isRelated && !strongEnum && mn) // function name already found
7175 {
7176 AUTO_TRACE_ADD("member name exists ({} members with this name)",mn->size());
7177 if (!className.empty()) // class name is valid
7178 {
7179 if (funcSpec.empty()) // not a member specialization
7180 {
7181 addMemberFunction(root,mn,scopeName,namespaceName,className,funcType,funcName,
7182 funcArgs,funcTempList,exceptions,
7183 type,args,isFriend,spec,relates,funcDecl,overloaded,isFunc);
7184 }
7185 else if (cd) // member specialization
7186 {
7187 addMemberSpecialization(root,mn,cd,funcType,funcName,funcArgs,funcDecl,exceptions,spec);
7188 }
7189 else
7190 {
7191 //printf("*** Specialized member %s of unknown scope %s%s found!\n",
7192 // qPrint(scopeName),qPrint(funcName),qPrint(funcArgs));
7193 }
7194 }
7195 else if (overloaded) // check if the function belongs to only one class
7196 {
7197 addOverloaded(root,mn,funcType,funcName,funcArgs,funcDecl,exceptions,spec);
7198 }
7199 else // unrelated function with the same name as a member
7200 {
7201 if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec))
7202 {
7203 DString fullFuncDecl=funcDecl;
7204 if (isFunc) fullFuncDecl+=argListToString(root->argList,true);
7205 warn(root->fileName,root->startLine,
7206 "Cannot determine class for function\n{}",
7207 fullFuncDecl
7208 );
7209 }
7210 }
7211 }
7212 else if (isRelated && !relates.empty())
7213 {
7214 AUTO_TRACE_ADD("related function scopeName='{}' className='{}'",scopeName,className);
7215 if (className.empty()) className=relates;
7216 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
7217 if ((cd=getClassMutable(scopeName)))
7218 {
7219 bool newMember=true; // assume we have a new member
7220 MemberDefMutable *mdDefine=nullptr;
7221 {
7222 mn = Doxygen::functionNameLinkedMap->find(funcName);
7223 if (mn)
7224 {
7225 for (const auto &imd : *mn)
7226 {
7227 MemberDefMutable *md = toMemberDefMutable(imd.get());
7228 if (md && md->isDefine())
7229 {
7230 mdDefine = md;
7231 break;
7232 }
7233 }
7234 }
7235 }
7236
7237 if (mdDefine) // macro definition is already created by the preprocessor and inserted as a file member
7238 {
7239 //printf("moving #define %s into class %s\n",qPrint(mdDefine->name()),qPrint(cd->name()));
7240
7241 // take mdDefine from the Doxygen::functionNameLinkedMap (without deleting the data)
7242 auto mdDefineTaken = Doxygen::functionNameLinkedMap->take(funcName,mdDefine);
7243 // insert it as a class member
7244 if ((mn=Doxygen::memberNameLinkedMap->find(funcName))==nullptr)
7245 {
7246 mn=Doxygen::memberNameLinkedMap->add(funcName);
7247 }
7248
7249 if (mdDefine->getFileDef())
7250 {
7251 mdDefine->getFileDef()->removeMember(mdDefine);
7252 }
7253 mdDefine->makeRelated();
7254 mdDefine->setMemberClass(cd);
7255 mdDefine->moveTo(cd);
7256 cd->insertMember(mdDefine);
7257 // also insert the member as an alias in the parent's scope, so it can be referenced also without cd's scope
7258 insertMemberAlias(cd->getOuterScope(),mdDefine);
7259 mn->push_back(std::move(mdDefineTaken));
7260 }
7261 else // normal member, needs to be created and added to the class
7262 {
7263 FileDef *fd=root->fileDef();
7264
7265 if ((mn=Doxygen::memberNameLinkedMap->find(funcName))==nullptr)
7266 {
7267 mn=Doxygen::memberNameLinkedMap->add(funcName);
7268 }
7269 else
7270 {
7271 // see if we got another member with matching arguments
7272 MemberDefMutable *rmd_found = nullptr;
7273 for (const auto &irmd : *mn)
7274 {
7275 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
7276 if (rmd)
7277 {
7278 const ArgumentList &rmdAl = rmd->argumentList();
7279
7280 newMember=
7281 className!=rmd->getOuterScope()->name() ||
7282 !matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmd->typeString(),&rmdAl,
7283 cd,fd,root->type,&root->argList,
7284 true,root->lang);
7285 if (!newMember)
7286 {
7287 rmd_found = rmd;
7288 }
7289 }
7290 }
7291 if (rmd_found) // member already exists as rmd -> add docs
7292 {
7293 AUTO_TRACE_ADD("addMemberDocs for related member {}",root->name);
7294 addMemberDocs(root,rmd_found,funcDecl,nullptr,overloaded,spec);
7295 newMember=false;
7296 }
7297 }
7298
7299 if (newMember) // need to create a new member
7300 {
7301 MemberType mtype = MemberType::Function;
7302 switch (root->mtype)
7303 {
7304 case MethodTypes::Method: mtype = MemberType::Function; break;
7305 case MethodTypes::Signal: mtype = MemberType::Signal; break;
7306 case MethodTypes::Slot: mtype = MemberType::Slot; break;
7307 case MethodTypes::DCOP: mtype = MemberType::DCOP; break;
7308 case MethodTypes::Property: mtype = MemberType::Property; break;
7309 case MethodTypes::Event: mtype = MemberType::Event; break;
7310 }
7311
7312 //printf("New related name '%s' '%d'\n",qPrint(funcName),
7313 // root->argList ? (int)root->argList->count() : -1);
7314
7315 // first note that we pass:
7316 // (root->tArgLists ? root->tArgLists->last() : nullptr)
7317 // for the template arguments for the new "member."
7318 // this accurately reflects the template arguments of
7319 // the related function, which don't have to do with
7320 // those of the related class.
7321 auto md = createMemberDef(
7322 root->fileName,root->startLine,root->startColumn,
7323 funcType,funcName,funcArgs,exceptions,
7324 root->protection,root->virt,
7325 root->isStatic,
7326 isMemberOf ? Relationship::Foreign : Relationship::Related,
7327 mtype,
7328 (!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList()),
7329 funcArgs.empty() ? ArgumentList() : root->argList,
7330 root->metaData);
7331 auto mmd = toMemberDefMutable(md.get());
7332
7333 // also insert the member as an alias in the parent's scope, so it can be referenced also without cd's scope
7334 insertMemberAlias(cd->getOuterScope(),md.get());
7335
7336 // we still have the problem that
7337 // MemberDef::writeDocumentation() in memberdef.cpp
7338 // writes the template argument list for the class,
7339 // as if this member is a member of the class.
7340 // fortunately, MemberDef::writeDocumentation() has
7341 // a special mechanism that allows us to totally
7342 // override the set of template argument lists that
7343 // are printed. We use that and set it to the
7344 // template argument lists of the related function.
7345 //
7346 mmd->setDefinitionTemplateParameterLists(root->tArgLists);
7347
7348 mmd->setTagInfo(root->tagInfo());
7349
7350 addIncludeFile(mmd,root->fileDef(),root);
7351 //printf("Related member name='%s' decl='%s' bodyLine='%d'\n",
7352 // qPrint(funcName),qPrint(funcDecl),root->bodyLine);
7353
7354 // try to find the matching line number of the body from the
7355 // global function list
7356 bool found=false;
7357 if (root->bodyLine==-1)
7358 {
7360 if (rmn)
7361 {
7362 const MemberDefMutable *rmd_found=nullptr;
7363 for (const auto &irmd : *rmn)
7364 {
7365 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
7366 if (rmd)
7367 {
7368 const ArgumentList &rmdAl = rmd->argumentList();
7369 // check for matching argument lists
7370 if (
7371 matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmd->typeString(),&rmdAl,
7372 cd,fd,root->type,&root->argList,
7373 true,root->lang)
7374 )
7375 {
7376 found=true;
7377 rmd_found = rmd;
7378 break;
7379 }
7380 }
7381 }
7382 if (rmd_found) // member found -> copy line number info
7383 {
7384 mmd->setBodySegment(rmd_found->getDefLine(),rmd_found->getStartBodyLine(),rmd_found->getEndBodyLine());
7385 mmd->setBodyDef(rmd_found->getBodyDef());
7386 //md->setBodyMember(rmd);
7387 }
7388 }
7389 }
7390 if (!found) // line number could not be found or is available in this
7391 // entry
7392 {
7393 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
7394 mmd->setBodyDef(fd);
7395 }
7396
7397 //if (root->mGrpId!=-1)
7398 //{
7399 // md->setMemberGroup(memberGroupDict[root->mGrpId]);
7400 //}
7401 mmd->setMemberClass(cd);
7402 mmd->setMemberSpecifiers(spec);
7403 mmd->setVhdlSpecifiers(root->vhdlSpec);
7404 mmd->setDefinition(funcDecl);
7406 mmd->addQualifiers(root->qualifiers);
7407 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
7408 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
7409 mmd->setDocsForDefinition(!root->proto);
7410 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
7411 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7412 mmd->addSectionsToDefinition(root->anchors);
7413 mmd->setMemberGroupId(root->mGrpId);
7414 mmd->setLanguage(root->lang);
7415 mmd->setId(root->id);
7416 //md->setMemberDefTemplateArguments(root->mtArgList);
7417 cd->insertMember(md.get());
7418 cd->insertUsedFile(fd);
7419 mmd->setRefItems(root->sli);
7420 mmd->setRequirementReferences(root->rqli);
7421 if (root->relatesType==RelatesType::Duplicate) mmd->setRelatedAlso(cd);
7422 addMemberToGroups(root,md.get());
7424 //printf("Adding member=%s\n",qPrint(md->name()));
7425 mn->push_back(std::move(md));
7426 }
7427 if (root->relatesType==RelatesType::Duplicate)
7428 {
7429 if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec))
7430 {
7431 DString fullFuncDecl=funcDecl;
7432 if (isFunc) fullFuncDecl+=argListToString(root->argList,true);
7433 warn(root->fileName,root->startLine,
7434 "Cannot determine file/namespace for relatedalso function\n{}",
7435 fullFuncDecl
7436 );
7437 }
7438 }
7439 }
7440 }
7441 else
7442 {
7443 warn_undoc(root->fileName,root->startLine, "class '{}' for related function '{}' is not documented.", className,funcName);
7444 }
7445 }
7446 else if (root->parent() && root->parent()->section.isObjcImpl())
7447 {
7448 addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec);
7449 }
7450 else // unrelated not overloaded member found
7451 {
7452 bool globMem = findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec);
7453 if (className.empty() && !globMem)
7454 {
7455 warn(root->fileName,root->startLine, "class for member '{}' cannot be found.", funcName);
7456 }
7457 else if (!className.empty() && !globMem)
7458 {
7459 warn(root->fileName,root->startLine,
7460 "member '{}' of class '{}' cannot be found",
7461 funcName,className);
7462 }
7463 }
7464 }
7465 else
7466 {
7467 // this should not be called
7468 warn(root->fileName,root->startLine,"member with no name found.");
7469 }
7470 return;
7471}
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:318
static void insertMemberAlias(Definition *outerScope, const MemberDef *md)
Definition doxygen.cpp:6807
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:6674
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:6318
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:6738
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:5897

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 7626 of file doxygen.cpp.

7627{
7628 if (root->section.isMemberDoc() ||
7629 root->section.isOverloadDoc() ||
7630 root->section.isFunction() ||
7631 root->section.isVariable() ||
7632 root->section.isVariableDoc() ||
7633 root->section.isDefine() ||
7634 root->section.isIncludedService() ||
7635 root->section.isExportedInterface()
7636 )
7637 {
7638 AUTO_TRACE();
7639 if (root->relatesType==RelatesType::Duplicate && !root->relates.empty())
7640 {
7642 }
7644 }
7645 for (const auto &e : root->children())
7646 {
7647 if (!e->section.isEnum())
7648 {
7649 findMemberDocumentation(e.get());
7650 }
7651 }
7652}
static void findMemberDocumentation(const Entry *root)
Definition doxygen.cpp:7626
static void filterMemberDocumentation(const Entry *root, const DString &relates)
Definition doxygen.cpp:7477

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 7656 of file doxygen.cpp.

7657{
7658 AUTO_TRACE();
7659 for (const auto &objCImpl : root->children())
7660 {
7661 if (objCImpl->section.isObjcImpl())
7662 {
7663 for (const auto &objCMethod : objCImpl->children())
7664 {
7665 if (objCMethod->section.isFunction())
7666 {
7667 //printf(" Found ObjC method definition %s\n",qPrint(objCMethod->name));
7668 findMember(objCMethod.get(),
7669 objCMethod->relates,
7670 objCMethod->type,
7671 objCMethod->args,
7672 objCMethod->type+" "+objCImpl->name+"::"+objCMethod->name+" "+objCMethod->args,
7673 false,true);
7674 objCMethod->section=EntryType::makeEmpty();
7675 }
7676 }
7677 }
7678 }
7679}

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 9494 of file doxygen.cpp.

9495{
9496 // for each class
9497 for (const auto &cd : *Doxygen::classLinkedMap)
9498 {
9499 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9500 if (cdm)
9501 {
9503 }
9504 }
9505 // for each concept
9506 for (const auto &cd : *Doxygen::conceptLinkedMap)
9507 {
9508 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
9509 if (cdm)
9510 {
9512 }
9513 }
9514 // for each file
9515 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9516 {
9517 for (const auto &fd : *fn)
9518 {
9519 fd->findSectionsInDocumentation();
9520 }
9521 }
9522 // for each namespace
9523 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9524 {
9526 if (ndm)
9527 {
9529 }
9530 }
9531 // for each group
9532 for (const auto &gd : *Doxygen::groupLinkedMap)
9533 {
9534 gd->findSectionsInDocumentation();
9535 }
9536 // for each page
9537 for (const auto &pd : *Doxygen::pageLinkedMap)
9538 {
9539 pd->findSectionsInDocumentation();
9540 }
9541 // for each directory
9542 for (const auto &dd : *Doxygen::dirLinkedMap)
9543 {
9544 dd->findSectionsInDocumentation();
9545 }
9547 if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
9548}
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 1796 of file doxygen.cpp.

1797{
1798 std::set<const Definition *> candidates;
1799 for (auto &cd : *Doxygen::classLinkedMap)
1800 {
1801 Definition *scope = cd->getOuterScope();
1802 //printf(" scope=%s for class %s\n",qPrint(scope?scope->name():"<null>"),qPrint(cd->name()));
1803 if (scope && scope->definitionType()==Definition::TypeNamespace) // class that is not nested
1804 {
1805 const NamespaceDef *nd = toNamespaceDef(scope);
1806 if (nd && nd==Doxygen::globalScope) // class at global namespace
1807 {
1808 const FileDef *fd = cd->getFileDef();
1809 if (fd)
1810 {
1811 findTagLessClasses(candidates,fd);
1812 }
1813 }
1814 else if (nd) // class in a namespace
1815 {
1816 findTagLessClasses(candidates,nd);
1817 }
1818 }
1819 }
1820
1821 // since processTagLessClasses is potentially adding classes to Doxygen::classLinkedMap
1822 // we need to call it outside of the loop above, otherwise the iterator gets invalidated!
1823 for (const auto &d : candidates)
1824 {
1825 //printf("------ processing tag-less classes for %s\n",qPrint(d->name()));
1826 if (d->definitionType()==Definition::TypeNamespace)
1827 {
1828 const NamespaceDef *nd = toNamespaceDef(d);
1829 processTagLessClasses(nd,nd,nd,MemberListType::DecVarMembers(),MemberListType::DecEnumMembers(),"",0);
1830 }
1831 else if (d->definitionType()==Definition::TypeFile)
1832 {
1833 const FileDef *fd = toFileDef(d);
1834 processTagLessClasses(fd,fd,fd,MemberListType::DecVarMembers(),MemberListType::DecEnumMembers(),"",0);
1835 }
1836 else if (d->definitionType()==Definition::TypeClass)
1837 {
1838 const ClassDef *cd = toClassDef(d);
1839 processTagLessClasses(cd,cd,cd,MemberListType::PubAttribs(),MemberListType::PubTypes(),"",0);
1840 }
1841 }
1842}
ClassDef * toClassDef(Definition *d)
static void processTagLessClasses(const Definition *root, const Container *cd, 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:1704
static void findTagLessClasses()
Definition doxygen.cpp:1796

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 1783 of file doxygen.cpp.

1784{
1785 for (const auto &icd : cd->getClasses())
1786 {
1787 if (icd->name().find('@')==DString::npos) // process all non-anonymous inner classes
1788 {
1789 findTagLessClasses(candidates,icd);
1790 }
1791 }
1792
1793 candidates.insert(cd);
1794}

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 4899 of file doxygen.cpp.

4904{
4905 AUTO_TRACE("Derived from template '{}' with parameters '{}' isArtificial={}",
4906 templateClass->name(),templSpec,isArtificial);
4907
4908 DString tempArgsStr = tempArgListToString(templateClass->templateArguments(),root->lang,false);
4909 bool existingClass = templSpec==tempArgsStr;
4910 if (existingClass) return; // avoid recursion
4911
4912 bool freshInstance=false;
4913 ClassDefMutable *instanceClass = toClassDefMutable(
4914 templateClass->insertTemplateInstance(
4915 root->fileName,root->startLine,root->startColumn,templSpec,freshInstance));
4916 if (instanceClass)
4917 {
4918 if (freshInstance)
4919 {
4920 instanceClass->setArtificial(true);
4921 instanceClass->setLanguage(root->lang);
4922
4923 AUTO_TRACE_ADD("found fresh instance '{}'",instanceClass->name());
4924 instanceClass->setTemplateBaseClassNames(templateNames);
4925
4926 // search for new template instances caused by base classes of
4927 // instanceClass
4928 auto it_pair = g_classEntries.equal_range(templateClass->name().str());
4929 for (auto it=it_pair.first ; it!=it_pair.second ; ++it)
4930 {
4931 const Entry *templateRoot = it->second;
4932 AUTO_TRACE_ADD("template root found '{}' templSpec='{}'",templateRoot->name,templSpec);
4933 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(root->lang,templSpec);
4934 findBaseClassesForClass(templateRoot,context,templateClass,instanceClass,
4935 TemplateInstances,isArtificial,templArgs.get(),templateNames);
4936
4937 findUsedClassesForClass(templateRoot,context,templateClass,instanceClass,
4938 isArtificial,templArgs.get(),templateNames);
4939 }
4940 }
4941 else
4942 {
4943 AUTO_TRACE_ADD("instance already exists");
4944 }
4945 }
4946}
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:4692

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 4990 of file doxygen.cpp.

4991{
4992 if (name.empty()) return 0;
4993 int l = static_cast<int>(name.length());
4994 if (name[l-1]=='>') // search backward to find the matching <, allowing nested <...> and strings.
4995 {
4996 int count=1;
4997 int i=l-2;
4998 char insideQuote=0;
4999 while (count>0 && i>=0)
5000 {
5001 char c = name[i--];
5002 switch (c)
5003 {
5004 case '>': if (!insideQuote) count++; break;
5005 case '<': if (!insideQuote) count--; break;
5006 case '\'': if (!insideQuote) insideQuote=c;
5007 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
5008 break;
5009 case '"': if (!insideQuote) insideQuote=c;
5010 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
5011 break;
5012 default: break;
5013 }
5014 }
5015 if (i>=0) l=i+1;
5016 }
5017 return l;
5018}

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

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 4692 of file doxygen.cpp.

4700{
4701 AUTO_TRACE();
4702 const ArgumentList &formalArgs = masterCd->templateArguments();
4703 for (auto &mni : masterCd->memberNameInfoLinkedMap())
4704 {
4705 for (auto &mi : *mni)
4706 {
4707 const MemberDef *md=mi->memberDef();
4708 if (md->isVariable() || md->isObjCProperty()) // for each member variable in this class
4709 {
4710 AUTO_TRACE_ADD("Found variable '{}' in class '{}'",md->name(),masterCd->name());
4711 DString type = normalizeNonTemplateArgumentsInString(md->typeString(),masterCd,formalArgs);
4712 DString typedefValue = md->getLanguage()==SrcLangExt::Java ? type : resolveTypeDef(masterCd,type);
4713 if (!typedefValue.empty())
4714 {
4715 type = typedefValue;
4716 }
4717 int pos=0;
4718 DString usedClassName;
4719 DString templSpec;
4720 bool found=false;
4721 // the type can contain template variables, replace them if present
4722 type = substituteTemplateArgumentsInString(type,formalArgs,actualArgs);
4723
4724 //printf(" template substitution gives=%s\n",qPrint(type));
4725 while (!found && extractClassNameFromType(type,pos,usedClassName,templSpec,root->lang)!=-1)
4726 {
4727 // find the type (if any) that matches usedClassName
4728 SymbolResolver resolver(masterCd->getFileDef());
4729 const ClassDefMutable *typeCd = resolver.resolveClassMutable(masterCd,usedClassName,false,true);
4730 //printf("====> usedClassName=%s -> typeCd=%s\n",
4731 // qPrint(usedClassName),typeCd?qPrint(typeCd->name()):"<none>");
4732 if (typeCd)
4733 {
4734 usedClassName = typeCd->name();
4735 }
4736
4737 // replace any namespace aliases
4738 replaceNamespaceAliases(usedClassName);
4739 // add any template arguments to the class
4740 DString usedName = removeRedundantWhiteSpace(usedClassName+templSpec);
4741 //printf(" usedName=%s usedClassName=%s templSpec=%s\n",qPrint(usedName),qPrint(usedClassName),qPrint(templSpec));
4742
4743 TemplateNameMap formTemplateNames;
4744 if (templateNames.empty())
4745 {
4746 formTemplateNames = getTemplateArgumentsInName(formalArgs,usedName.str());
4747 }
4748 BaseInfo bi(usedName,Protection::Public,Specifier::Normal);
4749 findClassRelation(root,context,instanceCd,&bi,formTemplateNames,TemplateInstances,isArtificial);
4750
4751 for (const Argument &arg : masterCd->templateArguments())
4752 {
4753 if (arg.name==usedName) // type is a template argument
4754 {
4755 ClassDef *usedCd = Doxygen::hiddenClassLinkedMap->find(usedName);
4756 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4757 if (usedCd==nullptr)
4758 {
4759 usedCdm = toClassDefMutable(
4760 Doxygen::hiddenClassLinkedMap->add(usedName,
4762 masterCd->getDefFileName(),masterCd->getDefLine(),
4763 masterCd->getDefColumn(),
4764 usedName,
4765 ClassDef::Class)));
4766 if (usedCdm)
4767 {
4768 //printf("making %s a template argument!!!\n",qPrint(usedCd->name()));
4769 usedCdm->makeTemplateArgument();
4770 usedCdm->setUsedOnly(true);
4771 usedCdm->setLanguage(masterCd->getLanguage());
4772 usedCd = usedCdm;
4773 }
4774 }
4775 if (usedCd)
4776 {
4777 found=true;
4778 AUTO_TRACE_ADD("case 1: adding used class '{}'", usedCd->name());
4779 instanceCd->addUsedClass(usedCd,md->name(),md->protection());
4780 if (usedCdm)
4781 {
4782 if (isArtificial) usedCdm->setArtificial(true);
4783 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4784 }
4785 }
4786 }
4787 }
4788
4789 if (!found)
4790 {
4791 ClassDef *usedCd=findClassWithinClassContext(context,masterCd,usedName);
4792 //printf("Looking for used class %s: result=%s master=%s\n",
4793 // qPrint(usedName),usedCd?qPrint(usedCd->name()):"<none>",masterCd?qPrint(masterCd->name()):"<none>");
4794
4795 if (usedCd)
4796 {
4797 found=true;
4798 AUTO_TRACE_ADD("case 2: adding used class '{}'", usedCd->name());
4799 instanceCd->addUsedClass(usedCd,md->name(),md->protection()); // class exists
4800 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4801 if (usedCdm)
4802 {
4803 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4804 }
4805 }
4806 }
4807 }
4808 if (!found && !type.empty()) // used class is not documented in any scope
4809 {
4811 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4812 if (usedCd==nullptr && !Config_getBool(HIDE_UNDOC_RELATIONS))
4813 {
4814 if (type.endsWith("(*") || type.endsWith("(^")) // type is a function pointer
4815 {
4816 type+=md->argsString();
4817 }
4818 AUTO_TRACE_ADD("New undocumented used class '{}'", type);
4819 usedCdm = toClassDefMutable(
4822 masterCd->getDefFileName(),masterCd->getDefLine(),
4823 masterCd->getDefColumn(),
4824 type,ClassDef::Class)));
4825 if (usedCdm)
4826 {
4827 usedCdm->setUsedOnly(true);
4828 usedCdm->setLanguage(masterCd->getLanguage());
4829 usedCd = usedCdm;
4830 }
4831 }
4832 if (usedCd)
4833 {
4834 AUTO_TRACE_ADD("case 3: adding used class '{}'", usedCd->name());
4835 instanceCd->addUsedClass(usedCd,md->name(),md->protection());
4836 if (usedCdm)
4837 {
4838 if (isArtificial) usedCdm->setArtificial(true);
4839 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4840 }
4841 }
4842 }
4843 }
4844 }
4845 }
4846}
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:3466
int extractClassNameFromType(const DString &type, int &pos, DString &name, DString &templSpec, SrcLangExt lang)
Definition util.cpp:3381

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 2019 of file doxygen.cpp.

2021{
2022 NamespaceDef *usingNd =nullptr;
2023 for (auto &und : unl)
2024 {
2025 DString uScope=und->name()+"::";
2026 usingNd = getResolvedNamespace(uScope+name);
2027 if (usingNd!=nullptr) break;
2028 }
2029 return usingNd;
2030}

References getResolvedNamespace().

Referenced by findUsingDirectives().

◆ findUsedTemplateInstances()

void findUsedTemplateInstances ( )
static

Definition at line 5452 of file doxygen.cpp.

5453{
5454 AUTO_TRACE();
5455 for (const auto &[name,root] : g_classEntries)
5456 {
5457 DString bName = extractClassName(root);
5458 ClassDefMutable *cdm = getClassMutable(bName);
5459 if (cdm)
5460 {
5461 findUsedClassesForClass(root,cdm,cdm,cdm,true);
5463 cdm->addTypeConstraints();
5464 }
5465 }
5466}
virtual void addTypeConstraints()=0
static void makeTemplateInstanceRelation(const Entry *root, ClassDefMutable *cd)
Definition doxygen.cpp:5434

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 2189 of file doxygen.cpp.

2190{
2191 if (root->section.isUsingDecl() &&
2192 !root->parent()->section.isCompound() && // not a class/struct member
2193 (!filterPythonPackages || (root->lang==SrcLangExt::Python && root->fileName.endsWith("__init__.py")))
2194 )
2195 {
2196 AUTO_TRACE("Found using declaration '{}' at line {} of {} inside section {}",
2197 root->name,root->startLine,root->fileName,root->parent()->section);
2198 if (!root->name.empty())
2199 {
2200 const Definition *usingDef = nullptr;
2201 NamespaceDefMutable *nd = nullptr;
2202 FileDef *fd = root->fileDef();
2203 DString scName;
2204
2205 // see if the using statement was found inside a namespace or inside
2206 // the global file scope.
2207 if (root->parent()->section.isNamespace())
2208 {
2209 scName=root->parent()->name;
2210 if (!scName.empty())
2211 {
2212 nd = getResolvedNamespaceMutable(scName);
2213 }
2214 }
2215
2216 // Assume the using statement was used to import a class.
2217 // Find the scope in which the 'using' namespace is defined by prepending
2218 // the possible scopes in which the using statement was found, starting
2219 // with the most inner scope and going to the most outer scope (i.e.
2220 // file scope).
2221
2222 DString name = substitute(root->name,".","::"); //Java/C# scope->internal
2223
2224 SymbolResolver resolver;
2225 const Definition *scope = nd;
2226 if (nd==nullptr) scope = fd;
2227 usingDef = resolver.resolveSymbol(scope,name);
2228
2229 //printf("usingDef(scope=%s,name=%s)=%s\n",qPrint(nd?nd->qualifiedName():""),qPrint(name),usingDef?qPrint(usingDef->qualifiedName()):"nullptr");
2230
2231 if (!usingDef)
2232 {
2233 usingDef = getClass(name); // try direct lookup, this is needed to get
2234 // builtin STL classes to properly resolve, e.g.
2235 // vector -> std::vector
2236 }
2237 if (!usingDef)
2238 {
2239 usingDef = Doxygen::hiddenClassLinkedMap->find(name); // check if it is already hidden
2240 }
2241#if 0
2242 if (!usingDef)
2243 {
2244 AUTO_TRACE_ADD("New using class '{}' (sec={})! #tArgLists={}",
2245 name,root->section,root->tArgLists.size());
2248 createClassDef( "<using>",1,1, name, ClassDef::Class)));
2249 if (usingCd)
2250 {
2251 usingCd->setArtificial(true);
2252 usingCd->setLanguage(root->lang);
2253 usingDef = usingCd;
2254 }
2255 }
2256#endif
2257 else
2258 {
2259 AUTO_TRACE_ADD("Found used type '{}' in scope='{}'",
2260 usingDef->name(), nd ? nd->name(): fd ? fd->name() : DString("<unknown>"));
2261 }
2262
2263 if (usingDef)
2264 {
2265 if (nd)
2266 {
2267 nd->addUsingDeclaration(usingDef);
2268 }
2269 else if (fd)
2270 {
2271 fd->addUsingDeclaration(usingDef);
2272 }
2273 }
2274 }
2275 }
2276 for (const auto &e : root->children()) findUsingDeclarations(e.get(),filterPythonPackages);
2277}
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:2189

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 2342 of file doxygen.cpp.

2343{
2344 if (root->section.isUsingDecl() &&
2345 root->parent()->section.isCompound() // in a class/struct member
2346 )
2347 {
2348 AUTO_TRACE("Found using declaration '{}' inside section {}", root->name, root->parent()->section);
2349 DString fullName=removeRedundantWhiteSpace(root->parent()->name);
2350 fullName=stripAnonymousNamespaceScope(fullName);
2351 fullName=stripTemplateSpecifiersFromScope(fullName);
2352 ClassDefMutable *cd = getClassMutable(fullName);
2353 if (cd)
2354 {
2355 AUTO_TRACE_ADD("found class '{}'",cd->name());
2356 size_t i=root->name.rfind("::");
2357 if (i!=DString::npos)
2358 {
2359 DString scope=root->name.left(i);
2360 DString memName=root->name.mid(i+2);
2361 SymbolResolver resolver;
2362 const ClassDef *bcd = resolver.resolveClass(cd,scope); // todo: file in fileScope parameter
2363 AUTO_TRACE_ADD("name={} scope={} bcd={}",scope,cd?cd->name():"<none>",bcd?bcd->name():"<none>");
2364 if (bcd && bcd!=cd)
2365 {
2366 AUTO_TRACE_ADD("found class '{}' memName='{}'",bcd->name(),memName);
2368 const MemberNameInfo *mni = mnlm.find(memName);
2369 if (mni)
2370 {
2371 for (auto &mi : *mni)
2372 {
2373 const MemberDef *md = mi->memberDef();
2374 if (md && md->protection()!=Protection::Private)
2375 {
2376 AUTO_TRACE_ADD("found member '{}'",mni->memberName());
2377 DString fileName = root->fileName;
2378 if (fileName.empty() && root->tagInfo())
2379 {
2380 fileName = root->tagInfo()->tagName;
2381 }
2382 if (!cd->containsOverload(md))
2383 {
2384 createUsingMemberImportForClass(root,cd,md,fileName,memName);
2385 // also insert the member into copies of the class
2386 auto it = g_usingClassMap.find(cd->qualifiedName().str());
2387 if (it != g_usingClassMap.end())
2388 {
2389 for (const auto &copyCd : it->second)
2390 {
2391 createUsingMemberImportForClass(root,copyCd,md,fileName,memName);
2392 }
2393 }
2394 }
2395 }
2396 }
2397 }
2398 }
2399 }
2400 }
2401 }
2402 else if (root->section.isUsingDecl() &&
2403 (root->parent()->section.isNamespace() || root->parent()->section.isEmpty()) && // namespace or global member
2404 root->lang==SrcLangExt::Cpp // do we also want this for e.g. Fortran? (see test case 095)
2405 )
2406 {
2407 AUTO_TRACE("Found using declaration '{}' inside section {}", root->name, root->parent()->section);
2408 Definition *scope = nullptr;
2409 NamespaceDefMutable *nd = nullptr;
2410 FileDef *fd = root->parent()->fileDef();
2411 if (!root->parent()->name.empty())
2412 {
2413 DString fullName=removeRedundantWhiteSpace(root->parent()->name);
2414 fullName=stripAnonymousNamespaceScope(fullName);
2416 scope = nd;
2417 }
2418 else
2419 {
2420 scope = fd;
2421 }
2422 if (scope)
2423 {
2424 AUTO_TRACE_ADD("found scope '{}'",scope->name());
2425 SymbolResolver resolver;
2426 const Definition *def = resolver.resolveSymbol(root->name.startsWith("::") ? nullptr : scope,root->name);
2427 if (def && def->definitionType()==Definition::TypeMember)
2428 {
2429 size_t i=root->name.rfind("::");
2430 DString memName;
2431 if (i!=DString::npos)
2432 {
2433 memName = root->name.right(root->name.length()-i-2);
2434 }
2435 else
2436 {
2437 memName = root->name;
2438 }
2439 const MemberDef *md = toMemberDef(def);
2440 AUTO_TRACE_ADD("found member '{}' for name '{}'",md->qualifiedName(),root->name);
2441 DString fileName = root->fileName;
2442 if (fileName.empty() && root->tagInfo())
2443 {
2444 fileName = root->tagInfo()->tagName;
2445 }
2446 const ArgumentList &templAl = md->templateArguments();
2447 const ArgumentList &al = md->argumentList();
2448
2449 auto newMd = createMemberDef(
2450 fileName,root->startLine,root->startColumn,
2451 md->typeString(),memName,md->argsString(),
2452 md->excpString(),root->protection,root->virt,
2453 md->isStatic(),Relationship::Member,md->memberType(),
2454 templAl,al,root->metaData
2455 );
2456 auto newMmd = toMemberDefMutable(newMd.get());
2457 if (nd)
2458 {
2459 newMmd->setNamespace(nd);
2460 nd->insertMember(newMd.get());
2461 }
2462 if (fd)
2463 {
2464 newMmd->setFileDef(fd);
2465 fd->insertMember(newMd.get());
2466 }
2467 if (!root->doc.empty() || !root->brief.empty())
2468 {
2469 newMmd->setDocumentation(root->doc,root->docFile,root->docLine);
2470 newMmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2471 newMmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2472 }
2473 else
2474 {
2475 newMmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
2476 newMmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
2477 newMmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
2478 }
2479 newMmd->setDefinition(md->definition());
2480 applyMemberOverrideOptions(root,newMmd);
2481 newMmd->addQualifiers(root->qualifiers);
2482 newMmd->setBitfields(md->bitfieldString());
2483 newMmd->addSectionsToDefinition(root->anchors);
2484 newMmd->setBodySegment(md->getDefLine(),md->getStartBodyLine(),md->getEndBodyLine());
2485 newMmd->setBodyDef(md->getBodyDef());
2486 newMmd->setInitializer(md->initializer());
2487 newMmd->setRequiresClause(md->requiresClause());
2488 newMmd->setMaxInitLines(md->initializerLines());
2489 newMmd->setMemberGroupId(root->mGrpId);
2490 newMmd->setMemberSpecifiers(md->getMemberSpecifiers());
2491 newMmd->setVhdlSpecifiers(md->getVhdlSpecifiers());
2492 newMmd->setLanguage(root->lang);
2493 newMmd->setId(root->id);
2495 mn->push_back(std::move(newMd));
2496#if 0 // insert an alias instead of a copy
2497 const MemberDef *md = toMemberDef(def);
2498 AUTO_TRACE_ADD("found member '{}' for name '{}'",md->qualifiedName(),root->name);
2499 auto aliasMd = createMemberDefAlias(nd,md);
2500 DString aliasFullName = nd->qualifiedName()+"::"+aliasMd->localName();
2501 if (nd && aliasMd.get())
2502 {
2503 nd->insertMember(aliasMd.get());
2504 }
2505 if (fd && aliasMd.get())
2506 {
2507 fd->insertMember(aliasMd.get());
2508 }
2509 MemberName *mn = Doxygen::memberNameLinkedMap->add(aliasFullName);
2510 mn->push_back(std::move(aliasMd));
2511#endif
2512 }
2513 else if (def && def->definitionType()==Definition::TypeClass)
2514 {
2515 const ClassDef *cd = toClassDef(def);
2516 DString copyFullName;
2517 if (nd==nullptr)
2518 {
2519 copyFullName = cd->localName();
2520 }
2521 else
2522 {
2523 copyFullName = nd->qualifiedName()+"::"+cd->localName();
2524 }
2525 if (Doxygen::classLinkedMap->find(copyFullName)==nullptr)
2526 {
2528 Doxygen::classLinkedMap->add(copyFullName,
2529 cd->deepCopy(copyFullName)));
2530 AUTO_TRACE_ADD("found class '{}' for name '{}' copy '{}' obj={}",cd->qualifiedName(),root->name,copyFullName,(void*)ncdm);
2531 g_usingClassMap[cd->qualifiedName().str()].push_back(ncdm);
2532 if (ncdm)
2533 {
2534 if (nd) ncdm->moveTo(nd);
2535 if ((!root->doc.empty() || !root->brief.empty())) // use docs at using statement
2536 {
2537 ncdm->setDocumentation(root->doc,root->docFile,root->docLine);
2538 ncdm->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2539 }
2540 else // use docs from used class
2541 {
2542 ncdm->setDocumentation(cd->documentation(),cd->docFile(),cd->docLine());
2544 }
2545 if (nd)
2546 {
2547 nd->addInnerCompound(ncdm);
2548 nd->addUsingDeclaration(ncdm);
2549 }
2550 if (fd)
2551 {
2552 if (ncdm) ncdm->setFileDef(fd);
2553 fd->insertClass(ncdm);
2554 fd->addUsingDeclaration(ncdm);
2555 }
2556 }
2557 }
2558#if 0 // insert an alias instead of a copy
2559 auto aliasCd = createClassDefAlias(nd,cd);
2560 DString aliasFullName;
2561 if (nd==nullptr)
2562 {
2563 aliasFullName = aliasCd->localName();
2564 }
2565 else
2566 {
2567 aliasFullName = nd->qualifiedName()+"::"+aliasCd->localName();
2568 }
2569 AUTO_TRACE_ADD("found class '{}' for name '{}' aliasFullName='{}'",cd->qualifiedName(),root->name,aliasFullName);
2570 auto acd = Doxygen::classLinkedMap->add(aliasFullName,std::move(aliasCd));
2571 if (nd && acd)
2572 {
2573 nd->addInnerCompound(acd);
2574 }
2575 if (fd && acd)
2576 {
2577 fd->insertClass(acd);
2578 }
2579#endif
2580 }
2581 else if (scope)
2582 {
2583 AUTO_TRACE_ADD("no symbol with name '{}' in scope {}",root->name,scope->name());
2584 }
2585 }
2586 }
2587 for (const auto &e : root->children()) findUsingDeclImports(e.get());
2588}
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:803
static void findUsingDeclImports(const Entry *root)
Definition doxygen.cpp:2342
static void createUsingMemberImportForClass(const Entry *root, ClassDefMutable *cd, const MemberDef *md, const DString &fileName, const DString &memName)
Definition doxygen.cpp:2293
static std::unordered_map< std::string, std::vector< ClassDefMutable * > > g_usingClassMap
Definition doxygen.cpp:2340
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 2032 of file doxygen.cpp.

2033{
2034 if (root->section.isUsingDir())
2035 {
2036 AUTO_TRACE("Found using directive {} at line {} of {}",root->name,root->startLine,root->fileName);
2037 DString name=substitute(root->name,".","::");
2038 if (name.endsWith("::"))
2039 {
2040 name=name.left(name.length()-2);
2041 }
2042 if (!name.empty())
2043 {
2044 NamespaceDef *usingNd = nullptr;
2045 NamespaceDefMutable *nd = nullptr;
2046 FileDef *fd = root->fileDef();
2047 DString nsName;
2048
2049 // see if the using statement was found inside a namespace or inside
2050 // the global file scope.
2051 if (root->parent() && root->parent()->section.isNamespace() &&
2052 (fd==nullptr || fd->getLanguage()!=SrcLangExt::Java) // not a .java file
2053 )
2054 {
2055 nsName=stripAnonymousNamespaceScope(root->parent()->name);
2056 if (!nsName.empty())
2057 {
2058 nd = getResolvedNamespaceMutable(nsName);
2059 }
2060 }
2061
2062 // find the scope in which the 'using' namespace is defined by prepending
2063 // the possible scopes in which the using statement was found, starting
2064 // with the most inner scope and going to the most outer scope (i.e.
2065 // file scope).
2066 int scopeOffset = static_cast<int>(nsName.length());
2067 do
2068 {
2069 DString scope=scopeOffset>0 ?
2070 nsName.left(scopeOffset)+"::" : DString();
2071 usingNd = getResolvedNamespace(scope+name);
2072 //printf("Trying with scope='%s' usingNd=%p\n",(scope+qPrint(name)),usingNd);
2073 if (scopeOffset==0)
2074 {
2075 scopeOffset=-1;
2076 }
2077 else
2078 {
2079 size_t o = nsName.rfind("::",scopeOffset-1);
2080 scopeOffset = o!=DString::npos ? static_cast<int>(o) : 0;
2081 }
2082 } while (scopeOffset>=0 && usingNd==nullptr);
2083
2084 if (usingNd==nullptr && nd) // not found, try used namespaces in this scope
2085 // or in one of the parent namespace scopes
2086 {
2087 const NamespaceDefMutable *pnd = nd;
2088 while (pnd && usingNd==nullptr)
2089 {
2090 // also try with one of the used namespaces found earlier
2092
2093 // goto the parent
2094 Definition *s = pnd->getOuterScope();
2096 {
2098 }
2099 else
2100 {
2101 pnd = nullptr;
2102 }
2103 }
2104 }
2105 if (usingNd==nullptr && fd) // still nothing, also try used namespace in the
2106 // global scope
2107 {
2108 usingNd = findUsedNamespace(fd->getUsedNamespaces(),name);
2109 }
2110
2111 //printf("%s -> %s\n",qPrint(name),usingNd?qPrint(usingNd->name()):"<none>");
2112
2113 // add the namespace the correct scope
2114 if (usingNd)
2115 {
2116 //printf("using fd=%p nd=%p\n",fd,nd);
2117 if (nd)
2118 {
2119 //printf("Inside namespace %s\n",qPrint(nd->name()));
2120 nd->addUsingDirective(usingNd);
2121 }
2122 else if (fd)
2123 {
2124 //printf("Inside file %s\n",qPrint(fd->name()));
2125 fd->addUsingDirective(usingNd);
2126 }
2127 }
2128 else // unknown namespace, but add it anyway.
2129 {
2130 AUTO_TRACE_ADD("new unknown namespace {} lang={} hidden={}",name,root->lang,root->hidden);
2131 // add namespace to the list
2134 createNamespaceDef(root->fileName,root->startLine,root->startColumn,name)));
2135 if (nd)
2136 {
2137 nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
2138 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2140 nd->setHidden(root->hidden);
2141 nd->setArtificial(true);
2142 nd->setLanguage(root->lang);
2143 nd->setId(root->id);
2144 nd->setMetaData(root->metaData);
2145 nd->setInline(root->spec.isInline());
2146 nd->setExported(root->exported);
2147
2148 for (const Grouping &g : root->groups)
2149 {
2150 GroupDef *gd=nullptr;
2152 gd->addNamespace(nd);
2153 }
2154
2155 // insert the namespace in the file definition
2156 if (fd)
2157 {
2158 fd->insertNamespace(nd);
2159 fd->addUsingDirective(nd);
2160 }
2161
2162 // the empty string test is needed for extract all case
2163 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2164 nd->insertUsedFile(fd);
2165 nd->setRefItems(root->sli);
2166 nd->setRequirementReferences(root->rqli);
2167 }
2168 }
2169 }
2170 }
2171 for (const auto &e : root->children()) findUsingDirectives(e.get());
2172}
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:2019
static void findUsingDirectives(const Entry *root)
Definition doxygen.cpp:2032

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(), DString::endsWith(), 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 9553 of file doxygen.cpp.

9554{
9555 // remove all references to classes from the cache
9556 // as there can be new template instances in the inheritance path
9557 // to this class. Optimization: only remove those classes that
9558 // have inheritance instances as direct or indirect sub classes.
9560
9561 // remove all cached typedef resolutions whose target is a
9562 // template class as this may now be a template instance
9563 // for each global function name
9564 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9565 {
9566 // for each function with that name
9567 for (const auto &ifmd : *fn)
9568 {
9569 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9570 if (fmd && fmd->isTypedefValCached())
9571 {
9572 const ClassDef *cd = fmd->getCachedTypedefVal();
9573 if (cd->isTemplate()) fmd->invalidateTypedefValCache();
9574 }
9575 }
9576 }
9577 // for each class method name
9578 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9579 {
9580 // for each function with that name
9581 for (const auto &imd : *nm)
9582 {
9583 MemberDefMutable *md = toMemberDefMutable(imd.get());
9584 if (md && md->isTypedefValCached())
9585 {
9586 const ClassDef *cd = md->getCachedTypedefVal();
9587 if (cd->isTemplate()) md->invalidateTypedefValCache();
9588 }
9589 }
9590 }
9591}
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 9595 of file doxygen.cpp.

9596{
9597 // Remove all unresolved references to classes from the cache.
9598 // This is needed before resolving the inheritance relations, since
9599 // it would otherwise not find the inheritance relation
9600 // for C in the example below, as B::I was already found to be unresolvable
9601 // (which is correct if you ignore the inheritance relation between A and B).
9602 //
9603 // class A { class I {} };
9604 // class B : public A {};
9605 // class C : public B::I {};
9607
9608 // for each class method name
9609 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9610 {
9611 // for each function with that name
9612 for (const auto &imd : *nm)
9613 {
9614 MemberDefMutable *md = toMemberDefMutable(imd.get());
9615 if (md)
9616 {
9618 }
9619 }
9620 }
9621
9622}
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 9311 of file doxygen.cpp.

9312{
9313 std::vector<ClassDefMutable*> classList;
9314 for (const auto &cdi : *Doxygen::classLinkedMap)
9315 {
9316 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9317 if (cd && (cd->getOuterScope()==nullptr ||
9319 {
9320 addClassAndNestedClasses(classList,cd);
9321 }
9322 }
9323 for (const auto &cdi : *Doxygen::hiddenClassLinkedMap)
9324 {
9325 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9326 if (cd && (cd->getOuterScope()==nullptr ||
9328 {
9329 addClassAndNestedClasses(classList,cd);
9330 }
9331 }
9332 generateDocsForClassList(classList);
9333}
static void generateDocsForClassList(const std::vector< ClassDefMutable * > &classList)
Definition doxygen.cpp:9213

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 9337 of file doxygen.cpp.

9338{
9339 for (const auto &cdi : *Doxygen::conceptLinkedMap)
9340 {
9342
9343 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9344 if (cd &&
9345 (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9346 cd->getOuterScope()==Doxygen::globalScope // only look at global concepts
9347 ) && !cd->isHidden() && cd->isLinkableInProject()
9348 )
9349 {
9350 msg("Generating docs for concept {}...\n",cd->displayName());
9352 }
9353 }
9354}
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 10433 of file doxygen.cpp.

10435{
10436 std::ofstream f;
10437 bool fileOpened=openOutputFile(configFile,f);
10438 bool writeToStdout=configFile=="-";
10439 if (fileOpened)
10440 {
10441 TextStream t(&f);
10442 Config::writeTemplate(t,shortList,updateOnly);
10443 if (!writeToStdout)
10444 {
10445 if (!updateOnly)
10446 {
10447 msg("\n\nConfiguration file '{}' created.\n\n",configFile);
10448 msg("Now edit the configuration file and enter\n\n");
10449 if (configFile!="Doxyfile" && configFile!="doxyfile")
10450 msg(" doxygen {}\n\n",configFile);
10451 else
10452 msg(" doxygen\n\n");
10453 msg("to generate the documentation for your project\n\n");
10454 }
10455 else
10456 {
10457 msg("\n\nConfiguration file '{}' updated.\n\n",configFile);
10458 }
10459 }
10460 }
10461 else
10462 {
10463 term("Cannot open file {} for writing\n",configFile);
10464 }
10465}
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 10687 of file doxygen.cpp.

10688{
10689 for (const auto &fn : *Doxygen::inputNameLinkedMap)
10690 {
10691 struct FileEntry
10692 {
10693 FileEntry(const DString &p,FileDef *fd) : path(p), fileDef(fd) {}
10694 DString path;
10695 FileDef *fileDef;
10696 };
10697
10698 // collect the entry for which to compute the longest common prefix (LCP) of the path
10699 std::vector<FileEntry> fileEntries;
10700 for (const auto &fd : *fn)
10701 {
10702 if (!fd->isReference()) // skip external references
10703 {
10704 fileEntries.emplace_back(fd->getPath(),fd.get());
10705 }
10706 }
10707
10708 size_t size = fileEntries.size();
10709
10710 if (size==1) // name if unique, so diskname is simply the name
10711 {
10712 FileDef *fd = fileEntries[0].fileDef;
10713 fd->setDiskName(fn->fileName());
10714 }
10715 else if (size>1) // multiple occurrences of the same file name
10716 {
10717 // sort the array
10718 std::stable_sort(fileEntries.begin(),
10719 fileEntries.end(),
10720 [](const FileEntry &fe1,const FileEntry &fe2)
10721 { return dstricmp_sort(fe1.path,fe2.path)<0; }
10722 );
10723
10724 // since the entries are sorted, the common prefix of the whole array is same
10725 // as the common prefix between the first and last entry
10726 const FileEntry &first = fileEntries[0];
10727 const FileEntry &last = fileEntries[size-1];
10728 int first_path_size = static_cast<int>(first.path.size())-1; // -1 to skip trailing slash
10729 int last_path_size = static_cast<int>(last.path.size())-1; // -1 to skip trailing slash
10730 int j=0;
10731 int i=0;
10732 for (i=0;i<first_path_size && i<last_path_size;i++)
10733 {
10734 if (first.path[i]=='/') j=i;
10735 if (first.path[i]!=last.path[i]) break;
10736 }
10737 if (i==first_path_size && i<last_path_size && last.path[i]=='/')
10738 {
10739 // case first='some/path' and last='some/path/more' => match is 'some/path'
10740 j=first_path_size;
10741 }
10742 else if (i==last_path_size && i<first_path_size && first.path[i]=='/')
10743 {
10744 // case first='some/path/more' and last='some/path' => match is 'some/path'
10745 j=last_path_size;
10746 }
10747
10748 // add non-common part of the path to the name
10749 for (auto &fileEntry : fileEntries)
10750 {
10751 DString prefix = fileEntry.path.right(fileEntry.path.length()-j-1);
10752 fileEntry.fileDef->setName(prefix+fn->fileName());
10753 //printf("!!!!!!!! non unique disk name=%s:%s\n",qPrint(prefix),fn->fileName());
10754 fileEntry.fileDef->setDiskName(prefix+fn->fileName());
10755 }
10756 }
10757 }
10758}
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 9213 of file doxygen.cpp.

9214{
9215 AUTO_TRACE();
9216 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
9217 if (numThreads>1) // multi threaded processing
9218 {
9219 struct DocContext
9220 {
9221 DocContext(ClassDefMutable *cd_,const OutputList &ol_)
9222 : cd(cd_), ol(ol_) {}
9223 ClassDefMutable *cd;
9224 OutputList ol;
9225 };
9226 ThreadPool threadPool(numThreads);
9227 std::vector< std::future< std::shared_ptr<DocContext> > > results;
9228 for (const auto &cd : classList)
9229 {
9230 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9231 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9232 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9233 )
9234 {
9235 auto ctx = std::make_shared<DocContext>(cd,*g_outputList);
9236 auto processFile = [ctx]()
9237 {
9238 msg("Generating docs for compound {}...\n",ctx->cd->displayName());
9239
9240 // skip external references, anonymous compounds and
9241 // template instances
9242 if (!ctx->cd->isHidden() && !ctx->cd->isEmbeddedInOuterScope() &&
9243 ctx->cd->isLinkableInProject() && !ctx->cd->isImplicitTemplateInstance())
9244 {
9245 ctx->cd->writeDocumentation(ctx->ol);
9246 ctx->cd->writeMemberList(ctx->ol);
9247 }
9248
9249 // even for undocumented classes, the inner classes can be documented.
9250 ctx->cd->writeDocumentationForInnerClasses(ctx->ol);
9251 return ctx;
9252 };
9253 results.emplace_back(threadPool.queue(processFile));
9254 }
9255 }
9256 for (auto &f : results)
9257 {
9258 auto ctx = f.get();
9259 }
9260 }
9261 else // single threaded processing
9262 {
9263 for (const auto &cd : classList)
9264 {
9265 //printf("cd=%s getOuterScope=%p global=%p hidden=%d embeddedInOuterScope=%d\n",
9266 // qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope,cd->isHidden(),cd->isEmbeddedInOuterScope());
9267 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9268 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9269 )
9270 {
9271 // skip external references, anonymous compounds and
9272 // template instances
9273 if ( !cd->isHidden() && !cd->isEmbeddedInOuterScope() &&
9274 cd->isLinkableInProject() && !cd->isImplicitTemplateInstance())
9275 {
9276 msg("Generating docs for compound {}...\n",cd->displayName());
9277
9278 cd->writeDocumentation(*g_outputList);
9279 cd->writeMemberList(*g_outputList);
9280 }
9281 // even for undocumented classes, the inner classes can be documented.
9282 cd->writeDocumentationForInnerClasses(*g_outputList);
9283 }
9284 }
9285 }
9286}

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

Referenced by generateClassDocs().

◆ generateExampleDocs()

void generateExampleDocs ( )
static

Definition at line 10137 of file doxygen.cpp.

10138{
10140 for (const auto &pd : *Doxygen::exampleLinkedMap)
10141 {
10142 msg("Generating docs for example {}...\n",pd->name());
10143 SrcLangExt lang = getLanguageFromFileName(pd->name(), SrcLangExt::Unknown);
10144 if (lang != SrcLangExt::Unknown)
10145 {
10146 DString ext = getFileNameExtension(pd->name());
10147 auto intf = Doxygen::parserManager->getCodeParser(ext);
10148 intf->resetCodeParserState();
10149 }
10150 DString n=pd->getOutputFileBase();
10151 startFile(*g_outputList,n,false,n,pd->name());
10153 g_outputList->docify(pd->name());
10156 DString lineNoOptStr;
10157 if (pd->showLineNo())
10158 {
10159 lineNoOptStr="{lineno}";
10160 }
10161 g_outputList->generateDoc(pd->docFile(), // file
10162 pd->docLine(), // startLine
10163 pd.get(), // context
10164 nullptr, // memberDef
10165 (pd->briefDescription().empty()?"":pd->briefDescription()+"\n\n")+
10166 pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
10167 DocOptions()
10168 .setIndexWords(true)
10169 .setExample(pd->name()));
10170 endFile(*g_outputList); // contains g_outputList->endContents()
10171 }
10173}
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:4211
SrcLangExt getLanguageFromFileName(const DString &fileName, SrcLangExt defLang)
Definition util.cpp:4169

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 8876 of file doxygen.cpp.

8877{
8878 if (Index::instance().numDocumentedFiles()==0) return;
8879
8880 if (!Doxygen::inputNameLinkedMap->empty())
8881 {
8882 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8883 if (numThreads>1) // multi threaded processing
8884 {
8885 struct DocContext
8886 {
8887 DocContext(FileDef *fd_,const OutputList &ol_)
8888 : fd(fd_), ol(ol_) {}
8889 FileDef *fd;
8890 OutputList ol;
8891 };
8892 ThreadPool threadPool(numThreads);
8893 std::vector< std::future< std::shared_ptr<DocContext> > > results;
8894 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8895 {
8896 for (const auto &fd : *fn)
8897 {
8898 bool doc = fd->isLinkableInProject();
8899 if (doc)
8900 {
8901 auto ctx = std::make_shared<DocContext>(fd.get(),*g_outputList);
8902 auto processFile = [ctx]() {
8903 msg("Generating docs for file {}...\n",ctx->fd->docName());
8904 ctx->fd->writeDocumentation(ctx->ol);
8905 return ctx;
8906 };
8907 results.emplace_back(threadPool.queue(processFile));
8908 }
8909 }
8910 }
8911 for (auto &f : results)
8912 {
8913 auto ctx = f.get();
8914 }
8915 }
8916 else // single threaded processing
8917 {
8918 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8919 {
8920 for (const auto &fd : *fn)
8921 {
8922 bool doc = fd->isLinkableInProject();
8923 if (doc)
8924 {
8925 msg("Generating docs for file {}...\n",fd->docName());
8926 fd->writeDocumentation(*g_outputList);
8927 }
8928 }
8929 }
8930 }
8931 }
8932}

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

Referenced by generateOutput().

◆ generateFileSources()

void generateFileSources ( )
static

Definition at line 8710 of file doxygen.cpp.

8711{
8712 auto processSourceFile = [](FileDef *fd,OutputList &ol,ClangTUParser *parser)
8713 {
8714 bool showSources = fd->generateSourceFile() && !Htags::useHtags; // sources need to be shown in the output
8715 bool parseSources = !fd->isReference() && Doxygen::parseSourcesNeeded; // we needed to parse the sources even if we do not show them
8716 if (showSources)
8717 {
8718 msg("Generating code for file {}...\n",fd->docName());
8719 fd->writeSourceHeader(ol);
8720 fd->writeSourceBody(ol,parser);
8721 fd->writeSourceFooter(ol);
8722 }
8723 else if (parseSources)
8724 {
8725 msg("Parsing code for file {}...\n",fd->docName());
8726 fd->parseSource(parser);
8727 }
8728 };
8729 if (!Doxygen::inputNameLinkedMap->empty())
8730 {
8731#if USE_LIBCLANG
8733 {
8734 StringUnorderedSet processedFiles;
8735
8736 // create a dictionary with files to process
8737 StringUnorderedSet filesToProcess;
8738
8739 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8740 {
8741 for (const auto &fd : *fn)
8742 {
8743 filesToProcess.insert(fd->absFilePath().str());
8744 }
8745 }
8746 // process source files (and their include dependencies)
8747 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8748 {
8749 for (const auto &fd : *fn)
8750 {
8751 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp &&
8752 (fd->generateSourceFile() ||
8754 )
8755 )
8756 {
8757 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8758 clangParser->parse();
8759 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8760
8761 for (auto incFile : clangParser->filesInSameTU())
8762 {
8763 if (filesToProcess.find(incFile)!=filesToProcess.end() && // part of input
8764 fd->absFilePath()!=incFile && // not same file
8765 processedFiles.find(incFile)==processedFiles.end()) // not yet marked as processed
8766 {
8767 StringVector moreFiles;
8768 bool ambig = false;
8769 FileDef *ifd=Doxygen::inputNameLinkedMap->findFileDef(incFile,ambig);
8770 if (ifd && !ifd->isReference())
8771 {
8772 processSourceFile(ifd,*g_outputList,clangParser.get());
8773 processedFiles.insert(incFile);
8774 }
8775 }
8776 }
8777 processedFiles.insert(fd->absFilePath().str());
8778 }
8779 }
8780 }
8781 // process remaining files
8782 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8783 {
8784 for (const auto &fd : *fn)
8785 {
8786 if (processedFiles.find(fd->absFilePath().str())==processedFiles.end()) // not yet processed
8787 {
8788 if (fd->getLanguage()==SrcLangExt::Cpp) // C/C++ file, use clang parser
8789 {
8790 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8791 clangParser->parse();
8792 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8793 }
8794 else // non C/C++ file, use built-in parser
8795 {
8796 processSourceFile(fd.get(),*g_outputList,nullptr);
8797 }
8798 }
8799 }
8800 }
8801 }
8802 else
8803#endif
8804 {
8805 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8806 if (numThreads>1)
8807 {
8808 msg("Generating code files using {} threads.\n",numThreads);
8809 struct SourceContext
8810 {
8811 SourceContext(FileDef *fd_,bool gen_,const OutputList &ol_)
8812 : fd(fd_), generateSourceFile(gen_), ol(ol_) {}
8813 FileDef *fd;
8814 bool generateSourceFile;
8815 OutputList ol;
8816 };
8817 ThreadPool threadPool(numThreads);
8818 std::vector< std::future< std::shared_ptr<SourceContext> > > results;
8819 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8820 {
8821 for (const auto &fd : *fn)
8822 {
8823 bool generateSourceFile = fd->generateSourceFile() && !Htags::useHtags;
8824 auto ctx = std::make_shared<SourceContext>(fd.get(),generateSourceFile,*g_outputList);
8825 auto processFile = [ctx]()
8826 {
8827 if (ctx->generateSourceFile)
8828 {
8829 msg("Generating code for file {}...\n",ctx->fd->docName());
8830 }
8831 else
8832 {
8833 msg("Parsing code for file {}...\n",ctx->fd->docName());
8834 }
8835 StringVector filesInSameTu;
8836 ctx->fd->getAllIncludeFilesRecursively(filesInSameTu);
8837 if (ctx->generateSourceFile) // sources need to be shown in the output
8838 {
8839 ctx->fd->writeSourceHeader(ctx->ol);
8840 ctx->fd->writeSourceBody(ctx->ol,nullptr);
8841 ctx->fd->writeSourceFooter(ctx->ol);
8842 }
8843 else if (!ctx->fd->isReference() && Doxygen::parseSourcesNeeded)
8844 // we needed to parse the sources even if we do not show them
8845 {
8846 ctx->fd->parseSource(nullptr);
8847 }
8848 return ctx;
8849 };
8850 results.emplace_back(threadPool.queue(processFile));
8851 }
8852 }
8853 for (auto &f : results)
8854 {
8855 auto ctx = f.get();
8856 }
8857 }
8858 else // single threaded version
8859 {
8860 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8861 {
8862 for (const auto &fd : *fn)
8863 {
8864 StringVector filesInSameTu;
8865 fd->getAllIncludeFilesRecursively(filesInSameTu);
8866 processSourceFile(fd.get(),*g_outputList,nullptr);
8867 }
8868 }
8869 }
8870 }
8871 }
8872}
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 10178 of file doxygen.cpp.

10179{
10180 for (const auto &gd : *Doxygen::groupLinkedMap)
10181 {
10182 if (!gd->isReference())
10183 {
10184 gd->writeDocumentation(*g_outputList);
10185 }
10186 }
10187}

References g_outputList, and Doxygen::groupLinkedMap.

Referenced by generateOutput().

◆ generateNamespaceClassDocs()

void generateNamespaceClassDocs ( const ClassLinkedRefMap & classList)
static

Definition at line 10192 of file doxygen.cpp.

10193{
10194 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10195 if (numThreads>1) // multi threaded processing
10196 {
10197 struct DocContext
10198 {
10199 DocContext(ClassDefMutable *cdm_,const OutputList &ol_)
10200 : cdm(cdm_), ol(ol_) {}
10201 ClassDefMutable *cdm;
10202 OutputList ol;
10203 };
10204 ThreadPool threadPool(numThreads);
10205 std::vector< std::future< std::shared_ptr<DocContext> > > results;
10206 // for each class in the namespace...
10207 for (const auto &cd : classList)
10208 {
10210 if (cdm)
10211 {
10212 auto ctx = std::make_shared<DocContext>(cdm,*g_outputList);
10213 auto processFile = [ctx]()
10214 {
10215 if ( ( ctx->cdm->isLinkableInProject() &&
10216 !ctx->cdm->isImplicitTemplateInstance()
10217 ) // skip external references, anonymous compounds and
10218 // template instances and nested classes
10219 && !ctx->cdm->isHidden() && !ctx->cdm->isEmbeddedInOuterScope()
10220 )
10221 {
10222 msg("Generating docs for compound {}...\n",ctx->cdm->displayName());
10223 ctx->cdm->writeDocumentation(ctx->ol);
10224 ctx->cdm->writeMemberList(ctx->ol);
10225 }
10226 ctx->cdm->writeDocumentationForInnerClasses(ctx->ol);
10227 return ctx;
10228 };
10229 results.emplace_back(threadPool.queue(processFile));
10230 }
10231 }
10232 // wait for the results
10233 for (auto &f : results)
10234 {
10235 auto ctx = f.get();
10236 }
10237 }
10238 else // single threaded processing
10239 {
10240 // for each class in the namespace...
10241 for (const auto &cd : classList)
10242 {
10244 if (cdm)
10245 {
10246 if ( ( cd->isLinkableInProject() &&
10247 !cd->isImplicitTemplateInstance()
10248 ) // skip external references, anonymous compounds and
10249 // template instances and nested classes
10250 && !cd->isHidden() && !cd->isEmbeddedInOuterScope()
10251 )
10252 {
10253 msg("Generating docs for compound {}...\n",cd->displayName());
10254
10257 }
10259 }
10260 }
10261 }
10262}
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 10264 of file doxygen.cpp.

10265{
10266 // for each concept in the namespace...
10267 for (const auto &cd : conceptList)
10268 {
10270 if ( cdm && cd->isLinkableInProject() && !cd->isHidden())
10271 {
10272 msg("Generating docs for concept {}...\n",cd->name());
10274 }
10275 }
10276}

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

Referenced by generateNamespaceDocs().

◆ generateNamespaceDocs()

void generateNamespaceDocs ( )
static

Definition at line 10278 of file doxygen.cpp.

10279{
10280 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
10281
10282 //writeNamespaceIndex(*g_outputList);
10283
10284 // for each namespace...
10285 for (const auto &nd : *Doxygen::namespaceLinkedMap)
10286 {
10287 if (nd->isLinkableInProject())
10288 {
10290 if (ndm)
10291 {
10292 msg("Generating docs for namespace {}\n",nd->displayName());
10294 }
10295 }
10296
10297 generateNamespaceClassDocs(nd->getClasses());
10298 if (sliceOpt)
10299 {
10300 generateNamespaceClassDocs(nd->getInterfaces());
10301 generateNamespaceClassDocs(nd->getStructs());
10302 generateNamespaceClassDocs(nd->getExceptions());
10303 }
10304 generateNamespaceConceptDocs(nd->getConcepts());
10305 }
10306}
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 13238 of file doxygen.cpp.

13239{
13240 AUTO_TRACE();
13241 /**************************************************************************
13242 * Initialize output generators *
13243 **************************************************************************/
13244
13245 /// add extra languages for which we can only produce syntax highlighted code
13247
13248 //// dump all symbols
13249 if (g_dumpSymbolMap)
13250 {
13251 dumpSymbolMap();
13252 exit(0);
13253 }
13254
13255 bool generateHtml = Config_getBool(GENERATE_HTML);
13256 bool generateLatex = Config_getBool(GENERATE_LATEX);
13257 bool generateMan = Config_getBool(GENERATE_MAN);
13258 bool generateRtf = Config_getBool(GENERATE_RTF);
13259 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
13260
13261
13263 if (generateHtml)
13264 {
13268 }
13269 if (generateLatex)
13270 {
13273 }
13274 if (generateDocbook)
13275 {
13278 }
13279 if (generateMan)
13280 {
13283 }
13284 if (generateRtf)
13285 {
13288 }
13289 if (Config_getBool(USE_HTAGS))
13290 {
13291 Htags::useHtags = true;
13292 DString htmldir = Config_getString(HTML_OUTPUT);
13293 if (!Htags::execute(htmldir))
13294 err("USE_HTAGS is YES but htags(1) failed. \n");
13295 else if (!Htags::loadFilemap(htmldir))
13296 err("htags(1) ended normally but failed to load the filemap. \n");
13297 }
13298
13299 /**************************************************************************
13300 * Generate documentation *
13301 **************************************************************************/
13302
13303 g_s.begin("Generating style sheet...\n");
13304 //printf("writing style info\n");
13305 g_outputList->writeStyleInfo(0); // write first part
13306 g_s.end();
13307
13308 bool searchEngine = Config_getBool(SEARCHENGINE);
13309 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
13310
13311 g_s.begin("Generating search indices...\n");
13312 if (searchEngine && !serverBasedSearch && generateHtml)
13313 {
13315 }
13316
13317 // generate search indices (need to do this before writing other HTML
13318 // pages as these contain a drop down menu with options depending on
13319 // what categories we find in this function.
13320 if (generateHtml && searchEngine)
13321 {
13322 DString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
13323 Dir searchDir(searchDirName.str());
13324 if (!searchDir.exists() && !searchDir.mkdir(searchDirName.str()))
13325 {
13326 term("Could not create search results directory '{}' $PWD='{}'\n",
13327 searchDirName,Dir::currentDirPath());
13328 }
13329 HtmlGenerator::writeSearchData(searchDirName);
13330 if (!serverBasedSearch) // client side search index
13331 {
13333 }
13334 }
13335 g_s.end();
13336
13337 // copy static stuff
13338 if (generateHtml)
13339 {
13341 copyLogo(Config_getString(HTML_OUTPUT),true);
13342 copyIcon(Config_getString(HTML_OUTPUT),true);
13343 copyExtraFiles(Config_getList(HTML_EXTRA_FILES),"HTML_EXTRA_FILES",Config_getString(HTML_OUTPUT),true);
13344 }
13345 if (generateLatex)
13346 {
13348 copyLogo(Config_getString(LATEX_OUTPUT),false);
13349 copyIcon(Config_getString(LATEX_OUTPUT),false);
13350 copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT),false);
13351 }
13352 if (generateDocbook)
13353 {
13354 copyLogo(Config_getString(DOCBOOK_OUTPUT),false);
13355 copyIcon(Config_getString(DOCBOOK_OUTPUT),false);
13356 }
13357 if (generateRtf)
13358 {
13359 copyLogo(Config_getString(RTF_OUTPUT),false);
13360 copyIcon(Config_getString(RTF_OUTPUT),false);
13361 copyExtraFiles(Config_getList(RTF_EXTRA_FILES),"RTF_EXTRA_FILES",Config_getString(RTF_OUTPUT),false);
13362 }
13363
13365 if (fm.hasFormulas() && generateHtml
13366 && !Config_getBool(USE_MATHJAX))
13367 {
13368 g_s.begin("Generating images for formulas in HTML...\n");
13369 fm.generateImages(Config_getString(HTML_OUTPUT), true, Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg ?
13371 g_s.end();
13372 }
13373 if (fm.hasFormulas() && generateRtf)
13374 {
13375 g_s.begin("Generating images for formulas in RTF...\n");
13377 g_s.end();
13378 }
13379
13380 if (fm.hasFormulas() && generateDocbook)
13381 {
13382 g_s.begin("Generating images for formulas in Docbook...\n");
13384 g_s.end();
13385 }
13386
13387 g_s.begin("Generating example documentation...\n");
13389 g_s.end();
13390
13391 g_s.begin("Generating file sources...\n");
13393 g_s.end();
13394
13395 g_s.begin("Counting members...\n");
13396 // needs to be done after generating the sources
13397 // but before generating the compound documentation, see bug #12233
13398 countMembers();
13399 g_s.end();
13400
13401 g_s.begin("Generating file documentation...\n");
13403 g_s.end();
13404
13405 g_s.begin("Generating page documentation...\n");
13407 g_s.end();
13408
13409 g_s.begin("Generating group documentation...\n");
13411 g_s.end();
13412
13413 g_s.begin("Generating class documentation...\n");
13415 g_s.end();
13416
13417 g_s.begin("Generating concept documentation...\n");
13419 g_s.end();
13420
13421 g_s.begin("Generating module documentation...\n");
13423 g_s.end();
13424
13425 g_s.begin("Generating namespace documentation...\n");
13427 g_s.end();
13428
13429 if (Config_getBool(GENERATE_LEGEND))
13430 {
13431 g_s.begin("Generating graph info page...\n");
13433 g_s.end();
13434 }
13435
13436 g_s.begin("Generating directory documentation...\n");
13438 g_s.end();
13439
13440 if (g_outputList->size()>0)
13441 {
13443 }
13444
13445 g_s.begin("finalizing index lists...\n");
13447 g_s.end();
13448
13449 g_s.begin("writing tag file...\n");
13450 writeTagFile();
13451 g_s.end();
13452
13453 if (Config_getBool(GENERATE_XML))
13454 {
13455 g_s.begin("Generating XML output...\n");
13457 generateXML();
13459 g_s.end();
13460 }
13461 if (Config_getBool(GENERATE_SQLITE3))
13462 {
13463 g_s.begin("Generating SQLITE3 output...\n");
13465 g_s.end();
13466 }
13467
13468 if (Config_getBool(GENERATE_AUTOGEN_DEF))
13469 {
13470 g_s.begin("Generating AutoGen DEF output...\n");
13471 generateDEF();
13472 g_s.end();
13473 }
13474 if (Config_getBool(GENERATE_PERLMOD))
13475 {
13476 g_s.begin("Generating Perl module output...\n");
13478 g_s.end();
13479 }
13480 if (generateHtml && searchEngine && serverBasedSearch)
13481 {
13482 g_s.begin("Generating search index\n");
13483 if (Doxygen::searchIndex.kind()==SearchIndexIntf::Internal) // write own search index
13484 {
13486 Doxygen::searchIndex.write(Config_getString(HTML_OUTPUT)+"/search/search.idx");
13487 }
13488 else // write data for external search index
13489 {
13491 DString searchDataFile = Config_getString(SEARCHDATA_FILE);
13492 if (searchDataFile.empty())
13493 {
13494 searchDataFile="searchdata.xml";
13495 }
13496 if (!Portable::isAbsolutePath(searchDataFile.data()))
13497 {
13498 searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/");
13499 }
13500 Doxygen::searchIndex.write(searchDataFile);
13501 }
13502 g_s.end();
13503 }
13504
13505 if (generateRtf)
13506 {
13507 g_s.begin("Combining RTF output...\n");
13508 if (!RTFGenerator::preProcessFileInplace(Config_getString(RTF_OUTPUT),"refman.rtf"))
13509 {
13510 err("An error occurred during post-processing the RTF files!\n");
13511 }
13512 g_s.end();
13513 }
13514
13515 if (PlantumlManager::instance().needToRun())
13516 {
13517 g_s.begin("Running plantuml with JAVA...\n");
13519 g_s.end();
13520 }
13521
13522 if (MermaidManager::instance().needToRun())
13523 {
13524 g_s.begin("Running mermaid (mmdc)...\n");
13526 g_s.end();
13527 }
13528
13529 if (Config_getBool(HAVE_DOT) && DotManager::instance()->needToRun())
13530 {
13531 g_s.begin("Running dot...\n");
13533 g_s.end();
13534 }
13535
13536 if (generateHtml &&
13537 Config_getBool(GENERATE_HTMLHELP) &&
13538 !Config_getString(HHC_LOCATION).empty())
13539 {
13540 g_s.begin("Running html help compiler...\n");
13542 g_s.end();
13543 }
13544
13545 if ( generateHtml &&
13546 Config_getBool(GENERATE_QHP) &&
13547 !Config_getString(QHG_LOCATION).empty())
13548 {
13549 g_s.begin("Running qhelpgenerator...\n");
13551 g_s.end();
13552 }
13553
13556
13558
13560 {
13561
13562 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
13563 if (numThreads<1) numThreads=1;
13564 msg("Total elapsed time: {:.6f} seconds\n(of which an average of {:.6f} seconds per thread waiting for external tools to finish)\n",
13565 (static_cast<double>(Debug::elapsedTime())),
13566 Portable::getSysElapsedTime()/static_cast<double>(numThreads)
13567 );
13568 g_s.print();
13569
13571 msg("finished...\n");
13573 }
13574 else
13575 {
13576 msg("finished...\n");
13577 }
13578
13579
13580 /**************************************************************************
13581 * Start cleaning up *
13582 **************************************************************************/
13583
13585
13587 Dir thisDir;
13588 thisDir.remove(Doxygen::filterDBFileName.str());
13590 exitTracing();
13592 delete Doxygen::clangUsrMap;
13593 g_successfulRun=true;
13594
13595 //dumpDocNodeSizes();
13596}
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:1455
static void init()
Definition htmlgen.cpp:1275
static void writeSearchPage()
Definition htmlgen.cpp:3272
static void writeTabData()
Additional initialization after indices have been created.
Definition htmlgen.cpp:1439
static void writeExternalSearchPage()
Definition htmlgen.cpp:3371
void finalize()
Definition indexlist.h:104
Generator for LaTeX output.
Definition latexgen.h:93
static void init()
Definition latexgen.cpp:634
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:8876
static void generatePageDocs()
static void copyIcon(const DString &outputOption, bool toIndex)
static void generateFileSources()
Definition doxygen.cpp:8710
static void copyExtraFiles(StringVector files, const DString &filesOption, const DString &outputOption, bool toIndex)
static void generateClassDocs()
Definition doxygen.cpp:9311
static void countMembers()
Definition doxygen.cpp:9172
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:9337
void writeGraphInfo(OutputList &ol)
Definition index.cpp:4097
void writeIndexHierarchy(OutputList &ol)
Definition index.cpp:5811
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:4163
void cleanupInlineGraphs()
Definition util.cpp:5399
void generateXML()
Definition xmlgen.cpp:2316

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 10052 of file doxygen.cpp.

10053{
10054 //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageLinkedMap->count());
10055 if (Index::instance().numDocumentedPages()==0) return;
10056 for (const auto &pd : *Doxygen::pageLinkedMap)
10057 {
10058 if (!pd->getGroupDef() && !pd->isReference())
10059 {
10060 msg("Generating docs for page {}...\n",pd->name());
10061 pd->writeDocumentation(*g_outputList);
10062 }
10063 }
10064}

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

Referenced by generateOutput().

◆ generateXRefPages()

void generateXRefPages ( )
static

Definition at line 5692 of file doxygen.cpp.

5693{
5694 AUTO_TRACE();
5696 {
5697 rl->generatePage();
5698 }
5699}
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 11486 of file doxygen.cpp.

11487{
11488 char *s=nullptr;
11489 if (dstrlen(&argv[optInd][2])>0)
11490 s=&argv[optInd][2];
11491 else if (optInd+1<argc && argv[optInd+1][0]!='-')
11492 s=argv[++optInd];
11493 return s;
11494}
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 10764 of file doxygen.cpp.

10765{
10766 DString fileName=fn;
10767 DString extension;
10768 size_t sep = fileName.rfind('/');
10769 size_t ei = fileName.rfind('.');
10770 if (ei!=DString::npos && (sep==DString::npos || ei>sep)) // matches dir/file.ext but not dir.1/file
10771 {
10772 extension=fileName.mid(ei);
10773 }
10774 else
10775 {
10776 extension = ".no_extension";
10777 }
10778
10779 return Doxygen::parserManager->getOutlineParser(extension);
10780}
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(), DString::find(), LinkedMap< T, Hash, KeyEqual, Map >::find(), getClass(), DString::left(), 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 4629 of file doxygen.cpp.

4630{
4631 std::map<std::string,int> templateNames;
4632 int count=0;
4633 for (const Argument &arg : templateArguments)
4634 {
4635 static const reg::Ex re(R"(\a[\w:]*)");
4636 reg::Iterator it(name,re);
4638 for (; it!=end ; ++it)
4639 {
4640 const auto &match = *it;
4641 std::string n = match.str();
4642 if (n==arg.name.str())
4643 {
4644 if (templateNames.find(n)==templateNames.end())
4645 {
4646 templateNames.emplace(n,count);
4647 }
4648 }
4649 }
4650 }
4651 return templateNames;
4652}

References end().

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

◆ haveEqualFileNames()

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

Definition at line 9628 of file doxygen.cpp.

9629{
9630 if (const FileDef *fd = md->getFileDef())
9631 {
9632 return fd->absFilePath() == root->fileName;
9633 }
9634 return false;
9635}

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

Referenced by findDefineDocumentation().

◆ inheritDocumentation()

void inheritDocumentation ( )
static

Definition at line 9358 of file doxygen.cpp.

9359{
9360 for (const auto &mn : *Doxygen::memberNameLinkedMap)
9361 {
9362 for (const auto &imd : *mn)
9363 {
9364 MemberDefMutable *md = toMemberDefMutable(imd.get());
9365 //static int count=0;
9366 //printf("%04d Member '%s'\n",count++,qPrint(md->qualifiedName()));
9367 if (md && md->documentation().empty() && md->briefDescription().empty())
9368 { // no documentation yet
9369 const MemberDef *bmd = md->reimplements();
9370 while (bmd && bmd->documentation().empty() &&
9371 bmd->briefDescription().empty()
9372 )
9373 { // search up the inheritance tree for a documentation member
9374 //printf("bmd=%s class=%s\n",qPrint(bmd->name()),qPrint(bmd->getClassDef()->name()));
9375 bmd = bmd->reimplements();
9376 }
9377 if (bmd) // copy the documentation from the reimplemented member
9378 {
9379 md->setInheritsDocsFrom(bmd);
9380 md->setDocumentation(bmd->documentation(),bmd->docFile(),bmd->docLine());
9382 md->setBriefDescription(bmd->briefDescription(),bmd->briefFile(),bmd->briefLine());
9383 md->copyArgumentNames(bmd);
9385 }
9386 }
9387 }
9388 }
9389}
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 11513 of file doxygen.cpp.

11514{
11515 initResources();
11516 DString lang = Portable::getenv("LC_ALL");
11517 if (!lang.empty()) Portable::setenv("LANG",lang);
11518 std::setlocale(LC_ALL,"");
11519 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
11520 std::setlocale(LC_NUMERIC,"C");
11521
11523
11547
11548 // register any additional parsers here...
11549
11551
11552#if USE_LIBCLANG
11554#endif
11563 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
11564 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
11565 //Doxygen::tagDestinationDict.setAutoDelete(true);
11567
11568 // initialization of these globals depends on
11569 // configuration switches so we need to postpone these
11570 Doxygen::globalScope = nullptr;
11580
11581}
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:4096

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 6807 of file doxygen.cpp.

6808{
6809 if (outerScope && outerScope!=Doxygen::globalScope)
6810 {
6811 auto aliasMd = createMemberDefAlias(outerScope,md);
6812 if (outerScope->definitionType()==Definition::TypeClass)
6813 {
6814 ClassDefMutable *cdm = toClassDefMutable(outerScope);
6815 if (cdm)
6816 {
6817 cdm->insertMember(aliasMd.get());
6818 }
6819 }
6820 else if (outerScope->definitionType()==Definition::TypeNamespace)
6821 {
6822 NamespaceDefMutable *ndm = toNamespaceDefMutable(outerScope);
6823 if (ndm)
6824 {
6825 ndm->insertMember(aliasMd.get());
6826 }
6827 }
6828 else if (outerScope->definitionType()==Definition::TypeFile)
6829 {
6830 toFileDef(outerScope)->insertMember(aliasMd.get());
6831 }
6832 if (aliasMd)
6833 {
6834 Doxygen::functionNameLinkedMap->add(md->name())->push_back(std::move(aliasMd));
6835 }
6836 }
6837}

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 5362 of file doxygen.cpp.

5363{
5364 if ( !root->name.empty() )
5365 {
5366 if (root->section.isCompound())
5367 // is it a compound (class, struct, union, interface ...)
5368 {
5369 return true;
5370 }
5371 else if (root->section.isCompoundDoc())
5372 // is it a documentation block with inheritance info.
5373 {
5374 bool hasExtends = !root->extends.empty();
5375 if (hasExtends) return true;
5376 }
5377 }
5378 return false;
5379}

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 5873 of file doxygen.cpp.

5874{
5875 const GroupDef *gd = md->getGroupDef();
5876 if (!gd)
5877 {
5878 return allowNoGroup;
5879 }
5880
5881 for (const auto &g : root->groups)
5882 {
5883 if (g.groupname == gd->name())
5884 {
5885 return true; // matching group
5886 }
5887 }
5888
5889 return false;
5890}

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 4979 of file doxygen.cpp.

4980{
4981 DString n=name;
4982 if (size_t index=n.find('<'); index!=DString::npos)
4983 {
4984 n=n.left(index);
4985 }
4986 bool result = rightScopeMatch(scope,n);
4987 return result;
4988}

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 6105 of file doxygen.cpp.

6109{
6110 auto srcIt = srcTempArgLists.begin();
6111 auto dstIt = dstTempArgLists.begin();
6112 while (srcIt!=srcTempArgLists.end() && dstIt!=dstTempArgLists.end())
6113 {
6114 if ((*srcIt).size()!=(*dstIt).size()) return true;
6115 ++srcIt;
6116 ++dstIt;
6117 }
6118 return false;
6119}

Referenced by addMemberFunction().

◆ isSymbolHidden()

bool isSymbolHidden ( const Definition * d)
static

Definition at line 9105 of file doxygen.cpp.

9106{
9107 bool hidden = d->isHidden();
9108 const Definition *parent = d->getOuterScope();
9109 return parent ? hidden || isSymbolHidden(parent) : hidden;
9110}
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 3093 of file doxygen.cpp.

3094{
3095 bool result = false;
3096 bool typeIsClass = false;
3097 bool typePtrType = false;
3098 DString type;
3099 Definition *ctx = nullptr;
3100 FileDef *fd = root->fileDef();
3101 SymbolResolver resolver(fd);
3102
3103 AUTO_TRACE("isVarWithConstructor({})",root->name);
3104 if (root->parent()->section.isCompound())
3105 { // inside a class
3106 result=false;
3107 AUTO_TRACE_EXIT("inside class: result={}",result);
3108 return result;
3109 }
3110 else if ((fd != nullptr) && (fd->name().endsWith(".c") || fd->name().endsWith(".h")))
3111 { // inside a .c file
3112 result=false;
3113 AUTO_TRACE_EXIT("inside C file: result={}",result);
3114 return result;
3115 }
3116 if (root->type.empty())
3117 {
3118 result=false;
3119 AUTO_TRACE_EXIT("no type: result={}",result);
3120 return result;
3121 }
3122 if (!root->parent()->name.empty())
3123 {
3125 }
3126 type = root->type;
3127 // remove qualifiers
3128 type.findAndRemoveWord("const");
3129 type.findAndRemoveWord("static");
3130 type.findAndRemoveWord("volatile");
3131 typePtrType = type.find('*')!=DString::npos || type.find('&')!=DString::npos;
3132 if (!typePtrType)
3133 {
3134 typeIsClass = resolver.resolveClass(ctx,type)!=nullptr;
3135 if (size_t ti=type.find('<'); !typeIsClass && ti!=DString::npos)
3136 {
3137 typeIsClass=resolver.resolveClass(ctx,type.left(ti))!=nullptr;
3138 }
3139 }
3140 if (typeIsClass) // now we still have to check if the arguments are
3141 // types or values. Since we do not have complete type info
3142 // we need to rely on heuristics :-(
3143 {
3144 if (root->argList.empty())
3145 {
3146 result=false; // empty arg list -> function prototype.
3147 AUTO_TRACE_EXIT("empty arg list: result={}",result);
3148 return result;
3149 }
3150 for (const Argument &a : root->argList)
3151 {
3152 static const reg::Ex initChars(R"([\d"'&*!^]+)");
3154 if (!a.name.empty() || !a.defval.empty())
3155 {
3156 std::string name = a.name.str();
3157 if (reg::search(name,match,initChars) && match.position()==0)
3158 {
3159 result=true;
3160 }
3161 else
3162 {
3163 result=false; // arg has (type,name) pair -> function prototype
3164 }
3165 AUTO_TRACE_EXIT("function prototype: result={}",result);
3166 return result;
3167 }
3168 if (!a.type.empty() &&
3169 (a.type.at(a.type.length()-1)=='*' ||
3170 a.type.at(a.type.length()-1)=='&'))
3171 // type ends with * or & => pointer or reference
3172 {
3173 result=false;
3174 AUTO_TRACE_EXIT("pointer or reference: result={}",result);
3175 return result;
3176 }
3177 if (a.type.empty() || resolver.resolveClass(ctx,a.type)!=nullptr)
3178 {
3179 result=false; // arg type is a known type
3180 AUTO_TRACE_EXIT("known type: result={}",result);
3181 return result;
3182 }
3183 if (checkIfTypedef(ctx,fd,a.type))
3184 {
3185 result=false; // argument is a typedef
3186 AUTO_TRACE_EXIT("typedef: result={}",result);
3187 return result;
3188 }
3189 std::string atype = a.type.str();
3190 if (reg::search(atype,match,initChars) && match.position()==0)
3191 {
3192 result=true; // argument type starts with typical initializer char
3193 AUTO_TRACE_EXIT("argument with init char: result={}",result);
3194 return result;
3195 }
3196 std::string resType=resolveTypeDef(ctx,a.type).str();
3197 if (resType.empty()) resType=atype;
3198 static const reg::Ex idChars(R"(\a\w*)");
3199 if (reg::search(resType,match,idChars) && match.position()==0) // resType starts with identifier
3200 {
3201 resType=match.str();
3202 if (resType=="int" || resType=="long" ||
3203 resType=="float" || resType=="double" ||
3204 resType=="char" || resType=="void" ||
3205 resType=="signed" || resType=="unsigned" ||
3206 resType=="const" || resType=="volatile" )
3207 {
3208 result=false; // type keyword -> function prototype
3209 AUTO_TRACE_EXIT("type keyword: result={}",result);
3210 return result;
3211 }
3212 }
3213 }
3214 result=true;
3215 }
3216
3217 AUTO_TRACE_EXIT("end: result={}",result);
3218 return result;
3219}
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:4272

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 11508 of file doxygen.cpp.

11509{
11510 return []() { return std::make_unique<T>(); };
11511}

Referenced by initDoxygen().

◆ makeTemplateInstanceRelation()

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

Definition at line 5434 of file doxygen.cpp.

5435{
5436 AUTO_TRACE("root->name={} cd={}",root->name,cd->name());
5437 size_t i = root->name.find('<');
5438 size_t j = root->name.rfind('>');
5439 size_t k = j!=DString::npos ? root->name.find("::",j+1) : DString::npos; // A<T::B> => ok, A<T>::B => nok
5440 if (i!=DString::npos && j!=DString::npos && k==DString::npos && root->lang!=SrcLangExt::CSharp && root->lang!=SrcLangExt::Java)
5441 {
5442 ClassDefMutable *master = getClassMutable(root->name.left(i));
5443 if (master && master!=cd && !cd->templateMaster())
5444 {
5445 AUTO_TRACE_ADD("class={} master={}",cd->name(),cd->templateMaster()?cd->templateMaster()->name():"<none>",master->name());
5446 cd->setTemplateMaster(master);
5447 master->insertExplicitTemplateInstance(cd,root->name.mid(i));
5448 }
5449 }
5450}
virtual const ClassDef * templateMaster() const =0
Returns the template master of which this class is an instance.
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 8659 of file doxygen.cpp.

8660{
8661 AUTO_TRACE();
8662 // merge members of categories into the class they extend
8663 for (const auto &cd : *Doxygen::classLinkedMap)
8664 {
8665 if (size_t i=cd->name().find('('); i!=DString::npos) // it is an Objective-C category
8666 {
8667 DString baseName=cd->name().left(i);
8668 ClassDefMutable *baseClass=toClassDefMutable(Doxygen::classLinkedMap->find(baseName));
8669 if (baseClass)
8670 {
8671 AUTO_TRACE_ADD("merging members of category {} into {}",cd->name(),baseClass->name());
8672 baseClass->mergeCategory(cd.get());
8673 }
8674 }
8675 }
8676}
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 10782 of file doxygen.cpp.

10785{
10786 DString fileName=fn;
10787 AUTO_TRACE("fileName={}",fileName);
10788 DString extension;
10789 if (size_t ei = fileName.rfind('.'); ei!=DString::npos)
10790 {
10791 extension=fileName.mid(ei);
10792 }
10793 else
10794 {
10795 extension = ".no_extension";
10796 }
10797
10798 FileInfo fi(fileName.str());
10799 std::string preBuf;
10800
10801 if (Config_getBool(ENABLE_PREPROCESSING) &&
10802 parser.needsPreprocessing(extension))
10803 {
10804 Preprocessor preprocessor;
10805 StringVector includePath = Config_getList(INCLUDE_PATH);
10806 for (const auto &s : includePath)
10807 {
10808 std::string absPath = FileInfo(s).absFilePath();
10809 preprocessor.addSearchDir(absPath);
10810 }
10811 std::string inBuf;
10812 msg("Preprocessing {}...\n",fn);
10813 readInputFile(fileName,inBuf);
10814 addTerminalCharIfMissing(inBuf,'\n');
10815 preprocessor.processFile(fileName,inBuf,preBuf);
10816 }
10817 else // no preprocessing
10818 {
10819 msg("Reading {}...\n",fn);
10820 readInputFile(fileName,preBuf);
10821 addTerminalCharIfMissing(preBuf,'\n');
10822 }
10823
10824 std::string convBuf;
10825 convBuf.reserve(preBuf.size()+1024);
10826
10827 // convert multi-line C++ comments to C style comments
10828 convertCppComments(preBuf,convBuf,fileName.str());
10829
10830 std::shared_ptr<Entry> fileRoot = std::make_shared<Entry>();
10831 // use language parse to parse the file
10832 if (clangParser)
10833 {
10834 if (newTU) clangParser->parse();
10835 clangParser->switchToFile(fd);
10836 }
10837 parser.parseInput(fileName,convBuf.data(),fileRoot,clangParser);
10838 fileRoot->setFileDef(fd);
10839 return fileRoot;
10840}
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:4302
void addSearchDir(const DString &dir)
Definition pre.l:4284
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, bool filter, bool isSourceCode)
read a file name fileName and optionally filter and transcode it
Definition util.cpp:4375

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 10843 of file doxygen.cpp.

10844{
10845 AUTO_TRACE();
10846#if USE_LIBCLANG
10848 {
10849 StringUnorderedSet processedFiles;
10850
10851 // create a dictionary with files to process
10852 StringUnorderedSet filesToProcess;
10853 for (const auto &s : g_inputFiles)
10854 {
10855 filesToProcess.insert(s);
10856 }
10857
10858 std::mutex processedFilesLock;
10859 // process source files (and their include dependencies)
10860 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10861 msg("Processing input using {} threads.\n",numThreads);
10862 ThreadPool threadPool(numThreads);
10863 using FutureType = std::vector< std::shared_ptr<Entry> >;
10864 std::vector< std::future< FutureType > > results;
10865 for (const auto &s : g_inputFiles)
10866 {
10867 bool ambig = false;
10868 DString qs = s;
10870 ASSERT(fd!=nullptr);
10871 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp) // this is a source file
10872 {
10873 // lambda representing the work to executed by a thread
10874 auto processFile = [qs,&filesToProcess,&processedFilesLock,&processedFiles]() {
10875 bool ambig_l = false;
10876 std::vector< std::shared_ptr<Entry> > roots;
10877 FileDef *fd_l = Doxygen::inputNameLinkedMap->findFileDef(qs,ambig_l);
10878 auto clangParser = ClangParser::instance()->createTUParser(fd_l);
10879 auto parser = getParserForFile(qs);
10880 auto fileRoot { parseFile(*parser.get(),fd_l,qs,clangParser.get(),true) };
10881 roots.push_back(fileRoot);
10882
10883 // Now process any include files in the same translation unit
10884 // first. When libclang is used this is much more efficient.
10885 for (auto incFile : clangParser->filesInSameTU())
10886 {
10887 DString qincFile = incFile;
10888 if (filesToProcess.find(incFile)!=filesToProcess.end())
10889 {
10890 bool needsToBeProcessed = false;
10891 {
10892 std::lock_guard<std::mutex> lock(processedFilesLock);
10893 needsToBeProcessed = processedFiles.find(incFile)==processedFiles.end();
10894 if (needsToBeProcessed) processedFiles.insert(incFile);
10895 }
10896 if (qincFile!=qs && needsToBeProcessed)
10897 {
10898 FileDef *ifd=Doxygen::inputNameLinkedMap->findFileDef(qincFile,ambig_l);
10899 if (ifd && !ifd->isReference())
10900 {
10901 //printf(" Processing %s in same translation unit as %s\n",incFile,qPrint(s));
10902 fileRoot = parseFile(*parser.get(),ifd,qincFile,clangParser.get(),false);
10903 roots.push_back(fileRoot);
10904 }
10905 }
10906 }
10907 }
10908 return roots;
10909 };
10910 // dispatch the work and collect the future results
10911 results.emplace_back(threadPool.queue(processFile));
10912 }
10913 }
10914 // synchronize with the Entry result lists produced and add them to the root
10915 for (auto &f : results)
10916 {
10917 auto l = f.get();
10918 for (auto &e : l)
10919 {
10920 root->moveToSubEntryAndKeep(e);
10921 }
10922 }
10923 // process remaining files
10924 results.clear();
10925 for (const auto &s : g_inputFiles)
10926 {
10927 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
10928 {
10929 // lambda representing the work to executed by a thread
10930 auto processFile = [s]() {
10931 bool ambig = false;
10932 DString qs = s;
10933 std::vector< std::shared_ptr<Entry> > roots;
10935 auto parser { getParserForFile(qs) };
10936 bool useClang = getLanguageFromFileName(qs)==SrcLangExt::Cpp;
10937 if (useClang)
10938 {
10939 auto clangParser = ClangParser::instance()->createTUParser(fd);
10940 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10941 roots.push_back(fileRoot);
10942 }
10943 else
10944 {
10945 auto fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10946 roots.push_back(fileRoot);
10947 }
10948 return roots;
10949 };
10950 results.emplace_back(threadPool.queue(processFile));
10951 }
10952 }
10953 // synchronize with the Entry result lists produced and add them to the root
10954 for (auto &f : results)
10955 {
10956 auto l = f.get();
10957 for (auto &e : l)
10958 {
10959 root->moveToSubEntryAndKeep(e);
10960 }
10961 }
10962 }
10963 else // normal processing
10964#endif
10965 {
10966 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10967 msg("Processing input using {} threads.\n",numThreads);
10968 ThreadPool threadPool(numThreads);
10969 using FutureType = std::shared_ptr<Entry>;
10970 std::vector< std::future< FutureType > > results;
10971 for (const auto &s : g_inputFiles)
10972 {
10973 // lambda representing the work to executed by a thread
10974 auto processFile = [s]() {
10975 bool ambig = false;
10976 DString qs = s;
10978 auto parser = getParserForFile(qs);
10979 auto fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10980 return fileRoot;
10981 };
10982 // dispatch the work and collect the future results
10983 results.emplace_back(threadPool.queue(processFile));
10984 }
10985 // synchronize with the Entry results produced and add them to the root
10986 for (auto &f : results)
10987 {
10988 root->moveToSubEntryAndKeep(f.get());
10989 }
10990 }
10991}
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 10994 of file doxygen.cpp.

10995{
10996 AUTO_TRACE();
10997#if USE_LIBCLANG
10999 {
11000 StringUnorderedSet processedFiles;
11001
11002 // create a dictionary with files to process
11003 StringUnorderedSet filesToProcess;
11004 for (const auto &s : g_inputFiles)
11005 {
11006 filesToProcess.insert(s);
11007 }
11008
11009 // process source files (and their include dependencies)
11010 for (const auto &s : g_inputFiles)
11011 {
11012 bool ambig = false;
11013 DString qs =s;
11015 ASSERT(fd!=nullptr);
11016 if (fd->isSource() && !fd->isReference() && getLanguageFromFileName(qs)==SrcLangExt::Cpp) // this is a source file
11017 {
11018 auto clangParser = ClangParser::instance()->createTUParser(fd);
11019 auto parser { getParserForFile(qs) };
11020 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
11021 root->moveToSubEntryAndKeep(fileRoot);
11022 processedFiles.insert(s);
11023
11024 // Now process any include files in the same translation unit
11025 // first. When libclang is used this is much more efficient.
11026 for (auto incFile : clangParser->filesInSameTU())
11027 {
11028 //printf(" file %s\n",qPrint(incFile));
11029 if (filesToProcess.find(incFile)!=filesToProcess.end() && // file need to be processed
11030 processedFiles.find(incFile)==processedFiles.end()) // and is not processed already
11031 {
11032 FileDef *ifd=Doxygen::inputNameLinkedMap->findFileDef(incFile,ambig);
11033 if (ifd && !ifd->isReference())
11034 {
11035 //printf(" Processing %s in same translation unit as %s\n",qPrint(incFile),qPrint(qs));
11036 fileRoot = parseFile(*parser.get(),ifd,incFile,clangParser.get(),false);
11037 root->moveToSubEntryAndKeep(fileRoot);
11038 processedFiles.insert(incFile);
11039 }
11040 }
11041 }
11042 }
11043 }
11044 // process remaining files
11045 for (const auto &s : g_inputFiles)
11046 {
11047 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
11048 {
11049 bool ambig = false;
11050 DString qs = s;
11052 if (getLanguageFromFileName(qs)==SrcLangExt::Cpp) // not yet processed
11053 {
11054 auto clangParser = ClangParser::instance()->createTUParser(fd);
11055 auto parser { getParserForFile(qs) };
11056 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
11057 root->moveToSubEntryAndKeep(fileRoot);
11058 }
11059 else
11060 {
11061 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
11062 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
11063 root->moveToSubEntryAndKeep(fileRoot);
11064 }
11065 processedFiles.insert(s);
11066 }
11067 }
11068 }
11069 else // normal processing
11070#endif
11071 {
11072 for (const auto &s : g_inputFiles)
11073 {
11074 bool ambig = false;
11075 DString qs = s;
11077 ASSERT(fd!=nullptr);
11078 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
11079 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
11080 root->moveToSubEntryAndKeep(std::move(fileRoot));
11081 }
11082 }
11083}

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 12569 of file doxygen.cpp.

12570{
12571 AUTO_TRACE();
12572 std::atexit(exitDoxygen);
12573
12574 Portable::correctPath(Config_getList(EXTERNAL_TOOL_PATH));
12575
12576#if USE_LIBCLANG
12577 Doxygen::clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
12578#endif
12579
12580 // we would like to show the versionString earlier, but we first have to handle the configuration file
12581 // to know the value of the QUIET setting.
12582 DString versionString = getFullVersion();
12583 msg("Doxygen version used: {}\n",versionString);
12584
12586
12587 /**************************************************************************
12588 * Make sure the output directory exists
12589 **************************************************************************/
12590 DString outputDirectory = Config_getString(OUTPUT_DIRECTORY);
12591 if (!g_singleComment)
12592 {
12593 if (outputDirectory.empty())
12594 {
12595 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,Dir::currentDirPath());
12596 }
12597 else
12598 {
12599 Dir dir(outputDirectory.str());
12600 if (!dir.exists())
12601 {
12602 dir.setPath(Dir::currentDirPath());
12603 if (!dir.mkdir(outputDirectory.str()))
12604 {
12605 term("tag OUTPUT_DIRECTORY: Output directory '{}' does not "
12606 "exist and cannot be created\n",outputDirectory);
12607 }
12608 else
12609 {
12610 msg("Notice: Output directory '{}' does not exist. "
12611 "I have created it for you.\n", outputDirectory);
12612 }
12613 dir.setPath(outputDirectory.str());
12614 }
12615 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,dir.absPath());
12616 }
12617 }
12618 AUTO_TRACE_ADD("outputDirectory={}",outputDirectory);
12619
12620 /**************************************************************************
12621 * Initialize global lists and dictionaries
12622 **************************************************************************/
12623
12624#ifdef HAS_SIGNALS
12625 signal(SIGINT, stopDoxygen);
12626#endif
12627
12628 uint32_t pid = Portable::pid();
12629 Doxygen::filterDBFileName.sprintf("doxygen_filterdb_%d.tmp",pid);
12630 Doxygen::filterDBFileName.prepend(outputDirectory+"/");
12631
12632 /**************************************************************************
12633 * Check/create output directories *
12634 **************************************************************************/
12635
12636 bool generateHtml = Config_getBool(GENERATE_HTML);
12637 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
12638 bool generateXml = Config_getBool(GENERATE_XML);
12639 bool generateLatex = Config_getBool(GENERATE_LATEX);
12640 bool generateRtf = Config_getBool(GENERATE_RTF);
12641 bool generateMan = Config_getBool(GENERATE_MAN);
12642 bool generateSql = Config_getBool(GENERATE_SQLITE3);
12643 DString htmlOutput;
12644 DString docbookOutput;
12645 DString xmlOutput;
12646 DString latexOutput;
12647 DString rtfOutput;
12648 DString manOutput;
12649 DString sqlOutput;
12650
12651 if (!g_singleComment)
12652 {
12653 if (generateHtml)
12654 {
12655 htmlOutput = createOutputDirectory(outputDirectory,Config_getString(HTML_OUTPUT),"/html");
12656 Config_updateString(HTML_OUTPUT,htmlOutput);
12657
12658 DString sitemapUrl = Config_getString(SITEMAP_URL);
12659 bool generateSitemap = !sitemapUrl.empty();
12660 if (generateSitemap && !sitemapUrl.endsWith("/"))
12661 {
12662 Config_updateString(SITEMAP_URL,sitemapUrl+"/");
12663 }
12664
12665 // add HTML indexers that are enabled
12666 bool generateHtmlHelp = Config_getBool(GENERATE_HTMLHELP);
12667 bool generateEclipseHelp = Config_getBool(GENERATE_ECLIPSEHELP);
12668 bool generateQhp = Config_getBool(GENERATE_QHP);
12669 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
12670 bool generateDocSet = Config_getBool(GENERATE_DOCSET);
12671 if (generateEclipseHelp) Doxygen::indexList->addIndex<EclipseHelp>();
12672 if (generateHtmlHelp) Doxygen::indexList->addIndex<HtmlHelp>();
12673 if (generateQhp) Doxygen::indexList->addIndex<Qhp>();
12674 if (generateSitemap) Doxygen::indexList->addIndex<Sitemap>();
12675 if (generateTreeView) Doxygen::indexList->addIndex<FTVHelp>(true);
12676 if (generateDocSet) Doxygen::indexList->addIndex<DocSets>();
12679 }
12680
12681 if (generateDocbook)
12682 {
12683 docbookOutput = createOutputDirectory(outputDirectory,Config_getString(DOCBOOK_OUTPUT),"/docbook");
12684 Config_updateString(DOCBOOK_OUTPUT,docbookOutput);
12685 }
12686
12687 if (generateXml)
12688 {
12689 xmlOutput = createOutputDirectory(outputDirectory,Config_getString(XML_OUTPUT),"/xml");
12690 Config_updateString(XML_OUTPUT,xmlOutput);
12691 }
12692
12693 if (generateLatex)
12694 {
12695 latexOutput = createOutputDirectory(outputDirectory,Config_getString(LATEX_OUTPUT), "/latex");
12696 Config_updateString(LATEX_OUTPUT,latexOutput);
12697 }
12698
12699 if (generateRtf)
12700 {
12701 rtfOutput = createOutputDirectory(outputDirectory,Config_getString(RTF_OUTPUT),"/rtf");
12702 Config_updateString(RTF_OUTPUT,rtfOutput);
12703 }
12704
12705 if (generateMan)
12706 {
12707 manOutput = createOutputDirectory(outputDirectory,Config_getString(MAN_OUTPUT),"/man");
12708 Config_updateString(MAN_OUTPUT,manOutput);
12709 }
12710
12711 if (generateSql)
12712 {
12713 sqlOutput = createOutputDirectory(outputDirectory,Config_getString(SQLITE3_OUTPUT),"/sqlite3");
12714 Config_updateString(SQLITE3_OUTPUT,sqlOutput);
12715 }
12716 }
12717
12718 if (Config_getBool(HAVE_DOT))
12719 {
12720 DString curFontPath = Config_getString(DOT_FONTPATH);
12721 if (curFontPath.empty())
12722 {
12723 Portable::getenv("DOTFONTPATH");
12724 DString newFontPath = ".";
12725 if (!curFontPath.empty())
12726 {
12727 newFontPath+=Portable::pathListSeparator();
12728 newFontPath+=curFontPath;
12729 }
12730 Portable::setenv("DOTFONTPATH",qPrint(newFontPath));
12731 }
12732 else
12733 {
12734 Portable::setenv("DOTFONTPATH",qPrint(curFontPath));
12735 }
12736 }
12737
12738 /**************************************************************************
12739 * Handle layout file *
12740 **************************************************************************/
12741
12743 DString layoutFileName = Config_getString(LAYOUT_FILE);
12744 bool defaultLayoutUsed = false;
12745 if (layoutFileName.empty())
12746 {
12747 layoutFileName = Config_updateString(LAYOUT_FILE,"DoxygenLayout.xml");
12748 defaultLayoutUsed = true;
12749 }
12750 AUTO_TRACE_ADD("defaultLayoutUsed={}, layoutFileName={}",defaultLayoutUsed,layoutFileName);
12751
12752 FileInfo fi(layoutFileName.str());
12753 if (fi.exists())
12754 {
12755 msg("Parsing layout file {}...\n",layoutFileName);
12756 LayoutDocManager::instance().parse(layoutFileName);
12757 }
12758 else if (!defaultLayoutUsed)
12759 {
12760 warn_uncond("failed to open layout file '{}' for reading! Using default settings.\n",layoutFileName);
12761 }
12762 printLayout();
12763
12764 /**************************************************************************
12765 * Read and preprocess input *
12766 **************************************************************************/
12767
12768 // prevent search in the output directories
12769 StringVector exclPatterns = Config_getList(EXCLUDE_PATTERNS);
12770 if (generateHtml) exclPatterns.push_back(htmlOutput.str());
12771 if (generateDocbook) exclPatterns.push_back(docbookOutput.str());
12772 if (generateXml) exclPatterns.push_back(xmlOutput.str());
12773 if (generateLatex) exclPatterns.push_back(latexOutput.str());
12774 if (generateRtf) exclPatterns.push_back(rtfOutput.str());
12775 if (generateMan) exclPatterns.push_back(manOutput.str());
12776 Config_updateList(EXCLUDE_PATTERNS,exclPatterns);
12777
12778 if (!g_singleComment)
12779 {
12781
12783 }
12784
12785 // Notice: the order of the function calls below is very important!
12786
12787 if (generateHtml && !Config_getBool(USE_MATHJAX))
12788 {
12790 }
12791 if (generateRtf)
12792 {
12794 }
12795 if (generateDocbook)
12796 {
12798 }
12799
12801
12802 /**************************************************************************
12803 * Handle Tag Files *
12804 **************************************************************************/
12805
12806 std::shared_ptr<Entry> root = std::make_shared<Entry>();
12807
12808 if (!g_singleComment)
12809 {
12810 msg("Reading and parsing tag files\n");
12811 StringVector tagFileList = Config_getList(TAGFILES);
12812 for (const auto &s : tagFileList)
12813 {
12814 readTagFile(root,s.c_str());
12815 }
12816 }
12817
12818 /**************************************************************************
12819 * Parse source files *
12820 **************************************************************************/
12821
12822 addSTLSupport(root);
12823
12824 g_s.begin("Parsing files\n");
12825 if (g_singleComment)
12826 {
12827 //printf("Parsing comment %s\n",qPrint(g_commentFileName));
12828 if (g_commentFileName=="-")
12829 {
12830 std::string text = fileToString(g_commentFileName).str();
12831 addTerminalCharIfMissing(text,'\n');
12832 generateHtmlForComment("stdin.md",text);
12833 }
12834 else if (FileInfo(g_commentFileName.str()).isFile())
12835 {
12836 std::string text;
12838 addTerminalCharIfMissing(text,'\n');
12840 }
12841 else
12842 {
12843 }
12845 exit(0);
12846 }
12847 else
12848 {
12849 if (Config_getInt(NUM_PROC_THREADS)==1)
12850 {
12852 }
12853 else
12854 {
12856 }
12857 }
12858 g_s.end();
12859
12860 /**************************************************************************
12861 * Gather information *
12862 **************************************************************************/
12863
12864 g_s.begin("Building macro definition list...\n");
12866 g_s.end();
12867
12868 g_s.begin("Building group list...\n");
12869 buildGroupList(root.get());
12870 organizeSubGroups(root.get());
12871 g_s.end();
12872
12873 g_s.begin("Building directory list...\n");
12875 findDirDocumentation(root.get());
12876 g_s.end();
12877
12878 g_s.begin("Building namespace list...\n");
12879 buildNamespaceList(root.get());
12880 findUsingDirectives(root.get());
12881 g_s.end();
12882
12883 g_s.begin("Building file list...\n");
12884 buildFileList(root.get());
12885 g_s.end();
12886
12887 g_s.begin("Building class list...\n");
12888 buildClassList(root.get());
12889 g_s.end();
12890
12891 g_s.begin("Building concept list...\n");
12892 buildConceptList(root.get());
12893 g_s.end();
12894
12895 // build list of using declarations here (global list)
12896 buildListOfUsingDecls(root.get());
12897 g_s.end();
12898
12899 g_s.begin("Computing nesting relations for classes...\n");
12901 g_s.end();
12902 // 1.8.2-20121111: no longer add nested classes to the group as well
12903 //distributeClassGroupRelations();
12904
12905 // calling buildClassList may result in cached relations that
12906 // become invalid after resolveClassNestingRelations(), that's why
12907 // we need to clear the cache here
12909 // we don't need the list of using declaration anymore
12910 g_usingDeclarations.clear();
12911
12912 g_s.begin("Associating documentation with classes...\n");
12913 buildClassDocList(root.get());
12914 g_s.end();
12915
12916 g_s.begin("Associating documentation with concepts...\n");
12917 buildConceptDocList(root.get());
12919 g_s.end();
12920
12921 g_s.begin("Associating documentation with modules...\n");
12922 findModuleDocumentation(root.get());
12923 g_s.end();
12924
12925 g_s.begin("Building example list...\n");
12926 buildExampleList(root.get());
12927 g_s.end();
12928
12929 g_s.begin("Searching for enumerations...\n");
12930 findEnums(root.get());
12931 g_s.end();
12932
12933 // Since buildVarList calls isVarWithConstructor
12934 // and this calls getResolvedClass we need to process
12935 // typedefs first so the relations between classes via typedefs
12936 // are properly resolved. See bug 536385 for an example.
12937 g_s.begin("Searching for documented typedefs...\n");
12938 buildTypedefList(root.get());
12939 g_s.end();
12940
12941 if (Config_getBool(OPTIMIZE_OUTPUT_SLICE))
12942 {
12943 g_s.begin("Searching for documented sequences...\n");
12944 buildSequenceList(root.get());
12945 g_s.end();
12946
12947 g_s.begin("Searching for documented dictionaries...\n");
12948 buildDictionaryList(root.get());
12949 g_s.end();
12950 }
12951
12952 g_s.begin("Searching for members imported via using declarations...\n");
12953 // this should be after buildTypedefList in order to properly import
12954 // used typedefs
12955 findUsingDeclarations(root.get(),true); // do for python packages first
12956 findUsingDeclarations(root.get(),false); // then the rest
12957 g_s.end();
12958
12959 g_s.begin("Searching for included using directives...\n");
12961 g_s.end();
12962
12963 g_s.begin("Searching for documented variables...\n");
12964 buildVarList(root.get());
12965 g_s.end();
12966
12967 g_s.begin("Building interface member list...\n");
12968 buildInterfaceAndServiceList(root.get()); // UNO IDL
12969
12970 g_s.begin("Building member list...\n"); // using class info only !
12971 buildFunctionList(root.get());
12972 g_s.end();
12973
12974 g_s.begin("Searching for friends...\n");
12975 findFriends();
12976 g_s.end();
12977
12978 g_s.begin("Searching for documented defines...\n");
12979 findDefineDocumentation(root.get());
12980 g_s.end();
12981
12982 g_s.begin("Computing class inheritance relations...\n");
12983 findClassEntries(root.get());
12985 g_s.end();
12986
12987 g_s.begin("Computing class usage relations...\n");
12989 g_s.end();
12990
12991 g_s.begin("Flushing cached template relations that have become invalid...\n");
12993 g_s.end();
12994
12995 g_s.begin("Warn for undocumented namespaces...\n");
12997 g_s.end();
12998
12999 g_s.begin("Computing class relations...\n");
13002 if (Config_getBool(OPTIMIZE_OUTPUT_VHDL))
13003 {
13005 }
13007 g_classEntries.clear();
13008 g_s.end();
13009
13010 g_s.begin("Add enum values to enums...\n");
13011 addEnumValuesToEnums(root.get());
13012 findEnumDocumentation(root.get());
13013 g_s.end();
13014
13015 g_s.begin("Searching for member function documentation...\n");
13016 findObjCMethodDefinitions(root.get());
13017 findMemberDocumentation(root.get()); // may introduce new members !
13018 findUsingDeclImports(root.get()); // may introduce new members !
13019 g_usingClassMap.clear();
13023 g_s.end();
13024
13025 // moved to after finding and copying documentation,
13026 // as this introduces new members see bug 722654
13027 g_s.begin("Creating members for template instances...\n");
13029 g_s.end();
13030
13031 g_s.begin("Searching for tag less structs...\n");
13033 g_s.end();
13034
13035 g_s.begin("Building page list...\n");
13036 buildPageList(root.get());
13037 g_s.end();
13038
13039 g_s.begin("Building requirements list...\n");
13040 buildRequirementsList(root.get());
13041 g_s.end();
13042
13043 g_s.begin("Search for main page...\n");
13044 findMainPage(root.get());
13045 findMainPageTagFiles(root.get());
13046 g_s.end();
13047
13048 g_s.begin("Computing page relations...\n");
13049 computePageRelations(root.get());
13051 g_s.end();
13052
13053 g_s.begin("Determining the scope of groups...\n");
13054 findGroupScope(root.get());
13055 g_s.end();
13056
13057 g_s.begin("Computing module relations...\n");
13058 auto &mm = ModuleManager::instance();
13059 mm.resolvePartitions();
13060 mm.resolveImports();
13061 mm.collectExportedSymbols();
13062 g_s.end();
13063
13064 auto memberNameComp = [](const MemberNameLinkedMap::Ptr &n1,const MemberNameLinkedMap::Ptr &n2)
13065 {
13066 return dstricmp_sort(n1->memberName().data()+getPrefixIndex(n1->memberName()),
13067 n2->memberName().data()+getPrefixIndex(n2->memberName())
13068 )<0;
13069 };
13070
13071 auto classComp = [](const ClassLinkedMap::Ptr &c1,const ClassLinkedMap::Ptr &c2)
13072 {
13073 if (Config_getBool(SORT_BY_SCOPE_NAME))
13074 {
13075 return dstricmp_sort(c1->name(), c2->name())<0;
13076 }
13077 else
13078 {
13079 int i = dstricmp_sort(c1->className(), c2->className());
13080 return i==0 ? dstricmp_sort(c1->name(), c2->name())<0 : i<0;
13081 }
13082 };
13083
13084 auto namespaceComp = [](const NamespaceLinkedMap::Ptr &n1,const NamespaceLinkedMap::Ptr &n2)
13085 {
13086 return dstricmp_sort(n1->name(),n2->name())<0;
13087 };
13088
13089 auto conceptComp = [](const ConceptLinkedMap::Ptr &c1,const ConceptLinkedMap::Ptr &c2)
13090 {
13091 return dstricmp_sort(c1->name(),c2->name())<0;
13092 };
13093
13094 g_s.begin("Sorting lists...\n");
13095 std::stable_sort(Doxygen::memberNameLinkedMap->begin(),
13097 memberNameComp);
13098 std::stable_sort(Doxygen::functionNameLinkedMap->begin(),
13100 memberNameComp);
13101 std::stable_sort(Doxygen::hiddenClassLinkedMap->begin(),
13103 classComp);
13104 std::stable_sort(Doxygen::classLinkedMap->begin(),
13106 classComp);
13107 std::stable_sort(Doxygen::conceptLinkedMap->begin(),
13109 conceptComp);
13110 std::stable_sort(Doxygen::namespaceLinkedMap->begin(),
13112 namespaceComp);
13113 g_s.end();
13114
13115 g_s.begin("Determining which enums are documented\n");
13117 g_s.end();
13118
13119 g_s.begin("Computing member relations...\n");
13122 g_s.end();
13123
13124 g_s.begin("Building full member lists recursively...\n");
13126 g_s.end();
13127
13128 g_s.begin("Adding members to member groups.\n");
13130 g_s.end();
13131
13132 if (Config_getBool(DISTRIBUTE_GROUP_DOC))
13133 {
13134 g_s.begin("Distributing member group documentation.\n");
13136 g_s.end();
13137 }
13138
13139 g_s.begin("Computing member references...\n");
13141 g_s.end();
13142
13143 if (Config_getBool(INHERIT_DOCS))
13144 {
13145 g_s.begin("Inheriting documentation...\n");
13147 g_s.end();
13148 }
13149
13150
13151 // compute the shortest possible names of all files
13152 // without losing the uniqueness of the file names.
13153 g_s.begin("Generating disk names...\n");
13155 g_s.end();
13156
13157 g_s.begin("Adding source references...\n");
13159 g_s.end();
13160
13161 g_s.begin("Adding xrefitems...\n");
13164 g_s.end();
13165
13166 g_s.begin("Adding requirements...\n");
13169 g_s.end();
13170
13171 g_s.begin("Sorting member lists...\n");
13173 g_s.end();
13174
13175 g_s.begin("Setting anonymous enum type...\n");
13177 g_s.end();
13178
13179 g_s.begin("Computing dependencies between directories...\n");
13181 g_s.end();
13182
13183 g_s.begin("Generating citations page...\n");
13185 g_s.end();
13186
13187 g_s.begin("Counting data structures...\n");
13189 g_s.end();
13190
13191 g_s.begin("Resolving user defined references...\n");
13193 g_s.end();
13194
13195 g_s.begin("Finding anchors and sections in the documentation...\n");
13197 g_s.end();
13198
13199 g_s.begin("Transferring function references...\n");
13201 g_s.end();
13202
13203 g_s.begin("Combining using relations...\n");
13205 g_s.end();
13206
13208 g_s.begin("Adding members to index pages...\n");
13210 addToIndices();
13211 g_s.end();
13212
13213 g_s.begin("Correcting members for VHDL...\n");
13215 g_s.end();
13216
13217 g_s.begin("Computing tooltip texts...\n");
13219 g_s.end();
13220
13221 if (Config_getBool(SORT_GROUP_NAMES))
13222 {
13223 std::stable_sort(Doxygen::groupLinkedMap->begin(),
13225 [](const auto &g1,const auto &g2)
13226 { return g1->groupTitle() < g2->groupTitle(); });
13227
13228 for (const auto &gd : *Doxygen::groupLinkedMap)
13229 {
13230 gd->sortSubGroups();
13231 }
13232 }
13233
13234 printNavTree(root.get(),0);
13236}
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:1472
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition layout.cpp:1439
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:5419
void printNavTree(Entry *root, int indent)
static void buildGroupList(const Entry *root)
Definition doxygen.cpp:540
static void flushCachedTemplateRelations()
Definition doxygen.cpp:9553
static void computeTemplateClassRelations()
Definition doxygen.cpp:5513
void printSectionsTree()
static void generateXRefPages()
Definition doxygen.cpp:5692
static void warnUndocumentedNamespaces()
Definition doxygen.cpp:5468
static void resolveClassNestingRelations()
Definition doxygen.cpp:1391
static void vhdlCorrectMemberProperties()
Definition doxygen.cpp:8512
static void stopDoxygen(int)
static void computeMemberReferences()
Definition doxygen.cpp:5582
static void transferRelatedFunctionDocumentation()
Definition doxygen.cpp:4543
static void addMembersToMemberGroup()
Definition doxygen.cpp:9418
static void distributeConceptGroups()
Definition doxygen.cpp:1358
static void transferFunctionDocumentation()
Definition doxygen.cpp:4462
static void setAnonymousEnumType()
Definition doxygen.cpp:9158
static void sortMemberLists()
Definition doxygen.cpp:9063
static void createTemplateInstanceMembers()
Definition doxygen.cpp:8640
void transferStaticInstanceInitializers()
Definition doxygen.cpp:4592
static void findObjCMethodDefinitions(const Entry *root)
Definition doxygen.cpp:7656
static void distributeMemberGroupDocumentation()
Definition doxygen.cpp:9456
static void resolveUserReferences()
Definition doxygen.cpp:9984
static void findIncludedUsingDirectives()
Definition doxygen.cpp:2592
static void organizeSubGroups(const Entry *root)
Definition doxygen.cpp:599
void searchInputFiles()
static void findFriends()
Definition doxygen.cpp:4365
static DString g_commentFileName
Definition doxygen.cpp:196
static void addListReferences()
Definition doxygen.cpp:5683
static void exitDoxygen() noexcept
static void addMembersToIndex()
Definition doxygen.cpp:8302
static void addSourceReferences()
Definition doxygen.cpp:8936
static void inheritDocumentation()
Definition doxygen.cpp:9358
static void flushUnresolvedRelations()
Definition doxygen.cpp:9595
static void findDocumentedEnumValues()
Definition doxygen.cpp:8294
static void generateDiskNames()
static void addToIndices()
Definition doxygen.cpp:8344
static void computeClassRelations()
Definition doxygen.cpp:5488
static void checkPageRelations()
Definition doxygen.cpp:9964
static void readTagFile(const std::shared_ptr< Entry > &root, const DString &tagLine)
static void addRequirementReferences()
Definition doxygen.cpp:5675
static void computeVerifiedDotPath()
static bool g_singleComment
Definition doxygen.cpp:197
static void findSectionsInDocumentation()
Definition doxygen.cpp:9494
static void mergeCategories()
Definition doxygen.cpp:8659
static void findUsedTemplateInstances()
Definition doxygen.cpp:5452
static void computeTooltipTexts()
Definition doxygen.cpp:9112
static void parseFilesSingleThreading(const std::shared_ptr< Entry > &root)
parse the list of input files
static void buildCompleteMemberLists()
Definition doxygen.cpp:8680
static void combineUsingRelations()
Definition doxygen.cpp:9393
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:4495
static void buildDefineList()
Definition doxygen.cpp:9015
static void computeMemberRelations()
Definition doxygen.cpp:8624
int dstricmp_sort(const char *str1, const char *str2)
Definition dstring.h:67
void printLayout()
Definition layout.cpp:1824
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:1053
int getPrefixIndex(const DString &name)
Definition util.cpp:2652

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 10098 of file doxygen.cpp.

10099{
10101 {
10102 DString indentStr;
10103 indentStr.fill(' ',indent);
10104 Debug::print(Debug::Entries,0,"{}{} at {}:{} (sec={}, spec={})\n",
10105 indentStr.empty()?"":indentStr,
10106 root->name.empty()?"<empty>":root->name,
10107 root->fileName,root->startLine,
10108 root->section.to_string(),
10109 root->spec.to_string());
10110 for (const auto &e : root->children())
10111 {
10112 printNavTree(e.get(),indent+2);
10113 }
10114 }
10115}
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 10121 of file doxygen.cpp.

10122{
10124 {
10125 for (const auto &si : SectionManager::instance())
10126 {
10127 Debug::print(Debug::Sections,0,"Section = {}, file = {}, title = {}, type = {}, ref = {}\n",
10128 si->label(),si->fileName(),si->title(),si->type().level(),si->ref());
10129 }
10130 }
10131}
@ 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 * cd,
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 1704 of file doxygen.cpp.

1710{
1711 AUTO_TRACE("count={} name={}\n",count,cd->name());
1712 if (tagParent /*&& !cd->getClasses().empty()*/)
1713 {
1714 MemberList *ml = cd->getMemberList(varFilter);
1715 if (ml)
1716 {
1717 int pos=0;
1718 for (const auto &md : *ml)
1719 {
1720 DString type = md->typeString();
1721 //printf(" member %s: type='%s' outerScope='%s'\n",qPrint(md->name()),qPrint(type),qPrint(md->getOuterScope()?md->getOuterScope()->name():"<null>"));
1722 if ((cd->definitionType()!=Definition::TypeFile || md->getOuterScope()==Doxygen::globalScope) && // part namespace members only if cd is a namespace
1723 (type.find("::@")!=DString::npos || type.find(" @")!=DString::npos)) // member of tag less struct/union
1724 {
1725 std::vector<const ClassDef *> candidates;
1726 for (const auto &icd : cd->getClasses())
1727 {
1728 candidates.push_back(icd);
1729 }
1730 for (const auto &icd : candidates)
1731 {
1732 //printf(" comparing '%s'<->'%s'\n",qPrint(type),qPrint(icd->name()));
1733 if (type.find(icd->name())!=DString::npos) // matching tag less struct/union
1734 {
1735 DString name = md->name();
1736 if (md->isAnonymous()) name = "__unnamed" + DString().setNum(pos++)+"__";
1737 if (!prefix.empty()) name.prepend(prefix+".");
1738 //printf(" found %s in scope %s\n",qPrint(name),qPrint(cd->name()));
1739 ClassDefMutable *ncd = createTagLessInstance(root,icd,name);
1740 if (ncd)
1741 {
1742 processTagLessClasses(ncd,icd,ncd,MemberListType::PubAttribs(),MemberListType::PubTypes(),name,count+1);
1743 //printf(" addTagged %s to %s\n",qPrint(ncd->name()),qPrint(tagParent->name()));
1744 ncd->setTagLessReference(icd);
1745
1746 // associate the variable of the anonymous type with the type member
1747 MemberList *pml = tagParent->getMemberList(varFilter);
1748 if (pml)
1749 {
1750 for (const auto &pmd : *pml)
1751 {
1753 if (pmdm && pmd->name()==md->name())
1754 {
1755 pmdm->setClassDefOfAnonymousType(ncd);
1756 }
1757 }
1758 }
1759 }
1760 }
1761 else
1762 {
1763 //printf(" no match for %s in %s\n",qPrint(icd->name()),qPrint(type));
1764 }
1765 }
1766 }
1767 }
1768 }
1769 // associate the variable of the anonymous enum type with the type member
1770 ml = cd->getMemberList(typeFilter);
1771 if (ml)
1772 {
1773 for (const auto &md : *ml)
1774 {
1775 MemberListType mlFilter = cd->definitionType()==Definition::TypeClass ? MemberListType::PubAttribs() : MemberListType::DecVarMembers();
1776 associateVariableWithAnonymousEnumType(md,cd,md,mlFilter);
1777 }
1778 }
1779 }
1780}
virtual void setTagLessReference(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)
Definition doxygen.cpp:1572

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

Referenced by findTagLessClasses(), and processTagLessClasses().

◆ readConfiguration()

void readConfiguration ( int argc,
char ** argv )

Definition at line 11616 of file doxygen.cpp.

11617{
11618 DString versionString = getFullVersion();
11619
11620 // helper that calls \a func to write to file \a fileName via a TextStream
11621 auto writeFile = [](const char *fileName,std::function<void(TextStream&)> func) -> bool
11622 {
11623 std::ofstream f;
11624 if (openOutputFile(fileName,f))
11625 {
11626 TextStream t(&f);
11627 func(t);
11628 return true;
11629 }
11630 return false;
11631 };
11632
11633
11634 /**************************************************************************
11635 * Handle arguments *
11636 **************************************************************************/
11637
11638 int optInd=1;
11639 DString configName;
11640 DString traceName;
11641 bool genConfig=false;
11642 bool shortList=false;
11643 bool traceTiming=false;
11645 bool updateConfig=false;
11646 bool quiet = false;
11647 while (optInd<argc && argv[optInd][0]=='-' &&
11648 (isalpha(argv[optInd][1]) || argv[optInd][1]=='?' ||
11649 argv[optInd][1]=='-')
11650 )
11651 {
11652 switch(argv[optInd][1])
11653 {
11654 case 'g':
11655 {
11656 genConfig=true;
11657 }
11658 break;
11659 case 'l':
11660 {
11661 DString layoutName;
11662 if (optInd+1>=argc)
11663 {
11664 layoutName="DoxygenLayout.xml";
11665 }
11666 else
11667 {
11668 layoutName=argv[optInd+1];
11669 }
11670 writeDefaultLayoutFile(layoutName);
11672 exit(0);
11673 }
11674 break;
11675 case 'c':
11676 if (optInd+1>=argc) // no file name given
11677 {
11678 msg("option \"-c\" is missing the file name to read\n");
11679 devUsage();
11681 exit(1);
11682 }
11683 else
11684 {
11685 g_commentFileName=argv[optInd+1];
11686 optInd++;
11687 }
11688 g_singleComment=true;
11689 quiet=true;
11690 break;
11691 case 'd':
11692 {
11693 DString debugLabel=getArg(argc,argv,optInd);
11694 if (debugLabel.empty())
11695 {
11696 devUsage();
11698 exit(0);
11699 }
11700 int retVal = Debug::setFlagStr(debugLabel);
11701 if (!retVal)
11702 {
11703 msg("option \"-d\" has unknown debug specifier: \"{}\".\n",debugLabel);
11704 devUsage();
11706 exit(1);
11707 }
11708 }
11709 break;
11710 case 't':
11711 {
11712#if ENABLE_TRACING
11713 if (!strcmp(argv[optInd]+1,"t_time"))
11714 {
11715 traceTiming = true;
11716 }
11717 else if (!strcmp(argv[optInd]+1,"t"))
11718 {
11719 traceTiming = false;
11720 }
11721 else
11722 {
11723 err("option should be \"-t\" or \"-t_time\", found: \"{}\".\n",argv[optInd]);
11725 exit(1);
11726 }
11727 if (optInd+1>=argc || argv[optInd+1][0] == '-') // no file name given
11728 {
11729 traceName="stdout";
11730 }
11731 else
11732 {
11733 traceName=argv[optInd+1];
11734 optInd++;
11735 }
11736#else
11737 err("support for option \"-t\" has not been compiled in (use a debug build or a release build with tracing enabled).\n");
11739 exit(1);
11740#endif
11741 }
11742 break;
11743 case 'x':
11744 if (!strcmp(argv[optInd]+1,"x_noenv")) diffList=Config::CompareMode::CompressedNoEnv;
11745 else if (!strcmp(argv[optInd]+1,"x")) diffList=Config::CompareMode::Compressed;
11746 else
11747 {
11748 err("option should be \"-x\" or \"-x_noenv\", found: \"{}\".\n",argv[optInd]);
11750 exit(1);
11751 }
11752 break;
11753 case 's':
11754 shortList=true;
11755 break;
11756 case 'u':
11757 updateConfig=true;
11758 break;
11759 case 'e':
11760 {
11761 DString formatName=getArg(argc,argv,optInd);
11762 if (formatName.empty())
11763 {
11764 err("option \"-e\" is missing format specifier rtf.\n");
11766 exit(1);
11767 }
11768 if (dstricmp(formatName.data(),"rtf")==0)
11769 {
11770 if (optInd+1>=argc)
11771 {
11772 err("option \"-e rtf\" is missing an extensions file name\n");
11774 exit(1);
11775 }
11776 writeFile(argv[optInd+1],RTFGenerator::writeExtensionsFile);
11778 exit(0);
11779 }
11780 err("option \"-e\" has invalid format specifier.\n");
11782 exit(1);
11783 }
11784 break;
11785 case 'f':
11786 {
11787 DString listName=getArg(argc,argv,optInd);
11788 if (listName.empty())
11789 {
11790 err("option \"-f\" is missing list specifier.\n");
11792 exit(1);
11793 }
11794 if (dstricmp(listName.data(),"emoji")==0)
11795 {
11796 if (optInd+1>=argc)
11797 {
11798 err("option \"-f emoji\" is missing an output file name\n");
11800 exit(1);
11801 }
11802 writeFile(argv[optInd+1],[](TextStream &t) { EmojiEntityMapper::instance().writeEmojiFile(t); });
11804 exit(0);
11805 }
11806 err("option \"-f\" has invalid list specifier.\n");
11808 exit(1);
11809 }
11810 break;
11811 case 'w':
11812 {
11813 DString formatName=getArg(argc,argv,optInd);
11814 if (formatName.empty())
11815 {
11816 err("option \"-w\" is missing format specifier rtf, html or latex\n");
11818 exit(1);
11819 }
11820 if (dstricmp(formatName.data(),"rtf")==0)
11821 {
11822 if (optInd+1>=argc)
11823 {
11824 err("option \"-w rtf\" is missing a style sheet file name\n");
11826 exit(1);
11827 }
11828 if (!writeFile(argv[optInd+1],RTFGenerator::writeStyleSheetFile))
11829 {
11830 err("error opening RTF style sheet file {}!\n",argv[optInd+1]);
11832 exit(1);
11833 }
11835 exit(0);
11836 }
11837 else if (dstricmp(formatName.data(),"html")==0)
11838 {
11839 Config::init();
11840 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11841 // explicit config file mentioned or default found on disk
11842 {
11843 DString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? DString("Doxyfile") : DString("doxyfile"));
11844 if (!Config::parse(df)) // parse the config file
11845 {
11846 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
11848 exit(1);
11849 }
11850 }
11851 if (optInd+3>=argc)
11852 {
11853 err("option \"-w html\" does not have enough arguments\n");
11855 exit(1);
11856 }
11857 Config::postProcess(true);
11860 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11861 writeFile(argv[optInd+1],[&](TextStream &t) { HtmlGenerator::writeHeaderFile(t,argv[optInd+3]); });
11862 writeFile(argv[optInd+2],HtmlGenerator::writeFooterFile);
11863 writeFile(argv[optInd+3],HtmlGenerator::writeStyleSheetFile);
11865 exit(0);
11866 }
11867 else if (dstricmp(formatName.data(),"latex")==0)
11868 {
11869 Config::init();
11870 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11871 {
11872 DString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? DString("Doxyfile") : DString("doxyfile"));
11873 if (!Config::parse(df))
11874 {
11875 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
11877 exit(1);
11878 }
11879 }
11880 if (optInd+3>=argc)
11881 {
11882 err("option \"-w latex\" does not have enough arguments\n");
11884 exit(1);
11885 }
11886 Config::postProcess(true);
11889 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11890 writeFile(argv[optInd+1],LatexGenerator::writeHeaderFile);
11891 writeFile(argv[optInd+2],LatexGenerator::writeFooterFile);
11892 writeFile(argv[optInd+3],LatexGenerator::writeStyleSheetFile);
11894 exit(0);
11895 }
11896 else
11897 {
11898 err("Illegal format specifier \"{}\": should be one of rtf, html or latex\n",formatName);
11900 exit(1);
11901 }
11902 }
11903 break;
11904 case 'm':
11905 g_dumpSymbolMap = true;
11906 break;
11907 case 'v':
11908 version(false);
11910 exit(0);
11911 break;
11912 case 'V':
11913 version(true);
11915 exit(0);
11916 break;
11917 case '-':
11918 if (dstrcmp(&argv[optInd][2],"help")==0)
11919 {
11920 usage(argv[0],versionString);
11921 exit(0);
11922 }
11923 else if (dstrcmp(&argv[optInd][2],"version")==0)
11924 {
11925 version(false);
11927 exit(0);
11928 }
11929 else if ((dstrcmp(&argv[optInd][2],"Version")==0) ||
11930 (dstrcmp(&argv[optInd][2],"VERSION")==0))
11931 {
11932 version(true);
11934 exit(0);
11935 }
11936 else
11937 {
11938 err("Unknown option \"-{}\"\n",&argv[optInd][1]);
11939 usage(argv[0],versionString);
11940 exit(1);
11941 }
11942 break;
11943 case 'b':
11944 setvbuf(stdout,nullptr,_IONBF,0);
11945 break;
11946 case 'q':
11947 quiet = true;
11948 break;
11949 case 'h':
11950 case '?':
11951 usage(argv[0],versionString);
11952 exit(0);
11953 break;
11954 default:
11955 err("Unknown option \"-{:c}\"\n",argv[optInd][1]);
11956 usage(argv[0],versionString);
11957 exit(1);
11958 }
11959 optInd++;
11960 }
11961
11962 /**************************************************************************
11963 * Parse or generate the config file *
11964 **************************************************************************/
11965
11966 initTracing(traceName.data(),traceTiming);
11967 TRACE("Doxygen version used: {}",getFullVersion());
11968 Config::init();
11969
11970 FileInfo configFileInfo1("Doxyfile"),configFileInfo2("doxyfile");
11971 if (optInd>=argc)
11972 {
11973 if (configFileInfo1.exists())
11974 {
11975 configName="Doxyfile";
11976 }
11977 else if (configFileInfo2.exists())
11978 {
11979 configName="doxyfile";
11980 }
11981 else if (genConfig)
11982 {
11983 configName="Doxyfile";
11984 }
11985 else
11986 {
11987 err("Doxyfile not found and no input file specified!\n");
11988 usage(argv[0],versionString);
11989 exit(1);
11990 }
11991 }
11992 else
11993 {
11994 FileInfo fi(argv[optInd]);
11995 if (fi.exists() || dstrcmp(argv[optInd],"-")==0 || genConfig)
11996 {
11997 configName=argv[optInd];
11998 }
11999 else
12000 {
12001 err("configuration file {} not found!\n",argv[optInd]);
12002 usage(argv[0],versionString);
12003 exit(1);
12004 }
12005 }
12006
12007 if (genConfig)
12008 {
12009 generateConfigFile(configName,shortList);
12011 exit(0);
12012 }
12013
12014 if (!Config::parse(configName,updateConfig,diffList))
12015 {
12016 err("could not open or read configuration file {}!\n",configName);
12018 exit(1);
12019 }
12020
12021 if (diffList!=Config::CompareMode::Full)
12022 {
12024 compareDoxyfile(diffList);
12026 exit(0);
12027 }
12028
12029 if (updateConfig)
12030 {
12032 generateConfigFile(configName,shortList,true);
12034 exit(0);
12035 }
12036
12037 /* Perlmod wants to know the path to the config file.*/
12038 FileInfo configFileInfo(configName.str());
12039 setPerlModDoxyfile(configFileInfo.absFilePath());
12040
12041 /* handle -q option */
12042 if (quiet) Config_updateBool(QUIET,true);
12043}
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:1623
static void writeFooterFile(TextStream &t)
Definition htmlgen.cpp:1629
static void writeStyleSheetFile(TextStream &t)
Definition htmlgen.cpp:1617
static void writeFooterFile(TextStream &t)
Definition latexgen.cpp:698
static void writeStyleSheetFile(TextStream &t)
Definition latexgen.cpp:704
static void writeHeaderFile(TextStream &t)
Definition latexgen.cpp:692
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:1736
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 11159 of file doxygen.cpp.

11171{
11172 std::string dirName = fi->absFilePath();
11173 if (paths && !dirName.empty())
11174 {
11175 paths->insert(dirName);
11176 }
11177 //printf("%s isSymLink()=%d\n",qPrint(dirName),fi->isSymLink());
11178 if (fi->isSymLink())
11179 {
11180 dirName = resolveSymlink(dirName);
11181 if (dirName.empty())
11182 {
11183 //printf("RECURSIVE SYMLINK: %s\n",qPrint(dirName));
11184 return; // recursive symlink
11185 }
11186 }
11187
11188 if (g_pathsVisited.find(dirName)!=g_pathsVisited.end())
11189 {
11190 //printf("PATH ALREADY VISITED: %s\n",qPrint(dirName));
11191 return; // already visited path
11192 }
11193 g_pathsVisited.insert(dirName);
11194
11195 Dir dir(dirName);
11196 msg("Searching for files in directory {}\n", fi->absFilePath());
11197 //printf("killSet=%p count=%d\n",killSet,killSet ? (int)killSet->count() : -1);
11198
11199 StringVector dirResultList;
11200
11201 bool caseSenseNames = useCaseSenseNames();
11202
11203 for (const auto &dirEntry : dir.iterator())
11204 {
11205 FileInfo cfi(dirEntry.path());
11206 auto checkPatterns = [&]() -> bool
11207 {
11208 return (patList==nullptr || cfi.match(*patList,caseSenseNames)) &&
11209 (exclPatList==nullptr || !cfi.match(*exclPatList,caseSenseNames)) &&
11210 (killSet==nullptr || killSet->find(cfi.absFilePath())==killSet->end());
11211 };
11212
11213 if (exclSet==nullptr || exclSet->find(cfi.absFilePath())==exclSet->end())
11214 { // file should not be excluded
11215 //printf("killSet->find(%s)\n",qPrint(cfi->absFilePath()));
11216 if (Config_getBool(EXCLUDE_SYMLINKS) && cfi.isSymLink())
11217 {
11218 }
11219 else if (!cfi.exists() || !cfi.isReadable())
11220 {
11221 if (errorIfNotExist && checkPatterns())
11222 {
11223 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",cfi.absFilePath());
11224 }
11225 }
11226 else if (cfi.isFile() && checkPatterns())
11227 {
11228 std::string name=cfi.fileName();
11229 std::string path=cfi.dirPath()+"/";
11230 std::string fullName=path+name;
11231 if (fnMap)
11232 {
11233 auto fd = createFileDef(path,name);
11234 FileName *fn=nullptr;
11235 if (!name.empty())
11236 {
11237 fn = fnMap->add(name);
11238 fn->push_back(std::move(fd));
11239 }
11240 }
11241 dirResultList.push_back(fullName);
11242 if (resultSet) resultSet->insert(fullName);
11243 if (killSet) killSet->insert(fullName);
11244 }
11245 else if (recursive &&
11246 cfi.isDir() &&
11247 (exclPatList==nullptr || !cfi.match(*exclPatList,caseSenseNames)) &&
11248 cfi.fileName().at(0)!='.') // skip "." ".." and ".dir"
11249 {
11250 FileInfo acfi(cfi.absFilePath());
11251 readDir(&acfi,fnMap,exclSet,
11252 patList,exclPatList,&dirResultList,resultSet,errorIfNotExist,
11253 recursive,killSet,paths);
11254 }
11255 }
11256 }
11257 if (resultList && !dirResultList.empty())
11258 {
11259 // sort the resulting list to make the order platform independent.
11260 std::stable_sort(dirResultList.begin(),
11261 dirResultList.end(),
11262 [](const auto &f1,const auto &f2) { return dstricmp_sort(f1.c_str(),f2.c_str())<0; });
11263
11264 // append the sorted results to resultList
11265 resultList->insert(resultList->end(), dirResultList.begin(), dirResultList.end());
11266 }
11267}
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:2680

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 11274 of file doxygen.cpp.

11286{
11287 //printf("killSet count=%d\n",killSet ? (int)killSet->size() : -1);
11288 // strip trailing slashes
11289 if (s.empty()) return;
11290
11291 g_pathsVisited.clear();
11292
11293 FileInfo fi(s.str());
11294 //printf("readFileOrDirectory(%s)\n",s);
11295 {
11296 if (exclSet==nullptr || exclSet->find(fi.absFilePath())==exclSet->end())
11297 {
11298 if (Config_getBool(EXCLUDE_SYMLINKS) && fi.isSymLink())
11299 {
11300 }
11301 else if (!fi.exists() || !fi.isReadable())
11302 {
11303 if (errorIfNotExist)
11304 {
11305 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",s);
11306 }
11307 }
11308 else if (fi.isFile())
11309 {
11310 std::string dirPath = fi.dirPath(true);
11311 std::string filePath = fi.absFilePath();
11312 if (paths && !dirPath.empty())
11313 {
11314 paths->insert(dirPath);
11315 }
11316 //printf("killSet.find(%s)=%d\n",qPrint(fi.absFilePath()),killSet.find(fi.absFilePath())!=killSet.end());
11317 if (killSet==nullptr || killSet->find(filePath)==killSet->end())
11318 {
11319 std::string name=fi.fileName();
11320 if (fnMap)
11321 {
11322 auto fd = createFileDef(dirPath+"/",name);
11323 if (!name.empty())
11324 {
11325 FileName *fn = fnMap->add(name);
11326 fn->push_back(std::move(fd));
11327 }
11328 }
11329 if (resultList || resultSet)
11330 {
11331 if (resultList) resultList->push_back(filePath);
11332 if (resultSet) resultSet->insert(filePath);
11333 }
11334
11335 if (killSet) killSet->insert(fi.absFilePath());
11336 }
11337 }
11338 else if (fi.isDir()) // readable dir
11339 {
11340 readDir(&fi,fnMap,exclSet,patList,
11341 exclPatList,resultList,resultSet,errorIfNotExist,
11342 recursive,killSet,paths);
11343 }
11344 }
11345 }
11346}

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 10485 of file doxygen.cpp.

10486{
10487 DString fileName;
10488 DString destName;
10489 if (size_t eqPos = tagLine.find('='); eqPos!=DString::npos) // tag command contains a destination
10490 {
10491 fileName = tagLine.left(eqPos).stripWhiteSpace();
10492 destName = tagLine.mid(eqPos+1).stripWhiteSpace();
10493 if (fileName.empty() || destName.empty()) return;
10494 //printf("insert tagDestination %s->%s\n",qPrint(fi.fileName()),qPrint(destName));
10495 }
10496 else
10497 {
10498 fileName = tagLine;
10499 }
10500
10501 FileInfo fi(fileName.str());
10502 if (!fi.exists() || !fi.isFile())
10503 {
10504 err("Tag file '{}' does not exist or is not a file. Skipping it...\n",fileName);
10505 return;
10506 }
10507
10508 if (Doxygen::tagFileSet.find(fi.absFilePath()) != Doxygen::tagFileSet.end()) return;
10509
10510 Doxygen::tagFileSet.emplace(fi.absFilePath());
10511
10512 if (!destName.empty())
10513 {
10514 Doxygen::tagDestinationMap.emplace(fi.absFilePath(), destName.str());
10515 msg("Reading tag file '{}', location '{}'...\n",fileName,destName);
10516 }
10517 else
10518 {
10519 msg("Reading tag file '{}'...\n",fileName);
10520 }
10521
10522 parseTagFile(root,fi.absFilePath().c_str());
10523}
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 {
1415 DString name = stripAnonymousNamespaceScope(icd->name());
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(), DString::startsWith(), stripAnonymousNamespaceScope(), toClassDefMutable(), toDefinitionMutable(), toNamespaceDef(), Definition::TypeNamespace, and warn.

Referenced by parseInput().

◆ resolveSymlink()

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

Definition at line 11087 of file doxygen.cpp.

11088{
11089 size_t sepPos=0;
11090 size_t oldPos=0;
11091 StringUnorderedSet nonSymlinks;
11092 StringUnorderedSet known;
11093 DString result(path);
11094 DString oldPrefix = "/";
11095 do
11096 {
11097#if defined(_WIN32)
11098 // UNC path, skip server and share name
11099 if (sepPos==0 && (result.startsWith("//") || result.startsWith("\\\\")))
11100 sepPos = result.find('/',2);
11101 if (sepPos!=DString::npos)
11102 sepPos = result.find('/',sepPos+1);
11103#else
11104 sepPos = result.find('/',sepPos+1);
11105#endif
11106 DString prefix = sepPos==DString::npos ? result : result.left(sepPos);
11107 if (nonSymlinks.find(prefix.str())==nonSymlinks.end())
11108 {
11109 FileInfo fi(prefix.str());
11110 if (fi.isSymLink())
11111 {
11112 DString target = fi.readLink();
11113 bool isRelative = FileInfo(target.str()).isRelative();
11114 if (isRelative)
11115 {
11116 target = Dir::cleanDirPath(oldPrefix.str()+"/"+target.str());
11117 }
11118 if (sepPos!=DString::npos)
11119 {
11120 if (fi.isDir() && !target.empty() && target.at(target.length()-1)!='/')
11121 {
11122 target+='/';
11123 }
11124 target+=result.mid(sepPos);
11125 }
11126 result = Dir::cleanDirPath(target.str());
11127 if (known.find(result.str())!=known.end()) return std::string(); // recursive symlink!
11128 known.insert(result.str());
11129 if (isRelative)
11130 {
11131 sepPos = oldPos;
11132 }
11133 else // link to absolute path
11134 {
11135 sepPos = 0;
11136 oldPrefix = "/";
11137 }
11138 }
11139 else
11140 {
11141 nonSymlinks.insert(prefix.str());
11142 oldPrefix = prefix;
11143 }
11144 oldPos = sepPos;
11145 }
11146 }
11147 while (sepPos!=DString::npos);
11148 return Dir::cleanDirPath(result.str());
11149}
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 4950 of file doxygen.cpp.

4951{
4952 // For a statement like 'using X = T<A>', add a template instance 'T<A>' as a symbol, so it can
4953 // be used to match arguments (see issue #11111)
4954 AUTO_TRACE();
4955 DString ttype = md->typeString();
4956 ttype.stripPrefix("typedef ");
4957 if (size_t ti=ttype.find('<'); ti!=DString::npos)
4958 {
4959 DString templateClassName = ttype.left(ti);
4960 SymbolResolver resolver(root->fileDef());
4961 ClassDefMutable *baseClass = resolver.resolveClassMutable(scope ? scope : Doxygen::globalScope,
4962 templateClassName, true, true);
4963 AUTO_TRACE_ADD("templateClassName={} baseClass={}",templateClassName,baseClass?baseClass->name():"<none>");
4964 if (baseClass)
4965 {
4966 const ArgumentList &tl = baseClass->templateArguments();
4967 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,templateClassName.str());
4969 baseClass,
4970 ttype.mid(ti),
4971 templateNames,
4972 baseClass->isArtificial());
4973 }
4974 }
4975}

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 9984 of file doxygen.cpp.

9985{
9986 for (const auto &si : SectionManager::instance())
9987 {
9988 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
9989 // qPrint(si->label),si->definition?qPrint(si->definition->name()):"<none>",
9990 // qPrint(si->fileName));
9991 PageDef *pd=nullptr;
9992
9993 // hack: the items of a todo/test/bug/deprecated list are all fragments from
9994 // different files, so the resulting section's all have the wrong file
9995 // name (not from the todo/test/bug/deprecated list, but from the file in
9996 // which they are defined). We correct this here by looking at the
9997 // generated section labels!
9999 {
10000 DString label="_"+rl->listName(); // "_todo", "_test", ...
10001 if (si->label().left(label.length())==label)
10002 {
10003 si->setFileName(rl->listName());
10004 si->setGenerated(true);
10005 break;
10006 }
10007 }
10008
10009 //printf("start: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
10010 if (!si->generated())
10011 {
10012 // if this section is in a page and the page is in a group, then we
10013 // have to adjust the link file name to point to the group.
10014 if (!si->fileName().empty() &&
10015 (pd=Doxygen::pageLinkedMap->find(si->fileName())) &&
10016 pd->getGroupDef())
10017 {
10018 si->setFileName(pd->getGroupDef()->getOutputFileBase());
10019 }
10020
10021 if (si->definition())
10022 {
10023 // TODO: there should be one function in Definition that returns
10024 // the file to link to, so we can avoid the following tests.
10025 const GroupDef *gd=nullptr;
10026 if (si->definition()->definitionType()==Definition::TypeMember)
10027 {
10028 gd = (toMemberDef(si->definition()))->getGroupDef();
10029 }
10030
10031 if (gd)
10032 {
10033 si->setFileName(gd->getOutputFileBase());
10034 }
10035 else
10036 {
10037 //si->fileName=si->definition->getOutputFileBase();
10038 //printf("Setting si->fileName to %s\n",qPrint(si->fileName));
10039 }
10040 }
10041 }
10042 //printf("end: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
10043 }
10044}
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 10308 of file doxygen.cpp.

10309{
10310 std::string oldDir = Dir::currentDirPath();
10311 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10314 {
10315 err("failed to run html help compiler on {}\n", HtmlHelp::hhpFileName);
10316 }
10317 Dir::setCurrent(oldDir);
10318}
@ 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 10320 of file doxygen.cpp.

10321{
10322 DString args = Qhp::qhpFileName + " -o \"" + Qhp::getQchFileName() + "\"";
10323 std::string oldDir = Dir::currentDirPath();
10324 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10325
10326 DString qhgLocation=Config_getString(QHG_LOCATION);
10327 if (Debug::isFlagSet(Debug::Qhp)) // produce info for debugging
10328 {
10329 // run qhelpgenerator -v and extract the Qt version used
10330 DString cmd=qhgLocation+ " -v 2>&1";
10331 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10332 FILE *f=Portable::popen(cmd,"r");
10333 if (!f)
10334 {
10335 err("could not execute {}\n",qhgLocation);
10336 }
10337 else
10338 {
10339 const size_t bufSize = 1024;
10340 char inBuf[bufSize+1];
10341 size_t numRead=fread(inBuf,1,bufSize,f);
10342 inBuf[numRead] = '\0';
10343 Debug::print(Debug::Qhp,0,"{}",inBuf);
10345
10346 int qtVersion=0;
10347 static const reg::Ex versionReg(R"(Qt (\d+)\.(\d+)\.(\d+))");
10349 std::string s = inBuf;
10350 if (reg::search(s,match,versionReg))
10351 {
10352 qtVersion = 10000*DString(match[1].str()).toInt() +
10353 100*DString(match[2].str()).toInt() +
10354 DString(match[3].str()).toInt();
10355 }
10356 if (qtVersion>0 && (qtVersion<60000 || qtVersion >= 60205))
10357 {
10358 // dump the output of qhelpgenerator -c file.qhp
10359 // Qt<6 or Qt>=6.2.5 or higher, see https://bugreports.qt.io/browse/QTBUG-101070
10360 cmd=qhgLocation+ " -c " + Qhp::qhpFileName + " 2>&1";
10361 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10362 f=Portable::popen(cmd,"r");
10363 if (!f)
10364 {
10365 err("could not execute {}\n",qhgLocation);
10366 }
10367 else
10368 {
10369 std::string output;
10370 while ((numRead=fread(inBuf,1,bufSize,f))>0)
10371 {
10372 inBuf[numRead] = '\0';
10373 output += inBuf;
10374 }
10376 Debug::print(Debug::Qhp,0,"{}",output);
10377 }
10378 }
10379 }
10380 }
10381
10382 if (Portable::system(qhgLocation, args, false))
10383 {
10384 err("failed to run qhelpgenerator on {}\n",Qhp::qhpFileName);
10385 }
10386 Dir::setCurrent(oldDir);
10387}
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 6121 of file doxygen.cpp.

6122{
6123 bool result=false;
6124 //printf("> scopeIsTemplate(%s)\n",qPrint(d?d->name():"null"));
6126 {
6127 auto cd = toClassDef(d);
6128 result = cd->templateArguments().hasParameters() || cd->templateMaster()!=nullptr ||
6130 }
6131 //printf("< scopeIsTemplate=%d\n",result);
6132 return result;
6133}

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

Referenced by addMemberFunction(), and scopeIsTemplate().

◆ searchInputFiles()

void searchInputFiles ( )

Definition at line 12316 of file doxygen.cpp.

12317{
12318 StringUnorderedSet killSet;
12319
12320 StringVector exclPatterns = Config_getList(EXCLUDE_PATTERNS);
12321 bool alwaysRecursive = Config_getBool(RECURSIVE);
12322 StringUnorderedSet excludeNameSet;
12323
12324 // gather names of all files in the include path
12325 g_s.begin("Searching for include files...\n");
12326 killSet.clear();
12327 StringVector includePathList = Config_getList(INCLUDE_PATH);
12328 for (const auto &s : includePathList)
12329 {
12330 size_t plSize = Config_getList(INCLUDE_FILE_PATTERNS).size();
12331 StringVector pl = plSize==0 ? Config_getList(FILE_PATTERNS) :
12332 Config_getList(INCLUDE_FILE_PATTERNS);
12333 readFileOrDirectory(s, // s
12335 nullptr, // exclSet
12336 &pl, // patList
12337 &exclPatterns, // exclPatList
12338 nullptr, // resultList
12339 nullptr, // resultSet
12340 false, // INCLUDE_PATH isn't recursive
12341 true, // errorIfNotExist
12342 &killSet); // killSet
12343 }
12344 g_s.end();
12345
12346 g_s.begin("Searching for example files...\n");
12347 killSet.clear();
12348 StringVector examplePathList = Config_getList(EXAMPLE_PATH);
12349 for (const auto &s : examplePathList)
12350 {
12351 StringVector patterns = Config_getList(EXAMPLE_PATTERNS);
12352 readFileOrDirectory(s, // s
12354 nullptr, // exclSet
12355 &patterns, // patList
12356 nullptr, // exclPatList
12357 nullptr, // resultList
12358 nullptr, // resultSet
12359 (alwaysRecursive || Config_getBool(EXAMPLE_RECURSIVE)), // recursive
12360 true, // errorIfNotExist
12361 &killSet); // killSet
12362 }
12363 g_s.end();
12364
12365 g_s.begin("Searching for images...\n");
12366 killSet.clear();
12367 StringVector imagePathList=Config_getList(IMAGE_PATH);
12368 for (const auto &s : imagePathList)
12369 {
12370 readFileOrDirectory(s, // s
12372 nullptr, // exclSet
12373 nullptr, // patList
12374 nullptr, // exclPatList
12375 nullptr, // resultList
12376 nullptr, // resultSet
12377 alwaysRecursive, // recursive
12378 true, // errorIfNotExist
12379 &killSet); // killSet
12380 }
12381 g_s.end();
12382
12383 g_s.begin("Searching for dot files...\n");
12384 killSet.clear();
12385 StringVector dotFileList=Config_getList(DOTFILE_DIRS);
12386 for (const auto &s : dotFileList)
12387 {
12388 readFileOrDirectory(s, // s
12390 nullptr, // exclSet
12391 nullptr, // patList
12392 nullptr, // exclPatList
12393 nullptr, // resultList
12394 nullptr, // resultSet
12395 alwaysRecursive, // recursive
12396 true, // errorIfNotExist
12397 &killSet); // killSet
12398 }
12399 g_s.end();
12400
12401 g_s.begin("Searching for msc files...\n");
12402 killSet.clear();
12403 StringVector mscFileList=Config_getList(MSCFILE_DIRS);
12404 for (const auto &s : mscFileList)
12405 {
12406 readFileOrDirectory(s, // s
12408 nullptr, // exclSet
12409 nullptr, // patList
12410 nullptr, // exclPatList
12411 nullptr, // resultList
12412 nullptr, // resultSet
12413 alwaysRecursive, // recursive
12414 true, // errorIfNotExist
12415 &killSet); // killSet
12416 }
12417 g_s.end();
12418
12419 g_s.begin("Searching for dia files...\n");
12420 killSet.clear();
12421 StringVector diaFileList=Config_getList(DIAFILE_DIRS);
12422 for (const auto &s : diaFileList)
12423 {
12424 readFileOrDirectory(s, // s
12426 nullptr, // exclSet
12427 nullptr, // patList
12428 nullptr, // exclPatList
12429 nullptr, // resultList
12430 nullptr, // resultSet
12431 alwaysRecursive, // recursive
12432 true, // errorIfNotExist
12433 &killSet); // killSet
12434 }
12435 g_s.end();
12436
12437 g_s.begin("Searching for plantuml files...\n");
12438 killSet.clear();
12439 StringVector plantUmlFileList=Config_getList(PLANTUMLFILE_DIRS);
12440 for (const auto &s : plantUmlFileList)
12441 {
12442 readFileOrDirectory(s, // s
12444 nullptr, // exclSet
12445 nullptr, // patList
12446 nullptr, // exclPatList
12447 nullptr, // resultList
12448 nullptr, // resultSet
12449 alwaysRecursive, // recursive
12450 true, // errorIfNotExist
12451 &killSet); // killSet
12452 }
12453 g_s.end();
12454
12455 g_s.begin("Searching for mermaid files...\n");
12456 killSet.clear();
12457 StringVector mermaidFileList=Config_getList(MERMAIDFILE_DIRS);
12458 for (const auto &s : mermaidFileList)
12459 {
12460 readFileOrDirectory(s, // s
12462 nullptr, // exclSet
12463 nullptr, // patList
12464 nullptr, // exclPatList
12465 nullptr, // resultList
12466 nullptr, // resultSet
12467 alwaysRecursive, // recursive
12468 true, // errorIfNotExist
12469 &killSet); // killSet
12470 }
12471 g_s.end();
12472
12473 g_s.begin("Searching for files to exclude\n");
12474 StringVector excludeList = Config_getList(EXCLUDE);
12475 for (const auto &s : excludeList)
12476 {
12477 StringVector filePatterns = Config_getList(FILE_PATTERNS);
12478 readFileOrDirectory(s, // s
12479 nullptr, // fnDict
12480 nullptr, // exclSet
12481 &filePatterns, // patList
12482 nullptr, // exclPatList
12483 nullptr, // resultList
12484 &excludeNameSet, // resultSet
12485 alwaysRecursive, // recursive
12486 false); // errorIfNotExist
12487 }
12488 g_s.end();
12489
12490 /**************************************************************************
12491 * Determine Input Files *
12492 **************************************************************************/
12493
12494 g_s.begin("Searching INPUT for files to process...\n");
12495 killSet.clear();
12496 Doxygen::inputPaths.clear();
12497 StringVector inputList=Config_getList(INPUT);
12498 for (const auto &s : inputList)
12499 {
12500 DString path = s;
12501 size_t l = path.length();
12502 if (l>0)
12503 {
12504 // strip trailing slashes
12505 if (path.at(l-1)=='\\' || path.at(l-1)=='/') path=path.left(l-1);
12506
12507 StringVector filePatterns = Config_getList(FILE_PATTERNS);
12509 path, // s
12511 &excludeNameSet, // exclSet
12512 &filePatterns, // patList
12513 &exclPatterns, // exclPatList
12514 &g_inputFiles, // resultList
12515 nullptr, // resultSet
12516 alwaysRecursive, // recursive
12517 true, // errorIfNotExist
12518 &killSet, // killSet
12519 &Doxygen::inputPaths); // paths
12520 }
12521 }
12522
12523 // Sort the FileDef objects by full path to get a predictable ordering over multiple runs
12524 for (auto &fileName : *Doxygen::inputNameLinkedMap)
12525 {
12526 if (fileName->size()>1)
12527 {
12528 std::stable_sort(fileName->begin(),fileName->end(),[](const auto &f1,const auto &f2)
12529 {
12530 return dstricmp_sort(f1->absFilePath(),f2->absFilePath())<0;
12531 });
12532 }
12533 }
12534 std::stable_sort(Doxygen::inputNameLinkedMap->begin(),
12536 [](const auto &f1,const auto &f2)
12537 {
12538 return dstricmp_sort(f1->front()->absFilePath(),f2->front()->absFilePath())<0;
12539 });
12540 if (Doxygen::inputNameLinkedMap->empty())
12541 {
12542 warn_uncond("No files to be processed, please check your settings, in particular INPUT, FILE_PATTERNS, and RECURSIVE\n");
12543 }
12544 g_s.end();
12545}
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 9158 of file doxygen.cpp.

9159{
9160 for (const auto &cd : *Doxygen::classLinkedMap)
9161 {
9162 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9163 if (cdm)
9164 {
9165 cdm->setAnonymousEnumType();
9166 }
9167 }
9168}
virtual void setAnonymousEnumType()=0

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

Referenced by parseInput().

◆ sortMemberLists()

void sortMemberLists ( )
static

Definition at line 9063 of file doxygen.cpp.

9064{
9065 // sort class member lists
9066 for (const auto &cd : *Doxygen::classLinkedMap)
9067 {
9068 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9069 if (cdm)
9070 {
9071 cdm->sortMemberLists();
9072 }
9073 }
9074
9075 // sort namespace member lists
9076 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9077 {
9079 if (ndm)
9080 {
9081 ndm->sortMemberLists();
9082 }
9083 }
9084
9085 // sort file member lists
9086 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9087 {
9088 for (const auto &fd : *fn)
9089 {
9090 fd->sortMemberLists();
9091 }
9092 }
9093
9094 // sort group member lists
9095 for (const auto &gd : *Doxygen::groupLinkedMap)
9096 {
9097 gd->sortMemberLists();
9098 }
9099
9101}
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 12183 of file doxygen.cpp.

12184{
12185 signal(SIGINT,SIG_DFL); // Re-register signal handler for default action
12186 Dir thisDir;
12187 msg("Cleaning up...\n");
12188 if (!Doxygen::filterDBFileName.empty())
12189 {
12190 thisDir.remove(Doxygen::filterDBFileName.str());
12191 }
12192 killpg(0,SIGINT);
12194 exitTracing();
12195 exit(1);
12196}

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 6219 of file doxygen.cpp.

6225{
6226 auto dstIt = dst.begin();
6227 for (const Argument &sa : src)
6228 {
6229 DString dstType = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.type.str());
6230 DString dstArray = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.array.str());
6231 if (dstIt == dst.end())
6232 {
6233 Argument da = sa;
6234 da.type = dstType;
6235 da.array = dstArray;
6236 dst.push_back(da);
6237 dstIt = dst.end();
6238 }
6239 else
6240 {
6241 Argument da = *dstIt;
6242 da.type = dstType;
6243 da.array = dstArray;
6244 ++dstIt;
6245 }
6246 }
6247 dst.setConstSpecifier(src.constSpecifier());
6248 dst.setVolatileSpecifier(src.volatileSpecifier());
6249 dst.setPureSpecifier(src.pureSpecifier());
6251 srcTempArgLists,dstTempArgLists,
6252 src.trailingReturnType().str()));
6253 dst.setIsDeleted(src.isDeleted());
6254 dst.setRefQualifier(src.refQualifier());
6255 dst.setNoParameters(src.noParameters());
6256 //printf("substituteTemplatesInArgList: replacing %s with %s\n",
6257 // qPrint(argListToString(src)),qPrint(argListToString(dst))
6258 // );
6259}
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:6135

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 6135 of file doxygen.cpp.

6140{
6141 std::string dst;
6142 static const reg::Ex re(R"(\a\w*)");
6143 reg::Iterator it(src,re);
6145 //printf("type=%s\n",qPrint(sa->type));
6146 size_t p=0;
6147 for (; it!=end ; ++it) // for each word in srcType
6148 {
6149 const auto &match = *it;
6150 size_t i = match.position();
6151 size_t l = match.length();
6152 bool found=false;
6153 dst+=src.substr(p,i-p);
6154 std::string name=match.str();
6155
6156 auto srcIt = srcTempArgLists.begin();
6157 auto dstIt = dstTempArgLists.begin();
6158 while (srcIt!=srcTempArgLists.end() && !found)
6159 {
6160 const ArgumentList *tdAli = nullptr;
6161 std::vector<Argument>::const_iterator tdaIt;
6162 if (dstIt!=dstTempArgLists.end())
6163 {
6164 tdAli = &(*dstIt);
6165 tdaIt = tdAli->begin();
6166 ++dstIt;
6167 }
6168
6169 const ArgumentList &tsaLi = *srcIt;
6170 for (auto tsaIt = tsaLi.begin(); tsaIt!=tsaLi.end() && !found; ++tsaIt)
6171 {
6172 Argument tsa = *tsaIt;
6173 const Argument *tda = nullptr;
6174 if (tdAli && tdaIt!=tdAli->end())
6175 {
6176 tda = &(*tdaIt);
6177 ++tdaIt;
6178 }
6179 //if (tda) printf("tsa=%s|%s tda=%s|%s\n",
6180 // qPrint(tsa.type),qPrint(tsa.name),
6181 // qPrint(tda->type),qPrint(tda->name));
6182 if (name==tsa.name.str())
6183 {
6184 if (tda && tda->name.empty())
6185 {
6186 DString tdaName = tda->name;
6187 DString tdaType = tda->type;
6188 int vc=0;
6189 if (tdaType.startsWith("class ")) vc=6;
6190 else if (tdaType.startsWith("typename ")) vc=9;
6191 if (vc>0) // convert type=="class T" to type=="class" name=="T"
6192 {
6193 tdaName = tdaType.mid(vc);
6194 }
6195 if (!tdaName.empty())
6196 {
6197 name=tdaName.str(); // substitute
6198 found=true;
6199 }
6200 }
6201 }
6202 }
6203
6204 //printf(" srcList='%s' dstList='%s faList='%s'\n",
6205 // qPrint(argListToString(srclali.current())),
6206 // qPrint(argListToString(dstlali.current())),
6207 // funcTempArgList ? qPrint(argListToString(funcTempArgList)) : "<none>");
6208 ++srcIt;
6209 }
6210 dst+=name;
6211 p=i+l;
6212 }
6213 dst+=src.substr(p);
6214 //printf(" substituteTemplatesInString(%s)=%s\n",
6215 // qPrint(src),qPrint(dst));
6216 return dst;
6217}

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 4462 of file doxygen.cpp.

4463{
4464 AUTO_TRACE();
4465
4466 // find matching function declaration and definitions.
4467 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4468 {
4469 //printf("memberName=%s count=%zu\n",qPrint(mn->memberName()),mn->size());
4470 /* find a matching function declaration and definition for this function */
4471 for (const auto &imdec : *mn)
4472 {
4473 MemberDefMutable *mdec = toMemberDefMutable(imdec.get());
4474 if (mdec &&
4475 (mdec->isPrototype() ||
4476 (mdec->isVariable() && mdec->isExternal())
4477 ))
4478 {
4479 for (const auto &imdef : *mn)
4480 {
4481 MemberDefMutable *mdef = toMemberDefMutable(imdef.get());
4482 if (mdef && mdec!=mdef &&
4483 mdec->getNamespaceDef()==mdef->getNamespaceDef())
4484 {
4486 }
4487 }
4488 }
4489 }
4490 }
4491}
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 4495 of file doxygen.cpp.

4496{
4497 AUTO_TRACE();
4498 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4499 {
4500 MemberDefMutable *mdef=nullptr,*mdec=nullptr;
4501 /* find a matching function declaration and definition for this function */
4502 for (const auto &imd : *mn)
4503 {
4504 MemberDefMutable *md = toMemberDefMutable(imd.get());
4505 if (md)
4506 {
4507 if (md->isPrototype())
4508 mdec=md;
4509 else if (md->isVariable() && md->isExternal())
4510 mdec=md;
4511
4512 if (md->isFunction() && !md->isStatic() && !md->isPrototype())
4513 mdef=md;
4514 else if (md->isVariable() && !md->isExternal() && !md->isStatic())
4515 mdef=md;
4516 }
4517
4518 if (mdef && mdec) break;
4519 }
4520 if (mdef && mdec)
4521 {
4522 const ArgumentList &mdefAl = mdef->argumentList();
4523 const ArgumentList &mdecAl = mdec->argumentList();
4524 if (
4525 matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdef->typeString(),const_cast<ArgumentList*>(&mdefAl),
4526 mdec->getOuterScope(),mdec->getFileDef(),mdec->typeString(),const_cast<ArgumentList*>(&mdecAl),
4527 true,mdef->getLanguage()
4528 )
4529 ) /* match found */
4530 {
4531 AUTO_TRACE_ADD("merging references for mdec={} mdef={}",mdec->name(),mdef->name());
4532 mdef->mergeReferences(mdec);
4533 mdec->mergeReferences(mdef);
4534 mdef->mergeReferencedBy(mdec);
4535 mdec->mergeReferencedBy(mdef);
4536 }
4537 }
4538 }
4539}
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 4543 of file doxygen.cpp.

4544{
4545 AUTO_TRACE();
4546 // find match between function declaration and definition for
4547 // related functions
4548 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4549 {
4550 /* find a matching function declaration and definition for this function */
4551 // for each global function
4552 for (const auto &imd : *mn)
4553 {
4554 MemberDefMutable *md = toMemberDefMutable(imd.get());
4555 if (md)
4556 {
4557 //printf(" Function '%s'\n",qPrint(md->name()));
4559 if (rmn) // check if there is a member with the same name
4560 {
4561 //printf(" Member name found\n");
4562 // for each member with the same name
4563 for (const auto &irmd : *rmn)
4564 {
4565 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
4566 //printf(" Member found: related='%d'\n",rmd->isRelated());
4567 if (rmd &&
4568 (rmd->isRelated() || rmd->isForeign()) && // related function
4569 matchArguments2( md->getOuterScope(), md->getFileDef(), md->typeString(), &md->argumentList(),
4570 rmd->getOuterScope(),rmd->getFileDef(),rmd->typeString(),&rmd->argumentList(),
4571 true,md->getLanguage()
4572 )
4573 )
4574 {
4575 AUTO_TRACE_ADD("Found related member '{}'",md->name());
4576 if (rmd->relatedAlso())
4577 md->setRelatedAlso(rmd->relatedAlso());
4578 else if (rmd->isForeign())
4579 md->makeForeign();
4580 else
4581 md->makeRelated();
4582 }
4583 }
4584 }
4585 }
4586 }
4587 }
4588}
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 4592 of file doxygen.cpp.

4593{
4594 AUTO_TRACE();
4595 for (const auto &[qualifiedName,bodyInfo] : Doxygen::staticInitMap)
4596 {
4597 size_t i=qualifiedName.rfind("::");
4598 if (i!=std::string::npos)
4599 {
4600 DString scope = qualifiedName.substr(0,i);
4601 DString name = qualifiedName.substr(i+2);
4603 if (mn)
4604 {
4605 for (const auto &imd : *mn)
4606 {
4607 MemberDefMutable *md = toMemberDefMutable(imd.get());
4608 if (md && md->qualifiedName().str()==qualifiedName && md->isVariable())
4609 {
4610 AUTO_TRACE_ADD("found static member {} body [{}..{}]\n",
4611 md->qualifiedName(),bodyInfo.startLine,bodyInfo.endLine);
4612 md->setBodySegment(bodyInfo.defLine,
4613 bodyInfo.startLine,
4614 bodyInfo.endLine);
4615 }
4616 }
4617 }
4618 }
4619 }
4620}

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 8150 of file doxygen.cpp.

8151{
8152 for (const auto &g : root->groups)
8153 {
8154 const GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
8155 if (gd)
8156 {
8157 MemberList *ml = gd->getMemberList(MemberListType::DecEnumMembers());
8158 if (ml)
8159 {
8160 MemberDefMutable *md = toMemberDefMutable(ml->find(name));
8161 if (md)
8162 {
8163 addEnumDocs(root,md);
8164 return true;
8165 }
8166 }
8167 }
8168 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
8169 {
8170 warn(root->fileName, root->startLine,
8171 "Found non-existing group '{}' for the command '{}', ignoring command",
8172 g.groupname, Grouping::getGroupPriName( g.pri )
8173 );
8174 }
8175 }
8176
8177 return false;
8178}
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 11441 of file doxygen.cpp.

11442{
11444 msg("Doxygen version {0}\nCopyright Dimitri van Heesch 1997-2025\n\n"
11445 "You can use Doxygen in a number of ways:\n\n"
11446 "1) Use Doxygen to generate a template configuration file*:\n"
11447 " {1} [-s] -g [configName]\n\n"
11448 "2) Use Doxygen to update an old configuration file*:\n"
11449 " {1} [-s] -u [configName]\n\n"
11450 "3) Use Doxygen to generate documentation using an existing "
11451 "configuration file*:\n"
11452 " {1} [configName]\n\n"
11453 "4) Use Doxygen to generate a template file controlling the layout of the\n"
11454 " generated documentation:\n"
11455 " {1} -l [layoutFileName]\n\n"
11456 " In case layoutFileName is omitted DoxygenLayout.xml will be used as filename.\n"
11457 " If - is used for layoutFileName Doxygen will write to standard output.\n\n"
11458 "5) Use Doxygen to generate a template style sheet file for RTF, HTML or Latex.\n"
11459 " RTF: {1} -w rtf styleSheetFile\n"
11460 " HTML: {1} -w html headerFile footerFile styleSheetFile [configFile]\n"
11461 " LaTeX: {1} -w latex headerFile footerFile styleSheetFile [configFile]\n\n"
11462 "6) Use Doxygen to generate a rtf extensions file\n"
11463 " {1} -e rtf extensionsFile\n\n"
11464 " If - is used for extensionsFile Doxygen will write to standard output.\n\n"
11465 "7) Use Doxygen to compare the used configuration file with the template configuration file\n"
11466 " {1} -x [configFile]\n\n"
11467 " Use Doxygen to compare the used configuration file with the template configuration file\n"
11468 " without replacing the environment variables or CMake type replacement variables\n"
11469 " {1} -x_noenv [configFile]\n\n"
11470 "8) Use Doxygen to show a list of built-in emojis.\n"
11471 " {1} -f emoji outputFileName\n\n"
11472 " If - is used for outputFileName Doxygen will write to standard output.\n\n"
11473 "*) If -s is specified the comments of the configuration items in the config file will be omitted.\n"
11474 " If configName is omitted 'Doxyfile' will be used as a default.\n"
11475 " If - is used for configFile Doxygen will write / read the configuration to /from standard output / input.\n\n"
11476 "If -q is used for a Doxygen documentation run, Doxygen will see this as if QUIET=YES has been set.\n\n"
11477 "-v print version string, -V print extended version information\n"
11478 "-h,-? prints usage help information\n"
11479 "{1} -d prints additional usage flags for debugging purposes\n",versionString,name);
11480}

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

Referenced by readConfiguration().

◆ version()

void version ( const bool extended)
static

Definition at line 11411 of file doxygen.cpp.

11412{
11414 DString versionString = getFullVersion();
11415 msg("{}\n",versionString);
11416 if (extended)
11417 {
11418 DString extVers;
11419 if (!extVers.empty()) extVers+= ", ";
11420 extVers += "sqlite3 ";
11421 extVers += sqlite3_libversion();
11422#if USE_LIBCLANG
11423 if (!extVers.empty()) extVers+= ", ";
11424 extVers += "clang support ";
11425 extVers += CLANG_VERSION_STRING;
11426#endif
11427 if (!extVers.empty())
11428 {
11429 if (size_t lastComma = extVers.rfind(','); lastComma != DString::npos)
11430 {
11431 extVers = extVers.replace(lastComma,1," and");
11432 }
11433 msg(" with {}.\n",extVers);
11434 }
11435 }
11436}
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 8512 of file doxygen.cpp.

8513{
8514 // for each member name
8515 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8516 {
8517 // for each member definition
8518 for (const auto &imd : *mn)
8519 {
8520 MemberDefMutable *md = toMemberDefMutable(imd.get());
8521 if (md)
8522 {
8524 }
8525 }
8526 }
8527 // for each member name
8528 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8529 {
8530 // for each member definition
8531 for (const auto &imd : *mn)
8532 {
8533 MemberDefMutable *md = toMemberDefMutable(imd.get());
8534 if (md)
8535 {
8537 }
8538 }
8539 }
8540}
static void correctMemberProperties(MemberDefMutable *md)

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

Referenced by parseInput().

◆ warnUndocumentedNamespaces()

void warnUndocumentedNamespaces ( )
static

Definition at line 5468 of file doxygen.cpp.

5469{
5470 AUTO_TRACE();
5471 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5472 {
5473 if (!nd->hasDocumentation())
5474 {
5475 if ((EntryType::guessSection(nd->getDefFileName()).isHeader() ||
5476 nd->getLanguage() == SrcLangExt::Fortran) && // Fortran doesn't have header files.
5477 !Config_getBool(HIDE_UNDOC_NAMESPACES) // undocumented namespaces are visible
5478 )
5479 {
5480 warn_undoc(nd->getDefFileName(),nd->getDefLine(), "{} {} is not documented.",
5481 nd->getLanguage() == SrcLangExt::Fortran ? "Module" : "Namespace",
5482 nd->name());
5483 }
5484 }
5485 }
5486}

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

Referenced by parseInput().

◆ writeTagFile()

void writeTagFile ( )
static

Definition at line 12199 of file doxygen.cpp.

12200{
12201 DString generateTagFile = Config_getString(GENERATE_TAGFILE);
12202 if (generateTagFile.empty()) return;
12203
12204 std::ofstream f = Portable::openOutputStream(generateTagFile);
12205 if (!f.is_open())
12206 {
12207 err("cannot open tag file {} for writing\n", generateTagFile);
12208 return;
12209 }
12210 TextStream tagFile(&f);
12211 tagFile << "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>\n";
12212 tagFile << "<tagfile doxygen_version=\"" << getDoxygenVersion() << "\"";
12213 std::string gitVersion = getGitVersion();
12214 if (!gitVersion.empty())
12215 {
12216 tagFile << " doxygen_gitid=\"" << gitVersion << "\"";
12217 }
12218 tagFile << ">\n";
12219
12220 // for each file
12221 for (const auto &fn : *Doxygen::inputNameLinkedMap)
12222 {
12223 for (const auto &fd : *fn)
12224 {
12225 if (fd->isLinkableInProject()) fd->writeTagFile(tagFile);
12226 }
12227 }
12228 // for each class
12229 for (const auto &cd : *Doxygen::classLinkedMap)
12230 {
12231 ClassDefMutable *cdm = toClassDefMutable(cd.get());
12232 if (cdm && cdm->isLinkableInProject())
12233 {
12234 cdm->writeTagFile(tagFile);
12235 }
12236 }
12237 // for each concept
12238 for (const auto &cd : *Doxygen::conceptLinkedMap)
12239 {
12240 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
12241 if (cdm && cdm->isLinkableInProject())
12242 {
12243 cdm->writeTagFile(tagFile);
12244 }
12245 }
12246 // for each namespace
12247 for (const auto &nd : *Doxygen::namespaceLinkedMap)
12248 {
12250 if (ndm && nd->isLinkableInProject())
12251 {
12252 ndm->writeTagFile(tagFile);
12253 }
12254 }
12255 // for each group
12256 for (const auto &gd : *Doxygen::groupLinkedMap)
12257 {
12258 if (gd->isLinkableInProject()) gd->writeTagFile(tagFile);
12259 }
12260 // for each module
12261 for (const auto &mod : ModuleManager::instance().modules())
12262 {
12263 if (mod->isLinkableInProject()) mod->writeTagFile(tagFile);
12264 }
12265 // for each page
12266 for (const auto &pd : *Doxygen::pageLinkedMap)
12267 {
12268 if (pd->isLinkableInProject()) pd->writeTagFile(tagFile);
12269 }
12270 // for requirements
12272 // for each directory
12273 for (const auto &dd : *Doxygen::dirLinkedMap)
12274 {
12275 if (dd->isLinkableInProject()) dd->writeTagFile(tagFile);
12276 }
12277 if (Doxygen::mainPage) Doxygen::mainPage->writeTagFile(tagFile);
12278
12279 tagFile << "</tagfile>\n";
12280}
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 2340 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().