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 "version.h"
#include "doxygen.h"
#include "scanner.h"
#include "entry.h"
#include "index.h"
#include "indexlist.h"
#include "message.h"
#include "config.h"
#include "util.h"
#include "pre.h"
#include "tagreader.h"
#include "dot.h"
#include "msc.h"
#include "docparser.h"
#include "dirdef.h"
#include "outputlist.h"
#include "declinfo.h"
#include "htmlgen.h"
#include "latexgen.h"
#include "mangen.h"
#include "language.h"
#include "debug.h"
#include "htmlhelp.h"
#include "qhp.h"
#include "sitemap.h"
#include "ftvhelp.h"
#include "defargs.h"
#include "rtfgen.h"
#include "sqlite3gen.h"
#include "xmlgen.h"
#include "docbookgen.h"
#include "defgen.h"
#include "perlmodgen.h"
#include "reflist.h"
#include "pagedef.h"
#include "commentcnv.h"
#include "cmdmapper.h"
#include "searchindex_js.h"
#include "parserintf.h"
#include "htags.h"
#include "pycode.h"
#include "pyscanner.h"
#include "fortrancode.h"
#include "fortranscanner.h"
#include "xmlcode.h"
#include "sqlcode.h"
#include "lexcode.h"
#include "lexscanner.h"
#include "code.h"
#include "portable.h"
#include "vhdljjparser.h"
#include "vhdldocgen.h"
#include "vhdlcode.h"
#include "eclipsehelp.h"
#include "cite.h"
#include "markdown.h"
#include "arguments.h"
#include "memberlist.h"
#include "layout.h"
#include "groupdef.h"
#include "classlist.h"
#include "namespacedef.h"
#include "filename.h"
#include "membername.h"
#include "membergroup.h"
#include "docsets.h"
#include "formula.h"
#include "settings.h"
#include "fileparser.h"
#include "emoji.h"
#include "plantuml.h"
#include "stlsupport.h"
#include "threadpool.h"
#include "clangparser.h"
#include "symbolresolver.h"
#include "regex.h"
#include "aliases.h"
#include "fileinfo.h"
#include "dir.h"
#include "conceptdef.h"
#include "trace.h"
#include "moduledef.h"
#include "stringutil.h"
#include "singlecomment.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 ClassDefMutablecreateTagLessInstance (const ClassDef *rootCd, const ClassDef *templ, const QCString &fieldName)
static void processTagLessClasses (const ClassDef *rootCd, const ClassDef *cd, ClassDefMutable *tagParentCd, const QCString &prefix, int count)
 Look through the members of class cd and its public members.
static void findTagLessClasses (std::vector< ClassDefMutable * > &candidates, ClassDef *cd)
static void findTagLessClasses ()
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 ()
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 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 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)
static void copyIcon (const QCString &outputOption)
static void copyExtraFiles (const StringVector &files, const QCString &filesOption, const QCString &outputOption)
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 ()
static int computeIdealCacheParam (size_t v)
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 132 of file doxygen.cpp.

Enumeration Type Documentation

◆ FindBaseClassRelation_Mode

Enumerator
TemplateInstances 
DocumentedOnly 
Undocumented 

Definition at line 284 of file doxygen.cpp.

285{
289};
@ Undocumented
Definition doxygen.cpp:288
@ TemplateInstances
Definition doxygen.cpp:286
@ DocumentedOnly
Definition doxygen.cpp:287

Function Documentation

◆ addClassAndNestedClasses()

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

Definition at line 9084 of file doxygen.cpp.

9085{
9086 list.push_back(cd);
9087 for (const auto &innerCdi : cd->getClasses())
9088 {
9089 ClassDefMutable *innerCd = toClassDefMutable(innerCdi);
9090 if (innerCd)
9091 {
9092 AUTO_TRACE("innerCd={} isLinkable={} isImplicitTemplateInstance={} protectLevelVisible={} embeddedInOuterScope={}",
9093 innerCd->name(),innerCd->isLinkableInProject(),innerCd->isImplicitTemplateInstance(),protectionLevelVisible(innerCd->protection()),
9094 innerCd->isEmbeddedInOuterScope());
9095 }
9096 if (innerCd && innerCd->isLinkableInProject() && !innerCd->isImplicitTemplateInstance() &&
9097 protectionLevelVisible(innerCd->protection()) &&
9098 !innerCd->isEmbeddedInOuterScope()
9099 )
9100 {
9101 list.push_back(innerCd);
9102 addClassAndNestedClasses(list,innerCd);
9103 }
9104 }
9105}
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:46
static void addClassAndNestedClasses(std::vector< ClassDefMutable * > &list, ClassDefMutable *cd)
Definition doxygen.cpp:9084
bool protectionLevelVisible(Protection prot)
Definition util.cpp:5849

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

932{
933 AUTO_TRACE("name={}",root->name);
934 FileDef *fd = root->fileDef();
935
936 QCString scName;
937 if (root->parent()->section.isScope())
938 {
939 scName=root->parent()->name;
940 }
941 // name without parent's scope
942 QCString fullName = root->name;
943
944 // strip off any template parameters (but not those for specializations)
945 int idx=fullName.find('>');
946 if (idx!=-1 && root->lang==SrcLangExt::CSharp) // mangle A<S,T>::N as A-2-g::N
947 {
948 fullName = mangleCSharpGenericName(fullName.left(idx+1))+fullName.mid(idx+1);
949 }
950 fullName=stripTemplateSpecifiersFromScope(fullName);
951
952 // name with scope (if not present already)
953 QCString qualifiedName = fullName;
954 if (!scName.isEmpty() && !leftScopeMatch(scName,fullName))
955 {
956 qualifiedName.prepend(scName+"::");
957 }
958
959 // see if we already found the class before
960 ClassDefMutable *cd = getClassMutable(qualifiedName);
961
962 AUTO_TRACE_ADD("Found class with name '{}', qualifiedName '{}'", cd ? cd->name() : root->name, qualifiedName);
963
964 if (cd)
965 {
966 fullName=cd->name();
967 AUTO_TRACE_ADD("Existing class '{}'",cd->name());
968 //if (cd->templateArguments()==0)
969 //{
970 // //printf("existing ClassDef tempArgList=%p specScope=%s\n",root->tArgList,qPrint(root->scopeSpec));
971 // cd->setTemplateArguments(tArgList);
972 //}
973
974 cd->setDocumentation(root->doc,root->docFile,root->docLine);
975 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
976 root->commandOverrides.apply_collaborationGraph([&](bool b ) { cd->overrideCollaborationGraph(b); });
977 root->commandOverrides.apply_inheritanceGraph ([&](CLASS_GRAPH_t gt) { cd->overrideInheritanceGraph(gt); });
978
979 if (!root->spec.isForwardDecl() && cd->isForwardDeclared())
980 {
981 cd->setDefFile(root->fileName,root->startLine,root->startColumn);
982 if (root->bodyLine!=-1)
983 {
984 cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
985 cd->setBodyDef(fd);
986 }
987 }
988
989 if (cd->templateArguments().empty() || (cd->isForwardDeclared() && !root->spec.isForwardDecl()))
990 {
991 // this happens if a template class declared with @class is found
992 // before the actual definition or if a forward declaration has different template
993 // parameter names.
994 std::unique_ptr<ArgumentList> tArgList = getTemplateArgumentsFromName(cd->name(),root->tArgLists);
995 if (tArgList)
996 {
997 cd->setTemplateArguments(*tArgList);
998 }
999 }
1000 if (cd->requiresClause().isEmpty() && !root->req.isEmpty())
1001 {
1002 cd->setRequiresClause(root->req);
1003 }
1004
1006
1007 cd->setMetaData(root->metaData);
1008 }
1009 else // new class
1010 {
1012
1013 QCString className;
1014 QCString namespaceName;
1015 extractNamespaceName(fullName,className,namespaceName);
1016
1017 AUTO_TRACE_ADD("New class: fullname '{}' namespace '{}' name='{}' brief='{}' docs='{}'",
1018 fullName, namespaceName, className, Trace::trunc(root->brief), Trace::trunc(root->doc));
1019
1020 QCString tagName;
1021 QCString refFileName;
1022 const TagInfo *tagInfo = root->tagInfo();
1023 if (tagInfo)
1024 {
1025 tagName = tagInfo->tagName;
1026 refFileName = tagInfo->fileName;
1027 if (fullName.find("::")!=-1)
1028 // symbols imported via tag files may come without the parent scope,
1029 // so we artificially create it here
1030 {
1031 buildScopeFromQualifiedName(fullName,root->lang,tagInfo);
1032 }
1033 }
1034 std::unique_ptr<ArgumentList> tArgList;
1035 int i=0;
1036 if ((root->lang==SrcLangExt::CSharp || root->lang==SrcLangExt::Java) && (i=fullName.findRev('<'))!=-1)
1037 {
1038 // a Java/C# generic class looks like a C++ specialization, so we need to split the
1039 // name and template arguments here
1040 tArgList = stringToArgumentList(root->lang,fullName.mid(i));
1041 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
1042 // A -> A
1043 // A<T> -> A-1-g
1044 // A<T,S> -> A-2-g
1045 {
1046 fullName=mangleCSharpGenericName(fullName);
1047 }
1048 else
1049 {
1050 fullName=fullName.left(i);
1051 }
1052 }
1053 else
1054 {
1055 tArgList = getTemplateArgumentsFromName(fullName,root->tArgLists);
1056 }
1057 // add class to the list
1058 cd = toClassDefMutable(
1059 Doxygen::classLinkedMap->add(fullName,
1060 createClassDef(tagInfo?tagName:root->fileName,root->startLine,root->startColumn,
1061 fullName,sec,tagName,refFileName,TRUE,root->spec.isEnum()) ));
1062 if (cd)
1063 {
1064 AUTO_TRACE_ADD("New class '{}' type={} #tArgLists={} tagInfo={} hidden={} artificial={}",
1065 fullName,cd->compoundTypeString(),root->tArgLists.size(),
1066 fmt::ptr(tagInfo),root->hidden,root->artificial);
1067 cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1068 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1069 cd->setLanguage(root->lang);
1070 cd->setId(root->id);
1071 cd->setHidden(root->hidden);
1072 cd->setArtificial(root->artificial);
1073 cd->setClassSpecifier(root->spec);
1074 cd->addQualifiers(root->qualifiers);
1075 cd->setTypeConstraints(root->typeConstr);
1076 root->commandOverrides.apply_collaborationGraph([&](bool b ) { cd->overrideCollaborationGraph(b); });
1077 root->commandOverrides.apply_inheritanceGraph ([&](CLASS_GRAPH_t gt) { cd->overrideInheritanceGraph(gt); });
1078
1079 if (tArgList)
1080 {
1081 cd->setTemplateArguments(*tArgList);
1082 }
1083 cd->setRequiresClause(root->req);
1084 cd->setProtection(root->protection);
1085 cd->setIsStatic(root->isStatic);
1086
1087 // file definition containing the class cd
1088 cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1089 cd->setBodyDef(fd);
1090
1091 cd->setMetaData(root->metaData);
1092
1093 cd->insertUsedFile(fd);
1094 }
1095 else
1096 {
1097 AUTO_TRACE_ADD("Class {} not added, already exists as alias", fullName);
1098 }
1099 }
1100
1101 if (cd)
1102 {
1104 if (!root->subGrouping) cd->setSubGrouping(FALSE);
1105 if (!root->spec.isForwardDecl())
1106 {
1107 if (cd->hasDocumentation())
1108 {
1109 addIncludeFile(cd,fd,root);
1110 }
1111 if (fd && root->section.isCompound())
1112 {
1113 AUTO_TRACE_ADD("Inserting class {} in file {} (root->fileName='{}')", cd->name(), fd->name(), root->fileName);
1114 cd->setFileDef(fd);
1115 fd->insertClass(cd);
1116 }
1117 }
1118 addClassToGroups(root,cd);
1120 cd->setRefItems(root->sli);
1121 }
1122}
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 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 setRefItems(const RefItemVector &sli)=0
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:96
bool subGrouping
automatically group class members?
Definition entry.h:188
QCString metaData
Slice metadata.
Definition entry.h:233
int docLine
line number at which the documentation was found
Definition entry.h:201
ArgumentList typeConstr
where clause (C#) for type constraints
Definition entry.h:215
int endBodyLine
line number where the definition ends
Definition entry.h:218
const TagInfo * tagInfo() const
Definition entry.h:177
QCString id
libclang id
Definition entry.h:231
ArgumentLists tArgLists
template argument declarations
Definition entry.h:195
SrcLangExt lang
programming language in which this entry was found
Definition entry.h:227
Entry * parent() const
Definition entry.h:134
int startColumn
start column of entry in the source
Definition entry.h:225
std::vector< const SectionInfo * > anchors
list of anchors defined in this entry
Definition entry.h:222
QCString fileName
file this entry was extracted from
Definition entry.h:223
CommandOverrides commandOverrides
store info for commands whose default can be overridden
Definition entry.h:190
int startLine
start line of entry in the source
Definition entry.h:224
QCString req
C++20 requires clause.
Definition entry.h:234
QCString name
member name
Definition entry.h:174
EntryType section
entry type (see Sections);
Definition entry.h:172
QCString briefFile
file in which the brief desc. was found
Definition entry.h:205
int bodyLine
line number of the body in the source
Definition entry.h:216
std::vector< std::string > qualifiers
qualifiers specified with the qualifier command
Definition entry.h:235
QCString doc
documentation block (partly parsed)
Definition entry.h:200
RefItemVector sli
special lists (test/todo/bug/deprecated/..) this entry is in
Definition entry.h:226
QCString docFile
file in which the documentation was found
Definition entry.h:202
Protection protection
class protection
Definition entry.h:180
bool artificial
Artificially introduced item.
Definition entry.h:229
bool hidden
does this represent an entity that is hidden from the output
Definition entry.h:228
QCString brief
brief description (doc block)
Definition entry.h:203
int briefLine
line number at which the brief desc. was found
Definition entry.h:204
FileDef * fileDef() const
Definition entry.h:169
bool isStatic
static ?
Definition entry.h:185
TypeSpecifier spec
class/member specifiers
Definition entry.h:182
ENTRY_TYPES bool isCompound() const
Definition types.h:800
bool isScope() const
Definition types.h:801
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:101
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
QCString & prepend(const char *s)
Definition qcstring.h:422
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:241
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:163
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:96
QCString left(size_t len) const
Definition qcstring.h:229
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:559
ClassDefMutable * getClassMutable(const QCString &key)
Definition classdef.h:469
std::unique_ptr< ArgumentList > stringToArgumentList(SrcLangExt lang, const QCString &argsString, QCString *extraTypeChars=nullptr)
Definition defargs.l:809
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:47
static void addIncludeFile(DefMutable *cd, FileDef *ifd, const Entry *root)
Definition doxygen.cpp:581
static ClassDef::CompoundType convertToCompoundType(EntryType section, TypeSpecifier specifier)
Definition doxygen.cpp:889
std::unique_ptr< ArgumentList > getTemplateArgumentsFromName(const QCString &name, const ArgumentLists &tArgLists)
Definition doxygen.cpp:859
static Definition * buildScopeFromQualifiedName(const QCString &name_, SrcLangExt lang, const TagInfo *tagInfo)
Definition doxygen.cpp:705
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:103
QCString fileName
Definition entry.h:105
QCString tagName
Definition entry.h:104
bool leftScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:890
void extractNamespaceName(const QCString &scopeName, QCString &className, QCString &namespaceName, bool allowEmptyClass)
Definition util.cpp:3618
QCString mangleCSharpGenericName(const QCString &name)
Definition util.cpp:6823
QCString stripTemplateSpecifiersFromScope(const QCString &fullName, bool parentOnly, QCString *pLastScopeStripped, QCString scopeName, bool allowArtificial)
Definition util.cpp:4437

References addClassToGroups(), ModuleManager::addClassToModule(), addIncludeFile(), ClassDefMutable::addQualifiers(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, 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(), QCString::findRev(), 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::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::setProtection(), DefinitionMutable::setRefItems(), 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 1151 of file doxygen.cpp.

1152{
1153 AUTO_TRACE();
1154 FileDef *fd = root->fileDef();
1155
1156 QCString scName;
1157 if (root->parent()->section.isScope())
1158 {
1159 scName=root->parent()->name;
1160 }
1161
1162 // name with scope (if not present already)
1163 QCString qualifiedName = root->name;
1164 if (!scName.isEmpty() && !leftScopeMatch(qualifiedName,scName))
1165 {
1166 qualifiedName.prepend(scName+"::");
1167 }
1168
1169 // see if we already found the concept before
1170 ConceptDefMutable *cd = getConceptMutable(qualifiedName);
1171
1172 AUTO_TRACE_ADD("Found concept with name '{}' (qualifiedName='{}')", cd ? cd->name() : root->name, qualifiedName);
1173
1174 if (cd)
1175 {
1176 qualifiedName=cd->name();
1177 AUTO_TRACE_ADD("Existing concept '{}'",cd->name());
1178
1179 cd->setDocumentation(root->doc,root->docFile,root->docLine);
1180 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1181
1182 addIncludeFile(cd,fd,root);
1183 }
1184 else // new concept
1185 {
1186 QCString className;
1187 QCString namespaceName;
1188 extractNamespaceName(qualifiedName,className,namespaceName);
1189
1190 AUTO_TRACE_ADD("New concept: fullname '{}' namespace '{}' name='{}' brief='{}' docs='{}'",
1191 qualifiedName,namespaceName,className,root->brief,root->doc);
1192
1193 QCString tagName;
1194 QCString refFileName;
1195 const TagInfo *tagInfo = root->tagInfo();
1196 if (tagInfo)
1197 {
1198 tagName = tagInfo->tagName;
1199 refFileName = tagInfo->fileName;
1200 if (qualifiedName.find("::")!=-1)
1201 // symbols imported via tag files may come without the parent scope,
1202 // so we artificially create it here
1203 {
1204 buildScopeFromQualifiedName(qualifiedName,root->lang,tagInfo);
1205 }
1206 }
1207 std::unique_ptr<ArgumentList> tArgList = getTemplateArgumentsFromName(qualifiedName,root->tArgLists);
1208 // add concept to the list
1210 Doxygen::conceptLinkedMap->add(qualifiedName,
1211 createConceptDef(tagInfo?tagName:root->fileName,root->startLine,root->startColumn,
1212 qualifiedName,tagName,refFileName)));
1213 if (cd)
1214 {
1215 AUTO_TRACE_ADD("New concept '{}' #tArgLists={} tagInfo={}",
1216 qualifiedName,root->tArgLists.size(),fmt::ptr(tagInfo));
1217 cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1218 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1219 cd->setLanguage(root->lang);
1220 cd->setId(root->id);
1221 cd->setHidden(root->hidden);
1222 cd->setGroupId(root->mGrpId);
1223 if (tArgList)
1224 {
1225 cd->setTemplateArguments(*tArgList);
1226 }
1227 cd->setInitializer(root->initializer.str());
1228 // file definition containing the class cd
1229 cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1230 cd->setBodyDef(fd);
1231 addIncludeFile(cd,fd,root);
1232
1233 // also add namespace to the correct structural context
1234 Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,qualifiedName,nullptr,tagInfo);
1236 {
1238 if (dm)
1239 {
1240 dm->addInnerCompound(cd);
1241 }
1242 cd->setOuterScope(d);
1243 }
1244 }
1245 else
1246 {
1247 AUTO_TRACE_ADD("Concept '{}' not added, already exists (as alias)", qualifiedName);
1248 }
1249 }
1250
1251 if (cd)
1252 {
1254 if (fd)
1255 {
1256 AUTO_TRACE_ADD("Inserting concept '{}' in file '{}' (root->fileName='{}')", cd->name(), fd->name(), root->fileName);
1257 cd->setFileDef(fd);
1258 fd->insertConcept(cd);
1259 }
1260 addConceptToGroups(root,cd);
1262 cd->setRefItems(root->sli);
1263 }
1264}
virtual void setFileDef(FileDef *fd)=0
virtual void setInitializer(const QCString &init)=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:76
virtual DefType definitionType() const =0
virtual void addInnerCompound(Definition *d)=0
virtual void setOuterScope(Definition *d)=0
static ConceptLinkedMap * conceptLinkedMap
Definition doxygen.h:98
static NamespaceDefMutable * globalScope
Definition doxygen.h:121
TextStream initializer
initial value (for variables)
Definition entry.h:197
int mGrpId
member group id
Definition entry.h:219
virtual void insertConcept(ConceptDef *cd)=0
void addConceptToModule(const Entry *root, ConceptDef *cd)
std::string str() const
Return the contents of the buffer as a std::string object.
Definition textstream.h:229
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:90
DefinitionMutable * toDefinitionMutable(Definition *d)
static Definition * findScopeFromQualifiedName(NamespaceDefMutable *startScope, const QCString &n, FileDef *fileScope, const TagInfo *tagInfo)
Definition doxygen.cpp:774
void addConceptToGroups(const Entry *root, ConceptDef *cd)

References addConceptToGroups(), ModuleManager::addConceptToModule(), addIncludeFile(), DefinitionMutable::addInnerCompound(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, buildScopeFromQualifiedName(), 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::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(), 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 9475 of file doxygen.cpp.

9476{
9477 md->setDocumentation(root->doc,root->docFile,root->docLine);
9478 md->setDocsForDefinition(!root->proto);
9479 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9480 if (md->inbodyDocumentation().isEmpty())
9481 {
9483 }
9484 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
9485 {
9486 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
9487 md->setBodyDef(root->fileDef());
9488 }
9490 md->setMaxInitLines(root->initLines);
9492 md->setRefItems(root->sli);
9493 md->addQualifiers(root->qualifiers);
9494 if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
9495 addMemberToGroups(root,md);
9497}
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:187
QCString inbodyDocs
documentation inside the body of a function
Definition entry.h:206
int inbodyLine
line number at which the body doc was found
Definition entry.h:207
int initLines
define/variable initializer lines to show
Definition entry.h:184
QCString inbodyFile
file in which the body doc was found
Definition entry.h:208
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:2097
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, DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setMaxInitLines(), MemberDefMutable::setMemberGroupId(), DefinitionMutable::setRefItems(), Entry::sli, and Entry::startLine.

Referenced by findDefineDocumentation().

◆ addEnumDocs()

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

Definition at line 7903 of file doxygen.cpp.

7904{
7905 AUTO_TRACE();
7906 // documentation outside a compound overrides the documentation inside it
7907 {
7908 md->setDocumentation(root->doc,root->docFile,root->docLine);
7909 md->setDocsForDefinition(!root->proto);
7910 }
7911
7912 // brief descriptions inside a compound override the documentation
7913 // outside it
7914 {
7915 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7916 }
7917
7918 if (md->inbodyDocumentation().isEmpty() || !root->parent()->name.isEmpty())
7919 {
7921 }
7922
7923 if (root->mGrpId!=-1 && md->getMemberGroupId()==-1)
7924 {
7925 md->setMemberGroupId(root->mGrpId);
7926 }
7927
7929 md->setRefItems(root->sli);
7930
7931 const GroupDef *gd=md->getGroupDef();
7932 if (gd==nullptr && !root->groups.empty()) // member not grouped but out-of-line documentation is
7933 {
7934 addMemberToGroups(root,md);
7935 }
7937}
std::vector< Grouping > groups
list of groups this entry belongs to
Definition entry.h:221
A model of a group of symbols.
Definition groupdef.h: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, DefinitionMutable::setBriefDescription(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setMemberGroupId(), DefinitionMutable::setRefItems(), and Entry::sli.

Referenced by findEnumDocumentation(), and tryAddEnumDocsToGroupMember().

◆ addEnumValuesToEnums()

void addEnumValuesToEnums ( const Entry * root)
static

Definition at line 7654 of file doxygen.cpp.

7655{
7656 if (root->section.isEnum())
7657 // non anonymous enumeration
7658 {
7659 AUTO_TRACE("name={}",root->name);
7660 ClassDefMutable *cd = nullptr;
7661 FileDef *fd = nullptr;
7662 NamespaceDefMutable *nd = nullptr;
7663 MemberNameLinkedMap *mnsd = nullptr;
7664 bool isGlobal = false;
7665 bool isRelated = false;
7666 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
7667
7668 QCString name;
7669 QCString scope;
7670
7671 int i = root->name.findRev("::");
7672 if (i!=-1) // scope is specified
7673 {
7674 scope=root->name.left(i); // extract scope
7675 if (root->lang==SrcLangExt::CSharp)
7676 {
7677 scope = mangleCSharpGenericName(scope);
7678 }
7679 name=root->name.right(root->name.length()-i-2); // extract name
7680 if ((cd=getClassMutable(scope))==nullptr)
7681 {
7683 }
7684 }
7685 else // no scope, check the scope in which the docs where found
7686 {
7687 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7688 {
7689 scope=root->parent()->name;
7690 if (root->lang==SrcLangExt::CSharp)
7691 {
7692 scope = mangleCSharpGenericName(scope);
7693 }
7694 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7695 }
7696 name=root->name;
7697 }
7698
7699 if (!root->relates.isEmpty())
7700 { // related member, prefix user specified scope
7701 isRelated=TRUE;
7702 if (getClassMutable(root->relates)==nullptr && !scope.isEmpty())
7703 scope=mergeScopes(scope,root->relates);
7704 else
7705 scope=root->relates;
7706 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7707 }
7708
7709 if (cd && !name.isEmpty()) // found a enum inside a compound
7710 {
7711 //printf("Enum in class '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
7712 fd=nullptr;
7714 isGlobal=false;
7715 }
7716 else if (nd && !nd->isAnonymous()) // found enum inside namespace
7717 {
7718 //printf("Enum in namespace '%s'::'%s'\n",qPrint(nd->name()),qPrint(name));
7720 isGlobal=true;
7721 }
7722 else // found a global enum
7723 {
7724 fd=root->fileDef();
7725 //printf("Enum in file '%s': '%s'\n",qPrint(fd->name()),qPrint(name));
7727 isGlobal=true;
7728 }
7729
7730 if (!name.isEmpty())
7731 {
7732 //printf("** name=%s\n",qPrint(name));
7733 MemberName *mn = mnsd->find(name); // for all members with this name
7734 if (mn)
7735 {
7736 struct EnumValueInfo
7737 {
7738 EnumValueInfo(const QCString &n,std::unique_ptr<MemberDef> &&md) :
7739 name(n), member(std::move(md)) {}
7740 QCString name;
7741 std::unique_ptr<MemberDef> member;
7742 };
7743 std::vector< EnumValueInfo > extraMembers;
7744 // for each enum in this list
7745 for (const auto &imd : *mn)
7746 {
7747 MemberDefMutable *md = toMemberDefMutable(imd.get());
7748 // use raw pointer in this loop, since we modify mn and can then invalidate mdp.
7749 if (md && md->isEnumerate() && !root->children().empty())
7750 {
7751 AUTO_TRACE_ADD("enum {} with {} children",md->name(),root->children().size());
7752 for (const auto &e : root->children())
7753 {
7754 SrcLangExt sle = root->lang;
7755 bool isJavaLike = sle==SrcLangExt::CSharp || sle==SrcLangExt::Java || sle==SrcLangExt::XML;
7756 if ( isJavaLike || root->spec.isStrong())
7757 {
7758 if (sle == SrcLangExt::Cpp && e->section.isDefine()) continue;
7759 // Unlike classic C/C++ enums, for C++11, C# & Java enum
7760 // values are only visible inside the enum scope, so we must create
7761 // them here and only add them to the enum
7762 //printf("md->qualifiedName()=%s e->name=%s tagInfo=%p name=%s\n",
7763 // qPrint(md->qualifiedName()),qPrint(e->name),(void*)e->tagInfo(),qPrint(e->name));
7764 QCString qualifiedName = root->name;
7765 i = qualifiedName.findRev("::");
7766 if (i!=-1 && sle==SrcLangExt::CSharp)
7767 {
7768 qualifiedName = mangleCSharpGenericName(qualifiedName.left(i))+qualifiedName.mid(i);
7769 }
7770 if (isJavaLike)
7771 {
7772 qualifiedName=substitute(qualifiedName,"::",".");
7773 }
7774 if (md->qualifiedName()==qualifiedName) // enum value scope matches that of the enum
7775 {
7776 QCString fileName = e->fileName;
7777 if (fileName.isEmpty() && e->tagInfo())
7778 {
7779 fileName = e->tagInfo()->tagName;
7780 }
7781 AUTO_TRACE_ADD("strong enum value {}",e->name);
7782 auto fmd = createMemberDef(
7783 fileName,e->startLine,e->startColumn,
7784 e->type,e->name,e->args,QCString(),
7785 e->protection, Specifier::Normal,e->isStatic,Relationship::Member,
7787 auto fmmd = toMemberDefMutable(fmd.get());
7788 NamespaceDef *mnd = md->getNamespaceDef();
7789 if (md->getClassDef())
7790 fmmd->setMemberClass(md->getClassDef());
7791 else if (mnd && (mnd->isLinkable() || mnd->isAnonymous()))
7792 fmmd->setNamespace(mnd);
7793 else if (md->getFileDef())
7794 fmmd->setFileDef(md->getFileDef());
7795 fmmd->setOuterScope(md->getOuterScope());
7796 fmmd->setTagInfo(e->tagInfo());
7797 fmmd->setLanguage(e->lang);
7798 fmmd->setBodySegment(e->startLine,e->bodyLine,e->endBodyLine);
7799 fmmd->setBodyDef(e->fileDef());
7800 fmmd->setId(e->id);
7801 fmmd->setDocumentation(e->doc,e->docFile,e->docLine);
7802 fmmd->setBriefDescription(e->brief,e->briefFile,e->briefLine);
7803 fmmd->addSectionsToDefinition(e->anchors);
7804 fmmd->setInitializer(e->initializer.str());
7805 fmmd->setMaxInitLines(e->initLines);
7806 fmmd->setMemberGroupId(e->mGrpId);
7807 fmmd->setExplicitExternal(e->explicitExternal,fileName,e->startLine,e->startColumn);
7808 fmmd->setRefItems(e->sli);
7809 fmmd->setAnchor();
7810 md->insertEnumField(fmd.get());
7811 fmmd->setEnumScope(md,TRUE);
7812 extraMembers.emplace_back(e->name,std::move(fmd));
7813 }
7814 }
7815 else
7816 {
7817 AUTO_TRACE_ADD("enum value {}",e->name);
7818 //printf("e->name=%s isRelated=%d\n",qPrint(e->name),isRelated);
7819 MemberName *fmn=nullptr;
7820 MemberNameLinkedMap *emnsd = isRelated ? Doxygen::functionNameLinkedMap : mnsd;
7821 if (!e->name.isEmpty() && (fmn=emnsd->find(e->name)))
7822 // get list of members with the same name as the field
7823 {
7824 for (const auto &ifmd : *fmn)
7825 {
7826 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
7827 if (fmd && fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope
7828 {
7829 //printf("found enum value with same name %s in scope %s\n",
7830 // qPrint(fmd->name()),qPrint(fmd->getOuterScope()->name()));
7831 if (nd && !nd->isAnonymous())
7832 {
7833 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7834 {
7835 const NamespaceDef *fnd=fmd->getNamespaceDef();
7836 if (fnd==nd) // enum value is inside a namespace
7837 {
7838 md->insertEnumField(fmd);
7839 fmd->setEnumScope(md);
7840 }
7841 }
7842 }
7843 else if (isGlobal)
7844 {
7845 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7846 {
7847 const FileDef *ffd=fmd->getFileDef();
7848 if (ffd==fd && ffd==md->getFileDef()) // enum value has file scope
7849 {
7850 md->insertEnumField(fmd);
7851 fmd->setEnumScope(md);
7852 }
7853 }
7854 }
7855 else if (isRelated && cd) // reparent enum value to
7856 // match the enum's scope
7857 {
7858 md->insertEnumField(fmd); // add field def to list
7859 fmd->setEnumScope(md); // cross ref with enum name
7860 fmd->setEnumClassScope(cd); // cross ref with enum name
7861 fmd->setOuterScope(cd);
7862 fmd->makeRelated();
7863 cd->insertMember(fmd);
7864 }
7865 else
7866 {
7867 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7868 {
7869 const ClassDef *fcd=fmd->getClassDef();
7870 if (fcd==cd) // enum value is inside a class
7871 {
7872 //printf("Inserting enum field %s in enum scope %s\n",
7873 // qPrint(fmd->name()),qPrint(md->name()));
7874 md->insertEnumField(fmd); // add field def to list
7875 fmd->setEnumScope(md); // cross ref with enum name
7876 }
7877 }
7878 }
7879 }
7880 }
7881 }
7882 }
7883 }
7884 }
7885 }
7886 // move the newly added members into mn
7887 for (auto &e : extraMembers)
7888 {
7889 MemberName *emn=mnsd->add(e.name);
7890 emn->push_back(std::move(e.member));
7891 }
7892 }
7893 }
7894 }
7895 else
7896 {
7897 for (const auto &e : root->children()) addEnumValuesToEnums(e.get());
7898 }
7899}
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
const std::vector< std::shared_ptr< Entry > > & children() const
Definition entry.h:139
QCString relates
related class (doc block)
Definition entry.h:209
T * add(const char *k, Args &&... args)
Definition linkedmap.h:90
const T * find(const std::string &key) const
Definition linkedmap.h:47
virtual const ClassDef * getClassDef() const =0
virtual const FileDef * getFileDef() const =0
virtual bool isStrongEnumValue() const =0
virtual const NamespaceDef * getNamespaceDef() const =0
virtual bool isEnumerate() const =0
virtual bool isEnumValue() const =0
virtual void setEnumScope(MemberDef *md, bool livesInsideEnum=FALSE)=0
virtual void setEnumClassScope(ClassDef *cd)=0
virtual void insertEnumField(MemberDef *md)=0
virtual void makeRelated()=0
void push_back(Ptr &&p)
Definition membername.h: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:166
QCString right(size_t len) const
Definition qcstring.h:234
static void addEnumValuesToEnums(const Entry *root)
Definition doxygen.cpp:7654
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:482
@ EnumValue
Definition types.h:558
SrcLangExt
Definition types.h:207
QCString mergeScopes(const QCString &leftScope, const QCString &rightScope)
Definition util.cpp:4504

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addEnumValuesToEnums(), AUTO_TRACE, AUTO_TRACE_ADD, buildScopeFromQualifiedName(), Entry::children(), createMemberDef(), EnumValue, 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 3770 of file doxygen.cpp.

3771{
3772 QCString scope = sc;
3773
3774 // new global function
3776 auto md = createMemberDef(
3777 root->fileName,root->startLine,root->startColumn,
3778 root->type,name,root->args,root->exception,
3779 root->protection,root->virt,root->isStatic,Relationship::Member,
3781 !root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
3782 root->argList,root->metaData);
3783 auto mmd = toMemberDefMutable(md.get());
3784 mmd->setTagInfo(root->tagInfo());
3785 mmd->setLanguage(root->lang);
3786 mmd->setId(root->id);
3787 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3788 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3789 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3790 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
3791 mmd->setDocsForDefinition(!root->proto);
3792 mmd->setTypeConstraints(root->typeConstr);
3793 //md->setBody(root->body);
3794 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3795 FileDef *fd=root->fileDef();
3796 mmd->setBodyDef(fd);
3797 mmd->addSectionsToDefinition(root->anchors);
3798 mmd->setMemberSpecifiers(root->spec);
3799 mmd->setVhdlSpecifiers(root->vhdlSpec);
3800 mmd->setMemberGroupId(root->mGrpId);
3801 mmd->setRequiresClause(root->req);
3802 mmd->setExplicitExternal(root->explicitExternal,root->fileName,root->startLine,root->startColumn);
3803
3804 NamespaceDefMutable *nd = nullptr;
3805 // see if the function is inside a namespace that was not part of
3806 // the name already (in that case nd should be non-zero already)
3807 if (root->parent()->section.isNamespace())
3808 {
3809 //QCString nscope=removeAnonymousScopes(root->parent()->name);
3810 QCString nscope=root->parent()->name;
3811 if (!nscope.isEmpty())
3812 {
3813 nd = getResolvedNamespaceMutable(nscope);
3814 }
3815 }
3816 else if (root->parent()->section.isGroupDoc() && !scope.isEmpty())
3817 {
3819 }
3820
3821 if (!scope.isEmpty())
3822 {
3824 if (sep!="::")
3825 {
3826 scope = substitute(scope,"::",sep);
3827 }
3828 scope+=sep;
3829 }
3830
3831 if (Config_getBool(HIDE_SCOPE_NAMES)) scope = "";
3832 QCString def;
3833 //QCString optArgs = root->argList.empty() ? QCString() : root->args;
3834 if (!root->type.isEmpty())
3835 {
3836 def=root->type+" "+scope+name; //+optArgs;
3837 }
3838 else
3839 {
3840 def=scope+name; //+optArgs;
3841 }
3842 AUTO_TRACE("new non-member function type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
3843 root->type,scope,rname,root->args,root->proto,def);
3844 mmd->setDefinition(def);
3846 mmd->addQualifiers(root->qualifiers);
3847
3848 mmd->setRefItems(root->sli);
3849 if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
3850 {
3851 // add member to namespace
3852 mmd->setNamespace(nd);
3853 nd->insertMember(md.get());
3854 }
3855 if (fd)
3856 {
3857 // add member to the file (we do this even if we have already
3858 // inserted it into the namespace)
3859 mmd->setFileDef(fd);
3860 fd->insertMember(md.get());
3861 }
3862
3863 addMemberToGroups(root,md.get());
3865 if (root->relatesType == RelatesType::Simple) // if this is a relatesalso command,
3866 // allow find Member to pick it up
3867 {
3868 root->markAsProcessed(); // Otherwise we have finished with this entry.
3869 }
3870
3871 // add member to the list of file members
3873 mn->push_back(std::move(md));
3874}
VhdlSpecifier vhdlSpec
VHDL specifiers.
Definition entry.h:183
void markAsProcessed() const
Definition entry.h:167
bool explicitExternal
explicitly defined as external?
Definition entry.h:186
RelatesType relatesType
how relates is handled
Definition entry.h:210
QCString args
member argument string
Definition entry.h:192
QCString type
member type
Definition entry.h:173
QCString exception
throw specification
Definition entry.h:214
ArgumentList argList
member arguments as a list
Definition entry.h:194
Specifier virt
virtualness of the entry
Definition entry.h:191
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:593
#define Config_getBool(name)
Definition config.h:33
@ Function
Definition types.h:554
QCString removeRedundantWhiteSpace(const QCString &s)
Definition util.cpp:576
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
Definition util.cpp:5809

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, Function, 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::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 581 of file doxygen.cpp.

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

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

3524{
3525 FileDef *fd = root->fileDef();
3526 enum MemberType type = root->section.isExportedInterface() ? MemberType::Interface : MemberType::Service;
3527 QCString fileName = root->fileName;
3528 if (fileName.isEmpty() && root->tagInfo())
3529 {
3530 fileName = root->tagInfo()->tagName;
3531 }
3532 auto md = createMemberDef(
3533 fileName, root->startLine, root->startColumn, root->type, rname,
3534 "", "", root->protection, root->virt, root->isStatic, Relationship::Member,
3535 type, ArgumentList(), root->argList, root->metaData);
3536 auto mmd = toMemberDefMutable(md.get());
3537 mmd->setTagInfo(root->tagInfo());
3538 mmd->setMemberClass(cd);
3539 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3540 mmd->setDocsForDefinition(false);
3541 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3542 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3543 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3544 mmd->setMemberSpecifiers(root->spec);
3545 mmd->setVhdlSpecifiers(root->vhdlSpec);
3546 mmd->setMemberGroupId(root->mGrpId);
3547 mmd->setTypeConstraints(root->typeConstr);
3548 mmd->setLanguage(root->lang);
3549 mmd->setBodyDef(fd);
3550 mmd->setFileDef(fd);
3551 mmd->addSectionsToDefinition(root->anchors);
3552 QCString const def = root->type + " " + rname;
3553 mmd->setDefinition(def);
3555 mmd->addQualifiers(root->qualifiers);
3556
3557 AUTO_TRACE("Interface member: fileName='{}' type='{}' name='{}' mtype='{}' prot={} virt={} state={} proto={} def='{}'",
3558 fileName,root->type,rname,type,root->protection,root->virt,root->isStatic,root->proto,def);
3559
3560 // add member to the class cd
3561 cd->insertMember(md.get());
3562 // also add the member as a "base" (to get nicer diagrams)
3563 // "optional" interface/service get Protected which turns into dashed line
3564 BaseInfo base(rname,
3565 root->spec.isOptional() ? Protection::Protected : Protection::Public, Specifier::Normal);
3566 TemplateNameMap templateNames;
3567 findClassRelation(root,cd,cd,&base,templateNames,DocumentedOnly,true) ||
3568 findClassRelation(root,cd,cd,&base,templateNames,Undocumented,true);
3569 // add file to list of used files
3570 cd->insertUsedFile(fd);
3571
3572 addMemberToGroups(root,md.get());
3574 root->markAsProcessed();
3575 mmd->setRefItems(root->sli);
3576
3577 // add member to the global list of all members
3578 MemberName *mn = Doxygen::memberNameLinkedMap->add(rname);
3579 mn->push_back(std::move(md));
3580}
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:4843
This class stores information about an inheritance relation.
Definition entry.h:90
MemberType
Definition types.h:552
@ Interface
Definition types.h:565
@ Service
Definition types.h:566

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(), Interface, QCString::isEmpty(), Entry::isStatic, Entry::lang, Entry::markAsProcessed(), Doxygen::memberNameLinkedMap, Entry::metaData, Entry::mGrpId, Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, Entry::section, Service, 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 5440 of file doxygen.cpp.

5441{
5442 AUTO_TRACE();
5443 for (const auto &cd : *Doxygen::classLinkedMap)
5444 {
5445 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5446 if (cdm)
5447 {
5448 cdm->addListReferences();
5449 }
5450 }
5451
5452 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5453 {
5454 for (const auto &fd : *fn)
5455 {
5456 fd->addListReferences();
5457 }
5458 }
5459
5460 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5461 {
5463 if (ndm)
5464 {
5465 ndm->addListReferences();
5466 }
5467 }
5468
5469 for (const auto &gd : *Doxygen::groupLinkedMap)
5470 {
5471 gd->addListReferences();
5472 }
5473
5474 for (const auto &pd : *Doxygen::pageLinkedMap)
5475 {
5476 QCString name = pd->getOutputFileBase();
5477 if (pd->getGroupDef())
5478 {
5479 name = pd->getGroupDef()->getOutputFileBase();
5480 }
5481 {
5482 const RefItemVector &xrefItems = pd->xrefListItems();
5483 addRefItem(xrefItems,
5484 name,
5485 theTranslator->trPage(TRUE,TRUE),
5486 name,pd->title(),QCString(),nullptr);
5487 }
5488 }
5489
5490 for (const auto &dd : *Doxygen::dirLinkedMap)
5491 {
5492 QCString name = dd->getOutputFileBase();
5493 //if (dd->getGroupDef())
5494 //{
5495 // name = dd->getGroupDef()->getOutputFileBase();
5496 //}
5497 const RefItemVector &xrefItems = dd->xrefListItems();
5498 addRefItem(xrefItems,
5499 name,
5500 theTranslator->trDir(TRUE,TRUE),
5501 name,dd->displayName(),QCString(),nullptr);
5502 }
5503
5505}
virtual void addListReferences()=0
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:100
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:129
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:114
void addListReferences()
virtual void addListReferences()=0
Translator * theTranslator
Definition language.cpp:71
std::vector< RefItem * > RefItemVector
Definition reflist.h:133
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:4726

References ClassDefMutable::addListReferences(), ModuleManager::addListReferences(), NamespaceDefMutable::addListReferences(), addRefItem(), AUTO_TRACE, Doxygen::classLinkedMap, Doxygen::dirLinkedMap, Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, theTranslator, toClassDefMutable(), toNamespaceDefMutable(), and TRUE.

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

6082{
6083 AUTO_TRACE();
6084 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
6085 ClassDefMutable *cd=nullptr;
6086 if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClassMutable(scopeName)))
6087 {
6088 AUTO_TRACE_ADD("Local objective C method '{}' scopeName='{}'",root->name,scopeName);
6089 auto md = createMemberDef(
6090 root->fileName,root->startLine,root->startColumn,
6091 funcType,funcName,funcArgs,exceptions,
6092 root->protection,root->virt,root->isStatic,Relationship::Member,
6094 auto mmd = toMemberDefMutable(md.get());
6095 mmd->setTagInfo(root->tagInfo());
6096 mmd->setLanguage(root->lang);
6097 mmd->setId(root->id);
6098 mmd->makeImplementationDetail();
6099 mmd->setMemberClass(cd);
6100 mmd->setDefinition(funcDecl);
6102 mmd->addQualifiers(root->qualifiers);
6103 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6104 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6105 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6106 mmd->setDocsForDefinition(!root->proto);
6107 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6108 mmd->addSectionsToDefinition(root->anchors);
6109 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6110 FileDef *fd=root->fileDef();
6111 mmd->setBodyDef(fd);
6112 mmd->setMemberSpecifiers(spec);
6113 mmd->setVhdlSpecifiers(root->vhdlSpec);
6114 mmd->setMemberGroupId(root->mGrpId);
6115 cd->insertMember(md.get());
6116 cd->insertUsedFile(fd);
6117 mmd->setRefItems(root->sli);
6118
6120 mn->push_back(std::move(md));
6121 }
6122 else
6123 {
6124 // local objective C method found for class without interface
6125 }
6126}

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, Function, 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, 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 5523 of file doxygen.cpp.

5529{
5530 if (md==nullptr) return;
5531 AUTO_TRACE("scope='{}' name='{}' args='{}' funcDecl='{}' mSpec={}",
5532 root->parent()->name,md->name(),md->argsString(),funcDecl,spec);
5533 if (!root->section.isDoc()) // @fn or @var does not need to specify the complete definition, so don't overwrite it
5534 {
5535 QCString fDecl=funcDecl;
5536 // strip extern specifier
5537 fDecl.stripPrefix("extern ");
5538 md->setDefinition(fDecl);
5539 }
5541 md->addQualifiers(root->qualifiers);
5543 const NamespaceDef *nd=md->getNamespaceDef();
5544 QCString fullName;
5545 if (cd)
5546 fullName = cd->name();
5547 else if (nd)
5548 fullName = nd->name();
5549
5550 if (!fullName.isEmpty()) fullName+="::";
5551 fullName+=md->name();
5552 FileDef *rfd=root->fileDef();
5553
5554 // TODO determine scope based on root not md
5555 Definition *rscope = md->getOuterScope();
5556
5557 const ArgumentList &mdAl = md->argumentList();
5558 if (al)
5559 {
5560 ArgumentList mergedAl = *al;
5561 //printf("merging arguments (1) docs=%d\n",root->doc.isEmpty());
5562 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedAl,!root->doc.isEmpty());
5563 }
5564 else
5565 {
5566 if (
5567 matchArguments2( md->getOuterScope(), md->getFileDef(),const_cast<ArgumentList*>(&mdAl),
5568 rscope,rfd,&root->argList,
5569 TRUE, root->lang
5570 )
5571 )
5572 {
5573 //printf("merging arguments (2)\n");
5574 ArgumentList mergedArgList = root->argList;
5575 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.isEmpty());
5576 }
5577 }
5578 if (over_load) // the \overload keyword was used
5579 {
5581 if (!root->doc.isEmpty())
5582 {
5583 doc+="<p>";
5584 doc+=root->doc;
5585 }
5586 md->setDocumentation(doc,root->docFile,root->docLine);
5588 md->setDocsForDefinition(!root->proto);
5589 }
5590 else
5591 {
5592 //printf("overwrite!\n");
5593 md->setDocumentation(root->doc,root->docFile,root->docLine);
5594 md->setDocsForDefinition(!root->proto);
5595
5596 //printf("overwrite!\n");
5597 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
5598
5599 if (
5600 (md->inbodyDocumentation().isEmpty() ||
5601 !root->parent()->name.isEmpty()
5602 ) && !root->inbodyDocs.isEmpty()
5603 )
5604 {
5606 }
5607 }
5608
5609 //printf("initializer: '%s'(isEmpty=%d) '%s'(isEmpty=%d)\n",
5610 // qPrint(md->initializer()),md->initializer().isEmpty(),
5611 // qPrint(root->initializer),root->initializer.isEmpty()
5612 // );
5613 std::string rootInit = root->initializer.str();
5614 if (md->initializer().isEmpty() && !rootInit.empty())
5615 {
5616 //printf("setInitializer\n");
5617 md->setInitializer(rootInit);
5618 }
5619 if (md->requiresClause().isEmpty() && !root->req.isEmpty())
5620 {
5621 md->setRequiresClause(root->req);
5622 }
5623
5624 md->setMaxInitLines(root->initLines);
5625
5626 if (rfd)
5627 {
5628 if ((md->getStartBodyLine()==-1 && root->bodyLine!=-1)
5629 )
5630 {
5631 //printf("Setting new body segment [%d,%d]\n",root->bodyLine,root->endBodyLine);
5632 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
5633 md->setBodyDef(rfd);
5634 }
5635
5636 md->setRefItems(root->sli);
5637 }
5638
5640 md->addQualifiers(root->qualifiers);
5641
5642 md->mergeMemberSpecifiers(spec);
5644 addMemberToGroups(root,md);
5646 if (cd) cd->insertUsedFile(rfd);
5647 //printf("root->mGrpId=%d\n",root->mGrpId);
5648 if (root->mGrpId!=-1)
5649 {
5650 if (md->getMemberGroupId()!=-1)
5651 {
5652 if (md->getMemberGroupId()!=root->mGrpId)
5653 {
5654 warn(root->fileName,root->startLine,
5655 "member {} belongs to two different groups. The second one found here will be ignored.",
5656 md->name()
5657 );
5658 }
5659 }
5660 else // set group id
5661 {
5662 //printf("setMemberGroupId=%d md=%s\n",root->mGrpId,qPrint(md->name()));
5663 md->setMemberGroupId(root->mGrpId);
5664 }
5665 }
5666 md->addQualifiers(root->qualifiers);
5667}
bool isDoc() const
Definition types.h:804
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:213
bool matchArguments2(const Definition *srcScope, const FileDef *srcFileScope, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
Definition util.cpp:1956
void mergeArguments(ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
Definition util.cpp:2050
QCString getOverloadDocs()
Definition util.cpp:4010

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::section, DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), MemberDefMutable::setDefinition(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setInitializer(), MemberDefMutable::setMaxInitLines(), MemberDefMutable::setMemberGroupId(), DefinitionMutable::setRefItems(), MemberDefMutable::setRequiresClause(), Entry::sli, Entry::startLine, TextStream::str(), QCString::stripPrefix(), TRUE, 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 6130 of file doxygen.cpp.

6148{
6149 AUTO_TRACE();
6150 QCString funcType = funcTyp;
6151 int count=0;
6152 int noMatchCount=0;
6153 bool memFound=FALSE;
6154 for (const auto &imd : *mn)
6155 {
6156 MemberDefMutable *md = toMemberDefMutable(imd.get());
6157 if (md==nullptr) continue;
6159 if (cd==nullptr) continue;
6160 //AUTO_TRACE_ADD("member definition found, scope needed='{}' scope='{}' args='{}' fileName='{}'",
6161 // scopeName, cd->name(), md->argsString(), root->fileName);
6162 FileDef *fd=root->fileDef();
6163 NamespaceDef *nd=nullptr;
6164 if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName);
6165
6166 //printf("scopeName %s->%s\n",qPrint(scopeName),
6167 // qPrint(stripTemplateSpecifiersFromScope(scopeName,FALSE)));
6168
6169 // if the member we are searching for is an enum value that is part of
6170 // a "strong" enum, we need to look into the fields of the enum for a match
6171 int enumNamePos=0;
6172 if (md->isEnumValue() && (enumNamePos=className.findRev("::"))!=-1)
6173 {
6174 QCString enumName = className.mid(enumNamePos+2);
6175 QCString fullScope = className.left(enumNamePos);
6176 if (!namespaceName.isEmpty()) fullScope.prepend(namespaceName+"::");
6177 if (fullScope==cd->name())
6178 {
6179 MemberName *enumMn=Doxygen::memberNameLinkedMap->find(enumName);
6180 //printf("enumMn(%s)=%p\n",qPrint(className),(void*)enumMn);
6181 if (enumMn)
6182 {
6183 for (const auto &emd : *enumMn)
6184 {
6185 memFound = emd->isStrong() && md->getEnumScope()==emd.get();
6186 if (memFound)
6187 {
6188 addMemberDocs(root,md,funcDecl,nullptr,overloaded,spec);
6189 count++;
6190 }
6191 if (memFound) break;
6192 }
6193 }
6194 }
6195 }
6196 if (memFound) break;
6197
6198 const ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
6199 if (tcd==nullptr && cd && stripAnonymousNamespaceScope(cd->name())==scopeName)
6200 {
6201 // don't be fooled by anonymous scopes
6202 tcd=cd;
6203 }
6204 //printf("Looking for %s inside nd=%s result=%s cd=%s\n",
6205 // qPrint(scopeName),nd?qPrint(nd->name()):"<none>",tcd?qPrint(tcd->name()):"",qPrint(cd->name()));
6206
6207 if (cd && tcd==cd) // member's classes match
6208 {
6209 AUTO_TRACE_ADD("class definition '{}' found",cd->name());
6210
6211 // get the template parameter lists found at the member declaration
6212 ArgumentLists declTemplArgs = cd->getTemplateParameterLists();
6213 const ArgumentList &templAl = md->templateArguments();
6214 if (!templAl.empty())
6215 {
6216 declTemplArgs.push_back(templAl);
6217 }
6218
6219 // get the template parameter lists found at the member definition
6220 const ArgumentLists &defTemplArgs = root->tArgLists;
6221 //printf("defTemplArgs=%p\n",defTemplArgs);
6222
6223 // do we replace the decl argument lists with the def argument lists?
6224 bool substDone=FALSE;
6225 ArgumentList argList;
6226
6227 /* substitute the occurrences of class template names in the
6228 * argument list before matching
6229 */
6230 const ArgumentList &mdAl = md->argumentList();
6231 if (declTemplArgs.size()>0 && declTemplArgs.size()==defTemplArgs.size())
6232 {
6233 /* the function definition has template arguments
6234 * and the class definition also has template arguments, so
6235 * we must substitute the template names of the class by that
6236 * of the function definition before matching.
6237 */
6238 substituteTemplatesInArgList(declTemplArgs,defTemplArgs,mdAl,argList);
6239
6240 substDone=TRUE;
6241 }
6242 else /* no template arguments, compare argument lists directly */
6243 {
6244 argList = mdAl;
6245 }
6246
6247 AUTO_TRACE_ADD("matching '{}'<=>'{}' className='{}' namespaceName='{}'",
6248 argListToString(argList,TRUE),argListToString(root->argList,TRUE),className,namespaceName);
6249
6250 bool matching=
6251 md->isVariable() || md->isTypedef() || // needed for function pointers
6253 md->getClassDef(),md->getFileDef(),&argList,
6254 cd,fd,&root->argList,
6255 TRUE,root->lang);
6256
6257 if (md->getLanguage()==SrcLangExt::ObjC && md->isVariable() && root->section.isFunction())
6258 {
6259 matching = FALSE; // don't match methods and attributes with the same name
6260 }
6261
6262 // for template member we also need to check the return type
6263 if (!md->templateArguments().empty() && !root->tArgLists.empty())
6264 {
6265 QCString memType = md->typeString();
6266 memType.stripPrefix("static "); // see bug700696
6268 className+"::",""); // see bug700693 & bug732594
6270 className+"::",""); // see bug758900
6271 AUTO_TRACE_ADD("Comparing return types '{}'<->'{}' #args {}<->{}",
6272 md->typeString(),funcType,md->templateArguments().size(),root->tArgLists.back().size());
6273 if (md->templateArguments().size()!=root->tArgLists.back().size() || memType!=funcType)
6274 {
6275 //printf(" ---> no matching\n");
6276 matching = FALSE;
6277 }
6278 }
6279 else if (defTemplArgs.size()>declTemplArgs.size())
6280 {
6281 AUTO_TRACE_ADD("Different number of template arguments {} vs {}",defTemplArgs.size(),declTemplArgs.size());
6282 // avoid matching a non-template function in a template class against a
6283 // template function with the same name and parameters, see issue #10184
6284 substDone = false;
6285 matching = false;
6286 }
6287 bool rootIsUserDoc = root->section.isMemberDoc();
6288 bool classIsTemplate = scopeIsTemplate(md->getClassDef());
6289 bool mdIsTemplate = md->templateArguments().hasParameters();
6290 bool classOrMdIsTemplate = mdIsTemplate || classIsTemplate;
6291 bool rootIsTemplate = !root->tArgLists.empty();
6292 //printf("classIsTemplate=%d mdIsTemplate=%d rootIsTemplate=%d\n",classIsTemplate,mdIsTemplate,rootIsTemplate);
6293 if (!rootIsUserDoc && // don't check out-of-line @fn references, see bug722457
6294 (mdIsTemplate || rootIsTemplate) && // either md or root is a template
6295 ((classOrMdIsTemplate && !rootIsTemplate) || (!classOrMdIsTemplate && rootIsTemplate))
6296 )
6297 {
6298 // Method with template return type does not match method without return type
6299 // even if the parameters are the same. See also bug709052
6300 AUTO_TRACE_ADD("Comparing return types: template v.s. non-template");
6301 matching = FALSE;
6302 }
6303
6304 AUTO_TRACE_ADD("Match results of matchArguments2='{}' substDone='{}'",matching,substDone);
6305
6306 if (substDone) // found a new argument list
6307 {
6308 if (matching) // replace member's argument list
6309 {
6311 md->moveArgumentList(std::make_unique<ArgumentList>(argList));
6312 }
6313 else // no match
6314 {
6315 if (!funcTempList.isEmpty() &&
6316 isSpecialization(declTemplArgs,defTemplArgs))
6317 {
6318 // check if we are dealing with a partial template
6319 // specialization. In this case we add it to the class
6320 // even though the member arguments do not match.
6321
6322 addMethodToClass(root,cd,type,md->name(),args,isFriend,
6323 md->protection(),md->isStatic(),md->virtualness(),spec,relates);
6324 return;
6325 }
6326 }
6327 }
6328 if (matching)
6329 {
6330 addMemberDocs(root,md,funcDecl,nullptr,overloaded,spec);
6331 count++;
6332 memFound=TRUE;
6333 }
6334 }
6335 else if (cd && cd!=tcd) // we did find a class with the same name as cd
6336 // but in a different namespace
6337 {
6338 noMatchCount++;
6339 }
6340
6341 if (memFound) break;
6342 }
6343 if (count==0 && root->parent() && root->parent()->section.isObjcImpl())
6344 {
6345 addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec);
6346 return;
6347 }
6348 if (count==0 && !(isFriend && funcType=="class"))
6349 {
6350 int candidates=0;
6351 const ClassDef *ecd = nullptr, *ucd = nullptr;
6352 MemberDef *emd = nullptr, *umd = nullptr;
6353 //printf("Assume template class\n");
6354 for (const auto &md : *mn)
6355 {
6356 MemberDef *cmd=md.get();
6358 ClassDefMutable *ccd=cdmdm ? cdmdm->getClassDefMutable() : nullptr;
6359 //printf("ccd->name()==%s className=%s\n",qPrint(ccd->name()),qPrint(className));
6360 if (ccd!=nullptr && rightScopeMatch(ccd->name(),className))
6361 {
6362 const ArgumentList &templAl = md->templateArguments();
6363 if (!root->tArgLists.empty() && !templAl.empty() &&
6364 root->tArgLists.back().size()<=templAl.size())
6365 {
6366 AUTO_TRACE_ADD("add template specialization");
6367 addMethodToClass(root,ccd,type,md->name(),args,isFriend,
6368 root->protection,root->isStatic,root->virt,spec,relates);
6369 return;
6370 }
6373 { // exact argument list match -> remember
6374 ucd = ecd = ccd;
6375 umd = emd = cmd;
6376 AUTO_TRACE_ADD("new candidate className='{}' scope='{}' args='{}': exact match",
6377 className,ccd->name(),md->argsString());
6378 }
6379 else // arguments do not match, but member name and scope do -> remember
6380 {
6381 ucd = ccd;
6382 umd = cmd;
6383 AUTO_TRACE_ADD("new candidate className='{}' scope='{}' args='{}': no match",
6384 className,ccd->name(),md->argsString());
6385 }
6386 candidates++;
6387 }
6388 }
6389 bool strictProtoMatching = Config_getBool(STRICT_PROTO_MATCHING);
6390 if (!strictProtoMatching)
6391 {
6392 if (candidates==1 && ucd && umd)
6393 {
6394 // we didn't find an actual match on argument lists, but there is only 1 member with this
6395 // name in the same scope, so that has to be the one.
6396 addMemberDocs(root,toMemberDefMutable(umd),funcDecl,nullptr,overloaded,spec);
6397 return;
6398 }
6399 else if (candidates>1 && ecd && emd)
6400 {
6401 // we didn't find a unique match using type resolution,
6402 // but one of the matches has the exact same signature so
6403 // we take that one.
6404 addMemberDocs(root,toMemberDefMutable(emd),funcDecl,nullptr,overloaded,spec);
6405 return;
6406 }
6407 }
6408
6409 QCString warnMsg = "no ";
6410 if (noMatchCount>1) warnMsg+="uniquely ";
6411 warnMsg+="matching class member found for \n";
6412
6413 for (const ArgumentList &al : root->tArgLists)
6414 {
6415 warnMsg+=" template ";
6416 warnMsg+=tempArgListToString(al,root->lang);
6417 warnMsg+='\n';
6418 }
6419
6420 QCString fullFuncDecl=funcDecl;
6421 if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE);
6422
6423 warnMsg+=" ";
6424 warnMsg+=fullFuncDecl;
6425
6426 if (candidates>0 || noMatchCount>=1)
6427 {
6428 warnMsg+="\nPossible candidates:";
6429
6430 NamespaceDef *nd=nullptr;
6431 if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName);
6432 FileDef *fd=root->fileDef();
6433
6434 for (const auto &md : *mn)
6435 {
6436 const ClassDef *cd=md->getClassDef();
6437 const ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
6438 if (tcd==nullptr && cd && stripAnonymousNamespaceScope(cd->name())==scopeName)
6439 {
6440 // don't be fooled by anonymous scopes
6441 tcd=cd;
6442 }
6443 if (cd!=nullptr && (rightScopeMatch(cd->name(),className) || (cd!=tcd)))
6444 {
6445 warnMsg+='\n';
6446 const ArgumentList &templAl = md->templateArguments();
6447 warnMsg+=" '";
6448 if (templAl.hasParameters())
6449 {
6450 warnMsg+="template ";
6451 warnMsg+=tempArgListToString(templAl,root->lang);
6452 warnMsg+='\n';
6453 warnMsg+=" ";
6454 }
6455 if (!md->typeString().isEmpty())
6456 {
6457 warnMsg+=md->typeString();
6458 warnMsg+=' ';
6459 }
6461 if (!qScope.isEmpty())
6462 warnMsg+=qScope+"::"+md->name();
6463 warnMsg+=md->argsString();
6464 warnMsg+="' " + warn_line(md->getDefFileName(),md->getDefLine());
6465 }
6466 }
6467 }
6468 warn(root->fileName,root->startLine,"{}",warnMsg);
6469 }
6470}
std::vector< ArgumentList > ArgumentLists
Definition arguments.h:145
bool hasParameters() const
Definition arguments.h:76
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 QCString typeString() const =0
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:5919
static void substituteTemplatesInArgList(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const ArgumentList &src, ArgumentList &dst)
Definition doxygen.cpp:6033
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:6077
static void addMemberDocs(const Entry *root, MemberDefMutable *md, const QCString &funcDecl, const ArgumentList *al, bool over_load, TypeSpecifier spec)
Definition doxygen.cpp:5523
static bool scopeIsTemplate(const Definition *d)
Definition doxygen.cpp:5935
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:3634
static const ClassDef * findClassDefinition(FileDef *fd, NamespaceDef *nd, const QCString &scopeName)
Definition doxygen.cpp:5673
QCString warn_line(const QCString &file, int line)
Definition message.cpp:215
NamespaceDef * getResolvedNamespace(const QCString &name)
QCString stripAnonymousNamespaceScope(const QCString &s)
Definition util.cpp:239
QCString tempArgListToString(const ArgumentList &al, SrcLangExt lang, bool includeDefault)
Definition util.cpp:1244
QCString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:1199
bool rightScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:879
QCString replaceAnonymousScopes(const QCString &s, const QCString &replacement)
Definition util.cpp:227

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::size(), Entry::startLine, stripAnonymousNamespaceScope(), QCString::stripPrefix(), stripTemplateSpecifiersFromScope(), substitute(), substituteTemplatesInArgList(), Entry::tArgLists, tempArgListToString(), MemberDef::templateArguments(), toMemberDefMutable(), TRUE, 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 6474 of file doxygen.cpp.

6484{
6485 AUTO_TRACE("funcType={} funcName={} funcArgs={} funcDecl={} spec={}",funcType,funcName,funcArgs,funcDecl,spec);
6486 MemberDef *declMd=nullptr;
6487 for (const auto &md : *mn)
6488 {
6489 if (md->getClassDef()==cd)
6490 {
6491 // TODO: we should probably also check for matching arguments
6492 declMd = md.get();
6493 break;
6494 }
6495 }
6497 ArgumentList tArgList;
6498 // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6499 auto md = createMemberDef(
6500 root->fileName,root->startLine,root->startColumn,
6501 funcType,funcName,funcArgs,exceptions,
6502 declMd ? declMd->protection() : root->protection,
6503 root->virt,root->isStatic,Relationship::Member,
6504 mtype,tArgList,root->argList,root->metaData);
6505 auto mmd = toMemberDefMutable(md.get());
6506 //printf("new specialized member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6507 mmd->setTagInfo(root->tagInfo());
6508 mmd->setLanguage(root->lang);
6509 mmd->setId(root->id);
6510 mmd->setMemberClass(cd);
6511 mmd->setTemplateSpecialization(TRUE);
6512 mmd->setTypeConstraints(root->typeConstr);
6513 mmd->setDefinition(funcDecl);
6515 mmd->addQualifiers(root->qualifiers);
6516 mmd->setDocumentation(root->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 mmd->setRefItems(root->sli);
6530
6531 mn->push_back(std::move(md));
6532}

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, Function, 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, 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 8097 of file doxygen.cpp.

8098{
8099 auto &index = Index::instance();
8100 // for each class member name
8101 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8102 {
8103 // for each member definition
8104 for (const auto &md : *mn)
8105 {
8106 index.addClassMemberNameToIndex(md.get());
8107 if (md->getModuleDef())
8108 {
8109 index.addModuleMemberNameToIndex(md.get());
8110 }
8111 }
8112 }
8113 // for each file/namespace function name
8114 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8115 {
8116 // for each member definition
8117 for (const auto &md : *mn)
8118 {
8119 if (md->getNamespaceDef())
8120 {
8121 index.addNamespaceMemberNameToIndex(md.get());
8122 }
8123 else
8124 {
8125 index.addFileMemberNameToIndex(md.get());
8126 }
8127 if (md->getModuleDef())
8128 {
8129 index.addModuleMemberNameToIndex(md.get());
8130 }
8131 }
8132 }
8133
8134 index.sortMemberIndexLists();
8135}
static Index & instance()
Definition index.cpp:106

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

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

◆ addMembersToMemberGroup()

void addMembersToMemberGroup ( )
static

Definition at line 9214 of file doxygen.cpp.

9215{
9216 // for each class
9217 for (const auto &cd : *Doxygen::classLinkedMap)
9218 {
9219 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9220 if (cdm)
9221 {
9223 }
9224 }
9225 // for each file
9226 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9227 {
9228 for (const auto &fd : *fn)
9229 {
9230 fd->addMembersToMemberGroup();
9231 }
9232 }
9233 // for each namespace
9234 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9235 {
9237 if (ndm)
9238 {
9240 }
9241 }
9242 // for each group
9243 for (const auto &gd : *Doxygen::groupLinkedMap)
9244 {
9245 gd->addMembersToMemberGroup();
9246 }
9248}
virtual void addMembersToMemberGroup()=0
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 3634 of file doxygen.cpp.

3640{
3641 FileDef *fd=root->fileDef();
3642
3643 QCString type = rtype;
3644 QCString args = rargs;
3645
3647 name.stripPrefix("::");
3648
3650 if (isFriend) mtype=MemberType::Friend;
3651 else if (root->mtype==MethodTypes::Signal) mtype=MemberType::Signal;
3652 else if (root->mtype==MethodTypes::Slot) mtype=MemberType::Slot;
3653 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType::DCOP;
3654
3655 // strip redundant template specifier for constructors
3656 int i = -1;
3657 int j = -1;
3658 if ((fd==nullptr || fd->getLanguage()==SrcLangExt::Cpp) &&
3659 !name.startsWith("operator ") && // not operator
3660 (i=name.find('<'))!=-1 && // containing <
3661 (j=name.find('>'))!=-1 && // or >
3662 (j!=i+2 || name.at(i+1)!='=') // but not the C++20 spaceship operator <=>
3663 )
3664 {
3665 name=name.left(i);
3666 }
3667
3668 QCString fileName = root->fileName;
3669 if (fileName.isEmpty() && root->tagInfo())
3670 {
3671 fileName = root->tagInfo()->tagName;
3672 }
3673
3674 //printf("root->name='%s; args='%s' root->argList='%s'\n",
3675 // qPrint(root->name),qPrint(args),qPrint(argListToString(root->argList))
3676 // );
3677
3678 // adding class member
3679 Relationship relationship = relates.isEmpty() ? Relationship::Member :
3680 root->relatesType==RelatesType::MemberOf ? Relationship::Foreign :
3681 Relationship::Related ;
3682 auto md = createMemberDef(
3683 fileName,root->startLine,root->startColumn,
3684 type,name,args,root->exception,
3685 protection,virt,
3686 stat && root->relatesType!=RelatesType::MemberOf,
3687 relationship,
3688 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
3689 root->argList, root->metaData);
3690 auto mmd = toMemberDefMutable(md.get());
3691 mmd->setTagInfo(root->tagInfo());
3692 mmd->setMemberClass(cd);
3693 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3694 mmd->setDocsForDefinition(!root->proto);
3695 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3696 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3697 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3698 mmd->setMemberSpecifiers(spec);
3699 mmd->setVhdlSpecifiers(root->vhdlSpec);
3700 mmd->setMemberGroupId(root->mGrpId);
3701 mmd->setTypeConstraints(root->typeConstr);
3702 mmd->setLanguage(root->lang);
3703 mmd->setRequiresClause(root->req);
3704 mmd->setId(root->id);
3705 mmd->setBodyDef(fd);
3706 mmd->setFileDef(fd);
3707 mmd->addSectionsToDefinition(root->anchors);
3708 QCString def;
3710 SrcLangExt lang = cd->getLanguage();
3711 QCString scopeSeparator=getLanguageSpecificSeparator(lang);
3712 if (scopeSeparator!="::")
3713 {
3714 qualScope = substitute(qualScope,"::",scopeSeparator);
3715 }
3716 if (lang==SrcLangExt::PHP)
3717 {
3718 // for PHP we use Class::method and Namespace\method
3719 scopeSeparator="::";
3720 }
3721// QCString optArgs = root->argList.empty() ? args : QCString();
3722 if (!relates.isEmpty() || isFriend || Config_getBool(HIDE_SCOPE_NAMES))
3723 {
3724 if (!type.isEmpty())
3725 {
3726 def=type+" "+name; //+optArgs;
3727 }
3728 else
3729 {
3730 def=name; //+optArgs;
3731 }
3732 }
3733 else
3734 {
3735 if (!type.isEmpty())
3736 {
3737 def=type+" "+qualScope+scopeSeparator+name; //+optArgs;
3738 }
3739 else
3740 {
3741 def=qualScope+scopeSeparator+name; //+optArgs;
3742 }
3743 }
3744 def.stripPrefix("friend ");
3745 mmd->setDefinition(def);
3747 mmd->addQualifiers(root->qualifiers);
3748
3749 AUTO_TRACE("function member: type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
3750 type, qualScope, rname, args, root->proto, def);
3751
3752 // add member to the class cd
3753 cd->insertMember(md.get());
3754 // add file to list of used files
3755 cd->insertUsedFile(fd);
3756
3757 addMemberToGroups(root,md.get());
3759 root->markAsProcessed();
3760 mmd->setRefItems(root->sli);
3761
3762 // add member to the global list of all members
3763 //printf("Adding member=%s class=%s\n",qPrint(md->name()),qPrint(cd->name()));
3765 mn->push_back(std::move(md));
3766}
MethodTypes mtype
signal, slot, (dcop) method, or property?
Definition entry.h:181
bool startsWith(const char *s) const
Definition qcstring.h:507
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(), DCOP, Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Entry::exception, Entry::fileDef(), Entry::fileName, QCString::find(), Friend, Function, 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, Signal, Entry::sli, Slot, 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 6536 of file doxygen.cpp.

6539{
6540 // for unique overloaded member we allow the class to be
6541 // omitted, this is to be Qt compatible. Using this should
6542 // however be avoided, because it is error prone
6543 bool sameClass=false;
6544 if (mn->size()>0)
6545 {
6546 // check if all members with the same name are also in the same class
6547 sameClass = std::equal(mn->begin()+1,mn->end(),mn->begin(),
6548 [](const auto &md1,const auto &md2)
6549 { return md1->getClassDef()->name()==md2->getClassDef()->name(); });
6550 }
6551 if (sameClass)
6552 {
6553 MemberDefMutable *mdm = toMemberDefMutable(mn->front().get());
6554 ClassDefMutable *cd = mdm ? mdm->getClassDefMutable() : nullptr;
6555 if (cd==nullptr) return;
6556
6558 if (root->mtype==MethodTypes::Signal) mtype=MemberType::Signal;
6559 else if (root->mtype==MethodTypes::Slot) mtype=MemberType::Slot;
6560 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType::DCOP;
6561
6562 // new overloaded member function
6563 std::unique_ptr<ArgumentList> tArgList =
6564 getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6565 //printf("new related member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6566 auto md = createMemberDef(
6567 root->fileName,root->startLine,root->startColumn,
6568 funcType,funcName,funcArgs,exceptions,
6569 root->protection,root->virt,root->isStatic,Relationship::Related,
6570 mtype,tArgList ? *tArgList : ArgumentList(),root->argList,root->metaData);
6571 auto mmd = toMemberDefMutable(md.get());
6572 mmd->setTagInfo(root->tagInfo());
6573 mmd->setLanguage(root->lang);
6574 mmd->setId(root->id);
6575 mmd->setTypeConstraints(root->typeConstr);
6576 mmd->setMemberClass(cd);
6577 mmd->setDefinition(funcDecl);
6579 mmd->addQualifiers(root->qualifiers);
6581 doc+="<p>";
6582 doc+=root->doc;
6583 mmd->setDocumentation(doc,root->docFile,root->docLine);
6584 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6585 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6586 mmd->setDocsForDefinition(!root->proto);
6587 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6588 mmd->addSectionsToDefinition(root->anchors);
6589 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6590 FileDef *fd=root->fileDef();
6591 mmd->setBodyDef(fd);
6592 mmd->setMemberSpecifiers(spec);
6593 mmd->setVhdlSpecifiers(root->vhdlSpec);
6594 mmd->setMemberGroupId(root->mGrpId);
6595 cd->insertMember(md.get());
6596 cd->insertUsedFile(fd);
6597 mmd->setRefItems(root->sli);
6598
6599 mn->push_back(std::move(md));
6600 }
6601}
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(), DCOP, Entry::doc, Entry::docFile, Entry::docLine, MemberName::end(), Entry::endBodyLine, Entry::fileDef(), Entry::fileName, MemberName::front(), Function, 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, DefinitionMutable::setBodyDef(), Signal, MemberName::size(), Entry::sli, Slot, 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 309 of file doxygen.cpp.

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

329{
330 GroupDef *gd=nullptr;
331 for (const Grouping &g : root->groups)
332 {
333 if (!g.groupname.isEmpty() && (gd=Doxygen::groupLinkedMap->find(g.groupname))) break;
334 }
335 //printf("---> addRelatedPage() %s gd=%p\n",qPrint(root->name),gd);
336 QCString doc=root->doc+root->inbodyDocs;
337
338 PageDef *pd = addRelatedPage(root->name,root->args,doc,
339 root->docFile,
340 root->docLine,
341 root->startLine,
342 root->sli,
343 gd,root->tagInfo(),
344 FALSE,
345 root->lang
346 );
347 if (pd)
348 {
349 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
351 pd->setLocalToc(root->localToc);
352 addPageToContext(pd,root);
353 }
354}
LocalToc localToc
Definition entry.h:232
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:328
static void addPageToContext(PageDef *pd, Entry *root)
Definition doxygen.cpp:309
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(), buildPageList(), CitationManager::generatePage(), and RefList::generatePage().

◆ addSourceReferences()

void addSourceReferences ( )
static

Definition at line 8732 of file doxygen.cpp.

8733{
8734 // add source references for class definitions
8735 for (const auto &cd : *Doxygen::classLinkedMap)
8736 {
8737 const FileDef *fd=cd->getBodyDef();
8738 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8739 {
8740 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8741 }
8742 }
8743 // add source references for concept definitions
8744 for (const auto &cd : *Doxygen::conceptLinkedMap)
8745 {
8746 const FileDef *fd=cd->getBodyDef();
8747 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8748 {
8749 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8750 }
8751 }
8752 // add source references for namespace definitions
8753 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8754 {
8755 const FileDef *fd=nd->getBodyDef();
8756 if (fd && nd->isLinkableInProject() && nd->getStartDefLine()!=-1)
8757 {
8758 const_cast<FileDef*>(fd)->addSourceRef(nd->getStartDefLine(),nd.get(),nullptr);
8759 }
8760 }
8761
8762 // add source references for member names
8763 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8764 {
8765 for (const auto &md : *mn)
8766 {
8767 //printf("class member %s: def=%s body=%d link?=%d\n",
8768 // qPrint(md->name()),
8769 // md->getBodyDef()?qPrint(md->getBodyDef()->name()):"<none>",
8770 // md->getStartBodyLine(),md->isLinkableInProject());
8771 const FileDef *fd=md->getBodyDef();
8772 if (fd &&
8773 md->getStartDefLine()!=-1 &&
8774 md->isLinkableInProject() &&
8776 )
8777 {
8778 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8779 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8780 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8781 }
8782 }
8783 }
8784 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8785 {
8786 for (const auto &md : *mn)
8787 {
8788 const FileDef *fd=md->getBodyDef();
8789 //printf("member %s body=[%d,%d] fd=%p link=%d parseSources=%d\n",
8790 // qPrint(md->name()),
8791 // md->getStartBodyLine(),md->getEndBodyLine(),fd,
8792 // md->isLinkableInProject(),
8793 // Doxygen::parseSourcesNeeded);
8794 if (fd &&
8795 md->getStartDefLine()!=-1 &&
8796 md->isLinkableInProject() &&
8798 )
8799 {
8800 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8801 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8802 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8803 }
8804 }
8805 }
8806}
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 8139 of file doxygen.cpp.

8140{
8141 for (const auto &cd : *Doxygen::classLinkedMap)
8142 {
8143 if (cd->isLinkableInProject())
8144 {
8145 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8146 if (Doxygen::searchIndex.enabled())
8147 {
8148 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
8149 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
8150 }
8151 }
8152 }
8153
8154 for (const auto &cd : *Doxygen::conceptLinkedMap)
8155 {
8156 if (cd->isLinkableInProject())
8157 {
8158 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8159 if (Doxygen::searchIndex.enabled())
8160 {
8161 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
8162 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
8163 }
8164 }
8165 }
8166
8167 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8168 {
8169 if (nd->isLinkableInProject())
8170 {
8171 Doxygen::indexList->addIndexItem(nd.get(),nullptr);
8172 if (Doxygen::searchIndex.enabled())
8173 {
8174 Doxygen::searchIndex.setCurrentDoc(nd.get(),nd->anchor(),FALSE);
8175 Doxygen::searchIndex.addWord(nd->localName(),TRUE);
8176 }
8177 }
8178 }
8179
8180 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8181 {
8182 for (const auto &fd : *fn)
8183 {
8184 if (Doxygen::searchIndex.enabled() && fd->isLinkableInProject())
8185 {
8186 Doxygen::searchIndex.setCurrentDoc(fd.get(),fd->anchor(),FALSE);
8187 Doxygen::searchIndex.addWord(fd->localName(),TRUE);
8188 }
8189 }
8190 }
8191
8192 auto addWordsForTitle = [](const Definition *d,const QCString &anchor,const QCString &title)
8193 {
8194 Doxygen::indexList->addIndexItem(d,nullptr,QCString(),filterTitle(title));
8195 if (Doxygen::searchIndex.enabled())
8196 {
8197 Doxygen::searchIndex.setCurrentDoc(d,anchor,false);
8198 std::string s = title.str();
8199 static const reg::Ex re(R"(\a[\w-]*)");
8200 reg::Iterator it(s,re);
8202 for (; it!=end ; ++it)
8203 {
8204 const auto &match = *it;
8205 std::string matchStr = match.str();
8206 Doxygen::searchIndex.addWord(matchStr,true);
8207 }
8208 }
8209 };
8210
8211 for (const auto &gd : *Doxygen::groupLinkedMap)
8212 {
8213 if (gd->isLinkableInProject())
8214 {
8215 addWordsForTitle(gd.get(),gd->anchor(),gd->groupTitle());
8216 }
8217 }
8218
8219 for (const auto &pd : *Doxygen::pageLinkedMap)
8220 {
8221 if (pd->isLinkableInProject())
8222 {
8223 addWordsForTitle(pd.get(),pd->anchor(),pd->title());
8224 }
8225 }
8226
8228 {
8229 addWordsForTitle(Doxygen::mainPage.get(),Doxygen::mainPage->anchor(),Doxygen::mainPage->title());
8230 }
8231
8232 auto addMemberToSearchIndex = [](const MemberDef *md)
8233 {
8234 if (Doxygen::searchIndex.enabled())
8235 {
8236 Doxygen::searchIndex.setCurrentDoc(md,md->anchor(),FALSE);
8237 QCString ln=md->localName();
8238 QCString qn=md->qualifiedName();
8239 Doxygen::searchIndex.addWord(ln,TRUE);
8240 if (ln!=qn)
8241 {
8242 Doxygen::searchIndex.addWord(qn,TRUE);
8243 if (md->getClassDef())
8244 {
8245 Doxygen::searchIndex.addWord(md->getClassDef()->displayName(),TRUE);
8246 }
8247 if (md->getNamespaceDef())
8248 {
8249 Doxygen::searchIndex.addWord(md->getNamespaceDef()->displayName(),TRUE);
8250 }
8251 }
8252 }
8253 };
8254
8255 auto getScope = [](const MemberDef *md)
8256 {
8257 const Definition *scope = nullptr;
8258 if (md->getGroupDef()) scope = md->getGroupDef();
8259 else if (md->getClassDef()) scope = md->getClassDef();
8260 else if (md->getNamespaceDef()) scope = md->getNamespaceDef();
8261 else if (md->getFileDef()) scope = md->getFileDef();
8262 return scope;
8263 };
8264
8265 auto addMemberToIndices = [addMemberToSearchIndex,getScope](const MemberDef *md)
8266 {
8267 if (md->isLinkableInProject())
8268 {
8269 if (!(md->isEnumerate() && md->isAnonymous()))
8270 {
8271 Doxygen::indexList->addIndexItem(getScope(md),md);
8273 }
8274 if (md->isEnumerate())
8275 {
8276 for (const auto &fmd : md->enumFieldList())
8277 {
8278 Doxygen::indexList->addIndexItem(getScope(fmd),fmd);
8280 }
8281 }
8282 }
8283 };
8284
8285 // for each class member name
8286 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8287 {
8288 // for each member definition
8289 for (const auto &md : *mn)
8290 {
8291 addMemberToIndices(md.get());
8292 }
8293 }
8294 // for each file/namespace function name
8295 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8296 {
8297 // for each member definition
8298 for (const auto &md : *mn)
8299 {
8300 addMemberToIndices(md.get());
8301 }
8302 }
8303}
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:101
static IndexList * indexList
Definition doxygen.h:134
static SearchIndexIntf searchIndex
Definition doxygen.h:124
Class representing a regular expression.
Definition regex.h:39
Class to iterate through matches.
Definition regex.h:232
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:759
static void addMemberToSearchIndex(const MemberDef *md)
QCString filterTitle(const QCString &title)
Definition util.cpp:5526

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

3098{
3099 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
3100
3101 AUTO_TRACE("VARIABLE_SEC: type='{}' name='{}' args='{}' bodyLine={} endBodyLine={} mGrpId={} relates='{}'",
3102 root->type, root->name, root->args, root->bodyLine, root->endBodyLine, root->mGrpId, root->relates);
3103 //printf("root->parent->name=%s\n",qPrint(root->parent->name));
3104
3105 QCString type = root->type;
3106 QCString name = root->name;
3107 QCString args = root->args;
3108 if (type.isEmpty() && name.find("operator")==-1 &&
3109 (name.find('*')!=-1 || name.find('&')!=-1))
3110 {
3111 // recover from parse error caused by redundant braces
3112 // like in "int *(var[10]);", which is parsed as
3113 // type="" name="int *" args="(var[10])"
3114
3115 type=name;
3116 std::string sargs = args.str();
3117 static const reg::Ex reName(R"(\a\w*)");
3119 if (reg::search(sargs,match,reName))
3120 {
3121 name = match.str(); // e.g. 'var' in '(var[10])'
3122 sargs = match.suffix().str(); // e.g. '[10]) in '(var[10])'
3123 size_t j = sargs.find(')');
3124 if (j!=std::string::npos) args=sargs.substr(0,j); // extract, e.g '[10]' from '[10])'
3125 }
3126 }
3127 else
3128 {
3129 int i=isFuncPtr;
3130 if (i==-1 && (root->spec.isAlias())==0) i=findFunctionPtr(type.str(),root->lang); // for typedefs isFuncPtr is not yet set
3131 AUTO_TRACE_ADD("functionPtr={}",i!=-1?"yes":"no");
3132 if (i>=0) // function pointer
3133 {
3134 int ai = type.find('[',i);
3135 if (ai>i) // function pointer array
3136 {
3137 args.prepend(type.right(type.length()-ai));
3138 type=type.left(ai);
3139 }
3140 else if (type.find(')',i)!=-1) // function ptr, not variable like "int (*bla)[10]"
3141 {
3142 type=type.left(type.length()-1);
3143 args.prepend(") ");
3144 }
3145 }
3146 }
3147 AUTO_TRACE_ADD("after correction: type='{}' name='{}' args='{}'",type,name,args);
3148
3149 QCString scope;
3150 name=removeRedundantWhiteSpace(name);
3151
3152 // find the scope of this variable
3153 int index = computeQualifiedIndex(name);
3154 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
3155 // grouped members are stored with full scope
3156 {
3157 buildScopeFromQualifiedName(name.left(index+2),root->lang,root->tagInfo());
3158 scope=name.left(index);
3159 name=name.mid(index+2);
3160 }
3161 else
3162 {
3163 Entry *p = root->parent();
3164 while (p->section.isScope())
3165 {
3166 QCString scopeName = p->name;
3167 if (!scopeName.isEmpty())
3168 {
3169 scope.prepend(scopeName);
3170 break;
3171 }
3172 p=p->parent();
3173 }
3174 }
3175
3176 type=type.stripWhiteSpace();
3177 ClassDefMutable *cd=nullptr;
3178 bool isRelated=FALSE;
3179 bool isMemberOf=FALSE;
3180
3181 QCString classScope=stripAnonymousNamespaceScope(scope);
3182 if (root->lang==SrcLangExt::CSharp)
3183 {
3184 classScope=mangleCSharpGenericName(classScope);
3185 }
3186 else
3187 {
3188 classScope=stripTemplateSpecifiersFromScope(classScope,FALSE);
3189 }
3190 QCString annScopePrefix=scope.left(scope.length()-classScope.length());
3191
3192
3193 // Look for last :: not part of template specifier
3194 int p=-1;
3195 for (size_t i=0;i<name.length()-1;i++)
3196 {
3197 if (name[i]==':' && name[i+1]==':')
3198 {
3199 p=static_cast<int>(i);
3200 }
3201 else if (name[i]=='<') // skip over template parts,
3202 // i.e. A::B<C::D> => p=1 and
3203 // A<B::C>::D => p=8
3204 {
3205 int e = findEndOfTemplate(name,i+1);
3206 if (e!=-1) i=static_cast<int>(e);
3207 }
3208 }
3209
3210 if (p!=-1) // found it
3211 {
3212 if (type=="friend class" || type=="friend struct" ||
3213 type=="friend union")
3214 {
3215 cd=getClassMutable(scope);
3216 if (cd)
3217 {
3218 addVariableToClass(root, // entry
3219 cd, // class to add member to
3220 MemberType::Friend, // type of member
3221 type, // type value as string
3222 name, // name of the member
3223 args, // arguments as string
3224 FALSE, // from Anonymous scope
3225 nullptr, // anonymous member
3226 Protection::Public, // protection
3227 Relationship::Member // related to a class
3228 );
3229 }
3230 }
3231 if (root->bodyLine!=-1 && root->endBodyLine!=-1) // store the body location for later use
3232 {
3233 Doxygen::staticInitMap.emplace(name.str(),BodyInfo{root->startLine,root->bodyLine,root->endBodyLine});
3234 }
3235
3236
3237 AUTO_TRACE_ADD("static variable {} body=[{}..{}]",name,root->bodyLine,root->endBodyLine);
3238 return; /* skip this member, because it is a
3239 * static variable definition (always?), which will be
3240 * found in a class scope as well, but then we know the
3241 * correct protection level, so only then it will be
3242 * inserted in the correct list!
3243 */
3244 }
3245
3247 if (type=="@")
3249 else if (type.startsWith("typedef "))
3250 mtype=MemberType::Typedef;
3251 else if (type.startsWith("friend "))
3252 mtype=MemberType::Friend;
3253 else if (root->mtype==MethodTypes::Property)
3255 else if (root->mtype==MethodTypes::Event)
3256 mtype=MemberType::Event;
3257 else if (type.find("sequence<") != -1)
3258 mtype=sliceOpt ? MemberType::Sequence : MemberType::Typedef;
3259 else if (type.find("dictionary<") != -1)
3261
3262 if (!root->relates.isEmpty()) // related variable
3263 {
3264 isRelated=TRUE;
3265 isMemberOf=(root->relatesType==RelatesType::MemberOf);
3266 if (getClass(root->relates)==nullptr && !scope.isEmpty())
3267 scope=mergeScopes(scope,root->relates);
3268 else
3269 scope=root->relates;
3270 }
3271
3272 cd=getClassMutable(scope);
3273 if (cd==nullptr && classScope!=scope) cd=getClassMutable(classScope);
3274 if (cd)
3275 {
3276 MemberDef *md=nullptr;
3277
3278 // if cd is an anonymous (=tag less) scope we insert the member
3279 // into a non-anonymous parent scope as well. This is needed to
3280 // be able to refer to it using \var or \fn
3281
3282 //int indentDepth=0;
3283 int si=scope.find('@');
3284 //int anonyScopes = 0;
3285 //bool added=FALSE;
3286
3287 bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS);
3288 Relationship relationship = isMemberOf ? Relationship::Foreign :
3289 isRelated ? Relationship::Related :
3290 Relationship::Member ;
3291 if (si!=-1 && !inlineSimpleStructs) // anonymous scope or type
3292 {
3293 QCString pScope;
3294 ClassDefMutable *pcd=nullptr;
3295 pScope = scope.left(std::max(si-2,0)); // scope without tag less parts
3296 if (!pScope.isEmpty())
3297 pScope.prepend(annScopePrefix);
3298 else if (annScopePrefix.length()>2)
3299 pScope=annScopePrefix.left(annScopePrefix.length()-2);
3300 if (name.at(0)!='@')
3301 {
3302 if (!pScope.isEmpty() && (pcd=getClassMutable(pScope)))
3303 {
3304 AUTO_TRACE_ADD("Adding anonymous member to scope '{}'",pScope);
3305 md=addVariableToClass(root, // entry
3306 pcd, // class to add member to
3307 mtype, // member type
3308 type, // type value as string
3309 name, // member name
3310 args, // arguments as string
3311 TRUE, // from anonymous scope
3312 nullptr, // from anonymous member
3313 root->protection,
3314 relationship
3315 );
3316 //added=TRUE;
3317 }
3318 else // anonymous scope inside namespace or file => put variable in the global scope
3319 {
3320 if (mtype==MemberType::Variable)
3321 {
3322 AUTO_TRACE_ADD("Adding anonymous member to global scope '{}'");
3323 md=addVariableToFile(root,mtype,pScope,type,name,args,TRUE,nullptr);
3324 }
3325 //added=TRUE;
3326 }
3327 }
3328 }
3329
3330 addVariableToClass(root, // entry
3331 cd, // class to add member to
3332 mtype, // member type
3333 type, // type value as string
3334 name, // name of the member
3335 args, // arguments as string
3336 FALSE, // from anonymous scope
3337 md, // from anonymous member
3338 root->protection,
3339 relationship
3340 );
3341 }
3342 else if (!name.isEmpty()) // global variable
3343 {
3344 addVariableToFile(root,mtype,scope,type,name,args,FALSE,/*nullptr,*/nullptr);
3345 }
3346
3347}
static StaticInitMap staticInitMap
Definition doxygen.h:143
Represents an unstructured piece of information, about an entity found in the sources.
Definition entry.h:116
const std::string & str() const
Definition qcstring.h:552
ClassDef * getClass(const QCString &n)
Object representing the matching results.
Definition regex.h:153
static int findEndOfTemplate(const QCString &s, size_t startPos)
Definition doxygen.cpp:3029
static int findFunctionPtr(const std::string &type, SrcLangExt lang, int *pLength=nullptr)
Definition doxygen.cpp:2825
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:2425
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:2585
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:748
Data associated with description found in the body.
Definition definition.h:63
@ Dictionary
Definition types.h:568
@ Sequence
Definition types.h:567
@ Variable
Definition types.h:555
@ Property
Definition types.h:563
@ Typedef
Definition types.h:556
int computeQualifiedIndex(const QCString &name)
Return the index of the last :: in the string name that is still before the first <.
Definition util.cpp:6734

References addVariableToClass(), addVariableToFile(), Entry::args, QCString::at(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, buildScopeFromQualifiedName(), computeQualifiedIndex(), Config_getBool, Dictionary, Entry::endBodyLine, EnumValue, Event, FALSE, QCString::find(), findEndOfTemplate(), findFunctionPtr(), Friend, 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(), Property, Entry::protection, Entry::relates, Entry::relatesType, removeRedundantWhiteSpace(), QCString::right(), reg::search(), Entry::section, Sequence, Entry::spec, QCString::startsWith(), Doxygen::staticInitMap, QCString::str(), stripAnonymousNamespaceScope(), stripTemplateSpecifiersFromScope(), QCString::stripWhiteSpace(), Entry::tagInfo(), TRUE, Entry::type, Typedef, and Variable.

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

2436{
2438 QCString scopeSeparator="::";
2439 SrcLangExt lang = cd->getLanguage();
2440 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
2441 {
2442 qualScope = substitute(qualScope,"::",".");
2443 scopeSeparator=".";
2444 }
2445 AUTO_TRACE("class variable: file='{}' type='{}' scope='{}' name='{}' args='{}' prot={} mtype={} lang={} ann={} init='{}'",
2446 root->fileName, type, qualScope, name, args, root->protection, mtype, lang, fromAnnScope, root->initializer.str());
2447
2448 QCString def;
2449 if (!type.isEmpty())
2450 {
2451 if (related!=Relationship::Member || mtype==MemberType::Friend || Config_getBool(HIDE_SCOPE_NAMES))
2452 {
2453 if (root->spec.isAlias()) // turn 'typedef B A' into 'using A'
2454 {
2455 def="using "+name;
2456 }
2457 else
2458 {
2459 def=type+" "+name+args;
2460 }
2461 }
2462 else
2463 {
2464 if (root->spec.isAlias()) // turn 'typedef B C::A' into 'using C::A'
2465 {
2466 def="using "+qualScope+scopeSeparator+name;
2467 }
2468 else
2469 {
2470 def=type+" "+qualScope+scopeSeparator+name+args;
2471 }
2472 }
2473 }
2474 else
2475 {
2476 if (Config_getBool(HIDE_SCOPE_NAMES))
2477 {
2478 def=name+args;
2479 }
2480 else
2481 {
2482 def=qualScope+scopeSeparator+name+args;
2483 }
2484 }
2485 def.stripPrefix("static ");
2486
2487 // see if the member is already found in the same scope
2488 // (this may be the case for a static member that is initialized
2489 // outside the class)
2491 if (mn)
2492 {
2493 for (const auto &imd : *mn)
2494 {
2495 //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n",
2496 // md->getClassDef(),cd,qPrint(type),md->typeString());
2497 MemberDefMutable *md = toMemberDefMutable(imd.get());
2498 if (md &&
2499 md->getClassDef()==cd &&
2500 ((lang==SrcLangExt::Python && type.isEmpty() && !md->typeString().isEmpty()) ||
2502 // member already in the scope
2503 {
2504
2505 if (root->lang==SrcLangExt::ObjC &&
2506 root->mtype==MethodTypes::Property &&
2508 { // Objective-C 2.0 property
2509 // turn variable into a property
2510 md->setProtection(root->protection);
2512 }
2513 addMemberDocs(root,md,def,nullptr,FALSE,root->spec);
2514 AUTO_TRACE_ADD("Member already found!");
2515 return md;
2516 }
2517 }
2518 }
2519
2520 QCString fileName = root->fileName;
2521 if (fileName.isEmpty() && root->tagInfo())
2522 {
2523 fileName = root->tagInfo()->tagName;
2524 }
2525
2526 // new member variable, typedef or enum value
2527 auto md = createMemberDef(
2528 fileName,root->startLine,root->startColumn,
2529 type,name,args,root->exception,
2530 prot,Specifier::Normal,root->isStatic,related,
2531 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
2532 ArgumentList(), root->metaData);
2533 auto mmd = toMemberDefMutable(md.get());
2534 mmd->setTagInfo(root->tagInfo());
2535 mmd->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope())
2536 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
2537 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2538 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2539 mmd->setDefinition(def);
2540 mmd->setBitfields(root->bitfields);
2541 mmd->addSectionsToDefinition(root->anchors);
2542 mmd->setFromAnonymousScope(fromAnnScope);
2543 mmd->setFromAnonymousMember(fromAnnMemb);
2544 //md->setIndentDepth(indentDepth);
2545 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2546 mmd->setInitializer(root->initializer.str());
2547 mmd->setMaxInitLines(root->initLines);
2548 mmd->setMemberGroupId(root->mGrpId);
2549 mmd->setMemberSpecifiers(root->spec);
2550 mmd->setVhdlSpecifiers(root->vhdlSpec);
2551 mmd->setReadAccessor(root->read);
2552 mmd->setWriteAccessor(root->write);
2554 mmd->setHidden(root->hidden);
2555 mmd->setArtificial(root->artificial);
2556 mmd->setLanguage(root->lang);
2557 mmd->setId(root->id);
2558 addMemberToGroups(root,md.get());
2560 mmd->setBodyDef(root->fileDef());
2561 mmd->addQualifiers(root->qualifiers);
2562
2563 AUTO_TRACE_ADD("Adding new member to class '{}'",cd->name());
2564 cd->insertMember(md.get());
2565 mmd->setRefItems(root->sli);
2566
2567 cd->insertUsedFile(root->fileDef());
2568 root->markAsProcessed();
2569
2570 if (mtype==MemberType::Typedef)
2571 {
2572 resolveTemplateInstanceInType(root,cd,md.get());
2573 }
2574
2575 // add the member to the global list
2576 MemberDef *result = md.get();
2577 mn = Doxygen::memberNameLinkedMap->add(name);
2578 mn->push_back(std::move(md));
2579
2580 return result;
2581}
virtual void reclassifyMember(MemberDefMutable *md, MemberType t)=0
QCString bitfields
member's bit fields
Definition entry.h:193
QCString write
property write accessor
Definition entry.h:212
QCString read
property read accessor
Definition entry.h:211
virtual MemberType memberType() const =0
virtual void setProtection(Protection p)=0
static void resolveTemplateInstanceInType(const Entry *root, const Definition *scope, const MemberDef *md)
Definition doxygen.cpp:4771

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, Friend, 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(), Property, Entry::protection, MemberName::push_back(), ClassDef::qualifiedNameWithTemplateParameters(), Entry::qualifiers, Entry::read, ClassDefMutable::reclassifyMember(), removeRedundantWhiteSpace(), resolveTemplateInstanceInType(), MemberDefMutable::setProtection(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, TextStream::str(), QCString::stripPrefix(), substitute(), Entry::tagInfo(), TagInfo::tagName, Entry::tArgLists, toMemberDefMutable(), Typedef, MemberDef::typeString(), Variable, 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 2585 of file doxygen.cpp.

2594{
2595 AUTO_TRACE("global variable: file='{}' type='{}' scope='{}' name='{}' args='{}' prot={} mtype={} lang={} init='{}'",
2596 root->fileName, type, scope, name, args, root->protection, mtype, root->lang, root->initializer.str());
2597
2598 FileDef *fd = root->fileDef();
2599
2600 // see if we have a typedef that should hide a struct or union
2601 if (mtype==MemberType::Typedef && Config_getBool(TYPEDEF_HIDES_STRUCT))
2602 {
2603 QCString ttype = type;
2604 ttype.stripPrefix("typedef ");
2605 if (ttype.stripPrefix("struct ") || ttype.stripPrefix("union "))
2606 {
2607 static const reg::Ex re(R"(\a\w*)");
2609 std::string typ = ttype.str();
2610 if (reg::search(typ,match,re))
2611 {
2612 QCString typeValue = match.str();
2613 ClassDefMutable *cd = getClassMutable(typeValue);
2614 if (cd)
2615 {
2616 // this typedef should hide compound name cd, so we
2617 // change the name that is displayed from cd.
2618 cd->setClassName(name);
2619 cd->setDocumentation(root->doc,root->docFile,root->docLine);
2620 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2621 return nullptr;
2622 }
2623 }
2624 }
2625 }
2626
2627 // see if the function is inside a namespace
2628 NamespaceDefMutable *nd = nullptr;
2629 if (!scope.isEmpty())
2630 {
2631 if (scope.find('@')!=-1) return nullptr; // anonymous scope!
2632 nd = getResolvedNamespaceMutable(scope);
2633 }
2634 QCString def;
2635
2636 // determine the definition of the global variable
2637 if (nd && !nd->isAnonymous() &&
2638 !Config_getBool(HIDE_SCOPE_NAMES)
2639 )
2640 // variable is inside a namespace, so put the scope before the name
2641 {
2642 SrcLangExt lang = nd->getLanguage();
2644
2645 if (!type.isEmpty())
2646 {
2647 if (root->spec.isAlias()) // turn 'typedef B NS::A' into 'using NS::A'
2648 {
2649 def="using "+nd->name()+sep+name;
2650 }
2651 else // normal member
2652 {
2653 def=type+" "+nd->name()+sep+name+args;
2654 }
2655 }
2656 else
2657 {
2658 def=nd->name()+sep+name+args;
2659 }
2660 }
2661 else
2662 {
2663 if (!type.isEmpty() && !root->name.isEmpty())
2664 {
2665 if (name.at(0)=='@') // dummy variable representing anonymous union
2666 {
2667 def=type;
2668 }
2669 else
2670 {
2671 if (root->spec.isAlias()) // turn 'typedef B A' into 'using A'
2672 {
2673 def="using "+root->name;
2674 }
2675 else // normal member
2676 {
2677 def=type+" "+name+args;
2678 }
2679 }
2680 }
2681 else
2682 {
2683 def=name+args;
2684 }
2685 }
2686 def.stripPrefix("static ");
2687
2689 if (mn)
2690 {
2691 //QCString nscope=removeAnonymousScopes(scope);
2692 //NamespaceDef *nd=nullptr;
2693 //if (!nscope.isEmpty())
2694 if (!scope.isEmpty())
2695 {
2696 nd = getResolvedNamespaceMutable(scope);
2697 }
2698 for (const auto &imd : *mn)
2699 {
2700 MemberDefMutable *md = toMemberDefMutable(imd.get());
2701 if (md &&
2702 ((nd==nullptr && md->getNamespaceDef()==nullptr && md->getFileDef() &&
2703 root->fileName==md->getFileDef()->absFilePath()
2704 ) // both variable names in the same file
2705 || (nd!=nullptr && md->getNamespaceDef()==nd) // both in same namespace
2706 )
2707 && !md->isDefine() // function style #define's can be "overloaded" by typedefs or variables
2708 && !md->isEnumerate() // in C# an enum value and enum can have the same name
2709 )
2710 // variable already in the scope
2711 {
2712 bool isPHPArray = md->getLanguage()==SrcLangExt::PHP &&
2713 md->argsString()!=args &&
2714 args.find('[')!=-1;
2715 bool staticsInDifferentFiles =
2716 root->isStatic && md->isStatic() &&
2717 root->fileName!=md->getDefFileName();
2718
2719 if (md->getFileDef() &&
2720 !isPHPArray && // not a php array
2721 !staticsInDifferentFiles
2722 )
2723 // not a php array variable
2724 {
2725 AUTO_TRACE_ADD("variable already found: scope='{}'",md->getOuterScope()->name());
2726 addMemberDocs(root,md,def,nullptr,FALSE,root->spec);
2727 md->setRefItems(root->sli);
2728 // if md is a variable forward declaration and root is the definition that
2729 // turn md into the definition
2730 if (!root->explicitExternal && md->isExternal())
2731 {
2732 md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn());
2734 }
2735 // if md is the definition and root point at a declaration, then add the
2736 // declaration info
2737 else if (root->explicitExternal && !md->isExternal())
2738 {
2739 md->setDeclFile(root->fileName,root->startLine,root->startColumn);
2740 }
2741 return md;
2742 }
2743 }
2744 }
2745 }
2746
2747 QCString fileName = root->fileName;
2748 if (fileName.isEmpty() && root->tagInfo())
2749 {
2750 fileName = root->tagInfo()->tagName;
2751 }
2752
2753 AUTO_TRACE_ADD("new variable, namespace='{}'",nd?nd->name():QCString("<global>"));
2754 // new global variable, enum value or typedef
2755 auto md = createMemberDef(
2756 fileName,root->startLine,root->startColumn,
2757 type,name,args,QCString(),
2758 root->protection, Specifier::Normal,root->isStatic,Relationship::Member,
2759 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
2760 root->argList, root->metaData);
2761 auto mmd = toMemberDefMutable(md.get());
2762 mmd->setTagInfo(root->tagInfo());
2763 mmd->setMemberSpecifiers(root->spec);
2764 mmd->setVhdlSpecifiers(root->vhdlSpec);
2765 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
2766 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2767 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2768 mmd->addSectionsToDefinition(root->anchors);
2769 mmd->setFromAnonymousScope(fromAnnScope);
2770 mmd->setFromAnonymousMember(fromAnnMemb);
2771 mmd->setInitializer(root->initializer.str());
2772 mmd->setMaxInitLines(root->initLines);
2773 mmd->setMemberGroupId(root->mGrpId);
2774 mmd->setDefinition(def);
2775 mmd->setLanguage(root->lang);
2776 mmd->setId(root->id);
2778 mmd->setExplicitExternal(root->explicitExternal,fileName,root->startLine,root->startColumn);
2779 mmd->addQualifiers(root->qualifiers);
2780 //md->setOuterScope(fd);
2781 if (!root->explicitExternal)
2782 {
2783 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2784 mmd->setBodyDef(fd);
2785 }
2786 addMemberToGroups(root,md.get());
2788
2789 mmd->setRefItems(root->sli);
2790 if (nd && !nd->isAnonymous())
2791 {
2792 mmd->setNamespace(nd);
2793 nd->insertMember(md.get());
2794 }
2795
2796 // add member to the file (we do this even if we have already inserted
2797 // it into the namespace.
2798 if (fd)
2799 {
2800 mmd->setFileDef(fd);
2801 fd->insertMember(md.get());
2802 }
2803
2804 root->markAsProcessed();
2805
2806 if (mtype==MemberType::Typedef)
2807 {
2808 resolveTemplateInstanceInType(root,nd,md.get());
2809 }
2810
2811 // add member definition to the list of globals
2812 MemberDef *result = md.get();
2813 mn = Doxygen::functionNameLinkedMap->add(name);
2814 mn->push_back(std::move(md));
2815
2816
2817
2818 return result;
2819}
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(), reg::search(), DefinitionMutable::setBriefDescription(), ClassDefMutable::setClassName(), MemberDefMutable::setDeclFile(), DefinitionMutable::setDocumentation(), MemberDefMutable::setExplicitExternal(), DefinitionMutable::setRefItems(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, QCString::str(), TextStream::str(), QCString::stripPrefix(), Entry::tagInfo(), TagInfo::tagName, Entry::tArgLists, toMemberDefMutable(), Typedef, and Entry::vhdlSpec.

Referenced by addVariable().

◆ adjustConfiguration()

void adjustConfiguration ( )

adjust globals that depend on configuration settings.

Definition at line 11887 of file doxygen.cpp.

11888{
11889 AUTO_TRACE();
11890 Doxygen::globalNamespaceDef = createNamespaceDef("<globalScope>",1,1,"<globalScope>");
11900
11901 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11902
11903 /* Set the global html file extension. */
11904 Doxygen::htmlFileExtension = Config_getString(HTML_FILE_EXTENSION);
11905
11906
11908 Config_getBool(CALLER_GRAPH) ||
11909 Config_getBool(REFERENCES_RELATION) ||
11910 Config_getBool(REFERENCED_BY_RELATION);
11911
11912 /**************************************************************************
11913 * Add custom extension mappings
11914 **************************************************************************/
11915
11916 const StringVector &extMaps = Config_getList(EXTENSION_MAPPING);
11917 for (const auto &mapping : extMaps)
11918 {
11919 QCString mapStr = mapping;
11920 int i=mapStr.find('=');
11921 if (i==-1)
11922 {
11923 continue;
11924 }
11925 else
11926 {
11927 QCString ext = mapStr.left(i).stripWhiteSpace().lower();
11928 QCString language = mapStr.mid(i+1).stripWhiteSpace().lower();
11929 if (ext.isEmpty() || language.isEmpty())
11930 {
11931 continue;
11932 }
11933
11934 if (!updateLanguageMapping(ext,language))
11935 {
11936 err("Failed to map file extension '{}' to unsupported language '{}'.\n"
11937 "Check the EXTENSION_MAPPING setting in the config file.\n",
11938 ext,language);
11939 }
11940 else
11941 {
11942 msg("Adding custom extension mapping: '{}' will be treated as language '{}'\n",
11943 ext,language);
11944 }
11945 }
11946 }
11947 // create input file exncodings
11948
11949 // check INPUT_ENCODING
11950 void *cd = portable_iconv_open("UTF-8",Config_getString(INPUT_ENCODING).data());
11951 if (cd==reinterpret_cast<void *>(-1))
11952 {
11953 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
11954 "Check the 'INPUT_ENCODING' setting in the config file!\n",
11955 Config_getString(INPUT_ENCODING),strerror(errno));
11956 }
11957 else
11958 {
11960 }
11961
11962 // check and split INPUT_FILE_ENCODING
11963 const StringVector &fileEncod = Config_getList(INPUT_FILE_ENCODING);
11964 for (const auto &mapping : fileEncod)
11965 {
11966 QCString mapStr = mapping;
11967 int i=mapStr.find('=');
11968 if (i==-1)
11969 {
11970 continue;
11971 }
11972 else
11973 {
11974 QCString pattern = mapStr.left(i).stripWhiteSpace().lower();
11975 QCString encoding = mapStr.mid(i+1).stripWhiteSpace().lower();
11976 if (pattern.isEmpty() || encoding.isEmpty())
11977 {
11978 continue;
11979 }
11980 cd = portable_iconv_open("UTF-8",encoding.data());
11981 if (cd==reinterpret_cast<void *>(-1))
11982 {
11983 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
11984 "Check the 'INPUT_FILE_ENCODING' setting in the config file!\n",
11985 encoding,strerror(errno));
11986 }
11987 else
11988 {
11990 }
11991
11992 Doxygen::inputFileEncodingList.emplace_back(pattern, encoding);
11993 }
11994 }
11995
11996 // add predefined macro name to a dictionary
11997 const StringVector &expandAsDefinedList =Config_getList(EXPAND_AS_DEFINED);
11998 for (const auto &s : expandAsDefinedList)
11999 {
12001 }
12002
12003 // read aliases and store them in a dictionary
12004 readAliases();
12005
12006 // store number of spaces in a tab into Doxygen::spaces
12007 int tabSize = Config_getInt(TAB_SIZE);
12008 Doxygen::spaces.resize(tabSize);
12009 for (int sp=0; sp<tabSize; sp++) Doxygen::spaces.at(sp)=' ';
12010 Doxygen::spaces.at(tabSize)='\0';
12011}
void readAliases()
Definition aliases.cpp:170
static FileNameLinkedMap * plantUmlFileNameLinkedMap
Definition doxygen.h:110
static StringUnorderedSet expandAsDefinedSet
Definition doxygen.h:119
static InputFileEncodingList inputFileEncodingList
Definition doxygen.h:140
static FileNameLinkedMap * dotFileNameLinkedMap
Definition doxygen.h:107
static FileNameLinkedMap * imageNameLinkedMap
Definition doxygen.h:106
static FileNameLinkedMap * mscFileNameLinkedMap
Definition doxygen.h:108
static QCString spaces
Definition doxygen.h:135
static FileNameLinkedMap * diaFileNameLinkedMap
Definition doxygen.h:109
static QCString htmlFileExtension
Definition doxygen.h:122
static std::unique_ptr< NamespaceDef > globalNamespaceDef
Definition doxygen.h:120
static FileNameLinkedMap * includeNameLinkedMap
Definition doxygen.h:102
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:103
Ordered dictionary of FileName objects.
Definition filename.h:73
QCString lower() const
Definition qcstring.h:249
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:172
#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:5002

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(), 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 2097 of file doxygen.cpp.

2098{
2099 root->commandOverrides.apply_callGraph ([&](bool b) { md->overrideCallGraph(b); });
2100 root->commandOverrides.apply_callerGraph ([&](bool b) { md->overrideCallerGraph(b); });
2101 root->commandOverrides.apply_referencedByRelation([&](bool b) { md->overrideReferencedByRelation(b); });
2102 root->commandOverrides.apply_referencesRelation ([&](bool b) { md->overrideReferencesRelation(b); });
2103 root->commandOverrides.apply_inlineSource ([&](bool b) { md->overrideInlineSource(b); });
2104 root->commandOverrides.apply_enumValues ([&](bool b) { md->overrideEnumValues(b); });
2105}
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().

◆ buildClassDocList()

void buildClassDocList ( const Entry * root)
static

Definition at line 1137 of file doxygen.cpp.

1138{
1139 if ((root->section.isCompoundDoc()) && !root->name.isEmpty())
1140 {
1141 AUTO_TRACE();
1142 addClassToContext(root);
1143 }
1144 for (const auto &e : root->children()) buildClassDocList(e.get());
1145}
bool isCompoundDoc() const
Definition types.h:803
static void addClassToContext(const Entry *root)
Definition doxygen.cpp:931
static void buildClassDocList(const Entry *root)
Definition doxygen.cpp:1137

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

1128{
1129 if ((root->section.isCompound() || root->section.isObjcImpl()) && !root->name.isEmpty())
1130 {
1131 AUTO_TRACE();
1132 addClassToContext(root);
1133 }
1134 for (const auto &e : root->children()) buildClassList(e.get());
1135}
static void buildClassList(const Entry *root)
Definition doxygen.cpp:1127

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

8477{
8478 // merge the member list of base classes into the inherited classes.
8479 for (const auto &cd : *Doxygen::classLinkedMap)
8480 {
8481 if (// !cd->isReference() && // not an external class
8482 cd->subClasses().empty() && // is a root of the hierarchy
8483 !cd->baseClasses().empty()) // and has at least one base class
8484 {
8485 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8486 if (cdm)
8487 {
8488 //printf("*** merging members for %s\n",qPrint(cd->name()));
8489 cdm->mergeMembers();
8490 }
8491 }
8492 }
8493 // now sort the member list of all members for all classes.
8494 for (const auto &cd : *Doxygen::classLinkedMap)
8495 {
8496 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8497 if (cdm)
8498 {
8499 cdm->sortAllMembersList();
8500 }
8501 }
8502}
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 1286 of file doxygen.cpp.

1287{
1288 if (root->section.isConceptDoc())
1289 {
1290 AUTO_TRACE();
1291 addConceptToContext(root);
1292 }
1293 for (const auto &e : root->children()) buildConceptDocList(e.get());
1294}
static void addConceptToContext(const Entry *root)
Definition doxygen.cpp:1151
static void buildConceptDocList(const Entry *root)
Definition doxygen.cpp:1286

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

1277{
1278 if (root->section.isConcept())
1279 {
1280 AUTO_TRACE();
1281 addConceptToContext(root);
1282 }
1283 for (const auto &e : root->children()) buildConceptList(e.get());
1284}
static void buildConceptList(const Entry *root)
Definition doxygen.cpp:1276

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

Referenced by buildConceptList(), and parseInput().

◆ buildDefineList()

void buildDefineList ( )
static

Definition at line 8811 of file doxygen.cpp.

8812{
8813 AUTO_TRACE();
8814 for (const auto &s : g_inputFiles)
8815 {
8816 auto it = Doxygen::macroDefinitions.find(s);
8818 {
8819 for (const auto &def : it->second)
8820 {
8821 auto md = createMemberDef(
8822 def.fileName,def.lineNr,def.columnNr,
8823 "#define",def.name,def.args,QCString(),
8824 Protection::Public,Specifier::Normal,FALSE,Relationship::Member,MemberType::Define,
8825 ArgumentList(),ArgumentList(),"");
8826 auto mmd = toMemberDefMutable(md.get());
8827
8828 if (!def.args.isEmpty())
8829 {
8830 mmd->moveArgumentList(stringToArgumentList(SrcLangExt::Cpp, def.args));
8831 }
8832 mmd->setInitializer(def.definition);
8833 mmd->setFileDef(def.fileDef);
8834 mmd->setDefinition("#define "+def.name);
8835
8836 MemberName *mn=Doxygen::functionNameLinkedMap->add(def.name);
8837 if (def.fileDef)
8838 {
8839 const MemberList *defMl = def.fileDef->getMemberList(MemberListType::DocDefineMembers());
8840 if (defMl)
8841 {
8842 const MemberDef *defMd = defMl->findRev(def.name);
8843 if (defMd) // definition already stored
8844 {
8845 mmd->setRedefineCount(defMd->redefineCount()+1);
8846 }
8847 }
8848 def.fileDef->insertMember(md.get());
8849 }
8850 AUTO_TRACE_ADD("adding macro {} with definition {}",def.name,def.definition);
8851 mn->push_back(std::move(md));
8852 }
8853 }
8854 }
8855}
static DefinesPerFileList macroDefinitions
Definition doxygen.h:137
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:187

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

3470{
3471 if (!root->name.isEmpty() &&
3472 root->section.isVariable() &&
3473 root->type.find("dictionary<")!=-1 // it's a dictionary
3474 )
3475 {
3476 AUTO_TRACE();
3477 addVariable(root);
3478 }
3479 for (const auto &e : root->children())
3480 if (!e->section.isEnum())
3481 buildDictionaryList(e.get());
3482}
static void buildDictionaryList(const Entry *root)
Definition doxygen.cpp:3469
static void addVariable(const Entry *root, int isFuncPtr=-1)
Definition doxygen.cpp:3097

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

9896{
9897 if ((root->section.isExample() || root->section.isExampleLineno()) && !root->name.isEmpty())
9898 {
9899 if (Doxygen::exampleLinkedMap->find(root->name))
9900 {
9901 warn(root->fileName,root->startLine,"Example {} was already documented. Ignoring documentation found here.",root->name);
9902 }
9903 else
9904 {
9905 PageDef *pd = Doxygen::exampleLinkedMap->add(root->name,
9906 createPageDef(root->fileName,root->startLine,
9907 root->name,root->brief+root->doc+root->inbodyDocs,root->args));
9908 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9909 pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE));
9911 pd->setLanguage(root->lang);
9912 pd->setShowLineNo(root->section.isExampleLineno());
9913
9914 //we don't add example to groups
9915 //addExampleToGroups(root,pd);
9916 }
9917 }
9918 for (const auto &e : root->children()) buildExampleList(e.get());
9919}
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:99
virtual void setFileName(const QCString &name)=0
virtual void setShowLineNo(bool)=0
static void buildExampleList(Entry *root)
Definition doxygen.cpp:9895
std::unique_ptr< PageDef > createPageDef(const QCString &f, int l, const QCString &n, const QCString &d, const QCString &t)
Definition pagedef.cpp:80
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3425

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

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

3879{
3880 if (root->section.isFunction())
3881 {
3882 AUTO_TRACE("member function: type='{}' scope='{}' name='{}' args='{}' relates='{}' relatesType='{}'"
3883 " file='{}' line={} bodyLine={} #tArgLists={} mGrpId={}"
3884 " spec={} proto={} docFile='{}'",
3885 root->type, root->parent()->name, root->name, root->args, root->relates, root->relatesType,
3886 root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(), root->mGrpId,
3887 root->spec, root->proto, root->docFile);
3888
3889 bool isFriend=root->type.find("friend ")!=-1;
3891 //printf("rname=%s\n",qPrint(rname));
3892
3893 QCString scope;
3894 int index = computeQualifiedIndex(rname);
3895 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
3896 // grouped members are stored with full scope
3897 {
3898 buildScopeFromQualifiedName(rname.left(index+2),root->lang,root->tagInfo());
3899 scope=rname.left(index);
3900 rname=rname.mid(index+2);
3901 }
3902 else
3903 {
3904 scope=root->parent()->name; //stripAnonymousNamespaceScope(root->parent->name);
3905 }
3906 if (!rname.isEmpty() && scope.find('@')==-1)
3907 {
3908 // check if this function's parent is a class
3909 if (root->lang==SrcLangExt::CSharp)
3910 {
3911 scope=mangleCSharpGenericName(scope);
3912 }
3913 else
3914 {
3916 }
3917
3918 FileDef *rfd=root->fileDef();
3919
3920 int memIndex=rname.findRev("::");
3921
3923 if (cd && scope+"::"==rname.left(scope.length()+2)) // found A::f inside A
3924 {
3925 // strip scope from name
3926 rname=rname.right(rname.length()-root->parent()->name.length()-2);
3927 }
3928
3929 bool isMember=FALSE;
3930 if (memIndex!=-1)
3931 {
3932 int ts=rname.find('<');
3933 int te=rname.find('>');
3934 if (memIndex>0 && (ts==-1 || te==-1))
3935 {
3936 // note: the following code was replaced by inMember=TRUE to deal with a
3937 // function rname='X::foo' of class X inside a namespace also called X...
3938 // bug id 548175
3939 //nd = Doxygen::namespaceLinkedMap->find(rname.left(memIndex));
3940 //isMember = nd==nullptr;
3941 //if (nd)
3942 //{
3943 // // strip namespace scope from name
3944 // scope=rname.left(memIndex);
3945 // rname=rname.right(rname.length()-memIndex-2);
3946 //}
3947 isMember = TRUE;
3948 }
3949 else
3950 {
3951 isMember=memIndex<ts || memIndex>te;
3952 }
3953 }
3954
3955 if (!root->parent()->name.isEmpty() && root->parent()->section.isCompound() && cd)
3956 {
3957 AUTO_TRACE_ADD("member '{}' of class '{}'", rname,cd->name());
3958 addMethodToClass(root,cd,root->type,rname,root->args,isFriend,
3959 root->protection,root->isStatic,root->virt,root->spec,root->relates);
3960 }
3961 else if (root->parent()->section.isObjcImpl() && cd)
3962 {
3963 const MemberDef *md = cd->getMemberByName(rname);
3964 if (md)
3965 {
3966 MemberDefMutable *mdm = toMemberDefMutable(const_cast<MemberDef*>(md));
3967 if (mdm)
3968 {
3969 mdm->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3970 mdm->setBodyDef(root->fileDef());
3971 }
3972 }
3973 }
3974 else if (!root->parent()->section.isCompound() && !root->parent()->section.isObjcImpl() &&
3975 !isMember &&
3976 (root->relates.isEmpty() || root->relatesType==RelatesType::Duplicate) &&
3977 !root->type.startsWith("extern ") && !root->type.startsWith("typedef ")
3978 )
3979 // no member => unrelated function
3980 {
3981 /* check the uniqueness of the function name in the file.
3982 * A file could contain a function prototype and a function definition
3983 * or even multiple function prototypes.
3984 */
3985 bool found=FALSE;
3986 MemberDef *md_found=nullptr;
3987 MemberName *mn = Doxygen::functionNameLinkedMap->find(rname);
3988 if (mn)
3989 {
3990 AUTO_TRACE_ADD("function '{}' already found",rname);
3991 for (const auto &imd : *mn)
3992 {
3993 MemberDefMutable *md = toMemberDefMutable(imd.get());
3994 if (md)
3995 {
3996 const NamespaceDef *mnd = md->getNamespaceDef();
3997 NamespaceDef *rnd = nullptr;
3998 //printf("root namespace=%s\n",qPrint(rootNav->parent()->name()));
3999 QCString fullScope = scope;
4000 QCString parentScope = root->parent()->name;
4001 if (!parentScope.isEmpty() && !leftScopeMatch(parentScope,scope))
4002 {
4003 if (!scope.isEmpty()) fullScope.prepend("::");
4004 fullScope.prepend(parentScope);
4005 }
4006 //printf("fullScope=%s\n",qPrint(fullScope));
4007 rnd = getResolvedNamespace(fullScope);
4008 const FileDef *mfd = md->getFileDef();
4009 QCString nsName,rnsName;
4010 if (mnd) nsName = mnd->name();
4011 if (rnd) rnsName = rnd->name();
4012 //printf("matching arguments for %s%s %s%s\n",
4013 // qPrint(md->name()),md->argsString(),qPrint(rname),qPrint(argListToString(root->argList)));
4014 const ArgumentList &mdAl = md->argumentList();
4015 const ArgumentList &mdTempl = md->templateArguments();
4016
4017 // in case of template functions, we need to check if the
4018 // functions have the same number of template parameters
4019 bool sameTemplateArgs = TRUE;
4020 bool matchingReturnTypes = TRUE;
4021 bool sameRequiresClause = TRUE;
4022 if (!mdTempl.empty() && !root->tArgLists.empty())
4023 {
4024 sameTemplateArgs = matchTemplateArguments(mdTempl,root->tArgLists.back());
4025 if (md->typeString()!=removeRedundantWhiteSpace(root->type))
4026 {
4027 matchingReturnTypes = FALSE;
4028 }
4029 if (md->requiresClause()!=root->req)
4030 {
4031 sameRequiresClause = FALSE;
4032 }
4033 }
4034 else if (!mdTempl.empty() || !root->tArgLists.empty())
4035 { // if one has template parameters and the other doesn't then that also counts as a
4036 // difference
4037 sameTemplateArgs = FALSE;
4038 }
4039
4040 bool staticsInDifferentFiles =
4041 root->isStatic && md->isStatic() && root->fileName!=md->getDefFileName();
4042
4043 if (
4044 matchArguments2(md->getOuterScope(),mfd,&mdAl,
4045 rnd ? rnd : Doxygen::globalScope,rfd,&root->argList,
4046 FALSE,root->lang) &&
4047 sameTemplateArgs &&
4048 matchingReturnTypes &&
4049 sameRequiresClause &&
4050 !staticsInDifferentFiles
4051 )
4052 {
4053 GroupDef *gd=nullptr;
4054 if (!root->groups.empty() && !root->groups.front().groupname.isEmpty())
4055 {
4056 gd = Doxygen::groupLinkedMap->find(root->groups.front().groupname);
4057 }
4058 //printf("match!\n");
4059 //printf("mnd=%p rnd=%p nsName=%s rnsName=%s\n",mnd,rnd,qPrint(nsName),qPrint(rnsName));
4060 // see if we need to create a new member
4061 found=(mnd && rnd && nsName==rnsName) || // members are in the same namespace
4062 ((mnd==nullptr && rnd==nullptr && mfd!=nullptr && // no external reference and
4063 mfd->absFilePath()==root->fileName // prototype in the same file
4064 )
4065 );
4066 // otherwise, allow a duplicate global member with the same argument list
4067 if (!found && gd && gd==md->getGroupDef() && nsName==rnsName)
4068 {
4069 // member is already in the group, so we don't want to add it again.
4070 found=TRUE;
4071 }
4072
4073 AUTO_TRACE_ADD("combining function with prototype found={} in namespace '{}'",found,nsName);
4074
4075 if (found)
4076 {
4077 // merge argument lists
4078 ArgumentList mergedArgList = root->argList;
4079 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.isEmpty());
4080 // merge documentation
4081 if (md->documentation().isEmpty() && !root->doc.isEmpty())
4082 {
4083 if (root->proto)
4084 {
4086 }
4087 else
4088 {
4090 }
4091 }
4092
4093 md->setDocumentation(root->doc,root->docFile,root->docLine);
4095 md->setDocsForDefinition(!root->proto);
4096 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
4097 {
4098 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
4099 md->setBodyDef(rfd);
4100 }
4101
4102 if (md->briefDescription().isEmpty() && !root->brief.isEmpty())
4103 {
4104 md->setArgsString(root->args);
4105 }
4106 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
4107
4109
4111 md->addQualifiers(root->qualifiers);
4112
4113 // merge ingroup specifiers
4114 if (md->getGroupDef()==nullptr && !root->groups.empty())
4115 {
4116 addMemberToGroups(root,md);
4117 }
4118 else if (md->getGroupDef()!=nullptr && root->groups.empty())
4119 {
4120 //printf("existing member is grouped, new member not\n");
4121 }
4122 else if (md->getGroupDef()!=nullptr && !root->groups.empty())
4123 {
4124 //printf("both members are grouped\n");
4125 }
4127
4128 // if md is a declaration and root is the corresponding
4129 // definition, then turn md into a definition.
4130 if (md->isPrototype() && !root->proto)
4131 {
4132 md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn());
4133 md->setPrototype(FALSE,root->fileName,root->startLine,root->startColumn);
4134 }
4135 // if md is already the definition, then add the declaration info
4136 else if (!md->isPrototype() && root->proto)
4137 {
4138 md->setDeclFile(root->fileName,root->startLine,root->startColumn);
4139 }
4140 }
4141 }
4142 }
4143 if (found)
4144 {
4145 md_found = md;
4146 break;
4147 }
4148 }
4149 }
4150 if (!found) /* global function is unique with respect to the file */
4151 {
4152 addGlobalFunction(root,rname,scope);
4153 }
4154 else
4155 {
4156 FileDef *fd=root->fileDef();
4157 if (fd)
4158 {
4159 // add member to the file (we do this even if we have already
4160 // inserted it into the namespace)
4161 fd->insertMember(md_found);
4162 }
4163 }
4164
4165 AUTO_TRACE_ADD("unrelated function type='{}' name='{}' args='{}'",root->type,rname,root->args);
4166 }
4167 else
4168 {
4169 AUTO_TRACE_ADD("function '{}' is not processed",rname);
4170 }
4171 }
4172 else if (rname.isEmpty())
4173 {
4174 warn(root->fileName,root->startLine,
4175 "Illegal member name found."
4176 );
4177 }
4178 }
4179 for (const auto &e : root->children()) buildFunctionList(e.get());
4180}
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:3770
static void buildFunctionList(const Entry *root)
Definition doxygen.cpp:3878
bool matchTemplateArguments(const ArgumentList &srcAl, const ArgumentList &dstAl)
Definition util.cpp:2194

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

426{
427 // --- first process only local groups
428 // first process the @defgroups blocks
430 // then process the @addtogroup, @weakgroup blocks
432
433 // --- then also process external groups
434 // first process the @defgroups blocks
436 // then process the @addtogroup, @weakgroup blocks
438}
static void buildGroupListFiltered(const Entry *root, bool additional, bool includeExternal)
Definition doxygen.cpp:356

References buildGroupListFiltered(), FALSE, and TRUE.

Referenced by parseInput().

◆ buildGroupListFiltered()

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

Definition at line 356 of file doxygen.cpp.

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

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::section, DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), GroupDef::setGroupTitle(), DefinitionMutable::setInbodyDocumentation(), DefinitionMutable::setLanguage(), DefinitionMutable::setReference(), DefinitionMutable::setRefItems(), 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 3582 of file doxygen.cpp.

3583{
3584 if (root->section.isExportedInterface() || root->section.isIncludedService())
3585 {
3586 AUTO_TRACE("Exported interface/included service: type='{}' scope='{}' name='{}' args='{}'"
3587 " relates='{}' relatesType='{}' file='{}' line={} bodyLine={} #tArgLists={}"
3588 " mGrpId={} spec={} proto={} docFile='{}'",
3589 root->type, root->parent()->name, root->name, root->args,
3590 root->relates, root->relatesType, root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(),
3591 root->mGrpId, root->spec, root->proto, root->docFile);
3592
3594
3595 if (!rname.isEmpty())
3596 {
3597 QCString scope = root->parent()->name;
3598 ClassDefMutable *cd = getClassMutable(scope);
3599 assert(cd);
3600 if (cd && ((ClassDef::Interface == cd->compoundType()) ||
3601 (ClassDef::Service == cd->compoundType()) ||
3603 {
3605 }
3606 else
3607 {
3608 assert(false); // was checked by scanner.l
3609 }
3610 }
3611 else if (rname.isEmpty())
3612 {
3613 warn(root->fileName,root->startLine,
3614 "Illegal member name found.");
3615 }
3616 }
3617 // can only have these in IDL anyway
3618 switch (root->lang)
3619 {
3620 case SrcLangExt::Unknown: // fall through (root node always is Unknown)
3621 case SrcLangExt::IDL:
3622 for (const auto &e : root->children()) buildInterfaceAndServiceList(e.get());
3623 break;
3624 default:
3625 return; // nothing to do here
3626 }
3627}
@ Singleton
Definition classdef.h:117
@ Interface
Definition classdef.h:112
virtual CompoundType compoundType() const =0
Returns the type of compound this is, i.e.
static void addInterfaceOrServiceToServiceOrSingleton(const Entry *root, ClassDefMutable *cd, QCString const &rname)
Definition doxygen.cpp:3520
static void buildInterfaceAndServiceList(const Entry *root)
Definition doxygen.cpp:3582

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

1993{
1994 if (root->section.isUsingDecl() &&
1995 !root->parent()->section.isCompound() // not a class/struct member
1996 )
1997 {
1998 QCString name = substitute(root->name,".","::");
1999 g_usingDeclarations.insert(name.str());
2000 }
2001 for (const auto &e : root->children()) buildListOfUsingDecls(e.get());
2002}
static StringSet g_usingDeclarations
Definition doxygen.cpp:189
static void buildListOfUsingDecls(const Entry *root)
Definition doxygen.cpp:1992

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

1671{
1672 if (
1673 (root->section.isNamespace() ||
1674 root->section.isNamespaceDoc() ||
1675 root->section.isPackageDoc()
1676 ) &&
1677 !root->name.isEmpty()
1678 )
1679 {
1680 AUTO_TRACE("name={}",root->name);
1681
1682 QCString fName = root->name;
1683 if (root->section.isPackageDoc())
1684 {
1685 fName=substitute(fName,".","::");
1686 }
1687
1688 QCString fullName = stripAnonymousNamespaceScope(fName);
1689 if (!fullName.isEmpty())
1690 {
1691 AUTO_TRACE_ADD("Found namespace {} in {} at line {}",root->name,root->fileName,root->startLine);
1692 NamespaceDef *ndi = Doxygen::namespaceLinkedMap->find(fullName);
1693 if (ndi) // existing namespace
1694 {
1696 if (nd) // non-inline namespace
1697 {
1698 AUTO_TRACE_ADD("Existing namespace");
1699 nd->setDocumentation(root->doc,root->docFile,root->docLine);
1700 nd->setName(fullName); // change name to match docs
1702 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1703 if (nd->getLanguage()==SrcLangExt::Unknown)
1704 {
1705 nd->setLanguage(root->lang);
1706 }
1707 if (root->tagInfo()==nullptr && nd->isReference() && !(root->doc.isEmpty() && root->brief.isEmpty()))
1708 // if we previously found namespace nd in a tag file and now we find a
1709 // documented namespace with the same name in the project, then remove
1710 // the tag file reference
1711 {
1712 nd->setReference("");
1713 nd->setFileName(fullName);
1714 }
1715 nd->setMetaData(root->metaData);
1716
1717 // file definition containing the namespace nd
1718 FileDef *fd=root->fileDef();
1719 if (nd->isArtificial())
1720 {
1721 nd->setArtificial(FALSE); // found namespace explicitly, so cannot be artificial
1722 nd->setDefFile(root->fileName,root->startLine,root->startColumn);
1723 }
1724 // insert the namespace in the file definition
1725 if (fd) fd->insertNamespace(nd);
1726 addNamespaceToGroups(root,nd);
1727 nd->setRefItems(root->sli);
1728 }
1729 }
1730 else // fresh namespace
1731 {
1732 QCString tagName;
1733 QCString tagFileName;
1734 const TagInfo *tagInfo = root->tagInfo();
1735 if (tagInfo)
1736 {
1737 tagName = tagInfo->tagName;
1738 tagFileName = tagInfo->fileName;
1739 }
1740 AUTO_TRACE_ADD("new namespace {} lang={} tagName={}",fullName,langToString(root->lang),tagName);
1741 // add namespace to the list
1743 Doxygen::namespaceLinkedMap->add(fullName,
1744 createNamespaceDef(tagInfo?tagName:root->fileName,root->startLine,
1745 root->startColumn,fullName,tagName,tagFileName,
1746 root->type,root->spec.isPublished())));
1747 if (nd)
1748 {
1749 nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1750 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1752 nd->setHidden(root->hidden);
1753 nd->setArtificial(root->artificial);
1754 nd->setLanguage(root->lang);
1755 nd->setId(root->id);
1756 nd->setMetaData(root->metaData);
1757 nd->setInline(root->spec.isInline());
1758 nd->setExported(root->exported);
1759
1760 addNamespaceToGroups(root,nd);
1761 nd->setRefItems(root->sli);
1762
1763 // file definition containing the namespace nd
1764 FileDef *fd=root->fileDef();
1765 // insert the namespace in the file definition
1766 if (fd) fd->insertNamespace(nd);
1767
1768 // the empty string test is needed for extract all case
1769 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1770 nd->insertUsedFile(fd);
1771 nd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1772 nd->setBodyDef(fd);
1773
1774 // also add namespace to the correct structural context
1775 Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName,nullptr,tagInfo);
1776 AUTO_TRACE_ADD("adding namespace {} to context {}",nd->name(),d ? d->name() : QCString("<none>"));
1777 if (d==nullptr) // we didn't find anything, create the scope artificially
1778 // anyway, so we can at least relate scopes properly.
1779 {
1780 d = buildScopeFromQualifiedName(fullName,nd->getLanguage(),tagInfo);
1782 if (dm)
1783 {
1784 dm->addInnerCompound(nd);
1785 }
1786 nd->setOuterScope(d);
1787 // TODO: Due to the order in which the tag file is written
1788 // a nested class can be found before its parent!
1789 }
1790 else
1791 {
1793 if (dm)
1794 {
1795 dm->addInnerCompound(nd);
1796 }
1797 nd->setOuterScope(d);
1798 // in case of d is an inline namespace, alias insert nd in the part scope of d.
1800 {
1801 NamespaceDef *pnd = toNamespaceDef(d);
1802 if (pnd && pnd->isInline())
1803 {
1804 d = d->getOuterScope();
1805 if (d)
1806 {
1807 dm = toDefinitionMutable(d);
1808 if (dm)
1809 {
1810 auto aliasNd = createNamespaceDefAlias(d,nd);
1811 dm->addInnerCompound(aliasNd.get());
1812 QCString aliasName = aliasNd->name();
1813 AUTO_TRACE_ADD("adding alias {} to {}",aliasName,d->name());
1814 Doxygen::namespaceLinkedMap->add(aliasName,std::move(aliasNd));
1815 }
1816 }
1817 else
1818 {
1819 break;
1820 }
1821 }
1822 else
1823 {
1824 break;
1825 }
1826 }
1827 }
1828 }
1829 }
1830 }
1831 }
1832 for (const auto &e : root->children()) buildNamespaceList(e.get());
1833}
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:189
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:1670
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:5803

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

9652{
9653 if (root->section.isPageDoc())
9654 {
9655 if (!root->name.isEmpty())
9656 {
9657 addRelatedPage(root);
9658 }
9659 }
9660 else if (root->section.isMainpageDoc())
9661 {
9662 QCString title=root->args.stripWhiteSpace();
9663 if (title.isEmpty()) title=theTranslator->trMainPage();
9664 //QCString name = Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9665 QCString name = "index";
9666 addRefItem(root->sli,
9667 name,
9668 "page",
9669 name,
9670 title,
9671 QCString(),nullptr
9672 );
9673 }
9674 for (const auto &e : root->children()) buildPageList(e.get());
9675}
static void buildPageList(Entry *root)
Definition doxygen.cpp:9651

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

Referenced by buildPageList(), 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 705 of file doxygen.cpp.

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

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

3452{
3453 if (!root->name.isEmpty() &&
3454 root->section.isVariable() &&
3455 root->type.find("sequence<")!=-1 // it's a sequence
3456 )
3457 {
3458 AUTO_TRACE();
3459 addVariable(root);
3460 }
3461 for (const auto &e : root->children())
3462 if (!e->section.isEnum())
3463 buildSequenceList(e.get());
3464}
static void buildSequenceList(const Entry *root)
Definition doxygen.cpp:3451

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

3353{
3354 //printf("buildVarList(%s)\n",qPrint(rootNav->name()));
3355 if (!root->name.isEmpty() &&
3356 root->section.isVariable() &&
3357 root->type.find("typedef ")!=-1 // its a typedef
3358 )
3359 {
3360 AUTO_TRACE();
3362 QCString scope;
3363 int index = computeQualifiedIndex(rname);
3364 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
3365 // grouped members are stored with full scope
3366 {
3367 buildScopeFromQualifiedName(rname.left(index+2),root->lang,root->tagInfo());
3368 scope=rname.left(index);
3369 rname=rname.mid(index+2);
3370 }
3371 else
3372 {
3373 scope=root->parent()->name; //stripAnonymousNamespaceScope(root->parent->name);
3374 }
3377 MemberName *mn = Doxygen::functionNameLinkedMap->find(rname);
3378 bool found=false;
3379 if (mn) // symbol with the same name already found
3380 {
3381 for (auto &imd : *mn)
3382 {
3383 if (!imd->isTypedef())
3384 continue;
3385
3386 QCString rtype = root->type;
3387 rtype.stripPrefix("typedef ");
3388
3389 // merge the typedefs only if they're not both grouped, and both are
3390 // either part of the same class, part of the same namespace, or both
3391 // are global (i.e., neither in a class or a namespace)
3392 bool notBothGrouped = root->groups.empty() || imd->getGroupDef()==nullptr; // see example #100
3393 bool bothSameScope = (!cd && !nd) || (cd && imd->getClassDef() == cd) || (nd && imd->getNamespaceDef() == nd);
3394 //printf("imd->isTypedef()=%d imd->typeString()=%s root->type=%s\n",imd->isTypedef(),
3395 // qPrint(imd->typeString()),qPrint(root->type));
3396 if (notBothGrouped && bothSameScope && imd->typeString()==rtype)
3397 {
3398 MemberDefMutable *md = toMemberDefMutable(imd.get());
3399 if (md)
3400 {
3401 md->setDocumentation(root->doc,root->docFile,root->docLine);
3403 md->setDocsForDefinition(!root->proto);
3404 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3406 md->setRefItems(root->sli);
3407 md->addQualifiers(root->qualifiers);
3408
3409 // merge ingroup specifiers
3410 if (md->getGroupDef()==nullptr && !root->groups.empty())
3411 {
3412 addMemberToGroups(root,md);
3413 }
3414 else if (md->getGroupDef()!=nullptr && root->groups.empty())
3415 {
3416 //printf("existing member is grouped, new member not\n");
3417 }
3418 else if (md->getGroupDef()!=nullptr && !root->groups.empty())
3419 {
3420 //printf("both members are grouped\n");
3421 }
3422 found=true;
3423 break;
3424 }
3425 }
3426 }
3427 }
3428 if (found)
3429 {
3430 AUTO_TRACE_ADD("typedef '{}' already found",rname);
3431 // mark the entry as processed, as we copied everything from it elsewhere
3432 // also, otherwise, due to containing `typedef` it may later get treated
3433 // as a function typedef in filterMemberDocumentation, which is incorrect
3434 root->markAsProcessed();
3435 }
3436 else
3437 {
3438 AUTO_TRACE_ADD("new typedef '{}'",rname);
3439 addVariable(root);
3440 }
3441
3442 }
3443 for (const auto &e : root->children())
3444 if (!e->section.isEnum())
3445 buildTypedefList(e.get());
3446}
static void buildTypedefList(const Entry *root)
Definition doxygen.cpp:3352

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::section, DefinitionMutable::setBriefDescription(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setInbodyDocumentation(), DefinitionMutable::setRefItems(), 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 3488 of file doxygen.cpp.

3489{
3490 //printf("buildVarList(%s) section=%08x\n",qPrint(rootNav->name()),rootNav->section());
3491 int isFuncPtr=-1;
3492 if (!root->name.isEmpty() &&
3493 (root->type.isEmpty() || g_compoundKeywords.find(root->type.str())==g_compoundKeywords.end()) &&
3494 (
3495 (root->section.isVariable() && // it's a variable
3496 root->type.find("typedef ")==-1 // and not a typedef
3497 ) ||
3498 (root->section.isFunction() && // or maybe a function pointer variable
3499 (isFuncPtr=findFunctionPtr(root->type.str(),root->lang))!=-1
3500 ) ||
3501 (root->section.isFunction() && // class variable initialized by constructor
3503 )
3504 )
3505 ) // documented variable
3506 {
3507 AUTO_TRACE();
3508 addVariable(root,isFuncPtr);
3509 }
3510 for (const auto &e : root->children())
3511 if (!e->section.isEnum())
3512 buildVarList(e.get());
3513}
static void buildVarList(const Entry *root)
Definition doxygen.cpp:3488
static bool isVarWithConstructor(const Entry *root)
Definition doxygen.cpp:2885
static const StringUnorderedSet g_compoundKeywords
Definition doxygen.cpp:198

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

11877{
11878 AUTO_TRACE();
11879
11884}
void initWarningFormat()
Definition message.cpp:237
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 12356 of file doxygen.cpp.

12357{
12358 if (Config_getBool(MARKDOWN_SUPPORT))
12359 {
12360 QCString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
12361 if (mdfileAsMainPage.isEmpty()) return;
12362 FileInfo fi(mdfileAsMainPage.data());
12363 if (!fi.exists())
12364 {
12365 warn_uncond("Specified markdown mainpage '{}' does not exist\n",mdfileAsMainPage);
12366 return;
12367 }
12368 bool ambig = false;
12369 if (findFileDef(Doxygen::inputNameLinkedMap,fi.absFilePath(),ambig)==nullptr)
12370 {
12371 warn_uncond("Specified markdown mainpage '{}' has not been defined as input file\n",mdfileAsMainPage);
12372 return;
12373 }
12374 }
12375}
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 9790 of file doxygen.cpp.

9791{
9792 for (const auto &pd : *Doxygen::pageLinkedMap)
9793 {
9794 Definition *ppd = pd->getOuterScope();
9795 while (ppd)
9796 {
9797 if (ppd==pd.get())
9798 {
9799 term("page defined {} with label {} is a subpage "
9800 "of itself! Please remove this cyclic dependency.\n",
9801 warn_line(pd->docFile(),pd->docLine()),pd->name());
9802 }
9803 ppd=ppd->getOuterScope();
9804 }
9805 }
9806}

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

Referenced by parseInput().

◆ cleanUpDoxygen()

void cleanUpDoxygen ( )

Definition at line 11402 of file doxygen.cpp.

11403{
11407
11408 delete Doxygen::indexList;
11417 Doxygen::mainPage.reset();
11421 Doxygen::globalScope = nullptr;
11423 delete theTranslator;
11424 delete g_outputList;
11425
11430 delete Doxygen::dirLinkedMap;
11431 delete Doxygen::symbolMap;
11432}
static ParserManager * parserManager
Definition doxygen.h:131
static SymbolMap< Definition > * symbolMap
Definition doxygen.h:125
static FormulaManager & instance()
Definition formula.cpp:54
void clear()
Definition linkedmap.h:212
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:178
static OutputList * g_outputList
Definition doxygen.cpp:188

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

202{
203 g_inputFiles.clear();
204 //g_excludeNameDict.clear();
205 //delete g_outputList; g_outputList=nullptr;
206
211 Doxygen::pageLinkedMap->clear();
224 Doxygen::mainPage.reset();
226}
static CitationManager & instance()
Definition cite.cpp:86
void clear()
clears the database
Definition cite.cpp:112
static StringMap tagDestinationMap
Definition doxygen.h:116
static ClassLinkedMap * hiddenClassLinkedMap
Definition doxygen.h:97

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::mscFileNameLinkedMap, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, Doxygen::plantUmlFileNameLinkedMap, and Doxygen::tagDestinationMap.

◆ combineUsingRelations()

void combineUsingRelations ( )
static

Definition at line 9189 of file doxygen.cpp.

9190{
9191 // for each file
9192 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9193 {
9194 for (const auto &fd : *fn)
9195 {
9196 fd->combineUsingRelations();
9197 }
9198 }
9199
9200 // for each namespace
9201 NamespaceDefSet visitedNamespaces;
9202 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9203 {
9205 if (ndm)
9206 {
9207 ndm->combineUsingRelations(visitedNamespaces);
9208 }
9209 }
9210}
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 10289 of file doxygen.cpp.

10290{
10291 std::ofstream f;
10292 bool fileOpened=openOutputFile("-",f);
10293 if (fileOpened)
10294 {
10295 TextStream t(&f);
10296 Config::compareDoxyfile(t,diffList);
10297 }
10298 else
10299 {
10300 term("Cannot open stdout for writing\n");
10301 }
10302}
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:6206

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

Referenced by readConfiguration().

◆ computeClassRelations()

void computeClassRelations ( )
static

Definition at line 5312 of file doxygen.cpp.

5313{
5314 AUTO_TRACE();
5315 for (const auto &[name,root] : g_classEntries)
5316 {
5317 QCString bName = extractClassName(root);
5318 ClassDefMutable *cd = getClassMutable(bName);
5319 if (cd)
5320 {
5322 }
5323 size_t numMembers = cd ? cd->memberNameInfoLinkedMap().size() : 0;
5324 if ((cd==nullptr || (!cd->hasDocumentation() && !cd->isReference())) && numMembers>0 && !bName.endsWith("::"))
5325 {
5326 if (!root->name.isEmpty() && root->name.find('@')==-1 && // normal name
5327 (guessSection(root->fileName).isHeader() ||
5328 Config_getBool(EXTRACT_LOCAL_CLASSES)) && // not defined in source file
5329 protectionLevelVisible(root->protection) && // hidden by protection
5330 !Config_getBool(HIDE_UNDOC_CLASSES) // undocumented class are visible
5331 )
5332 warn_undoc(root->fileName,root->startLine, "Compound {} is not documented.", root->name);
5333 }
5334 }
5335}
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:524
static QCString extractClassName(const Entry *root)
Definition doxygen.cpp:5215
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:4669
static std::multimap< std::string, const Entry * > g_classEntries
Definition doxygen.cpp:186
#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().

◆ computeIdealCacheParam()

int computeIdealCacheParam ( size_t v)
static

Definition at line 11434 of file doxygen.cpp.

11435{
11436 //printf("computeIdealCacheParam(v=%u)\n",v);
11437
11438 int r=0;
11439 while (v!=0) v>>=1,r++;
11440 // r = log2(v)
11441
11442 // convert to a valid cache size value
11443 return std::max(0,std::min(r-16,9));
11444}

Referenced by generateOutput().

◆ computeMemberReferences()

void computeMemberReferences ( )
static

Definition at line 5406 of file doxygen.cpp.

5407{
5408 AUTO_TRACE();
5409 for (const auto &cd : *Doxygen::classLinkedMap)
5410 {
5411 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5412 if (cdm)
5413 {
5414 cdm->computeAnchors();
5415 }
5416 }
5417 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5418 {
5419 for (const auto &fd : *fn)
5420 {
5421 fd->computeAnchors();
5422 }
5423 }
5424 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5425 {
5427 if (ndm)
5428 {
5429 ndm->computeAnchors();
5430 }
5431 }
5432 for (const auto &gd : *Doxygen::groupLinkedMap)
5433 {
5434 gd->computeAnchors();
5435 }
5436}
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 8419 of file doxygen.cpp.

8420{
8421 for (const auto &cd : *Doxygen::classLinkedMap)
8422 {
8423 if (cd->isLinkable())
8424 {
8425 for (const auto &bcd : cd->baseClasses())
8426 {
8428 }
8429 }
8430 }
8431}
static void computeMemberRelationsForBaseClass(const ClassDef *cd, const BaseClassDef *bcd)
Definition doxygen.cpp:8339

References Doxygen::classLinkedMap, and computeMemberRelationsForBaseClass().

Referenced by parseInput().

◆ computeMemberRelationsForBaseClass()

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

Definition at line 8339 of file doxygen.cpp.

8340{
8341 for (const auto &mn : cd->memberNameInfoLinkedMap()) // for each member in class cd with a unique name
8342 {
8343 for (const auto &imd : *mn) // for each member with a given name
8344 {
8345 MemberDefMutable *md = toMemberDefMutable(imd->memberDef());
8346 if (md && (md->isFunction() || md->isCSharpProperty())) // filter on reimplementable members
8347 {
8348 ClassDef *mbcd = bcd->classDef;
8349 if (mbcd && mbcd->isLinkable()) // filter on linkable classes
8350 {
8351 const auto &bmn = mbcd->memberNameInfoLinkedMap();
8352 const auto &bmni = bmn.find(mn->memberName());
8353 if (bmni) // there are base class members with the same name
8354 {
8355 for (const auto &ibmd : *bmni) // for base class member with that name
8356 {
8357 MemberDefMutable *bmd = toMemberDefMutable(ibmd->memberDef());
8358 if (bmd) // not part of an inline namespace
8359 {
8360 auto lang = bmd->getLanguage();
8361 auto compType = mbcd->compoundType();
8362 if (bmd->virtualness()!=Specifier::Normal ||
8363 lang==SrcLangExt::Python ||
8364 lang==SrcLangExt::Java ||
8365 lang==SrcLangExt::PHP ||
8366 compType==ClassDef::Interface ||
8367 compType==ClassDef::Protocol)
8368 {
8369 const ArgumentList &bmdAl = bmd->argumentList();
8370 const ArgumentList &mdAl = md->argumentList();
8371 //printf(" Base argList='%s'\n Super argList='%s'\n",
8372 // qPrint(argListToString(bmdAl)),
8373 // qPrint(argListToString(mdAl))
8374 // );
8375 if (
8376 lang==SrcLangExt::Python ||
8377 matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),&bmdAl,
8378 md->getOuterScope(), md->getFileDef(), &mdAl,
8379 TRUE,lang
8380 )
8381 )
8382 {
8383 if (lang==SrcLangExt::Python && md->name().startsWith("__")) continue; // private members do not reimplement
8384 //printf("match!\n");
8385 const MemberDef *rmd = md->reimplements();
8386 if (rmd==nullptr) // not already assigned
8387 {
8388 //printf("%s: setting (new) reimplements member %s\n",qPrint(md->qualifiedName()),qPrint(bmd->qualifiedName()));
8389 md->setReimplements(bmd);
8390 }
8391 //printf("%s: add reimplementedBy member %s\n",qPrint(bmd->qualifiedName()),qPrint(md->qualifiedName()));
8392 bmd->insertReimplementedBy(md);
8393 }
8394 else
8395 {
8396 //printf("no match!\n");
8397 }
8398 }
8399 }
8400 }
8401 }
8402 }
8403 }
8404 }
8405 }
8406
8407 // do also for indirect base classes
8408 for (const auto &bbcd : bcd->classDef->baseClasses())
8409 {
8411 }
8412}
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, and MemberDef::virtualness().

Referenced by computeMemberRelations(), and computeMemberRelationsForBaseClass().

◆ computePageRelations()

void computePageRelations ( Entry * root)
static

Definition at line 9760 of file doxygen.cpp.

9761{
9762 if ((root->section.isPageDoc() || root->section.isMainpageDoc()) && !root->name.isEmpty())
9763 {
9764 PageDef *pd = root->section.isPageDoc() ?
9765 Doxygen::pageLinkedMap->find(root->name) :
9766 Doxygen::mainPage.get();
9767 if (pd)
9768 {
9769 for (const BaseInfo &bi : root->extends)
9770 {
9771 PageDef *subPd = Doxygen::pageLinkedMap->find(bi.name);
9772 if (pd==subPd)
9773 {
9774 term("page defined {} with label {} is a direct "
9775 "subpage of itself! Please remove this cyclic dependency.\n",
9776 warn_line(pd->docFile(),pd->docLine()),pd->name());
9777 }
9778 else if (subPd)
9779 {
9780 pd->addInnerCompound(subPd);
9781 //printf("*** Added subpage relation: %s->%s\n",
9782 // qPrint(pd->name()),qPrint(subPd->name()));
9783 }
9784 }
9785 }
9786 }
9787 for (const auto &e : root->children()) computePageRelations(e.get());
9788}
virtual QCString docFile() const =0
virtual int docLine() const =0
std::vector< BaseInfo > extends
list of base classes
Definition entry.h:220
static void computePageRelations(Entry *root)
Definition doxygen.cpp:9760
QCString name
the name of the base class
Definition entry.h:94

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

5338{
5339 AUTO_TRACE();
5340 for (const auto &[name,root] : g_classEntries)
5341 {
5342 QCString bName=stripAnonymousNamespaceScope(root->name);
5345 // strip any anonymous scopes first
5346 if (cd && !cd->getTemplateInstances().empty())
5347 {
5348 AUTO_TRACE_ADD("Template class '{}'",cd->name());
5349 for (const auto &ti : cd->getTemplateInstances()) // for each template instance
5350 {
5351 ClassDefMutable *tcd=toClassDefMutable(ti.classDef);
5352 if (tcd)
5353 {
5354 AUTO_TRACE_ADD("Template instance '{}'",tcd->name());
5355 QCString templSpec = ti.templSpec;
5356 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(tcd->getLanguage(),templSpec);
5357 for (const BaseInfo &bi : root->extends)
5358 {
5359 // check if the base class is a template argument
5360 BaseInfo tbi = bi;
5361 const ArgumentList &tl = cd->templateArguments();
5362 if (!tl.empty())
5363 {
5364 TemplateNameMap baseClassNames = tcd->getTemplateBaseClassNames();
5365 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,bi.name.str());
5366 // for each template name that we inherit from we need to
5367 // substitute the formal with the actual arguments
5368 TemplateNameMap actualTemplateNames;
5369 for (const auto &tn_kv : templateNames)
5370 {
5371 size_t templIndex = tn_kv.second;
5372 Argument actArg;
5373 bool hasActArg=FALSE;
5374 if (templIndex<templArgs->size())
5375 {
5376 actArg=templArgs->at(templIndex);
5377 hasActArg=TRUE;
5378 }
5379 if (hasActArg &&
5380 baseClassNames.find(actArg.type.str())!=baseClassNames.end() &&
5381 actualTemplateNames.find(actArg.type.str())==actualTemplateNames.end()
5382 )
5383 {
5384 actualTemplateNames.emplace(actArg.type.str(),static_cast<int>(templIndex));
5385 }
5386 }
5387
5388 tbi.name = substituteTemplateArgumentsInString(bi.name,tl,templArgs.get());
5389 // find a documented base class in the correct scope
5390 if (!findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE))
5391 {
5392 // no documented base class -> try to find an undocumented one
5393 findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,Undocumented,TRUE);
5394 }
5395 }
5396 }
5397 }
5398 }
5399 }
5400 }
5401}
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:4448
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:4275

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

8909{
8910 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8911 if (numThreads>1)
8912 {
8913 ThreadPool threadPool(numThreads);
8914 std::vector < std::future< void > > results;
8915 // queue the work
8916 for (const auto &[name,symList] : *Doxygen::symbolMap)
8917 {
8918 for (const auto &def : symList)
8919 {
8921 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
8922 {
8923 auto processTooltip = [dm]() {
8924 dm->computeTooltip();
8925 };
8926 results.emplace_back(threadPool.queue(processTooltip));
8927 }
8928 }
8929 }
8930 // wait for the results
8931 for (auto &f : results)
8932 {
8933 f.get();
8934 }
8935 }
8936 else
8937 {
8938 for (const auto &[name,symList] : *Doxygen::symbolMap)
8939 {
8940 for (const auto &def : symList)
8941 {
8943 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
8944 {
8945 dm->computeTooltip();
8946 }
8947 }
8948 }
8949 }
8950}
virtual void computeTooltip()=0
Class managing a pool of worker threads.
Definition threadpool.h:48
static bool isSymbolHidden(const Definition *d)
Definition doxygen.cpp:8901

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

Referenced by parseInput().

◆ computeVerifiedDotPath()

void computeVerifiedDotPath ( )
static

Definition at line 10217 of file doxygen.cpp.

10218{
10219 // check dot path
10220 QCString dotPath = Config_getString(DOT_PATH);
10221 if (!dotPath.isEmpty())
10222 {
10223 FileInfo fi(dotPath.str());
10224 if (!(fi.exists() && fi.isFile()) )// not an existing user specified path + exec
10225 {
10226 dotPath = dotPath+"/dot"+Portable::commandExtension();
10227 FileInfo dp(dotPath.str());
10228 if (!dp.exists() || !dp.isFile())
10229 {
10230 warn_uncond("the dot tool could not be found as '{}'\n",dotPath);
10231 dotPath = "dot";
10232 dotPath += Portable::commandExtension();
10233 }
10234 }
10235#if defined(_WIN32) // convert slashes
10236 size_t l=dotPath.length();
10237 for (size_t i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\';
10238#endif
10239 }
10240 else
10241 {
10242 dotPath = "dot";
10243 dotPath += Portable::commandExtension();
10244 }
10245 Doxygen::verifiedDotPath = dotPath;
10247}
static QCString verifiedDotPath
Definition doxygen.h:139
const char * commandExtension()
Definition portable.cpp:462
#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 889 of file doxygen.cpp.

890{
892
893 if (specifier.isStruct())
895 else if (specifier.isUnion())
896 sec=ClassDef::Union;
897 else if (specifier.isCategory())
899 else if (specifier.isInterface())
901 else if (specifier.isProtocol())
903 else if (specifier.isException())
905 else if (specifier.isService())
907 else if (specifier.isSingleton())
909
910 if (section.isUnionDoc())
911 sec=ClassDef::Union;
912 else if (section.isStructDoc())
914 else if (section.isInterfaceDoc())
916 else if (section.isProtocolDoc())
918 else if (section.isCategoryDoc())
920 else if (section.isExceptionDoc())
922 else if (section.isServiceDoc())
924 else if (section.isSingletonDoc())
926
927 return sec;
928}
@ 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 )
static

Definition at line 10483 of file doxygen.cpp.

10484{
10485 for (const auto &fileName : files)
10486 {
10487 if (!fileName.empty())
10488 {
10489 FileInfo fi(fileName);
10490 if (!fi.exists())
10491 {
10492 err("Extra file '{}' specified in {} does not exist!\n", fileName,filesOption);
10493 }
10494 else if (fi.isDir())
10495 {
10496 err("Extra file '{}' specified in {} is a directory, it has to be a file!\n", fileName,filesOption);
10497 }
10498 else
10499 {
10500 QCString destFileName = outputOption+"/"+fi.fileName();
10501 Doxygen::indexList->addImageFile(fi.fileName());
10502 copyFile(fileName, destFileName);
10503 }
10504 }
10505 }
10506}
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:5769

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

Referenced by generateOutput().

◆ copyIcon()

void copyIcon ( const QCString & outputOption)
static

Definition at line 10458 of file doxygen.cpp.

10459{
10460 QCString projectIcon = Config_getString(PROJECT_ICON);
10461 if (!projectIcon.isEmpty())
10462 {
10463 FileInfo fi(projectIcon.str());
10464 if (!fi.exists())
10465 {
10466 err("Project icon '{}' specified by PROJECT_ICON does not exist!\n",projectIcon);
10467 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10468 }
10469 else if (fi.isDir())
10470 {
10471 err("Project icon '{}' specified by PROJECT_ICON is a directory, it has to be a file!\n",projectIcon);
10472 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10473 }
10474 else
10475 {
10476 QCString destFileName = outputOption+"/"+fi.fileName();
10477 copyFile(projectIcon,destFileName);
10478 Doxygen::indexList->addImageFile(fi.fileName());
10479 }
10480 }
10481}
#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 10349 of file doxygen.cpp.

10350{
10351 const StringVector &latexExtraStyleSheet = Config_getList(LATEX_EXTRA_STYLESHEET);
10352 for (const auto &sheet : latexExtraStyleSheet)
10353 {
10354 std::string fileName = sheet;
10355 if (!fileName.empty())
10356 {
10357 FileInfo fi(fileName);
10358 if (!fi.exists())
10359 {
10360 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET does not exist!\n",fileName);
10361 }
10362 else if (fi.isDir())
10363 {
10364 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET is a directory, it has to be a file!\n", fileName);
10365 }
10366 else
10367 {
10368 QCString destFileName = Config_getString(LATEX_OUTPUT)+"/"+fi.fileName();
10369 if (!checkExtension(fi.fileName(), LATEX_STYLE_EXTENSION))
10370 {
10371 destFileName += LATEX_STYLE_EXTENSION;
10372 }
10373 copyFile(fileName, destFileName);
10374 }
10375 }
10376 }
10377}
#define LATEX_STYLE_EXTENSION
Definition latexgen.h:22
bool checkExtension(const QCString &fName, const QCString &ext)
Definition util.cpp:4818

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)
static

Definition at line 10433 of file doxygen.cpp.

10434{
10435 QCString projectLogo = projectLogoFile();
10436 if (!projectLogo.isEmpty())
10437 {
10438 FileInfo fi(projectLogo.str());
10439 if (!fi.exists())
10440 {
10441 err("Project logo '{}' specified by PROJECT_LOGO does not exist!\n",projectLogo);
10442 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10443 }
10444 else if (fi.isDir())
10445 {
10446 err("Project logo '{}' specified by PROJECT_LOGO is a directory, it has to be a file!\n",projectLogo);
10447 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10448 }
10449 else
10450 {
10451 QCString destFileName = outputOption+"/"+fi.fileName();
10452 copyFile(projectLogo,destFileName);
10453 Doxygen::indexList->addImageFile(fi.fileName());
10454 }
10455 }
10456}
QCString projectLogoFile()
Definition util.cpp:3067

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

10381{
10382 QCString htmlStyleSheet = Config_getString(HTML_STYLESHEET);
10383 if (!htmlStyleSheet.isEmpty())
10384 {
10385 if (!htmlStyleSheet.startsWith("http:") && !htmlStyleSheet.startsWith("https:"))
10386 {
10387 FileInfo fi(htmlStyleSheet.str());
10388 if (!fi.exists())
10389 {
10390 err("Style sheet '{}' specified by HTML_STYLESHEET does not exist!\n",htmlStyleSheet);
10391 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10392 }
10393 else if (fi.isDir())
10394 {
10395 err("Style sheet '{}' specified by HTML_STYLESHEET is a directory, it has to be a file!\n",htmlStyleSheet);
10396 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10397 }
10398 else
10399 {
10400 QCString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10401 copyFile(htmlStyleSheet,destFileName);
10402 }
10403 }
10404 }
10405 const StringVector &htmlExtraStyleSheet = Config_getList(HTML_EXTRA_STYLESHEET);
10406 for (const auto &sheet : htmlExtraStyleSheet)
10407 {
10408 QCString fileName(sheet);
10409 if (!fileName.isEmpty() && !fileName.startsWith("http:") && !fileName.startsWith("https:"))
10410 {
10411 FileInfo fi(fileName.str());
10412 if (!fi.exists())
10413 {
10414 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET does not exist!\n",fileName);
10415 }
10416 else if (fi.fileName()=="doxygen.css" || fi.fileName()=="tabs.css" || fi.fileName()=="navtree.css")
10417 {
10418 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is already a built-in stylesheet. Please use a different name\n",fi.fileName());
10419 }
10420 else if (fi.isDir())
10421 {
10422 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is a directory, it has to be a file!\n",fileName);
10423 }
10424 else
10425 {
10426 QCString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10427 copyFile(fileName, destFileName);
10428 }
10429 }
10430 }
10431}

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

8969{
8970 for (const auto &cd : *Doxygen::classLinkedMap)
8971 {
8972 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8973 if (cdm)
8974 {
8975 cdm->countMembers();
8976 }
8977 }
8978
8979 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8980 {
8982 if (ndm)
8983 {
8984 ndm->countMembers();
8985 }
8986 }
8987
8988 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8989 {
8990 for (const auto &fd : *fn)
8991 {
8992 fd->countMembers();
8993 }
8994 }
8995
8996 for (const auto &gd : *Doxygen::groupLinkedMap)
8997 {
8998 gd->countMembers();
8999 }
9000
9001 auto &mm = ModuleManager::instance();
9002 mm.countMembers();
9003}
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 parseInput().

◆ createOutputDirectory()

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

Definition at line 12124 of file doxygen.cpp.

12127{
12128 QCString result = formatDirName;
12129 if (result.isEmpty())
12130 {
12131 result = baseDirName + defaultDirName;
12132 }
12133 else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':'))
12134 {
12135 result.prepend(baseDirName+"/");
12136 }
12137 Dir formatDir(result.str());
12138 if (!formatDir.exists() && !formatDir.mkdir(result.str()))
12139 {
12140 term("Could not create output directory {}\n", result);
12141 }
12142 return result;
12143}
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().

◆ createTagLessInstance()

ClassDefMutable * createTagLessInstance ( const ClassDef * rootCd,
const ClassDef * templ,
const QCString & fieldName )
static

Definition at line 1479 of file doxygen.cpp.

1480{
1481 QCString fullName = removeAnonymousScopes(templ->name());
1482 if (fullName.endsWith("::")) fullName=fullName.left(fullName.length()-2);
1483 fullName+="."+fieldName;
1484
1485 //printf("** adding class %s based on %s\n",qPrint(fullName),qPrint(templ->name()));
1487 Doxygen::classLinkedMap->add(fullName,
1489 templ->getDefLine(),
1490 templ->getDefColumn(),
1491 fullName,
1492 templ->compoundType())));
1493 if (cd)
1494 {
1495 cd->setDocumentation(templ->documentation(),templ->docFile(),templ->docLine()); // copy docs to definition
1496 cd->setBriefDescription(templ->briefDescription(),templ->briefFile(),templ->briefLine());
1497 cd->setLanguage(templ->getLanguage());
1498 cd->setBodySegment(templ->getDefLine(),templ->getStartBodyLine(),templ->getEndBodyLine());
1499 cd->setBodyDef(templ->getBodyDef());
1500
1501 cd->setOuterScope(rootCd->getOuterScope());
1502 if (rootCd->getOuterScope()!=Doxygen::globalScope)
1503 {
1504 DefinitionMutable *outerScope = toDefinitionMutable(rootCd->getOuterScope());
1505 if (outerScope)
1506 {
1507 outerScope->addInnerCompound(cd);
1508 }
1509 }
1510
1511 FileDef *fd = templ->getFileDef();
1512 if (fd)
1513 {
1514 cd->setFileDef(fd);
1515 fd->insertClass(cd);
1516 }
1517 for (auto &gd : rootCd->partOfGroups())
1518 {
1519 cd->makePartOfGroup(gd);
1520 gd->addClass(cd);
1521 }
1522
1523 MemberList *ml = templ->getMemberList(MemberListType::PubAttribs());
1524 if (ml)
1525 {
1526 for (const auto &md : *ml)
1527 {
1528 //printf(" Member %s type=%s\n",qPrint(md->name()),md->typeString());
1529 auto newMd = createMemberDef(md->getDefFileName(),md->getDefLine(),md->getDefColumn(),
1530 md->typeString(),md->name(),md->argsString(),md->excpString(),
1531 md->protection(),md->virtualness(),md->isStatic(),Relationship::Member,
1532 md->memberType(),
1533 ArgumentList(),ArgumentList(),"");
1534 MemberDefMutable *imd = toMemberDefMutable(newMd.get());
1535 imd->setMemberClass(cd);
1536 imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
1537 imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
1538 imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
1539 imd->setMemberSpecifiers(md->getMemberSpecifiers());
1540 imd->setVhdlSpecifiers(md->getVhdlSpecifiers());
1541 imd->setMemberGroupId(md->getMemberGroupId());
1542 imd->setInitializer(md->initializer());
1543 imd->setRequiresClause(md->requiresClause());
1544 imd->setMaxInitLines(md->initializerLines());
1545 imd->setBitfields(md->bitfieldString());
1546 imd->setLanguage(md->getLanguage());
1547 cd->insertMember(imd);
1548 MemberName *mn = Doxygen::memberNameLinkedMap->add(md->name());
1549 mn->push_back(std::move(newMd));
1550 }
1551 }
1552 }
1553 return cd;
1554}
virtual MemberList * getMemberList(MemberListType lt) const =0
Returns the members in the list identified by lt.
virtual FileDef * getFileDef() const =0
Returns the namespace this compound is in, or 0 if it has a global scope.
virtual int getEndBodyLine() const =0
virtual int briefLine() const =0
virtual const GroupList & partOfGroups() const =0
virtual QCString briefFile() const =0
virtual void setMemberClass(ClassDef *cd)=0
virtual void setMemberSpecifiers(TypeSpecifier s)=0
virtual void setBitfields(const QCString &s)=0
virtual void setVhdlSpecifiers(VhdlSpecifier s)=0
QCString removeAnonymousScopes(const QCString &str)
Definition util.cpp:170

References DefinitionMutable::addInnerCompound(), Definition::briefDescription(), Definition::briefFile(), Definition::briefLine(), Doxygen::classLinkedMap, ClassDef::compoundType(), createClassDef(), createMemberDef(), Definition::docFile(), Definition::docLine(), Definition::documentation(), QCString::endsWith(), Definition::getBodyDef(), Definition::getDefColumn(), Definition::getDefFileName(), Definition::getDefLine(), Definition::getEndBodyLine(), ClassDef::getFileDef(), Definition::getLanguage(), ClassDef::getMemberList(), Definition::getOuterScope(), Definition::getStartBodyLine(), Doxygen::globalScope, FileDef::insertClass(), ClassDefMutable::insertMember(), QCString::left(), QCString::length(), DefinitionMutable::makePartOfGroup(), Doxygen::memberNameLinkedMap, Definition::name(), Definition::partOfGroups(), MemberName::push_back(), removeAnonymousScopes(), MemberDefMutable::setBitfields(), DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), ClassDefMutable::setFileDef(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setInitializer(), DefinitionMutable::setLanguage(), MemberDefMutable::setMaxInitLines(), MemberDefMutable::setMemberClass(), MemberDefMutable::setMemberGroupId(), MemberDefMutable::setMemberSpecifiers(), DefinitionMutable::setOuterScope(), MemberDefMutable::setRequiresClause(), MemberDefMutable::setVhdlSpecifiers(), toClassDefMutable(), toDefinitionMutable(), and toMemberDefMutable().

Referenced by processTagLessClasses().

◆ createTemplateInstanceMembers()

void createTemplateInstanceMembers ( )
static

Definition at line 8435 of file doxygen.cpp.

8436{
8437 // for each class
8438 for (const auto &cd : *Doxygen::classLinkedMap)
8439 {
8440 // that is a template
8441 for (const auto &ti : cd->getTemplateInstances())
8442 {
8443 ClassDefMutable *tcdm = toClassDefMutable(ti.classDef);
8444 if (tcdm)
8445 {
8446 tcdm->addMembersToTemplateInstance(cd.get(),cd->templateArguments(),ti.templSpec);
8447 }
8448 }
8449 }
8450}
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 2109 of file doxygen.cpp.

2111{
2112 AUTO_TRACE("creating new member {} for class {}",memName,cd->name());
2113 const ArgumentList &templAl = md->templateArguments();
2114 const ArgumentList &al = md->argumentList();
2115 auto newMd = createMemberDef(
2116 fileName,root->startLine,root->startColumn,
2117 md->typeString(),memName,md->argsString(),
2118 md->excpString(),root->protection,root->virt,
2119 md->isStatic(),Relationship::Member,md->memberType(),
2120 templAl,al,root->metaData
2121 );
2122 auto newMmd = toMemberDefMutable(newMd.get());
2123 newMmd->setMemberClass(cd);
2124 cd->insertMember(newMd.get());
2125 if (!root->doc.isEmpty() || !root->brief.isEmpty())
2126 {
2127 newMmd->setDocumentation(root->doc,root->docFile,root->docLine);
2128 newMmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2129 newMmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2130 }
2131 else
2132 {
2133 newMmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
2134 newMmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
2135 newMmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
2136 }
2137 newMmd->setDefinition(md->definition());
2138 applyMemberOverrideOptions(root,newMmd);
2139 newMmd->addQualifiers(root->qualifiers);
2140 newMmd->setBitfields(md->bitfieldString());
2141 newMmd->addSectionsToDefinition(root->anchors);
2142 newMmd->setBodySegment(md->getDefLine(),md->getStartBodyLine(),md->getEndBodyLine());
2143 newMmd->setBodyDef(md->getBodyDef());
2144 newMmd->setInitializer(md->initializer());
2145 newMmd->setRequiresClause(md->requiresClause());
2146 newMmd->setMaxInitLines(md->initializerLines());
2147 newMmd->setMemberGroupId(root->mGrpId);
2148 newMmd->setMemberSpecifiers(md->getMemberSpecifiers());
2149 newMmd->setVhdlSpecifiers(md->getVhdlSpecifiers());
2150 newMmd->setLanguage(root->lang);
2151 newMmd->setId(root->id);
2152 MemberName *mn = Doxygen::memberNameLinkedMap->add(memName);
2153 mn->push_back(std::move(newMd));
2154}
virtual int inbodyLine() 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().

◆ devUsage()

void devUsage ( )
static

Definition at line 11213 of file doxygen.cpp.

11214{
11216 msg("Developer parameters:\n");
11217 msg(" -m dump symbol map\n");
11218 msg(" -b making messages output unbuffered\n");
11219 msg(" -c <file> process input file as a comment block and produce HTML output\n");
11220#if ENABLE_TRACING
11221 msg(" -t [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout)\n");
11222 msg(" -t_time [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout),\n"
11223 " and include time and thread information\n");
11224#endif
11225 msg(" -d <level> enable a debug level, such as (multiple invocations of -d are possible):\n");
11227}
@ Time
Definition debug.h:35
static void printFlags()
Definition debug.cpp:137
static void clearFlag(const DebugMask mask)
Definition debug.cpp:122

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

Referenced by readConfiguration().

◆ distributeClassGroupRelations()

void distributeClassGroupRelations ( )

Definition at line 1446 of file doxygen.cpp.

1447{
1448 //bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
1449 //if (!inlineGroupedClasses) return;
1450 //printf("** distributeClassGroupRelations()\n");
1451
1452 ClassDefSet visitedClasses;
1453 for (const auto &cd : *Doxygen::classLinkedMap)
1454 {
1455 //printf("Checking %s\n",qPrint(cd->name()));
1456 // distribute the group to nested classes as well
1457 if (visitedClasses.find(cd.get())==visitedClasses.end() && !cd->partOfGroups().empty())
1458 {
1459 //printf(" Candidate for merging\n");
1460 GroupDef *gd = cd->partOfGroups().front();
1461 for (auto &ncd : cd->getClasses())
1462 {
1464 if (ncdm && ncdm->partOfGroups().empty())
1465 {
1466 //printf(" Adding %s to group '%s'\n",qPrint(ncd->name()),
1467 // gd->groupTitle());
1468 ncdm->makePartOfGroup(gd);
1469 gd->addClass(ncdm);
1470 }
1471 }
1472 visitedClasses.insert(cd.get()); // only visit every class once
1473 }
1474 }
1475}
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 1298 of file doxygen.cpp.

1299{
1300 AUTO_TRACE();
1301 for (const auto &cd : *Doxygen::conceptLinkedMap)
1302 {
1303 if (cd->groupId()!=DOX_NOGROUP)
1304 {
1305 for (const auto &ocd : *Doxygen::conceptLinkedMap)
1306 {
1307 if (cd!=ocd && cd->groupId()==ocd->groupId() &&
1308 !cd->partOfGroups().empty() && ocd->partOfGroups().empty())
1309 {
1310 ConceptDefMutable *ocdm = toConceptDefMutable(ocd.get());
1311 if (ocdm)
1312 {
1313 for (const auto &gd : cd->partOfGroups())
1314 {
1315 if (gd)
1316 {
1317 AUTO_TRACE_ADD("making concept '{}' part of group '{}'",ocdm->name(),gd->name());
1318 ocdm->makePartOfGroup(gd);
1319 gd->addConcept(ocd.get());
1320 }
1321 }
1322 }
1323 }
1324 }
1325 }
1326 }
1327}
#define DOX_NOGROUP
Definition membergroup.h:26

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

Referenced by parseInput().

◆ distributeMemberGroupDocumentation()

void distributeMemberGroupDocumentation ( )
static

Definition at line 9252 of file doxygen.cpp.

9253{
9254 // for each class
9255 for (const auto &cd : *Doxygen::classLinkedMap)
9256 {
9257 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9258 if (cdm)
9259 {
9261 }
9262 }
9263 // for each file
9264 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9265 {
9266 for (const auto &fd : *fn)
9267 {
9268 fd->distributeMemberGroupDocumentation();
9269 }
9270 }
9271 // for each namespace
9272 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9273 {
9275 if (ndm)
9276 {
9278 }
9279 }
9280 // for each group
9281 for (const auto &gd : *Doxygen::groupLinkedMap)
9282 {
9283 gd->distributeMemberGroupDocumentation();
9284 }
9286}
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 11172 of file doxygen.cpp.

11173{
11174 QCString anchor;
11176 {
11177 MemberDef *md = toMemberDef(d);
11178 anchor=":"+md->anchor();
11179 }
11180 QCString scope;
11181 QCString fn = d->getOutputFileBase();
11184 {
11185 scope = fn;
11186 }
11187 t << "REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
11188 << fn+anchor << "','"
11189 << scope << "','"
11190 << d->name() << "','"
11191 << d->getDefFileName() << "','"
11192 << d->getDefLine()
11193 << "');\n";
11194}
virtual QCString anchor() const =0
virtual QCString getOutputFileBase() const =0
MemberDef * toMemberDef(Definition *d)
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:4823

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

11197{
11198 std::ofstream f = Portable::openOutputStream("symbols.sql");
11199 if (f.is_open())
11200 {
11201 TextStream t(&f);
11202 for (const auto &[name,symList] : *Doxygen::symbolMap)
11203 {
11204 for (const auto &def : symList)
11205 {
11206 dumpSymbol(t,def);
11207 }
11208 }
11209 }
11210}
static void dumpSymbol(TextStream &t, Definition *d)
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:649

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

Referenced by generateOutput().

◆ exitDoxygen()

void exitDoxygen ( )
staticnoexcept

Definition at line 12111 of file doxygen.cpp.

12112{
12113 if (!g_successfulRun) // premature exit
12114 {
12115 Dir thisDir;
12116 msg("Exiting...\n");
12117 if (!Doxygen::filterDBFileName.isEmpty())
12118 {
12119 thisDir.remove(Doxygen::filterDBFileName.str());
12120 }
12121 }
12122}
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:314
static QCString filterDBFileName
Definition doxygen.h:133
static bool g_successfulRun
Definition doxygen.cpp:190

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

Referenced by parseInput().

◆ extractClassName()

QCString extractClassName ( const Entry * root)
static

Definition at line 5215 of file doxygen.cpp.

5216{
5217 // strip any anonymous scopes first
5220 int i=0;
5221 if ((root->lang==SrcLangExt::CSharp || root->lang==SrcLangExt::Java) &&
5222 (i=bName.find('<'))!=-1)
5223 {
5224 // a Java/C# generic class looks like a C++ specialization, so we need to strip the
5225 // template part before looking for matches
5226 if (root->lang==SrcLangExt::CSharp)
5227 {
5228 bName = mangleCSharpGenericName(root->name);
5229 }
5230 else
5231 {
5232 bName = bName.left(i);
5233 }
5234 }
5235 return bName;
5236}

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

7272{
7273 AUTO_TRACE("root->type='{}' root->inside='{}' root->name='{}' root->args='{}' section={} root->spec={} root->mGrpId={}",
7274 root->type,root->inside,root->name,root->args,root->section,root->spec,root->mGrpId);
7275 //printf("root->parent()->name=%s\n",qPrint(root->parent()->name));
7276 bool isFunc=TRUE;
7277
7278 QCString type = root->type;
7279 QCString args = root->args;
7280 int i=-1, l=0;
7281 if ( // detect func variable/typedef to func ptr
7282 (i=findFunctionPtr(type.str(),root->lang,&l))!=-1
7283 )
7284 {
7285 //printf("Fixing function pointer!\n");
7286 // fix type and argument
7287 args.prepend(type.right(type.length()-i-l));
7288 type=type.left(i+l);
7289 //printf("Results type=%s,name=%s,args=%s\n",qPrint(type),qPrint(root->name),qPrint(args));
7290 isFunc=FALSE;
7291 }
7292 else if ((type.startsWith("typedef ") && args.find('(')!=-1))
7293 // detect function types marked as functions
7294 {
7295 isFunc=FALSE;
7296 }
7297
7298 //printf("Member %s isFunc=%d\n",qPrint(root->name),isFunc);
7299 if (root->section.isMemberDoc())
7300 {
7301 //printf("Documentation for inline member '%s' found args='%s'\n",
7302 // qPrint(root->name),qPrint(args));
7303 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7304 if (type.isEmpty())
7305 {
7306 findMember(root,
7307 relates,
7308 type,
7309 args,
7310 root->name + args + root->exception,
7311 FALSE,
7312 isFunc);
7313 }
7314 else
7315 {
7316 findMember(root,
7317 relates,
7318 type,
7319 args,
7320 type + " " + root->name + args + root->exception,
7321 FALSE,
7322 isFunc);
7323 }
7324 }
7325 else if (root->section.isOverloadDoc())
7326 {
7327 //printf("Overloaded member %s found\n",qPrint(root->name));
7328 findMember(root,
7329 relates,
7330 type,
7331 args,
7332 root->name,
7333 TRUE,
7334 isFunc);
7335 }
7336 else if
7337 ((root->section.isFunction() // function
7338 ||
7339 (root->section.isVariable() && // variable
7340 !type.isEmpty() && // with a type
7341 g_compoundKeywords.find(type.str())==g_compoundKeywords.end() // that is not a keyword
7342 // (to skip forward declaration of class etc.)
7343 )
7344 )
7345 )
7346 {
7347 //printf("Documentation for member '%s' found args='%s' excp='%s'\n",
7348 // qPrint(root->name),qPrint(args),qPrint(root->exception));
7349 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7350 //printf("Inside=%s\n Relates=%s\n",qPrint(root->inside),qPrint(relates));
7351 if (type=="friend class" || type=="friend struct" ||
7352 type=="friend union")
7353 {
7354 findMember(root,
7355 relates,
7356 type,
7357 args,
7358 type+" "+root->name,
7359 FALSE,FALSE);
7360
7361 }
7362 else if (!type.isEmpty())
7363 {
7364 findMember(root,
7365 relates,
7366 type,
7367 args,
7368 type+" "+ root->inside + root->name + args + root->exception,
7369 FALSE,isFunc);
7370 }
7371 else
7372 {
7373 findMember(root,
7374 relates,
7375 type,
7376 args,
7377 root->inside + root->name + args + root->exception,
7378 FALSE,isFunc);
7379 }
7380 }
7381 else if (root->section.isDefine() && !relates.isEmpty())
7382 {
7383 findMember(root,
7384 relates,
7385 type,
7386 args,
7387 root->name + args,
7388 FALSE,
7389 !args.isEmpty());
7390 }
7391 else if (root->section.isVariableDoc())
7392 {
7393 //printf("Documentation for variable %s found\n",qPrint(root->name));
7394 //if (!relates.isEmpty()) printf(" Relates %s\n",qPrint(relates));
7395 findMember(root,
7396 relates,
7397 type,
7398 args,
7399 root->name,
7400 FALSE,
7401 FALSE);
7402 }
7403 else if (root->section.isExportedInterface() ||
7404 root->section.isIncludedService())
7405 {
7406 findMember(root,
7407 relates,
7408 type,
7409 args,
7410 type + " " + root->name,
7411 FALSE,
7412 FALSE);
7413 }
7414 else
7415 {
7416 // skip section
7417 //printf("skip section\n");
7418 }
7419}
QCString inside
name of the class in which documents are found
Definition entry.h:213
static void findMember(const Entry *root, const QCString &relates, const QCString &type, const QCString &args, QCString funcDecl, bool overloaded, bool isFunc)
Definition doxygen.cpp:6646

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

4679{
4680 AUTO_TRACE("name={}",root->name);
4681 // The base class could ofcouse also be a non-nested class
4682 const ArgumentList &formalArgs = masterCd->templateArguments();
4683 for (const BaseInfo &bi : root->extends)
4684 {
4685 //printf("masterCd=%s bi.name='%s' #actualArgs=%d\n",
4686 // qPrint(masterCd->localName()),qPrint(bi.name),actualArgs ? (int)actualArgs->size() : -1);
4687 TemplateNameMap formTemplateNames;
4688 if (templateNames.empty())
4689 {
4690 formTemplateNames = getTemplateArgumentsInName(formalArgs,bi.name.str());
4691 }
4692 BaseInfo tbi = bi;
4693 tbi.name = substituteTemplateArgumentsInString(bi.name,formalArgs,actualArgs);
4694 //printf("masterCd=%p instanceCd=%p bi->name=%s tbi.name=%s\n",(void*)masterCd,(void*)instanceCd,qPrint(bi.name),qPrint(tbi.name));
4695
4696 if (mode==DocumentedOnly)
4697 {
4698 // find a documented base class in the correct scope
4699 if (!findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,DocumentedOnly,isArtificial))
4700 {
4701 // 1.8.2: decided to show inheritance relations even if not documented,
4702 // we do make them artificial, so they do not appear in the index
4703 //if (!Config_getBool(HIDE_UNDOC_RELATIONS))
4704 bool b = Config_getBool(HIDE_UNDOC_RELATIONS) ? TRUE : isArtificial;
4705 //{
4706 // no documented base class -> try to find an undocumented one
4707 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,Undocumented,b);
4708 //}
4709 }
4710 }
4711 else if (mode==TemplateInstances)
4712 {
4713 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,TemplateInstances,isArtificial);
4714 }
4715 }
4716}

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

5675{
5676 SymbolResolver resolver(fd);
5677 const ClassDef *tcd = resolver.resolveClass(nd,scopeName,true,true);
5678 //printf("findClassDefinition(fd=%s,ns=%s,scopeName=%s)='%s'\n",
5679 // qPrint(fd?fd->name():""),qPrint(nd?nd->name():""),
5680 // qPrint(scopeName),qPrint(tcd?tcd->name():""));
5681 return tcd;
5682}

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

5207{
5208 if (isClassSection(root))
5209 {
5210 g_classEntries.emplace(root->name.str(),root);
5211 }
5212 for (const auto &e : root->children()) findClassEntries(e.get());
5213}
static void findClassEntries(const Entry *root)
Definition doxygen.cpp:5206
static bool isClassSection(const Entry *root)
Definition doxygen.cpp:5184

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

4852{
4853 AUTO_TRACE("name={} base={} isArtificial={} mode={}",cd->name(),bi->name,isArtificial,(int)mode);
4854
4855 QCString biName=bi->name;
4856 bool explicitGlobalScope=FALSE;
4857 if (biName.startsWith("::")) // explicit global scope
4858 {
4859 biName=biName.right(biName.length()-2);
4860 explicitGlobalScope=TRUE;
4861 }
4862
4863 Entry *parentNode=root->parent();
4864 bool lastParent=FALSE;
4865 do // for each parent scope, starting with the largest scope
4866 // (in case of nested classes)
4867 {
4868 QCString scopeName= parentNode ? parentNode->name : QCString();
4869 int scopeOffset=explicitGlobalScope ? 0 : static_cast<int>(scopeName.length());
4870 do // try all parent scope prefixes, starting with the largest scope
4871 {
4872 //printf("scopePrefix='%s' biName='%s'\n",
4873 // qPrint(scopeName.left(scopeOffset)),qPrint(biName));
4874
4875 QCString baseClassName=biName;
4876 if (scopeOffset>0)
4877 {
4878 baseClassName.prepend(scopeName.left(scopeOffset)+"::");
4879 }
4880 if (root->lang==SrcLangExt::CSharp)
4881 {
4882 baseClassName = mangleCSharpGenericName(baseClassName);
4883 }
4884 AUTO_TRACE_ADD("cd='{}' baseClassName='{}'",cd->name(),baseClassName);
4885 SymbolResolver resolver(cd->getFileDef());
4886 ClassDefMutable *baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
4887 baseClassName,
4888 mode==Undocumented,
4889 true
4890 );
4891 const MemberDef *baseClassTypeDef = resolver.getTypedef();
4892 QCString templSpec = resolver.getTemplateSpec();
4893 //printf("baseClassName=%s baseClass=%p cd=%p explicitGlobalScope=%d\n",
4894 // qPrint(baseClassName),baseClass,cd,explicitGlobalScope);
4895 //printf(" scope='%s' baseClassName='%s' baseClass=%s templSpec=%s\n",
4896 // cd ? qPrint(cd->name()):"<none>",
4897 // qPrint(baseClassName),
4898 // baseClass?qPrint(baseClass->name()):"<none>",
4899 // qPrint(templSpec)
4900 // );
4901 //if (baseClassName.left(root->name.length())!=root->name ||
4902 // baseClassName.at(root->name.length())!='<'
4903 // ) // Check for base class with the same name.
4904 // // If found then look in the outer scope for a match
4905 // // and prevent recursion.
4906 if (!isRecursiveBaseClass(root->name,baseClassName)
4907 || explicitGlobalScope
4908 // sadly isRecursiveBaseClass always true for UNO IDL ifc/svc members
4909 // (i.e. this is needed for addInterfaceOrServiceToServiceOrSingleton)
4910 || (root->lang==SrcLangExt::IDL &&
4911 (root->section.isExportedInterface() ||
4912 root->section.isIncludedService()))
4913 )
4914 {
4915 AUTO_TRACE_ADD("class relation '{}' inherited/used by '{}' found prot={} virt={} templSpec='{}'",
4916 baseClassName, root->name, bi->prot, bi->virt, templSpec);
4917
4918 int i=findTemplateSpecializationPosition(baseClassName);
4919 int si=baseClassName.findRev("::",i);
4920 if (si==-1) si=0;
4921 if (baseClass==nullptr && static_cast<size_t>(i)!=baseClassName.length())
4922 // base class has template specifiers
4923 {
4924 // TODO: here we should try to find the correct template specialization
4925 // but for now, we only look for the unspecialized base class.
4926 int e=findEndOfTemplate(baseClassName,i+1);
4927 //printf("baseClass==0 i=%d e=%d\n",i,e);
4928 if (e!=-1) // end of template was found at e
4929 {
4930 templSpec = removeRedundantWhiteSpace(baseClassName.mid(i,e-i));
4931 baseClassName = baseClassName.left(i)+baseClassName.right(baseClassName.length()-e);
4932 baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
4933 baseClassName,
4934 mode==Undocumented,
4935 true
4936 );
4937 baseClassTypeDef = resolver.getTypedef();
4938 //printf("baseClass=%p -> baseClass=%s templSpec=%s\n",
4939 // baseClass,qPrint(baseClassName),qPrint(templSpec));
4940 }
4941 }
4942 else if (baseClass && !templSpec.isEmpty()) // we have a known class, but also
4943 // know it is a template, so see if
4944 // we can also link to the explicit
4945 // instance (for instance if a class
4946 // derived from a template argument)
4947 {
4948 //printf("baseClass=%s templSpec=%s\n",qPrint(baseClass->name()),qPrint(templSpec));
4949 ClassDefMutable *templClass=getClassMutable(baseClass->name()+templSpec);
4950 if (templClass)
4951 {
4952 // use the template instance instead of the template base.
4953 baseClass = templClass;
4954 templSpec.clear();
4955 }
4956 }
4957
4958 //printf("cd=%p baseClass=%p\n",cd,baseClass);
4959 bool found=baseClass!=nullptr && (baseClass!=cd || mode==TemplateInstances);
4960 AUTO_TRACE_ADD("1. found={}",found);
4961 if (!found && si!=-1)
4962 {
4963 // replace any namespace aliases
4964 replaceNamespaceAliases(baseClassName);
4965 baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
4966 baseClassName,
4967 mode==Undocumented,
4968 true
4969 );
4970 baseClassTypeDef = resolver.getTypedef();
4971 found=baseClass!=nullptr && baseClass!=cd;
4972 if (found) templSpec = resolver.getTemplateSpec();
4973 }
4974 AUTO_TRACE_ADD("2. found={}",found);
4975
4976 if (!found)
4977 {
4978 baseClass=toClassDefMutable(findClassWithinClassContext(context,cd,baseClassName));
4979 //printf("findClassWithinClassContext(%s,%s)=%p\n",
4980 // qPrint(cd->name()),qPrint(baseClassName),baseClass);
4981 found = baseClass!=nullptr && baseClass!=cd;
4982
4983 }
4984 AUTO_TRACE_ADD("3. found={}",found);
4985 if (!found)
4986 {
4987 // for PHP the "use A\B as C" construct map class C to A::B, so we lookup
4988 // the class name also in the alias mapping.
4989 auto it = Doxygen::namespaceAliasMap.find(baseClassName.str());
4990 if (it!=Doxygen::namespaceAliasMap.end()) // see if it is indeed a class.
4991 {
4992 baseClass=getClassMutable(it->second.alias);
4993 found = baseClass!=nullptr && baseClass!=cd;
4994 }
4995 }
4996 bool isATemplateArgument = templateNames.find(biName.str())!=templateNames.end();
4997
4998 AUTO_TRACE_ADD("4. found={}",found);
4999 if (found)
5000 {
5001 AUTO_TRACE_ADD("Documented base class '{}' templSpec='{}'",biName,templSpec);
5002 // add base class to this class
5003
5004 // if templSpec is not empty then we should "instantiate"
5005 // the template baseClass. A new ClassDef should be created
5006 // to represent the instance. To be able to add the (instantiated)
5007 // members and documentation of a template class
5008 // (inserted in that template class at a later stage),
5009 // the template should know about its instances.
5010 // the instantiation process, should be done in a recursive way,
5011 // since instantiating a template may introduce new inheritance
5012 // relations.
5013 if (!templSpec.isEmpty() && mode==TemplateInstances)
5014 {
5015 // if baseClass is actually a typedef then we should not
5016 // instantiate it, since typedefs are in a different namespace
5017 // see bug531637 for an example where this would otherwise hang
5018 // Doxygen
5019 if (baseClassTypeDef==nullptr)
5020 {
5021 //printf(" => findTemplateInstanceRelation: %s\n",qPrint(baseClass->name()));
5022 findTemplateInstanceRelation(root,context,baseClass,templSpec,templateNames,baseClass->isArtificial());
5023 }
5024 }
5025 else if (mode==DocumentedOnly || mode==Undocumented)
5026 {
5027 //printf(" => insert base class\n");
5028 QCString usedName;
5029 if (baseClassTypeDef)
5030 {
5031 usedName=biName;
5032 //printf("***** usedName=%s templSpec=%s\n",qPrint(usedName),qPrint(templSpec));
5033 }
5034 Protection prot = bi->prot;
5035 if (Config_getBool(SIP_SUPPORT)) prot=Protection::Public;
5036 if (cd!=baseClass && !cd->isSubClass(baseClass) && baseClass->isBaseClass(cd,true,templSpec)==0) // check for recursion, see bug690787
5037 {
5038 AUTO_TRACE_ADD("insertBaseClass name={} prot={} virt={} templSpec={}",usedName,prot,bi->virt,templSpec);
5039 cd->insertBaseClass(baseClass,usedName,prot,bi->virt,templSpec);
5040 // add this class as super class to the base class
5041 baseClass->insertSubClass(cd,prot,bi->virt,templSpec);
5042 }
5043 else
5044 {
5045 warn(root->fileName,root->startLine,
5046 "Detected potential recursive class relation "
5047 "between class {} and base class {}!",
5048 cd->name(),baseClass->name()
5049 );
5050 }
5051 }
5052 return TRUE;
5053 }
5054 else if (mode==Undocumented && (scopeOffset==0 || isATemplateArgument))
5055 {
5056 AUTO_TRACE_ADD("New undocumented base class '{}' baseClassName='{}' templSpec='{}' isArtificial={}",
5057 biName,baseClassName,templSpec,isArtificial);
5058 baseClass=nullptr;
5059 if (isATemplateArgument)
5060 {
5061 baseClass = toClassDefMutable(Doxygen::hiddenClassLinkedMap->find(baseClassName));
5062 if (baseClass==nullptr) // not found (or alias)
5063 {
5064 baseClass= toClassDefMutable(
5065 Doxygen::hiddenClassLinkedMap->add(baseClassName,
5066 createClassDef(root->fileName,root->startLine,root->startColumn,
5067 baseClassName,
5068 ClassDef::Class)));
5069 if (baseClass) // really added (not alias)
5070 {
5071 if (isArtificial) baseClass->setArtificial(TRUE);
5072 baseClass->setLanguage(root->lang);
5073 }
5074 }
5075 }
5076 else
5077 {
5078 baseClass = toClassDefMutable(Doxygen::classLinkedMap->find(baseClassName));
5079 //printf("*** classDDict->find(%s)=%p biName=%s templSpec=%s\n",
5080 // qPrint(baseClassName),baseClass,qPrint(biName),qPrint(templSpec));
5081 if (baseClass==nullptr) // not found (or alias)
5082 {
5083 baseClass = toClassDefMutable(
5084 Doxygen::classLinkedMap->add(baseClassName,
5085 createClassDef(root->fileName,root->startLine,root->startColumn,
5086 baseClassName,
5087 ClassDef::Class)));
5088 if (baseClass) // really added (not alias)
5089 {
5090 if (isArtificial) baseClass->setArtificial(TRUE);
5091 baseClass->setLanguage(root->lang);
5092 si = baseClassName.findRev("::");
5093 if (si!=-1) // class is nested
5094 {
5095 Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),nullptr,root->tagInfo());
5096 if (sd==nullptr || sd==Doxygen::globalScope) // outer scope not found
5097 {
5098 baseClass->setArtificial(TRUE); // see bug678139
5099 }
5100 }
5101 }
5102 }
5103 }
5104 if (baseClass)
5105 {
5106 if (biName.endsWith("-p"))
5107 {
5108 biName="<"+biName.left(biName.length()-2)+">";
5109 }
5110 if (!cd->isSubClass(baseClass) && cd!=baseClass && cd->isBaseClass(baseClass,true,templSpec)==0) // check for recursion
5111 {
5112 AUTO_TRACE_ADD("insertBaseClass name={} prot={} virt={} templSpec={}",biName,bi->prot,bi->virt,templSpec);
5113 // add base class to this class
5114 cd->insertBaseClass(baseClass,biName,bi->prot,bi->virt,templSpec);
5115 // add this class as super class to the base class
5116 baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
5117 }
5118 // the undocumented base was found in this file
5119 baseClass->insertUsedFile(root->fileDef());
5120
5121 Definition *scope = buildScopeFromQualifiedName(baseClass->name(),root->lang,nullptr);
5122 if (scope!=baseClass)
5123 {
5124 baseClass->setOuterScope(scope);
5125 }
5126
5127 if (baseClassName.endsWith("-p"))
5128 {
5130 }
5131 return TRUE;
5132 }
5133 else
5134 {
5135 AUTO_TRACE_ADD("Base class '{}' not created (alias?)",biName);
5136 }
5137 }
5138 else
5139 {
5140 AUTO_TRACE_ADD("Base class '{}' not found",biName);
5141 }
5142 }
5143 else
5144 {
5145 if (mode!=TemplateInstances)
5146 {
5147 warn(root->fileName,root->startLine,
5148 "Detected potential recursive class relation "
5149 "between class {} and base class {}!",
5150 root->name,baseClassName
5151 );
5152 }
5153 // for mode==TemplateInstance this case is quite common and
5154 // indicates a relation between a template class and a template
5155 // instance with the same name.
5156 }
5157 if (scopeOffset==0)
5158 {
5159 scopeOffset=-1;
5160 }
5161 else if ((scopeOffset=scopeName.findRev("::",scopeOffset-1))==-1)
5162 {
5163 scopeOffset=0;
5164 }
5165 //printf("new scopeOffset='%d'",scopeOffset);
5166 } while (scopeOffset>=0);
5167
5168 if (parentNode==nullptr)
5169 {
5170 lastParent=TRUE;
5171 }
5172 else
5173 {
5174 parentNode=parentNode->parent();
5175 }
5176 } while (lastParent);
5177
5178 return FALSE;
5179}
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 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:182
static bool isRecursiveBaseClass(const QCString &scope, const QCString &name)
Definition doxygen.cpp:4801
static void findTemplateInstanceRelation(const Entry *root, Definition *context, ClassDefMutable *templateClass, const QCString &templSpec, const TemplateNameMap &templateNames, bool isArtificial)
Definition doxygen.cpp:4720
static ClassDef * findClassWithinClassContext(Definition *context, ClassDef *cd, const QCString &name)
Definition doxygen.cpp:4476
static int findTemplateSpecializationPosition(const QCString &name)
Definition doxygen.cpp:4813
void replaceNamespaceAliases(QCString &name)
Protection prot
inheritance type
Definition entry.h:95
Specifier virt
virtualness
Definition entry.h:96
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 4476 of file doxygen.cpp.

4477{
4478 ClassDef *result=nullptr;
4479 if (cd==nullptr)
4480 {
4481 return result;
4482 }
4483 FileDef *fd=cd->getFileDef();
4484 SymbolResolver resolver(fd);
4485 if (context && cd!=context)
4486 {
4487 result = const_cast<ClassDef*>(resolver.resolveClass(context,name,true,true));
4488 }
4489 //printf("1. result=%p\n",result);
4490 if (result==nullptr)
4491 {
4492 result = const_cast<ClassDef*>(resolver.resolveClass(cd,name,true,true));
4493 }
4494 //printf("2. result=%p\n",result);
4495 if (result==nullptr) // try direct class, needed for namespaced classes imported via tag files (see bug624095)
4496 {
4497 result = getClass(name);
4498 }
4499 //printf("3. result=%p\n",result);
4500 //printf("** Trying to find %s within context %s class %s result=%s lookup=%p\n",
4501 // qPrint(name),
4502 // context ? qPrint(context->name()) : "<none>",
4503 // cd ? qPrint(cd->name()) : "<none>",
4504 // result ? qPrint(result->name()) : "<none>",
4505 // Doxygen::classLinkedMap->find(name)
4506 // );
4507 return result;
4508}

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

Referenced by findClassRelation(), and findUsedClassesForClass().

◆ findDefineDocumentation()

void findDefineDocumentation ( Entry * root)
static

Definition at line 9501 of file doxygen.cpp.

9502{
9503 if ((root->section.isDefineDoc() || root->section.isDefine()) && !root->name.isEmpty())
9504 {
9505 //printf("found define '%s' '%s' brief='%s' doc='%s'\n",
9506 // qPrint(root->name),qPrint(root->args),qPrint(root->brief),qPrint(root->doc));
9507
9508 if (root->tagInfo() && !root->name.isEmpty()) // define read from a tag file
9509 {
9510 auto md = createMemberDef(root->tagInfo()->tagName,1,1,
9511 "#define",root->name,root->args,QCString(),
9512 Protection::Public,Specifier::Normal,FALSE,Relationship::Member,MemberType::Define,
9513 ArgumentList(),ArgumentList(),"");
9514 auto mmd = toMemberDefMutable(md.get());
9515 mmd->setTagInfo(root->tagInfo());
9516 mmd->setLanguage(root->lang);
9517 mmd->addQualifiers(root->qualifiers);
9518 //printf("Searching for '%s' fd=%p\n",qPrint(filePathName),fd);
9519 mmd->setFileDef(root->parent()->fileDef());
9520 //printf("Adding member=%s\n",qPrint(md->name()));
9522 mn->push_back(std::move(md));
9523 }
9525 if (mn)
9526 {
9527 int count=0;
9528 for (const auto &md : *mn)
9529 {
9530 if (md->memberType()==MemberType::Define) count++;
9531 }
9532 if (count==1)
9533 {
9534 for (const auto &imd : *mn)
9535 {
9536 MemberDefMutable *md = toMemberDefMutable(imd.get());
9537 if (md && md->memberType()==MemberType::Define)
9538 {
9539 addDefineDoc(root,md);
9540 }
9541 }
9542 }
9543 else if (count>1 &&
9544 (!root->doc.isEmpty() ||
9545 !root->brief.isEmpty() ||
9546 root->bodyLine!=-1
9547 )
9548 )
9549 // multiple defines don't know where to add docs
9550 // but maybe they are in different files together with their documentation
9551 {
9552 for (const auto &imd : *mn)
9553 {
9554 MemberDefMutable *md = toMemberDefMutable(imd.get());
9555 if (md && md->memberType()==MemberType::Define)
9556 {
9557 if (haveEqualFileNames(root, md) || isEntryInGroupOfMember(root, md))
9558 // doc and define in the same file or group assume they belong together.
9559 {
9560 addDefineDoc(root,md);
9561 }
9562 }
9563 }
9564 //warn("define {} found in the following files:\n",root->name);
9565 //warn("Cannot determine where to add the documentation found "
9566 // "at line {} of file {}. \n",
9567 // root->startLine,root->fileName);
9568 }
9569 }
9570 else if (!root->doc.isEmpty() || !root->brief.isEmpty()) // define not found
9571 {
9572 bool preEnabled = Config_getBool(ENABLE_PREPROCESSING);
9573 if (preEnabled)
9574 {
9575 warn(root->fileName,root->startLine,"documentation for unknown define {} found.",root->name);
9576 }
9577 else
9578 {
9579 warn(root->fileName,root->startLine, "found documented #define {} but ignoring it because ENABLE_PREPROCESSING is NO.", root->name);
9580 }
9581 }
9582 }
9583 for (const auto &e : root->children()) findDefineDocumentation(e.get());
9584}
static void findDefineDocumentation(Entry *root)
Definition doxygen.cpp:9501
static void addDefineDoc(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:9475
static bool haveEqualFileNames(const Entry *root, const MemberDef *md)
Definition doxygen.cpp:9462
static bool isEntryInGroupOfMember(const Entry *root, const MemberDef *md, bool allowNoGroup=false)
Definition doxygen.cpp:5688

References addDefineDoc(), Entry::args, Entry::bodyLine, Entry::brief, Entry::children(), Config_getBool, createMemberDef(), Define, 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 8063 of file doxygen.cpp.

8064{
8065 // for each member name
8066 for (const auto &mn : mnsd)
8067 {
8068 // for each member definition
8069 for (const auto &imd : *mn)
8070 {
8071 MemberDefMutable *md = toMemberDefMutable(imd.get());
8072 if (md && md->isEnumerate()) // member is an enum
8073 {
8074 int documentedEnumValues=0;
8075 // for each enum value
8076 for (const auto &fmd : md->enumFieldList())
8077 {
8078 if (fmd->isLinkableInProject()) documentedEnumValues++;
8079 }
8080 // at least one enum value is documented
8081 if (documentedEnumValues>0) md->setDocumentedEnumValues(TRUE);
8082 }
8083 }
8084 }
8085}
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 9588 of file doxygen.cpp.

9589{
9590 if (root->section.isDirDoc())
9591 {
9592 QCString normalizedName = root->name;
9593 normalizedName = substitute(normalizedName,"\\","/");
9594 //printf("root->docFile=%s normalizedName=%s\n",
9595 // qPrint(root->docFile),qPrint(normalizedName));
9596 if (root->docFile==normalizedName) // current dir?
9597 {
9598 int lastSlashPos=normalizedName.findRev('/');
9599 if (lastSlashPos!=-1) // strip file name
9600 {
9601 normalizedName=normalizedName.left(lastSlashPos);
9602 }
9603 }
9604 if (normalizedName.at(normalizedName.length()-1)!='/')
9605 {
9606 normalizedName+='/';
9607 }
9608 DirDef *matchingDir=nullptr;
9609 for (const auto &dir : *Doxygen::dirLinkedMap)
9610 {
9611 //printf("Dir: %s<->%s\n",qPrint(dir->name()),qPrint(normalizedName));
9612 if (dir->name().right(normalizedName.length())==normalizedName)
9613 {
9614 if (matchingDir)
9615 {
9616 warn(root->fileName,root->startLine,
9617 "\\dir command matches multiple directories.\n"
9618 " Applying the command for directory {}\n"
9619 " Ignoring the command for directory {}",
9620 matchingDir->name(),dir->name()
9621 );
9622 }
9623 else
9624 {
9625 matchingDir=dir.get();
9626 }
9627 }
9628 }
9629 if (matchingDir)
9630 {
9631 //printf("Match for with dir %s #anchor=%zu\n",qPrint(matchingDir->name()),root->anchors.size());
9632 matchingDir->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9633 matchingDir->setDocumentation(root->doc,root->docFile,root->docLine);
9634 matchingDir->setRefItems(root->sli);
9635 matchingDir->addSectionsToDefinition(root->anchors);
9636 root->commandOverrides.apply_directoryGraph([&](bool b) { matchingDir->overrideDirectoryGraph(b); });
9637 addDirToGroups(root,matchingDir);
9638 }
9639 else
9640 {
9641 warn(root->fileName,root->startLine,"No matching directory found for command \\dir {}",normalizedName);
9642 }
9643 }
9644 for (const auto &e : root->children()) findDirDocumentation(e.get());
9645}
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:9588
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::section, DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), DefinitionMutable::setRefItems(), Entry::sli, Entry::startLine, substitute(), and warn.

Referenced by findDirDocumentation(), and parseInput().

◆ findDocumentedEnumValues()

void findDocumentedEnumValues ( )
static

Definition at line 8089 of file doxygen.cpp.

8090{
8093}
static void findDEV(const MemberNameLinkedMap &mnsd)
Definition doxygen.cpp:8063

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

3030{
3031 // locate end of template
3032 size_t e=startPos;
3033 int brCount=1;
3034 int roundCount=0;
3035 size_t len = s.length();
3036 bool insideString=FALSE;
3037 bool insideChar=FALSE;
3038 char pc = 0;
3039 while (e<len && brCount!=0)
3040 {
3041 char c=s.at(e);
3042 switch(c)
3043 {
3044 case '<':
3045 if (!insideString && !insideChar)
3046 {
3047 if (e<len-1 && s.at(e+1)=='<')
3048 e++;
3049 else if (roundCount==0)
3050 brCount++;
3051 }
3052 break;
3053 case '>':
3054 if (!insideString && !insideChar)
3055 {
3056 if (e<len-1 && s.at(e+1)=='>')
3057 e++;
3058 else if (roundCount==0)
3059 brCount--;
3060 }
3061 break;
3062 case '(':
3063 if (!insideString && !insideChar)
3064 roundCount++;
3065 break;
3066 case ')':
3067 if (!insideString && !insideChar)
3068 roundCount--;
3069 break;
3070 case '"':
3071 if (!insideChar)
3072 {
3073 if (insideString && pc!='\\')
3074 insideString=FALSE;
3075 else
3076 insideString=TRUE;
3077 }
3078 break;
3079 case '\'':
3080 if (!insideString)
3081 {
3082 if (insideChar && pc!='\\')
3083 insideChar=FALSE;
3084 else
3085 insideChar=TRUE;
3086 }
3087 break;
3088 }
3089 pc = c;
3090 e++;
3091 }
3092 return brCount==0 ? static_cast<int>(e) : -1;
3093}

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

Referenced by addVariable(), and findClassRelation().

◆ findEnumDocumentation()

void findEnumDocumentation ( const Entry * root)
static

Definition at line 7977 of file doxygen.cpp.

7978{
7979 if (root->section.isEnumDoc() &&
7980 !root->name.isEmpty() &&
7981 root->name.at(0)!='@' // skip anonymous enums
7982 )
7983 {
7984 QCString name;
7985 QCString scope;
7986 int i = root->name.findRev("::");
7987 if (i!=-1) // scope is specified as part of the name
7988 {
7989 name=root->name.right(root->name.length()-i-2); // extract name
7990 scope=root->name.left(i); // extract scope
7991 //printf("Scope='%s' Name='%s'\n",qPrint(scope),qPrint(name));
7992 }
7993 else // just the name
7994 {
7995 name=root->name;
7996 }
7997 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7998 {
7999 if (!scope.isEmpty()) scope.prepend("::");
8000 scope.prepend(root->parent()->name);
8001 }
8002 const ClassDef *cd = getClass(scope);
8003 const NamespaceDef *nd=Doxygen::namespaceLinkedMap->find(scope);
8004 const FileDef *fd = root->fileDef();
8005 AUTO_TRACE("Found docs for enum with name '{}' and scope '{}' in context '{}' cd='{}', nd='{}' fd='{}'",
8006 name,scope,root->parent()->name,
8007 cd ? cd->name() : QCString("<none>"),
8008 nd ? nd->name() : QCString("<none>"),
8009 fd ? fd->name() : QCString("<none>"));
8010
8011 if (!name.isEmpty())
8012 {
8013 bool found = tryAddEnumDocsToGroupMember(root, name);
8014 if (!found)
8015 {
8016 MemberName *mn = cd ? Doxygen::memberNameLinkedMap->find(name) : Doxygen::functionNameLinkedMap->find(name);
8017 if (mn)
8018 {
8019 for (const auto &imd : *mn)
8020 {
8021 MemberDefMutable *md = toMemberDefMutable(imd.get());
8022 if (md && md->isEnumerate())
8023 {
8024 const ClassDef *mcd = md->getClassDef();
8025 const NamespaceDef *mnd = md->getNamespaceDef();
8026 const FileDef *mfd = md->getFileDef();
8027 if (cd && mcd==cd)
8028 {
8029 AUTO_TRACE_ADD("Match found for class scope");
8030 addEnumDocs(root,md);
8031 found = TRUE;
8032 break;
8033 }
8034 else if (cd==nullptr && mcd==nullptr && nd!=nullptr && mnd==nd)
8035 {
8036 AUTO_TRACE_ADD("Match found for namespace scope");
8037 addEnumDocs(root,md);
8038 found = TRUE;
8039 break;
8040 }
8041 else if (cd==nullptr && nd==nullptr && mcd==nullptr && mnd==nullptr && fd==mfd)
8042 {
8043 AUTO_TRACE_ADD("Match found for global scope");
8044 addEnumDocs(root,md);
8045 found = TRUE;
8046 break;
8047 }
8048 }
8049 }
8050 }
8051 }
8052 if (!found)
8053 {
8054 warn(root->fileName,root->startLine, "Documentation for undefined enum '{}' found.", name);
8055 }
8056 }
8057 }
8058 for (const auto &e : root->children()) findEnumDocumentation(e.get());
8059}
static bool tryAddEnumDocsToGroupMember(const Entry *root, const QCString &name)
Definition doxygen.cpp:7944
static void addEnumDocs(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:7903
static void findEnumDocumentation(const Entry *root)
Definition doxygen.cpp:7977

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

7480{
7481 if (root->section.isEnum())
7482 {
7483 AUTO_TRACE("name={}",root->name);
7484 ClassDefMutable *cd = nullptr;
7485 FileDef *fd = nullptr;
7486 NamespaceDefMutable *nd = nullptr;
7487 MemberNameLinkedMap *mnsd = nullptr;
7488 bool isGlobal = false;
7489 bool isRelated = false;
7490 bool isMemberOf = false;
7491 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
7492
7493 QCString name;
7494 QCString scope;
7495
7496 int i = root->name.findRev("::");
7497 if (i!=-1) // scope is specified
7498 {
7499 scope=root->name.left(i); // extract scope
7500 if (root->lang==SrcLangExt::CSharp)
7501 {
7502 scope = mangleCSharpGenericName(scope);
7503 }
7504 name=root->name.right(root->name.length()-i-2); // extract name
7505 if ((cd=getClassMutable(scope))==nullptr)
7506 {
7508 }
7509 }
7510 else // no scope, check the scope in which the docs where found
7511 {
7512 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7513 {
7514 scope=root->parent()->name;
7515 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7516 }
7517 name=root->name;
7518 }
7519
7520 if (!root->relates.isEmpty())
7521 { // related member, prefix user specified scope
7522 isRelated=TRUE;
7523 isMemberOf=(root->relatesType==RelatesType::MemberOf);
7524 if (getClass(root->relates)==nullptr && !scope.isEmpty())
7525 scope=mergeScopes(scope,root->relates);
7526 else
7527 scope=root->relates;
7528 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7529 }
7530
7531 if (cd && !name.isEmpty()) // found a enum inside a compound
7532 {
7533 //printf("Enum '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
7534 fd=nullptr;
7536 isGlobal=false;
7537 }
7538 else if (nd) // found enum inside namespace
7539 {
7541 isGlobal=true;
7542 }
7543 else // found a global enum
7544 {
7545 fd=root->fileDef();
7547 isGlobal=true;
7548 }
7549
7550 if (!name.isEmpty())
7551 {
7552 // new enum type
7553 AUTO_TRACE_ADD("new enum {} at line {} of {}",name,root->bodyLine,root->fileName);
7554 auto md = createMemberDef(
7555 root->fileName,root->startLine,root->startColumn,
7556 QCString(),name,QCString(),QCString(),
7557 root->protection,Specifier::Normal,FALSE,
7558 isMemberOf ? Relationship::Foreign : isRelated ? Relationship::Related : Relationship::Member,
7561 auto mmd = toMemberDefMutable(md.get());
7562 mmd->setTagInfo(root->tagInfo());
7563 mmd->setLanguage(root->lang);
7564 mmd->setId(root->id);
7565 if (!isGlobal) mmd->setMemberClass(cd); else mmd->setFileDef(fd);
7566 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
7567 mmd->setBodyDef(root->fileDef());
7568 mmd->setMemberSpecifiers(root->spec);
7569 mmd->setVhdlSpecifiers(root->vhdlSpec);
7570 mmd->setEnumBaseType(root->args);
7571 //printf("Enum %s definition at line %d of %s: protection=%d scope=%s\n",
7572 // qPrint(root->name),root->bodyLine,qPrint(root->fileName),root->protection,cd?qPrint(cd->name()):"<none>");
7573 mmd->addSectionsToDefinition(root->anchors);
7574 mmd->setMemberGroupId(root->mGrpId);
7576 mmd->addQualifiers(root->qualifiers);
7577 //printf("%s::setRefItems(%zu)\n",qPrint(md->name()),root->sli.size());
7578 mmd->setRefItems(root->sli);
7579 //printf("found enum %s nd=%p\n",qPrint(md->name()),nd);
7580 bool defSet=FALSE;
7581
7582 QCString baseType = root->args;
7583 if (!baseType.isEmpty())
7584 {
7585 baseType.prepend(" : ");
7586 }
7587
7588 if (nd)
7589 {
7590 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES))
7591 {
7592 mmd->setDefinition(name+baseType);
7593 }
7594 else
7595 {
7596 mmd->setDefinition(nd->name()+"::"+name+baseType);
7597 }
7598 //printf("definition=%s\n",md->definition());
7599 defSet=TRUE;
7600 mmd->setNamespace(nd);
7601 nd->insertMember(md.get());
7602 }
7603
7604 // even if we have already added the enum to a namespace, we still
7605 // also want to add it to other appropriate places such as file
7606 // or class.
7607 if (isGlobal && (nd==nullptr || !nd->isAnonymous()))
7608 {
7609 if (!defSet) mmd->setDefinition(name+baseType);
7610 if (fd==nullptr && root->parent())
7611 {
7612 fd=root->parent()->fileDef();
7613 }
7614 if (fd)
7615 {
7616 mmd->setFileDef(fd);
7617 fd->insertMember(md.get());
7618 }
7619 }
7620 else if (cd)
7621 {
7622 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES))
7623 {
7624 mmd->setDefinition(name+baseType);
7625 }
7626 else
7627 {
7628 mmd->setDefinition(cd->name()+"::"+name+baseType);
7629 }
7630 cd->insertMember(md.get());
7631 cd->insertUsedFile(fd);
7632 }
7633 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
7634 mmd->setDocsForDefinition(!root->proto);
7635 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7636 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
7637
7638 //printf("Adding member=%s\n",qPrint(md->name()));
7639 addMemberToGroups(root,md.get());
7641
7642 MemberName *mn = mnsd->add(name);
7643 mn->push_back(std::move(md));
7644 }
7645 }
7646 else
7647 {
7648 for (const auto &e : root->children()) findEnums(e.get());
7649 }
7650}
static void findEnums(const Entry *root)
Definition doxygen.cpp:7479
@ Enumeration
Definition types.h:557

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, Enumeration, 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::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 4184 of file doxygen.cpp.

4185{
4186 AUTO_TRACE();
4187 for (const auto &fn : *Doxygen::functionNameLinkedMap) // for each global function name
4188 {
4189 MemberName *mn = Doxygen::memberNameLinkedMap->find(fn->memberName());
4190 if (mn)
4191 { // there are members with the same name
4192 // for each function with that name
4193 for (const auto &ifmd : *fn)
4194 {
4195 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
4196 // for each member with that name
4197 for (const auto &immd : *mn)
4198 {
4199 MemberDefMutable *mmd = toMemberDefMutable(immd.get());
4200 //printf("Checking for matching arguments
4201 // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n",
4202 // mmd->isRelated(),mmd->isFriend(),mmd->isFunction());
4203 if (fmd && mmd &&
4204 (mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) &&
4205 matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), &mmd->argumentList(),
4206 fmd->getOuterScope(), fmd->getFileDef(), &fmd->argumentList(),
4207 TRUE,mmd->getLanguage()
4208 )
4209
4210 ) // if the member is related and the arguments match then the
4211 // function is actually a friend.
4212 {
4213 AUTO_TRACE_ADD("Merging related global and member '{}' isFriend={} isRelated={} isFunction={}",
4214 mmd->name(),mmd->isFriend(),mmd->isRelated(),mmd->isFunction());
4215 const ArgumentList &mmdAl = mmd->argumentList();
4216 const ArgumentList &fmdAl = fmd->argumentList();
4217 mergeArguments(const_cast<ArgumentList&>(fmdAl),const_cast<ArgumentList&>(mmdAl));
4218
4219 // reset argument lists to add missing default parameters
4220 QCString mmdAlStr = argListToString(mmdAl);
4221 QCString fmdAlStr = argListToString(fmdAl);
4222 mmd->setArgsString(mmdAlStr);
4223 fmd->setArgsString(fmdAlStr);
4224 mmd->moveDeclArgumentList(std::make_unique<ArgumentList>(mmdAl));
4225 fmd->moveDeclArgumentList(std::make_unique<ArgumentList>(fmdAl));
4226 AUTO_TRACE_ADD("friend args='{}' member args='{}'",argListToString(fmd->argumentList()),argListToString(mmd->argumentList()));
4227
4228 if (!fmd->documentation().isEmpty())
4229 {
4230 mmd->setDocumentation(fmd->documentation(),fmd->docFile(),fmd->docLine());
4231 }
4232 else if (!mmd->documentation().isEmpty())
4233 {
4234 fmd->setDocumentation(mmd->documentation(),mmd->docFile(),mmd->docLine());
4235 }
4236 if (mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
4237 {
4238 mmd->setBriefDescription(fmd->briefDescription(),fmd->briefFile(),fmd->briefLine());
4239 }
4240 else if (!mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
4241 {
4242 fmd->setBriefDescription(mmd->briefDescription(),mmd->briefFile(),mmd->briefLine());
4243 }
4244 if (!fmd->inbodyDocumentation().isEmpty())
4245 {
4247 }
4248 else if (!mmd->inbodyDocumentation().isEmpty())
4249 {
4251 }
4252 //printf("body mmd %d fmd %d\n",mmd->getStartBodyLine(),fmd->getStartBodyLine());
4253 if (mmd->getStartBodyLine()==-1 && fmd->getStartBodyLine()!=-1)
4254 {
4255 mmd->setBodySegment(fmd->getDefLine(),fmd->getStartBodyLine(),fmd->getEndBodyLine());
4256 mmd->setBodyDef(fmd->getBodyDef());
4257 //mmd->setBodyMember(fmd);
4258 }
4259 else if (mmd->getStartBodyLine()!=-1 && fmd->getStartBodyLine()==-1)
4260 {
4261 fmd->setBodySegment(mmd->getDefLine(),mmd->getStartBodyLine(),mmd->getEndBodyLine());
4262 fmd->setBodyDef(mmd->getBodyDef());
4263 //fmd->setBodyMember(mmd);
4264 }
4266
4268
4269 mmd->addQualifiers(fmd->getQualifiers());
4270 fmd->addQualifiers(mmd->getQualifiers());
4271
4272 }
4273 }
4274 }
4275 }
4276 }
4277}
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:6771

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(), and TRUE.

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

2826{
2827 AUTO_TRACE("type='{}' lang={}",type,lang);
2828 if (lang == SrcLangExt::Fortran || lang == SrcLangExt::VHDL)
2829 {
2830 return -1; // Fortran and VHDL do not have function pointers
2831 }
2832
2833 static const reg::Ex re(R"(\‍([^)]*[*&^][^)]*\))");
2835 size_t i=std::string::npos;
2836 size_t l=0;
2837 if (reg::search(type,match,re)) // contains (...*...) or (...&...) or (...^...)
2838 {
2839 i = match.position();
2840 l = match.length();
2841 }
2842 if (i!=std::string::npos)
2843 {
2844 size_t di = type.find("decltype(");
2845 if (di!=std::string::npos && di<i)
2846 {
2847 i = std::string::npos;
2848 }
2849 }
2850 size_t bb=type.find('<');
2851 size_t be=type.rfind('>');
2852 bool templFp = false;
2853 if (be!=std::string::npos) {
2854 size_t cc_ast = type.find("::*");
2855 size_t cc_amp = type.find("::&");
2856 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>::*)'
2857 }
2858
2859 if (!type.empty() && // return type is non-empty
2860 i!=std::string::npos && // contains (...*...)
2861 type.find("operator")==std::string::npos && // not an operator
2862 (type.find(")(")==std::string::npos || type.find("typedef ")!=std::string::npos) &&
2863 // not a function pointer return type
2864 (!(bb<i && i<be) || templFp) // bug665855: avoid treating "typedef A<void (T*)> type" as a function pointer
2865 )
2866 {
2867 if (pLength) *pLength=static_cast<int>(l);
2868 //printf("findFunctionPtr=%d\n",(int)i);
2869 AUTO_TRACE_EXIT("result={}",i);
2870 return static_cast<int>(i);
2871 }
2872 else
2873 {
2874 //printf("findFunctionPtr=%d\n",-1);
2875 AUTO_TRACE_EXIT("result=-1");
2876 return -1;
2877 }
2878}
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:48

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

5720{
5721 AUTO_TRACE("namespace='{}' type='{}' name='{}' tempArg='{}' decl='{}'",namespaceName,type,name,tempArg,decl);
5722 QCString n=name;
5723 if (n.isEmpty()) return FALSE;
5724 if (n.find("::")!=-1) return FALSE; // skip undefined class members
5725 MemberName *mn=Doxygen::functionNameLinkedMap->find(n+tempArg); // look in function dictionary
5726 if (mn==nullptr)
5727 {
5728 mn=Doxygen::functionNameLinkedMap->find(n); // try without template arguments
5729 }
5730 if (mn) // function name defined
5731 {
5732 AUTO_TRACE_ADD("Found symbol name");
5733 //int count=0;
5734 bool found=FALSE;
5735 for (const auto &md : *mn)
5736 {
5737 // If the entry has groups, then restrict the search to members which are
5738 // in one of the groups of the entry. If md is not associated with a group yet,
5739 // allow this documentation entry to add the group info.
5740 if (!root->groups.empty() && !isEntryInGroupOfMember(root, md.get(), true))
5741 {
5742 continue;
5743 }
5744
5745 const NamespaceDef *nd=nullptr;
5746 if (md->isAlias() && md->getOuterScope() &&
5747 md->getOuterScope()->definitionType()==Definition::TypeNamespace)
5748 {
5749 nd = toNamespaceDef(md->getOuterScope());
5750 }
5751 else
5752 {
5753 nd = md->getNamespaceDef();
5754 }
5755
5756 // special case for strong enums
5757 int enumNamePos=0;
5758 if (nd && md->isEnumValue() && (enumNamePos=namespaceName.findRev("::"))!=-1)
5759 { // md part of a strong enum in a namespace?
5760 QCString enumName = namespaceName.mid(enumNamePos+2);
5761 if (namespaceName.left(enumNamePos)==nd->name())
5762 {
5763 MemberName *enumMn=Doxygen::functionNameLinkedMap->find(enumName);
5764 if (enumMn)
5765 {
5766 for (const auto &emd : *enumMn)
5767 {
5768 found = emd->isStrong() && md->getEnumScope()==emd.get();
5769 if (found)
5770 {
5771 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,nullptr,FALSE,root->spec);
5772 break;
5773 }
5774 }
5775 }
5776 }
5777 if (found)
5778 {
5779 break;
5780 }
5781 }
5782 else if (nd==nullptr && md->isEnumValue()) // md part of global strong enum?
5783 {
5784 MemberName *enumMn=Doxygen::functionNameLinkedMap->find(namespaceName);
5785 if (enumMn)
5786 {
5787 for (const auto &emd : *enumMn)
5788 {
5789 found = emd->isStrong() && md->getEnumScope()==emd.get();
5790 if (found)
5791 {
5792 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,nullptr,FALSE,root->spec);
5793 break;
5794 }
5795 }
5796 }
5797 }
5798
5799 const FileDef *fd=root->fileDef();
5800 //printf("File %s\n",fd ? qPrint(fd->name()) : "<none>");
5802 if (fd)
5803 {
5804 nl = fd->getUsedNamespaces();
5805 }
5806 //printf("NamespaceList %p\n",nl);
5807
5808 // search in the list of namespaces that are imported via a
5809 // using declaration
5810 bool viaUsingDirective = nd && nl.find(nd->qualifiedName())!=nullptr;
5811
5812 if ((namespaceName.isEmpty() && nd==nullptr) || // not in a namespace
5813 (nd && nd->name()==namespaceName) || // or in the same namespace
5814 viaUsingDirective // member in 'using' namespace
5815 )
5816 {
5817 AUTO_TRACE_ADD("Try to add member '{}' to scope '{}'",md->name(),namespaceName);
5818
5819 NamespaceDef *rnd = nullptr;
5820 if (!namespaceName.isEmpty()) rnd = Doxygen::namespaceLinkedMap->find(namespaceName);
5821
5822 const ArgumentList &mdAl = md.get()->argumentList();
5823 bool matching=
5824 (mdAl.empty() && root->argList.empty()) ||
5825 md->isVariable() || md->isTypedef() || /* in case of function pointers */
5826 matchArguments2(md->getOuterScope(),md.get()->getFileDef(),&mdAl,
5827 rnd ? rnd : Doxygen::globalScope,fd,&root->argList,
5828 FALSE,root->lang);
5829
5830 // for template members we need to check if the number of
5831 // template arguments is the same, otherwise we are dealing with
5832 // different functions.
5833 if (matching && !root->tArgLists.empty())
5834 {
5835 const ArgumentList &mdTempl = md->templateArguments();
5836 if (root->tArgLists.back().size()!=mdTempl.size())
5837 {
5838 matching=FALSE;
5839 }
5840 }
5841
5842 //printf("%s<->%s\n",
5843 // qPrint(argListToString(md->argumentList())),
5844 // qPrint(argListToString(root->argList)));
5845
5846 // For static members we also check if the comment block was found in
5847 // the same file. This is needed because static members with the same
5848 // name can be in different files. Thus it would be wrong to just
5849 // put the comment block at the first syntactically matching member. If
5850 // the comment block belongs to a group of the static member, then add
5851 // the documentation even if it is in a different file.
5852 if (matching && md->isStatic() &&
5853 md->getDefFileName()!=root->fileName &&
5854 mn->size()>1 &&
5855 !isEntryInGroupOfMember(root,md.get()))
5856 {
5857 matching = FALSE;
5858 }
5859
5860 // for template member we also need to check the return type and requires
5861 if (!md->templateArguments().empty() && !root->tArgLists.empty())
5862 {
5863 //printf("Comparing return types '%s'<->'%s'\n",
5864 // md->typeString(),type);
5865 if (md->templateArguments().size()!=root->tArgLists.back().size() ||
5866 md->typeString()!=type ||
5867 md->requiresClause()!=root->req)
5868 {
5869 //printf(" ---> no matching\n");
5870 matching = FALSE;
5871 }
5872 }
5873
5874 if (matching) // add docs to the member
5875 {
5876 AUTO_TRACE_ADD("Match found");
5877 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,&root->argList,FALSE,root->spec);
5878 found=TRUE;
5879 break;
5880 }
5881 }
5882 }
5883 if (!found && root->relatesType!=RelatesType::Duplicate && root->section.isFunction()) // no match
5884 {
5885 QCString fullFuncDecl=decl;
5886 if (!root->argList.empty()) fullFuncDecl+=argListToString(root->argList,TRUE);
5887 QCString warnMsg = "no matching file member found for \n"+fullFuncDecl;
5888 if (mn->size()>0)
5889 {
5890 warnMsg+="\nPossible candidates:";
5891 for (const auto &md : *mn)
5892 {
5893 warnMsg+="\n '";
5894 warnMsg+=replaceAnonymousScopes(md->declaration());
5895 warnMsg+="' " + warn_line(md->getDefFileName(),md->getDefLine());
5896 }
5897 }
5898 warn(root->fileName,root->startLine, "{}", qPrint(warnMsg));
5899 }
5900 }
5901 else // got docs for an undefined member!
5902 {
5903 if (root->type!="friend class" &&
5904 root->type!="friend struct" &&
5905 root->type!="friend union" &&
5906 root->type!="friend" &&
5907 (!Config_getBool(TYPEDEF_HIDES_STRUCT) ||
5908 root->type.find("typedef ")==-1)
5909 )
5910 {
5911 warn(root->fileName,root->startLine,
5912 "documented symbol '{}' was not declared or defined.",qPrint(decl)
5913 );
5914 }
5915 }
5916 return TRUE;
5917}
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:169

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

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

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

2409{
2410 FileDefSet visitedFiles;
2411 // then recursively add using directives found in #include files
2412 // to files that have not been visited.
2413 for (const auto &fn : *Doxygen::inputNameLinkedMap)
2414 {
2415 for (const auto &fd : *fn)
2416 {
2417 //printf("----- adding using directives for file %s\n",qPrint(fd->name()));
2418 fd->addIncludedUsingDirectives(visitedFiles);
2419 }
2420 }
2421}
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 5243 of file doxygen.cpp.

5244{
5245 AUTO_TRACE();
5246 ClassDefSet visitedClasses;
5247 for (const auto &[name,root] : g_classEntries)
5248 {
5249 QCString bName = extractClassName(root);
5250 ClassDefMutable *cdm = getClassMutable(bName);
5251 if (cdm)
5252 {
5254 }
5255 }
5256}

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

Referenced by parseInput().

◆ findMainPage()

void findMainPage ( Entry * root)
static

Definition at line 9678 of file doxygen.cpp.

9679{
9680 if (root->section.isMainpageDoc())
9681 {
9682 if (Doxygen::mainPage==nullptr && root->tagInfo()==nullptr)
9683 {
9684 //printf("mainpage: docLine=%d startLine=%d\n",root->docLine,root->startLine);
9685 //printf("Found main page! \n======\n%s\n=======\n",qPrint(root->doc));
9686 QCString title=root->args.stripWhiteSpace();
9687 if (title.isEmpty()) title = Config_getString(PROJECT_NAME);
9688 //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9689 QCString indexName="index";
9691 indexName, root->brief+root->doc+root->inbodyDocs,title);
9692 //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
9693 Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9694 Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1);
9695 Doxygen::mainPage->setFileName(indexName);
9696 Doxygen::mainPage->setLocalToc(root->localToc);
9698
9700 if (si)
9701 {
9702 if (!si->ref().isEmpty()) // we are from a tag file
9703 {
9704 // a page name is a label as well! but should no be double either
9706 Doxygen::mainPage->name(),
9707 indexName,
9708 root->startLine,
9709 Doxygen::mainPage->title(),
9711 0); // level 0
9712 }
9713 else if (si->lineNr() != -1)
9714 {
9715 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {}, line {})",
9716 Doxygen::mainPage->name(),si->fileName(),si->lineNr());
9717 }
9718 else
9719 {
9720 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {})",
9721 Doxygen::mainPage->name(),si->fileName());
9722 }
9723 }
9724 else
9725 {
9726 // a page name is a label as well! but should no be double either
9728 Doxygen::mainPage->name(),
9729 indexName,
9730 root->startLine,
9731 Doxygen::mainPage->title(),
9733 0); // level 0
9734 }
9735 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9736 }
9737 else if (root->tagInfo()==nullptr)
9738 {
9739 warn(root->fileName,root->startLine,
9740 "found more than one \\mainpage comment block! (first occurrence: {}, line {}), Skipping current block!",
9741 Doxygen::mainPage->docFile(),Doxygen::mainPage->getStartBodyLine());
9742 }
9743 }
9744 for (const auto &e : root->children()) findMainPage(e.get());
9745}
class that provide information about a section.
Definition section.h:57
QCString ref() const
Definition section.h:71
QCString fileName() const
Definition section.h:73
int lineNr() const
Definition section.h:72
SectionInfo * replace(const QCString &label, const QCString &fileName, int lineNr, const QCString &title, SectionType type, int level, const QCString &ref=QCString())
Definition section.h:156
SectionInfo * add(const SectionInfo &si)
Definition section.h:138
static constexpr int Page
Definition section.h:31
static void findMainPage(Entry *root)
Definition doxygen.cpp:9678

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

9749{
9750 if (root->section.isMainpageDoc())
9751 {
9752 if (Doxygen::mainPage && root->tagInfo())
9753 {
9754 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9755 }
9756 }
9757 for (const auto &e : root->children()) findMainPageTagFiles(e.get());
9758}
static void findMainPageTagFiles(Entry *root)
Definition doxygen.cpp:9748

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

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

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(), DCOP, Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Event, extractNamespaceName(), FALSE, Entry::fileDef(), Entry::fileName, QCString::find(), findGlobalMember(), Function, 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(), Property, Entry::protection, Entry::proto, MemberName::push_back(), ClassDef::qualifiedNameWithTemplateParameters(), Entry::qualifiers, Entry::relatesType, FileDef::removeMember(), removeRedundantWhiteSpace(), QCString::right(), Entry::section, MemberDefMutable::setMemberClass(), Signal, MemberName::size(), Entry::sli, Slot, Entry::spec, Entry::startColumn, Entry::startLine, QCString::startsWith(), QCString::stripPrefix(), stripTemplateSpecifiersFromScope(), QCString::stripWhiteSpace(), substitute(), Entry::tagInfo(), Entry::tArgLists, toMemberDefMutable(), TRUE, Entry::vhdlSpec, Entry::virt, warn, and warn_undoc.

Referenced by filterMemberDocumentation(), and findObjCMethodDefinitions().

◆ findMemberDocumentation()

void findMemberDocumentation ( const Entry * root)
static

Definition at line 7421 of file doxygen.cpp.

7422{
7423 if (root->section.isMemberDoc() ||
7424 root->section.isOverloadDoc() ||
7425 root->section.isFunction() ||
7426 root->section.isVariable() ||
7427 root->section.isVariableDoc() ||
7428 root->section.isDefine() ||
7429 root->section.isIncludedService() ||
7430 root->section.isExportedInterface()
7431 )
7432 {
7433 AUTO_TRACE();
7434 if (root->relatesType==RelatesType::Duplicate && !root->relates.isEmpty())
7435 {
7437 }
7439 }
7440 for (const auto &e : root->children())
7441 {
7442 if (!e->section.isEnum())
7443 {
7444 findMemberDocumentation(e.get());
7445 }
7446 }
7447}
static void findMemberDocumentation(const Entry *root)
Definition doxygen.cpp:7421
static void filterMemberDocumentation(const Entry *root, const QCString &relates)
Definition doxygen.cpp:7271

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

1267{
1268 if (root->section.isModuleDoc())
1269 {
1270 AUTO_TRACE();
1272 }
1273 for (const auto &e : root->children()) findModuleDocumentation(e.get());
1274}
void addDocs(const Entry *root)
static void findModuleDocumentation(const Entry *root)
Definition doxygen.cpp:1266

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

7452{
7453 AUTO_TRACE();
7454 for (const auto &objCImpl : root->children())
7455 {
7456 if (objCImpl->section.isObjcImpl())
7457 {
7458 for (const auto &objCMethod : objCImpl->children())
7459 {
7460 if (objCMethod->section.isFunction())
7461 {
7462 //printf(" Found ObjC method definition %s\n",qPrint(objCMethod->name));
7463 findMember(objCMethod.get(),
7464 objCMethod->relates,
7465 objCMethod->type,
7466 objCMethod->args,
7467 objCMethod->type+" "+objCImpl->name+"::"+objCMethod->name+" "+objCMethod->args,
7468 FALSE,TRUE);
7469 objCMethod->section=EntryType::makeEmpty();
7470 }
7471 }
7472 }
7473 }
7474}

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

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

9291{
9292 // for each class
9293 for (const auto &cd : *Doxygen::classLinkedMap)
9294 {
9295 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9296 if (cdm)
9297 {
9299 }
9300 }
9301 // for each concept
9302 for (const auto &cd : *Doxygen::conceptLinkedMap)
9303 {
9304 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
9305 if (cdm)
9306 {
9308 }
9309 }
9310 // for each file
9311 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9312 {
9313 for (const auto &fd : *fn)
9314 {
9315 fd->findSectionsInDocumentation();
9316 }
9317 }
9318 // for each namespace
9319 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9320 {
9322 if (ndm)
9323 {
9325 }
9326 }
9327 // for each group
9328 for (const auto &gd : *Doxygen::groupLinkedMap)
9329 {
9330 gd->findSectionsInDocumentation();
9331 }
9332 // for each page
9333 for (const auto &pd : *Doxygen::pageLinkedMap)
9334 {
9335 pd->findSectionsInDocumentation();
9336 }
9337 // for each directory
9338 for (const auto &dd : *Doxygen::dirLinkedMap)
9339 {
9340 dd->findSectionsInDocumentation();
9341 }
9343 if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
9344}
virtual void findSectionsInDocumentation()=0
virtual void findSectionsInDocumentation()=0
void findSectionsInDocumentation()
virtual void findSectionsInDocumentation()=0

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

Referenced by parseInput().

◆ findTagLessClasses() [1/2]

void findTagLessClasses ( )
static

Definition at line 1646 of file doxygen.cpp.

1647{
1648 std::vector<ClassDefMutable *> candidates;
1649 for (auto &cd : *Doxygen::classLinkedMap)
1650 {
1651 Definition *scope = cd->getOuterScope();
1652 if (scope && scope->definitionType()!=Definition::TypeClass) // that is not nested
1653 {
1654 findTagLessClasses(candidates,cd.get());
1655 }
1656 }
1657
1658 // since processTagLessClasses is potentially adding classes to Doxygen::classLinkedMap
1659 // we need to call it outside of the loop above, otherwise the iterator gets invalidated!
1660 for (auto &cd : candidates)
1661 {
1662 processTagLessClasses(cd,cd,cd,"",0); // process tag less inner struct/classes
1663 }
1664}
static void processTagLessClasses(const ClassDef *rootCd, const ClassDef *cd, ClassDefMutable *tagParentCd, const QCString &prefix, int count)
Look through the members of class cd and its public members.
Definition doxygen.cpp:1565
static void findTagLessClasses()
Definition doxygen.cpp:1646

References Doxygen::classLinkedMap, Definition::definitionType(), findTagLessClasses(), Definition::getOuterScope(), processTagLessClasses(), and Definition::TypeClass.

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

◆ findTagLessClasses() [2/2]

void findTagLessClasses ( std::vector< ClassDefMutable * > & candidates,
ClassDef * cd )
static

Definition at line 1629 of file doxygen.cpp.

1630{
1631 for (const auto &icd : cd->getClasses())
1632 {
1633 if (icd->name().find("@")==-1) // process all non-anonymous inner classes
1634 {
1635 findTagLessClasses(candidates,icd);
1636 }
1637 }
1638
1640 if (cdm)
1641 {
1642 candidates.push_back(cdm);
1643 }
1644}

References findTagLessClasses(), ClassDef::getClasses(), and toClassDefMutable().

◆ findTemplateInstanceRelation()

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

Definition at line 4720 of file doxygen.cpp.

4725{
4726 AUTO_TRACE("Derived from template '{}' with parameters '{}' isArtificial={}",
4727 templateClass->name(),templSpec,isArtificial);
4728
4729 QCString tempArgsStr = tempArgListToString(templateClass->templateArguments(),root->lang,false);
4730 bool existingClass = templSpec==tempArgsStr;
4731 if (existingClass) return; // avoid recursion
4732
4733 bool freshInstance=FALSE;
4734 ClassDefMutable *instanceClass = toClassDefMutable(
4735 templateClass->insertTemplateInstance(
4736 root->fileName,root->startLine,root->startColumn,templSpec,freshInstance));
4737 if (instanceClass)
4738 {
4739 if (freshInstance)
4740 {
4741 instanceClass->setArtificial(TRUE);
4742 instanceClass->setLanguage(root->lang);
4743
4744 AUTO_TRACE_ADD("found fresh instance '{}'",instanceClass->name());
4745 instanceClass->setTemplateBaseClassNames(templateNames);
4746
4747 // search for new template instances caused by base classes of
4748 // instanceClass
4749 auto it_pair = g_classEntries.equal_range(templateClass->name().str());
4750 for (auto it=it_pair.first ; it!=it_pair.second ; ++it)
4751 {
4752 const Entry *templateRoot = it->second;
4753 AUTO_TRACE_ADD("template root found '{}' templSpec='{}'",templateRoot->name,templSpec);
4754 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(root->lang,templSpec);
4755 findBaseClassesForClass(templateRoot,context,templateClass,instanceClass,
4756 TemplateInstances,isArtificial,templArgs.get(),templateNames);
4757
4758 findUsedClassesForClass(templateRoot,context,templateClass,instanceClass,
4759 isArtificial,templArgs.get(),templateNames);
4760 }
4761 }
4762 else
4763 {
4764 AUTO_TRACE_ADD("instance already exists");
4765 }
4766 }
4767}
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:4511

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

4814{
4815 if (name.isEmpty()) return 0;
4816 int l = static_cast<int>(name.length());
4817 if (name[l-1]=='>') // search backward to find the matching <, allowing nested <...> and strings.
4818 {
4819 int count=1;
4820 int i=l-2;
4821 char insideQuote=0;
4822 while (count>0 && i>=0)
4823 {
4824 char c = name[i--];
4825 switch (c)
4826 {
4827 case '>': if (!insideQuote) count++; break;
4828 case '<': if (!insideQuote) count--; break;
4829 case '\'': if (!insideQuote) insideQuote=c;
4830 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4831 break;
4832 case '"': if (!insideQuote) insideQuote=c;
4833 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4834 break;
4835 default: break;
4836 }
4837 }
4838 if (i>=0) l=i+1;
4839 }
4840 return l;
4841}

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

4519{
4520 AUTO_TRACE();
4521 const ArgumentList &formalArgs = masterCd->templateArguments();
4522 for (auto &mni : masterCd->memberNameInfoLinkedMap())
4523 {
4524 for (auto &mi : *mni)
4525 {
4526 const MemberDef *md=mi->memberDef();
4527 if (md->isVariable() || md->isObjCProperty()) // for each member variable in this class
4528 {
4529 AUTO_TRACE_ADD("Found variable '{}' in class '{}'",md->name(),masterCd->name());
4530 QCString type = normalizeNonTemplateArgumentsInString(md->typeString(),masterCd,formalArgs);
4531 QCString typedefValue = md->getLanguage()==SrcLangExt::Java ? type : resolveTypeDef(masterCd,type);
4532 if (!typedefValue.isEmpty())
4533 {
4534 type = typedefValue;
4535 }
4536 int pos=0;
4537 QCString usedClassName;
4538 QCString templSpec;
4539 bool found=FALSE;
4540 // the type can contain template variables, replace them if present
4541 type = substituteTemplateArgumentsInString(type,formalArgs,actualArgs);
4542
4543 //printf(" template substitution gives=%s\n",qPrint(type));
4544 while (!found && extractClassNameFromType(type,pos,usedClassName,templSpec,root->lang)!=-1)
4545 {
4546 // find the type (if any) that matches usedClassName
4547 SymbolResolver resolver(masterCd->getFileDef());
4548 const ClassDefMutable *typeCd = resolver.resolveClassMutable(masterCd,usedClassName,false,true);
4549 //printf("====> usedClassName=%s -> typeCd=%s\n",
4550 // qPrint(usedClassName),typeCd?qPrint(typeCd->name()):"<none>");
4551 if (typeCd)
4552 {
4553 usedClassName = typeCd->name();
4554 }
4555
4556 int sp=usedClassName.find('<');
4557 if (sp==-1) sp=0;
4558 // replace any namespace aliases
4559 replaceNamespaceAliases(usedClassName);
4560 // add any template arguments to the class
4561 QCString usedName = removeRedundantWhiteSpace(usedClassName+templSpec);
4562 //printf(" usedName=%s usedClassName=%s templSpec=%s\n",qPrint(usedName),qPrint(usedClassName),qPrint(templSpec));
4563
4564 TemplateNameMap formTemplateNames;
4565 if (templateNames.empty())
4566 {
4567 formTemplateNames = getTemplateArgumentsInName(formalArgs,usedName.str());
4568 }
4569 BaseInfo bi(usedName,Protection::Public,Specifier::Normal);
4570 findClassRelation(root,context,instanceCd,&bi,formTemplateNames,TemplateInstances,isArtificial);
4571
4572 for (const Argument &arg : masterCd->templateArguments())
4573 {
4574 if (arg.name==usedName) // type is a template argument
4575 {
4576 ClassDef *usedCd = Doxygen::hiddenClassLinkedMap->find(usedName);
4577 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4578 if (usedCd==nullptr)
4579 {
4580 usedCdm = toClassDefMutable(
4581 Doxygen::hiddenClassLinkedMap->add(usedName,
4583 masterCd->getDefFileName(),masterCd->getDefLine(),
4584 masterCd->getDefColumn(),
4585 usedName,
4586 ClassDef::Class)));
4587 if (usedCdm)
4588 {
4589 //printf("making %s a template argument!!!\n",qPrint(usedCd->name()));
4590 usedCdm->makeTemplateArgument();
4591 usedCdm->setUsedOnly(TRUE);
4592 usedCdm->setLanguage(masterCd->getLanguage());
4593 usedCd = usedCdm;
4594 }
4595 }
4596 if (usedCd)
4597 {
4598 found=TRUE;
4599 AUTO_TRACE_ADD("case 1: adding used class '{}'", usedCd->name());
4600 instanceCd->addUsedClass(usedCd,md->name(),md->protection());
4601 if (usedCdm)
4602 {
4603 if (isArtificial) usedCdm->setArtificial(TRUE);
4604 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4605 }
4606 }
4607 }
4608 }
4609
4610 if (!found)
4611 {
4612 ClassDef *usedCd=findClassWithinClassContext(context,masterCd,usedName);
4613 //printf("Looking for used class %s: result=%s master=%s\n",
4614 // qPrint(usedName),usedCd?qPrint(usedCd->name()):"<none>",masterCd?qPrint(masterCd->name()):"<none>");
4615
4616 if (usedCd)
4617 {
4618 found=TRUE;
4619 AUTO_TRACE_ADD("case 2: adding used class '{}'", usedCd->name());
4620 instanceCd->addUsedClass(usedCd,md->name(),md->protection()); // class exists
4621 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4622 if (usedCdm)
4623 {
4624 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4625 }
4626 }
4627 }
4628 }
4629 if (!found && !type.isEmpty()) // used class is not documented in any scope
4630 {
4631 ClassDef *usedCd = Doxygen::hiddenClassLinkedMap->find(type);
4632 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4633 if (usedCd==nullptr && !Config_getBool(HIDE_UNDOC_RELATIONS))
4634 {
4635 if (type.endsWith("(*") || type.endsWith("(^")) // type is a function pointer
4636 {
4637 type+=md->argsString();
4638 }
4639 AUTO_TRACE_ADD("New undocumented used class '{}'", type);
4640 usedCdm = toClassDefMutable(
4643 masterCd->getDefFileName(),masterCd->getDefLine(),
4644 masterCd->getDefColumn(),
4645 type,ClassDef::Class)));
4646 if (usedCdm)
4647 {
4648 usedCdm->setUsedOnly(TRUE);
4649 usedCdm->setLanguage(masterCd->getLanguage());
4650 usedCd = usedCdm;
4651 }
4652 }
4653 if (usedCd)
4654 {
4655 AUTO_TRACE_ADD("case 3: adding used class '{}'", usedCd->name());
4656 instanceCd->addUsedClass(usedCd,md->name(),md->protection());
4657 if (usedCdm)
4658 {
4659 if (isArtificial) usedCdm->setArtificial(TRUE);
4660 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4661 }
4662 }
4663 }
4664 }
4665 }
4666 }
4667}
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:4210
int extractClassNameFromType(const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt lang)
Definition util.cpp:4136
QCString resolveTypeDef(const Definition *context, const QCString &qualifiedName, const Definition **typedefContext)
Definition util.cpp:382

References ClassDefMutable::addUsedByClass(), ClassDefMutable::addUsedClass(), MemberDef::argsString(), AUTO_TRACE, AUTO_TRACE_ADD, ClassDef::Class, Config_getBool, createClassDef(), QCString::endsWith(), extractClassNameFromType(), FALSE, QCString::find(), 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 1837 of file doxygen.cpp.

1839{
1840 NamespaceDef *usingNd =nullptr;
1841 for (auto &und : unl)
1842 {
1843 QCString uScope=und->name()+"::";
1844 usingNd = getResolvedNamespace(uScope+name);
1845 if (usingNd!=nullptr) break;
1846 }
1847 return usingNd;
1848}

References getResolvedNamespace().

Referenced by findUsingDirectives().

◆ findUsedTemplateInstances()

void findUsedTemplateInstances ( )
static

Definition at line 5276 of file doxygen.cpp.

5277{
5278 AUTO_TRACE();
5279 for (const auto &[name,root] : g_classEntries)
5280 {
5281 QCString bName = extractClassName(root);
5282 ClassDefMutable *cdm = getClassMutable(bName);
5283 if (cdm)
5284 {
5285 findUsedClassesForClass(root,cdm,cdm,cdm,TRUE);
5287 cdm->addTypeConstraints();
5288 }
5289 }
5290}
virtual void addTypeConstraints()=0
static void makeTemplateInstanceRelation(const Entry *root, ClassDefMutable *cd)
Definition doxygen.cpp:5258

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

2006{
2007 if (root->section.isUsingDecl() &&
2008 !root->parent()->section.isCompound() && // not a class/struct member
2009 (!filterPythonPackages || (root->lang==SrcLangExt::Python && root->fileName.endsWith("__init__.py")))
2010 )
2011 {
2012 AUTO_TRACE("Found using declaration '{}' at line {} of {} inside section {}",
2013 root->name,root->startLine,root->fileName,root->parent()->section);
2014 if (!root->name.isEmpty())
2015 {
2016 const Definition *usingDef = nullptr;
2017 NamespaceDefMutable *nd = nullptr;
2018 FileDef *fd = root->fileDef();
2019 QCString scName;
2020
2021 // see if the using statement was found inside a namespace or inside
2022 // the global file scope.
2023 if (root->parent()->section.isNamespace())
2024 {
2025 scName=root->parent()->name;
2026 if (!scName.isEmpty())
2027 {
2028 nd = getResolvedNamespaceMutable(scName);
2029 }
2030 }
2031
2032 // Assume the using statement was used to import a class.
2033 // Find the scope in which the 'using' namespace is defined by prepending
2034 // the possible scopes in which the using statement was found, starting
2035 // with the most inner scope and going to the most outer scope (i.e.
2036 // file scope).
2037
2038 QCString name = substitute(root->name,".","::"); //Java/C# scope->internal
2039
2040 SymbolResolver resolver;
2041 const Definition *scope = nd;
2042 if (nd==nullptr) scope = fd;
2043 usingDef = resolver.resolveSymbol(scope,name);
2044
2045 //printf("usingDef(scope=%s,name=%s)=%s\n",qPrint(nd?nd->qualifiedName():""),qPrint(name),usingDef?qPrint(usingDef->qualifiedName()):"nullptr");
2046
2047 if (!usingDef)
2048 {
2049 usingDef = getClass(name); // try direct lookup, this is needed to get
2050 // builtin STL classes to properly resolve, e.g.
2051 // vector -> std::vector
2052 }
2053 if (!usingDef)
2054 {
2055 usingDef = Doxygen::hiddenClassLinkedMap->find(name); // check if it is already hidden
2056 }
2057#if 0
2058 if (!usingDef)
2059 {
2060 AUTO_TRACE_ADD("New using class '{}' (sec={})! #tArgLists={}",
2061 name,root->section,root->tArgLists.size());
2064 createClassDef( "<using>",1,1, name, ClassDef::Class)));
2065 if (usingCd)
2066 {
2067 usingCd->setArtificial(TRUE);
2068 usingCd->setLanguage(root->lang);
2069 usingDef = usingCd;
2070 }
2071 }
2072#endif
2073 else
2074 {
2075 AUTO_TRACE_ADD("Found used type '{}' in scope='{}'",
2076 usingDef->name(), nd ? nd->name(): fd ? fd->name() : QCString("<unknown>"));
2077 }
2078
2079 if (usingDef)
2080 {
2081 if (nd)
2082 {
2083 nd->addUsingDeclaration(usingDef);
2084 }
2085 else if (fd)
2086 {
2087 fd->addUsingDeclaration(usingDef);
2088 }
2089 }
2090 }
2091 }
2092 for (const auto &e : root->children()) findUsingDeclarations(e.get(),filterPythonPackages);
2093}
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:2005

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

2159{
2160 if (root->section.isUsingDecl() &&
2161 root->parent()->section.isCompound() // in a class/struct member
2162 )
2163 {
2164 AUTO_TRACE("Found using declaration '{}' inside section {}", root->name, root->parent()->section);
2165 QCString fullName=removeRedundantWhiteSpace(root->parent()->name);
2166 fullName=stripAnonymousNamespaceScope(fullName);
2167 fullName=stripTemplateSpecifiersFromScope(fullName);
2168 ClassDefMutable *cd = getClassMutable(fullName);
2169 if (cd)
2170 {
2171 AUTO_TRACE_ADD("found class '{}'",cd->name());
2172 int i=root->name.findRev("::");
2173 if (i!=-1)
2174 {
2175 QCString scope=root->name.left(i);
2176 QCString memName=root->name.right(root->name.length()-i-2);
2177 SymbolResolver resolver;
2178 const ClassDef *bcd = resolver.resolveClass(cd,scope); // todo: file in fileScope parameter
2179 AUTO_TRACE_ADD("name={} scope={} bcd={}",scope,cd?cd->name():"<none>",bcd?bcd->name():"<none>");
2180 if (bcd && bcd!=cd)
2181 {
2182 AUTO_TRACE_ADD("found class '{}' memName='{}'",bcd->name(),memName);
2184 const MemberNameInfo *mni = mnlm.find(memName);
2185 if (mni)
2186 {
2187 for (auto &mi : *mni)
2188 {
2189 const MemberDef *md = mi->memberDef();
2190 if (md && md->protection()!=Protection::Private)
2191 {
2192 AUTO_TRACE_ADD("found member '{}'",mni->memberName());
2193 QCString fileName = root->fileName;
2194 if (fileName.isEmpty() && root->tagInfo())
2195 {
2196 fileName = root->tagInfo()->tagName;
2197 }
2198 if (!cd->containsOverload(md))
2199 {
2200 createUsingMemberImportForClass(root,cd,md,fileName,memName);
2201 // also insert the member into copies of the class
2202 auto it = g_usingClassMap.find(cd->qualifiedName().str());
2203 if (it != g_usingClassMap.end())
2204 {
2205 for (const auto &copyCd : it->second)
2206 {
2207 createUsingMemberImportForClass(root,copyCd,md,fileName,memName);
2208 }
2209 }
2210 }
2211 }
2212 }
2213 }
2214 }
2215 }
2216 }
2217 }
2218 else if (root->section.isUsingDecl() &&
2219 (root->parent()->section.isNamespace() || root->parent()->section.isEmpty()) && // namespace or global member
2220 root->lang==SrcLangExt::Cpp // do we also want this for e.g. Fortran? (see test case 095)
2221 )
2222 {
2223 AUTO_TRACE("Found using declaration '{}' inside section {}", root->name, root->parent()->section);
2224 Definition *scope = nullptr;
2225 NamespaceDefMutable *nd = nullptr;
2226 FileDef *fd = root->parent()->fileDef();
2227 if (!root->parent()->name.isEmpty())
2228 {
2229 QCString fullName=removeRedundantWhiteSpace(root->parent()->name);
2230 fullName=stripAnonymousNamespaceScope(fullName);
2232 scope = nd;
2233 }
2234 else
2235 {
2236 scope = fd;
2237 }
2238 if (scope)
2239 {
2240 AUTO_TRACE_ADD("found scope '{}'",scope->name());
2241 SymbolResolver resolver;
2242 const Definition *def = resolver.resolveSymbol(root->name.startsWith("::") ? nullptr : scope,root->name);
2243 if (def && def->definitionType()==Definition::TypeMember)
2244 {
2245 int i=root->name.findRev("::");
2246 QCString memName;
2247 if (i!=-1)
2248 {
2249 memName = root->name.right(root->name.length()-i-2);
2250 }
2251 else
2252 {
2253 memName = root->name;
2254 }
2255 const MemberDef *md = toMemberDef(def);
2256 AUTO_TRACE_ADD("found member '{}' for name '{}'",md->qualifiedName(),root->name);
2257 QCString fileName = root->fileName;
2258 if (fileName.isEmpty() && root->tagInfo())
2259 {
2260 fileName = root->tagInfo()->tagName;
2261 }
2262 const ArgumentList &templAl = md->templateArguments();
2263 const ArgumentList &al = md->argumentList();
2264
2265 auto newMd = createMemberDef(
2266 fileName,root->startLine,root->startColumn,
2267 md->typeString(),memName,md->argsString(),
2268 md->excpString(),root->protection,root->virt,
2269 md->isStatic(),Relationship::Member,md->memberType(),
2270 templAl,al,root->metaData
2271 );
2272 auto newMmd = toMemberDefMutable(newMd.get());
2273 if (nd)
2274 {
2275 newMmd->setNamespace(nd);
2276 nd->insertMember(newMd.get());
2277 }
2278 if (fd)
2279 {
2280 newMmd->setFileDef(fd);
2281 fd->insertMember(newMd.get());
2282 }
2283 if (!root->doc.isEmpty() || !root->brief.isEmpty())
2284 {
2285 newMmd->setDocumentation(root->doc,root->docFile,root->docLine);
2286 newMmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2287 newMmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2288 }
2289 else
2290 {
2291 newMmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
2292 newMmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
2293 newMmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
2294 }
2295 newMmd->setDefinition(md->definition());
2296 applyMemberOverrideOptions(root,newMmd);
2297 newMmd->addQualifiers(root->qualifiers);
2298 newMmd->setBitfields(md->bitfieldString());
2299 newMmd->addSectionsToDefinition(root->anchors);
2300 newMmd->setBodySegment(md->getDefLine(),md->getStartBodyLine(),md->getEndBodyLine());
2301 newMmd->setBodyDef(md->getBodyDef());
2302 newMmd->setInitializer(md->initializer());
2303 newMmd->setRequiresClause(md->requiresClause());
2304 newMmd->setMaxInitLines(md->initializerLines());
2305 newMmd->setMemberGroupId(root->mGrpId);
2306 newMmd->setMemberSpecifiers(md->getMemberSpecifiers());
2307 newMmd->setVhdlSpecifiers(md->getVhdlSpecifiers());
2308 newMmd->setLanguage(root->lang);
2309 newMmd->setId(root->id);
2310 MemberName *mn = Doxygen::functionNameLinkedMap->add(memName);
2311 mn->push_back(std::move(newMd));
2312#if 0 // insert an alias instead of a copy
2313 const MemberDef *md = toMemberDef(def);
2314 AUTO_TRACE_ADD("found member '{}' for name '{}'",md->qualifiedName(),root->name);
2315 auto aliasMd = createMemberDefAlias(nd,md);
2316 QCString aliasFullName = nd->qualifiedName()+"::"+aliasMd->localName();
2317 if (nd && aliasMd.get())
2318 {
2319 nd->insertMember(aliasMd.get());
2320 }
2321 if (fd && aliasMd.get())
2322 {
2323 fd->insertMember(aliasMd.get());
2324 }
2325 MemberName *mn = Doxygen::memberNameLinkedMap->add(aliasFullName);
2326 mn->push_back(std::move(aliasMd));
2327#endif
2328 }
2329 else if (def && def->definitionType()==Definition::TypeClass)
2330 {
2331 const ClassDef *cd = toClassDef(def);
2332 QCString copyFullName;
2333 if (nd==nullptr)
2334 {
2335 copyFullName = cd->localName();
2336 }
2337 else
2338 {
2339 copyFullName = nd->qualifiedName()+"::"+cd->localName();
2340 }
2341 if (Doxygen::classLinkedMap->find(copyFullName)==nullptr)
2342 {
2344 Doxygen::classLinkedMap->add(copyFullName,
2345 cd->deepCopy(copyFullName)));
2346 AUTO_TRACE_ADD("found class '{}' for name '{}' copy '{}' obj={}",cd->qualifiedName(),root->name,copyFullName,(void*)ncdm);
2347 g_usingClassMap[cd->qualifiedName().str()].push_back(ncdm);
2348 if (ncdm)
2349 {
2350 if (nd) ncdm->moveTo(nd);
2351 if ((!root->doc.isEmpty() || !root->brief.isEmpty())) // use docs at using statement
2352 {
2353 ncdm->setDocumentation(root->doc,root->docFile,root->docLine);
2354 ncdm->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2355 }
2356 else // use docs from used class
2357 {
2358 ncdm->setDocumentation(cd->documentation(),cd->docFile(),cd->docLine());
2360 }
2361 if (nd)
2362 {
2363 nd->addInnerCompound(ncdm);
2364 nd->addUsingDeclaration(ncdm);
2365 }
2366 if (fd)
2367 {
2368 if (ncdm) ncdm->setFileDef(fd);
2369 fd->insertClass(ncdm);
2370 fd->addUsingDeclaration(ncdm);
2371 }
2372 }
2373 }
2374#if 0 // insert an alias instead of a copy
2375 auto aliasCd = createClassDefAlias(nd,cd);
2376 QCString aliasFullName;
2377 if (nd==nullptr)
2378 {
2379 aliasFullName = aliasCd->localName();
2380 }
2381 else
2382 {
2383 aliasFullName = nd->qualifiedName()+"::"+aliasCd->localName();
2384 }
2385 AUTO_TRACE_ADD("found class '{}' for name '{}' aliasFullName='{}'",cd->qualifiedName(),root->name,aliasFullName);
2386 auto acd = Doxygen::classLinkedMap->add(aliasFullName,std::move(aliasCd));
2387 if (nd && acd)
2388 {
2389 nd->addInnerCompound(acd);
2390 }
2391 if (fd && acd)
2392 {
2393 fd->insertClass(acd);
2394 }
2395#endif
2396 }
2397 else if (scope)
2398 {
2399 AUTO_TRACE_ADD("no symbol with name '{}' in scope {}",root->name,scope->name());
2400 }
2401 }
2402 }
2403 for (const auto &e : root->children()) findUsingDeclImports(e.get());
2404}
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:788
ClassDef * toClassDef(Definition *d)
static void createUsingMemberImportForClass(const Entry *root, ClassDefMutable *cd, const MemberDef *md, const QCString &fileName, const QCString &memName)
Definition doxygen.cpp:2109
static void findUsingDeclImports(const Entry *root)
Definition doxygen.cpp:2158
static std::unordered_map< std::string, std::vector< ClassDefMutable * > > g_usingClassMap
Definition doxygen.cpp:2156
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 1850 of file doxygen.cpp.

1851{
1852 if (root->section.isUsingDir())
1853 {
1854 AUTO_TRACE("Found using directive {} at line {} of {}",root->name,root->startLine,root->fileName);
1855 QCString name=substitute(root->name,".","::");
1856 if (name.endsWith("::"))
1857 {
1858 name=name.left(name.length()-2);
1859 }
1860 if (!name.isEmpty())
1861 {
1862 NamespaceDef *usingNd = nullptr;
1863 NamespaceDefMutable *nd = nullptr;
1864 FileDef *fd = root->fileDef();
1865 QCString nsName;
1866
1867 // see if the using statement was found inside a namespace or inside
1868 // the global file scope.
1869 if (root->parent() && root->parent()->section.isNamespace() &&
1870 (fd==nullptr || fd->getLanguage()!=SrcLangExt::Java) // not a .java file
1871 )
1872 {
1873 nsName=stripAnonymousNamespaceScope(root->parent()->name);
1874 if (!nsName.isEmpty())
1875 {
1876 nd = getResolvedNamespaceMutable(nsName);
1877 }
1878 }
1879
1880 // find the scope in which the 'using' namespace is defined by prepending
1881 // the possible scopes in which the using statement was found, starting
1882 // with the most inner scope and going to the most outer scope (i.e.
1883 // file scope).
1884 int scopeOffset = static_cast<int>(nsName.length());
1885 do
1886 {
1887 QCString scope=scopeOffset>0 ?
1888 nsName.left(scopeOffset)+"::" : QCString();
1889 usingNd = getResolvedNamespace(scope+name);
1890 //printf("Trying with scope='%s' usingNd=%p\n",(scope+qPrint(name)),usingNd);
1891 if (scopeOffset==0)
1892 {
1893 scopeOffset=-1;
1894 }
1895 else if ((scopeOffset=nsName.findRev("::",scopeOffset-1))==-1)
1896 {
1897 scopeOffset=0;
1898 }
1899 } while (scopeOffset>=0 && usingNd==nullptr);
1900
1901 if (usingNd==nullptr && nd) // not found, try used namespaces in this scope
1902 // or in one of the parent namespace scopes
1903 {
1904 const NamespaceDefMutable *pnd = nd;
1905 while (pnd && usingNd==nullptr)
1906 {
1907 // also try with one of the used namespaces found earlier
1909
1910 // goto the parent
1911 Definition *s = pnd->getOuterScope();
1913 {
1915 }
1916 else
1917 {
1918 pnd = nullptr;
1919 }
1920 }
1921 }
1922 if (usingNd==nullptr && fd) // still nothing, also try used namespace in the
1923 // global scope
1924 {
1925 usingNd = findUsedNamespace(fd->getUsedNamespaces(),name);
1926 }
1927
1928 //printf("%s -> %s\n",qPrint(name),usingNd?qPrint(usingNd->name()):"<none>");
1929
1930 // add the namespace the correct scope
1931 if (usingNd)
1932 {
1933 //printf("using fd=%p nd=%p\n",fd,nd);
1934 if (nd)
1935 {
1936 //printf("Inside namespace %s\n",qPrint(nd->name()));
1937 nd->addUsingDirective(usingNd);
1938 }
1939 else if (fd)
1940 {
1941 //printf("Inside file %s\n",qPrint(fd->name()));
1942 fd->addUsingDirective(usingNd);
1943 }
1944 }
1945 else // unknown namespace, but add it anyway.
1946 {
1947 AUTO_TRACE_ADD("new unknown namespace {} lang={} hidden={}",name,langToString(root->lang),root->hidden);
1948 // add namespace to the list
1951 createNamespaceDef(root->fileName,root->startLine,root->startColumn,name)));
1952 if (nd)
1953 {
1954 nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1955 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1957 nd->setHidden(root->hidden);
1958 nd->setArtificial(TRUE);
1959 nd->setLanguage(root->lang);
1960 nd->setId(root->id);
1961 nd->setMetaData(root->metaData);
1962 nd->setInline(root->spec.isInline());
1963 nd->setExported(root->exported);
1964
1965 for (const Grouping &g : root->groups)
1966 {
1967 GroupDef *gd=nullptr;
1968 if (!g.groupname.isEmpty() && (gd=Doxygen::groupLinkedMap->find(g.groupname)))
1969 gd->addNamespace(nd);
1970 }
1971
1972 // insert the namespace in the file definition
1973 if (fd)
1974 {
1975 fd->insertNamespace(nd);
1976 fd->addUsingDirective(nd);
1977 }
1978
1979 // the empty string test is needed for extract all case
1980 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1981 nd->insertUsedFile(fd);
1982 nd->setRefItems(root->sli);
1983 }
1984 }
1985 }
1986 }
1987 for (const auto &e : root->children()) findUsingDirectives(e.get());
1988}
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:1837
static void findUsingDirectives(const Entry *root)
Definition doxygen.cpp:1850

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::section, DefinitionMutable::setArtificial(), DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), DefinitionMutable::setExported(), DefinitionMutable::setHidden(), DefinitionMutable::setId(), NamespaceDefMutable::setInline(), DefinitionMutable::setLanguage(), NamespaceDefMutable::setMetaData(), DefinitionMutable::setRefItems(), 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 9349 of file doxygen.cpp.

9350{
9351 // remove all references to classes from the cache
9352 // as there can be new template instances in the inheritance path
9353 // to this class. Optimization: only remove those classes that
9354 // have inheritance instances as direct or indirect sub classes.
9355 StringVector elementsToRemove;
9356 for (const auto &ci : *Doxygen::typeLookupCache)
9357 {
9358 const LookupInfo &li = ci.second;
9359 if (li.definition)
9360 {
9361 elementsToRemove.push_back(ci.first);
9362 }
9363 }
9364 for (const auto &k : elementsToRemove)
9365 {
9366 Doxygen::typeLookupCache->remove(k);
9367 }
9368
9369 // remove all cached typedef resolutions whose target is a
9370 // template class as this may now be a template instance
9371 // for each global function name
9372 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9373 {
9374 // for each function with that name
9375 for (const auto &ifmd : *fn)
9376 {
9377 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9378 if (fmd && fmd->isTypedefValCached())
9379 {
9380 const ClassDef *cd = fmd->getCachedTypedefVal();
9381 if (cd->isTemplate()) fmd->invalidateTypedefValCache();
9382 }
9383 }
9384 }
9385 // for each class method name
9386 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9387 {
9388 // for each function with that name
9389 for (const auto &imd : *nm)
9390 {
9391 MemberDefMutable *md = toMemberDefMutable(imd.get());
9392 if (md && md->isTypedefValCached())
9393 {
9394 const ClassDef *cd = md->getCachedTypedefVal();
9395 if (cd->isTemplate()) md->invalidateTypedefValCache();
9396 }
9397 }
9398 }
9399}
virtual bool isTemplate() const =0
Returns TRUE if this class is a template.
static Cache< std::string, LookupInfo > * typeLookupCache
Definition doxygen.h:127
virtual const ClassDef * getCachedTypedefVal() const =0
virtual bool isTypedefValCached() const =0
virtual void invalidateTypedefValCache()=0
const Definition * definition
Definition doxygen.h:60

References LookupInfo::definition, Doxygen::functionNameLinkedMap, MemberDef::getCachedTypedefVal(), MemberDefMutable::invalidateTypedefValCache(), ClassDef::isTemplate(), MemberDef::isTypedefValCached(), Doxygen::memberNameLinkedMap, toMemberDefMutable(), and Doxygen::typeLookupCache.

Referenced by parseInput().

◆ flushUnresolvedRelations()

void flushUnresolvedRelations ( )
static

Definition at line 9403 of file doxygen.cpp.

9404{
9405 // Remove all unresolved references to classes from the cache.
9406 // This is needed before resolving the inheritance relations, since
9407 // it would otherwise not find the inheritance relation
9408 // for C in the example below, as B::I was already found to be unresolvable
9409 // (which is correct if you ignore the inheritance relation between A and B).
9410 //
9411 // class A { class I {} };
9412 // class B : public A {};
9413 // class C : public B::I {};
9414
9415 StringVector elementsToRemove;
9416 for (const auto &ci : *Doxygen::typeLookupCache)
9417 {
9418 const LookupInfo &li = ci.second;
9419 if (li.definition==nullptr && li.typeDef==nullptr)
9420 {
9421 elementsToRemove.push_back(ci.first);
9422 }
9423 }
9424 for (const auto &k : elementsToRemove)
9425 {
9426 Doxygen::typeLookupCache->remove(k);
9427 }
9428
9429 // for each global function name
9430 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9431 {
9432 // for each function with that name
9433 for (const auto &ifmd : *fn)
9434 {
9435 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9436 if (fmd)
9437 {
9439 }
9440 }
9441 }
9442 // for each class method name
9443 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9444 {
9445 // for each function with that name
9446 for (const auto &imd : *nm)
9447 {
9448 MemberDefMutable *md = toMemberDefMutable(imd.get());
9449 if (md)
9450 {
9452 }
9453 }
9454 }
9455
9456}
virtual void invalidateCachedArgumentTypes()=0
const MemberDef * typeDef
Definition doxygen.h:61

References LookupInfo::definition, Doxygen::functionNameLinkedMap, MemberDefMutable::invalidateCachedArgumentTypes(), Doxygen::memberNameLinkedMap, toMemberDefMutable(), LookupInfo::typeDef, and Doxygen::typeLookupCache.

Referenced by parseInput().

◆ g_pathsVisited()

StringUnorderedSet g_pathsVisited ( 1009 )
static

Referenced by readDir(), and readFileOrDirectory().

◆ generateClassDocs()

void generateClassDocs ( )
static

Definition at line 9107 of file doxygen.cpp.

9108{
9109 std::vector<ClassDefMutable*> classList;
9110 for (const auto &cdi : *Doxygen::classLinkedMap)
9111 {
9112 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9113 if (cd && (cd->getOuterScope()==nullptr ||
9115 {
9116 addClassAndNestedClasses(classList,cd);
9117 }
9118 }
9119 for (const auto &cdi : *Doxygen::hiddenClassLinkedMap)
9120 {
9121 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9122 if (cd && (cd->getOuterScope()==nullptr ||
9124 {
9125 addClassAndNestedClasses(classList,cd);
9126 }
9127 }
9128 generateDocsForClassList(classList);
9129}
static void generateDocsForClassList(const std::vector< ClassDefMutable * > &classList)
Definition doxygen.cpp:9009

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

9134{
9135 for (const auto &cdi : *Doxygen::conceptLinkedMap)
9136 {
9138
9139 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9140 if (cd &&
9141 (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9142 cd->getOuterScope()==Doxygen::globalScope // only look at global concepts
9143 ) && !cd->isHidden() && cd->isLinkableInProject()
9144 )
9145 {
9146 msg("Generating docs for concept {}...\n",cd->displayName());
9148 }
9149 }
9150}
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 10255 of file doxygen.cpp.

10257{
10258 std::ofstream f;
10259 bool fileOpened=openOutputFile(configFile,f);
10260 bool writeToStdout=configFile=="-";
10261 if (fileOpened)
10262 {
10263 TextStream t(&f);
10264 Config::writeTemplate(t,shortList,updateOnly);
10265 if (!writeToStdout)
10266 {
10267 if (!updateOnly)
10268 {
10269 msg("\n\nConfiguration file '{}' created.\n\n",configFile);
10270 msg("Now edit the configuration file and enter\n\n");
10271 if (configFile!="Doxyfile" && configFile!="doxyfile")
10272 msg(" doxygen {}\n\n",configFile);
10273 else
10274 msg(" doxygen\n\n");
10275 msg("to generate the documentation for your project\n\n");
10276 }
10277 else
10278 {
10279 msg("\n\nConfiguration file '{}' updated.\n\n",configFile);
10280 }
10281 }
10282 }
10283 else
10284 {
10285 term("Cannot open file {} for writing\n",configFile);
10286 }
10287}
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 10510 of file doxygen.cpp.

10511{
10512 for (const auto &fn : *Doxygen::inputNameLinkedMap)
10513 {
10514 struct FileEntry
10515 {
10516 FileEntry(const QCString &p,FileDef *fd) : path(p), fileDef(fd) {}
10517 QCString path;
10518 FileDef *fileDef;
10519 };
10520
10521 // collect the entry for which to compute the longest common prefix (LCP) of the path
10522 std::vector<FileEntry> fileEntries;
10523 for (const auto &fd : *fn)
10524 {
10525 if (!fd->isReference()) // skip external references
10526 {
10527 fileEntries.emplace_back(fd->getPath(),fd.get());
10528 }
10529 }
10530
10531 size_t size = fileEntries.size();
10532
10533 if (size==1) // name if unique, so diskname is simply the name
10534 {
10535 FileDef *fd = fileEntries[0].fileDef;
10536 fd->setDiskName(fn->fileName());
10537 }
10538 else if (size>1) // multiple occurrences of the same file name
10539 {
10540 // sort the array
10541 std::stable_sort(fileEntries.begin(),
10542 fileEntries.end(),
10543 [](const FileEntry &fe1,const FileEntry &fe2)
10544 { return qstricmp_sort(fe1.path,fe2.path)<0; }
10545 );
10546
10547 // since the entries are sorted, the common prefix of the whole array is same
10548 // as the common prefix between the first and last entry
10549 const FileEntry &first = fileEntries[0];
10550 const FileEntry &last = fileEntries[size-1];
10551 int first_path_size = static_cast<int>(first.path.size())-1; // -1 to skip trailing slash
10552 int last_path_size = static_cast<int>(last.path.size())-1; // -1 to skip trailing slash
10553 int j=0;
10554 int i=0;
10555 for (i=0;i<first_path_size && i<last_path_size;i++)
10556 {
10557 if (first.path[i]=='/') j=i;
10558 if (first.path[i]!=last.path[i]) break;
10559 }
10560 if (i==first_path_size && i<last_path_size && last.path[i]=='/')
10561 {
10562 // case first='some/path' and last='some/path/more' => match is 'some/path'
10563 j=first_path_size;
10564 }
10565 else if (i==last_path_size && i<first_path_size && first.path[i]=='/')
10566 {
10567 // case first='some/path/more' and last='some/path' => match is 'some/path'
10568 j=last_path_size;
10569 }
10570
10571 // add non-common part of the path to the name
10572 for (auto &fileEntry : fileEntries)
10573 {
10574 QCString prefix = fileEntry.path.right(fileEntry.path.length()-j-1);
10575 fileEntry.fileDef->setName(prefix+fn->fileName());
10576 //printf("!!!!!!!! non unique disk name=%s:%s\n",qPrint(prefix),fn->fileName());
10577 fileEntry.fileDef->setDiskName(prefix+fn->fileName());
10578 }
10579 }
10580 }
10581}
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 9009 of file doxygen.cpp.

9010{
9011 AUTO_TRACE();
9012 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
9013 if (numThreads>1) // multi threaded processing
9014 {
9015 struct DocContext
9016 {
9017 DocContext(ClassDefMutable *cd_,const OutputList &ol_)
9018 : cd(cd_), ol(ol_) {}
9019 ClassDefMutable *cd;
9020 OutputList ol;
9021 };
9022 ThreadPool threadPool(numThreads);
9023 std::vector< std::future< std::shared_ptr<DocContext> > > results;
9024 for (const auto &cd : classList)
9025 {
9026 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9027 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9028 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9029 )
9030 {
9031 auto ctx = std::make_shared<DocContext>(cd,*g_outputList);
9032 auto processFile = [ctx]()
9033 {
9034 msg("Generating docs for compound {}...\n",ctx->cd->displayName());
9035
9036 // skip external references, anonymous compounds and
9037 // template instances
9038 if (!ctx->cd->isHidden() && !ctx->cd->isEmbeddedInOuterScope() &&
9039 ctx->cd->isLinkableInProject() && !ctx->cd->isImplicitTemplateInstance())
9040 {
9041 ctx->cd->writeDocumentation(ctx->ol);
9042 ctx->cd->writeMemberList(ctx->ol);
9043 }
9044
9045 // even for undocumented classes, the inner classes can be documented.
9046 ctx->cd->writeDocumentationForInnerClasses(ctx->ol);
9047 return ctx;
9048 };
9049 results.emplace_back(threadPool.queue(processFile));
9050 }
9051 }
9052 for (auto &f : results)
9053 {
9054 auto ctx = f.get();
9055 }
9056 }
9057 else // single threaded processing
9058 {
9059 for (const auto &cd : classList)
9060 {
9061 //printf("cd=%s getOuterScope=%p global=%p hidden=%d embeddedInOuterScope=%d\n",
9062 // qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope,cd->isHidden(),cd->isEmbeddedInOuterScope());
9063 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9064 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9065 )
9066 {
9067 // skip external references, anonymous compounds and
9068 // template instances
9069 if ( !cd->isHidden() && !cd->isEmbeddedInOuterScope() &&
9070 cd->isLinkableInProject() && !cd->isImplicitTemplateInstance())
9071 {
9072 msg("Generating docs for compound {}...\n",cd->displayName());
9073
9074 cd->writeDocumentation(*g_outputList);
9075 cd->writeMemberList(*g_outputList);
9076 }
9077 // even for undocumented classes, the inner classes can be documented.
9078 cd->writeDocumentationForInnerClasses(*g_outputList);
9079 }
9080 }
9081 }
9082}

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

Referenced by generateClassDocs().

◆ generateExampleDocs()

void generateExampleDocs ( )
static

Definition at line 9963 of file doxygen.cpp.

9964{
9965 g_outputList->disable(OutputType::Man);
9966 for (const auto &pd : *Doxygen::exampleLinkedMap)
9967 {
9968 msg("Generating docs for example {}...\n",pd->name());
9969 SrcLangExt lang = getLanguageFromFileName(pd->name(), SrcLangExt::Unknown);
9970 if (lang != SrcLangExt::Unknown)
9971 {
9972 QCString ext = getFileNameExtension(pd->name());
9973 auto intf = Doxygen::parserManager->getCodeParser(ext);
9974 intf->resetCodeParserState();
9975 }
9976 QCString n=pd->getOutputFileBase();
9977 startFile(*g_outputList,n,false,n,pd->name());
9979 g_outputList->docify(pd->name());
9981 g_outputList->startContents();
9982 QCString lineNoOptStr;
9983 if (pd->showLineNo())
9984 {
9985 lineNoOptStr="{lineno}";
9986 }
9987 g_outputList->generateDoc(pd->docFile(), // file
9988 pd->docLine(), // startLine
9989 pd.get(), // context
9990 nullptr, // memberDef
9991 (pd->briefDescription().isEmpty()?"":pd->briefDescription()+"\n\n")+
9992 pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
9993 DocOptions()
9994 .setIndexWords(true)
9995 .setExample(pd->name()));
9996 endFile(*g_outputList); // contains g_outputList->endContents()
9997 }
9999}
void startTitle(OutputList &ol, const QCString &fileName, const DefinitionMutable *def)
Definition index.cpp:384
void endFile(OutputList &ol, bool skipNavIndex, bool skipEndContents, const QCString &navPath)
Definition index.cpp:427
void endTitle(OutputList &ol, const QCString &fileName, const QCString &name)
Definition index.cpp:394
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:401
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5107
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5149

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

8673{
8674 if (Index::instance().numDocumentedFiles()==0) return;
8675
8676 if (!Doxygen::inputNameLinkedMap->empty())
8677 {
8678 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8679 if (numThreads>1) // multi threaded processing
8680 {
8681 struct DocContext
8682 {
8683 DocContext(FileDef *fd_,const OutputList &ol_)
8684 : fd(fd_), ol(ol_) {}
8685 FileDef *fd;
8686 OutputList ol;
8687 };
8688 ThreadPool threadPool(numThreads);
8689 std::vector< std::future< std::shared_ptr<DocContext> > > results;
8690 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8691 {
8692 for (const auto &fd : *fn)
8693 {
8694 bool doc = fd->isLinkableInProject();
8695 if (doc)
8696 {
8697 auto ctx = std::make_shared<DocContext>(fd.get(),*g_outputList);
8698 auto processFile = [ctx]() {
8699 msg("Generating docs for file {}...\n",ctx->fd->docName());
8700 ctx->fd->writeDocumentation(ctx->ol);
8701 return ctx;
8702 };
8703 results.emplace_back(threadPool.queue(processFile));
8704 }
8705 }
8706 }
8707 for (auto &f : results)
8708 {
8709 auto ctx = f.get();
8710 }
8711 }
8712 else // single threaded processing
8713 {
8714 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8715 {
8716 for (const auto &fd : *fn)
8717 {
8718 bool doc = fd->isLinkableInProject();
8719 if (doc)
8720 {
8721 msg("Generating docs for file {}...\n",fd->docName());
8722 fd->writeDocumentation(*g_outputList);
8723 }
8724 }
8725 }
8726 }
8727 }
8728}

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

Referenced by generateOutput().

◆ generateFileSources()

void generateFileSources ( )
static

Definition at line 8506 of file doxygen.cpp.

8507{
8508 auto processSourceFile = [](FileDef *fd,OutputList &ol,ClangTUParser *parser)
8509 {
8510 bool showSources = fd->generateSourceFile() && !Htags::useHtags; // sources need to be shown in the output
8511 bool parseSources = !fd->isReference() && Doxygen::parseSourcesNeeded; // we needed to parse the sources even if we do not show them
8512 if (showSources)
8513 {
8514 msg("Generating code for file {}...\n",fd->docName());
8515 fd->writeSourceHeader(ol);
8516 fd->writeSourceBody(ol,parser);
8517 fd->writeSourceFooter(ol);
8518 }
8519 else if (parseSources)
8520 {
8521 msg("Parsing code for file {}...\n",fd->docName());
8522 fd->parseSource(parser);
8523 }
8524 };
8525 if (!Doxygen::inputNameLinkedMap->empty())
8526 {
8527#if USE_LIBCLANG
8529 {
8530 StringUnorderedSet processedFiles;
8531
8532 // create a dictionary with files to process
8533 StringUnorderedSet filesToProcess;
8534
8535 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8536 {
8537 for (const auto &fd : *fn)
8538 {
8539 filesToProcess.insert(fd->absFilePath().str());
8540 }
8541 }
8542 // process source files (and their include dependencies)
8543 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8544 {
8545 for (const auto &fd : *fn)
8546 {
8547 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp &&
8548 (fd->generateSourceFile() ||
8550 )
8551 )
8552 {
8553 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8554 clangParser->parse();
8555 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8556
8557 for (auto incFile : clangParser->filesInSameTU())
8558 {
8559 if (filesToProcess.find(incFile)!=filesToProcess.end() && // part of input
8560 fd->absFilePath()!=incFile && // not same file
8561 processedFiles.find(incFile)==processedFiles.end()) // not yet marked as processed
8562 {
8563 StringVector moreFiles;
8564 bool ambig = false;
8566 if (ifd && !ifd->isReference())
8567 {
8568 processSourceFile(ifd,*g_outputList,clangParser.get());
8569 processedFiles.insert(incFile);
8570 }
8571 }
8572 }
8573 processedFiles.insert(fd->absFilePath().str());
8574 }
8575 }
8576 }
8577 // process remaining files
8578 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8579 {
8580 for (const auto &fd : *fn)
8581 {
8582 if (processedFiles.find(fd->absFilePath().str())==processedFiles.end()) // not yet processed
8583 {
8584 if (fd->getLanguage()==SrcLangExt::Cpp) // C/C++ file, use clang parser
8585 {
8586 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8587 clangParser->parse();
8588 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8589 }
8590 else // non C/C++ file, use built-in parser
8591 {
8592 processSourceFile(fd.get(),*g_outputList,nullptr);
8593 }
8594 }
8595 }
8596 }
8597 }
8598 else
8599#endif
8600 {
8601 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8602 if (numThreads>1)
8603 {
8604 msg("Generating code files using {} threads.\n",numThreads);
8605 struct SourceContext
8606 {
8607 SourceContext(FileDef *fd_,bool gen_,const OutputList &ol_)
8608 : fd(fd_), generateSourceFile(gen_), ol(ol_) {}
8609 FileDef *fd;
8610 bool generateSourceFile;
8611 OutputList ol;
8612 };
8613 ThreadPool threadPool(numThreads);
8614 std::vector< std::future< std::shared_ptr<SourceContext> > > results;
8615 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8616 {
8617 for (const auto &fd : *fn)
8618 {
8619 bool generateSourceFile = fd->generateSourceFile() && !Htags::useHtags;
8620 auto ctx = std::make_shared<SourceContext>(fd.get(),generateSourceFile,*g_outputList);
8621 auto processFile = [ctx]()
8622 {
8623 if (ctx->generateSourceFile)
8624 {
8625 msg("Generating code for file {}...\n",ctx->fd->docName());
8626 }
8627 else
8628 {
8629 msg("Parsing code for file {}...\n",ctx->fd->docName());
8630 }
8631 StringVector filesInSameTu;
8632 ctx->fd->getAllIncludeFilesRecursively(filesInSameTu);
8633 if (ctx->generateSourceFile) // sources need to be shown in the output
8634 {
8635 ctx->fd->writeSourceHeader(ctx->ol);
8636 ctx->fd->writeSourceBody(ctx->ol,nullptr);
8637 ctx->fd->writeSourceFooter(ctx->ol);
8638 }
8639 else if (!ctx->fd->isReference() && Doxygen::parseSourcesNeeded)
8640 // we needed to parse the sources even if we do not show them
8641 {
8642 ctx->fd->parseSource(nullptr);
8643 }
8644 return ctx;
8645 };
8646 results.emplace_back(threadPool.queue(processFile));
8647 }
8648 }
8649 for (auto &f : results)
8650 {
8651 auto ctx = f.get();
8652 }
8653 }
8654 else // single threaded version
8655 {
8656 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8657 {
8658 for (const auto &fd : *fn)
8659 {
8660 StringVector filesInSameTu;
8661 fd->getAllIncludeFilesRecursively(filesInSameTu);
8662 processSourceFile(fd.get(),*g_outputList,nullptr);
8663 }
8664 }
8665 }
8666 }
8667 }
8668}
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:138
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 10004 of file doxygen.cpp.

10005{
10006 for (const auto &gd : *Doxygen::groupLinkedMap)
10007 {
10008 if (!gd->isReference())
10009 {
10010 gd->writeDocumentation(*g_outputList);
10011 }
10012 }
10013}

References g_outputList, and Doxygen::groupLinkedMap.

Referenced by generateOutput().

◆ generateNamespaceClassDocs()

void generateNamespaceClassDocs ( const ClassLinkedRefMap & classList)
static

Definition at line 10018 of file doxygen.cpp.

10019{
10020 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10021 if (numThreads>1) // multi threaded processing
10022 {
10023 struct DocContext
10024 {
10025 DocContext(ClassDefMutable *cdm_,const OutputList &ol_)
10026 : cdm(cdm_), ol(ol_) {}
10027 ClassDefMutable *cdm;
10028 OutputList ol;
10029 };
10030 ThreadPool threadPool(numThreads);
10031 std::vector< std::future< std::shared_ptr<DocContext> > > results;
10032 // for each class in the namespace...
10033 for (const auto &cd : classList)
10034 {
10036 if (cdm)
10037 {
10038 auto ctx = std::make_shared<DocContext>(cdm,*g_outputList);
10039 auto processFile = [ctx]()
10040 {
10041 if ( ( ctx->cdm->isLinkableInProject() &&
10042 !ctx->cdm->isImplicitTemplateInstance()
10043 ) // skip external references, anonymous compounds and
10044 // template instances and nested classes
10045 && !ctx->cdm->isHidden() && !ctx->cdm->isEmbeddedInOuterScope()
10046 )
10047 {
10048 msg("Generating docs for compound {}...\n",ctx->cdm->displayName());
10049 ctx->cdm->writeDocumentation(ctx->ol);
10050 ctx->cdm->writeMemberList(ctx->ol);
10051 }
10052 ctx->cdm->writeDocumentationForInnerClasses(ctx->ol);
10053 return ctx;
10054 };
10055 results.emplace_back(threadPool.queue(processFile));
10056 }
10057 }
10058 // wait for the results
10059 for (auto &f : results)
10060 {
10061 auto ctx = f.get();
10062 }
10063 }
10064 else // single threaded processing
10065 {
10066 // for each class in the namespace...
10067 for (const auto &cd : classList)
10068 {
10070 if (cdm)
10071 {
10072 if ( ( cd->isLinkableInProject() &&
10073 !cd->isImplicitTemplateInstance()
10074 ) // skip external references, anonymous compounds and
10075 // template instances and nested classes
10076 && !cd->isHidden() && !cd->isEmbeddedInOuterScope()
10077 )
10078 {
10079 msg("Generating docs for compound {}...\n",cd->displayName());
10080
10083 }
10085 }
10086 }
10087 }
10088}
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 10090 of file doxygen.cpp.

10091{
10092 // for each concept in the namespace...
10093 for (const auto &cd : conceptList)
10094 {
10096 if ( cdm && cd->isLinkableInProject() && !cd->isHidden())
10097 {
10098 msg("Generating docs for concept {}...\n",cd->name());
10100 }
10101 }
10102}

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

Referenced by generateNamespaceDocs().

◆ generateNamespaceDocs()

void generateNamespaceDocs ( )
static

Definition at line 10104 of file doxygen.cpp.

10105{
10106 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
10107
10108 //writeNamespaceIndex(*g_outputList);
10109
10110 // for each namespace...
10111 for (const auto &nd : *Doxygen::namespaceLinkedMap)
10112 {
10113 if (nd->isLinkableInProject())
10114 {
10116 if (ndm)
10117 {
10118 msg("Generating docs for namespace {}\n",nd->displayName());
10120 }
10121 }
10122
10123 generateNamespaceClassDocs(nd->getClasses());
10124 if (sliceOpt)
10125 {
10126 generateNamespaceClassDocs(nd->getInterfaces());
10127 generateNamespaceClassDocs(nd->getStructs());
10128 generateNamespaceClassDocs(nd->getExceptions());
10129 }
10130 generateNamespaceConceptDocs(nd->getConcepts());
10131 }
10132}
virtual void writeDocumentation(OutputList &ol)=0
static void generateNamespaceConceptDocs(const ConceptLinkedRefMap &conceptList)
static void generateNamespaceClassDocs(const ClassLinkedRefMap &classList)

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

Referenced by generateOutput().

◆ generateOutput()

void generateOutput ( )

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

Definition at line 13052 of file doxygen.cpp.

13053{
13054 AUTO_TRACE();
13055 /**************************************************************************
13056 * Initialize output generators *
13057 **************************************************************************/
13058
13059 /// add extra languages for which we can only produce syntax highlighted code
13061
13062 //// dump all symbols
13063 if (g_dumpSymbolMap)
13064 {
13065 dumpSymbolMap();
13066 exit(0);
13067 }
13068
13069 bool generateHtml = Config_getBool(GENERATE_HTML);
13070 bool generateLatex = Config_getBool(GENERATE_LATEX);
13071 bool generateMan = Config_getBool(GENERATE_MAN);
13072 bool generateRtf = Config_getBool(GENERATE_RTF);
13073 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
13074
13075
13077 if (generateHtml)
13078 {
13082 }
13083 if (generateLatex)
13084 {
13087 }
13088 if (generateDocbook)
13089 {
13092 }
13093 if (generateMan)
13094 {
13095 g_outputList->add<ManGenerator>();
13097 }
13098 if (generateRtf)
13099 {
13100 g_outputList->add<RTFGenerator>();
13102 }
13103 if (Config_getBool(USE_HTAGS))
13104 {
13106 QCString htmldir = Config_getString(HTML_OUTPUT);
13107 if (!Htags::execute(htmldir))
13108 err("USE_HTAGS is YES but htags(1) failed. \n");
13109 else if (!Htags::loadFilemap(htmldir))
13110 err("htags(1) ended normally but failed to load the filemap. \n");
13111 }
13112
13113 /**************************************************************************
13114 * Generate documentation *
13115 **************************************************************************/
13116
13117 g_s.begin("Generating style sheet...\n");
13118 //printf("writing style info\n");
13119 g_outputList->writeStyleInfo(0); // write first part
13120 g_s.end();
13121
13122 bool searchEngine = Config_getBool(SEARCHENGINE);
13123 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
13124
13125 g_s.begin("Generating search indices...\n");
13126 if (searchEngine && !serverBasedSearch && generateHtml)
13127 {
13129 }
13130
13131 // generate search indices (need to do this before writing other HTML
13132 // pages as these contain a drop down menu with options depending on
13133 // what categories we find in this function.
13134 if (generateHtml && searchEngine)
13135 {
13136 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
13137 Dir searchDir(searchDirName.str());
13138 if (!searchDir.exists() && !searchDir.mkdir(searchDirName.str()))
13139 {
13140 term("Could not create search results directory '{}' $PWD='{}'\n",
13141 searchDirName,Dir::currentDirPath());
13142 }
13143 HtmlGenerator::writeSearchData(searchDirName);
13144 if (!serverBasedSearch) // client side search index
13145 {
13147 }
13148 }
13149 g_s.end();
13150
13151 // copy static stuff
13152 if (generateHtml)
13153 {
13155 copyLogo(Config_getString(HTML_OUTPUT));
13156 copyIcon(Config_getString(HTML_OUTPUT));
13157 copyExtraFiles(Config_getList(HTML_EXTRA_FILES),"HTML_EXTRA_FILES",Config_getString(HTML_OUTPUT));
13158 }
13159 if (generateLatex)
13160 {
13162 copyLogo(Config_getString(LATEX_OUTPUT));
13163 copyIcon(Config_getString(LATEX_OUTPUT));
13164 copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT));
13165 }
13166 if (generateDocbook)
13167 {
13168 copyLogo(Config_getString(DOCBOOK_OUTPUT));
13169 copyIcon(Config_getString(DOCBOOK_OUTPUT));
13170 }
13171 if (generateRtf)
13172 {
13173 copyLogo(Config_getString(RTF_OUTPUT));
13174 copyIcon(Config_getString(RTF_OUTPUT));
13175 copyExtraFiles(Config_getList(RTF_EXTRA_FILES),"RTF_EXTRA_FILES",Config_getString(RTF_OUTPUT));
13176 }
13177
13179 if (fm.hasFormulas() && generateHtml
13180 && !Config_getBool(USE_MATHJAX))
13181 {
13182 g_s.begin("Generating images for formulas in HTML...\n");
13183 fm.generateImages(Config_getString(HTML_OUTPUT), Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg ?
13185 g_s.end();
13186 }
13187 if (fm.hasFormulas() && generateRtf)
13188 {
13189 g_s.begin("Generating images for formulas in RTF...\n");
13191 g_s.end();
13192 }
13193
13194 if (fm.hasFormulas() && generateDocbook)
13195 {
13196 g_s.begin("Generating images for formulas in Docbook...\n");
13198 g_s.end();
13199 }
13200
13201 g_s.begin("Generating example documentation...\n");
13203 g_s.end();
13204
13205 g_s.begin("Generating file sources...\n");
13207 g_s.end();
13208
13209 g_s.begin("Generating file documentation...\n");
13211 g_s.end();
13212
13213 g_s.begin("Generating page documentation...\n");
13215 g_s.end();
13216
13217 g_s.begin("Generating group documentation...\n");
13219 g_s.end();
13220
13221 g_s.begin("Generating class documentation...\n");
13223 g_s.end();
13224
13225 g_s.begin("Generating concept documentation...\n");
13227 g_s.end();
13228
13229 g_s.begin("Generating module documentation...\n");
13231 g_s.end();
13232
13233 g_s.begin("Generating namespace documentation...\n");
13235 g_s.end();
13236
13237 if (Config_getBool(GENERATE_LEGEND))
13238 {
13239 g_s.begin("Generating graph info page...\n");
13241 g_s.end();
13242 }
13243
13244 g_s.begin("Generating directory documentation...\n");
13246 g_s.end();
13247
13248 if (g_outputList->size()>0)
13249 {
13251 }
13252
13253 g_s.begin("finalizing index lists...\n");
13254 Doxygen::indexList->finalize();
13255 g_s.end();
13256
13257 g_s.begin("writing tag file...\n");
13258 writeTagFile();
13259 g_s.end();
13260
13261 if (Config_getBool(GENERATE_XML))
13262 {
13263 g_s.begin("Generating XML output...\n");
13265 generateXML();
13267 g_s.end();
13268 }
13269 if (Config_getBool(GENERATE_SQLITE3))
13270 {
13271 g_s.begin("Generating SQLITE3 output...\n");
13273 g_s.end();
13274 }
13275
13276 if (Config_getBool(GENERATE_AUTOGEN_DEF))
13277 {
13278 g_s.begin("Generating AutoGen DEF output...\n");
13279 generateDEF();
13280 g_s.end();
13281 }
13282 if (Config_getBool(GENERATE_PERLMOD))
13283 {
13284 g_s.begin("Generating Perl module output...\n");
13286 g_s.end();
13287 }
13288 if (generateHtml && searchEngine && serverBasedSearch)
13289 {
13290 g_s.begin("Generating search index\n");
13291 if (Doxygen::searchIndex.kind()==SearchIndexIntf::Internal) // write own search index
13292 {
13294 Doxygen::searchIndex.write(Config_getString(HTML_OUTPUT)+"/search/search.idx");
13295 }
13296 else // write data for external search index
13297 {
13299 QCString searchDataFile = Config_getString(SEARCHDATA_FILE);
13300 if (searchDataFile.isEmpty())
13301 {
13302 searchDataFile="searchdata.xml";
13303 }
13304 if (!Portable::isAbsolutePath(searchDataFile.data()))
13305 {
13306 searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/");
13307 }
13308 Doxygen::searchIndex.write(searchDataFile);
13309 }
13310 g_s.end();
13311 }
13312
13313 if (generateRtf)
13314 {
13315 g_s.begin("Combining RTF output...\n");
13316 if (!RTFGenerator::preProcessFileInplace(Config_getString(RTF_OUTPUT),"refman.rtf"))
13317 {
13318 err("An error occurred during post-processing the RTF files!\n");
13319 }
13320 g_s.end();
13321 }
13322
13323 g_s.begin("Running plantuml with JAVA...\n");
13325 g_s.end();
13326
13327 if (Config_getBool(HAVE_DOT))
13328 {
13329 g_s.begin("Running dot...\n");
13331 g_s.end();
13332 }
13333
13334 if (generateHtml &&
13335 Config_getBool(GENERATE_HTMLHELP) &&
13336 !Config_getString(HHC_LOCATION).isEmpty())
13337 {
13338 g_s.begin("Running html help compiler...\n");
13340 g_s.end();
13341 }
13342
13343 if ( generateHtml &&
13344 Config_getBool(GENERATE_QHP) &&
13345 !Config_getString(QHG_LOCATION).isEmpty())
13346 {
13347 g_s.begin("Running qhelpgenerator...\n");
13349 g_s.end();
13350 }
13351
13352 g_outputList->cleanup();
13353
13354 msg("type lookup cache used {}/{} hits={} misses={}\n",
13356 Doxygen::typeLookupCache->capacity(),
13358 Doxygen::typeLookupCache->misses());
13359 msg("symbol lookup cache used {}/{} hits={} misses={}\n",
13361 Doxygen::symbolLookupCache->capacity(),
13363 Doxygen::symbolLookupCache->misses());
13364 int typeCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::typeLookupCache->misses()*2/3)); // part of the cache is flushed, hence the 2/3 correction factor
13365 int symbolCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::symbolLookupCache->misses()));
13366 int cacheParam = std::max(typeCacheParam,symbolCacheParam);
13367 if (cacheParam>Config_getInt(LOOKUP_CACHE_SIZE))
13368 {
13369 msg("Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is {} at the cost of higher memory usage.\n",cacheParam);
13370 }
13371
13373 {
13374
13375 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
13376 if (numThreads<1) numThreads=1;
13377 msg("Total elapsed time: {:.6f} seconds\n(of which an average of {:.6f} seconds per thread waiting for external tools to finish)\n",
13378 (static_cast<double>(Debug::elapsedTime())),
13379 Portable::getSysElapsedTime()/static_cast<double>(numThreads)
13380 );
13381 g_s.print();
13382
13384 msg("finished...\n");
13386 }
13387 else
13388 {
13389 msg("finished...\n");
13390 }
13391
13392
13393 /**************************************************************************
13394 * Start cleaning up *
13395 **************************************************************************/
13396
13398
13400 Dir thisDir;
13401 thisDir.remove(Doxygen::filterDBFileName.str());
13403 exitTracing();
13405 delete Doxygen::clangUsrMap;
13407
13408 //dumpDocNodeSizes();
13409}
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
static double elapsedTime()
Definition debug.cpp:201
static void setFlag(const DebugMask mask)
Definition debug.cpp:117
static std::string currentDirPath()
Definition dir.cpp:342
static void init()
bool run()
Definition dot.cpp:128
static DotManager * instance()
Definition dot.cpp:78
static Cache< std::string, LookupInfo > * symbolLookupCache
Definition doxygen.h:128
static bool generatingXmlOutput
Definition doxygen.h:136
static ClangUsrMap * clangUsrMap
Definition doxygen.h:126
bool hasFormulas() const
Definition formula.cpp:720
void generateImages(const QCString &outputDir, Format format, HighDPI hd=HighDPI::Off)
Definition formula.cpp:636
Generator for HTML output.
Definition htmlgen.h:96
static void init()
Definition htmlgen.cpp:1203
static void writeSearchPage()
Definition htmlgen.cpp:3170
static void writeTabData()
Additional initialization after indices have been created.
Definition htmlgen.cpp:1354
static void writeSearchData(const QCString &dir)
Definition htmlgen.cpp:1363
static void writeExternalSearchPage()
Definition htmlgen.cpp:3269
Generator for LaTeX output.
Definition latexgen.h:94
static void init()
Definition latexgen.cpp:633
Generator for Man page output.
Definition mangen.h:69
static void init()
Definition mangen.cpp:272
void writeDocumentation(OutputList &ol)
static PlantumlManager & instance()
Definition plantuml.cpp:231
void run()
Run plant UML tool for all images.
Definition plantuml.cpp:389
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
void generateDEF()
Definition defgen.cpp:482
void generateDirDocs(OutputList &ol)
Definition dirdef.cpp:1193
static void copyLatexStyleSheet()
static void runQHelpGenerator()
class Statistics g_s
static void copyStyleSheet()
static void generateGroupDocs()
static void generateExampleDocs()
Definition doxygen.cpp:9963
static void dumpSymbolMap()
static void generateFileDocs()
Definition doxygen.cpp:8672
static void copyIcon(const QCString &outputOption)
static void generatePageDocs()
Definition doxygen.cpp:9878
static void generateFileSources()
Definition doxygen.cpp:8506
static void copyLogo(const QCString &outputOption)
static void generateClassDocs()
Definition doxygen.cpp:9107
static int computeIdealCacheParam(size_t v)
static void copyExtraFiles(const StringVector &files, const QCString &filesOption, const QCString &outputOption)
static void runHtmlHelpCompiler()
static bool g_dumpSymbolMap
Definition doxygen.cpp:191
static void generateNamespaceDocs()
static void writeTagFile()
void cleanUpDoxygen()
static void generateConceptDocs()
Definition doxygen.cpp:9133
void writeGraphInfo(OutputList &ol)
Definition index.cpp:4053
void writeIndexHierarchy(OutputList &ol)
Definition index.cpp:5759
void finishWarnExit()
Definition message.cpp:295
void deinit()
bool isAbsolutePath(const QCString &fileName)
Definition portable.cpp:498
double getSysElapsedTime()
Definition portable.cpp:98
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:5101
void generateXML()
Definition xmlgen.cpp:2214

References addCodeOnlyMappings(), AUTO_TRACE, FormulaManager::Bitmap, Doxygen::clangUsrMap, cleanUpDoxygen(), Debug::clearFlag(), computeIdealCacheParam(), Config_getBool, Config_getEnum, Config_getInt, Config_getList, Config_getString, copyExtraFiles(), copyIcon(), copyLatexStyleSheet(), copyLogo(), copyStyleSheet(), 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(), 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(), PlantumlManager::run(), runHtmlHelpCompiler(), runQHelpGenerator(), Doxygen::searchIndex, Debug::setFlag(), QCString::str(), Doxygen::symbolLookupCache, term, Debug::Time, TRUE, Doxygen::typeLookupCache, 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 9878 of file doxygen.cpp.

9879{
9880 //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageLinkedMap->count());
9881 if (Index::instance().numDocumentedPages()==0) return;
9882 for (const auto &pd : *Doxygen::pageLinkedMap)
9883 {
9884 if (!pd->getGroupDef() && !pd->isReference())
9885 {
9886 msg("Generating docs for page {}...\n",pd->name());
9887 pd->writeDocumentation(*g_outputList);
9888 }
9889 }
9890}

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

Referenced by generateOutput().

◆ generateXRefPages()

void generateXRefPages ( )
static

Definition at line 5509 of file doxygen.cpp.

5510{
5511 AUTO_TRACE();
5513 {
5514 rl->generatePage();
5515 }
5516}
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 11306 of file doxygen.cpp.

11307{
11308 char *s=nullptr;
11309 if (qstrlen(&argv[optInd][2])>0)
11310 s=&argv[optInd][2];
11311 else if (optInd+1<argc && argv[optInd+1][0]!='-')
11312 s=argv[++optInd];
11313 return s;
11314}
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 10587 of file doxygen.cpp.

10588{
10589 QCString fileName=fn;
10590 QCString extension;
10591 int sep = fileName.findRev('/');
10592 int ei = fileName.findRev('.');
10593 if (ei!=-1 && (sep==-1 || ei>sep)) // matches dir/file.ext but not dir.1/file
10594 {
10595 extension=fileName.right(fileName.length()-ei);
10596 }
10597 else
10598 {
10599 extension = ".no_extension";
10600 }
10601
10602 return Doxygen::parserManager->getOutlineParser(extension);
10603}

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

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

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

4449{
4450 std::map<std::string,int> templateNames;
4451 int count=0;
4452 for (const Argument &arg : templateArguments)
4453 {
4454 static const reg::Ex re(R"(\a[\w:]*)");
4455 reg::Iterator it(name,re);
4457 for (; it!=end ; ++it)
4458 {
4459 const auto &match = *it;
4460 std::string n = match.str();
4461 if (n==arg.name.str())
4462 {
4463 if (templateNames.find(n)==templateNames.end())
4464 {
4465 templateNames.emplace(n,count);
4466 }
4467 }
4468 }
4469 }
4470 return templateNames;
4471}

References end().

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

◆ haveEqualFileNames()

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

Definition at line 9462 of file doxygen.cpp.

9463{
9464 const FileDef *fd = md->getFileDef();
9465 if (!fd)
9466 {
9467 return FALSE;
9468 }
9469
9470 return fd->absFilePath() == root->fileName;
9471}

References FileDef::absFilePath(), FALSE, Entry::fileName, and MemberDef::getFileDef().

Referenced by findDefineDocumentation().

◆ inheritDocumentation()

void inheritDocumentation ( )
static

Definition at line 9154 of file doxygen.cpp.

9155{
9156 for (const auto &mn : *Doxygen::memberNameLinkedMap)
9157 {
9158 for (const auto &imd : *mn)
9159 {
9160 MemberDefMutable *md = toMemberDefMutable(imd.get());
9161 //static int count=0;
9162 //printf("%04d Member '%s'\n",count++,qPrint(md->qualifiedName()));
9163 if (md && md->documentation().isEmpty() && md->briefDescription().isEmpty())
9164 { // no documentation yet
9165 const MemberDef *bmd = md->reimplements();
9166 while (bmd && bmd->documentation().isEmpty() &&
9167 bmd->briefDescription().isEmpty()
9168 )
9169 { // search up the inheritance tree for a documentation member
9170 //printf("bmd=%s class=%s\n",qPrint(bmd->name()),qPrint(bmd->getClassDef()->name()));
9171 bmd = bmd->reimplements();
9172 }
9173 if (bmd) // copy the documentation from the reimplemented member
9174 {
9175 md->setInheritsDocsFrom(bmd);
9176 md->setDocumentation(bmd->documentation(),bmd->docFile(),bmd->docLine());
9178 md->setBriefDescription(bmd->briefDescription(),bmd->briefFile(),bmd->briefLine());
9179 md->copyArgumentNames(bmd);
9181 }
9182 }
9183 }
9184 }
9185}
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 11333 of file doxygen.cpp.

11334{
11335 initResources();
11336 QCString lang = Portable::getenv("LC_ALL");
11337 if (!lang.isEmpty()) Portable::setenv("LANG",lang);
11338 std::setlocale(LC_ALL,"");
11339 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
11340 std::setlocale(LC_NUMERIC,"C");
11341
11343
11367
11368 // register any additional parsers here...
11369
11371
11372#if USE_LIBCLANG
11374#endif
11383 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
11384 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
11385 //Doxygen::tagDestinationDict.setAutoDelete(TRUE);
11387
11388 // initialization of these globals depends on
11389 // configuration switches so we need to postpone these
11390 Doxygen::globalScope = nullptr;
11399
11400}
static void startTimer()
Definition debug.cpp:196
A linked map of directories.
Definition dirdef.h:173
A list of index interfaces.
Definition indexlist.h:64
Manages programming language parsers.
Definition parserintf.h:147
std::function< std::unique_ptr< T >() > make_parser_factory()
void initResources()
std::unordered_map< std::string, const Definition * > ClangUsrMap
Definition doxygen.h:83
void setenv(const QCString &variable, const QCString &value)
Definition portable.cpp:287
QCString getenv(const QCString &variable)
Definition portable.cpp:322
void initDefaultExtensionMapping()
Definition util.cpp:5034

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

6604{
6605 if (outerScope && outerScope!=Doxygen::globalScope)
6606 {
6607 auto aliasMd = createMemberDefAlias(outerScope,md);
6608 if (outerScope->definitionType()==Definition::TypeClass)
6609 {
6610 ClassDefMutable *cdm = toClassDefMutable(outerScope);
6611 if (cdm)
6612 {
6613 cdm->insertMember(aliasMd.get());
6614 }
6615 }
6616 else if (outerScope->definitionType()==Definition::TypeNamespace)
6617 {
6618 NamespaceDefMutable *ndm = toNamespaceDefMutable(outerScope);
6619 if (ndm)
6620 {
6621 ndm->insertMember(aliasMd.get());
6622 }
6623 }
6624 else if (outerScope->definitionType()==Definition::TypeFile)
6625 {
6626 toFileDef(outerScope)->insertMember(aliasMd.get());
6627 }
6628 if (aliasMd)
6629 {
6630 Doxygen::functionNameLinkedMap->add(md->name())->push_back(std::move(aliasMd));
6631 }
6632 }
6633}
FileDef * toFileDef(Definition *d)
Definition filedef.cpp:1954

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

5185{
5186 if ( !root->name.isEmpty() )
5187 {
5188 if (root->section.isCompound())
5189 // is it a compound (class, struct, union, interface ...)
5190 {
5191 return TRUE;
5192 }
5193 else if (root->section.isCompoundDoc())
5194 // is it a documentation block with inheritance info.
5195 {
5196 bool hasExtends = !root->extends.empty();
5197 if (hasExtends) return TRUE;
5198 }
5199 }
5200 return FALSE;
5201}

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

5689{
5690 const GroupDef *gd = md->getGroupDef();
5691 if (!gd)
5692 {
5693 return allowNoGroup;
5694 }
5695
5696 for (const auto &g : root->groups)
5697 {
5698 if (g.groupname == gd->name())
5699 {
5700 return true; // matching group
5701 }
5702 }
5703
5704 return false;
5705}

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

4802{
4803 QCString n=name;
4804 int index=n.find('<');
4805 if (index!=-1)
4806 {
4807 n=n.left(index);
4808 }
4809 bool result = rightScopeMatch(scope,n);
4810 return result;
4811}

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

Referenced by findClassRelation().

◆ isSpecialization()

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

Definition at line 5919 of file doxygen.cpp.

5923{
5924 auto srcIt = srcTempArgLists.begin();
5925 auto dstIt = dstTempArgLists.begin();
5926 while (srcIt!=srcTempArgLists.end() && dstIt!=dstTempArgLists.end())
5927 {
5928 if ((*srcIt).size()!=(*dstIt).size()) return TRUE;
5929 ++srcIt;
5930 ++dstIt;
5931 }
5932 return FALSE;
5933}

References FALSE, and TRUE.

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

◆ isSymbolHidden()

bool isSymbolHidden ( const Definition * d)
static

Definition at line 8901 of file doxygen.cpp.

8902{
8903 bool hidden = d->isHidden();
8904 const Definition *parent = d->getOuterScope();
8905 return parent ? hidden || isSymbolHidden(parent) : hidden;
8906}
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:1330

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

2886{
2887 bool result = false;
2888 bool typeIsClass = false;
2889 bool typePtrType = false;
2890 QCString type;
2891 Definition *ctx = nullptr;
2892 FileDef *fd = root->fileDef();
2893 SymbolResolver resolver(fd);
2894
2895 AUTO_TRACE("isVarWithConstructor({})",root->name);
2896 if (root->parent()->section.isCompound())
2897 { // inside a class
2898 result=FALSE;
2899 AUTO_TRACE_EXIT("inside class: result={}",result);
2900 return result;
2901 }
2902 else if ((fd != nullptr) && (fd->name().endsWith(".c") || fd->name().endsWith(".h")))
2903 { // inside a .c file
2904 result=FALSE;
2905 AUTO_TRACE_EXIT("inside C file: result={}",result);
2906 return result;
2907 }
2908 if (root->type.isEmpty())
2909 {
2910 result=FALSE;
2911 AUTO_TRACE_EXIT("no type: result={}",result);
2912 return result;
2913 }
2914 if (!root->parent()->name.isEmpty())
2915 {
2916 ctx=Doxygen::namespaceLinkedMap->find(root->parent()->name);
2917 }
2918 type = root->type;
2919 // remove qualifiers
2920 findAndRemoveWord(type,"const");
2921 findAndRemoveWord(type,"static");
2922 findAndRemoveWord(type,"volatile");
2923 typePtrType = type.find('*')!=-1 || type.find('&')!=-1;
2924 if (!typePtrType)
2925 {
2926 typeIsClass = resolver.resolveClass(ctx,type)!=nullptr;
2927 int ti=0;
2928 if (!typeIsClass && (ti=type.find('<'))!=-1)
2929 {
2930 typeIsClass=resolver.resolveClass(ctx,type.left(ti))!=nullptr;
2931 }
2932 }
2933 if (typeIsClass) // now we still have to check if the arguments are
2934 // types or values. Since we do not have complete type info
2935 // we need to rely on heuristics :-(
2936 {
2937 if (root->argList.empty())
2938 {
2939 result=FALSE; // empty arg list -> function prototype.
2940 AUTO_TRACE_EXIT("empty arg list: result={}",result);
2941 return result;
2942 }
2943 for (const Argument &a : root->argList)
2944 {
2945 static const reg::Ex initChars(R"([\d"'&*!^]+)");
2947 if (!a.name.isEmpty() || !a.defval.isEmpty())
2948 {
2949 std::string name = a.name.str();
2950 if (reg::search(name,match,initChars) && match.position()==0)
2951 {
2952 result=TRUE;
2953 }
2954 else
2955 {
2956 result=FALSE; // arg has (type,name) pair -> function prototype
2957 }
2958 AUTO_TRACE_EXIT("function prototype: result={}",result);
2959 return result;
2960 }
2961 if (!a.type.isEmpty() &&
2962 (a.type.at(a.type.length()-1)=='*' ||
2963 a.type.at(a.type.length()-1)=='&'))
2964 // type ends with * or & => pointer or reference
2965 {
2966 result=FALSE;
2967 AUTO_TRACE_EXIT("pointer or reference: result={}",result);
2968 return result;
2969 }
2970 if (a.type.isEmpty() || resolver.resolveClass(ctx,a.type)!=nullptr)
2971 {
2972 result=FALSE; // arg type is a known type
2973 AUTO_TRACE_EXIT("known type: result={}",result);
2974 return result;
2975 }
2976 if (checkIfTypedef(ctx,fd,a.type))
2977 {
2978 result=FALSE; // argument is a typedef
2979 AUTO_TRACE_EXIT("typedef: result={}",result);
2980 return result;
2981 }
2982 std::string atype = a.type.str();
2983 if (reg::search(atype,match,initChars) && match.position()==0)
2984 {
2985 result=TRUE; // argument type starts with typical initializer char
2986 AUTO_TRACE_EXIT("argument with init char: result={}",result);
2987 return result;
2988 }
2989 std::string resType=resolveTypeDef(ctx,a.type).str();
2990 if (resType.empty()) resType=atype;
2991 static const reg::Ex idChars(R"(\a\w*)");
2992 if (reg::search(resType,match,idChars) && match.position()==0) // resType starts with identifier
2993 {
2994 resType=match.str();
2995 if (resType=="int" || resType=="long" ||
2996 resType=="float" || resType=="double" ||
2997 resType=="char" || resType=="void" ||
2998 resType=="signed" || resType=="unsigned" ||
2999 resType=="const" || resType=="volatile" )
3000 {
3001 result=FALSE; // type keyword -> function prototype
3002 AUTO_TRACE_EXIT("type keyword: result={}",result);
3003 return result;
3004 }
3005 }
3006 }
3007 result=TRUE;
3008 }
3009
3010 AUTO_TRACE_EXIT("end: result={}",result);
3011 return result;
3012}
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:5211
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:4883

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

11329{
11330 return []() { return std::make_unique<T>(); };
11331}

Referenced by initDoxygen().

◆ makeTemplateInstanceRelation()

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

Definition at line 5258 of file doxygen.cpp.

5259{
5260 AUTO_TRACE("root->name={} cd={}",root->name,cd->name());
5261 int i = root->name.find('<');
5262 int j = root->name.findRev('>');
5263 int k = root->name.find("::",j+1); // A<T::B> => ok, A<T>::B => nok
5264 if (i!=-1 && j!=-1 && k==-1 && root->lang!=SrcLangExt::CSharp && root->lang!=SrcLangExt::Java)
5265 {
5266 ClassDefMutable *master = getClassMutable(root->name.left(i));
5267 if (master && master!=cd && !cd->templateMaster())
5268 {
5269 AUTO_TRACE_ADD("class={} master={}",cd->name(),cd->templateMaster()?cd->templateMaster()->name():"<none>",master->name());
5270 cd->setTemplateMaster(master);
5271 master->insertExplicitTemplateInstance(cd,root->name.mid(i));
5272 }
5273 }
5274}
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 8454 of file doxygen.cpp.

8455{
8456 AUTO_TRACE();
8457 // merge members of categories into the class they extend
8458 for (const auto &cd : *Doxygen::classLinkedMap)
8459 {
8460 int i=cd->name().find('(');
8461 if (i!=-1) // it is an Objective-C category
8462 {
8463 QCString baseName=cd->name().left(i);
8464 ClassDefMutable *baseClass=toClassDefMutable(Doxygen::classLinkedMap->find(baseName));
8465 if (baseClass)
8466 {
8467 AUTO_TRACE_ADD("merging members of category {} into {}",cd->name(),baseClass->name());
8468 baseClass->mergeCategory(cd.get());
8469 }
8470 }
8471 }
8472}
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 484 of file doxygen.cpp.

485{
486 //printf("Defining groups\n");
487 // first process the @defgroups blocks
489 //printf("Additional groups\n");
490 // then process the @addtogroup, @weakgroup blocks
492}
static void organizeSubGroupsFiltered(const Entry *root, bool additional)
Definition doxygen.cpp:465

References FALSE, organizeSubGroupsFiltered(), and TRUE.

Referenced by parseInput().

◆ organizeSubGroupsFiltered()

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

Definition at line 465 of file doxygen.cpp.

466{
467 if (root->section.isGroupDoc() && !root->name.isEmpty())
468 {
469 AUTO_TRACE("additional={}",additional);
470 if ((root->groupDocType==Entry::GROUPDOC_NORMAL && !additional) ||
471 (root->groupDocType!=Entry::GROUPDOC_NORMAL && additional))
472 {
473 GroupDef *gd = Doxygen::groupLinkedMap->find(root->name);
474 if (gd)
475 {
476 AUTO_TRACE_ADD("adding {} to group {}",root->name,gd->name());
477 addGroupToGroups(root,gd);
478 }
479 }
480 }
481 for (const auto &e : root->children()) organizeSubGroupsFiltered(e.get(),additional);
482}
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 10605 of file doxygen.cpp.

10608{
10609 QCString fileName=fn;
10610 AUTO_TRACE("fileName={}",fileName);
10611 QCString extension;
10612 int ei = fileName.findRev('.');
10613 if (ei!=-1)
10614 {
10615 extension=fileName.right(fileName.length()-ei);
10616 }
10617 else
10618 {
10619 extension = ".no_extension";
10620 }
10621
10622 FileInfo fi(fileName.str());
10623 std::string preBuf;
10624
10625 if (Config_getBool(ENABLE_PREPROCESSING) &&
10626 parser.needsPreprocessing(extension))
10627 {
10628 Preprocessor preprocessor;
10629 const StringVector &includePath = Config_getList(INCLUDE_PATH);
10630 for (const auto &s : includePath)
10631 {
10632 std::string absPath = FileInfo(s).absFilePath();
10633 preprocessor.addSearchDir(absPath);
10634 }
10635 std::string inBuf;
10636 msg("Preprocessing {}...\n",fn);
10637 readInputFile(fileName,inBuf);
10638 addTerminalCharIfMissing(inBuf,'\n');
10639 preprocessor.processFile(fileName,inBuf,preBuf);
10640 }
10641 else // no preprocessing
10642 {
10643 msg("Reading {}...\n",fn);
10644 readInputFile(fileName,preBuf);
10645 addTerminalCharIfMissing(preBuf,'\n');
10646 }
10647
10648 std::string convBuf;
10649 convBuf.reserve(preBuf.size()+1024);
10650
10651 // convert multi-line C++ comments to C style comments
10652 convertCppComments(preBuf,convBuf,fileName.str());
10653
10654 std::shared_ptr<Entry> fileRoot = std::make_shared<Entry>();
10655 // use language parse to parse the file
10656 if (clangParser)
10657 {
10658 if (newTU) clangParser->parse();
10659 clangParser->switchToFile(fd);
10660 }
10661 parser.parseInput(fileName,convBuf.data(),fileRoot,clangParser);
10662 fileRoot->setFileDef(fd);
10663 return fileRoot;
10664}
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:4073
void addSearchDir(const QCString &dir)
Definition pre.l:4055
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:5446

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

10668{
10669 AUTO_TRACE();
10670#if USE_LIBCLANG
10672 {
10673 StringUnorderedSet processedFiles;
10674
10675 // create a dictionary with files to process
10676 StringUnorderedSet filesToProcess;
10677 for (const auto &s : g_inputFiles)
10678 {
10679 filesToProcess.insert(s);
10680 }
10681
10682 std::mutex processedFilesLock;
10683 // process source files (and their include dependencies)
10684 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10685 msg("Processing input using {} threads.\n",numThreads);
10686 ThreadPool threadPool(numThreads);
10687 using FutureType = std::vector< std::shared_ptr<Entry> >;
10688 std::vector< std::future< FutureType > > results;
10689 for (const auto &s : g_inputFiles)
10690 {
10691 bool ambig = false;
10692 QCString qs = s;
10694 ASSERT(fd!=nullptr);
10695 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp) // this is a source file
10696 {
10697 // lambda representing the work to executed by a thread
10698 auto processFile = [qs,&filesToProcess,&processedFilesLock,&processedFiles]() {
10699 bool ambig_l = false;
10700 std::vector< std::shared_ptr<Entry> > roots;
10702 auto clangParser = ClangParser::instance()->createTUParser(fd_l);
10703 auto parser = getParserForFile(qs);
10704 auto fileRoot { parseFile(*parser.get(),fd_l,qs,clangParser.get(),true) };
10705 roots.push_back(fileRoot);
10706
10707 // Now process any include files in the same translation unit
10708 // first. When libclang is used this is much more efficient.
10709 for (auto incFile : clangParser->filesInSameTU())
10710 {
10711 QCString qincFile = incFile;
10712 if (filesToProcess.find(incFile)!=filesToProcess.end())
10713 {
10714 bool needsToBeProcessed = false;
10715 {
10716 std::lock_guard<std::mutex> lock(processedFilesLock);
10717 needsToBeProcessed = processedFiles.find(incFile)==processedFiles.end();
10718 if (needsToBeProcessed) processedFiles.insert(incFile);
10719 }
10720 if (qincFile!=qs && needsToBeProcessed)
10721 {
10722 FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,qincFile,ambig_l);
10723 if (ifd && !ifd->isReference())
10724 {
10725 //printf(" Processing %s in same translation unit as %s\n",incFile,qPrint(s));
10726 fileRoot = parseFile(*parser.get(),ifd,qincFile,clangParser.get(),false);
10727 roots.push_back(fileRoot);
10728 }
10729 }
10730 }
10731 }
10732 return roots;
10733 };
10734 // dispatch the work and collect the future results
10735 results.emplace_back(threadPool.queue(processFile));
10736 }
10737 }
10738 // synchronize with the Entry result lists produced and add them to the root
10739 for (auto &f : results)
10740 {
10741 auto l = f.get();
10742 for (auto &e : l)
10743 {
10744 root->moveToSubEntryAndKeep(e);
10745 }
10746 }
10747 // process remaining files
10748 results.clear();
10749 for (const auto &s : g_inputFiles)
10750 {
10751 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
10752 {
10753 // lambda representing the work to executed by a thread
10754 auto processFile = [s]() {
10755 bool ambig = false;
10756 QCString qs = s;
10757 std::vector< std::shared_ptr<Entry> > roots;
10759 auto parser { getParserForFile(qs) };
10760 bool useClang = getLanguageFromFileName(qs)==SrcLangExt::Cpp;
10761 if (useClang)
10762 {
10763 auto clangParser = ClangParser::instance()->createTUParser(fd);
10764 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10765 roots.push_back(fileRoot);
10766 }
10767 else
10768 {
10769 auto fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10770 roots.push_back(fileRoot);
10771 }
10772 return roots;
10773 };
10774 results.emplace_back(threadPool.queue(processFile));
10775 }
10776 }
10777 // synchronize with the Entry result lists produced and add them to the root
10778 for (auto &f : results)
10779 {
10780 auto l = f.get();
10781 for (auto &e : l)
10782 {
10783 root->moveToSubEntryAndKeep(e);
10784 }
10785 }
10786 }
10787 else // normal processing
10788#endif
10789 {
10790 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10791 msg("Processing input using {} threads.\n",numThreads);
10792 ThreadPool threadPool(numThreads);
10793 using FutureType = std::shared_ptr<Entry>;
10794 std::vector< std::future< FutureType > > results;
10795 for (const auto &s : g_inputFiles)
10796 {
10797 // lambda representing the work to executed by a thread
10798 auto processFile = [s]() {
10799 bool ambig = false;
10800 QCString qs = s;
10802 auto parser = getParserForFile(qs);
10803 auto fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10804 return fileRoot;
10805 };
10806 // dispatch the work and collect the future results
10807 results.emplace_back(threadPool.queue(processFile));
10808 }
10809 // synchronize with the Entry results produced and add them to the root
10810 for (auto &f : results)
10811 {
10812 root->moveToSubEntryAndKeep(f.get());
10813 }
10814 }
10815}
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 10818 of file doxygen.cpp.

10819{
10820 AUTO_TRACE();
10821#if USE_LIBCLANG
10823 {
10824 StringUnorderedSet processedFiles;
10825
10826 // create a dictionary with files to process
10827 StringUnorderedSet filesToProcess;
10828 for (const auto &s : g_inputFiles)
10829 {
10830 filesToProcess.insert(s);
10831 }
10832
10833 // process source files (and their include dependencies)
10834 for (const auto &s : g_inputFiles)
10835 {
10836 bool ambig = false;
10837 QCString qs =s;
10839 ASSERT(fd!=nullptr);
10840 if (fd->isSource() && !fd->isReference() && getLanguageFromFileName(qs)==SrcLangExt::Cpp) // this is a source file
10841 {
10842 auto clangParser = ClangParser::instance()->createTUParser(fd);
10843 auto parser { getParserForFile(qs) };
10844 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10845 root->moveToSubEntryAndKeep(fileRoot);
10846 processedFiles.insert(s);
10847
10848 // Now process any include files in the same translation unit
10849 // first. When libclang is used this is much more efficient.
10850 for (auto incFile : clangParser->filesInSameTU())
10851 {
10852 //printf(" file %s\n",qPrint(incFile));
10853 if (filesToProcess.find(incFile)!=filesToProcess.end() && // file need to be processed
10854 processedFiles.find(incFile)==processedFiles.end()) // and is not processed already
10855 {
10857 if (ifd && !ifd->isReference())
10858 {
10859 //printf(" Processing %s in same translation unit as %s\n",qPrint(incFile),qPrint(qs));
10860 fileRoot = parseFile(*parser.get(),ifd,incFile,clangParser.get(),false);
10861 root->moveToSubEntryAndKeep(fileRoot);
10862 processedFiles.insert(incFile);
10863 }
10864 }
10865 }
10866 }
10867 }
10868 // process remaining files
10869 for (const auto &s : g_inputFiles)
10870 {
10871 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
10872 {
10873 bool ambig = false;
10874 QCString qs = s;
10876 if (getLanguageFromFileName(qs)==SrcLangExt::Cpp) // not yet processed
10877 {
10878 auto clangParser = ClangParser::instance()->createTUParser(fd);
10879 auto parser { getParserForFile(qs) };
10880 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10881 root->moveToSubEntryAndKeep(fileRoot);
10882 }
10883 else
10884 {
10885 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
10886 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10887 root->moveToSubEntryAndKeep(fileRoot);
10888 }
10889 processedFiles.insert(s);
10890 }
10891 }
10892 }
10893 else // normal processing
10894#endif
10895 {
10896 for (const auto &s : g_inputFiles)
10897 {
10898 bool ambig = false;
10899 QCString qs = s;
10901 ASSERT(fd!=nullptr);
10902 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
10903 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10904 root->moveToSubEntryAndKeep(std::move(fileRoot));
10905 }
10906 }
10907}

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

12378{
12379 AUTO_TRACE();
12380 std::atexit(exitDoxygen);
12381
12382 Portable::correctPath(Config_getList(EXTERNAL_TOOL_PATH));
12383
12384#if USE_LIBCLANG
12385 Doxygen::clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
12386#endif
12387
12388 // we would like to show the versionString earlier, but we first have to handle the configuration file
12389 // to know the value of the QUIET setting.
12390 QCString versionString = getFullVersion();
12391 msg("Doxygen version used: {}\n",versionString);
12392
12394
12395 /**************************************************************************
12396 * Make sure the output directory exists
12397 **************************************************************************/
12398 QCString outputDirectory = Config_getString(OUTPUT_DIRECTORY);
12399 if (!g_singleComment)
12400 {
12401 if (outputDirectory.isEmpty())
12402 {
12403 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,Dir::currentDirPath());
12404 }
12405 else
12406 {
12407 Dir dir(outputDirectory.str());
12408 if (!dir.exists())
12409 {
12410 dir.setPath(Dir::currentDirPath());
12411 if (!dir.mkdir(outputDirectory.str()))
12412 {
12413 term("tag OUTPUT_DIRECTORY: Output directory '{}' does not "
12414 "exist and cannot be created\n",outputDirectory);
12415 }
12416 else
12417 {
12418 msg("Notice: Output directory '{}' does not exist. "
12419 "I have created it for you.\n", outputDirectory);
12420 }
12421 dir.setPath(outputDirectory.str());
12422 }
12423 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,dir.absPath());
12424 }
12425 }
12426 AUTO_TRACE_ADD("outputDirectory={}",outputDirectory);
12427
12428 /**************************************************************************
12429 * Initialize global lists and dictionaries
12430 **************************************************************************/
12431
12432 // also scale lookup cache with SYMBOL_CACHE_SIZE
12433 int cacheSize = Config_getInt(LOOKUP_CACHE_SIZE);
12434 if (cacheSize<0) cacheSize=0;
12435 if (cacheSize>9) cacheSize=9;
12436 uint32_t lookupSize = 65536 << cacheSize;
12439
12440#ifdef HAS_SIGNALS
12441 signal(SIGINT, stopDoxygen);
12442#endif
12443
12444 uint32_t pid = Portable::pid();
12445 Doxygen::filterDBFileName.sprintf("doxygen_filterdb_%d.tmp",pid);
12446 Doxygen::filterDBFileName.prepend(outputDirectory+"/");
12447
12448 /**************************************************************************
12449 * Check/create output directories *
12450 **************************************************************************/
12451
12452 bool generateHtml = Config_getBool(GENERATE_HTML);
12453 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
12454 bool generateXml = Config_getBool(GENERATE_XML);
12455 bool generateLatex = Config_getBool(GENERATE_LATEX);
12456 bool generateRtf = Config_getBool(GENERATE_RTF);
12457 bool generateMan = Config_getBool(GENERATE_MAN);
12458 bool generateSql = Config_getBool(GENERATE_SQLITE3);
12459 QCString htmlOutput;
12460 QCString docbookOutput;
12461 QCString xmlOutput;
12462 QCString latexOutput;
12463 QCString rtfOutput;
12464 QCString manOutput;
12465 QCString sqlOutput;
12466
12467 if (!g_singleComment)
12468 {
12469 if (generateHtml)
12470 {
12471 htmlOutput = createOutputDirectory(outputDirectory,Config_getString(HTML_OUTPUT),"/html");
12472 Config_updateString(HTML_OUTPUT,htmlOutput);
12473
12474 QCString sitemapUrl = Config_getString(SITEMAP_URL);
12475 bool generateSitemap = !sitemapUrl.isEmpty();
12476 if (generateSitemap && !sitemapUrl.endsWith("/"))
12477 {
12478 Config_updateString(SITEMAP_URL,sitemapUrl+"/");
12479 }
12480
12481 // add HTML indexers that are enabled
12482 bool generateHtmlHelp = Config_getBool(GENERATE_HTMLHELP);
12483 bool generateEclipseHelp = Config_getBool(GENERATE_ECLIPSEHELP);
12484 bool generateQhp = Config_getBool(GENERATE_QHP);
12485 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
12486 bool generateDocSet = Config_getBool(GENERATE_DOCSET);
12487 if (generateEclipseHelp) Doxygen::indexList->addIndex<EclipseHelp>();
12488 if (generateHtmlHelp) Doxygen::indexList->addIndex<HtmlHelp>();
12489 if (generateQhp) Doxygen::indexList->addIndex<Qhp>();
12490 if (generateSitemap) Doxygen::indexList->addIndex<Sitemap>();
12491 if (generateTreeView) Doxygen::indexList->addIndex<FTVHelp>(TRUE);
12492 if (generateDocSet) Doxygen::indexList->addIndex<DocSets>();
12493 Doxygen::indexList->addIndex<Crawlmap>();
12494 Doxygen::indexList->initialize();
12495 }
12496
12497 if (generateDocbook)
12498 {
12499 docbookOutput = createOutputDirectory(outputDirectory,Config_getString(DOCBOOK_OUTPUT),"/docbook");
12500 Config_updateString(DOCBOOK_OUTPUT,docbookOutput);
12501 }
12502
12503 if (generateXml)
12504 {
12505 xmlOutput = createOutputDirectory(outputDirectory,Config_getString(XML_OUTPUT),"/xml");
12506 Config_updateString(XML_OUTPUT,xmlOutput);
12507 }
12508
12509 if (generateLatex)
12510 {
12511 latexOutput = createOutputDirectory(outputDirectory,Config_getString(LATEX_OUTPUT), "/latex");
12512 Config_updateString(LATEX_OUTPUT,latexOutput);
12513 }
12514
12515 if (generateRtf)
12516 {
12517 rtfOutput = createOutputDirectory(outputDirectory,Config_getString(RTF_OUTPUT),"/rtf");
12518 Config_updateString(RTF_OUTPUT,rtfOutput);
12519 }
12520
12521 if (generateMan)
12522 {
12523 manOutput = createOutputDirectory(outputDirectory,Config_getString(MAN_OUTPUT),"/man");
12524 Config_updateString(MAN_OUTPUT,manOutput);
12525 }
12526
12527 if (generateSql)
12528 {
12529 sqlOutput = createOutputDirectory(outputDirectory,Config_getString(SQLITE3_OUTPUT),"/sqlite3");
12530 Config_updateString(SQLITE3_OUTPUT,sqlOutput);
12531 }
12532 }
12533
12534 if (Config_getBool(HAVE_DOT))
12535 {
12536 QCString curFontPath = Config_getString(DOT_FONTPATH);
12537 if (curFontPath.isEmpty())
12538 {
12539 Portable::getenv("DOTFONTPATH");
12540 QCString newFontPath = ".";
12541 if (!curFontPath.isEmpty())
12542 {
12543 newFontPath+=Portable::pathListSeparator();
12544 newFontPath+=curFontPath;
12545 }
12546 Portable::setenv("DOTFONTPATH",qPrint(newFontPath));
12547 }
12548 else
12549 {
12550 Portable::setenv("DOTFONTPATH",qPrint(curFontPath));
12551 }
12552 }
12553
12554 /**************************************************************************
12555 * Handle layout file *
12556 **************************************************************************/
12557
12559 QCString layoutFileName = Config_getString(LAYOUT_FILE);
12560 bool defaultLayoutUsed = FALSE;
12561 if (layoutFileName.isEmpty())
12562 {
12563 layoutFileName = Config_updateString(LAYOUT_FILE,"DoxygenLayout.xml");
12564 defaultLayoutUsed = TRUE;
12565 }
12566 AUTO_TRACE_ADD("defaultLayoutUsed={}, layoutFileName={}",defaultLayoutUsed,layoutFileName);
12567
12568 FileInfo fi(layoutFileName.str());
12569 if (fi.exists())
12570 {
12571 msg("Parsing layout file {}...\n",layoutFileName);
12572 LayoutDocManager::instance().parse(layoutFileName);
12573 }
12574 else if (!defaultLayoutUsed)
12575 {
12576 warn_uncond("failed to open layout file '{}' for reading! Using default settings.\n",layoutFileName);
12577 }
12578 printLayout();
12579
12580 /**************************************************************************
12581 * Read and preprocess input *
12582 **************************************************************************/
12583
12584 // prevent search in the output directories
12585 StringVector exclPatterns = Config_getList(EXCLUDE_PATTERNS);
12586 if (generateHtml) exclPatterns.push_back(htmlOutput.str());
12587 if (generateDocbook) exclPatterns.push_back(docbookOutput.str());
12588 if (generateXml) exclPatterns.push_back(xmlOutput.str());
12589 if (generateLatex) exclPatterns.push_back(latexOutput.str());
12590 if (generateRtf) exclPatterns.push_back(rtfOutput.str());
12591 if (generateMan) exclPatterns.push_back(manOutput.str());
12592 Config_updateList(EXCLUDE_PATTERNS,exclPatterns);
12593
12594 if (!g_singleComment)
12595 {
12597
12599 }
12600
12601 // Notice: the order of the function calls below is very important!
12602
12603 if (generateHtml && !Config_getBool(USE_MATHJAX))
12604 {
12606 }
12607 if (generateRtf)
12608 {
12610 }
12611 if (generateDocbook)
12612 {
12614 }
12615
12617
12618 /**************************************************************************
12619 * Handle Tag Files *
12620 **************************************************************************/
12621
12622 std::shared_ptr<Entry> root = std::make_shared<Entry>();
12623
12624 if (!g_singleComment)
12625 {
12626 msg("Reading and parsing tag files\n");
12627 const StringVector &tagFileList = Config_getList(TAGFILES);
12628 for (const auto &s : tagFileList)
12629 {
12630 readTagFile(root,s.c_str());
12631 }
12632 }
12633
12634 /**************************************************************************
12635 * Parse source files *
12636 **************************************************************************/
12637
12638 addSTLSupport(root);
12639
12640 g_s.begin("Parsing files\n");
12641 if (g_singleComment)
12642 {
12643 //printf("Parsing comment %s\n",qPrint(g_commentFileName));
12644 if (g_commentFileName=="-")
12645 {
12646 std::string text = fileToString(g_commentFileName).str();
12647 addTerminalCharIfMissing(text,'\n');
12648 generateHtmlForComment("stdin.md",text);
12649 }
12650 else if (FileInfo(g_commentFileName.str()).isFile())
12651 {
12652 std::string text;
12654 addTerminalCharIfMissing(text,'\n');
12656 }
12657 else
12658 {
12659 }
12661 exit(0);
12662 }
12663 else
12664 {
12665 if (Config_getInt(NUM_PROC_THREADS)==1)
12666 {
12668 }
12669 else
12670 {
12672 }
12673 }
12674 g_s.end();
12675
12676 /**************************************************************************
12677 * Gather information *
12678 **************************************************************************/
12679
12680 g_s.begin("Building macro definition list...\n");
12682 g_s.end();
12683
12684 g_s.begin("Building group list...\n");
12685 buildGroupList(root.get());
12686 organizeSubGroups(root.get());
12687 g_s.end();
12688
12689 g_s.begin("Building directory list...\n");
12691 findDirDocumentation(root.get());
12692 g_s.end();
12693
12694 g_s.begin("Building namespace list...\n");
12695 buildNamespaceList(root.get());
12696 findUsingDirectives(root.get());
12697 g_s.end();
12698
12699 g_s.begin("Building file list...\n");
12700 buildFileList(root.get());
12701 g_s.end();
12702
12703 g_s.begin("Building class list...\n");
12704 buildClassList(root.get());
12705 g_s.end();
12706
12707 g_s.begin("Building concept list...\n");
12708 buildConceptList(root.get());
12709 g_s.end();
12710
12711 // build list of using declarations here (global list)
12712 buildListOfUsingDecls(root.get());
12713 g_s.end();
12714
12715 g_s.begin("Computing nesting relations for classes...\n");
12717 g_s.end();
12718 // 1.8.2-20121111: no longer add nested classes to the group as well
12719 //distributeClassGroupRelations();
12720
12721 // calling buildClassList may result in cached relations that
12722 // become invalid after resolveClassNestingRelations(), that's why
12723 // we need to clear the cache here
12724 Doxygen::typeLookupCache->clear();
12725 // we don't need the list of using declaration anymore
12726 g_usingDeclarations.clear();
12727
12728 g_s.begin("Associating documentation with classes...\n");
12729 buildClassDocList(root.get());
12730 g_s.end();
12731
12732 g_s.begin("Associating documentation with concepts...\n");
12733 buildConceptDocList(root.get());
12735 g_s.end();
12736
12737 g_s.begin("Associating documentation with modules...\n");
12738 findModuleDocumentation(root.get());
12739 g_s.end();
12740
12741 g_s.begin("Building example list...\n");
12742 buildExampleList(root.get());
12743 g_s.end();
12744
12745 g_s.begin("Searching for enumerations...\n");
12746 findEnums(root.get());
12747 g_s.end();
12748
12749 // Since buildVarList calls isVarWithConstructor
12750 // and this calls getResolvedClass we need to process
12751 // typedefs first so the relations between classes via typedefs
12752 // are properly resolved. See bug 536385 for an example.
12753 g_s.begin("Searching for documented typedefs...\n");
12754 buildTypedefList(root.get());
12755 g_s.end();
12756
12757 if (Config_getBool(OPTIMIZE_OUTPUT_SLICE))
12758 {
12759 g_s.begin("Searching for documented sequences...\n");
12760 buildSequenceList(root.get());
12761 g_s.end();
12762
12763 g_s.begin("Searching for documented dictionaries...\n");
12764 buildDictionaryList(root.get());
12765 g_s.end();
12766 }
12767
12768 g_s.begin("Searching for members imported via using declarations...\n");
12769 // this should be after buildTypedefList in order to properly import
12770 // used typedefs
12771 findUsingDeclarations(root.get(),TRUE); // do for python packages first
12772 findUsingDeclarations(root.get(),FALSE); // then the rest
12773 g_s.end();
12774
12775 g_s.begin("Searching for included using directives...\n");
12777 g_s.end();
12778
12779 g_s.begin("Searching for documented variables...\n");
12780 buildVarList(root.get());
12781 g_s.end();
12782
12783 g_s.begin("Building interface member list...\n");
12784 buildInterfaceAndServiceList(root.get()); // UNO IDL
12785
12786 g_s.begin("Building member list...\n"); // using class info only !
12787 buildFunctionList(root.get());
12788 g_s.end();
12789
12790 g_s.begin("Searching for friends...\n");
12791 findFriends();
12792 g_s.end();
12793
12794 g_s.begin("Searching for documented defines...\n");
12795 findDefineDocumentation(root.get());
12796 g_s.end();
12797
12798 g_s.begin("Computing class inheritance relations...\n");
12799 findClassEntries(root.get());
12801 g_s.end();
12802
12803 g_s.begin("Computing class usage relations...\n");
12805 g_s.end();
12806
12807 if (Config_getBool(INLINE_SIMPLE_STRUCTS))
12808 {
12809 g_s.begin("Searching for tag less structs...\n");
12811 g_s.end();
12812 }
12813
12814 g_s.begin("Flushing cached template relations that have become invalid...\n");
12816 g_s.end();
12817
12818 g_s.begin("Warn for undocumented namespaces...\n");
12820 g_s.end();
12821
12822 g_s.begin("Computing class relations...\n");
12825 if (Config_getBool(OPTIMIZE_OUTPUT_VHDL))
12826 {
12828 }
12830 g_classEntries.clear();
12831 g_s.end();
12832
12833 g_s.begin("Add enum values to enums...\n");
12834 addEnumValuesToEnums(root.get());
12835 findEnumDocumentation(root.get());
12836 g_s.end();
12837
12838 g_s.begin("Searching for member function documentation...\n");
12839 findObjCMethodDefinitions(root.get());
12840 findMemberDocumentation(root.get()); // may introduce new members !
12841 findUsingDeclImports(root.get()); // may introduce new members !
12842 g_usingClassMap.clear();
12846 g_s.end();
12847
12848 // moved to after finding and copying documentation,
12849 // as this introduces new members see bug 722654
12850 g_s.begin("Creating members for template instances...\n");
12852 g_s.end();
12853
12854 g_s.begin("Building page list...\n");
12855 buildPageList(root.get());
12856 g_s.end();
12857
12858 g_s.begin("Search for main page...\n");
12859 findMainPage(root.get());
12860 findMainPageTagFiles(root.get());
12861 g_s.end();
12862
12863 g_s.begin("Computing page relations...\n");
12864 computePageRelations(root.get());
12866 g_s.end();
12867
12868 g_s.begin("Determining the scope of groups...\n");
12869 findGroupScope(root.get());
12870 g_s.end();
12871
12872 g_s.begin("Computing module relations...\n");
12873 auto &mm = ModuleManager::instance();
12874 mm.resolvePartitions();
12875 mm.resolveImports();
12876 mm.collectExportedSymbols();
12877 g_s.end();
12878
12879 auto memberNameComp = [](const MemberNameLinkedMap::Ptr &n1,const MemberNameLinkedMap::Ptr &n2)
12880 {
12881 return qstricmp_sort(n1->memberName().data()+getPrefixIndex(n1->memberName()),
12882 n2->memberName().data()+getPrefixIndex(n2->memberName())
12883 )<0;
12884 };
12885
12886 auto classComp = [](const ClassLinkedMap::Ptr &c1,const ClassLinkedMap::Ptr &c2)
12887 {
12888 if (Config_getBool(SORT_BY_SCOPE_NAME))
12889 {
12890 return qstricmp_sort(c1->name(), c2->name())<0;
12891 }
12892 else
12893 {
12894 int i = qstricmp_sort(c1->className(), c2->className());
12895 return i==0 ? qstricmp_sort(c1->name(), c2->name())<0 : i<0;
12896 }
12897 };
12898
12899 auto namespaceComp = [](const NamespaceLinkedMap::Ptr &n1,const NamespaceLinkedMap::Ptr &n2)
12900 {
12901 return qstricmp_sort(n1->name(),n2->name())<0;
12902 };
12903
12904 auto conceptComp = [](const ConceptLinkedMap::Ptr &c1,const ConceptLinkedMap::Ptr &c2)
12905 {
12906 return qstricmp_sort(c1->name(),c2->name())<0;
12907 };
12908
12909 g_s.begin("Sorting lists...\n");
12910 std::stable_sort(Doxygen::memberNameLinkedMap->begin(),
12912 memberNameComp);
12913 std::stable_sort(Doxygen::functionNameLinkedMap->begin(),
12915 memberNameComp);
12916 std::stable_sort(Doxygen::hiddenClassLinkedMap->begin(),
12918 classComp);
12919 std::stable_sort(Doxygen::classLinkedMap->begin(),
12921 classComp);
12922 std::stable_sort(Doxygen::conceptLinkedMap->begin(),
12924 conceptComp);
12925 std::stable_sort(Doxygen::namespaceLinkedMap->begin(),
12927 namespaceComp);
12928 g_s.end();
12929
12930 g_s.begin("Determining which enums are documented\n");
12932 g_s.end();
12933
12934 g_s.begin("Computing member relations...\n");
12937 g_s.end();
12938
12939 g_s.begin("Building full member lists recursively...\n");
12941 g_s.end();
12942
12943 g_s.begin("Adding members to member groups.\n");
12945 g_s.end();
12946
12947 if (Config_getBool(DISTRIBUTE_GROUP_DOC))
12948 {
12949 g_s.begin("Distributing member group documentation.\n");
12951 g_s.end();
12952 }
12953
12954 g_s.begin("Computing member references...\n");
12956 g_s.end();
12957
12958 if (Config_getBool(INHERIT_DOCS))
12959 {
12960 g_s.begin("Inheriting documentation...\n");
12962 g_s.end();
12963 }
12964
12965
12966 // compute the shortest possible names of all files
12967 // without losing the uniqueness of the file names.
12968 g_s.begin("Generating disk names...\n");
12970 g_s.end();
12971
12972 g_s.begin("Adding source references...\n");
12974 g_s.end();
12975
12976 g_s.begin("Adding xrefitems...\n");
12979 g_s.end();
12980
12981 g_s.begin("Sorting member lists...\n");
12983 g_s.end();
12984
12985 g_s.begin("Setting anonymous enum type...\n");
12987 g_s.end();
12988
12989 g_s.begin("Computing dependencies between directories...\n");
12991 g_s.end();
12992
12993 g_s.begin("Generating citations page...\n");
12995 g_s.end();
12996
12997 g_s.begin("Counting members...\n");
12998 countMembers();
12999 g_s.end();
13000
13001 g_s.begin("Counting data structures...\n");
13003 g_s.end();
13004
13005 g_s.begin("Resolving user defined references...\n");
13007 g_s.end();
13008
13009 g_s.begin("Finding anchors and sections in the documentation...\n");
13011 g_s.end();
13012
13013 g_s.begin("Transferring function references...\n");
13015 g_s.end();
13016
13017 g_s.begin("Combining using relations...\n");
13019 g_s.end();
13020
13022 g_s.begin("Adding members to index pages...\n");
13024 addToIndices();
13025 g_s.end();
13026
13027 g_s.begin("Correcting members for VHDL...\n");
13029 g_s.end();
13030
13031 g_s.begin("Computing tooltip texts...\n");
13033 g_s.end();
13034
13035 if (Config_getBool(SORT_GROUP_NAMES))
13036 {
13037 std::stable_sort(Doxygen::groupLinkedMap->begin(),
13039 [](const auto &g1,const auto &g2)
13040 { return g1->groupTitle() < g2->groupTitle(); });
13041
13042 for (const auto &gd : *Doxygen::groupLinkedMap)
13043 {
13044 gd->sortSubGroups();
13045 }
13046 }
13047
13048 printNavTree(root.get(),0);
13050}
Definition cache.h:32
void generatePage()
Generate the citations page.
Definition cite.cpp:333
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:60
void checkRepositories()
Definition formula.cpp:173
A class that generated the HTML Help specific files.
Definition htmlhelp.h:36
void countDataStructures()
Definition index.cpp:262
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition layout.cpp:1435
void parse(const QCString &fileName, const char *data=nullptr)
Parses a user provided layout.
Definition layout.cpp:1468
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:1102
void computeDirDependencies()
Definition dirdef.cpp:1176
static void findInheritedTemplateInstances()
Definition doxygen.cpp:5243
void printNavTree(Entry *root, int indent)
Definition doxygen.cpp:9924
static void buildGroupList(const Entry *root)
Definition doxygen.cpp:425
static void flushCachedTemplateRelations()
Definition doxygen.cpp:9349
static void computeTemplateClassRelations()
Definition doxygen.cpp:5337
void printSectionsTree()
Definition doxygen.cpp:9947
static void generateXRefPages()
Definition doxygen.cpp:5509
static void warnUndocumentedNamespaces()
Definition doxygen.cpp:5292
static void resolveClassNestingRelations()
Definition doxygen.cpp:1331
static void vhdlCorrectMemberProperties()
Definition doxygen.cpp:8307
static void stopDoxygen(int)
static void computeMemberReferences()
Definition doxygen.cpp:5406
static void transferRelatedFunctionDocumentation()
Definition doxygen.cpp:4362
static void addMembersToMemberGroup()
Definition doxygen.cpp:9214
static void distributeConceptGroups()
Definition doxygen.cpp:1298
static void transferFunctionDocumentation()
Definition doxygen.cpp:4281
static void setAnonymousEnumType()
Definition doxygen.cpp:8954
static void sortMemberLists()
Definition doxygen.cpp:8859
static void createTemplateInstanceMembers()
Definition doxygen.cpp:8435
void transferStaticInstanceInitializers()
Definition doxygen.cpp:4411
static void findObjCMethodDefinitions(const Entry *root)
Definition doxygen.cpp:7451
static void distributeMemberGroupDocumentation()
Definition doxygen.cpp:9252
static void resolveUserReferences()
Definition doxygen.cpp:9810
static void readTagFile(const std::shared_ptr< Entry > &root, const QCString &tagLine)
static void findIncludedUsingDirectives()
Definition doxygen.cpp:2408
static void countMembers()
Definition doxygen.cpp:8968
static void organizeSubGroups(const Entry *root)
Definition doxygen.cpp:484
void searchInputFiles()
static void findFriends()
Definition doxygen.cpp:4184
static void addListReferences()
Definition doxygen.cpp:5440
static void exitDoxygen() noexcept
static void addMembersToIndex()
Definition doxygen.cpp:8097
static void addSourceReferences()
Definition doxygen.cpp:8732
static void inheritDocumentation()
Definition doxygen.cpp:9154
static void flushUnresolvedRelations()
Definition doxygen.cpp:9403
static QCString g_commentFileName
Definition doxygen.cpp:192
static void findDocumentedEnumValues()
Definition doxygen.cpp:8089
static void generateDiskNames()
static void addToIndices()
Definition doxygen.cpp:8139
static void computeClassRelations()
Definition doxygen.cpp:5312
static void checkPageRelations()
Definition doxygen.cpp:9790
static QCString createOutputDirectory(const QCString &baseDirName, const QCString &formatDirName, const char *defaultDirName)
static void computeVerifiedDotPath()
static bool g_singleComment
Definition doxygen.cpp:193
static void findSectionsInDocumentation()
Definition doxygen.cpp:9290
static void mergeCategories()
Definition doxygen.cpp:8454
static void findUsedTemplateInstances()
Definition doxygen.cpp:5276
static void computeTooltipTexts()
Definition doxygen.cpp:8908
static void parseFilesSingleThreading(const std::shared_ptr< Entry > &root)
parse the list of input files
static void buildCompleteMemberLists()
Definition doxygen.cpp:8476
static void combineUsingRelations()
Definition doxygen.cpp:9189
static void checkMarkdownMainfile()
static void parseFilesMultiThreading(const std::shared_ptr< Entry > &root)
parse the list of input files
static void transferFunctionReferences()
Definition doxygen.cpp:4314
static void buildDefineList()
Definition doxygen.cpp:8811
static void computeMemberRelations()
Definition doxygen.cpp:8419
void printLayout()
Definition layout.cpp:1820
void correctPath(const StringVector &list)
Correct a possible wrong PATH variable.
Definition portable.cpp:517
QCString pathListSeparator()
Definition portable.cpp:384
uint32_t pid()
Definition portable.cpp:249
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:1439
int getPrefixIndex(const QCString &name)
Definition util.cpp:3158

References Dir::absPath(), addEnumValuesToEnums(), addListReferences(), addMembersToIndex(), addMembersToMemberGroup(), addSourceReferences(), addSTLSupport(), addTerminalCharIfMissing(), addToIndices(), AUTO_TRACE, AUTO_TRACE_ADD, begin(), buildClassDocList(), buildClassList(), buildCompleteMemberLists(), buildConceptDocList(), buildConceptList(), buildDefineList(), buildDictionaryList(), buildDirectories(), buildExampleList(), buildFileList(), buildFunctionList(), buildGroupList(), buildInterfaceAndServiceList(), buildListOfUsingDecls(), buildNamespaceList(), buildPageList(), buildSequenceList(), buildTypedefList(), buildVarList(), checkMarkdownMainfile(), checkPageRelations(), FormulaManager::checkRepositories(), Doxygen::clangAssistedParsing, Doxygen::classLinkedMap, cleanUpDoxygen(), 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(), countMembers(), createOutputDirectory(), createTemplateInstanceMembers(), Dir::currentDirPath(), 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(), findTagLessClasses(), findUsedTemplateInstances(), findUsingDeclarations(), findUsingDeclImports(), findUsingDirectives(), flushCachedTemplateRelations(), flushUnresolvedRelations(), Doxygen::functionNameLinkedMap, g_classEntries, g_commentFileName, g_s, g_singleComment, g_usingClassMap, g_usingDeclarations, generateDiskNames(), generateHtmlForComment(), CitationManager::generatePage(), 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(), 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(), Doxygen::symbolLookupCache, term, transferFunctionDocumentation(), transferFunctionReferences(), transferRelatedFunctionDocumentation(), transferStaticInstanceInitializers(), TRUE, Doxygen::typeLookupCache, vhdlCorrectMemberProperties(), warn_uncond, and warnUndocumentedNamespaces().

Referenced by main().

◆ printNavTree()

void printNavTree ( Entry * root,
int indent )

Definition at line 9924 of file doxygen.cpp.

9925{
9927 {
9928 QCString indentStr;
9929 indentStr.fill(' ',indent);
9930 Debug::print(Debug::Entries,0,"{}{} at {}:{} (sec={}, spec={})\n",
9931 indentStr.isEmpty()?"":indentStr,
9932 root->name.isEmpty()?"<empty>":root->name,
9933 root->fileName,root->startLine,
9934 root->section.to_string(),
9935 root->spec.to_string());
9936 for (const auto &e : root->children())
9937 {
9938 printNavTree(e.get(),indent+2);
9939 }
9940 }
9941}
@ Entries
Definition debug.h:47
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
Definition debug.h:76
std::string to_string() const
Definition types.h:805
QCString fill(char c, int len=-1)
Fills a string with a predefined character.
Definition qcstring.h:193
std::string to_string() const
Definition types.h:682

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

9948{
9950 {
9951 for (const auto &si : SectionManager::instance())
9952 {
9953 Debug::print(Debug::Sections,0,"Section = {}, file = {}, title = {}, type = {}, ref = {}\n",
9954 si->label(),si->fileName(),si->title(),si->type().level(),si->ref());
9955 }
9956 }
9957}
@ Sections
Definition debug.h:48

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

Referenced by parseInput().

◆ processTagLessClasses()

void processTagLessClasses ( const ClassDef * rootCd,
const ClassDef * cd,
ClassDefMutable * tagParentCd,
const QCString & prefix,
int count )
static

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

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

Definition at line 1565 of file doxygen.cpp.

1569{
1570 //printf("%d: processTagLessClasses %s\n",count,qPrint(cd->name()));
1571 //printf("checking members for %s\n",qPrint(cd->name()));
1572 if (tagParentCd && !cd->getClasses().empty())
1573 {
1574 MemberList *ml = cd->getMemberList(MemberListType::PubAttribs());
1575 if (ml)
1576 {
1577 int pos=0;
1578 for (const auto &md : *ml)
1579 {
1580 QCString type = md->typeString();
1581 if (type.find("::@")!=-1) // member of tag less struct/union
1582 {
1583 for (const auto &icd : cd->getClasses())
1584 {
1585 //printf(" member %s: type='%s'\n",qPrint(md->name()),qPrint(type));
1586 //printf(" comparing '%s'<->'%s'\n",qPrint(type),qPrint(icd->name()));
1587 if (type.find(icd->name())!=-1) // matching tag less struct/union
1588 {
1589 QCString name = md->name();
1590 if (md->isAnonymous()) name = "__unnamed" + QCString().setNum(pos++)+"__";
1591 if (!prefix.isEmpty()) name.prepend(prefix+".");
1592 //printf(" found %s for class %s\n",qPrint(name),qPrint(cd->name()));
1593 ClassDefMutable *ncd = createTagLessInstance(rootCd,icd,name);
1594 if (ncd)
1595 {
1596 processTagLessClasses(rootCd,icd,ncd,name,count+1);
1597 //printf(" addTagged %s to %s\n",qPrint(ncd->name()),qPrint(tagParentCd->name()));
1598 ncd->setTagLessReference(icd);
1599
1600 // replace tag-less type for generated/original member
1601 // by newly created class name.
1602 // note the difference between changing cd and tagParentCd.
1603 // for the initial call this is the same pointer, but for
1604 // recursive calls cd is the original tag-less struct (of which
1605 // there is only one instance) and tagParentCd is the newly
1606 // generated tagged struct of which there can be multiple instances!
1607 MemberList *pml = tagParentCd->getMemberList(MemberListType::PubAttribs());
1608 if (pml)
1609 {
1610 for (const auto &pmd : *pml)
1611 {
1613 if (pmdm && pmd->name()==md->name())
1614 {
1615 pmdm->setAccessorType(ncd,substitute(pmd->typeString(),icd->name(),ncd->name()));
1616 //pmd->setType(substitute(pmd->typeString(),icd->name(),ncd->name()));
1617 }
1618 }
1619 }
1620 }
1621 }
1622 }
1623 }
1624 }
1625 }
1626 }
1627}
virtual void setTagLessReference(const ClassDef *cd)=0
virtual void setAccessorType(ClassDef *cd, const QCString &t)=0
QCString & setNum(short n)
Definition qcstring.h:459
static ClassDefMutable * createTagLessInstance(const ClassDef *rootCd, const ClassDef *templ, const QCString &fieldName)
Definition doxygen.cpp:1479

References createTagLessInstance(), LinkedRefMap< T, Hash, KeyEqual, Map >::empty(), QCString::find(), ClassDef::getClasses(), ClassDef::getMemberList(), Definition::name(), prefix, QCString::prepend(), processTagLessClasses(), MemberDefMutable::setAccessorType(), QCString::setNum(), ClassDefMutable::setTagLessReference(), substitute(), and toMemberDefMutable().

Referenced by findTagLessClasses(), and processTagLessClasses().

◆ readConfiguration()

void readConfiguration ( int argc,
char ** argv )

Definition at line 11446 of file doxygen.cpp.

11447{
11448 QCString versionString = getFullVersion();
11449
11450 // helper that calls \a func to write to file \a fileName via a TextStream
11451 auto writeFile = [](const char *fileName,std::function<void(TextStream&)> func) -> bool
11452 {
11453 std::ofstream f;
11454 if (openOutputFile(fileName,f))
11455 {
11456 TextStream t(&f);
11457 func(t);
11458 return true;
11459 }
11460 return false;
11461 };
11462
11463
11464 /**************************************************************************
11465 * Handle arguments *
11466 **************************************************************************/
11467
11468 int optInd=1;
11469 QCString configName;
11470 QCString traceName;
11471 bool genConfig=false;
11472 bool shortList=false;
11473 bool traceTiming=false;
11475 bool updateConfig=false;
11476 bool quiet = false;
11477 while (optInd<argc && argv[optInd][0]=='-' &&
11478 (isalpha(argv[optInd][1]) || argv[optInd][1]=='?' ||
11479 argv[optInd][1]=='-')
11480 )
11481 {
11482 switch(argv[optInd][1])
11483 {
11484 case 'g':
11485 {
11486 genConfig=TRUE;
11487 }
11488 break;
11489 case 'l':
11490 {
11491 QCString layoutName;
11492 if (optInd+1>=argc)
11493 {
11494 layoutName="DoxygenLayout.xml";
11495 }
11496 else
11497 {
11498 layoutName=argv[optInd+1];
11499 }
11500 writeDefaultLayoutFile(layoutName);
11502 exit(0);
11503 }
11504 break;
11505 case 'c':
11506 if (optInd+1>=argc) // no file name given
11507 {
11508 msg("option \"-c\" is missing the file name to read\n");
11509 devUsage();
11511 exit(1);
11512 }
11513 else
11514 {
11515 g_commentFileName=argv[optInd+1];
11516 optInd++;
11517 }
11518 g_singleComment=true;
11519 quiet=true;
11520 break;
11521 case 'd':
11522 {
11523 QCString debugLabel=getArg(argc,argv,optInd);
11524 if (debugLabel.isEmpty())
11525 {
11526 devUsage();
11528 exit(0);
11529 }
11530 int retVal = Debug::setFlagStr(debugLabel);
11531 if (!retVal)
11532 {
11533 msg("option \"-d\" has unknown debug specifier: \"{}\".\n",debugLabel);
11534 devUsage();
11536 exit(1);
11537 }
11538 }
11539 break;
11540 case 't':
11541 {
11542#if ENABLE_TRACING
11543 if (!strcmp(argv[optInd]+1,"t_time"))
11544 {
11545 traceTiming = true;
11546 }
11547 else if (!strcmp(argv[optInd]+1,"t"))
11548 {
11549 traceTiming = false;
11550 }
11551 else
11552 {
11553 err("option should be \"-t\" or \"-t_time\", found: \"{}\".\n",argv[optInd]);
11555 exit(1);
11556 }
11557 if (optInd+1>=argc || argv[optInd+1][0] == '-') // no file name given
11558 {
11559 traceName="stdout";
11560 }
11561 else
11562 {
11563 traceName=argv[optInd+1];
11564 optInd++;
11565 }
11566#else
11567 err("support for option \"-t\" has not been compiled in (use a debug build or a release build with tracing enabled).\n");
11569 exit(1);
11570#endif
11571 }
11572 break;
11573 case 'x':
11574 if (!strcmp(argv[optInd]+1,"x_noenv")) diffList=Config::CompareMode::CompressedNoEnv;
11575 else if (!strcmp(argv[optInd]+1,"x")) diffList=Config::CompareMode::Compressed;
11576 else
11577 {
11578 err("option should be \"-x\" or \"-x_noenv\", found: \"{}\".\n",argv[optInd]);
11580 exit(1);
11581 }
11582 break;
11583 case 's':
11584 shortList=TRUE;
11585 break;
11586 case 'u':
11587 updateConfig=TRUE;
11588 break;
11589 case 'e':
11590 {
11591 QCString formatName=getArg(argc,argv,optInd);
11592 if (formatName.isEmpty())
11593 {
11594 err("option \"-e\" is missing format specifier rtf.\n");
11596 exit(1);
11597 }
11598 if (qstricmp(formatName.data(),"rtf")==0)
11599 {
11600 if (optInd+1>=argc)
11601 {
11602 err("option \"-e rtf\" is missing an extensions file name\n");
11604 exit(1);
11605 }
11606 writeFile(argv[optInd+1],RTFGenerator::writeExtensionsFile);
11608 exit(0);
11609 }
11610 err("option \"-e\" has invalid format specifier.\n");
11612 exit(1);
11613 }
11614 break;
11615 case 'f':
11616 {
11617 QCString listName=getArg(argc,argv,optInd);
11618 if (listName.isEmpty())
11619 {
11620 err("option \"-f\" is missing list specifier.\n");
11622 exit(1);
11623 }
11624 if (qstricmp(listName.data(),"emoji")==0)
11625 {
11626 if (optInd+1>=argc)
11627 {
11628 err("option \"-f emoji\" is missing an output file name\n");
11630 exit(1);
11631 }
11632 writeFile(argv[optInd+1],[](TextStream &t) { EmojiEntityMapper::instance().writeEmojiFile(t); });
11634 exit(0);
11635 }
11636 err("option \"-f\" has invalid list specifier.\n");
11638 exit(1);
11639 }
11640 break;
11641 case 'w':
11642 {
11643 QCString formatName=getArg(argc,argv,optInd);
11644 if (formatName.isEmpty())
11645 {
11646 err("option \"-w\" is missing format specifier rtf, html or latex\n");
11648 exit(1);
11649 }
11650 if (qstricmp(formatName.data(),"rtf")==0)
11651 {
11652 if (optInd+1>=argc)
11653 {
11654 err("option \"-w rtf\" is missing a style sheet file name\n");
11656 exit(1);
11657 }
11658 if (!writeFile(argv[optInd+1],RTFGenerator::writeStyleSheetFile))
11659 {
11660 err("error opening RTF style sheet file {}!\n",argv[optInd+1]);
11662 exit(1);
11663 }
11665 exit(0);
11666 }
11667 else if (qstricmp(formatName.data(),"html")==0)
11668 {
11669 Config::init();
11670 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11671 // explicit config file mentioned or default found on disk
11672 {
11673 QCString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? QCString("Doxyfile") : QCString("doxyfile"));
11674 if (!Config::parse(df)) // parse the config file
11675 {
11676 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
11678 exit(1);
11679 }
11680 }
11681 if (optInd+3>=argc)
11682 {
11683 err("option \"-w html\" does not have enough arguments\n");
11685 exit(1);
11686 }
11690 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11691 writeFile(argv[optInd+1],[&](TextStream &t) { HtmlGenerator::writeHeaderFile(t,argv[optInd+3]); });
11692 writeFile(argv[optInd+2],HtmlGenerator::writeFooterFile);
11693 writeFile(argv[optInd+3],HtmlGenerator::writeStyleSheetFile);
11695 exit(0);
11696 }
11697 else if (qstricmp(formatName.data(),"latex")==0)
11698 {
11699 Config::init();
11700 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11701 {
11702 QCString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? QCString("Doxyfile") : QCString("doxyfile"));
11703 if (!Config::parse(df))
11704 {
11705 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
11707 exit(1);
11708 }
11709 }
11710 if (optInd+3>=argc)
11711 {
11712 err("option \"-w latex\" does not have enough arguments\n");
11714 exit(1);
11715 }
11719 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11720 writeFile(argv[optInd+1],LatexGenerator::writeHeaderFile);
11721 writeFile(argv[optInd+2],LatexGenerator::writeFooterFile);
11722 writeFile(argv[optInd+3],LatexGenerator::writeStyleSheetFile);
11724 exit(0);
11725 }
11726 else
11727 {
11728 err("Illegal format specifier \"{}\": should be one of rtf, html or latex\n",formatName);
11730 exit(1);
11731 }
11732 }
11733 break;
11734 case 'm':
11736 break;
11737 case 'v':
11738 version(false);
11740 exit(0);
11741 break;
11742 case 'V':
11743 version(true);
11745 exit(0);
11746 break;
11747 case '-':
11748 if (qstrcmp(&argv[optInd][2],"help")==0)
11749 {
11750 usage(argv[0],versionString);
11751 exit(0);
11752 }
11753 else if (qstrcmp(&argv[optInd][2],"version")==0)
11754 {
11755 version(false);
11757 exit(0);
11758 }
11759 else if ((qstrcmp(&argv[optInd][2],"Version")==0) ||
11760 (qstrcmp(&argv[optInd][2],"VERSION")==0))
11761 {
11762 version(true);
11764 exit(0);
11765 }
11766 else
11767 {
11768 err("Unknown option \"-{}\"\n",&argv[optInd][1]);
11769 usage(argv[0],versionString);
11770 exit(1);
11771 }
11772 break;
11773 case 'b':
11774 setvbuf(stdout,nullptr,_IONBF,0);
11775 break;
11776 case 'q':
11777 quiet = true;
11778 break;
11779 case 'h':
11780 case '?':
11781 usage(argv[0],versionString);
11782 exit(0);
11783 break;
11784 default:
11785 err("Unknown option \"-{:c}\"\n",argv[optInd][1]);
11786 usage(argv[0],versionString);
11787 exit(1);
11788 }
11789 optInd++;
11790 }
11791
11792 /**************************************************************************
11793 * Parse or generate the config file *
11794 **************************************************************************/
11795
11796 initTracing(traceName.data(),traceTiming);
11797 TRACE("Doxygen version used: {}",getFullVersion());
11798 Config::init();
11799
11800 FileInfo configFileInfo1("Doxyfile"),configFileInfo2("doxyfile");
11801 if (optInd>=argc)
11802 {
11803 if (configFileInfo1.exists())
11804 {
11805 configName="Doxyfile";
11806 }
11807 else if (configFileInfo2.exists())
11808 {
11809 configName="doxyfile";
11810 }
11811 else if (genConfig)
11812 {
11813 configName="Doxyfile";
11814 }
11815 else
11816 {
11817 err("Doxyfile not found and no input file specified!\n");
11818 usage(argv[0],versionString);
11819 exit(1);
11820 }
11821 }
11822 else
11823 {
11824 FileInfo fi(argv[optInd]);
11825 if (fi.exists() || qstrcmp(argv[optInd],"-")==0 || genConfig)
11826 {
11827 configName=argv[optInd];
11828 }
11829 else
11830 {
11831 err("configuration file {} not found!\n",argv[optInd]);
11832 usage(argv[0],versionString);
11833 exit(1);
11834 }
11835 }
11836
11837 if (genConfig)
11838 {
11839 generateConfigFile(configName,shortList);
11841 exit(0);
11842 }
11843
11844 if (!Config::parse(configName,updateConfig,diffList))
11845 {
11846 err("could not open or read configuration file {}!\n",configName);
11848 exit(1);
11849 }
11850
11851 if (diffList!=Config::CompareMode::Full)
11852 {
11854 compareDoxyfile(diffList);
11856 exit(0);
11857 }
11858
11859 if (updateConfig)
11860 {
11862 generateConfigFile(configName,shortList,TRUE);
11864 exit(0);
11865 }
11866
11867 /* Perlmod wants to know the path to the config file.*/
11868 FileInfo configFileInfo(configName.str());
11869 setPerlModDoxyfile(configFileInfo.absFilePath());
11870
11871 /* handle -q option */
11872 if (quiet) Config_updateBool(QUIET,TRUE);
11873}
static bool setFlagStr(const QCString &label)
Definition debug.cpp:103
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:1537
static void writeStyleSheetFile(TextStream &t)
Definition htmlgen.cpp:1525
static void writeHeaderFile(TextStream &t, const QCString &cssname)
Definition htmlgen.cpp:1531
static void writeFooterFile(TextStream &t)
Definition latexgen.cpp:697
static void writeStyleSheetFile(TextStream &t)
Definition latexgen.cpp:703
static void writeHeaderFile(TextStream &t)
Definition latexgen.cpp:691
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:1732
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:447
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 10983 of file doxygen.cpp.

10995{
10996 std::string dirName = fi->absFilePath();
10997 if (paths && !dirName.empty())
10998 {
10999 paths->insert(dirName);
11000 }
11001 //printf("%s isSymLink()=%d\n",qPrint(dirName),fi->isSymLink());
11002 if (fi->isSymLink())
11003 {
11004 dirName = resolveSymlink(dirName);
11005 if (dirName.empty())
11006 {
11007 //printf("RECURSIVE SYMLINK: %s\n",qPrint(dirName));
11008 return; // recursive symlink
11009 }
11010 }
11011
11012 if (g_pathsVisited.find(dirName)!=g_pathsVisited.end())
11013 {
11014 //printf("PATH ALREADY VISITED: %s\n",qPrint(dirName));
11015 return; // already visited path
11016 }
11017 g_pathsVisited.insert(dirName);
11018
11019 Dir dir(dirName);
11020 msg("Searching for files in directory {}\n", fi->absFilePath());
11021 //printf("killSet=%p count=%d\n",killSet,killSet ? (int)killSet->count() : -1);
11022
11023 StringVector dirResultList;
11024
11025 for (const auto &dirEntry : dir.iterator())
11026 {
11027 FileInfo cfi(dirEntry.path());
11028 auto checkPatterns = [&]() -> bool
11029 {
11030 return (patList==nullptr || patternMatch(cfi,*patList)) &&
11031 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
11032 (killSet==nullptr || killSet->find(cfi.absFilePath())==killSet->end());
11033 };
11034
11035 if (exclSet==nullptr || exclSet->find(cfi.absFilePath())==exclSet->end())
11036 { // file should not be excluded
11037 //printf("killSet->find(%s)\n",qPrint(cfi->absFilePath()));
11038 if (Config_getBool(EXCLUDE_SYMLINKS) && cfi.isSymLink())
11039 {
11040 }
11041 else if (!cfi.exists() || !cfi.isReadable())
11042 {
11043 if (errorIfNotExist && checkPatterns())
11044 {
11045 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",cfi.absFilePath());
11046 }
11047 }
11048 else if (cfi.isFile() && checkPatterns())
11049 {
11050 std::string name=cfi.fileName();
11051 std::string path=cfi.dirPath()+"/";
11052 std::string fullName=path+name;
11053 if (fnMap)
11054 {
11055 auto fd = createFileDef(path,name);
11056 FileName *fn=nullptr;
11057 if (!name.empty())
11058 {
11059 fn = fnMap->add(name,fullName);
11060 fn->push_back(std::move(fd));
11061 }
11062 }
11063 dirResultList.push_back(fullName);
11064 if (resultSet) resultSet->insert(fullName);
11065 if (killSet) killSet->insert(fullName);
11066 }
11067 else if (recursive &&
11068 cfi.isDir() &&
11069 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
11070 cfi.fileName().at(0)!='.') // skip "." ".." and ".dir"
11071 {
11072 FileInfo acfi(cfi.absFilePath());
11073 readDir(&acfi,fnMap,exclSet,
11074 patList,exclPatList,&dirResultList,resultSet,errorIfNotExist,
11075 recursive,killSet,paths);
11076 }
11077 }
11078 }
11079 if (resultList && !dirResultList.empty())
11080 {
11081 // sort the resulting list to make the order platform independent.
11082 std::stable_sort(dirResultList.begin(),
11083 dirResultList.end(),
11084 [](const auto &f1,const auto &f2) { return qstricmp_sort(f1.c_str(),f2.c_str())<0; });
11085
11086 // append the sorted results to resultList
11087 resultList->insert(resultList->end(), dirResultList.begin(), dirResultList.end());
11088 }
11089}
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:5600

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

11108{
11109 //printf("killSet count=%d\n",killSet ? (int)killSet->size() : -1);
11110 // strip trailing slashes
11111 if (s.isEmpty()) return;
11112
11113 g_pathsVisited.clear();
11114
11115 FileInfo fi(s.str());
11116 //printf("readFileOrDirectory(%s)\n",s);
11117 {
11118 if (exclSet==nullptr || exclSet->find(fi.absFilePath())==exclSet->end())
11119 {
11120 if (Config_getBool(EXCLUDE_SYMLINKS) && fi.isSymLink())
11121 {
11122 }
11123 else if (!fi.exists() || !fi.isReadable())
11124 {
11125 if (errorIfNotExist)
11126 {
11127 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",s);
11128 }
11129 }
11130 else if (fi.isFile())
11131 {
11132 std::string dirPath = fi.dirPath(true);
11133 std::string filePath = fi.absFilePath();
11134 if (paths && !dirPath.empty())
11135 {
11136 paths->insert(dirPath);
11137 }
11138 //printf("killSet.find(%s)=%d\n",qPrint(fi.absFilePath()),killSet.find(fi.absFilePath())!=killSet.end());
11139 if (killSet==nullptr || killSet->find(filePath)==killSet->end())
11140 {
11141 std::string name=fi.fileName();
11142 if (fnMap)
11143 {
11144 auto fd = createFileDef(dirPath+"/",name);
11145 if (!name.empty())
11146 {
11147 FileName *fn = fnMap->add(name,filePath);
11148 fn->push_back(std::move(fd));
11149 }
11150 }
11151 if (resultList || resultSet)
11152 {
11153 if (resultList) resultList->push_back(filePath);
11154 if (resultSet) resultSet->insert(filePath);
11155 }
11156
11157 if (killSet) killSet->insert(fi.absFilePath());
11158 }
11159 }
11160 else if (fi.isDir()) // readable dir
11161 {
11162 readDir(&fi,fnMap,exclSet,patList,
11163 exclPatList,resultList,resultSet,errorIfNotExist,
11164 recursive,killSet,paths);
11165 }
11166 }
11167 }
11168}

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

10308{
10309 QCString fileName;
10310 QCString destName;
10311 int eqPos = tagLine.find('=');
10312 if (eqPos!=-1) // tag command contains a destination
10313 {
10314 fileName = tagLine.left(eqPos).stripWhiteSpace();
10315 destName = tagLine.right(tagLine.length()-eqPos-1).stripWhiteSpace();
10316 if (fileName.isEmpty() || destName.isEmpty()) return;
10317 //printf("insert tagDestination %s->%s\n",qPrint(fi.fileName()),qPrint(destName));
10318 }
10319 else
10320 {
10321 fileName = tagLine;
10322 }
10323
10324 FileInfo fi(fileName.str());
10325 if (!fi.exists() || !fi.isFile())
10326 {
10327 err("Tag file '{}' does not exist or is not a file. Skipping it...\n",fileName);
10328 return;
10329 }
10330
10331 if (Doxygen::tagFileSet.find(fi.absFilePath()) != Doxygen::tagFileSet.end()) return;
10332
10333 Doxygen::tagFileSet.emplace(fi.absFilePath());
10334
10335 if (!destName.isEmpty())
10336 {
10337 Doxygen::tagDestinationMap.emplace(fi.absFilePath(), destName.str());
10338 msg("Reading tag file '{}', location '{}'...\n",fileName,destName);
10339 }
10340 else
10341 {
10342 msg("Reading tag file '{}'...\n",fileName);
10343 }
10344
10345 parseTagFile(root,fi.absFilePath().c_str());
10346}
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 1331 of file doxygen.cpp.

1332{
1333 ClassDefSet visitedClasses;
1334
1335 bool done=FALSE;
1336 //int iteration=0;
1337 while (!done)
1338 {
1339 done=TRUE;
1340 //++iteration;
1341 struct ClassAlias
1342 {
1343 ClassAlias(const QCString &name,std::unique_ptr<ClassDef> cd,DefinitionMutable *ctx) :
1344 aliasFullName(name),aliasCd(std::move(cd)), aliasContext(ctx) {}
1345 QCString aliasFullName;
1346 std::unique_ptr<ClassDef> aliasCd;
1347 DefinitionMutable *aliasContext;
1348 };
1349 std::vector<ClassAlias> aliases;
1350 for (const auto &icd : *Doxygen::classLinkedMap)
1351 {
1352 ClassDefMutable *cd = toClassDefMutable(icd.get());
1353 if (cd && visitedClasses.find(icd.get())==visitedClasses.end())
1354 {
1355 QCString name = stripAnonymousNamespaceScope(icd->name());
1356 //printf("processing=%s, iteration=%d\n",qPrint(cd->name()),iteration);
1357 // also add class to the correct structural context
1359 name,icd->getFileDef(),nullptr);
1360 if (d)
1361 {
1362 //printf("****** adding %s to scope %s in iteration %d\n",qPrint(cd->name()),qPrint(d->name()),iteration);
1364 if (dm)
1365 {
1366 dm->addInnerCompound(cd);
1367 }
1368 cd->setOuterScope(d);
1369
1370 // for inline namespace add an alias of the class to the outer scope
1372 {
1374 //printf("nd->isInline()=%d\n",nd->isInline());
1375 if (nd && nd->isInline())
1376 {
1377 d = d->getOuterScope();
1378 if (d)
1379 {
1380 dm = toDefinitionMutable(d);
1381 if (dm)
1382 {
1383 auto aliasCd = createClassDefAlias(d,cd);
1384 QCString aliasFullName = d->qualifiedName()+"::"+aliasCd->localName();
1385 aliases.emplace_back(aliasFullName,std::move(aliasCd),dm);
1386 //printf("adding %s to %s as %s\n",qPrint(aliasCd->name()),qPrint(d->name()),qPrint(aliasFullName));
1387 }
1388 }
1389 }
1390 else
1391 {
1392 break;
1393 }
1394 }
1395
1396 visitedClasses.insert(icd.get());
1397 done=FALSE;
1398 }
1399 //else
1400 //{
1401 // printf("****** ignoring %s: scope not (yet) found in iteration %d\n",qPrint(cd->name()),iteration);
1402 //}
1403 }
1404 }
1405 // add aliases
1406 for (auto &alias : aliases)
1407 {
1408 ClassDef *aliasCd = Doxygen::classLinkedMap->add(alias.aliasFullName,std::move(alias.aliasCd));
1409 if (aliasCd)
1410 {
1411 alias.aliasContext->addInnerCompound(aliasCd);
1412 }
1413 }
1414 }
1415
1416 //give warnings for unresolved compounds
1417 for (const auto &icd : *Doxygen::classLinkedMap)
1418 {
1419 ClassDefMutable *cd = toClassDefMutable(icd.get());
1420 if (cd && visitedClasses.find(icd.get())==visitedClasses.end())
1421 {
1423 /// create the scope artificially
1424 // anyway, so we can at least relate scopes properly.
1425 Definition *d = buildScopeFromQualifiedName(name,cd->getLanguage(),nullptr);
1426 if (d && d!=cd && !cd->getDefFileName().isEmpty())
1427 // avoid recursion in case of redundant scopes, i.e: namespace N { class N::C {}; }
1428 // for this case doxygen assumes the existence of a namespace N::N in which C is to be found!
1429 // also avoid warning for stuff imported via a tagfile.
1430 {
1432 if (dm)
1433 {
1434 dm->addInnerCompound(cd);
1435 }
1436 cd->setOuterScope(d);
1437 warn(cd->getDefFileName(),cd->getDefLine(),
1438 "Incomplete input: scope for class {} not found!{}",name,
1439 name.startsWith("std::") ? " Try enabling BUILTIN_STL_SUPPORT." : ""
1440 );
1441 }
1442 }
1443 }
1444}

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

10912{
10913 int sepPos=0;
10914 int oldPos=0;
10915 StringUnorderedSet nonSymlinks;
10916 StringUnorderedSet known;
10917 QCString result(path);
10918 QCString oldPrefix = "/";
10919 do
10920 {
10921#if defined(_WIN32)
10922 // UNC path, skip server and share name
10923 if (sepPos==0 && (result.startsWith("//") || result.startsWith("\\\\")))
10924 sepPos = result.find('/',2);
10925 if (sepPos!=-1)
10926 sepPos = result.find('/',sepPos+1);
10927#else
10928 sepPos = result.find('/',sepPos+1);
10929#endif
10930 QCString prefix = sepPos==-1 ? result : result.left(sepPos);
10931 if (nonSymlinks.find(prefix.str())==nonSymlinks.end())
10932 {
10933 FileInfo fi(prefix.str());
10934 if (fi.isSymLink())
10935 {
10936 QCString target = fi.readLink();
10937 bool isRelative = FileInfo(target.str()).isRelative();
10938 if (isRelative)
10939 {
10940 target = Dir::cleanDirPath(oldPrefix.str()+"/"+target.str());
10941 }
10942 if (sepPos!=-1)
10943 {
10944 if (fi.isDir() && target.length()>0 && target.at(target.length()-1)!='/')
10945 {
10946 target+='/';
10947 }
10948 target+=result.mid(sepPos);
10949 }
10950 result = Dir::cleanDirPath(target.str());
10951 if (known.find(result.str())!=known.end()) return std::string(); // recursive symlink!
10952 known.insert(result.str());
10953 if (isRelative)
10954 {
10955 sepPos = oldPos;
10956 }
10957 else // link to absolute path
10958 {
10959 sepPos = 0;
10960 oldPrefix = "/";
10961 }
10962 }
10963 else
10964 {
10965 nonSymlinks.insert(prefix.str());
10966 oldPrefix = prefix;
10967 }
10968 oldPos = sepPos;
10969 }
10970 }
10971 while (sepPos!=-1);
10972 return Dir::cleanDirPath(result.str());
10973}
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 4771 of file doxygen.cpp.

4772{
4773 // For a statement like 'using X = T<A>', add a template instance 'T<A>' as a symbol, so it can
4774 // be used to match arguments (see issue #11111)
4775 AUTO_TRACE();
4776 QCString ttype = md->typeString();
4777 ttype.stripPrefix("typedef ");
4778 int ti=ttype.find('<');
4779 if (ti!=-1)
4780 {
4781 QCString templateClassName = ttype.left(ti);
4782 SymbolResolver resolver(root->fileDef());
4783 ClassDefMutable *baseClass = resolver.resolveClassMutable(scope ? scope : Doxygen::globalScope,
4784 templateClassName, true, true);
4785 AUTO_TRACE_ADD("templateClassName={} baseClass={}",templateClassName,baseClass?baseClass->name():"<none>");
4786 if (baseClass)
4787 {
4788 const ArgumentList &tl = baseClass->templateArguments();
4789 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,templateClassName.str());
4791 baseClass,
4792 ttype.mid(ti),
4793 templateNames,
4794 baseClass->isArtificial());
4795 }
4796 }
4797}

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

9811{
9812 for (const auto &si : SectionManager::instance())
9813 {
9814 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
9815 // qPrint(si->label),si->definition?qPrint(si->definition->name()):"<none>",
9816 // qPrint(si->fileName));
9817 PageDef *pd=nullptr;
9818
9819 // hack: the items of a todo/test/bug/deprecated list are all fragments from
9820 // different files, so the resulting section's all have the wrong file
9821 // name (not from the todo/test/bug/deprecated list, but from the file in
9822 // which they are defined). We correct this here by looking at the
9823 // generated section labels!
9825 {
9826 QCString label="_"+rl->listName(); // "_todo", "_test", ...
9827 if (si->label().left(label.length())==label)
9828 {
9829 si->setFileName(rl->listName());
9830 si->setGenerated(TRUE);
9831 break;
9832 }
9833 }
9834
9835 //printf("start: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9836 if (!si->generated())
9837 {
9838 // if this section is in a page and the page is in a group, then we
9839 // have to adjust the link file name to point to the group.
9840 if (!si->fileName().isEmpty() &&
9841 (pd=Doxygen::pageLinkedMap->find(si->fileName())) &&
9842 pd->getGroupDef())
9843 {
9844 si->setFileName(pd->getGroupDef()->getOutputFileBase());
9845 }
9846
9847 if (si->definition())
9848 {
9849 // TODO: there should be one function in Definition that returns
9850 // the file to link to, so we can avoid the following tests.
9851 const GroupDef *gd=nullptr;
9852 if (si->definition()->definitionType()==Definition::TypeMember)
9853 {
9854 gd = (toMemberDef(si->definition()))->getGroupDef();
9855 }
9856
9857 if (gd)
9858 {
9859 si->setFileName(gd->getOutputFileBase());
9860 }
9861 else
9862 {
9863 //si->fileName=si->definition->getOutputFileBase();
9864 //printf("Setting si->fileName to %s\n",qPrint(si->fileName));
9865 }
9866 }
9867 }
9868 //printf("end: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9869 }
9870}
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 10134 of file doxygen.cpp.

10135{
10136 std::string oldDir = Dir::currentDirPath();
10137 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10140 {
10141 err("failed to run html help compiler on {}\n", HtmlHelp::hhpFileName);
10142 }
10143 Dir::setCurrent(oldDir);
10144}
@ 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:106
void setShortDir()
Definition portable.cpp:554

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

10147{
10148 QCString args = Qhp::qhpFileName + " -o \"" + Qhp::getQchFileName() + "\"";
10149 std::string oldDir = Dir::currentDirPath();
10150 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10151
10152 QCString qhgLocation=Config_getString(QHG_LOCATION);
10153 if (Debug::isFlagSet(Debug::Qhp)) // produce info for debugging
10154 {
10155 // run qhelpgenerator -v and extract the Qt version used
10156 QCString cmd=qhgLocation+ " -v 2>&1";
10157 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10158 FILE *f=Portable::popen(cmd,"r");
10159 if (!f)
10160 {
10161 err("could not execute {}\n",qhgLocation);
10162 }
10163 else
10164 {
10165 const size_t bufSize = 1024;
10166 char inBuf[bufSize+1];
10167 size_t numRead=fread(inBuf,1,bufSize,f);
10168 inBuf[numRead] = '\0';
10169 Debug::print(Debug::Qhp,0,"{}",inBuf);
10171
10172 int qtVersion=0;
10173 static const reg::Ex versionReg(R"(Qt (\d+)\.(\d+)\.(\d+))");
10175 std::string s = inBuf;
10176 if (reg::search(inBuf,match,versionReg))
10177 {
10178 qtVersion = 10000*QCString(match[1].str()).toInt() +
10179 100*QCString(match[2].str()).toInt() +
10180 QCString(match[3].str()).toInt();
10181 }
10182 if (qtVersion>0 && (qtVersion<60000 || qtVersion >= 60205))
10183 {
10184 // dump the output of qhelpgenerator -c file.qhp
10185 // Qt<6 or Qt>=6.2.5 or higher, see https://bugreports.qt.io/browse/QTBUG-101070
10186 cmd=qhgLocation+ " -c " + Qhp::qhpFileName + " 2>&1";
10187 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10188 f=Portable::popen(cmd,"r");
10189 if (!f)
10190 {
10191 err("could not execute {}\n",qhgLocation);
10192 }
10193 else
10194 {
10195 std::string output;
10196 while ((numRead=fread(inBuf,1,bufSize,f))>0)
10197 {
10198 inBuf[numRead] = '\0';
10199 output += inBuf;
10200 }
10202 Debug::print(Debug::Qhp,0,"{}",output);
10203 }
10204 }
10205 }
10206 }
10207
10208 if (Portable::system(qhgLocation, args, FALSE))
10209 {
10210 err("failed to run qhelpgenerator on {}\n",Qhp::qhpFileName);
10211 }
10212 Dir::setCurrent(oldDir);
10213}
@ 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:480
int pclose(FILE *stream)
Definition portable.cpp:489

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

5936{
5937 bool result=FALSE;
5938 //printf("> scopeIsTemplate(%s)\n",qPrint(d?d->name():"null"));
5940 {
5941 auto cd = toClassDef(d);
5942 result = cd->templateArguments().hasParameters() || cd->templateMaster()!=nullptr ||
5944 }
5945 //printf("< scopeIsTemplate=%d\n",result);
5946 return result;
5947}

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

Referenced by addMemberFunction(), and scopeIsTemplate().

◆ searchInputFiles()

void searchInputFiles ( )

Definition at line 12145 of file doxygen.cpp.

12146{
12147 StringUnorderedSet killSet;
12148
12149 const StringVector &exclPatterns = Config_getList(EXCLUDE_PATTERNS);
12150 bool alwaysRecursive = Config_getBool(RECURSIVE);
12151 StringUnorderedSet excludeNameSet;
12152
12153 // gather names of all files in the include path
12154 g_s.begin("Searching for include files...\n");
12155 killSet.clear();
12156 const StringVector &includePathList = Config_getList(INCLUDE_PATH);
12157 for (const auto &s : includePathList)
12158 {
12159 size_t plSize = Config_getList(INCLUDE_FILE_PATTERNS).size();
12160 const StringVector &pl = plSize==0 ? Config_getList(FILE_PATTERNS) :
12161 Config_getList(INCLUDE_FILE_PATTERNS);
12162 readFileOrDirectory(s, // s
12164 nullptr, // exclSet
12165 &pl, // patList
12166 &exclPatterns, // exclPatList
12167 nullptr, // resultList
12168 nullptr, // resultSet
12169 false, // INCLUDE_PATH isn't recursive
12170 TRUE, // errorIfNotExist
12171 &killSet); // killSet
12172 }
12173 g_s.end();
12174
12175 g_s.begin("Searching for example files...\n");
12176 killSet.clear();
12177 const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
12178 for (const auto &s : examplePathList)
12179 {
12180 readFileOrDirectory(s, // s
12182 nullptr, // exclSet
12183 &Config_getList(EXAMPLE_PATTERNS), // patList
12184 nullptr, // exclPatList
12185 nullptr, // resultList
12186 nullptr, // resultSet
12187 (alwaysRecursive || Config_getBool(EXAMPLE_RECURSIVE)), // recursive
12188 TRUE, // errorIfNotExist
12189 &killSet); // killSet
12190 }
12191 g_s.end();
12192
12193 g_s.begin("Searching for images...\n");
12194 killSet.clear();
12195 const StringVector &imagePathList=Config_getList(IMAGE_PATH);
12196 for (const auto &s : imagePathList)
12197 {
12198 readFileOrDirectory(s, // s
12200 nullptr, // exclSet
12201 nullptr, // patList
12202 nullptr, // exclPatList
12203 nullptr, // resultList
12204 nullptr, // resultSet
12205 alwaysRecursive, // recursive
12206 TRUE, // errorIfNotExist
12207 &killSet); // killSet
12208 }
12209 g_s.end();
12210
12211 g_s.begin("Searching for dot files...\n");
12212 killSet.clear();
12213 const StringVector &dotFileList=Config_getList(DOTFILE_DIRS);
12214 for (const auto &s : dotFileList)
12215 {
12216 readFileOrDirectory(s, // s
12218 nullptr, // exclSet
12219 nullptr, // patList
12220 nullptr, // exclPatList
12221 nullptr, // resultList
12222 nullptr, // resultSet
12223 alwaysRecursive, // recursive
12224 TRUE, // errorIfNotExist
12225 &killSet); // killSet
12226 }
12227 g_s.end();
12228
12229 g_s.begin("Searching for msc files...\n");
12230 killSet.clear();
12231 const StringVector &mscFileList=Config_getList(MSCFILE_DIRS);
12232 for (const auto &s : mscFileList)
12233 {
12234 readFileOrDirectory(s, // s
12236 nullptr, // exclSet
12237 nullptr, // patList
12238 nullptr, // exclPatList
12239 nullptr, // resultList
12240 nullptr, // resultSet
12241 alwaysRecursive, // recursive
12242 TRUE, // errorIfNotExist
12243 &killSet); // killSet
12244 }
12245 g_s.end();
12246
12247 g_s.begin("Searching for dia files...\n");
12248 killSet.clear();
12249 const StringVector &diaFileList=Config_getList(DIAFILE_DIRS);
12250 for (const auto &s : diaFileList)
12251 {
12252 readFileOrDirectory(s, // s
12254 nullptr, // exclSet
12255 nullptr, // patList
12256 nullptr, // exclPatList
12257 nullptr, // resultList
12258 nullptr, // resultSet
12259 alwaysRecursive, // recursive
12260 TRUE, // errorIfNotExist
12261 &killSet); // killSet
12262 }
12263 g_s.end();
12264
12265 g_s.begin("Searching for plantuml files...\n");
12266 killSet.clear();
12267 const StringVector &plantUmlFileList=Config_getList(PLANTUMLFILE_DIRS);
12268 for (const auto &s : plantUmlFileList)
12269 {
12270 readFileOrDirectory(s, // s
12272 nullptr, // exclSet
12273 nullptr, // patList
12274 nullptr, // exclPatList
12275 nullptr, // resultList
12276 nullptr, // resultSet
12277 alwaysRecursive, // recursive
12278 TRUE, // errorIfNotExist
12279 &killSet); // killSet
12280 }
12281 g_s.end();
12282
12283 g_s.begin("Searching for files to exclude\n");
12284 const StringVector &excludeList = Config_getList(EXCLUDE);
12285 for (const auto &s : excludeList)
12286 {
12287 readFileOrDirectory(s, // s
12288 nullptr, // fnDict
12289 nullptr, // exclSet
12290 &Config_getList(FILE_PATTERNS), // patList
12291 nullptr, // exclPatList
12292 nullptr, // resultList
12293 &excludeNameSet, // resultSet
12294 alwaysRecursive, // recursive
12295 FALSE); // errorIfNotExist
12296 }
12297 g_s.end();
12298
12299 /**************************************************************************
12300 * Determine Input Files *
12301 **************************************************************************/
12302
12303 g_s.begin("Searching INPUT for files to process...\n");
12304 killSet.clear();
12305 Doxygen::inputPaths.clear();
12306 const StringVector &inputList=Config_getList(INPUT);
12307 for (const auto &s : inputList)
12308 {
12309 QCString path = s;
12310 size_t l = path.length();
12311 if (l>0)
12312 {
12313 // strip trailing slashes
12314 if (path.at(l-1)=='\\' || path.at(l-1)=='/') path=path.left(l-1);
12315
12317 path, // s
12319 &excludeNameSet, // exclSet
12320 &Config_getList(FILE_PATTERNS), // patList
12321 &exclPatterns, // exclPatList
12322 &g_inputFiles, // resultList
12323 nullptr, // resultSet
12324 alwaysRecursive, // recursive
12325 TRUE, // errorIfNotExist
12326 &killSet, // killSet
12327 &Doxygen::inputPaths); // paths
12328 }
12329 }
12330
12331 // Sort the FileDef objects by full path to get a predictable ordering over multiple runs
12332 std::stable_sort(Doxygen::inputNameLinkedMap->begin(),
12334 [](const auto &f1,const auto &f2)
12335 {
12336 return qstricmp_sort(f1->fullName(),f2->fullName())<0;
12337 });
12338 for (auto &fileName : *Doxygen::inputNameLinkedMap)
12339 {
12340 if (fileName->size()>1)
12341 {
12342 std::stable_sort(fileName->begin(),fileName->end(),[](const auto &f1,const auto &f2)
12343 {
12344 return qstricmp_sort(f1->absFilePath(),f2->absFilePath())<0;
12345 });
12346 }
12347 }
12348 if (Doxygen::inputNameLinkedMap->empty())
12349 {
12350 warn_uncond("No files to be processed, please check your settings, in particular INPUT, FILE_PATTERNS, and RECURSIVE\n");
12351 }
12352 g_s.end();
12353}
static StringUnorderedSet inputPaths
Definition doxygen.h:104
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::mscFileNameLinkedMap, Doxygen::plantUmlFileNameLinkedMap, qstricmp_sort(), readFileOrDirectory(), TRUE, and warn_uncond.

Referenced by parseInput().

◆ setAnonymousEnumType()

void setAnonymousEnumType ( )
static

Definition at line 8954 of file doxygen.cpp.

8955{
8956 for (const auto &cd : *Doxygen::classLinkedMap)
8957 {
8958 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8959 if (cdm)
8960 {
8961 cdm->setAnonymousEnumType();
8962 }
8963 }
8964}
virtual void setAnonymousEnumType()=0

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

Referenced by parseInput().

◆ sortMemberLists()

void sortMemberLists ( )
static

Definition at line 8859 of file doxygen.cpp.

8860{
8861 // sort class member lists
8862 for (const auto &cd : *Doxygen::classLinkedMap)
8863 {
8864 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8865 if (cdm)
8866 {
8867 cdm->sortMemberLists();
8868 }
8869 }
8870
8871 // sort namespace member lists
8872 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8873 {
8875 if (ndm)
8876 {
8877 ndm->sortMemberLists();
8878 }
8879 }
8880
8881 // sort file member lists
8882 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8883 {
8884 for (const auto &fd : *fn)
8885 {
8886 fd->sortMemberLists();
8887 }
8888 }
8889
8890 // sort group member lists
8891 for (const auto &gd : *Doxygen::groupLinkedMap)
8892 {
8893 gd->sortMemberLists();
8894 }
8895
8897}
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 12014 of file doxygen.cpp.

12015{
12016 signal(SIGINT,SIG_DFL); // Re-register signal handler for default action
12017 Dir thisDir;
12018 msg("Cleaning up...\n");
12019 if (!Doxygen::filterDBFileName.isEmpty())
12020 {
12021 thisDir.remove(Doxygen::filterDBFileName.str());
12022 }
12023 killpg(0,SIGINT);
12025 exitTracing();
12026 exit(1);
12027}

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

Referenced by parseInput().

◆ stripTemplateSpecifiers()

QCString stripTemplateSpecifiers ( const QCString & s)

Definition at line 678 of file doxygen.cpp.

679{
680 size_t l = s.length();
681 int count=0;
682 int round=0;
683 QCString result;
684 for (size_t i=0;i<l;i++)
685 {
686 char c=s.at(i);
687 if (c=='(') round++;
688 else if (c==')' && round>0) round--;
689 else if (c=='<' && round==0) count++;
690 if (count==0)
691 {
692 result+=c;
693 }
694 if (c=='>' && round==0 && count>0) count--;
695 }
696 //printf("stripTemplateSpecifiers(%s)=%s\n",qPrint(s),qPrint(result));
697 return result;
698}

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

6039{
6040 auto dstIt = dst.begin();
6041 for (const Argument &sa : src)
6042 {
6043 QCString dstType = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.type.str());
6044 QCString dstArray = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.array.str());
6045 if (dstIt == dst.end())
6046 {
6047 Argument da = sa;
6048 da.type = dstType;
6049 da.array = dstArray;
6050 dst.push_back(da);
6051 dstIt = dst.end();
6052 }
6053 else
6054 {
6055 Argument da = *dstIt;
6056 da.type = dstType;
6057 da.array = dstArray;
6058 ++dstIt;
6059 }
6060 }
6061 dst.setConstSpecifier(src.constSpecifier());
6062 dst.setVolatileSpecifier(src.volatileSpecifier());
6063 dst.setPureSpecifier(src.pureSpecifier());
6065 srcTempArgLists,dstTempArgLists,
6066 src.trailingReturnType().str()));
6067 dst.setIsDeleted(src.isDeleted());
6068 dst.setRefQualifier(src.refQualifier());
6069 dst.setNoParameters(src.noParameters());
6070 //printf("substituteTemplatesInArgList: replacing %s with %s\n",
6071 // qPrint(argListToString(src)),qPrint(argListToString(dst))
6072 // );
6073}
iterator end()
Definition arguments.h:94
void setTrailingReturnType(const QCString &s)
Definition arguments.h:122
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:124
void setIsDeleted(bool b)
Definition arguments.h:123
iterator begin()
Definition arguments.h:93
void setNoParameters(bool b)
Definition arguments.h:125
void setVolatileSpecifier(bool b)
Definition arguments.h:120
static QCString substituteTemplatesInString(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const std::string &src)
Definition doxygen.cpp:5949
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 5949 of file doxygen.cpp.

5954{
5955 std::string dst;
5956 static const reg::Ex re(R"(\a\w*)");
5957 reg::Iterator it(src,re);
5959 //printf("type=%s\n",qPrint(sa->type));
5960 size_t p=0;
5961 for (; it!=end ; ++it) // for each word in srcType
5962 {
5963 const auto &match = *it;
5964 size_t i = match.position();
5965 size_t l = match.length();
5966 bool found=FALSE;
5967 dst+=src.substr(p,i-p);
5968 std::string name=match.str();
5969
5970 auto srcIt = srcTempArgLists.begin();
5971 auto dstIt = dstTempArgLists.begin();
5972 while (srcIt!=srcTempArgLists.end() && !found)
5973 {
5974 const ArgumentList *tdAli = nullptr;
5975 std::vector<Argument>::const_iterator tdaIt;
5976 if (dstIt!=dstTempArgLists.end())
5977 {
5978 tdAli = &(*dstIt);
5979 tdaIt = tdAli->begin();
5980 ++dstIt;
5981 }
5982
5983 const ArgumentList &tsaLi = *srcIt;
5984 for (auto tsaIt = tsaLi.begin(); tsaIt!=tsaLi.end() && !found; ++tsaIt)
5985 {
5986 Argument tsa = *tsaIt;
5987 const Argument *tda = nullptr;
5988 if (tdAli && tdaIt!=tdAli->end())
5989 {
5990 tda = &(*tdaIt);
5991 ++tdaIt;
5992 }
5993 //if (tda) printf("tsa=%s|%s tda=%s|%s\n",
5994 // qPrint(tsa.type),qPrint(tsa.name),
5995 // qPrint(tda->type),qPrint(tda->name));
5996 if (name==tsa.name.str())
5997 {
5998 if (tda && tda->name.isEmpty())
5999 {
6000 QCString tdaName = tda->name;
6001 QCString tdaType = tda->type;
6002 int vc=0;
6003 if (tdaType.startsWith("class ")) vc=6;
6004 else if (tdaType.startsWith("typename ")) vc=9;
6005 if (vc>0) // convert type=="class T" to type=="class" name=="T"
6006 {
6007 tdaName = tdaType.mid(vc);
6008 }
6009 if (!tdaName.isEmpty())
6010 {
6011 name=tdaName.str(); // substitute
6012 found=TRUE;
6013 }
6014 }
6015 }
6016 }
6017
6018 //printf(" srcList='%s' dstList='%s faList='%s'\n",
6019 // qPrint(argListToString(srclali.current())),
6020 // qPrint(argListToString(dstlali.current())),
6021 // funcTempArgList ? qPrint(argListToString(funcTempArgList)) : "<none>");
6022 ++srcIt;
6023 }
6024 dst+=name;
6025 p=i+l;
6026 }
6027 dst+=src.substr(p);
6028 //printf(" substituteTemplatesInString(%s)=%s\n",
6029 // qPrint(src),qPrint(dst));
6030 return dst;
6031}

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

4282{
4283 AUTO_TRACE();
4284
4285 // find matching function declaration and definitions.
4286 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4287 {
4288 //printf("memberName=%s count=%zu\n",qPrint(mn->memberName()),mn->size());
4289 /* find a matching function declaration and definition for this function */
4290 for (const auto &imdec : *mn)
4291 {
4292 MemberDefMutable *mdec = toMemberDefMutable(imdec.get());
4293 if (mdec &&
4294 (mdec->isPrototype() ||
4295 (mdec->isVariable() && mdec->isExternal())
4296 ))
4297 {
4298 for (const auto &imdef : *mn)
4299 {
4300 MemberDefMutable *mdef = toMemberDefMutable(imdef.get());
4301 if (mdef && mdec!=mdef &&
4302 mdec->getNamespaceDef()==mdef->getNamespaceDef())
4303 {
4305 }
4306 }
4307 }
4308 }
4309 }
4310}
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 4314 of file doxygen.cpp.

4315{
4316 AUTO_TRACE();
4317 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4318 {
4319 MemberDefMutable *mdef=nullptr,*mdec=nullptr;
4320 /* find a matching function declaration and definition for this function */
4321 for (const auto &imd : *mn)
4322 {
4323 MemberDefMutable *md = toMemberDefMutable(imd.get());
4324 if (md)
4325 {
4326 if (md->isPrototype())
4327 mdec=md;
4328 else if (md->isVariable() && md->isExternal())
4329 mdec=md;
4330
4331 if (md->isFunction() && !md->isStatic() && !md->isPrototype())
4332 mdef=md;
4333 else if (md->isVariable() && !md->isExternal() && !md->isStatic())
4334 mdef=md;
4335 }
4336
4337 if (mdef && mdec) break;
4338 }
4339 if (mdef && mdec)
4340 {
4341 const ArgumentList &mdefAl = mdef->argumentList();
4342 const ArgumentList &mdecAl = mdec->argumentList();
4343 if (
4344 matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),const_cast<ArgumentList*>(&mdefAl),
4345 mdec->getOuterScope(),mdec->getFileDef(),const_cast<ArgumentList*>(&mdecAl),
4346 TRUE,mdef->getLanguage()
4347 )
4348 ) /* match found */
4349 {
4350 AUTO_TRACE_ADD("merging references for mdec={} mdef={}",mdec->name(),mdef->name());
4351 mdef->mergeReferences(mdec);
4352 mdec->mergeReferences(mdef);
4353 mdef->mergeReferencedBy(mdec);
4354 mdec->mergeReferencedBy(mdef);
4355 }
4356 }
4357 }
4358}
virtual void mergeReferencedBy(const Definition *other)=0
virtual void mergeReferences(const Definition *other)=0

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

Referenced by parseInput().

◆ transferRelatedFunctionDocumentation()

void transferRelatedFunctionDocumentation ( )
static

Definition at line 4362 of file doxygen.cpp.

4363{
4364 AUTO_TRACE();
4365 // find match between function declaration and definition for
4366 // related functions
4367 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4368 {
4369 /* find a matching function declaration and definition for this function */
4370 // for each global function
4371 for (const auto &imd : *mn)
4372 {
4373 MemberDefMutable *md = toMemberDefMutable(imd.get());
4374 if (md)
4375 {
4376 //printf(" Function '%s'\n",qPrint(md->name()));
4377 MemberName *rmn = Doxygen::memberNameLinkedMap->find(md->name());
4378 if (rmn) // check if there is a member with the same name
4379 {
4380 //printf(" Member name found\n");
4381 // for each member with the same name
4382 for (const auto &irmd : *rmn)
4383 {
4384 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
4385 //printf(" Member found: related='%d'\n",rmd->isRelated());
4386 if (rmd &&
4387 (rmd->isRelated() || rmd->isForeign()) && // related function
4389 rmd->getOuterScope(),rmd->getFileDef(),&rmd->argumentList(),
4390 TRUE,md->getLanguage()
4391 )
4392 )
4393 {
4394 AUTO_TRACE_ADD("Found related member '{}'",md->name());
4395 if (rmd->relatedAlso())
4396 md->setRelatedAlso(rmd->relatedAlso());
4397 else if (rmd->isForeign())
4398 md->makeForeign();
4399 else
4400 md->makeRelated();
4401 }
4402 }
4403 }
4404 }
4405 }
4406 }
4407}
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(), and TRUE.

Referenced by parseInput().

◆ transferStaticInstanceInitializers()

void transferStaticInstanceInitializers ( )

Definition at line 4411 of file doxygen.cpp.

4412{
4413 AUTO_TRACE();
4414 for (const auto &[qualifiedName,bodyInfo] : Doxygen::staticInitMap)
4415 {
4416 size_t i=qualifiedName.rfind("::");
4417 if (i!=std::string::npos)
4418 {
4419 QCString scope = qualifiedName.substr(0,i);
4420 QCString name = qualifiedName.substr(i+2);
4421 MemberName *mn = Doxygen::memberNameLinkedMap->find(name);
4422 if (mn)
4423 {
4424 for (const auto &imd : *mn)
4425 {
4426 MemberDefMutable *md = toMemberDefMutable(imd.get());
4427 if (md && md->qualifiedName().str()==qualifiedName && md->isVariable())
4428 {
4429 AUTO_TRACE_ADD("found static member {} body [{}..{}]\n",
4430 md->qualifiedName(),bodyInfo.startLine,bodyInfo.endLine);
4431 md->setBodySegment(bodyInfo.defLine,
4432 bodyInfo.startLine,
4433 bodyInfo.endLine);
4434 }
4435 }
4436 }
4437 }
4438 }
4439}

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

7945{
7946 for (const auto &g : root->groups)
7947 {
7948 const GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
7949 if (gd)
7950 {
7951 MemberList *ml = gd->getMemberList(MemberListType::DecEnumMembers());
7952 if (ml)
7953 {
7954 MemberDefMutable *md = toMemberDefMutable(ml->find(name));
7955 if (md)
7956 {
7957 addEnumDocs(root,md);
7958 return TRUE;
7959 }
7960 }
7961 }
7962 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
7963 {
7964 warn(root->fileName, root->startLine,
7965 "Found non-existing group '{}' for the command '{}', ignoring command",
7966 g.groupname, Grouping::getGroupPriName( g.pri )
7967 );
7968 }
7969 }
7970
7971 return FALSE;
7972}
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 11261 of file doxygen.cpp.

11262{
11264 msg("Doxygen version {0}\nCopyright Dimitri van Heesch 1997-2025\n\n"
11265 "You can use Doxygen in a number of ways:\n\n"
11266 "1) Use Doxygen to generate a template configuration file*:\n"
11267 " {1} [-s] -g [configName]\n\n"
11268 "2) Use Doxygen to update an old configuration file*:\n"
11269 " {1} [-s] -u [configName]\n\n"
11270 "3) Use Doxygen to generate documentation using an existing "
11271 "configuration file*:\n"
11272 " {1} [configName]\n\n"
11273 "4) Use Doxygen to generate a template file controlling the layout of the\n"
11274 " generated documentation:\n"
11275 " {1} -l [layoutFileName]\n\n"
11276 " In case layoutFileName is omitted DoxygenLayout.xml will be used as filename.\n"
11277 " If - is used for layoutFileName Doxygen will write to standard output.\n\n"
11278 "5) Use Doxygen to generate a template style sheet file for RTF, HTML or Latex.\n"
11279 " RTF: {1} -w rtf styleSheetFile\n"
11280 " HTML: {1}-w html headerFile footerFile styleSheetFile [configFile]\n"
11281 " LaTeX: {1} -w latex headerFile footerFile styleSheetFile [configFile]\n\n"
11282 "6) Use Doxygen to generate a rtf extensions file\n"
11283 " {1} -e rtf extensionsFile\n\n"
11284 " If - is used for extensionsFile Doxygen will write to standard output.\n\n"
11285 "7) Use Doxygen to compare the used configuration file with the template configuration file\n"
11286 " {1} -x [configFile]\n\n"
11287 " Use Doxygen to compare the used configuration file with the template configuration file\n"
11288 " without replacing the environment variables or CMake type replacement variables\n"
11289 " {1} -x_noenv [configFile]\n\n"
11290 "8) Use Doxygen to show a list of built-in emojis.\n"
11291 " {1} -f emoji outputFileName\n\n"
11292 " If - is used for outputFileName Doxygen will write to standard output.\n\n"
11293 "*) If -s is specified the comments of the configuration items in the config file will be omitted.\n"
11294 " If configName is omitted 'Doxyfile' will be used as a default.\n"
11295 " If - is used for configFile Doxygen will write / read the configuration to /from standard output / input.\n\n"
11296 "If -q is used for a Doxygen documentation run, Doxygen will see this as if QUIET=YES has been set.\n\n"
11297 "-v print version string, -V print extended version information\n"
11298 "-h,-? prints usage help information\n"
11299 "{1} -d prints additional usage flags for debugging purposes\n",versionString,name);
11300}

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

Referenced by readConfiguration().

◆ version()

void version ( const bool extended)
static

Definition at line 11233 of file doxygen.cpp.

11234{
11236 QCString versionString = getFullVersion();
11237 msg("{}\n",versionString);
11238 if (extended)
11239 {
11240 QCString extVers;
11241 if (!extVers.isEmpty()) extVers+= ", ";
11242 extVers += "sqlite3 ";
11243 extVers += sqlite3_libversion();
11244#if USE_LIBCLANG
11245 if (!extVers.isEmpty()) extVers+= ", ";
11246 extVers += "clang support ";
11247 extVers += CLANG_VERSION_STRING;
11248#endif
11249 if (!extVers.isEmpty())
11250 {
11251 int lastComma = extVers.findRev(',');
11252 if (lastComma != -1) extVers = extVers.replace(lastComma,1," and");
11253 msg(" with {}.\n",extVers);
11254 }
11255 }
11256}
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 8307 of file doxygen.cpp.

8308{
8309 // for each member name
8310 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8311 {
8312 // for each member definition
8313 for (const auto &imd : *mn)
8314 {
8315 MemberDefMutable *md = toMemberDefMutable(imd.get());
8316 if (md)
8317 {
8319 }
8320 }
8321 }
8322 // for each member name
8323 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8324 {
8325 // for each member definition
8326 for (const auto &imd : *mn)
8327 {
8328 MemberDefMutable *md = toMemberDefMutable(imd.get());
8329 if (md)
8330 {
8332 }
8333 }
8334 }
8335}
static void correctMemberProperties(MemberDefMutable *md)

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

Referenced by parseInput().

◆ warnUndocumentedNamespaces()

void warnUndocumentedNamespaces ( )
static

Definition at line 5292 of file doxygen.cpp.

5293{
5294 AUTO_TRACE();
5295 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5296 {
5297 if (!nd->hasDocumentation())
5298 {
5299 if ((guessSection(nd->getDefFileName()).isHeader() ||
5300 nd->getLanguage() == SrcLangExt::Fortran) && // Fortran doesn't have header files.
5301 !Config_getBool(HIDE_UNDOC_NAMESPACES) // undocumented namespaces are visible
5302 )
5303 {
5304 warn_undoc(nd->getDefFileName(),nd->getDefLine(), "{} {} is not documented.",
5305 nd->getLanguage() == SrcLangExt::Fortran ? "Module" : "Namespace",
5306 nd->name());
5307 }
5308 }
5309 }
5310}

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

Referenced by parseInput().

◆ writeTagFile()

void writeTagFile ( )
static

Definition at line 12030 of file doxygen.cpp.

12031{
12032 QCString generateTagFile = Config_getString(GENERATE_TAGFILE);
12033 if (generateTagFile.isEmpty()) return;
12034
12035 std::ofstream f = Portable::openOutputStream(generateTagFile);
12036 if (!f.is_open())
12037 {
12038 err("cannot open tag file {} for writing\n", generateTagFile);
12039 return;
12040 }
12041 TextStream tagFile(&f);
12042 tagFile << "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>\n";
12043 tagFile << "<tagfile doxygen_version=\"" << getDoxygenVersion() << "\"";
12044 std::string gitVersion = getGitVersion();
12045 if (!gitVersion.empty())
12046 {
12047 tagFile << " doxygen_gitid=\"" << gitVersion << "\"";
12048 }
12049 tagFile << ">\n";
12050
12051 // for each file
12052 for (const auto &fn : *Doxygen::inputNameLinkedMap)
12053 {
12054 for (const auto &fd : *fn)
12055 {
12056 if (fd->isLinkableInProject()) fd->writeTagFile(tagFile);
12057 }
12058 }
12059 // for each class
12060 for (const auto &cd : *Doxygen::classLinkedMap)
12061 {
12062 ClassDefMutable *cdm = toClassDefMutable(cd.get());
12063 if (cdm && cdm->isLinkableInProject())
12064 {
12065 cdm->writeTagFile(tagFile);
12066 }
12067 }
12068 // for each concept
12069 for (const auto &cd : *Doxygen::conceptLinkedMap)
12070 {
12071 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
12072 if (cdm && cdm->isLinkableInProject())
12073 {
12074 cdm->writeTagFile(tagFile);
12075 }
12076 }
12077 // for each namespace
12078 for (const auto &nd : *Doxygen::namespaceLinkedMap)
12079 {
12081 if (ndm && nd->isLinkableInProject())
12082 {
12083 ndm->writeTagFile(tagFile);
12084 }
12085 }
12086 // for each group
12087 for (const auto &gd : *Doxygen::groupLinkedMap)
12088 {
12089 if (gd->isLinkableInProject()) gd->writeTagFile(tagFile);
12090 }
12091 // for each module
12092 for (const auto &mod : ModuleManager::instance().modules())
12093 {
12094 if (mod->isLinkableInProject()) mod->writeTagFile(tagFile);
12095 }
12096 // for each page
12097 for (const auto &pd : *Doxygen::pageLinkedMap)
12098 {
12099 if (pd->isLinkableInProject()) pd->writeTagFile(tagFile);
12100 }
12101 // for each directory
12102 for (const auto &dd : *Doxygen::dirLinkedMap)
12103 {
12104 if (dd->isLinkableInProject()) dd->writeTagFile(tagFile);
12105 }
12106 if (Doxygen::mainPage) Doxygen::mainPage->writeTagFile(tagFile);
12107
12108 tagFile << "</tagfile>\n";
12109}
virtual void writeTagFile(TextStream &) const =0
virtual void writeTagFile(TextStream &)=0
virtual void writeTagFile(TextStream &)=0

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

Referenced by generateOutput().

Variable Documentation

◆ g_classEntries

◆ g_commentFileName

QCString g_commentFileName
static

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

Referenced by parseInput(), and readConfiguration().

◆ g_successfulRun

bool g_successfulRun = FALSE
static

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

Referenced by findUsingDeclImports(), and parseInput().

◆ g_usingDeclarations

StringSet g_usingDeclarations
static

Definition at line 189 of file doxygen.cpp.

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