Doxygen
Loading...
Searching...
No Matches
doxygen.cpp File Reference
#include <cstdio>
#include <cstdlib>
#include <cerrno>
#include <sys/stat.h>
#include <algorithm>
#include <unordered_map>
#include <memory>
#include <cinttypes>
#include <chrono>
#include <clocale>
#include <locale>
#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 "doxygen.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 QCString &funcDecl, const ArgumentList *al, bool over_load, TypeSpecifier spec)
static void findMember (const Entry *root, const QCString &relates, const QCString &type, const QCString &args, QCString 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)
static DefinitionfindScopeFromQualifiedName (NamespaceDefMutable *startScope, const QCString &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)
template<class DefMutable>
static void addIncludeFile (DefMutable *cd, FileDef *ifd, const Entry *root)
QCString stripTemplateSpecifiers (const QCString &s)
static DefinitionbuildScopeFromQualifiedName (const QCString &name_, SrcLangExt lang, const TagInfo *tagInfo)
std::unique_ptr< ArgumentListgetTemplateArgumentsFromName (const QCString &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 ()
static void buildNamespaceList (const Entry *root)
static NamespaceDeffindUsedNamespace (const LinkedRefMap< NamespaceDef > &unl, const QCString &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 QCString &fileName, const QCString &memName)
static void findUsingDeclImports (const Entry *root)
static void findIncludedUsingDirectives ()
static MemberDefaddVariableToClass (const Entry *root, ClassDefMutable *cd, MemberType mtype, const QCString &type, const QCString &name, const QCString &args, bool fromAnnScope, MemberDef *fromAnnMemb, Protection prot, Relationship related)
static MemberDefaddVariableToFile (const Entry *root, MemberType mtype, const QCString &scope, const QCString &type, const QCString &name, const QCString &args, bool fromAnnScope, MemberDef *fromAnnMemb)
static int findFunctionPtr (const std::string &type, SrcLangExt lang, int *pLength=nullptr)
static bool isVarWithConstructor (const Entry *root)
static int findEndOfTemplate (const QCString &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, QCString const &rname)
static void buildInterfaceAndServiceList (const Entry *root)
static void addMethodToClass (const Entry *root, ClassDefMutable *cd, const QCString &rtype, const QCString &rname, const QCString &rargs, bool isFriend, Protection protection, bool stat, Specifier virt, TypeSpecifier spec, const QCString &relates)
static void addGlobalFunction (const Entry *root, const QCString &rname, const QCString &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 ClassDeffindClassWithinClassContext (Definition *context, ClassDef *cd, const QCString &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 QCString &templSpec, const TemplateNameMap &templateNames, bool isArtificial)
static bool isRecursiveBaseClass (const QCString &scope, const QCString &name)
static int findTemplateSpecializationPosition (const QCString &name)
static bool isClassSection (const Entry *root)
static void findClassEntries (const Entry *root)
static QCString 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 ClassDeffindClassDefinition (FileDef *fd, NamespaceDef *nd, const QCString &scopeName)
static bool isEntryInGroupOfMember (const Entry *root, const MemberDef *md, bool allowNoGroup=false)
static bool findGlobalMember (const Entry *root, const QCString &namespaceName, const QCString &type, const QCString &name, const QCString &tempArg, const QCString &, const QCString &decl, TypeSpecifier)
static bool isSpecialization (const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists)
static bool scopeIsTemplate (const Definition *d)
static QCString 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 QCString &scopeName, const QCString &funcType, const QCString &funcName, const QCString &funcArgs, const QCString &exceptions, const QCString &funcDecl, TypeSpecifier spec)
static void addMemberFunction (const Entry *root, MemberName *mn, const QCString &scopeName, const QCString &namespaceName, const QCString &className, const QCString &funcTyp, const QCString &funcName, const QCString &funcArgs, const QCString &funcTempList, const QCString &exceptions, const QCString &type, const QCString &args, bool isFriend, TypeSpecifier spec, const QCString &relates, const QCString &funcDecl, bool overloaded, bool isFunc)
static void addMemberSpecialization (const Entry *root, MemberName *mn, ClassDefMutable *cd, const QCString &funcType, const QCString &funcName, const QCString &funcArgs, const QCString &funcDecl, const QCString &exceptions, TypeSpecifier spec)
static void addOverloaded (const Entry *root, MemberName *mn, const QCString &funcType, const QCString &funcName, const QCString &funcArgs, const QCString &funcDecl, const QCString &exceptions, TypeSpecifier spec)
static void insertMemberAlias (Definition *outerScope, const MemberDef *md)
static void filterMemberDocumentation (const Entry *root, const QCString &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 QCString &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 determineScopeForAnonymousMembers ()
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 QCString &configFile, bool shortList, bool updateOnly=FALSE)
static void compareDoxyfile (Config::CompareMode diffList)
static void readTagFile (const std::shared_ptr< Entry > &root, const QCString &tagLine)
static void copyLatexStyleSheet ()
static void copyStyleSheet ()
static void copyLogo (const QCString &outputOption, bool toIndex)
static void copyIcon (const QCString &outputOption, bool toIndex)
static void copyExtraFiles (const StringVector &files, const QCString &filesOption, const QCString &outputOption, bool toIndex)
static void generateDiskNames ()
static std::unique_ptr< OutlineParserInterfacegetParserForFile (const QCString &fn)
static std::shared_ptr< EntryparseFile (OutlineParserInterface &parser, FileDef *fd, const QCString &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 QCString &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 QCString &name, const QCString &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 QCString createOutputDirectory (const QCString &baseDirName, const QCString &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 OutputListg_outputList = nullptr
static StringSet g_usingDeclarations
static bool g_successfulRun = FALSE
static bool g_dumpSymbolMap = FALSE
static QCString 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 134 of file doxygen.cpp.

Enumeration Type Documentation

◆ FindBaseClassRelation_Mode

Enumerator
TemplateInstances 
DocumentedOnly 
Undocumented 

Definition at line 286 of file doxygen.cpp.

287{
291};
@ Undocumented
Definition doxygen.cpp:290
@ TemplateInstances
Definition doxygen.cpp:288
@ DocumentedOnly
Definition doxygen.cpp:289

Function Documentation

◆ addClassAndNestedClasses()

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

Definition at line 9050 of file doxygen.cpp.

9051{
9052 list.push_back(cd);
9053 for (const auto &innerCdi : cd->getClasses())
9054 {
9055 ClassDefMutable *innerCd = toClassDefMutable(innerCdi);
9056 if (innerCd)
9057 {
9058 AUTO_TRACE("innerCd={} isLinkable={} isImplicitTemplateInstance={} protectLevelVisible={} embeddedInOuterScope={}",
9059 innerCd->name(),innerCd->isLinkableInProject(),innerCd->isImplicitTemplateInstance(),protectionLevelVisible(innerCd->protection()),
9060 innerCd->isEmbeddedInOuterScope());
9061 }
9062 if (innerCd && innerCd->isLinkableInProject() && !innerCd->isImplicitTemplateInstance() &&
9063 protectionLevelVisible(innerCd->protection()) &&
9064 !innerCd->isEmbeddedInOuterScope()
9065 )
9066 {
9067 list.push_back(innerCd);
9068 addClassAndNestedClasses(list,innerCd);
9069 }
9070 }
9071}
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 bool isLinkableInProject() const =0
virtual const QCString & name() const =0
ClassDefMutable * toClassDefMutable(Definition *d)
#define AUTO_TRACE(...)
Definition docnode.cpp:48
static void addClassAndNestedClasses(std::vector< ClassDefMutable * > &list, ClassDefMutable *cd)
Definition doxygen.cpp:9050
bool protectionLevelVisible(Protection prot)
Definition util.cpp:5959

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

940{
941 AUTO_TRACE("name={}",root->name);
942 FileDef *fd = root->fileDef();
943
944 QCString scName;
945 if (root->parent()->section.isScope())
946 {
947 scName=root->parent()->name;
948 }
949 // name without parent's scope
950 QCString fullName = root->name;
951
952 // strip off any template parameters (but not those for specializations)
953 int idx=fullName.find('>');
954 if (idx!=-1 && root->lang==SrcLangExt::CSharp) // mangle A<S,T>::N as A-2-g::N
955 {
956 fullName = mangleCSharpGenericName(fullName.left(idx+1))+fullName.mid(idx+1);
957 }
958 fullName=stripTemplateSpecifiersFromScope(fullName);
959
960 // name with scope (if not present already)
961 QCString qualifiedName = fullName;
962 if (!scName.isEmpty() && !leftScopeMatch(scName,fullName))
963 {
964 qualifiedName.prepend(scName+"::");
965 }
966
967 // see if we already found the class before
968 ClassDefMutable *cd = getClassMutable(qualifiedName);
969
970 AUTO_TRACE_ADD("Found class with name '{}', qualifiedName '{}'", cd ? cd->name() : root->name, qualifiedName);
971
972 if (cd)
973 {
974 fullName=cd->name();
975 AUTO_TRACE_ADD("Existing class '{}'",cd->name());
976 //if (cd->templateArguments()==0)
977 //{
978 // //printf("existing ClassDef tempArgList=%p specScope=%s\n",root->tArgList,qPrint(root->scopeSpec));
979 // cd->setTemplateArguments(tArgList);
980 //}
981
982 cd->setDocumentation(root->doc,root->docFile,root->docLine);
983 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
984 root->commandOverrides.apply_collaborationGraph([&](bool b ) { cd->overrideCollaborationGraph(b); });
985 root->commandOverrides.apply_inheritanceGraph ([&](CLASS_GRAPH_t gt) { cd->overrideInheritanceGraph(gt); });
986
987 if (!root->spec.isForwardDecl() && cd->isForwardDeclared())
988 {
989 cd->setDefFile(root->fileName,root->startLine,root->startColumn);
990 if (root->bodyLine!=-1)
991 {
992 cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
993 cd->setBodyDef(fd);
994 }
995 }
996
997 if (cd->templateArguments().empty() || (cd->isForwardDeclared() && !root->spec.isForwardDecl()))
998 {
999 // this happens if a template class declared with @class is found
1000 // before the actual definition or if a forward declaration has different template
1001 // parameter names.
1002 std::unique_ptr<ArgumentList> tArgList = getTemplateArgumentsFromName(cd->name(),root->tArgLists);
1003 if (tArgList)
1004 {
1005 cd->setTemplateArguments(*tArgList);
1006 }
1007 }
1008 if (cd->requiresClause().isEmpty() && !root->req.isEmpty())
1009 {
1010 cd->setRequiresClause(root->req);
1011 }
1012
1014
1015 cd->setMetaData(root->metaData);
1016 }
1017 else // new class
1018 {
1020
1021 QCString className;
1022 QCString namespaceName;
1023 extractNamespaceName(fullName,className,namespaceName);
1024
1025 AUTO_TRACE_ADD("New class: fullname '{}' namespace '{}' name='{}' brief='{}' docs='{}'",
1026 fullName, namespaceName, className, Trace::trunc(root->brief), Trace::trunc(root->doc));
1027
1028 QCString tagName;
1029 QCString refFileName;
1030 const TagInfo *tagInfo = root->tagInfo();
1031 if (tagInfo)
1032 {
1033 tagName = tagInfo->tagName;
1034 refFileName = tagInfo->fileName;
1035 if (fullName.find("::")!=-1)
1036 // symbols imported via tag files may come without the parent scope,
1037 // so we artificially create it here
1038 {
1039 buildScopeFromQualifiedName(fullName,root->lang,tagInfo);
1040 }
1041 }
1042 std::unique_ptr<ArgumentList> tArgList;
1043 int i=0;
1044 if ((root->lang==SrcLangExt::CSharp || root->lang==SrcLangExt::Java) &&
1045 (i=fullName.find('<'))!=-1)
1046 {
1047 // a Java/C# generic class looks like a C++ specialization, so we need to split the
1048 // name and template arguments here
1049 tArgList = stringToArgumentList(root->lang,fullName.mid(i));
1050 if (i!=-1 && 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
1051 // A -> A
1052 // A<T> -> A-1-g
1053 // A<T,S> -> A-2-g
1054 {
1055 fullName=mangleCSharpGenericName(fullName);
1056 }
1057 else
1058 {
1059 fullName=fullName.left(i);
1060 }
1061 }
1062 else
1063 {
1064 tArgList = getTemplateArgumentsFromName(fullName,root->tArgLists);
1065 }
1066 // add class to the list
1067 cd = toClassDefMutable(
1068 Doxygen::classLinkedMap->add(fullName,
1069 createClassDef(tagInfo?tagName:root->fileName,root->startLine,root->startColumn,
1070 fullName,sec,tagName,refFileName,TRUE,root->spec.isEnum()) ));
1071 if (cd)
1072 {
1073 AUTO_TRACE_ADD("New class '{}' type={} #tArgLists={} tagInfo={} hidden={} artificial={}",
1074 fullName,cd->compoundTypeString(),root->tArgLists.size(),
1075 fmt::ptr(tagInfo),root->hidden,root->artificial);
1076 cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1077 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1078 cd->setLanguage(root->lang);
1079 cd->setId(root->id);
1080 cd->setHidden(root->hidden);
1081 cd->setArtificial(root->artificial);
1082 cd->setClassSpecifier(root->spec);
1083 if (root->lang==SrcLangExt::CSharp && !root->args.isEmpty())
1084 {
1086 }
1087 cd->addQualifiers(root->qualifiers);
1088 cd->setTypeConstraints(root->typeConstr);
1089 root->commandOverrides.apply_collaborationGraph([&](bool b ) { cd->overrideCollaborationGraph(b); });
1090 root->commandOverrides.apply_inheritanceGraph ([&](CLASS_GRAPH_t gt) { cd->overrideInheritanceGraph(gt); });
1091
1092 if (tArgList)
1093 {
1094 cd->setTemplateArguments(*tArgList);
1095 }
1096 cd->setRequiresClause(root->req);
1097 cd->setProtection(root->protection);
1098 cd->setIsStatic(root->isStatic);
1099
1100 // file definition containing the class cd
1101 cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1102 cd->setBodyDef(fd);
1103
1104 cd->setMetaData(root->metaData);
1105
1106 cd->insertUsedFile(fd);
1107 }
1108 else
1109 {
1110 AUTO_TRACE_ADD("Class {} not added, already exists as alias", fullName);
1111 }
1112 }
1113
1114 if (cd)
1115 {
1117 if (!root->subGrouping) cd->setSubGrouping(FALSE);
1118 if (!root->spec.isForwardDecl())
1119 {
1120 if (cd->hasDocumentation())
1121 {
1122 addIncludeFile(cd,fd,root);
1123 }
1124 if (fd && root->section.isCompound())
1125 {
1126 AUTO_TRACE_ADD("Inserting class {} in file {} (root->fileName='{}')", cd->name(), fd->name(), root->fileName);
1127 cd->setFileDef(fd);
1128 fd->insertClass(cd);
1129 }
1130 }
1131 addClassToGroups(root,cd);
1133 cd->setRefItems(root->sli);
1134 cd->setRequirementReferences(root->rqli);
1135 }
1136}
bool empty() const
Definition arguments.h:99
virtual const ArgumentList & templateArguments() const =0
Returns the template arguments of this class.
virtual QCString 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:109
virtual QCString requiresClause() const =0
virtual void overrideCollaborationGraph(bool e)=0
virtual void setPrimaryConstructorParams(const ArgumentList &list)=0
virtual void setMetaData(const QCString &md)=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 setRequiresClause(const QCString &req)=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 setIsStatic(bool b)=0
virtual void setSubGrouping(bool enabled)=0
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 QCString &d, const QCString &docFile, int docLine, bool stripWhiteSpace=TRUE)=0
virtual void setDefFile(const QCString &df, int defLine, int 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 setId(const QCString &name)=0
virtual void setBodyDef(const FileDef *fd)=0
virtual void setBriefDescription(const QCString &b, const QCString &briefFile, int briefLine)=0
virtual void setRequirementReferences(const RequirementRefs &rqli)=0
virtual void setRefItems(const RefItemVector &sli)=0
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:95
bool subGrouping
automatically group class members?
Definition entry.h:189
RequirementRefs rqli
references to requirements
Definition entry.h:228
QCString metaData
Slice metadata.
Definition entry.h:235
int docLine
line number at which the documentation was found
Definition entry.h:202
ArgumentList typeConstr
where clause (C#) for type constraints
Definition entry.h:216
int endBodyLine
line number where the definition ends
Definition entry.h:219
const TagInfo * tagInfo() const
Definition entry.h:178
QCString id
libclang id
Definition entry.h:233
ArgumentLists tArgLists
template argument declarations
Definition entry.h:196
SrcLangExt lang
programming language in which this entry was found
Definition entry.h:229
Entry * parent() const
Definition entry.h:135
int startColumn
start column of entry in the source
Definition entry.h:226
std::vector< const SectionInfo * > anchors
list of anchors defined in this entry
Definition entry.h:223
QCString fileName
file this entry was extracted from
Definition entry.h:224
QCString args
member argument string
Definition entry.h:193
CommandOverrides commandOverrides
store info for commands whose default can be overridden
Definition entry.h:191
int startLine
start line of entry in the source
Definition entry.h:225
QCString req
C++20 requires clause.
Definition entry.h:236
QCString name
member name
Definition entry.h:175
EntryType section
entry type (see Sections);
Definition entry.h:173
QCString briefFile
file in which the brief desc. was found
Definition entry.h:206
int bodyLine
line number of the body in the source
Definition entry.h:217
std::vector< std::string > qualifiers
qualifiers specified with the qualifier command
Definition entry.h:237
QCString doc
documentation block (partly parsed)
Definition entry.h:201
RefItemVector sli
special lists (test/todo/bug/deprecated/..) this entry is in
Definition entry.h:227
QCString docFile
file in which the documentation was found
Definition entry.h:203
Protection protection
class protection
Definition entry.h:181
bool artificial
Artificially introduced item.
Definition entry.h:231
bool hidden
does this represent an entity that is hidden from the output
Definition entry.h:230
QCString brief
brief description (doc block)
Definition entry.h:204
int briefLine
line number at which the brief desc. was found
Definition entry.h:205
FileDef * fileDef() const
Definition entry.h:170
bool isStatic
static ?
Definition entry.h:186
TypeSpecifier spec
class/member specifiers
Definition entry.h:183
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:99
virtual void insertClass(ClassDef *cd)=0
static ModuleManager & instance()
void addClassToModule(const Entry *root, ClassDef *cd)
This is an alternative implementation of QCString.
Definition qcstring.h:103
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
QCString & prepend(const char *s)
Definition qcstring.h:426
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:245
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:167
QCString left(size_t len) const
Definition qcstring.h:233
std::unique_ptr< ClassDef > createClassDef(const QCString &fileName, int startLine, int startColumn, const QCString &name, ClassDef::CompoundType ct, const QCString &ref, const QCString &fName, bool isSymbol, bool isJavaEnum)
Factory method to create a new ClassDef object.
Definition classdef.cpp:560
ClassDefMutable * getClassMutable(const QCString &key)
Definition classdef.h:470
std::unique_ptr< ArgumentList > stringToArgumentList(SrcLangExt lang, const QCString &argsString, QCString *extraTypeChars=nullptr)
Definition defargs.l:826
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:49
static void addIncludeFile(DefMutable *cd, FileDef *ifd, const Entry *root)
Definition doxygen.cpp:589
static ClassDef::CompoundType convertToCompoundType(EntryType section, TypeSpecifier specifier)
Definition doxygen.cpp:897
std::unique_ptr< ArgumentList > getTemplateArgumentsFromName(const QCString &name, const ArgumentLists &tArgLists)
Definition doxygen.cpp:867
static Definition * buildScopeFromQualifiedName(const QCString &name_, SrcLangExt lang, const TagInfo *tagInfo)
Definition doxygen.cpp:713
void addClassToGroups(const Entry *root, ClassDef *cd)
QCString trunc(const QCString &s, size_t numChars=15)
Definition trace.h:56
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
This struct is used to capture the tag file information for an Entry.
Definition entry.h:104
QCString fileName
Definition entry.h:106
QCString tagName
Definition entry.h:105
bool leftScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:881
void extractNamespaceName(const QCString &scopeName, QCString &className, QCString &namespaceName, bool allowEmptyClass)
Definition util.cpp:3718
QCString mangleCSharpGenericName(const QCString &name)
Definition util.cpp:6935
QCString stripTemplateSpecifiersFromScope(const QCString &fullName, bool parentOnly, QCString *pLastScopeStripped, QCString scopeName, bool allowArtificial)
Definition util.cpp:4552

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(), Entry::endBodyLine, extractNamespaceName(), FALSE, Entry::fileDef(), Entry::fileName, TagInfo::fileName, QCString::find(), getClassMutable(), getTemplateArgumentsFromName(), Definition::hasDocumentation(), Entry::hidden, Entry::id, FileDef::insertClass(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), EntryType::isCompound(), QCString::isEmpty(), ClassDef::isForwardDeclared(), EntryType::isScope(), Entry::isStatic, Entry::lang, QCString::left(), leftScopeMatch(), mangleCSharpGenericName(), Entry::metaData, QCString::mid(), Definition::name(), Entry::name, ClassDefMutable::overrideCollaborationGraph(), ClassDefMutable::overrideInheritanceGraph(), Entry::parent(), QCString::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(), TRUE, Trace::trunc(), and Entry::typeConstr.

Referenced by buildClassDocList(), and buildClassList().

◆ addConceptToContext()

void addConceptToContext ( const Entry * root)
static

Definition at line 1165 of file doxygen.cpp.

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

9402{
9403 md->setDocumentation(root->doc,root->docFile,root->docLine);
9404 md->setDocsForDefinition(!root->proto);
9405 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9406 if (md->inbodyDocumentation().isEmpty())
9407 {
9409 }
9410 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
9411 {
9412 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
9413 md->setBodyDef(root->fileDef());
9414 }
9416 md->setMaxInitLines(root->initLines);
9418 md->setRefItems(root->sli);
9419 md->setRequirementReferences(root->rqli);
9420 md->addQualifiers(root->qualifiers);
9421 if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
9422 addMemberToGroups(root,md);
9424}
virtual int getStartBodyLine() const =0
virtual QCString inbodyDocumentation() const =0
virtual void setInbodyDocumentation(const QCString &d, const QCString &docFile, int docLine)=0
bool proto
prototype ?
Definition entry.h:188
QCString inbodyDocs
documentation inside the body of a function
Definition entry.h:207
int inbodyLine
line number at which the body doc was found
Definition entry.h:208
int initLines
define/variable initializer lines to show
Definition entry.h:185
QCString inbodyFile
file in which the body doc was found
Definition entry.h:209
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:1960
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, Entry::endBodyLine, Entry::fileDef(), Definition::getStartBodyLine(), Entry::inbodyDocs, Definition::inbodyDocumentation(), Entry::inbodyFile, Entry::inbodyLine, Entry::initLines, ModuleManager::instance(), QCString::isEmpty(), 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 7840 of file doxygen.cpp.

7841{
7842 AUTO_TRACE();
7843 // documentation outside a compound overrides the documentation inside it
7844 {
7845 md->setDocumentation(root->doc,root->docFile,root->docLine);
7846 md->setDocsForDefinition(!root->proto);
7847 }
7848
7849 // brief descriptions inside a compound override the documentation
7850 // outside it
7851 {
7852 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7853 }
7854
7855 if (md->inbodyDocumentation().isEmpty() || !root->parent()->name.isEmpty())
7856 {
7858 }
7859
7860 if (root->mGrpId!=-1 && md->getMemberGroupId()==-1)
7861 {
7862 md->setMemberGroupId(root->mGrpId);
7863 }
7864
7866 md->setRefItems(root->sli);
7867 md->setRequirementReferences(root->rqli);
7868
7869 const GroupDef *gd=md->getGroupDef();
7870 if (gd==nullptr && !root->groups.empty()) // member not grouped but out-of-line documentation is
7871 {
7872 addMemberToGroups(root,md);
7873 }
7875}
std::vector< Grouping > groups
list of groups this entry belongs to
Definition entry.h:222
A model of a group of symbols.
Definition groupdef.h:52
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, MemberDef::getGroupDef(), MemberDef::getMemberGroupId(), Entry::groups, Entry::inbodyDocs, Definition::inbodyDocumentation(), Entry::inbodyFile, Entry::inbodyLine, ModuleManager::instance(), QCString::isEmpty(), 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 7590 of file doxygen.cpp.

7591{
7592 if (root->section.isEnum())
7593 // non anonymous enumeration
7594 {
7595 AUTO_TRACE("name={}",root->name);
7596 ClassDefMutable *cd = nullptr;
7597 FileDef *fd = nullptr;
7598 NamespaceDefMutable *nd = nullptr;
7599 MemberNameLinkedMap *mnsd = nullptr;
7600 bool isGlobal = false;
7601 bool isRelated = false;
7602 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
7603
7604 QCString name;
7605 QCString scope;
7606
7607 int i = root->name.findRev("::");
7608 if (i!=-1) // scope is specified
7609 {
7610 scope=root->name.left(i); // extract scope
7611 if (root->lang==SrcLangExt::CSharp)
7612 {
7613 scope = mangleCSharpGenericName(scope);
7614 }
7615 name=root->name.right(root->name.length()-i-2); // extract name
7616 if ((cd=getClassMutable(scope))==nullptr)
7617 {
7619 }
7620 }
7621 else // no scope, check the scope in which the docs where found
7622 {
7623 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7624 {
7625 scope=root->parent()->name;
7626 if (root->lang==SrcLangExt::CSharp)
7627 {
7628 scope = mangleCSharpGenericName(scope);
7629 }
7630 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7631 }
7632 name=root->name;
7633 }
7634
7635 if (!root->relates.isEmpty())
7636 { // related member, prefix user specified scope
7637 isRelated=TRUE;
7638 if (getClassMutable(root->relates)==nullptr && !scope.isEmpty())
7639 scope=mergeScopes(scope,root->relates);
7640 else
7641 scope=root->relates;
7642 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7643 }
7644
7645 if (cd && !name.isEmpty()) // found a enum inside a compound
7646 {
7647 //printf("Enum in class '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
7648 fd=nullptr;
7650 isGlobal=false;
7651 }
7652 else if (nd && !nd->isAnonymous()) // found enum inside namespace
7653 {
7654 //printf("Enum in namespace '%s'::'%s'\n",qPrint(nd->name()),qPrint(name));
7656 isGlobal=true;
7657 }
7658 else // found a global enum
7659 {
7660 fd=root->fileDef();
7661 //printf("Enum in file '%s': '%s'\n",qPrint(fd->name()),qPrint(name));
7663 isGlobal=true;
7664 }
7665
7666 if (!name.isEmpty())
7667 {
7668 //printf("** name=%s\n",qPrint(name));
7669 MemberName *mn = mnsd->find(name); // for all members with this name
7670 if (mn)
7671 {
7672 struct EnumValueInfo
7673 {
7674 EnumValueInfo(const QCString &n,std::unique_ptr<MemberDef> &&md) :
7675 name(n), member(std::move(md)) {}
7676 QCString name;
7677 std::unique_ptr<MemberDef> member;
7678 };
7679 std::vector< EnumValueInfo > extraMembers;
7680 // for each enum in this list
7681 for (const auto &imd : *mn)
7682 {
7683 MemberDefMutable *md = toMemberDefMutable(imd.get());
7684 // use raw pointer in this loop, since we modify mn and can then invalidate mdp.
7685 if (md && md->isEnumerate() && !root->children().empty())
7686 {
7687 AUTO_TRACE_ADD("enum {} with {} children",md->name(),root->children().size());
7688 for (const auto &e : root->children())
7689 {
7690 SrcLangExt sle = root->lang;
7691 bool isJavaLike = sle==SrcLangExt::CSharp || sle==SrcLangExt::Java || sle==SrcLangExt::XML;
7692 if ( isJavaLike || root->spec.isStrong())
7693 {
7694 if (sle == SrcLangExt::Cpp && e->section.isDefine()) continue;
7695 // Unlike classic C/C++ enums, for C++11, C# & Java enum
7696 // values are only visible inside the enum scope, so we must create
7697 // them here and only add them to the enum
7698 //printf("md->qualifiedName()=%s e->name=%s tagInfo=%p name=%s\n",
7699 // qPrint(md->qualifiedName()),qPrint(e->name),(void*)e->tagInfo(),qPrint(e->name));
7700 QCString qualifiedName = root->name;
7701 i = qualifiedName.findRev("::");
7702 if (i!=-1 && sle==SrcLangExt::CSharp)
7703 {
7704 qualifiedName = mangleCSharpGenericName(qualifiedName.left(i))+qualifiedName.mid(i);
7705 }
7706 if (isJavaLike)
7707 {
7708 qualifiedName=substitute(qualifiedName,"::",".");
7709 }
7710 if (md->qualifiedName()==qualifiedName) // enum value scope matches that of the enum
7711 {
7712 QCString fileName = e->fileName;
7713 if (fileName.isEmpty() && e->tagInfo())
7714 {
7715 fileName = e->tagInfo()->tagName;
7716 }
7717 AUTO_TRACE_ADD("strong enum value {}",e->name);
7718 auto fmd = createMemberDef(
7719 fileName,e->startLine,e->startColumn,
7720 e->type,e->name,e->args,QCString(),
7721 e->protection, Specifier::Normal,e->isStatic,Relationship::Member,
7722 MemberType::EnumValue,ArgumentList(),ArgumentList(),e->metaData);
7723 auto fmmd = toMemberDefMutable(fmd.get());
7724 NamespaceDef *mnd = md->getNamespaceDef();
7725 if (md->getClassDef())
7726 fmmd->setMemberClass(md->getClassDef());
7727 else if (mnd && (mnd->isLinkable() || mnd->isAnonymous()))
7728 fmmd->setNamespace(mnd);
7729 else if (md->getFileDef())
7730 fmmd->setFileDef(md->getFileDef());
7731 fmmd->setOuterScope(md->getOuterScope());
7732 fmmd->setTagInfo(e->tagInfo());
7733 fmmd->setLanguage(e->lang);
7734 fmmd->setBodySegment(e->startLine,e->bodyLine,e->endBodyLine);
7735 fmmd->setBodyDef(e->fileDef());
7736 fmmd->setId(e->id);
7737 fmmd->setDocumentation(e->doc,e->docFile,e->docLine);
7738 fmmd->setBriefDescription(e->brief,e->briefFile,e->briefLine);
7739 fmmd->addSectionsToDefinition(e->anchors);
7740 fmmd->setInitializer(e->initializer.str());
7741 fmmd->setMaxInitLines(e->initLines);
7742 fmmd->setMemberGroupId(e->mGrpId);
7743 fmmd->setExplicitExternal(e->explicitExternal,fileName,e->startLine,e->startColumn);
7744 fmmd->setRefItems(e->sli);
7745 fmmd->setRequirementReferences(e->rqli);
7746 fmmd->setAnchor();
7747 md->insertEnumField(fmd.get());
7748 fmmd->setEnumScope(md,TRUE);
7749 extraMembers.emplace_back(e->name,std::move(fmd));
7750 }
7751 }
7752 else
7753 {
7754 AUTO_TRACE_ADD("enum value {}",e->name);
7755 //printf("e->name=%s isRelated=%d\n",qPrint(e->name),isRelated);
7756 MemberName *fmn=nullptr;
7757 MemberNameLinkedMap *emnsd = isRelated ? Doxygen::functionNameLinkedMap : mnsd;
7758 if (!e->name.isEmpty() && (fmn=emnsd->find(e->name)))
7759 // get list of members with the same name as the field
7760 {
7761 for (const auto &ifmd : *fmn)
7762 {
7763 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
7764 if (fmd && fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope
7765 {
7766 //printf("found enum value with same name %s in scope %s\n",
7767 // qPrint(fmd->name()),qPrint(fmd->getOuterScope()->name()));
7768 if (nd && !nd->isAnonymous())
7769 {
7770 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7771 {
7772 const NamespaceDef *fnd=fmd->getNamespaceDef();
7773 if (fnd==nd) // enum value is inside a namespace
7774 {
7775 md->insertEnumField(fmd);
7776 fmd->setEnumScope(md);
7777 }
7778 }
7779 }
7780 else if (isGlobal)
7781 {
7782 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7783 {
7784 const FileDef *ffd=fmd->getFileDef();
7785 if (ffd==fd && ffd==md->getFileDef()) // enum value has file scope
7786 {
7787 md->insertEnumField(fmd);
7788 fmd->setEnumScope(md);
7789 }
7790 }
7791 }
7792 else if (isRelated && cd) // reparent enum value to
7793 // match the enum's scope
7794 {
7795 md->insertEnumField(fmd); // add field def to list
7796 fmd->setEnumScope(md); // cross ref with enum name
7797 fmd->setEnumClassScope(cd); // cross ref with enum name
7798 fmd->setOuterScope(cd);
7799 fmd->makeRelated();
7800 cd->insertMember(fmd);
7801 }
7802 else
7803 {
7804 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7805 {
7806 const ClassDef *fcd=fmd->getClassDef();
7807 if (fcd==cd) // enum value is inside a class
7808 {
7809 //printf("Inserting enum field %s in enum scope %s\n",
7810 // qPrint(fmd->name()),qPrint(md->name()));
7811 md->insertEnumField(fmd); // add field def to list
7812 fmd->setEnumScope(md); // cross ref with enum name
7813 }
7814 }
7815 }
7816 }
7817 }
7818 }
7819 }
7820 }
7821 }
7822 }
7823 // move the newly added members into mn
7824 for (auto &e : extraMembers)
7825 {
7826 MemberName *emn=mnsd->add(e.name);
7827 emn->push_back(std::move(e.member));
7828 }
7829 }
7830 }
7831 }
7832 else
7833 {
7834 for (const auto &e : root->children()) addEnumValuesToEnums(e.get());
7835 }
7836}
This class represents an function or template argument list.
Definition arguments.h:65
A abstract class representing of a compound symbol.
Definition classdef.h:104
virtual void insertMember(MemberDef *)=0
virtual bool isLinkable() const =0
virtual bool isAnonymous() const =0
virtual QCString qualifiedName() const =0
virtual Definition * getOuterScope() const =0
static MemberNameLinkedMap * functionNameLinkedMap
Definition doxygen.h:112
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:111
QCString relates
related class (doc block)
Definition entry.h:210
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:54
Ordered dictionary of MemberName objects.
Definition membername.h:63
An abstract interface of a namespace symbol.
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:170
QCString right(size_t len) const
Definition qcstring.h:238
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:96
static void addEnumValuesToEnums(const Entry *root)
Definition doxygen.cpp:7590
MemberDefMutable * toMemberDefMutable(Definition *d)
std::unique_ptr< MemberDef > createMemberDef(const QCString &defFileName, int defLine, int defColumn, const QCString &type, const QCString &name, const QCString &args, const QCString &excp, Protection prot, Specifier virt, bool stat, Relationship related, MemberType t, const ArgumentList &tal, const ArgumentList &al, const QCString &metaData)
Factory method to create a new instance of a MemberDef.
NamespaceDefMutable * toNamespaceDefMutable(Definition *d)
NamespaceDefMutable * getResolvedNamespaceMutable(const QCString &key)
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:571
SrcLangExt
Definition types.h:207
QCString mergeScopes(const QCString &leftScope, const QCString &rightScope)
Definition util.cpp:4619

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

Referenced by addEnumValuesToEnums(), and parseInput().

◆ addGlobalFunction()

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

Definition at line 3682 of file doxygen.cpp.

3683{
3684 QCString scope = sc;
3685
3686 // new global function
3688 auto md = createMemberDef(
3689 root->fileName,root->startLine,root->startColumn,
3690 root->type,name,root->args,root->exception,
3691 root->protection,root->virt,root->isStatic,Relationship::Member,
3692 MemberType::Function,
3693 !root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
3694 root->argList,root->metaData);
3695 auto mmd = toMemberDefMutable(md.get());
3696 mmd->setTagInfo(root->tagInfo());
3697 mmd->setLanguage(root->lang);
3698 mmd->setId(root->id);
3699 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3700 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3701 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3702 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
3703 mmd->setDocsForDefinition(!root->proto);
3704 mmd->setTypeConstraints(root->typeConstr);
3705 //md->setBody(root->body);
3706 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3707 FileDef *fd=root->fileDef();
3708 mmd->setBodyDef(fd);
3709 mmd->addSectionsToDefinition(root->anchors);
3710 mmd->setMemberSpecifiers(root->spec);
3711 mmd->setVhdlSpecifiers(root->vhdlSpec);
3712 mmd->setMemberGroupId(root->mGrpId);
3713 mmd->setRequiresClause(root->req);
3714 mmd->setExplicitExternal(root->explicitExternal,root->fileName,root->startLine,root->startColumn);
3715
3716 NamespaceDefMutable *nd = nullptr;
3717 // see if the function is inside a namespace that was not part of
3718 // the name already (in that case nd should be non-zero already)
3719 if (root->parent()->section.isNamespace())
3720 {
3721 //QCString nscope=removeAnonymousScopes(root->parent()->name);
3722 QCString nscope=root->parent()->name;
3723 if (!nscope.isEmpty())
3724 {
3725 nd = getResolvedNamespaceMutable(nscope);
3726 }
3727 }
3728 else if (root->parent()->section.isGroupDoc() && !scope.isEmpty())
3729 {
3731 }
3732
3733 if (!scope.isEmpty())
3734 {
3736 if (sep!="::")
3737 {
3738 scope = substitute(scope,"::",sep);
3739 }
3740 scope+=sep;
3741 }
3742
3743 if (Config_getBool(HIDE_SCOPE_NAMES) || root->lang==SrcLangExt::Python) scope = "";
3744 QCString def;
3745 //QCString optArgs = root->argList.empty() ? QCString() : root->args;
3746 if (!root->type.isEmpty())
3747 {
3748 def=root->type+" "+scope+name; //+optArgs;
3749 }
3750 else
3751 {
3752 def=scope+name; //+optArgs;
3753 }
3754 AUTO_TRACE("new non-member function type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
3755 root->type,scope,rname,root->args,root->proto,def);
3756 mmd->setDefinition(def);
3758 mmd->addQualifiers(root->qualifiers);
3759
3760 mmd->setRefItems(root->sli);
3761 mmd->setRequirementReferences(root->rqli);
3762 if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
3763 {
3764 // add member to namespace
3765 mmd->setNamespace(nd);
3766 nd->insertMember(md.get());
3767 }
3768 if (fd)
3769 {
3770 // add member to the file (we do this even if we have already
3771 // inserted it into the namespace)
3772 mmd->setFileDef(fd);
3773 fd->insertMember(md.get());
3774 }
3775
3776 addMemberToGroups(root,md.get());
3778 if (root->relatesType == RelatesType::Simple) // if this is a relatesalso command,
3779 // allow find Member to pick it up
3780 {
3781 root->markAsProcessed(); // Otherwise we have finished with this entry.
3782 }
3783
3784 // add member to the list of file members
3786 mn->push_back(std::move(md));
3787}
VhdlSpecifier vhdlSpec
VHDL specifiers.
Definition entry.h:184
void markAsProcessed() const
Definition entry.h:168
bool explicitExternal
explicitly defined as external?
Definition entry.h:187
RelatesType relatesType
how relates is handled
Definition entry.h:211
QCString type
member type
Definition entry.h:174
QCString exception
throw specification
Definition entry.h:215
ArgumentList argList
member arguments as a list
Definition entry.h:195
Specifier virt
virtualness of the entry
Definition entry.h:192
virtual void insertMember(MemberDef *md)=0
virtual void insertMember(MemberDef *md)=0
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:597
#define Config_getBool(name)
Definition config.h:33
QCString removeRedundantWhiteSpace(const QCString &s)
Definition util.cpp:567
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
Definition util.cpp:5919

References addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, Entry::args, QCString::at(), AUTO_TRACE, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, 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(), QCString::isEmpty(), 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 DefMutable>
void addIncludeFile ( DefMutable * cd,
FileDef * ifd,
const Entry * root )
static

Definition at line 589 of file doxygen.cpp.

590{
591 if (
592 (!root->doc.stripWhiteSpace().isEmpty() ||
593 !root->brief.stripWhiteSpace().isEmpty() ||
594 Config_getBool(EXTRACT_ALL)
595 ) && root->protection!=Protection::Private
596 )
597 {
598 //printf(">>>>>> includeFile=%s\n",qPrint(root->includeFile));
599
600 bool local=Config_getBool(FORCE_LOCAL_INCLUDES);
601 QCString includeFile = root->includeFile;
602 if (!includeFile.isEmpty() && includeFile.at(0)=='"')
603 {
604 local = TRUE;
605 includeFile=includeFile.mid(1,includeFile.length()-2);
606 }
607 else if (!includeFile.isEmpty() && includeFile.at(0)=='<')
608 {
609 local = FALSE;
610 includeFile=includeFile.mid(1,includeFile.length()-2);
611 }
612
613 bool ambig = false;
614 FileDef *fd=nullptr;
615 // see if we need to include a verbatim copy of the header file
616 //printf("root->includeFile=%s\n",qPrint(root->includeFile));
617 if (!includeFile.isEmpty() &&
618 (fd=findFileDef(Doxygen::inputNameLinkedMap,includeFile,ambig))==nullptr
619 )
620 { // explicit request
621 QCString text;
622 text.sprintf("the name '%s' supplied as "
623 "the argument of the \\class, \\struct, \\union, or \\include command ",
624 qPrint(includeFile)
625 );
626 if (ambig) // name is ambiguous
627 {
628 text+="matches the following input files:\n";
630 text+="\n";
631 text+="Please use a more specific name by "
632 "including a (larger) part of the path!";
633 }
634 else // name is not an input file
635 {
636 text+="is not an input file";
637 }
638 warn(root->fileName,root->startLine, "{}", text);
639 }
640 else if (includeFile.isEmpty() && ifd &&
641 // see if the file extension makes sense
642 guessSection(ifd->name()).isHeader())
643 { // implicit assumption
644 fd=ifd;
645 }
646
647 // if a file is found, we mark it as a source file.
648 if (fd)
649 {
650 QCString iName = !root->includeName.isEmpty() ?
651 root->includeName : includeFile;
652 if (!iName.isEmpty()) // user specified include file
653 {
654 if (iName.at(0)=='<') local=FALSE; // explicit override
655 else if (iName.at(0)=='"') local=TRUE;
656 if (iName.at(0)=='"' || iName.at(0)=='<')
657 {
658 iName=iName.mid(1,iName.length()-2); // strip quotes or brackets
659 }
660 if (iName.isEmpty())
661 {
662 iName=fd->name();
663 }
664 }
665 else if (!Config_getList(STRIP_FROM_INC_PATH).empty())
666 {
668 }
669 else // use name of the file containing the class definition
670 {
671 iName=fd->name();
672 }
673 if (fd->generateSourceFile()) // generate code for header
674 {
675 cd->setIncludeFile(fd,iName,local,!root->includeName.isEmpty());
676 }
677 else // put #include in the class documentation without link
678 {
679 cd->setIncludeFile(nullptr,iName,local,TRUE);
680 }
681 }
682 }
683}
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:104
QCString includeName
include name (3 arg of \class)
Definition entry.h:200
QCString includeFile
include file (2 arg of \class, must be unique)
Definition entry.h:199
virtual bool generateSourceFile() const =0
virtual QCString absFilePath() const =0
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:264
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
#define Config_getList(name)
Definition config.h:38
#define warn(file, line, fmt,...)
Definition message.h:97
const char * qPrint(const char *s)
Definition qcstring.h:691
QCString stripFromIncludePath(const QCString &path)
Definition util.cpp:329
QCString showFileDefMatches(const FileNameLinkedMap *fnMap, const QCString &n)
Definition util.cpp:3039
EntryType guessSection(const QCString &name)
Definition util.cpp:338
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:2904

References FileDef::absFilePath(), QCString::at(), Entry::brief, Config_getBool, Config_getList, Entry::doc, FALSE, Entry::fileName, findFileDef(), FileDef::generateSourceFile(), guessSection(), Entry::includeFile, Entry::includeName, Doxygen::inputNameLinkedMap, QCString::isEmpty(), QCString::length(), QCString::mid(), Definition::name(), Entry::protection, qPrint(), showFileDefMatches(), QCString::sprintf(), Entry::startLine, stripFromIncludePath(), QCString::stripWhiteSpace(), TRUE, and warn.

Referenced by addClassToContext(), and addConceptToContext().

◆ addInterfaceOrServiceToServiceOrSingleton()

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

Definition at line 3431 of file doxygen.cpp.

3435{
3436 FileDef *fd = root->fileDef();
3437 enum MemberType type = root->section.isExportedInterface() ? MemberType::Interface : MemberType::Service;
3438 QCString fileName = root->fileName;
3439 if (fileName.isEmpty() && root->tagInfo())
3440 {
3441 fileName = root->tagInfo()->tagName;
3442 }
3443 auto md = createMemberDef(
3444 fileName, root->startLine, root->startColumn, root->type, rname,
3445 "", "", root->protection, root->virt, root->isStatic, Relationship::Member,
3446 type, ArgumentList(), root->argList, root->metaData);
3447 auto mmd = toMemberDefMutable(md.get());
3448 mmd->setTagInfo(root->tagInfo());
3449 mmd->setMemberClass(cd);
3450 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3451 mmd->setDocsForDefinition(false);
3452 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3453 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3454 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3455 mmd->setMemberSpecifiers(root->spec);
3456 mmd->setVhdlSpecifiers(root->vhdlSpec);
3457 mmd->setMemberGroupId(root->mGrpId);
3458 mmd->setTypeConstraints(root->typeConstr);
3459 mmd->setLanguage(root->lang);
3460 mmd->setBodyDef(fd);
3461 mmd->setFileDef(fd);
3462 mmd->addSectionsToDefinition(root->anchors);
3463 QCString const def = root->type + " " + rname;
3464 mmd->setDefinition(def);
3466 mmd->addQualifiers(root->qualifiers);
3467
3468 AUTO_TRACE("Interface member: fileName='{}' type='{}' name='{}' mtype='{}' prot={} virt={} state={} proto={} def='{}'",
3469 fileName,root->type,rname,type,root->protection,root->virt,root->isStatic,root->proto,def);
3470
3471 // add member to the class cd
3472 cd->insertMember(md.get());
3473 // also add the member as a "base" (to get nicer diagrams)
3474 // "optional" interface/service get Protected which turns into dashed line
3475 BaseInfo base(rname,
3476 root->spec.isOptional() ? Protection::Protected : Protection::Public, Specifier::Normal);
3477 TemplateNameMap templateNames;
3478 findClassRelation(root,cd,cd,&base,templateNames,DocumentedOnly,true) ||
3479 findClassRelation(root,cd,cd,&base,templateNames,Undocumented,true);
3480 // add file to list of used files
3481 cd->insertUsedFile(fd);
3482
3483 addMemberToGroups(root,md.get());
3485 root->markAsProcessed();
3486 mmd->setRefItems(root->sli);
3487 mmd->setRequirementReferences(root->rqli);
3488
3489 // add member to the global list of all members
3490 MemberName *mn = Doxygen::memberNameLinkedMap->add(rname);
3491 mn->push_back(std::move(md));
3492}
std::map< std::string, int > TemplateNameMap
Definition classdef.h:93
static bool findClassRelation(const Entry *root, Definition *context, ClassDefMutable *cd, const BaseInfo *bi, const TemplateNameMap &templateNames, FindBaseClassRelation_Mode mode, bool isArtificial)
Definition doxygen.cpp:4753
This class stores information about an inheritance relation.
Definition entry.h:91
MemberType
Definition types.h:569

References 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, Entry::endBodyLine, Entry::fileDef(), Entry::fileName, findClassRelation(), Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), QCString::isEmpty(), 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 5417 of file doxygen.cpp.

5418{
5419 AUTO_TRACE();
5420 applyToAllDefinitions([](auto* obj) { obj->addListReferences(); });
5421}
static void applyToAllDefinitions(Func func)
Definition doxygen.cpp:5352

References applyToAllDefinitions(), and AUTO_TRACE.

Referenced by parseInput().

◆ addLocalObjCMethod()

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

Definition at line 5996 of file doxygen.cpp.

6001{
6002 AUTO_TRACE();
6003 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
6004 ClassDefMutable *cd=nullptr;
6005 if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClassMutable(scopeName)))
6006 {
6007 AUTO_TRACE_ADD("Local objective C method '{}' scopeName='{}'",root->name,scopeName);
6008 auto md = createMemberDef(
6009 root->fileName,root->startLine,root->startColumn,
6010 funcType,funcName,funcArgs,exceptions,
6011 root->protection,root->virt,root->isStatic,Relationship::Member,
6012 MemberType::Function,ArgumentList(),root->argList,root->metaData);
6013 auto mmd = toMemberDefMutable(md.get());
6014 mmd->setTagInfo(root->tagInfo());
6015 mmd->setLanguage(root->lang);
6016 mmd->setId(root->id);
6017 mmd->makeImplementationDetail();
6018 mmd->setMemberClass(cd);
6019 mmd->setDefinition(funcDecl);
6021 mmd->addQualifiers(root->qualifiers);
6022 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6023 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6024 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6025 mmd->setDocsForDefinition(!root->proto);
6026 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6027 mmd->addSectionsToDefinition(root->anchors);
6028 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6029 FileDef *fd=root->fileDef();
6030 mmd->setBodyDef(fd);
6031 mmd->setMemberSpecifiers(spec);
6032 mmd->setVhdlSpecifiers(root->vhdlSpec);
6033 mmd->setMemberGroupId(root->mGrpId);
6034 cd->insertMember(md.get());
6035 cd->insertUsedFile(fd);
6036 mmd->setRefItems(root->sli);
6037 mmd->setRequirementReferences(root->rqli);
6038
6040 mn->push_back(std::move(md));
6041 }
6042 else
6043 {
6044 // local objective C method found for class without interface
6045 }
6046}

References 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 QCString & funcDecl,
const ArgumentList * al,
bool over_load,
TypeSpecifier spec )
static

Definition at line 5440 of file doxygen.cpp.

5446{
5447 if (md==nullptr) return;
5448 AUTO_TRACE("scope='{}' name='{}' args='{}' funcDecl='{}' mSpec={}",
5449 root->parent()->name,md->name(),md->argsString(),funcDecl,spec);
5450 if (!root->section.isDoc()) // @fn or @var does not need to specify the complete definition, so don't overwrite it
5451 {
5452 QCString fDecl=funcDecl;
5453 // strip extern specifier
5454 fDecl.stripPrefix("extern ");
5455 md->setDefinition(fDecl);
5456 }
5458 md->addQualifiers(root->qualifiers);
5460 const NamespaceDef *nd=md->getNamespaceDef();
5461 QCString fullName;
5462 if (cd)
5463 fullName = cd->name();
5464 else if (nd)
5465 fullName = nd->name();
5466
5467 if (!fullName.isEmpty()) fullName+="::";
5468 fullName+=md->name();
5469 FileDef *rfd=root->fileDef();
5470
5471 // TODO determine scope based on root not md
5472 Definition *rscope = md->getOuterScope();
5473
5474 const ArgumentList &mdAl = md->argumentList();
5475 if (al)
5476 {
5477 ArgumentList mergedAl = *al;
5478 //printf("merging arguments (1) docs=%d\n",root->doc.isEmpty());
5479 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedAl,!root->doc.isEmpty());
5480 }
5481 else
5482 {
5483 if (
5484 matchArguments2( md->getOuterScope(), md->getFileDef(),md->typeString(),const_cast<ArgumentList*>(&mdAl),
5485 rscope,rfd,root->type,&root->argList,
5486 TRUE, root->lang
5487 )
5488 )
5489 {
5490 //printf("merging arguments (2)\n");
5491 ArgumentList mergedArgList = root->argList;
5492 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.isEmpty());
5493 }
5494 }
5495 if (over_load) // the \overload keyword was used
5496 {
5498 if (!root->doc.isEmpty())
5499 {
5500 doc+="<p>";
5501 doc+=root->doc;
5502 }
5503 md->setDocumentation(doc,root->docFile,root->docLine);
5505 md->setDocsForDefinition(!root->proto);
5506 }
5507 else
5508 {
5509 //printf("overwrite!\n");
5510 md->setDocumentation(root->doc,root->docFile,root->docLine);
5511 md->setDocsForDefinition(!root->proto);
5512
5513 //printf("overwrite!\n");
5514 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
5515
5516 if (
5517 (md->inbodyDocumentation().isEmpty() ||
5518 !root->parent()->name.isEmpty()
5519 ) && !root->inbodyDocs.isEmpty()
5520 )
5521 {
5523 }
5524 }
5525
5526 //printf("initializer: '%s'(isEmpty=%d) '%s'(isEmpty=%d)\n",
5527 // qPrint(md->initializer()),md->initializer().isEmpty(),
5528 // qPrint(root->initializer),root->initializer.isEmpty()
5529 // );
5530 std::string rootInit = root->initializer.str();
5531 if (md->initializer().isEmpty() && !rootInit.empty())
5532 {
5533 //printf("setInitializer\n");
5534 md->setInitializer(rootInit);
5535 }
5536 if (md->requiresClause().isEmpty() && !root->req.isEmpty())
5537 {
5538 md->setRequiresClause(root->req);
5539 }
5540
5541 md->setMaxInitLines(root->initLines);
5542
5543 if (rfd)
5544 {
5545 if ((md->getStartBodyLine()==-1 && root->bodyLine!=-1)
5546 )
5547 {
5548 //printf("Setting new body segment [%d,%d]\n",root->bodyLine,root->endBodyLine);
5549 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
5550 md->setBodyDef(rfd);
5551 }
5552
5553 md->setRefItems(root->sli);
5554 md->setRequirementReferences(root->rqli);
5555 }
5556
5558 md->addQualifiers(root->qualifiers);
5559
5560 md->mergeMemberSpecifiers(spec);
5562 addMemberToGroups(root,md);
5564 if (cd) cd->insertUsedFile(rfd);
5565 //printf("root->mGrpId=%d\n",root->mGrpId);
5566 if (root->mGrpId!=-1)
5567 {
5568 if (md->getMemberGroupId()!=-1)
5569 {
5570 if (md->getMemberGroupId()!=root->mGrpId)
5571 {
5572 warn(root->fileName,root->startLine,
5573 "member {} belongs to two different groups. The second one found here will be ignored.",
5574 md->name()
5575 );
5576 }
5577 }
5578 else // set group id
5579 {
5580 //printf("setMemberGroupId=%d md=%s\n",root->mGrpId,qPrint(md->name()));
5581 md->setMemberGroupId(root->mGrpId);
5582 }
5583 }
5584 md->addQualifiers(root->qualifiers);
5585}
constexpr bool isDoc() const noexcept
Definition types.h:867
virtual QCString typeString() const =0
virtual QCString requiresClause() const =0
virtual const ArgumentList & argumentList() const =0
virtual QCString argsString() const =0
virtual const QCString & initializer() const =0
virtual void setDefinition(const QCString &d)=0
virtual ClassDefMutable * getClassDefMutable()=0
virtual void setRequiresClause(const QCString &req)=0
virtual void setInitializer(const QCString &i)=0
virtual void mergeMemberSpecifiers(TypeSpecifier s)=0
bool stripPrefix(const QCString &prefix)
Definition qcstring.h:217
bool matchArguments2(const Definition *srcScope, const FileDef *srcFileScope, const QCString &srcReturnType, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const QCString &dstReturnType, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
Definition util.cpp:2031
void mergeArguments(ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
Definition util.cpp:2131
QCString getOverloadDocs()
Definition util.cpp:4114

References 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, Entry::endBodyLine, Entry::fileDef(), Entry::fileName, MemberDefMutable::getClassDefMutable(), MemberDef::getFileDef(), MemberDef::getMemberGroupId(), MemberDef::getNamespaceDef(), Definition::getOuterScope(), getOverloadDocs(), Definition::getStartBodyLine(), Entry::inbodyDocs, Definition::inbodyDocumentation(), Entry::inbodyFile, Entry::inbodyLine, Entry::initializer, MemberDef::initializer(), Entry::initLines, ClassDefMutable::insertUsedFile(), ModuleManager::instance(), EntryType::isDoc(), QCString::isEmpty(), 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(), QCString::stripPrefix(), TRUE, Entry::type, MemberDef::typeString(), and warn.

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

◆ addMemberFunction()

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

Definition at line 6050 of file doxygen.cpp.

6068{
6069 AUTO_TRACE();
6070 QCString funcType = funcTyp;
6071 int count=0;
6072 int noMatchCount=0;
6073 bool memFound=FALSE;
6074 for (const auto &imd : *mn)
6075 {
6076 MemberDefMutable *md = toMemberDefMutable(imd.get());
6077 if (md==nullptr) continue;
6079 if (cd==nullptr) continue;
6080 //AUTO_TRACE_ADD("member definition found, scope needed='{}' scope='{}' args='{}' fileName='{}'",
6081 // scopeName, cd->name(), md->argsString(), root->fileName);
6082 FileDef *fd=root->fileDef();
6083 NamespaceDef *nd=nullptr;
6084 if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName);
6085
6086 //printf("scopeName %s->%s\n",qPrint(scopeName),
6087 // qPrint(stripTemplateSpecifiersFromScope(scopeName,FALSE)));
6088
6089 // if the member we are searching for is an enum value that is part of
6090 // a "strong" enum, we need to look into the fields of the enum for a match
6091 int enumNamePos=0;
6092 if (md->isEnumValue() && (enumNamePos=className.findRev("::"))!=-1)
6093 {
6094 QCString enumName = className.mid(enumNamePos+2);
6095 QCString fullScope = className.left(enumNamePos);
6096 if (!namespaceName.isEmpty()) fullScope.prepend(namespaceName+"::");
6097 if (fullScope==cd->name())
6098 {
6099 MemberName *enumMn=Doxygen::memberNameLinkedMap->find(enumName);
6100 //printf("enumMn(%s)=%p\n",qPrint(className),(void*)enumMn);
6101 if (enumMn)
6102 {
6103 for (const auto &emd : *enumMn)
6104 {
6105 memFound = emd->isStrong() && md->getEnumScope()==emd.get();
6106 if (memFound)
6107 {
6108 addMemberDocs(root,md,funcDecl,nullptr,overloaded,spec);
6109 count++;
6110 }
6111 if (memFound) break;
6112 }
6113 }
6114 }
6115 }
6116 if (memFound) break;
6117
6118 const ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
6119 if (tcd==nullptr && cd && stripAnonymousNamespaceScope(cd->name())==scopeName)
6120 {
6121 // don't be fooled by anonymous scopes
6122 tcd=cd;
6123 }
6124 //printf("Looking for %s inside nd=%s result=%s cd=%s\n",
6125 // qPrint(scopeName),nd?qPrint(nd->name()):"<none>",tcd?qPrint(tcd->name()):"",qPrint(cd->name()));
6126
6127 if (cd && tcd==cd) // member's classes match
6128 {
6129 AUTO_TRACE_ADD("class definition '{}' found",cd->name());
6130
6131 // get the template parameter lists found at the member declaration
6132 ArgumentLists declTemplArgs = cd->getTemplateParameterLists();
6133 const ArgumentList &templAl = md->templateArguments();
6134 if (!templAl.empty())
6135 {
6136 declTemplArgs.push_back(templAl);
6137 }
6138
6139 // get the template parameter lists found at the member definition
6140 const ArgumentLists &defTemplArgs = root->tArgLists;
6141 //printf("defTemplArgs=%p\n",defTemplArgs);
6142
6143 // do we replace the decl argument lists with the def argument lists?
6144 bool substDone=false;
6145 ArgumentList argList;
6146
6147 /* substitute the occurrences of class template names in the
6148 * argument list before matching
6149 */
6150 const ArgumentList &mdAl = md->argumentList();
6151 if (declTemplArgs.size()>0 && declTemplArgs.size()==defTemplArgs.size())
6152 {
6153 /* the function definition has template arguments
6154 * and the class definition also has template arguments, so
6155 * we must substitute the template names of the class by that
6156 * of the function definition before matching.
6157 */
6158 substituteTemplatesInArgList(declTemplArgs,defTemplArgs,mdAl,argList);
6159
6160 substDone=TRUE;
6161 }
6162 else /* no template arguments, compare argument lists directly */
6163 {
6164 argList = mdAl;
6165 }
6166
6167 bool matching=
6168 md->isVariable() || md->isTypedef() || // needed for function pointers
6170 md->getClassDef(),md->getFileDef(),md->typeString(),&argList,
6171 cd,fd,root->type,&root->argList,
6172 TRUE,root->lang);
6173
6174 AUTO_TRACE_ADD("matching '{}'<=>'{}' className='{}' namespaceName='{}' result={}",
6175 argListToString(argList,TRUE),argListToString(root->argList,TRUE),className,namespaceName,matching);
6176
6177 if (md->getLanguage()==SrcLangExt::ObjC && md->isVariable() && root->section.isFunction())
6178 {
6179 matching = FALSE; // don't match methods and attributes with the same name
6180 }
6181
6182 // for template member we also need to check the return type
6183 if (!md->templateArguments().empty() && !root->tArgLists.empty())
6184 {
6185 QCString memType = md->typeString();
6186 memType.stripPrefix("static "); // see bug700696
6188 className+"::",""); // see bug700693 & bug732594
6190 className+"::",""); // see bug758900
6191 if (memType=="auto" && !argList.trailingReturnType().isEmpty())
6192 {
6193 memType = argList.trailingReturnType();
6194 memType.stripPrefix(" -> ");
6195 }
6196 if (funcType=="auto" && !root->argList.trailingReturnType().isEmpty())
6197 {
6198 funcType = root->argList.trailingReturnType();
6199 funcType.stripPrefix(" -> ");
6201 substDone=true;
6202 }
6203 AUTO_TRACE_ADD("Comparing return types '{}'<->'{}' #args {}<->{}",
6204 memType,funcType,md->templateArguments().size(),root->tArgLists.back().size());
6205 if (md->templateArguments().size()!=root->tArgLists.back().size() || memType!=funcType)
6206 {
6207 //printf(" ---> no matching\n");
6208 matching = FALSE;
6209 }
6210 }
6211 else if (defTemplArgs.size()>declTemplArgs.size())
6212 {
6213 AUTO_TRACE_ADD("Different number of template arguments {} vs {}",defTemplArgs.size(),declTemplArgs.size());
6214 // avoid matching a non-template function in a template class against a
6215 // template function with the same name and parameters, see issue #10184
6216 substDone = false;
6217 matching = false;
6218 }
6219 bool rootIsUserDoc = root->section.isMemberDoc();
6220 bool classIsTemplate = scopeIsTemplate(md->getClassDef());
6221 bool mdIsTemplate = md->templateArguments().hasParameters();
6222 bool classOrMdIsTemplate = mdIsTemplate || classIsTemplate;
6223 bool rootIsTemplate = !root->tArgLists.empty();
6224 //printf("classIsTemplate=%d mdIsTemplate=%d rootIsTemplate=%d\n",classIsTemplate,mdIsTemplate,rootIsTemplate);
6225 if (!rootIsUserDoc && // don't check out-of-line @fn references, see bug722457
6226 (mdIsTemplate || rootIsTemplate) && // either md or root is a template
6227 ((classOrMdIsTemplate && !rootIsTemplate) || (!classOrMdIsTemplate && rootIsTemplate))
6228 )
6229 {
6230 // Method with template return type does not match method without return type
6231 // even if the parameters are the same. See also bug709052
6232 AUTO_TRACE_ADD("Comparing return types: template v.s. non-template");
6233 matching = FALSE;
6234 }
6235
6236 AUTO_TRACE_ADD("Match results of matchArguments2='{}' substDone='{}'",matching,substDone);
6237
6238 if (substDone) // found a new argument list
6239 {
6240 if (matching) // replace member's argument list
6241 {
6243 md->moveArgumentList(std::make_unique<ArgumentList>(argList));
6244 }
6245 else // no match
6246 {
6247 if (!funcTempList.isEmpty() &&
6248 isSpecialization(declTemplArgs,defTemplArgs))
6249 {
6250 // check if we are dealing with a partial template
6251 // specialization. In this case we add it to the class
6252 // even though the member arguments do not match.
6253
6254 addMethodToClass(root,cd,type,md->name(),args,isFriend,
6255 md->protection(),md->isStatic(),md->virtualness(),spec,relates);
6256 return;
6257 }
6258 }
6259 }
6260 if (matching)
6261 {
6262 addMemberDocs(root,md,funcDecl,nullptr,overloaded,spec);
6263 count++;
6264 memFound=TRUE;
6265 }
6266 }
6267 else if (cd && cd!=tcd) // we did find a class with the same name as cd
6268 // but in a different namespace
6269 {
6270 noMatchCount++;
6271 }
6272
6273 if (memFound) break;
6274 }
6275 if (count==0 && root->parent() && root->parent()->section.isObjcImpl())
6276 {
6277 addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec);
6278 return;
6279 }
6280 if (count==0 && !(isFriend && funcType=="class"))
6281 {
6282 int candidates=0;
6283 const ClassDef *ecd = nullptr, *ucd = nullptr;
6284 MemberDef *emd = nullptr, *umd = nullptr;
6285 //printf("Assume template class\n");
6286 for (const auto &md : *mn)
6287 {
6288 MemberDef *cmd=md.get();
6290 ClassDefMutable *ccd=cdmdm ? cdmdm->getClassDefMutable() : nullptr;
6291 //printf("ccd->name()==%s className=%s\n",qPrint(ccd->name()),qPrint(className));
6292 if (ccd!=nullptr && rightScopeMatch(ccd->name(),className))
6293 {
6294 const ArgumentList &templAl = md->templateArguments();
6295 if (!root->tArgLists.empty() && !templAl.empty() &&
6296 root->tArgLists.back().size()<=templAl.size())
6297 {
6298 AUTO_TRACE_ADD("add template specialization");
6299 addMethodToClass(root,ccd,type,md->name(),args,isFriend,
6300 root->protection,root->isStatic,root->virt,spec,relates);
6301 return;
6302 }
6305 { // exact argument list match -> remember
6306 ucd = ecd = ccd;
6307 umd = emd = cmd;
6308 AUTO_TRACE_ADD("new candidate className='{}' scope='{}' args='{}': exact match",
6309 className,ccd->name(),md->argsString());
6310 }
6311 else // arguments do not match, but member name and scope do -> remember
6312 {
6313 ucd = ccd;
6314 umd = cmd;
6315 AUTO_TRACE_ADD("new candidate className='{}' scope='{}' args='{}': no match",
6316 className,ccd->name(),md->argsString());
6317 }
6318 candidates++;
6319 }
6320 }
6321 bool strictProtoMatching = Config_getBool(STRICT_PROTO_MATCHING);
6322 if (!strictProtoMatching)
6323 {
6324 if (candidates==1 && ucd && umd)
6325 {
6326 // we didn't find an actual match on argument lists, but there is only 1 member with this
6327 // name in the same scope, so that has to be the one.
6328 addMemberDocs(root,toMemberDefMutable(umd),funcDecl,nullptr,overloaded,spec);
6329 return;
6330 }
6331 else if (candidates>1 && ecd && emd)
6332 {
6333 // we didn't find a unique match using type resolution,
6334 // but one of the matches has the exact same signature so
6335 // we take that one.
6336 addMemberDocs(root,toMemberDefMutable(emd),funcDecl,nullptr,overloaded,spec);
6337 return;
6338 }
6339 }
6340
6341 QCString warnMsg = "no ";
6342 if (noMatchCount>1) warnMsg+="uniquely ";
6343 warnMsg+="matching class member found for \n";
6344
6345 for (const ArgumentList &al : root->tArgLists)
6346 {
6347 warnMsg+=" template ";
6348 warnMsg+=tempArgListToString(al,root->lang);
6349 warnMsg+='\n';
6350 }
6351
6352 QCString fullFuncDecl=funcDecl;
6353 if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE);
6354
6355 warnMsg+=" ";
6356 warnMsg+=fullFuncDecl;
6357
6358 if (candidates>0 || noMatchCount>=1)
6359 {
6360 warnMsg+="\nPossible candidates:";
6361
6362 NamespaceDef *nd=nullptr;
6363 if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName);
6364 FileDef *fd=root->fileDef();
6365
6366 for (const auto &md : *mn)
6367 {
6368 const ClassDef *cd=md->getClassDef();
6369 const ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
6370 if (tcd==nullptr && cd && stripAnonymousNamespaceScope(cd->name())==scopeName)
6371 {
6372 // don't be fooled by anonymous scopes
6373 tcd=cd;
6374 }
6375 if (cd!=nullptr && (rightScopeMatch(cd->name(),className) || (cd!=tcd)))
6376 {
6377 warnMsg+='\n';
6378 const ArgumentList &templAl = md->templateArguments();
6379 warnMsg+=" '";
6380 if (templAl.hasParameters())
6381 {
6382 warnMsg+="template ";
6383 warnMsg+=tempArgListToString(templAl,root->lang);
6384 warnMsg+='\n';
6385 warnMsg+=" ";
6386 }
6387 if (!md->typeString().isEmpty())
6388 {
6389 warnMsg+=md->typeString();
6390 warnMsg+=' ';
6391 }
6393 if (!qScope.isEmpty())
6394 warnMsg+=qScope+"::"+md->name();
6395 warnMsg+=md->argsString();
6396 warnMsg+="' " + warn_line(md->getDefFileName(),md->getDefLine());
6397 }
6398 }
6399 }
6400 warn(root->fileName,root->startLine,"{}",warnMsg);
6401 }
6402}
std::vector< ArgumentList > ArgumentLists
Definition arguments.h:147
void setTrailingReturnType(const QCString &s)
Definition arguments.cpp:36
bool hasParameters() const
Definition arguments.h:76
QCString trailingReturnType() const
Definition arguments.h:114
size_t size() const
Definition arguments.h:100
virtual ArgumentLists getTemplateParameterLists() const =0
Returns the template parameter lists that form the template declaration of this class.
virtual QCString 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 QCString getDefFileName() const =0
virtual int getDefLine() const =0
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
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:5838
static void substituteTemplatesInArgList(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const ArgumentList &src, ArgumentList &dst)
Definition doxygen.cpp:5952
static void addLocalObjCMethod(const Entry *root, const QCString &scopeName, const QCString &funcType, const QCString &funcName, const QCString &funcArgs, const QCString &exceptions, const QCString &funcDecl, TypeSpecifier spec)
Definition doxygen.cpp:5996
static void addMemberDocs(const Entry *root, MemberDefMutable *md, const QCString &funcDecl, const ArgumentList *al, bool over_load, TypeSpecifier spec)
Definition doxygen.cpp:5440
static bool scopeIsTemplate(const Definition *d)
Definition doxygen.cpp:5854
static void addMethodToClass(const Entry *root, ClassDefMutable *cd, const QCString &rtype, const QCString &rname, const QCString &rargs, bool isFriend, Protection protection, bool stat, Specifier virt, TypeSpecifier spec, const QCString &relates)
Definition doxygen.cpp:3546
static const ClassDef * findClassDefinition(FileDef *fd, NamespaceDef *nd, const QCString &scopeName)
Definition doxygen.cpp:5591
QCString warn_line(const QCString &file, int line)
Definition message.cpp:214
NamespaceDef * getResolvedNamespace(const QCString &name)
QCString stripAnonymousNamespaceScope(const QCString &s)
Definition util.cpp:230
QCString tempArgListToString(const ArgumentList &al, SrcLangExt lang, bool includeDefault)
Definition util.cpp:1299
QCString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:1254
bool rightScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:870
QCString replaceAnonymousScopes(const QCString &s, const QCString &replacement)
Definition util.cpp:218

References addLocalObjCMethod(), addMemberDocs(), addMethodToClass(), Entry::argList, argListToString(), MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, Config_getBool, ArgumentList::empty(), FALSE, Entry::fileDef(), Entry::fileName, findClassDefinition(), QCString::findRev(), MemberDef::getClassDef(), MemberDefMutable::getClassDefMutable(), MemberDef::getEnumScope(), MemberDef::getFileDef(), Definition::getLanguage(), getResolvedNamespace(), ClassDef::getTemplateParameterLists(), ArgumentList::hasParameters(), QCString::isEmpty(), MemberDef::isEnumValue(), isSpecialization(), Entry::isStatic, MemberDef::isStatic(), MemberDef::isTypedef(), MemberDef::isVariable(), Entry::lang, QCString::left(), matchArguments2(), Doxygen::memberNameLinkedMap, QCString::mid(), MemberDefMutable::moveArgumentList(), Definition::name(), Entry::parent(), QCString::prepend(), Entry::protection, MemberDef::protection(), ClassDef::qualifiedNameWithTemplateParameters(), replaceAnonymousScopes(), rightScopeMatch(), scopeIsTemplate(), Entry::section, MemberDefMutable::setDefinitionTemplateParameterLists(), ArgumentList::setTrailingReturnType(), ArgumentList::size(), Entry::startLine, stripAnonymousNamespaceScope(), QCString::stripPrefix(), stripTemplateSpecifiersFromScope(), substitute(), substituteTemplatesInArgList(), Entry::tArgLists, tempArgListToString(), MemberDef::templateArguments(), toMemberDefMutable(), ArgumentList::trailingReturnType(), TRUE, 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 QCString & funcType,
const QCString & funcName,
const QCString & funcArgs,
const QCString & funcDecl,
const QCString & exceptions,
TypeSpecifier spec )
static

Definition at line 6406 of file doxygen.cpp.

6416{
6417 AUTO_TRACE("funcType={} funcName={} funcArgs={} funcDecl={} spec={}",funcType,funcName,funcArgs,funcDecl,spec);
6418 MemberDef *declMd=nullptr;
6419 for (const auto &md : *mn)
6420 {
6421 if (md->getClassDef()==cd)
6422 {
6423 // TODO: we should probably also check for matching arguments
6424 declMd = md.get();
6425 break;
6426 }
6427 }
6428 MemberType mtype=MemberType::Function;
6429 ArgumentList tArgList;
6430 // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6431 auto md = createMemberDef(
6432 root->fileName,root->startLine,root->startColumn,
6433 funcType,funcName,funcArgs,exceptions,
6434 declMd ? declMd->protection() : root->protection,
6435 root->virt,root->isStatic,Relationship::Member,
6436 mtype,tArgList,root->argList,root->metaData);
6437 auto mmd = toMemberDefMutable(md.get());
6438 //printf("new specialized member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6439 mmd->setTagInfo(root->tagInfo());
6440 mmd->setLanguage(root->lang);
6441 mmd->setId(root->id);
6442 mmd->setMemberClass(cd);
6443 mmd->setTemplateSpecialization(TRUE);
6444 mmd->setTypeConstraints(root->typeConstr);
6445 mmd->setDefinition(funcDecl);
6447 mmd->addQualifiers(root->qualifiers);
6448 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6449 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6450 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6451 mmd->setDocsForDefinition(!root->proto);
6452 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6453 mmd->addSectionsToDefinition(root->anchors);
6454 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6455 FileDef *fd=root->fileDef();
6456 mmd->setBodyDef(fd);
6457 mmd->setMemberSpecifiers(spec);
6458 mmd->setVhdlSpecifiers(root->vhdlSpec);
6459 mmd->setMemberGroupId(root->mGrpId);
6460 cd->insertMember(md.get());
6461 mmd->setRefItems(root->sli);
6462 mmd->setRequirementReferences(root->rqli);
6463
6464 mn->push_back(std::move(md));
6465}

References 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(), TRUE, Entry::typeConstr, Entry::vhdlSpec, and Entry::virt.

Referenced by findMember().

◆ addMembersToIndex()

void addMembersToIndex ( )
static

Definition at line 8035 of file doxygen.cpp.

8036{
8037 auto &index = Index::instance();
8038 // for each class member name
8039 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8040 {
8041 // for each member definition
8042 for (const auto &md : *mn)
8043 {
8044 index.addClassMemberNameToIndex(md.get());
8045 if (md->getModuleDef())
8046 {
8047 index.addModuleMemberNameToIndex(md.get());
8048 }
8049 }
8050 }
8051 // for each file/namespace function name
8052 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8053 {
8054 // for each member definition
8055 for (const auto &md : *mn)
8056 {
8057 if (md->getNamespaceDef())
8058 {
8059 index.addNamespaceMemberNameToIndex(md.get());
8060 }
8061 else
8062 {
8063 index.addFileMemberNameToIndex(md.get());
8064 }
8065 if (md->getModuleDef())
8066 {
8067 index.addModuleMemberNameToIndex(md.get());
8068 }
8069 }
8070 }
8071
8072 index.sortMemberIndexLists();
8073}
static Index & instance()
Definition index.cpp:108

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

Referenced by addMembersToIndex(), parseInput(), writeClassTree(), writeDirHierarchy(), and writeDirTreeNode().

◆ addMembersToMemberGroup()

void addMembersToMemberGroup ( )
static

Definition at line 9180 of file doxygen.cpp.

9181{
9182 // for each class
9183 for (const auto &cd : *Doxygen::classLinkedMap)
9184 {
9185 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9186 if (cdm)
9187 {
9189 }
9190 }
9191 // for each file
9192 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9193 {
9194 for (const auto &fd : *fn)
9195 {
9196 fd->addMembersToMemberGroup();
9197 }
9198 }
9199 // for each namespace
9200 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9201 {
9203 if (ndm)
9204 {
9206 }
9207 }
9208 // for each group
9209 for (const auto &gd : *Doxygen::groupLinkedMap)
9210 {
9211 gd->addMembersToMemberGroup();
9212 }
9214}
virtual void addMembersToMemberGroup()=0
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:114
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 QCString & rtype,
const QCString & rname,
const QCString & rargs,
bool isFriend,
Protection protection,
bool stat,
Specifier virt,
TypeSpecifier spec,
const QCString & relates )
static

Definition at line 3546 of file doxygen.cpp.

3552{
3553 FileDef *fd=root->fileDef();
3554
3555 QCString type = rtype;
3556 QCString args = rargs;
3557
3559 name.stripPrefix("::");
3560
3561 MemberType mtype = MemberType::Function;
3562 if (isFriend) mtype=MemberType::Friend;
3563 else if (root->mtype==MethodTypes::Signal) mtype=MemberType::Signal;
3564 else if (root->mtype==MethodTypes::Slot) mtype=MemberType::Slot;
3565 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType::DCOP;
3566
3567 // strip redundant template specifier for constructors
3568 int i = -1;
3569 int j = -1;
3570 if ((fd==nullptr || fd->getLanguage()==SrcLangExt::Cpp) &&
3571 !name.startsWith("operator ") && // not operator
3572 (i=name.find('<'))!=-1 && // containing <
3573 (j=name.find('>'))!=-1 && // or >
3574 (j!=i+2 || name.at(i+1)!='=') // but not the C++20 spaceship operator <=>
3575 )
3576 {
3577 name=name.left(i);
3578 }
3579
3580 QCString fileName = root->fileName;
3581 if (fileName.isEmpty() && root->tagInfo())
3582 {
3583 fileName = root->tagInfo()->tagName;
3584 }
3585
3586 //printf("root->name='%s; args='%s' root->argList='%s'\n",
3587 // qPrint(root->name),qPrint(args),qPrint(argListToString(root->argList))
3588 // );
3589
3590 // adding class member
3591 Relationship relationship = relates.isEmpty() ? Relationship::Member :
3592 root->relatesType==RelatesType::MemberOf ? Relationship::Foreign :
3593 Relationship::Related ;
3594 auto md = createMemberDef(
3595 fileName,root->startLine,root->startColumn,
3596 type,name,args,root->exception,
3597 protection,virt,
3598 stat && root->relatesType!=RelatesType::MemberOf,
3599 relationship,
3600 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
3601 root->argList, root->metaData);
3602 auto mmd = toMemberDefMutable(md.get());
3603 mmd->setTagInfo(root->tagInfo());
3604 mmd->setMemberClass(cd);
3605 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3606 mmd->setDocsForDefinition(!root->proto);
3607 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3608 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3609 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3610 mmd->setMemberSpecifiers(spec);
3611 mmd->setVhdlSpecifiers(root->vhdlSpec);
3612 mmd->setMemberGroupId(root->mGrpId);
3613 mmd->setTypeConstraints(root->typeConstr);
3614 mmd->setLanguage(root->lang);
3615 mmd->setRequiresClause(root->req);
3616 mmd->setId(root->id);
3617 mmd->setBodyDef(fd);
3618 mmd->setFileDef(fd);
3619 mmd->addSectionsToDefinition(root->anchors);
3620 QCString def;
3622 SrcLangExt lang = cd->getLanguage();
3623 QCString scopeSeparator=getLanguageSpecificSeparator(lang);
3624 if (scopeSeparator!="::")
3625 {
3626 qualScope = substitute(qualScope,"::",scopeSeparator);
3627 }
3628 if (lang==SrcLangExt::PHP)
3629 {
3630 // for PHP we use Class::method and Namespace\method
3631 scopeSeparator="::";
3632 }
3633 if (!relates.isEmpty() || isFriend || Config_getBool(HIDE_SCOPE_NAMES))
3634 {
3635 if (!type.isEmpty())
3636 {
3637 def=type+" "+name; //+optArgs;
3638 }
3639 else
3640 {
3641 def=name; //+optArgs;
3642 }
3643 }
3644 else
3645 {
3646 if (!type.isEmpty())
3647 {
3648 def=type+" "+qualScope+scopeSeparator+name; //+optArgs;
3649 }
3650 else
3651 {
3652 def=qualScope+scopeSeparator+name; //+optArgs;
3653 }
3654 }
3655 def.stripPrefix("friend ");
3656 mmd->setDefinition(def);
3658 mmd->addQualifiers(root->qualifiers);
3659
3660 AUTO_TRACE("function member: type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
3661 type, qualScope, rname, args, root->proto, def);
3662
3663 // add member to the class cd
3664 cd->insertMember(md.get());
3665 // add file to list of used files
3666 cd->insertUsedFile(fd);
3667
3668 addMemberToGroups(root,md.get());
3670 root->markAsProcessed();
3671 mmd->setRefItems(root->sli);
3672 mmd->setRequirementReferences(root->rqli);
3673
3674 // add member to the global list of all members
3675 //printf("Adding member=%s class=%s\n",qPrint(md->name()),qPrint(cd->name()));
3677 mn->push_back(std::move(md));
3678}
MethodTypes mtype
signal, slot, (dcop) method, or property?
Definition entry.h:182
bool startsWith(const char *s) const
Definition qcstring.h:511
Relationship
Definition types.h:167

References addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, QCString::at(), AUTO_TRACE, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Entry::exception, Entry::fileDef(), Entry::fileName, QCString::find(), Definition::getLanguage(), getLanguageSpecificSeparator(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), QCString::isEmpty(), Entry::lang, QCString::left(), Entry::markAsProcessed(), Doxygen::memberNameLinkedMap, Entry::metaData, Entry::mGrpId, Entry::mtype, Entry::proto, MemberName::push_back(), ClassDef::qualifiedNameWithTemplateParameters(), Entry::qualifiers, Entry::relatesType, removeRedundantWhiteSpace(), Entry::req, Entry::rqli, Entry::sli, Entry::startColumn, Entry::startLine, QCString::startsWith(), QCString::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 QCString & funcType,
const QCString & funcName,
const QCString & funcArgs,
const QCString & funcDecl,
const QCString & exceptions,
TypeSpecifier spec )
static

Definition at line 6469 of file doxygen.cpp.

6472{
6473 // for unique overloaded member we allow the class to be
6474 // omitted, this is to be Qt compatible. Using this should
6475 // however be avoided, because it is error prone
6476 bool sameClass=false;
6477 if (mn->size()>0)
6478 {
6479 // check if all members with the same name are also in the same class
6480 sameClass = std::equal(mn->begin()+1,mn->end(),mn->begin(),
6481 [](const auto &md1,const auto &md2)
6482 { return md1->getClassDef()->name()==md2->getClassDef()->name(); });
6483 }
6484 if (sameClass)
6485 {
6486 MemberDefMutable *mdm = toMemberDefMutable(mn->front().get());
6487 ClassDefMutable *cd = mdm ? mdm->getClassDefMutable() : nullptr;
6488 if (cd==nullptr) return;
6489
6490 MemberType mtype = MemberType::Function;
6491 if (root->mtype==MethodTypes::Signal) mtype=MemberType::Signal;
6492 else if (root->mtype==MethodTypes::Slot) mtype=MemberType::Slot;
6493 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType::DCOP;
6494
6495 // new overloaded member function
6496 std::unique_ptr<ArgumentList> tArgList =
6497 getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6498 //printf("new related member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6499 auto md = createMemberDef(
6500 root->fileName,root->startLine,root->startColumn,
6501 funcType,funcName,funcArgs,exceptions,
6502 root->protection,root->virt,root->isStatic,Relationship::Related,
6503 mtype,tArgList ? *tArgList : ArgumentList(),root->argList,root->metaData);
6504 auto mmd = toMemberDefMutable(md.get());
6505 mmd->setTagInfo(root->tagInfo());
6506 mmd->setLanguage(root->lang);
6507 mmd->setId(root->id);
6508 mmd->setTypeConstraints(root->typeConstr);
6509 mmd->setMemberClass(cd);
6510 mmd->setDefinition(funcDecl);
6512 mmd->addQualifiers(root->qualifiers);
6514 doc+="<p>";
6515 doc+=root->doc;
6516 mmd->setDocumentation(doc,root->docFile,root->docLine);
6517 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6518 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6519 mmd->setDocsForDefinition(!root->proto);
6520 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6521 mmd->addSectionsToDefinition(root->anchors);
6522 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6523 FileDef *fd=root->fileDef();
6524 mmd->setBodyDef(fd);
6525 mmd->setMemberSpecifiers(spec);
6526 mmd->setVhdlSpecifiers(root->vhdlSpec);
6527 mmd->setMemberGroupId(root->mGrpId);
6528 cd->insertMember(md.get());
6529 cd->insertUsedFile(fd);
6530 mmd->setRefItems(root->sli);
6531 mmd->setRequirementReferences(root->rqli);
6532
6533 mn->push_back(std::move(md));
6534 }
6535}
Ptr & front()
Definition membername.h:51
size_t size() const
Definition membername.h:48
iterator begin()
Definition membername.h:37
iterator end()
Definition membername.h:38

References 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(), getOverloadDocs(), 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, toMemberDefMutable(), Entry::typeConstr, Entry::vhdlSpec, and Entry::virt.

Referenced by findMember().

◆ addPageToContext()

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

Definition at line 311 of file doxygen.cpp.

312{
313 if (root->parent()) // add the page to it's scope
314 {
315 QCString scope = root->parent()->name;
316 if (root->parent()->section.isPackageDoc())
317 {
318 scope=substitute(scope,".","::");
319 }
320 scope = stripAnonymousNamespaceScope(scope);
321 scope+="::"+pd->name();
323 if (d)
324 {
325 pd->setPageScope(d);
326 }
327 }
328}
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 330 of file doxygen.cpp.

331{
332 GroupDef *gd=nullptr;
333 for (const Grouping &g : root->groups)
334 {
335 if (!g.groupname.isEmpty() && (gd=Doxygen::groupLinkedMap->find(g.groupname))) break;
336 }
337 //printf("---> addRelatedPage() %s gd=%p\n",qPrint(root->name),gd);
338 QCString doc=root->doc+root->inbodyDocs;
339
340 PageDef *pd = addRelatedPage(root->name, // name
341 root->args, // ptitle
342 doc, // doc
343 root->docFile, // fileName
344 root->docLine, // docLine
345 root->startLine, // startLine
346 root->sli, // sli
347 gd, // gd
348 root->tagInfo(), // tagInfo
349 FALSE, // xref
350 root->lang // lang
351 );
352 if (pd)
353 {
354 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
356 pd->setLocalToc(root->localToc);
357 addPageToContext(pd,root);
358 }
359}
LocalToc localToc
Definition entry.h:234
A model of a page symbol.
Definition pagedef.h:26
virtual void setLocalToc(const LocalToc &tl)=0
static void addRelatedPage(Entry *root)
Definition doxygen.cpp:330
static void addPageToContext(PageDef *pd, Entry *root)
Definition doxygen.cpp:311
Grouping info.
Definition types.h:227
QCString 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, FALSE, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, Entry::inbodyDocs, QCString::isEmpty(), Entry::lang, Entry::localToc, Entry::name, DefinitionMutable::setBriefDescription(), PageDef::setLocalToc(), Entry::sli, Entry::startLine, and Entry::tagInfo().

Referenced by addRelatedPage(), RequirementManager::addRequirement(), buildPageList(), CitationManager::generatePage(), and RefList::generatePage().

◆ addRequirementReferences()

void addRequirementReferences ( )
static

Definition at line 5409 of file doxygen.cpp.

5410{
5411 AUTO_TRACE();
5412 applyToAllDefinitions([](auto* obj) { obj->addRequirementReferences(); });
5413}

References applyToAllDefinitions(), and AUTO_TRACE.

Referenced by parseInput().

◆ addSourceReferences()

void addSourceReferences ( )
static

Definition at line 8670 of file doxygen.cpp.

8671{
8672 // add source references for class definitions
8673 for (const auto &cd : *Doxygen::classLinkedMap)
8674 {
8675 const FileDef *fd=cd->getBodyDef();
8676 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8677 {
8678 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8679 }
8680 }
8681 // add source references for concept definitions
8682 for (const auto &cd : *Doxygen::conceptLinkedMap)
8683 {
8684 const FileDef *fd=cd->getBodyDef();
8685 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8686 {
8687 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8688 }
8689 }
8690 // add source references for namespace definitions
8691 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8692 {
8693 const FileDef *fd=nd->getBodyDef();
8694 if (fd && nd->isLinkableInProject() && nd->getStartDefLine()!=-1)
8695 {
8696 const_cast<FileDef*>(fd)->addSourceRef(nd->getStartDefLine(),nd.get(),nullptr);
8697 }
8698 }
8699
8700 // add source references for member names
8701 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8702 {
8703 for (const auto &md : *mn)
8704 {
8705 //printf("class member %s: def=%s body=%d link?=%d\n",
8706 // qPrint(md->name()),
8707 // md->getBodyDef()?qPrint(md->getBodyDef()->name()):"<none>",
8708 // md->getStartBodyLine(),md->isLinkableInProject());
8709 const FileDef *fd=md->getBodyDef();
8710 if (fd &&
8711 md->getStartDefLine()!=-1 &&
8712 md->isLinkableInProject() &&
8714 )
8715 {
8716 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8717 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8718 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8719 }
8720 }
8721 }
8722 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8723 {
8724 for (const auto &md : *mn)
8725 {
8726 const FileDef *fd=md->getBodyDef();
8727 //printf("member %s body=[%d,%d] fd=%p link=%d parseSources=%d\n",
8728 // qPrint(md->name()),
8729 // md->getStartBodyLine(),md->getEndBodyLine(),fd,
8730 // md->isLinkableInProject(),
8731 // Doxygen::parseSourcesNeeded);
8732 if (fd &&
8733 md->getStartDefLine()!=-1 &&
8734 md->isLinkableInProject() &&
8736 )
8737 {
8738 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8739 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8740 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8741 }
8742 }
8743 }
8744}
virtual const FileDef * getBodyDef() const =0
static bool parseSourcesNeeded
Definition doxygen.h:123

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

8078{
8079 for (const auto &cd : *Doxygen::classLinkedMap)
8080 {
8081 if (cd->isLinkableInProject())
8082 {
8083 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8084 if (Doxygen::searchIndex.enabled())
8085 {
8086 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
8087 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
8088 }
8089 }
8090 }
8091
8092 for (const auto &cd : *Doxygen::conceptLinkedMap)
8093 {
8094 if (cd->isLinkableInProject())
8095 {
8096 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8097 if (Doxygen::searchIndex.enabled())
8098 {
8099 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
8100 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
8101 }
8102 }
8103 }
8104
8105 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8106 {
8107 if (nd->isLinkableInProject())
8108 {
8109 Doxygen::indexList->addIndexItem(nd.get(),nullptr);
8110 if (Doxygen::searchIndex.enabled())
8111 {
8112 Doxygen::searchIndex.setCurrentDoc(nd.get(),nd->anchor(),FALSE);
8113 Doxygen::searchIndex.addWord(nd->localName(),TRUE);
8114 }
8115 }
8116 }
8117
8118 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8119 {
8120 for (const auto &fd : *fn)
8121 {
8122 if (Doxygen::searchIndex.enabled() && fd->isLinkableInProject())
8123 {
8124 Doxygen::searchIndex.setCurrentDoc(fd.get(),fd->anchor(),FALSE);
8125 Doxygen::searchIndex.addWord(fd->localName(),TRUE);
8126 }
8127 }
8128 }
8129
8130 auto addWordsForTitle = [](const Definition *d,const QCString &anchor,const QCString &title)
8131 {
8132 Doxygen::indexList->addIndexItem(d,nullptr,QCString(),filterTitle(title));
8133 if (Doxygen::searchIndex.enabled())
8134 {
8135 Doxygen::searchIndex.setCurrentDoc(d,anchor,false);
8136 std::string s = title.str();
8137 static const reg::Ex re(R"(\a[\w-]*)");
8138 reg::Iterator it(s,re);
8140 for (; it!=end ; ++it)
8141 {
8142 const auto &match = *it;
8143 std::string matchStr = match.str();
8144 Doxygen::searchIndex.addWord(matchStr,true);
8145 }
8146 }
8147 };
8148
8149 for (const auto &gd : *Doxygen::groupLinkedMap)
8150 {
8151 if (gd->isLinkableInProject())
8152 {
8153 addWordsForTitle(gd.get(),gd->anchor(),gd->groupTitle());
8154 }
8155 }
8156
8157 for (const auto &pd : *Doxygen::pageLinkedMap)
8158 {
8159 if (pd->isLinkableInProject())
8160 {
8161 addWordsForTitle(pd.get(),pd->anchor(),pd->title());
8162 }
8163 }
8164
8166 {
8167 addWordsForTitle(Doxygen::mainPage.get(),Doxygen::mainPage->anchor(),Doxygen::mainPage->title());
8168 }
8169
8170 auto addMemberToSearchIndex = [](const MemberDef *md)
8171 {
8172 if (Doxygen::searchIndex.enabled())
8173 {
8174 Doxygen::searchIndex.setCurrentDoc(md,md->anchor(),FALSE);
8175 QCString ln=md->localName();
8176 QCString qn=md->qualifiedName();
8177 Doxygen::searchIndex.addWord(ln,TRUE);
8178 if (ln!=qn)
8179 {
8180 Doxygen::searchIndex.addWord(qn,TRUE);
8181 if (md->getClassDef())
8182 {
8183 Doxygen::searchIndex.addWord(md->getClassDef()->displayName(),TRUE);
8184 }
8185 if (md->getNamespaceDef())
8186 {
8187 Doxygen::searchIndex.addWord(md->getNamespaceDef()->displayName(),TRUE);
8188 }
8189 }
8190 }
8191 };
8192
8193 auto getScope = [](const MemberDef *md)
8194 {
8195 const Definition *scope = nullptr;
8196 if (md->getGroupDef()) scope = md->getGroupDef();
8197 else if (md->getClassDef()) scope = md->getClassDef();
8198 else if (md->getNamespaceDef()) scope = md->getNamespaceDef();
8199 else if (md->getFileDef()) scope = md->getFileDef();
8200 return scope;
8201 };
8202
8203 auto addMemberToIndices = [addMemberToSearchIndex,getScope](const MemberDef *md)
8204 {
8205 if (md->isLinkableInProject())
8206 {
8207 if (!(md->isEnumerate() && md->isAnonymous()))
8208 {
8209 Doxygen::indexList->addIndexItem(getScope(md),md);
8211 }
8212 if (md->isEnumerate())
8213 {
8214 for (const auto &fmd : md->enumFieldList())
8215 {
8216 Doxygen::indexList->addIndexItem(getScope(fmd),fmd);
8218 }
8219 }
8220 }
8221 };
8222
8223 // for each class member name
8224 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8225 {
8226 // for each member definition
8227 for (const auto &md : *mn)
8228 {
8229 addMemberToIndices(md.get());
8230 }
8231 }
8232 // for each file/namespace function name
8233 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8234 {
8235 // for each member definition
8236 for (const auto &md : *mn)
8237 {
8238 addMemberToIndices(md.get());
8239 }
8240 }
8241}
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:100
static IndexList * indexList
Definition doxygen.h:132
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:99
static SearchIndexIntf searchIndex
Definition doxygen.h:124
Class representing a regular expression.
Definition regex.h:39
Class to iterate through matches.
Definition regex.h:230
DirIterator end(const DirIterator &) noexcept
Definition dir.cpp:175
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:855
static void addMemberToSearchIndex(const MemberDef *md)
QCString filterTitle(const QCString &title)
Definition util.cpp:5654

References addMemberToSearchIndex(), Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, end(), FALSE, filterTitle(), Doxygen::functionNameLinkedMap, Doxygen::groupLinkedMap, Doxygen::indexList, Doxygen::inputNameLinkedMap, Doxygen::mainPage, Doxygen::memberNameLinkedMap, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, Doxygen::searchIndex, and TRUE.

Referenced by parseInput().

◆ addVariable()

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

Definition at line 3007 of file doxygen.cpp.

3008{
3009 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
3010
3011 AUTO_TRACE("VARIABLE_SEC: type='{}' name='{}' args='{}' bodyLine={} endBodyLine={} mGrpId={} relates='{}'",
3012 root->type, root->name, root->args, root->bodyLine, root->endBodyLine, root->mGrpId, root->relates);
3013 //printf("root->parent->name=%s\n",qPrint(root->parent->name));
3014
3015 QCString type = root->type;
3016 QCString name = root->name;
3017 QCString args = root->args;
3018 if (type.isEmpty() && name.find("operator")==-1 &&
3019 (name.find('*')!=-1 || name.find('&')!=-1))
3020 {
3021 // recover from parse error caused by redundant braces
3022 // like in "int *(var[10]);", which is parsed as
3023 // type="" name="int *" args="(var[10])"
3024
3025 type=name;
3026 std::string sargs = args.str();
3027 static const reg::Ex reName(R"(\a\w*)");
3029 if (reg::search(sargs,match,reName))
3030 {
3031 name = match.str(); // e.g. 'var' in '(var[10])'
3032 sargs = match.suffix().str(); // e.g. '[10]) in '(var[10])'
3033 size_t j = sargs.find(')');
3034 if (j!=std::string::npos) args=sargs.substr(0,j); // extract, e.g '[10]' from '[10])'
3035 }
3036 }
3037 else
3038 {
3039 int i=isFuncPtr;
3040 if (i==-1 && (root->spec.isAlias())==0) i=findFunctionPtr(type.str(),root->lang); // for typedefs isFuncPtr is not yet set
3041 AUTO_TRACE_ADD("functionPtr={}",i!=-1?"yes":"no");
3042 if (i>=0) // function pointer
3043 {
3044 int ai = type.find('[',i);
3045 if (ai>i) // function pointer array
3046 {
3047 args.prepend(type.right(type.length()-ai));
3048 type=type.left(ai);
3049 }
3050 else if (type.find(')',i)!=-1) // function ptr, not variable like "int (*bla)[10]"
3051 {
3052 type=type.left(type.length()-1);
3053 args.prepend(") ");
3054 }
3055 }
3056 }
3057 AUTO_TRACE_ADD("after correction: type='{}' name='{}' args='{}'",type,name,args);
3058
3059 QCString scope;
3060 name=removeRedundantWhiteSpace(name);
3061
3062 // find the scope of this variable
3063 int index = computeQualifiedIndex(name);
3064 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
3065 // grouped members are stored with full scope
3066 {
3067 buildScopeFromQualifiedName(name.left(index+2),root->lang,root->tagInfo());
3068 scope=name.left(index);
3069 name=name.mid(index+2);
3070 }
3071 else
3072 {
3073 Entry *p = root->parent();
3074 while (p->section.isScope())
3075 {
3076 QCString scopeName = p->name;
3077 if (!scopeName.isEmpty())
3078 {
3079 scope.prepend(scopeName);
3080 break;
3081 }
3082 p=p->parent();
3083 }
3084 }
3085
3086 QCString type_s = type;
3087 type=type.stripWhiteSpace();
3088 ClassDefMutable *cd=nullptr;
3089 bool isRelated=FALSE;
3090 bool isMemberOf=FALSE;
3091
3092 QCString classScope=stripAnonymousNamespaceScope(scope);
3093 if (root->lang==SrcLangExt::CSharp)
3094 {
3095 classScope=mangleCSharpGenericName(classScope);
3096 }
3097 else
3098 {
3099 classScope=stripTemplateSpecifiersFromScope(classScope,FALSE);
3100 }
3101 QCString annScopePrefix=scope.left(scope.length()-classScope.length());
3102
3103
3104 // Look for last :: not part of template specifier
3105 int p=-1;
3106 for (size_t i=0;i<name.length()-1;i++)
3107 {
3108 if (name[i]==':' && name[i+1]==':')
3109 {
3110 p=static_cast<int>(i);
3111 }
3112 else if (name[i]=='<') // skip over template parts,
3113 // i.e. A::B<C::D> => p=1 and
3114 // A<B::C>::D => p=8
3115 {
3116 int e = findEndOfTemplate(name,i+1);
3117 if (e!=-1) i=static_cast<int>(e);
3118 }
3119 }
3120
3121 if (p!=-1) // found it
3122 {
3123 if (type=="friend class" || type=="friend struct" ||
3124 type=="friend union")
3125 {
3126 cd=getClassMutable(scope);
3127 if (cd)
3128 {
3129 addVariableToClass(root, // entry
3130 cd, // class to add member to
3131 MemberType::Friend, // type of member
3132 type, // type value as string
3133 name, // name of the member
3134 args, // arguments as string
3135 FALSE, // from Anonymous scope
3136 nullptr, // anonymous member
3137 Protection::Public, // protection
3138 Relationship::Member // related to a class
3139 );
3140 }
3141 }
3142 if (root->bodyLine!=-1 && root->endBodyLine!=-1) // store the body location for later use
3143 {
3144 Doxygen::staticInitMap.emplace(name.str(),BodyInfo{root->startLine,root->bodyLine,root->endBodyLine});
3145 }
3146
3147
3148 AUTO_TRACE_ADD("static variable {} body=[{}..{}]",name,root->bodyLine,root->endBodyLine);
3149 return; /* skip this member, because it is a
3150 * static variable definition (always?), which will be
3151 * found in a class scope as well, but then we know the
3152 * correct protection level, so only then it will be
3153 * inserted in the correct list!
3154 */
3155 }
3156
3157 MemberType mtype = MemberType::Variable;
3158 if (type=="@")
3159 mtype=MemberType::EnumValue;
3160 else if (type_s.startsWith("typedef "))
3161 mtype=MemberType::Typedef;
3162 else if (type_s.startsWith("friend "))
3163 mtype=MemberType::Friend;
3164 else if (root->mtype==MethodTypes::Property)
3165 mtype=MemberType::Property;
3166 else if (root->mtype==MethodTypes::Event)
3167 mtype=MemberType::Event;
3168 else if (type.find("sequence<") != -1)
3169 mtype=sliceOpt ? MemberType::Sequence : MemberType::Typedef;
3170 else if (type.find("dictionary<") != -1)
3171 mtype=sliceOpt ? MemberType::Dictionary : MemberType::Typedef;
3172
3173 if (!root->relates.isEmpty()) // related variable
3174 {
3175 isRelated=TRUE;
3176 isMemberOf=(root->relatesType==RelatesType::MemberOf);
3177 if (getClass(root->relates)==nullptr && !scope.isEmpty())
3178 scope=mergeScopes(scope,root->relates);
3179 else
3180 scope=root->relates;
3181 }
3182
3183 cd=getClassMutable(scope);
3184 if (cd==nullptr && classScope!=scope) cd=getClassMutable(classScope);
3185 if (cd)
3186 {
3187 MemberDef *md=nullptr;
3188
3189 // if cd is an anonymous (=tag less) scope we insert the member
3190 // into a non-anonymous parent scope as well. This is needed to
3191 // be able to refer to it using \var or \fn
3192
3193 //int indentDepth=0;
3194 int si=scope.find('@');
3195 //int anonyScopes = 0;
3196 //bool added=FALSE;
3197
3198 Relationship relationship = isMemberOf ? Relationship::Foreign :
3199 isRelated ? Relationship::Related :
3200 Relationship::Member ;
3201 if (si!=-1) // anonymous scope or type
3202 {
3203 QCString pScope;
3204 ClassDefMutable *pcd=nullptr;
3205 pScope = scope.left(std::max(si-2,0)); // scope without tag less parts
3206 if (!pScope.isEmpty())
3207 pScope.prepend(annScopePrefix);
3208 else if (annScopePrefix.length()>2)
3209 pScope=annScopePrefix.left(annScopePrefix.length()-2);
3210 if (name.at(0)!='@')
3211 {
3212 if (!pScope.isEmpty() && (pcd=getClassMutable(pScope)))
3213 {
3214 AUTO_TRACE_ADD("Adding member '{}' in anonymous scope to parent scope '{}'",name,pScope);
3215 md=addVariableToClass(root, // entry
3216 pcd, // class to add member to
3217 mtype, // member type
3218 type, // type value as string
3219 name, // member name
3220 args, // arguments as string
3221 TRUE, // from anonymous scope
3222 nullptr, // from anonymous member
3223 root->protection,
3224 relationship
3225 );
3226 //added=TRUE;
3227 }
3228 else // anonymous scope inside namespace or file => put variable in the global scope
3229 {
3230 if (mtype==MemberType::Variable)
3231 {
3232 AUTO_TRACE_ADD("Adding member '{}' in anonymous scope to global scope",name);
3233 md=addVariableToFile(root,mtype,pScope,type,name,args,TRUE,nullptr);
3234 }
3235 //added=TRUE;
3236 }
3237 }
3238 }
3239
3240 addVariableToClass(root, // entry
3241 cd, // class to add member to
3242 mtype, // member type
3243 type, // type value as string
3244 name, // name of the member
3245 args, // arguments as string
3246 FALSE, // from anonymous scope
3247 md, // from anonymous member
3248 root->protection,
3249 relationship
3250 );
3251 }
3252 else if (!name.isEmpty()) // global variable
3253 {
3254 addVariableToFile(root,mtype,scope,type,name,args,FALSE,/*nullptr,*/nullptr);
3255 }
3256
3257}
static StaticInitMap staticInitMap
Definition doxygen.h:141
Represents an unstructured piece of information, about an entity found in the sources.
Definition entry.h:117
const std::string & str() const
Definition qcstring.h:556
ClassDef * getClass(const QCString &n)
Object representing the matching results.
Definition regex.h:151
static int findEndOfTemplate(const QCString &s, size_t startPos)
Definition doxygen.cpp:2939
static int findFunctionPtr(const std::string &type, SrcLangExt lang, int *pLength=nullptr)
Definition doxygen.cpp:2735
static MemberDef * addVariableToClass(const Entry *root, ClassDefMutable *cd, MemberType mtype, const QCString &type, const QCString &name, const QCString &args, bool fromAnnScope, MemberDef *fromAnnMemb, Protection prot, Relationship related)
Definition doxygen.cpp:2288
static MemberDef * addVariableToFile(const Entry *root, MemberType mtype, const QCString &scope, const QCString &type, const QCString &name, const QCString &args, bool fromAnnScope, MemberDef *fromAnnMemb)
Definition doxygen.cpp:2471
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:844
Data associated with description found in the body.
Definition definition.h:64
int computeQualifiedIndex(const QCString &name)
Return the index of the last :: in the string name that is still before the first <.
Definition util.cpp:6846

References addVariableToClass(), addVariableToFile(), Entry::args, QCString::at(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, buildScopeFromQualifiedName(), computeQualifiedIndex(), Config_getBool, Entry::endBodyLine, FALSE, QCString::find(), findEndOfTemplate(), findFunctionPtr(), getClass(), getClassMutable(), QCString::isEmpty(), EntryType::isScope(), Entry::lang, QCString::left(), QCString::length(), mangleCSharpGenericName(), mergeScopes(), Entry::mGrpId, QCString::mid(), Entry::mtype, Entry::name, Entry::parent(), QCString::prepend(), Entry::protection, Entry::relates, Entry::relatesType, removeRedundantWhiteSpace(), QCString::right(), reg::search(), Entry::section, Entry::spec, QCString::startsWith(), Doxygen::staticInitMap, QCString::str(), stripAnonymousNamespaceScope(), stripTemplateSpecifiersFromScope(), QCString::stripWhiteSpace(), Entry::tagInfo(), TRUE, and Entry::type.

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

◆ addVariableToClass()

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

Definition at line 2288 of file doxygen.cpp.

2299{
2301 QCString scopeSeparator="::";
2302 SrcLangExt lang = cd->getLanguage();
2303 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
2304 {
2305 qualScope = substitute(qualScope,"::",".");
2306 scopeSeparator=".";
2307 }
2308 AUTO_TRACE("class variable: file='{}' type='{}' scope='{}' name='{}' args='{}' prot={} mtype={} lang={} ann={} init='{}'",
2309 root->fileName, type, qualScope, name, args, root->protection, mtype, lang, fromAnnScope, root->initializer.str());
2310
2311 QCString def;
2312 if (!type.isEmpty())
2313 {
2314 if (related!=Relationship::Member || mtype==MemberType::Friend || Config_getBool(HIDE_SCOPE_NAMES))
2315 {
2316 if (root->spec.isAlias()) // turn 'typedef B A' into 'using A'
2317 {
2318 if (lang==SrcLangExt::Python)
2319 {
2320 def="type "+name+args;
2321 }
2322 else
2323 {
2324 def="using "+name;
2325 }
2326 }
2327 else
2328 {
2329 def=type+" "+name+args;
2330 }
2331 }
2332 else
2333 {
2334 if (root->spec.isAlias()) // turn 'typedef B C::A' into 'using C::A'
2335 {
2336 if (lang==SrcLangExt::Python)
2337 {
2338 def="type "+qualScope+scopeSeparator+name+args;
2339 }
2340 else
2341 {
2342 def="using "+qualScope+scopeSeparator+name;
2343 }
2344 }
2345 else
2346 {
2347 def=type+" "+qualScope+scopeSeparator+name+args;
2348 }
2349 }
2350 }
2351 else
2352 {
2353 if (Config_getBool(HIDE_SCOPE_NAMES))
2354 {
2355 def=name+args;
2356 }
2357 else
2358 {
2359 def=qualScope+scopeSeparator+name+args;
2360 }
2361 }
2362 def.stripPrefix("static ");
2363
2364 // see if the member is already found in the same scope
2365 // (this may be the case for a static member that is initialized
2366 // outside the class)
2368 if (mn)
2369 {
2370 for (const auto &imd : *mn)
2371 {
2372 //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n",
2373 // md->getClassDef(),cd,qPrint(type),md->typeString());
2374 MemberDefMutable *md = toMemberDefMutable(imd.get());
2375 if (md &&
2376 md->getClassDef()==cd &&
2377 ((lang==SrcLangExt::Python && type.isEmpty() && !md->typeString().isEmpty()) ||
2379 // member already in the scope
2380 {
2381
2382 if (root->lang==SrcLangExt::ObjC &&
2383 root->mtype==MethodTypes::Property &&
2384 md->memberType()==MemberType::Variable)
2385 { // Objective-C 2.0 property
2386 // turn variable into a property
2387 md->setProtection(root->protection);
2388 cd->reclassifyMember(md,MemberType::Property);
2389 }
2390 addMemberDocs(root,md,def,nullptr,FALSE,root->spec);
2391 AUTO_TRACE_ADD("Member already found!");
2392 return md;
2393 }
2394 }
2395 }
2396
2397 QCString fileName = root->fileName;
2398 if (fileName.isEmpty() && root->tagInfo())
2399 {
2400 fileName = root->tagInfo()->tagName;
2401 }
2402
2403 // new member variable, typedef or enum value
2404 auto md = createMemberDef(
2405 fileName,root->startLine,root->startColumn,
2406 type,name,args,root->exception,
2407 prot,Specifier::Normal,root->isStatic,related,
2408 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
2409 ArgumentList(), root->metaData);
2410 auto mmd = toMemberDefMutable(md.get());
2411 mmd->setTagInfo(root->tagInfo());
2412 mmd->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope())
2413 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
2414 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2415 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2416 mmd->setDefinition(def);
2417 mmd->setBitfields(root->bitfields);
2418 mmd->addSectionsToDefinition(root->anchors);
2419 mmd->setFromAnonymousScope(fromAnnScope);
2420 mmd->setFromAnonymousMember(fromAnnMemb);
2421 if (fromAnnMemb)
2422 {
2423 MemberDefMutable *fromAnnMmd = toMemberDefMutable(fromAnnMemb);
2424 if (fromAnnMmd)
2425 {
2426 fromAnnMmd->setToAnonymousMember(mmd);
2427 }
2428 }
2429 //md->setIndentDepth(indentDepth);
2430 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2431 mmd->setInitializer(root->initializer.str());
2432 mmd->setMaxInitLines(root->initLines);
2433 mmd->setMemberGroupId(root->mGrpId);
2434 mmd->setMemberSpecifiers(root->spec);
2435 mmd->setVhdlSpecifiers(root->vhdlSpec);
2436 mmd->setReadAccessor(root->read);
2437 mmd->setWriteAccessor(root->write);
2439 mmd->setHidden(root->hidden);
2440 mmd->setArtificial(root->artificial);
2441 mmd->setLanguage(root->lang);
2442 mmd->setId(root->id);
2443 addMemberToGroups(root,md.get());
2445 mmd->setBodyDef(root->fileDef());
2446 mmd->addQualifiers(root->qualifiers);
2447
2448 AUTO_TRACE_ADD("Adding new member '{}' to class '{}'",name,cd->name());
2449 cd->insertMember(md.get());
2450 mmd->setRefItems(root->sli);
2451 mmd->setRequirementReferences(root->rqli);
2452
2453 cd->insertUsedFile(root->fileDef());
2454 root->markAsProcessed();
2455
2456 if (mtype==MemberType::Typedef)
2457 {
2458 resolveTemplateInstanceInType(root,cd,md.get());
2459 }
2460
2461 // add the member to the global list
2462 MemberDef *result = md.get();
2463 mn = Doxygen::memberNameLinkedMap->add(name);
2464 mn->push_back(std::move(md));
2465
2466 return result;
2467}
virtual void reclassifyMember(MemberDefMutable *md, MemberType t)=0
QCString bitfields
member's bit fields
Definition entry.h:194
QCString write
property write accessor
Definition entry.h:213
QCString read
property read accessor
Definition entry.h:212
virtual MemberType memberType() const =0
virtual void setProtection(Protection p)=0
virtual void setToAnonymousMember(MemberDef *m)=0
static void resolveTemplateInstanceInType(const Entry *root, const Definition *scope, const MemberDef *md)
Definition doxygen.cpp:4681

References 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, Entry::endBodyLine, Entry::exception, FALSE, Entry::fileDef(), Entry::fileName, MemberDef::getClassDef(), Definition::getLanguage(), Entry::hidden, Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, Entry::initializer, Entry::initLines, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), QCString::isEmpty(), 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(), MemberDefMutable::setToAnonymousMember(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, TextStream::str(), QCString::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 QCString & scope,
const QCString & type,
const QCString & name,
const QCString & args,
bool fromAnnScope,
MemberDef * fromAnnMemb )
static

Definition at line 2471 of file doxygen.cpp.

2480{
2481 AUTO_TRACE("global variable: file='{}' type='{}' scope='{}' name='{}' args='{}' prot={} mtype={} lang={} init='{}'",
2482 root->fileName, type, scope, name, args, root->protection, mtype, root->lang, root->initializer.str());
2483
2484 FileDef *fd = root->fileDef();
2485
2486 // see if we have a typedef that should hide a struct or union
2487 if (mtype==MemberType::Typedef && Config_getBool(TYPEDEF_HIDES_STRUCT))
2488 {
2489 QCString ttype = type;
2490 ttype.stripPrefix("typedef ");
2491 if (ttype.stripPrefix("struct ") || ttype.stripPrefix("union "))
2492 {
2493 static const reg::Ex re(R"(\a\w*)");
2495 const std::string &typ = ttype.str();
2496 if (reg::search(typ,match,re))
2497 {
2498 QCString typeValue = match.str();
2499 ClassDefMutable *cd = getClassMutable(typeValue);
2500 if (cd)
2501 {
2502 // this typedef should hide compound name cd, so we
2503 // change the name that is displayed from cd.
2504 cd->setClassName(name);
2505 cd->setDocumentation(root->doc,root->docFile,root->docLine);
2506 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2507 return nullptr;
2508 }
2509 }
2510 }
2511 }
2512
2513 // see if the function is inside a namespace
2514 NamespaceDefMutable *nd = nullptr;
2515 if (!scope.isEmpty())
2516 {
2517 if (scope.find('@')!=-1) return nullptr; // anonymous scope!
2518 nd = getResolvedNamespaceMutable(scope);
2519 }
2520 QCString def;
2521
2522 // determine the definition of the global variable
2523 if (nd && !nd->isAnonymous() &&
2524 !Config_getBool(HIDE_SCOPE_NAMES)
2525 )
2526 // variable is inside a namespace, so put the scope before the name
2527 {
2528 SrcLangExt lang = nd->getLanguage();
2530
2531 if (!type.isEmpty())
2532 {
2533 if (root->spec.isAlias()) // turn 'typedef B NS::A' into 'using NS::A'
2534 {
2535 if (lang==SrcLangExt::Python)
2536 {
2537 def="type "+nd->name()+sep+name+args;
2538 }
2539 else
2540 {
2541 def="using "+nd->name()+sep+name;
2542 }
2543 }
2544 else // normal member
2545 {
2546 def=type+" "+nd->name()+sep+name+args;
2547 }
2548 }
2549 else
2550 {
2551 def=nd->name()+sep+name+args;
2552 }
2553 }
2554 else
2555 {
2556 if (!type.isEmpty() && !root->name.isEmpty())
2557 {
2558 if (name.at(0)=='@') // dummy variable representing anonymous union
2559 {
2560 def=type;
2561 }
2562 else
2563 {
2564 if (root->spec.isAlias()) // turn 'typedef B A' into 'using A'
2565 {
2566 if (root->lang==SrcLangExt::Python)
2567 {
2568 def="type "+root->name+args;
2569 }
2570 else
2571 {
2572 def="using "+root->name;
2573 }
2574 }
2575 else // normal member
2576 {
2577 def=type+" "+name+args;
2578 }
2579 }
2580 }
2581 else
2582 {
2583 def=name+args;
2584 }
2585 }
2586 def.stripPrefix("static ");
2587
2589 if (mn)
2590 {
2591 //QCString nscope=removeAnonymousScopes(scope);
2592 //NamespaceDef *nd=nullptr;
2593 //if (!nscope.isEmpty())
2594 if (!scope.isEmpty())
2595 {
2596 nd = getResolvedNamespaceMutable(scope);
2597 }
2598 for (const auto &imd : *mn)
2599 {
2600 MemberDefMutable *md = toMemberDefMutable(imd.get());
2601 if (md &&
2602 ((nd==nullptr && md->getNamespaceDef()==nullptr && md->getFileDef() &&
2603 root->fileName==md->getFileDef()->absFilePath()
2604 ) // both variable names in the same file
2605 || (nd!=nullptr && md->getNamespaceDef()==nd) // both in same namespace
2606 )
2607 && !md->isDefine() // function style #define's can be "overloaded" by typedefs or variables
2608 && !md->isEnumerate() // in C# an enum value and enum can have the same name
2609 )
2610 // variable already in the scope
2611 {
2612 bool isPHPArray = md->getLanguage()==SrcLangExt::PHP &&
2613 md->argsString()!=args &&
2614 args.find('[')!=-1;
2615 bool staticsInDifferentFiles =
2616 root->isStatic && md->isStatic() &&
2617 root->fileName!=md->getDefFileName();
2618
2619 if (md->getFileDef() &&
2620 !isPHPArray && // not a php array
2621 !staticsInDifferentFiles
2622 )
2623 // not a php array variable
2624 {
2625 AUTO_TRACE_ADD("variable already found: scope='{}'",md->getOuterScope()->name());
2626 addMemberDocs(root,md,def,nullptr,FALSE,root->spec);
2627 md->setRefItems(root->sli);
2628 md->setRequirementReferences(root->rqli);
2629 // if md is a variable forward declaration and root is the definition that
2630 // turn md into the definition
2631 if (!root->explicitExternal && md->isExternal())
2632 {
2633 md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn());
2635 }
2636 // if md is the definition and root point at a declaration, then add the
2637 // declaration info
2638 else if (root->explicitExternal && !md->isExternal())
2639 {
2640 md->setDeclFile(root->fileName,root->startLine,root->startColumn);
2641 }
2642 return md;
2643 }
2644 }
2645 }
2646 }
2647
2648 QCString fileName = root->fileName;
2649 if (fileName.isEmpty() && root->tagInfo())
2650 {
2651 fileName = root->tagInfo()->tagName;
2652 }
2653
2654 AUTO_TRACE_ADD("new variable, namespace='{}'",nd?nd->name():QCString("<global>"));
2655 // new global variable, enum value or typedef
2656 auto md = createMemberDef(
2657 fileName,root->startLine,root->startColumn,
2658 type,name,args,QCString(),
2659 root->protection, Specifier::Normal,root->isStatic,Relationship::Member,
2660 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
2661 root->argList, root->metaData);
2662 auto mmd = toMemberDefMutable(md.get());
2663 mmd->setTagInfo(root->tagInfo());
2664 mmd->setMemberSpecifiers(root->spec);
2665 mmd->setVhdlSpecifiers(root->vhdlSpec);
2666 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
2667 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2668 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2669 mmd->addSectionsToDefinition(root->anchors);
2670 mmd->setFromAnonymousScope(fromAnnScope);
2671 mmd->setFromAnonymousMember(fromAnnMemb);
2672 if (fromAnnMemb)
2673 {
2674 MemberDefMutable *fromAnnMmd = toMemberDefMutable(fromAnnMemb);
2675 if (fromAnnMmd)
2676 {
2677 fromAnnMmd->setToAnonymousMember(mmd);
2678 }
2679 }
2680 mmd->setInitializer(root->initializer.str());
2681 mmd->setMaxInitLines(root->initLines);
2682 mmd->setMemberGroupId(root->mGrpId);
2683 mmd->setDefinition(def);
2684 mmd->setLanguage(root->lang);
2685 mmd->setId(root->id);
2687 mmd->setExplicitExternal(root->explicitExternal,fileName,root->startLine,root->startColumn);
2688 mmd->addQualifiers(root->qualifiers);
2689 //md->setOuterScope(fd);
2690 if (!root->explicitExternal)
2691 {
2692 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2693 mmd->setBodyDef(fd);
2694 }
2695 addMemberToGroups(root,md.get());
2697
2698 mmd->setRefItems(root->sli);
2699 mmd->setRequirementReferences(root->rqli);
2700 if (nd && !nd->isAnonymous())
2701 {
2702 mmd->setNamespace(nd);
2703 nd->insertMember(md.get());
2704 }
2705
2706 // add member to the file (we do this even if we have already inserted
2707 // it into the namespace.
2708 if (fd)
2709 {
2710 mmd->setFileDef(fd);
2711 fd->insertMember(md.get());
2712 }
2713
2714 root->markAsProcessed();
2715
2716 if (mtype==MemberType::Typedef)
2717 {
2718 resolveTemplateInstanceInType(root,nd,md.get());
2719 }
2720
2721 // add member definition to the list of globals
2722 MemberDef *result = md.get();
2723 mn = Doxygen::functionNameLinkedMap->add(name);
2724 mn->push_back(std::move(md));
2725
2726
2727
2728 return result;
2729}
virtual void setClassName(const QCString &name)=0
virtual int getDefColumn() const =0
virtual bool isExternal() const =0
virtual bool isDefine() const =0
virtual void setExplicitExternal(bool b, const QCString &df, int line, int column)=0
virtual void setDeclFile(const QCString &df, int line, int column)=0

References FileDef::absFilePath(), addMemberDocs(), addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, MemberDef::argsString(), QCString::at(), 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::explicitExternal, FALSE, Entry::fileDef(), Entry::fileName, QCString::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(), QCString::isEmpty(), MemberDef::isEnumerate(), MemberDef::isExternal(), Entry::isStatic, MemberDef::isStatic(), Entry::lang, Entry::markAsProcessed(), Entry::metaData, Entry::mGrpId, Definition::name(), Entry::name, 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(), MemberDefMutable::setToAnonymousMember(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, QCString::str(), TextStream::str(), QCString::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 11814 of file doxygen.cpp.

11815{
11816 AUTO_TRACE();
11817 Doxygen::globalNamespaceDef = createNamespaceDef("<globalScope>",1,1,"<globalScope>");
11828
11829 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11830
11831 /* Set the global html file extension. */
11832 Doxygen::htmlFileExtension = Config_getString(HTML_FILE_EXTENSION);
11833
11834
11836 Config_getBool(CALLER_GRAPH) ||
11837 Config_getBool(REFERENCES_RELATION) ||
11838 Config_getBool(REFERENCED_BY_RELATION);
11839
11840 /**************************************************************************
11841 * Add custom extension mappings
11842 **************************************************************************/
11843
11844 const StringVector &extMaps = Config_getList(EXTENSION_MAPPING);
11845 for (const auto &mapping : extMaps)
11846 {
11847 QCString mapStr = mapping;
11848 int i=mapStr.find('=');
11849 if (i==-1)
11850 {
11851 continue;
11852 }
11853 else
11854 {
11855 QCString ext = mapStr.left(i).stripWhiteSpace().lower();
11856 QCString language = mapStr.mid(i+1).stripWhiteSpace().lower();
11857 if (ext.isEmpty() || language.isEmpty())
11858 {
11859 continue;
11860 }
11861
11862 if (!updateLanguageMapping(ext,language))
11863 {
11864 err("Failed to map file extension '{}' to unsupported language '{}'.\n"
11865 "Check the EXTENSION_MAPPING setting in the config file.\n",
11866 ext,language);
11867 }
11868 else
11869 {
11870 msg("Adding custom extension mapping: '{}' will be treated as language '{}'\n",
11871 ext,language);
11872 }
11873 }
11874 }
11875 // create input file exncodings
11876
11877 // check INPUT_ENCODING
11878 void *cd = portable_iconv_open("UTF-8",Config_getString(INPUT_ENCODING).data());
11879 if (cd==reinterpret_cast<void *>(-1))
11880 {
11881 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
11882 "Check the 'INPUT_ENCODING' setting in the config file!\n",
11883 Config_getString(INPUT_ENCODING),strerror(errno));
11884 }
11885 else
11886 {
11888 }
11889
11890 // check and split INPUT_FILE_ENCODING
11891 const StringVector &fileEncod = Config_getList(INPUT_FILE_ENCODING);
11892 for (const auto &mapping : fileEncod)
11893 {
11894 QCString mapStr = mapping;
11895 int i=mapStr.find('=');
11896 if (i==-1)
11897 {
11898 continue;
11899 }
11900 else
11901 {
11902 QCString pattern = mapStr.left(i).stripWhiteSpace().lower();
11903 QCString encoding = mapStr.mid(i+1).stripWhiteSpace().lower();
11904 if (pattern.isEmpty() || encoding.isEmpty())
11905 {
11906 continue;
11907 }
11908 cd = portable_iconv_open("UTF-8",encoding.data());
11909 if (cd==reinterpret_cast<void *>(-1))
11910 {
11911 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
11912 "Check the 'INPUT_FILE_ENCODING' setting in the config file!\n",
11913 encoding,strerror(errno));
11914 }
11915 else
11916 {
11918 }
11919
11920 Doxygen::inputFileEncodingList.emplace_back(pattern, encoding);
11921 }
11922 }
11923
11924 // add predefined macro name to a dictionary
11925 const StringVector &expandAsDefinedList =Config_getList(EXPAND_AS_DEFINED);
11926 for (const auto &s : expandAsDefinedList)
11927 {
11929 }
11930
11931 // read aliases and store them in a dictionary
11932 readAliases();
11933
11934 // store number of spaces in a tab into Doxygen::spaces
11935 int tabSize = Config_getInt(TAB_SIZE);
11936 Doxygen::spaces.resize(tabSize);
11937 for (int sp=0; sp<tabSize; sp++) Doxygen::spaces.at(sp)=' ';
11938 Doxygen::spaces.at(tabSize)='\0';
11939}
void readAliases()
Definition aliases.cpp:161
static FileNameLinkedMap * plantUmlFileNameLinkedMap
Definition doxygen.h:109
static StringUnorderedSet expandAsDefinedSet
Definition doxygen.h:119
static InputFileEncodingList inputFileEncodingList
Definition doxygen.h:138
static FileNameLinkedMap * dotFileNameLinkedMap
Definition doxygen.h:106
static FileNameLinkedMap * imageNameLinkedMap
Definition doxygen.h:105
static FileNameLinkedMap * mscFileNameLinkedMap
Definition doxygen.h:107
static FileNameLinkedMap * mermaidFileNameLinkedMap
Definition doxygen.h:110
static QCString spaces
Definition doxygen.h:133
static FileNameLinkedMap * diaFileNameLinkedMap
Definition doxygen.h:108
static QCString htmlFileExtension
Definition doxygen.h:122
static std::unique_ptr< NamespaceDef > globalNamespaceDef
Definition doxygen.h:120
static FileNameLinkedMap * includeNameLinkedMap
Definition doxygen.h:101
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:102
Ordered dictionary of FileName objects.
Definition filename.h:69
QCString lower() const
Definition qcstring.h:253
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:176
#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:73
#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 QCString &defFileName, int defLine, int defColumn, const QCString &name, const QCString &ref, const QCString &refFile, const QCString &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 QCString &extension, const QCString &language)
Definition util.cpp:5130

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

Referenced by main().

◆ applyMemberOverrideOptions()

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

Definition at line 1960 of file doxygen.cpp.

1961{
1962 root->commandOverrides.apply_callGraph ([&](bool b) { md->overrideCallGraph(b); });
1963 root->commandOverrides.apply_callerGraph ([&](bool b) { md->overrideCallerGraph(b); });
1964 root->commandOverrides.apply_referencedByRelation([&](bool b) { md->overrideReferencedByRelation(b); });
1965 root->commandOverrides.apply_referencesRelation ([&](bool b) { md->overrideReferencesRelation(b); });
1966 root->commandOverrides.apply_inlineSource ([&](bool b) { md->overrideInlineSource(b); });
1967 root->commandOverrides.apply_enumValues ([&](bool b) { md->overrideEnumValues(b); });
1968}
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 5352 of file doxygen.cpp.

5353{
5354 for (const auto &cd : *Doxygen::classLinkedMap)
5355 {
5356 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5357 if (cdm)
5358 {
5359 func(cdm);
5360 }
5361 }
5362
5363 for (const auto &cd : *Doxygen::conceptLinkedMap)
5364 {
5365 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
5366 if (cdm)
5367 {
5368 func(cdm);
5369 }
5370 }
5371
5372 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5373 {
5374 for (const auto &fd : *fn)
5375 {
5376 func(fd.get());
5377 }
5378 }
5379
5380 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5381 {
5383 if (ndm)
5384 {
5385 func(ndm);
5386 }
5387 }
5388
5389 for (const auto &gd : *Doxygen::groupLinkedMap)
5390 {
5391 func(gd.get());
5392 }
5393
5394 for (const auto &pd : *Doxygen::pageLinkedMap)
5395 {
5396 func(pd.get());
5397 }
5398
5399 for (const auto &dd : *Doxygen::dirLinkedMap)
5400 {
5401 func(dd.get());
5402 }
5403
5404 func(&ModuleManager::instance());
5405}
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:127

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().

◆ buildClassDocList()

void buildClassDocList ( const Entry * root)
static

Definition at line 1151 of file doxygen.cpp.

1152{
1153 if ((root->section.isCompoundDoc()) && !root->name.isEmpty())
1154 {
1155 AUTO_TRACE();
1156 addClassToContext(root);
1157 }
1158 for (const auto &e : root->children()) buildClassDocList(e.get());
1159}
constexpr bool isCompoundDoc() const noexcept
Definition types.h:866
static void addClassToContext(const Entry *root)
Definition doxygen.cpp:939
static void buildClassDocList(const Entry *root)
Definition doxygen.cpp:1151

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

Referenced by buildClassDocList(), and parseInput().

◆ buildClassList()

void buildClassList ( const Entry * root)
static

Definition at line 1141 of file doxygen.cpp.

1142{
1143 if ((root->section.isCompound() || root->section.isObjcImpl()) && !root->name.isEmpty())
1144 {
1145 AUTO_TRACE();
1146 addClassToContext(root);
1147 }
1148 for (const auto &e : root->children()) buildClassList(e.get());
1149}
static void buildClassList(const Entry *root)
Definition doxygen.cpp:1141

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

Referenced by buildClassList(), and parseInput().

◆ buildCompleteMemberLists()

void buildCompleteMemberLists ( )
static

Definition at line 8414 of file doxygen.cpp.

8415{
8416 // merge the member list of base classes into the inherited classes.
8417 for (const auto &cd : *Doxygen::classLinkedMap)
8418 {
8419 if (// !cd->isReference() && // not an external class
8420 cd->subClasses().empty() && // is a root of the hierarchy
8421 !cd->baseClasses().empty()) // and has at least one base class
8422 {
8423 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8424 if (cdm)
8425 {
8426 //printf("*** merging members for %s\n",qPrint(cd->name()));
8427 cdm->mergeMembers();
8428 }
8429 }
8430 }
8431 // now sort the member list of all members for all classes.
8432 for (const auto &cd : *Doxygen::classLinkedMap)
8433 {
8434 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8435 if (cdm)
8436 {
8437 cdm->sortAllMembersList();
8438 }
8439 }
8440}
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 1336 of file doxygen.cpp.

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

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

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

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

Referenced by buildConceptList(), and parseInput().

◆ buildDefineList()

void buildDefineList ( )
static

Definition at line 8777 of file doxygen.cpp.

8778{
8779 AUTO_TRACE();
8780 for (const auto &s : g_inputFiles)
8781 {
8782 auto it = Doxygen::macroDefinitions.find(s);
8784 {
8785 for (const auto &def : it->second)
8786 {
8787 auto md = createMemberDef(
8788 def.fileName,def.lineNr,def.columnNr,
8789 "#define",def.name,def.args,QCString(),
8790 Protection::Public,Specifier::Normal,FALSE,Relationship::Member,MemberType::Define,
8791 ArgumentList(),ArgumentList(),"");
8792 auto mmd = toMemberDefMutable(md.get());
8793
8794 if (!def.args.isEmpty())
8795 {
8796 mmd->moveArgumentList(stringToArgumentList(SrcLangExt::Cpp, def.args));
8797 }
8798 mmd->setInitializer(def.definition);
8799 mmd->setFileDef(def.fileDef);
8800 mmd->setDefinition("#define "+def.name);
8801
8802 MemberName *mn=Doxygen::functionNameLinkedMap->add(def.name);
8803 if (def.fileDef)
8804 {
8805 const MemberList *defMl = def.fileDef->getMemberList(MemberListType::DocDefineMembers());
8806 if (defMl)
8807 {
8808 const MemberDef *defMd = defMl->findRev(def.name);
8809 if (defMd) // definition already stored
8810 {
8811 mmd->setRedefineCount(defMd->redefineCount()+1);
8812 }
8813 }
8814 def.fileDef->insertMember(md.get());
8815 }
8816 AUTO_TRACE_ADD("adding macro {} with definition {}",def.name,def.definition);
8817 mn->push_back(std::move(md));
8818 }
8819 }
8820 }
8821}
static DefinesPerFileList macroDefinitions
Definition doxygen.h:135
virtual int redefineCount() const =0
A list of MemberDef objects as shown in documentation sections.
Definition memberlist.h:125
const MemberDef * findRev(const QCString &name) const
Definition memberlist.h:106
static StringVector g_inputFiles
Definition doxygen.cpp:188

References AUTO_TRACE, AUTO_TRACE_ADD, createMemberDef(), end(), FALSE, 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 3380 of file doxygen.cpp.

3381{
3382 if (!root->name.isEmpty() &&
3383 root->section.isVariable() &&
3384 root->type.find("dictionary<")!=-1 // it's a dictionary
3385 )
3386 {
3387 AUTO_TRACE();
3388 addVariable(root);
3389 }
3390 for (const auto &e : root->children())
3391 if (!e->section.isEnum())
3392 buildDictionaryList(e.get());
3393}
static void buildDictionaryList(const Entry *root)
Definition doxygen.cpp:3380
static void addVariable(const Entry *root, int isFuncPtr=-1)
Definition doxygen.cpp:3007

References addVariable(), AUTO_TRACE, buildDictionaryList(), Entry::children(), QCString::find(), QCString::isEmpty(), Entry::name, Entry::section, and Entry::type.

Referenced by buildDictionaryList(), and parseInput().

◆ buildExampleList()

void buildExampleList ( Entry * root)
static

Definition at line 9832 of file doxygen.cpp.

9833{
9834 if ((root->section.isExample() || root->section.isExampleLineno()) && !root->name.isEmpty())
9835 {
9836 if (Doxygen::exampleLinkedMap->find(root->name))
9837 {
9838 warn(root->fileName,root->startLine,"Example {} was already documented. Ignoring documentation found here.",root->name);
9839 }
9840 else
9841 {
9842 PageDef *pd = Doxygen::exampleLinkedMap->add(root->name,
9843 createPageDef(root->fileName,root->startLine,
9844 root->name,root->brief+root->doc+root->inbodyDocs,root->args));
9845 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9846 pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE));
9848 pd->setLanguage(root->lang);
9849 pd->setShowLineNo(root->section.isExampleLineno());
9850
9851 //we don't add example to groups
9852 //addExampleToGroups(root,pd);
9853 }
9854 }
9855 for (const auto &e : root->children()) buildExampleList(e.get());
9856}
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:98
virtual void setFileName(const QCString &name)=0
virtual void setShowLineNo(bool)=0
static void buildExampleList(Entry *root)
Definition doxygen.cpp:9832
std::unique_ptr< PageDef > createPageDef(const QCString &f, int l, const QCString &n, const QCString &d, const QCString &t)
Definition pagedef.cpp:82
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3525

References DefinitionMutable::addSectionsToDefinition(), Entry::anchors, Entry::args, Entry::brief, Entry::briefFile, Entry::briefLine, buildExampleList(), Entry::children(), convertNameToFile(), createPageDef(), Entry::doc, Doxygen::exampleLinkedMap, FALSE, Entry::fileName, Entry::inbodyDocs, QCString::isEmpty(), Entry::lang, Definition::name(), Entry::name, Entry::section, DefinitionMutable::setBriefDescription(), PageDef::setFileName(), DefinitionMutable::setLanguage(), PageDef::setShowLineNo(), Entry::startLine, TRUE, and warn.

Referenced by buildExampleList(), and parseInput().

◆ buildFileList()

void buildFileList ( const Entry * root)
static

Definition at line 503 of file doxygen.cpp.

504{
505 if ((root->section.isFileDoc() || (root->section.isFile() && Config_getBool(EXTRACT_ALL))) &&
506 !root->name.isEmpty() && !root->tagInfo() // skip any file coming from tag files
507 )
508 {
509 bool ambig = false;
511 if (!fd || ambig)
512 {
513 bool save_ambig = ambig;
514 // use the directory of the file to see if the described file is in the same
515 // directory as the describing file.
516 QCString fn = root->fileName;
517 int newIndex=fn.findRev('/');
518 if (newIndex<0)
519 {
520 fn = root->name;
521 }
522 else
523 {
524 fn = fn.left(newIndex)+"/"+root->name;
525 }
527 if (!fd) ambig = save_ambig;
528 }
529 //printf("**************** root->name=%s fd=%p\n",qPrint(root->name),(void*)fd);
530 if (fd && !ambig)
531 {
532 //printf("Adding documentation!\n");
533 // using FALSE in setDocumentation is small hack to make sure a file
534 // is documented even if a \file command is used without further
535 // documentation
536 fd->setDocumentation(root->doc,root->docFile,root->docLine,FALSE);
537 fd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
539 fd->setRefItems(root->sli);
541 root->commandOverrides.apply_includeGraph ([&](bool b) { fd->overrideIncludeGraph(b); });
542 root->commandOverrides.apply_includedByGraph([&](bool b) { fd->overrideIncludedByGraph(b); });
543 for (const Grouping &g : root->groups)
544 {
545 GroupDef *gd=nullptr;
546 if (!g.groupname.isEmpty() && (gd=Doxygen::groupLinkedMap->find(g.groupname)))
547 {
548 if (!gd->containsFile(fd))
549 {
550 gd->addFile(fd);
551 fd->makePartOfGroup(gd);
552 //printf("File %s: in group %s\n",qPrint(fd->name()),qPrint(gd->name()));
553 }
554 }
555 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
556 {
557 warn(root->fileName, root->startLine,
558 "Found non-existing group '{}' for the command '{}', ignoring command",
560 );
561 }
562 }
563 }
564 else
565 {
567 text.sprintf("the name '%s' supplied as "
568 "the argument in the \\file statement ",
569 qPrint(root->name));
570 if (ambig) // name is ambiguous
571 {
572 text+="matches the following input files:\n";
574 text+="\n";
575 text+="Please use a more specific name by "
576 "including a (larger) part of the path!";
577 }
578 else // name is not an input file
579 {
580 text+="is not an input file";
581 }
582 warn(root->fileName,root->startLine,"{}", text);
583 }
584 }
585 for (const auto &e : root->children()) buildFileList(e.get());
586}
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
@ ExplicitSize
Definition qcstring.h:150
static void buildFileList(const Entry *root)
Definition doxygen.cpp:503
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(), 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, QCString::ExplicitSize, FALSE, Entry::fileName, findFileDef(), QCString::findRev(), Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, Doxygen::inputNameLinkedMap, QCString::isEmpty(), EntryType::isFile(), QCString::left(), DefinitionMutable::makePartOfGroup(), Entry::name, FileDef::overrideIncludedByGraph(), FileDef::overrideIncludeGraph(), Grouping::pri, qPrint(), Entry::rqli, Entry::section, DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), showFileDefMatches(), Entry::sli, QCString::sprintf(), Entry::startLine, Entry::tagInfo(), and warn.

Referenced by buildFileList(), and parseInput().

◆ buildFunctionList()

void buildFunctionList ( const Entry * root)
static

Definition at line 3791 of file doxygen.cpp.

3792{
3793 if (root->section.isFunction())
3794 {
3795 AUTO_TRACE("member function: type='{}' scope='{}' name='{}' args='{}' relates='{}' relatesType='{}'"
3796 " file='{}' line={} bodyLine={} #tArgLists={} mGrpId={}"
3797 " spec={} proto={} docFile='{}'",
3798 root->type, root->parent()->name, root->name, root->args, root->relates, root->relatesType,
3799 root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(), root->mGrpId,
3800 root->spec, root->proto, root->docFile);
3801
3802 bool isFriend=root->type=="friend" || root->type.find("friend ")!=-1;
3804 //printf("rname=%s\n",qPrint(rname));
3805
3806 QCString scope;
3807 int index = computeQualifiedIndex(rname);
3808 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
3809 // grouped members are stored with full scope
3810 {
3811 buildScopeFromQualifiedName(rname.left(index+2),root->lang,root->tagInfo());
3812 scope=rname.left(index);
3813 rname=rname.mid(index+2);
3814 }
3815 else
3816 {
3817 scope=root->parent()->name; //stripAnonymousNamespaceScope(root->parent->name);
3818 }
3819 if (!rname.isEmpty() && scope.find('@')==-1)
3820 {
3821 // check if this function's parent is a class
3822 if (root->lang==SrcLangExt::CSharp)
3823 {
3824 scope=mangleCSharpGenericName(scope);
3825 }
3826 else
3827 {
3829 }
3830
3831 FileDef *rfd=root->fileDef();
3832
3833 int memIndex=rname.findRev("::");
3834
3836 if (cd && scope+"::"==rname.left(scope.length()+2)) // found A::f inside A
3837 {
3838 // strip scope from name
3839 rname=rname.right(rname.length()-root->parent()->name.length()-2);
3840 }
3841
3842 bool isMember=FALSE;
3843 if (memIndex!=-1)
3844 {
3845 int ts=rname.find('<');
3846 int te=rname.find('>');
3847 if (memIndex>0 && (ts==-1 || te==-1))
3848 {
3849 // note: the following code was replaced by inMember=TRUE to deal with a
3850 // function rname='X::foo' of class X inside a namespace also called X...
3851 // bug id 548175
3852 //nd = Doxygen::namespaceLinkedMap->find(rname.left(memIndex));
3853 //isMember = nd==nullptr;
3854 //if (nd)
3855 //{
3856 // // strip namespace scope from name
3857 // scope=rname.left(memIndex);
3858 // rname=rname.right(rname.length()-memIndex-2);
3859 //}
3860 isMember = TRUE;
3861 }
3862 else
3863 {
3864 isMember=memIndex<ts || memIndex>te;
3865 }
3866 }
3867
3868 if (!root->parent()->name.isEmpty() && root->parent()->section.isCompound() && cd)
3869 {
3870 AUTO_TRACE_ADD("member '{}' of class '{}'", rname,cd->name());
3871 addMethodToClass(root,cd,root->type,rname,root->args,isFriend,
3872 root->protection,root->isStatic,root->virt,root->spec,root->relates);
3873 }
3874 else if (root->parent()->section.isObjcImpl() && cd)
3875 {
3876 const MemberDef *md = cd->getMemberByName(rname);
3877 if (md)
3878 {
3879 MemberDefMutable *mdm = toMemberDefMutable(const_cast<MemberDef*>(md));
3880 if (mdm)
3881 {
3882 mdm->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3883 mdm->setBodyDef(root->fileDef());
3884 }
3885 }
3886 }
3887 else if (!root->parent()->section.isCompound() && !root->parent()->section.isObjcImpl() &&
3888 !isMember &&
3889 (root->relates.isEmpty() || root->relatesType==RelatesType::Duplicate) &&
3890 !root->type.startsWith("extern ") && !root->type.startsWith("typedef ")
3891 )
3892 // no member => unrelated function
3893 {
3894 /* check the uniqueness of the function name in the file.
3895 * A file could contain a function prototype and a function definition
3896 * or even multiple function prototypes.
3897 */
3898 bool found=FALSE;
3899 MemberDef *md_found=nullptr;
3900 MemberName *mn = Doxygen::functionNameLinkedMap->find(rname);
3901 if (mn)
3902 {
3903 AUTO_TRACE_ADD("function '{}' already found",rname);
3904 for (const auto &imd : *mn)
3905 {
3906 MemberDefMutable *md = toMemberDefMutable(imd.get());
3907 if (md)
3908 {
3909 const NamespaceDef *mnd = md->getNamespaceDef();
3910 NamespaceDef *rnd = nullptr;
3911 //printf("root namespace=%s\n",qPrint(rootNav->parent()->name()));
3912 QCString fullScope = scope;
3913 QCString parentScope = root->parent()->name;
3914 if (!parentScope.isEmpty() && !leftScopeMatch(parentScope,scope))
3915 {
3916 if (!scope.isEmpty()) fullScope.prepend("::");
3917 fullScope.prepend(parentScope);
3918 }
3919 //printf("fullScope=%s\n",qPrint(fullScope));
3920 rnd = getResolvedNamespace(fullScope);
3921 const FileDef *mfd = md->getFileDef();
3922 QCString nsName,rnsName;
3923 if (mnd) nsName = mnd->name();
3924 if (rnd) rnsName = rnd->name();
3925 //printf("matching arguments for %s%s %s%s\n",
3926 // qPrint(md->name()),md->argsString(),qPrint(rname),qPrint(argListToString(root->argList)));
3927 const ArgumentList &mdAl = md->argumentList();
3928 const ArgumentList &mdTempl = md->templateArguments();
3929
3930 // in case of template functions, we need to check if the
3931 // functions have the same number of template parameters
3932 bool sameTemplateArgs = TRUE;
3933 bool matchingReturnTypes = TRUE;
3934 bool sameRequiresClause = TRUE;
3935 if (!mdTempl.empty() && !root->tArgLists.empty())
3936 {
3937 sameTemplateArgs = matchTemplateArguments(mdTempl,root->tArgLists.back());
3938 if (md->typeString()!=removeRedundantWhiteSpace(root->type))
3939 {
3940 matchingReturnTypes = FALSE;
3941 }
3942 if (md->requiresClause()!=root->req)
3943 {
3944 sameRequiresClause = FALSE;
3945 }
3946 }
3947 else if (!mdTempl.empty() || !root->tArgLists.empty())
3948 { // if one has template parameters and the other doesn't then that also counts as a
3949 // difference
3950 sameTemplateArgs = FALSE;
3951 }
3952
3953 bool staticsInDifferentFiles =
3954 root->isStatic && md->isStatic() && root->fileName!=md->getDefFileName();
3955
3956 if (sameTemplateArgs &&
3957 matchingReturnTypes &&
3958 sameRequiresClause &&
3959 !staticsInDifferentFiles &&
3960 matchArguments2(md->getOuterScope(),mfd,md->typeString(),&mdAl,
3961 rnd ? rnd : Doxygen::globalScope,rfd,root->type,&root->argList,
3962 FALSE,root->lang)
3963 )
3964 {
3965 GroupDef *gd=nullptr;
3966 if (!root->groups.empty() && !root->groups.front().groupname.isEmpty())
3967 {
3968 gd = Doxygen::groupLinkedMap->find(root->groups.front().groupname);
3969 }
3970 //printf("match!\n");
3971 //printf("mnd=%p rnd=%p nsName=%s rnsName=%s\n",mnd,rnd,qPrint(nsName),qPrint(rnsName));
3972 // see if we need to create a new member
3973 found=(mnd && rnd && nsName==rnsName) || // members are in the same namespace
3974 ((mnd==nullptr && rnd==nullptr && mfd!=nullptr && // no external reference and
3975 mfd->absFilePath()==root->fileName // prototype in the same file
3976 )
3977 );
3978 // otherwise, allow a duplicate global member with the same argument list
3979 if (!found && gd && gd==md->getGroupDef() && nsName==rnsName)
3980 {
3981 // member is already in the group, so we don't want to add it again.
3982 found=TRUE;
3983 }
3984
3985 AUTO_TRACE_ADD("combining function with prototype found={} in namespace '{}'",found,nsName);
3986
3987 if (found)
3988 {
3989 // merge argument lists
3990 ArgumentList mergedArgList = root->argList;
3991 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.isEmpty());
3992 // merge documentation
3993 if (md->documentation().isEmpty() && !root->doc.isEmpty())
3994 {
3995 if (root->proto)
3996 {
3998 }
3999 else
4000 {
4002 }
4003 }
4004
4005 md->setDocumentation(root->doc,root->docFile,root->docLine);
4007 md->setDocsForDefinition(!root->proto);
4008 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
4009 {
4010 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
4011 md->setBodyDef(rfd);
4012 }
4013
4014 if (md->briefDescription().isEmpty() && !root->brief.isEmpty())
4015 {
4016 md->setArgsString(root->args);
4017 }
4018 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
4019
4021
4023 md->addQualifiers(root->qualifiers);
4024
4025 // merge ingroup specifiers
4026 if (md->getGroupDef()==nullptr && !root->groups.empty())
4027 {
4028 addMemberToGroups(root,md);
4029 }
4030 else if (md->getGroupDef()!=nullptr && root->groups.empty())
4031 {
4032 //printf("existing member is grouped, new member not\n");
4033 }
4034 else if (md->getGroupDef()!=nullptr && !root->groups.empty())
4035 {
4036 //printf("both members are grouped\n");
4037 }
4039
4040 // if md is a declaration and root is the corresponding
4041 // definition, then turn md into a definition.
4042 if (md->isPrototype() && !root->proto)
4043 {
4044 md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn());
4045 md->setPrototype(FALSE,root->fileName,root->startLine,root->startColumn);
4046 }
4047 // if md is already the definition, then add the declaration info
4048 else if (!md->isPrototype() && root->proto)
4049 {
4050 md->setDeclFile(root->fileName,root->startLine,root->startColumn);
4051 }
4052 }
4053 }
4054 }
4055 if (found)
4056 {
4057 md_found = md;
4058 break;
4059 }
4060 }
4061 }
4062 if (!found) /* global function is unique with respect to the file */
4063 {
4064 addGlobalFunction(root,rname,scope);
4065 }
4066 else
4067 {
4068 FileDef *fd=root->fileDef();
4069 if (fd)
4070 {
4071 // add member to the file (we do this even if we have already
4072 // inserted it into the namespace)
4073 fd->insertMember(md_found);
4074 }
4075 }
4076
4077 AUTO_TRACE_ADD("unrelated function type='{}' name='{}' args='{}'",root->type,rname,root->args);
4078 }
4079 else
4080 {
4081 AUTO_TRACE_ADD("function '{}' is not processed",rname);
4082 }
4083 }
4084 else if (rname.isEmpty())
4085 {
4086 warn(root->fileName,root->startLine,
4087 "Illegal member name found."
4088 );
4089 }
4090 }
4091 for (const auto &e : root->children()) buildFunctionList(e.get());
4092}
virtual const MemberDef * getMemberByName(const QCString &) const =0
Returns the member with the given name.
virtual QCString briefDescription(bool abbreviate=FALSE) const =0
virtual QCString documentation() const =0
virtual bool isPrototype() const =0
virtual void setPrototype(bool p, const QCString &df, int line, int column)=0
virtual void setArgsString(const QCString &as)=0
virtual void moveDeclArgumentList(std::unique_ptr< ArgumentList > al)=0
static void addGlobalFunction(const Entry *root, const QCString &rname, const QCString &sc)
Definition doxygen.cpp:3682
static void buildFunctionList(const Entry *root)
Definition doxygen.cpp:3791
bool matchTemplateArguments(const ArgumentList &srcAl, const ArgumentList &dstAl)
Definition util.cpp:2275

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(), Entry::endBodyLine, FALSE, Entry::fileDef(), Entry::fileName, QCString::find(), QCString::findRev(), 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(), QCString::isEmpty(), MemberDef::isPrototype(), Entry::isStatic, MemberDef::isStatic(), Entry::lang, QCString::left(), leftScopeMatch(), QCString::length(), mangleCSharpGenericName(), matchArguments2(), matchTemplateArguments(), mergeArguments(), Entry::mGrpId, QCString::mid(), MemberDefMutable::moveArgumentList(), MemberDefMutable::moveDeclArgumentList(), Definition::name(), Entry::name, Entry::parent(), QCString::prepend(), Entry::protection, Entry::proto, Entry::qualifiers, Entry::relates, Entry::relatesType, removeRedundantWhiteSpace(), Entry::req, MemberDef::requiresClause(), QCString::right(), 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, QCString::startsWith(), stringToArgumentList(), stripTemplateSpecifiersFromScope(), Entry::tagInfo(), Entry::tArgLists, MemberDef::templateArguments(), toMemberDefMutable(), TRUE, Entry::type, MemberDef::typeString(), Entry::virt, and warn.

Referenced by buildFunctionList(), and parseInput().

◆ buildGroupList()

void buildGroupList ( const Entry * root)
static

Definition at line 432 of file doxygen.cpp.

433{
434 // --- first process only local groups
435 // first process the @defgroups blocks
437 // then process the @addtogroup, @weakgroup blocks
439
440 // --- then also process external groups
441 // first process the @defgroups blocks
443 // then process the @addtogroup, @weakgroup blocks
445}
static void buildGroupListFiltered(const Entry *root, bool additional, bool includeExternal)
Definition doxygen.cpp:361

References buildGroupListFiltered(), FALSE, and TRUE.

Referenced by parseInput().

◆ buildGroupListFiltered()

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

Definition at line 361 of file doxygen.cpp.

362{
363 if (root->section.isGroupDoc() && !root->name.isEmpty() &&
364 ((!includeExternal && root->tagInfo()==nullptr) ||
365 ( includeExternal && root->tagInfo()!=nullptr))
366 )
367 {
368 AUTO_TRACE("additional={} includeExternal={}",additional,includeExternal);
369 if ((root->groupDocType==Entry::GROUPDOC_NORMAL && !additional) ||
370 (root->groupDocType!=Entry::GROUPDOC_NORMAL && additional))
371 {
372 GroupDef *gd = Doxygen::groupLinkedMap->find(root->name);
373 AUTO_TRACE_ADD("Processing group '{}':'{}' gd={}", root->type,root->name,(void*)gd);
374
375 if (gd)
376 {
377 if ( !gd->hasGroupTitle() )
378 {
379 gd->setGroupTitle( root->type );
380 }
381 else if ( root->type.length() > 0 && root->name != root->type && gd->groupTitle() != root->type )
382 {
383 warn( root->fileName,root->startLine,
384 "group {}: ignoring title \"{}\" that does not match old title \"{}\"",
385 root->name, root->type, gd->groupTitle() );
386 }
387 gd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
388 gd->setDocumentation( root->doc, root->docFile, root->docLine );
389 gd->setInbodyDocumentation( root->inbodyDocs, root->inbodyFile, root->inbodyLine );
391 gd->setRefItems(root->sli);
393 gd->setLanguage(root->lang);
395 {
396 root->commandOverrides.apply_groupGraph([&](bool b) { gd->overrideGroupGraph(b); });
397 }
398 }
399 else
400 {
401 if (root->tagInfo())
402 {
403 gd = Doxygen::groupLinkedMap->add(root->name,
404 std::unique_ptr<GroupDef>(
405 createGroupDef(root->fileName,root->startLine,root->name,root->type,root->tagInfo()->fileName)));
406 gd->setReference(root->tagInfo()->tagName);
407 }
408 else
409 {
410 gd = Doxygen::groupLinkedMap->add(root->name,
411 std::unique_ptr<GroupDef>(
412 createGroupDef(root->fileName,root->startLine,root->name,root->type)));
413 }
414 gd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
415 // allow empty docs for group
416 gd->setDocumentation(!root->doc.isEmpty() ? root->doc : QCString(" "),root->docFile,root->docLine,FALSE);
417 gd->setInbodyDocumentation( root->inbodyDocs, root->inbodyFile, root->inbodyLine );
419 gd->setRefItems(root->sli);
421 gd->setLanguage(root->lang);
423 {
424 root->commandOverrides.apply_groupGraph([&](bool b) { gd->overrideGroupGraph(b); });
425 }
426 }
427 }
428 }
429 for (const auto &e : root->children()) buildGroupListFiltered(e.get(),additional,includeExternal);
430}
virtual void setReference(const QCString &r)=0
GroupDocType groupDocType
Definition entry.h:232
@ GROUPDOC_NORMAL
defgroup
Definition entry.h:122
virtual QCString groupTitle() const =0
virtual void overrideGroupGraph(bool e)=0
virtual void setGroupTitle(const QCString &newtitle)=0
virtual bool hasGroupTitle() const =0
std::unique_ptr< GroupDef > createGroupDef(const QCString &fileName, int line, const QCString &name, const QCString &title, const QCString &refFileName)
Definition groupdef.cpp:178

References 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, FALSE, Entry::fileName, TagInfo::fileName, Entry::GROUPDOC_NORMAL, Entry::groupDocType, Doxygen::groupLinkedMap, GroupDef::groupTitle(), GroupDef::hasGroupTitle(), Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, QCString::isEmpty(), Entry::lang, QCString::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 3494 of file doxygen.cpp.

3495{
3496 if (root->section.isExportedInterface() || root->section.isIncludedService())
3497 {
3498 AUTO_TRACE("Exported interface/included service: type='{}' scope='{}' name='{}' args='{}'"
3499 " relates='{}' relatesType='{}' file='{}' line={} bodyLine={} #tArgLists={}"
3500 " mGrpId={} spec={} proto={} docFile='{}'",
3501 root->type, root->parent()->name, root->name, root->args,
3502 root->relates, root->relatesType, root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(),
3503 root->mGrpId, root->spec, root->proto, root->docFile);
3504
3506
3507 if (!rname.isEmpty())
3508 {
3509 QCString scope = root->parent()->name;
3510 ClassDefMutable *cd = getClassMutable(scope);
3511 assert(cd);
3512 if (cd && ((ClassDef::Interface == cd->compoundType()) ||
3513 (ClassDef::Service == cd->compoundType()) ||
3515 {
3517 }
3518 else
3519 {
3520 assert(false); // was checked by scanner.l
3521 }
3522 }
3523 else if (rname.isEmpty())
3524 {
3525 warn(root->fileName,root->startLine,
3526 "Illegal member name found.");
3527 }
3528 }
3529 // can only have these in IDL anyway
3530 switch (root->lang)
3531 {
3532 case SrcLangExt::Unknown: // fall through (root node always is Unknown)
3533 case SrcLangExt::IDL:
3534 for (const auto &e : root->children()) buildInterfaceAndServiceList(e.get());
3535 break;
3536 default:
3537 return; // nothing to do here
3538 }
3539}
@ Singleton
Definition classdef.h:117
@ Interface
Definition classdef.h:112
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, QCString const &rname)
Definition doxygen.cpp:3431
static void buildInterfaceAndServiceList(const Entry *root)
Definition doxygen.cpp:3494

References addInterfaceOrServiceToServiceOrSingleton(), Entry::args, AUTO_TRACE, Entry::bodyLine, buildInterfaceAndServiceList(), Entry::children(), ClassDef::compoundType(), Entry::docFile, Entry::fileName, getClassMutable(), ClassDef::Interface, QCString::isEmpty(), 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 1855 of file doxygen.cpp.

1856{
1857 if (root->section.isUsingDecl() &&
1858 !root->parent()->section.isCompound() // not a class/struct member
1859 )
1860 {
1861 QCString name = substitute(root->name,".","::");
1862 g_usingDeclarations.insert(name.str());
1863 }
1864 for (const auto &e : root->children()) buildListOfUsingDecls(e.get());
1865}
static StringSet g_usingDeclarations
Definition doxygen.cpp:190
static void buildListOfUsingDecls(const Entry *root)
Definition doxygen.cpp:1855

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

Referenced by buildListOfUsingDecls(), and parseInput().

◆ buildNamespaceList()

void buildNamespaceList ( const Entry * root)
static

Definition at line 1530 of file doxygen.cpp.

1531{
1532 if (
1533 (root->section.isNamespace() ||
1534 root->section.isNamespaceDoc() ||
1535 root->section.isPackageDoc()
1536 ) &&
1537 !root->name.isEmpty()
1538 )
1539 {
1540 AUTO_TRACE("name={}",root->name);
1541
1542 QCString fName = root->name;
1543 if (root->section.isPackageDoc())
1544 {
1545 fName=substitute(fName,".","::");
1546 }
1547
1548 QCString fullName = stripAnonymousNamespaceScope(fName);
1549 if (!fullName.isEmpty())
1550 {
1551 AUTO_TRACE_ADD("Found namespace {} in {} at line {}",root->name,root->fileName,root->startLine);
1552 NamespaceDef *ndi = Doxygen::namespaceLinkedMap->find(fullName);
1553 if (ndi) // existing namespace
1554 {
1556 if (nd) // non-inline namespace
1557 {
1558 AUTO_TRACE_ADD("Existing namespace");
1559 nd->setDocumentation(root->doc,root->docFile,root->docLine);
1560 nd->setName(fullName); // change name to match docs
1562 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1563 if (nd->getLanguage()==SrcLangExt::Unknown)
1564 {
1565 nd->setLanguage(root->lang);
1566 }
1567 if (root->tagInfo()==nullptr && nd->isReference() && !(root->doc.isEmpty() && root->brief.isEmpty()))
1568 // if we previously found namespace nd in a tag file and now we find a
1569 // documented namespace with the same name in the project, then remove
1570 // the tag file reference
1571 {
1572 nd->setReference("");
1573 nd->setFileName(fullName);
1574 }
1575 nd->setMetaData(root->metaData);
1576
1577 // file definition containing the namespace nd
1578 FileDef *fd=root->fileDef();
1579 if (nd->isArtificial())
1580 {
1581 nd->setArtificial(FALSE); // found namespace explicitly, so cannot be artificial
1582 nd->setDefFile(root->fileName,root->startLine,root->startColumn);
1583 }
1584 // insert the namespace in the file definition
1585 if (fd) fd->insertNamespace(nd);
1586 addNamespaceToGroups(root,nd);
1587 nd->setRefItems(root->sli);
1588 nd->setRequirementReferences(root->rqli);
1589 }
1590 }
1591 else // fresh namespace
1592 {
1593 QCString tagName;
1594 QCString tagFileName;
1595 const TagInfo *tagInfo = root->tagInfo();
1596 if (tagInfo)
1597 {
1598 tagName = tagInfo->tagName;
1599 tagFileName = tagInfo->fileName;
1600 }
1601 AUTO_TRACE_ADD("new namespace {} lang={} tagName={}",fullName,langToString(root->lang),tagName);
1602 // add namespace to the list
1604 Doxygen::namespaceLinkedMap->add(fullName,
1605 createNamespaceDef(tagInfo?tagName:root->fileName,root->startLine,
1606 root->startColumn,fullName,tagName,tagFileName,
1607 root->type,root->spec.isPublished())));
1608 if (nd)
1609 {
1610 nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1611 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1613 nd->setHidden(root->hidden);
1614 nd->setArtificial(root->artificial);
1615 nd->setLanguage(root->lang);
1616 nd->setId(root->id);
1617 nd->setMetaData(root->metaData);
1618 nd->setInline(root->spec.isInline());
1619 nd->setExported(root->exported);
1620
1621 addNamespaceToGroups(root,nd);
1622 nd->setRefItems(root->sli);
1623 nd->setRequirementReferences(root->rqli);
1624
1625 // file definition containing the namespace nd
1626 FileDef *fd=root->fileDef();
1627 // insert the namespace in the file definition
1628 if (fd) fd->insertNamespace(nd);
1629
1630 // the empty string test is needed for extract all case
1631 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1632 nd->insertUsedFile(fd);
1633 nd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1634 nd->setBodyDef(fd);
1635
1636 // also add namespace to the correct structural context
1637 Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName,nullptr,tagInfo);
1638 AUTO_TRACE_ADD("adding namespace {} to context {}",nd->name(),d ? d->name() : QCString("<none>"));
1639 if (d==nullptr) // we didn't find anything, create the scope artificially
1640 // anyway, so we can at least relate scopes properly.
1641 {
1642 d = buildScopeFromQualifiedName(fullName,nd->getLanguage(),tagInfo);
1644 if (dm)
1645 {
1646 dm->addInnerCompound(nd);
1647 }
1648 nd->setOuterScope(d);
1649 // TODO: Due to the order in which the tag file is written
1650 // a nested class can be found before its parent!
1651 }
1652 else
1653 {
1655 if (dm)
1656 {
1657 dm->addInnerCompound(nd);
1658 }
1659 nd->setOuterScope(d);
1660 // in case of d is an inline namespace, alias insert nd in the part scope of d.
1662 {
1663 NamespaceDef *pnd = toNamespaceDef(d);
1664 if (pnd && pnd->isInline())
1665 {
1666 d = d->getOuterScope();
1667 if (d)
1668 {
1669 dm = toDefinitionMutable(d);
1670 if (dm)
1671 {
1672 auto aliasNd = createNamespaceDefAlias(d,nd);
1673 dm->addInnerCompound(aliasNd.get());
1674 QCString aliasName = aliasNd->name();
1675 AUTO_TRACE_ADD("adding alias {} to {}",aliasName,d->name());
1676 Doxygen::namespaceLinkedMap->add(aliasName,std::move(aliasNd));
1677 }
1678 }
1679 else
1680 {
1681 break;
1682 }
1683 }
1684 else
1685 {
1686 break;
1687 }
1688 }
1689 }
1690 }
1691 }
1692 }
1693 }
1694 for (const auto &e : root->children()) buildNamespaceList(e.get());
1695}
virtual bool isArtificial() const =0
virtual bool isReference() const =0
virtual void setExported(bool b)=0
virtual void setName(const QCString &name)=0
bool exported
is the symbol exported from a C++20 module
Definition entry.h:190
virtual void insertNamespace(NamespaceDef *nd)=0
virtual bool isInline() const =0
virtual void insertUsedFile(FileDef *fd)=0
virtual void setMetaData(const QCString &m)=0
virtual void setInline(bool isInline)=0
virtual void setFileName(const QCString &fn)=0
static void buildNamespaceList(const Entry *root)
Definition doxygen.cpp:1530
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)
QCString langToString(SrcLangExt lang)
Returns a string representation of lang.
Definition util.cpp:5913

References 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, Entry::endBodyLine, Entry::exported, FALSE, Entry::fileDef(), Entry::fileName, TagInfo::fileName, findScopeFromQualifiedName(), Definition::getLanguage(), Definition::getOuterScope(), Doxygen::globalScope, Entry::hidden, Entry::id, FileDef::insertNamespace(), NamespaceDefMutable::insertUsedFile(), Definition::isArtificial(), QCString::isEmpty(), NamespaceDef::isInline(), Definition::isReference(), Entry::lang, langToString(), 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 9588 of file doxygen.cpp.

9589{
9590 if (root->section.isPageDoc())
9591 {
9592 if (!root->name.isEmpty())
9593 {
9594 addRelatedPage(root);
9595 }
9596 }
9597 else if (root->section.isMainpageDoc())
9598 {
9599 QCString title=root->args.stripWhiteSpace();
9600 if (title.isEmpty()) title=theTranslator->trMainPage();
9601 //QCString name = Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9602 QCString name = "index";
9603 addRefItem(root->sli,
9604 name,
9605 theTranslator->trPage(TRUE,TRUE),
9606 name,
9607 title,
9608 QCString(),nullptr
9609 );
9610 }
9611 for (const auto &e : root->children()) buildPageList(e.get());
9612}
static void buildPageList(Entry *root)
Definition doxygen.cpp:9588
Translator * theTranslator
Definition language.cpp:71
void addRefItem(const RefItemVector &sli, const QCString &key, const QCString &prefix, const QCString &name, const QCString &title, const QCString &args, const Definition *scope)
Definition util.cpp:4849

References addRefItem(), addRelatedPage(), Entry::args, buildPageList(), Entry::children(), QCString::isEmpty(), Entry::name, Entry::section, Entry::sli, QCString::stripWhiteSpace(), theTranslator, and TRUE.

Referenced by buildPageList(), and parseInput().

◆ buildRequirementsList()

void buildRequirementsList ( Entry * root)
static

Definition at line 9576 of file doxygen.cpp.

9577{
9578 if (root->section.isRequirementDoc())
9579 {
9581 }
9582 for (const auto &e : root->children()) buildRequirementsList(e.get());
9583}
static RequirementManager & instance()
void addRequirement(Entry *e)
static void buildRequirementsList(Entry *root)
Definition doxygen.cpp:9576

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

Referenced by buildRequirementsList(), and parseInput().

◆ buildScopeFromQualifiedName()

Definition * buildScopeFromQualifiedName ( const QCString & 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 713 of file doxygen.cpp.

714{
715 QCString name = stripTemplateSpecifiers(name_);
716 name.stripPrefix("::");
717 int level = name.contains("::");
718 //printf("buildScopeFromQualifiedName(%s) level=%d\n",qPrint(name),level);
719 int i=0, p=0, l=0;
721 QCString fullScope;
722 while (i<level)
723 {
724 int idx=getScopeFragment(name,p,&l);
725 if (idx==-1) return prevScope;
726 QCString nsName = name.mid(idx,l);
727 if (nsName.isEmpty()) return prevScope;
728 if (!fullScope.isEmpty()) fullScope+="::";
729 fullScope+=nsName;
730 NamespaceDef *nd=Doxygen::namespaceLinkedMap->find(fullScope);
731 DefinitionMutable *innerScope = toDefinitionMutable(nd);
732 ClassDef *cd=nullptr;
733 if (nd==nullptr) cd = getClass(fullScope);
734 if (nd==nullptr && cd) // scope is a class
735 {
736 innerScope = toDefinitionMutable(cd);
737 }
738 else if (nd==nullptr && cd==nullptr && fullScope.find('<')==-1) // scope is not known and could be a namespace!
739 {
740 // introduce bogus namespace
741 //printf("++ adding dummy namespace %s to %s tagInfo=%p\n",qPrint(nsName),qPrint(prevScope->name()),(void*)tagInfo);
742 NamespaceDefMutable *newNd=
744 Doxygen::namespaceLinkedMap->add(fullScope,
746 "[generated]",1,1,fullScope,
747 tagInfo?tagInfo->tagName:QCString(),
748 tagInfo?tagInfo->fileName:QCString())));
749 if (newNd)
750 {
751 newNd->setLanguage(lang);
752 newNd->setArtificial(TRUE);
753 // add namespace to the list
754 innerScope = newNd;
755 }
756 }
757 else // scope is a namespace
758 {
759 }
760 if (innerScope)
761 {
762 // make the parent/child scope relation
763 DefinitionMutable *prevScopeMutable = toDefinitionMutable(prevScope);
764 if (prevScopeMutable)
765 {
766 prevScopeMutable->addInnerCompound(toDefinition(innerScope));
767 }
768 innerScope->setOuterScope(prevScope);
769 }
770 else // current scope is a class, so return only the namespace part...
771 {
772 return prevScope;
773 }
774 // proceed to the next scope fragment
775 p=idx+l+2;
776 prevScope=toDefinition(innerScope);
777 i++;
778 }
779 return prevScope;
780}
int contains(char c, bool cs=TRUE) const
Definition qcstring.cpp:148
Definition * toDefinition(DefinitionMutable *dm)
QCString stripTemplateSpecifiers(const QCString &s)
Definition doxygen.cpp:686
int getScopeFragment(const QCString &s, int p, int *l)
Definition util.cpp:4664

References DefinitionMutable::addInnerCompound(), QCString::contains(), createNamespaceDef(), TagInfo::fileName, QCString::find(), getClass(), getScopeFragment(), Doxygen::globalScope, QCString::isEmpty(), QCString::mid(), Doxygen::namespaceLinkedMap, DefinitionMutable::setArtificial(), DefinitionMutable::setLanguage(), DefinitionMutable::setOuterScope(), QCString::stripPrefix(), stripTemplateSpecifiers(), TagInfo::tagName, toDefinition(), toDefinitionMutable(), toNamespaceDefMutable(), and TRUE.

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

◆ buildSequenceList()

void buildSequenceList ( const Entry * root)
static

Definition at line 3362 of file doxygen.cpp.

3363{
3364 if (!root->name.isEmpty() &&
3365 root->section.isVariable() &&
3366 root->type.find("sequence<")!=-1 // it's a sequence
3367 )
3368 {
3369 AUTO_TRACE();
3370 addVariable(root);
3371 }
3372 for (const auto &e : root->children())
3373 if (!e->section.isEnum())
3374 buildSequenceList(e.get());
3375}
static void buildSequenceList(const Entry *root)
Definition doxygen.cpp:3362

References addVariable(), AUTO_TRACE, buildSequenceList(), Entry::children(), QCString::find(), QCString::isEmpty(), Entry::name, Entry::section, and Entry::type.

Referenced by buildSequenceList(), and parseInput().

◆ buildTypedefList()

void buildTypedefList ( const Entry * root)
static

Definition at line 3262 of file doxygen.cpp.

3263{
3264 //printf("buildVarList(%s)\n",qPrint(rootNav->name()));
3265 if (!root->name.isEmpty() &&
3266 root->section.isVariable() &&
3267 root->type.find("typedef ")!=-1 // its a typedef
3268 )
3269 {
3270 AUTO_TRACE();
3272 QCString scope;
3273 int index = computeQualifiedIndex(rname);
3274 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
3275 // grouped members are stored with full scope
3276 {
3277 buildScopeFromQualifiedName(rname.left(index+2),root->lang,root->tagInfo());
3278 scope=rname.left(index);
3279 rname=rname.mid(index+2);
3280 }
3281 else
3282 {
3283 scope=root->parent()->name; //stripAnonymousNamespaceScope(root->parent->name);
3284 }
3287 MemberName *mn = Doxygen::functionNameLinkedMap->find(rname);
3288 bool found=false;
3289 if (mn) // symbol with the same name already found
3290 {
3291 for (auto &imd : *mn)
3292 {
3293 if (!imd->isTypedef())
3294 continue;
3295
3296 QCString rtype = root->type;
3297 rtype.stripPrefix("typedef ");
3298
3299 // merge the typedefs only if they're not both grouped, and both are
3300 // either part of the same class, part of the same namespace, or both
3301 // are global (i.e., neither in a class or a namespace)
3302 bool notBothGrouped = root->groups.empty() || imd->getGroupDef()==nullptr; // see example #100
3303 bool bothSameScope = (!cd && !nd) || (cd && imd->getClassDef() == cd) || (nd && imd->getNamespaceDef() == nd);
3304 //printf("imd->isTypedef()=%d imd->typeString()=%s root->type=%s\n",imd->isTypedef(),
3305 // qPrint(imd->typeString()),qPrint(root->type));
3306 if (notBothGrouped && bothSameScope && imd->typeString()==rtype)
3307 {
3308 MemberDefMutable *md = toMemberDefMutable(imd.get());
3309 if (md)
3310 {
3311 md->setDocumentation(root->doc,root->docFile,root->docLine);
3313 md->setDocsForDefinition(!root->proto);
3314 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3316 md->setRefItems(root->sli);
3317 md->setRequirementReferences(root->rqli);
3318 md->addQualifiers(root->qualifiers);
3319
3320 // merge ingroup specifiers
3321 if (md->getGroupDef()==nullptr && !root->groups.empty())
3322 {
3323 addMemberToGroups(root,md);
3324 }
3325 else if (md->getGroupDef()!=nullptr && root->groups.empty())
3326 {
3327 //printf("existing member is grouped, new member not\n");
3328 }
3329 else if (md->getGroupDef()!=nullptr && !root->groups.empty())
3330 {
3331 //printf("both members are grouped\n");
3332 }
3333 found=true;
3334 break;
3335 }
3336 }
3337 }
3338 }
3339 if (found)
3340 {
3341 AUTO_TRACE_ADD("typedef '{}' already found",rname);
3342 // mark the entry as processed, as we copied everything from it elsewhere
3343 // also, otherwise, due to containing `typedef` it may later get treated
3344 // as a function typedef in filterMemberDocumentation, which is incorrect
3345 root->markAsProcessed();
3346 }
3347 else
3348 {
3349 AUTO_TRACE_ADD("new typedef '{}'",rname);
3350 addVariable(root);
3351 }
3352
3353 }
3354 for (const auto &e : root->children())
3355 if (!e->section.isEnum())
3356 buildTypedefList(e.get());
3357}
static void buildTypedefList(const Entry *root)
Definition doxygen.cpp:3262

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, QCString::find(), Doxygen::functionNameLinkedMap, getClassMutable(), MemberDef::getGroupDef(), getResolvedNamespace(), Entry::groups, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, QCString::isEmpty(), Entry::lang, QCString::left(), Entry::markAsProcessed(), QCString::mid(), Entry::name, 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, QCString::stripPrefix(), Entry::tagInfo(), toMemberDefMutable(), and Entry::type.

Referenced by buildTypedefList(), and parseInput().

◆ buildVarList()

void buildVarList ( const Entry * root)
static

Definition at line 3399 of file doxygen.cpp.

3400{
3401 //printf("buildVarList(%s) section=%08x\n",qPrint(rootNav->name()),rootNav->section());
3402 int isFuncPtr=-1;
3403 if (!root->name.isEmpty() &&
3404 (root->type.isEmpty() || g_compoundKeywords.find(root->type.str())==g_compoundKeywords.end()) &&
3405 (
3406 (root->section.isVariable() && // it's a variable
3407 root->type.find("typedef ")==-1 // and not a typedef
3408 ) ||
3409 (root->section.isFunction() && // or maybe a function pointer variable
3410 (isFuncPtr=findFunctionPtr(root->type.str(),root->lang))!=-1
3411 ) ||
3412 (root->section.isFunction() && // class variable initialized by constructor
3414 )
3415 )
3416 ) // documented variable
3417 {
3418 AUTO_TRACE();
3419 addVariable(root,isFuncPtr);
3420 }
3421 for (const auto &e : root->children())
3422 if (!e->section.isEnum())
3423 buildVarList(e.get());
3424}
static void buildVarList(const Entry *root)
Definition doxygen.cpp:3399
static bool isVarWithConstructor(const Entry *root)
Definition doxygen.cpp:2795
static const StringUnorderedSet g_compoundKeywords
Definition doxygen.cpp:199

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

Referenced by buildVarList(), and parseInput().

◆ checkConfiguration()

void checkConfiguration ( )

check and resolve config options

Definition at line 11803 of file doxygen.cpp.

11804{
11805 AUTO_TRACE();
11806
11811}
void initWarningFormat()
Definition message.cpp:236
void postProcess(bool clearHeaderAndFooter, CompareMode compareMode=CompareMode::Full)
void checkAndCorrect(bool quiet, const bool check)
void updateObsolete()

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

Referenced by main().

◆ checkMarkdownMainfile()

void checkMarkdownMainfile ( )
static

Definition at line 12304 of file doxygen.cpp.

12305{
12306 if (Config_getBool(MARKDOWN_SUPPORT))
12307 {
12308 QCString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
12309 if (mdfileAsMainPage.isEmpty()) return;
12310 FileInfo fi(mdfileAsMainPage.data());
12311 if (!fi.exists())
12312 {
12313 warn_uncond("Specified markdown mainpage '{}' does not exist\n",mdfileAsMainPage);
12314 return;
12315 }
12316 bool ambig = false;
12317 if (findFileDef(Doxygen::inputNameLinkedMap,fi.absFilePath(),ambig)==nullptr)
12318 {
12319 warn_uncond("Specified markdown mainpage '{}' has not been defined as input file\n",mdfileAsMainPage);
12320 return;
12321 }
12322 }
12323}
Minimal replacement for QFileInfo.
Definition fileinfo.h:23
#define warn_uncond(fmt,...)
Definition message.h:122

References FileInfo::absFilePath(), Config_getBool, Config_getString, QCString::data(), FileInfo::exists(), findFileDef(), Doxygen::inputNameLinkedMap, QCString::isEmpty(), and warn_uncond.

Referenced by parseInput().

◆ checkPageRelations()

void checkPageRelations ( )
static

Definition at line 9727 of file doxygen.cpp.

9728{
9729 for (const auto &pd : *Doxygen::pageLinkedMap)
9730 {
9731 Definition *ppd = pd->getOuterScope();
9732 while (ppd)
9733 {
9734 if (ppd==pd.get())
9735 {
9736 term("page defined {} with label {} is a subpage "
9737 "of itself! Please remove this cyclic dependency.\n",
9738 warn_line(pd->docFile(),pd->docLine()),pd->name());
9739 }
9740 ppd=ppd->getOuterScope();
9741 }
9742 }
9743}

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

Referenced by parseInput().

◆ cleanUpDoxygen()

void cleanUpDoxygen ( )

Definition at line 11340 of file doxygen.cpp.

11341{
11345
11346 delete Doxygen::indexList;
11356 Doxygen::mainPage.reset();
11360 Doxygen::globalScope = nullptr;
11362 delete theTranslator;
11363 delete g_outputList;
11364
11369 delete Doxygen::dirLinkedMap;
11370 delete Doxygen::symbolMap;
11371}
static ParserManager * parserManager
Definition doxygen.h:129
static SymbolMap< Definition > * symbolMap
Definition doxygen.h:125
static FormulaManager & instance()
Definition formula.cpp:53
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:189

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

203{
204 g_inputFiles.clear();
205 //g_excludeNameDict.clear();
206 //delete g_outputList; g_outputList=nullptr;
207
212 Doxygen::pageLinkedMap->clear();
226 Doxygen::mainPage.reset();
228}
static CitationManager & instance()
Definition cite.cpp:85
void clear()
clears the database
Definition cite.cpp:110
static StringMap tagDestinationMap
Definition doxygen.h:116
static ClassLinkedMap * hiddenClassLinkedMap
Definition doxygen.h:96

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

9156{
9157 // for each file
9158 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9159 {
9160 for (const auto &fd : *fn)
9161 {
9162 fd->combineUsingRelations();
9163 }
9164 }
9165
9166 // for each namespace
9167 NamespaceDefSet visitedNamespaces;
9168 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9169 {
9171 if (ndm)
9172 {
9173 ndm->combineUsingRelations(visitedNamespaces);
9174 }
9175 }
9176}
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 10226 of file doxygen.cpp.

10227{
10228 std::ofstream f;
10229 bool fileOpened=openOutputFile("-",f);
10230 if (fileOpened)
10231 {
10232 TextStream t(&f);
10233 Config::compareDoxyfile(t,diffList);
10234 }
10235 else
10236 {
10237 term("Cannot open stdout for writing\n");
10238 }
10239}
Text streaming class that buffers data.
Definition textstream.h:36
void compareDoxyfile(TextStream &t, CompareMode compareMode)
bool openOutputFile(const QCString &outFile, std::ofstream &f)
Definition util.cpp:6318

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

Referenced by readConfiguration().

◆ computeClassRelations()

void computeClassRelations ( )
static

Definition at line 5222 of file doxygen.cpp.

5223{
5224 AUTO_TRACE();
5225 for (const auto &[name,root] : g_classEntries)
5226 {
5227 QCString bName = extractClassName(root);
5228 ClassDefMutable *cd = getClassMutable(bName);
5229 if (cd)
5230 {
5232 }
5233 size_t numMembers = cd ? cd->memberNameInfoLinkedMap().size() : 0;
5234 if ((cd==nullptr || (!cd->hasDocumentation() && !cd->isReference())) && numMembers>0 && !bName.endsWith("::"))
5235 {
5236 if (!root->name.isEmpty() && root->name.find('@')==-1 && // normal name
5237 (guessSection(root->fileName).isHeader() ||
5238 Config_getBool(EXTRACT_LOCAL_CLASSES)) && // not defined in source file
5239 protectionLevelVisible(root->protection) && // hidden by protection
5240 !Config_getBool(HIDE_UNDOC_CLASSES) // undocumented class are visible
5241 )
5242 warn_undoc(root->fileName,root->startLine, "Compound {} is not documented.", root->name);
5243 }
5244 }
5245}
virtual const MemberNameInfoLinkedMap & memberNameInfoLinkedMap() const =0
Returns a dictionary of all members.
size_t size() const
Definition linkedmap.h:210
bool endsWith(const char *s) const
Definition qcstring.h:528
static QCString extractClassName(const Entry *root)
Definition doxygen.cpp:5125
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:4579
static std::multimap< std::string, const Entry * > g_classEntries
Definition doxygen.cpp:187
#define warn_undoc(file, line, fmt,...)
Definition message.h:102

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

Referenced by parseInput().

◆ computeMemberReferences()

void computeMemberReferences ( )
static

Definition at line 5316 of file doxygen.cpp.

5317{
5318 AUTO_TRACE();
5319 for (const auto &cd : *Doxygen::classLinkedMap)
5320 {
5321 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5322 if (cdm)
5323 {
5324 cdm->computeAnchors();
5325 }
5326 }
5327 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5328 {
5329 for (const auto &fd : *fn)
5330 {
5331 fd->computeAnchors();
5332 }
5333 }
5334 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5335 {
5337 if (ndm)
5338 {
5339 ndm->computeAnchors();
5340 }
5341 }
5342 for (const auto &gd : *Doxygen::groupLinkedMap)
5343 {
5344 gd->computeAnchors();
5345 }
5346}
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 8357 of file doxygen.cpp.

8358{
8359 for (const auto &cd : *Doxygen::classLinkedMap)
8360 {
8361 if (cd->isLinkable())
8362 {
8363 for (const auto &bcd : cd->baseClasses())
8364 {
8366 }
8367 }
8368 }
8369}
static void computeMemberRelationsForBaseClass(const ClassDef *cd, const BaseClassDef *bcd)
Definition doxygen.cpp:8277

References Doxygen::classLinkedMap, and computeMemberRelationsForBaseClass().

Referenced by parseInput().

◆ computeMemberRelationsForBaseClass()

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

Definition at line 8277 of file doxygen.cpp.

8278{
8279 for (const auto &mn : cd->memberNameInfoLinkedMap()) // for each member in class cd with a unique name
8280 {
8281 for (const auto &imd : *mn) // for each member with a given name
8282 {
8283 MemberDefMutable *md = toMemberDefMutable(imd->memberDef());
8284 if (md && (md->isFunction() || md->isCSharpProperty())) // filter on reimplementable members
8285 {
8286 ClassDef *mbcd = bcd->classDef;
8287 if (mbcd && mbcd->isLinkable()) // filter on linkable classes
8288 {
8289 const auto &bmn = mbcd->memberNameInfoLinkedMap();
8290 const auto &bmni = bmn.find(mn->memberName());
8291 if (bmni) // there are base class members with the same name
8292 {
8293 for (const auto &ibmd : *bmni) // for base class member with that name
8294 {
8295 MemberDefMutable *bmd = toMemberDefMutable(ibmd->memberDef());
8296 if (bmd) // not part of an inline namespace
8297 {
8298 auto lang = bmd->getLanguage();
8299 auto compType = mbcd->compoundType();
8300 if (bmd->virtualness()!=Specifier::Normal ||
8301 lang==SrcLangExt::Python ||
8302 lang==SrcLangExt::Java ||
8303 lang==SrcLangExt::PHP ||
8304 compType==ClassDef::Interface ||
8305 compType==ClassDef::Protocol)
8306 {
8307 const ArgumentList &bmdAl = bmd->argumentList();
8308 const ArgumentList &mdAl = md->argumentList();
8309 //printf(" Base argList='%s'\n Super argList='%s'\n",
8310 // qPrint(argListToString(bmdAl)),
8311 // qPrint(argListToString(mdAl))
8312 // );
8313 if (
8314 lang==SrcLangExt::Python ||
8315 matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),bmd->typeString(),&bmdAl,
8316 md->getOuterScope(), md->getFileDef(), md->typeString(),&mdAl,
8317 TRUE,lang
8318 )
8319 )
8320 {
8321 if (lang==SrcLangExt::Python && md->name().startsWith("__")) continue; // private members do not reimplement
8322 //printf("match!\n");
8323 const MemberDef *rmd = md->reimplements();
8324 if (rmd==nullptr) // not already assigned
8325 {
8326 //printf("%s: setting (new) reimplements member %s\n",qPrint(md->qualifiedName()),qPrint(bmd->qualifiedName()));
8327 md->setReimplements(bmd);
8328 }
8329 //printf("%s: add reimplementedBy member %s\n",qPrint(bmd->qualifiedName()),qPrint(md->qualifiedName()));
8330 bmd->insertReimplementedBy(md);
8331 }
8332 else
8333 {
8334 //printf("no match!\n");
8335 }
8336 }
8337 }
8338 }
8339 }
8340 }
8341 }
8342 }
8343 }
8344
8345 // do also for indirect base classes
8346 for (const auto &bbcd : bcd->classDef->baseClasses())
8347 {
8349 }
8350}
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:60

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(), QCString::startsWith(), toMemberDefMutable(), TRUE, MemberDef::typeString(), and MemberDef::virtualness().

Referenced by computeMemberRelations(), and computeMemberRelationsForBaseClass().

◆ computePageRelations()

void computePageRelations ( Entry * root)
static

Definition at line 9697 of file doxygen.cpp.

9698{
9699 if ((root->section.isPageDoc() || root->section.isMainpageDoc()) && !root->name.isEmpty())
9700 {
9701 PageDef *pd = root->section.isPageDoc() ?
9702 Doxygen::pageLinkedMap->find(root->name) :
9703 Doxygen::mainPage.get();
9704 if (pd)
9705 {
9706 for (const BaseInfo &bi : root->extends)
9707 {
9708 PageDef *subPd = Doxygen::pageLinkedMap->find(bi.name);
9709 if (pd==subPd)
9710 {
9711 term("page defined {} with label {} is a direct "
9712 "subpage of itself! Please remove this cyclic dependency.\n",
9713 warn_line(pd->docFile(),pd->docLine()),pd->name());
9714 }
9715 else if (subPd)
9716 {
9717 pd->addInnerCompound(subPd);
9718 //printf("*** Added subpage relation: %s->%s\n",
9719 // qPrint(pd->name()),qPrint(subPd->name()));
9720 }
9721 }
9722 }
9723 }
9724 for (const auto &e : root->children()) computePageRelations(e.get());
9725}
virtual QCString docFile() const =0
virtual int docLine() const =0
std::vector< BaseInfo > extends
list of base classes
Definition entry.h:221
static void computePageRelations(Entry *root)
Definition doxygen.cpp:9697
QCString name
the name of the base class
Definition entry.h:95

References DefinitionMutable::addInnerCompound(), Entry::children(), computePageRelations(), Definition::docFile(), Definition::docLine(), Entry::extends, QCString::isEmpty(), 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 5247 of file doxygen.cpp.

5248{
5249 AUTO_TRACE();
5250 for (const auto &[name,root] : g_classEntries)
5251 {
5252 QCString bName=stripAnonymousNamespaceScope(root->name);
5255 // strip any anonymous scopes first
5256 if (cd && !cd->getTemplateInstances().empty())
5257 {
5258 AUTO_TRACE_ADD("Template class '{}'",cd->name());
5259 for (const auto &ti : cd->getTemplateInstances()) // for each template instance
5260 {
5261 ClassDefMutable *tcd=toClassDefMutable(ti.classDef);
5262 if (tcd)
5263 {
5264 AUTO_TRACE_ADD("Template instance '{}'",tcd->name());
5265 QCString templSpec = ti.templSpec;
5266 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(tcd->getLanguage(),templSpec);
5267 for (const BaseInfo &bi : root->extends)
5268 {
5269 // check if the base class is a template argument
5270 BaseInfo tbi = bi;
5271 const ArgumentList &tl = cd->templateArguments();
5272 if (!tl.empty())
5273 {
5274 TemplateNameMap baseClassNames = tcd->getTemplateBaseClassNames();
5275 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,bi.name.str());
5276 // for each template name that we inherit from we need to
5277 // substitute the formal with the actual arguments
5278 TemplateNameMap actualTemplateNames;
5279 for (const auto &tn_kv : templateNames)
5280 {
5281 size_t templIndex = tn_kv.second;
5282 Argument actArg;
5283 bool hasActArg=FALSE;
5284 if (templIndex<templArgs->size())
5285 {
5286 actArg=templArgs->at(templIndex);
5287 hasActArg=TRUE;
5288 }
5289 if (hasActArg &&
5290 baseClassNames.find(actArg.type.str())!=baseClassNames.end() &&
5291 actualTemplateNames.find(actArg.type.str())==actualTemplateNames.end()
5292 )
5293 {
5294 actualTemplateNames.emplace(actArg.type.str(),static_cast<int>(templIndex));
5295 }
5296 }
5297
5298 tbi.name = substituteTemplateArgumentsInString(bi.name,tl,templArgs.get());
5299 // find a documented base class in the correct scope
5300 if (!findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE))
5301 {
5302 // no documented base class -> try to find an undocumented one
5303 findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,Undocumented,TRUE);
5304 }
5305 }
5306 }
5307 }
5308 }
5309 }
5310 }
5311}
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:4360
This class contains the information about the argument of a function or template.
Definition arguments.h:27
QCString type
Definition arguments.h:42
QCString substituteTemplateArgumentsInString(const QCString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
Definition util.cpp:4390

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

Referenced by parseInput().

◆ computeTooltipTexts()

void computeTooltipTexts ( )
static

Definition at line 8874 of file doxygen.cpp.

8875{
8876 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8877 if (numThreads>1)
8878 {
8879 ThreadPool threadPool(numThreads);
8880 std::vector < std::future< void > > results;
8881 // queue the work
8882 for (const auto &[name,symList] : *Doxygen::symbolMap)
8883 {
8884 for (const auto &def : symList)
8885 {
8887 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
8888 {
8889 auto processTooltip = [dm]() {
8890 dm->computeTooltip();
8891 };
8892 results.emplace_back(threadPool.queue(processTooltip));
8893 }
8894 }
8895 }
8896 // wait for the results
8897 for (auto &f : results)
8898 {
8899 f.get();
8900 }
8901 }
8902 else
8903 {
8904 for (const auto &[name,symList] : *Doxygen::symbolMap)
8905 {
8906 for (const auto &def : symList)
8907 {
8909 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
8910 {
8911 dm->computeTooltip();
8912 }
8913 }
8914 }
8915 }
8916}
virtual void computeTooltip()=0
Class managing a pool of worker threads.
Definition threadpool.h:48
static bool isSymbolHidden(const Definition *d)
Definition doxygen.cpp:8867

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

Referenced by parseInput().

◆ computeVerifiedDotPath()

void computeVerifiedDotPath ( )
static

Definition at line 10154 of file doxygen.cpp.

10155{
10156 // check dot path
10157 QCString dotPath = Config_getString(DOT_PATH);
10158 if (!dotPath.isEmpty())
10159 {
10160 FileInfo fi(dotPath.str());
10161 if (!(fi.exists() && fi.isFile()) )// not an existing user specified path + exec
10162 {
10163 dotPath = dotPath+"/dot"+Portable::commandExtension();
10164 FileInfo dp(dotPath.str());
10165 if (!dp.exists() || !dp.isFile())
10166 {
10167 warn_uncond("the dot tool could not be found as '{}'\n",dotPath);
10168 dotPath = "dot";
10169 dotPath += Portable::commandExtension();
10170 }
10171 }
10172#if defined(_WIN32) // convert slashes
10173 size_t l=dotPath.length();
10174 for (size_t i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\';
10175#endif
10176 }
10177 else
10178 {
10179 dotPath = "dot";
10180 dotPath += Portable::commandExtension();
10181 }
10182 Doxygen::verifiedDotPath = dotPath;
10184}
static QCString verifiedDotPath
Definition doxygen.h:137
const char * commandExtension()
Definition portable.cpp:461
#define TRACE(...)
Definition trace.h:77

References QCString::at(), Portable::commandExtension(), Config_getString, FileInfo::exists(), QCString::isEmpty(), FileInfo::isFile(), QCString::length(), QCString::str(), TRACE, Doxygen::verifiedDotPath, and warn_uncond.

Referenced by parseInput().

◆ convertToCompoundType()

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

Definition at line 897 of file doxygen.cpp.

898{
900
901 if (specifier.isStruct())
903 else if (specifier.isUnion())
904 sec=ClassDef::Union;
905 else if (specifier.isCategory())
907 else if (specifier.isInterface())
909 else if (specifier.isProtocol())
911 else if (specifier.isException())
913 else if (specifier.isService())
915 else if (specifier.isSingleton())
917
918 if (section.isUnionDoc())
919 sec=ClassDef::Union;
920 else if (section.isStructDoc())
922 else if (section.isInterfaceDoc())
924 else if (section.isProtocolDoc())
926 else if (section.isCategoryDoc())
928 else if (section.isExceptionDoc())
930 else if (section.isServiceDoc())
932 else if (section.isSingletonDoc())
934
935 return sec;
936}
@ Exception
Definition classdef.h:115

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 ( const StringVector & files,
const QCString & filesOption,
const QCString & outputOption,
bool toIndex )
static

Definition at line 10420 of file doxygen.cpp.

10421{
10422 for (const auto &fileName : files)
10423 {
10424 if (!fileName.empty())
10425 {
10426 FileInfo fi(fileName);
10427 if (!fi.exists())
10428 {
10429 err("Extra file '{}' specified in {} does not exist!\n", fileName,filesOption);
10430 }
10431 else if (fi.isDir())
10432 {
10433 err("Extra file '{}' specified in {} is a directory, it has to be a file!\n", fileName,filesOption);
10434 }
10435 else
10436 {
10437 QCString destFileName = outputOption+"/"+fi.fileName();
10438 copyFile(fileName, destFileName);
10439 if (toIndex) Doxygen::indexList->addImageFile(fi.fileName());
10440 }
10441 }
10442 }
10443}
bool copyFile(const QCString &src, const QCString &dest)
Copies the contents of file with name src to the newly created file with name dest.
Definition util.cpp:5879

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

Referenced by generateOutput().

◆ copyIcon()

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

Definition at line 10395 of file doxygen.cpp.

10396{
10397 QCString projectIcon = Config_getString(PROJECT_ICON);
10398 if (!projectIcon.isEmpty())
10399 {
10400 FileInfo fi(projectIcon.str());
10401 if (!fi.exists())
10402 {
10403 err("Project icon '{}' specified by PROJECT_ICON does not exist!\n",projectIcon);
10404 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10405 }
10406 else if (fi.isDir())
10407 {
10408 err("Project icon '{}' specified by PROJECT_ICON is a directory, it has to be a file!\n",projectIcon);
10409 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10410 }
10411 else
10412 {
10413 QCString destFileName = outputOption+"/"+fi.fileName();
10414 copyFile(projectIcon,destFileName);
10415 if (toIndex) Doxygen::indexList->addImageFile(fi.fileName());
10416 }
10417 }
10418}
#define Config_updateString(name, value)
Definition config.h:39

References Config_getString, Config_updateString, copyFile(), err, FileInfo::exists(), FileInfo::fileName(), Doxygen::indexList, FileInfo::isDir(), QCString::isEmpty(), and QCString::str().

Referenced by generateOutput().

◆ copyLatexStyleSheet()

void copyLatexStyleSheet ( )
static

Definition at line 10286 of file doxygen.cpp.

10287{
10288 const StringVector &latexExtraStyleSheet = Config_getList(LATEX_EXTRA_STYLESHEET);
10289 for (const auto &sheet : latexExtraStyleSheet)
10290 {
10291 std::string fileName = sheet;
10292 if (!fileName.empty())
10293 {
10294 FileInfo fi(fileName);
10295 if (!fi.exists())
10296 {
10297 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET does not exist!\n",fileName);
10298 }
10299 else if (fi.isDir())
10300 {
10301 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET is a directory, it has to be a file!\n", fileName);
10302 }
10303 else
10304 {
10305 QCString destFileName = Config_getString(LATEX_OUTPUT)+"/"+fi.fileName();
10306 if (!checkExtension(fi.fileName(), LATEX_STYLE_EXTENSION))
10307 {
10308 destFileName += LATEX_STYLE_EXTENSION;
10309 }
10310 copyFile(fileName, destFileName);
10311 }
10312 }
10313 }
10314}
#define LATEX_STYLE_EXTENSION
Definition latexgen.h:22
bool checkExtension(const QCString &fName, const QCString &ext)
Definition util.cpp:4941

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 QCString & outputOption,
bool toIndex )
static

Definition at line 10370 of file doxygen.cpp.

10371{
10372 QCString projectLogo = projectLogoFile();
10373 if (!projectLogo.isEmpty())
10374 {
10375 FileInfo fi(projectLogo.str());
10376 if (!fi.exists())
10377 {
10378 err("Project logo '{}' specified by PROJECT_LOGO does not exist!\n",projectLogo);
10379 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10380 }
10381 else if (fi.isDir())
10382 {
10383 err("Project logo '{}' specified by PROJECT_LOGO is a directory, it has to be a file!\n",projectLogo);
10384 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10385 }
10386 else
10387 {
10388 QCString destFileName = outputOption+"/"+fi.fileName();
10389 copyFile(projectLogo,destFileName);
10390 if (toIndex) Doxygen::indexList->addImageFile(fi.fileName());
10391 }
10392 }
10393}
QCString projectLogoFile()
Definition util.cpp:3161

References Config_updateString, copyFile(), err, FileInfo::exists(), FileInfo::fileName(), Doxygen::indexList, FileInfo::isDir(), QCString::isEmpty(), projectLogoFile(), and QCString::str().

Referenced by generateOutput().

◆ copyStyleSheet()

void copyStyleSheet ( )
static

Definition at line 10317 of file doxygen.cpp.

10318{
10319 QCString htmlStyleSheet = Config_getString(HTML_STYLESHEET);
10320 if (!htmlStyleSheet.isEmpty())
10321 {
10322 if (!htmlStyleSheet.startsWith("http:") && !htmlStyleSheet.startsWith("https:"))
10323 {
10324 FileInfo fi(htmlStyleSheet.str());
10325 if (!fi.exists())
10326 {
10327 err("Style sheet '{}' specified by HTML_STYLESHEET does not exist!\n",htmlStyleSheet);
10328 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10329 }
10330 else if (fi.isDir())
10331 {
10332 err("Style sheet '{}' specified by HTML_STYLESHEET is a directory, it has to be a file!\n",htmlStyleSheet);
10333 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10334 }
10335 else
10336 {
10337 QCString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10338 copyFile(htmlStyleSheet,destFileName);
10339 }
10340 }
10341 }
10342 const StringVector &htmlExtraStyleSheet = Config_getList(HTML_EXTRA_STYLESHEET);
10343 for (const auto &sheet : htmlExtraStyleSheet)
10344 {
10345 QCString fileName(sheet);
10346 if (!fileName.isEmpty() && !fileName.startsWith("http:") && !fileName.startsWith("https:"))
10347 {
10348 FileInfo fi(fileName.str());
10349 if (!fi.exists())
10350 {
10351 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET does not exist!\n",fileName);
10352 }
10353 else if (fi.fileName()=="doxygen.css" || fi.fileName()=="tabs.css" || fi.fileName()=="navtree.css")
10354 {
10355 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is already a built-in stylesheet. Please use a different name\n",fi.fileName());
10356 }
10357 else if (fi.isDir())
10358 {
10359 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is a directory, it has to be a file!\n",fileName);
10360 }
10361 else
10362 {
10363 QCString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10364 copyFile(fileName, destFileName);
10365 }
10366 }
10367 }
10368}

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

Referenced by generateOutput().

◆ countMembers()

void countMembers ( )
static

Definition at line 8934 of file doxygen.cpp.

8935{
8936 for (const auto &cd : *Doxygen::classLinkedMap)
8937 {
8938 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8939 if (cdm)
8940 {
8941 cdm->countMembers();
8942 }
8943 }
8944
8945 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8946 {
8948 if (ndm)
8949 {
8950 ndm->countMembers();
8951 }
8952 }
8953
8954 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8955 {
8956 for (const auto &fd : *fn)
8957 {
8958 fd->countMembers();
8959 }
8960 }
8961
8962 for (const auto &gd : *Doxygen::groupLinkedMap)
8963 {
8964 gd->countMembers();
8965 }
8966
8967 auto &mm = ModuleManager::instance();
8968 mm.countMembers();
8969}
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()

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

Definition at line 12054 of file doxygen.cpp.

12057{
12058 QCString result = formatDirName;
12059 if (result.isEmpty())
12060 {
12061 result = baseDirName + defaultDirName;
12062 }
12063 else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':'))
12064 {
12065 result.prepend(baseDirName+"/");
12066 }
12067 Dir formatDir(result.str());
12068 if (!formatDir.exists() && !formatDir.mkdir(result.str()))
12069 {
12070 term("Could not create output directory {}\n", result);
12071 }
12072 return result;
12073}
Class representing a directory in the file system.
Definition dir.h:75

References Dir::exists(), QCString::isEmpty(), QCString::length(), Dir::mkdir(), QCString::prepend(), QCString::str(), and term.

Referenced by parseInput().

◆ createTemplateInstanceMembers()

void createTemplateInstanceMembers ( )
static

Definition at line 8373 of file doxygen.cpp.

8374{
8375 // for each class
8376 for (const auto &cd : *Doxygen::classLinkedMap)
8377 {
8378 // that is a template
8379 for (const auto &ti : cd->getTemplateInstances())
8380 {
8381 ClassDefMutable *tcdm = toClassDefMutable(ti.classDef);
8382 if (tcdm)
8383 {
8384 tcdm->addMembersToTemplateInstance(cd.get(),cd->templateArguments(),ti.templSpec);
8385 }
8386 }
8387 }
8388}
virtual void addMembersToTemplateInstance(const ClassDef *cd, const ArgumentList &templateArguments, const QCString &templSpec)=0

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

Referenced by parseInput().

◆ createUsingMemberImportForClass()

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

Definition at line 1972 of file doxygen.cpp.

1974{
1975 AUTO_TRACE("creating new member {} for class {}",memName,cd->name());
1976 const ArgumentList &templAl = md->templateArguments();
1977 const ArgumentList &al = md->argumentList();
1978 auto newMd = createMemberDef(
1979 fileName,root->startLine,root->startColumn,
1980 md->typeString(),memName,md->argsString(),
1981 md->excpString(),root->protection,root->virt,
1982 md->isStatic(),Relationship::Member,md->memberType(),
1983 templAl,al,root->metaData
1984 );
1985 auto newMmd = toMemberDefMutable(newMd.get());
1986 newMmd->setMemberClass(cd);
1987 cd->insertMember(newMd.get());
1988 if (!root->doc.isEmpty() || !root->brief.isEmpty())
1989 {
1990 newMmd->setDocumentation(root->doc,root->docFile,root->docLine);
1991 newMmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1992 newMmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
1993 }
1994 else
1995 {
1996 newMmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
1997 newMmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
1998 newMmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
1999 }
2000 newMmd->setDefinition(md->definition());
2001 applyMemberOverrideOptions(root,newMmd);
2002 newMmd->addQualifiers(root->qualifiers);
2003 newMmd->setBitfields(md->bitfieldString());
2004 newMmd->addSectionsToDefinition(root->anchors);
2005 newMmd->setBodySegment(md->getDefLine(),md->getStartBodyLine(),md->getEndBodyLine());
2006 newMmd->setBodyDef(md->getBodyDef());
2007 newMmd->setInitializer(md->initializer());
2008 newMmd->setRequiresClause(md->requiresClause());
2009 newMmd->setMaxInitLines(md->initializerLines());
2010 newMmd->setMemberGroupId(root->mGrpId);
2011 newMmd->setMemberSpecifiers(md->getMemberSpecifiers());
2012 newMmd->setVhdlSpecifiers(md->getVhdlSpecifiers());
2013 newMmd->setLanguage(root->lang);
2014 newMmd->setId(root->id);
2015 MemberName *mn = Doxygen::memberNameLinkedMap->add(memName);
2016 mn->push_back(std::move(newMd));
2017}
virtual int getEndBodyLine() const =0
virtual int inbodyLine() const =0
virtual int briefLine() const =0
virtual QCString briefFile() const =0
virtual QCString inbodyFile() const =0
virtual QCString definition() const =0
virtual QCString excpString() const =0
virtual VhdlSpecifier getVhdlSpecifiers() const =0
virtual QCString bitfieldString() const =0
virtual TypeSpecifier getMemberSpecifiers() const =0
virtual int initializerLines() const =0

References 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(), 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(), QCString::isEmpty(), 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().

◆ determineScopeForAnonymousMembers()

void determineScopeForAnonymousMembers ( )
static

Definition at line 8748 of file doxygen.cpp.

8749{
8750 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8751 {
8752 for (const auto &md : *mn)
8753 {
8754 MemberDefMutable *mdm = toMemberDefMutable(md.get());
8755 if (mdm)
8756 {
8758 }
8759 }
8760 }
8761 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8762 {
8763 for (const auto &md : *mn)
8764 {
8765 MemberDefMutable *mdm = toMemberDefMutable(md.get());
8766 if (mdm)
8767 {
8769 }
8770 }
8771 }
8772}
virtual void determineScopeForAnonymousMembers()=0

References MemberDefMutable::determineScopeForAnonymousMembers(), Doxygen::functionNameLinkedMap, Doxygen::memberNameLinkedMap, and toMemberDefMutable().

Referenced by parseInput().

◆ devUsage()

void devUsage ( )
static

Definition at line 11150 of file doxygen.cpp.

11151{
11153 msg("Developer parameters:\n");
11154 msg(" -m dump symbol map\n");
11155 msg(" -b making messages output unbuffered\n");
11156 msg(" -c <file> process input file as a comment block and produce HTML output\n");
11157#if ENABLE_TRACING
11158 msg(" -t [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout)\n");
11159 msg(" -t_time [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout),\n"
11160 " and include time and thread information\n");
11161#endif
11162 msg(" -d <level> enable a debug level, such as (multiple invocations of -d are possible):\n");
11164}
@ Time
Definition debug.h:35
static void printFlags()
Definition debug.cpp:138
static void clearFlag(const DebugMask mask)
Definition debug.cpp:123

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

Referenced by readConfiguration().

◆ distributeClassGroupRelations()

void distributeClassGroupRelations ( )

Definition at line 1496 of file doxygen.cpp.

1497{
1498 //bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
1499 //if (!inlineGroupedClasses) return;
1500 //printf("** distributeClassGroupRelations()\n");
1501
1502 ClassDefSet visitedClasses;
1503 for (const auto &cd : *Doxygen::classLinkedMap)
1504 {
1505 //printf("Checking %s\n",qPrint(cd->name()));
1506 // distribute the group to nested classes as well
1507 if (visitedClasses.find(cd.get())==visitedClasses.end() && !cd->partOfGroups().empty())
1508 {
1509 //printf(" Candidate for merging\n");
1510 GroupDef *gd = cd->partOfGroups().front();
1511 for (auto &ncd : cd->getClasses())
1512 {
1514 if (ncdm && ncdm->partOfGroups().empty())
1515 {
1516 //printf(" Adding %s to group '%s'\n",qPrint(ncd->name()),
1517 // gd->groupTitle());
1518 ncdm->makePartOfGroup(gd);
1519 gd->addClass(ncdm);
1520 }
1521 }
1522 visitedClasses.insert(cd.get()); // only visit every class once
1523 }
1524 }
1525}
virtual const GroupList & partOfGroups() const =0
virtual bool addClass(ClassDef *def)=0
std::unordered_set< const ClassDef * > ClassDefSet
Definition classdef.h:95

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

◆ distributeConceptGroups()

void distributeConceptGroups ( )
static

Definition at line 1348 of file doxygen.cpp.

1349{
1350 AUTO_TRACE();
1351 for (const auto &cd : *Doxygen::conceptLinkedMap)
1352 {
1353 if (cd->groupId()!=DOX_NOGROUP)
1354 {
1355 for (const auto &ocd : *Doxygen::conceptLinkedMap)
1356 {
1357 if (cd!=ocd && cd->groupId()==ocd->groupId() &&
1358 !cd->partOfGroups().empty() && ocd->partOfGroups().empty())
1359 {
1360 ConceptDefMutable *ocdm = toConceptDefMutable(ocd.get());
1361 if (ocdm)
1362 {
1363 for (const auto &gd : cd->partOfGroups())
1364 {
1365 if (gd)
1366 {
1367 AUTO_TRACE_ADD("making concept '{}' part of group '{}'",ocdm->name(),gd->name());
1368 ocdm->makePartOfGroup(gd);
1369 gd->addConcept(ocd.get());
1370 }
1371 }
1372 }
1373 }
1374 }
1375 }
1376 }
1377}
#define DOX_NOGROUP
Definition membergroup.h:27

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

9219{
9220 // for each class
9221 for (const auto &cd : *Doxygen::classLinkedMap)
9222 {
9223 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9224 if (cdm)
9225 {
9227 }
9228 }
9229 // for each file
9230 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9231 {
9232 for (const auto &fd : *fn)
9233 {
9234 fd->distributeMemberGroupDocumentation();
9235 }
9236 }
9237 // for each namespace
9238 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9239 {
9241 if (ndm)
9242 {
9244 }
9245 }
9246 // for each group
9247 for (const auto &gd : *Doxygen::groupLinkedMap)
9248 {
9249 gd->distributeMemberGroupDocumentation();
9250 }
9252}
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 11109 of file doxygen.cpp.

11110{
11111 QCString anchor;
11113 {
11114 MemberDef *md = toMemberDef(d);
11115 anchor=":"+md->anchor();
11116 }
11117 QCString scope;
11118 QCString fn = d->getOutputFileBase();
11121 {
11122 scope = fn;
11123 }
11124 t << "REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
11125 << fn+anchor << "','"
11126 << scope << "','"
11127 << d->name() << "','"
11128 << d->getDefFileName() << "','"
11129 << d->getDefLine()
11130 << "');\n";
11131}
virtual QCString anchor() const =0
virtual QCString getOutputFileBase() const =0
MemberDef * toMemberDef(Definition *d)
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:4946

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

11134{
11135 std::ofstream f = Portable::openOutputStream("symbols.sql");
11136 if (f.is_open())
11137 {
11138 TextStream t(&f);
11139 for (const auto &[name,symList] : *Doxygen::symbolMap)
11140 {
11141 for (const auto &def : symList)
11142 {
11143 dumpSymbol(t,def);
11144 }
11145 }
11146 }
11147}
static void dumpSymbol(TextStream &t, Definition *d)
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:648

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

Referenced by generateOutput().

◆ exitDoxygen()

void exitDoxygen ( )
staticnoexcept

Definition at line 12041 of file doxygen.cpp.

12042{
12043 if (!g_successfulRun) // premature exit
12044 {
12045 Dir thisDir;
12046 msg("Exiting...\n");
12047 if (!Doxygen::filterDBFileName.isEmpty())
12048 {
12049 thisDir.remove(Doxygen::filterDBFileName.str());
12050 }
12051 }
12052}
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:314
static QCString filterDBFileName
Definition doxygen.h:131
static bool g_successfulRun
Definition doxygen.cpp:191

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

Referenced by parseInput().

◆ extractClassName()

QCString extractClassName ( const Entry * root)
static

Definition at line 5125 of file doxygen.cpp.

5126{
5127 // strip any anonymous scopes first
5130 int i=0;
5131 if ((root->lang==SrcLangExt::CSharp || root->lang==SrcLangExt::Java) &&
5132 (i=bName.find('<'))!=-1)
5133 {
5134 // a Java/C# generic class looks like a C++ specialization, so we need to strip the
5135 // template part before looking for matches
5136 if (root->lang==SrcLangExt::CSharp)
5137 {
5138 bName = mangleCSharpGenericName(root->name);
5139 }
5140 else
5141 {
5142 bName = bName.left(i);
5143 }
5144 }
5145 return bName;
5146}

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

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

◆ filterMemberDocumentation()

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

Definition at line 7206 of file doxygen.cpp.

7207{
7208 AUTO_TRACE("root->type='{}' root->inside='{}' root->name='{}' root->args='{}' section={} root->spec={} root->mGrpId={}",
7209 root->type,root->inside,root->name,root->args,root->section,root->spec,root->mGrpId);
7210 //printf("root->parent()->name=%s\n",qPrint(root->parent()->name));
7211 bool isFunc=TRUE;
7212
7213 QCString type = root->type;
7214 QCString args = root->args;
7215 int i=-1, l=0;
7216 if ( // detect func variable/typedef to func ptr
7217 (i=findFunctionPtr(type.str(),root->lang,&l))!=-1
7218 )
7219 {
7220 //printf("Fixing function pointer!\n");
7221 // fix type and argument
7222 args.prepend(type.right(type.length()-i-l));
7223 type=type.left(i+l);
7224 //printf("Results type=%s,name=%s,args=%s\n",qPrint(type),qPrint(root->name),qPrint(args));
7225 isFunc=FALSE;
7226 }
7227 else if ((type.startsWith("typedef ") && args.find('(')!=-1))
7228 // detect function types marked as functions
7229 {
7230 isFunc=FALSE;
7231 }
7232
7233 //printf("Member %s isFunc=%d\n",qPrint(root->name),isFunc);
7234 if (root->section.isMemberDoc())
7235 {
7236 //printf("Documentation for inline member '%s' found args='%s'\n",
7237 // qPrint(root->name),qPrint(args));
7238 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7239 if (type.isEmpty())
7240 {
7241 findMember(root,
7242 relates,
7243 type,
7244 args,
7245 root->name + args + root->exception,
7246 FALSE,
7247 isFunc);
7248 }
7249 else
7250 {
7251 findMember(root,
7252 relates,
7253 type,
7254 args,
7255 type + " " + root->name + args + root->exception,
7256 FALSE,
7257 isFunc);
7258 }
7259 }
7260 else if (root->section.isOverloadDoc())
7261 {
7262 //printf("Overloaded member %s found\n",qPrint(root->name));
7263 findMember(root,
7264 relates,
7265 type,
7266 args,
7267 root->name,
7268 TRUE,
7269 isFunc);
7270 }
7271 else if
7272 ((root->section.isFunction() // function
7273 ||
7274 (root->section.isVariable() && // variable
7275 !type.isEmpty() && // with a type
7276 g_compoundKeywords.find(type.str())==g_compoundKeywords.end() // that is not a keyword
7277 // (to skip forward declaration of class etc.)
7278 )
7279 )
7280 )
7281 {
7282 //printf("Documentation for member '%s' found args='%s' excp='%s'\n",
7283 // qPrint(root->name),qPrint(args),qPrint(root->exception));
7284 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7285 //printf("Inside=%s\n Relates=%s\n",qPrint(root->inside),qPrint(relates));
7286 if (type=="friend class" || type=="friend struct" ||
7287 type=="friend union")
7288 {
7289 findMember(root,
7290 relates,
7291 type,
7292 args,
7293 type+" "+root->name,
7294 FALSE,FALSE);
7295
7296 }
7297 else if (!type.isEmpty())
7298 {
7299 findMember(root,
7300 relates,
7301 type,
7302 args,
7303 type+" "+ root->inside + root->name + args + root->exception,
7304 FALSE,isFunc);
7305 }
7306 else
7307 {
7308 findMember(root,
7309 relates,
7310 type,
7311 args,
7312 root->inside + root->name + args + root->exception,
7313 FALSE,isFunc);
7314 }
7315 }
7316 else if (root->section.isDefine() && !relates.isEmpty())
7317 {
7318 findMember(root,
7319 relates,
7320 type,
7321 args,
7322 root->name + args,
7323 FALSE,
7324 !args.isEmpty());
7325 }
7326 else if (root->section.isVariableDoc())
7327 {
7328 //printf("Documentation for variable %s found\n",qPrint(root->name));
7329 //if (!relates.isEmpty()) printf(" Relates %s\n",qPrint(relates));
7330 findMember(root,
7331 relates,
7332 type,
7333 args,
7334 root->name,
7335 FALSE,
7336 FALSE);
7337 }
7338 else if (root->section.isExportedInterface() ||
7339 root->section.isIncludedService())
7340 {
7341 findMember(root,
7342 relates,
7343 type,
7344 args,
7345 type + " " + root->name,
7346 FALSE,
7347 FALSE);
7348 }
7349 else
7350 {
7351 // skip section
7352 //printf("skip section\n");
7353 }
7354}
QCString inside
name of the class in which documents are found
Definition entry.h:214
static void findMember(const Entry *root, const QCString &relates, const QCString &type, const QCString &args, QCString funcDecl, bool overloaded, bool isFunc)
Definition doxygen.cpp:6580

References Entry::args, AUTO_TRACE, Entry::exception, FALSE, QCString::find(), findFunctionPtr(), findMember(), g_compoundKeywords, Entry::inside, QCString::isEmpty(), Entry::lang, QCString::left(), QCString::length(), Entry::mGrpId, Entry::name, QCString::prepend(), QCString::right(), Entry::section, Entry::spec, QCString::startsWith(), QCString::str(), TRUE, 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 4579 of file doxygen.cpp.

4589{
4590 AUTO_TRACE("name={}",root->name);
4591 // The base class could ofcouse also be a non-nested class
4592 const ArgumentList &formalArgs = masterCd->templateArguments();
4593 for (const BaseInfo &bi : root->extends)
4594 {
4595 //printf("masterCd=%s bi.name='%s' #actualArgs=%d\n",
4596 // qPrint(masterCd->localName()),qPrint(bi.name),actualArgs ? (int)actualArgs->size() : -1);
4597 TemplateNameMap formTemplateNames;
4598 if (templateNames.empty())
4599 {
4600 formTemplateNames = getTemplateArgumentsInName(formalArgs,bi.name.str());
4601 }
4602 BaseInfo tbi = bi;
4603 tbi.name = substituteTemplateArgumentsInString(bi.name,formalArgs,actualArgs);
4604 //printf("masterCd=%p instanceCd=%p bi->name=%s tbi.name=%s\n",(void*)masterCd,(void*)instanceCd,qPrint(bi.name),qPrint(tbi.name));
4605
4606 if (mode==DocumentedOnly)
4607 {
4608 // find a documented base class in the correct scope
4609 if (!findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,DocumentedOnly,isArtificial))
4610 {
4611 // 1.8.2: decided to show inheritance relations even if not documented,
4612 // we do make them artificial, so they do not appear in the index
4613 //if (!Config_getBool(HIDE_UNDOC_RELATIONS))
4614 bool b = Config_getBool(HIDE_UNDOC_RELATIONS) ? TRUE : isArtificial;
4615 //{
4616 // no documented base class -> try to find an undocumented one
4617 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,Undocumented,b);
4618 //}
4619 }
4620 }
4621 else if (mode==TemplateInstances)
4622 {
4623 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,TemplateInstances,isArtificial);
4624 }
4625 }
4626}

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

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

◆ findClassDefinition()

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

Definition at line 5591 of file doxygen.cpp.

5593{
5594 SymbolResolver resolver(fd);
5595 const ClassDef *tcd = resolver.resolveClass(nd,scopeName,true,true);
5596 //printf("findClassDefinition(fd=%s,ns=%s,scopeName=%s)='%s'\n",
5597 // qPrint(fd?fd->name():""),qPrint(nd?nd->name():""),
5598 // qPrint(scopeName),qPrint(tcd?tcd->name():""));
5599 return tcd;
5600}

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

5117{
5118 if (isClassSection(root))
5119 {
5120 g_classEntries.emplace(root->name.str(),root);
5121 }
5122 for (const auto &e : root->children()) findClassEntries(e.get());
5123}
static void findClassEntries(const Entry *root)
Definition doxygen.cpp:5116
static bool isClassSection(const Entry *root)
Definition doxygen.cpp:5094

References Entry::children(), findClassEntries(), g_classEntries, isClassSection(), Entry::name, and QCString::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 4753 of file doxygen.cpp.

4762{
4763 AUTO_TRACE("name={} base={} isArtificial={} mode={}",cd->name(),bi->name,isArtificial,(int)mode);
4764
4765 QCString biName=bi->name;
4766 bool explicitGlobalScope=FALSE;
4767 if (biName.startsWith("::")) // explicit global scope
4768 {
4769 biName=biName.right(biName.length()-2);
4770 explicitGlobalScope=TRUE;
4771 }
4772
4773 Entry *parentNode=root->parent();
4774 bool lastParent=FALSE;
4775 do // for each parent scope, starting with the largest scope
4776 // (in case of nested classes)
4777 {
4778 QCString scopeName= parentNode ? parentNode->name : QCString();
4779 int scopeOffset=explicitGlobalScope ? 0 : static_cast<int>(scopeName.length());
4780 do // try all parent scope prefixes, starting with the largest scope
4781 {
4782 //printf("scopePrefix='%s' biName='%s'\n",
4783 // qPrint(scopeName.left(scopeOffset)),qPrint(biName));
4784
4785 QCString baseClassName=biName;
4786 if (scopeOffset>0)
4787 {
4788 baseClassName.prepend(scopeName.left(scopeOffset)+"::");
4789 }
4790 if (root->lang==SrcLangExt::CSharp)
4791 {
4792 baseClassName = mangleCSharpGenericName(baseClassName);
4793 }
4794 AUTO_TRACE_ADD("cd='{}' baseClassName='{}'",cd->name(),baseClassName);
4795 SymbolResolver resolver(cd->getFileDef());
4796 ClassDefMutable *baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
4797 baseClassName,
4798 mode==Undocumented,
4799 true
4800 );
4801 const MemberDef *baseClassTypeDef = resolver.getTypedef();
4802 QCString templSpec = resolver.getTemplateSpec();
4803 //printf("baseClassName=%s baseClass=%p cd=%p explicitGlobalScope=%d\n",
4804 // qPrint(baseClassName),baseClass,cd,explicitGlobalScope);
4805 //printf(" scope='%s' baseClassName='%s' baseClass=%s templSpec=%s\n",
4806 // cd ? qPrint(cd->name()):"<none>",
4807 // qPrint(baseClassName),
4808 // baseClass?qPrint(baseClass->name()):"<none>",
4809 // qPrint(templSpec)
4810 // );
4811 //if (baseClassName.left(root->name.length())!=root->name ||
4812 // baseClassName.at(root->name.length())!='<'
4813 // ) // Check for base class with the same name.
4814 // // If found then look in the outer scope for a match
4815 // // and prevent recursion.
4816 if (!isRecursiveBaseClass(root->name,baseClassName)
4817 || explicitGlobalScope
4818 // sadly isRecursiveBaseClass always true for UNO IDL ifc/svc members
4819 // (i.e. this is needed for addInterfaceOrServiceToServiceOrSingleton)
4820 || (root->lang==SrcLangExt::IDL &&
4821 (root->section.isExportedInterface() ||
4822 root->section.isIncludedService()))
4823 )
4824 {
4825 AUTO_TRACE_ADD("class relation '{}' inherited/used by '{}' found prot={} virt={} templSpec='{}'",
4826 baseClassName, root->name, bi->prot, bi->virt, templSpec);
4827
4828 int i=findTemplateSpecializationPosition(baseClassName);
4829 int si=baseClassName.findRev("::",i);
4830 if (si==-1) si=0;
4831 if (baseClass==nullptr && static_cast<size_t>(i)!=baseClassName.length())
4832 // base class has template specifiers
4833 {
4834 // TODO: here we should try to find the correct template specialization
4835 // but for now, we only look for the unspecialized base class.
4836 int e=findEndOfTemplate(baseClassName,i+1);
4837 //printf("baseClass==0 i=%d e=%d\n",i,e);
4838 if (e!=-1) // end of template was found at e
4839 {
4840 templSpec = removeRedundantWhiteSpace(baseClassName.mid(i,e-i));
4841 baseClassName = baseClassName.left(i)+baseClassName.right(baseClassName.length()-e);
4842 baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
4843 baseClassName,
4844 mode==Undocumented,
4845 true
4846 );
4847 baseClassTypeDef = resolver.getTypedef();
4848 //printf("baseClass=%p -> baseClass=%s templSpec=%s\n",
4849 // baseClass,qPrint(baseClassName),qPrint(templSpec));
4850 }
4851 }
4852 else if (baseClass && !templSpec.isEmpty()) // we have a known class, but also
4853 // know it is a template, so see if
4854 // we can also link to the explicit
4855 // instance (for instance if a class
4856 // derived from a template argument)
4857 {
4858 //printf("baseClass=%s templSpec=%s\n",qPrint(baseClass->name()),qPrint(templSpec));
4859 ClassDefMutable *templClass=getClassMutable(baseClass->name()+templSpec);
4860 if (templClass)
4861 {
4862 // use the template instance instead of the template base.
4863 baseClass = templClass;
4864 templSpec.clear();
4865 }
4866 }
4867
4868 //printf("cd=%p baseClass=%p\n",cd,baseClass);
4869 bool found=baseClass!=nullptr && (baseClass!=cd || mode==TemplateInstances);
4870 AUTO_TRACE_ADD("1. found={}",found);
4871 if (!found && si!=-1)
4872 {
4873 // replace any namespace aliases
4874 replaceNamespaceAliases(baseClassName);
4875 baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
4876 baseClassName,
4877 mode==Undocumented,
4878 true
4879 );
4880 baseClassTypeDef = resolver.getTypedef();
4881 found=baseClass!=nullptr && baseClass!=cd;
4882 if (found) templSpec = resolver.getTemplateSpec();
4883 }
4884 AUTO_TRACE_ADD("2. found={}",found);
4885
4886 if (!found)
4887 {
4888 baseClass=toClassDefMutable(findClassWithinClassContext(context,cd,baseClassName));
4889 //printf("findClassWithinClassContext(%s,%s)=%p\n",
4890 // qPrint(cd->name()),qPrint(baseClassName),baseClass);
4891 found = baseClass!=nullptr && baseClass!=cd;
4892
4893 }
4894 AUTO_TRACE_ADD("3. found={}",found);
4895 if (!found)
4896 {
4897 // for PHP the "use A\B as C" construct map class C to A::B, so we lookup
4898 // the class name also in the alias mapping.
4899 auto it = Doxygen::namespaceAliasMap.find(baseClassName.str());
4900 if (it!=Doxygen::namespaceAliasMap.end()) // see if it is indeed a class.
4901 {
4902 baseClass=getClassMutable(it->second.alias);
4903 found = baseClass!=nullptr && baseClass!=cd;
4904 }
4905 }
4906 bool isATemplateArgument = templateNames.find(biName.str())!=templateNames.end();
4907
4908 AUTO_TRACE_ADD("4. found={}",found);
4909 if (found)
4910 {
4911 AUTO_TRACE_ADD("Documented base class '{}' templSpec='{}'",biName,templSpec);
4912 // add base class to this class
4913
4914 // if templSpec is not empty then we should "instantiate"
4915 // the template baseClass. A new ClassDef should be created
4916 // to represent the instance. To be able to add the (instantiated)
4917 // members and documentation of a template class
4918 // (inserted in that template class at a later stage),
4919 // the template should know about its instances.
4920 // the instantiation process, should be done in a recursive way,
4921 // since instantiating a template may introduce new inheritance
4922 // relations.
4923 if (!templSpec.isEmpty() && mode==TemplateInstances)
4924 {
4925 // if baseClass is actually a typedef then we should not
4926 // instantiate it, since typedefs are in a different namespace
4927 // see bug531637 for an example where this would otherwise hang
4928 // Doxygen
4929 if (baseClassTypeDef==nullptr)
4930 {
4931 //printf(" => findTemplateInstanceRelation: %s\n",qPrint(baseClass->name()));
4932 findTemplateInstanceRelation(root,context,baseClass,templSpec,templateNames,baseClass->isArtificial());
4933 }
4934 }
4935 else if (mode==DocumentedOnly || mode==Undocumented)
4936 {
4937 //printf(" => insert base class\n");
4938 QCString usedName;
4939 if (baseClassTypeDef)
4940 {
4941 usedName=biName;
4942 //printf("***** usedName=%s templSpec=%s\n",qPrint(usedName),qPrint(templSpec));
4943 }
4944 Protection prot = bi->prot;
4945 if (Config_getBool(SIP_SUPPORT)) prot=Protection::Public;
4946 if (cd!=baseClass && !cd->isSubClass(baseClass) && baseClass->isBaseClass(cd,true,templSpec)==0) // check for recursion, see bug690787
4947 {
4948 AUTO_TRACE_ADD("insertBaseClass name={} prot={} virt={} templSpec={}",usedName,prot,bi->virt,templSpec);
4949 cd->insertBaseClass(baseClass,usedName,prot,bi->virt,templSpec);
4950 // add this class as super class to the base class
4951 baseClass->insertSubClass(cd,prot,bi->virt,templSpec);
4952 }
4953 else
4954 {
4955 warn(root->fileName,root->startLine,
4956 "Detected potential recursive class relation "
4957 "between class {} and base class {}!",
4958 cd->name(),baseClass->name()
4959 );
4960 }
4961 }
4962 return TRUE;
4963 }
4964 else if (mode==Undocumented && (scopeOffset==0 || isATemplateArgument))
4965 {
4966 AUTO_TRACE_ADD("New undocumented base class '{}' baseClassName='{}' templSpec='{}' isArtificial={}",
4967 biName,baseClassName,templSpec,isArtificial);
4968 baseClass=nullptr;
4969 if (isATemplateArgument)
4970 {
4971 baseClass = toClassDefMutable(Doxygen::hiddenClassLinkedMap->find(baseClassName));
4972 if (baseClass==nullptr) // not found (or alias)
4973 {
4974 baseClass= toClassDefMutable(
4975 Doxygen::hiddenClassLinkedMap->add(baseClassName,
4976 createClassDef(root->fileName,root->startLine,root->startColumn,
4977 baseClassName,
4978 ClassDef::Class)));
4979 if (baseClass) // really added (not alias)
4980 {
4981 if (isArtificial) baseClass->setArtificial(TRUE);
4982 baseClass->setLanguage(root->lang);
4983 }
4984 }
4985 }
4986 else
4987 {
4988 baseClass = toClassDefMutable(Doxygen::classLinkedMap->find(baseClassName));
4989 //printf("*** classDDict->find(%s)=%p biName=%s templSpec=%s\n",
4990 // qPrint(baseClassName),baseClass,qPrint(biName),qPrint(templSpec));
4991 if (baseClass==nullptr) // not found (or alias)
4992 {
4993 baseClass = toClassDefMutable(
4994 Doxygen::classLinkedMap->add(baseClassName,
4995 createClassDef(root->fileName,root->startLine,root->startColumn,
4996 baseClassName,
4997 ClassDef::Class)));
4998 if (baseClass) // really added (not alias)
4999 {
5000 if (isArtificial) baseClass->setArtificial(TRUE);
5001 baseClass->setLanguage(root->lang);
5002 si = baseClassName.findRev("::");
5003 if (si!=-1) // class is nested
5004 {
5005 Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),nullptr,root->tagInfo());
5006 if (sd==nullptr || sd==Doxygen::globalScope) // outer scope not found
5007 {
5008 baseClass->setArtificial(TRUE); // see bug678139
5009 }
5010 }
5011 }
5012 }
5013 }
5014 if (baseClass)
5015 {
5016 if (biName.endsWith("-p"))
5017 {
5018 biName="<"+biName.left(biName.length()-2)+">";
5019 }
5020 if (!cd->isSubClass(baseClass) && cd!=baseClass && cd->isBaseClass(baseClass,true,templSpec)==0) // check for recursion
5021 {
5022 AUTO_TRACE_ADD("insertBaseClass name={} prot={} virt={} templSpec={}",biName,bi->prot,bi->virt,templSpec);
5023 // add base class to this class
5024 cd->insertBaseClass(baseClass,biName,bi->prot,bi->virt,templSpec);
5025 // add this class as super class to the base class
5026 baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
5027 }
5028 // the undocumented base was found in this file
5029 baseClass->insertUsedFile(root->fileDef());
5030
5031 Definition *scope = buildScopeFromQualifiedName(baseClass->name(),root->lang,nullptr);
5032 if (scope!=baseClass)
5033 {
5034 baseClass->setOuterScope(scope);
5035 }
5036
5037 if (baseClassName.endsWith("-p"))
5038 {
5040 }
5041 return TRUE;
5042 }
5043 else
5044 {
5045 AUTO_TRACE_ADD("Base class '{}' not created (alias?)",biName);
5046 }
5047 }
5048 else
5049 {
5050 AUTO_TRACE_ADD("Base class '{}' not found",biName);
5051 }
5052 }
5053 else
5054 {
5055 if (mode!=TemplateInstances)
5056 {
5057 warn(root->fileName,root->startLine,
5058 "Detected potential recursive class relation "
5059 "between class {} and base class {}!",
5060 root->name,baseClassName
5061 );
5062 }
5063 // for mode==TemplateInstance this case is quite common and
5064 // indicates a relation between a template class and a template
5065 // instance with the same name.
5066 }
5067 if (scopeOffset==0)
5068 {
5069 scopeOffset=-1;
5070 }
5071 else if ((scopeOffset=scopeName.findRev("::",scopeOffset-1))==-1)
5072 {
5073 scopeOffset=0;
5074 }
5075 //printf("new scopeOffset='%d'",scopeOffset);
5076 } while (scopeOffset>=0);
5077
5078 if (parentNode==nullptr)
5079 {
5080 lastParent=TRUE;
5081 }
5082 else
5083 {
5084 parentNode=parentNode->parent();
5085 }
5086 } while (lastParent);
5087
5088 return FALSE;
5089}
virtual int isBaseClass(const ClassDef *bcd, bool followInstances, const QCString &templSpec=QCString()) 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 namespace this compound is in, or 0 if it has a global scope.
virtual void insertBaseClass(ClassDef *, const QCString &name, Protection p, Specifier s, const QCString &t=QCString())=0
virtual void insertSubClass(ClassDef *, Protection p, Specifier s, const QCString &t=QCString())=0
static NamespaceAliasInfoMap namespaceAliasMap
Definition doxygen.h:113
void clear()
Definition qcstring.h:186
static bool isRecursiveBaseClass(const QCString &scope, const QCString &name)
Definition doxygen.cpp:4711
static void findTemplateInstanceRelation(const Entry *root, Definition *context, ClassDefMutable *templateClass, const QCString &templSpec, const TemplateNameMap &templateNames, bool isArtificial)
Definition doxygen.cpp:4630
static ClassDef * findClassWithinClassContext(Definition *context, ClassDef *cd, const QCString &name)
Definition doxygen.cpp:4388
static int findTemplateSpecializationPosition(const QCString &name)
Definition doxygen.cpp:4723
void replaceNamespaceAliases(QCString &name)
Protection prot
inheritance type
Definition entry.h:96
Specifier virt
virtualness
Definition entry.h:97
Protection
Definition types.h:32

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

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

◆ findClassWithinClassContext()

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

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

Definition at line 4388 of file doxygen.cpp.

4389{
4390 ClassDef *result=nullptr;
4391 if (cd==nullptr)
4392 {
4393 return result;
4394 }
4395 FileDef *fd=cd->getFileDef();
4396 SymbolResolver resolver(fd);
4397 if (context && cd!=context)
4398 {
4399 result = const_cast<ClassDef*>(resolver.resolveClass(context,name,true,true));
4400 }
4401 //printf("1. result=%p\n",result);
4402 if (result==nullptr)
4403 {
4404 result = const_cast<ClassDef*>(resolver.resolveClass(cd,name,true,true));
4405 }
4406 //printf("2. result=%p\n",result);
4407 if (result==nullptr) // try direct class, needed for namespaced classes imported via tag files (see bug624095)
4408 {
4409 result = getClass(name);
4410 }
4411 //printf("3. result=%p\n",result);
4412 //printf("** Trying to find %s within context %s class %s result=%s lookup=%p\n",
4413 // qPrint(name),
4414 // context ? qPrint(context->name()) : "<none>",
4415 // cd ? qPrint(cd->name()) : "<none>",
4416 // result ? qPrint(result->name()) : "<none>",
4417 // Doxygen::classLinkedMap->find(name)
4418 // );
4419 return result;
4420}

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

Referenced by findClassRelation(), and findUsedClassesForClass().

◆ findDefineDocumentation()

void findDefineDocumentation ( Entry * root)
static

Definition at line 9428 of file doxygen.cpp.

9429{
9430 if ((root->section.isDefineDoc() || root->section.isDefine()) && !root->name.isEmpty())
9431 {
9432 //printf("found define '%s' '%s' brief='%s' doc='%s'\n",
9433 // qPrint(root->name),qPrint(root->args),qPrint(root->brief),qPrint(root->doc));
9434
9435 if (root->tagInfo() && !root->name.isEmpty()) // define read from a tag file
9436 {
9437 auto md = createMemberDef(root->tagInfo()->tagName,1,1,
9438 "#define",root->name,root->args,QCString(),
9439 Protection::Public,Specifier::Normal,FALSE,Relationship::Member,MemberType::Define,
9440 ArgumentList(),ArgumentList(),"");
9441 auto mmd = toMemberDefMutable(md.get());
9442 mmd->setTagInfo(root->tagInfo());
9443 mmd->setLanguage(root->lang);
9444 mmd->addQualifiers(root->qualifiers);
9445 //printf("Searching for '%s' fd=%p\n",qPrint(filePathName),fd);
9446 mmd->setFileDef(root->parent()->fileDef());
9447 //printf("Adding member=%s\n",qPrint(md->name()));
9449 mn->push_back(std::move(md));
9450 }
9452 if (mn)
9453 {
9454 int count=0;
9455 for (const auto &md : *mn)
9456 {
9457 if (md->memberType()==MemberType::Define) count++;
9458 }
9459 if (count==1)
9460 {
9461 for (const auto &imd : *mn)
9462 {
9463 MemberDefMutable *md = toMemberDefMutable(imd.get());
9464 if (md && md->memberType()==MemberType::Define)
9465 {
9466 addDefineDoc(root,md);
9467 }
9468 }
9469 }
9470 else if (count>1 &&
9471 (!root->doc.isEmpty() ||
9472 !root->brief.isEmpty() ||
9473 root->bodyLine!=-1
9474 )
9475 )
9476 // multiple defines don't know where to add docs
9477 // but maybe they are in different files together with their documentation
9478 {
9479 for (const auto &imd : *mn)
9480 {
9481 MemberDefMutable *md = toMemberDefMutable(imd.get());
9482 if (md && md->memberType()==MemberType::Define)
9483 {
9484 if (haveEqualFileNames(root, md) || isEntryInGroupOfMember(root, md))
9485 // doc and define in the same file or group assume they belong together.
9486 {
9487 addDefineDoc(root,md);
9488 }
9489 }
9490 }
9491 //warn("define {} found in the following files:\n",root->name);
9492 //warn("Cannot determine where to add the documentation found "
9493 // "at line {} of file {}. \n",
9494 // root->startLine,root->fileName);
9495 }
9496 }
9497 else if (!root->doc.isEmpty() || !root->brief.isEmpty()) // define not found
9498 {
9499 bool preEnabled = Config_getBool(ENABLE_PREPROCESSING);
9500 if (preEnabled)
9501 {
9502 warn(root->fileName,root->startLine,"documentation for unknown define {} found.",root->name);
9503 }
9504 else
9505 {
9506 warn(root->fileName,root->startLine, "found documented #define {} but ignoring it because ENABLE_PREPROCESSING is NO.", root->name);
9507 }
9508 }
9509 }
9510 for (const auto &e : root->children()) findDefineDocumentation(e.get());
9511}
static void findDefineDocumentation(Entry *root)
Definition doxygen.cpp:9428
static void addDefineDoc(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:9401
static bool haveEqualFileNames(const Entry *root, const MemberDef *md)
Definition doxygen.cpp:9390
static bool isEntryInGroupOfMember(const Entry *root, const MemberDef *md, bool allowNoGroup=false)
Definition doxygen.cpp:5606

References addDefineDoc(), Entry::args, Entry::bodyLine, Entry::brief, Entry::children(), Config_getBool, createMemberDef(), Entry::doc, FALSE, Entry::fileDef(), Entry::fileName, findDefineDocumentation(), Doxygen::functionNameLinkedMap, haveEqualFileNames(), QCString::isEmpty(), 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 8001 of file doxygen.cpp.

8002{
8003 // for each member name
8004 for (const auto &mn : mnsd)
8005 {
8006 // for each member definition
8007 for (const auto &imd : *mn)
8008 {
8009 MemberDefMutable *md = toMemberDefMutable(imd.get());
8010 if (md && md->isEnumerate()) // member is an enum
8011 {
8012 int documentedEnumValues=0;
8013 // for each enum value
8014 for (const auto &fmd : md->enumFieldList())
8015 {
8016 if (fmd->isLinkableInProject()) documentedEnumValues++;
8017 }
8018 // at least one enum value is documented
8019 if (documentedEnumValues>0) md->setDocumentedEnumValues(TRUE);
8020 }
8021 }
8022 }
8023}
virtual const MemberVector & enumFieldList() const =0
virtual void setDocumentedEnumValues(bool value)=0

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

Referenced by findDocumentedEnumValues().

◆ findDirDocumentation()

void findDirDocumentation ( const Entry * root)
static

Definition at line 9515 of file doxygen.cpp.

9516{
9517 if (root->section.isDirDoc())
9518 {
9519 QCString normalizedName = root->name;
9520 normalizedName = substitute(normalizedName,"\\","/");
9521 //printf("root->docFile=%s normalizedName=%s\n",
9522 // qPrint(root->docFile),qPrint(normalizedName));
9523 if (root->docFile==normalizedName) // current dir?
9524 {
9525 int lastSlashPos=normalizedName.findRev('/');
9526 if (lastSlashPos!=-1) // strip file name
9527 {
9528 normalizedName=normalizedName.left(lastSlashPos);
9529 }
9530 }
9531 if (normalizedName.at(normalizedName.length()-1)!='/')
9532 {
9533 normalizedName+='/';
9534 }
9535 DirDef *matchingDir=nullptr;
9536 for (const auto &dir : *Doxygen::dirLinkedMap)
9537 {
9538 //printf("Dir: %s<->%s\n",qPrint(dir->name()),qPrint(normalizedName));
9539 if (dir->name().right(normalizedName.length())==normalizedName)
9540 {
9541 if (matchingDir)
9542 {
9543 warn(root->fileName,root->startLine,
9544 "\\dir command matches multiple directories.\n"
9545 " Applying the command for directory {}\n"
9546 " Ignoring the command for directory {}",
9547 matchingDir->name(),dir->name()
9548 );
9549 }
9550 else
9551 {
9552 matchingDir=dir.get();
9553 }
9554 }
9555 }
9556 if (matchingDir)
9557 {
9558 //printf("Match for with dir %s #anchor=%zu\n",qPrint(matchingDir->name()),root->anchors.size());
9559 matchingDir->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9560 matchingDir->setDocumentation(root->doc,root->docFile,root->docLine);
9561 matchingDir->setRefItems(root->sli);
9562 matchingDir->setRequirementReferences(root->rqli);
9563 matchingDir->addSectionsToDefinition(root->anchors);
9564 root->commandOverrides.apply_directoryGraph([&](bool b) { matchingDir->overrideDirectoryGraph(b); });
9565 addDirToGroups(root,matchingDir);
9566 }
9567 else
9568 {
9569 warn(root->fileName,root->startLine,"No matching directory found for command \\dir {}",normalizedName);
9570 }
9571 }
9572 for (const auto &e : root->children()) findDirDocumentation(e.get());
9573}
A model of a directory symbol.
Definition dirdef.h:110
virtual void overrideDirectoryGraph(bool e)=0
static void findDirDocumentation(const Entry *root)
Definition doxygen.cpp:9515
void addDirToGroups(const Entry *root, DirDef *dd)

References addDirToGroups(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, QCString::at(), Entry::brief, Entry::briefFile, Entry::briefLine, Entry::children(), Entry::commandOverrides, Doxygen::dirLinkedMap, Entry::doc, Entry::docFile, Entry::docLine, Entry::fileName, findDirDocumentation(), QCString::findRev(), QCString::left(), QCString::length(), Definition::name(), Entry::name, DirDef::overrideDirectoryGraph(), 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 8027 of file doxygen.cpp.

8028{
8031}
static void findDEV(const MemberNameLinkedMap &mnsd)
Definition doxygen.cpp:8001

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

Referenced by parseInput().

◆ findEndOfTemplate()

int findEndOfTemplate ( const QCString & 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<"<">
Class<'<'>
Class<(")<")>

Definition at line 2939 of file doxygen.cpp.

2940{
2941 // locate end of template
2942 size_t e=startPos;
2943 int brCount=1;
2944 int roundCount=0;
2945 size_t len = s.length();
2946 bool insideString=FALSE;
2947 bool insideChar=FALSE;
2948 char pc = 0;
2949 while (e<len && brCount!=0)
2950 {
2951 char c=s.at(e);
2952 switch(c)
2953 {
2954 case '<':
2955 if (!insideString && !insideChar)
2956 {
2957 if (e<len-1 && s.at(e+1)=='<')
2958 e++;
2959 else if (roundCount==0)
2960 brCount++;
2961 }
2962 break;
2963 case '>':
2964 if (!insideString && !insideChar)
2965 {
2966 if (e<len-1 && s.at(e+1)=='>')
2967 e++;
2968 else if (roundCount==0)
2969 brCount--;
2970 }
2971 break;
2972 case '(':
2973 if (!insideString && !insideChar)
2974 roundCount++;
2975 break;
2976 case ')':
2977 if (!insideString && !insideChar)
2978 roundCount--;
2979 break;
2980 case '"':
2981 if (!insideChar)
2982 {
2983 if (insideString && pc!='\\')
2984 insideString=FALSE;
2985 else
2986 insideString=TRUE;
2987 }
2988 break;
2989 case '\'':
2990 if (!insideString)
2991 {
2992 if (insideChar && pc!='\\')
2993 insideChar=FALSE;
2994 else
2995 insideChar=TRUE;
2996 }
2997 break;
2998 }
2999 pc = c;
3000 e++;
3001 }
3002 return brCount==0 ? static_cast<int>(e) : -1;
3003}

References QCString::at(), FALSE, QCString::length(), and TRUE.

Referenced by addVariable(), and findClassRelation().

◆ findEnumDocumentation()

void findEnumDocumentation ( const Entry * root)
static

Definition at line 7915 of file doxygen.cpp.

7916{
7917 if (root->section.isEnumDoc() &&
7918 !root->name.isEmpty() &&
7919 root->name.at(0)!='@' // skip anonymous enums
7920 )
7921 {
7922 QCString name;
7923 QCString scope;
7924 int i = root->name.findRev("::");
7925 if (i!=-1) // scope is specified as part of the name
7926 {
7927 name=root->name.right(root->name.length()-i-2); // extract name
7928 scope=root->name.left(i); // extract scope
7929 //printf("Scope='%s' Name='%s'\n",qPrint(scope),qPrint(name));
7930 }
7931 else // just the name
7932 {
7933 name=root->name;
7934 }
7935 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7936 {
7937 if (!scope.isEmpty()) scope.prepend("::");
7938 scope.prepend(root->parent()->name);
7939 }
7940 const ClassDef *cd = getClass(scope);
7941 const NamespaceDef *nd=Doxygen::namespaceLinkedMap->find(scope);
7942 const FileDef *fd = root->fileDef();
7943 AUTO_TRACE("Found docs for enum with name '{}' and scope '{}' in context '{}' cd='{}', nd='{}' fd='{}'",
7944 name,scope,root->parent()->name,
7945 cd ? cd->name() : QCString("<none>"),
7946 nd ? nd->name() : QCString("<none>"),
7947 fd ? fd->name() : QCString("<none>"));
7948
7949 if (!name.isEmpty())
7950 {
7951 bool found = tryAddEnumDocsToGroupMember(root, name);
7952 if (!found)
7953 {
7954 MemberName *mn = cd ? Doxygen::memberNameLinkedMap->find(name) : Doxygen::functionNameLinkedMap->find(name);
7955 if (mn)
7956 {
7957 for (const auto &imd : *mn)
7958 {
7959 MemberDefMutable *md = toMemberDefMutable(imd.get());
7960 if (md && md->isEnumerate())
7961 {
7962 const ClassDef *mcd = md->getClassDef();
7963 const NamespaceDef *mnd = md->getNamespaceDef();
7964 const FileDef *mfd = md->getFileDef();
7965 if (cd && mcd==cd)
7966 {
7967 AUTO_TRACE_ADD("Match found for class scope");
7968 addEnumDocs(root,md);
7969 found = TRUE;
7970 break;
7971 }
7972 else if (cd==nullptr && mcd==nullptr && nd!=nullptr && mnd==nd)
7973 {
7974 AUTO_TRACE_ADD("Match found for namespace scope");
7975 addEnumDocs(root,md);
7976 found = TRUE;
7977 break;
7978 }
7979 else if (cd==nullptr && nd==nullptr && mcd==nullptr && mnd==nullptr && fd==mfd)
7980 {
7981 AUTO_TRACE_ADD("Match found for global scope");
7982 addEnumDocs(root,md);
7983 found = TRUE;
7984 break;
7985 }
7986 }
7987 }
7988 }
7989 }
7990 if (!found)
7991 {
7992 warn(root->fileName,root->startLine, "Documentation for undefined enum '{}' found.", name);
7993 }
7994 }
7995 }
7996 for (const auto &e : root->children()) findEnumDocumentation(e.get());
7997}
static bool tryAddEnumDocsToGroupMember(const Entry *root, const QCString &name)
Definition doxygen.cpp:7882
static void addEnumDocs(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:7840
static void findEnumDocumentation(const Entry *root)
Definition doxygen.cpp:7915

References addEnumDocs(), QCString::at(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::children(), Entry::fileDef(), Entry::fileName, findEnumDocumentation(), QCString::findRev(), Doxygen::functionNameLinkedMap, getClass(), MemberDef::getClassDef(), MemberDef::getFileDef(), MemberDef::getNamespaceDef(), QCString::isEmpty(), MemberDef::isEnumerate(), EntryType::isScope(), QCString::left(), QCString::length(), Doxygen::memberNameLinkedMap, Definition::name(), Entry::name, Doxygen::namespaceLinkedMap, Entry::parent(), QCString::prepend(), QCString::right(), Entry::section, Entry::startLine, toMemberDefMutable(), TRUE, tryAddEnumDocsToGroupMember(), and warn.

Referenced by findEnumDocumentation(), and parseInput().

◆ findEnums()

void findEnums ( const Entry * root)
static

Definition at line 7414 of file doxygen.cpp.

7415{
7416 if (root->section.isEnum())
7417 {
7418 AUTO_TRACE("name={}",root->name);
7419 ClassDefMutable *cd = nullptr;
7420 FileDef *fd = nullptr;
7421 NamespaceDefMutable *nd = nullptr;
7422 MemberNameLinkedMap *mnsd = nullptr;
7423 bool isGlobal = false;
7424 bool isRelated = false;
7425 bool isMemberOf = false;
7426 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
7427
7428 QCString name;
7429 QCString scope;
7430
7431 int i = root->name.findRev("::");
7432 if (i!=-1) // scope is specified
7433 {
7434 scope=root->name.left(i); // extract scope
7435 if (root->lang==SrcLangExt::CSharp)
7436 {
7437 scope = mangleCSharpGenericName(scope);
7438 }
7439 name=root->name.right(root->name.length()-i-2); // extract name
7440 if ((cd=getClassMutable(scope))==nullptr)
7441 {
7443 }
7444 }
7445 else // no scope, check the scope in which the docs where found
7446 {
7447 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7448 {
7449 scope=root->parent()->name;
7450 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7451 }
7452 name=root->name;
7453 }
7454
7455 if (!root->relates.isEmpty())
7456 { // related member, prefix user specified scope
7457 isRelated=TRUE;
7458 isMemberOf=(root->relatesType==RelatesType::MemberOf);
7459 if (getClass(root->relates)==nullptr && !scope.isEmpty())
7460 scope=mergeScopes(scope,root->relates);
7461 else
7462 scope=root->relates;
7463 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7464 }
7465
7466 if (cd && !name.isEmpty()) // found a enum inside a compound
7467 {
7468 //printf("Enum '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
7469 fd=nullptr;
7471 isGlobal=false;
7472 }
7473 else if (nd) // found enum inside namespace
7474 {
7476 isGlobal=true;
7477 }
7478 else // found a global enum
7479 {
7480 fd=root->fileDef();
7482 isGlobal=true;
7483 }
7484
7485 if (!name.isEmpty())
7486 {
7487 // new enum type
7488 AUTO_TRACE_ADD("new enum {} at line {} of {}",name,root->bodyLine,root->fileName);
7489 auto md = createMemberDef(
7490 root->fileName,root->startLine,root->startColumn,
7491 QCString(),name,QCString(),QCString(),
7492 root->protection,Specifier::Normal,FALSE,
7493 isMemberOf ? Relationship::Foreign : isRelated ? Relationship::Related : Relationship::Member,
7494 MemberType::Enumeration,
7496 auto mmd = toMemberDefMutable(md.get());
7497 mmd->setTagInfo(root->tagInfo());
7498 mmd->setLanguage(root->lang);
7499 mmd->setId(root->id);
7500 if (!isGlobal) mmd->setMemberClass(cd); else mmd->setFileDef(fd);
7501 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
7502 mmd->setBodyDef(root->fileDef());
7503 mmd->setMemberSpecifiers(root->spec);
7504 mmd->setVhdlSpecifiers(root->vhdlSpec);
7505 mmd->setEnumBaseType(root->args);
7506 //printf("Enum %s definition at line %d of %s: protection=%d scope=%s\n",
7507 // qPrint(root->name),root->bodyLine,qPrint(root->fileName),root->protection,cd?qPrint(cd->name()):"<none>");
7508 mmd->addSectionsToDefinition(root->anchors);
7509 mmd->setMemberGroupId(root->mGrpId);
7511 mmd->addQualifiers(root->qualifiers);
7512 //printf("%s::setRefItems(%zu)\n",qPrint(md->name()),root->sli.size());
7513 mmd->setRefItems(root->sli);
7514 mmd->setRequirementReferences(root->rqli);
7515 //printf("found enum %s nd=%p\n",qPrint(md->name()),nd);
7516 bool defSet=FALSE;
7517
7518 QCString baseType = root->args;
7519 if (!baseType.isEmpty())
7520 {
7521 baseType.prepend(" : ");
7522 }
7523
7524 if (nd)
7525 {
7526 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES) || root->lang==SrcLangExt::Python)
7527 {
7528 mmd->setDefinition(name+baseType);
7529 }
7530 else
7531 {
7532 mmd->setDefinition(nd->name()+"::"+name+baseType);
7533 }
7534 //printf("definition=%s\n",md->definition());
7535 defSet=TRUE;
7536 mmd->setNamespace(nd);
7537 nd->insertMember(md.get());
7538 }
7539
7540 // even if we have already added the enum to a namespace, we still
7541 // also want to add it to other appropriate places such as file
7542 // or class.
7543 if (isGlobal && (nd==nullptr || !nd->isAnonymous()))
7544 {
7545 if (!defSet) mmd->setDefinition(name+baseType);
7546 if (fd==nullptr && root->parent())
7547 {
7548 fd=root->parent()->fileDef();
7549 }
7550 if (fd)
7551 {
7552 mmd->setFileDef(fd);
7553 fd->insertMember(md.get());
7554 }
7555 }
7556 else if (cd)
7557 {
7558 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES) || root->lang==SrcLangExt::Python)
7559 {
7560 mmd->setDefinition(name+baseType);
7561 }
7562 else
7563 {
7564 mmd->setDefinition(cd->name()+"::"+name+baseType);
7565 }
7566 cd->insertMember(md.get());
7567 cd->insertUsedFile(fd);
7568 }
7569 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
7570 mmd->setDocsForDefinition(!root->proto);
7571 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7572 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
7573
7574 //printf("Adding member=%s\n",qPrint(md->name()));
7575 addMemberToGroups(root,md.get());
7577
7578 MemberName *mn = mnsd->add(name);
7579 mn->push_back(std::move(md));
7580 }
7581 }
7582 else
7583 {
7584 for (const auto &e : root->children()) findEnums(e.get());
7585 }
7586}
static void findEnums(const Entry *root)
Definition doxygen.cpp:7414

References LinkedMap< T, Hash, KeyEqual, Map >::add(), 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, Entry::endBodyLine, FALSE, Entry::fileDef(), Entry::fileName, findEnums(), QCString::findRev(), 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(), QCString::isEmpty(), EntryType::isScope(), Entry::lang, QCString::left(), QCString::length(), mangleCSharpGenericName(), Doxygen::memberNameLinkedMap, mergeScopes(), Entry::metaData, Entry::mGrpId, Definition::name(), Entry::name, Entry::parent(), QCString::prepend(), Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, Entry::relates, Entry::relatesType, QCString::right(), Entry::rqli, Entry::section, Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, Entry::tagInfo(), toMemberDefMutable(), toNamespaceDefMutable(), TRUE, and Entry::vhdlSpec.

Referenced by findEnums(), and parseInput().

◆ findFriends()

void findFriends ( )
static

Definition at line 4096 of file doxygen.cpp.

4097{
4098 AUTO_TRACE();
4099 for (const auto &fn : *Doxygen::functionNameLinkedMap) // for each global function name
4100 {
4101 MemberName *mn = Doxygen::memberNameLinkedMap->find(fn->memberName());
4102 if (mn)
4103 { // there are members with the same name
4104 // for each function with that name
4105 for (const auto &ifmd : *fn)
4106 {
4107 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
4108 // for each member with that name
4109 for (const auto &immd : *mn)
4110 {
4111 MemberDefMutable *mmd = toMemberDefMutable(immd.get());
4112 //printf("Checking for matching arguments
4113 // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n",
4114 // mmd->isRelated(),mmd->isFriend(),mmd->isFunction());
4115 if (fmd && mmd &&
4116 (mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) &&
4117 matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), mmd->typeString(), &mmd->argumentList(),
4118 fmd->getOuterScope(), fmd->getFileDef(), fmd->typeString(), &fmd->argumentList(),
4119 TRUE,mmd->getLanguage()
4120 )
4121
4122 ) // if the member is related and the arguments match then the
4123 // function is actually a friend.
4124 {
4125 AUTO_TRACE_ADD("Merging related global and member '{}' isFriend={} isRelated={} isFunction={}",
4126 mmd->name(),mmd->isFriend(),mmd->isRelated(),mmd->isFunction());
4127 const ArgumentList &mmdAl = mmd->argumentList();
4128 const ArgumentList &fmdAl = fmd->argumentList();
4129 mergeArguments(const_cast<ArgumentList&>(fmdAl),const_cast<ArgumentList&>(mmdAl));
4130
4131 // reset argument lists to add missing default parameters
4132 QCString mmdAlStr = argListToString(mmdAl);
4133 QCString fmdAlStr = argListToString(fmdAl);
4134 mmd->setArgsString(mmdAlStr);
4135 fmd->setArgsString(fmdAlStr);
4136 mmd->moveDeclArgumentList(std::make_unique<ArgumentList>(mmdAl));
4137 fmd->moveDeclArgumentList(std::make_unique<ArgumentList>(fmdAl));
4138 AUTO_TRACE_ADD("friend args='{}' member args='{}'",argListToString(fmd->argumentList()),argListToString(mmd->argumentList()));
4139
4140 if (!fmd->documentation().isEmpty())
4141 {
4142 mmd->setDocumentation(fmd->documentation(),fmd->docFile(),fmd->docLine());
4143 }
4144 else if (!mmd->documentation().isEmpty())
4145 {
4146 fmd->setDocumentation(mmd->documentation(),mmd->docFile(),mmd->docLine());
4147 }
4148 if (mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
4149 {
4150 mmd->setBriefDescription(fmd->briefDescription(),fmd->briefFile(),fmd->briefLine());
4151 }
4152 else if (!mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
4153 {
4154 fmd->setBriefDescription(mmd->briefDescription(),mmd->briefFile(),mmd->briefLine());
4155 }
4156 if (!fmd->inbodyDocumentation().isEmpty())
4157 {
4159 }
4160 else if (!mmd->inbodyDocumentation().isEmpty())
4161 {
4163 }
4164 //printf("body mmd %d fmd %d\n",mmd->getStartBodyLine(),fmd->getStartBodyLine());
4165 if (mmd->getStartBodyLine()==-1 && fmd->getStartBodyLine()!=-1)
4166 {
4167 mmd->setBodySegment(fmd->getDefLine(),fmd->getStartBodyLine(),fmd->getEndBodyLine());
4168 mmd->setBodyDef(fmd->getBodyDef());
4169 //mmd->setBodyMember(fmd);
4170 }
4171 else if (mmd->getStartBodyLine()!=-1 && fmd->getStartBodyLine()==-1)
4172 {
4173 fmd->setBodySegment(mmd->getDefLine(),mmd->getStartBodyLine(),mmd->getEndBodyLine());
4174 fmd->setBodyDef(mmd->getBodyDef());
4175 //fmd->setBodyMember(mmd);
4176 }
4178
4180
4181 mmd->addQualifiers(fmd->getQualifiers());
4182 fmd->addQualifiers(mmd->getQualifiers());
4183
4184 }
4185 }
4186 }
4187 }
4188 }
4189}
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)
Definition util.cpp:6883

References MemberDefMutable::addQualifiers(), argListToString(), MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, Definition::briefDescription(), Definition::briefFile(), Definition::briefLine(), Definition::docFile(), Definition::docLine(), Definition::documentation(), 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(), QCString::isEmpty(), 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(), TRUE, 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 2735 of file doxygen.cpp.

2736{
2737 AUTO_TRACE("type='{}' lang={}",type,lang);
2738 if (lang == SrcLangExt::Fortran || lang == SrcLangExt::VHDL)
2739 {
2740 return -1; // Fortran and VHDL do not have function pointers
2741 }
2742
2743 static const reg::Ex re(R"(\‍([^)]*[*&^][^)]*\))");
2745 size_t i=std::string::npos;
2746 size_t l=0;
2747 if (reg::search(type,match,re)) // contains (...*...) or (...&...) or (...^...)
2748 {
2749 i = match.position();
2750 l = match.length();
2751 }
2752 if (i!=std::string::npos)
2753 {
2754 size_t di = type.find("decltype(");
2755 if (di!=std::string::npos && di<i)
2756 {
2757 i = std::string::npos;
2758 }
2759 }
2760 size_t bb=type.find('<');
2761 size_t be=type.rfind('>');
2762 bool templFp = false;
2763 if (be!=std::string::npos) {
2764 size_t cc_ast = type.find("::*");
2765 size_t cc_amp = type.find("::&");
2766 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>::*)'
2767 }
2768
2769 if (!type.empty() && // return type is non-empty
2770 i!=std::string::npos && // contains (...*...)
2771 type.find("operator")==std::string::npos && // not an operator
2772 (type.find(")(")==std::string::npos || type.find("typedef ")!=std::string::npos) &&
2773 // not a function pointer return type
2774 (!(bb<i && i<be) || templFp) // bug665855: avoid treating "typedef A<void (T*)> type" as a function pointer
2775 )
2776 {
2777 if (pLength) *pLength=static_cast<int>(l);
2778 //printf("findFunctionPtr=%d\n",(int)i);
2779 AUTO_TRACE_EXIT("result={}",i);
2780 return static_cast<int>(i);
2781 }
2782 else
2783 {
2784 //printf("findFunctionPtr=%d\n",-1);
2785 AUTO_TRACE_EXIT("result=-1");
2786 return -1;
2787 }
2788}
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:50

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

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

◆ findGlobalMember()

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

Definition at line 5630 of file doxygen.cpp.

5638{
5639 AUTO_TRACE("namespace='{}' type='{}' name='{}' tempArg='{}' decl='{}'",namespaceName,type,name,tempArg,decl);
5640 QCString n=name;
5641 if (n.isEmpty()) return FALSE;
5642 if (n.find("::")!=-1) return FALSE; // skip undefined class members
5643 MemberName *mn=Doxygen::functionNameLinkedMap->find(n+tempArg); // look in function dictionary
5644 if (mn==nullptr)
5645 {
5646 mn=Doxygen::functionNameLinkedMap->find(n); // try without template arguments
5647 }
5648 if (mn) // function name defined
5649 {
5650 AUTO_TRACE_ADD("Found symbol name");
5651 //int count=0;
5652 bool found=FALSE;
5653 for (const auto &md : *mn)
5654 {
5655 // If the entry has groups, then restrict the search to members which are
5656 // in one of the groups of the entry. If md is not associated with a group yet,
5657 // allow this documentation entry to add the group info.
5658 if (!root->groups.empty() && !isEntryInGroupOfMember(root, md.get(), true))
5659 {
5660 continue;
5661 }
5662
5663 const NamespaceDef *nd=nullptr;
5664 if (md->isAlias() && md->getOuterScope() &&
5665 md->getOuterScope()->definitionType()==Definition::TypeNamespace)
5666 {
5667 nd = toNamespaceDef(md->getOuterScope());
5668 }
5669 else
5670 {
5671 nd = md->getNamespaceDef();
5672 }
5673
5674 // special case for strong enums
5675 int enumNamePos=0;
5676 if (nd && md->isEnumValue() && (enumNamePos=namespaceName.findRev("::"))!=-1)
5677 { // md part of a strong enum in a namespace?
5678 QCString enumName = namespaceName.mid(enumNamePos+2);
5679 if (namespaceName.left(enumNamePos)==nd->name())
5680 {
5681 MemberName *enumMn=Doxygen::functionNameLinkedMap->find(enumName);
5682 if (enumMn)
5683 {
5684 for (const auto &emd : *enumMn)
5685 {
5686 found = emd->isStrong() && md->getEnumScope()==emd.get();
5687 if (found)
5688 {
5689 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,nullptr,FALSE,root->spec);
5690 break;
5691 }
5692 }
5693 }
5694 }
5695 if (found)
5696 {
5697 break;
5698 }
5699 }
5700 else if (nd==nullptr && md->isEnumValue()) // md part of global strong enum?
5701 {
5702 MemberName *enumMn=Doxygen::functionNameLinkedMap->find(namespaceName);
5703 if (enumMn)
5704 {
5705 for (const auto &emd : *enumMn)
5706 {
5707 found = emd->isStrong() && md->getEnumScope()==emd.get();
5708 if (found)
5709 {
5710 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,nullptr,FALSE,root->spec);
5711 break;
5712 }
5713 }
5714 }
5715 }
5716
5717 const FileDef *fd=root->fileDef();
5718 //printf("File %s\n",fd ? qPrint(fd->name()) : "<none>");
5720 if (fd)
5721 {
5722 nl = fd->getUsedNamespaces();
5723 }
5724 //printf("NamespaceList %p\n",nl);
5725
5726 // search in the list of namespaces that are imported via a
5727 // using declaration
5728 bool viaUsingDirective = nd && nl.find(nd->qualifiedName())!=nullptr;
5729
5730 if ((namespaceName.isEmpty() && nd==nullptr) || // not in a namespace
5731 (nd && nd->name()==namespaceName) || // or in the same namespace
5732 viaUsingDirective // member in 'using' namespace
5733 )
5734 {
5735 AUTO_TRACE_ADD("Try to add member '{}' to scope '{}'",md->name(),namespaceName);
5736
5737 NamespaceDef *rnd = nullptr;
5738 if (!namespaceName.isEmpty()) rnd = Doxygen::namespaceLinkedMap->find(namespaceName);
5739
5740 const ArgumentList &mdAl = md.get()->argumentList();
5741 bool matching=
5742 (mdAl.empty() && root->argList.empty()) ||
5743 md->isVariable() || md->isTypedef() || /* in case of function pointers */
5744 matchArguments2(md->getOuterScope(),md->getFileDef(),md->typeString(),&mdAl,
5745 rnd ? rnd : Doxygen::globalScope,fd,root->type,&root->argList,
5746 FALSE,root->lang);
5747
5748 // for template members we need to check if the number of
5749 // template arguments is the same, otherwise we are dealing with
5750 // different functions.
5751 if (matching && !root->tArgLists.empty())
5752 {
5753 const ArgumentList &mdTempl = md->templateArguments();
5754 if (root->tArgLists.back().size()!=mdTempl.size())
5755 {
5756 matching=FALSE;
5757 }
5758 }
5759
5760 //printf("%s<->%s\n",
5761 // qPrint(argListToString(md->argumentList())),
5762 // qPrint(argListToString(root->argList)));
5763
5764 // For static members we also check if the comment block was found in
5765 // the same file. This is needed because static members with the same
5766 // name can be in different files. Thus it would be wrong to just
5767 // put the comment block at the first syntactically matching member. If
5768 // the comment block belongs to a group of the static member, then add
5769 // the documentation even if it is in a different file.
5770 if (matching && md->isStatic() &&
5771 md->getDefFileName()!=root->fileName &&
5772 mn->size()>1 &&
5773 !isEntryInGroupOfMember(root,md.get()))
5774 {
5775 matching = FALSE;
5776 }
5777
5778 // for template member we also need to check the return type and requires
5779 if (!md->templateArguments().empty() && !root->tArgLists.empty())
5780 {
5781 //printf("Comparing return types '%s'<->'%s'\n",
5782 // md->typeString(),type);
5783 //printf("%s: Comparing '%s'<=>'%s'\n",qPrint(md->name()),qPrint(md->requiresClause()),qPrint(root->req));
5784 if (md->templateArguments().size()!=root->tArgLists.back().size() ||
5785 md->typeString()!=type ||
5786 md->requiresClause()!=root->req)
5787 {
5788 //printf(" ---> no matching\n");
5789 matching = FALSE;
5790 }
5791 }
5792
5793 if (matching) // add docs to the member
5794 {
5795 AUTO_TRACE_ADD("Match found");
5796 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,&root->argList,FALSE,root->spec);
5797 found=TRUE;
5798 break;
5799 }
5800 }
5801 }
5802 if (!found && root->relatesType!=RelatesType::Duplicate && root->section.isFunction()) // no match
5803 {
5804 QCString fullFuncDecl=decl;
5805 if (!root->argList.empty()) fullFuncDecl+=argListToString(root->argList,TRUE);
5806 QCString warnMsg = "no matching file member found for \n"+fullFuncDecl;
5807 if (mn->size()>0)
5808 {
5809 warnMsg+="\nPossible candidates:";
5810 for (const auto &md : *mn)
5811 {
5812 warnMsg+="\n '";
5813 warnMsg+=replaceAnonymousScopes(md->declaration());
5814 warnMsg+="' " + warn_line(md->getDefFileName(),md->getDefLine());
5815 }
5816 }
5817 warn(root->fileName,root->startLine, "{}", qPrint(warnMsg));
5818 }
5819 }
5820 else // got docs for an undefined member!
5821 {
5822 if (root->type!="friend class" &&
5823 root->type!="friend struct" &&
5824 root->type!="friend union" &&
5825 root->type!="friend" &&
5826 (!Config_getBool(TYPEDEF_HIDES_STRUCT) ||
5827 root->type.find("typedef ")==-1)
5828 )
5829 {
5830 warn(root->fileName,root->startLine,
5831 "documented symbol '{}' was not declared or defined.",qPrint(decl)
5832 );
5833 }
5834 }
5835 return TRUE;
5836}
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
size_t size() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:173

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

Referenced by findMember().

◆ findGroupScope()

void findGroupScope ( const Entry * root)
static

Definition at line 447 of file doxygen.cpp.

448{
449 if (root->section.isGroupDoc() && !root->name.isEmpty() &&
450 root->parent() && !root->parent()->name.isEmpty())
451 {
452 GroupDef *gd = Doxygen::groupLinkedMap->find(root->name);
453 if (gd)
454 {
455 QCString scope = root->parent()->name;
456 if (root->parent()->section.isPackageDoc())
457 {
458 scope=substitute(scope,".","::");
459 }
460 scope = stripAnonymousNamespaceScope(scope);
461 scope+="::"+gd->name();
463 if (d)
464 {
465 gd->setGroupScope(d);
466 }
467 }
468 }
469 for (const auto &e : root->children()) findGroupScope(e.get());
470}
virtual void setGroupScope(Definition *d)=0
static void findGroupScope(const Entry *root)
Definition doxygen.cpp:447

References Entry::children(), findGroupScope(), findScopeFromQualifiedName(), Doxygen::globalScope, Doxygen::groupLinkedMap, QCString::isEmpty(), 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 2271 of file doxygen.cpp.

2272{
2273 FileDefSet visitedFiles;
2274 // then recursively add using directives found in #include files
2275 // to files that have not been visited.
2276 for (const auto &fn : *Doxygen::inputNameLinkedMap)
2277 {
2278 for (const auto &fd : *fn)
2279 {
2280 //printf("----- adding using directives for file %s\n",qPrint(fd->name()));
2281 fd->addIncludedUsingDirectives(visitedFiles);
2282 }
2283 }
2284}
std::unordered_set< const FileDef * > FileDefSet
Definition filedef.h:44

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

5154{
5155 AUTO_TRACE();
5156 ClassDefSet visitedClasses;
5157 for (const auto &[name,root] : g_classEntries)
5158 {
5159 QCString bName = extractClassName(root);
5160 ClassDefMutable *cdm = getClassMutable(bName);
5161 if (cdm)
5162 {
5164 }
5165 }
5166}

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

Referenced by parseInput().

◆ findMainPage()

void findMainPage ( Entry * root)
static

Definition at line 9615 of file doxygen.cpp.

9616{
9617 if (root->section.isMainpageDoc())
9618 {
9619 if (Doxygen::mainPage==nullptr && root->tagInfo()==nullptr)
9620 {
9621 //printf("mainpage: docLine=%d startLine=%d\n",root->docLine,root->startLine);
9622 //printf("Found main page! \n======\n%s\n=======\n",qPrint(root->doc));
9623 QCString title=root->args.stripWhiteSpace();
9624 if (title.isEmpty()) title = Config_getString(PROJECT_NAME);
9625 //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9626 QCString indexName="index";
9628 indexName, root->brief+root->doc+root->inbodyDocs,title);
9629 //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
9630 Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9631 Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1);
9632 Doxygen::mainPage->setFileName(indexName);
9633 Doxygen::mainPage->setLocalToc(root->localToc);
9635
9637 if (si)
9638 {
9639 if (!si->ref().isEmpty()) // we are from a tag file
9640 {
9641 // a page name is a label as well! but should no be double either
9643 Doxygen::mainPage->name(),
9644 indexName,
9645 root->startLine,
9646 Doxygen::mainPage->title(),
9648 0); // level 0
9649 }
9650 else if (si->lineNr() != -1)
9651 {
9652 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {}, line {})",
9653 Doxygen::mainPage->name(),si->fileName(),si->lineNr());
9654 }
9655 else
9656 {
9657 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {})",
9658 Doxygen::mainPage->name(),si->fileName());
9659 }
9660 }
9661 else
9662 {
9663 // a page name is a label as well! but should no be double either
9665 Doxygen::mainPage->name(),
9666 indexName,
9667 root->startLine,
9668 Doxygen::mainPage->title(),
9670 0); // level 0
9671 }
9672 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9673 }
9674 else if (root->tagInfo()==nullptr)
9675 {
9676 warn(root->fileName,root->startLine,
9677 "found more than one \\mainpage comment block! (first occurrence: {}, line {}), Skipping current block!",
9678 Doxygen::mainPage->docFile(),Doxygen::mainPage->getStartBodyLine());
9679 }
9680 }
9681 for (const auto &e : root->children()) findMainPage(e.get());
9682}
class that provide information about a section.
Definition section.h:58
QCString ref() const
Definition section.h:72
QCString fileName() const
Definition section.h:74
int lineNr() const
Definition section.h:73
SectionInfo * replace(const QCString &label, const QCString &fileName, int lineNr, const QCString &title, SectionType type, int level, const QCString &ref=QCString())
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:9615

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, Entry::fileName, SectionInfo::fileName(), LinkedMap< T, Hash, KeyEqual, Map >::find(), findMainPage(), Entry::inbodyDocs, SectionManager::instance(), QCString::isEmpty(), SectionInfo::lineNr(), Entry::localToc, Doxygen::mainPage, SectionType::Page, SectionInfo::ref(), SectionManager::replace(), Entry::section, Entry::startLine, QCString::stripWhiteSpace(), Entry::tagInfo(), and warn.

Referenced by findMainPage(), and parseInput().

◆ findMainPageTagFiles()

void findMainPageTagFiles ( Entry * root)
static

Definition at line 9685 of file doxygen.cpp.

9686{
9687 if (root->section.isMainpageDoc())
9688 {
9689 if (Doxygen::mainPage && root->tagInfo())
9690 {
9691 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9692 }
9693 }
9694 for (const auto &e : root->children()) findMainPageTagFiles(e.get());
9695}
static void findMainPageTagFiles(Entry *root)
Definition doxygen.cpp:9685

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 QCString & relates,
const QCString & type,
const QCString & args,
QCString 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 6580 of file doxygen.cpp.

6588{
6589 AUTO_TRACE("root='{}' funcDecl='{}' related='{}' overload={} isFunc={} mGrpId={} #tArgList={} spec={} lang={}",
6590 root->name, funcDecl, relates, overloaded, isFunc, root->mGrpId, root->tArgLists.size(),
6591 root->spec, root->lang);
6592
6593 QCString scopeName;
6594 QCString className;
6595 QCString namespaceName;
6596 QCString funcType;
6597 QCString funcName;
6598 QCString funcArgs;
6599 QCString funcTempList;
6600 QCString exceptions;
6601 QCString funcSpec;
6602 bool isRelated=false;
6603 bool isMemberOf=false;
6604 bool isFriend=false;
6605 bool done=false;
6606 TypeSpecifier spec = root->spec;
6607 while (!done)
6608 {
6609 done=true;
6610 if (funcDecl.stripPrefix("friend ")) // treat friends as related members
6611 {
6612 isFriend=true;
6613 done=false;
6614 }
6615 if (funcDecl.stripPrefix("inline "))
6616 {
6617 spec.setInline(true);
6618 done=false;
6619 }
6620 if (funcDecl.stripPrefix("explicit "))
6621 {
6622 spec.setExplicit(true);
6623 done=false;
6624 }
6625 if (funcDecl.stripPrefix("mutable "))
6626 {
6627 spec.setMutable(true);
6628 done=false;
6629 }
6630 if (funcDecl.stripPrefix("thread_local "))
6631 {
6632 spec.setThreadLocal(true);
6633 done=false;
6634 }
6635 if (funcDecl.stripPrefix("virtual "))
6636 {
6637 done=false;
6638 }
6639 }
6640
6641 // delete any ; from the function declaration
6642 int sep=0;
6643 while ((sep=funcDecl.find(';'))!=-1)
6644 {
6645 funcDecl=(funcDecl.left(sep)+funcDecl.right(funcDecl.length()-sep-1)).stripWhiteSpace();
6646 }
6647
6648 // make sure the first character is a space to simplify searching.
6649 if (!funcDecl.isEmpty() && funcDecl[0]!=' ') funcDecl.prepend(" ");
6650
6651 // remove some superfluous spaces
6652 funcDecl= substitute(
6653 substitute(
6654 substitute(funcDecl,"~ ","~"),
6655 ":: ","::"
6656 ),
6657 " ::","::"
6658 ).stripWhiteSpace();
6659
6660 //printf("funcDecl='%s'\n",qPrint(funcDecl));
6661 if (isFriend && funcDecl.startsWith("class "))
6662 {
6663 //printf("friend class\n");
6664 funcDecl=funcDecl.right(funcDecl.length()-6);
6665 funcName = funcDecl;
6666 }
6667 else if (isFriend && funcDecl.startsWith("struct "))
6668 {
6669 funcDecl=funcDecl.right(funcDecl.length()-7);
6670 funcName = funcDecl;
6671 }
6672 else
6673 {
6674 // extract information from the declarations
6675 parseFuncDecl(funcDecl,root->lang,scopeName,funcType,funcName,
6676 funcArgs,funcTempList,exceptions
6677 );
6678 }
6679
6680 // the class name can also be a namespace name, we decide this later.
6681 // if a related class name is specified and the class name could
6682 // not be derived from the function declaration, then use the
6683 // related field.
6684 AUTO_TRACE_ADD("scopeName='{}' className='{}' namespaceName='{}' funcType='{}' funcName='{}' funcArgs='{}'",
6685 scopeName,className,namespaceName,funcType,funcName,funcArgs);
6686 if (!relates.isEmpty())
6687 { // related member, prefix user specified scope
6688 isRelated=TRUE;
6689 isMemberOf=(root->relatesType == RelatesType::MemberOf);
6690 if (getClass(relates)==nullptr && !scopeName.isEmpty())
6691 {
6692 scopeName= mergeScopes(scopeName,relates);
6693 }
6694 else
6695 {
6696 scopeName = relates;
6697 }
6698 }
6699
6700 if (relates.isEmpty() && root->parent() &&
6701 (root->parent()->section.isScope() || root->parent()->section.isObjcImpl()) &&
6702 !root->parent()->name.isEmpty()) // see if we can combine scopeName
6703 // with the scope in which it was found
6704 {
6705 QCString joinedName = root->parent()->name+"::"+scopeName;
6706 if (!scopeName.isEmpty() &&
6707 (getClass(joinedName) || Doxygen::namespaceLinkedMap->find(joinedName)))
6708 {
6709 scopeName = joinedName;
6710 }
6711 else
6712 {
6713 scopeName = mergeScopes(root->parent()->name,scopeName);
6714 }
6715 }
6716 else // see if we can prefix a namespace or class that is used from the file
6717 {
6718 FileDef *fd=root->fileDef();
6719 if (fd)
6720 {
6721 for (const auto &fnd : fd->getUsedNamespaces())
6722 {
6723 QCString joinedName = fnd->name()+"::"+scopeName;
6724 if (Doxygen::namespaceLinkedMap->find(joinedName))
6725 {
6726 scopeName=joinedName;
6727 break;
6728 }
6729 }
6730 }
6731 }
6733 removeRedundantWhiteSpace(scopeName),false,&funcSpec,QCString(),false);
6734
6735 // funcSpec contains the last template specifiers of the given scope.
6736 // If this method does not have any template arguments or they are
6737 // empty while funcSpec is not empty we assume this is a
6738 // specialization of a method. If not, we clear the funcSpec and treat
6739 // this as a normal method of a template class.
6740 if (!(root->tArgLists.size()>0 &&
6741 root->tArgLists.front().size()==0
6742 )
6743 )
6744 {
6745 funcSpec.clear();
6746 }
6747
6748 //namespaceName=removeAnonymousScopes(namespaceName);
6749 if (!Config_getBool(EXTRACT_ANON_NSPACES) && scopeName.find('@')!=-1) return; // skip stuff in anonymous namespace...
6750
6751 // split scope into a namespace and a class part
6752 extractNamespaceName(scopeName,className,namespaceName,TRUE);
6753 AUTO_TRACE_ADD("scopeName='{}' className='{}' namespaceName='{}'",scopeName,className,namespaceName);
6754
6755 //printf("namespaceName='%s' className='%s'\n",qPrint(namespaceName),qPrint(className));
6756 // merge class and namespace scopes again
6757 scopeName.clear();
6758 if (!namespaceName.isEmpty())
6759 {
6760 if (className.isEmpty())
6761 {
6762 scopeName=namespaceName;
6763 }
6764 else if (!relates.isEmpty() || // relates command with explicit scope
6765 !getClass(className)) // class name only exists in a namespace
6766 {
6767 scopeName=namespaceName+"::"+className;
6768 }
6769 else
6770 {
6771 scopeName=className;
6772 }
6773 }
6774 else if (!className.isEmpty())
6775 {
6776 scopeName=className;
6777 }
6778 //printf("new scope='%s'\n",qPrint(scopeName));
6779
6780 QCString tempScopeName=scopeName;
6781 ClassDefMutable *cd=getClassMutable(scopeName);
6782 if (cd)
6783 {
6784 if (funcSpec.isEmpty())
6785 {
6786 uint32_t argListIndex=0;
6787 tempScopeName=cd->qualifiedNameWithTemplateParameters(&root->tArgLists,&argListIndex);
6788 }
6789 else
6790 {
6791 tempScopeName=scopeName+funcSpec;
6792 }
6793 }
6794 //printf("scopeName=%s cd=%p root->tArgLists=%p result=%s\n",
6795 // qPrint(scopeName),cd,root->tArgLists,qPrint(tempScopeName));
6796
6797 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
6798 // rebuild the function declaration (needed to get the scope right).
6799 if (!scopeName.isEmpty() && !isRelated && !isFriend && !Config_getBool(HIDE_SCOPE_NAMES) && root->lang!=SrcLangExt::Python)
6800 {
6801 if (!funcType.isEmpty())
6802 {
6803 if (isFunc) // a function -> we use argList for the arguments
6804 {
6805 funcDecl=funcType+" "+tempScopeName+"::"+funcName+funcTempList;
6806 }
6807 else
6808 {
6809 funcDecl=funcType+" "+tempScopeName+"::"+funcName+funcArgs;
6810 }
6811 }
6812 else
6813 {
6814 if (isFunc) // a function => we use argList for the arguments
6815 {
6816 funcDecl=tempScopeName+"::"+funcName+funcTempList;
6817 }
6818 else // variable => add 'argument' list
6819 {
6820 funcDecl=tempScopeName+"::"+funcName+funcArgs;
6821 }
6822 }
6823 }
6824 else // build declaration without scope
6825 {
6826 if (!funcType.isEmpty()) // but with a type
6827 {
6828 if (isFunc) // function => omit argument list
6829 {
6830 funcDecl=funcType+" "+funcName+funcTempList;
6831 }
6832 else // variable => add 'argument' list
6833 {
6834 funcDecl=funcType+" "+funcName+funcArgs;
6835 }
6836 }
6837 else // no type
6838 {
6839 if (isFunc)
6840 {
6841 funcDecl=funcName+funcTempList;
6842 }
6843 else
6844 {
6845 funcDecl=funcName+funcArgs;
6846 }
6847 }
6848 }
6849
6850 if (funcType=="template class" && !funcTempList.isEmpty())
6851 return; // ignore explicit template instantiations
6852
6853 AUTO_TRACE_ADD("Parse results: namespaceName='{}' className=`{}` funcType='{}' funcSpec='{}' "
6854 " funcName='{}' funcArgs='{}' funcTempList='{}' funcDecl='{}' relates='{}'"
6855 " exceptions='{}' isRelated={} isMemberOf={} isFriend={} isFunc={}",
6856 namespaceName, className, funcType, funcSpec,
6857 funcName, funcArgs, funcTempList, funcDecl, relates,
6858 exceptions, isRelated, isMemberOf, isFriend, isFunc);
6859
6860 if (!funcName.isEmpty()) // function name is valid
6861 {
6862 // check if 'className' is actually a scoped enum, in which case we need to
6863 // process it as a global, see issue #6471
6864 bool strongEnum = false;
6865 MemberName *mn=nullptr;
6866 if (!className.isEmpty() && (mn=Doxygen::functionNameLinkedMap->find(className)))
6867 {
6868 for (const auto &imd : *mn)
6869 {
6870 MemberDefMutable *md = toMemberDefMutable(imd.get());
6871 Definition *mdScope = nullptr;
6872 if (md && md->isEnumerate() && md->isStrong() && (mdScope=md->getOuterScope()) &&
6873 // need filter for the correct scope, see issue #9668
6874 ((namespaceName.isEmpty() && mdScope==Doxygen::globalScope) || (mdScope->name()==namespaceName)))
6875 {
6876 AUTO_TRACE_ADD("'{}' is a strong enum! (namespace={} md->getOuterScope()->name()={})",md->name(),namespaceName,md->getOuterScope()->name());
6877 strongEnum = true;
6878 // pass the scope name name as a 'namespace' to the findGlobalMember function
6879 if (!namespaceName.isEmpty())
6880 {
6881 namespaceName+="::"+className;
6882 }
6883 else
6884 {
6885 namespaceName=className;
6886 }
6887 }
6888 }
6889 }
6890
6891 if (funcName.startsWith("operator ")) // strip class scope from cast operator
6892 {
6893 funcName = substitute(funcName,className+"::","");
6894 }
6895 mn = nullptr;
6896 if (!funcTempList.isEmpty()) // try with member specialization
6897 {
6898 mn=Doxygen::memberNameLinkedMap->find(funcName+funcTempList);
6899 }
6900 if (mn==nullptr) // try without specialization
6901 {
6902 mn=Doxygen::memberNameLinkedMap->find(funcName);
6903 }
6904 if (!isRelated && !strongEnum && mn) // function name already found
6905 {
6906 AUTO_TRACE_ADD("member name exists ({} members with this name)",mn->size());
6907 if (!className.isEmpty()) // class name is valid
6908 {
6909 if (funcSpec.isEmpty()) // not a member specialization
6910 {
6911 addMemberFunction(root,mn,scopeName,namespaceName,className,funcType,funcName,
6912 funcArgs,funcTempList,exceptions,
6913 type,args,isFriend,spec,relates,funcDecl,overloaded,isFunc);
6914 }
6915 else if (cd) // member specialization
6916 {
6917 addMemberSpecialization(root,mn,cd,funcType,funcName,funcArgs,funcDecl,exceptions,spec);
6918 }
6919 else
6920 {
6921 //printf("*** Specialized member %s of unknown scope %s%s found!\n",
6922 // qPrint(scopeName),qPrint(funcName),qPrint(funcArgs));
6923 }
6924 }
6925 else if (overloaded) // check if the function belongs to only one class
6926 {
6927 addOverloaded(root,mn,funcType,funcName,funcArgs,funcDecl,exceptions,spec);
6928 }
6929 else // unrelated function with the same name as a member
6930 {
6931 if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec))
6932 {
6933 QCString fullFuncDecl=funcDecl;
6934 if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE);
6935 warn(root->fileName,root->startLine,
6936 "Cannot determine class for function\n{}",
6937 fullFuncDecl
6938 );
6939 }
6940 }
6941 }
6942 else if (isRelated && !relates.isEmpty())
6943 {
6944 AUTO_TRACE_ADD("related function scopeName='{}' className='{}'",scopeName,className);
6945 if (className.isEmpty()) className=relates;
6946 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
6947 if ((cd=getClassMutable(scopeName)))
6948 {
6949 bool newMember=TRUE; // assume we have a new member
6950 MemberDefMutable *mdDefine=nullptr;
6951 {
6952 mn = Doxygen::functionNameLinkedMap->find(funcName);
6953 if (mn)
6954 {
6955 for (const auto &imd : *mn)
6956 {
6957 MemberDefMutable *md = toMemberDefMutable(imd.get());
6958 if (md && md->isDefine())
6959 {
6960 mdDefine = md;
6961 break;
6962 }
6963 }
6964 }
6965 }
6966
6967 if (mdDefine) // macro definition is already created by the preprocessor and inserted as a file member
6968 {
6969 //printf("moving #define %s into class %s\n",qPrint(mdDefine->name()),qPrint(cd->name()));
6970
6971 // take mdDefine from the Doxygen::functionNameLinkedMap (without deleting the data)
6972 auto mdDefineTaken = Doxygen::functionNameLinkedMap->take(funcName,mdDefine);
6973 // insert it as a class member
6974 if ((mn=Doxygen::memberNameLinkedMap->find(funcName))==nullptr)
6975 {
6976 mn=Doxygen::memberNameLinkedMap->add(funcName);
6977 }
6978
6979 if (mdDefine->getFileDef())
6980 {
6981 mdDefine->getFileDef()->removeMember(mdDefine);
6982 }
6983 mdDefine->makeRelated();
6984 mdDefine->setMemberClass(cd);
6985 mdDefine->moveTo(cd);
6986 cd->insertMember(mdDefine);
6987 // also insert the member as an alias in the parent's scope, so it can be referenced also without cd's scope
6988 insertMemberAlias(cd->getOuterScope(),mdDefine);
6989 mn->push_back(std::move(mdDefineTaken));
6990 }
6991 else // normal member, needs to be created and added to the class
6992 {
6993 FileDef *fd=root->fileDef();
6994
6995 if ((mn=Doxygen::memberNameLinkedMap->find(funcName))==nullptr)
6996 {
6997 mn=Doxygen::memberNameLinkedMap->add(funcName);
6998 }
6999 else
7000 {
7001 // see if we got another member with matching arguments
7002 MemberDefMutable *rmd_found = nullptr;
7003 for (const auto &irmd : *mn)
7004 {
7005 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
7006 if (rmd)
7007 {
7008 const ArgumentList &rmdAl = rmd->argumentList();
7009
7010 newMember=
7011 className!=rmd->getOuterScope()->name() ||
7012 !matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmd->typeString(),&rmdAl,
7013 cd,fd,root->type,&root->argList,
7014 TRUE,root->lang);
7015 if (!newMember)
7016 {
7017 rmd_found = rmd;
7018 }
7019 }
7020 }
7021 if (rmd_found) // member already exists as rmd -> add docs
7022 {
7023 AUTO_TRACE_ADD("addMemberDocs for related member {}",root->name);
7024 addMemberDocs(root,rmd_found,funcDecl,nullptr,overloaded,spec);
7025 newMember=false;
7026 }
7027 }
7028
7029 if (newMember) // need to create a new member
7030 {
7031 MemberType mtype = MemberType::Function;
7032 switch (root->mtype)
7033 {
7034 case MethodTypes::Method: mtype = MemberType::Function; break;
7035 case MethodTypes::Signal: mtype = MemberType::Signal; break;
7036 case MethodTypes::Slot: mtype = MemberType::Slot; break;
7037 case MethodTypes::DCOP: mtype = MemberType::DCOP; break;
7038 case MethodTypes::Property: mtype = MemberType::Property; break;
7039 case MethodTypes::Event: mtype = MemberType::Event; break;
7040 }
7041
7042 //printf("New related name '%s' '%d'\n",qPrint(funcName),
7043 // root->argList ? (int)root->argList->count() : -1);
7044
7045 // first note that we pass:
7046 // (root->tArgLists ? root->tArgLists->last() : nullptr)
7047 // for the template arguments for the new "member."
7048 // this accurately reflects the template arguments of
7049 // the related function, which don't have to do with
7050 // those of the related class.
7051 auto md = createMemberDef(
7052 root->fileName,root->startLine,root->startColumn,
7053 funcType,funcName,funcArgs,exceptions,
7054 root->protection,root->virt,
7055 root->isStatic,
7056 isMemberOf ? Relationship::Foreign : Relationship::Related,
7057 mtype,
7058 (!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList()),
7059 funcArgs.isEmpty() ? ArgumentList() : root->argList,
7060 root->metaData);
7061 auto mmd = toMemberDefMutable(md.get());
7062
7063 // also insert the member as an alias in the parent's scope, so it can be referenced also without cd's scope
7064 insertMemberAlias(cd->getOuterScope(),md.get());
7065
7066 // we still have the problem that
7067 // MemberDef::writeDocumentation() in memberdef.cpp
7068 // writes the template argument list for the class,
7069 // as if this member is a member of the class.
7070 // fortunately, MemberDef::writeDocumentation() has
7071 // a special mechanism that allows us to totally
7072 // override the set of template argument lists that
7073 // are printed. We use that and set it to the
7074 // template argument lists of the related function.
7075 //
7076 mmd->setDefinitionTemplateParameterLists(root->tArgLists);
7077
7078 mmd->setTagInfo(root->tagInfo());
7079
7080 //printf("Related member name='%s' decl='%s' bodyLine='%d'\n",
7081 // qPrint(funcName),qPrint(funcDecl),root->bodyLine);
7082
7083 // try to find the matching line number of the body from the
7084 // global function list
7085 bool found=FALSE;
7086 if (root->bodyLine==-1)
7087 {
7088 MemberName *rmn=Doxygen::functionNameLinkedMap->find(funcName);
7089 if (rmn)
7090 {
7091 const MemberDefMutable *rmd_found=nullptr;
7092 for (const auto &irmd : *rmn)
7093 {
7094 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
7095 if (rmd)
7096 {
7097 const ArgumentList &rmdAl = rmd->argumentList();
7098 // check for matching argument lists
7099 if (
7100 matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmd->typeString(),&rmdAl,
7101 cd,fd,root->type,&root->argList,
7102 TRUE,root->lang)
7103 )
7104 {
7105 found=TRUE;
7106 rmd_found = rmd;
7107 break;
7108 }
7109 }
7110 }
7111 if (rmd_found) // member found -> copy line number info
7112 {
7113 mmd->setBodySegment(rmd_found->getDefLine(),rmd_found->getStartBodyLine(),rmd_found->getEndBodyLine());
7114 mmd->setBodyDef(rmd_found->getBodyDef());
7115 //md->setBodyMember(rmd);
7116 }
7117 }
7118 }
7119 if (!found) // line number could not be found or is available in this
7120 // entry
7121 {
7122 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
7123 mmd->setBodyDef(fd);
7124 }
7125
7126 //if (root->mGrpId!=-1)
7127 //{
7128 // md->setMemberGroup(memberGroupDict[root->mGrpId]);
7129 //}
7130 mmd->setMemberClass(cd);
7131 mmd->setMemberSpecifiers(spec);
7132 mmd->setVhdlSpecifiers(root->vhdlSpec);
7133 mmd->setDefinition(funcDecl);
7135 mmd->addQualifiers(root->qualifiers);
7136 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
7137 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
7138 mmd->setDocsForDefinition(!root->proto);
7139 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
7140 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7141 mmd->addSectionsToDefinition(root->anchors);
7142 mmd->setMemberGroupId(root->mGrpId);
7143 mmd->setLanguage(root->lang);
7144 mmd->setId(root->id);
7145 //md->setMemberDefTemplateArguments(root->mtArgList);
7146 cd->insertMember(md.get());
7147 cd->insertUsedFile(fd);
7148 mmd->setRefItems(root->sli);
7149 mmd->setRequirementReferences(root->rqli);
7150 if (root->relatesType==RelatesType::Duplicate) mmd->setRelatedAlso(cd);
7151 addMemberToGroups(root,md.get());
7153 //printf("Adding member=%s\n",qPrint(md->name()));
7154 mn->push_back(std::move(md));
7155 }
7156 if (root->relatesType==RelatesType::Duplicate)
7157 {
7158 if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec))
7159 {
7160 QCString fullFuncDecl=funcDecl;
7161 if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE);
7162 warn(root->fileName,root->startLine,
7163 "Cannot determine file/namespace for relatedalso function\n{}",
7164 fullFuncDecl
7165 );
7166 }
7167 }
7168 }
7169 }
7170 else
7171 {
7172 warn_undoc(root->fileName,root->startLine, "class '{}' for related function '{}' is not documented.", className,funcName);
7173 }
7174 }
7175 else if (root->parent() && root->parent()->section.isObjcImpl())
7176 {
7177 addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec);
7178 }
7179 else // unrelated not overloaded member found
7180 {
7181 bool globMem = findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec);
7182 if (className.isEmpty() && !globMem)
7183 {
7184 warn(root->fileName,root->startLine, "class for member '{}' cannot be found.", funcName);
7185 }
7186 else if (!className.isEmpty() && !globMem)
7187 {
7188 warn(root->fileName,root->startLine,
7189 "member '{}' of class '{}' cannot be found",
7190 funcName,className);
7191 }
7192 }
7193 }
7194 else
7195 {
7196 // this should not be called
7197 warn(root->fileName,root->startLine,"member with no name found.");
7198 }
7199 return;
7200}
virtual void removeMember(MemberDef *md)=0
virtual void moveTo(Definition *)=0
virtual bool isStrong() const =0
virtual void setMemberClass(ClassDef *cd)=0
Wrapper class for a number of boolean properties.
Definition types.h:694
void parseFuncDecl(const QCString &decl, const SrcLangExt lang, QCString &clName, QCString &type, QCString &name, QCString &args, QCString &funcTempList, QCString &exceptions)
Definition declinfo.l:325
static void insertMemberAlias(Definition *outerScope, const MemberDef *md)
Definition doxygen.cpp:6537
static void addMemberFunction(const Entry *root, MemberName *mn, const QCString &scopeName, const QCString &namespaceName, const QCString &className, const QCString &funcTyp, const QCString &funcName, const QCString &funcArgs, const QCString &funcTempList, const QCString &exceptions, const QCString &type, const QCString &args, bool isFriend, TypeSpecifier spec, const QCString &relates, const QCString &funcDecl, bool overloaded, bool isFunc)
Definition doxygen.cpp:6050
static void addOverloaded(const Entry *root, MemberName *mn, const QCString &funcType, const QCString &funcName, const QCString &funcArgs, const QCString &funcDecl, const QCString &exceptions, TypeSpecifier spec)
Definition doxygen.cpp:6469
static bool findGlobalMember(const Entry *root, const QCString &namespaceName, const QCString &type, const QCString &name, const QCString &tempArg, const QCString &, const QCString &decl, TypeSpecifier)
Definition doxygen.cpp:5630
static void addMemberSpecialization(const Entry *root, MemberName *mn, ClassDefMutable *cd, const QCString &funcType, const QCString &funcName, const QCString &funcArgs, const QCString &funcDecl, const QCString &exceptions, TypeSpecifier spec)
Definition doxygen.cpp:6406

References 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, QCString::clear(), Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, extractNamespaceName(), FALSE, Entry::fileDef(), Entry::fileName, QCString::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(), QCString::isEmpty(), MemberDef::isEnumerate(), EntryType::isScope(), Entry::isStatic, MemberDef::isStrong(), Entry::lang, QCString::left(), QCString::length(), MemberDefMutable::makeRelated(), matchArguments2(), Doxygen::memberNameLinkedMap, mergeScopes(), Entry::metaData, Entry::mGrpId, MemberDef::moveTo(), Entry::mtype, Definition::name(), Entry::name, Doxygen::namespaceLinkedMap, Entry::parent(), parseFuncDecl(), QCString::prepend(), Entry::protection, Entry::proto, MemberName::push_back(), ClassDef::qualifiedNameWithTemplateParameters(), Entry::qualifiers, Entry::relatesType, FileDef::removeMember(), removeRedundantWhiteSpace(), QCString::right(), Entry::rqli, Entry::section, MemberDefMutable::setMemberClass(), MemberName::size(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, QCString::startsWith(), QCString::stripPrefix(), stripTemplateSpecifiersFromScope(), QCString::stripWhiteSpace(), substitute(), Entry::tagInfo(), Entry::tArgLists, toMemberDefMutable(), TRUE, 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 7356 of file doxygen.cpp.

7357{
7358 if (root->section.isMemberDoc() ||
7359 root->section.isOverloadDoc() ||
7360 root->section.isFunction() ||
7361 root->section.isVariable() ||
7362 root->section.isVariableDoc() ||
7363 root->section.isDefine() ||
7364 root->section.isIncludedService() ||
7365 root->section.isExportedInterface()
7366 )
7367 {
7368 AUTO_TRACE();
7369 if (root->relatesType==RelatesType::Duplicate && !root->relates.isEmpty())
7370 {
7372 }
7374 }
7375 for (const auto &e : root->children())
7376 {
7377 if (!e->section.isEnum())
7378 {
7379 findMemberDocumentation(e.get());
7380 }
7381 }
7382}
static void findMemberDocumentation(const Entry *root)
Definition doxygen.cpp:7356
static void filterMemberDocumentation(const Entry *root, const QCString &relates)
Definition doxygen.cpp:7206

References AUTO_TRACE, Entry::children(), filterMemberDocumentation(), findMemberDocumentation(), QCString::isEmpty(), Entry::relates, Entry::relatesType, and Entry::section.

Referenced by findMemberDocumentation(), and parseInput().

◆ findModuleDocumentation()

void findModuleDocumentation ( const Entry * root)
static

Definition at line 1316 of file doxygen.cpp.

1317{
1318 if (root->section.isModuleDoc())
1319 {
1320 AUTO_TRACE();
1322 }
1323 for (const auto &e : root->children()) findModuleDocumentation(e.get());
1324}
void addDocs(const Entry *root)
static void findModuleDocumentation(const Entry *root)
Definition doxygen.cpp:1316

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

7387{
7388 AUTO_TRACE();
7389 for (const auto &objCImpl : root->children())
7390 {
7391 if (objCImpl->section.isObjcImpl())
7392 {
7393 for (const auto &objCMethod : objCImpl->children())
7394 {
7395 if (objCMethod->section.isFunction())
7396 {
7397 //printf(" Found ObjC method definition %s\n",qPrint(objCMethod->name));
7398 findMember(objCMethod.get(),
7399 objCMethod->relates,
7400 objCMethod->type,
7401 objCMethod->args,
7402 objCMethod->type+" "+objCImpl->name+"::"+objCMethod->name+" "+objCMethod->args,
7403 FALSE,TRUE);
7404 objCMethod->section=EntryType::makeEmpty();
7405 }
7406 }
7407 }
7408 }
7409}

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

Referenced by parseInput().

◆ findScopeFromQualifiedName()

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

Definition at line 782 of file doxygen.cpp.

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

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

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

◆ findSectionsInDocumentation()

void findSectionsInDocumentation ( )
static

Definition at line 9256 of file doxygen.cpp.

9257{
9258 // for each class
9259 for (const auto &cd : *Doxygen::classLinkedMap)
9260 {
9261 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9262 if (cdm)
9263 {
9265 }
9266 }
9267 // for each concept
9268 for (const auto &cd : *Doxygen::conceptLinkedMap)
9269 {
9270 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
9271 if (cdm)
9272 {
9274 }
9275 }
9276 // for each file
9277 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9278 {
9279 for (const auto &fd : *fn)
9280 {
9281 fd->findSectionsInDocumentation();
9282 }
9283 }
9284 // for each namespace
9285 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9286 {
9288 if (ndm)
9289 {
9291 }
9292 }
9293 // for each group
9294 for (const auto &gd : *Doxygen::groupLinkedMap)
9295 {
9296 gd->findSectionsInDocumentation();
9297 }
9298 // for each page
9299 for (const auto &pd : *Doxygen::pageLinkedMap)
9300 {
9301 pd->findSectionsInDocumentation();
9302 }
9303 // for each directory
9304 for (const auto &dd : *Doxygen::dirLinkedMap)
9305 {
9306 dd->findSectionsInDocumentation();
9307 }
9309 if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
9310}
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().

◆ findTemplateInstanceRelation()

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

Definition at line 4630 of file doxygen.cpp.

4635{
4636 AUTO_TRACE("Derived from template '{}' with parameters '{}' isArtificial={}",
4637 templateClass->name(),templSpec,isArtificial);
4638
4639 QCString tempArgsStr = tempArgListToString(templateClass->templateArguments(),root->lang,false);
4640 bool existingClass = templSpec==tempArgsStr;
4641 if (existingClass) return; // avoid recursion
4642
4643 bool freshInstance=FALSE;
4644 ClassDefMutable *instanceClass = toClassDefMutable(
4645 templateClass->insertTemplateInstance(
4646 root->fileName,root->startLine,root->startColumn,templSpec,freshInstance));
4647 if (instanceClass)
4648 {
4649 if (freshInstance)
4650 {
4651 instanceClass->setArtificial(TRUE);
4652 instanceClass->setLanguage(root->lang);
4653
4654 AUTO_TRACE_ADD("found fresh instance '{}'",instanceClass->name());
4655 instanceClass->setTemplateBaseClassNames(templateNames);
4656
4657 // search for new template instances caused by base classes of
4658 // instanceClass
4659 auto it_pair = g_classEntries.equal_range(templateClass->name().str());
4660 for (auto it=it_pair.first ; it!=it_pair.second ; ++it)
4661 {
4662 const Entry *templateRoot = it->second;
4663 AUTO_TRACE_ADD("template root found '{}' templSpec='{}'",templateRoot->name,templSpec);
4664 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(root->lang,templSpec);
4665 findBaseClassesForClass(templateRoot,context,templateClass,instanceClass,
4666 TemplateInstances,isArtificial,templArgs.get(),templateNames);
4667
4668 findUsedClassesForClass(templateRoot,context,templateClass,instanceClass,
4669 isArtificial,templArgs.get(),templateNames);
4670 }
4671 }
4672 else
4673 {
4674 AUTO_TRACE_ADD("instance already exists");
4675 }
4676 }
4677}
virtual void setTemplateBaseClassNames(const TemplateNameMap &templateNames)=0
virtual ClassDef * insertTemplateInstance(const QCString &fileName, int startLine, int startColumn, const QCString &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:4423

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

Referenced by findClassRelation(), and resolveTemplateInstanceInType().

◆ findTemplateSpecializationPosition()

int findTemplateSpecializationPosition ( const QCString & name)
static

Definition at line 4723 of file doxygen.cpp.

4724{
4725 if (name.isEmpty()) return 0;
4726 int l = static_cast<int>(name.length());
4727 if (name[l-1]=='>') // search backward to find the matching <, allowing nested <...> and strings.
4728 {
4729 int count=1;
4730 int i=l-2;
4731 char insideQuote=0;
4732 while (count>0 && i>=0)
4733 {
4734 char c = name[i--];
4735 switch (c)
4736 {
4737 case '>': if (!insideQuote) count++; break;
4738 case '<': if (!insideQuote) count--; break;
4739 case '\'': if (!insideQuote) insideQuote=c;
4740 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4741 break;
4742 case '"': if (!insideQuote) insideQuote=c;
4743 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4744 break;
4745 default: break;
4746 }
4747 }
4748 if (i>=0) l=i+1;
4749 }
4750 return l;
4751}

References QCString::isEmpty(), and QCString::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 4423 of file doxygen.cpp.

4431{
4432 AUTO_TRACE();
4433 const ArgumentList &formalArgs = masterCd->templateArguments();
4434 for (auto &mni : masterCd->memberNameInfoLinkedMap())
4435 {
4436 for (auto &mi : *mni)
4437 {
4438 const MemberDef *md=mi->memberDef();
4439 if (md->isVariable() || md->isObjCProperty()) // for each member variable in this class
4440 {
4441 AUTO_TRACE_ADD("Found variable '{}' in class '{}'",md->name(),masterCd->name());
4442 QCString type = normalizeNonTemplateArgumentsInString(md->typeString(),masterCd,formalArgs);
4443 QCString typedefValue = md->getLanguage()==SrcLangExt::Java ? type : resolveTypeDef(masterCd,type);
4444 if (!typedefValue.isEmpty())
4445 {
4446 type = typedefValue;
4447 }
4448 int pos=0;
4449 QCString usedClassName;
4450 QCString templSpec;
4451 bool found=FALSE;
4452 // the type can contain template variables, replace them if present
4453 type = substituteTemplateArgumentsInString(type,formalArgs,actualArgs);
4454
4455 //printf(" template substitution gives=%s\n",qPrint(type));
4456 while (!found && extractClassNameFromType(type,pos,usedClassName,templSpec,root->lang)!=-1)
4457 {
4458 // find the type (if any) that matches usedClassName
4459 SymbolResolver resolver(masterCd->getFileDef());
4460 const ClassDefMutable *typeCd = resolver.resolveClassMutable(masterCd,usedClassName,false,true);
4461 //printf("====> usedClassName=%s -> typeCd=%s\n",
4462 // qPrint(usedClassName),typeCd?qPrint(typeCd->name()):"<none>");
4463 if (typeCd)
4464 {
4465 usedClassName = typeCd->name();
4466 }
4467
4468 // replace any namespace aliases
4469 replaceNamespaceAliases(usedClassName);
4470 // add any template arguments to the class
4471 QCString usedName = removeRedundantWhiteSpace(usedClassName+templSpec);
4472 //printf(" usedName=%s usedClassName=%s templSpec=%s\n",qPrint(usedName),qPrint(usedClassName),qPrint(templSpec));
4473
4474 TemplateNameMap formTemplateNames;
4475 if (templateNames.empty())
4476 {
4477 formTemplateNames = getTemplateArgumentsInName(formalArgs,usedName.str());
4478 }
4479 BaseInfo bi(usedName,Protection::Public,Specifier::Normal);
4480 findClassRelation(root,context,instanceCd,&bi,formTemplateNames,TemplateInstances,isArtificial);
4481
4482 for (const Argument &arg : masterCd->templateArguments())
4483 {
4484 if (arg.name==usedName) // type is a template argument
4485 {
4486 ClassDef *usedCd = Doxygen::hiddenClassLinkedMap->find(usedName);
4487 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4488 if (usedCd==nullptr)
4489 {
4490 usedCdm = toClassDefMutable(
4491 Doxygen::hiddenClassLinkedMap->add(usedName,
4493 masterCd->getDefFileName(),masterCd->getDefLine(),
4494 masterCd->getDefColumn(),
4495 usedName,
4496 ClassDef::Class)));
4497 if (usedCdm)
4498 {
4499 //printf("making %s a template argument!!!\n",qPrint(usedCd->name()));
4500 usedCdm->makeTemplateArgument();
4501 usedCdm->setUsedOnly(TRUE);
4502 usedCdm->setLanguage(masterCd->getLanguage());
4503 usedCd = usedCdm;
4504 }
4505 }
4506 if (usedCd)
4507 {
4508 found=TRUE;
4509 AUTO_TRACE_ADD("case 1: adding used class '{}'", usedCd->name());
4510 instanceCd->addUsedClass(usedCd,md->name(),md->protection());
4511 if (usedCdm)
4512 {
4513 if (isArtificial) usedCdm->setArtificial(TRUE);
4514 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4515 }
4516 }
4517 }
4518 }
4519
4520 if (!found)
4521 {
4522 ClassDef *usedCd=findClassWithinClassContext(context,masterCd,usedName);
4523 //printf("Looking for used class %s: result=%s master=%s\n",
4524 // qPrint(usedName),usedCd?qPrint(usedCd->name()):"<none>",masterCd?qPrint(masterCd->name()):"<none>");
4525
4526 if (usedCd)
4527 {
4528 found=TRUE;
4529 AUTO_TRACE_ADD("case 2: adding used class '{}'", usedCd->name());
4530 instanceCd->addUsedClass(usedCd,md->name(),md->protection()); // class exists
4531 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4532 if (usedCdm)
4533 {
4534 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4535 }
4536 }
4537 }
4538 }
4539 if (!found && !type.isEmpty()) // used class is not documented in any scope
4540 {
4541 ClassDef *usedCd = Doxygen::hiddenClassLinkedMap->find(type);
4542 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4543 if (usedCd==nullptr && !Config_getBool(HIDE_UNDOC_RELATIONS))
4544 {
4545 if (type.endsWith("(*") || type.endsWith("(^")) // type is a function pointer
4546 {
4547 type+=md->argsString();
4548 }
4549 AUTO_TRACE_ADD("New undocumented used class '{}'", type);
4550 usedCdm = toClassDefMutable(
4553 masterCd->getDefFileName(),masterCd->getDefLine(),
4554 masterCd->getDefColumn(),
4555 type,ClassDef::Class)));
4556 if (usedCdm)
4557 {
4558 usedCdm->setUsedOnly(TRUE);
4559 usedCdm->setLanguage(masterCd->getLanguage());
4560 usedCd = usedCdm;
4561 }
4562 }
4563 if (usedCd)
4564 {
4565 AUTO_TRACE_ADD("case 3: adding used class '{}'", usedCd->name());
4566 instanceCd->addUsedClass(usedCd,md->name(),md->protection());
4567 if (usedCdm)
4568 {
4569 if (isArtificial) usedCdm->setArtificial(TRUE);
4570 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4571 }
4572 }
4573 }
4574 }
4575 }
4576 }
4577}
virtual void makeTemplateArgument(bool b=TRUE)=0
virtual void addUsedClass(ClassDef *cd, const QCString &accessName, Protection prot)=0
virtual void setUsedOnly(bool b)=0
virtual void addUsedByClass(ClassDef *cd, const QCString &accessName, Protection prot)=0
virtual bool isObjCProperty() const =0
QCString normalizeNonTemplateArgumentsInString(const QCString &name, const Definition *context, const ArgumentList &formalArgs)
Definition util.cpp:4325
int extractClassNameFromType(const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt lang)
Definition util.cpp:4240
QCString resolveTypeDef(const Definition *context, const QCString &qualifiedName, const Definition **typedefContext)
Definition util.cpp:373

References ClassDefMutable::addUsedByClass(), ClassDefMutable::addUsedClass(), MemberDef::argsString(), AUTO_TRACE, AUTO_TRACE_ADD, ClassDef::Class, Config_getBool, createClassDef(), QCString::endsWith(), extractClassNameFromType(), FALSE, findClassRelation(), findClassWithinClassContext(), Definition::getDefColumn(), Definition::getDefFileName(), Definition::getDefLine(), ClassDef::getFileDef(), Definition::getLanguage(), getTemplateArgumentsInName(), Doxygen::hiddenClassLinkedMap, QCString::isEmpty(), 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(), QCString::str(), substituteTemplateArgumentsInString(), ClassDef::templateArguments(), TemplateInstances, toClassDefMutable(), TRUE, and MemberDef::typeString().

Referenced by findTemplateInstanceRelation(), and findUsedTemplateInstances().

◆ findUsedNamespace()

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

Definition at line 1699 of file doxygen.cpp.

1701{
1702 NamespaceDef *usingNd =nullptr;
1703 for (auto &und : unl)
1704 {
1705 QCString uScope=und->name()+"::";
1706 usingNd = getResolvedNamespace(uScope+name);
1707 if (usingNd!=nullptr) break;
1708 }
1709 return usingNd;
1710}

References getResolvedNamespace().

Referenced by findUsingDirectives().

◆ findUsedTemplateInstances()

void findUsedTemplateInstances ( )
static

Definition at line 5186 of file doxygen.cpp.

5187{
5188 AUTO_TRACE();
5189 for (const auto &[name,root] : g_classEntries)
5190 {
5191 QCString bName = extractClassName(root);
5192 ClassDefMutable *cdm = getClassMutable(bName);
5193 if (cdm)
5194 {
5195 findUsedClassesForClass(root,cdm,cdm,cdm,TRUE);
5197 cdm->addTypeConstraints();
5198 }
5199 }
5200}
virtual void addTypeConstraints()=0
static void makeTemplateInstanceRelation(const Entry *root, ClassDefMutable *cd)
Definition doxygen.cpp:5168

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

Referenced by parseInput().

◆ findUsingDeclarations()

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

Definition at line 1868 of file doxygen.cpp.

1869{
1870 if (root->section.isUsingDecl() &&
1871 !root->parent()->section.isCompound() && // not a class/struct member
1872 (!filterPythonPackages || (root->lang==SrcLangExt::Python && root->fileName.endsWith("__init__.py")))
1873 )
1874 {
1875 AUTO_TRACE("Found using declaration '{}' at line {} of {} inside section {}",
1876 root->name,root->startLine,root->fileName,root->parent()->section);
1877 if (!root->name.isEmpty())
1878 {
1879 const Definition *usingDef = nullptr;
1880 NamespaceDefMutable *nd = nullptr;
1881 FileDef *fd = root->fileDef();
1882 QCString scName;
1883
1884 // see if the using statement was found inside a namespace or inside
1885 // the global file scope.
1886 if (root->parent()->section.isNamespace())
1887 {
1888 scName=root->parent()->name;
1889 if (!scName.isEmpty())
1890 {
1891 nd = getResolvedNamespaceMutable(scName);
1892 }
1893 }
1894
1895 // Assume the using statement was used to import a class.
1896 // Find the scope in which the 'using' namespace is defined by prepending
1897 // the possible scopes in which the using statement was found, starting
1898 // with the most inner scope and going to the most outer scope (i.e.
1899 // file scope).
1900
1901 QCString name = substitute(root->name,".","::"); //Java/C# scope->internal
1902
1903 SymbolResolver resolver;
1904 const Definition *scope = nd;
1905 if (nd==nullptr) scope = fd;
1906 usingDef = resolver.resolveSymbol(scope,name);
1907
1908 //printf("usingDef(scope=%s,name=%s)=%s\n",qPrint(nd?nd->qualifiedName():""),qPrint(name),usingDef?qPrint(usingDef->qualifiedName()):"nullptr");
1909
1910 if (!usingDef)
1911 {
1912 usingDef = getClass(name); // try direct lookup, this is needed to get
1913 // builtin STL classes to properly resolve, e.g.
1914 // vector -> std::vector
1915 }
1916 if (!usingDef)
1917 {
1918 usingDef = Doxygen::hiddenClassLinkedMap->find(name); // check if it is already hidden
1919 }
1920#if 0
1921 if (!usingDef)
1922 {
1923 AUTO_TRACE_ADD("New using class '{}' (sec={})! #tArgLists={}",
1924 name,root->section,root->tArgLists.size());
1927 createClassDef( "<using>",1,1, name, ClassDef::Class)));
1928 if (usingCd)
1929 {
1930 usingCd->setArtificial(TRUE);
1931 usingCd->setLanguage(root->lang);
1932 usingDef = usingCd;
1933 }
1934 }
1935#endif
1936 else
1937 {
1938 AUTO_TRACE_ADD("Found used type '{}' in scope='{}'",
1939 usingDef->name(), nd ? nd->name(): fd ? fd->name() : QCString("<unknown>"));
1940 }
1941
1942 if (usingDef)
1943 {
1944 if (nd)
1945 {
1946 nd->addUsingDeclaration(usingDef);
1947 }
1948 else if (fd)
1949 {
1950 fd->addUsingDeclaration(usingDef);
1951 }
1952 }
1953 }
1954 }
1955 for (const auto &e : root->children()) findUsingDeclarations(e.get(),filterPythonPackages);
1956}
virtual void addUsingDeclaration(const Definition *d)=0
virtual void addUsingDeclaration(const Definition *d)=0
const Definition * resolveSymbol(const Definition *scope, const QCString &name, const QCString &args=QCString(), 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:1868

References FileDef::addUsingDeclaration(), NamespaceDefMutable::addUsingDeclaration(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::children(), ClassDef::Class, createClassDef(), QCString::endsWith(), Entry::fileDef(), Entry::fileName, findUsingDeclarations(), getClass(), getResolvedNamespaceMutable(), Doxygen::hiddenClassLinkedMap, EntryType::isCompound(), QCString::isEmpty(), Entry::lang, Definition::name(), Entry::name, Entry::parent(), SymbolResolver::resolveSymbol(), Entry::section, DefinitionMutable::setArtificial(), DefinitionMutable::setLanguage(), Entry::startLine, substitute(), Entry::tArgLists, toClassDefMutable(), and TRUE.

Referenced by findUsingDeclarations(), and parseInput().

◆ findUsingDeclImports()

void findUsingDeclImports ( const Entry * root)
static

Definition at line 2021 of file doxygen.cpp.

2022{
2023 if (root->section.isUsingDecl() &&
2024 root->parent()->section.isCompound() // in a class/struct member
2025 )
2026 {
2027 AUTO_TRACE("Found using declaration '{}' inside section {}", root->name, root->parent()->section);
2028 QCString fullName=removeRedundantWhiteSpace(root->parent()->name);
2029 fullName=stripAnonymousNamespaceScope(fullName);
2030 fullName=stripTemplateSpecifiersFromScope(fullName);
2031 ClassDefMutable *cd = getClassMutable(fullName);
2032 if (cd)
2033 {
2034 AUTO_TRACE_ADD("found class '{}'",cd->name());
2035 int i=root->name.findRev("::");
2036 if (i!=-1)
2037 {
2038 QCString scope=root->name.left(i);
2039 QCString memName=root->name.right(root->name.length()-i-2);
2040 SymbolResolver resolver;
2041 const ClassDef *bcd = resolver.resolveClass(cd,scope); // todo: file in fileScope parameter
2042 AUTO_TRACE_ADD("name={} scope={} bcd={}",scope,cd?cd->name():"<none>",bcd?bcd->name():"<none>");
2043 if (bcd && bcd!=cd)
2044 {
2045 AUTO_TRACE_ADD("found class '{}' memName='{}'",bcd->name(),memName);
2047 const MemberNameInfo *mni = mnlm.find(memName);
2048 if (mni)
2049 {
2050 for (auto &mi : *mni)
2051 {
2052 const MemberDef *md = mi->memberDef();
2053 if (md && md->protection()!=Protection::Private)
2054 {
2055 AUTO_TRACE_ADD("found member '{}'",mni->memberName());
2056 QCString fileName = root->fileName;
2057 if (fileName.isEmpty() && root->tagInfo())
2058 {
2059 fileName = root->tagInfo()->tagName;
2060 }
2061 if (!cd->containsOverload(md))
2062 {
2063 createUsingMemberImportForClass(root,cd,md,fileName,memName);
2064 // also insert the member into copies of the class
2065 auto it = g_usingClassMap.find(cd->qualifiedName().str());
2066 if (it != g_usingClassMap.end())
2067 {
2068 for (const auto &copyCd : it->second)
2069 {
2070 createUsingMemberImportForClass(root,copyCd,md,fileName,memName);
2071 }
2072 }
2073 }
2074 }
2075 }
2076 }
2077 }
2078 }
2079 }
2080 }
2081 else if (root->section.isUsingDecl() &&
2082 (root->parent()->section.isNamespace() || root->parent()->section.isEmpty()) && // namespace or global member
2083 root->lang==SrcLangExt::Cpp // do we also want this for e.g. Fortran? (see test case 095)
2084 )
2085 {
2086 AUTO_TRACE("Found using declaration '{}' inside section {}", root->name, root->parent()->section);
2087 Definition *scope = nullptr;
2088 NamespaceDefMutable *nd = nullptr;
2089 FileDef *fd = root->parent()->fileDef();
2090 if (!root->parent()->name.isEmpty())
2091 {
2092 QCString fullName=removeRedundantWhiteSpace(root->parent()->name);
2093 fullName=stripAnonymousNamespaceScope(fullName);
2095 scope = nd;
2096 }
2097 else
2098 {
2099 scope = fd;
2100 }
2101 if (scope)
2102 {
2103 AUTO_TRACE_ADD("found scope '{}'",scope->name());
2104 SymbolResolver resolver;
2105 const Definition *def = resolver.resolveSymbol(root->name.startsWith("::") ? nullptr : scope,root->name);
2106 if (def && def->definitionType()==Definition::TypeMember)
2107 {
2108 int i=root->name.findRev("::");
2109 QCString memName;
2110 if (i!=-1)
2111 {
2112 memName = root->name.right(root->name.length()-i-2);
2113 }
2114 else
2115 {
2116 memName = root->name;
2117 }
2118 const MemberDef *md = toMemberDef(def);
2119 AUTO_TRACE_ADD("found member '{}' for name '{}'",md->qualifiedName(),root->name);
2120 QCString fileName = root->fileName;
2121 if (fileName.isEmpty() && root->tagInfo())
2122 {
2123 fileName = root->tagInfo()->tagName;
2124 }
2125 const ArgumentList &templAl = md->templateArguments();
2126 const ArgumentList &al = md->argumentList();
2127
2128 auto newMd = createMemberDef(
2129 fileName,root->startLine,root->startColumn,
2130 md->typeString(),memName,md->argsString(),
2131 md->excpString(),root->protection,root->virt,
2132 md->isStatic(),Relationship::Member,md->memberType(),
2133 templAl,al,root->metaData
2134 );
2135 auto newMmd = toMemberDefMutable(newMd.get());
2136 if (nd)
2137 {
2138 newMmd->setNamespace(nd);
2139 nd->insertMember(newMd.get());
2140 }
2141 if (fd)
2142 {
2143 newMmd->setFileDef(fd);
2144 fd->insertMember(newMd.get());
2145 }
2146 if (!root->doc.isEmpty() || !root->brief.isEmpty())
2147 {
2148 newMmd->setDocumentation(root->doc,root->docFile,root->docLine);
2149 newMmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2150 newMmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2151 }
2152 else
2153 {
2154 newMmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
2155 newMmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
2156 newMmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
2157 }
2158 newMmd->setDefinition(md->definition());
2159 applyMemberOverrideOptions(root,newMmd);
2160 newMmd->addQualifiers(root->qualifiers);
2161 newMmd->setBitfields(md->bitfieldString());
2162 newMmd->addSectionsToDefinition(root->anchors);
2163 newMmd->setBodySegment(md->getDefLine(),md->getStartBodyLine(),md->getEndBodyLine());
2164 newMmd->setBodyDef(md->getBodyDef());
2165 newMmd->setInitializer(md->initializer());
2166 newMmd->setRequiresClause(md->requiresClause());
2167 newMmd->setMaxInitLines(md->initializerLines());
2168 newMmd->setMemberGroupId(root->mGrpId);
2169 newMmd->setMemberSpecifiers(md->getMemberSpecifiers());
2170 newMmd->setVhdlSpecifiers(md->getVhdlSpecifiers());
2171 newMmd->setLanguage(root->lang);
2172 newMmd->setId(root->id);
2173 MemberName *mn = Doxygen::functionNameLinkedMap->add(memName);
2174 mn->push_back(std::move(newMd));
2175#if 0 // insert an alias instead of a copy
2176 const MemberDef *md = toMemberDef(def);
2177 AUTO_TRACE_ADD("found member '{}' for name '{}'",md->qualifiedName(),root->name);
2178 auto aliasMd = createMemberDefAlias(nd,md);
2179 QCString aliasFullName = nd->qualifiedName()+"::"+aliasMd->localName();
2180 if (nd && aliasMd.get())
2181 {
2182 nd->insertMember(aliasMd.get());
2183 }
2184 if (fd && aliasMd.get())
2185 {
2186 fd->insertMember(aliasMd.get());
2187 }
2188 MemberName *mn = Doxygen::memberNameLinkedMap->add(aliasFullName);
2189 mn->push_back(std::move(aliasMd));
2190#endif
2191 }
2192 else if (def && def->definitionType()==Definition::TypeClass)
2193 {
2194 const ClassDef *cd = toClassDef(def);
2195 QCString copyFullName;
2196 if (nd==nullptr)
2197 {
2198 copyFullName = cd->localName();
2199 }
2200 else
2201 {
2202 copyFullName = nd->qualifiedName()+"::"+cd->localName();
2203 }
2204 if (Doxygen::classLinkedMap->find(copyFullName)==nullptr)
2205 {
2207 Doxygen::classLinkedMap->add(copyFullName,
2208 cd->deepCopy(copyFullName)));
2209 AUTO_TRACE_ADD("found class '{}' for name '{}' copy '{}' obj={}",cd->qualifiedName(),root->name,copyFullName,(void*)ncdm);
2210 g_usingClassMap[cd->qualifiedName().str()].push_back(ncdm);
2211 if (ncdm)
2212 {
2213 if (nd) ncdm->moveTo(nd);
2214 if ((!root->doc.isEmpty() || !root->brief.isEmpty())) // use docs at using statement
2215 {
2216 ncdm->setDocumentation(root->doc,root->docFile,root->docLine);
2217 ncdm->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2218 }
2219 else // use docs from used class
2220 {
2221 ncdm->setDocumentation(cd->documentation(),cd->docFile(),cd->docLine());
2223 }
2224 if (nd)
2225 {
2226 nd->addInnerCompound(ncdm);
2227 nd->addUsingDeclaration(ncdm);
2228 }
2229 if (fd)
2230 {
2231 if (ncdm) ncdm->setFileDef(fd);
2232 fd->insertClass(ncdm);
2233 fd->addUsingDeclaration(ncdm);
2234 }
2235 }
2236 }
2237#if 0 // insert an alias instead of a copy
2238 auto aliasCd = createClassDefAlias(nd,cd);
2239 QCString aliasFullName;
2240 if (nd==nullptr)
2241 {
2242 aliasFullName = aliasCd->localName();
2243 }
2244 else
2245 {
2246 aliasFullName = nd->qualifiedName()+"::"+aliasCd->localName();
2247 }
2248 AUTO_TRACE_ADD("found class '{}' for name '{}' aliasFullName='{}'",cd->qualifiedName(),root->name,aliasFullName);
2249 auto acd = Doxygen::classLinkedMap->add(aliasFullName,std::move(aliasCd));
2250 if (nd && acd)
2251 {
2252 nd->addInnerCompound(acd);
2253 }
2254 if (fd && acd)
2255 {
2256 fd->insertClass(acd);
2257 }
2258#endif
2259 }
2260 else if (scope)
2261 {
2262 AUTO_TRACE_ADD("no symbol with name '{}' in scope {}",root->name,scope->name());
2263 }
2264 }
2265 }
2266 for (const auto &e : root->children()) findUsingDeclImports(e.get());
2267}
virtual void moveTo(Definition *)=0
virtual std::unique_ptr< ClassDef > deepCopy(const QCString &name) const =0
virtual bool containsOverload(const MemberDef *md) const =0
virtual const QCString & localName() const =0
const ClassDef * resolveClass(const Definition *scope, const QCString &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:787
ClassDef * toClassDef(Definition *d)
static void createUsingMemberImportForClass(const Entry *root, ClassDefMutable *cd, const MemberDef *md, const QCString &fileName, const QCString &memName)
Definition doxygen.cpp:1972
static void findUsingDeclImports(const Entry *root)
Definition doxygen.cpp:2021
static std::unordered_map< std::string, std::vector< ClassDefMutable * > > g_usingClassMap
Definition doxygen.cpp:2019
std::unique_ptr< MemberDef > createMemberDefAlias(const Definition *newScope, const MemberDef *aliasMd)

References 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(), MemberDef::excpString(), Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::findRev(), 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(), QCString::isEmpty(), MemberDef::isStatic(), Entry::lang, QCString::left(), QCString::length(), Definition::localName(), ClassDef::memberNameInfoLinkedMap(), Doxygen::memberNameLinkedMap, MemberDef::memberType(), Entry::metaData, Entry::mGrpId, ClassDef::moveTo(), Definition::name(), Entry::name, Entry::parent(), Entry::protection, MemberDef::protection(), MemberName::push_back(), Definition::qualifiedName(), Entry::qualifiers, removeRedundantWhiteSpace(), MemberDef::requiresClause(), SymbolResolver::resolveClass(), SymbolResolver::resolveSymbol(), QCString::right(), Entry::section, DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), ClassDefMutable::setFileDef(), Entry::startColumn, Entry::startLine, QCString::startsWith(), QCString::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 1712 of file doxygen.cpp.

1713{
1714 if (root->section.isUsingDir())
1715 {
1716 AUTO_TRACE("Found using directive {} at line {} of {}",root->name,root->startLine,root->fileName);
1717 QCString name=substitute(root->name,".","::");
1718 if (name.endsWith("::"))
1719 {
1720 name=name.left(name.length()-2);
1721 }
1722 if (!name.isEmpty())
1723 {
1724 NamespaceDef *usingNd = nullptr;
1725 NamespaceDefMutable *nd = nullptr;
1726 FileDef *fd = root->fileDef();
1727 QCString nsName;
1728
1729 // see if the using statement was found inside a namespace or inside
1730 // the global file scope.
1731 if (root->parent() && root->parent()->section.isNamespace() &&
1732 (fd==nullptr || fd->getLanguage()!=SrcLangExt::Java) // not a .java file
1733 )
1734 {
1735 nsName=stripAnonymousNamespaceScope(root->parent()->name);
1736 if (!nsName.isEmpty())
1737 {
1738 nd = getResolvedNamespaceMutable(nsName);
1739 }
1740 }
1741
1742 // find the scope in which the 'using' namespace is defined by prepending
1743 // the possible scopes in which the using statement was found, starting
1744 // with the most inner scope and going to the most outer scope (i.e.
1745 // file scope).
1746 int scopeOffset = static_cast<int>(nsName.length());
1747 do
1748 {
1749 QCString scope=scopeOffset>0 ?
1750 nsName.left(scopeOffset)+"::" : QCString();
1751 usingNd = getResolvedNamespace(scope+name);
1752 //printf("Trying with scope='%s' usingNd=%p\n",(scope+qPrint(name)),usingNd);
1753 if (scopeOffset==0)
1754 {
1755 scopeOffset=-1;
1756 }
1757 else if ((scopeOffset=nsName.findRev("::",scopeOffset-1))==-1)
1758 {
1759 scopeOffset=0;
1760 }
1761 } while (scopeOffset>=0 && usingNd==nullptr);
1762
1763 if (usingNd==nullptr && nd) // not found, try used namespaces in this scope
1764 // or in one of the parent namespace scopes
1765 {
1766 const NamespaceDefMutable *pnd = nd;
1767 while (pnd && usingNd==nullptr)
1768 {
1769 // also try with one of the used namespaces found earlier
1771
1772 // goto the parent
1773 Definition *s = pnd->getOuterScope();
1775 {
1777 }
1778 else
1779 {
1780 pnd = nullptr;
1781 }
1782 }
1783 }
1784 if (usingNd==nullptr && fd) // still nothing, also try used namespace in the
1785 // global scope
1786 {
1787 usingNd = findUsedNamespace(fd->getUsedNamespaces(),name);
1788 }
1789
1790 //printf("%s -> %s\n",qPrint(name),usingNd?qPrint(usingNd->name()):"<none>");
1791
1792 // add the namespace the correct scope
1793 if (usingNd)
1794 {
1795 //printf("using fd=%p nd=%p\n",fd,nd);
1796 if (nd)
1797 {
1798 //printf("Inside namespace %s\n",qPrint(nd->name()));
1799 nd->addUsingDirective(usingNd);
1800 }
1801 else if (fd)
1802 {
1803 //printf("Inside file %s\n",qPrint(fd->name()));
1804 fd->addUsingDirective(usingNd);
1805 }
1806 }
1807 else // unknown namespace, but add it anyway.
1808 {
1809 AUTO_TRACE_ADD("new unknown namespace {} lang={} hidden={}",name,langToString(root->lang),root->hidden);
1810 // add namespace to the list
1813 createNamespaceDef(root->fileName,root->startLine,root->startColumn,name)));
1814 if (nd)
1815 {
1816 nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1817 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1819 nd->setHidden(root->hidden);
1820 nd->setArtificial(TRUE);
1821 nd->setLanguage(root->lang);
1822 nd->setId(root->id);
1823 nd->setMetaData(root->metaData);
1824 nd->setInline(root->spec.isInline());
1825 nd->setExported(root->exported);
1826
1827 for (const Grouping &g : root->groups)
1828 {
1829 GroupDef *gd=nullptr;
1830 if (!g.groupname.isEmpty() && (gd=Doxygen::groupLinkedMap->find(g.groupname)))
1831 gd->addNamespace(nd);
1832 }
1833
1834 // insert the namespace in the file definition
1835 if (fd)
1836 {
1837 fd->insertNamespace(nd);
1838 fd->addUsingDirective(nd);
1839 }
1840
1841 // the empty string test is needed for extract all case
1842 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1843 nd->insertUsedFile(fd);
1844 nd->setRefItems(root->sli);
1845 nd->setRequirementReferences(root->rqli);
1846 }
1847 }
1848 }
1849 }
1850 for (const auto &e : root->children()) findUsingDirectives(e.get());
1851}
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 QCString &name)
Definition doxygen.cpp:1699
static void findUsingDirectives(const Entry *root)
Definition doxygen.cpp:1712

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, QCString::endsWith(), Entry::exported, Entry::fileDef(), Entry::fileName, QCString::findRev(), 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(), QCString::isEmpty(), Entry::lang, langToString(), QCString::left(), QCString::length(), Entry::metaData, Entry::name, Doxygen::namespaceLinkedMap, Entry::parent(), 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(), TRUE, and Definition::TypeNamespace.

Referenced by findUsingDirectives(), and parseInput().

◆ flushCachedTemplateRelations()

void flushCachedTemplateRelations ( )
static

Definition at line 9315 of file doxygen.cpp.

9316{
9317 // remove all references to classes from the cache
9318 // as there can be new template instances in the inheritance path
9319 // to this class. Optimization: only remove those classes that
9320 // have inheritance instances as direct or indirect sub classes.
9322
9323 // remove all cached typedef resolutions whose target is a
9324 // template class as this may now be a template instance
9325 // for each global function name
9326 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9327 {
9328 // for each function with that name
9329 for (const auto &ifmd : *fn)
9330 {
9331 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9332 if (fmd && fmd->isTypedefValCached())
9333 {
9334 const ClassDef *cd = fmd->getCachedTypedefVal();
9335 if (cd->isTemplate()) fmd->invalidateTypedefValCache();
9336 }
9337 }
9338 }
9339 // for each class method name
9340 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9341 {
9342 // for each function with that name
9343 for (const auto &imd : *nm)
9344 {
9345 MemberDefMutable *md = toMemberDefMutable(imd.get());
9346 if (md && md->isTypedefValCached())
9347 {
9348 const ClassDef *cd = md->getCachedTypedefVal();
9349 if (cd->isTemplate()) md->invalidateTypedefValCache();
9350 }
9351 }
9352 }
9353}
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 9357 of file doxygen.cpp.

9358{
9359 // Remove all unresolved references to classes from the cache.
9360 // This is needed before resolving the inheritance relations, since
9361 // it would otherwise not find the inheritance relation
9362 // for C in the example below, as B::I was already found to be unresolvable
9363 // (which is correct if you ignore the inheritance relation between A and B).
9364 //
9365 // class A { class I {} };
9366 // class B : public A {};
9367 // class C : public B::I {};
9369
9370 // for each class method name
9371 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9372 {
9373 // for each function with that name
9374 for (const auto &imd : *nm)
9375 {
9376 MemberDefMutable *md = toMemberDefMutable(imd.get());
9377 if (md)
9378 {
9380 }
9381 }
9382 }
9383
9384}
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 9073 of file doxygen.cpp.

9074{
9075 std::vector<ClassDefMutable*> classList;
9076 for (const auto &cdi : *Doxygen::classLinkedMap)
9077 {
9078 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9079 if (cd && (cd->getOuterScope()==nullptr ||
9081 {
9082 addClassAndNestedClasses(classList,cd);
9083 }
9084 }
9085 for (const auto &cdi : *Doxygen::hiddenClassLinkedMap)
9086 {
9087 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9088 if (cd && (cd->getOuterScope()==nullptr ||
9090 {
9091 addClassAndNestedClasses(classList,cd);
9092 }
9093 }
9094 generateDocsForClassList(classList);
9095}
static void generateDocsForClassList(const std::vector< ClassDefMutable * > &classList)
Definition doxygen.cpp:8975

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

9100{
9101 for (const auto &cdi : *Doxygen::conceptLinkedMap)
9102 {
9104
9105 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9106 if (cd &&
9107 (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9108 cd->getOuterScope()==Doxygen::globalScope // only look at global concepts
9109 ) && !cd->isHidden() && cd->isLinkableInProject()
9110 )
9111 {
9112 msg("Generating docs for concept {}...\n",cd->displayName());
9114 }
9115 }
9116}
virtual void writeDocumentation(OutputList &ol)=0
virtual bool isHidden() const =0
virtual QCString displayName(bool includeScope=TRUE) 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 QCString & 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 10192 of file doxygen.cpp.

10194{
10195 std::ofstream f;
10196 bool fileOpened=openOutputFile(configFile,f);
10197 bool writeToStdout=configFile=="-";
10198 if (fileOpened)
10199 {
10200 TextStream t(&f);
10201 Config::writeTemplate(t,shortList,updateOnly);
10202 if (!writeToStdout)
10203 {
10204 if (!updateOnly)
10205 {
10206 msg("\n\nConfiguration file '{}' created.\n\n",configFile);
10207 msg("Now edit the configuration file and enter\n\n");
10208 if (configFile!="Doxyfile" && configFile!="doxyfile")
10209 msg(" doxygen {}\n\n",configFile);
10210 else
10211 msg(" doxygen\n\n");
10212 msg("to generate the documentation for your project\n\n");
10213 }
10214 else
10215 {
10216 msg("\n\nConfiguration file '{}' updated.\n\n",configFile);
10217 }
10218 }
10219 }
10220 else
10221 {
10222 term("Cannot open file {} for writing\n",configFile);
10223 }
10224}
void writeTemplate(TextStream &t, bool shortList, bool updateOnly=FALSE)

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

Referenced by readConfiguration().

◆ generateDiskNames()

void generateDiskNames ( )
static

Definition at line 10447 of file doxygen.cpp.

10448{
10449 for (const auto &fn : *Doxygen::inputNameLinkedMap)
10450 {
10451 struct FileEntry
10452 {
10453 FileEntry(const QCString &p,FileDef *fd) : path(p), fileDef(fd) {}
10454 QCString path;
10455 FileDef *fileDef;
10456 };
10457
10458 // collect the entry for which to compute the longest common prefix (LCP) of the path
10459 std::vector<FileEntry> fileEntries;
10460 for (const auto &fd : *fn)
10461 {
10462 if (!fd->isReference()) // skip external references
10463 {
10464 fileEntries.emplace_back(fd->getPath(),fd.get());
10465 }
10466 }
10467
10468 size_t size = fileEntries.size();
10469
10470 if (size==1) // name if unique, so diskname is simply the name
10471 {
10472 FileDef *fd = fileEntries[0].fileDef;
10473 fd->setDiskName(fn->fileName());
10474 }
10475 else if (size>1) // multiple occurrences of the same file name
10476 {
10477 // sort the array
10478 std::stable_sort(fileEntries.begin(),
10479 fileEntries.end(),
10480 [](const FileEntry &fe1,const FileEntry &fe2)
10481 { return qstricmp_sort(fe1.path,fe2.path)<0; }
10482 );
10483
10484 // since the entries are sorted, the common prefix of the whole array is same
10485 // as the common prefix between the first and last entry
10486 const FileEntry &first = fileEntries[0];
10487 const FileEntry &last = fileEntries[size-1];
10488 int first_path_size = static_cast<int>(first.path.size())-1; // -1 to skip trailing slash
10489 int last_path_size = static_cast<int>(last.path.size())-1; // -1 to skip trailing slash
10490 int j=0;
10491 int i=0;
10492 for (i=0;i<first_path_size && i<last_path_size;i++)
10493 {
10494 if (first.path[i]=='/') j=i;
10495 if (first.path[i]!=last.path[i]) break;
10496 }
10497 if (i==first_path_size && i<last_path_size && last.path[i]=='/')
10498 {
10499 // case first='some/path' and last='some/path/more' => match is 'some/path'
10500 j=first_path_size;
10501 }
10502 else if (i==last_path_size && i<first_path_size && first.path[i]=='/')
10503 {
10504 // case first='some/path/more' and last='some/path' => match is 'some/path'
10505 j=last_path_size;
10506 }
10507
10508 // add non-common part of the path to the name
10509 for (auto &fileEntry : fileEntries)
10510 {
10511 QCString prefix = fileEntry.path.right(fileEntry.path.length()-j-1);
10512 fileEntry.fileDef->setName(prefix+fn->fileName());
10513 //printf("!!!!!!!! non unique disk name=%s:%s\n",qPrint(prefix),fn->fileName());
10514 fileEntry.fileDef->setDiskName(prefix+fn->fileName());
10515 }
10516 }
10517 }
10518}
constexpr auto prefix
Definition anchor.cpp:44
virtual void setDiskName(const QCString &name)=0

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

Referenced by parseInput().

◆ generateDocsForClassList()

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

Definition at line 8975 of file doxygen.cpp.

8976{
8977 AUTO_TRACE();
8978 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8979 if (numThreads>1) // multi threaded processing
8980 {
8981 struct DocContext
8982 {
8983 DocContext(ClassDefMutable *cd_,const OutputList &ol_)
8984 : cd(cd_), ol(ol_) {}
8985 ClassDefMutable *cd;
8986 OutputList ol;
8987 };
8988 ThreadPool threadPool(numThreads);
8989 std::vector< std::future< std::shared_ptr<DocContext> > > results;
8990 for (const auto &cd : classList)
8991 {
8992 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
8993 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
8994 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
8995 )
8996 {
8997 auto ctx = std::make_shared<DocContext>(cd,*g_outputList);
8998 auto processFile = [ctx]()
8999 {
9000 msg("Generating docs for compound {}...\n",ctx->cd->displayName());
9001
9002 // skip external references, anonymous compounds and
9003 // template instances
9004 if (!ctx->cd->isHidden() && !ctx->cd->isEmbeddedInOuterScope() &&
9005 ctx->cd->isLinkableInProject() && !ctx->cd->isImplicitTemplateInstance())
9006 {
9007 ctx->cd->writeDocumentation(ctx->ol);
9008 ctx->cd->writeMemberList(ctx->ol);
9009 }
9010
9011 // even for undocumented classes, the inner classes can be documented.
9012 ctx->cd->writeDocumentationForInnerClasses(ctx->ol);
9013 return ctx;
9014 };
9015 results.emplace_back(threadPool.queue(processFile));
9016 }
9017 }
9018 for (auto &f : results)
9019 {
9020 auto ctx = f.get();
9021 }
9022 }
9023 else // single threaded processing
9024 {
9025 for (const auto &cd : classList)
9026 {
9027 //printf("cd=%s getOuterScope=%p global=%p hidden=%d embeddedInOuterScope=%d\n",
9028 // qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope,cd->isHidden(),cd->isEmbeddedInOuterScope());
9029 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9030 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9031 )
9032 {
9033 // skip external references, anonymous compounds and
9034 // template instances
9035 if ( !cd->isHidden() && !cd->isEmbeddedInOuterScope() &&
9036 cd->isLinkableInProject() && !cd->isImplicitTemplateInstance())
9037 {
9038 msg("Generating docs for compound {}...\n",cd->displayName());
9039
9040 cd->writeDocumentation(*g_outputList);
9041 cd->writeMemberList(*g_outputList);
9042 }
9043 // even for undocumented classes, the inner classes can be documented.
9044 cd->writeDocumentationForInnerClasses(*g_outputList);
9045 }
9046 }
9047 }
9048}

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

Referenced by generateClassDocs().

◆ generateExampleDocs()

void generateExampleDocs ( )
static

Definition at line 9900 of file doxygen.cpp.

9901{
9902 g_outputList->disable(OutputType::Man);
9903 for (const auto &pd : *Doxygen::exampleLinkedMap)
9904 {
9905 msg("Generating docs for example {}...\n",pd->name());
9906 SrcLangExt lang = getLanguageFromFileName(pd->name(), SrcLangExt::Unknown);
9907 if (lang != SrcLangExt::Unknown)
9908 {
9909 QCString ext = getFileNameExtension(pd->name());
9910 auto intf = Doxygen::parserManager->getCodeParser(ext);
9911 intf->resetCodeParserState();
9912 }
9913 QCString n=pd->getOutputFileBase();
9914 startFile(*g_outputList,n,false,n,pd->name());
9916 g_outputList->docify(pd->name());
9918 g_outputList->startContents();
9919 QCString lineNoOptStr;
9920 if (pd->showLineNo())
9921 {
9922 lineNoOptStr="{lineno}";
9923 }
9924 g_outputList->generateDoc(pd->docFile(), // file
9925 pd->docLine(), // startLine
9926 pd.get(), // context
9927 nullptr, // memberDef
9928 (pd->briefDescription().isEmpty()?"":pd->briefDescription()+"\n\n")+
9929 pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
9930 DocOptions()
9931 .setIndexWords(true)
9932 .setExample(pd->name()));
9933 endFile(*g_outputList); // contains g_outputList->endContents()
9934 }
9936}
void startTitle(OutputList &ol, const QCString &fileName, const DefinitionMutable *def)
Definition index.cpp:386
void endFile(OutputList &ol, bool skipNavIndex, bool skipEndContents, const QCString &navPath)
Definition index.cpp:429
void endTitle(OutputList &ol, const QCString &fileName, const QCString &name)
Definition index.cpp:396
void startFile(OutputList &ol, const QCString &name, bool isSource, const QCString &manName, const QCString &title, HighlightedItem hli, bool additionalIndices, const QCString &altSidebarName, int hierarchyLevel, const QCString &allMembersFile)
Definition index.cpp:403
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5235
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5277

References endFile(), endTitle(), Doxygen::exampleLinkedMap, g_outputList, getFileNameExtension(), getLanguageFromFileName(), Man, msg, Doxygen::parserManager, startFile(), and startTitle().

Referenced by generateOutput().

◆ generateFileDocs()

void generateFileDocs ( )
static

Definition at line 8610 of file doxygen.cpp.

8611{
8612 if (Index::instance().numDocumentedFiles()==0) return;
8613
8614 if (!Doxygen::inputNameLinkedMap->empty())
8615 {
8616 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8617 if (numThreads>1) // multi threaded processing
8618 {
8619 struct DocContext
8620 {
8621 DocContext(FileDef *fd_,const OutputList &ol_)
8622 : fd(fd_), ol(ol_) {}
8623 FileDef *fd;
8624 OutputList ol;
8625 };
8626 ThreadPool threadPool(numThreads);
8627 std::vector< std::future< std::shared_ptr<DocContext> > > results;
8628 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8629 {
8630 for (const auto &fd : *fn)
8631 {
8632 bool doc = fd->isLinkableInProject();
8633 if (doc)
8634 {
8635 auto ctx = std::make_shared<DocContext>(fd.get(),*g_outputList);
8636 auto processFile = [ctx]() {
8637 msg("Generating docs for file {}...\n",ctx->fd->docName());
8638 ctx->fd->writeDocumentation(ctx->ol);
8639 return ctx;
8640 };
8641 results.emplace_back(threadPool.queue(processFile));
8642 }
8643 }
8644 }
8645 for (auto &f : results)
8646 {
8647 auto ctx = f.get();
8648 }
8649 }
8650 else // single threaded processing
8651 {
8652 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8653 {
8654 for (const auto &fd : *fn)
8655 {
8656 bool doc = fd->isLinkableInProject();
8657 if (doc)
8658 {
8659 msg("Generating docs for file {}...\n",fd->docName());
8660 fd->writeDocumentation(*g_outputList);
8661 }
8662 }
8663 }
8664 }
8665 }
8666}

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

Referenced by generateOutput().

◆ generateFileSources()

void generateFileSources ( )
static

Definition at line 8444 of file doxygen.cpp.

8445{
8446 auto processSourceFile = [](FileDef *fd,OutputList &ol,ClangTUParser *parser)
8447 {
8448 bool showSources = fd->generateSourceFile() && !Htags::useHtags; // sources need to be shown in the output
8449 bool parseSources = !fd->isReference() && Doxygen::parseSourcesNeeded; // we needed to parse the sources even if we do not show them
8450 if (showSources)
8451 {
8452 msg("Generating code for file {}...\n",fd->docName());
8453 fd->writeSourceHeader(ol);
8454 fd->writeSourceBody(ol,parser);
8455 fd->writeSourceFooter(ol);
8456 }
8457 else if (parseSources)
8458 {
8459 msg("Parsing code for file {}...\n",fd->docName());
8460 fd->parseSource(parser);
8461 }
8462 };
8463 if (!Doxygen::inputNameLinkedMap->empty())
8464 {
8465#if USE_LIBCLANG
8467 {
8468 StringUnorderedSet processedFiles;
8469
8470 // create a dictionary with files to process
8471 StringUnorderedSet filesToProcess;
8472
8473 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8474 {
8475 for (const auto &fd : *fn)
8476 {
8477 filesToProcess.insert(fd->absFilePath().str());
8478 }
8479 }
8480 // process source files (and their include dependencies)
8481 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8482 {
8483 for (const auto &fd : *fn)
8484 {
8485 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp &&
8486 (fd->generateSourceFile() ||
8488 )
8489 )
8490 {
8491 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8492 clangParser->parse();
8493 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8494
8495 for (auto incFile : clangParser->filesInSameTU())
8496 {
8497 if (filesToProcess.find(incFile)!=filesToProcess.end() && // part of input
8498 fd->absFilePath()!=incFile && // not same file
8499 processedFiles.find(incFile)==processedFiles.end()) // not yet marked as processed
8500 {
8501 StringVector moreFiles;
8502 bool ambig = false;
8504 if (ifd && !ifd->isReference())
8505 {
8506 processSourceFile(ifd,*g_outputList,clangParser.get());
8507 processedFiles.insert(incFile);
8508 }
8509 }
8510 }
8511 processedFiles.insert(fd->absFilePath().str());
8512 }
8513 }
8514 }
8515 // process remaining files
8516 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8517 {
8518 for (const auto &fd : *fn)
8519 {
8520 if (processedFiles.find(fd->absFilePath().str())==processedFiles.end()) // not yet processed
8521 {
8522 if (fd->getLanguage()==SrcLangExt::Cpp) // C/C++ file, use clang parser
8523 {
8524 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8525 clangParser->parse();
8526 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8527 }
8528 else // non C/C++ file, use built-in parser
8529 {
8530 processSourceFile(fd.get(),*g_outputList,nullptr);
8531 }
8532 }
8533 }
8534 }
8535 }
8536 else
8537#endif
8538 {
8539 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8540 if (numThreads>1)
8541 {
8542 msg("Generating code files using {} threads.\n",numThreads);
8543 struct SourceContext
8544 {
8545 SourceContext(FileDef *fd_,bool gen_,const OutputList &ol_)
8546 : fd(fd_), generateSourceFile(gen_), ol(ol_) {}
8547 FileDef *fd;
8548 bool generateSourceFile;
8549 OutputList ol;
8550 };
8551 ThreadPool threadPool(numThreads);
8552 std::vector< std::future< std::shared_ptr<SourceContext> > > results;
8553 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8554 {
8555 for (const auto &fd : *fn)
8556 {
8557 bool generateSourceFile = fd->generateSourceFile() && !Htags::useHtags;
8558 auto ctx = std::make_shared<SourceContext>(fd.get(),generateSourceFile,*g_outputList);
8559 auto processFile = [ctx]()
8560 {
8561 if (ctx->generateSourceFile)
8562 {
8563 msg("Generating code for file {}...\n",ctx->fd->docName());
8564 }
8565 else
8566 {
8567 msg("Parsing code for file {}...\n",ctx->fd->docName());
8568 }
8569 StringVector filesInSameTu;
8570 ctx->fd->getAllIncludeFilesRecursively(filesInSameTu);
8571 if (ctx->generateSourceFile) // sources need to be shown in the output
8572 {
8573 ctx->fd->writeSourceHeader(ctx->ol);
8574 ctx->fd->writeSourceBody(ctx->ol,nullptr);
8575 ctx->fd->writeSourceFooter(ctx->ol);
8576 }
8577 else if (!ctx->fd->isReference() && Doxygen::parseSourcesNeeded)
8578 // we needed to parse the sources even if we do not show them
8579 {
8580 ctx->fd->parseSource(nullptr);
8581 }
8582 return ctx;
8583 };
8584 results.emplace_back(threadPool.queue(processFile));
8585 }
8586 }
8587 for (auto &f : results)
8588 {
8589 auto ctx = f.get();
8590 }
8591 }
8592 else // single threaded version
8593 {
8594 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8595 {
8596 for (const auto &fd : *fn)
8597 {
8598 StringVector filesInSameTu;
8599 fd->getAllIncludeFilesRecursively(filesInSameTu);
8600 processSourceFile(fd.get(),*g_outputList,nullptr);
8601 }
8602 }
8603 }
8604 }
8605 }
8606}
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:136
virtual void writeSourceHeader(OutputList &ol)=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
virtual const QCString & docName() const =0
Class representing a list of output generators that are written to in parallel.
Definition outputlist.h:315
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(), QCString::find(), findFileDef(), g_outputList, FileDef::generateSourceFile(), FileDef::getAllIncludeFilesRecursively(), Definition::getLanguage(), Doxygen::inputNameLinkedMap, ClangParser::instance(), Definition::isReference(), FileDef::isSource(), msg, FileDef::parseSource(), Doxygen::parseSourcesNeeded, ThreadPool::queue(), QCString::str(), Htags::useHtags, FileDef::writeSourceBody(), FileDef::writeSourceFooter(), and FileDef::writeSourceHeader().

Referenced by generateOutput().

◆ generateGroupDocs()

void generateGroupDocs ( )
static

Definition at line 9941 of file doxygen.cpp.

9942{
9943 for (const auto &gd : *Doxygen::groupLinkedMap)
9944 {
9945 if (!gd->isReference())
9946 {
9947 gd->writeDocumentation(*g_outputList);
9948 }
9949 }
9950}

References g_outputList, and Doxygen::groupLinkedMap.

Referenced by generateOutput().

◆ generateNamespaceClassDocs()

void generateNamespaceClassDocs ( const ClassLinkedRefMap & classList)
static

Definition at line 9955 of file doxygen.cpp.

9956{
9957 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
9958 if (numThreads>1) // multi threaded processing
9959 {
9960 struct DocContext
9961 {
9962 DocContext(ClassDefMutable *cdm_,const OutputList &ol_)
9963 : cdm(cdm_), ol(ol_) {}
9964 ClassDefMutable *cdm;
9965 OutputList ol;
9966 };
9967 ThreadPool threadPool(numThreads);
9968 std::vector< std::future< std::shared_ptr<DocContext> > > results;
9969 // for each class in the namespace...
9970 for (const auto &cd : classList)
9971 {
9973 if (cdm)
9974 {
9975 auto ctx = std::make_shared<DocContext>(cdm,*g_outputList);
9976 auto processFile = [ctx]()
9977 {
9978 if ( ( ctx->cdm->isLinkableInProject() &&
9979 !ctx->cdm->isImplicitTemplateInstance()
9980 ) // skip external references, anonymous compounds and
9981 // template instances and nested classes
9982 && !ctx->cdm->isHidden() && !ctx->cdm->isEmbeddedInOuterScope()
9983 )
9984 {
9985 msg("Generating docs for compound {}...\n",ctx->cdm->displayName());
9986 ctx->cdm->writeDocumentation(ctx->ol);
9987 ctx->cdm->writeMemberList(ctx->ol);
9988 }
9989 ctx->cdm->writeDocumentationForInnerClasses(ctx->ol);
9990 return ctx;
9991 };
9992 results.emplace_back(threadPool.queue(processFile));
9993 }
9994 }
9995 // wait for the results
9996 for (auto &f : results)
9997 {
9998 auto ctx = f.get();
9999 }
10000 }
10001 else // single threaded processing
10002 {
10003 // for each class in the namespace...
10004 for (const auto &cd : classList)
10005 {
10007 if (cdm)
10008 {
10009 if ( ( cd->isLinkableInProject() &&
10010 !cd->isImplicitTemplateInstance()
10011 ) // skip external references, anonymous compounds and
10012 // template instances and nested classes
10013 && !cd->isHidden() && !cd->isEmbeddedInOuterScope()
10014 )
10015 {
10016 msg("Generating docs for compound {}...\n",cd->displayName());
10017
10020 }
10022 }
10023 }
10024 }
10025}
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 10027 of file doxygen.cpp.

10028{
10029 // for each concept in the namespace...
10030 for (const auto &cd : conceptList)
10031 {
10033 if ( cdm && cd->isLinkableInProject() && !cd->isHidden())
10034 {
10035 msg("Generating docs for concept {}...\n",cd->name());
10037 }
10038 }
10039}

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

Referenced by generateNamespaceDocs().

◆ generateNamespaceDocs()

void generateNamespaceDocs ( )
static

Definition at line 10041 of file doxygen.cpp.

10042{
10043 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
10044
10045 //writeNamespaceIndex(*g_outputList);
10046
10047 // for each namespace...
10048 for (const auto &nd : *Doxygen::namespaceLinkedMap)
10049 {
10050 if (nd->isLinkableInProject())
10051 {
10053 if (ndm)
10054 {
10055 msg("Generating docs for namespace {}\n",nd->displayName());
10057 }
10058 }
10059
10060 generateNamespaceClassDocs(nd->getClasses());
10061 if (sliceOpt)
10062 {
10063 generateNamespaceClassDocs(nd->getInterfaces());
10064 generateNamespaceClassDocs(nd->getStructs());
10065 generateNamespaceClassDocs(nd->getExceptions());
10066 }
10067 generateNamespaceConceptDocs(nd->getConcepts());
10068 }
10069}
virtual void writeDocumentation(OutputList &ol)=0
static void generateNamespaceConceptDocs(const ConceptLinkedRefMap &conceptList)
static void generateNamespaceClassDocs(const ClassLinkedRefMap &classList)
Definition doxygen.cpp:9955

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

12992{
12993 AUTO_TRACE();
12994 /**************************************************************************
12995 * Initialize output generators *
12996 **************************************************************************/
12997
12998 /// add extra languages for which we can only produce syntax highlighted code
13000
13001 //// dump all symbols
13002 if (g_dumpSymbolMap)
13003 {
13004 dumpSymbolMap();
13005 exit(0);
13006 }
13007
13008 bool generateHtml = Config_getBool(GENERATE_HTML);
13009 bool generateLatex = Config_getBool(GENERATE_LATEX);
13010 bool generateMan = Config_getBool(GENERATE_MAN);
13011 bool generateRtf = Config_getBool(GENERATE_RTF);
13012 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
13013
13014
13016 if (generateHtml)
13017 {
13021 }
13022 if (generateLatex)
13023 {
13026 }
13027 if (generateDocbook)
13028 {
13031 }
13032 if (generateMan)
13033 {
13034 g_outputList->add<ManGenerator>();
13036 }
13037 if (generateRtf)
13038 {
13039 g_outputList->add<RTFGenerator>();
13041 }
13042 if (Config_getBool(USE_HTAGS))
13043 {
13045 QCString htmldir = Config_getString(HTML_OUTPUT);
13046 if (!Htags::execute(htmldir))
13047 err("USE_HTAGS is YES but htags(1) failed. \n");
13048 else if (!Htags::loadFilemap(htmldir))
13049 err("htags(1) ended normally but failed to load the filemap. \n");
13050 }
13051
13052 /**************************************************************************
13053 * Generate documentation *
13054 **************************************************************************/
13055
13056 g_s.begin("Generating style sheet...\n");
13057 //printf("writing style info\n");
13058 g_outputList->writeStyleInfo(0); // write first part
13059 g_s.end();
13060
13061 bool searchEngine = Config_getBool(SEARCHENGINE);
13062 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
13063
13064 g_s.begin("Generating search indices...\n");
13065 if (searchEngine && !serverBasedSearch && generateHtml)
13066 {
13068 }
13069
13070 // generate search indices (need to do this before writing other HTML
13071 // pages as these contain a drop down menu with options depending on
13072 // what categories we find in this function.
13073 if (generateHtml && searchEngine)
13074 {
13075 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
13076 Dir searchDir(searchDirName.str());
13077 if (!searchDir.exists() && !searchDir.mkdir(searchDirName.str()))
13078 {
13079 term("Could not create search results directory '{}' $PWD='{}'\n",
13080 searchDirName,Dir::currentDirPath());
13081 }
13082 HtmlGenerator::writeSearchData(searchDirName);
13083 if (!serverBasedSearch) // client side search index
13084 {
13086 }
13087 }
13088 g_s.end();
13089
13090 // copy static stuff
13091 if (generateHtml)
13092 {
13094 copyLogo(Config_getString(HTML_OUTPUT),true);
13095 copyIcon(Config_getString(HTML_OUTPUT),true);
13096 copyExtraFiles(Config_getList(HTML_EXTRA_FILES),"HTML_EXTRA_FILES",Config_getString(HTML_OUTPUT),true);
13097 }
13098 if (generateLatex)
13099 {
13101 copyLogo(Config_getString(LATEX_OUTPUT),false);
13102 copyIcon(Config_getString(LATEX_OUTPUT),false);
13103 copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT),false);
13104 }
13105 if (generateDocbook)
13106 {
13107 copyLogo(Config_getString(DOCBOOK_OUTPUT),false);
13108 copyIcon(Config_getString(DOCBOOK_OUTPUT),false);
13109 }
13110 if (generateRtf)
13111 {
13112 copyLogo(Config_getString(RTF_OUTPUT),false);
13113 copyIcon(Config_getString(RTF_OUTPUT),false);
13114 copyExtraFiles(Config_getList(RTF_EXTRA_FILES),"RTF_EXTRA_FILES",Config_getString(RTF_OUTPUT),false);
13115 }
13116
13118 if (fm.hasFormulas() && generateHtml
13119 && !Config_getBool(USE_MATHJAX))
13120 {
13121 g_s.begin("Generating images for formulas in HTML...\n");
13122 fm.generateImages(Config_getString(HTML_OUTPUT), true, Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg ?
13124 g_s.end();
13125 }
13126 if (fm.hasFormulas() && generateRtf)
13127 {
13128 g_s.begin("Generating images for formulas in RTF...\n");
13130 g_s.end();
13131 }
13132
13133 if (fm.hasFormulas() && generateDocbook)
13134 {
13135 g_s.begin("Generating images for formulas in Docbook...\n");
13137 g_s.end();
13138 }
13139
13140 g_s.begin("Generating example documentation...\n");
13142 g_s.end();
13143
13144 g_s.begin("Generating file sources...\n");
13146 g_s.end();
13147
13148 g_s.begin("Counting members...\n");
13149 // needs to be done after generating the sources
13150 // but before generating the compound documentation, see bug #12233
13151 countMembers();
13152 g_s.end();
13153
13154 g_s.begin("Generating file documentation...\n");
13156 g_s.end();
13157
13158 g_s.begin("Generating page documentation...\n");
13160 g_s.end();
13161
13162 g_s.begin("Generating group documentation...\n");
13164 g_s.end();
13165
13166 g_s.begin("Generating class documentation...\n");
13168 g_s.end();
13169
13170 g_s.begin("Generating concept documentation...\n");
13172 g_s.end();
13173
13174 g_s.begin("Generating module documentation...\n");
13176 g_s.end();
13177
13178 g_s.begin("Generating namespace documentation...\n");
13180 g_s.end();
13181
13182 if (Config_getBool(GENERATE_LEGEND))
13183 {
13184 g_s.begin("Generating graph info page...\n");
13186 g_s.end();
13187 }
13188
13189 g_s.begin("Generating directory documentation...\n");
13191 g_s.end();
13192
13193 if (g_outputList->size()>0)
13194 {
13196 }
13197
13198 g_s.begin("finalizing index lists...\n");
13199 Doxygen::indexList->finalize();
13200 g_s.end();
13201
13202 g_s.begin("writing tag file...\n");
13203 writeTagFile();
13204 g_s.end();
13205
13206 if (Config_getBool(GENERATE_XML))
13207 {
13208 g_s.begin("Generating XML output...\n");
13210 generateXML();
13212 g_s.end();
13213 }
13214 if (Config_getBool(GENERATE_SQLITE3))
13215 {
13216 g_s.begin("Generating SQLITE3 output...\n");
13218 g_s.end();
13219 }
13220
13221 if (Config_getBool(GENERATE_AUTOGEN_DEF))
13222 {
13223 g_s.begin("Generating AutoGen DEF output...\n");
13224 generateDEF();
13225 g_s.end();
13226 }
13227 if (Config_getBool(GENERATE_PERLMOD))
13228 {
13229 g_s.begin("Generating Perl module output...\n");
13231 g_s.end();
13232 }
13233 if (generateHtml && searchEngine && serverBasedSearch)
13234 {
13235 g_s.begin("Generating search index\n");
13236 if (Doxygen::searchIndex.kind()==SearchIndexIntf::Internal) // write own search index
13237 {
13239 Doxygen::searchIndex.write(Config_getString(HTML_OUTPUT)+"/search/search.idx");
13240 }
13241 else // write data for external search index
13242 {
13244 QCString searchDataFile = Config_getString(SEARCHDATA_FILE);
13245 if (searchDataFile.isEmpty())
13246 {
13247 searchDataFile="searchdata.xml";
13248 }
13249 if (!Portable::isAbsolutePath(searchDataFile.data()))
13250 {
13251 searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/");
13252 }
13253 Doxygen::searchIndex.write(searchDataFile);
13254 }
13255 g_s.end();
13256 }
13257
13258 if (generateRtf)
13259 {
13260 g_s.begin("Combining RTF output...\n");
13261 if (!RTFGenerator::preProcessFileInplace(Config_getString(RTF_OUTPUT),"refman.rtf"))
13262 {
13263 err("An error occurred during post-processing the RTF files!\n");
13264 }
13265 g_s.end();
13266 }
13267
13268 if (PlantumlManager::instance().needToRun())
13269 {
13270 g_s.begin("Running plantuml with JAVA...\n");
13272 g_s.end();
13273 }
13274
13275 if (MermaidManager::instance().needToRun())
13276 {
13277 g_s.begin("Running mermaid (mmdc)...\n");
13279 g_s.end();
13280 }
13281
13282 if (Config_getBool(HAVE_DOT) && DotManager::instance()->needToRun())
13283 {
13284 g_s.begin("Running dot...\n");
13286 g_s.end();
13287 }
13288
13289 if (generateHtml &&
13290 Config_getBool(GENERATE_HTMLHELP) &&
13291 !Config_getString(HHC_LOCATION).isEmpty())
13292 {
13293 g_s.begin("Running html help compiler...\n");
13295 g_s.end();
13296 }
13297
13298 if ( generateHtml &&
13299 Config_getBool(GENERATE_QHP) &&
13300 !Config_getString(QHG_LOCATION).isEmpty())
13301 {
13302 g_s.begin("Running qhelpgenerator...\n");
13304 g_s.end();
13305 }
13306
13307 g_outputList->cleanup();
13309
13311
13313 {
13314
13315 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
13316 if (numThreads<1) numThreads=1;
13317 msg("Total elapsed time: {:.6f} seconds\n(of which an average of {:.6f} seconds per thread waiting for external tools to finish)\n",
13318 (static_cast<double>(Debug::elapsedTime())),
13319 Portable::getSysElapsedTime()/static_cast<double>(numThreads)
13320 );
13321 g_s.print();
13322
13324 msg("finished...\n");
13326 }
13327 else
13328 {
13329 msg("finished...\n");
13330 }
13331
13332
13333 /**************************************************************************
13334 * Start cleaning up *
13335 **************************************************************************/
13336
13338
13340 Dir thisDir;
13341 thisDir.remove(Doxygen::filterDBFileName.str());
13343 exitTracing();
13345 delete Doxygen::clangUsrMap;
13347
13348 //dumpDocNodeSizes();
13349}
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:133
static double elapsedTime()
Definition debug.cpp:201
static void setFlag(const DebugMask mask)
Definition debug.cpp:118
static std::string currentDirPath()
Definition dir.cpp:342
static void init()
bool run()
Definition dot.cpp:119
static DotManager * instance()
Definition dot.cpp:78
static bool generatingXmlOutput
Definition doxygen.h:134
static ClangUsrMap * clangUsrMap
Definition doxygen.h:126
bool hasFormulas() const
Definition formula.cpp:720
void generateImages(const QCString &outputDir, bool toIndex, Format format, HighDPI hd=HighDPI::Off)
Definition formula.cpp:635
Generator for HTML output.
Definition htmlgen.h:96
static void init()
Definition htmlgen.cpp:1248
static void writeSearchPage()
Definition htmlgen.cpp:3238
static void writeTabData()
Additional initialization after indices have been created.
Definition htmlgen.cpp:1412
static void writeSearchData(const QCString &dir)
Definition htmlgen.cpp:1421
static void writeExternalSearchPage()
Definition htmlgen.cpp:3337
Generator for LaTeX output.
Definition latexgen.h:94
static void init()
Definition latexgen.cpp:632
Generator for Man page output.
Definition mangen.h:69
static void init()
Definition mangen.cpp:272
void run()
Run mmdc tool for all collected diagrams.
Definition mermaid.cpp:252
static MermaidManager & instance()
Definition mermaid.cpp:33
void writeDocumentation(OutputList &ol)
static PlantumlManager & instance()
Definition plantuml.cpp:232
void run()
Run plant UML tool for all images.
Definition plantuml.cpp:390
Generator for RTF output.
Definition rtfgen.h:80
static void init()
Definition rtfgen.cpp:461
static bool preProcessFileInplace(const QCString &path, const QCString &name)
This is an API to a VERY brittle RTF preprocessor that combines nested RTF files.
Definition rtfgen.cpp:2461
static void showCacheUsage()
Show usage of the type lookup cache.
void generateDEF()
Definition defgen.cpp:464
void generateDirDocs(OutputList &ol)
Definition dirdef.cpp:1210
static void copyLatexStyleSheet()
static void runQHelpGenerator()
static void copyExtraFiles(const StringVector &files, const QCString &filesOption, const QCString &outputOption, bool toIndex)
class Statistics g_s
static void copyStyleSheet()
static void generateGroupDocs()
Definition doxygen.cpp:9941
static void generateExampleDocs()
Definition doxygen.cpp:9900
static void dumpSymbolMap()
static void generateFileDocs()
Definition doxygen.cpp:8610
static void generatePageDocs()
Definition doxygen.cpp:9815
static void generateFileSources()
Definition doxygen.cpp:8444
static void generateClassDocs()
Definition doxygen.cpp:9073
static void countMembers()
Definition doxygen.cpp:8934
static void copyLogo(const QCString &outputOption, bool toIndex)
static void runHtmlHelpCompiler()
static bool g_dumpSymbolMap
Definition doxygen.cpp:192
static void copyIcon(const QCString &outputOption, bool toIndex)
static void generateNamespaceDocs()
static void writeTagFile()
void cleanUpDoxygen()
static void generateConceptDocs()
Definition doxygen.cpp:9099
void writeGraphInfo(OutputList &ol)
Definition index.cpp:4108
void writeIndexHierarchy(OutputList &ol)
Definition index.cpp:5822
void finishWarnExit()
Definition message.cpp:294
void deinit()
bool isAbsolutePath(const QCString &fileName)
Definition portable.cpp:497
double getSysElapsedTime()
Definition portable.cpp:97
void generatePerlMod()
void finalizeSearchIndexer()
void createJavaScriptSearchIndex()
void writeJavaScriptSearchIndex()
void generateSqlite3()
static bool execute(const QCString &htmldir)
Definition htags.cpp:38
static bool loadFilemap(const QCString &htmldir)
Definition htags.cpp:107
void exitTracing()
Definition trace.cpp:52
void addCodeOnlyMappings()
Definition util.cpp:5229
void cleanupInlineGraph()
Definition util.cpp:7012
void generateXML()
Definition xmlgen.cpp:2317

References addCodeOnlyMappings(), AUTO_TRACE, FormulaManager::Bitmap, Doxygen::clangUsrMap, cleanUpDoxygen(), cleanupInlineGraph(), Debug::clearFlag(), Config_getBool, Config_getEnum, Config_getInt, Config_getList, Config_getString, copyExtraFiles(), copyIcon(), copyLatexStyleSheet(), copyLogo(), copyStyleSheet(), countMembers(), createJavaScriptSearchIndex(), Dir::currentDirPath(), QCString::data(), Config::deinit(), dumpSymbolMap(), Debug::elapsedTime(), err, Htags::execute(), Dir::exists(), exitTracing(), FALSE, Doxygen::filterDBFileName, 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(), QCString::isEmpty(), Debug::isFlagSet(), Htags::loadFilemap(), Dir::mkdir(), msg, FormulaManager::On, QCString::prepend(), RTFGenerator::preProcessFileInplace(), Dir::remove(), DotManager::run(), MermaidManager::run(), PlantumlManager::run(), runHtmlHelpCompiler(), runQHelpGenerator(), Doxygen::searchIndex, Debug::setFlag(), SymbolResolver::showCacheUsage(), QCString::str(), term, Debug::Time, TRUE, Htags::useHtags, FormulaManager::Vector, ModuleManager::writeDocumentation(), HtmlGenerator::writeExternalSearchPage(), writeGraphInfo(), writeIndexHierarchy(), writeJavaScriptSearchIndex(), HtmlGenerator::writeSearchData(), HtmlGenerator::writeSearchPage(), HtmlGenerator::writeTabData(), and writeTagFile().

Referenced by main().

◆ generatePageDocs()

void generatePageDocs ( )
static

Definition at line 9815 of file doxygen.cpp.

9816{
9817 //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageLinkedMap->count());
9818 if (Index::instance().numDocumentedPages()==0) return;
9819 for (const auto &pd : *Doxygen::pageLinkedMap)
9820 {
9821 if (!pd->getGroupDef() && !pd->isReference())
9822 {
9823 msg("Generating docs for page {}...\n",pd->name());
9824 pd->writeDocumentation(*g_outputList);
9825 }
9826 }
9827}

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

Referenced by generateOutput().

◆ generateXRefPages()

void generateXRefPages ( )
static

Definition at line 5426 of file doxygen.cpp.

5427{
5428 AUTO_TRACE();
5430 {
5431 rl->generatePage();
5432 }
5433}
std::unique_ptr< RefList > Ptr
Definition linkedmap.h:38
static RefListManager & instance()
Definition reflist.h:121

References AUTO_TRACE, and RefListManager::instance().

Referenced by parseInput().

◆ getArg()

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

Definition at line 11243 of file doxygen.cpp.

11244{
11245 char *s=nullptr;
11246 if (qstrlen(&argv[optInd][2])>0)
11247 s=&argv[optInd][2];
11248 else if (optInd+1<argc && argv[optInd+1][0]!='-')
11249 s=argv[++optInd];
11250 return s;
11251}
uint32_t qstrlen(const char *str)
Returns the length of string str, or 0 if a null pointer is passed.
Definition qcstring.h:58

References qstrlen().

Referenced by readConfiguration().

◆ getParserForFile()

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

Definition at line 10524 of file doxygen.cpp.

10525{
10526 QCString fileName=fn;
10527 QCString extension;
10528 int sep = fileName.findRev('/');
10529 int ei = fileName.findRev('.');
10530 if (ei!=-1 && (sep==-1 || ei>sep)) // matches dir/file.ext but not dir.1/file
10531 {
10532 extension=fileName.right(fileName.length()-ei);
10533 }
10534 else
10535 {
10536 extension = ".no_extension";
10537 }
10538
10539 return Doxygen::parserManager->getOutlineParser(extension);
10540}

References QCString::findRev(), QCString::length(), Doxygen::parserManager, and QCString::right().

Referenced by parseFilesMultiThreading(), and parseFilesSingleThreading().

◆ getTemplateArgumentsFromName()

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

Definition at line 867 of file doxygen.cpp.

870{
871 // for each scope fragment, check if it is a template and advance through
872 // the list if so.
873 int i=0, p=0;
874 auto alIt = tArgLists.begin();
875 while ((i=name.find("::",p))!=-1 && alIt!=tArgLists.end())
876 {
877 NamespaceDef *nd = Doxygen::namespaceLinkedMap->find(name.left(i));
878 if (nd==nullptr)
879 {
880 ClassDef *cd = getClass(name.left(i));
881 if (cd)
882 {
883 if (!cd->templateArguments().empty())
884 {
885 ++alIt;
886 }
887 }
888 }
889 p=i+2;
890 }
891 return alIt!=tArgLists.end() ?
892 std::make_unique<ArgumentList>(*alIt) :
893 std::unique_ptr<ArgumentList>();
894}

References ArgumentList::empty(), QCString::find(), getClass(), QCString::left(), Doxygen::namespaceLinkedMap, 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 4360 of file doxygen.cpp.

4361{
4362 std::map<std::string,int> templateNames;
4363 int count=0;
4364 for (const Argument &arg : templateArguments)
4365 {
4366 static const reg::Ex re(R"(\a[\w:]*)");
4367 reg::Iterator it(name,re);
4369 for (; it!=end ; ++it)
4370 {
4371 const auto &match = *it;
4372 std::string n = match.str();
4373 if (n==arg.name.str())
4374 {
4375 if (templateNames.find(n)==templateNames.end())
4376 {
4377 templateNames.emplace(n,count);
4378 }
4379 }
4380 }
4381 }
4382 return templateNames;
4383}

References end().

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

◆ haveEqualFileNames()

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

Definition at line 9390 of file doxygen.cpp.

9391{
9392 if (const FileDef *fd = md->getFileDef())
9393 {
9394 return fd->absFilePath() == root->fileName;
9395 }
9396 return false;
9397}

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

Referenced by findDefineDocumentation().

◆ inheritDocumentation()

void inheritDocumentation ( )
static

Definition at line 9120 of file doxygen.cpp.

9121{
9122 for (const auto &mn : *Doxygen::memberNameLinkedMap)
9123 {
9124 for (const auto &imd : *mn)
9125 {
9126 MemberDefMutable *md = toMemberDefMutable(imd.get());
9127 //static int count=0;
9128 //printf("%04d Member '%s'\n",count++,qPrint(md->qualifiedName()));
9129 if (md && md->documentation().isEmpty() && md->briefDescription().isEmpty())
9130 { // no documentation yet
9131 const MemberDef *bmd = md->reimplements();
9132 while (bmd && bmd->documentation().isEmpty() &&
9133 bmd->briefDescription().isEmpty()
9134 )
9135 { // search up the inheritance tree for a documentation member
9136 //printf("bmd=%s class=%s\n",qPrint(bmd->name()),qPrint(bmd->getClassDef()->name()));
9137 bmd = bmd->reimplements();
9138 }
9139 if (bmd) // copy the documentation from the reimplemented member
9140 {
9141 md->setInheritsDocsFrom(bmd);
9142 md->setDocumentation(bmd->documentation(),bmd->docFile(),bmd->docLine());
9144 md->setBriefDescription(bmd->briefDescription(),bmd->briefFile(),bmd->briefLine());
9145 md->copyArgumentNames(bmd);
9147 }
9148 }
9149 }
9150 }
9151}
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(), Definition::inbodyDocumentation(), Definition::inbodyFile(), Definition::inbodyLine(), MemberDef::isDocsForDefinition(), QCString::isEmpty(), 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 11270 of file doxygen.cpp.

11271{
11272 initResources();
11273 QCString lang = Portable::getenv("LC_ALL");
11274 if (!lang.isEmpty()) Portable::setenv("LANG",lang);
11275 std::setlocale(LC_ALL,"");
11276 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
11277 std::setlocale(LC_NUMERIC,"C");
11278
11280
11304
11305 // register any additional parsers here...
11306
11308
11309#if USE_LIBCLANG
11311#endif
11320 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
11321 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
11322 //Doxygen::tagDestinationDict.setAutoDelete(TRUE);
11324
11325 // initialization of these globals depends on
11326 // configuration switches so we need to postpone these
11327 Doxygen::globalScope = nullptr;
11337
11338}
static void startTimer()
Definition debug.cpp:196
A linked map of directories.
Definition dirdef.h:175
A list of index interfaces.
Definition indexlist.h:64
Manages programming language parsers.
Definition parserintf.h:183
std::function< std::unique_ptr< T >() > make_parser_factory()
void initResources()
std::unordered_map< std::string, const Definition * > ClangUsrMap
Definition doxygen.h:82
void setenv(const QCString &variable, const QCString &value)
Definition portable.cpp:286
QCString getenv(const QCString &variable)
Definition portable.cpp:321
void initDefaultExtensionMapping()
Definition util.cpp:5162

References Doxygen::clangUsrMap, Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Doxygen::diaFileNameLinkedMap, Doxygen::dirLinkedMap, Doxygen::dotFileNameLinkedMap, Doxygen::exampleLinkedMap, Doxygen::exampleNameLinkedMap, Doxygen::functionNameLinkedMap, Portable::getenv(), Doxygen::globalScope, Doxygen::groupLinkedMap, Doxygen::hiddenClassLinkedMap, Doxygen::imageNameLinkedMap, Doxygen::includeNameLinkedMap, Doxygen::indexList, initDefaultExtensionMapping(), initResources(), Doxygen::inputNameLinkedMap, QCString::isEmpty(), make_parser_factory(), Doxygen::memberNameLinkedMap, Doxygen::mermaidFileNameLinkedMap, Doxygen::mscFileNameLinkedMap, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, Doxygen::parserManager, Doxygen::plantUmlFileNameLinkedMap, 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 6537 of file doxygen.cpp.

6538{
6539 if (outerScope && outerScope!=Doxygen::globalScope)
6540 {
6541 auto aliasMd = createMemberDefAlias(outerScope,md);
6542 if (outerScope->definitionType()==Definition::TypeClass)
6543 {
6544 ClassDefMutable *cdm = toClassDefMutable(outerScope);
6545 if (cdm)
6546 {
6547 cdm->insertMember(aliasMd.get());
6548 }
6549 }
6550 else if (outerScope->definitionType()==Definition::TypeNamespace)
6551 {
6552 NamespaceDefMutable *ndm = toNamespaceDefMutable(outerScope);
6553 if (ndm)
6554 {
6555 ndm->insertMember(aliasMd.get());
6556 }
6557 }
6558 else if (outerScope->definitionType()==Definition::TypeFile)
6559 {
6560 toFileDef(outerScope)->insertMember(aliasMd.get());
6561 }
6562 if (aliasMd)
6563 {
6564 Doxygen::functionNameLinkedMap->add(md->name())->push_back(std::move(aliasMd));
6565 }
6566 }
6567}
FileDef * toFileDef(Definition *d)
Definition filedef.cpp:1966

References createMemberDefAlias(), Definition::definitionType(), Doxygen::functionNameLinkedMap, Doxygen::globalScope, ClassDefMutable::insertMember(), FileDef::insertMember(), NamespaceDefMutable::insertMember(), Definition::name(), toClassDefMutable(), toFileDef(), toNamespaceDefMutable(), Definition::TypeClass, Definition::TypeFile, and Definition::TypeNamespace.

Referenced by findMember().

◆ isClassSection()

bool isClassSection ( const Entry * root)
static

Definition at line 5094 of file doxygen.cpp.

5095{
5096 if ( !root->name.isEmpty() )
5097 {
5098 if (root->section.isCompound())
5099 // is it a compound (class, struct, union, interface ...)
5100 {
5101 return TRUE;
5102 }
5103 else if (root->section.isCompoundDoc())
5104 // is it a documentation block with inheritance info.
5105 {
5106 bool hasExtends = !root->extends.empty();
5107 if (hasExtends) return TRUE;
5108 }
5109 }
5110 return FALSE;
5111}

References Entry::extends, FALSE, EntryType::isCompound(), EntryType::isCompoundDoc(), QCString::isEmpty(), Entry::name, Entry::section, and TRUE.

Referenced by findClassEntries().

◆ isEntryInGroupOfMember()

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

Definition at line 5606 of file doxygen.cpp.

5607{
5608 const GroupDef *gd = md->getGroupDef();
5609 if (!gd)
5610 {
5611 return allowNoGroup;
5612 }
5613
5614 for (const auto &g : root->groups)
5615 {
5616 if (g.groupname == gd->name())
5617 {
5618 return true; // matching group
5619 }
5620 }
5621
5622 return false;
5623}

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

Referenced by findDefineDocumentation(), and findGlobalMember().

◆ isRecursiveBaseClass()

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

Definition at line 4711 of file doxygen.cpp.

4712{
4713 QCString n=name;
4714 int index=n.find('<');
4715 if (index!=-1)
4716 {
4717 n=n.left(index);
4718 }
4719 bool result = rightScopeMatch(scope,n);
4720 return result;
4721}

References QCString::find(), QCString::left(), and rightScopeMatch().

Referenced by findClassRelation().

◆ isSpecialization()

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

Definition at line 5838 of file doxygen.cpp.

5842{
5843 auto srcIt = srcTempArgLists.begin();
5844 auto dstIt = dstTempArgLists.begin();
5845 while (srcIt!=srcTempArgLists.end() && dstIt!=dstTempArgLists.end())
5846 {
5847 if ((*srcIt).size()!=(*dstIt).size()) return TRUE;
5848 ++srcIt;
5849 ++dstIt;
5850 }
5851 return FALSE;
5852}

References FALSE, and TRUE.

Referenced by addMemberFunction(), makeQualifiedNameWithTemplateParameters(), and searchTemplateSpecs().

◆ isSymbolHidden()

bool isSymbolHidden ( const Definition * d)
static

Definition at line 8867 of file doxygen.cpp.

8868{
8869 bool hidden = d->isHidden();
8870 const Definition *parent = d->getOuterScope();
8871 return parent ? hidden || isSymbolHidden(parent) : hidden;
8872}
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 2795 of file doxygen.cpp.

2796{
2797 bool result = false;
2798 bool typeIsClass = false;
2799 bool typePtrType = false;
2800 QCString type;
2801 Definition *ctx = nullptr;
2802 FileDef *fd = root->fileDef();
2803 SymbolResolver resolver(fd);
2804
2805 AUTO_TRACE("isVarWithConstructor({})",root->name);
2806 if (root->parent()->section.isCompound())
2807 { // inside a class
2808 result=FALSE;
2809 AUTO_TRACE_EXIT("inside class: result={}",result);
2810 return result;
2811 }
2812 else if ((fd != nullptr) && (fd->name().endsWith(".c") || fd->name().endsWith(".h")))
2813 { // inside a .c file
2814 result=FALSE;
2815 AUTO_TRACE_EXIT("inside C file: result={}",result);
2816 return result;
2817 }
2818 if (root->type.isEmpty())
2819 {
2820 result=FALSE;
2821 AUTO_TRACE_EXIT("no type: result={}",result);
2822 return result;
2823 }
2824 if (!root->parent()->name.isEmpty())
2825 {
2826 ctx=Doxygen::namespaceLinkedMap->find(root->parent()->name);
2827 }
2828 type = root->type;
2829 // remove qualifiers
2830 findAndRemoveWord(type,"const");
2831 findAndRemoveWord(type,"static");
2832 findAndRemoveWord(type,"volatile");
2833 typePtrType = type.find('*')!=-1 || type.find('&')!=-1;
2834 if (!typePtrType)
2835 {
2836 typeIsClass = resolver.resolveClass(ctx,type)!=nullptr;
2837 int ti=0;
2838 if (!typeIsClass && (ti=type.find('<'))!=-1)
2839 {
2840 typeIsClass=resolver.resolveClass(ctx,type.left(ti))!=nullptr;
2841 }
2842 }
2843 if (typeIsClass) // now we still have to check if the arguments are
2844 // types or values. Since we do not have complete type info
2845 // we need to rely on heuristics :-(
2846 {
2847 if (root->argList.empty())
2848 {
2849 result=FALSE; // empty arg list -> function prototype.
2850 AUTO_TRACE_EXIT("empty arg list: result={}",result);
2851 return result;
2852 }
2853 for (const Argument &a : root->argList)
2854 {
2855 static const reg::Ex initChars(R"([\d"'&*!^]+)");
2857 if (!a.name.isEmpty() || !a.defval.isEmpty())
2858 {
2859 std::string name = a.name.str();
2860 if (reg::search(name,match,initChars) && match.position()==0)
2861 {
2862 result=TRUE;
2863 }
2864 else
2865 {
2866 result=FALSE; // arg has (type,name) pair -> function prototype
2867 }
2868 AUTO_TRACE_EXIT("function prototype: result={}",result);
2869 return result;
2870 }
2871 if (!a.type.isEmpty() &&
2872 (a.type.at(a.type.length()-1)=='*' ||
2873 a.type.at(a.type.length()-1)=='&'))
2874 // type ends with * or & => pointer or reference
2875 {
2876 result=FALSE;
2877 AUTO_TRACE_EXIT("pointer or reference: result={}",result);
2878 return result;
2879 }
2880 if (a.type.isEmpty() || resolver.resolveClass(ctx,a.type)!=nullptr)
2881 {
2882 result=FALSE; // arg type is a known type
2883 AUTO_TRACE_EXIT("known type: result={}",result);
2884 return result;
2885 }
2886 if (checkIfTypedef(ctx,fd,a.type))
2887 {
2888 result=FALSE; // argument is a typedef
2889 AUTO_TRACE_EXIT("typedef: result={}",result);
2890 return result;
2891 }
2892 std::string atype = a.type.str();
2893 if (reg::search(atype,match,initChars) && match.position()==0)
2894 {
2895 result=TRUE; // argument type starts with typical initializer char
2896 AUTO_TRACE_EXIT("argument with init char: result={}",result);
2897 return result;
2898 }
2899 std::string resType=resolveTypeDef(ctx,a.type).str();
2900 if (resType.empty()) resType=atype;
2901 static const reg::Ex idChars(R"(\a\w*)");
2902 if (reg::search(resType,match,idChars) && match.position()==0) // resType starts with identifier
2903 {
2904 resType=match.str();
2905 if (resType=="int" || resType=="long" ||
2906 resType=="float" || resType=="double" ||
2907 resType=="char" || resType=="void" ||
2908 resType=="signed" || resType=="unsigned" ||
2909 resType=="const" || resType=="volatile" )
2910 {
2911 result=FALSE; // type keyword -> function prototype
2912 AUTO_TRACE_EXIT("type keyword: result={}",result);
2913 return result;
2914 }
2915 }
2916 }
2917 result=TRUE;
2918 }
2919
2920 AUTO_TRACE_EXIT("end: result={}",result);
2921 return result;
2922}
QCString name
Definition arguments.h:44
QCString defval
Definition arguments.h:46
bool checkIfTypedef(const Definition *scope, const FileDef *fileScope, const QCString &n)
Definition util.cpp:5339
bool findAndRemoveWord(QCString &sentence, const char *word)
removes occurrences of whole word from sentence, while keeps internal spaces and reducing multiple se...
Definition util.cpp:5011

References Entry::argList, QCString::at(), AUTO_TRACE, AUTO_TRACE_EXIT, checkIfTypedef(), Argument::defval, ArgumentList::empty(), QCString::endsWith(), FALSE, Entry::fileDef(), QCString::find(), findAndRemoveWord(), EntryType::isCompound(), QCString::isEmpty(), QCString::left(), QCString::length(), Argument::name, Definition::name(), Entry::name, Doxygen::namespaceLinkedMap, Entry::parent(), SymbolResolver::resolveClass(), resolveTypeDef(), reg::search(), Entry::section, QCString::str(), TRUE, 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 11265 of file doxygen.cpp.

11266{
11267 return []() { return std::make_unique<T>(); };
11268}

Referenced by initDoxygen().

◆ makeTemplateInstanceRelation()

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

Definition at line 5168 of file doxygen.cpp.

5169{
5170 AUTO_TRACE("root->name={} cd={}",root->name,cd->name());
5171 int i = root->name.find('<');
5172 int j = root->name.findRev('>');
5173 int k = root->name.find("::",j+1); // A<T::B> => ok, A<T>::B => nok
5174 if (i!=-1 && j!=-1 && k==-1 && root->lang!=SrcLangExt::CSharp && root->lang!=SrcLangExt::Java)
5175 {
5176 ClassDefMutable *master = getClassMutable(root->name.left(i));
5177 if (master && master!=cd && !cd->templateMaster())
5178 {
5179 AUTO_TRACE_ADD("class={} master={}",cd->name(),cd->templateMaster()?cd->templateMaster()->name():"<none>",master->name());
5180 cd->setTemplateMaster(master);
5181 master->insertExplicitTemplateInstance(cd,root->name.mid(i));
5182 }
5183 }
5184}
virtual const ClassDef * templateMaster() const =0
Returns the template master of which this class is an instance.
virtual void insertExplicitTemplateInstance(ClassDef *instance, const QCString &spec)=0
virtual void setTemplateMaster(const ClassDef *tm)=0

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

Referenced by findUsedTemplateInstances().

◆ mergeCategories()

void mergeCategories ( )
static

Definition at line 8392 of file doxygen.cpp.

8393{
8394 AUTO_TRACE();
8395 // merge members of categories into the class they extend
8396 for (const auto &cd : *Doxygen::classLinkedMap)
8397 {
8398 int i=cd->name().find('(');
8399 if (i!=-1) // it is an Objective-C category
8400 {
8401 QCString baseName=cd->name().left(i);
8402 ClassDefMutable *baseClass=toClassDefMutable(Doxygen::classLinkedMap->find(baseName));
8403 if (baseClass)
8404 {
8405 AUTO_TRACE_ADD("merging members of category {} into {}",cd->name(),baseClass->name());
8406 baseClass->mergeCategory(cd.get());
8407 }
8408 }
8409 }
8410}
virtual void mergeCategory(ClassDef *category)=0

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

Referenced by parseInput().

◆ organizeSubGroups()

void organizeSubGroups ( const Entry * root)
static

Definition at line 491 of file doxygen.cpp.

492{
493 //printf("Defining groups\n");
494 // first process the @defgroups blocks
496 //printf("Additional groups\n");
497 // then process the @addtogroup, @weakgroup blocks
499}
static void organizeSubGroupsFiltered(const Entry *root, bool additional)
Definition doxygen.cpp:472

References FALSE, organizeSubGroupsFiltered(), and TRUE.

Referenced by parseInput().

◆ organizeSubGroupsFiltered()

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

Definition at line 472 of file doxygen.cpp.

473{
474 if (root->section.isGroupDoc() && !root->name.isEmpty())
475 {
476 AUTO_TRACE("additional={}",additional);
477 if ((root->groupDocType==Entry::GROUPDOC_NORMAL && !additional) ||
478 (root->groupDocType!=Entry::GROUPDOC_NORMAL && additional))
479 {
480 GroupDef *gd = Doxygen::groupLinkedMap->find(root->name);
481 if (gd)
482 {
483 AUTO_TRACE_ADD("adding {} to group {}",root->name,gd->name());
484 addGroupToGroups(root,gd);
485 }
486 }
487 }
488 for (const auto &e : root->children()) organizeSubGroupsFiltered(e.get(),additional);
489}
void addGroupToGroups(const Entry *root, GroupDef *subGroup)

References addGroupToGroups(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::children(), Entry::GROUPDOC_NORMAL, Entry::groupDocType, Doxygen::groupLinkedMap, QCString::isEmpty(), Definition::name(), Entry::name, organizeSubGroupsFiltered(), and Entry::section.

Referenced by organizeSubGroups(), and organizeSubGroupsFiltered().

◆ parseFile()

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

Definition at line 10542 of file doxygen.cpp.

10545{
10546 QCString fileName=fn;
10547 AUTO_TRACE("fileName={}",fileName);
10548 QCString extension;
10549 int ei = fileName.findRev('.');
10550 if (ei!=-1)
10551 {
10552 extension=fileName.right(fileName.length()-ei);
10553 }
10554 else
10555 {
10556 extension = ".no_extension";
10557 }
10558
10559 FileInfo fi(fileName.str());
10560 std::string preBuf;
10561
10562 if (Config_getBool(ENABLE_PREPROCESSING) &&
10563 parser.needsPreprocessing(extension))
10564 {
10565 Preprocessor preprocessor;
10566 const StringVector &includePath = Config_getList(INCLUDE_PATH);
10567 for (const auto &s : includePath)
10568 {
10569 std::string absPath = FileInfo(s).absFilePath();
10570 preprocessor.addSearchDir(absPath);
10571 }
10572 std::string inBuf;
10573 msg("Preprocessing {}...\n",fn);
10574 readInputFile(fileName,inBuf);
10575 addTerminalCharIfMissing(inBuf,'\n');
10576 preprocessor.processFile(fileName,inBuf,preBuf);
10577 }
10578 else // no preprocessing
10579 {
10580 msg("Reading {}...\n",fn);
10581 readInputFile(fileName,preBuf);
10582 addTerminalCharIfMissing(preBuf,'\n');
10583 }
10584
10585 std::string convBuf;
10586 convBuf.reserve(preBuf.size()+1024);
10587
10588 // convert multi-line C++ comments to C style comments
10589 convertCppComments(preBuf,convBuf,fileName.str());
10590
10591 std::shared_ptr<Entry> fileRoot = std::make_shared<Entry>();
10592 // use language parse to parse the file
10593 if (clangParser)
10594 {
10595 if (newTU) clangParser->parse();
10596 clangParser->switchToFile(fd);
10597 }
10598 parser.parseInput(fileName,convBuf.data(),fileRoot,clangParser);
10599 fileRoot->setFileDef(fd);
10600 return fileRoot;
10601}
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:101
virtual bool needsPreprocessing(const QCString &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 QCString &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 QCString &fileName, const std::string &input, std::string &output)
Definition pre.l:4248
void addSearchDir(const QCString &dir)
Definition pre.l:4230
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:84
bool readInputFile(const QCString &fileName, std::string &contents, bool filter, bool isSourceCode)
read a file name fileName and optionally filter and transcode it
Definition util.cpp:5574

References FileInfo::absFilePath(), Preprocessor::addSearchDir(), addTerminalCharIfMissing(), AUTO_TRACE, Config_getBool, Config_getList, convertCppComments(), QCString::data(), QCString::findRev(), QCString::length(), msg, OutlineParserInterface::needsPreprocessing(), ClangTUParser::parse(), OutlineParserInterface::parseInput(), Preprocessor::processFile(), readInputFile(), QCString::right(), QCString::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 10604 of file doxygen.cpp.

10605{
10606 AUTO_TRACE();
10607#if USE_LIBCLANG
10609 {
10610 StringUnorderedSet processedFiles;
10611
10612 // create a dictionary with files to process
10613 StringUnorderedSet filesToProcess;
10614 for (const auto &s : g_inputFiles)
10615 {
10616 filesToProcess.insert(s);
10617 }
10618
10619 std::mutex processedFilesLock;
10620 // process source files (and their include dependencies)
10621 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10622 msg("Processing input using {} threads.\n",numThreads);
10623 ThreadPool threadPool(numThreads);
10624 using FutureType = std::vector< std::shared_ptr<Entry> >;
10625 std::vector< std::future< FutureType > > results;
10626 for (const auto &s : g_inputFiles)
10627 {
10628 bool ambig = false;
10629 QCString qs = s;
10631 ASSERT(fd!=nullptr);
10632 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp) // this is a source file
10633 {
10634 // lambda representing the work to executed by a thread
10635 auto processFile = [qs,&filesToProcess,&processedFilesLock,&processedFiles]() {
10636 bool ambig_l = false;
10637 std::vector< std::shared_ptr<Entry> > roots;
10639 auto clangParser = ClangParser::instance()->createTUParser(fd_l);
10640 auto parser = getParserForFile(qs);
10641 auto fileRoot { parseFile(*parser.get(),fd_l,qs,clangParser.get(),true) };
10642 roots.push_back(fileRoot);
10643
10644 // Now process any include files in the same translation unit
10645 // first. When libclang is used this is much more efficient.
10646 for (auto incFile : clangParser->filesInSameTU())
10647 {
10648 QCString qincFile = incFile;
10649 if (filesToProcess.find(incFile)!=filesToProcess.end())
10650 {
10651 bool needsToBeProcessed = false;
10652 {
10653 std::lock_guard<std::mutex> lock(processedFilesLock);
10654 needsToBeProcessed = processedFiles.find(incFile)==processedFiles.end();
10655 if (needsToBeProcessed) processedFiles.insert(incFile);
10656 }
10657 if (qincFile!=qs && needsToBeProcessed)
10658 {
10659 FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,qincFile,ambig_l);
10660 if (ifd && !ifd->isReference())
10661 {
10662 //printf(" Processing %s in same translation unit as %s\n",incFile,qPrint(s));
10663 fileRoot = parseFile(*parser.get(),ifd,qincFile,clangParser.get(),false);
10664 roots.push_back(fileRoot);
10665 }
10666 }
10667 }
10668 }
10669 return roots;
10670 };
10671 // dispatch the work and collect the future results
10672 results.emplace_back(threadPool.queue(processFile));
10673 }
10674 }
10675 // synchronize with the Entry result lists produced and add them to the root
10676 for (auto &f : results)
10677 {
10678 auto l = f.get();
10679 for (auto &e : l)
10680 {
10681 root->moveToSubEntryAndKeep(e);
10682 }
10683 }
10684 // process remaining files
10685 results.clear();
10686 for (const auto &s : g_inputFiles)
10687 {
10688 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
10689 {
10690 // lambda representing the work to executed by a thread
10691 auto processFile = [s]() {
10692 bool ambig = false;
10693 QCString qs = s;
10694 std::vector< std::shared_ptr<Entry> > roots;
10696 auto parser { getParserForFile(qs) };
10697 bool useClang = getLanguageFromFileName(qs)==SrcLangExt::Cpp;
10698 if (useClang)
10699 {
10700 auto clangParser = ClangParser::instance()->createTUParser(fd);
10701 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10702 roots.push_back(fileRoot);
10703 }
10704 else
10705 {
10706 auto fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10707 roots.push_back(fileRoot);
10708 }
10709 return roots;
10710 };
10711 results.emplace_back(threadPool.queue(processFile));
10712 }
10713 }
10714 // synchronize with the Entry result lists produced and add them to the root
10715 for (auto &f : results)
10716 {
10717 auto l = f.get();
10718 for (auto &e : l)
10719 {
10720 root->moveToSubEntryAndKeep(e);
10721 }
10722 }
10723 }
10724 else // normal processing
10725#endif
10726 {
10727 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10728 msg("Processing input using {} threads.\n",numThreads);
10729 ThreadPool threadPool(numThreads);
10730 using FutureType = std::shared_ptr<Entry>;
10731 std::vector< std::future< FutureType > > results;
10732 for (const auto &s : g_inputFiles)
10733 {
10734 // lambda representing the work to executed by a thread
10735 auto processFile = [s]() {
10736 bool ambig = false;
10737 QCString qs = s;
10739 auto parser = getParserForFile(qs);
10740 auto fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10741 return fileRoot;
10742 };
10743 // dispatch the work and collect the future results
10744 results.emplace_back(threadPool.queue(processFile));
10745 }
10746 // synchronize with the Entry results produced and add them to the root
10747 for (auto &f : results)
10748 {
10749 root->moveToSubEntryAndKeep(f.get());
10750 }
10751 }
10752}
static std::shared_ptr< Entry > parseFile(OutlineParserInterface &parser, FileDef *fd, const QCString &fn, ClangTUParser *clangParser, bool newTU)
static std::unique_ptr< OutlineParserInterface > getParserForFile(const QCString &fn)
#define ASSERT(x)
Definition qcstring.h:39

References ASSERT, AUTO_TRACE, Doxygen::clangAssistedParsing, Config_getInt, ClangParser::createTUParser(), 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 10755 of file doxygen.cpp.

10756{
10757 AUTO_TRACE();
10758#if USE_LIBCLANG
10760 {
10761 StringUnorderedSet processedFiles;
10762
10763 // create a dictionary with files to process
10764 StringUnorderedSet filesToProcess;
10765 for (const auto &s : g_inputFiles)
10766 {
10767 filesToProcess.insert(s);
10768 }
10769
10770 // process source files (and their include dependencies)
10771 for (const auto &s : g_inputFiles)
10772 {
10773 bool ambig = false;
10774 QCString qs =s;
10776 ASSERT(fd!=nullptr);
10777 if (fd->isSource() && !fd->isReference() && getLanguageFromFileName(qs)==SrcLangExt::Cpp) // this is a source file
10778 {
10779 auto clangParser = ClangParser::instance()->createTUParser(fd);
10780 auto parser { getParserForFile(qs) };
10781 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10782 root->moveToSubEntryAndKeep(fileRoot);
10783 processedFiles.insert(s);
10784
10785 // Now process any include files in the same translation unit
10786 // first. When libclang is used this is much more efficient.
10787 for (auto incFile : clangParser->filesInSameTU())
10788 {
10789 //printf(" file %s\n",qPrint(incFile));
10790 if (filesToProcess.find(incFile)!=filesToProcess.end() && // file need to be processed
10791 processedFiles.find(incFile)==processedFiles.end()) // and is not processed already
10792 {
10794 if (ifd && !ifd->isReference())
10795 {
10796 //printf(" Processing %s in same translation unit as %s\n",qPrint(incFile),qPrint(qs));
10797 fileRoot = parseFile(*parser.get(),ifd,incFile,clangParser.get(),false);
10798 root->moveToSubEntryAndKeep(fileRoot);
10799 processedFiles.insert(incFile);
10800 }
10801 }
10802 }
10803 }
10804 }
10805 // process remaining files
10806 for (const auto &s : g_inputFiles)
10807 {
10808 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
10809 {
10810 bool ambig = false;
10811 QCString qs = s;
10813 if (getLanguageFromFileName(qs)==SrcLangExt::Cpp) // not yet processed
10814 {
10815 auto clangParser = ClangParser::instance()->createTUParser(fd);
10816 auto parser { getParserForFile(qs) };
10817 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10818 root->moveToSubEntryAndKeep(fileRoot);
10819 }
10820 else
10821 {
10822 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
10823 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10824 root->moveToSubEntryAndKeep(fileRoot);
10825 }
10826 processedFiles.insert(s);
10827 }
10828 }
10829 }
10830 else // normal processing
10831#endif
10832 {
10833 for (const auto &s : g_inputFiles)
10834 {
10835 bool ambig = false;
10836 QCString qs = s;
10838 ASSERT(fd!=nullptr);
10839 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
10840 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10841 root->moveToSubEntryAndKeep(std::move(fileRoot));
10842 }
10843 }
10844}

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

Referenced by parseInput().

◆ parseInput()

void parseInput ( )

Definition at line 12325 of file doxygen.cpp.

12326{
12327 AUTO_TRACE();
12328 std::atexit(exitDoxygen);
12329
12330 Portable::correctPath(Config_getList(EXTERNAL_TOOL_PATH));
12331
12332#if USE_LIBCLANG
12333 Doxygen::clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
12334#endif
12335
12336 // we would like to show the versionString earlier, but we first have to handle the configuration file
12337 // to know the value of the QUIET setting.
12338 QCString versionString = getFullVersion();
12339 msg("Doxygen version used: {}\n",versionString);
12340
12342
12343 /**************************************************************************
12344 * Make sure the output directory exists
12345 **************************************************************************/
12346 QCString outputDirectory = Config_getString(OUTPUT_DIRECTORY);
12347 if (!g_singleComment)
12348 {
12349 if (outputDirectory.isEmpty())
12350 {
12351 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,Dir::currentDirPath());
12352 }
12353 else
12354 {
12355 Dir dir(outputDirectory.str());
12356 if (!dir.exists())
12357 {
12358 dir.setPath(Dir::currentDirPath());
12359 if (!dir.mkdir(outputDirectory.str()))
12360 {
12361 term("tag OUTPUT_DIRECTORY: Output directory '{}' does not "
12362 "exist and cannot be created\n",outputDirectory);
12363 }
12364 else
12365 {
12366 msg("Notice: Output directory '{}' does not exist. "
12367 "I have created it for you.\n", outputDirectory);
12368 }
12369 dir.setPath(outputDirectory.str());
12370 }
12371 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,dir.absPath());
12372 }
12373 }
12374 AUTO_TRACE_ADD("outputDirectory={}",outputDirectory);
12375
12376 /**************************************************************************
12377 * Initialize global lists and dictionaries
12378 **************************************************************************/
12379
12380#ifdef HAS_SIGNALS
12381 signal(SIGINT, stopDoxygen);
12382#endif
12383
12384 uint32_t pid = Portable::pid();
12385 Doxygen::filterDBFileName.sprintf("doxygen_filterdb_%d.tmp",pid);
12386 Doxygen::filterDBFileName.prepend(outputDirectory+"/");
12387
12388 /**************************************************************************
12389 * Check/create output directories *
12390 **************************************************************************/
12391
12392 bool generateHtml = Config_getBool(GENERATE_HTML);
12393 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
12394 bool generateXml = Config_getBool(GENERATE_XML);
12395 bool generateLatex = Config_getBool(GENERATE_LATEX);
12396 bool generateRtf = Config_getBool(GENERATE_RTF);
12397 bool generateMan = Config_getBool(GENERATE_MAN);
12398 bool generateSql = Config_getBool(GENERATE_SQLITE3);
12399 QCString htmlOutput;
12400 QCString docbookOutput;
12401 QCString xmlOutput;
12402 QCString latexOutput;
12403 QCString rtfOutput;
12404 QCString manOutput;
12405 QCString sqlOutput;
12406
12407 if (!g_singleComment)
12408 {
12409 if (generateHtml)
12410 {
12411 htmlOutput = createOutputDirectory(outputDirectory,Config_getString(HTML_OUTPUT),"/html");
12412 Config_updateString(HTML_OUTPUT,htmlOutput);
12413
12414 QCString sitemapUrl = Config_getString(SITEMAP_URL);
12415 bool generateSitemap = !sitemapUrl.isEmpty();
12416 if (generateSitemap && !sitemapUrl.endsWith("/"))
12417 {
12418 Config_updateString(SITEMAP_URL,sitemapUrl+"/");
12419 }
12420
12421 // add HTML indexers that are enabled
12422 bool generateHtmlHelp = Config_getBool(GENERATE_HTMLHELP);
12423 bool generateEclipseHelp = Config_getBool(GENERATE_ECLIPSEHELP);
12424 bool generateQhp = Config_getBool(GENERATE_QHP);
12425 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
12426 bool generateDocSet = Config_getBool(GENERATE_DOCSET);
12427 if (generateEclipseHelp) Doxygen::indexList->addIndex<EclipseHelp>();
12428 if (generateHtmlHelp) Doxygen::indexList->addIndex<HtmlHelp>();
12429 if (generateQhp) Doxygen::indexList->addIndex<Qhp>();
12430 if (generateSitemap) Doxygen::indexList->addIndex<Sitemap>();
12431 if (generateTreeView) Doxygen::indexList->addIndex<FTVHelp>(TRUE);
12432 if (generateDocSet) Doxygen::indexList->addIndex<DocSets>();
12433 Doxygen::indexList->addIndex<Crawlmap>();
12434 Doxygen::indexList->initialize();
12435 }
12436
12437 if (generateDocbook)
12438 {
12439 docbookOutput = createOutputDirectory(outputDirectory,Config_getString(DOCBOOK_OUTPUT),"/docbook");
12440 Config_updateString(DOCBOOK_OUTPUT,docbookOutput);
12441 }
12442
12443 if (generateXml)
12444 {
12445 xmlOutput = createOutputDirectory(outputDirectory,Config_getString(XML_OUTPUT),"/xml");
12446 Config_updateString(XML_OUTPUT,xmlOutput);
12447 }
12448
12449 if (generateLatex)
12450 {
12451 latexOutput = createOutputDirectory(outputDirectory,Config_getString(LATEX_OUTPUT), "/latex");
12452 Config_updateString(LATEX_OUTPUT,latexOutput);
12453 }
12454
12455 if (generateRtf)
12456 {
12457 rtfOutput = createOutputDirectory(outputDirectory,Config_getString(RTF_OUTPUT),"/rtf");
12458 Config_updateString(RTF_OUTPUT,rtfOutput);
12459 }
12460
12461 if (generateMan)
12462 {
12463 manOutput = createOutputDirectory(outputDirectory,Config_getString(MAN_OUTPUT),"/man");
12464 Config_updateString(MAN_OUTPUT,manOutput);
12465 }
12466
12467 if (generateSql)
12468 {
12469 sqlOutput = createOutputDirectory(outputDirectory,Config_getString(SQLITE3_OUTPUT),"/sqlite3");
12470 Config_updateString(SQLITE3_OUTPUT,sqlOutput);
12471 }
12472 }
12473
12474 if (Config_getBool(HAVE_DOT))
12475 {
12476 QCString curFontPath = Config_getString(DOT_FONTPATH);
12477 if (curFontPath.isEmpty())
12478 {
12479 Portable::getenv("DOTFONTPATH");
12480 QCString newFontPath = ".";
12481 if (!curFontPath.isEmpty())
12482 {
12483 newFontPath+=Portable::pathListSeparator();
12484 newFontPath+=curFontPath;
12485 }
12486 Portable::setenv("DOTFONTPATH",qPrint(newFontPath));
12487 }
12488 else
12489 {
12490 Portable::setenv("DOTFONTPATH",qPrint(curFontPath));
12491 }
12492 }
12493
12494 /**************************************************************************
12495 * Handle layout file *
12496 **************************************************************************/
12497
12499 QCString layoutFileName = Config_getString(LAYOUT_FILE);
12500 bool defaultLayoutUsed = FALSE;
12501 if (layoutFileName.isEmpty())
12502 {
12503 layoutFileName = Config_updateString(LAYOUT_FILE,"DoxygenLayout.xml");
12504 defaultLayoutUsed = TRUE;
12505 }
12506 AUTO_TRACE_ADD("defaultLayoutUsed={}, layoutFileName={}",defaultLayoutUsed,layoutFileName);
12507
12508 FileInfo fi(layoutFileName.str());
12509 if (fi.exists())
12510 {
12511 msg("Parsing layout file {}...\n",layoutFileName);
12512 LayoutDocManager::instance().parse(layoutFileName);
12513 }
12514 else if (!defaultLayoutUsed)
12515 {
12516 warn_uncond("failed to open layout file '{}' for reading! Using default settings.\n",layoutFileName);
12517 }
12518 printLayout();
12519
12520 /**************************************************************************
12521 * Read and preprocess input *
12522 **************************************************************************/
12523
12524 // prevent search in the output directories
12525 StringVector exclPatterns = Config_getList(EXCLUDE_PATTERNS);
12526 if (generateHtml) exclPatterns.push_back(htmlOutput.str());
12527 if (generateDocbook) exclPatterns.push_back(docbookOutput.str());
12528 if (generateXml) exclPatterns.push_back(xmlOutput.str());
12529 if (generateLatex) exclPatterns.push_back(latexOutput.str());
12530 if (generateRtf) exclPatterns.push_back(rtfOutput.str());
12531 if (generateMan) exclPatterns.push_back(manOutput.str());
12532 Config_updateList(EXCLUDE_PATTERNS,exclPatterns);
12533
12534 if (!g_singleComment)
12535 {
12537
12539 }
12540
12541 // Notice: the order of the function calls below is very important!
12542
12543 if (generateHtml && !Config_getBool(USE_MATHJAX))
12544 {
12546 }
12547 if (generateRtf)
12548 {
12550 }
12551 if (generateDocbook)
12552 {
12554 }
12555
12557
12558 /**************************************************************************
12559 * Handle Tag Files *
12560 **************************************************************************/
12561
12562 std::shared_ptr<Entry> root = std::make_shared<Entry>();
12563
12564 if (!g_singleComment)
12565 {
12566 msg("Reading and parsing tag files\n");
12567 const StringVector &tagFileList = Config_getList(TAGFILES);
12568 for (const auto &s : tagFileList)
12569 {
12570 readTagFile(root,s.c_str());
12571 }
12572 }
12573
12574 /**************************************************************************
12575 * Parse source files *
12576 **************************************************************************/
12577
12578 addSTLSupport(root);
12579
12580 g_s.begin("Parsing files\n");
12581 if (g_singleComment)
12582 {
12583 //printf("Parsing comment %s\n",qPrint(g_commentFileName));
12584 if (g_commentFileName=="-")
12585 {
12586 std::string text = fileToString(g_commentFileName).str();
12587 addTerminalCharIfMissing(text,'\n');
12588 generateHtmlForComment("stdin.md",text);
12589 }
12590 else if (FileInfo(g_commentFileName.str()).isFile())
12591 {
12592 std::string text;
12594 addTerminalCharIfMissing(text,'\n');
12596 }
12597 else
12598 {
12599 }
12601 exit(0);
12602 }
12603 else
12604 {
12605 if (Config_getInt(NUM_PROC_THREADS)==1)
12606 {
12608 }
12609 else
12610 {
12612 }
12613 }
12614 g_s.end();
12615
12616 /**************************************************************************
12617 * Gather information *
12618 **************************************************************************/
12619
12620 g_s.begin("Building macro definition list...\n");
12622 g_s.end();
12623
12624 g_s.begin("Building group list...\n");
12625 buildGroupList(root.get());
12626 organizeSubGroups(root.get());
12627 g_s.end();
12628
12629 g_s.begin("Building directory list...\n");
12631 findDirDocumentation(root.get());
12632 g_s.end();
12633
12634 g_s.begin("Building namespace list...\n");
12635 buildNamespaceList(root.get());
12636 findUsingDirectives(root.get());
12637 g_s.end();
12638
12639 g_s.begin("Building file list...\n");
12640 buildFileList(root.get());
12641 g_s.end();
12642
12643 g_s.begin("Building class list...\n");
12644 buildClassList(root.get());
12645 g_s.end();
12646
12647 g_s.begin("Building concept list...\n");
12648 buildConceptList(root.get());
12649 g_s.end();
12650
12651 // build list of using declarations here (global list)
12652 buildListOfUsingDecls(root.get());
12653 g_s.end();
12654
12655 g_s.begin("Computing nesting relations for classes...\n");
12657 g_s.end();
12658 // 1.8.2-20121111: no longer add nested classes to the group as well
12659 //distributeClassGroupRelations();
12660
12661 // calling buildClassList may result in cached relations that
12662 // become invalid after resolveClassNestingRelations(), that's why
12663 // we need to clear the cache here
12665 // we don't need the list of using declaration anymore
12666 g_usingDeclarations.clear();
12667
12668 g_s.begin("Associating documentation with classes...\n");
12669 buildClassDocList(root.get());
12670 g_s.end();
12671
12672 g_s.begin("Associating documentation with concepts...\n");
12673 buildConceptDocList(root.get());
12675 g_s.end();
12676
12677 g_s.begin("Associating documentation with modules...\n");
12678 findModuleDocumentation(root.get());
12679 g_s.end();
12680
12681 g_s.begin("Building example list...\n");
12682 buildExampleList(root.get());
12683 g_s.end();
12684
12685 g_s.begin("Searching for enumerations...\n");
12686 findEnums(root.get());
12687 g_s.end();
12688
12689 // Since buildVarList calls isVarWithConstructor
12690 // and this calls getResolvedClass we need to process
12691 // typedefs first so the relations between classes via typedefs
12692 // are properly resolved. See bug 536385 for an example.
12693 g_s.begin("Searching for documented typedefs...\n");
12694 buildTypedefList(root.get());
12695 g_s.end();
12696
12697 if (Config_getBool(OPTIMIZE_OUTPUT_SLICE))
12698 {
12699 g_s.begin("Searching for documented sequences...\n");
12700 buildSequenceList(root.get());
12701 g_s.end();
12702
12703 g_s.begin("Searching for documented dictionaries...\n");
12704 buildDictionaryList(root.get());
12705 g_s.end();
12706 }
12707
12708 g_s.begin("Searching for members imported via using declarations...\n");
12709 // this should be after buildTypedefList in order to properly import
12710 // used typedefs
12711 findUsingDeclarations(root.get(),TRUE); // do for python packages first
12712 findUsingDeclarations(root.get(),FALSE); // then the rest
12713 g_s.end();
12714
12715 g_s.begin("Searching for included using directives...\n");
12717 g_s.end();
12718
12719 g_s.begin("Searching for documented variables...\n");
12720 buildVarList(root.get());
12721 g_s.end();
12722
12723 g_s.begin("Building interface member list...\n");
12724 buildInterfaceAndServiceList(root.get()); // UNO IDL
12725
12726 g_s.begin("Building member list...\n"); // using class info only !
12727 buildFunctionList(root.get());
12728 g_s.end();
12729
12730 g_s.begin("Searching for friends...\n");
12731 findFriends();
12732 g_s.end();
12733
12734 g_s.begin("Searching for documented defines...\n");
12735 findDefineDocumentation(root.get());
12736 g_s.end();
12737
12738 g_s.begin("Computing class inheritance relations...\n");
12739 findClassEntries(root.get());
12741 g_s.end();
12742
12743 g_s.begin("Computing class usage relations...\n");
12745 g_s.end();
12746
12747 g_s.begin("Flushing cached template relations that have become invalid...\n");
12749 g_s.end();
12750
12751 g_s.begin("Warn for undocumented namespaces...\n");
12753 g_s.end();
12754
12755 g_s.begin("Computing class relations...\n");
12758 if (Config_getBool(OPTIMIZE_OUTPUT_VHDL))
12759 {
12761 }
12763 g_classEntries.clear();
12764 g_s.end();
12765
12766 g_s.begin("Add enum values to enums...\n");
12767 addEnumValuesToEnums(root.get());
12768 findEnumDocumentation(root.get());
12769 g_s.end();
12770
12771 g_s.begin("Searching for member function documentation...\n");
12772 findObjCMethodDefinitions(root.get());
12773 findMemberDocumentation(root.get()); // may introduce new members !
12774 findUsingDeclImports(root.get()); // may introduce new members !
12775 g_usingClassMap.clear();
12779 g_s.end();
12780
12781 // moved to after finding and copying documentation,
12782 // as this introduces new members see bug 722654
12783 g_s.begin("Creating members for template instances...\n");
12785 g_s.end();
12786
12787 g_s.begin("Building page list...\n");
12788 buildPageList(root.get());
12789 g_s.end();
12790
12791 g_s.begin("Building requirements list...\n");
12792 buildRequirementsList(root.get());
12793 g_s.end();
12794
12795 g_s.begin("Search for main page...\n");
12796 findMainPage(root.get());
12797 findMainPageTagFiles(root.get());
12798 g_s.end();
12799
12800 g_s.begin("Computing page relations...\n");
12801 computePageRelations(root.get());
12803 g_s.end();
12804
12805 g_s.begin("Determining the scope of groups...\n");
12806 findGroupScope(root.get());
12807 g_s.end();
12808
12809 g_s.begin("Computing module relations...\n");
12810 auto &mm = ModuleManager::instance();
12811 mm.resolvePartitions();
12812 mm.resolveImports();
12813 mm.collectExportedSymbols();
12814 g_s.end();
12815
12816 auto memberNameComp = [](const MemberNameLinkedMap::Ptr &n1,const MemberNameLinkedMap::Ptr &n2)
12817 {
12818 return qstricmp_sort(n1->memberName().data()+getPrefixIndex(n1->memberName()),
12819 n2->memberName().data()+getPrefixIndex(n2->memberName())
12820 )<0;
12821 };
12822
12823 auto classComp = [](const ClassLinkedMap::Ptr &c1,const ClassLinkedMap::Ptr &c2)
12824 {
12825 if (Config_getBool(SORT_BY_SCOPE_NAME))
12826 {
12827 return qstricmp_sort(c1->name(), c2->name())<0;
12828 }
12829 else
12830 {
12831 int i = qstricmp_sort(c1->className(), c2->className());
12832 return i==0 ? qstricmp_sort(c1->name(), c2->name())<0 : i<0;
12833 }
12834 };
12835
12836 auto namespaceComp = [](const NamespaceLinkedMap::Ptr &n1,const NamespaceLinkedMap::Ptr &n2)
12837 {
12838 return qstricmp_sort(n1->name(),n2->name())<0;
12839 };
12840
12841 auto conceptComp = [](const ConceptLinkedMap::Ptr &c1,const ConceptLinkedMap::Ptr &c2)
12842 {
12843 return qstricmp_sort(c1->name(),c2->name())<0;
12844 };
12845
12846 g_s.begin("Sorting lists...\n");
12847 std::stable_sort(Doxygen::memberNameLinkedMap->begin(),
12849 memberNameComp);
12850 std::stable_sort(Doxygen::functionNameLinkedMap->begin(),
12852 memberNameComp);
12853 std::stable_sort(Doxygen::hiddenClassLinkedMap->begin(),
12855 classComp);
12856 std::stable_sort(Doxygen::classLinkedMap->begin(),
12858 classComp);
12859 std::stable_sort(Doxygen::conceptLinkedMap->begin(),
12861 conceptComp);
12862 std::stable_sort(Doxygen::namespaceLinkedMap->begin(),
12864 namespaceComp);
12865 g_s.end();
12866
12867 g_s.begin("Determining which enums are documented\n");
12869 g_s.end();
12870
12871 g_s.begin("Computing member relations...\n");
12875 g_s.end();
12876
12877 g_s.begin("Building full member lists recursively...\n");
12879 g_s.end();
12880
12881 g_s.begin("Adding members to member groups.\n");
12883 g_s.end();
12884
12885 if (Config_getBool(DISTRIBUTE_GROUP_DOC))
12886 {
12887 g_s.begin("Distributing member group documentation.\n");
12889 g_s.end();
12890 }
12891
12892 g_s.begin("Computing member references...\n");
12894 g_s.end();
12895
12896 if (Config_getBool(INHERIT_DOCS))
12897 {
12898 g_s.begin("Inheriting documentation...\n");
12900 g_s.end();
12901 }
12902
12903
12904 // compute the shortest possible names of all files
12905 // without losing the uniqueness of the file names.
12906 g_s.begin("Generating disk names...\n");
12908 g_s.end();
12909
12910 g_s.begin("Adding source references...\n");
12912 g_s.end();
12913
12914 g_s.begin("Adding xrefitems...\n");
12917 g_s.end();
12918
12919 g_s.begin("Adding requirements...\n");
12922 g_s.end();
12923
12924 g_s.begin("Sorting member lists...\n");
12926 g_s.end();
12927
12928 g_s.begin("Setting anonymous enum type...\n");
12930 g_s.end();
12931
12932 g_s.begin("Computing dependencies between directories...\n");
12934 g_s.end();
12935
12936 g_s.begin("Generating citations page...\n");
12938 g_s.end();
12939
12940 g_s.begin("Counting data structures...\n");
12942 g_s.end();
12943
12944 g_s.begin("Resolving user defined references...\n");
12946 g_s.end();
12947
12948 g_s.begin("Finding anchors and sections in the documentation...\n");
12950 g_s.end();
12951
12952 g_s.begin("Transferring function references...\n");
12954 g_s.end();
12955
12956 g_s.begin("Combining using relations...\n");
12958 g_s.end();
12959
12961 g_s.begin("Adding members to index pages...\n");
12963 addToIndices();
12964 g_s.end();
12965
12966 g_s.begin("Correcting members for VHDL...\n");
12968 g_s.end();
12969
12970 g_s.begin("Computing tooltip texts...\n");
12972 g_s.end();
12973
12974 if (Config_getBool(SORT_GROUP_NAMES))
12975 {
12976 std::stable_sort(Doxygen::groupLinkedMap->begin(),
12978 [](const auto &g1,const auto &g2)
12979 { return g1->groupTitle() < g2->groupTitle(); });
12980
12981 for (const auto &gd : *Doxygen::groupLinkedMap)
12982 {
12983 gd->sortSubGroups();
12984 }
12985 }
12986
12987 printNavTree(root.get(),0);
12989}
void generatePage()
Generate the citations page.
Definition cite.cpp:331
A class that generates docset files.
Definition docsets.h:36
Generator for Eclipse help files.
Definition eclipsehelp.h:44
A class that generates a dynamic tree view side panel.
Definition ftvhelp.h:41
bool isFile() const
Definition fileinfo.cpp:63
void initFromRepository(const QCString &dir)
Definition formula.cpp:59
void checkRepositories()
Definition formula.cpp:172
A class that generated the HTML Help specific files.
Definition htmlhelp.h:36
void countDataStructures()
Definition index.cpp:264
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition layout.cpp:1437
void parse(const QCString &fileName, const char *data=nullptr)
Parses a user provided layout.
Definition layout.cpp:1470
Definition qhp.h:27
static void computeVhdlComponentRelations()
#define Config_updateList(name,...)
Definition config.h:43
DirIterator begin(DirIterator it) noexcept
Definition dir.cpp:170
void buildDirectories()
Definition dirdef.cpp:1119
void computeDirDependencies()
Definition dirdef.cpp:1193
static void findInheritedTemplateInstances()
Definition doxygen.cpp:5153
void printNavTree(Entry *root, int indent)
Definition doxygen.cpp:9861
static void buildGroupList(const Entry *root)
Definition doxygen.cpp:432
static void flushCachedTemplateRelations()
Definition doxygen.cpp:9315
static void computeTemplateClassRelations()
Definition doxygen.cpp:5247
void printSectionsTree()
Definition doxygen.cpp:9884
static void generateXRefPages()
Definition doxygen.cpp:5426
static void warnUndocumentedNamespaces()
Definition doxygen.cpp:5202
static void resolveClassNestingRelations()
Definition doxygen.cpp:1381
static void vhdlCorrectMemberProperties()
Definition doxygen.cpp:8245
static void stopDoxygen(int)
static void computeMemberReferences()
Definition doxygen.cpp:5316
static void transferRelatedFunctionDocumentation()
Definition doxygen.cpp:4274
static void addMembersToMemberGroup()
Definition doxygen.cpp:9180
static void distributeConceptGroups()
Definition doxygen.cpp:1348
static void transferFunctionDocumentation()
Definition doxygen.cpp:4193
static void setAnonymousEnumType()
Definition doxygen.cpp:8920
static void sortMemberLists()
Definition doxygen.cpp:8825
static void createTemplateInstanceMembers()
Definition doxygen.cpp:8373
void transferStaticInstanceInitializers()
Definition doxygen.cpp:4323
static void findObjCMethodDefinitions(const Entry *root)
Definition doxygen.cpp:7386
static void distributeMemberGroupDocumentation()
Definition doxygen.cpp:9218
static void resolveUserReferences()
Definition doxygen.cpp:9747
static void readTagFile(const std::shared_ptr< Entry > &root, const QCString &tagLine)
static void findIncludedUsingDirectives()
Definition doxygen.cpp:2271
static void organizeSubGroups(const Entry *root)
Definition doxygen.cpp:491
void searchInputFiles()
static void findFriends()
Definition doxygen.cpp:4096
static void addListReferences()
Definition doxygen.cpp:5417
static void exitDoxygen() noexcept
static void addMembersToIndex()
Definition doxygen.cpp:8035
static void addSourceReferences()
Definition doxygen.cpp:8670
static void inheritDocumentation()
Definition doxygen.cpp:9120
static void flushUnresolvedRelations()
Definition doxygen.cpp:9357
static QCString g_commentFileName
Definition doxygen.cpp:193
static void findDocumentedEnumValues()
Definition doxygen.cpp:8027
static void generateDiskNames()
static void addToIndices()
Definition doxygen.cpp:8077
static void computeClassRelations()
Definition doxygen.cpp:5222
static void checkPageRelations()
Definition doxygen.cpp:9727
static QCString createOutputDirectory(const QCString &baseDirName, const QCString &formatDirName, const char *defaultDirName)
static void determineScopeForAnonymousMembers()
Definition doxygen.cpp:8748
static void addRequirementReferences()
Definition doxygen.cpp:5409
static void computeVerifiedDotPath()
static bool g_singleComment
Definition doxygen.cpp:194
static void findSectionsInDocumentation()
Definition doxygen.cpp:9256
static void mergeCategories()
Definition doxygen.cpp:8392
static void findUsedTemplateInstances()
Definition doxygen.cpp:5186
static void computeTooltipTexts()
Definition doxygen.cpp:8874
static void parseFilesSingleThreading(const std::shared_ptr< Entry > &root)
parse the list of input files
static void buildCompleteMemberLists()
Definition doxygen.cpp:8414
static void combineUsingRelations()
Definition doxygen.cpp:9155
static void checkMarkdownMainfile()
static void parseFilesMultiThreading(const std::shared_ptr< Entry > &root)
parse the list of input files
static void transferFunctionReferences()
Definition doxygen.cpp:4226
static void buildDefineList()
Definition doxygen.cpp:8777
static void computeMemberRelations()
Definition doxygen.cpp:8357
void printLayout()
Definition layout.cpp:1822
void correctPath(const StringVector &list)
Correct a possible wrong PATH variable.
Definition portable.cpp:516
QCString pathListSeparator()
Definition portable.cpp:383
uint32_t pid()
Definition portable.cpp:248
int qstricmp_sort(const char *str1, const char *str2)
Definition qcstring.h:86
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.
QCString fileToString(const QCString &name, bool filter, bool isSourceCode)
Definition util.cpp:1494
int getPrefixIndex(const QCString &name)
Definition util.cpp:3252

References Dir::absPath(), addEnumValuesToEnums(), addListReferences(), addMembersToIndex(), addMembersToMemberGroup(), addRequirementReferences(), addSourceReferences(), addSTLSupport(), addTerminalCharIfMissing(), addToIndices(), SymbolResolver::All, AUTO_TRACE, AUTO_TRACE_ADD, 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(), determineScopeForAnonymousMembers(), distributeConceptGroups(), distributeMemberGroupDocumentation(), end(), QCString::endsWith(), Dir::exists(), FileInfo::exists(), exitDoxygen(), FALSE, fileToString(), Doxygen::filterDBFileName, findClassEntries(), findDefineDocumentation(), findDirDocumentation(), findDocumentedEnumValues(), findEnumDocumentation(), findEnums(), findFriends(), findGroupScope(), findIncludedUsingDirectives(), findInheritedTemplateInstances(), findMainPage(), findMainPageTagFiles(), findMemberDocumentation(), findModuleDocumentation(), findObjCMethodDefinitions(), findSectionsInDocumentation(), 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(), initSearchIndexer(), CitationManager::instance(), FormulaManager::instance(), Index::instance(), LayoutDocManager::instance(), ModuleManager::instance(), RequirementManager::instance(), QCString::isEmpty(), FileInfo::isFile(), Doxygen::memberNameLinkedMap, mergeCategories(), Dir::mkdir(), msg, Doxygen::namespaceLinkedMap, organizeSubGroups(), LayoutDocManager::parse(), parseFilesMultiThreading(), parseFilesSingleThreading(), Portable::pathListSeparator(), Portable::pid(), printLayout(), printNavTree(), printSectionsTree(), qPrint(), qstricmp_sort(), readInputFile(), readTagFile(), resolveClassNestingRelations(), resolveUserReferences(), searchInputFiles(), setAnonymousEnumType(), Portable::setenv(), Dir::setPath(), sortMemberLists(), stopDoxygen(), QCString::str(), term, transferFunctionDocumentation(), transferFunctionReferences(), transferRelatedFunctionDocumentation(), transferStaticInstanceInitializers(), TRUE, vhdlCorrectMemberProperties(), warn_uncond, and warnUndocumentedNamespaces().

Referenced by main().

◆ printNavTree()

void printNavTree ( Entry * root,
int indent )

Definition at line 9861 of file doxygen.cpp.

9862{
9864 {
9865 QCString indentStr;
9866 indentStr.fill(' ',indent);
9867 Debug::print(Debug::Entries,0,"{}{} at {}:{} (sec={}, spec={})\n",
9868 indentStr.isEmpty()?"":indentStr,
9869 root->name.isEmpty()?"<empty>":root->name,
9870 root->fileName,root->startLine,
9871 root->section.to_string(),
9872 root->spec.to_string());
9873 for (const auto &e : root->children())
9874 {
9875 printNavTree(e.get(),indent+2);
9876 }
9877 }
9878}
@ Entries
Definition debug.h:47
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
Definition debug.h:77
std::string to_string() const
Definition types.h:868
QCString fill(char c, int len=-1)
Fills a string with a predefined character.
Definition qcstring.h:197
std::string to_string() const
Definition types.h:738

References Entry::children(), Debug::Entries, Entry::fileName, QCString::fill(), QCString::isEmpty(), 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 9884 of file doxygen.cpp.

9885{
9887 {
9888 for (const auto &si : SectionManager::instance())
9889 {
9890 Debug::print(Debug::Sections,0,"Section = {}, file = {}, title = {}, type = {}, ref = {}\n",
9891 si->label(),si->fileName(),si->title(),si->type().level(),si->ref());
9892 }
9893 }
9894}
@ Sections
Definition debug.h:48

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

Referenced by parseInput().

◆ readConfiguration()

void readConfiguration ( int argc,
char ** argv )

Definition at line 11373 of file doxygen.cpp.

11374{
11375 QCString versionString = getFullVersion();
11376
11377 // helper that calls \a func to write to file \a fileName via a TextStream
11378 auto writeFile = [](const char *fileName,std::function<void(TextStream&)> func) -> bool
11379 {
11380 std::ofstream f;
11381 if (openOutputFile(fileName,f))
11382 {
11383 TextStream t(&f);
11384 func(t);
11385 return true;
11386 }
11387 return false;
11388 };
11389
11390
11391 /**************************************************************************
11392 * Handle arguments *
11393 **************************************************************************/
11394
11395 int optInd=1;
11396 QCString configName;
11397 QCString traceName;
11398 bool genConfig=false;
11399 bool shortList=false;
11400 bool traceTiming=false;
11402 bool updateConfig=false;
11403 bool quiet = false;
11404 while (optInd<argc && argv[optInd][0]=='-' &&
11405 (isalpha(argv[optInd][1]) || argv[optInd][1]=='?' ||
11406 argv[optInd][1]=='-')
11407 )
11408 {
11409 switch(argv[optInd][1])
11410 {
11411 case 'g':
11412 {
11413 genConfig=TRUE;
11414 }
11415 break;
11416 case 'l':
11417 {
11418 QCString layoutName;
11419 if (optInd+1>=argc)
11420 {
11421 layoutName="DoxygenLayout.xml";
11422 }
11423 else
11424 {
11425 layoutName=argv[optInd+1];
11426 }
11427 writeDefaultLayoutFile(layoutName);
11429 exit(0);
11430 }
11431 break;
11432 case 'c':
11433 if (optInd+1>=argc) // no file name given
11434 {
11435 msg("option \"-c\" is missing the file name to read\n");
11436 devUsage();
11438 exit(1);
11439 }
11440 else
11441 {
11442 g_commentFileName=argv[optInd+1];
11443 optInd++;
11444 }
11445 g_singleComment=true;
11446 quiet=true;
11447 break;
11448 case 'd':
11449 {
11450 QCString debugLabel=getArg(argc,argv,optInd);
11451 if (debugLabel.isEmpty())
11452 {
11453 devUsage();
11455 exit(0);
11456 }
11457 int retVal = Debug::setFlagStr(debugLabel);
11458 if (!retVal)
11459 {
11460 msg("option \"-d\" has unknown debug specifier: \"{}\".\n",debugLabel);
11461 devUsage();
11463 exit(1);
11464 }
11465 }
11466 break;
11467 case 't':
11468 {
11469#if ENABLE_TRACING
11470 if (!strcmp(argv[optInd]+1,"t_time"))
11471 {
11472 traceTiming = true;
11473 }
11474 else if (!strcmp(argv[optInd]+1,"t"))
11475 {
11476 traceTiming = false;
11477 }
11478 else
11479 {
11480 err("option should be \"-t\" or \"-t_time\", found: \"{}\".\n",argv[optInd]);
11482 exit(1);
11483 }
11484 if (optInd+1>=argc || argv[optInd+1][0] == '-') // no file name given
11485 {
11486 traceName="stdout";
11487 }
11488 else
11489 {
11490 traceName=argv[optInd+1];
11491 optInd++;
11492 }
11493#else
11494 err("support for option \"-t\" has not been compiled in (use a debug build or a release build with tracing enabled).\n");
11496 exit(1);
11497#endif
11498 }
11499 break;
11500 case 'x':
11501 if (!strcmp(argv[optInd]+1,"x_noenv")) diffList=Config::CompareMode::CompressedNoEnv;
11502 else if (!strcmp(argv[optInd]+1,"x")) diffList=Config::CompareMode::Compressed;
11503 else
11504 {
11505 err("option should be \"-x\" or \"-x_noenv\", found: \"{}\".\n",argv[optInd]);
11507 exit(1);
11508 }
11509 break;
11510 case 's':
11511 shortList=TRUE;
11512 break;
11513 case 'u':
11514 updateConfig=TRUE;
11515 break;
11516 case 'e':
11517 {
11518 QCString formatName=getArg(argc,argv,optInd);
11519 if (formatName.isEmpty())
11520 {
11521 err("option \"-e\" is missing format specifier rtf.\n");
11523 exit(1);
11524 }
11525 if (qstricmp(formatName.data(),"rtf")==0)
11526 {
11527 if (optInd+1>=argc)
11528 {
11529 err("option \"-e rtf\" is missing an extensions file name\n");
11531 exit(1);
11532 }
11533 writeFile(argv[optInd+1],RTFGenerator::writeExtensionsFile);
11535 exit(0);
11536 }
11537 err("option \"-e\" has invalid format specifier.\n");
11539 exit(1);
11540 }
11541 break;
11542 case 'f':
11543 {
11544 QCString listName=getArg(argc,argv,optInd);
11545 if (listName.isEmpty())
11546 {
11547 err("option \"-f\" is missing list specifier.\n");
11549 exit(1);
11550 }
11551 if (qstricmp(listName.data(),"emoji")==0)
11552 {
11553 if (optInd+1>=argc)
11554 {
11555 err("option \"-f emoji\" is missing an output file name\n");
11557 exit(1);
11558 }
11559 writeFile(argv[optInd+1],[](TextStream &t) { EmojiEntityMapper::instance().writeEmojiFile(t); });
11561 exit(0);
11562 }
11563 err("option \"-f\" has invalid list specifier.\n");
11565 exit(1);
11566 }
11567 break;
11568 case 'w':
11569 {
11570 QCString formatName=getArg(argc,argv,optInd);
11571 if (formatName.isEmpty())
11572 {
11573 err("option \"-w\" is missing format specifier rtf, html or latex\n");
11575 exit(1);
11576 }
11577 if (qstricmp(formatName.data(),"rtf")==0)
11578 {
11579 if (optInd+1>=argc)
11580 {
11581 err("option \"-w rtf\" is missing a style sheet file name\n");
11583 exit(1);
11584 }
11585 if (!writeFile(argv[optInd+1],RTFGenerator::writeStyleSheetFile))
11586 {
11587 err("error opening RTF style sheet file {}!\n",argv[optInd+1]);
11589 exit(1);
11590 }
11592 exit(0);
11593 }
11594 else if (qstricmp(formatName.data(),"html")==0)
11595 {
11596 Config::init();
11597 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11598 // explicit config file mentioned or default found on disk
11599 {
11600 QCString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? QCString("Doxyfile") : QCString("doxyfile"));
11601 if (!Config::parse(df)) // parse the config file
11602 {
11603 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
11605 exit(1);
11606 }
11607 }
11608 if (optInd+3>=argc)
11609 {
11610 err("option \"-w html\" does not have enough arguments\n");
11612 exit(1);
11613 }
11617 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11618 writeFile(argv[optInd+1],[&](TextStream &t) { HtmlGenerator::writeHeaderFile(t,argv[optInd+3]); });
11619 writeFile(argv[optInd+2],HtmlGenerator::writeFooterFile);
11620 writeFile(argv[optInd+3],HtmlGenerator::writeStyleSheetFile);
11622 exit(0);
11623 }
11624 else if (qstricmp(formatName.data(),"latex")==0)
11625 {
11626 Config::init();
11627 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11628 {
11629 QCString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? QCString("Doxyfile") : QCString("doxyfile"));
11630 if (!Config::parse(df))
11631 {
11632 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
11634 exit(1);
11635 }
11636 }
11637 if (optInd+3>=argc)
11638 {
11639 err("option \"-w latex\" does not have enough arguments\n");
11641 exit(1);
11642 }
11646 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11647 writeFile(argv[optInd+1],LatexGenerator::writeHeaderFile);
11648 writeFile(argv[optInd+2],LatexGenerator::writeFooterFile);
11649 writeFile(argv[optInd+3],LatexGenerator::writeStyleSheetFile);
11651 exit(0);
11652 }
11653 else
11654 {
11655 err("Illegal format specifier \"{}\": should be one of rtf, html or latex\n",formatName);
11657 exit(1);
11658 }
11659 }
11660 break;
11661 case 'm':
11663 break;
11664 case 'v':
11665 version(false);
11667 exit(0);
11668 break;
11669 case 'V':
11670 version(true);
11672 exit(0);
11673 break;
11674 case '-':
11675 if (qstrcmp(&argv[optInd][2],"help")==0)
11676 {
11677 usage(argv[0],versionString);
11678 exit(0);
11679 }
11680 else if (qstrcmp(&argv[optInd][2],"version")==0)
11681 {
11682 version(false);
11684 exit(0);
11685 }
11686 else if ((qstrcmp(&argv[optInd][2],"Version")==0) ||
11687 (qstrcmp(&argv[optInd][2],"VERSION")==0))
11688 {
11689 version(true);
11691 exit(0);
11692 }
11693 else
11694 {
11695 err("Unknown option \"-{}\"\n",&argv[optInd][1]);
11696 usage(argv[0],versionString);
11697 exit(1);
11698 }
11699 break;
11700 case 'b':
11701 setvbuf(stdout,nullptr,_IONBF,0);
11702 break;
11703 case 'q':
11704 quiet = true;
11705 break;
11706 case 'h':
11707 case '?':
11708 usage(argv[0],versionString);
11709 exit(0);
11710 break;
11711 default:
11712 err("Unknown option \"-{:c}\"\n",argv[optInd][1]);
11713 usage(argv[0],versionString);
11714 exit(1);
11715 }
11716 optInd++;
11717 }
11718
11719 /**************************************************************************
11720 * Parse or generate the config file *
11721 **************************************************************************/
11722
11723 initTracing(traceName.data(),traceTiming);
11724 TRACE("Doxygen version used: {}",getFullVersion());
11725 Config::init();
11726
11727 FileInfo configFileInfo1("Doxyfile"),configFileInfo2("doxyfile");
11728 if (optInd>=argc)
11729 {
11730 if (configFileInfo1.exists())
11731 {
11732 configName="Doxyfile";
11733 }
11734 else if (configFileInfo2.exists())
11735 {
11736 configName="doxyfile";
11737 }
11738 else if (genConfig)
11739 {
11740 configName="Doxyfile";
11741 }
11742 else
11743 {
11744 err("Doxyfile not found and no input file specified!\n");
11745 usage(argv[0],versionString);
11746 exit(1);
11747 }
11748 }
11749 else
11750 {
11751 FileInfo fi(argv[optInd]);
11752 if (fi.exists() || qstrcmp(argv[optInd],"-")==0 || genConfig)
11753 {
11754 configName=argv[optInd];
11755 }
11756 else
11757 {
11758 err("configuration file {} not found!\n",argv[optInd]);
11759 usage(argv[0],versionString);
11760 exit(1);
11761 }
11762 }
11763
11764 if (genConfig)
11765 {
11766 generateConfigFile(configName,shortList);
11768 exit(0);
11769 }
11770
11771 if (!Config::parse(configName,updateConfig,diffList))
11772 {
11773 err("could not open or read configuration file {}!\n",configName);
11775 exit(1);
11776 }
11777
11778 if (diffList!=Config::CompareMode::Full)
11779 {
11781 compareDoxyfile(diffList);
11783 exit(0);
11784 }
11785
11786 if (updateConfig)
11787 {
11789 generateConfigFile(configName,shortList,TRUE);
11791 exit(0);
11792 }
11793
11794 /* Perlmod wants to know the path to the config file.*/
11795 FileInfo configFileInfo(configName.str());
11796 setPerlModDoxyfile(configFileInfo.absFilePath());
11797
11798 /* handle -q option */
11799 if (quiet) Config_updateBool(QUIET,TRUE);
11800}
static bool setFlagStr(const QCString &label)
Definition debug.cpp:104
static EmojiEntityMapper & instance()
Returns the one and only instance of the Emoji entity mapper.
Definition emoji.cpp:1978
void writeEmojiFile(TextStream &t)
Writes the list of supported emojis to the given file.
Definition emoji.cpp:1999
bool exists() const
Definition fileinfo.cpp:30
static void writeFooterFile(TextStream &t)
Definition htmlgen.cpp:1595
static void writeStyleSheetFile(TextStream &t)
Definition htmlgen.cpp:1583
static void writeHeaderFile(TextStream &t, const QCString &cssname)
Definition htmlgen.cpp:1589
static void writeFooterFile(TextStream &t)
Definition latexgen.cpp:696
static void writeStyleSheetFile(TextStream &t)
Definition latexgen.cpp:702
static void writeHeaderFile(TextStream &t)
Definition latexgen.cpp:690
static void writeStyleSheetFile(TextStream &t)
Definition rtfgen.cpp:394
static void writeExtensionsFile(TextStream &t)
Definition rtfgen.cpp:409
#define Config_updateBool(name, value)
Definition config.h:40
static void generateConfigFile(const QCString &configFile, bool shortList, bool updateOnly=FALSE)
static void compareDoxyfile(Config::CompareMode diffList)
static void usage(const QCString &name, const QCString &versionString)
static void devUsage()
static void version(const bool extended)
static const char * getArg(int argc, char **argv, int &optInd)
void writeDefaultLayoutFile(const QCString &fileName)
Definition layout.cpp:1734
CompareMode
Definition config.h:54
bool parse(const QCString &fileName, bool update=FALSE, CompareMode compareMode=CompareMode::Full)
void init()
void setPerlModDoxyfile(const QCString &qs)
int qstricmp(const char *s1, const char *s2)
Definition qcstring.cpp:530
int qstrcmp(const char *str1, const char *str2)
Definition qcstring.h:69
void initTracing(const QCString &logFile, bool timing)
Definition trace.cpp:22

References FileInfo::absFilePath(), Config::checkAndCorrect(), cleanUpDoxygen(), compareDoxyfile(), Config::Compressed, Config::CompressedNoEnv, Config_getBool, Config_getEnum, Config_updateBool, QCString::data(), devUsage(), err, FileInfo::exists(), Config::Full, g_commentFileName, g_dumpSymbolMap, g_singleComment, generateConfigFile(), getArg(), Config::init(), initTracing(), EmojiEntityMapper::instance(), QCString::isEmpty(), msg, openOutputFile(), Config::parse(), Config::postProcess(), qstrcmp(), qstricmp(), Debug::setFlagStr(), setPerlModDoxyfile(), setTranslator(), QCString::str(), TRACE, TRUE, 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 10920 of file doxygen.cpp.

10932{
10933 std::string dirName = fi->absFilePath();
10934 if (paths && !dirName.empty())
10935 {
10936 paths->insert(dirName);
10937 }
10938 //printf("%s isSymLink()=%d\n",qPrint(dirName),fi->isSymLink());
10939 if (fi->isSymLink())
10940 {
10941 dirName = resolveSymlink(dirName);
10942 if (dirName.empty())
10943 {
10944 //printf("RECURSIVE SYMLINK: %s\n",qPrint(dirName));
10945 return; // recursive symlink
10946 }
10947 }
10948
10949 if (g_pathsVisited.find(dirName)!=g_pathsVisited.end())
10950 {
10951 //printf("PATH ALREADY VISITED: %s\n",qPrint(dirName));
10952 return; // already visited path
10953 }
10954 g_pathsVisited.insert(dirName);
10955
10956 Dir dir(dirName);
10957 msg("Searching for files in directory {}\n", fi->absFilePath());
10958 //printf("killSet=%p count=%d\n",killSet,killSet ? (int)killSet->count() : -1);
10959
10960 StringVector dirResultList;
10961
10962 for (const auto &dirEntry : dir.iterator())
10963 {
10964 FileInfo cfi(dirEntry.path());
10965 auto checkPatterns = [&]() -> bool
10966 {
10967 return (patList==nullptr || patternMatch(cfi,*patList)) &&
10968 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
10969 (killSet==nullptr || killSet->find(cfi.absFilePath())==killSet->end());
10970 };
10971
10972 if (exclSet==nullptr || exclSet->find(cfi.absFilePath())==exclSet->end())
10973 { // file should not be excluded
10974 //printf("killSet->find(%s)\n",qPrint(cfi->absFilePath()));
10975 if (Config_getBool(EXCLUDE_SYMLINKS) && cfi.isSymLink())
10976 {
10977 }
10978 else if (!cfi.exists() || !cfi.isReadable())
10979 {
10980 if (errorIfNotExist && checkPatterns())
10981 {
10982 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",cfi.absFilePath());
10983 }
10984 }
10985 else if (cfi.isFile() && checkPatterns())
10986 {
10987 std::string name=cfi.fileName();
10988 std::string path=cfi.dirPath()+"/";
10989 std::string fullName=path+name;
10990 if (fnMap)
10991 {
10992 auto fd = createFileDef(path,name);
10993 FileName *fn=nullptr;
10994 if (!name.empty())
10995 {
10996 fn = fnMap->add(name);
10997 fn->push_back(std::move(fd));
10998 }
10999 }
11000 dirResultList.push_back(fullName);
11001 if (resultSet) resultSet->insert(fullName);
11002 if (killSet) killSet->insert(fullName);
11003 }
11004 else if (recursive &&
11005 cfi.isDir() &&
11006 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
11007 cfi.fileName().at(0)!='.') // skip "." ".." and ".dir"
11008 {
11009 FileInfo acfi(cfi.absFilePath());
11010 readDir(&acfi,fnMap,exclSet,
11011 patList,exclPatList,&dirResultList,resultSet,errorIfNotExist,
11012 recursive,killSet,paths);
11013 }
11014 }
11015 }
11016 if (resultList && !dirResultList.empty())
11017 {
11018 // sort the resulting list to make the order platform independent.
11019 std::stable_sort(dirResultList.begin(),
11020 dirResultList.end(),
11021 [](const auto &f1,const auto &f2) { return qstricmp_sort(f1.c_str(),f2.c_str())<0; });
11022
11023 // append the sorted results to resultList
11024 resultList->insert(resultList->end(), dirResultList.begin(), dirResultList.end());
11025 }
11026}
bool isSymLink() const
Definition fileinfo.cpp:77
Class representing all files with a certain base name.
Definition filename.h:30
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 QCString &p, const QCString &n, const QCString &ref, const QCString &dn)
Definition filedef.cpp:268
bool patternMatch(const FileInfo &fi, const StringVector &patList)
Definition util.cpp:5728

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(), msg, patternMatch(), readDir(), resolveSymlink(), and warn_uncond.

Referenced by readDir(), and readFileOrDirectory().

◆ readFileOrDirectory()

void readFileOrDirectory ( const QCString & 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 11033 of file doxygen.cpp.

11045{
11046 //printf("killSet count=%d\n",killSet ? (int)killSet->size() : -1);
11047 // strip trailing slashes
11048 if (s.isEmpty()) return;
11049
11050 g_pathsVisited.clear();
11051
11052 FileInfo fi(s.str());
11053 //printf("readFileOrDirectory(%s)\n",s);
11054 {
11055 if (exclSet==nullptr || exclSet->find(fi.absFilePath())==exclSet->end())
11056 {
11057 if (Config_getBool(EXCLUDE_SYMLINKS) && fi.isSymLink())
11058 {
11059 }
11060 else if (!fi.exists() || !fi.isReadable())
11061 {
11062 if (errorIfNotExist)
11063 {
11064 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",s);
11065 }
11066 }
11067 else if (fi.isFile())
11068 {
11069 std::string dirPath = fi.dirPath(true);
11070 std::string filePath = fi.absFilePath();
11071 if (paths && !dirPath.empty())
11072 {
11073 paths->insert(dirPath);
11074 }
11075 //printf("killSet.find(%s)=%d\n",qPrint(fi.absFilePath()),killSet.find(fi.absFilePath())!=killSet.end());
11076 if (killSet==nullptr || killSet->find(filePath)==killSet->end())
11077 {
11078 std::string name=fi.fileName();
11079 if (fnMap)
11080 {
11081 auto fd = createFileDef(dirPath+"/",name);
11082 if (!name.empty())
11083 {
11084 FileName *fn = fnMap->add(name);
11085 fn->push_back(std::move(fd));
11086 }
11087 }
11088 if (resultList || resultSet)
11089 {
11090 if (resultList) resultList->push_back(filePath);
11091 if (resultSet) resultSet->insert(filePath);
11092 }
11093
11094 if (killSet) killSet->insert(fi.absFilePath());
11095 }
11096 }
11097 else if (fi.isDir()) // readable dir
11098 {
11099 readDir(&fi,fnMap,exclSet,patList,
11100 exclPatList,resultList,resultSet,errorIfNotExist,
11101 recursive,killSet,paths);
11102 }
11103 }
11104 }
11105}

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

Referenced by searchInputFiles().

◆ readTagFile()

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

Definition at line 10244 of file doxygen.cpp.

10245{
10246 QCString fileName;
10247 QCString destName;
10248 int eqPos = tagLine.find('=');
10249 if (eqPos!=-1) // tag command contains a destination
10250 {
10251 fileName = tagLine.left(eqPos).stripWhiteSpace();
10252 destName = tagLine.right(tagLine.length()-eqPos-1).stripWhiteSpace();
10253 if (fileName.isEmpty() || destName.isEmpty()) return;
10254 //printf("insert tagDestination %s->%s\n",qPrint(fi.fileName()),qPrint(destName));
10255 }
10256 else
10257 {
10258 fileName = tagLine;
10259 }
10260
10261 FileInfo fi(fileName.str());
10262 if (!fi.exists() || !fi.isFile())
10263 {
10264 err("Tag file '{}' does not exist or is not a file. Skipping it...\n",fileName);
10265 return;
10266 }
10267
10268 if (Doxygen::tagFileSet.find(fi.absFilePath()) != Doxygen::tagFileSet.end()) return;
10269
10270 Doxygen::tagFileSet.emplace(fi.absFilePath());
10271
10272 if (!destName.isEmpty())
10273 {
10274 Doxygen::tagDestinationMap.emplace(fi.absFilePath(), destName.str());
10275 msg("Reading tag file '{}', location '{}'...\n",fileName,destName);
10276 }
10277 else
10278 {
10279 msg("Reading tag file '{}'...\n",fileName);
10280 }
10281
10282 parseTagFile(root,fi.absFilePath().c_str());
10283}
static StringUnorderedSet tagFileSet
Definition doxygen.h:117
void parseTagFile(const std::shared_ptr< Entry > &root, const char *fullName)

References FileInfo::absFilePath(), err, FileInfo::exists(), QCString::find(), QCString::isEmpty(), FileInfo::isFile(), QCString::left(), QCString::length(), msg, parseTagFile(), QCString::right(), QCString::str(), QCString::stripWhiteSpace(), Doxygen::tagDestinationMap, and Doxygen::tagFileSet.

Referenced by parseInput().

◆ resolveClassNestingRelations()

void resolveClassNestingRelations ( )
static

create the scope artificially

Definition at line 1381 of file doxygen.cpp.

1382{
1383 ClassDefSet visitedClasses;
1384
1385 bool done=FALSE;
1386 //int iteration=0;
1387 while (!done)
1388 {
1389 done=TRUE;
1390 //++iteration;
1391 struct ClassAlias
1392 {
1393 ClassAlias(const QCString &name,std::unique_ptr<ClassDef> cd,DefinitionMutable *ctx) :
1394 aliasFullName(name),aliasCd(std::move(cd)), aliasContext(ctx) {}
1395 QCString aliasFullName;
1396 std::unique_ptr<ClassDef> aliasCd;
1397 DefinitionMutable *aliasContext;
1398 };
1399 std::vector<ClassAlias> aliases;
1400 for (const auto &icd : *Doxygen::classLinkedMap)
1401 {
1402 ClassDefMutable *cd = toClassDefMutable(icd.get());
1403 if (cd && visitedClasses.find(icd.get())==visitedClasses.end())
1404 {
1405 QCString name = stripAnonymousNamespaceScope(icd->name());
1406 //printf("processing=%s, iteration=%d\n",qPrint(cd->name()),iteration);
1407 // also add class to the correct structural context
1409 name,icd->getFileDef(),nullptr);
1410 if (d)
1411 {
1412 //printf("****** adding %s to scope %s in iteration %d\n",qPrint(cd->name()),qPrint(d->name()),iteration);
1414 if (dm)
1415 {
1416 dm->addInnerCompound(cd);
1417 }
1418 cd->setOuterScope(d);
1419
1420 // for inline namespace add an alias of the class to the outer scope
1422 {
1424 //printf("nd->isInline()=%d\n",nd->isInline());
1425 if (nd && nd->isInline())
1426 {
1427 d = d->getOuterScope();
1428 if (d)
1429 {
1430 dm = toDefinitionMutable(d);
1431 if (dm)
1432 {
1433 auto aliasCd = createClassDefAlias(d,cd);
1434 QCString aliasFullName = d->qualifiedName()+"::"+aliasCd->localName();
1435 aliases.emplace_back(aliasFullName,std::move(aliasCd),dm);
1436 //printf("adding %s to %s as %s\n",qPrint(aliasCd->name()),qPrint(d->name()),qPrint(aliasFullName));
1437 }
1438 }
1439 }
1440 else
1441 {
1442 break;
1443 }
1444 }
1445
1446 visitedClasses.insert(icd.get());
1447 done=FALSE;
1448 }
1449 //else
1450 //{
1451 // printf("****** ignoring %s: scope not (yet) found in iteration %d\n",qPrint(cd->name()),iteration);
1452 //}
1453 }
1454 }
1455 // add aliases
1456 for (auto &alias : aliases)
1457 {
1458 ClassDef *aliasCd = Doxygen::classLinkedMap->add(alias.aliasFullName,std::move(alias.aliasCd));
1459 if (aliasCd)
1460 {
1461 alias.aliasContext->addInnerCompound(aliasCd);
1462 }
1463 }
1464 }
1465
1466 //give warnings for unresolved compounds
1467 for (const auto &icd : *Doxygen::classLinkedMap)
1468 {
1469 ClassDefMutable *cd = toClassDefMutable(icd.get());
1470 if (cd && visitedClasses.find(icd.get())==visitedClasses.end())
1471 {
1473 /// create the scope artificially
1474 // anyway, so we can at least relate scopes properly.
1475 Definition *d = buildScopeFromQualifiedName(name,cd->getLanguage(),nullptr);
1476 if (d && d!=cd && !cd->getDefFileName().isEmpty())
1477 // avoid recursion in case of redundant scopes, i.e: namespace N { class N::C {}; }
1478 // for this case doxygen assumes the existence of a namespace N::N in which C is to be found!
1479 // also avoid warning for stuff imported via a tagfile.
1480 {
1482 if (dm)
1483 {
1484 dm->addInnerCompound(cd);
1485 }
1486 cd->setOuterScope(d);
1487 warn(cd->getDefFileName(),cd->getDefLine(),
1488 "Incomplete input: scope for class {} not found!{}",name,
1489 name.startsWith("std::") ? " Try enabling BUILTIN_STL_SUPPORT." : ""
1490 );
1491 }
1492 }
1493 }
1494}

References DefinitionMutable::addInnerCompound(), buildScopeFromQualifiedName(), Doxygen::classLinkedMap, createClassDefAlias(), Definition::definitionType(), FALSE, findScopeFromQualifiedName(), Definition::getDefFileName(), Definition::getDefLine(), Definition::getLanguage(), Definition::getOuterScope(), Doxygen::globalScope, QCString::isEmpty(), NamespaceDef::isInline(), Definition::name(), Definition::qualifiedName(), DefinitionMutable::setOuterScope(), QCString::startsWith(), stripAnonymousNamespaceScope(), toClassDefMutable(), toDefinitionMutable(), toNamespaceDef(), TRUE, Definition::TypeNamespace, and warn.

Referenced by parseInput().

◆ resolveSymlink()

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

Definition at line 10848 of file doxygen.cpp.

10849{
10850 int sepPos=0;
10851 int oldPos=0;
10852 StringUnorderedSet nonSymlinks;
10853 StringUnorderedSet known;
10854 QCString result(path);
10855 QCString oldPrefix = "/";
10856 do
10857 {
10858#if defined(_WIN32)
10859 // UNC path, skip server and share name
10860 if (sepPos==0 && (result.startsWith("//") || result.startsWith("\\\\")))
10861 sepPos = result.find('/',2);
10862 if (sepPos!=-1)
10863 sepPos = result.find('/',sepPos+1);
10864#else
10865 sepPos = result.find('/',sepPos+1);
10866#endif
10867 QCString prefix = sepPos==-1 ? result : result.left(sepPos);
10868 if (nonSymlinks.find(prefix.str())==nonSymlinks.end())
10869 {
10870 FileInfo fi(prefix.str());
10871 if (fi.isSymLink())
10872 {
10873 QCString target = fi.readLink();
10874 bool isRelative = FileInfo(target.str()).isRelative();
10875 if (isRelative)
10876 {
10877 target = Dir::cleanDirPath(oldPrefix.str()+"/"+target.str());
10878 }
10879 if (sepPos!=-1)
10880 {
10881 if (fi.isDir() && target.length()>0 && target.at(target.length()-1)!='/')
10882 {
10883 target+='/';
10884 }
10885 target+=result.mid(sepPos);
10886 }
10887 result = Dir::cleanDirPath(target.str());
10888 if (known.find(result.str())!=known.end()) return std::string(); // recursive symlink!
10889 known.insert(result.str());
10890 if (isRelative)
10891 {
10892 sepPos = oldPos;
10893 }
10894 else // link to absolute path
10895 {
10896 sepPos = 0;
10897 oldPrefix = "/";
10898 }
10899 }
10900 else
10901 {
10902 nonSymlinks.insert(prefix.str());
10903 oldPrefix = prefix;
10904 }
10905 oldPos = sepPos;
10906 }
10907 }
10908 while (sepPos!=-1);
10909 return Dir::cleanDirPath(result.str());
10910}
static std::string cleanDirPath(const std::string &path)
Definition dir.cpp:357
bool isRelative() const
Definition fileinfo.cpp:58

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

Referenced by readDir().

◆ resolveTemplateInstanceInType()

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

Definition at line 4681 of file doxygen.cpp.

4682{
4683 // For a statement like 'using X = T<A>', add a template instance 'T<A>' as a symbol, so it can
4684 // be used to match arguments (see issue #11111)
4685 AUTO_TRACE();
4686 QCString ttype = md->typeString();
4687 ttype.stripPrefix("typedef ");
4688 int ti=ttype.find('<');
4689 if (ti!=-1)
4690 {
4691 QCString templateClassName = ttype.left(ti);
4692 SymbolResolver resolver(root->fileDef());
4693 ClassDefMutable *baseClass = resolver.resolveClassMutable(scope ? scope : Doxygen::globalScope,
4694 templateClassName, true, true);
4695 AUTO_TRACE_ADD("templateClassName={} baseClass={}",templateClassName,baseClass?baseClass->name():"<none>");
4696 if (baseClass)
4697 {
4698 const ArgumentList &tl = baseClass->templateArguments();
4699 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,templateClassName.str());
4701 baseClass,
4702 ttype.mid(ti),
4703 templateNames,
4704 baseClass->isArtificial());
4705 }
4706 }
4707}

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

Referenced by addVariableToClass(), and addVariableToFile().

◆ resolveUserReferences()

void resolveUserReferences ( )
static

Definition at line 9747 of file doxygen.cpp.

9748{
9749 for (const auto &si : SectionManager::instance())
9750 {
9751 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
9752 // qPrint(si->label),si->definition?qPrint(si->definition->name()):"<none>",
9753 // qPrint(si->fileName));
9754 PageDef *pd=nullptr;
9755
9756 // hack: the items of a todo/test/bug/deprecated list are all fragments from
9757 // different files, so the resulting section's all have the wrong file
9758 // name (not from the todo/test/bug/deprecated list, but from the file in
9759 // which they are defined). We correct this here by looking at the
9760 // generated section labels!
9762 {
9763 QCString label="_"+rl->listName(); // "_todo", "_test", ...
9764 if (si->label().left(label.length())==label)
9765 {
9766 si->setFileName(rl->listName());
9767 si->setGenerated(TRUE);
9768 break;
9769 }
9770 }
9771
9772 //printf("start: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9773 if (!si->generated())
9774 {
9775 // if this section is in a page and the page is in a group, then we
9776 // have to adjust the link file name to point to the group.
9777 if (!si->fileName().isEmpty() &&
9778 (pd=Doxygen::pageLinkedMap->find(si->fileName())) &&
9779 pd->getGroupDef())
9780 {
9781 si->setFileName(pd->getGroupDef()->getOutputFileBase());
9782 }
9783
9784 if (si->definition())
9785 {
9786 // TODO: there should be one function in Definition that returns
9787 // the file to link to, so we can avoid the following tests.
9788 const GroupDef *gd=nullptr;
9789 if (si->definition()->definitionType()==Definition::TypeMember)
9790 {
9791 gd = (toMemberDef(si->definition()))->getGroupDef();
9792 }
9793
9794 if (gd)
9795 {
9796 si->setFileName(gd->getOutputFileBase());
9797 }
9798 else
9799 {
9800 //si->fileName=si->definition->getOutputFileBase();
9801 //printf("Setting si->fileName to %s\n",qPrint(si->fileName));
9802 }
9803 }
9804 }
9805 //printf("end: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9806 }
9807}
virtual const GroupDef * getGroupDef() const =0

References PageDef::getGroupDef(), Definition::getOutputFileBase(), RefListManager::instance(), SectionManager::instance(), QCString::length(), Doxygen::pageLinkedMap, toMemberDef(), TRUE, and Definition::TypeMember.

Referenced by parseInput().

◆ runHtmlHelpCompiler()

void runHtmlHelpCompiler ( )
static

Definition at line 10071 of file doxygen.cpp.

10072{
10073 std::string oldDir = Dir::currentDirPath();
10074 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10077 {
10078 err("failed to run html help compiler on {}\n", HtmlHelp::hhpFileName);
10079 }
10080 Dir::setCurrent(oldDir);
10081}
@ ExtCmd
Definition debug.h:36
static bool setCurrent(const std::string &path)
Definition dir.cpp:350
static const QCString hhpFileName
Definition htmlhelp.h:89
int system(const QCString &command, const QCString &args, bool commandHasConsole=true)
Definition portable.cpp:105
void setShortDir()
Definition portable.cpp:553

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

10084{
10085 QCString args = Qhp::qhpFileName + " -o \"" + Qhp::getQchFileName() + "\"";
10086 std::string oldDir = Dir::currentDirPath();
10087 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10088
10089 QCString qhgLocation=Config_getString(QHG_LOCATION);
10090 if (Debug::isFlagSet(Debug::Qhp)) // produce info for debugging
10091 {
10092 // run qhelpgenerator -v and extract the Qt version used
10093 QCString cmd=qhgLocation+ " -v 2>&1";
10094 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10095 FILE *f=Portable::popen(cmd,"r");
10096 if (!f)
10097 {
10098 err("could not execute {}\n",qhgLocation);
10099 }
10100 else
10101 {
10102 const size_t bufSize = 1024;
10103 char inBuf[bufSize+1];
10104 size_t numRead=fread(inBuf,1,bufSize,f);
10105 inBuf[numRead] = '\0';
10106 Debug::print(Debug::Qhp,0,"{}",inBuf);
10108
10109 int qtVersion=0;
10110 static const reg::Ex versionReg(R"(Qt (\d+)\.(\d+)\.(\d+))");
10112 std::string s = inBuf;
10113 if (reg::search(s,match,versionReg))
10114 {
10115 qtVersion = 10000*QCString(match[1].str()).toInt() +
10116 100*QCString(match[2].str()).toInt() +
10117 QCString(match[3].str()).toInt();
10118 }
10119 if (qtVersion>0 && (qtVersion<60000 || qtVersion >= 60205))
10120 {
10121 // dump the output of qhelpgenerator -c file.qhp
10122 // Qt<6 or Qt>=6.2.5 or higher, see https://bugreports.qt.io/browse/QTBUG-101070
10123 cmd=qhgLocation+ " -c " + Qhp::qhpFileName + " 2>&1";
10124 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10125 f=Portable::popen(cmd,"r");
10126 if (!f)
10127 {
10128 err("could not execute {}\n",qhgLocation);
10129 }
10130 else
10131 {
10132 std::string output;
10133 while ((numRead=fread(inBuf,1,bufSize,f))>0)
10134 {
10135 inBuf[numRead] = '\0';
10136 output += inBuf;
10137 }
10139 Debug::print(Debug::Qhp,0,"{}",output);
10140 }
10141 }
10142 }
10143 }
10144
10145 if (Portable::system(qhgLocation, args, FALSE))
10146 {
10147 err("failed to run qhelpgenerator on {}\n",Qhp::qhpFileName);
10148 }
10149 Dir::setCurrent(oldDir);
10150}
@ Qhp
Definition debug.h:44
int toInt(bool *ok=nullptr, int base=10) const
Definition qcstring.cpp:254
static const QCString qhpFileName
Definition qhp.h:47
static QCString getQchFileName()
Definition qhp.cpp:426
FILE * popen(const QCString &name, const QCString &type)
Definition portable.cpp:479
int pclose(FILE *stream)
Definition portable.cpp:488

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

Referenced by generateOutput().

◆ scopeIsTemplate()

bool scopeIsTemplate ( const Definition * d)
static

Definition at line 5854 of file doxygen.cpp.

5855{
5856 bool result=FALSE;
5857 //printf("> scopeIsTemplate(%s)\n",qPrint(d?d->name():"null"));
5859 {
5860 auto cd = toClassDef(d);
5861 result = cd->templateArguments().hasParameters() || cd->templateMaster()!=nullptr ||
5863 }
5864 //printf("< scopeIsTemplate=%d\n",result);
5865 return result;
5866}

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

Referenced by addMemberFunction(), and scopeIsTemplate().

◆ searchInputFiles()

void searchInputFiles ( )

Definition at line 12075 of file doxygen.cpp.

12076{
12077 StringUnorderedSet killSet;
12078
12079 const StringVector &exclPatterns = Config_getList(EXCLUDE_PATTERNS);
12080 bool alwaysRecursive = Config_getBool(RECURSIVE);
12081 StringUnorderedSet excludeNameSet;
12082
12083 // gather names of all files in the include path
12084 g_s.begin("Searching for include files...\n");
12085 killSet.clear();
12086 const StringVector &includePathList = Config_getList(INCLUDE_PATH);
12087 for (const auto &s : includePathList)
12088 {
12089 size_t plSize = Config_getList(INCLUDE_FILE_PATTERNS).size();
12090 const StringVector &pl = plSize==0 ? Config_getList(FILE_PATTERNS) :
12091 Config_getList(INCLUDE_FILE_PATTERNS);
12092 readFileOrDirectory(s, // s
12094 nullptr, // exclSet
12095 &pl, // patList
12096 &exclPatterns, // exclPatList
12097 nullptr, // resultList
12098 nullptr, // resultSet
12099 false, // INCLUDE_PATH isn't recursive
12100 TRUE, // errorIfNotExist
12101 &killSet); // killSet
12102 }
12103 g_s.end();
12104
12105 g_s.begin("Searching for example files...\n");
12106 killSet.clear();
12107 const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
12108 for (const auto &s : examplePathList)
12109 {
12110 readFileOrDirectory(s, // s
12112 nullptr, // exclSet
12113 &Config_getList(EXAMPLE_PATTERNS), // patList
12114 nullptr, // exclPatList
12115 nullptr, // resultList
12116 nullptr, // resultSet
12117 (alwaysRecursive || Config_getBool(EXAMPLE_RECURSIVE)), // recursive
12118 TRUE, // errorIfNotExist
12119 &killSet); // killSet
12120 }
12121 g_s.end();
12122
12123 g_s.begin("Searching for images...\n");
12124 killSet.clear();
12125 const StringVector &imagePathList=Config_getList(IMAGE_PATH);
12126 for (const auto &s : imagePathList)
12127 {
12128 readFileOrDirectory(s, // s
12130 nullptr, // exclSet
12131 nullptr, // patList
12132 nullptr, // exclPatList
12133 nullptr, // resultList
12134 nullptr, // resultSet
12135 alwaysRecursive, // recursive
12136 TRUE, // errorIfNotExist
12137 &killSet); // killSet
12138 }
12139 g_s.end();
12140
12141 g_s.begin("Searching for dot files...\n");
12142 killSet.clear();
12143 const StringVector &dotFileList=Config_getList(DOTFILE_DIRS);
12144 for (const auto &s : dotFileList)
12145 {
12146 readFileOrDirectory(s, // s
12148 nullptr, // exclSet
12149 nullptr, // patList
12150 nullptr, // exclPatList
12151 nullptr, // resultList
12152 nullptr, // resultSet
12153 alwaysRecursive, // recursive
12154 TRUE, // errorIfNotExist
12155 &killSet); // killSet
12156 }
12157 g_s.end();
12158
12159 g_s.begin("Searching for msc files...\n");
12160 killSet.clear();
12161 const StringVector &mscFileList=Config_getList(MSCFILE_DIRS);
12162 for (const auto &s : mscFileList)
12163 {
12164 readFileOrDirectory(s, // s
12166 nullptr, // exclSet
12167 nullptr, // patList
12168 nullptr, // exclPatList
12169 nullptr, // resultList
12170 nullptr, // resultSet
12171 alwaysRecursive, // recursive
12172 TRUE, // errorIfNotExist
12173 &killSet); // killSet
12174 }
12175 g_s.end();
12176
12177 g_s.begin("Searching for dia files...\n");
12178 killSet.clear();
12179 const StringVector &diaFileList=Config_getList(DIAFILE_DIRS);
12180 for (const auto &s : diaFileList)
12181 {
12182 readFileOrDirectory(s, // s
12184 nullptr, // exclSet
12185 nullptr, // patList
12186 nullptr, // exclPatList
12187 nullptr, // resultList
12188 nullptr, // resultSet
12189 alwaysRecursive, // recursive
12190 TRUE, // errorIfNotExist
12191 &killSet); // killSet
12192 }
12193 g_s.end();
12194
12195 g_s.begin("Searching for plantuml files...\n");
12196 killSet.clear();
12197 const StringVector &plantUmlFileList=Config_getList(PLANTUMLFILE_DIRS);
12198 for (const auto &s : plantUmlFileList)
12199 {
12200 readFileOrDirectory(s, // s
12202 nullptr, // exclSet
12203 nullptr, // patList
12204 nullptr, // exclPatList
12205 nullptr, // resultList
12206 nullptr, // resultSet
12207 alwaysRecursive, // recursive
12208 TRUE, // errorIfNotExist
12209 &killSet); // killSet
12210 }
12211 g_s.end();
12212
12213 g_s.begin("Searching for mermaid files...\n");
12214 killSet.clear();
12215 const StringVector &mermaidFileList=Config_getList(MERMAIDFILE_DIRS);
12216 for (const auto &s : mermaidFileList)
12217 {
12218 readFileOrDirectory(s, // s
12220 nullptr, // exclSet
12221 nullptr, // patList
12222 nullptr, // exclPatList
12223 nullptr, // resultList
12224 nullptr, // resultSet
12225 alwaysRecursive, // recursive
12226 TRUE, // errorIfNotExist
12227 &killSet); // killSet
12228 }
12229 g_s.end();
12230
12231 g_s.begin("Searching for files to exclude\n");
12232 const StringVector &excludeList = Config_getList(EXCLUDE);
12233 for (const auto &s : excludeList)
12234 {
12235 readFileOrDirectory(s, // s
12236 nullptr, // fnDict
12237 nullptr, // exclSet
12238 &Config_getList(FILE_PATTERNS), // patList
12239 nullptr, // exclPatList
12240 nullptr, // resultList
12241 &excludeNameSet, // resultSet
12242 alwaysRecursive, // recursive
12243 FALSE); // errorIfNotExist
12244 }
12245 g_s.end();
12246
12247 /**************************************************************************
12248 * Determine Input Files *
12249 **************************************************************************/
12250
12251 g_s.begin("Searching INPUT for files to process...\n");
12252 killSet.clear();
12253 Doxygen::inputPaths.clear();
12254 const StringVector &inputList=Config_getList(INPUT);
12255 for (const auto &s : inputList)
12256 {
12257 QCString path = s;
12258 size_t l = path.length();
12259 if (l>0)
12260 {
12261 // strip trailing slashes
12262 if (path.at(l-1)=='\\' || path.at(l-1)=='/') path=path.left(l-1);
12263
12265 path, // s
12267 &excludeNameSet, // exclSet
12268 &Config_getList(FILE_PATTERNS), // patList
12269 &exclPatterns, // exclPatList
12270 &g_inputFiles, // resultList
12271 nullptr, // resultSet
12272 alwaysRecursive, // recursive
12273 TRUE, // errorIfNotExist
12274 &killSet, // killSet
12275 &Doxygen::inputPaths); // paths
12276 }
12277 }
12278
12279 // Sort the FileDef objects by full path to get a predictable ordering over multiple runs
12280 for (auto &fileName : *Doxygen::inputNameLinkedMap)
12281 {
12282 if (fileName->size()>1)
12283 {
12284 std::stable_sort(fileName->begin(),fileName->end(),[](const auto &f1,const auto &f2)
12285 {
12286 return qstricmp_sort(f1->absFilePath(),f2->absFilePath())<0;
12287 });
12288 }
12289 }
12290 std::stable_sort(Doxygen::inputNameLinkedMap->begin(),
12292 [](const auto &f1,const auto &f2)
12293 {
12294 return qstricmp_sort(f1->front()->absFilePath(),f2->front()->absFilePath())<0;
12295 });
12296 if (Doxygen::inputNameLinkedMap->empty())
12297 {
12298 warn_uncond("No files to be processed, please check your settings, in particular INPUT, FILE_PATTERNS, and RECURSIVE\n");
12299 }
12300 g_s.end();
12301}
static StringUnorderedSet inputPaths
Definition doxygen.h:103
void readFileOrDirectory(const QCString &s, FileNameLinkedMap *fnMap, StringUnorderedSet *exclSet, const StringVector *patList, const StringVector *exclPatList, StringVector *resultList, StringUnorderedSet *resultSet, bool recursive, bool errorIfNotExist, StringUnorderedSet *killSet, StringUnorderedSet *paths)

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

Referenced by parseInput().

◆ setAnonymousEnumType()

void setAnonymousEnumType ( )
static

Definition at line 8920 of file doxygen.cpp.

8921{
8922 for (const auto &cd : *Doxygen::classLinkedMap)
8923 {
8924 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8925 if (cdm)
8926 {
8927 cdm->setAnonymousEnumType();
8928 }
8929 }
8930}
virtual void setAnonymousEnumType()=0

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

Referenced by parseInput().

◆ sortMemberLists()

void sortMemberLists ( )
static

Definition at line 8825 of file doxygen.cpp.

8826{
8827 // sort class member lists
8828 for (const auto &cd : *Doxygen::classLinkedMap)
8829 {
8830 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8831 if (cdm)
8832 {
8833 cdm->sortMemberLists();
8834 }
8835 }
8836
8837 // sort namespace member lists
8838 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8839 {
8841 if (ndm)
8842 {
8843 ndm->sortMemberLists();
8844 }
8845 }
8846
8847 // sort file member lists
8848 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8849 {
8850 for (const auto &fd : *fn)
8851 {
8852 fd->sortMemberLists();
8853 }
8854 }
8855
8856 // sort group member lists
8857 for (const auto &gd : *Doxygen::groupLinkedMap)
8858 {
8859 gd->sortMemberLists();
8860 }
8861
8863}
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 11942 of file doxygen.cpp.

11943{
11944 signal(SIGINT,SIG_DFL); // Re-register signal handler for default action
11945 Dir thisDir;
11946 msg("Cleaning up...\n");
11947 if (!Doxygen::filterDBFileName.isEmpty())
11948 {
11949 thisDir.remove(Doxygen::filterDBFileName.str());
11950 }
11951 killpg(0,SIGINT);
11953 exitTracing();
11954 exit(1);
11955}

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

Referenced by parseInput().

◆ stripTemplateSpecifiers()

QCString stripTemplateSpecifiers ( const QCString & s)

Definition at line 686 of file doxygen.cpp.

687{
688 size_t l = s.length();
689 int count=0;
690 int round=0;
691 QCString result;
692 for (size_t i=0;i<l;i++)
693 {
694 char c=s.at(i);
695 if (c=='(') round++;
696 else if (c==')' && round>0) round--;
697 else if (c=='<' && round==0) count++;
698 if (count==0)
699 {
700 result+=c;
701 }
702 if (c=='>' && round==0 && count>0) count--;
703 }
704 //printf("stripTemplateSpecifiers(%s)=%s\n",qPrint(s),qPrint(result));
705 return result;
706}

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

Referenced by buildScopeFromQualifiedName().

◆ substituteTemplatesInArgList()

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

Definition at line 5952 of file doxygen.cpp.

5958{
5959 auto dstIt = dst.begin();
5960 for (const Argument &sa : src)
5961 {
5962 QCString dstType = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.type.str());
5963 QCString dstArray = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.array.str());
5964 if (dstIt == dst.end())
5965 {
5966 Argument da = sa;
5967 da.type = dstType;
5968 da.array = dstArray;
5969 dst.push_back(da);
5970 dstIt = dst.end();
5971 }
5972 else
5973 {
5974 Argument da = *dstIt;
5975 da.type = dstType;
5976 da.array = dstArray;
5977 ++dstIt;
5978 }
5979 }
5980 dst.setConstSpecifier(src.constSpecifier());
5981 dst.setVolatileSpecifier(src.volatileSpecifier());
5982 dst.setPureSpecifier(src.pureSpecifier());
5984 srcTempArgLists,dstTempArgLists,
5985 src.trailingReturnType().str()));
5986 dst.setIsDeleted(src.isDeleted());
5987 dst.setRefQualifier(src.refQualifier());
5988 dst.setNoParameters(src.noParameters());
5989 //printf("substituteTemplatesInArgList: replacing %s with %s\n",
5990 // qPrint(argListToString(src)),qPrint(argListToString(dst))
5991 // );
5992}
iterator end()
Definition arguments.h:94
void setPureSpecifier(bool b)
Definition arguments.h:121
void push_back(const Argument &a)
Definition arguments.h:102
void setConstSpecifier(bool b)
Definition arguments.h:119
void setRefQualifier(RefQualifierType t)
Definition arguments.h:126
void setIsDeleted(bool b)
Definition arguments.h:125
iterator begin()
Definition arguments.h:93
void setNoParameters(bool b)
Definition arguments.h:127
void setVolatileSpecifier(bool b)
Definition arguments.h:120
static QCString substituteTemplatesInString(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const std::string &src)
Definition doxygen.cpp:5868
QCString array
Definition arguments.h:45

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(), QCString::str(), substituteTemplatesInString(), ArgumentList::trailingReturnType(), Argument::type, and ArgumentList::volatileSpecifier().

Referenced by addMemberFunction().

◆ substituteTemplatesInString()

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

Definition at line 5868 of file doxygen.cpp.

5873{
5874 std::string dst;
5875 static const reg::Ex re(R"(\a\w*)");
5876 reg::Iterator it(src,re);
5878 //printf("type=%s\n",qPrint(sa->type));
5879 size_t p=0;
5880 for (; it!=end ; ++it) // for each word in srcType
5881 {
5882 const auto &match = *it;
5883 size_t i = match.position();
5884 size_t l = match.length();
5885 bool found=FALSE;
5886 dst+=src.substr(p,i-p);
5887 std::string name=match.str();
5888
5889 auto srcIt = srcTempArgLists.begin();
5890 auto dstIt = dstTempArgLists.begin();
5891 while (srcIt!=srcTempArgLists.end() && !found)
5892 {
5893 const ArgumentList *tdAli = nullptr;
5894 std::vector<Argument>::const_iterator tdaIt;
5895 if (dstIt!=dstTempArgLists.end())
5896 {
5897 tdAli = &(*dstIt);
5898 tdaIt = tdAli->begin();
5899 ++dstIt;
5900 }
5901
5902 const ArgumentList &tsaLi = *srcIt;
5903 for (auto tsaIt = tsaLi.begin(); tsaIt!=tsaLi.end() && !found; ++tsaIt)
5904 {
5905 Argument tsa = *tsaIt;
5906 const Argument *tda = nullptr;
5907 if (tdAli && tdaIt!=tdAli->end())
5908 {
5909 tda = &(*tdaIt);
5910 ++tdaIt;
5911 }
5912 //if (tda) printf("tsa=%s|%s tda=%s|%s\n",
5913 // qPrint(tsa.type),qPrint(tsa.name),
5914 // qPrint(tda->type),qPrint(tda->name));
5915 if (name==tsa.name.str())
5916 {
5917 if (tda && tda->name.isEmpty())
5918 {
5919 QCString tdaName = tda->name;
5920 QCString tdaType = tda->type;
5921 int vc=0;
5922 if (tdaType.startsWith("class ")) vc=6;
5923 else if (tdaType.startsWith("typename ")) vc=9;
5924 if (vc>0) // convert type=="class T" to type=="class" name=="T"
5925 {
5926 tdaName = tdaType.mid(vc);
5927 }
5928 if (!tdaName.isEmpty())
5929 {
5930 name=tdaName.str(); // substitute
5931 found=TRUE;
5932 }
5933 }
5934 }
5935 }
5936
5937 //printf(" srcList='%s' dstList='%s faList='%s'\n",
5938 // qPrint(argListToString(srclali.current())),
5939 // qPrint(argListToString(dstlali.current())),
5940 // funcTempArgList ? qPrint(argListToString(funcTempArgList)) : "<none>");
5941 ++srcIt;
5942 }
5943 dst+=name;
5944 p=i+l;
5945 }
5946 dst+=src.substr(p);
5947 //printf(" substituteTemplatesInString(%s)=%s\n",
5948 // qPrint(src),qPrint(dst));
5949 return dst;
5950}

References ArgumentList::begin(), ArgumentList::end(), end(), FALSE, QCString::isEmpty(), QCString::mid(), Argument::name, QCString::startsWith(), QCString::str(), TRUE, and Argument::type.

Referenced by substituteTemplatesInArgList().

◆ transferFunctionDocumentation()

void transferFunctionDocumentation ( )
static

Definition at line 4193 of file doxygen.cpp.

4194{
4195 AUTO_TRACE();
4196
4197 // find matching function declaration and definitions.
4198 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4199 {
4200 //printf("memberName=%s count=%zu\n",qPrint(mn->memberName()),mn->size());
4201 /* find a matching function declaration and definition for this function */
4202 for (const auto &imdec : *mn)
4203 {
4204 MemberDefMutable *mdec = toMemberDefMutable(imdec.get());
4205 if (mdec &&
4206 (mdec->isPrototype() ||
4207 (mdec->isVariable() && mdec->isExternal())
4208 ))
4209 {
4210 for (const auto &imdef : *mn)
4211 {
4212 MemberDefMutable *mdef = toMemberDefMutable(imdef.get());
4213 if (mdef && mdec!=mdef &&
4214 mdec->getNamespaceDef()==mdef->getNamespaceDef())
4215 {
4217 }
4218 }
4219 }
4220 }
4221 }
4222}
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 4226 of file doxygen.cpp.

4227{
4228 AUTO_TRACE();
4229 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4230 {
4231 MemberDefMutable *mdef=nullptr,*mdec=nullptr;
4232 /* find a matching function declaration and definition for this function */
4233 for (const auto &imd : *mn)
4234 {
4235 MemberDefMutable *md = toMemberDefMutable(imd.get());
4236 if (md)
4237 {
4238 if (md->isPrototype())
4239 mdec=md;
4240 else if (md->isVariable() && md->isExternal())
4241 mdec=md;
4242
4243 if (md->isFunction() && !md->isStatic() && !md->isPrototype())
4244 mdef=md;
4245 else if (md->isVariable() && !md->isExternal() && !md->isStatic())
4246 mdef=md;
4247 }
4248
4249 if (mdef && mdec) break;
4250 }
4251 if (mdef && mdec)
4252 {
4253 const ArgumentList &mdefAl = mdef->argumentList();
4254 const ArgumentList &mdecAl = mdec->argumentList();
4255 if (
4256 matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdef->typeString(),const_cast<ArgumentList*>(&mdefAl),
4257 mdec->getOuterScope(),mdec->getFileDef(),mdec->typeString(),const_cast<ArgumentList*>(&mdecAl),
4258 TRUE,mdef->getLanguage()
4259 )
4260 ) /* match found */
4261 {
4262 AUTO_TRACE_ADD("merging references for mdec={} mdef={}",mdec->name(),mdef->name());
4263 mdef->mergeReferences(mdec);
4264 mdec->mergeReferences(mdef);
4265 mdef->mergeReferencedBy(mdec);
4266 mdec->mergeReferencedBy(mdef);
4267 }
4268 }
4269 }
4270}
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(), TRUE, and MemberDef::typeString().

Referenced by parseInput().

◆ transferRelatedFunctionDocumentation()

void transferRelatedFunctionDocumentation ( )
static

Definition at line 4274 of file doxygen.cpp.

4275{
4276 AUTO_TRACE();
4277 // find match between function declaration and definition for
4278 // related functions
4279 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4280 {
4281 /* find a matching function declaration and definition for this function */
4282 // for each global function
4283 for (const auto &imd : *mn)
4284 {
4285 MemberDefMutable *md = toMemberDefMutable(imd.get());
4286 if (md)
4287 {
4288 //printf(" Function '%s'\n",qPrint(md->name()));
4289 MemberName *rmn = Doxygen::memberNameLinkedMap->find(md->name());
4290 if (rmn) // check if there is a member with the same name
4291 {
4292 //printf(" Member name found\n");
4293 // for each member with the same name
4294 for (const auto &irmd : *rmn)
4295 {
4296 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
4297 //printf(" Member found: related='%d'\n",rmd->isRelated());
4298 if (rmd &&
4299 (rmd->isRelated() || rmd->isForeign()) && // related function
4300 matchArguments2( md->getOuterScope(), md->getFileDef(), md->typeString(), &md->argumentList(),
4301 rmd->getOuterScope(),rmd->getFileDef(),rmd->typeString(),&rmd->argumentList(),
4302 TRUE,md->getLanguage()
4303 )
4304 )
4305 {
4306 AUTO_TRACE_ADD("Found related member '{}'",md->name());
4307 if (rmd->relatedAlso())
4308 md->setRelatedAlso(rmd->relatedAlso());
4309 else if (rmd->isForeign())
4310 md->makeForeign();
4311 else
4312 md->makeRelated();
4313 }
4314 }
4315 }
4316 }
4317 }
4318 }
4319}
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, 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(), TRUE, and MemberDef::typeString().

Referenced by parseInput().

◆ transferStaticInstanceInitializers()

void transferStaticInstanceInitializers ( )

Definition at line 4323 of file doxygen.cpp.

4324{
4325 AUTO_TRACE();
4326 for (const auto &[qualifiedName,bodyInfo] : Doxygen::staticInitMap)
4327 {
4328 size_t i=qualifiedName.rfind("::");
4329 if (i!=std::string::npos)
4330 {
4331 QCString scope = qualifiedName.substr(0,i);
4332 QCString name = qualifiedName.substr(i+2);
4333 MemberName *mn = Doxygen::memberNameLinkedMap->find(name);
4334 if (mn)
4335 {
4336 for (const auto &imd : *mn)
4337 {
4338 MemberDefMutable *md = toMemberDefMutable(imd.get());
4339 if (md && md->qualifiedName().str()==qualifiedName && md->isVariable())
4340 {
4341 AUTO_TRACE_ADD("found static member {} body [{}..{}]\n",
4342 md->qualifiedName(),bodyInfo.startLine,bodyInfo.endLine);
4343 md->setBodySegment(bodyInfo.defLine,
4344 bodyInfo.startLine,
4345 bodyInfo.endLine);
4346 }
4347 }
4348 }
4349 }
4350 }
4351}

References AUTO_TRACE, AUTO_TRACE_ADD, MemberDef::isVariable(), Doxygen::memberNameLinkedMap, Definition::qualifiedName(), DefinitionMutable::setBodySegment(), Doxygen::staticInitMap, QCString::str(), and toMemberDefMutable().

Referenced by parseInput().

◆ tryAddEnumDocsToGroupMember()

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

Definition at line 7882 of file doxygen.cpp.

7883{
7884 for (const auto &g : root->groups)
7885 {
7886 const GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
7887 if (gd)
7888 {
7889 MemberList *ml = gd->getMemberList(MemberListType::DecEnumMembers());
7890 if (ml)
7891 {
7892 MemberDefMutable *md = toMemberDefMutable(ml->find(name));
7893 if (md)
7894 {
7895 addEnumDocs(root,md);
7896 return TRUE;
7897 }
7898 }
7899 }
7900 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
7901 {
7902 warn(root->fileName, root->startLine,
7903 "Found non-existing group '{}' for the command '{}', ignoring command",
7904 g.groupname, Grouping::getGroupPriName( g.pri )
7905 );
7906 }
7907 }
7908
7909 return FALSE;
7910}
virtual MemberList * getMemberList(MemberListType lt) const =0
const MemberDef * find(const QCString &name) const
Definition memberlist.h:93

References addEnumDocs(), FALSE, Entry::fileName, MemberVector::find(), Grouping::getGroupPriName(), GroupDef::getMemberList(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Entry::groups, Entry::startLine, toMemberDefMutable(), TRUE, and warn.

Referenced by findEnumDocumentation().

◆ usage()

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

Definition at line 11198 of file doxygen.cpp.

11199{
11201 msg("Doxygen version {0}\nCopyright Dimitri van Heesch 1997-2025\n\n"
11202 "You can use Doxygen in a number of ways:\n\n"
11203 "1) Use Doxygen to generate a template configuration file*:\n"
11204 " {1} [-s] -g [configName]\n\n"
11205 "2) Use Doxygen to update an old configuration file*:\n"
11206 " {1} [-s] -u [configName]\n\n"
11207 "3) Use Doxygen to generate documentation using an existing "
11208 "configuration file*:\n"
11209 " {1} [configName]\n\n"
11210 "4) Use Doxygen to generate a template file controlling the layout of the\n"
11211 " generated documentation:\n"
11212 " {1} -l [layoutFileName]\n\n"
11213 " In case layoutFileName is omitted DoxygenLayout.xml will be used as filename.\n"
11214 " If - is used for layoutFileName Doxygen will write to standard output.\n\n"
11215 "5) Use Doxygen to generate a template style sheet file for RTF, HTML or Latex.\n"
11216 " RTF: {1} -w rtf styleSheetFile\n"
11217 " HTML: {1} -w html headerFile footerFile styleSheetFile [configFile]\n"
11218 " LaTeX: {1} -w latex headerFile footerFile styleSheetFile [configFile]\n\n"
11219 "6) Use Doxygen to generate a rtf extensions file\n"
11220 " {1} -e rtf extensionsFile\n\n"
11221 " If - is used for extensionsFile Doxygen will write to standard output.\n\n"
11222 "7) Use Doxygen to compare the used configuration file with the template configuration file\n"
11223 " {1} -x [configFile]\n\n"
11224 " Use Doxygen to compare the used configuration file with the template configuration file\n"
11225 " without replacing the environment variables or CMake type replacement variables\n"
11226 " {1} -x_noenv [configFile]\n\n"
11227 "8) Use Doxygen to show a list of built-in emojis.\n"
11228 " {1} -f emoji outputFileName\n\n"
11229 " If - is used for outputFileName Doxygen will write to standard output.\n\n"
11230 "*) If -s is specified the comments of the configuration items in the config file will be omitted.\n"
11231 " If configName is omitted 'Doxyfile' will be used as a default.\n"
11232 " If - is used for configFile Doxygen will write / read the configuration to /from standard output / input.\n\n"
11233 "If -q is used for a Doxygen documentation run, Doxygen will see this as if QUIET=YES has been set.\n\n"
11234 "-v print version string, -V print extended version information\n"
11235 "-h,-? prints usage help information\n"
11236 "{1} -d prints additional usage flags for debugging purposes\n",versionString,name);
11237}

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

Referenced by readConfiguration().

◆ version()

void version ( const bool extended)
static

Definition at line 11170 of file doxygen.cpp.

11171{
11173 QCString versionString = getFullVersion();
11174 msg("{}\n",versionString);
11175 if (extended)
11176 {
11177 QCString extVers;
11178 if (!extVers.isEmpty()) extVers+= ", ";
11179 extVers += "sqlite3 ";
11180 extVers += sqlite3_libversion();
11181#if USE_LIBCLANG
11182 if (!extVers.isEmpty()) extVers+= ", ";
11183 extVers += "clang support ";
11184 extVers += CLANG_VERSION_STRING;
11185#endif
11186 if (!extVers.isEmpty())
11187 {
11188 int lastComma = extVers.findRev(',');
11189 if (lastComma != -1) extVers = extVers.replace(lastComma,1," and");
11190 msg(" with {}.\n",extVers);
11191 }
11192 }
11193}
QCString & replace(size_t index, size_t len, const char *s)
Definition qcstring.cpp:217

References Debug::clearFlag(), QCString::findRev(), QCString::isEmpty(), msg, QCString::replace(), and Debug::Time.

Referenced by readConfiguration(), and LayoutParser::startLayout().

◆ vhdlCorrectMemberProperties()

void vhdlCorrectMemberProperties ( )
static

Definition at line 8245 of file doxygen.cpp.

8246{
8247 // for each member name
8248 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8249 {
8250 // for each member definition
8251 for (const auto &imd : *mn)
8252 {
8253 MemberDefMutable *md = toMemberDefMutable(imd.get());
8254 if (md)
8255 {
8257 }
8258 }
8259 }
8260 // for each member name
8261 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8262 {
8263 // for each member definition
8264 for (const auto &imd : *mn)
8265 {
8266 MemberDefMutable *md = toMemberDefMutable(imd.get());
8267 if (md)
8268 {
8270 }
8271 }
8272 }
8273}
static void correctMemberProperties(MemberDefMutable *md)

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

Referenced by parseInput().

◆ warnUndocumentedNamespaces()

void warnUndocumentedNamespaces ( )
static

Definition at line 5202 of file doxygen.cpp.

5203{
5204 AUTO_TRACE();
5205 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5206 {
5207 if (!nd->hasDocumentation())
5208 {
5209 if ((guessSection(nd->getDefFileName()).isHeader() ||
5210 nd->getLanguage() == SrcLangExt::Fortran) && // Fortran doesn't have header files.
5211 !Config_getBool(HIDE_UNDOC_NAMESPACES) // undocumented namespaces are visible
5212 )
5213 {
5214 warn_undoc(nd->getDefFileName(),nd->getDefLine(), "{} {} is not documented.",
5215 nd->getLanguage() == SrcLangExt::Fortran ? "Module" : "Namespace",
5216 nd->name());
5217 }
5218 }
5219 }
5220}

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

Referenced by parseInput().

◆ writeTagFile()

void writeTagFile ( )
static

Definition at line 11958 of file doxygen.cpp.

11959{
11960 QCString generateTagFile = Config_getString(GENERATE_TAGFILE);
11961 if (generateTagFile.isEmpty()) return;
11962
11963 std::ofstream f = Portable::openOutputStream(generateTagFile);
11964 if (!f.is_open())
11965 {
11966 err("cannot open tag file {} for writing\n", generateTagFile);
11967 return;
11968 }
11969 TextStream tagFile(&f);
11970 tagFile << "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>\n";
11971 tagFile << "<tagfile doxygen_version=\"" << getDoxygenVersion() << "\"";
11972 std::string gitVersion = getGitVersion();
11973 if (!gitVersion.empty())
11974 {
11975 tagFile << " doxygen_gitid=\"" << gitVersion << "\"";
11976 }
11977 tagFile << ">\n";
11978
11979 // for each file
11980 for (const auto &fn : *Doxygen::inputNameLinkedMap)
11981 {
11982 for (const auto &fd : *fn)
11983 {
11984 if (fd->isLinkableInProject()) fd->writeTagFile(tagFile);
11985 }
11986 }
11987 // for each class
11988 for (const auto &cd : *Doxygen::classLinkedMap)
11989 {
11990 ClassDefMutable *cdm = toClassDefMutable(cd.get());
11991 if (cdm && cdm->isLinkableInProject())
11992 {
11993 cdm->writeTagFile(tagFile);
11994 }
11995 }
11996 // for each concept
11997 for (const auto &cd : *Doxygen::conceptLinkedMap)
11998 {
11999 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
12000 if (cdm && cdm->isLinkableInProject())
12001 {
12002 cdm->writeTagFile(tagFile);
12003 }
12004 }
12005 // for each namespace
12006 for (const auto &nd : *Doxygen::namespaceLinkedMap)
12007 {
12009 if (ndm && nd->isLinkableInProject())
12010 {
12011 ndm->writeTagFile(tagFile);
12012 }
12013 }
12014 // for each group
12015 for (const auto &gd : *Doxygen::groupLinkedMap)
12016 {
12017 if (gd->isLinkableInProject()) gd->writeTagFile(tagFile);
12018 }
12019 // for each module
12020 for (const auto &mod : ModuleManager::instance().modules())
12021 {
12022 if (mod->isLinkableInProject()) mod->writeTagFile(tagFile);
12023 }
12024 // for each page
12025 for (const auto &pd : *Doxygen::pageLinkedMap)
12026 {
12027 if (pd->isLinkableInProject()) pd->writeTagFile(tagFile);
12028 }
12029 // for requirements
12031 // for each directory
12032 for (const auto &dd : *Doxygen::dirLinkedMap)
12033 {
12034 if (dd->isLinkableInProject()) dd->writeTagFile(tagFile);
12035 }
12036 if (Doxygen::mainPage) Doxygen::mainPage->writeTagFile(tagFile);
12037
12038 tagFile << "</tagfile>\n";
12039}
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, err, Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), RequirementManager::instance(), QCString::isEmpty(), 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

QCString g_commentFileName
static

Definition at line 193 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 199 of file doxygen.cpp.

199 { "template class", "template struct", "class", "struct", "union", "interface", "exception" };

Referenced by buildVarList(), and filterMemberDocumentation().

◆ g_dumpSymbolMap

bool g_dumpSymbolMap = FALSE
static

Definition at line 192 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 194 of file doxygen.cpp.

Referenced by parseInput(), and readConfiguration().

◆ g_successfulRun

bool g_successfulRun = FALSE
static

Definition at line 191 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 2019 of file doxygen.cpp.

Referenced by findUsingDeclImports(), and parseInput().

◆ g_usingDeclarations

StringSet g_usingDeclarations
static

Definition at line 190 of file doxygen.cpp.

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