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

9136{
9137 list.push_back(cd);
9138 for (const auto &innerCdi : cd->getClasses())
9139 {
9140 ClassDefMutable *innerCd = toClassDefMutable(innerCdi);
9141 if (innerCd)
9142 {
9143 AUTO_TRACE("innerCd={} isLinkable={} isImplicitTemplateInstance={} protectLevelVisible={} embeddedInOuterScope={}",
9144 innerCd->name(),innerCd->isLinkableInProject(),innerCd->isImplicitTemplateInstance(),protectionLevelVisible(innerCd->protection()),
9145 innerCd->isEmbeddedInOuterScope());
9146 }
9147 if (innerCd && innerCd->isLinkableInProject() && !innerCd->isImplicitTemplateInstance() &&
9148 protectionLevelVisible(innerCd->protection()) &&
9149 !innerCd->isEmbeddedInOuterScope()
9150 )
9151 {
9152 list.push_back(innerCd);
9153 addClassAndNestedClasses(list,innerCd);
9154 }
9155 }
9156}
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:9135
bool protectionLevelVisible(Protection prot)
Definition util.cpp:5906

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) &&
1037 (i=fullName.find('<'))!=-1)
1038 {
1039 // a Java/C# generic class looks like a C++ specialization, so we need to split the
1040 // name and template arguments here
1041 tArgList = stringToArgumentList(root->lang,fullName.mid(i));
1042 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
1043 // A -> A
1044 // A<T> -> A-1-g
1045 // A<T,S> -> A-2-g
1046 {
1047 fullName=mangleCSharpGenericName(fullName);
1048 }
1049 else
1050 {
1051 fullName=fullName.left(i);
1052 }
1053 }
1054 else
1055 {
1056 tArgList = getTemplateArgumentsFromName(fullName,root->tArgLists);
1057 }
1058 // add class to the list
1059 cd = toClassDefMutable(
1060 Doxygen::classLinkedMap->add(fullName,
1061 createClassDef(tagInfo?tagName:root->fileName,root->startLine,root->startColumn,
1062 fullName,sec,tagName,refFileName,TRUE,root->spec.isEnum()) ));
1063 if (cd)
1064 {
1065 AUTO_TRACE_ADD("New class '{}' type={} #tArgLists={} tagInfo={} hidden={} artificial={}",
1066 fullName,cd->compoundTypeString(),root->tArgLists.size(),
1067 fmt::ptr(tagInfo),root->hidden,root->artificial);
1068 cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1069 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1070 cd->setLanguage(root->lang);
1071 cd->setId(root->id);
1072 cd->setHidden(root->hidden);
1073 cd->setArtificial(root->artificial);
1074 cd->setClassSpecifier(root->spec);
1075 cd->addQualifiers(root->qualifiers);
1076 cd->setTypeConstraints(root->typeConstr);
1077 root->commandOverrides.apply_collaborationGraph([&](bool b ) { cd->overrideCollaborationGraph(b); });
1078 root->commandOverrides.apply_inheritanceGraph ([&](CLASS_GRAPH_t gt) { cd->overrideInheritanceGraph(gt); });
1079
1080 if (tArgList)
1081 {
1082 cd->setTemplateArguments(*tArgList);
1083 }
1084 cd->setRequiresClause(root->req);
1085 cd->setProtection(root->protection);
1086 cd->setIsStatic(root->isStatic);
1087
1088 // file definition containing the class cd
1089 cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1090 cd->setBodyDef(fd);
1091
1092 cd->setMetaData(root->metaData);
1093
1094 cd->insertUsedFile(fd);
1095 }
1096 else
1097 {
1098 AUTO_TRACE_ADD("Class {} not added, already exists as alias", fullName);
1099 }
1100 }
1101
1102 if (cd)
1103 {
1105 if (!root->subGrouping) cd->setSubGrouping(FALSE);
1106 if (!root->spec.isForwardDecl())
1107 {
1108 if (cd->hasDocumentation())
1109 {
1110 addIncludeFile(cd,fd,root);
1111 }
1112 if (fd && root->section.isCompound())
1113 {
1114 AUTO_TRACE_ADD("Inserting class {} in file {} (root->fileName='{}')", cd->name(), fd->name(), root->fileName);
1115 cd->setFileDef(fd);
1116 fd->insertClass(cd);
1117 }
1118 }
1119 addClassToGroups(root,cd);
1121 cd->setRefItems(root->sli);
1122 }
1123}
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:95
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 constexpr bool isCompound() const noexcept
Definition types.h:822
constexpr bool isScope() const noexcept
Definition types.h:823
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
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:822
#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:882
void extractNamespaceName(const QCString &scopeName, QCString &className, QCString &namespaceName, bool allowEmptyClass)
Definition util.cpp:3651
QCString mangleCSharpGenericName(const QCString &name)
Definition util.cpp:6882
QCString stripTemplateSpecifiersFromScope(const QCString &fullName, bool parentOnly, QCString *pLastScopeStripped, QCString scopeName, bool allowArtificial)
Definition util.cpp:4481

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

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

9525{
9526 md->setDocumentation(root->doc,root->docFile,root->docLine);
9527 md->setDocsForDefinition(!root->proto);
9528 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9529 if (md->inbodyDocumentation().isEmpty())
9530 {
9532 }
9533 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
9534 {
9535 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
9536 md->setBodyDef(root->fileDef());
9537 }
9539 md->setMaxInitLines(root->initLines);
9541 md->setRefItems(root->sli);
9542 md->addQualifiers(root->qualifiers);
9543 if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
9544 addMemberToGroups(root,md);
9546}
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:2131
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 7954 of file doxygen.cpp.

7955{
7956 AUTO_TRACE();
7957 // documentation outside a compound overrides the documentation inside it
7958 {
7959 md->setDocumentation(root->doc,root->docFile,root->docLine);
7960 md->setDocsForDefinition(!root->proto);
7961 }
7962
7963 // brief descriptions inside a compound override the documentation
7964 // outside it
7965 {
7966 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7967 }
7968
7969 if (md->inbodyDocumentation().isEmpty() || !root->parent()->name.isEmpty())
7970 {
7972 }
7973
7974 if (root->mGrpId!=-1 && md->getMemberGroupId()==-1)
7975 {
7976 md->setMemberGroupId(root->mGrpId);
7977 }
7978
7980 md->setRefItems(root->sli);
7981
7982 const GroupDef *gd=md->getGroupDef();
7983 if (gd==nullptr && !root->groups.empty()) // member not grouped but out-of-line documentation is
7984 {
7985 addMemberToGroups(root,md);
7986 }
7988}
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 7705 of file doxygen.cpp.

7706{
7707 if (root->section.isEnum())
7708 // non anonymous enumeration
7709 {
7710 AUTO_TRACE("name={}",root->name);
7711 ClassDefMutable *cd = nullptr;
7712 FileDef *fd = nullptr;
7713 NamespaceDefMutable *nd = nullptr;
7714 MemberNameLinkedMap *mnsd = nullptr;
7715 bool isGlobal = false;
7716 bool isRelated = false;
7717 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
7718
7719 QCString name;
7720 QCString scope;
7721
7722 int i = root->name.findRev("::");
7723 if (i!=-1) // scope is specified
7724 {
7725 scope=root->name.left(i); // extract scope
7726 if (root->lang==SrcLangExt::CSharp)
7727 {
7728 scope = mangleCSharpGenericName(scope);
7729 }
7730 name=root->name.right(root->name.length()-i-2); // extract name
7731 if ((cd=getClassMutable(scope))==nullptr)
7732 {
7734 }
7735 }
7736 else // no scope, check the scope in which the docs where found
7737 {
7738 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7739 {
7740 scope=root->parent()->name;
7741 if (root->lang==SrcLangExt::CSharp)
7742 {
7743 scope = mangleCSharpGenericName(scope);
7744 }
7745 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7746 }
7747 name=root->name;
7748 }
7749
7750 if (!root->relates.isEmpty())
7751 { // related member, prefix user specified scope
7752 isRelated=TRUE;
7753 if (getClassMutable(root->relates)==nullptr && !scope.isEmpty())
7754 scope=mergeScopes(scope,root->relates);
7755 else
7756 scope=root->relates;
7757 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7758 }
7759
7760 if (cd && !name.isEmpty()) // found a enum inside a compound
7761 {
7762 //printf("Enum in class '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
7763 fd=nullptr;
7765 isGlobal=false;
7766 }
7767 else if (nd && !nd->isAnonymous()) // found enum inside namespace
7768 {
7769 //printf("Enum in namespace '%s'::'%s'\n",qPrint(nd->name()),qPrint(name));
7771 isGlobal=true;
7772 }
7773 else // found a global enum
7774 {
7775 fd=root->fileDef();
7776 //printf("Enum in file '%s': '%s'\n",qPrint(fd->name()),qPrint(name));
7778 isGlobal=true;
7779 }
7780
7781 if (!name.isEmpty())
7782 {
7783 //printf("** name=%s\n",qPrint(name));
7784 MemberName *mn = mnsd->find(name); // for all members with this name
7785 if (mn)
7786 {
7787 struct EnumValueInfo
7788 {
7789 EnumValueInfo(const QCString &n,std::unique_ptr<MemberDef> &&md) :
7790 name(n), member(std::move(md)) {}
7791 QCString name;
7792 std::unique_ptr<MemberDef> member;
7793 };
7794 std::vector< EnumValueInfo > extraMembers;
7795 // for each enum in this list
7796 for (const auto &imd : *mn)
7797 {
7798 MemberDefMutable *md = toMemberDefMutable(imd.get());
7799 // use raw pointer in this loop, since we modify mn and can then invalidate mdp.
7800 if (md && md->isEnumerate() && !root->children().empty())
7801 {
7802 AUTO_TRACE_ADD("enum {} with {} children",md->name(),root->children().size());
7803 for (const auto &e : root->children())
7804 {
7805 SrcLangExt sle = root->lang;
7806 bool isJavaLike = sle==SrcLangExt::CSharp || sle==SrcLangExt::Java || sle==SrcLangExt::XML;
7807 if ( isJavaLike || root->spec.isStrong())
7808 {
7809 if (sle == SrcLangExt::Cpp && e->section.isDefine()) continue;
7810 // Unlike classic C/C++ enums, for C++11, C# & Java enum
7811 // values are only visible inside the enum scope, so we must create
7812 // them here and only add them to the enum
7813 //printf("md->qualifiedName()=%s e->name=%s tagInfo=%p name=%s\n",
7814 // qPrint(md->qualifiedName()),qPrint(e->name),(void*)e->tagInfo(),qPrint(e->name));
7815 QCString qualifiedName = root->name;
7816 i = qualifiedName.findRev("::");
7817 if (i!=-1 && sle==SrcLangExt::CSharp)
7818 {
7819 qualifiedName = mangleCSharpGenericName(qualifiedName.left(i))+qualifiedName.mid(i);
7820 }
7821 if (isJavaLike)
7822 {
7823 qualifiedName=substitute(qualifiedName,"::",".");
7824 }
7825 if (md->qualifiedName()==qualifiedName) // enum value scope matches that of the enum
7826 {
7827 QCString fileName = e->fileName;
7828 if (fileName.isEmpty() && e->tagInfo())
7829 {
7830 fileName = e->tagInfo()->tagName;
7831 }
7832 AUTO_TRACE_ADD("strong enum value {}",e->name);
7833 auto fmd = createMemberDef(
7834 fileName,e->startLine,e->startColumn,
7835 e->type,e->name,e->args,QCString(),
7836 e->protection, Specifier::Normal,e->isStatic,Relationship::Member,
7838 auto fmmd = toMemberDefMutable(fmd.get());
7839 NamespaceDef *mnd = md->getNamespaceDef();
7840 if (md->getClassDef())
7841 fmmd->setMemberClass(md->getClassDef());
7842 else if (mnd && (mnd->isLinkable() || mnd->isAnonymous()))
7843 fmmd->setNamespace(mnd);
7844 else if (md->getFileDef())
7845 fmmd->setFileDef(md->getFileDef());
7846 fmmd->setOuterScope(md->getOuterScope());
7847 fmmd->setTagInfo(e->tagInfo());
7848 fmmd->setLanguage(e->lang);
7849 fmmd->setBodySegment(e->startLine,e->bodyLine,e->endBodyLine);
7850 fmmd->setBodyDef(e->fileDef());
7851 fmmd->setId(e->id);
7852 fmmd->setDocumentation(e->doc,e->docFile,e->docLine);
7853 fmmd->setBriefDescription(e->brief,e->briefFile,e->briefLine);
7854 fmmd->addSectionsToDefinition(e->anchors);
7855 fmmd->setInitializer(e->initializer.str());
7856 fmmd->setMaxInitLines(e->initLines);
7857 fmmd->setMemberGroupId(e->mGrpId);
7858 fmmd->setExplicitExternal(e->explicitExternal,fileName,e->startLine,e->startColumn);
7859 fmmd->setRefItems(e->sli);
7860 fmmd->setAnchor();
7861 md->insertEnumField(fmd.get());
7862 fmmd->setEnumScope(md,TRUE);
7863 extraMembers.emplace_back(e->name,std::move(fmd));
7864 }
7865 }
7866 else
7867 {
7868 AUTO_TRACE_ADD("enum value {}",e->name);
7869 //printf("e->name=%s isRelated=%d\n",qPrint(e->name),isRelated);
7870 MemberName *fmn=nullptr;
7871 MemberNameLinkedMap *emnsd = isRelated ? Doxygen::functionNameLinkedMap : mnsd;
7872 if (!e->name.isEmpty() && (fmn=emnsd->find(e->name)))
7873 // get list of members with the same name as the field
7874 {
7875 for (const auto &ifmd : *fmn)
7876 {
7877 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
7878 if (fmd && fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope
7879 {
7880 //printf("found enum value with same name %s in scope %s\n",
7881 // qPrint(fmd->name()),qPrint(fmd->getOuterScope()->name()));
7882 if (nd && !nd->isAnonymous())
7883 {
7884 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7885 {
7886 const NamespaceDef *fnd=fmd->getNamespaceDef();
7887 if (fnd==nd) // enum value is inside a namespace
7888 {
7889 md->insertEnumField(fmd);
7890 fmd->setEnumScope(md);
7891 }
7892 }
7893 }
7894 else if (isGlobal)
7895 {
7896 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7897 {
7898 const FileDef *ffd=fmd->getFileDef();
7899 if (ffd==fd && ffd==md->getFileDef()) // enum value has file scope
7900 {
7901 md->insertEnumField(fmd);
7902 fmd->setEnumScope(md);
7903 }
7904 }
7905 }
7906 else if (isRelated && cd) // reparent enum value to
7907 // match the enum's scope
7908 {
7909 md->insertEnumField(fmd); // add field def to list
7910 fmd->setEnumScope(md); // cross ref with enum name
7911 fmd->setEnumClassScope(cd); // cross ref with enum name
7912 fmd->setOuterScope(cd);
7913 fmd->makeRelated();
7914 cd->insertMember(fmd);
7915 }
7916 else
7917 {
7918 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7919 {
7920 const ClassDef *fcd=fmd->getClassDef();
7921 if (fcd==cd) // enum value is inside a class
7922 {
7923 //printf("Inserting enum field %s in enum scope %s\n",
7924 // qPrint(fmd->name()),qPrint(md->name()));
7925 md->insertEnumField(fmd); // add field def to list
7926 fmd->setEnumScope(md); // cross ref with enum name
7927 }
7928 }
7929 }
7930 }
7931 }
7932 }
7933 }
7934 }
7935 }
7936 }
7937 // move the newly added members into mn
7938 for (auto &e : extraMembers)
7939 {
7940 MemberName *emn=mnsd->add(e.name);
7941 emn->push_back(std::move(e.member));
7942 }
7943 }
7944 }
7945 }
7946 else
7947 {
7948 for (const auto &e : root->children()) addEnumValuesToEnums(e.get());
7949 }
7950}
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:111
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:110
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
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:96
static void addEnumValuesToEnums(const Entry *root)
Definition doxygen.cpp:7705
MemberDefMutable * toMemberDefMutable(Definition *d)
std::unique_ptr< MemberDef > createMemberDef(const QCString &defFileName, int defLine, int defColumn, const QCString &type, const QCString &name, const QCString &args, const QCString &excp, Protection prot, Specifier virt, bool stat, Relationship related, MemberType t, const ArgumentList &tal, const ArgumentList &al, const QCString &metaData)
Factory method to create a new instance of a MemberDef.
NamespaceDefMutable * toNamespaceDefMutable(Definition *d)
NamespaceDefMutable * getResolvedNamespaceMutable(const QCString &key)
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:571
@ EnumValue
Definition types.h:558
SrcLangExt
Definition types.h:207
QCString mergeScopes(const QCString &leftScope, const QCString &rightScope)
Definition util.cpp:4548

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

3804{
3805 QCString scope = sc;
3806
3807 // new global function
3809 auto md = createMemberDef(
3810 root->fileName,root->startLine,root->startColumn,
3811 root->type,name,root->args,root->exception,
3812 root->protection,root->virt,root->isStatic,Relationship::Member,
3814 !root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
3815 root->argList,root->metaData);
3816 auto mmd = toMemberDefMutable(md.get());
3817 mmd->setTagInfo(root->tagInfo());
3818 mmd->setLanguage(root->lang);
3819 mmd->setId(root->id);
3820 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3821 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3822 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3823 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
3824 mmd->setDocsForDefinition(!root->proto);
3825 mmd->setTypeConstraints(root->typeConstr);
3826 //md->setBody(root->body);
3827 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3828 FileDef *fd=root->fileDef();
3829 mmd->setBodyDef(fd);
3830 mmd->addSectionsToDefinition(root->anchors);
3831 mmd->setMemberSpecifiers(root->spec);
3832 mmd->setVhdlSpecifiers(root->vhdlSpec);
3833 mmd->setMemberGroupId(root->mGrpId);
3834 mmd->setRequiresClause(root->req);
3835 mmd->setExplicitExternal(root->explicitExternal,root->fileName,root->startLine,root->startColumn);
3836
3837 NamespaceDefMutable *nd = nullptr;
3838 // see if the function is inside a namespace that was not part of
3839 // the name already (in that case nd should be non-zero already)
3840 if (root->parent()->section.isNamespace())
3841 {
3842 //QCString nscope=removeAnonymousScopes(root->parent()->name);
3843 QCString nscope=root->parent()->name;
3844 if (!nscope.isEmpty())
3845 {
3846 nd = getResolvedNamespaceMutable(nscope);
3847 }
3848 }
3849 else if (root->parent()->section.isGroupDoc() && !scope.isEmpty())
3850 {
3852 }
3853
3854 if (!scope.isEmpty())
3855 {
3857 if (sep!="::")
3858 {
3859 scope = substitute(scope,"::",sep);
3860 }
3861 scope+=sep;
3862 }
3863
3864 if (Config_getBool(HIDE_SCOPE_NAMES)) scope = "";
3865 QCString def;
3866 //QCString optArgs = root->argList.empty() ? QCString() : root->args;
3867 if (!root->type.isEmpty())
3868 {
3869 def=root->type+" "+scope+name; //+optArgs;
3870 }
3871 else
3872 {
3873 def=scope+name; //+optArgs;
3874 }
3875 AUTO_TRACE("new non-member function type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
3876 root->type,scope,rname,root->args,root->proto,def);
3877 mmd->setDefinition(def);
3879 mmd->addQualifiers(root->qualifiers);
3880
3881 mmd->setRefItems(root->sli);
3882 if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
3883 {
3884 // add member to namespace
3885 mmd->setNamespace(nd);
3886 nd->insertMember(md.get());
3887 }
3888 if (fd)
3889 {
3890 // add member to the file (we do this even if we have already
3891 // inserted it into the namespace)
3892 mmd->setFileDef(fd);
3893 fd->insertMember(md.get());
3894 }
3895
3896 addMemberToGroups(root,md.get());
3898 if (root->relatesType == RelatesType::Simple) // if this is a relatesalso command,
3899 // allow find Member to pick it up
3900 {
3901 root->markAsProcessed(); // Otherwise we have finished with this entry.
3902 }
3903
3904 // add member to the list of file members
3906 mn->push_back(std::move(md));
3907}
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:568
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
Definition util.cpp:5866

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:104
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:330
QCString showFileDefMatches(const FileNameLinkedMap *fnMap, const QCString &n)
Definition util.cpp:2972
EntryType guessSection(const QCString &name)
Definition util.cpp:339
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:2844

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

3558{
3559 FileDef *fd = root->fileDef();
3560 enum MemberType type = root->section.isExportedInterface() ? MemberType::Interface : MemberType::Service;
3561 QCString fileName = root->fileName;
3562 if (fileName.isEmpty() && root->tagInfo())
3563 {
3564 fileName = root->tagInfo()->tagName;
3565 }
3566 auto md = createMemberDef(
3567 fileName, root->startLine, root->startColumn, root->type, rname,
3568 "", "", root->protection, root->virt, root->isStatic, Relationship::Member,
3569 type, ArgumentList(), root->argList, root->metaData);
3570 auto mmd = toMemberDefMutable(md.get());
3571 mmd->setTagInfo(root->tagInfo());
3572 mmd->setMemberClass(cd);
3573 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3574 mmd->setDocsForDefinition(false);
3575 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3576 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3577 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3578 mmd->setMemberSpecifiers(root->spec);
3579 mmd->setVhdlSpecifiers(root->vhdlSpec);
3580 mmd->setMemberGroupId(root->mGrpId);
3581 mmd->setTypeConstraints(root->typeConstr);
3582 mmd->setLanguage(root->lang);
3583 mmd->setBodyDef(fd);
3584 mmd->setFileDef(fd);
3585 mmd->addSectionsToDefinition(root->anchors);
3586 QCString const def = root->type + " " + rname;
3587 mmd->setDefinition(def);
3589 mmd->addQualifiers(root->qualifiers);
3590
3591 AUTO_TRACE("Interface member: fileName='{}' type='{}' name='{}' mtype='{}' prot={} virt={} state={} proto={} def='{}'",
3592 fileName,root->type,rname,type,root->protection,root->virt,root->isStatic,root->proto,def);
3593
3594 // add member to the class cd
3595 cd->insertMember(md.get());
3596 // also add the member as a "base" (to get nicer diagrams)
3597 // "optional" interface/service get Protected which turns into dashed line
3598 BaseInfo base(rname,
3599 root->spec.isOptional() ? Protection::Protected : Protection::Public, Specifier::Normal);
3600 TemplateNameMap templateNames;
3601 findClassRelation(root,cd,cd,&base,templateNames,DocumentedOnly,true) ||
3602 findClassRelation(root,cd,cd,&base,templateNames,Undocumented,true);
3603 // add file to list of used files
3604 cd->insertUsedFile(fd);
3605
3606 addMemberToGroups(root,md.get());
3608 root->markAsProcessed();
3609 mmd->setRefItems(root->sli);
3610
3611 // add member to the global list of all members
3612 MemberName *mn = Doxygen::memberNameLinkedMap->add(rname);
3613 mn->push_back(std::move(md));
3614}
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:4873
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 5470 of file doxygen.cpp.

5471{
5472 AUTO_TRACE();
5473 for (const auto &cd : *Doxygen::classLinkedMap)
5474 {
5475 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5476 if (cdm)
5477 {
5478 cdm->addListReferences();
5479 }
5480 }
5481
5482 for (const auto &cd : *Doxygen::conceptLinkedMap)
5483 {
5484 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
5485 if (cdm)
5486 {
5487 cdm->addListReferences();
5488 }
5489 }
5490
5491 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5492 {
5493 for (const auto &fd : *fn)
5494 {
5495 fd->addListReferences();
5496 }
5497 }
5498
5499 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5500 {
5502 if (ndm)
5503 {
5504 ndm->addListReferences();
5505 }
5506 }
5507
5508 for (const auto &gd : *Doxygen::groupLinkedMap)
5509 {
5510 gd->addListReferences();
5511 }
5512
5513 for (const auto &pd : *Doxygen::pageLinkedMap)
5514 {
5515 QCString name = pd->getOutputFileBase();
5516 if (pd->getGroupDef())
5517 {
5518 name = pd->getGroupDef()->getOutputFileBase();
5519 }
5520 {
5521 const RefItemVector &xrefItems = pd->xrefListItems();
5522 addRefItem(xrefItems,
5523 name,
5524 theTranslator->trPage(TRUE,TRUE),
5525 name,pd->title(),QCString(),nullptr);
5526 }
5527 }
5528
5529 for (const auto &dd : *Doxygen::dirLinkedMap)
5530 {
5531 QCString name = dd->getOutputFileBase();
5532 //if (dd->getGroupDef())
5533 //{
5534 // name = dd->getGroupDef()->getOutputFileBase();
5535 //}
5536 const RefItemVector &xrefItems = dd->xrefListItems();
5537 addRefItem(xrefItems,
5538 name,
5539 theTranslator->trDir(TRUE,TRUE),
5540 name,dd->displayName(),QCString(),nullptr);
5541 }
5542
5544}
virtual void addListReferences()=0
virtual void addListReferences()=0
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:114
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:99
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:128
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:113
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:4778

References ClassDefMutable::addListReferences(), ConceptDefMutable::addListReferences(), ModuleManager::addListReferences(), NamespaceDefMutable::addListReferences(), addRefItem(), AUTO_TRACE, Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Doxygen::dirLinkedMap, Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, theTranslator, toClassDefMutable(), toConceptDefMutable(), 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 6116 of file doxygen.cpp.

6121{
6122 AUTO_TRACE();
6123 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
6124 ClassDefMutable *cd=nullptr;
6125 if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClassMutable(scopeName)))
6126 {
6127 AUTO_TRACE_ADD("Local objective C method '{}' scopeName='{}'",root->name,scopeName);
6128 auto md = createMemberDef(
6129 root->fileName,root->startLine,root->startColumn,
6130 funcType,funcName,funcArgs,exceptions,
6131 root->protection,root->virt,root->isStatic,Relationship::Member,
6133 auto mmd = toMemberDefMutable(md.get());
6134 mmd->setTagInfo(root->tagInfo());
6135 mmd->setLanguage(root->lang);
6136 mmd->setId(root->id);
6137 mmd->makeImplementationDetail();
6138 mmd->setMemberClass(cd);
6139 mmd->setDefinition(funcDecl);
6141 mmd->addQualifiers(root->qualifiers);
6142 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6143 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6144 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6145 mmd->setDocsForDefinition(!root->proto);
6146 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6147 mmd->addSectionsToDefinition(root->anchors);
6148 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6149 FileDef *fd=root->fileDef();
6150 mmd->setBodyDef(fd);
6151 mmd->setMemberSpecifiers(spec);
6152 mmd->setVhdlSpecifiers(root->vhdlSpec);
6153 mmd->setMemberGroupId(root->mGrpId);
6154 cd->insertMember(md.get());
6155 cd->insertUsedFile(fd);
6156 mmd->setRefItems(root->sli);
6157
6159 mn->push_back(std::move(md));
6160 }
6161 else
6162 {
6163 // local objective C method found for class without interface
6164 }
6165}

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

5568{
5569 if (md==nullptr) return;
5570 AUTO_TRACE("scope='{}' name='{}' args='{}' funcDecl='{}' mSpec={}",
5571 root->parent()->name,md->name(),md->argsString(),funcDecl,spec);
5572 if (!root->section.isDoc()) // @fn or @var does not need to specify the complete definition, so don't overwrite it
5573 {
5574 QCString fDecl=funcDecl;
5575 // strip extern specifier
5576 fDecl.stripPrefix("extern ");
5577 md->setDefinition(fDecl);
5578 }
5580 md->addQualifiers(root->qualifiers);
5582 const NamespaceDef *nd=md->getNamespaceDef();
5583 QCString fullName;
5584 if (cd)
5585 fullName = cd->name();
5586 else if (nd)
5587 fullName = nd->name();
5588
5589 if (!fullName.isEmpty()) fullName+="::";
5590 fullName+=md->name();
5591 FileDef *rfd=root->fileDef();
5592
5593 // TODO determine scope based on root not md
5594 Definition *rscope = md->getOuterScope();
5595
5596 const ArgumentList &mdAl = md->argumentList();
5597 if (al)
5598 {
5599 ArgumentList mergedAl = *al;
5600 //printf("merging arguments (1) docs=%d\n",root->doc.isEmpty());
5601 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedAl,!root->doc.isEmpty());
5602 }
5603 else
5604 {
5605 if (
5606 matchArguments2( md->getOuterScope(), md->getFileDef(),md->typeString(),const_cast<ArgumentList*>(&mdAl),
5607 rscope,rfd,root->type,&root->argList,
5608 TRUE, root->lang
5609 )
5610 )
5611 {
5612 //printf("merging arguments (2)\n");
5613 ArgumentList mergedArgList = root->argList;
5614 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.isEmpty());
5615 }
5616 }
5617 if (over_load) // the \overload keyword was used
5618 {
5620 if (!root->doc.isEmpty())
5621 {
5622 doc+="<p>";
5623 doc+=root->doc;
5624 }
5625 md->setDocumentation(doc,root->docFile,root->docLine);
5627 md->setDocsForDefinition(!root->proto);
5628 }
5629 else
5630 {
5631 //printf("overwrite!\n");
5632 md->setDocumentation(root->doc,root->docFile,root->docLine);
5633 md->setDocsForDefinition(!root->proto);
5634
5635 //printf("overwrite!\n");
5636 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
5637
5638 if (
5639 (md->inbodyDocumentation().isEmpty() ||
5640 !root->parent()->name.isEmpty()
5641 ) && !root->inbodyDocs.isEmpty()
5642 )
5643 {
5645 }
5646 }
5647
5648 //printf("initializer: '%s'(isEmpty=%d) '%s'(isEmpty=%d)\n",
5649 // qPrint(md->initializer()),md->initializer().isEmpty(),
5650 // qPrint(root->initializer),root->initializer.isEmpty()
5651 // );
5652 std::string rootInit = root->initializer.str();
5653 if (md->initializer().isEmpty() && !rootInit.empty())
5654 {
5655 //printf("setInitializer\n");
5656 md->setInitializer(rootInit);
5657 }
5658 if (md->requiresClause().isEmpty() && !root->req.isEmpty())
5659 {
5660 md->setRequiresClause(root->req);
5661 }
5662
5663 md->setMaxInitLines(root->initLines);
5664
5665 if (rfd)
5666 {
5667 if ((md->getStartBodyLine()==-1 && root->bodyLine!=-1)
5668 )
5669 {
5670 //printf("Setting new body segment [%d,%d]\n",root->bodyLine,root->endBodyLine);
5671 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
5672 md->setBodyDef(rfd);
5673 }
5674
5675 md->setRefItems(root->sli);
5676 }
5677
5679 md->addQualifiers(root->qualifiers);
5680
5681 md->mergeMemberSpecifiers(spec);
5683 addMemberToGroups(root,md);
5685 if (cd) cd->insertUsedFile(rfd);
5686 //printf("root->mGrpId=%d\n",root->mGrpId);
5687 if (root->mGrpId!=-1)
5688 {
5689 if (md->getMemberGroupId()!=-1)
5690 {
5691 if (md->getMemberGroupId()!=root->mGrpId)
5692 {
5693 warn(root->fileName,root->startLine,
5694 "member {} belongs to two different groups. The second one found here will be ignored.",
5695 md->name()
5696 );
5697 }
5698 }
5699 else // set group id
5700 {
5701 //printf("setMemberGroupId=%d md=%s\n",root->mGrpId,qPrint(md->name()));
5702 md->setMemberGroupId(root->mGrpId);
5703 }
5704 }
5705 md->addQualifiers(root->qualifiers);
5706}
constexpr bool isDoc() const noexcept
Definition types.h:826
virtual QCString typeString() const =0
virtual QCString requiresClause() const =0
virtual const ArgumentList & argumentList() const =0
virtual QCString argsString() const =0
virtual const QCString & initializer() const =0
virtual void setDefinition(const QCString &d)=0
virtual ClassDefMutable * getClassDefMutable()=0
virtual void setRequiresClause(const QCString &req)=0
virtual void setInitializer(const QCString &i)=0
virtual void mergeMemberSpecifiers(TypeSpecifier s)=0
bool stripPrefix(const QCString &prefix)
Definition qcstring.h:213
bool matchArguments2(const Definition *srcScope, const FileDef *srcFileScope, const QCString &srcReturnType, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const QCString &dstReturnType, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
Definition util.cpp:1971
void mergeArguments(ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
Definition util.cpp:2071
QCString getOverloadDocs()
Definition util.cpp:4043

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, Entry::type, MemberDef::typeString(), and warn.

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

◆ addMemberFunction()

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

Definition at line 6169 of file doxygen.cpp.

6187{
6188 AUTO_TRACE();
6189 QCString funcType = funcTyp;
6190 int count=0;
6191 int noMatchCount=0;
6192 bool memFound=FALSE;
6193 for (const auto &imd : *mn)
6194 {
6195 MemberDefMutable *md = toMemberDefMutable(imd.get());
6196 if (md==nullptr) continue;
6198 if (cd==nullptr) continue;
6199 //AUTO_TRACE_ADD("member definition found, scope needed='{}' scope='{}' args='{}' fileName='{}'",
6200 // scopeName, cd->name(), md->argsString(), root->fileName);
6201 FileDef *fd=root->fileDef();
6202 NamespaceDef *nd=nullptr;
6203 if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName);
6204
6205 //printf("scopeName %s->%s\n",qPrint(scopeName),
6206 // qPrint(stripTemplateSpecifiersFromScope(scopeName,FALSE)));
6207
6208 // if the member we are searching for is an enum value that is part of
6209 // a "strong" enum, we need to look into the fields of the enum for a match
6210 int enumNamePos=0;
6211 if (md->isEnumValue() && (enumNamePos=className.findRev("::"))!=-1)
6212 {
6213 QCString enumName = className.mid(enumNamePos+2);
6214 QCString fullScope = className.left(enumNamePos);
6215 if (!namespaceName.isEmpty()) fullScope.prepend(namespaceName+"::");
6216 if (fullScope==cd->name())
6217 {
6218 MemberName *enumMn=Doxygen::memberNameLinkedMap->find(enumName);
6219 //printf("enumMn(%s)=%p\n",qPrint(className),(void*)enumMn);
6220 if (enumMn)
6221 {
6222 for (const auto &emd : *enumMn)
6223 {
6224 memFound = emd->isStrong() && md->getEnumScope()==emd.get();
6225 if (memFound)
6226 {
6227 addMemberDocs(root,md,funcDecl,nullptr,overloaded,spec);
6228 count++;
6229 }
6230 if (memFound) break;
6231 }
6232 }
6233 }
6234 }
6235 if (memFound) break;
6236
6237 const ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
6238 if (tcd==nullptr && cd && stripAnonymousNamespaceScope(cd->name())==scopeName)
6239 {
6240 // don't be fooled by anonymous scopes
6241 tcd=cd;
6242 }
6243 //printf("Looking for %s inside nd=%s result=%s cd=%s\n",
6244 // qPrint(scopeName),nd?qPrint(nd->name()):"<none>",tcd?qPrint(tcd->name()):"",qPrint(cd->name()));
6245
6246 if (cd && tcd==cd) // member's classes match
6247 {
6248 AUTO_TRACE_ADD("class definition '{}' found",cd->name());
6249
6250 // get the template parameter lists found at the member declaration
6251 ArgumentLists declTemplArgs = cd->getTemplateParameterLists();
6252 const ArgumentList &templAl = md->templateArguments();
6253 if (!templAl.empty())
6254 {
6255 declTemplArgs.push_back(templAl);
6256 }
6257
6258 // get the template parameter lists found at the member definition
6259 const ArgumentLists &defTemplArgs = root->tArgLists;
6260 //printf("defTemplArgs=%p\n",defTemplArgs);
6261
6262 // do we replace the decl argument lists with the def argument lists?
6263 bool substDone=false;
6264 ArgumentList argList;
6265
6266 /* substitute the occurrences of class template names in the
6267 * argument list before matching
6268 */
6269 const ArgumentList &mdAl = md->argumentList();
6270 if (declTemplArgs.size()>0 && declTemplArgs.size()==defTemplArgs.size())
6271 {
6272 /* the function definition has template arguments
6273 * and the class definition also has template arguments, so
6274 * we must substitute the template names of the class by that
6275 * of the function definition before matching.
6276 */
6277 substituteTemplatesInArgList(declTemplArgs,defTemplArgs,mdAl,argList);
6278
6279 substDone=TRUE;
6280 }
6281 else /* no template arguments, compare argument lists directly */
6282 {
6283 argList = mdAl;
6284 }
6285
6286 bool matching=
6287 md->isVariable() || md->isTypedef() || // needed for function pointers
6289 md->getClassDef(),md->getFileDef(),md->typeString(),&argList,
6290 cd,fd,root->type,&root->argList,
6291 TRUE,root->lang);
6292
6293 AUTO_TRACE_ADD("matching '{}'<=>'{}' className='{}' namespaceName='{}' result={}",
6294 argListToString(argList,TRUE),argListToString(root->argList,TRUE),className,namespaceName,matching);
6295
6296 if (md->getLanguage()==SrcLangExt::ObjC && md->isVariable() && root->section.isFunction())
6297 {
6298 matching = FALSE; // don't match methods and attributes with the same name
6299 }
6300
6301 // for template member we also need to check the return type
6302 if (!md->templateArguments().empty() && !root->tArgLists.empty())
6303 {
6304 QCString memType = md->typeString();
6305 memType.stripPrefix("static "); // see bug700696
6307 className+"::",""); // see bug700693 & bug732594
6309 className+"::",""); // see bug758900
6310 if (memType=="auto" && !argList.trailingReturnType().isEmpty())
6311 {
6312 memType = argList.trailingReturnType();
6313 memType.stripPrefix(" -> ");
6314 }
6315 if (funcType=="auto" && !root->argList.trailingReturnType().isEmpty())
6316 {
6317 funcType = root->argList.trailingReturnType();
6318 funcType.stripPrefix(" -> ");
6320 substDone=true;
6321 }
6322 AUTO_TRACE_ADD("Comparing return types '{}'<->'{}' #args {}<->{}",
6323 memType,funcType,md->templateArguments().size(),root->tArgLists.back().size());
6324 if (md->templateArguments().size()!=root->tArgLists.back().size() || memType!=funcType)
6325 {
6326 //printf(" ---> no matching\n");
6327 matching = FALSE;
6328 }
6329 }
6330 else if (defTemplArgs.size()>declTemplArgs.size())
6331 {
6332 AUTO_TRACE_ADD("Different number of template arguments {} vs {}",defTemplArgs.size(),declTemplArgs.size());
6333 // avoid matching a non-template function in a template class against a
6334 // template function with the same name and parameters, see issue #10184
6335 substDone = false;
6336 matching = false;
6337 }
6338 bool rootIsUserDoc = root->section.isMemberDoc();
6339 bool classIsTemplate = scopeIsTemplate(md->getClassDef());
6340 bool mdIsTemplate = md->templateArguments().hasParameters();
6341 bool classOrMdIsTemplate = mdIsTemplate || classIsTemplate;
6342 bool rootIsTemplate = !root->tArgLists.empty();
6343 //printf("classIsTemplate=%d mdIsTemplate=%d rootIsTemplate=%d\n",classIsTemplate,mdIsTemplate,rootIsTemplate);
6344 if (!rootIsUserDoc && // don't check out-of-line @fn references, see bug722457
6345 (mdIsTemplate || rootIsTemplate) && // either md or root is a template
6346 ((classOrMdIsTemplate && !rootIsTemplate) || (!classOrMdIsTemplate && rootIsTemplate))
6347 )
6348 {
6349 // Method with template return type does not match method without return type
6350 // even if the parameters are the same. See also bug709052
6351 AUTO_TRACE_ADD("Comparing return types: template v.s. non-template");
6352 matching = FALSE;
6353 }
6354
6355 AUTO_TRACE_ADD("Match results of matchArguments2='{}' substDone='{}'",matching,substDone);
6356
6357 if (substDone) // found a new argument list
6358 {
6359 if (matching) // replace member's argument list
6360 {
6362 md->moveArgumentList(std::make_unique<ArgumentList>(argList));
6363 }
6364 else // no match
6365 {
6366 if (!funcTempList.isEmpty() &&
6367 isSpecialization(declTemplArgs,defTemplArgs))
6368 {
6369 // check if we are dealing with a partial template
6370 // specialization. In this case we add it to the class
6371 // even though the member arguments do not match.
6372
6373 addMethodToClass(root,cd,type,md->name(),args,isFriend,
6374 md->protection(),md->isStatic(),md->virtualness(),spec,relates);
6375 return;
6376 }
6377 }
6378 }
6379 if (matching)
6380 {
6381 addMemberDocs(root,md,funcDecl,nullptr,overloaded,spec);
6382 count++;
6383 memFound=TRUE;
6384 }
6385 }
6386 else if (cd && cd!=tcd) // we did find a class with the same name as cd
6387 // but in a different namespace
6388 {
6389 noMatchCount++;
6390 }
6391
6392 if (memFound) break;
6393 }
6394 if (count==0 && root->parent() && root->parent()->section.isObjcImpl())
6395 {
6396 addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec);
6397 return;
6398 }
6399 if (count==0 && !(isFriend && funcType=="class"))
6400 {
6401 int candidates=0;
6402 const ClassDef *ecd = nullptr, *ucd = nullptr;
6403 MemberDef *emd = nullptr, *umd = nullptr;
6404 //printf("Assume template class\n");
6405 for (const auto &md : *mn)
6406 {
6407 MemberDef *cmd=md.get();
6409 ClassDefMutable *ccd=cdmdm ? cdmdm->getClassDefMutable() : nullptr;
6410 //printf("ccd->name()==%s className=%s\n",qPrint(ccd->name()),qPrint(className));
6411 if (ccd!=nullptr && rightScopeMatch(ccd->name(),className))
6412 {
6413 const ArgumentList &templAl = md->templateArguments();
6414 if (!root->tArgLists.empty() && !templAl.empty() &&
6415 root->tArgLists.back().size()<=templAl.size())
6416 {
6417 AUTO_TRACE_ADD("add template specialization");
6418 addMethodToClass(root,ccd,type,md->name(),args,isFriend,
6419 root->protection,root->isStatic,root->virt,spec,relates);
6420 return;
6421 }
6424 { // exact argument list match -> remember
6425 ucd = ecd = ccd;
6426 umd = emd = cmd;
6427 AUTO_TRACE_ADD("new candidate className='{}' scope='{}' args='{}': exact match",
6428 className,ccd->name(),md->argsString());
6429 }
6430 else // arguments do not match, but member name and scope do -> remember
6431 {
6432 ucd = ccd;
6433 umd = cmd;
6434 AUTO_TRACE_ADD("new candidate className='{}' scope='{}' args='{}': no match",
6435 className,ccd->name(),md->argsString());
6436 }
6437 candidates++;
6438 }
6439 }
6440 bool strictProtoMatching = Config_getBool(STRICT_PROTO_MATCHING);
6441 if (!strictProtoMatching)
6442 {
6443 if (candidates==1 && ucd && umd)
6444 {
6445 // we didn't find an actual match on argument lists, but there is only 1 member with this
6446 // name in the same scope, so that has to be the one.
6447 addMemberDocs(root,toMemberDefMutable(umd),funcDecl,nullptr,overloaded,spec);
6448 return;
6449 }
6450 else if (candidates>1 && ecd && emd)
6451 {
6452 // we didn't find a unique match using type resolution,
6453 // but one of the matches has the exact same signature so
6454 // we take that one.
6455 addMemberDocs(root,toMemberDefMutable(emd),funcDecl,nullptr,overloaded,spec);
6456 return;
6457 }
6458 }
6459
6460 QCString warnMsg = "no ";
6461 if (noMatchCount>1) warnMsg+="uniquely ";
6462 warnMsg+="matching class member found for \n";
6463
6464 for (const ArgumentList &al : root->tArgLists)
6465 {
6466 warnMsg+=" template ";
6467 warnMsg+=tempArgListToString(al,root->lang);
6468 warnMsg+='\n';
6469 }
6470
6471 QCString fullFuncDecl=funcDecl;
6472 if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE);
6473
6474 warnMsg+=" ";
6475 warnMsg+=fullFuncDecl;
6476
6477 if (candidates>0 || noMatchCount>=1)
6478 {
6479 warnMsg+="\nPossible candidates:";
6480
6481 NamespaceDef *nd=nullptr;
6482 if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName);
6483 FileDef *fd=root->fileDef();
6484
6485 for (const auto &md : *mn)
6486 {
6487 const ClassDef *cd=md->getClassDef();
6488 const ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
6489 if (tcd==nullptr && cd && stripAnonymousNamespaceScope(cd->name())==scopeName)
6490 {
6491 // don't be fooled by anonymous scopes
6492 tcd=cd;
6493 }
6494 if (cd!=nullptr && (rightScopeMatch(cd->name(),className) || (cd!=tcd)))
6495 {
6496 warnMsg+='\n';
6497 const ArgumentList &templAl = md->templateArguments();
6498 warnMsg+=" '";
6499 if (templAl.hasParameters())
6500 {
6501 warnMsg+="template ";
6502 warnMsg+=tempArgListToString(templAl,root->lang);
6503 warnMsg+='\n';
6504 warnMsg+=" ";
6505 }
6506 if (!md->typeString().isEmpty())
6507 {
6508 warnMsg+=md->typeString();
6509 warnMsg+=' ';
6510 }
6512 if (!qScope.isEmpty())
6513 warnMsg+=qScope+"::"+md->name();
6514 warnMsg+=md->argsString();
6515 warnMsg+="' " + warn_line(md->getDefFileName(),md->getDefLine());
6516 }
6517 }
6518 }
6519 warn(root->fileName,root->startLine,"{}",warnMsg);
6520 }
6521}
std::vector< ArgumentList > ArgumentLists
Definition arguments.h:147
void setTrailingReturnType(const QCString &s)
Definition arguments.cpp:36
bool hasParameters() const
Definition arguments.h:76
QCString trailingReturnType() const
Definition arguments.h:114
size_t size() const
Definition arguments.h:100
virtual ArgumentLists getTemplateParameterLists() const =0
Returns the template parameter lists that form the template declaration of this class.
virtual QCString qualifiedNameWithTemplateParameters(const ArgumentLists *actualParams=nullptr, uint32_t *actualParamIndex=nullptr) const =0
virtual SrcLangExt getLanguage() const =0
Returns the programming language this definition was written in.
virtual QCString getDefFileName() const =0
virtual int getDefLine() const =0
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
virtual const ArgumentList & templateArguments() const =0
virtual bool isTypedef() const =0
virtual bool isStatic() const =0
virtual Protection protection() const =0
virtual bool isVariable() const =0
virtual Specifier virtualness(int count=0) const =0
virtual const MemberDef * getEnumScope() const =0
virtual void setDefinitionTemplateParameterLists(const ArgumentLists &lists)=0
virtual void moveArgumentList(std::unique_ptr< ArgumentList > al)=0
static bool isSpecialization(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists)
Definition doxygen.cpp:5958
static void substituteTemplatesInArgList(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const ArgumentList &src, ArgumentList &dst)
Definition doxygen.cpp:6072
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:6116
static void addMemberDocs(const Entry *root, MemberDefMutable *md, const QCString &funcDecl, const ArgumentList *al, bool over_load, TypeSpecifier spec)
Definition doxygen.cpp:5562
static bool scopeIsTemplate(const Definition *d)
Definition doxygen.cpp:5974
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:3668
static const ClassDef * findClassDefinition(FileDef *fd, NamespaceDef *nd, const QCString &scopeName)
Definition doxygen.cpp:5712
QCString warn_line(const QCString &file, int line)
Definition message.cpp:214
NamespaceDef * getResolvedNamespace(const QCString &name)
QCString stripAnonymousNamespaceScope(const QCString &s)
Definition util.cpp:231
QCString tempArgListToString(const ArgumentList &al, SrcLangExt lang, bool includeDefault)
Definition util.cpp:1249
QCString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:1204
bool rightScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:871
QCString replaceAnonymousScopes(const QCString &s, const QCString &replacement)
Definition util.cpp:219

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

Referenced by findMember().

◆ addMemberSpecialization()

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

Definition at line 6525 of file doxygen.cpp.

6535{
6536 AUTO_TRACE("funcType={} funcName={} funcArgs={} funcDecl={} spec={}",funcType,funcName,funcArgs,funcDecl,spec);
6537 MemberDef *declMd=nullptr;
6538 for (const auto &md : *mn)
6539 {
6540 if (md->getClassDef()==cd)
6541 {
6542 // TODO: we should probably also check for matching arguments
6543 declMd = md.get();
6544 break;
6545 }
6546 }
6548 ArgumentList tArgList;
6549 // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6550 auto md = createMemberDef(
6551 root->fileName,root->startLine,root->startColumn,
6552 funcType,funcName,funcArgs,exceptions,
6553 declMd ? declMd->protection() : root->protection,
6554 root->virt,root->isStatic,Relationship::Member,
6555 mtype,tArgList,root->argList,root->metaData);
6556 auto mmd = toMemberDefMutable(md.get());
6557 //printf("new specialized member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6558 mmd->setTagInfo(root->tagInfo());
6559 mmd->setLanguage(root->lang);
6560 mmd->setId(root->id);
6561 mmd->setMemberClass(cd);
6562 mmd->setTemplateSpecialization(TRUE);
6563 mmd->setTypeConstraints(root->typeConstr);
6564 mmd->setDefinition(funcDecl);
6566 mmd->addQualifiers(root->qualifiers);
6567 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6568 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6569 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6570 mmd->setDocsForDefinition(!root->proto);
6571 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6572 mmd->addSectionsToDefinition(root->anchors);
6573 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6574 FileDef *fd=root->fileDef();
6575 mmd->setBodyDef(fd);
6576 mmd->setMemberSpecifiers(spec);
6577 mmd->setVhdlSpecifiers(root->vhdlSpec);
6578 mmd->setMemberGroupId(root->mGrpId);
6579 cd->insertMember(md.get());
6580 mmd->setRefItems(root->sli);
6581
6582 mn->push_back(std::move(md));
6583}

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

8149{
8150 auto &index = Index::instance();
8151 // for each class member name
8152 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8153 {
8154 // for each member definition
8155 for (const auto &md : *mn)
8156 {
8157 index.addClassMemberNameToIndex(md.get());
8158 if (md->getModuleDef())
8159 {
8160 index.addModuleMemberNameToIndex(md.get());
8161 }
8162 }
8163 }
8164 // for each file/namespace function name
8165 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8166 {
8167 // for each member definition
8168 for (const auto &md : *mn)
8169 {
8170 if (md->getNamespaceDef())
8171 {
8172 index.addNamespaceMemberNameToIndex(md.get());
8173 }
8174 else
8175 {
8176 index.addFileMemberNameToIndex(md.get());
8177 }
8178 if (md->getModuleDef())
8179 {
8180 index.addModuleMemberNameToIndex(md.get());
8181 }
8182 }
8183 }
8184
8185 index.sortMemberIndexLists();
8186}
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 9265 of file doxygen.cpp.

9266{
9267 // for each class
9268 for (const auto &cd : *Doxygen::classLinkedMap)
9269 {
9270 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9271 if (cdm)
9272 {
9274 }
9275 }
9276 // for each file
9277 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9278 {
9279 for (const auto &fd : *fn)
9280 {
9281 fd->addMembersToMemberGroup();
9282 }
9283 }
9284 // for each namespace
9285 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9286 {
9288 if (ndm)
9289 {
9291 }
9292 }
9293 // for each group
9294 for (const auto &gd : *Doxygen::groupLinkedMap)
9295 {
9296 gd->addMembersToMemberGroup();
9297 }
9299}
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 3668 of file doxygen.cpp.

3674{
3675 FileDef *fd=root->fileDef();
3676
3677 QCString type = rtype;
3678 QCString args = rargs;
3679
3681 name.stripPrefix("::");
3682
3684 if (isFriend) mtype=MemberType::Friend;
3685 else if (root->mtype==MethodTypes::Signal) mtype=MemberType::Signal;
3686 else if (root->mtype==MethodTypes::Slot) mtype=MemberType::Slot;
3687 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType::DCOP;
3688
3689 // strip redundant template specifier for constructors
3690 int i = -1;
3691 int j = -1;
3692 if ((fd==nullptr || fd->getLanguage()==SrcLangExt::Cpp) &&
3693 !name.startsWith("operator ") && // not operator
3694 (i=name.find('<'))!=-1 && // containing <
3695 (j=name.find('>'))!=-1 && // or >
3696 (j!=i+2 || name.at(i+1)!='=') // but not the C++20 spaceship operator <=>
3697 )
3698 {
3699 name=name.left(i);
3700 }
3701
3702 QCString fileName = root->fileName;
3703 if (fileName.isEmpty() && root->tagInfo())
3704 {
3705 fileName = root->tagInfo()->tagName;
3706 }
3707
3708 //printf("root->name='%s; args='%s' root->argList='%s'\n",
3709 // qPrint(root->name),qPrint(args),qPrint(argListToString(root->argList))
3710 // );
3711
3712 // adding class member
3713 Relationship relationship = relates.isEmpty() ? Relationship::Member :
3714 root->relatesType==RelatesType::MemberOf ? Relationship::Foreign :
3715 Relationship::Related ;
3716 auto md = createMemberDef(
3717 fileName,root->startLine,root->startColumn,
3718 type,name,args,root->exception,
3719 protection,virt,
3720 stat && root->relatesType!=RelatesType::MemberOf,
3721 relationship,
3722 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
3723 root->argList, root->metaData);
3724 auto mmd = toMemberDefMutable(md.get());
3725 mmd->setTagInfo(root->tagInfo());
3726 mmd->setMemberClass(cd);
3727 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3728 mmd->setDocsForDefinition(!root->proto);
3729 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3730 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3731 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3732 mmd->setMemberSpecifiers(spec);
3733 mmd->setVhdlSpecifiers(root->vhdlSpec);
3734 mmd->setMemberGroupId(root->mGrpId);
3735 mmd->setTypeConstraints(root->typeConstr);
3736 mmd->setLanguage(root->lang);
3737 mmd->setRequiresClause(root->req);
3738 mmd->setId(root->id);
3739 mmd->setBodyDef(fd);
3740 mmd->setFileDef(fd);
3741 mmd->addSectionsToDefinition(root->anchors);
3742 QCString def;
3744 SrcLangExt lang = cd->getLanguage();
3745 QCString scopeSeparator=getLanguageSpecificSeparator(lang);
3746 if (scopeSeparator!="::")
3747 {
3748 qualScope = substitute(qualScope,"::",scopeSeparator);
3749 }
3750 if (lang==SrcLangExt::PHP)
3751 {
3752 // for PHP we use Class::method and Namespace\method
3753 scopeSeparator="::";
3754 }
3755 if (!relates.isEmpty() || isFriend || Config_getBool(HIDE_SCOPE_NAMES))
3756 {
3757 if (!type.isEmpty())
3758 {
3759 def=type+" "+name; //+optArgs;
3760 }
3761 else
3762 {
3763 def=name; //+optArgs;
3764 }
3765 }
3766 else
3767 {
3768 if (!type.isEmpty())
3769 {
3770 def=type+" "+qualScope+scopeSeparator+name; //+optArgs;
3771 }
3772 else
3773 {
3774 def=qualScope+scopeSeparator+name; //+optArgs;
3775 }
3776 }
3777 def.stripPrefix("friend ");
3778 mmd->setDefinition(def);
3780 mmd->addQualifiers(root->qualifiers);
3781
3782 AUTO_TRACE("function member: type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
3783 type, qualScope, rname, args, root->proto, def);
3784
3785 // add member to the class cd
3786 cd->insertMember(md.get());
3787 // add file to list of used files
3788 cd->insertUsedFile(fd);
3789
3790 addMemberToGroups(root,md.get());
3792 root->markAsProcessed();
3793 mmd->setRefItems(root->sli);
3794
3795 // add member to the global list of all members
3796 //printf("Adding member=%s class=%s\n",qPrint(md->name()),qPrint(cd->name()));
3798 mn->push_back(std::move(md));
3799}
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 6587 of file doxygen.cpp.

6590{
6591 // for unique overloaded member we allow the class to be
6592 // omitted, this is to be Qt compatible. Using this should
6593 // however be avoided, because it is error prone
6594 bool sameClass=false;
6595 if (mn->size()>0)
6596 {
6597 // check if all members with the same name are also in the same class
6598 sameClass = std::equal(mn->begin()+1,mn->end(),mn->begin(),
6599 [](const auto &md1,const auto &md2)
6600 { return md1->getClassDef()->name()==md2->getClassDef()->name(); });
6601 }
6602 if (sameClass)
6603 {
6604 MemberDefMutable *mdm = toMemberDefMutable(mn->front().get());
6605 ClassDefMutable *cd = mdm ? mdm->getClassDefMutable() : nullptr;
6606 if (cd==nullptr) return;
6607
6609 if (root->mtype==MethodTypes::Signal) mtype=MemberType::Signal;
6610 else if (root->mtype==MethodTypes::Slot) mtype=MemberType::Slot;
6611 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType::DCOP;
6612
6613 // new overloaded member function
6614 std::unique_ptr<ArgumentList> tArgList =
6615 getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6616 //printf("new related member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6617 auto md = createMemberDef(
6618 root->fileName,root->startLine,root->startColumn,
6619 funcType,funcName,funcArgs,exceptions,
6620 root->protection,root->virt,root->isStatic,Relationship::Related,
6621 mtype,tArgList ? *tArgList : ArgumentList(),root->argList,root->metaData);
6622 auto mmd = toMemberDefMutable(md.get());
6623 mmd->setTagInfo(root->tagInfo());
6624 mmd->setLanguage(root->lang);
6625 mmd->setId(root->id);
6626 mmd->setTypeConstraints(root->typeConstr);
6627 mmd->setMemberClass(cd);
6628 mmd->setDefinition(funcDecl);
6630 mmd->addQualifiers(root->qualifiers);
6632 doc+="<p>";
6633 doc+=root->doc;
6634 mmd->setDocumentation(doc,root->docFile,root->docLine);
6635 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6636 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6637 mmd->setDocsForDefinition(!root->proto);
6638 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6639 mmd->addSectionsToDefinition(root->anchors);
6640 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6641 FileDef *fd=root->fileDef();
6642 mmd->setBodyDef(fd);
6643 mmd->setMemberSpecifiers(spec);
6644 mmd->setVhdlSpecifiers(root->vhdlSpec);
6645 mmd->setMemberGroupId(root->mGrpId);
6646 cd->insertMember(md.get());
6647 cd->insertUsedFile(fd);
6648 mmd->setRefItems(root->sli);
6649
6650 mn->push_back(std::move(md));
6651 }
6652}
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 8783 of file doxygen.cpp.

8784{
8785 // add source references for class definitions
8786 for (const auto &cd : *Doxygen::classLinkedMap)
8787 {
8788 const FileDef *fd=cd->getBodyDef();
8789 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8790 {
8791 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8792 }
8793 }
8794 // add source references for concept definitions
8795 for (const auto &cd : *Doxygen::conceptLinkedMap)
8796 {
8797 const FileDef *fd=cd->getBodyDef();
8798 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8799 {
8800 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8801 }
8802 }
8803 // add source references for namespace definitions
8804 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8805 {
8806 const FileDef *fd=nd->getBodyDef();
8807 if (fd && nd->isLinkableInProject() && nd->getStartDefLine()!=-1)
8808 {
8809 const_cast<FileDef*>(fd)->addSourceRef(nd->getStartDefLine(),nd.get(),nullptr);
8810 }
8811 }
8812
8813 // add source references for member names
8814 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8815 {
8816 for (const auto &md : *mn)
8817 {
8818 //printf("class member %s: def=%s body=%d link?=%d\n",
8819 // qPrint(md->name()),
8820 // md->getBodyDef()?qPrint(md->getBodyDef()->name()):"<none>",
8821 // md->getStartBodyLine(),md->isLinkableInProject());
8822 const FileDef *fd=md->getBodyDef();
8823 if (fd &&
8824 md->getStartDefLine()!=-1 &&
8825 md->isLinkableInProject() &&
8827 )
8828 {
8829 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8830 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8831 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8832 }
8833 }
8834 }
8835 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8836 {
8837 for (const auto &md : *mn)
8838 {
8839 const FileDef *fd=md->getBodyDef();
8840 //printf("member %s body=[%d,%d] fd=%p link=%d parseSources=%d\n",
8841 // qPrint(md->name()),
8842 // md->getStartBodyLine(),md->getEndBodyLine(),fd,
8843 // md->isLinkableInProject(),
8844 // Doxygen::parseSourcesNeeded);
8845 if (fd &&
8846 md->getStartDefLine()!=-1 &&
8847 md->isLinkableInProject() &&
8849 )
8850 {
8851 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8852 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8853 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8854 }
8855 }
8856 }
8857}
virtual const FileDef * getBodyDef() const =0
static bool parseSourcesNeeded
Definition doxygen.h:122

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

8191{
8192 for (const auto &cd : *Doxygen::classLinkedMap)
8193 {
8194 if (cd->isLinkableInProject())
8195 {
8196 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8197 if (Doxygen::searchIndex.enabled())
8198 {
8199 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
8200 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
8201 }
8202 }
8203 }
8204
8205 for (const auto &cd : *Doxygen::conceptLinkedMap)
8206 {
8207 if (cd->isLinkableInProject())
8208 {
8209 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8210 if (Doxygen::searchIndex.enabled())
8211 {
8212 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
8213 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
8214 }
8215 }
8216 }
8217
8218 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8219 {
8220 if (nd->isLinkableInProject())
8221 {
8222 Doxygen::indexList->addIndexItem(nd.get(),nullptr);
8223 if (Doxygen::searchIndex.enabled())
8224 {
8225 Doxygen::searchIndex.setCurrentDoc(nd.get(),nd->anchor(),FALSE);
8226 Doxygen::searchIndex.addWord(nd->localName(),TRUE);
8227 }
8228 }
8229 }
8230
8231 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8232 {
8233 for (const auto &fd : *fn)
8234 {
8235 if (Doxygen::searchIndex.enabled() && fd->isLinkableInProject())
8236 {
8237 Doxygen::searchIndex.setCurrentDoc(fd.get(),fd->anchor(),FALSE);
8238 Doxygen::searchIndex.addWord(fd->localName(),TRUE);
8239 }
8240 }
8241 }
8242
8243 auto addWordsForTitle = [](const Definition *d,const QCString &anchor,const QCString &title)
8244 {
8245 Doxygen::indexList->addIndexItem(d,nullptr,QCString(),filterTitle(title));
8246 if (Doxygen::searchIndex.enabled())
8247 {
8248 Doxygen::searchIndex.setCurrentDoc(d,anchor,false);
8249 std::string s = title.str();
8250 static const reg::Ex re(R"(\a[\w-]*)");
8251 reg::Iterator it(s,re);
8253 for (; it!=end ; ++it)
8254 {
8255 const auto &match = *it;
8256 std::string matchStr = match.str();
8257 Doxygen::searchIndex.addWord(matchStr,true);
8258 }
8259 }
8260 };
8261
8262 for (const auto &gd : *Doxygen::groupLinkedMap)
8263 {
8264 if (gd->isLinkableInProject())
8265 {
8266 addWordsForTitle(gd.get(),gd->anchor(),gd->groupTitle());
8267 }
8268 }
8269
8270 for (const auto &pd : *Doxygen::pageLinkedMap)
8271 {
8272 if (pd->isLinkableInProject())
8273 {
8274 addWordsForTitle(pd.get(),pd->anchor(),pd->title());
8275 }
8276 }
8277
8279 {
8280 addWordsForTitle(Doxygen::mainPage.get(),Doxygen::mainPage->anchor(),Doxygen::mainPage->title());
8281 }
8282
8283 auto addMemberToSearchIndex = [](const MemberDef *md)
8284 {
8285 if (Doxygen::searchIndex.enabled())
8286 {
8287 Doxygen::searchIndex.setCurrentDoc(md,md->anchor(),FALSE);
8288 QCString ln=md->localName();
8289 QCString qn=md->qualifiedName();
8290 Doxygen::searchIndex.addWord(ln,TRUE);
8291 if (ln!=qn)
8292 {
8293 Doxygen::searchIndex.addWord(qn,TRUE);
8294 if (md->getClassDef())
8295 {
8296 Doxygen::searchIndex.addWord(md->getClassDef()->displayName(),TRUE);
8297 }
8298 if (md->getNamespaceDef())
8299 {
8300 Doxygen::searchIndex.addWord(md->getNamespaceDef()->displayName(),TRUE);
8301 }
8302 }
8303 }
8304 };
8305
8306 auto getScope = [](const MemberDef *md)
8307 {
8308 const Definition *scope = nullptr;
8309 if (md->getGroupDef()) scope = md->getGroupDef();
8310 else if (md->getClassDef()) scope = md->getClassDef();
8311 else if (md->getNamespaceDef()) scope = md->getNamespaceDef();
8312 else if (md->getFileDef()) scope = md->getFileDef();
8313 return scope;
8314 };
8315
8316 auto addMemberToIndices = [addMemberToSearchIndex,getScope](const MemberDef *md)
8317 {
8318 if (md->isLinkableInProject())
8319 {
8320 if (!(md->isEnumerate() && md->isAnonymous()))
8321 {
8322 Doxygen::indexList->addIndexItem(getScope(md),md);
8324 }
8325 if (md->isEnumerate())
8326 {
8327 for (const auto &fmd : md->enumFieldList())
8328 {
8329 Doxygen::indexList->addIndexItem(getScope(fmd),fmd);
8331 }
8332 }
8333 }
8334 };
8335
8336 // for each class member name
8337 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8338 {
8339 // for each member definition
8340 for (const auto &md : *mn)
8341 {
8342 addMemberToIndices(md.get());
8343 }
8344 }
8345 // for each file/namespace function name
8346 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8347 {
8348 // for each member definition
8349 for (const auto &md : *mn)
8350 {
8351 addMemberToIndices(md.get());
8352 }
8353 }
8354}
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:100
static IndexList * indexList
Definition doxygen.h:133
static SearchIndexIntf searchIndex
Definition doxygen.h:123
Class representing a regular expression.
Definition regex.h:39
Class to iterate through matches.
Definition regex.h:230
DirIterator end(const DirIterator &) noexcept
Definition dir.cpp:175
bool match(std::string_view str, Match &match, const Ex &re)
Matches a given string str for a match against regular expression re.
Definition regex.cpp:855
static void addMemberToSearchIndex(const MemberDef *md)
QCString filterTitle(const QCString &title)
Definition util.cpp:5583

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

3132{
3133 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
3134
3135 AUTO_TRACE("VARIABLE_SEC: type='{}' name='{}' args='{}' bodyLine={} endBodyLine={} mGrpId={} relates='{}'",
3136 root->type, root->name, root->args, root->bodyLine, root->endBodyLine, root->mGrpId, root->relates);
3137 //printf("root->parent->name=%s\n",qPrint(root->parent->name));
3138
3139 QCString type = root->type;
3140 QCString name = root->name;
3141 QCString args = root->args;
3142 if (type.isEmpty() && name.find("operator")==-1 &&
3143 (name.find('*')!=-1 || name.find('&')!=-1))
3144 {
3145 // recover from parse error caused by redundant braces
3146 // like in "int *(var[10]);", which is parsed as
3147 // type="" name="int *" args="(var[10])"
3148
3149 type=name;
3150 std::string sargs = args.str();
3151 static const reg::Ex reName(R"(\a\w*)");
3153 if (reg::search(sargs,match,reName))
3154 {
3155 name = match.str(); // e.g. 'var' in '(var[10])'
3156 sargs = match.suffix().str(); // e.g. '[10]) in '(var[10])'
3157 size_t j = sargs.find(')');
3158 if (j!=std::string::npos) args=sargs.substr(0,j); // extract, e.g '[10]' from '[10])'
3159 }
3160 }
3161 else
3162 {
3163 int i=isFuncPtr;
3164 if (i==-1 && (root->spec.isAlias())==0) i=findFunctionPtr(type.str(),root->lang); // for typedefs isFuncPtr is not yet set
3165 AUTO_TRACE_ADD("functionPtr={}",i!=-1?"yes":"no");
3166 if (i>=0) // function pointer
3167 {
3168 int ai = type.find('[',i);
3169 if (ai>i) // function pointer array
3170 {
3171 args.prepend(type.right(type.length()-ai));
3172 type=type.left(ai);
3173 }
3174 else if (type.find(')',i)!=-1) // function ptr, not variable like "int (*bla)[10]"
3175 {
3176 type=type.left(type.length()-1);
3177 args.prepend(") ");
3178 }
3179 }
3180 }
3181 AUTO_TRACE_ADD("after correction: type='{}' name='{}' args='{}'",type,name,args);
3182
3183 QCString scope;
3184 name=removeRedundantWhiteSpace(name);
3185
3186 // find the scope of this variable
3187 int index = computeQualifiedIndex(name);
3188 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
3189 // grouped members are stored with full scope
3190 {
3191 buildScopeFromQualifiedName(name.left(index+2),root->lang,root->tagInfo());
3192 scope=name.left(index);
3193 name=name.mid(index+2);
3194 }
3195 else
3196 {
3197 Entry *p = root->parent();
3198 while (p->section.isScope())
3199 {
3200 QCString scopeName = p->name;
3201 if (!scopeName.isEmpty())
3202 {
3203 scope.prepend(scopeName);
3204 break;
3205 }
3206 p=p->parent();
3207 }
3208 }
3209
3210 type=type.stripWhiteSpace();
3211 ClassDefMutable *cd=nullptr;
3212 bool isRelated=FALSE;
3213 bool isMemberOf=FALSE;
3214
3215 QCString classScope=stripAnonymousNamespaceScope(scope);
3216 if (root->lang==SrcLangExt::CSharp)
3217 {
3218 classScope=mangleCSharpGenericName(classScope);
3219 }
3220 else
3221 {
3222 classScope=stripTemplateSpecifiersFromScope(classScope,FALSE);
3223 }
3224 QCString annScopePrefix=scope.left(scope.length()-classScope.length());
3225
3226
3227 // Look for last :: not part of template specifier
3228 int p=-1;
3229 for (size_t i=0;i<name.length()-1;i++)
3230 {
3231 if (name[i]==':' && name[i+1]==':')
3232 {
3233 p=static_cast<int>(i);
3234 }
3235 else if (name[i]=='<') // skip over template parts,
3236 // i.e. A::B<C::D> => p=1 and
3237 // A<B::C>::D => p=8
3238 {
3239 int e = findEndOfTemplate(name,i+1);
3240 if (e!=-1) i=static_cast<int>(e);
3241 }
3242 }
3243
3244 if (p!=-1) // found it
3245 {
3246 if (type=="friend class" || type=="friend struct" ||
3247 type=="friend union")
3248 {
3249 cd=getClassMutable(scope);
3250 if (cd)
3251 {
3252 addVariableToClass(root, // entry
3253 cd, // class to add member to
3254 MemberType::Friend, // type of member
3255 type, // type value as string
3256 name, // name of the member
3257 args, // arguments as string
3258 FALSE, // from Anonymous scope
3259 nullptr, // anonymous member
3260 Protection::Public, // protection
3261 Relationship::Member // related to a class
3262 );
3263 }
3264 }
3265 if (root->bodyLine!=-1 && root->endBodyLine!=-1) // store the body location for later use
3266 {
3267 Doxygen::staticInitMap.emplace(name.str(),BodyInfo{root->startLine,root->bodyLine,root->endBodyLine});
3268 }
3269
3270
3271 AUTO_TRACE_ADD("static variable {} body=[{}..{}]",name,root->bodyLine,root->endBodyLine);
3272 return; /* skip this member, because it is a
3273 * static variable definition (always?), which will be
3274 * found in a class scope as well, but then we know the
3275 * correct protection level, so only then it will be
3276 * inserted in the correct list!
3277 */
3278 }
3279
3281 if (type=="@")
3283 else if (type.startsWith("typedef "))
3284 mtype=MemberType::Typedef;
3285 else if (type.startsWith("friend "))
3286 mtype=MemberType::Friend;
3287 else if (root->mtype==MethodTypes::Property)
3289 else if (root->mtype==MethodTypes::Event)
3290 mtype=MemberType::Event;
3291 else if (type.find("sequence<") != -1)
3292 mtype=sliceOpt ? MemberType::Sequence : MemberType::Typedef;
3293 else if (type.find("dictionary<") != -1)
3295
3296 if (!root->relates.isEmpty()) // related variable
3297 {
3298 isRelated=TRUE;
3299 isMemberOf=(root->relatesType==RelatesType::MemberOf);
3300 if (getClass(root->relates)==nullptr && !scope.isEmpty())
3301 scope=mergeScopes(scope,root->relates);
3302 else
3303 scope=root->relates;
3304 }
3305
3306 cd=getClassMutable(scope);
3307 if (cd==nullptr && classScope!=scope) cd=getClassMutable(classScope);
3308 if (cd)
3309 {
3310 MemberDef *md=nullptr;
3311
3312 // if cd is an anonymous (=tag less) scope we insert the member
3313 // into a non-anonymous parent scope as well. This is needed to
3314 // be able to refer to it using \var or \fn
3315
3316 //int indentDepth=0;
3317 int si=scope.find('@');
3318 //int anonyScopes = 0;
3319 //bool added=FALSE;
3320
3321 bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS);
3322 Relationship relationship = isMemberOf ? Relationship::Foreign :
3323 isRelated ? Relationship::Related :
3324 Relationship::Member ;
3325 if (si!=-1 && !inlineSimpleStructs) // anonymous scope or type
3326 {
3327 QCString pScope;
3328 ClassDefMutable *pcd=nullptr;
3329 pScope = scope.left(std::max(si-2,0)); // scope without tag less parts
3330 if (!pScope.isEmpty())
3331 pScope.prepend(annScopePrefix);
3332 else if (annScopePrefix.length()>2)
3333 pScope=annScopePrefix.left(annScopePrefix.length()-2);
3334 if (name.at(0)!='@')
3335 {
3336 if (!pScope.isEmpty() && (pcd=getClassMutable(pScope)))
3337 {
3338 AUTO_TRACE_ADD("Adding anonymous member to scope '{}'",pScope);
3339 md=addVariableToClass(root, // entry
3340 pcd, // class to add member to
3341 mtype, // member type
3342 type, // type value as string
3343 name, // member name
3344 args, // arguments as string
3345 TRUE, // from anonymous scope
3346 nullptr, // from anonymous member
3347 root->protection,
3348 relationship
3349 );
3350 //added=TRUE;
3351 }
3352 else // anonymous scope inside namespace or file => put variable in the global scope
3353 {
3354 if (mtype==MemberType::Variable)
3355 {
3356 AUTO_TRACE_ADD("Adding anonymous member to global scope '{}'");
3357 md=addVariableToFile(root,mtype,pScope,type,name,args,TRUE,nullptr);
3358 }
3359 //added=TRUE;
3360 }
3361 }
3362 }
3363
3364 addVariableToClass(root, // entry
3365 cd, // class to add member to
3366 mtype, // member type
3367 type, // type value as string
3368 name, // name of the member
3369 args, // arguments as string
3370 FALSE, // from anonymous scope
3371 md, // from anonymous member
3372 root->protection,
3373 relationship
3374 );
3375 }
3376 else if (!name.isEmpty()) // global variable
3377 {
3378 addVariableToFile(root,mtype,scope,type,name,args,FALSE,/*nullptr,*/nullptr);
3379 }
3380
3381}
static StaticInitMap staticInitMap
Definition doxygen.h:142
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:151
static int findEndOfTemplate(const QCString &s, size_t startPos)
Definition doxygen.cpp:3063
static int findFunctionPtr(const std::string &type, SrcLangExt lang, int *pLength=nullptr)
Definition doxygen.cpp:2859
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:2459
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:2619
bool search(std::string_view str, Match &match, const Ex &re, size_t pos)
Search in a given string str starting at position pos for a match against regular expression re.
Definition regex.cpp:844
Data associated with description found in the body.
Definition definition.h: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:6793

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

2470{
2472 QCString scopeSeparator="::";
2473 SrcLangExt lang = cd->getLanguage();
2474 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
2475 {
2476 qualScope = substitute(qualScope,"::",".");
2477 scopeSeparator=".";
2478 }
2479 AUTO_TRACE("class variable: file='{}' type='{}' scope='{}' name='{}' args='{}' prot={} mtype={} lang={} ann={} init='{}'",
2480 root->fileName, type, qualScope, name, args, root->protection, mtype, lang, fromAnnScope, root->initializer.str());
2481
2482 QCString def;
2483 if (!type.isEmpty())
2484 {
2485 if (related!=Relationship::Member || mtype==MemberType::Friend || Config_getBool(HIDE_SCOPE_NAMES))
2486 {
2487 if (root->spec.isAlias()) // turn 'typedef B A' into 'using A'
2488 {
2489 def="using "+name;
2490 }
2491 else
2492 {
2493 def=type+" "+name+args;
2494 }
2495 }
2496 else
2497 {
2498 if (root->spec.isAlias()) // turn 'typedef B C::A' into 'using C::A'
2499 {
2500 def="using "+qualScope+scopeSeparator+name;
2501 }
2502 else
2503 {
2504 def=type+" "+qualScope+scopeSeparator+name+args;
2505 }
2506 }
2507 }
2508 else
2509 {
2510 if (Config_getBool(HIDE_SCOPE_NAMES))
2511 {
2512 def=name+args;
2513 }
2514 else
2515 {
2516 def=qualScope+scopeSeparator+name+args;
2517 }
2518 }
2519 def.stripPrefix("static ");
2520
2521 // see if the member is already found in the same scope
2522 // (this may be the case for a static member that is initialized
2523 // outside the class)
2525 if (mn)
2526 {
2527 for (const auto &imd : *mn)
2528 {
2529 //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n",
2530 // md->getClassDef(),cd,qPrint(type),md->typeString());
2531 MemberDefMutable *md = toMemberDefMutable(imd.get());
2532 if (md &&
2533 md->getClassDef()==cd &&
2534 ((lang==SrcLangExt::Python && type.isEmpty() && !md->typeString().isEmpty()) ||
2536 // member already in the scope
2537 {
2538
2539 if (root->lang==SrcLangExt::ObjC &&
2540 root->mtype==MethodTypes::Property &&
2542 { // Objective-C 2.0 property
2543 // turn variable into a property
2544 md->setProtection(root->protection);
2546 }
2547 addMemberDocs(root,md,def,nullptr,FALSE,root->spec);
2548 AUTO_TRACE_ADD("Member already found!");
2549 return md;
2550 }
2551 }
2552 }
2553
2554 QCString fileName = root->fileName;
2555 if (fileName.isEmpty() && root->tagInfo())
2556 {
2557 fileName = root->tagInfo()->tagName;
2558 }
2559
2560 // new member variable, typedef or enum value
2561 auto md = createMemberDef(
2562 fileName,root->startLine,root->startColumn,
2563 type,name,args,root->exception,
2564 prot,Specifier::Normal,root->isStatic,related,
2565 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
2566 ArgumentList(), root->metaData);
2567 auto mmd = toMemberDefMutable(md.get());
2568 mmd->setTagInfo(root->tagInfo());
2569 mmd->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope())
2570 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
2571 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2572 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2573 mmd->setDefinition(def);
2574 mmd->setBitfields(root->bitfields);
2575 mmd->addSectionsToDefinition(root->anchors);
2576 mmd->setFromAnonymousScope(fromAnnScope);
2577 mmd->setFromAnonymousMember(fromAnnMemb);
2578 //md->setIndentDepth(indentDepth);
2579 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2580 mmd->setInitializer(root->initializer.str());
2581 mmd->setMaxInitLines(root->initLines);
2582 mmd->setMemberGroupId(root->mGrpId);
2583 mmd->setMemberSpecifiers(root->spec);
2584 mmd->setVhdlSpecifiers(root->vhdlSpec);
2585 mmd->setReadAccessor(root->read);
2586 mmd->setWriteAccessor(root->write);
2588 mmd->setHidden(root->hidden);
2589 mmd->setArtificial(root->artificial);
2590 mmd->setLanguage(root->lang);
2591 mmd->setId(root->id);
2592 addMemberToGroups(root,md.get());
2594 mmd->setBodyDef(root->fileDef());
2595 mmd->addQualifiers(root->qualifiers);
2596
2597 AUTO_TRACE_ADD("Adding new member to class '{}'",cd->name());
2598 cd->insertMember(md.get());
2599 mmd->setRefItems(root->sli);
2600
2601 cd->insertUsedFile(root->fileDef());
2602 root->markAsProcessed();
2603
2604 if (mtype==MemberType::Typedef)
2605 {
2606 resolveTemplateInstanceInType(root,cd,md.get());
2607 }
2608
2609 // add the member to the global list
2610 MemberDef *result = md.get();
2611 mn = Doxygen::memberNameLinkedMap->add(name);
2612 mn->push_back(std::move(md));
2613
2614 return result;
2615}
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:4801

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

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

11941{
11942 AUTO_TRACE();
11943 Doxygen::globalNamespaceDef = createNamespaceDef("<globalScope>",1,1,"<globalScope>");
11953
11954 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11955
11956 /* Set the global html file extension. */
11957 Doxygen::htmlFileExtension = Config_getString(HTML_FILE_EXTENSION);
11958
11959
11961 Config_getBool(CALLER_GRAPH) ||
11962 Config_getBool(REFERENCES_RELATION) ||
11963 Config_getBool(REFERENCED_BY_RELATION);
11964
11965 /**************************************************************************
11966 * Add custom extension mappings
11967 **************************************************************************/
11968
11969 const StringVector &extMaps = Config_getList(EXTENSION_MAPPING);
11970 for (const auto &mapping : extMaps)
11971 {
11972 QCString mapStr = mapping;
11973 int i=mapStr.find('=');
11974 if (i==-1)
11975 {
11976 continue;
11977 }
11978 else
11979 {
11980 QCString ext = mapStr.left(i).stripWhiteSpace().lower();
11981 QCString language = mapStr.mid(i+1).stripWhiteSpace().lower();
11982 if (ext.isEmpty() || language.isEmpty())
11983 {
11984 continue;
11985 }
11986
11987 if (!updateLanguageMapping(ext,language))
11988 {
11989 err("Failed to map file extension '{}' to unsupported language '{}'.\n"
11990 "Check the EXTENSION_MAPPING setting in the config file.\n",
11991 ext,language);
11992 }
11993 else
11994 {
11995 msg("Adding custom extension mapping: '{}' will be treated as language '{}'\n",
11996 ext,language);
11997 }
11998 }
11999 }
12000 // create input file exncodings
12001
12002 // check INPUT_ENCODING
12003 void *cd = portable_iconv_open("UTF-8",Config_getString(INPUT_ENCODING).data());
12004 if (cd==reinterpret_cast<void *>(-1))
12005 {
12006 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
12007 "Check the 'INPUT_ENCODING' setting in the config file!\n",
12008 Config_getString(INPUT_ENCODING),strerror(errno));
12009 }
12010 else
12011 {
12013 }
12014
12015 // check and split INPUT_FILE_ENCODING
12016 const StringVector &fileEncod = Config_getList(INPUT_FILE_ENCODING);
12017 for (const auto &mapping : fileEncod)
12018 {
12019 QCString mapStr = mapping;
12020 int i=mapStr.find('=');
12021 if (i==-1)
12022 {
12023 continue;
12024 }
12025 else
12026 {
12027 QCString pattern = mapStr.left(i).stripWhiteSpace().lower();
12028 QCString encoding = mapStr.mid(i+1).stripWhiteSpace().lower();
12029 if (pattern.isEmpty() || encoding.isEmpty())
12030 {
12031 continue;
12032 }
12033 cd = portable_iconv_open("UTF-8",encoding.data());
12034 if (cd==reinterpret_cast<void *>(-1))
12035 {
12036 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
12037 "Check the 'INPUT_FILE_ENCODING' setting in the config file!\n",
12038 encoding,strerror(errno));
12039 }
12040 else
12041 {
12043 }
12044
12045 Doxygen::inputFileEncodingList.emplace_back(pattern, encoding);
12046 }
12047 }
12048
12049 // add predefined macro name to a dictionary
12050 const StringVector &expandAsDefinedList =Config_getList(EXPAND_AS_DEFINED);
12051 for (const auto &s : expandAsDefinedList)
12052 {
12054 }
12055
12056 // read aliases and store them in a dictionary
12057 readAliases();
12058
12059 // store number of spaces in a tab into Doxygen::spaces
12060 int tabSize = Config_getInt(TAB_SIZE);
12061 Doxygen::spaces.resize(tabSize);
12062 for (int sp=0; sp<tabSize; sp++) Doxygen::spaces.at(sp)=' ';
12063 Doxygen::spaces.at(tabSize)='\0';
12064}
void readAliases()
Definition aliases.cpp:161
static FileNameLinkedMap * plantUmlFileNameLinkedMap
Definition doxygen.h:109
static StringUnorderedSet expandAsDefinedSet
Definition doxygen.h:118
static InputFileEncodingList inputFileEncodingList
Definition doxygen.h:139
static FileNameLinkedMap * dotFileNameLinkedMap
Definition doxygen.h:106
static FileNameLinkedMap * imageNameLinkedMap
Definition doxygen.h:105
static FileNameLinkedMap * mscFileNameLinkedMap
Definition doxygen.h:107
static QCString spaces
Definition doxygen.h:134
static FileNameLinkedMap * diaFileNameLinkedMap
Definition doxygen.h:108
static QCString htmlFileExtension
Definition doxygen.h:121
static std::unique_ptr< NamespaceDef > globalNamespaceDef
Definition doxygen.h:119
static FileNameLinkedMap * includeNameLinkedMap
Definition doxygen.h:101
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:102
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:5059

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

2132{
2133 root->commandOverrides.apply_callGraph ([&](bool b) { md->overrideCallGraph(b); });
2134 root->commandOverrides.apply_callerGraph ([&](bool b) { md->overrideCallerGraph(b); });
2135 root->commandOverrides.apply_referencedByRelation([&](bool b) { md->overrideReferencedByRelation(b); });
2136 root->commandOverrides.apply_referencesRelation ([&](bool b) { md->overrideReferencesRelation(b); });
2137 root->commandOverrides.apply_inlineSource ([&](bool b) { md->overrideInlineSource(b); });
2138 root->commandOverrides.apply_enumValues ([&](bool b) { md->overrideEnumValues(b); });
2139}
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 1138 of file doxygen.cpp.

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

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

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

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

8528{
8529 // merge the member list of base classes into the inherited classes.
8530 for (const auto &cd : *Doxygen::classLinkedMap)
8531 {
8532 if (// !cd->isReference() && // not an external class
8533 cd->subClasses().empty() && // is a root of the hierarchy
8534 !cd->baseClasses().empty()) // and has at least one base class
8535 {
8536 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8537 if (cdm)
8538 {
8539 //printf("*** merging members for %s\n",qPrint(cd->name()));
8540 cdm->mergeMembers();
8541 }
8542 }
8543 }
8544 // now sort the member list of all members for all classes.
8545 for (const auto &cd : *Doxygen::classLinkedMap)
8546 {
8547 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8548 if (cdm)
8549 {
8550 cdm->sortAllMembersList();
8551 }
8552 }
8553}
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 1320 of file doxygen.cpp.

1321{
1322 if (root->section.isConceptDoc())
1323 {
1324 AUTO_TRACE();
1325 addConceptToContext(root);
1326 }
1327 for (const auto &e : root->children()) buildConceptDocList(e.get());
1328}
static void addConceptToContext(const Entry *root)
Definition doxygen.cpp:1152
static void buildConceptDocList(const Entry *root)
Definition doxygen.cpp:1320

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

1311{
1312 if (root->section.isConcept())
1313 {
1314 AUTO_TRACE();
1315 addConceptToContext(root);
1316 }
1317 for (const auto &e : root->children()) buildConceptList(e.get());
1318}
static void buildConceptList(const Entry *root)
Definition doxygen.cpp:1310

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

Referenced by buildConceptList(), and parseInput().

◆ buildDefineList()

void buildDefineList ( )
static

Definition at line 8862 of file doxygen.cpp.

8863{
8864 AUTO_TRACE();
8865 for (const auto &s : g_inputFiles)
8866 {
8867 auto it = Doxygen::macroDefinitions.find(s);
8869 {
8870 for (const auto &def : it->second)
8871 {
8872 auto md = createMemberDef(
8873 def.fileName,def.lineNr,def.columnNr,
8874 "#define",def.name,def.args,QCString(),
8875 Protection::Public,Specifier::Normal,FALSE,Relationship::Member,MemberType::Define,
8876 ArgumentList(),ArgumentList(),"");
8877 auto mmd = toMemberDefMutable(md.get());
8878
8879 if (!def.args.isEmpty())
8880 {
8881 mmd->moveArgumentList(stringToArgumentList(SrcLangExt::Cpp, def.args));
8882 }
8883 mmd->setInitializer(def.definition);
8884 mmd->setFileDef(def.fileDef);
8885 mmd->setDefinition("#define "+def.name);
8886
8887 MemberName *mn=Doxygen::functionNameLinkedMap->add(def.name);
8888 if (def.fileDef)
8889 {
8890 const MemberList *defMl = def.fileDef->getMemberList(MemberListType::DocDefineMembers());
8891 if (defMl)
8892 {
8893 const MemberDef *defMd = defMl->findRev(def.name);
8894 if (defMd) // definition already stored
8895 {
8896 mmd->setRedefineCount(defMd->redefineCount()+1);
8897 }
8898 }
8899 def.fileDef->insertMember(md.get());
8900 }
8901 AUTO_TRACE_ADD("adding macro {} with definition {}",def.name,def.definition);
8902 mn->push_back(std::move(md));
8903 }
8904 }
8905 }
8906}
static DefinesPerFileList macroDefinitions
Definition doxygen.h:136
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 3503 of file doxygen.cpp.

3504{
3505 if (!root->name.isEmpty() &&
3506 root->section.isVariable() &&
3507 root->type.find("dictionary<")!=-1 // it's a dictionary
3508 )
3509 {
3510 AUTO_TRACE();
3511 addVariable(root);
3512 }
3513 for (const auto &e : root->children())
3514 if (!e->section.isEnum())
3515 buildDictionaryList(e.get());
3516}
static void buildDictionaryList(const Entry *root)
Definition doxygen.cpp:3503
static void addVariable(const Entry *root, int isFuncPtr=-1)
Definition doxygen.cpp:3131

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

9945{
9946 if ((root->section.isExample() || root->section.isExampleLineno()) && !root->name.isEmpty())
9947 {
9948 if (Doxygen::exampleLinkedMap->find(root->name))
9949 {
9950 warn(root->fileName,root->startLine,"Example {} was already documented. Ignoring documentation found here.",root->name);
9951 }
9952 else
9953 {
9954 PageDef *pd = Doxygen::exampleLinkedMap->add(root->name,
9955 createPageDef(root->fileName,root->startLine,
9956 root->name,root->brief+root->doc+root->inbodyDocs,root->args));
9957 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9958 pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE));
9960 pd->setLanguage(root->lang);
9961 pd->setShowLineNo(root->section.isExampleLineno());
9962
9963 //we don't add example to groups
9964 //addExampleToGroups(root,pd);
9965 }
9966 }
9967 for (const auto &e : root->children()) buildExampleList(e.get());
9968}
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:98
virtual void setFileName(const QCString &name)=0
virtual void setShowLineNo(bool)=0
static void buildExampleList(Entry *root)
Definition doxygen.cpp:9944
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:3458

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
constexpr bool isFile() const noexcept
Definition types.h:824
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
static constexpr const char * getGroupPriName(GroupPri_t priority) noexcept
Definition types.h:240
@ GROUPING_INGROUP
membership in group was defined by @ingroup
Definition types.h:236
GroupPri_t pri
priority of this definition
Definition types.h:258

References GroupDef::addFile(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, Entry::brief, Entry::briefFile, Entry::briefLine, buildFileList(), Entry::children(), Entry::commandOverrides, Config_getBool, GroupDef::containsFile(), Entry::doc, Entry::docFile, Entry::docLine, QCString::ExplicitSize, FALSE, Entry::fileName, findFileDef(), QCString::findRev(), Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, Doxygen::inputNameLinkedMap, QCString::isEmpty(), EntryType::isFile(), QCString::left(), DefinitionMutable::makePartOfGroup(), Entry::name, FileDef::overrideIncludedByGraph(), FileDef::overrideIncludeGraph(), Grouping::pri, qPrint(), Entry::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 3911 of file doxygen.cpp.

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

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:176

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

3617{
3618 if (root->section.isExportedInterface() || root->section.isIncludedService())
3619 {
3620 AUTO_TRACE("Exported interface/included service: type='{}' scope='{}' name='{}' args='{}'"
3621 " relates='{}' relatesType='{}' file='{}' line={} bodyLine={} #tArgLists={}"
3622 " mGrpId={} spec={} proto={} docFile='{}'",
3623 root->type, root->parent()->name, root->name, root->args,
3624 root->relates, root->relatesType, root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(),
3625 root->mGrpId, root->spec, root->proto, root->docFile);
3626
3628
3629 if (!rname.isEmpty())
3630 {
3631 QCString scope = root->parent()->name;
3632 ClassDefMutable *cd = getClassMutable(scope);
3633 assert(cd);
3634 if (cd && ((ClassDef::Interface == cd->compoundType()) ||
3635 (ClassDef::Service == cd->compoundType()) ||
3637 {
3639 }
3640 else
3641 {
3642 assert(false); // was checked by scanner.l
3643 }
3644 }
3645 else if (rname.isEmpty())
3646 {
3647 warn(root->fileName,root->startLine,
3648 "Illegal member name found.");
3649 }
3650 }
3651 // can only have these in IDL anyway
3652 switch (root->lang)
3653 {
3654 case SrcLangExt::Unknown: // fall through (root node always is Unknown)
3655 case SrcLangExt::IDL:
3656 for (const auto &e : root->children()) buildInterfaceAndServiceList(e.get());
3657 break;
3658 default:
3659 return; // nothing to do here
3660 }
3661}
@ 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:3554
static void buildInterfaceAndServiceList(const Entry *root)
Definition doxygen.cpp:3616

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

2027{
2028 if (root->section.isUsingDecl() &&
2029 !root->parent()->section.isCompound() // not a class/struct member
2030 )
2031 {
2032 QCString name = substitute(root->name,".","::");
2033 g_usingDeclarations.insert(name.str());
2034 }
2035 for (const auto &e : root->children()) buildListOfUsingDecls(e.get());
2036}
static StringSet g_usingDeclarations
Definition doxygen.cpp:189
static void buildListOfUsingDecls(const Entry *root)
Definition doxygen.cpp:2026

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

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

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

9701{
9702 if (root->section.isPageDoc())
9703 {
9704 if (!root->name.isEmpty())
9705 {
9706 addRelatedPage(root);
9707 }
9708 }
9709 else if (root->section.isMainpageDoc())
9710 {
9711 QCString title=root->args.stripWhiteSpace();
9712 if (title.isEmpty()) title=theTranslator->trMainPage();
9713 //QCString name = Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9714 QCString name = "index";
9715 addRefItem(root->sli,
9716 name,
9717 "page",
9718 name,
9719 title,
9720 QCString(),nullptr
9721 );
9722 }
9723 for (const auto &e : root->children()) buildPageList(e.get());
9724}
static void buildPageList(Entry *root)
Definition doxygen.cpp:9700

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:4593

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

3486{
3487 if (!root->name.isEmpty() &&
3488 root->section.isVariable() &&
3489 root->type.find("sequence<")!=-1 // it's a sequence
3490 )
3491 {
3492 AUTO_TRACE();
3493 addVariable(root);
3494 }
3495 for (const auto &e : root->children())
3496 if (!e->section.isEnum())
3497 buildSequenceList(e.get());
3498}
static void buildSequenceList(const Entry *root)
Definition doxygen.cpp:3485

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

3387{
3388 //printf("buildVarList(%s)\n",qPrint(rootNav->name()));
3389 if (!root->name.isEmpty() &&
3390 root->section.isVariable() &&
3391 root->type.find("typedef ")!=-1 // its a typedef
3392 )
3393 {
3394 AUTO_TRACE();
3396 QCString scope;
3397 int index = computeQualifiedIndex(rname);
3398 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
3399 // grouped members are stored with full scope
3400 {
3401 buildScopeFromQualifiedName(rname.left(index+2),root->lang,root->tagInfo());
3402 scope=rname.left(index);
3403 rname=rname.mid(index+2);
3404 }
3405 else
3406 {
3407 scope=root->parent()->name; //stripAnonymousNamespaceScope(root->parent->name);
3408 }
3411 MemberName *mn = Doxygen::functionNameLinkedMap->find(rname);
3412 bool found=false;
3413 if (mn) // symbol with the same name already found
3414 {
3415 for (auto &imd : *mn)
3416 {
3417 if (!imd->isTypedef())
3418 continue;
3419
3420 QCString rtype = root->type;
3421 rtype.stripPrefix("typedef ");
3422
3423 // merge the typedefs only if they're not both grouped, and both are
3424 // either part of the same class, part of the same namespace, or both
3425 // are global (i.e., neither in a class or a namespace)
3426 bool notBothGrouped = root->groups.empty() || imd->getGroupDef()==nullptr; // see example #100
3427 bool bothSameScope = (!cd && !nd) || (cd && imd->getClassDef() == cd) || (nd && imd->getNamespaceDef() == nd);
3428 //printf("imd->isTypedef()=%d imd->typeString()=%s root->type=%s\n",imd->isTypedef(),
3429 // qPrint(imd->typeString()),qPrint(root->type));
3430 if (notBothGrouped && bothSameScope && imd->typeString()==rtype)
3431 {
3432 MemberDefMutable *md = toMemberDefMutable(imd.get());
3433 if (md)
3434 {
3435 md->setDocumentation(root->doc,root->docFile,root->docLine);
3437 md->setDocsForDefinition(!root->proto);
3438 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3440 md->setRefItems(root->sli);
3441 md->addQualifiers(root->qualifiers);
3442
3443 // merge ingroup specifiers
3444 if (md->getGroupDef()==nullptr && !root->groups.empty())
3445 {
3446 addMemberToGroups(root,md);
3447 }
3448 else if (md->getGroupDef()!=nullptr && root->groups.empty())
3449 {
3450 //printf("existing member is grouped, new member not\n");
3451 }
3452 else if (md->getGroupDef()!=nullptr && !root->groups.empty())
3453 {
3454 //printf("both members are grouped\n");
3455 }
3456 found=true;
3457 break;
3458 }
3459 }
3460 }
3461 }
3462 if (found)
3463 {
3464 AUTO_TRACE_ADD("typedef '{}' already found",rname);
3465 // mark the entry as processed, as we copied everything from it elsewhere
3466 // also, otherwise, due to containing `typedef` it may later get treated
3467 // as a function typedef in filterMemberDocumentation, which is incorrect
3468 root->markAsProcessed();
3469 }
3470 else
3471 {
3472 AUTO_TRACE_ADD("new typedef '{}'",rname);
3473 addVariable(root);
3474 }
3475
3476 }
3477 for (const auto &e : root->children())
3478 if (!e->section.isEnum())
3479 buildTypedefList(e.get());
3480}
static void buildTypedefList(const Entry *root)
Definition doxygen.cpp:3386

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

3523{
3524 //printf("buildVarList(%s) section=%08x\n",qPrint(rootNav->name()),rootNav->section());
3525 int isFuncPtr=-1;
3526 if (!root->name.isEmpty() &&
3527 (root->type.isEmpty() || g_compoundKeywords.find(root->type.str())==g_compoundKeywords.end()) &&
3528 (
3529 (root->section.isVariable() && // it's a variable
3530 root->type.find("typedef ")==-1 // and not a typedef
3531 ) ||
3532 (root->section.isFunction() && // or maybe a function pointer variable
3533 (isFuncPtr=findFunctionPtr(root->type.str(),root->lang))!=-1
3534 ) ||
3535 (root->section.isFunction() && // class variable initialized by constructor
3537 )
3538 )
3539 ) // documented variable
3540 {
3541 AUTO_TRACE();
3542 addVariable(root,isFuncPtr);
3543 }
3544 for (const auto &e : root->children())
3545 if (!e->section.isEnum())
3546 buildVarList(e.get());
3547}
static void buildVarList(const Entry *root)
Definition doxygen.cpp:3522
static bool isVarWithConstructor(const Entry *root)
Definition doxygen.cpp:2919
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 11929 of file doxygen.cpp.

11930{
11931 AUTO_TRACE();
11932
11937}
void initWarningFormat()
Definition message.cpp:236
void postProcess(bool clearHeaderAndFooter, CompareMode compareMode=CompareMode::Full)
void checkAndCorrect(bool quiet, const bool check)
void updateObsolete()

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

Referenced by main().

◆ checkMarkdownMainfile()

void checkMarkdownMainfile ( )
static

Definition at line 12409 of file doxygen.cpp.

12410{
12411 if (Config_getBool(MARKDOWN_SUPPORT))
12412 {
12413 QCString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
12414 if (mdfileAsMainPage.isEmpty()) return;
12415 FileInfo fi(mdfileAsMainPage.data());
12416 if (!fi.exists())
12417 {
12418 warn_uncond("Specified markdown mainpage '{}' does not exist\n",mdfileAsMainPage);
12419 return;
12420 }
12421 bool ambig = false;
12422 if (findFileDef(Doxygen::inputNameLinkedMap,fi.absFilePath(),ambig)==nullptr)
12423 {
12424 warn_uncond("Specified markdown mainpage '{}' has not been defined as input file\n",mdfileAsMainPage);
12425 return;
12426 }
12427 }
12428}
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 9839 of file doxygen.cpp.

9840{
9841 for (const auto &pd : *Doxygen::pageLinkedMap)
9842 {
9843 Definition *ppd = pd->getOuterScope();
9844 while (ppd)
9845 {
9846 if (ppd==pd.get())
9847 {
9848 term("page defined {} with label {} is a subpage "
9849 "of itself! Please remove this cyclic dependency.\n",
9850 warn_line(pd->docFile(),pd->docLine()),pd->name());
9851 }
9852 ppd=ppd->getOuterScope();
9853 }
9854 }
9855}

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

Referenced by parseInput().

◆ cleanUpDoxygen()

void cleanUpDoxygen ( )

Definition at line 11451 of file doxygen.cpp.

11452{
11456
11457 delete Doxygen::indexList;
11466 Doxygen::mainPage.reset();
11470 Doxygen::globalScope = nullptr;
11472 delete theTranslator;
11473 delete g_outputList;
11474
11479 delete Doxygen::dirLinkedMap;
11480 delete Doxygen::symbolMap;
11481}
static ParserManager * parserManager
Definition doxygen.h:130
static SymbolMap< Definition > * symbolMap
Definition doxygen.h:124
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:85
void clear()
clears the database
Definition cite.cpp:110
static StringMap tagDestinationMap
Definition doxygen.h:115
static ClassLinkedMap * hiddenClassLinkedMap
Definition doxygen.h:96

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

◆ combineUsingRelations()

void combineUsingRelations ( )
static

Definition at line 9240 of file doxygen.cpp.

9241{
9242 // for each file
9243 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9244 {
9245 for (const auto &fd : *fn)
9246 {
9247 fd->combineUsingRelations();
9248 }
9249 }
9250
9251 // for each namespace
9252 NamespaceDefSet visitedNamespaces;
9253 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9254 {
9256 if (ndm)
9257 {
9258 ndm->combineUsingRelations(visitedNamespaces);
9259 }
9260 }
9261}
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 10338 of file doxygen.cpp.

10339{
10340 std::ofstream f;
10341 bool fileOpened=openOutputFile("-",f);
10342 if (fileOpened)
10343 {
10344 TextStream t(&f);
10345 Config::compareDoxyfile(t,diffList);
10346 }
10347 else
10348 {
10349 term("Cannot open stdout for writing\n");
10350 }
10351}
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:6265

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

Referenced by readConfiguration().

◆ computeClassRelations()

void computeClassRelations ( )
static

Definition at line 5342 of file doxygen.cpp.

5343{
5344 AUTO_TRACE();
5345 for (const auto &[name,root] : g_classEntries)
5346 {
5347 QCString bName = extractClassName(root);
5348 ClassDefMutable *cd = getClassMutable(bName);
5349 if (cd)
5350 {
5352 }
5353 size_t numMembers = cd ? cd->memberNameInfoLinkedMap().size() : 0;
5354 if ((cd==nullptr || (!cd->hasDocumentation() && !cd->isReference())) && numMembers>0 && !bName.endsWith("::"))
5355 {
5356 if (!root->name.isEmpty() && root->name.find('@')==-1 && // normal name
5357 (guessSection(root->fileName).isHeader() ||
5358 Config_getBool(EXTRACT_LOCAL_CLASSES)) && // not defined in source file
5359 protectionLevelVisible(root->protection) && // hidden by protection
5360 !Config_getBool(HIDE_UNDOC_CLASSES) // undocumented class are visible
5361 )
5362 warn_undoc(root->fileName,root->startLine, "Compound {} is not documented.", root->name);
5363 }
5364 }
5365}
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:5245
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:4699
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 11483 of file doxygen.cpp.

11484{
11485 //printf("computeIdealCacheParam(v=%u)\n",v);
11486
11487 int r=0;
11488 while (v!=0)
11489 {
11490 v >>= 1;
11491 r++;
11492 }
11493 // r = log2(v)
11494
11495 // convert to a valid cache size value
11496 return std::max(0,std::min(r-16,9));
11497}

Referenced by generateOutput().

◆ computeMemberReferences()

void computeMemberReferences ( )
static

Definition at line 5436 of file doxygen.cpp.

5437{
5438 AUTO_TRACE();
5439 for (const auto &cd : *Doxygen::classLinkedMap)
5440 {
5441 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5442 if (cdm)
5443 {
5444 cdm->computeAnchors();
5445 }
5446 }
5447 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5448 {
5449 for (const auto &fd : *fn)
5450 {
5451 fd->computeAnchors();
5452 }
5453 }
5454 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5455 {
5457 if (ndm)
5458 {
5459 ndm->computeAnchors();
5460 }
5461 }
5462 for (const auto &gd : *Doxygen::groupLinkedMap)
5463 {
5464 gd->computeAnchors();
5465 }
5466}
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 8470 of file doxygen.cpp.

8471{
8472 for (const auto &cd : *Doxygen::classLinkedMap)
8473 {
8474 if (cd->isLinkable())
8475 {
8476 for (const auto &bcd : cd->baseClasses())
8477 {
8479 }
8480 }
8481 }
8482}
static void computeMemberRelationsForBaseClass(const ClassDef *cd, const BaseClassDef *bcd)
Definition doxygen.cpp:8390

References Doxygen::classLinkedMap, and computeMemberRelationsForBaseClass().

Referenced by parseInput().

◆ computeMemberRelationsForBaseClass()

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

Definition at line 8390 of file doxygen.cpp.

8391{
8392 for (const auto &mn : cd->memberNameInfoLinkedMap()) // for each member in class cd with a unique name
8393 {
8394 for (const auto &imd : *mn) // for each member with a given name
8395 {
8396 MemberDefMutable *md = toMemberDefMutable(imd->memberDef());
8397 if (md && (md->isFunction() || md->isCSharpProperty())) // filter on reimplementable members
8398 {
8399 ClassDef *mbcd = bcd->classDef;
8400 if (mbcd && mbcd->isLinkable()) // filter on linkable classes
8401 {
8402 const auto &bmn = mbcd->memberNameInfoLinkedMap();
8403 const auto &bmni = bmn.find(mn->memberName());
8404 if (bmni) // there are base class members with the same name
8405 {
8406 for (const auto &ibmd : *bmni) // for base class member with that name
8407 {
8408 MemberDefMutable *bmd = toMemberDefMutable(ibmd->memberDef());
8409 if (bmd) // not part of an inline namespace
8410 {
8411 auto lang = bmd->getLanguage();
8412 auto compType = mbcd->compoundType();
8413 if (bmd->virtualness()!=Specifier::Normal ||
8414 lang==SrcLangExt::Python ||
8415 lang==SrcLangExt::Java ||
8416 lang==SrcLangExt::PHP ||
8417 compType==ClassDef::Interface ||
8418 compType==ClassDef::Protocol)
8419 {
8420 const ArgumentList &bmdAl = bmd->argumentList();
8421 const ArgumentList &mdAl = md->argumentList();
8422 //printf(" Base argList='%s'\n Super argList='%s'\n",
8423 // qPrint(argListToString(bmdAl)),
8424 // qPrint(argListToString(mdAl))
8425 // );
8426 if (
8427 lang==SrcLangExt::Python ||
8428 matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),bmd->typeString(),&bmdAl,
8429 md->getOuterScope(), md->getFileDef(), md->typeString(),&mdAl,
8430 TRUE,lang
8431 )
8432 )
8433 {
8434 if (lang==SrcLangExt::Python && md->name().startsWith("__")) continue; // private members do not reimplement
8435 //printf("match!\n");
8436 const MemberDef *rmd = md->reimplements();
8437 if (rmd==nullptr) // not already assigned
8438 {
8439 //printf("%s: setting (new) reimplements member %s\n",qPrint(md->qualifiedName()),qPrint(bmd->qualifiedName()));
8440 md->setReimplements(bmd);
8441 }
8442 //printf("%s: add reimplementedBy member %s\n",qPrint(bmd->qualifiedName()),qPrint(md->qualifiedName()));
8443 bmd->insertReimplementedBy(md);
8444 }
8445 else
8446 {
8447 //printf("no match!\n");
8448 }
8449 }
8450 }
8451 }
8452 }
8453 }
8454 }
8455 }
8456 }
8457
8458 // do also for indirect base classes
8459 for (const auto &bbcd : bcd->classDef->baseClasses())
8460 {
8462 }
8463}
virtual const BaseClassList & baseClasses() const =0
Returns the list of base classes from which this class directly inherits.
virtual bool isCSharpProperty() const =0
virtual bool isFunction() const =0
virtual const MemberDef * reimplements() const =0
virtual void setReimplements(MemberDef *md)=0
virtual void insertReimplementedBy(MemberDef *md)=0
ClassDef * classDef
Class definition that this relation inherits from.
Definition classdef.h:60

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

Referenced by computeMemberRelations(), and computeMemberRelationsForBaseClass().

◆ computePageRelations()

void computePageRelations ( Entry * root)
static

Definition at line 9809 of file doxygen.cpp.

9810{
9811 if ((root->section.isPageDoc() || root->section.isMainpageDoc()) && !root->name.isEmpty())
9812 {
9813 PageDef *pd = root->section.isPageDoc() ?
9814 Doxygen::pageLinkedMap->find(root->name) :
9815 Doxygen::mainPage.get();
9816 if (pd)
9817 {
9818 for (const BaseInfo &bi : root->extends)
9819 {
9820 PageDef *subPd = Doxygen::pageLinkedMap->find(bi.name);
9821 if (pd==subPd)
9822 {
9823 term("page defined {} with label {} is a direct "
9824 "subpage of itself! Please remove this cyclic dependency.\n",
9825 warn_line(pd->docFile(),pd->docLine()),pd->name());
9826 }
9827 else if (subPd)
9828 {
9829 pd->addInnerCompound(subPd);
9830 //printf("*** Added subpage relation: %s->%s\n",
9831 // qPrint(pd->name()),qPrint(subPd->name()));
9832 }
9833 }
9834 }
9835 }
9836 for (const auto &e : root->children()) computePageRelations(e.get());
9837}
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:9809
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 5367 of file doxygen.cpp.

5368{
5369 AUTO_TRACE();
5370 for (const auto &[name,root] : g_classEntries)
5371 {
5372 QCString bName=stripAnonymousNamespaceScope(root->name);
5375 // strip any anonymous scopes first
5376 if (cd && !cd->getTemplateInstances().empty())
5377 {
5378 AUTO_TRACE_ADD("Template class '{}'",cd->name());
5379 for (const auto &ti : cd->getTemplateInstances()) // for each template instance
5380 {
5381 ClassDefMutable *tcd=toClassDefMutable(ti.classDef);
5382 if (tcd)
5383 {
5384 AUTO_TRACE_ADD("Template instance '{}'",tcd->name());
5385 QCString templSpec = ti.templSpec;
5386 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(tcd->getLanguage(),templSpec);
5387 for (const BaseInfo &bi : root->extends)
5388 {
5389 // check if the base class is a template argument
5390 BaseInfo tbi = bi;
5391 const ArgumentList &tl = cd->templateArguments();
5392 if (!tl.empty())
5393 {
5394 TemplateNameMap baseClassNames = tcd->getTemplateBaseClassNames();
5395 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,bi.name.str());
5396 // for each template name that we inherit from we need to
5397 // substitute the formal with the actual arguments
5398 TemplateNameMap actualTemplateNames;
5399 for (const auto &tn_kv : templateNames)
5400 {
5401 size_t templIndex = tn_kv.second;
5402 Argument actArg;
5403 bool hasActArg=FALSE;
5404 if (templIndex<templArgs->size())
5405 {
5406 actArg=templArgs->at(templIndex);
5407 hasActArg=TRUE;
5408 }
5409 if (hasActArg &&
5410 baseClassNames.find(actArg.type.str())!=baseClassNames.end() &&
5411 actualTemplateNames.find(actArg.type.str())==actualTemplateNames.end()
5412 )
5413 {
5414 actualTemplateNames.emplace(actArg.type.str(),static_cast<int>(templIndex));
5415 }
5416 }
5417
5418 tbi.name = substituteTemplateArgumentsInString(bi.name,tl,templArgs.get());
5419 // find a documented base class in the correct scope
5420 if (!findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE))
5421 {
5422 // no documented base class -> try to find an undocumented one
5423 findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,Undocumented,TRUE);
5424 }
5425 }
5426 }
5427 }
5428 }
5429 }
5430 }
5431}
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:4480
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:4319

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

8960{
8961 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8962 if (numThreads>1)
8963 {
8964 ThreadPool threadPool(numThreads);
8965 std::vector < std::future< void > > results;
8966 // queue the work
8967 for (const auto &[name,symList] : *Doxygen::symbolMap)
8968 {
8969 for (const auto &def : symList)
8970 {
8972 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
8973 {
8974 auto processTooltip = [dm]() {
8975 dm->computeTooltip();
8976 };
8977 results.emplace_back(threadPool.queue(processTooltip));
8978 }
8979 }
8980 }
8981 // wait for the results
8982 for (auto &f : results)
8983 {
8984 f.get();
8985 }
8986 }
8987 else
8988 {
8989 for (const auto &[name,symList] : *Doxygen::symbolMap)
8990 {
8991 for (const auto &def : symList)
8992 {
8994 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
8995 {
8996 dm->computeTooltip();
8997 }
8998 }
8999 }
9000 }
9001}
virtual void computeTooltip()=0
Class managing a pool of worker threads.
Definition threadpool.h:48
static bool isSymbolHidden(const Definition *d)
Definition doxygen.cpp:8952

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

Referenced by parseInput().

◆ computeVerifiedDotPath()

void computeVerifiedDotPath ( )
static

Definition at line 10266 of file doxygen.cpp.

10267{
10268 // check dot path
10269 QCString dotPath = Config_getString(DOT_PATH);
10270 if (!dotPath.isEmpty())
10271 {
10272 FileInfo fi(dotPath.str());
10273 if (!(fi.exists() && fi.isFile()) )// not an existing user specified path + exec
10274 {
10275 dotPath = dotPath+"/dot"+Portable::commandExtension();
10276 FileInfo dp(dotPath.str());
10277 if (!dp.exists() || !dp.isFile())
10278 {
10279 warn_uncond("the dot tool could not be found as '{}'\n",dotPath);
10280 dotPath = "dot";
10281 dotPath += Portable::commandExtension();
10282 }
10283 }
10284#if defined(_WIN32) // convert slashes
10285 size_t l=dotPath.length();
10286 for (size_t i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\';
10287#endif
10288 }
10289 else
10290 {
10291 dotPath = "dot";
10292 dotPath += Portable::commandExtension();
10293 }
10294 Doxygen::verifiedDotPath = dotPath;
10296}
static QCString verifiedDotPath
Definition doxygen.h:138
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 10532 of file doxygen.cpp.

10533{
10534 for (const auto &fileName : files)
10535 {
10536 if (!fileName.empty())
10537 {
10538 FileInfo fi(fileName);
10539 if (!fi.exists())
10540 {
10541 err("Extra file '{}' specified in {} does not exist!\n", fileName,filesOption);
10542 }
10543 else if (fi.isDir())
10544 {
10545 err("Extra file '{}' specified in {} is a directory, it has to be a file!\n", fileName,filesOption);
10546 }
10547 else
10548 {
10549 QCString destFileName = outputOption+"/"+fi.fileName();
10550 Doxygen::indexList->addImageFile(fi.fileName());
10551 copyFile(fileName, destFileName);
10552 }
10553 }
10554 }
10555}
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:5826

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

10508{
10509 QCString projectIcon = Config_getString(PROJECT_ICON);
10510 if (!projectIcon.isEmpty())
10511 {
10512 FileInfo fi(projectIcon.str());
10513 if (!fi.exists())
10514 {
10515 err("Project icon '{}' specified by PROJECT_ICON does not exist!\n",projectIcon);
10516 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10517 }
10518 else if (fi.isDir())
10519 {
10520 err("Project icon '{}' specified by PROJECT_ICON is a directory, it has to be a file!\n",projectIcon);
10521 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10522 }
10523 else
10524 {
10525 QCString destFileName = outputOption+"/"+fi.fileName();
10526 copyFile(projectIcon,destFileName);
10527 Doxygen::indexList->addImageFile(fi.fileName());
10528 }
10529 }
10530}
#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 10398 of file doxygen.cpp.

10399{
10400 const StringVector &latexExtraStyleSheet = Config_getList(LATEX_EXTRA_STYLESHEET);
10401 for (const auto &sheet : latexExtraStyleSheet)
10402 {
10403 std::string fileName = sheet;
10404 if (!fileName.empty())
10405 {
10406 FileInfo fi(fileName);
10407 if (!fi.exists())
10408 {
10409 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET does not exist!\n",fileName);
10410 }
10411 else if (fi.isDir())
10412 {
10413 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET is a directory, it has to be a file!\n", fileName);
10414 }
10415 else
10416 {
10417 QCString destFileName = Config_getString(LATEX_OUTPUT)+"/"+fi.fileName();
10418 if (!checkExtension(fi.fileName(), LATEX_STYLE_EXTENSION))
10419 {
10420 destFileName += LATEX_STYLE_EXTENSION;
10421 }
10422 copyFile(fileName, destFileName);
10423 }
10424 }
10425 }
10426}
#define LATEX_STYLE_EXTENSION
Definition latexgen.h:22
bool checkExtension(const QCString &fName, const QCString &ext)
Definition util.cpp:4870

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

10483{
10484 QCString projectLogo = projectLogoFile();
10485 if (!projectLogo.isEmpty())
10486 {
10487 FileInfo fi(projectLogo.str());
10488 if (!fi.exists())
10489 {
10490 err("Project logo '{}' specified by PROJECT_LOGO does not exist!\n",projectLogo);
10491 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10492 }
10493 else if (fi.isDir())
10494 {
10495 err("Project logo '{}' specified by PROJECT_LOGO is a directory, it has to be a file!\n",projectLogo);
10496 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10497 }
10498 else
10499 {
10500 QCString destFileName = outputOption+"/"+fi.fileName();
10501 copyFile(projectLogo,destFileName);
10502 Doxygen::indexList->addImageFile(fi.fileName());
10503 }
10504 }
10505}
QCString projectLogoFile()
Definition util.cpp:3094

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

10430{
10431 QCString htmlStyleSheet = Config_getString(HTML_STYLESHEET);
10432 if (!htmlStyleSheet.isEmpty())
10433 {
10434 if (!htmlStyleSheet.startsWith("http:") && !htmlStyleSheet.startsWith("https:"))
10435 {
10436 FileInfo fi(htmlStyleSheet.str());
10437 if (!fi.exists())
10438 {
10439 err("Style sheet '{}' specified by HTML_STYLESHEET does not exist!\n",htmlStyleSheet);
10440 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10441 }
10442 else if (fi.isDir())
10443 {
10444 err("Style sheet '{}' specified by HTML_STYLESHEET is a directory, it has to be a file!\n",htmlStyleSheet);
10445 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10446 }
10447 else
10448 {
10449 QCString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10450 copyFile(htmlStyleSheet,destFileName);
10451 }
10452 }
10453 }
10454 const StringVector &htmlExtraStyleSheet = Config_getList(HTML_EXTRA_STYLESHEET);
10455 for (const auto &sheet : htmlExtraStyleSheet)
10456 {
10457 QCString fileName(sheet);
10458 if (!fileName.isEmpty() && !fileName.startsWith("http:") && !fileName.startsWith("https:"))
10459 {
10460 FileInfo fi(fileName.str());
10461 if (!fi.exists())
10462 {
10463 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET does not exist!\n",fileName);
10464 }
10465 else if (fi.fileName()=="doxygen.css" || fi.fileName()=="tabs.css" || fi.fileName()=="navtree.css")
10466 {
10467 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is already a built-in stylesheet. Please use a different name\n",fi.fileName());
10468 }
10469 else if (fi.isDir())
10470 {
10471 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is a directory, it has to be a file!\n",fileName);
10472 }
10473 else
10474 {
10475 QCString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10476 copyFile(fileName, destFileName);
10477 }
10478 }
10479 }
10480}

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

9020{
9021 for (const auto &cd : *Doxygen::classLinkedMap)
9022 {
9023 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9024 if (cdm)
9025 {
9026 cdm->countMembers();
9027 }
9028 }
9029
9030 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9031 {
9033 if (ndm)
9034 {
9035 ndm->countMembers();
9036 }
9037 }
9038
9039 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9040 {
9041 for (const auto &fd : *fn)
9042 {
9043 fd->countMembers();
9044 }
9045 }
9046
9047 for (const auto &gd : *Doxygen::groupLinkedMap)
9048 {
9049 gd->countMembers();
9050 }
9051
9052 auto &mm = ModuleManager::instance();
9053 mm.countMembers();
9054}
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 12177 of file doxygen.cpp.

12180{
12181 QCString result = formatDirName;
12182 if (result.isEmpty())
12183 {
12184 result = baseDirName + defaultDirName;
12185 }
12186 else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':'))
12187 {
12188 result.prepend(baseDirName+"/");
12189 }
12190 Dir formatDir(result.str());
12191 if (!formatDir.exists() && !formatDir.mkdir(result.str()))
12192 {
12193 term("Could not create output directory {}\n", result);
12194 }
12195 return result;
12196}
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 1513 of file doxygen.cpp.

1514{
1515 QCString fullName = removeAnonymousScopes(templ->name());
1516 if (fullName.endsWith("::")) fullName=fullName.left(fullName.length()-2);
1517 fullName+="."+fieldName;
1518
1519 //printf("** adding class %s based on %s\n",qPrint(fullName),qPrint(templ->name()));
1521 Doxygen::classLinkedMap->add(fullName,
1523 templ->getDefLine(),
1524 templ->getDefColumn(),
1525 fullName,
1526 templ->compoundType())));
1527 if (cd)
1528 {
1529 cd->setDocumentation(templ->documentation(),templ->docFile(),templ->docLine()); // copy docs to definition
1530 cd->setBriefDescription(templ->briefDescription(),templ->briefFile(),templ->briefLine());
1531 cd->setLanguage(templ->getLanguage());
1532 cd->setBodySegment(templ->getDefLine(),templ->getStartBodyLine(),templ->getEndBodyLine());
1533 cd->setBodyDef(templ->getBodyDef());
1534
1535 cd->setOuterScope(rootCd->getOuterScope());
1536 if (rootCd->getOuterScope()!=Doxygen::globalScope)
1537 {
1538 DefinitionMutable *outerScope = toDefinitionMutable(rootCd->getOuterScope());
1539 if (outerScope)
1540 {
1541 outerScope->addInnerCompound(cd);
1542 }
1543 }
1544
1545 FileDef *fd = templ->getFileDef();
1546 if (fd)
1547 {
1548 cd->setFileDef(fd);
1549 fd->insertClass(cd);
1550 }
1551 for (auto &gd : rootCd->partOfGroups())
1552 {
1553 cd->makePartOfGroup(gd);
1554 gd->addClass(cd);
1555 }
1556
1557 MemberList *ml = templ->getMemberList(MemberListType::PubAttribs());
1558 if (ml)
1559 {
1560 for (const auto &md : *ml)
1561 {
1562 //printf(" Member %s type=%s\n",qPrint(md->name()),md->typeString());
1563 auto newMd = createMemberDef(md->getDefFileName(),md->getDefLine(),md->getDefColumn(),
1564 md->typeString(),md->name(),md->argsString(),md->excpString(),
1565 md->protection(),md->virtualness(),md->isStatic(),Relationship::Member,
1566 md->memberType(),
1567 ArgumentList(),ArgumentList(),"");
1568 MemberDefMutable *imd = toMemberDefMutable(newMd.get());
1569 imd->setMemberClass(cd);
1570 imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
1571 imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
1572 imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
1573 imd->setMemberSpecifiers(md->getMemberSpecifiers());
1574 imd->setVhdlSpecifiers(md->getVhdlSpecifiers());
1575 imd->setMemberGroupId(md->getMemberGroupId());
1576 imd->setInitializer(md->initializer());
1577 imd->setRequiresClause(md->requiresClause());
1578 imd->setMaxInitLines(md->initializerLines());
1579 imd->setBitfields(md->bitfieldString());
1580 imd->setLanguage(md->getLanguage());
1581 cd->insertMember(imd);
1582 MemberName *mn = Doxygen::memberNameLinkedMap->add(md->name());
1583 mn->push_back(std::move(newMd));
1584 }
1585 }
1586 }
1587 return cd;
1588}
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:162

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

8487{
8488 // for each class
8489 for (const auto &cd : *Doxygen::classLinkedMap)
8490 {
8491 // that is a template
8492 for (const auto &ti : cd->getTemplateInstances())
8493 {
8494 ClassDefMutable *tcdm = toClassDefMutable(ti.classDef);
8495 if (tcdm)
8496 {
8497 tcdm->addMembersToTemplateInstance(cd.get(),cd->templateArguments(),ti.templSpec);
8498 }
8499 }
8500 }
8501}
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 2143 of file doxygen.cpp.

2145{
2146 AUTO_TRACE("creating new member {} for class {}",memName,cd->name());
2147 const ArgumentList &templAl = md->templateArguments();
2148 const ArgumentList &al = md->argumentList();
2149 auto newMd = createMemberDef(
2150 fileName,root->startLine,root->startColumn,
2151 md->typeString(),memName,md->argsString(),
2152 md->excpString(),root->protection,root->virt,
2153 md->isStatic(),Relationship::Member,md->memberType(),
2154 templAl,al,root->metaData
2155 );
2156 auto newMmd = toMemberDefMutable(newMd.get());
2157 newMmd->setMemberClass(cd);
2158 cd->insertMember(newMd.get());
2159 if (!root->doc.isEmpty() || !root->brief.isEmpty())
2160 {
2161 newMmd->setDocumentation(root->doc,root->docFile,root->docLine);
2162 newMmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2163 newMmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2164 }
2165 else
2166 {
2167 newMmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
2168 newMmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
2169 newMmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
2170 }
2171 newMmd->setDefinition(md->definition());
2172 applyMemberOverrideOptions(root,newMmd);
2173 newMmd->addQualifiers(root->qualifiers);
2174 newMmd->setBitfields(md->bitfieldString());
2175 newMmd->addSectionsToDefinition(root->anchors);
2176 newMmd->setBodySegment(md->getDefLine(),md->getStartBodyLine(),md->getEndBodyLine());
2177 newMmd->setBodyDef(md->getBodyDef());
2178 newMmd->setInitializer(md->initializer());
2179 newMmd->setRequiresClause(md->requiresClause());
2180 newMmd->setMaxInitLines(md->initializerLines());
2181 newMmd->setMemberGroupId(root->mGrpId);
2182 newMmd->setMemberSpecifiers(md->getMemberSpecifiers());
2183 newMmd->setVhdlSpecifiers(md->getVhdlSpecifiers());
2184 newMmd->setLanguage(root->lang);
2185 newMmd->setId(root->id);
2186 MemberName *mn = Doxygen::memberNameLinkedMap->add(memName);
2187 mn->push_back(std::move(newMd));
2188}
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 11262 of file doxygen.cpp.

11263{
11265 msg("Developer parameters:\n");
11266 msg(" -m dump symbol map\n");
11267 msg(" -b making messages output unbuffered\n");
11268 msg(" -c <file> process input file as a comment block and produce HTML output\n");
11269#if ENABLE_TRACING
11270 msg(" -t [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout)\n");
11271 msg(" -t_time [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout),\n"
11272 " and include time and thread information\n");
11273#endif
11274 msg(" -d <level> enable a debug level, such as (multiple invocations of -d are possible):\n");
11276}
@ 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 1480 of file doxygen.cpp.

1481{
1482 //bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
1483 //if (!inlineGroupedClasses) return;
1484 //printf("** distributeClassGroupRelations()\n");
1485
1486 ClassDefSet visitedClasses;
1487 for (const auto &cd : *Doxygen::classLinkedMap)
1488 {
1489 //printf("Checking %s\n",qPrint(cd->name()));
1490 // distribute the group to nested classes as well
1491 if (visitedClasses.find(cd.get())==visitedClasses.end() && !cd->partOfGroups().empty())
1492 {
1493 //printf(" Candidate for merging\n");
1494 GroupDef *gd = cd->partOfGroups().front();
1495 for (auto &ncd : cd->getClasses())
1496 {
1498 if (ncdm && ncdm->partOfGroups().empty())
1499 {
1500 //printf(" Adding %s to group '%s'\n",qPrint(ncd->name()),
1501 // gd->groupTitle());
1502 ncdm->makePartOfGroup(gd);
1503 gd->addClass(ncdm);
1504 }
1505 }
1506 visitedClasses.insert(cd.get()); // only visit every class once
1507 }
1508 }
1509}
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 1332 of file doxygen.cpp.

1333{
1334 AUTO_TRACE();
1335 for (const auto &cd : *Doxygen::conceptLinkedMap)
1336 {
1337 if (cd->groupId()!=DOX_NOGROUP)
1338 {
1339 for (const auto &ocd : *Doxygen::conceptLinkedMap)
1340 {
1341 if (cd!=ocd && cd->groupId()==ocd->groupId() &&
1342 !cd->partOfGroups().empty() && ocd->partOfGroups().empty())
1343 {
1344 ConceptDefMutable *ocdm = toConceptDefMutable(ocd.get());
1345 if (ocdm)
1346 {
1347 for (const auto &gd : cd->partOfGroups())
1348 {
1349 if (gd)
1350 {
1351 AUTO_TRACE_ADD("making concept '{}' part of group '{}'",ocdm->name(),gd->name());
1352 ocdm->makePartOfGroup(gd);
1353 gd->addConcept(ocd.get());
1354 }
1355 }
1356 }
1357 }
1358 }
1359 }
1360 }
1361}
#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 9303 of file doxygen.cpp.

9304{
9305 // for each class
9306 for (const auto &cd : *Doxygen::classLinkedMap)
9307 {
9308 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9309 if (cdm)
9310 {
9312 }
9313 }
9314 // for each file
9315 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9316 {
9317 for (const auto &fd : *fn)
9318 {
9319 fd->distributeMemberGroupDocumentation();
9320 }
9321 }
9322 // for each namespace
9323 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9324 {
9326 if (ndm)
9327 {
9329 }
9330 }
9331 // for each group
9332 for (const auto &gd : *Doxygen::groupLinkedMap)
9333 {
9334 gd->distributeMemberGroupDocumentation();
9335 }
9337}
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 11221 of file doxygen.cpp.

11222{
11223 QCString anchor;
11225 {
11226 MemberDef *md = toMemberDef(d);
11227 anchor=":"+md->anchor();
11228 }
11229 QCString scope;
11230 QCString fn = d->getOutputFileBase();
11233 {
11234 scope = fn;
11235 }
11236 t << "REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
11237 << fn+anchor << "','"
11238 << scope << "','"
11239 << d->name() << "','"
11240 << d->getDefFileName() << "','"
11241 << d->getDefLine()
11242 << "');\n";
11243}
virtual QCString anchor() const =0
virtual QCString getOutputFileBase() const =0
MemberDef * toMemberDef(Definition *d)
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:4875

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

11246{
11247 std::ofstream f = Portable::openOutputStream("symbols.sql");
11248 if (f.is_open())
11249 {
11250 TextStream t(&f);
11251 for (const auto &[name,symList] : *Doxygen::symbolMap)
11252 {
11253 for (const auto &def : symList)
11254 {
11255 dumpSymbol(t,def);
11256 }
11257 }
11258 }
11259}
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 12164 of file doxygen.cpp.

12165{
12166 if (!g_successfulRun) // premature exit
12167 {
12168 Dir thisDir;
12169 msg("Exiting...\n");
12170 if (!Doxygen::filterDBFileName.isEmpty())
12171 {
12172 thisDir.remove(Doxygen::filterDBFileName.str());
12173 }
12174 }
12175}
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:314
static QCString filterDBFileName
Definition doxygen.h:132
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 5245 of file doxygen.cpp.

5246{
5247 // strip any anonymous scopes first
5250 int i=0;
5251 if ((root->lang==SrcLangExt::CSharp || root->lang==SrcLangExt::Java) &&
5252 (i=bName.find('<'))!=-1)
5253 {
5254 // a Java/C# generic class looks like a C++ specialization, so we need to strip the
5255 // template part before looking for matches
5256 if (root->lang==SrcLangExt::CSharp)
5257 {
5258 bName = mangleCSharpGenericName(root->name);
5259 }
5260 else
5261 {
5262 bName = bName.left(i);
5263 }
5264 }
5265 return bName;
5266}

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

7323{
7324 AUTO_TRACE("root->type='{}' root->inside='{}' root->name='{}' root->args='{}' section={} root->spec={} root->mGrpId={}",
7325 root->type,root->inside,root->name,root->args,root->section,root->spec,root->mGrpId);
7326 //printf("root->parent()->name=%s\n",qPrint(root->parent()->name));
7327 bool isFunc=TRUE;
7328
7329 QCString type = root->type;
7330 QCString args = root->args;
7331 int i=-1, l=0;
7332 if ( // detect func variable/typedef to func ptr
7333 (i=findFunctionPtr(type.str(),root->lang,&l))!=-1
7334 )
7335 {
7336 //printf("Fixing function pointer!\n");
7337 // fix type and argument
7338 args.prepend(type.right(type.length()-i-l));
7339 type=type.left(i+l);
7340 //printf("Results type=%s,name=%s,args=%s\n",qPrint(type),qPrint(root->name),qPrint(args));
7341 isFunc=FALSE;
7342 }
7343 else if ((type.startsWith("typedef ") && args.find('(')!=-1))
7344 // detect function types marked as functions
7345 {
7346 isFunc=FALSE;
7347 }
7348
7349 //printf("Member %s isFunc=%d\n",qPrint(root->name),isFunc);
7350 if (root->section.isMemberDoc())
7351 {
7352 //printf("Documentation for inline member '%s' found args='%s'\n",
7353 // qPrint(root->name),qPrint(args));
7354 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7355 if (type.isEmpty())
7356 {
7357 findMember(root,
7358 relates,
7359 type,
7360 args,
7361 root->name + args + root->exception,
7362 FALSE,
7363 isFunc);
7364 }
7365 else
7366 {
7367 findMember(root,
7368 relates,
7369 type,
7370 args,
7371 type + " " + root->name + args + root->exception,
7372 FALSE,
7373 isFunc);
7374 }
7375 }
7376 else if (root->section.isOverloadDoc())
7377 {
7378 //printf("Overloaded member %s found\n",qPrint(root->name));
7379 findMember(root,
7380 relates,
7381 type,
7382 args,
7383 root->name,
7384 TRUE,
7385 isFunc);
7386 }
7387 else if
7388 ((root->section.isFunction() // function
7389 ||
7390 (root->section.isVariable() && // variable
7391 !type.isEmpty() && // with a type
7392 g_compoundKeywords.find(type.str())==g_compoundKeywords.end() // that is not a keyword
7393 // (to skip forward declaration of class etc.)
7394 )
7395 )
7396 )
7397 {
7398 //printf("Documentation for member '%s' found args='%s' excp='%s'\n",
7399 // qPrint(root->name),qPrint(args),qPrint(root->exception));
7400 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7401 //printf("Inside=%s\n Relates=%s\n",qPrint(root->inside),qPrint(relates));
7402 if (type=="friend class" || type=="friend struct" ||
7403 type=="friend union")
7404 {
7405 findMember(root,
7406 relates,
7407 type,
7408 args,
7409 type+" "+root->name,
7410 FALSE,FALSE);
7411
7412 }
7413 else if (!type.isEmpty())
7414 {
7415 findMember(root,
7416 relates,
7417 type,
7418 args,
7419 type+" "+ root->inside + root->name + args + root->exception,
7420 FALSE,isFunc);
7421 }
7422 else
7423 {
7424 findMember(root,
7425 relates,
7426 type,
7427 args,
7428 root->inside + root->name + args + root->exception,
7429 FALSE,isFunc);
7430 }
7431 }
7432 else if (root->section.isDefine() && !relates.isEmpty())
7433 {
7434 findMember(root,
7435 relates,
7436 type,
7437 args,
7438 root->name + args,
7439 FALSE,
7440 !args.isEmpty());
7441 }
7442 else if (root->section.isVariableDoc())
7443 {
7444 //printf("Documentation for variable %s found\n",qPrint(root->name));
7445 //if (!relates.isEmpty()) printf(" Relates %s\n",qPrint(relates));
7446 findMember(root,
7447 relates,
7448 type,
7449 args,
7450 root->name,
7451 FALSE,
7452 FALSE);
7453 }
7454 else if (root->section.isExportedInterface() ||
7455 root->section.isIncludedService())
7456 {
7457 findMember(root,
7458 relates,
7459 type,
7460 args,
7461 type + " " + root->name,
7462 FALSE,
7463 FALSE);
7464 }
7465 else
7466 {
7467 // skip section
7468 //printf("skip section\n");
7469 }
7470}
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:6697

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

4709{
4710 AUTO_TRACE("name={}",root->name);
4711 // The base class could ofcouse also be a non-nested class
4712 const ArgumentList &formalArgs = masterCd->templateArguments();
4713 for (const BaseInfo &bi : root->extends)
4714 {
4715 //printf("masterCd=%s bi.name='%s' #actualArgs=%d\n",
4716 // qPrint(masterCd->localName()),qPrint(bi.name),actualArgs ? (int)actualArgs->size() : -1);
4717 TemplateNameMap formTemplateNames;
4718 if (templateNames.empty())
4719 {
4720 formTemplateNames = getTemplateArgumentsInName(formalArgs,bi.name.str());
4721 }
4722 BaseInfo tbi = bi;
4723 tbi.name = substituteTemplateArgumentsInString(bi.name,formalArgs,actualArgs);
4724 //printf("masterCd=%p instanceCd=%p bi->name=%s tbi.name=%s\n",(void*)masterCd,(void*)instanceCd,qPrint(bi.name),qPrint(tbi.name));
4725
4726 if (mode==DocumentedOnly)
4727 {
4728 // find a documented base class in the correct scope
4729 if (!findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,DocumentedOnly,isArtificial))
4730 {
4731 // 1.8.2: decided to show inheritance relations even if not documented,
4732 // we do make them artificial, so they do not appear in the index
4733 //if (!Config_getBool(HIDE_UNDOC_RELATIONS))
4734 bool b = Config_getBool(HIDE_UNDOC_RELATIONS) ? TRUE : isArtificial;
4735 //{
4736 // no documented base class -> try to find an undocumented one
4737 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,Undocumented,b);
4738 //}
4739 }
4740 }
4741 else if (mode==TemplateInstances)
4742 {
4743 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,TemplateInstances,isArtificial);
4744 }
4745 }
4746}

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

5714{
5715 SymbolResolver resolver(fd);
5716 const ClassDef *tcd = resolver.resolveClass(nd,scopeName,true,true);
5717 //printf("findClassDefinition(fd=%s,ns=%s,scopeName=%s)='%s'\n",
5718 // qPrint(fd?fd->name():""),qPrint(nd?nd->name():""),
5719 // qPrint(scopeName),qPrint(tcd?tcd->name():""));
5720 return tcd;
5721}

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

5237{
5238 if (isClassSection(root))
5239 {
5240 g_classEntries.emplace(root->name.str(),root);
5241 }
5242 for (const auto &e : root->children()) findClassEntries(e.get());
5243}
static void findClassEntries(const Entry *root)
Definition doxygen.cpp:5236
static bool isClassSection(const Entry *root)
Definition doxygen.cpp:5214

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

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

4509{
4510 ClassDef *result=nullptr;
4511 if (cd==nullptr)
4512 {
4513 return result;
4514 }
4515 FileDef *fd=cd->getFileDef();
4516 SymbolResolver resolver(fd);
4517 if (context && cd!=context)
4518 {
4519 result = const_cast<ClassDef*>(resolver.resolveClass(context,name,true,true));
4520 }
4521 //printf("1. result=%p\n",result);
4522 if (result==nullptr)
4523 {
4524 result = const_cast<ClassDef*>(resolver.resolveClass(cd,name,true,true));
4525 }
4526 //printf("2. result=%p\n",result);
4527 if (result==nullptr) // try direct class, needed for namespaced classes imported via tag files (see bug624095)
4528 {
4529 result = getClass(name);
4530 }
4531 //printf("3. result=%p\n",result);
4532 //printf("** Trying to find %s within context %s class %s result=%s lookup=%p\n",
4533 // qPrint(name),
4534 // context ? qPrint(context->name()) : "<none>",
4535 // cd ? qPrint(cd->name()) : "<none>",
4536 // result ? qPrint(result->name()) : "<none>",
4537 // Doxygen::classLinkedMap->find(name)
4538 // );
4539 return result;
4540}

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

Referenced by findClassRelation(), and findUsedClassesForClass().

◆ findDefineDocumentation()

void findDefineDocumentation ( Entry * root)
static

Definition at line 9550 of file doxygen.cpp.

9551{
9552 if ((root->section.isDefineDoc() || root->section.isDefine()) && !root->name.isEmpty())
9553 {
9554 //printf("found define '%s' '%s' brief='%s' doc='%s'\n",
9555 // qPrint(root->name),qPrint(root->args),qPrint(root->brief),qPrint(root->doc));
9556
9557 if (root->tagInfo() && !root->name.isEmpty()) // define read from a tag file
9558 {
9559 auto md = createMemberDef(root->tagInfo()->tagName,1,1,
9560 "#define",root->name,root->args,QCString(),
9561 Protection::Public,Specifier::Normal,FALSE,Relationship::Member,MemberType::Define,
9562 ArgumentList(),ArgumentList(),"");
9563 auto mmd = toMemberDefMutable(md.get());
9564 mmd->setTagInfo(root->tagInfo());
9565 mmd->setLanguage(root->lang);
9566 mmd->addQualifiers(root->qualifiers);
9567 //printf("Searching for '%s' fd=%p\n",qPrint(filePathName),fd);
9568 mmd->setFileDef(root->parent()->fileDef());
9569 //printf("Adding member=%s\n",qPrint(md->name()));
9571 mn->push_back(std::move(md));
9572 }
9574 if (mn)
9575 {
9576 int count=0;
9577 for (const auto &md : *mn)
9578 {
9579 if (md->memberType()==MemberType::Define) count++;
9580 }
9581 if (count==1)
9582 {
9583 for (const auto &imd : *mn)
9584 {
9585 MemberDefMutable *md = toMemberDefMutable(imd.get());
9586 if (md && md->memberType()==MemberType::Define)
9587 {
9588 addDefineDoc(root,md);
9589 }
9590 }
9591 }
9592 else if (count>1 &&
9593 (!root->doc.isEmpty() ||
9594 !root->brief.isEmpty() ||
9595 root->bodyLine!=-1
9596 )
9597 )
9598 // multiple defines don't know where to add docs
9599 // but maybe they are in different files together with their documentation
9600 {
9601 for (const auto &imd : *mn)
9602 {
9603 MemberDefMutable *md = toMemberDefMutable(imd.get());
9604 if (md && md->memberType()==MemberType::Define)
9605 {
9606 if (haveEqualFileNames(root, md) || isEntryInGroupOfMember(root, md))
9607 // doc and define in the same file or group assume they belong together.
9608 {
9609 addDefineDoc(root,md);
9610 }
9611 }
9612 }
9613 //warn("define {} found in the following files:\n",root->name);
9614 //warn("Cannot determine where to add the documentation found "
9615 // "at line {} of file {}. \n",
9616 // root->startLine,root->fileName);
9617 }
9618 }
9619 else if (!root->doc.isEmpty() || !root->brief.isEmpty()) // define not found
9620 {
9621 bool preEnabled = Config_getBool(ENABLE_PREPROCESSING);
9622 if (preEnabled)
9623 {
9624 warn(root->fileName,root->startLine,"documentation for unknown define {} found.",root->name);
9625 }
9626 else
9627 {
9628 warn(root->fileName,root->startLine, "found documented #define {} but ignoring it because ENABLE_PREPROCESSING is NO.", root->name);
9629 }
9630 }
9631 }
9632 for (const auto &e : root->children()) findDefineDocumentation(e.get());
9633}
static void findDefineDocumentation(Entry *root)
Definition doxygen.cpp:9550
static void addDefineDoc(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:9524
static bool haveEqualFileNames(const Entry *root, const MemberDef *md)
Definition doxygen.cpp:9513
static bool isEntryInGroupOfMember(const Entry *root, const MemberDef *md, bool allowNoGroup=false)
Definition doxygen.cpp:5727

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

8115{
8116 // for each member name
8117 for (const auto &mn : mnsd)
8118 {
8119 // for each member definition
8120 for (const auto &imd : *mn)
8121 {
8122 MemberDefMutable *md = toMemberDefMutable(imd.get());
8123 if (md && md->isEnumerate()) // member is an enum
8124 {
8125 int documentedEnumValues=0;
8126 // for each enum value
8127 for (const auto &fmd : md->enumFieldList())
8128 {
8129 if (fmd->isLinkableInProject()) documentedEnumValues++;
8130 }
8131 // at least one enum value is documented
8132 if (documentedEnumValues>0) md->setDocumentedEnumValues(TRUE);
8133 }
8134 }
8135 }
8136}
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 9637 of file doxygen.cpp.

9638{
9639 if (root->section.isDirDoc())
9640 {
9641 QCString normalizedName = root->name;
9642 normalizedName = substitute(normalizedName,"\\","/");
9643 //printf("root->docFile=%s normalizedName=%s\n",
9644 // qPrint(root->docFile),qPrint(normalizedName));
9645 if (root->docFile==normalizedName) // current dir?
9646 {
9647 int lastSlashPos=normalizedName.findRev('/');
9648 if (lastSlashPos!=-1) // strip file name
9649 {
9650 normalizedName=normalizedName.left(lastSlashPos);
9651 }
9652 }
9653 if (normalizedName.at(normalizedName.length()-1)!='/')
9654 {
9655 normalizedName+='/';
9656 }
9657 DirDef *matchingDir=nullptr;
9658 for (const auto &dir : *Doxygen::dirLinkedMap)
9659 {
9660 //printf("Dir: %s<->%s\n",qPrint(dir->name()),qPrint(normalizedName));
9661 if (dir->name().right(normalizedName.length())==normalizedName)
9662 {
9663 if (matchingDir)
9664 {
9665 warn(root->fileName,root->startLine,
9666 "\\dir command matches multiple directories.\n"
9667 " Applying the command for directory {}\n"
9668 " Ignoring the command for directory {}",
9669 matchingDir->name(),dir->name()
9670 );
9671 }
9672 else
9673 {
9674 matchingDir=dir.get();
9675 }
9676 }
9677 }
9678 if (matchingDir)
9679 {
9680 //printf("Match for with dir %s #anchor=%zu\n",qPrint(matchingDir->name()),root->anchors.size());
9681 matchingDir->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9682 matchingDir->setDocumentation(root->doc,root->docFile,root->docLine);
9683 matchingDir->setRefItems(root->sli);
9684 matchingDir->addSectionsToDefinition(root->anchors);
9685 root->commandOverrides.apply_directoryGraph([&](bool b) { matchingDir->overrideDirectoryGraph(b); });
9686 addDirToGroups(root,matchingDir);
9687 }
9688 else
9689 {
9690 warn(root->fileName,root->startLine,"No matching directory found for command \\dir {}",normalizedName);
9691 }
9692 }
9693 for (const auto &e : root->children()) findDirDocumentation(e.get());
9694}
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:9637
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 8140 of file doxygen.cpp.

8141{
8144}
static void findDEV(const MemberNameLinkedMap &mnsd)
Definition doxygen.cpp:8114

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

3064{
3065 // locate end of template
3066 size_t e=startPos;
3067 int brCount=1;
3068 int roundCount=0;
3069 size_t len = s.length();
3070 bool insideString=FALSE;
3071 bool insideChar=FALSE;
3072 char pc = 0;
3073 while (e<len && brCount!=0)
3074 {
3075 char c=s.at(e);
3076 switch(c)
3077 {
3078 case '<':
3079 if (!insideString && !insideChar)
3080 {
3081 if (e<len-1 && s.at(e+1)=='<')
3082 e++;
3083 else if (roundCount==0)
3084 brCount++;
3085 }
3086 break;
3087 case '>':
3088 if (!insideString && !insideChar)
3089 {
3090 if (e<len-1 && s.at(e+1)=='>')
3091 e++;
3092 else if (roundCount==0)
3093 brCount--;
3094 }
3095 break;
3096 case '(':
3097 if (!insideString && !insideChar)
3098 roundCount++;
3099 break;
3100 case ')':
3101 if (!insideString && !insideChar)
3102 roundCount--;
3103 break;
3104 case '"':
3105 if (!insideChar)
3106 {
3107 if (insideString && pc!='\\')
3108 insideString=FALSE;
3109 else
3110 insideString=TRUE;
3111 }
3112 break;
3113 case '\'':
3114 if (!insideString)
3115 {
3116 if (insideChar && pc!='\\')
3117 insideChar=FALSE;
3118 else
3119 insideChar=TRUE;
3120 }
3121 break;
3122 }
3123 pc = c;
3124 e++;
3125 }
3126 return brCount==0 ? static_cast<int>(e) : -1;
3127}

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

Referenced by addVariable(), and findClassRelation().

◆ findEnumDocumentation()

void findEnumDocumentation ( const Entry * root)
static

Definition at line 8028 of file doxygen.cpp.

8029{
8030 if (root->section.isEnumDoc() &&
8031 !root->name.isEmpty() &&
8032 root->name.at(0)!='@' // skip anonymous enums
8033 )
8034 {
8035 QCString name;
8036 QCString scope;
8037 int i = root->name.findRev("::");
8038 if (i!=-1) // scope is specified as part of the name
8039 {
8040 name=root->name.right(root->name.length()-i-2); // extract name
8041 scope=root->name.left(i); // extract scope
8042 //printf("Scope='%s' Name='%s'\n",qPrint(scope),qPrint(name));
8043 }
8044 else // just the name
8045 {
8046 name=root->name;
8047 }
8048 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
8049 {
8050 if (!scope.isEmpty()) scope.prepend("::");
8051 scope.prepend(root->parent()->name);
8052 }
8053 const ClassDef *cd = getClass(scope);
8054 const NamespaceDef *nd=Doxygen::namespaceLinkedMap->find(scope);
8055 const FileDef *fd = root->fileDef();
8056 AUTO_TRACE("Found docs for enum with name '{}' and scope '{}' in context '{}' cd='{}', nd='{}' fd='{}'",
8057 name,scope,root->parent()->name,
8058 cd ? cd->name() : QCString("<none>"),
8059 nd ? nd->name() : QCString("<none>"),
8060 fd ? fd->name() : QCString("<none>"));
8061
8062 if (!name.isEmpty())
8063 {
8064 bool found = tryAddEnumDocsToGroupMember(root, name);
8065 if (!found)
8066 {
8067 MemberName *mn = cd ? Doxygen::memberNameLinkedMap->find(name) : Doxygen::functionNameLinkedMap->find(name);
8068 if (mn)
8069 {
8070 for (const auto &imd : *mn)
8071 {
8072 MemberDefMutable *md = toMemberDefMutable(imd.get());
8073 if (md && md->isEnumerate())
8074 {
8075 const ClassDef *mcd = md->getClassDef();
8076 const NamespaceDef *mnd = md->getNamespaceDef();
8077 const FileDef *mfd = md->getFileDef();
8078 if (cd && mcd==cd)
8079 {
8080 AUTO_TRACE_ADD("Match found for class scope");
8081 addEnumDocs(root,md);
8082 found = TRUE;
8083 break;
8084 }
8085 else if (cd==nullptr && mcd==nullptr && nd!=nullptr && mnd==nd)
8086 {
8087 AUTO_TRACE_ADD("Match found for namespace scope");
8088 addEnumDocs(root,md);
8089 found = TRUE;
8090 break;
8091 }
8092 else if (cd==nullptr && nd==nullptr && mcd==nullptr && mnd==nullptr && fd==mfd)
8093 {
8094 AUTO_TRACE_ADD("Match found for global scope");
8095 addEnumDocs(root,md);
8096 found = TRUE;
8097 break;
8098 }
8099 }
8100 }
8101 }
8102 }
8103 if (!found)
8104 {
8105 warn(root->fileName,root->startLine, "Documentation for undefined enum '{}' found.", name);
8106 }
8107 }
8108 }
8109 for (const auto &e : root->children()) findEnumDocumentation(e.get());
8110}
static bool tryAddEnumDocsToGroupMember(const Entry *root, const QCString &name)
Definition doxygen.cpp:7995
static void addEnumDocs(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:7954
static void findEnumDocumentation(const Entry *root)
Definition doxygen.cpp:8028

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

7531{
7532 if (root->section.isEnum())
7533 {
7534 AUTO_TRACE("name={}",root->name);
7535 ClassDefMutable *cd = nullptr;
7536 FileDef *fd = nullptr;
7537 NamespaceDefMutable *nd = nullptr;
7538 MemberNameLinkedMap *mnsd = nullptr;
7539 bool isGlobal = false;
7540 bool isRelated = false;
7541 bool isMemberOf = false;
7542 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
7543
7544 QCString name;
7545 QCString scope;
7546
7547 int i = root->name.findRev("::");
7548 if (i!=-1) // scope is specified
7549 {
7550 scope=root->name.left(i); // extract scope
7551 if (root->lang==SrcLangExt::CSharp)
7552 {
7553 scope = mangleCSharpGenericName(scope);
7554 }
7555 name=root->name.right(root->name.length()-i-2); // extract name
7556 if ((cd=getClassMutable(scope))==nullptr)
7557 {
7559 }
7560 }
7561 else // no scope, check the scope in which the docs where found
7562 {
7563 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7564 {
7565 scope=root->parent()->name;
7566 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7567 }
7568 name=root->name;
7569 }
7570
7571 if (!root->relates.isEmpty())
7572 { // related member, prefix user specified scope
7573 isRelated=TRUE;
7574 isMemberOf=(root->relatesType==RelatesType::MemberOf);
7575 if (getClass(root->relates)==nullptr && !scope.isEmpty())
7576 scope=mergeScopes(scope,root->relates);
7577 else
7578 scope=root->relates;
7579 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7580 }
7581
7582 if (cd && !name.isEmpty()) // found a enum inside a compound
7583 {
7584 //printf("Enum '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
7585 fd=nullptr;
7587 isGlobal=false;
7588 }
7589 else if (nd) // found enum inside namespace
7590 {
7592 isGlobal=true;
7593 }
7594 else // found a global enum
7595 {
7596 fd=root->fileDef();
7598 isGlobal=true;
7599 }
7600
7601 if (!name.isEmpty())
7602 {
7603 // new enum type
7604 AUTO_TRACE_ADD("new enum {} at line {} of {}",name,root->bodyLine,root->fileName);
7605 auto md = createMemberDef(
7606 root->fileName,root->startLine,root->startColumn,
7607 QCString(),name,QCString(),QCString(),
7608 root->protection,Specifier::Normal,FALSE,
7609 isMemberOf ? Relationship::Foreign : isRelated ? Relationship::Related : Relationship::Member,
7612 auto mmd = toMemberDefMutable(md.get());
7613 mmd->setTagInfo(root->tagInfo());
7614 mmd->setLanguage(root->lang);
7615 mmd->setId(root->id);
7616 if (!isGlobal) mmd->setMemberClass(cd); else mmd->setFileDef(fd);
7617 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
7618 mmd->setBodyDef(root->fileDef());
7619 mmd->setMemberSpecifiers(root->spec);
7620 mmd->setVhdlSpecifiers(root->vhdlSpec);
7621 mmd->setEnumBaseType(root->args);
7622 //printf("Enum %s definition at line %d of %s: protection=%d scope=%s\n",
7623 // qPrint(root->name),root->bodyLine,qPrint(root->fileName),root->protection,cd?qPrint(cd->name()):"<none>");
7624 mmd->addSectionsToDefinition(root->anchors);
7625 mmd->setMemberGroupId(root->mGrpId);
7627 mmd->addQualifiers(root->qualifiers);
7628 //printf("%s::setRefItems(%zu)\n",qPrint(md->name()),root->sli.size());
7629 mmd->setRefItems(root->sli);
7630 //printf("found enum %s nd=%p\n",qPrint(md->name()),nd);
7631 bool defSet=FALSE;
7632
7633 QCString baseType = root->args;
7634 if (!baseType.isEmpty())
7635 {
7636 baseType.prepend(" : ");
7637 }
7638
7639 if (nd)
7640 {
7641 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES))
7642 {
7643 mmd->setDefinition(name+baseType);
7644 }
7645 else
7646 {
7647 mmd->setDefinition(nd->name()+"::"+name+baseType);
7648 }
7649 //printf("definition=%s\n",md->definition());
7650 defSet=TRUE;
7651 mmd->setNamespace(nd);
7652 nd->insertMember(md.get());
7653 }
7654
7655 // even if we have already added the enum to a namespace, we still
7656 // also want to add it to other appropriate places such as file
7657 // or class.
7658 if (isGlobal && (nd==nullptr || !nd->isAnonymous()))
7659 {
7660 if (!defSet) mmd->setDefinition(name+baseType);
7661 if (fd==nullptr && root->parent())
7662 {
7663 fd=root->parent()->fileDef();
7664 }
7665 if (fd)
7666 {
7667 mmd->setFileDef(fd);
7668 fd->insertMember(md.get());
7669 }
7670 }
7671 else if (cd)
7672 {
7673 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES))
7674 {
7675 mmd->setDefinition(name+baseType);
7676 }
7677 else
7678 {
7679 mmd->setDefinition(cd->name()+"::"+name+baseType);
7680 }
7681 cd->insertMember(md.get());
7682 cd->insertUsedFile(fd);
7683 }
7684 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
7685 mmd->setDocsForDefinition(!root->proto);
7686 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7687 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
7688
7689 //printf("Adding member=%s\n",qPrint(md->name()));
7690 addMemberToGroups(root,md.get());
7692
7693 MemberName *mn = mnsd->add(name);
7694 mn->push_back(std::move(md));
7695 }
7696 }
7697 else
7698 {
7699 for (const auto &e : root->children()) findEnums(e.get());
7700 }
7701}
static void findEnums(const Entry *root)
Definition doxygen.cpp:7530
@ 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 4216 of file doxygen.cpp.

4217{
4218 AUTO_TRACE();
4219 for (const auto &fn : *Doxygen::functionNameLinkedMap) // for each global function name
4220 {
4221 MemberName *mn = Doxygen::memberNameLinkedMap->find(fn->memberName());
4222 if (mn)
4223 { // there are members with the same name
4224 // for each function with that name
4225 for (const auto &ifmd : *fn)
4226 {
4227 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
4228 // for each member with that name
4229 for (const auto &immd : *mn)
4230 {
4231 MemberDefMutable *mmd = toMemberDefMutable(immd.get());
4232 //printf("Checking for matching arguments
4233 // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n",
4234 // mmd->isRelated(),mmd->isFriend(),mmd->isFunction());
4235 if (fmd && mmd &&
4236 (mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) &&
4237 matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), mmd->typeString(), &mmd->argumentList(),
4238 fmd->getOuterScope(), fmd->getFileDef(), fmd->typeString(), &fmd->argumentList(),
4239 TRUE,mmd->getLanguage()
4240 )
4241
4242 ) // if the member is related and the arguments match then the
4243 // function is actually a friend.
4244 {
4245 AUTO_TRACE_ADD("Merging related global and member '{}' isFriend={} isRelated={} isFunction={}",
4246 mmd->name(),mmd->isFriend(),mmd->isRelated(),mmd->isFunction());
4247 const ArgumentList &mmdAl = mmd->argumentList();
4248 const ArgumentList &fmdAl = fmd->argumentList();
4249 mergeArguments(const_cast<ArgumentList&>(fmdAl),const_cast<ArgumentList&>(mmdAl));
4250
4251 // reset argument lists to add missing default parameters
4252 QCString mmdAlStr = argListToString(mmdAl);
4253 QCString fmdAlStr = argListToString(fmdAl);
4254 mmd->setArgsString(mmdAlStr);
4255 fmd->setArgsString(fmdAlStr);
4256 mmd->moveDeclArgumentList(std::make_unique<ArgumentList>(mmdAl));
4257 fmd->moveDeclArgumentList(std::make_unique<ArgumentList>(fmdAl));
4258 AUTO_TRACE_ADD("friend args='{}' member args='{}'",argListToString(fmd->argumentList()),argListToString(mmd->argumentList()));
4259
4260 if (!fmd->documentation().isEmpty())
4261 {
4262 mmd->setDocumentation(fmd->documentation(),fmd->docFile(),fmd->docLine());
4263 }
4264 else if (!mmd->documentation().isEmpty())
4265 {
4266 fmd->setDocumentation(mmd->documentation(),mmd->docFile(),mmd->docLine());
4267 }
4268 if (mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
4269 {
4270 mmd->setBriefDescription(fmd->briefDescription(),fmd->briefFile(),fmd->briefLine());
4271 }
4272 else if (!mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
4273 {
4274 fmd->setBriefDescription(mmd->briefDescription(),mmd->briefFile(),mmd->briefLine());
4275 }
4276 if (!fmd->inbodyDocumentation().isEmpty())
4277 {
4279 }
4280 else if (!mmd->inbodyDocumentation().isEmpty())
4281 {
4283 }
4284 //printf("body mmd %d fmd %d\n",mmd->getStartBodyLine(),fmd->getStartBodyLine());
4285 if (mmd->getStartBodyLine()==-1 && fmd->getStartBodyLine()!=-1)
4286 {
4287 mmd->setBodySegment(fmd->getDefLine(),fmd->getStartBodyLine(),fmd->getEndBodyLine());
4288 mmd->setBodyDef(fmd->getBodyDef());
4289 //mmd->setBodyMember(fmd);
4290 }
4291 else if (mmd->getStartBodyLine()!=-1 && fmd->getStartBodyLine()==-1)
4292 {
4293 fmd->setBodySegment(mmd->getDefLine(),mmd->getStartBodyLine(),mmd->getEndBodyLine());
4294 fmd->setBodyDef(mmd->getBodyDef());
4295 //fmd->setBodyMember(mmd);
4296 }
4298
4300
4301 mmd->addQualifiers(fmd->getQualifiers());
4302 fmd->addQualifiers(mmd->getQualifiers());
4303
4304 }
4305 }
4306 }
4307 }
4308 }
4309}
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:6830

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

Referenced by parseInput().

◆ findFunctionPtr()

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

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

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

Definition at line 2859 of file doxygen.cpp.

2860{
2861 AUTO_TRACE("type='{}' lang={}",type,lang);
2862 if (lang == SrcLangExt::Fortran || lang == SrcLangExt::VHDL)
2863 {
2864 return -1; // Fortran and VHDL do not have function pointers
2865 }
2866
2867 static const reg::Ex re(R"(\‍([^)]*[*&^][^)]*\))");
2869 size_t i=std::string::npos;
2870 size_t l=0;
2871 if (reg::search(type,match,re)) // contains (...*...) or (...&...) or (...^...)
2872 {
2873 i = match.position();
2874 l = match.length();
2875 }
2876 if (i!=std::string::npos)
2877 {
2878 size_t di = type.find("decltype(");
2879 if (di!=std::string::npos && di<i)
2880 {
2881 i = std::string::npos;
2882 }
2883 }
2884 size_t bb=type.find('<');
2885 size_t be=type.rfind('>');
2886 bool templFp = false;
2887 if (be!=std::string::npos) {
2888 size_t cc_ast = type.find("::*");
2889 size_t cc_amp = type.find("::&");
2890 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>::*)'
2891 }
2892
2893 if (!type.empty() && // return type is non-empty
2894 i!=std::string::npos && // contains (...*...)
2895 type.find("operator")==std::string::npos && // not an operator
2896 (type.find(")(")==std::string::npos || type.find("typedef ")!=std::string::npos) &&
2897 // not a function pointer return type
2898 (!(bb<i && i<be) || templFp) // bug665855: avoid treating "typedef A<void (T*)> type" as a function pointer
2899 )
2900 {
2901 if (pLength) *pLength=static_cast<int>(l);
2902 //printf("findFunctionPtr=%d\n",(int)i);
2903 AUTO_TRACE_EXIT("result={}",i);
2904 return static_cast<int>(i);
2905 }
2906 else
2907 {
2908 //printf("findFunctionPtr=%d\n",-1);
2909 AUTO_TRACE_EXIT("result=-1");
2910 return -1;
2911 }
2912}
#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 5751 of file doxygen.cpp.

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

2443{
2444 FileDefSet visitedFiles;
2445 // then recursively add using directives found in #include files
2446 // to files that have not been visited.
2447 for (const auto &fn : *Doxygen::inputNameLinkedMap)
2448 {
2449 for (const auto &fd : *fn)
2450 {
2451 //printf("----- adding using directives for file %s\n",qPrint(fd->name()));
2452 fd->addIncludedUsingDirectives(visitedFiles);
2453 }
2454 }
2455}
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 5273 of file doxygen.cpp.

5274{
5275 AUTO_TRACE();
5276 ClassDefSet visitedClasses;
5277 for (const auto &[name,root] : g_classEntries)
5278 {
5279 QCString bName = extractClassName(root);
5280 ClassDefMutable *cdm = getClassMutable(bName);
5281 if (cdm)
5282 {
5284 }
5285 }
5286}

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

Referenced by parseInput().

◆ findMainPage()

void findMainPage ( Entry * root)
static

Definition at line 9727 of file doxygen.cpp.

9728{
9729 if (root->section.isMainpageDoc())
9730 {
9731 if (Doxygen::mainPage==nullptr && root->tagInfo()==nullptr)
9732 {
9733 //printf("mainpage: docLine=%d startLine=%d\n",root->docLine,root->startLine);
9734 //printf("Found main page! \n======\n%s\n=======\n",qPrint(root->doc));
9735 QCString title=root->args.stripWhiteSpace();
9736 if (title.isEmpty()) title = Config_getString(PROJECT_NAME);
9737 //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9738 QCString indexName="index";
9740 indexName, root->brief+root->doc+root->inbodyDocs,title);
9741 //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
9742 Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9743 Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1);
9744 Doxygen::mainPage->setFileName(indexName);
9745 Doxygen::mainPage->setLocalToc(root->localToc);
9747
9749 if (si)
9750 {
9751 if (!si->ref().isEmpty()) // we are from a tag file
9752 {
9753 // a page name is a label as well! but should no be double either
9755 Doxygen::mainPage->name(),
9756 indexName,
9757 root->startLine,
9758 Doxygen::mainPage->title(),
9760 0); // level 0
9761 }
9762 else if (si->lineNr() != -1)
9763 {
9764 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {}, line {})",
9765 Doxygen::mainPage->name(),si->fileName(),si->lineNr());
9766 }
9767 else
9768 {
9769 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {})",
9770 Doxygen::mainPage->name(),si->fileName());
9771 }
9772 }
9773 else
9774 {
9775 // a page name is a label as well! but should no be double either
9777 Doxygen::mainPage->name(),
9778 indexName,
9779 root->startLine,
9780 Doxygen::mainPage->title(),
9782 0); // level 0
9783 }
9784 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9785 }
9786 else if (root->tagInfo()==nullptr)
9787 {
9788 warn(root->fileName,root->startLine,
9789 "found more than one \\mainpage comment block! (first occurrence: {}, line {}), Skipping current block!",
9790 Doxygen::mainPage->docFile(),Doxygen::mainPage->getStartBodyLine());
9791 }
9792 }
9793 for (const auto &e : root->children()) findMainPage(e.get());
9794}
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:9727

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

9798{
9799 if (root->section.isMainpageDoc())
9800 {
9801 if (Doxygen::mainPage && root->tagInfo())
9802 {
9803 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9804 }
9805 }
9806 for (const auto &e : root->children()) findMainPageTagFiles(e.get());
9807}
static void findMainPageTagFiles(Entry *root)
Definition doxygen.cpp:9797

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

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

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::type, MemberDef::typeString(), Entry::vhdlSpec, Entry::virt, warn, and warn_undoc.

Referenced by filterMemberDocumentation(), and findObjCMethodDefinitions().

◆ findMemberDocumentation()

void findMemberDocumentation ( const Entry * root)
static

Definition at line 7472 of file doxygen.cpp.

7473{
7474 if (root->section.isMemberDoc() ||
7475 root->section.isOverloadDoc() ||
7476 root->section.isFunction() ||
7477 root->section.isVariable() ||
7478 root->section.isVariableDoc() ||
7479 root->section.isDefine() ||
7480 root->section.isIncludedService() ||
7481 root->section.isExportedInterface()
7482 )
7483 {
7484 AUTO_TRACE();
7485 if (root->relatesType==RelatesType::Duplicate && !root->relates.isEmpty())
7486 {
7488 }
7490 }
7491 for (const auto &e : root->children())
7492 {
7493 if (!e->section.isEnum())
7494 {
7495 findMemberDocumentation(e.get());
7496 }
7497 }
7498}
static void findMemberDocumentation(const Entry *root)
Definition doxygen.cpp:7472
static void filterMemberDocumentation(const Entry *root, const QCString &relates)
Definition doxygen.cpp:7322

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

1301{
1302 if (root->section.isModuleDoc())
1303 {
1304 AUTO_TRACE();
1306 }
1307 for (const auto &e : root->children()) findModuleDocumentation(e.get());
1308}
void addDocs(const Entry *root)
static void findModuleDocumentation(const Entry *root)
Definition doxygen.cpp:1300

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

7503{
7504 AUTO_TRACE();
7505 for (const auto &objCImpl : root->children())
7506 {
7507 if (objCImpl->section.isObjcImpl())
7508 {
7509 for (const auto &objCMethod : objCImpl->children())
7510 {
7511 if (objCMethod->section.isFunction())
7512 {
7513 //printf(" Found ObjC method definition %s\n",qPrint(objCMethod->name));
7514 findMember(objCMethod.get(),
7515 objCMethod->relates,
7516 objCMethod->type,
7517 objCMethod->args,
7518 objCMethod->type+" "+objCImpl->name+"::"+objCMethod->name+" "+objCMethod->args,
7519 FALSE,TRUE);
7520 objCMethod->section=EntryType::makeEmpty();
7521 }
7522 }
7523 }
7524 }
7525}

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

9342{
9343 // for each class
9344 for (const auto &cd : *Doxygen::classLinkedMap)
9345 {
9346 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9347 if (cdm)
9348 {
9350 }
9351 }
9352 // for each concept
9353 for (const auto &cd : *Doxygen::conceptLinkedMap)
9354 {
9355 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
9356 if (cdm)
9357 {
9359 }
9360 }
9361 // for each file
9362 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9363 {
9364 for (const auto &fd : *fn)
9365 {
9366 fd->findSectionsInDocumentation();
9367 }
9368 }
9369 // for each namespace
9370 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9371 {
9373 if (ndm)
9374 {
9376 }
9377 }
9378 // for each group
9379 for (const auto &gd : *Doxygen::groupLinkedMap)
9380 {
9381 gd->findSectionsInDocumentation();
9382 }
9383 // for each page
9384 for (const auto &pd : *Doxygen::pageLinkedMap)
9385 {
9386 pd->findSectionsInDocumentation();
9387 }
9388 // for each directory
9389 for (const auto &dd : *Doxygen::dirLinkedMap)
9390 {
9391 dd->findSectionsInDocumentation();
9392 }
9394 if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
9395}
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 1680 of file doxygen.cpp.

1681{
1682 std::vector<ClassDefMutable *> candidates;
1683 for (auto &cd : *Doxygen::classLinkedMap)
1684 {
1685 Definition *scope = cd->getOuterScope();
1686 if (scope && scope->definitionType()!=Definition::TypeClass) // that is not nested
1687 {
1688 findTagLessClasses(candidates,cd.get());
1689 }
1690 }
1691
1692 // since processTagLessClasses is potentially adding classes to Doxygen::classLinkedMap
1693 // we need to call it outside of the loop above, otherwise the iterator gets invalidated!
1694 for (auto &cd : candidates)
1695 {
1696 processTagLessClasses(cd,cd,cd,"",0); // process tag less inner struct/classes
1697 }
1698}
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:1599
static void findTagLessClasses()
Definition doxygen.cpp:1680

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

1664{
1665 for (const auto &icd : cd->getClasses())
1666 {
1667 if (icd->name().find("@")==-1) // process all non-anonymous inner classes
1668 {
1669 findTagLessClasses(candidates,icd);
1670 }
1671 }
1672
1674 if (cdm)
1675 {
1676 candidates.push_back(cdm);
1677 }
1678}

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

4755{
4756 AUTO_TRACE("Derived from template '{}' with parameters '{}' isArtificial={}",
4757 templateClass->name(),templSpec,isArtificial);
4758
4759 QCString tempArgsStr = tempArgListToString(templateClass->templateArguments(),root->lang,false);
4760 bool existingClass = templSpec==tempArgsStr;
4761 if (existingClass) return; // avoid recursion
4762
4763 bool freshInstance=FALSE;
4764 ClassDefMutable *instanceClass = toClassDefMutable(
4765 templateClass->insertTemplateInstance(
4766 root->fileName,root->startLine,root->startColumn,templSpec,freshInstance));
4767 if (instanceClass)
4768 {
4769 if (freshInstance)
4770 {
4771 instanceClass->setArtificial(TRUE);
4772 instanceClass->setLanguage(root->lang);
4773
4774 AUTO_TRACE_ADD("found fresh instance '{}'",instanceClass->name());
4775 instanceClass->setTemplateBaseClassNames(templateNames);
4776
4777 // search for new template instances caused by base classes of
4778 // instanceClass
4779 auto it_pair = g_classEntries.equal_range(templateClass->name().str());
4780 for (auto it=it_pair.first ; it!=it_pair.second ; ++it)
4781 {
4782 const Entry *templateRoot = it->second;
4783 AUTO_TRACE_ADD("template root found '{}' templSpec='{}'",templateRoot->name,templSpec);
4784 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(root->lang,templSpec);
4785 findBaseClassesForClass(templateRoot,context,templateClass,instanceClass,
4786 TemplateInstances,isArtificial,templArgs.get(),templateNames);
4787
4788 findUsedClassesForClass(templateRoot,context,templateClass,instanceClass,
4789 isArtificial,templArgs.get(),templateNames);
4790 }
4791 }
4792 else
4793 {
4794 AUTO_TRACE_ADD("instance already exists");
4795 }
4796 }
4797}
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:4543

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

4844{
4845 if (name.isEmpty()) return 0;
4846 int l = static_cast<int>(name.length());
4847 if (name[l-1]=='>') // search backward to find the matching <, allowing nested <...> and strings.
4848 {
4849 int count=1;
4850 int i=l-2;
4851 char insideQuote=0;
4852 while (count>0 && i>=0)
4853 {
4854 char c = name[i--];
4855 switch (c)
4856 {
4857 case '>': if (!insideQuote) count++; break;
4858 case '<': if (!insideQuote) count--; break;
4859 case '\'': if (!insideQuote) insideQuote=c;
4860 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4861 break;
4862 case '"': if (!insideQuote) insideQuote=c;
4863 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4864 break;
4865 default: break;
4866 }
4867 }
4868 if (i>=0) l=i+1;
4869 }
4870 return l;
4871}

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

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

References ClassDefMutable::addUsedByClass(), ClassDefMutable::addUsedClass(), MemberDef::argsString(), AUTO_TRACE, AUTO_TRACE_ADD, ClassDef::Class, Config_getBool, createClassDef(), QCString::endsWith(), extractClassNameFromType(), FALSE, findClassRelation(), findClassWithinClassContext(), Definition::getDefColumn(), Definition::getDefFileName(), Definition::getDefLine(), ClassDef::getFileDef(), Definition::getLanguage(), getTemplateArgumentsInName(), Doxygen::hiddenClassLinkedMap, QCString::isEmpty(), MemberDef::isObjCProperty(), MemberDef::isVariable(), Entry::lang, ClassDefMutable::makeTemplateArgument(), ClassDef::memberNameInfoLinkedMap(), Definition::name(), normalizeNonTemplateArgumentsInString(), MemberDef::protection(), removeRedundantWhiteSpace(), replaceNamespaceAliases(), SymbolResolver::resolveClassMutable(), resolveTypeDef(), DefinitionMutable::setArtificial(), DefinitionMutable::setLanguage(), ClassDefMutable::setUsedOnly(), QCString::str(), substituteTemplateArgumentsInString(), ClassDef::templateArguments(), TemplateInstances, toClassDefMutable(), TRUE, and MemberDef::typeString().

Referenced by findTemplateInstanceRelation(), and findUsedTemplateInstances().

◆ findUsedNamespace()

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

Definition at line 1871 of file doxygen.cpp.

1873{
1874 NamespaceDef *usingNd =nullptr;
1875 for (auto &und : unl)
1876 {
1877 QCString uScope=und->name()+"::";
1878 usingNd = getResolvedNamespace(uScope+name);
1879 if (usingNd!=nullptr) break;
1880 }
1881 return usingNd;
1882}

References getResolvedNamespace().

Referenced by findUsingDirectives().

◆ findUsedTemplateInstances()

void findUsedTemplateInstances ( )
static

Definition at line 5306 of file doxygen.cpp.

5307{
5308 AUTO_TRACE();
5309 for (const auto &[name,root] : g_classEntries)
5310 {
5311 QCString bName = extractClassName(root);
5312 ClassDefMutable *cdm = getClassMutable(bName);
5313 if (cdm)
5314 {
5315 findUsedClassesForClass(root,cdm,cdm,cdm,TRUE);
5317 cdm->addTypeConstraints();
5318 }
5319 }
5320}
virtual void addTypeConstraints()=0
static void makeTemplateInstanceRelation(const Entry *root, ClassDefMutable *cd)
Definition doxygen.cpp:5288

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

2040{
2041 if (root->section.isUsingDecl() &&
2042 !root->parent()->section.isCompound() && // not a class/struct member
2043 (!filterPythonPackages || (root->lang==SrcLangExt::Python && root->fileName.endsWith("__init__.py")))
2044 )
2045 {
2046 AUTO_TRACE("Found using declaration '{}' at line {} of {} inside section {}",
2047 root->name,root->startLine,root->fileName,root->parent()->section);
2048 if (!root->name.isEmpty())
2049 {
2050 const Definition *usingDef = nullptr;
2051 NamespaceDefMutable *nd = nullptr;
2052 FileDef *fd = root->fileDef();
2053 QCString scName;
2054
2055 // see if the using statement was found inside a namespace or inside
2056 // the global file scope.
2057 if (root->parent()->section.isNamespace())
2058 {
2059 scName=root->parent()->name;
2060 if (!scName.isEmpty())
2061 {
2062 nd = getResolvedNamespaceMutable(scName);
2063 }
2064 }
2065
2066 // Assume the using statement was used to import a class.
2067 // Find the scope in which the 'using' namespace is defined by prepending
2068 // the possible scopes in which the using statement was found, starting
2069 // with the most inner scope and going to the most outer scope (i.e.
2070 // file scope).
2071
2072 QCString name = substitute(root->name,".","::"); //Java/C# scope->internal
2073
2074 SymbolResolver resolver;
2075 const Definition *scope = nd;
2076 if (nd==nullptr) scope = fd;
2077 usingDef = resolver.resolveSymbol(scope,name);
2078
2079 //printf("usingDef(scope=%s,name=%s)=%s\n",qPrint(nd?nd->qualifiedName():""),qPrint(name),usingDef?qPrint(usingDef->qualifiedName()):"nullptr");
2080
2081 if (!usingDef)
2082 {
2083 usingDef = getClass(name); // try direct lookup, this is needed to get
2084 // builtin STL classes to properly resolve, e.g.
2085 // vector -> std::vector
2086 }
2087 if (!usingDef)
2088 {
2089 usingDef = Doxygen::hiddenClassLinkedMap->find(name); // check if it is already hidden
2090 }
2091#if 0
2092 if (!usingDef)
2093 {
2094 AUTO_TRACE_ADD("New using class '{}' (sec={})! #tArgLists={}",
2095 name,root->section,root->tArgLists.size());
2098 createClassDef( "<using>",1,1, name, ClassDef::Class)));
2099 if (usingCd)
2100 {
2101 usingCd->setArtificial(TRUE);
2102 usingCd->setLanguage(root->lang);
2103 usingDef = usingCd;
2104 }
2105 }
2106#endif
2107 else
2108 {
2109 AUTO_TRACE_ADD("Found used type '{}' in scope='{}'",
2110 usingDef->name(), nd ? nd->name(): fd ? fd->name() : QCString("<unknown>"));
2111 }
2112
2113 if (usingDef)
2114 {
2115 if (nd)
2116 {
2117 nd->addUsingDeclaration(usingDef);
2118 }
2119 else if (fd)
2120 {
2121 fd->addUsingDeclaration(usingDef);
2122 }
2123 }
2124 }
2125 }
2126 for (const auto &e : root->children()) findUsingDeclarations(e.get(),filterPythonPackages);
2127}
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:2039

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

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

1885{
1886 if (root->section.isUsingDir())
1887 {
1888 AUTO_TRACE("Found using directive {} at line {} of {}",root->name,root->startLine,root->fileName);
1889 QCString name=substitute(root->name,".","::");
1890 if (name.endsWith("::"))
1891 {
1892 name=name.left(name.length()-2);
1893 }
1894 if (!name.isEmpty())
1895 {
1896 NamespaceDef *usingNd = nullptr;
1897 NamespaceDefMutable *nd = nullptr;
1898 FileDef *fd = root->fileDef();
1899 QCString nsName;
1900
1901 // see if the using statement was found inside a namespace or inside
1902 // the global file scope.
1903 if (root->parent() && root->parent()->section.isNamespace() &&
1904 (fd==nullptr || fd->getLanguage()!=SrcLangExt::Java) // not a .java file
1905 )
1906 {
1907 nsName=stripAnonymousNamespaceScope(root->parent()->name);
1908 if (!nsName.isEmpty())
1909 {
1910 nd = getResolvedNamespaceMutable(nsName);
1911 }
1912 }
1913
1914 // find the scope in which the 'using' namespace is defined by prepending
1915 // the possible scopes in which the using statement was found, starting
1916 // with the most inner scope and going to the most outer scope (i.e.
1917 // file scope).
1918 int scopeOffset = static_cast<int>(nsName.length());
1919 do
1920 {
1921 QCString scope=scopeOffset>0 ?
1922 nsName.left(scopeOffset)+"::" : QCString();
1923 usingNd = getResolvedNamespace(scope+name);
1924 //printf("Trying with scope='%s' usingNd=%p\n",(scope+qPrint(name)),usingNd);
1925 if (scopeOffset==0)
1926 {
1927 scopeOffset=-1;
1928 }
1929 else if ((scopeOffset=nsName.findRev("::",scopeOffset-1))==-1)
1930 {
1931 scopeOffset=0;
1932 }
1933 } while (scopeOffset>=0 && usingNd==nullptr);
1934
1935 if (usingNd==nullptr && nd) // not found, try used namespaces in this scope
1936 // or in one of the parent namespace scopes
1937 {
1938 const NamespaceDefMutable *pnd = nd;
1939 while (pnd && usingNd==nullptr)
1940 {
1941 // also try with one of the used namespaces found earlier
1943
1944 // goto the parent
1945 Definition *s = pnd->getOuterScope();
1947 {
1949 }
1950 else
1951 {
1952 pnd = nullptr;
1953 }
1954 }
1955 }
1956 if (usingNd==nullptr && fd) // still nothing, also try used namespace in the
1957 // global scope
1958 {
1959 usingNd = findUsedNamespace(fd->getUsedNamespaces(),name);
1960 }
1961
1962 //printf("%s -> %s\n",qPrint(name),usingNd?qPrint(usingNd->name()):"<none>");
1963
1964 // add the namespace the correct scope
1965 if (usingNd)
1966 {
1967 //printf("using fd=%p nd=%p\n",fd,nd);
1968 if (nd)
1969 {
1970 //printf("Inside namespace %s\n",qPrint(nd->name()));
1971 nd->addUsingDirective(usingNd);
1972 }
1973 else if (fd)
1974 {
1975 //printf("Inside file %s\n",qPrint(fd->name()));
1976 fd->addUsingDirective(usingNd);
1977 }
1978 }
1979 else // unknown namespace, but add it anyway.
1980 {
1981 AUTO_TRACE_ADD("new unknown namespace {} lang={} hidden={}",name,langToString(root->lang),root->hidden);
1982 // add namespace to the list
1985 createNamespaceDef(root->fileName,root->startLine,root->startColumn,name)));
1986 if (nd)
1987 {
1988 nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1989 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1991 nd->setHidden(root->hidden);
1992 nd->setArtificial(TRUE);
1993 nd->setLanguage(root->lang);
1994 nd->setId(root->id);
1995 nd->setMetaData(root->metaData);
1996 nd->setInline(root->spec.isInline());
1997 nd->setExported(root->exported);
1998
1999 for (const Grouping &g : root->groups)
2000 {
2001 GroupDef *gd=nullptr;
2002 if (!g.groupname.isEmpty() && (gd=Doxygen::groupLinkedMap->find(g.groupname)))
2003 gd->addNamespace(nd);
2004 }
2005
2006 // insert the namespace in the file definition
2007 if (fd)
2008 {
2009 fd->insertNamespace(nd);
2010 fd->addUsingDirective(nd);
2011 }
2012
2013 // the empty string test is needed for extract all case
2014 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2015 nd->insertUsedFile(fd);
2016 nd->setRefItems(root->sli);
2017 }
2018 }
2019 }
2020 }
2021 for (const auto &e : root->children()) findUsingDirectives(e.get());
2022}
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:1871
static void findUsingDirectives(const Entry *root)
Definition doxygen.cpp:1884

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

9401{
9402 // remove all references to classes from the cache
9403 // as there can be new template instances in the inheritance path
9404 // to this class. Optimization: only remove those classes that
9405 // have inheritance instances as direct or indirect sub classes.
9406 StringVector elementsToRemove;
9407 for (const auto &ci : *Doxygen::typeLookupCache)
9408 {
9409 const LookupInfo &li = ci.second;
9410 if (li.definition)
9411 {
9412 elementsToRemove.push_back(ci.first);
9413 }
9414 }
9415 for (const auto &k : elementsToRemove)
9416 {
9417 Doxygen::typeLookupCache->remove(k);
9418 }
9419
9420 // remove all cached typedef resolutions whose target is a
9421 // template class as this may now be a template instance
9422 // for each global function name
9423 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9424 {
9425 // for each function with that name
9426 for (const auto &ifmd : *fn)
9427 {
9428 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9429 if (fmd && fmd->isTypedefValCached())
9430 {
9431 const ClassDef *cd = fmd->getCachedTypedefVal();
9432 if (cd->isTemplate()) fmd->invalidateTypedefValCache();
9433 }
9434 }
9435 }
9436 // for each class method name
9437 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9438 {
9439 // for each function with that name
9440 for (const auto &imd : *nm)
9441 {
9442 MemberDefMutable *md = toMemberDefMutable(imd.get());
9443 if (md && md->isTypedefValCached())
9444 {
9445 const ClassDef *cd = md->getCachedTypedefVal();
9446 if (cd->isTemplate()) md->invalidateTypedefValCache();
9447 }
9448 }
9449 }
9450}
virtual bool isTemplate() const =0
Returns TRUE if this class is a template.
static Cache< std::string, LookupInfo > * typeLookupCache
Definition doxygen.h:126
virtual const ClassDef * getCachedTypedefVal() const =0
virtual bool isTypedefValCached() const =0
virtual void invalidateTypedefValCache()=0
const Definition * definition
Definition doxygen.h:59

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

9455{
9456 // Remove all unresolved references to classes from the cache.
9457 // This is needed before resolving the inheritance relations, since
9458 // it would otherwise not find the inheritance relation
9459 // for C in the example below, as B::I was already found to be unresolvable
9460 // (which is correct if you ignore the inheritance relation between A and B).
9461 //
9462 // class A { class I {} };
9463 // class B : public A {};
9464 // class C : public B::I {};
9465
9466 StringVector elementsToRemove;
9467 for (const auto &ci : *Doxygen::typeLookupCache)
9468 {
9469 const LookupInfo &li = ci.second;
9470 if (li.definition==nullptr && li.typeDef==nullptr)
9471 {
9472 elementsToRemove.push_back(ci.first);
9473 }
9474 }
9475 for (const auto &k : elementsToRemove)
9476 {
9477 Doxygen::typeLookupCache->remove(k);
9478 }
9479
9480 // for each global function name
9481 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9482 {
9483 // for each function with that name
9484 for (const auto &ifmd : *fn)
9485 {
9486 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9487 if (fmd)
9488 {
9490 }
9491 }
9492 }
9493 // for each class method name
9494 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9495 {
9496 // for each function with that name
9497 for (const auto &imd : *nm)
9498 {
9499 MemberDefMutable *md = toMemberDefMutable(imd.get());
9500 if (md)
9501 {
9503 }
9504 }
9505 }
9506
9507}
virtual void invalidateCachedArgumentTypes()=0
const MemberDef * typeDef
Definition doxygen.h:60

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

9159{
9160 std::vector<ClassDefMutable*> classList;
9161 for (const auto &cdi : *Doxygen::classLinkedMap)
9162 {
9163 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9164 if (cd && (cd->getOuterScope()==nullptr ||
9166 {
9167 addClassAndNestedClasses(classList,cd);
9168 }
9169 }
9170 for (const auto &cdi : *Doxygen::hiddenClassLinkedMap)
9171 {
9172 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9173 if (cd && (cd->getOuterScope()==nullptr ||
9175 {
9176 addClassAndNestedClasses(classList,cd);
9177 }
9178 }
9179 generateDocsForClassList(classList);
9180}
static void generateDocsForClassList(const std::vector< ClassDefMutable * > &classList)
Definition doxygen.cpp:9060

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

9185{
9186 for (const auto &cdi : *Doxygen::conceptLinkedMap)
9187 {
9189
9190 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9191 if (cd &&
9192 (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9193 cd->getOuterScope()==Doxygen::globalScope // only look at global concepts
9194 ) && !cd->isHidden() && cd->isLinkableInProject()
9195 )
9196 {
9197 msg("Generating docs for concept {}...\n",cd->displayName());
9199 }
9200 }
9201}
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 10304 of file doxygen.cpp.

10306{
10307 std::ofstream f;
10308 bool fileOpened=openOutputFile(configFile,f);
10309 bool writeToStdout=configFile=="-";
10310 if (fileOpened)
10311 {
10312 TextStream t(&f);
10313 Config::writeTemplate(t,shortList,updateOnly);
10314 if (!writeToStdout)
10315 {
10316 if (!updateOnly)
10317 {
10318 msg("\n\nConfiguration file '{}' created.\n\n",configFile);
10319 msg("Now edit the configuration file and enter\n\n");
10320 if (configFile!="Doxyfile" && configFile!="doxyfile")
10321 msg(" doxygen {}\n\n",configFile);
10322 else
10323 msg(" doxygen\n\n");
10324 msg("to generate the documentation for your project\n\n");
10325 }
10326 else
10327 {
10328 msg("\n\nConfiguration file '{}' updated.\n\n",configFile);
10329 }
10330 }
10331 }
10332 else
10333 {
10334 term("Cannot open file {} for writing\n",configFile);
10335 }
10336}
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 10559 of file doxygen.cpp.

10560{
10561 for (const auto &fn : *Doxygen::inputNameLinkedMap)
10562 {
10563 struct FileEntry
10564 {
10565 FileEntry(const QCString &p,FileDef *fd) : path(p), fileDef(fd) {}
10566 QCString path;
10567 FileDef *fileDef;
10568 };
10569
10570 // collect the entry for which to compute the longest common prefix (LCP) of the path
10571 std::vector<FileEntry> fileEntries;
10572 for (const auto &fd : *fn)
10573 {
10574 if (!fd->isReference()) // skip external references
10575 {
10576 fileEntries.emplace_back(fd->getPath(),fd.get());
10577 }
10578 }
10579
10580 size_t size = fileEntries.size();
10581
10582 if (size==1) // name if unique, so diskname is simply the name
10583 {
10584 FileDef *fd = fileEntries[0].fileDef;
10585 fd->setDiskName(fn->fileName());
10586 }
10587 else if (size>1) // multiple occurrences of the same file name
10588 {
10589 // sort the array
10590 std::stable_sort(fileEntries.begin(),
10591 fileEntries.end(),
10592 [](const FileEntry &fe1,const FileEntry &fe2)
10593 { return qstricmp_sort(fe1.path,fe2.path)<0; }
10594 );
10595
10596 // since the entries are sorted, the common prefix of the whole array is same
10597 // as the common prefix between the first and last entry
10598 const FileEntry &first = fileEntries[0];
10599 const FileEntry &last = fileEntries[size-1];
10600 int first_path_size = static_cast<int>(first.path.size())-1; // -1 to skip trailing slash
10601 int last_path_size = static_cast<int>(last.path.size())-1; // -1 to skip trailing slash
10602 int j=0;
10603 int i=0;
10604 for (i=0;i<first_path_size && i<last_path_size;i++)
10605 {
10606 if (first.path[i]=='/') j=i;
10607 if (first.path[i]!=last.path[i]) break;
10608 }
10609 if (i==first_path_size && i<last_path_size && last.path[i]=='/')
10610 {
10611 // case first='some/path' and last='some/path/more' => match is 'some/path'
10612 j=first_path_size;
10613 }
10614 else if (i==last_path_size && i<first_path_size && first.path[i]=='/')
10615 {
10616 // case first='some/path/more' and last='some/path' => match is 'some/path'
10617 j=last_path_size;
10618 }
10619
10620 // add non-common part of the path to the name
10621 for (auto &fileEntry : fileEntries)
10622 {
10623 QCString prefix = fileEntry.path.right(fileEntry.path.length()-j-1);
10624 fileEntry.fileDef->setName(prefix+fn->fileName());
10625 //printf("!!!!!!!! non unique disk name=%s:%s\n",qPrint(prefix),fn->fileName());
10626 fileEntry.fileDef->setDiskName(prefix+fn->fileName());
10627 }
10628 }
10629 }
10630}
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 9060 of file doxygen.cpp.

9061{
9062 AUTO_TRACE();
9063 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
9064 if (numThreads>1) // multi threaded processing
9065 {
9066 struct DocContext
9067 {
9068 DocContext(ClassDefMutable *cd_,const OutputList &ol_)
9069 : cd(cd_), ol(ol_) {}
9070 ClassDefMutable *cd;
9071 OutputList ol;
9072 };
9073 ThreadPool threadPool(numThreads);
9074 std::vector< std::future< std::shared_ptr<DocContext> > > results;
9075 for (const auto &cd : classList)
9076 {
9077 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9078 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9079 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9080 )
9081 {
9082 auto ctx = std::make_shared<DocContext>(cd,*g_outputList);
9083 auto processFile = [ctx]()
9084 {
9085 msg("Generating docs for compound {}...\n",ctx->cd->displayName());
9086
9087 // skip external references, anonymous compounds and
9088 // template instances
9089 if (!ctx->cd->isHidden() && !ctx->cd->isEmbeddedInOuterScope() &&
9090 ctx->cd->isLinkableInProject() && !ctx->cd->isImplicitTemplateInstance())
9091 {
9092 ctx->cd->writeDocumentation(ctx->ol);
9093 ctx->cd->writeMemberList(ctx->ol);
9094 }
9095
9096 // even for undocumented classes, the inner classes can be documented.
9097 ctx->cd->writeDocumentationForInnerClasses(ctx->ol);
9098 return ctx;
9099 };
9100 results.emplace_back(threadPool.queue(processFile));
9101 }
9102 }
9103 for (auto &f : results)
9104 {
9105 auto ctx = f.get();
9106 }
9107 }
9108 else // single threaded processing
9109 {
9110 for (const auto &cd : classList)
9111 {
9112 //printf("cd=%s getOuterScope=%p global=%p hidden=%d embeddedInOuterScope=%d\n",
9113 // qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope,cd->isHidden(),cd->isEmbeddedInOuterScope());
9114 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9115 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9116 )
9117 {
9118 // skip external references, anonymous compounds and
9119 // template instances
9120 if ( !cd->isHidden() && !cd->isEmbeddedInOuterScope() &&
9121 cd->isLinkableInProject() && !cd->isImplicitTemplateInstance())
9122 {
9123 msg("Generating docs for compound {}...\n",cd->displayName());
9124
9125 cd->writeDocumentation(*g_outputList);
9126 cd->writeMemberList(*g_outputList);
9127 }
9128 // even for undocumented classes, the inner classes can be documented.
9129 cd->writeDocumentationForInnerClasses(*g_outputList);
9130 }
9131 }
9132 }
9133}

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

Referenced by generateClassDocs().

◆ generateExampleDocs()

void generateExampleDocs ( )
static

Definition at line 10012 of file doxygen.cpp.

10013{
10014 g_outputList->disable(OutputType::Man);
10015 for (const auto &pd : *Doxygen::exampleLinkedMap)
10016 {
10017 msg("Generating docs for example {}...\n",pd->name());
10018 SrcLangExt lang = getLanguageFromFileName(pd->name(), SrcLangExt::Unknown);
10019 if (lang != SrcLangExt::Unknown)
10020 {
10021 QCString ext = getFileNameExtension(pd->name());
10022 auto intf = Doxygen::parserManager->getCodeParser(ext);
10023 intf->resetCodeParserState();
10024 }
10025 QCString n=pd->getOutputFileBase();
10026 startFile(*g_outputList,n,false,n,pd->name());
10028 g_outputList->docify(pd->name());
10030 g_outputList->startContents();
10031 QCString lineNoOptStr;
10032 if (pd->showLineNo())
10033 {
10034 lineNoOptStr="{lineno}";
10035 }
10036 g_outputList->generateDoc(pd->docFile(), // file
10037 pd->docLine(), // startLine
10038 pd.get(), // context
10039 nullptr, // memberDef
10040 (pd->briefDescription().isEmpty()?"":pd->briefDescription()+"\n\n")+
10041 pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
10042 DocOptions()
10043 .setIndexWords(true)
10044 .setExample(pd->name()));
10045 endFile(*g_outputList); // contains g_outputList->endContents()
10046 }
10048}
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:5164
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5206

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

8724{
8725 if (Index::instance().numDocumentedFiles()==0) return;
8726
8727 if (!Doxygen::inputNameLinkedMap->empty())
8728 {
8729 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8730 if (numThreads>1) // multi threaded processing
8731 {
8732 struct DocContext
8733 {
8734 DocContext(FileDef *fd_,const OutputList &ol_)
8735 : fd(fd_), ol(ol_) {}
8736 FileDef *fd;
8737 OutputList ol;
8738 };
8739 ThreadPool threadPool(numThreads);
8740 std::vector< std::future< std::shared_ptr<DocContext> > > results;
8741 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8742 {
8743 for (const auto &fd : *fn)
8744 {
8745 bool doc = fd->isLinkableInProject();
8746 if (doc)
8747 {
8748 auto ctx = std::make_shared<DocContext>(fd.get(),*g_outputList);
8749 auto processFile = [ctx]() {
8750 msg("Generating docs for file {}...\n",ctx->fd->docName());
8751 ctx->fd->writeDocumentation(ctx->ol);
8752 return ctx;
8753 };
8754 results.emplace_back(threadPool.queue(processFile));
8755 }
8756 }
8757 }
8758 for (auto &f : results)
8759 {
8760 auto ctx = f.get();
8761 }
8762 }
8763 else // single threaded processing
8764 {
8765 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8766 {
8767 for (const auto &fd : *fn)
8768 {
8769 bool doc = fd->isLinkableInProject();
8770 if (doc)
8771 {
8772 msg("Generating docs for file {}...\n",fd->docName());
8773 fd->writeDocumentation(*g_outputList);
8774 }
8775 }
8776 }
8777 }
8778 }
8779}

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

Referenced by generateOutput().

◆ generateFileSources()

void generateFileSources ( )
static

Definition at line 8557 of file doxygen.cpp.

8558{
8559 auto processSourceFile = [](FileDef *fd,OutputList &ol,ClangTUParser *parser)
8560 {
8561 bool showSources = fd->generateSourceFile() && !Htags::useHtags; // sources need to be shown in the output
8562 bool parseSources = !fd->isReference() && Doxygen::parseSourcesNeeded; // we needed to parse the sources even if we do not show them
8563 if (showSources)
8564 {
8565 msg("Generating code for file {}...\n",fd->docName());
8566 fd->writeSourceHeader(ol);
8567 fd->writeSourceBody(ol,parser);
8568 fd->writeSourceFooter(ol);
8569 }
8570 else if (parseSources)
8571 {
8572 msg("Parsing code for file {}...\n",fd->docName());
8573 fd->parseSource(parser);
8574 }
8575 };
8576 if (!Doxygen::inputNameLinkedMap->empty())
8577 {
8578#if USE_LIBCLANG
8580 {
8581 StringUnorderedSet processedFiles;
8582
8583 // create a dictionary with files to process
8584 StringUnorderedSet filesToProcess;
8585
8586 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8587 {
8588 for (const auto &fd : *fn)
8589 {
8590 filesToProcess.insert(fd->absFilePath().str());
8591 }
8592 }
8593 // process source files (and their include dependencies)
8594 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8595 {
8596 for (const auto &fd : *fn)
8597 {
8598 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp &&
8599 (fd->generateSourceFile() ||
8601 )
8602 )
8603 {
8604 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8605 clangParser->parse();
8606 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8607
8608 for (auto incFile : clangParser->filesInSameTU())
8609 {
8610 if (filesToProcess.find(incFile)!=filesToProcess.end() && // part of input
8611 fd->absFilePath()!=incFile && // not same file
8612 processedFiles.find(incFile)==processedFiles.end()) // not yet marked as processed
8613 {
8614 StringVector moreFiles;
8615 bool ambig = false;
8617 if (ifd && !ifd->isReference())
8618 {
8619 processSourceFile(ifd,*g_outputList,clangParser.get());
8620 processedFiles.insert(incFile);
8621 }
8622 }
8623 }
8624 processedFiles.insert(fd->absFilePath().str());
8625 }
8626 }
8627 }
8628 // process remaining files
8629 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8630 {
8631 for (const auto &fd : *fn)
8632 {
8633 if (processedFiles.find(fd->absFilePath().str())==processedFiles.end()) // not yet processed
8634 {
8635 if (fd->getLanguage()==SrcLangExt::Cpp) // C/C++ file, use clang parser
8636 {
8637 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8638 clangParser->parse();
8639 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8640 }
8641 else // non C/C++ file, use built-in parser
8642 {
8643 processSourceFile(fd.get(),*g_outputList,nullptr);
8644 }
8645 }
8646 }
8647 }
8648 }
8649 else
8650#endif
8651 {
8652 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8653 if (numThreads>1)
8654 {
8655 msg("Generating code files using {} threads.\n",numThreads);
8656 struct SourceContext
8657 {
8658 SourceContext(FileDef *fd_,bool gen_,const OutputList &ol_)
8659 : fd(fd_), generateSourceFile(gen_), ol(ol_) {}
8660 FileDef *fd;
8661 bool generateSourceFile;
8662 OutputList ol;
8663 };
8664 ThreadPool threadPool(numThreads);
8665 std::vector< std::future< std::shared_ptr<SourceContext> > > results;
8666 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8667 {
8668 for (const auto &fd : *fn)
8669 {
8670 bool generateSourceFile = fd->generateSourceFile() && !Htags::useHtags;
8671 auto ctx = std::make_shared<SourceContext>(fd.get(),generateSourceFile,*g_outputList);
8672 auto processFile = [ctx]()
8673 {
8674 if (ctx->generateSourceFile)
8675 {
8676 msg("Generating code for file {}...\n",ctx->fd->docName());
8677 }
8678 else
8679 {
8680 msg("Parsing code for file {}...\n",ctx->fd->docName());
8681 }
8682 StringVector filesInSameTu;
8683 ctx->fd->getAllIncludeFilesRecursively(filesInSameTu);
8684 if (ctx->generateSourceFile) // sources need to be shown in the output
8685 {
8686 ctx->fd->writeSourceHeader(ctx->ol);
8687 ctx->fd->writeSourceBody(ctx->ol,nullptr);
8688 ctx->fd->writeSourceFooter(ctx->ol);
8689 }
8690 else if (!ctx->fd->isReference() && Doxygen::parseSourcesNeeded)
8691 // we needed to parse the sources even if we do not show them
8692 {
8693 ctx->fd->parseSource(nullptr);
8694 }
8695 return ctx;
8696 };
8697 results.emplace_back(threadPool.queue(processFile));
8698 }
8699 }
8700 for (auto &f : results)
8701 {
8702 auto ctx = f.get();
8703 }
8704 }
8705 else // single threaded version
8706 {
8707 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8708 {
8709 for (const auto &fd : *fn)
8710 {
8711 StringVector filesInSameTu;
8712 fd->getAllIncludeFilesRecursively(filesInSameTu);
8713 processSourceFile(fd.get(),*g_outputList,nullptr);
8714 }
8715 }
8716 }
8717 }
8718 }
8719}
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:137
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 10053 of file doxygen.cpp.

10054{
10055 for (const auto &gd : *Doxygen::groupLinkedMap)
10056 {
10057 if (!gd->isReference())
10058 {
10059 gd->writeDocumentation(*g_outputList);
10060 }
10061 }
10062}

References g_outputList, and Doxygen::groupLinkedMap.

Referenced by generateOutput().

◆ generateNamespaceClassDocs()

void generateNamespaceClassDocs ( const ClassLinkedRefMap & classList)
static

Definition at line 10067 of file doxygen.cpp.

10068{
10069 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10070 if (numThreads>1) // multi threaded processing
10071 {
10072 struct DocContext
10073 {
10074 DocContext(ClassDefMutable *cdm_,const OutputList &ol_)
10075 : cdm(cdm_), ol(ol_) {}
10076 ClassDefMutable *cdm;
10077 OutputList ol;
10078 };
10079 ThreadPool threadPool(numThreads);
10080 std::vector< std::future< std::shared_ptr<DocContext> > > results;
10081 // for each class in the namespace...
10082 for (const auto &cd : classList)
10083 {
10085 if (cdm)
10086 {
10087 auto ctx = std::make_shared<DocContext>(cdm,*g_outputList);
10088 auto processFile = [ctx]()
10089 {
10090 if ( ( ctx->cdm->isLinkableInProject() &&
10091 !ctx->cdm->isImplicitTemplateInstance()
10092 ) // skip external references, anonymous compounds and
10093 // template instances and nested classes
10094 && !ctx->cdm->isHidden() && !ctx->cdm->isEmbeddedInOuterScope()
10095 )
10096 {
10097 msg("Generating docs for compound {}...\n",ctx->cdm->displayName());
10098 ctx->cdm->writeDocumentation(ctx->ol);
10099 ctx->cdm->writeMemberList(ctx->ol);
10100 }
10101 ctx->cdm->writeDocumentationForInnerClasses(ctx->ol);
10102 return ctx;
10103 };
10104 results.emplace_back(threadPool.queue(processFile));
10105 }
10106 }
10107 // wait for the results
10108 for (auto &f : results)
10109 {
10110 auto ctx = f.get();
10111 }
10112 }
10113 else // single threaded processing
10114 {
10115 // for each class in the namespace...
10116 for (const auto &cd : classList)
10117 {
10119 if (cdm)
10120 {
10121 if ( ( cd->isLinkableInProject() &&
10122 !cd->isImplicitTemplateInstance()
10123 ) // skip external references, anonymous compounds and
10124 // template instances and nested classes
10125 && !cd->isHidden() && !cd->isEmbeddedInOuterScope()
10126 )
10127 {
10128 msg("Generating docs for compound {}...\n",cd->displayName());
10129
10132 }
10134 }
10135 }
10136 }
10137}
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 10139 of file doxygen.cpp.

10140{
10141 // for each concept in the namespace...
10142 for (const auto &cd : conceptList)
10143 {
10145 if ( cdm && cd->isLinkableInProject() && !cd->isHidden())
10146 {
10147 msg("Generating docs for concept {}...\n",cd->name());
10149 }
10150 }
10151}

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

Referenced by generateNamespaceDocs().

◆ generateNamespaceDocs()

void generateNamespaceDocs ( )
static

Definition at line 10153 of file doxygen.cpp.

10154{
10155 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
10156
10157 //writeNamespaceIndex(*g_outputList);
10158
10159 // for each namespace...
10160 for (const auto &nd : *Doxygen::namespaceLinkedMap)
10161 {
10162 if (nd->isLinkableInProject())
10163 {
10165 if (ndm)
10166 {
10167 msg("Generating docs for namespace {}\n",nd->displayName());
10169 }
10170 }
10171
10172 generateNamespaceClassDocs(nd->getClasses());
10173 if (sliceOpt)
10174 {
10175 generateNamespaceClassDocs(nd->getInterfaces());
10176 generateNamespaceClassDocs(nd->getStructs());
10177 generateNamespaceClassDocs(nd->getExceptions());
10178 }
10179 generateNamespaceConceptDocs(nd->getConcepts());
10180 }
10181}
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 13105 of file doxygen.cpp.

13106{
13107 AUTO_TRACE();
13108 /**************************************************************************
13109 * Initialize output generators *
13110 **************************************************************************/
13111
13112 /// add extra languages for which we can only produce syntax highlighted code
13114
13115 //// dump all symbols
13116 if (g_dumpSymbolMap)
13117 {
13118 dumpSymbolMap();
13119 exit(0);
13120 }
13121
13122 bool generateHtml = Config_getBool(GENERATE_HTML);
13123 bool generateLatex = Config_getBool(GENERATE_LATEX);
13124 bool generateMan = Config_getBool(GENERATE_MAN);
13125 bool generateRtf = Config_getBool(GENERATE_RTF);
13126 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
13127
13128
13130 if (generateHtml)
13131 {
13135 }
13136 if (generateLatex)
13137 {
13140 }
13141 if (generateDocbook)
13142 {
13145 }
13146 if (generateMan)
13147 {
13148 g_outputList->add<ManGenerator>();
13150 }
13151 if (generateRtf)
13152 {
13153 g_outputList->add<RTFGenerator>();
13155 }
13156 if (Config_getBool(USE_HTAGS))
13157 {
13159 QCString htmldir = Config_getString(HTML_OUTPUT);
13160 if (!Htags::execute(htmldir))
13161 err("USE_HTAGS is YES but htags(1) failed. \n");
13162 else if (!Htags::loadFilemap(htmldir))
13163 err("htags(1) ended normally but failed to load the filemap. \n");
13164 }
13165
13166 /**************************************************************************
13167 * Generate documentation *
13168 **************************************************************************/
13169
13170 g_s.begin("Generating style sheet...\n");
13171 //printf("writing style info\n");
13172 g_outputList->writeStyleInfo(0); // write first part
13173 g_s.end();
13174
13175 bool searchEngine = Config_getBool(SEARCHENGINE);
13176 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
13177
13178 g_s.begin("Generating search indices...\n");
13179 if (searchEngine && !serverBasedSearch && generateHtml)
13180 {
13182 }
13183
13184 // generate search indices (need to do this before writing other HTML
13185 // pages as these contain a drop down menu with options depending on
13186 // what categories we find in this function.
13187 if (generateHtml && searchEngine)
13188 {
13189 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
13190 Dir searchDir(searchDirName.str());
13191 if (!searchDir.exists() && !searchDir.mkdir(searchDirName.str()))
13192 {
13193 term("Could not create search results directory '{}' $PWD='{}'\n",
13194 searchDirName,Dir::currentDirPath());
13195 }
13196 HtmlGenerator::writeSearchData(searchDirName);
13197 if (!serverBasedSearch) // client side search index
13198 {
13200 }
13201 }
13202 g_s.end();
13203
13204 // copy static stuff
13205 if (generateHtml)
13206 {
13208 copyLogo(Config_getString(HTML_OUTPUT));
13209 copyIcon(Config_getString(HTML_OUTPUT));
13210 copyExtraFiles(Config_getList(HTML_EXTRA_FILES),"HTML_EXTRA_FILES",Config_getString(HTML_OUTPUT));
13211 }
13212 if (generateLatex)
13213 {
13215 copyLogo(Config_getString(LATEX_OUTPUT));
13216 copyIcon(Config_getString(LATEX_OUTPUT));
13217 copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT));
13218 }
13219 if (generateDocbook)
13220 {
13221 copyLogo(Config_getString(DOCBOOK_OUTPUT));
13222 copyIcon(Config_getString(DOCBOOK_OUTPUT));
13223 }
13224 if (generateRtf)
13225 {
13226 copyLogo(Config_getString(RTF_OUTPUT));
13227 copyIcon(Config_getString(RTF_OUTPUT));
13228 copyExtraFiles(Config_getList(RTF_EXTRA_FILES),"RTF_EXTRA_FILES",Config_getString(RTF_OUTPUT));
13229 }
13230
13232 if (fm.hasFormulas() && generateHtml
13233 && !Config_getBool(USE_MATHJAX))
13234 {
13235 g_s.begin("Generating images for formulas in HTML...\n");
13236 fm.generateImages(Config_getString(HTML_OUTPUT), Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg ?
13238 g_s.end();
13239 }
13240 if (fm.hasFormulas() && generateRtf)
13241 {
13242 g_s.begin("Generating images for formulas in RTF...\n");
13244 g_s.end();
13245 }
13246
13247 if (fm.hasFormulas() && generateDocbook)
13248 {
13249 g_s.begin("Generating images for formulas in Docbook...\n");
13251 g_s.end();
13252 }
13253
13254 g_s.begin("Generating example documentation...\n");
13256 g_s.end();
13257
13258 g_s.begin("Generating file sources...\n");
13260 g_s.end();
13261
13262 g_s.begin("Generating file documentation...\n");
13264 g_s.end();
13265
13266 g_s.begin("Generating page documentation...\n");
13268 g_s.end();
13269
13270 g_s.begin("Generating group documentation...\n");
13272 g_s.end();
13273
13274 g_s.begin("Generating class documentation...\n");
13276 g_s.end();
13277
13278 g_s.begin("Generating concept documentation...\n");
13280 g_s.end();
13281
13282 g_s.begin("Generating module documentation...\n");
13284 g_s.end();
13285
13286 g_s.begin("Generating namespace documentation...\n");
13288 g_s.end();
13289
13290 if (Config_getBool(GENERATE_LEGEND))
13291 {
13292 g_s.begin("Generating graph info page...\n");
13294 g_s.end();
13295 }
13296
13297 g_s.begin("Generating directory documentation...\n");
13299 g_s.end();
13300
13301 if (g_outputList->size()>0)
13302 {
13304 }
13305
13306 g_s.begin("finalizing index lists...\n");
13307 Doxygen::indexList->finalize();
13308 g_s.end();
13309
13310 g_s.begin("writing tag file...\n");
13311 writeTagFile();
13312 g_s.end();
13313
13314 if (Config_getBool(GENERATE_XML))
13315 {
13316 g_s.begin("Generating XML output...\n");
13318 generateXML();
13320 g_s.end();
13321 }
13322 if (Config_getBool(GENERATE_SQLITE3))
13323 {
13324 g_s.begin("Generating SQLITE3 output...\n");
13326 g_s.end();
13327 }
13328
13329 if (Config_getBool(GENERATE_AUTOGEN_DEF))
13330 {
13331 g_s.begin("Generating AutoGen DEF output...\n");
13332 generateDEF();
13333 g_s.end();
13334 }
13335 if (Config_getBool(GENERATE_PERLMOD))
13336 {
13337 g_s.begin("Generating Perl module output...\n");
13339 g_s.end();
13340 }
13341 if (generateHtml && searchEngine && serverBasedSearch)
13342 {
13343 g_s.begin("Generating search index\n");
13344 if (Doxygen::searchIndex.kind()==SearchIndexIntf::Internal) // write own search index
13345 {
13347 Doxygen::searchIndex.write(Config_getString(HTML_OUTPUT)+"/search/search.idx");
13348 }
13349 else // write data for external search index
13350 {
13352 QCString searchDataFile = Config_getString(SEARCHDATA_FILE);
13353 if (searchDataFile.isEmpty())
13354 {
13355 searchDataFile="searchdata.xml";
13356 }
13357 if (!Portable::isAbsolutePath(searchDataFile.data()))
13358 {
13359 searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/");
13360 }
13361 Doxygen::searchIndex.write(searchDataFile);
13362 }
13363 g_s.end();
13364 }
13365
13366 if (generateRtf)
13367 {
13368 g_s.begin("Combining RTF output...\n");
13369 if (!RTFGenerator::preProcessFileInplace(Config_getString(RTF_OUTPUT),"refman.rtf"))
13370 {
13371 err("An error occurred during post-processing the RTF files!\n");
13372 }
13373 g_s.end();
13374 }
13375
13376 g_s.begin("Running plantuml with JAVA...\n");
13378 g_s.end();
13379
13380 if (Config_getBool(HAVE_DOT))
13381 {
13382 g_s.begin("Running dot...\n");
13384 g_s.end();
13385 }
13386
13387 if (generateHtml &&
13388 Config_getBool(GENERATE_HTMLHELP) &&
13389 !Config_getString(HHC_LOCATION).isEmpty())
13390 {
13391 g_s.begin("Running html help compiler...\n");
13393 g_s.end();
13394 }
13395
13396 if ( generateHtml &&
13397 Config_getBool(GENERATE_QHP) &&
13398 !Config_getString(QHG_LOCATION).isEmpty())
13399 {
13400 g_s.begin("Running qhelpgenerator...\n");
13402 g_s.end();
13403 }
13404
13405 g_outputList->cleanup();
13407
13408 msg("type lookup cache used {}/{} hits={} misses={}\n",
13410 Doxygen::typeLookupCache->capacity(),
13412 Doxygen::typeLookupCache->misses());
13413 msg("symbol lookup cache used {}/{} hits={} misses={}\n",
13415 Doxygen::symbolLookupCache->capacity(),
13417 Doxygen::symbolLookupCache->misses());
13418 int typeCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::typeLookupCache->misses()*2/3)); // part of the cache is flushed, hence the 2/3 correction factor
13419 int symbolCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::symbolLookupCache->misses()));
13420 int cacheParam = std::max(typeCacheParam,symbolCacheParam);
13421 if (cacheParam>Config_getInt(LOOKUP_CACHE_SIZE))
13422 {
13423 msg("Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is {} at the cost of higher memory usage.\n",cacheParam);
13424 }
13425
13427 {
13428
13429 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
13430 if (numThreads<1) numThreads=1;
13431 msg("Total elapsed time: {:.6f} seconds\n(of which an average of {:.6f} seconds per thread waiting for external tools to finish)\n",
13432 (static_cast<double>(Debug::elapsedTime())),
13433 Portable::getSysElapsedTime()/static_cast<double>(numThreads)
13434 );
13435 g_s.print();
13436
13438 msg("finished...\n");
13440 }
13441 else
13442 {
13443 msg("finished...\n");
13444 }
13445
13446
13447 /**************************************************************************
13448 * Start cleaning up *
13449 **************************************************************************/
13450
13452
13454 Dir thisDir;
13455 thisDir.remove(Doxygen::filterDBFileName.str());
13457 exitTracing();
13459 delete Doxygen::clangUsrMap;
13461
13462 //dumpDocNodeSizes();
13463}
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
static double elapsedTime()
Definition debug.cpp:200
static void setFlag(const DebugMask mask)
Definition debug.cpp:117
static std::string currentDirPath()
Definition dir.cpp: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:127
static bool generatingXmlOutput
Definition doxygen.h:135
static ClangUsrMap * clangUsrMap
Definition doxygen.h:125
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:1193
static void writeSearchPage()
Definition htmlgen.cpp:3160
static void writeTabData()
Additional initialization after indices have been created.
Definition htmlgen.cpp:1344
static void writeSearchData(const QCString &dir)
Definition htmlgen.cpp:1353
static void writeExternalSearchPage()
Definition htmlgen.cpp:3259
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()
static void dumpSymbolMap()
static void generateFileDocs()
Definition doxygen.cpp:8723
static void copyIcon(const QCString &outputOption)
static void generatePageDocs()
Definition doxygen.cpp:9927
static void generateFileSources()
Definition doxygen.cpp:8557
static void copyLogo(const QCString &outputOption)
static void generateClassDocs()
Definition doxygen.cpp:9158
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:9184
void writeGraphInfo(OutputList &ol)
Definition index.cpp:4066
void writeIndexHierarchy(OutputList &ol)
Definition index.cpp:5780
void finishWarnExit()
Definition message.cpp:294
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:5158
void cleanupInlineGraph()
Definition util.cpp:6959
void generateXML()
Definition xmlgen.cpp:2231

References addCodeOnlyMappings(), AUTO_TRACE, FormulaManager::Bitmap, Doxygen::clangUsrMap, cleanUpDoxygen(), cleanupInlineGraph(), 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 9927 of file doxygen.cpp.

9928{
9929 //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageLinkedMap->count());
9930 if (Index::instance().numDocumentedPages()==0) return;
9931 for (const auto &pd : *Doxygen::pageLinkedMap)
9932 {
9933 if (!pd->getGroupDef() && !pd->isReference())
9934 {
9935 msg("Generating docs for page {}...\n",pd->name());
9936 pd->writeDocumentation(*g_outputList);
9937 }
9938 }
9939}

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

Referenced by generateOutput().

◆ generateXRefPages()

void generateXRefPages ( )
static

Definition at line 5548 of file doxygen.cpp.

5549{
5550 AUTO_TRACE();
5552 {
5553 rl->generatePage();
5554 }
5555}
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 11355 of file doxygen.cpp.

11356{
11357 char *s=nullptr;
11358 if (qstrlen(&argv[optInd][2])>0)
11359 s=&argv[optInd][2];
11360 else if (optInd+1<argc && argv[optInd+1][0]!='-')
11361 s=argv[++optInd];
11362 return s;
11363}
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 10636 of file doxygen.cpp.

10637{
10638 QCString fileName=fn;
10639 QCString extension;
10640 int sep = fileName.findRev('/');
10641 int ei = fileName.findRev('.');
10642 if (ei!=-1 && (sep==-1 || ei>sep)) // matches dir/file.ext but not dir.1/file
10643 {
10644 extension=fileName.right(fileName.length()-ei);
10645 }
10646 else
10647 {
10648 extension = ".no_extension";
10649 }
10650
10651 return Doxygen::parserManager->getOutlineParser(extension);
10652}

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

4481{
4482 std::map<std::string,int> templateNames;
4483 int count=0;
4484 for (const Argument &arg : templateArguments)
4485 {
4486 static const reg::Ex re(R"(\a[\w:]*)");
4487 reg::Iterator it(name,re);
4489 for (; it!=end ; ++it)
4490 {
4491 const auto &match = *it;
4492 std::string n = match.str();
4493 if (n==arg.name.str())
4494 {
4495 if (templateNames.find(n)==templateNames.end())
4496 {
4497 templateNames.emplace(n,count);
4498 }
4499 }
4500 }
4501 }
4502 return templateNames;
4503}

References end().

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

◆ haveEqualFileNames()

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

Definition at line 9513 of file doxygen.cpp.

9514{
9515 if (const FileDef *fd = md->getFileDef())
9516 {
9517 return fd->absFilePath() == root->fileName;
9518 }
9519 return false;
9520}

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

Referenced by findDefineDocumentation().

◆ inheritDocumentation()

void inheritDocumentation ( )
static

Definition at line 9205 of file doxygen.cpp.

9206{
9207 for (const auto &mn : *Doxygen::memberNameLinkedMap)
9208 {
9209 for (const auto &imd : *mn)
9210 {
9211 MemberDefMutable *md = toMemberDefMutable(imd.get());
9212 //static int count=0;
9213 //printf("%04d Member '%s'\n",count++,qPrint(md->qualifiedName()));
9214 if (md && md->documentation().isEmpty() && md->briefDescription().isEmpty())
9215 { // no documentation yet
9216 const MemberDef *bmd = md->reimplements();
9217 while (bmd && bmd->documentation().isEmpty() &&
9218 bmd->briefDescription().isEmpty()
9219 )
9220 { // search up the inheritance tree for a documentation member
9221 //printf("bmd=%s class=%s\n",qPrint(bmd->name()),qPrint(bmd->getClassDef()->name()));
9222 bmd = bmd->reimplements();
9223 }
9224 if (bmd) // copy the documentation from the reimplemented member
9225 {
9226 md->setInheritsDocsFrom(bmd);
9227 md->setDocumentation(bmd->documentation(),bmd->docFile(),bmd->docLine());
9229 md->setBriefDescription(bmd->briefDescription(),bmd->briefFile(),bmd->briefLine());
9230 md->copyArgumentNames(bmd);
9232 }
9233 }
9234 }
9235 }
9236}
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 11382 of file doxygen.cpp.

11383{
11384 initResources();
11385 QCString lang = Portable::getenv("LC_ALL");
11386 if (!lang.isEmpty()) Portable::setenv("LANG",lang);
11387 std::setlocale(LC_ALL,"");
11388 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
11389 std::setlocale(LC_NUMERIC,"C");
11390
11392
11416
11417 // register any additional parsers here...
11418
11420
11421#if USE_LIBCLANG
11423#endif
11432 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
11433 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
11434 //Doxygen::tagDestinationDict.setAutoDelete(TRUE);
11436
11437 // initialization of these globals depends on
11438 // configuration switches so we need to postpone these
11439 Doxygen::globalScope = nullptr;
11448
11449}
static void startTimer()
Definition debug.cpp:195
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:183
std::function< std::unique_ptr< T >() > make_parser_factory()
void initResources()
std::unordered_map< std::string, const Definition * > ClangUsrMap
Definition doxygen.h:82
void setenv(const QCString &variable, const QCString &value)
Definition portable.cpp:287
QCString getenv(const QCString &variable)
Definition portable.cpp:322
void initDefaultExtensionMapping()
Definition util.cpp:5091

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

6655{
6656 if (outerScope && outerScope!=Doxygen::globalScope)
6657 {
6658 auto aliasMd = createMemberDefAlias(outerScope,md);
6659 if (outerScope->definitionType()==Definition::TypeClass)
6660 {
6661 ClassDefMutable *cdm = toClassDefMutable(outerScope);
6662 if (cdm)
6663 {
6664 cdm->insertMember(aliasMd.get());
6665 }
6666 }
6667 else if (outerScope->definitionType()==Definition::TypeNamespace)
6668 {
6669 NamespaceDefMutable *ndm = toNamespaceDefMutable(outerScope);
6670 if (ndm)
6671 {
6672 ndm->insertMember(aliasMd.get());
6673 }
6674 }
6675 else if (outerScope->definitionType()==Definition::TypeFile)
6676 {
6677 toFileDef(outerScope)->insertMember(aliasMd.get());
6678 }
6679 if (aliasMd)
6680 {
6681 Doxygen::functionNameLinkedMap->add(md->name())->push_back(std::move(aliasMd));
6682 }
6683 }
6684}
FileDef * toFileDef(Definition *d)
Definition filedef.cpp:1951

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

5215{
5216 if ( !root->name.isEmpty() )
5217 {
5218 if (root->section.isCompound())
5219 // is it a compound (class, struct, union, interface ...)
5220 {
5221 return TRUE;
5222 }
5223 else if (root->section.isCompoundDoc())
5224 // is it a documentation block with inheritance info.
5225 {
5226 bool hasExtends = !root->extends.empty();
5227 if (hasExtends) return TRUE;
5228 }
5229 }
5230 return FALSE;
5231}

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

5728{
5729 const GroupDef *gd = md->getGroupDef();
5730 if (!gd)
5731 {
5732 return allowNoGroup;
5733 }
5734
5735 for (const auto &g : root->groups)
5736 {
5737 if (g.groupname == gd->name())
5738 {
5739 return true; // matching group
5740 }
5741 }
5742
5743 return false;
5744}

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

4832{
4833 QCString n=name;
4834 int index=n.find('<');
4835 if (index!=-1)
4836 {
4837 n=n.left(index);
4838 }
4839 bool result = rightScopeMatch(scope,n);
4840 return result;
4841}

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

Referenced by findClassRelation().

◆ isSpecialization()

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

Definition at line 5958 of file doxygen.cpp.

5962{
5963 auto srcIt = srcTempArgLists.begin();
5964 auto dstIt = dstTempArgLists.begin();
5965 while (srcIt!=srcTempArgLists.end() && dstIt!=dstTempArgLists.end())
5966 {
5967 if ((*srcIt).size()!=(*dstIt).size()) return TRUE;
5968 ++srcIt;
5969 ++dstIt;
5970 }
5971 return FALSE;
5972}

References FALSE, and TRUE.

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

◆ isSymbolHidden()

bool isSymbolHidden ( const Definition * d)
static

Definition at line 8952 of file doxygen.cpp.

8953{
8954 bool hidden = d->isHidden();
8955 const Definition *parent = d->getOuterScope();
8956 return parent ? hidden || isSymbolHidden(parent) : hidden;
8957}
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 2919 of file doxygen.cpp.

2920{
2921 bool result = false;
2922 bool typeIsClass = false;
2923 bool typePtrType = false;
2924 QCString type;
2925 Definition *ctx = nullptr;
2926 FileDef *fd = root->fileDef();
2927 SymbolResolver resolver(fd);
2928
2929 AUTO_TRACE("isVarWithConstructor({})",root->name);
2930 if (root->parent()->section.isCompound())
2931 { // inside a class
2932 result=FALSE;
2933 AUTO_TRACE_EXIT("inside class: result={}",result);
2934 return result;
2935 }
2936 else if ((fd != nullptr) && (fd->name().endsWith(".c") || fd->name().endsWith(".h")))
2937 { // inside a .c file
2938 result=FALSE;
2939 AUTO_TRACE_EXIT("inside C file: result={}",result);
2940 return result;
2941 }
2942 if (root->type.isEmpty())
2943 {
2944 result=FALSE;
2945 AUTO_TRACE_EXIT("no type: result={}",result);
2946 return result;
2947 }
2948 if (!root->parent()->name.isEmpty())
2949 {
2950 ctx=Doxygen::namespaceLinkedMap->find(root->parent()->name);
2951 }
2952 type = root->type;
2953 // remove qualifiers
2954 findAndRemoveWord(type,"const");
2955 findAndRemoveWord(type,"static");
2956 findAndRemoveWord(type,"volatile");
2957 typePtrType = type.find('*')!=-1 || type.find('&')!=-1;
2958 if (!typePtrType)
2959 {
2960 typeIsClass = resolver.resolveClass(ctx,type)!=nullptr;
2961 int ti=0;
2962 if (!typeIsClass && (ti=type.find('<'))!=-1)
2963 {
2964 typeIsClass=resolver.resolveClass(ctx,type.left(ti))!=nullptr;
2965 }
2966 }
2967 if (typeIsClass) // now we still have to check if the arguments are
2968 // types or values. Since we do not have complete type info
2969 // we need to rely on heuristics :-(
2970 {
2971 if (root->argList.empty())
2972 {
2973 result=FALSE; // empty arg list -> function prototype.
2974 AUTO_TRACE_EXIT("empty arg list: result={}",result);
2975 return result;
2976 }
2977 for (const Argument &a : root->argList)
2978 {
2979 static const reg::Ex initChars(R"([\d"'&*!^]+)");
2981 if (!a.name.isEmpty() || !a.defval.isEmpty())
2982 {
2983 std::string name = a.name.str();
2984 if (reg::search(name,match,initChars) && match.position()==0)
2985 {
2986 result=TRUE;
2987 }
2988 else
2989 {
2990 result=FALSE; // arg has (type,name) pair -> function prototype
2991 }
2992 AUTO_TRACE_EXIT("function prototype: result={}",result);
2993 return result;
2994 }
2995 if (!a.type.isEmpty() &&
2996 (a.type.at(a.type.length()-1)=='*' ||
2997 a.type.at(a.type.length()-1)=='&'))
2998 // type ends with * or & => pointer or reference
2999 {
3000 result=FALSE;
3001 AUTO_TRACE_EXIT("pointer or reference: result={}",result);
3002 return result;
3003 }
3004 if (a.type.isEmpty() || resolver.resolveClass(ctx,a.type)!=nullptr)
3005 {
3006 result=FALSE; // arg type is a known type
3007 AUTO_TRACE_EXIT("known type: result={}",result);
3008 return result;
3009 }
3010 if (checkIfTypedef(ctx,fd,a.type))
3011 {
3012 result=FALSE; // argument is a typedef
3013 AUTO_TRACE_EXIT("typedef: result={}",result);
3014 return result;
3015 }
3016 std::string atype = a.type.str();
3017 if (reg::search(atype,match,initChars) && match.position()==0)
3018 {
3019 result=TRUE; // argument type starts with typical initializer char
3020 AUTO_TRACE_EXIT("argument with init char: result={}",result);
3021 return result;
3022 }
3023 std::string resType=resolveTypeDef(ctx,a.type).str();
3024 if (resType.empty()) resType=atype;
3025 static const reg::Ex idChars(R"(\a\w*)");
3026 if (reg::search(resType,match,idChars) && match.position()==0) // resType starts with identifier
3027 {
3028 resType=match.str();
3029 if (resType=="int" || resType=="long" ||
3030 resType=="float" || resType=="double" ||
3031 resType=="char" || resType=="void" ||
3032 resType=="signed" || resType=="unsigned" ||
3033 resType=="const" || resType=="volatile" )
3034 {
3035 result=FALSE; // type keyword -> function prototype
3036 AUTO_TRACE_EXIT("type keyword: result={}",result);
3037 return result;
3038 }
3039 }
3040 }
3041 result=TRUE;
3042 }
3043
3044 AUTO_TRACE_EXIT("end: result={}",result);
3045 return result;
3046}
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:5268
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:4940

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

11378{
11379 return []() { return std::make_unique<T>(); };
11380}

Referenced by initDoxygen().

◆ makeTemplateInstanceRelation()

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

Definition at line 5288 of file doxygen.cpp.

5289{
5290 AUTO_TRACE("root->name={} cd={}",root->name,cd->name());
5291 int i = root->name.find('<');
5292 int j = root->name.findRev('>');
5293 int k = root->name.find("::",j+1); // A<T::B> => ok, A<T>::B => nok
5294 if (i!=-1 && j!=-1 && k==-1 && root->lang!=SrcLangExt::CSharp && root->lang!=SrcLangExt::Java)
5295 {
5296 ClassDefMutable *master = getClassMutable(root->name.left(i));
5297 if (master && master!=cd && !cd->templateMaster())
5298 {
5299 AUTO_TRACE_ADD("class={} master={}",cd->name(),cd->templateMaster()?cd->templateMaster()->name():"<none>",master->name());
5300 cd->setTemplateMaster(master);
5301 master->insertExplicitTemplateInstance(cd,root->name.mid(i));
5302 }
5303 }
5304}
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 8505 of file doxygen.cpp.

8506{
8507 AUTO_TRACE();
8508 // merge members of categories into the class they extend
8509 for (const auto &cd : *Doxygen::classLinkedMap)
8510 {
8511 int i=cd->name().find('(');
8512 if (i!=-1) // it is an Objective-C category
8513 {
8514 QCString baseName=cd->name().left(i);
8515 ClassDefMutable *baseClass=toClassDefMutable(Doxygen::classLinkedMap->find(baseName));
8516 if (baseClass)
8517 {
8518 AUTO_TRACE_ADD("merging members of category {} into {}",cd->name(),baseClass->name());
8519 baseClass->mergeCategory(cd.get());
8520 }
8521 }
8522 }
8523}
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 10654 of file doxygen.cpp.

10657{
10658 QCString fileName=fn;
10659 AUTO_TRACE("fileName={}",fileName);
10660 QCString extension;
10661 int ei = fileName.findRev('.');
10662 if (ei!=-1)
10663 {
10664 extension=fileName.right(fileName.length()-ei);
10665 }
10666 else
10667 {
10668 extension = ".no_extension";
10669 }
10670
10671 FileInfo fi(fileName.str());
10672 std::string preBuf;
10673
10674 if (Config_getBool(ENABLE_PREPROCESSING) &&
10675 parser.needsPreprocessing(extension))
10676 {
10677 Preprocessor preprocessor;
10678 const StringVector &includePath = Config_getList(INCLUDE_PATH);
10679 for (const auto &s : includePath)
10680 {
10681 std::string absPath = FileInfo(s).absFilePath();
10682 preprocessor.addSearchDir(absPath);
10683 }
10684 std::string inBuf;
10685 msg("Preprocessing {}...\n",fn);
10686 readInputFile(fileName,inBuf);
10687 addTerminalCharIfMissing(inBuf,'\n');
10688 preprocessor.processFile(fileName,inBuf,preBuf);
10689 }
10690 else // no preprocessing
10691 {
10692 msg("Reading {}...\n",fn);
10693 readInputFile(fileName,preBuf);
10694 addTerminalCharIfMissing(preBuf,'\n');
10695 }
10696
10697 std::string convBuf;
10698 convBuf.reserve(preBuf.size()+1024);
10699
10700 // convert multi-line C++ comments to C style comments
10701 convertCppComments(preBuf,convBuf,fileName.str());
10702
10703 std::shared_ptr<Entry> fileRoot = std::make_shared<Entry>();
10704 // use language parse to parse the file
10705 if (clangParser)
10706 {
10707 if (newTU) clangParser->parse();
10708 clangParser->switchToFile(fd);
10709 }
10710 parser.parseInput(fileName,convBuf.data(),fileRoot,clangParser);
10711 fileRoot->setFileDef(fd);
10712 return fileRoot;
10713}
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:4153
void addSearchDir(const QCString &dir)
Definition pre.l:4135
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:5503

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

10717{
10718 AUTO_TRACE();
10719#if USE_LIBCLANG
10721 {
10722 StringUnorderedSet processedFiles;
10723
10724 // create a dictionary with files to process
10725 StringUnorderedSet filesToProcess;
10726 for (const auto &s : g_inputFiles)
10727 {
10728 filesToProcess.insert(s);
10729 }
10730
10731 std::mutex processedFilesLock;
10732 // process source files (and their include dependencies)
10733 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10734 msg("Processing input using {} threads.\n",numThreads);
10735 ThreadPool threadPool(numThreads);
10736 using FutureType = std::vector< std::shared_ptr<Entry> >;
10737 std::vector< std::future< FutureType > > results;
10738 for (const auto &s : g_inputFiles)
10739 {
10740 bool ambig = false;
10741 QCString qs = s;
10743 ASSERT(fd!=nullptr);
10744 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp) // this is a source file
10745 {
10746 // lambda representing the work to executed by a thread
10747 auto processFile = [qs,&filesToProcess,&processedFilesLock,&processedFiles]() {
10748 bool ambig_l = false;
10749 std::vector< std::shared_ptr<Entry> > roots;
10751 auto clangParser = ClangParser::instance()->createTUParser(fd_l);
10752 auto parser = getParserForFile(qs);
10753 auto fileRoot { parseFile(*parser.get(),fd_l,qs,clangParser.get(),true) };
10754 roots.push_back(fileRoot);
10755
10756 // Now process any include files in the same translation unit
10757 // first. When libclang is used this is much more efficient.
10758 for (auto incFile : clangParser->filesInSameTU())
10759 {
10760 QCString qincFile = incFile;
10761 if (filesToProcess.find(incFile)!=filesToProcess.end())
10762 {
10763 bool needsToBeProcessed = false;
10764 {
10765 std::lock_guard<std::mutex> lock(processedFilesLock);
10766 needsToBeProcessed = processedFiles.find(incFile)==processedFiles.end();
10767 if (needsToBeProcessed) processedFiles.insert(incFile);
10768 }
10769 if (qincFile!=qs && needsToBeProcessed)
10770 {
10771 FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,qincFile,ambig_l);
10772 if (ifd && !ifd->isReference())
10773 {
10774 //printf(" Processing %s in same translation unit as %s\n",incFile,qPrint(s));
10775 fileRoot = parseFile(*parser.get(),ifd,qincFile,clangParser.get(),false);
10776 roots.push_back(fileRoot);
10777 }
10778 }
10779 }
10780 }
10781 return roots;
10782 };
10783 // dispatch the work and collect the future results
10784 results.emplace_back(threadPool.queue(processFile));
10785 }
10786 }
10787 // synchronize with the Entry result lists produced and add them to the root
10788 for (auto &f : results)
10789 {
10790 auto l = f.get();
10791 for (auto &e : l)
10792 {
10793 root->moveToSubEntryAndKeep(e);
10794 }
10795 }
10796 // process remaining files
10797 results.clear();
10798 for (const auto &s : g_inputFiles)
10799 {
10800 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
10801 {
10802 // lambda representing the work to executed by a thread
10803 auto processFile = [s]() {
10804 bool ambig = false;
10805 QCString qs = s;
10806 std::vector< std::shared_ptr<Entry> > roots;
10808 auto parser { getParserForFile(qs) };
10809 bool useClang = getLanguageFromFileName(qs)==SrcLangExt::Cpp;
10810 if (useClang)
10811 {
10812 auto clangParser = ClangParser::instance()->createTUParser(fd);
10813 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10814 roots.push_back(fileRoot);
10815 }
10816 else
10817 {
10818 auto fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10819 roots.push_back(fileRoot);
10820 }
10821 return roots;
10822 };
10823 results.emplace_back(threadPool.queue(processFile));
10824 }
10825 }
10826 // synchronize with the Entry result lists produced and add them to the root
10827 for (auto &f : results)
10828 {
10829 auto l = f.get();
10830 for (auto &e : l)
10831 {
10832 root->moveToSubEntryAndKeep(e);
10833 }
10834 }
10835 }
10836 else // normal processing
10837#endif
10838 {
10839 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10840 msg("Processing input using {} threads.\n",numThreads);
10841 ThreadPool threadPool(numThreads);
10842 using FutureType = std::shared_ptr<Entry>;
10843 std::vector< std::future< FutureType > > results;
10844 for (const auto &s : g_inputFiles)
10845 {
10846 // lambda representing the work to executed by a thread
10847 auto processFile = [s]() {
10848 bool ambig = false;
10849 QCString qs = s;
10851 auto parser = getParserForFile(qs);
10852 auto fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10853 return fileRoot;
10854 };
10855 // dispatch the work and collect the future results
10856 results.emplace_back(threadPool.queue(processFile));
10857 }
10858 // synchronize with the Entry results produced and add them to the root
10859 for (auto &f : results)
10860 {
10861 root->moveToSubEntryAndKeep(f.get());
10862 }
10863 }
10864}
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 10867 of file doxygen.cpp.

10868{
10869 AUTO_TRACE();
10870#if USE_LIBCLANG
10872 {
10873 StringUnorderedSet processedFiles;
10874
10875 // create a dictionary with files to process
10876 StringUnorderedSet filesToProcess;
10877 for (const auto &s : g_inputFiles)
10878 {
10879 filesToProcess.insert(s);
10880 }
10881
10882 // process source files (and their include dependencies)
10883 for (const auto &s : g_inputFiles)
10884 {
10885 bool ambig = false;
10886 QCString qs =s;
10888 ASSERT(fd!=nullptr);
10889 if (fd->isSource() && !fd->isReference() && getLanguageFromFileName(qs)==SrcLangExt::Cpp) // this is a source file
10890 {
10891 auto clangParser = ClangParser::instance()->createTUParser(fd);
10892 auto parser { getParserForFile(qs) };
10893 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10894 root->moveToSubEntryAndKeep(fileRoot);
10895 processedFiles.insert(s);
10896
10897 // Now process any include files in the same translation unit
10898 // first. When libclang is used this is much more efficient.
10899 for (auto incFile : clangParser->filesInSameTU())
10900 {
10901 //printf(" file %s\n",qPrint(incFile));
10902 if (filesToProcess.find(incFile)!=filesToProcess.end() && // file need to be processed
10903 processedFiles.find(incFile)==processedFiles.end()) // and is not processed already
10904 {
10906 if (ifd && !ifd->isReference())
10907 {
10908 //printf(" Processing %s in same translation unit as %s\n",qPrint(incFile),qPrint(qs));
10909 fileRoot = parseFile(*parser.get(),ifd,incFile,clangParser.get(),false);
10910 root->moveToSubEntryAndKeep(fileRoot);
10911 processedFiles.insert(incFile);
10912 }
10913 }
10914 }
10915 }
10916 }
10917 // process remaining files
10918 for (const auto &s : g_inputFiles)
10919 {
10920 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
10921 {
10922 bool ambig = false;
10923 QCString qs = s;
10925 if (getLanguageFromFileName(qs)==SrcLangExt::Cpp) // not yet processed
10926 {
10927 auto clangParser = ClangParser::instance()->createTUParser(fd);
10928 auto parser { getParserForFile(qs) };
10929 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10930 root->moveToSubEntryAndKeep(fileRoot);
10931 }
10932 else
10933 {
10934 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
10935 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10936 root->moveToSubEntryAndKeep(fileRoot);
10937 }
10938 processedFiles.insert(s);
10939 }
10940 }
10941 }
10942 else // normal processing
10943#endif
10944 {
10945 for (const auto &s : g_inputFiles)
10946 {
10947 bool ambig = false;
10948 QCString qs = s;
10950 ASSERT(fd!=nullptr);
10951 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
10952 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10953 root->moveToSubEntryAndKeep(std::move(fileRoot));
10954 }
10955 }
10956}

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

12431{
12432 AUTO_TRACE();
12433 std::atexit(exitDoxygen);
12434
12435 Portable::correctPath(Config_getList(EXTERNAL_TOOL_PATH));
12436
12437#if USE_LIBCLANG
12438 Doxygen::clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
12439#endif
12440
12441 // we would like to show the versionString earlier, but we first have to handle the configuration file
12442 // to know the value of the QUIET setting.
12443 QCString versionString = getFullVersion();
12444 msg("Doxygen version used: {}\n",versionString);
12445
12447
12448 /**************************************************************************
12449 * Make sure the output directory exists
12450 **************************************************************************/
12451 QCString outputDirectory = Config_getString(OUTPUT_DIRECTORY);
12452 if (!g_singleComment)
12453 {
12454 if (outputDirectory.isEmpty())
12455 {
12456 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,Dir::currentDirPath());
12457 }
12458 else
12459 {
12460 Dir dir(outputDirectory.str());
12461 if (!dir.exists())
12462 {
12463 dir.setPath(Dir::currentDirPath());
12464 if (!dir.mkdir(outputDirectory.str()))
12465 {
12466 term("tag OUTPUT_DIRECTORY: Output directory '{}' does not "
12467 "exist and cannot be created\n",outputDirectory);
12468 }
12469 else
12470 {
12471 msg("Notice: Output directory '{}' does not exist. "
12472 "I have created it for you.\n", outputDirectory);
12473 }
12474 dir.setPath(outputDirectory.str());
12475 }
12476 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,dir.absPath());
12477 }
12478 }
12479 AUTO_TRACE_ADD("outputDirectory={}",outputDirectory);
12480
12481 /**************************************************************************
12482 * Initialize global lists and dictionaries
12483 **************************************************************************/
12484
12485 // also scale lookup cache with SYMBOL_CACHE_SIZE
12486 int cacheSize = Config_getInt(LOOKUP_CACHE_SIZE);
12487 if (cacheSize<0) cacheSize=0;
12488 if (cacheSize>9) cacheSize=9;
12489 uint32_t lookupSize = 65536 << cacheSize;
12492
12493#ifdef HAS_SIGNALS
12494 signal(SIGINT, stopDoxygen);
12495#endif
12496
12497 uint32_t pid = Portable::pid();
12498 Doxygen::filterDBFileName.sprintf("doxygen_filterdb_%d.tmp",pid);
12499 Doxygen::filterDBFileName.prepend(outputDirectory+"/");
12500
12501 /**************************************************************************
12502 * Check/create output directories *
12503 **************************************************************************/
12504
12505 bool generateHtml = Config_getBool(GENERATE_HTML);
12506 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
12507 bool generateXml = Config_getBool(GENERATE_XML);
12508 bool generateLatex = Config_getBool(GENERATE_LATEX);
12509 bool generateRtf = Config_getBool(GENERATE_RTF);
12510 bool generateMan = Config_getBool(GENERATE_MAN);
12511 bool generateSql = Config_getBool(GENERATE_SQLITE3);
12512 QCString htmlOutput;
12513 QCString docbookOutput;
12514 QCString xmlOutput;
12515 QCString latexOutput;
12516 QCString rtfOutput;
12517 QCString manOutput;
12518 QCString sqlOutput;
12519
12520 if (!g_singleComment)
12521 {
12522 if (generateHtml)
12523 {
12524 htmlOutput = createOutputDirectory(outputDirectory,Config_getString(HTML_OUTPUT),"/html");
12525 Config_updateString(HTML_OUTPUT,htmlOutput);
12526
12527 QCString sitemapUrl = Config_getString(SITEMAP_URL);
12528 bool generateSitemap = !sitemapUrl.isEmpty();
12529 if (generateSitemap && !sitemapUrl.endsWith("/"))
12530 {
12531 Config_updateString(SITEMAP_URL,sitemapUrl+"/");
12532 }
12533
12534 // add HTML indexers that are enabled
12535 bool generateHtmlHelp = Config_getBool(GENERATE_HTMLHELP);
12536 bool generateEclipseHelp = Config_getBool(GENERATE_ECLIPSEHELP);
12537 bool generateQhp = Config_getBool(GENERATE_QHP);
12538 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
12539 bool generateDocSet = Config_getBool(GENERATE_DOCSET);
12540 if (generateEclipseHelp) Doxygen::indexList->addIndex<EclipseHelp>();
12541 if (generateHtmlHelp) Doxygen::indexList->addIndex<HtmlHelp>();
12542 if (generateQhp) Doxygen::indexList->addIndex<Qhp>();
12543 if (generateSitemap) Doxygen::indexList->addIndex<Sitemap>();
12544 if (generateTreeView) Doxygen::indexList->addIndex<FTVHelp>(TRUE);
12545 if (generateDocSet) Doxygen::indexList->addIndex<DocSets>();
12546 Doxygen::indexList->addIndex<Crawlmap>();
12547 Doxygen::indexList->initialize();
12548 }
12549
12550 if (generateDocbook)
12551 {
12552 docbookOutput = createOutputDirectory(outputDirectory,Config_getString(DOCBOOK_OUTPUT),"/docbook");
12553 Config_updateString(DOCBOOK_OUTPUT,docbookOutput);
12554 }
12555
12556 if (generateXml)
12557 {
12558 xmlOutput = createOutputDirectory(outputDirectory,Config_getString(XML_OUTPUT),"/xml");
12559 Config_updateString(XML_OUTPUT,xmlOutput);
12560 }
12561
12562 if (generateLatex)
12563 {
12564 latexOutput = createOutputDirectory(outputDirectory,Config_getString(LATEX_OUTPUT), "/latex");
12565 Config_updateString(LATEX_OUTPUT,latexOutput);
12566 }
12567
12568 if (generateRtf)
12569 {
12570 rtfOutput = createOutputDirectory(outputDirectory,Config_getString(RTF_OUTPUT),"/rtf");
12571 Config_updateString(RTF_OUTPUT,rtfOutput);
12572 }
12573
12574 if (generateMan)
12575 {
12576 manOutput = createOutputDirectory(outputDirectory,Config_getString(MAN_OUTPUT),"/man");
12577 Config_updateString(MAN_OUTPUT,manOutput);
12578 }
12579
12580 if (generateSql)
12581 {
12582 sqlOutput = createOutputDirectory(outputDirectory,Config_getString(SQLITE3_OUTPUT),"/sqlite3");
12583 Config_updateString(SQLITE3_OUTPUT,sqlOutput);
12584 }
12585 }
12586
12587 if (Config_getBool(HAVE_DOT))
12588 {
12589 QCString curFontPath = Config_getString(DOT_FONTPATH);
12590 if (curFontPath.isEmpty())
12591 {
12592 Portable::getenv("DOTFONTPATH");
12593 QCString newFontPath = ".";
12594 if (!curFontPath.isEmpty())
12595 {
12596 newFontPath+=Portable::pathListSeparator();
12597 newFontPath+=curFontPath;
12598 }
12599 Portable::setenv("DOTFONTPATH",qPrint(newFontPath));
12600 }
12601 else
12602 {
12603 Portable::setenv("DOTFONTPATH",qPrint(curFontPath));
12604 }
12605 }
12606
12607 /**************************************************************************
12608 * Handle layout file *
12609 **************************************************************************/
12610
12612 QCString layoutFileName = Config_getString(LAYOUT_FILE);
12613 bool defaultLayoutUsed = FALSE;
12614 if (layoutFileName.isEmpty())
12615 {
12616 layoutFileName = Config_updateString(LAYOUT_FILE,"DoxygenLayout.xml");
12617 defaultLayoutUsed = TRUE;
12618 }
12619 AUTO_TRACE_ADD("defaultLayoutUsed={}, layoutFileName={}",defaultLayoutUsed,layoutFileName);
12620
12621 FileInfo fi(layoutFileName.str());
12622 if (fi.exists())
12623 {
12624 msg("Parsing layout file {}...\n",layoutFileName);
12625 LayoutDocManager::instance().parse(layoutFileName);
12626 }
12627 else if (!defaultLayoutUsed)
12628 {
12629 warn_uncond("failed to open layout file '{}' for reading! Using default settings.\n",layoutFileName);
12630 }
12631 printLayout();
12632
12633 /**************************************************************************
12634 * Read and preprocess input *
12635 **************************************************************************/
12636
12637 // prevent search in the output directories
12638 StringVector exclPatterns = Config_getList(EXCLUDE_PATTERNS);
12639 if (generateHtml) exclPatterns.push_back(htmlOutput.str());
12640 if (generateDocbook) exclPatterns.push_back(docbookOutput.str());
12641 if (generateXml) exclPatterns.push_back(xmlOutput.str());
12642 if (generateLatex) exclPatterns.push_back(latexOutput.str());
12643 if (generateRtf) exclPatterns.push_back(rtfOutput.str());
12644 if (generateMan) exclPatterns.push_back(manOutput.str());
12645 Config_updateList(EXCLUDE_PATTERNS,exclPatterns);
12646
12647 if (!g_singleComment)
12648 {
12650
12652 }
12653
12654 // Notice: the order of the function calls below is very important!
12655
12656 if (generateHtml && !Config_getBool(USE_MATHJAX))
12657 {
12659 }
12660 if (generateRtf)
12661 {
12663 }
12664 if (generateDocbook)
12665 {
12667 }
12668
12670
12671 /**************************************************************************
12672 * Handle Tag Files *
12673 **************************************************************************/
12674
12675 std::shared_ptr<Entry> root = std::make_shared<Entry>();
12676
12677 if (!g_singleComment)
12678 {
12679 msg("Reading and parsing tag files\n");
12680 const StringVector &tagFileList = Config_getList(TAGFILES);
12681 for (const auto &s : tagFileList)
12682 {
12683 readTagFile(root,s.c_str());
12684 }
12685 }
12686
12687 /**************************************************************************
12688 * Parse source files *
12689 **************************************************************************/
12690
12691 addSTLSupport(root);
12692
12693 g_s.begin("Parsing files\n");
12694 if (g_singleComment)
12695 {
12696 //printf("Parsing comment %s\n",qPrint(g_commentFileName));
12697 if (g_commentFileName=="-")
12698 {
12699 std::string text = fileToString(g_commentFileName).str();
12700 addTerminalCharIfMissing(text,'\n');
12701 generateHtmlForComment("stdin.md",text);
12702 }
12703 else if (FileInfo(g_commentFileName.str()).isFile())
12704 {
12705 std::string text;
12707 addTerminalCharIfMissing(text,'\n');
12709 }
12710 else
12711 {
12712 }
12714 exit(0);
12715 }
12716 else
12717 {
12718 if (Config_getInt(NUM_PROC_THREADS)==1)
12719 {
12721 }
12722 else
12723 {
12725 }
12726 }
12727 g_s.end();
12728
12729 /**************************************************************************
12730 * Gather information *
12731 **************************************************************************/
12732
12733 g_s.begin("Building macro definition list...\n");
12735 g_s.end();
12736
12737 g_s.begin("Building group list...\n");
12738 buildGroupList(root.get());
12739 organizeSubGroups(root.get());
12740 g_s.end();
12741
12742 g_s.begin("Building directory list...\n");
12744 findDirDocumentation(root.get());
12745 g_s.end();
12746
12747 g_s.begin("Building namespace list...\n");
12748 buildNamespaceList(root.get());
12749 findUsingDirectives(root.get());
12750 g_s.end();
12751
12752 g_s.begin("Building file list...\n");
12753 buildFileList(root.get());
12754 g_s.end();
12755
12756 g_s.begin("Building class list...\n");
12757 buildClassList(root.get());
12758 g_s.end();
12759
12760 g_s.begin("Building concept list...\n");
12761 buildConceptList(root.get());
12762 g_s.end();
12763
12764 // build list of using declarations here (global list)
12765 buildListOfUsingDecls(root.get());
12766 g_s.end();
12767
12768 g_s.begin("Computing nesting relations for classes...\n");
12770 g_s.end();
12771 // 1.8.2-20121111: no longer add nested classes to the group as well
12772 //distributeClassGroupRelations();
12773
12774 // calling buildClassList may result in cached relations that
12775 // become invalid after resolveClassNestingRelations(), that's why
12776 // we need to clear the cache here
12777 Doxygen::typeLookupCache->clear();
12778 // we don't need the list of using declaration anymore
12779 g_usingDeclarations.clear();
12780
12781 g_s.begin("Associating documentation with classes...\n");
12782 buildClassDocList(root.get());
12783 g_s.end();
12784
12785 g_s.begin("Associating documentation with concepts...\n");
12786 buildConceptDocList(root.get());
12788 g_s.end();
12789
12790 g_s.begin("Associating documentation with modules...\n");
12791 findModuleDocumentation(root.get());
12792 g_s.end();
12793
12794 g_s.begin("Building example list...\n");
12795 buildExampleList(root.get());
12796 g_s.end();
12797
12798 g_s.begin("Searching for enumerations...\n");
12799 findEnums(root.get());
12800 g_s.end();
12801
12802 // Since buildVarList calls isVarWithConstructor
12803 // and this calls getResolvedClass we need to process
12804 // typedefs first so the relations between classes via typedefs
12805 // are properly resolved. See bug 536385 for an example.
12806 g_s.begin("Searching for documented typedefs...\n");
12807 buildTypedefList(root.get());
12808 g_s.end();
12809
12810 if (Config_getBool(OPTIMIZE_OUTPUT_SLICE))
12811 {
12812 g_s.begin("Searching for documented sequences...\n");
12813 buildSequenceList(root.get());
12814 g_s.end();
12815
12816 g_s.begin("Searching for documented dictionaries...\n");
12817 buildDictionaryList(root.get());
12818 g_s.end();
12819 }
12820
12821 g_s.begin("Searching for members imported via using declarations...\n");
12822 // this should be after buildTypedefList in order to properly import
12823 // used typedefs
12824 findUsingDeclarations(root.get(),TRUE); // do for python packages first
12825 findUsingDeclarations(root.get(),FALSE); // then the rest
12826 g_s.end();
12827
12828 g_s.begin("Searching for included using directives...\n");
12830 g_s.end();
12831
12832 g_s.begin("Searching for documented variables...\n");
12833 buildVarList(root.get());
12834 g_s.end();
12835
12836 g_s.begin("Building interface member list...\n");
12837 buildInterfaceAndServiceList(root.get()); // UNO IDL
12838
12839 g_s.begin("Building member list...\n"); // using class info only !
12840 buildFunctionList(root.get());
12841 g_s.end();
12842
12843 g_s.begin("Searching for friends...\n");
12844 findFriends();
12845 g_s.end();
12846
12847 g_s.begin("Searching for documented defines...\n");
12848 findDefineDocumentation(root.get());
12849 g_s.end();
12850
12851 g_s.begin("Computing class inheritance relations...\n");
12852 findClassEntries(root.get());
12854 g_s.end();
12855
12856 g_s.begin("Computing class usage relations...\n");
12858 g_s.end();
12859
12860 if (Config_getBool(INLINE_SIMPLE_STRUCTS))
12861 {
12862 g_s.begin("Searching for tag less structs...\n");
12864 g_s.end();
12865 }
12866
12867 g_s.begin("Flushing cached template relations that have become invalid...\n");
12869 g_s.end();
12870
12871 g_s.begin("Warn for undocumented namespaces...\n");
12873 g_s.end();
12874
12875 g_s.begin("Computing class relations...\n");
12878 if (Config_getBool(OPTIMIZE_OUTPUT_VHDL))
12879 {
12881 }
12883 g_classEntries.clear();
12884 g_s.end();
12885
12886 g_s.begin("Add enum values to enums...\n");
12887 addEnumValuesToEnums(root.get());
12888 findEnumDocumentation(root.get());
12889 g_s.end();
12890
12891 g_s.begin("Searching for member function documentation...\n");
12892 findObjCMethodDefinitions(root.get());
12893 findMemberDocumentation(root.get()); // may introduce new members !
12894 findUsingDeclImports(root.get()); // may introduce new members !
12895 g_usingClassMap.clear();
12899 g_s.end();
12900
12901 // moved to after finding and copying documentation,
12902 // as this introduces new members see bug 722654
12903 g_s.begin("Creating members for template instances...\n");
12905 g_s.end();
12906
12907 g_s.begin("Building page list...\n");
12908 buildPageList(root.get());
12909 g_s.end();
12910
12911 g_s.begin("Search for main page...\n");
12912 findMainPage(root.get());
12913 findMainPageTagFiles(root.get());
12914 g_s.end();
12915
12916 g_s.begin("Computing page relations...\n");
12917 computePageRelations(root.get());
12919 g_s.end();
12920
12921 g_s.begin("Determining the scope of groups...\n");
12922 findGroupScope(root.get());
12923 g_s.end();
12924
12925 g_s.begin("Computing module relations...\n");
12926 auto &mm = ModuleManager::instance();
12927 mm.resolvePartitions();
12928 mm.resolveImports();
12929 mm.collectExportedSymbols();
12930 g_s.end();
12931
12932 auto memberNameComp = [](const MemberNameLinkedMap::Ptr &n1,const MemberNameLinkedMap::Ptr &n2)
12933 {
12934 return qstricmp_sort(n1->memberName().data()+getPrefixIndex(n1->memberName()),
12935 n2->memberName().data()+getPrefixIndex(n2->memberName())
12936 )<0;
12937 };
12938
12939 auto classComp = [](const ClassLinkedMap::Ptr &c1,const ClassLinkedMap::Ptr &c2)
12940 {
12941 if (Config_getBool(SORT_BY_SCOPE_NAME))
12942 {
12943 return qstricmp_sort(c1->name(), c2->name())<0;
12944 }
12945 else
12946 {
12947 int i = qstricmp_sort(c1->className(), c2->className());
12948 return i==0 ? qstricmp_sort(c1->name(), c2->name())<0 : i<0;
12949 }
12950 };
12951
12952 auto namespaceComp = [](const NamespaceLinkedMap::Ptr &n1,const NamespaceLinkedMap::Ptr &n2)
12953 {
12954 return qstricmp_sort(n1->name(),n2->name())<0;
12955 };
12956
12957 auto conceptComp = [](const ConceptLinkedMap::Ptr &c1,const ConceptLinkedMap::Ptr &c2)
12958 {
12959 return qstricmp_sort(c1->name(),c2->name())<0;
12960 };
12961
12962 g_s.begin("Sorting lists...\n");
12963 std::stable_sort(Doxygen::memberNameLinkedMap->begin(),
12965 memberNameComp);
12966 std::stable_sort(Doxygen::functionNameLinkedMap->begin(),
12968 memberNameComp);
12969 std::stable_sort(Doxygen::hiddenClassLinkedMap->begin(),
12971 classComp);
12972 std::stable_sort(Doxygen::classLinkedMap->begin(),
12974 classComp);
12975 std::stable_sort(Doxygen::conceptLinkedMap->begin(),
12977 conceptComp);
12978 std::stable_sort(Doxygen::namespaceLinkedMap->begin(),
12980 namespaceComp);
12981 g_s.end();
12982
12983 g_s.begin("Determining which enums are documented\n");
12985 g_s.end();
12986
12987 g_s.begin("Computing member relations...\n");
12990 g_s.end();
12991
12992 g_s.begin("Building full member lists recursively...\n");
12994 g_s.end();
12995
12996 g_s.begin("Adding members to member groups.\n");
12998 g_s.end();
12999
13000 if (Config_getBool(DISTRIBUTE_GROUP_DOC))
13001 {
13002 g_s.begin("Distributing member group documentation.\n");
13004 g_s.end();
13005 }
13006
13007 g_s.begin("Computing member references...\n");
13009 g_s.end();
13010
13011 if (Config_getBool(INHERIT_DOCS))
13012 {
13013 g_s.begin("Inheriting documentation...\n");
13015 g_s.end();
13016 }
13017
13018
13019 // compute the shortest possible names of all files
13020 // without losing the uniqueness of the file names.
13021 g_s.begin("Generating disk names...\n");
13023 g_s.end();
13024
13025 g_s.begin("Adding source references...\n");
13027 g_s.end();
13028
13029 g_s.begin("Adding xrefitems...\n");
13032 g_s.end();
13033
13034 g_s.begin("Sorting member lists...\n");
13036 g_s.end();
13037
13038 g_s.begin("Setting anonymous enum type...\n");
13040 g_s.end();
13041
13042 g_s.begin("Computing dependencies between directories...\n");
13044 g_s.end();
13045
13046 g_s.begin("Generating citations page...\n");
13048 g_s.end();
13049
13050 g_s.begin("Counting members...\n");
13051 countMembers();
13052 g_s.end();
13053
13054 g_s.begin("Counting data structures...\n");
13056 g_s.end();
13057
13058 g_s.begin("Resolving user defined references...\n");
13060 g_s.end();
13061
13062 g_s.begin("Finding anchors and sections in the documentation...\n");
13064 g_s.end();
13065
13066 g_s.begin("Transferring function references...\n");
13068 g_s.end();
13069
13070 g_s.begin("Combining using relations...\n");
13072 g_s.end();
13073
13075 g_s.begin("Adding members to index pages...\n");
13077 addToIndices();
13078 g_s.end();
13079
13080 g_s.begin("Correcting members for VHDL...\n");
13082 g_s.end();
13083
13084 g_s.begin("Computing tooltip texts...\n");
13086 g_s.end();
13087
13088 if (Config_getBool(SORT_GROUP_NAMES))
13089 {
13090 std::stable_sort(Doxygen::groupLinkedMap->begin(),
13092 [](const auto &g1,const auto &g2)
13093 { return g1->groupTitle() < g2->groupTitle(); });
13094
13095 for (const auto &gd : *Doxygen::groupLinkedMap)
13096 {
13097 gd->sortSubGroups();
13098 }
13099 }
13100
13101 printNavTree(root.get(),0);
13103}
Definition cache.h:32
void generatePage()
Generate the citations page.
Definition cite.cpp:331
A class that generates docset files.
Definition docsets.h:36
Generator for Eclipse help files.
Definition eclipsehelp.h:44
A class that generates a dynamic tree view side panel.
Definition ftvhelp.h:41
bool isFile() const
Definition fileinfo.cpp:63
void initFromRepository(const QCString &dir)
Definition formula.cpp: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:1437
void parse(const QCString &fileName, const char *data=nullptr)
Parses a user provided layout.
Definition layout.cpp:1470
Definition qhp.h:27
static void computeVhdlComponentRelations()
#define Config_updateList(name,...)
Definition config.h:43
DirIterator begin(DirIterator it) noexcept
Definition dir.cpp:170
void buildDirectories()
Definition dirdef.cpp:1102
void computeDirDependencies()
Definition dirdef.cpp:1176
static void findInheritedTemplateInstances()
Definition doxygen.cpp:5273
void printNavTree(Entry *root, int indent)
Definition doxygen.cpp:9973
static void buildGroupList(const Entry *root)
Definition doxygen.cpp:425
static void flushCachedTemplateRelations()
Definition doxygen.cpp:9400
static void computeTemplateClassRelations()
Definition doxygen.cpp:5367
void printSectionsTree()
Definition doxygen.cpp:9996
static void generateXRefPages()
Definition doxygen.cpp:5548
static void warnUndocumentedNamespaces()
Definition doxygen.cpp:5322
static void resolveClassNestingRelations()
Definition doxygen.cpp:1365
static void vhdlCorrectMemberProperties()
Definition doxygen.cpp:8358
static void stopDoxygen(int)
static void computeMemberReferences()
Definition doxygen.cpp:5436
static void transferRelatedFunctionDocumentation()
Definition doxygen.cpp:4394
static void addMembersToMemberGroup()
Definition doxygen.cpp:9265
static void distributeConceptGroups()
Definition doxygen.cpp:1332
static void transferFunctionDocumentation()
Definition doxygen.cpp:4313
static void setAnonymousEnumType()
Definition doxygen.cpp:9005
static void sortMemberLists()
Definition doxygen.cpp:8910
static void createTemplateInstanceMembers()
Definition doxygen.cpp:8486
void transferStaticInstanceInitializers()
Definition doxygen.cpp:4443
static void findObjCMethodDefinitions(const Entry *root)
Definition doxygen.cpp:7502
static void distributeMemberGroupDocumentation()
Definition doxygen.cpp:9303
static void resolveUserReferences()
Definition doxygen.cpp:9859
static void readTagFile(const std::shared_ptr< Entry > &root, const QCString &tagLine)
static void findIncludedUsingDirectives()
Definition doxygen.cpp:2442
static void countMembers()
Definition doxygen.cpp:9019
static void organizeSubGroups(const Entry *root)
Definition doxygen.cpp:484
void searchInputFiles()
static void findFriends()
Definition doxygen.cpp:4216
static void addListReferences()
Definition doxygen.cpp:5470
static void exitDoxygen() noexcept
static void addMembersToIndex()
Definition doxygen.cpp:8148
static void addSourceReferences()
Definition doxygen.cpp:8783
static void inheritDocumentation()
Definition doxygen.cpp:9205
static void flushUnresolvedRelations()
Definition doxygen.cpp:9454
static QCString g_commentFileName
Definition doxygen.cpp:192
static void findDocumentedEnumValues()
Definition doxygen.cpp:8140
static void generateDiskNames()
static void addToIndices()
Definition doxygen.cpp:8190
static void computeClassRelations()
Definition doxygen.cpp:5342
static void checkPageRelations()
Definition doxygen.cpp:9839
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:9341
static void mergeCategories()
Definition doxygen.cpp:8505
static void findUsedTemplateInstances()
Definition doxygen.cpp:5306
static void computeTooltipTexts()
Definition doxygen.cpp:8959
static void parseFilesSingleThreading(const std::shared_ptr< Entry > &root)
parse the list of input files
static void buildCompleteMemberLists()
Definition doxygen.cpp:8527
static void combineUsingRelations()
Definition doxygen.cpp:9240
static void checkMarkdownMainfile()
static void parseFilesMultiThreading(const std::shared_ptr< Entry > &root)
parse the list of input files
static void transferFunctionReferences()
Definition doxygen.cpp:4346
static void buildDefineList()
Definition doxygen.cpp:8862
static void computeMemberRelations()
Definition doxygen.cpp:8470
void printLayout()
Definition layout.cpp:1822
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:1444
int getPrefixIndex(const QCString &name)
Definition util.cpp:3185

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

9974{
9976 {
9977 QCString indentStr;
9978 indentStr.fill(' ',indent);
9979 Debug::print(Debug::Entries,0,"{}{} at {}:{} (sec={}, spec={})\n",
9980 indentStr.isEmpty()?"":indentStr,
9981 root->name.isEmpty()?"<empty>":root->name,
9982 root->fileName,root->startLine,
9983 root->section.to_string(),
9984 root->spec.to_string());
9985 for (const auto &e : root->children())
9986 {
9987 printNavTree(e.get(),indent+2);
9988 }
9989 }
9990}
@ 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:827
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:698

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

9997{
9999 {
10000 for (const auto &si : SectionManager::instance())
10001 {
10002 Debug::print(Debug::Sections,0,"Section = {}, file = {}, title = {}, type = {}, ref = {}\n",
10003 si->label(),si->fileName(),si->title(),si->type().level(),si->ref());
10004 }
10005 }
10006}
@ 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 1599 of file doxygen.cpp.

1603{
1604 //printf("%d: processTagLessClasses %s\n",count,qPrint(cd->name()));
1605 //printf("checking members for %s\n",qPrint(cd->name()));
1606 if (tagParentCd && !cd->getClasses().empty())
1607 {
1608 MemberList *ml = cd->getMemberList(MemberListType::PubAttribs());
1609 if (ml)
1610 {
1611 int pos=0;
1612 for (const auto &md : *ml)
1613 {
1614 QCString type = md->typeString();
1615 if (type.find("::@")!=-1) // member of tag less struct/union
1616 {
1617 for (const auto &icd : cd->getClasses())
1618 {
1619 //printf(" member %s: type='%s'\n",qPrint(md->name()),qPrint(type));
1620 //printf(" comparing '%s'<->'%s'\n",qPrint(type),qPrint(icd->name()));
1621 if (type.find(icd->name())!=-1) // matching tag less struct/union
1622 {
1623 QCString name = md->name();
1624 if (md->isAnonymous()) name = "__unnamed" + QCString().setNum(pos++)+"__";
1625 if (!prefix.isEmpty()) name.prepend(prefix+".");
1626 //printf(" found %s for class %s\n",qPrint(name),qPrint(cd->name()));
1627 ClassDefMutable *ncd = createTagLessInstance(rootCd,icd,name);
1628 if (ncd)
1629 {
1630 processTagLessClasses(rootCd,icd,ncd,name,count+1);
1631 //printf(" addTagged %s to %s\n",qPrint(ncd->name()),qPrint(tagParentCd->name()));
1632 ncd->setTagLessReference(icd);
1633
1634 // replace tag-less type for generated/original member
1635 // by newly created class name.
1636 // note the difference between changing cd and tagParentCd.
1637 // for the initial call this is the same pointer, but for
1638 // recursive calls cd is the original tag-less struct (of which
1639 // there is only one instance) and tagParentCd is the newly
1640 // generated tagged struct of which there can be multiple instances!
1641 MemberList *pml = tagParentCd->getMemberList(MemberListType::PubAttribs());
1642 if (pml)
1643 {
1644 for (const auto &pmd : *pml)
1645 {
1647 if (pmdm && pmd->name()==md->name())
1648 {
1649 pmdm->setAccessorType(ncd,substitute(pmd->typeString(),icd->name(),ncd->name()));
1650 //pmd->setType(substitute(pmd->typeString(),icd->name(),ncd->name()));
1651 }
1652 }
1653 }
1654 }
1655 }
1656 }
1657 }
1658 }
1659 }
1660 }
1661}
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:1513

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

11500{
11501 QCString versionString = getFullVersion();
11502
11503 // helper that calls \a func to write to file \a fileName via a TextStream
11504 auto writeFile = [](const char *fileName,std::function<void(TextStream&)> func) -> bool
11505 {
11506 std::ofstream f;
11507 if (openOutputFile(fileName,f))
11508 {
11509 TextStream t(&f);
11510 func(t);
11511 return true;
11512 }
11513 return false;
11514 };
11515
11516
11517 /**************************************************************************
11518 * Handle arguments *
11519 **************************************************************************/
11520
11521 int optInd=1;
11522 QCString configName;
11523 QCString traceName;
11524 bool genConfig=false;
11525 bool shortList=false;
11526 bool traceTiming=false;
11528 bool updateConfig=false;
11529 bool quiet = false;
11530 while (optInd<argc && argv[optInd][0]=='-' &&
11531 (isalpha(argv[optInd][1]) || argv[optInd][1]=='?' ||
11532 argv[optInd][1]=='-')
11533 )
11534 {
11535 switch(argv[optInd][1])
11536 {
11537 case 'g':
11538 {
11539 genConfig=TRUE;
11540 }
11541 break;
11542 case 'l':
11543 {
11544 QCString layoutName;
11545 if (optInd+1>=argc)
11546 {
11547 layoutName="DoxygenLayout.xml";
11548 }
11549 else
11550 {
11551 layoutName=argv[optInd+1];
11552 }
11553 writeDefaultLayoutFile(layoutName);
11555 exit(0);
11556 }
11557 break;
11558 case 'c':
11559 if (optInd+1>=argc) // no file name given
11560 {
11561 msg("option \"-c\" is missing the file name to read\n");
11562 devUsage();
11564 exit(1);
11565 }
11566 else
11567 {
11568 g_commentFileName=argv[optInd+1];
11569 optInd++;
11570 }
11571 g_singleComment=true;
11572 quiet=true;
11573 break;
11574 case 'd':
11575 {
11576 QCString debugLabel=getArg(argc,argv,optInd);
11577 if (debugLabel.isEmpty())
11578 {
11579 devUsage();
11581 exit(0);
11582 }
11583 int retVal = Debug::setFlagStr(debugLabel);
11584 if (!retVal)
11585 {
11586 msg("option \"-d\" has unknown debug specifier: \"{}\".\n",debugLabel);
11587 devUsage();
11589 exit(1);
11590 }
11591 }
11592 break;
11593 case 't':
11594 {
11595#if ENABLE_TRACING
11596 if (!strcmp(argv[optInd]+1,"t_time"))
11597 {
11598 traceTiming = true;
11599 }
11600 else if (!strcmp(argv[optInd]+1,"t"))
11601 {
11602 traceTiming = false;
11603 }
11604 else
11605 {
11606 err("option should be \"-t\" or \"-t_time\", found: \"{}\".\n",argv[optInd]);
11608 exit(1);
11609 }
11610 if (optInd+1>=argc || argv[optInd+1][0] == '-') // no file name given
11611 {
11612 traceName="stdout";
11613 }
11614 else
11615 {
11616 traceName=argv[optInd+1];
11617 optInd++;
11618 }
11619#else
11620 err("support for option \"-t\" has not been compiled in (use a debug build or a release build with tracing enabled).\n");
11622 exit(1);
11623#endif
11624 }
11625 break;
11626 case 'x':
11627 if (!strcmp(argv[optInd]+1,"x_noenv")) diffList=Config::CompareMode::CompressedNoEnv;
11628 else if (!strcmp(argv[optInd]+1,"x")) diffList=Config::CompareMode::Compressed;
11629 else
11630 {
11631 err("option should be \"-x\" or \"-x_noenv\", found: \"{}\".\n",argv[optInd]);
11633 exit(1);
11634 }
11635 break;
11636 case 's':
11637 shortList=TRUE;
11638 break;
11639 case 'u':
11640 updateConfig=TRUE;
11641 break;
11642 case 'e':
11643 {
11644 QCString formatName=getArg(argc,argv,optInd);
11645 if (formatName.isEmpty())
11646 {
11647 err("option \"-e\" is missing format specifier rtf.\n");
11649 exit(1);
11650 }
11651 if (qstricmp(formatName.data(),"rtf")==0)
11652 {
11653 if (optInd+1>=argc)
11654 {
11655 err("option \"-e rtf\" is missing an extensions file name\n");
11657 exit(1);
11658 }
11659 writeFile(argv[optInd+1],RTFGenerator::writeExtensionsFile);
11661 exit(0);
11662 }
11663 err("option \"-e\" has invalid format specifier.\n");
11665 exit(1);
11666 }
11667 break;
11668 case 'f':
11669 {
11670 QCString listName=getArg(argc,argv,optInd);
11671 if (listName.isEmpty())
11672 {
11673 err("option \"-f\" is missing list specifier.\n");
11675 exit(1);
11676 }
11677 if (qstricmp(listName.data(),"emoji")==0)
11678 {
11679 if (optInd+1>=argc)
11680 {
11681 err("option \"-f emoji\" is missing an output file name\n");
11683 exit(1);
11684 }
11685 writeFile(argv[optInd+1],[](TextStream &t) { EmojiEntityMapper::instance().writeEmojiFile(t); });
11687 exit(0);
11688 }
11689 err("option \"-f\" has invalid list specifier.\n");
11691 exit(1);
11692 }
11693 break;
11694 case 'w':
11695 {
11696 QCString formatName=getArg(argc,argv,optInd);
11697 if (formatName.isEmpty())
11698 {
11699 err("option \"-w\" is missing format specifier rtf, html or latex\n");
11701 exit(1);
11702 }
11703 if (qstricmp(formatName.data(),"rtf")==0)
11704 {
11705 if (optInd+1>=argc)
11706 {
11707 err("option \"-w rtf\" is missing a style sheet file name\n");
11709 exit(1);
11710 }
11711 if (!writeFile(argv[optInd+1],RTFGenerator::writeStyleSheetFile))
11712 {
11713 err("error opening RTF style sheet file {}!\n",argv[optInd+1]);
11715 exit(1);
11716 }
11718 exit(0);
11719 }
11720 else if (qstricmp(formatName.data(),"html")==0)
11721 {
11722 Config::init();
11723 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11724 // explicit config file mentioned or default found on disk
11725 {
11726 QCString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? QCString("Doxyfile") : QCString("doxyfile"));
11727 if (!Config::parse(df)) // parse the config file
11728 {
11729 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
11731 exit(1);
11732 }
11733 }
11734 if (optInd+3>=argc)
11735 {
11736 err("option \"-w html\" does not have enough arguments\n");
11738 exit(1);
11739 }
11743 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11744 writeFile(argv[optInd+1],[&](TextStream &t) { HtmlGenerator::writeHeaderFile(t,argv[optInd+3]); });
11745 writeFile(argv[optInd+2],HtmlGenerator::writeFooterFile);
11746 writeFile(argv[optInd+3],HtmlGenerator::writeStyleSheetFile);
11748 exit(0);
11749 }
11750 else if (qstricmp(formatName.data(),"latex")==0)
11751 {
11752 Config::init();
11753 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11754 {
11755 QCString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? QCString("Doxyfile") : QCString("doxyfile"));
11756 if (!Config::parse(df))
11757 {
11758 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
11760 exit(1);
11761 }
11762 }
11763 if (optInd+3>=argc)
11764 {
11765 err("option \"-w latex\" does not have enough arguments\n");
11767 exit(1);
11768 }
11772 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11773 writeFile(argv[optInd+1],LatexGenerator::writeHeaderFile);
11774 writeFile(argv[optInd+2],LatexGenerator::writeFooterFile);
11775 writeFile(argv[optInd+3],LatexGenerator::writeStyleSheetFile);
11777 exit(0);
11778 }
11779 else
11780 {
11781 err("Illegal format specifier \"{}\": should be one of rtf, html or latex\n",formatName);
11783 exit(1);
11784 }
11785 }
11786 break;
11787 case 'm':
11789 break;
11790 case 'v':
11791 version(false);
11793 exit(0);
11794 break;
11795 case 'V':
11796 version(true);
11798 exit(0);
11799 break;
11800 case '-':
11801 if (qstrcmp(&argv[optInd][2],"help")==0)
11802 {
11803 usage(argv[0],versionString);
11804 exit(0);
11805 }
11806 else if (qstrcmp(&argv[optInd][2],"version")==0)
11807 {
11808 version(false);
11810 exit(0);
11811 }
11812 else if ((qstrcmp(&argv[optInd][2],"Version")==0) ||
11813 (qstrcmp(&argv[optInd][2],"VERSION")==0))
11814 {
11815 version(true);
11817 exit(0);
11818 }
11819 else
11820 {
11821 err("Unknown option \"-{}\"\n",&argv[optInd][1]);
11822 usage(argv[0],versionString);
11823 exit(1);
11824 }
11825 break;
11826 case 'b':
11827 setvbuf(stdout,nullptr,_IONBF,0);
11828 break;
11829 case 'q':
11830 quiet = true;
11831 break;
11832 case 'h':
11833 case '?':
11834 usage(argv[0],versionString);
11835 exit(0);
11836 break;
11837 default:
11838 err("Unknown option \"-{:c}\"\n",argv[optInd][1]);
11839 usage(argv[0],versionString);
11840 exit(1);
11841 }
11842 optInd++;
11843 }
11844
11845 /**************************************************************************
11846 * Parse or generate the config file *
11847 **************************************************************************/
11848
11849 initTracing(traceName.data(),traceTiming);
11850 TRACE("Doxygen version used: {}",getFullVersion());
11851 Config::init();
11852
11853 FileInfo configFileInfo1("Doxyfile"),configFileInfo2("doxyfile");
11854 if (optInd>=argc)
11855 {
11856 if (configFileInfo1.exists())
11857 {
11858 configName="Doxyfile";
11859 }
11860 else if (configFileInfo2.exists())
11861 {
11862 configName="doxyfile";
11863 }
11864 else if (genConfig)
11865 {
11866 configName="Doxyfile";
11867 }
11868 else
11869 {
11870 err("Doxyfile not found and no input file specified!\n");
11871 usage(argv[0],versionString);
11872 exit(1);
11873 }
11874 }
11875 else
11876 {
11877 FileInfo fi(argv[optInd]);
11878 if (fi.exists() || qstrcmp(argv[optInd],"-")==0 || genConfig)
11879 {
11880 configName=argv[optInd];
11881 }
11882 else
11883 {
11884 err("configuration file {} not found!\n",argv[optInd]);
11885 usage(argv[0],versionString);
11886 exit(1);
11887 }
11888 }
11889
11890 if (genConfig)
11891 {
11892 generateConfigFile(configName,shortList);
11894 exit(0);
11895 }
11896
11897 if (!Config::parse(configName,updateConfig,diffList))
11898 {
11899 err("could not open or read configuration file {}!\n",configName);
11901 exit(1);
11902 }
11903
11904 if (diffList!=Config::CompareMode::Full)
11905 {
11907 compareDoxyfile(diffList);
11909 exit(0);
11910 }
11911
11912 if (updateConfig)
11913 {
11915 generateConfigFile(configName,shortList,TRUE);
11917 exit(0);
11918 }
11919
11920 /* Perlmod wants to know the path to the config file.*/
11921 FileInfo configFileInfo(configName.str());
11922 setPerlModDoxyfile(configFileInfo.absFilePath());
11923
11924 /* handle -q option */
11925 if (quiet) Config_updateBool(QUIET,TRUE);
11926}
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:1527
static void writeStyleSheetFile(TextStream &t)
Definition htmlgen.cpp:1515
static void writeHeaderFile(TextStream &t, const QCString &cssname)
Definition htmlgen.cpp:1521
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:1734
CompareMode
Definition config.h:54
bool parse(const QCString &fileName, bool update=FALSE, CompareMode compareMode=CompareMode::Full)
void init()
void setPerlModDoxyfile(const QCString &qs)
int qstricmp(const char *s1, const char *s2)
Definition qcstring.cpp:530
int qstrcmp(const char *str1, const char *str2)
Definition qcstring.h:69
void initTracing(const QCString &logFile, bool timing)
Definition trace.cpp:22

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

Referenced by main().

◆ readDir()

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

Definition at line 11032 of file doxygen.cpp.

11044{
11045 std::string dirName = fi->absFilePath();
11046 if (paths && !dirName.empty())
11047 {
11048 paths->insert(dirName);
11049 }
11050 //printf("%s isSymLink()=%d\n",qPrint(dirName),fi->isSymLink());
11051 if (fi->isSymLink())
11052 {
11053 dirName = resolveSymlink(dirName);
11054 if (dirName.empty())
11055 {
11056 //printf("RECURSIVE SYMLINK: %s\n",qPrint(dirName));
11057 return; // recursive symlink
11058 }
11059 }
11060
11061 if (g_pathsVisited.find(dirName)!=g_pathsVisited.end())
11062 {
11063 //printf("PATH ALREADY VISITED: %s\n",qPrint(dirName));
11064 return; // already visited path
11065 }
11066 g_pathsVisited.insert(dirName);
11067
11068 Dir dir(dirName);
11069 msg("Searching for files in directory {}\n", fi->absFilePath());
11070 //printf("killSet=%p count=%d\n",killSet,killSet ? (int)killSet->count() : -1);
11071
11072 StringVector dirResultList;
11073
11074 for (const auto &dirEntry : dir.iterator())
11075 {
11076 FileInfo cfi(dirEntry.path());
11077 auto checkPatterns = [&]() -> bool
11078 {
11079 return (patList==nullptr || patternMatch(cfi,*patList)) &&
11080 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
11081 (killSet==nullptr || killSet->find(cfi.absFilePath())==killSet->end());
11082 };
11083
11084 if (exclSet==nullptr || exclSet->find(cfi.absFilePath())==exclSet->end())
11085 { // file should not be excluded
11086 //printf("killSet->find(%s)\n",qPrint(cfi->absFilePath()));
11087 if (Config_getBool(EXCLUDE_SYMLINKS) && cfi.isSymLink())
11088 {
11089 }
11090 else if (!cfi.exists() || !cfi.isReadable())
11091 {
11092 if (errorIfNotExist && checkPatterns())
11093 {
11094 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",cfi.absFilePath());
11095 }
11096 }
11097 else if (cfi.isFile() && checkPatterns())
11098 {
11099 std::string name=cfi.fileName();
11100 std::string path=cfi.dirPath()+"/";
11101 std::string fullName=path+name;
11102 if (fnMap)
11103 {
11104 auto fd = createFileDef(path,name);
11105 FileName *fn=nullptr;
11106 if (!name.empty())
11107 {
11108 fn = fnMap->add(name,fullName);
11109 fn->push_back(std::move(fd));
11110 }
11111 }
11112 dirResultList.push_back(fullName);
11113 if (resultSet) resultSet->insert(fullName);
11114 if (killSet) killSet->insert(fullName);
11115 }
11116 else if (recursive &&
11117 cfi.isDir() &&
11118 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
11119 cfi.fileName().at(0)!='.') // skip "." ".." and ".dir"
11120 {
11121 FileInfo acfi(cfi.absFilePath());
11122 readDir(&acfi,fnMap,exclSet,
11123 patList,exclPatList,&dirResultList,resultSet,errorIfNotExist,
11124 recursive,killSet,paths);
11125 }
11126 }
11127 }
11128 if (resultList && !dirResultList.empty())
11129 {
11130 // sort the resulting list to make the order platform independent.
11131 std::stable_sort(dirResultList.begin(),
11132 dirResultList.end(),
11133 [](const auto &f1,const auto &f2) { return qstricmp_sort(f1.c_str(),f2.c_str())<0; });
11134
11135 // append the sorted results to resultList
11136 resultList->insert(resultList->end(), dirResultList.begin(), dirResultList.end());
11137 }
11138}
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:5657

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

11157{
11158 //printf("killSet count=%d\n",killSet ? (int)killSet->size() : -1);
11159 // strip trailing slashes
11160 if (s.isEmpty()) return;
11161
11162 g_pathsVisited.clear();
11163
11164 FileInfo fi(s.str());
11165 //printf("readFileOrDirectory(%s)\n",s);
11166 {
11167 if (exclSet==nullptr || exclSet->find(fi.absFilePath())==exclSet->end())
11168 {
11169 if (Config_getBool(EXCLUDE_SYMLINKS) && fi.isSymLink())
11170 {
11171 }
11172 else if (!fi.exists() || !fi.isReadable())
11173 {
11174 if (errorIfNotExist)
11175 {
11176 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",s);
11177 }
11178 }
11179 else if (fi.isFile())
11180 {
11181 std::string dirPath = fi.dirPath(true);
11182 std::string filePath = fi.absFilePath();
11183 if (paths && !dirPath.empty())
11184 {
11185 paths->insert(dirPath);
11186 }
11187 //printf("killSet.find(%s)=%d\n",qPrint(fi.absFilePath()),killSet.find(fi.absFilePath())!=killSet.end());
11188 if (killSet==nullptr || killSet->find(filePath)==killSet->end())
11189 {
11190 std::string name=fi.fileName();
11191 if (fnMap)
11192 {
11193 auto fd = createFileDef(dirPath+"/",name);
11194 if (!name.empty())
11195 {
11196 FileName *fn = fnMap->add(name,filePath);
11197 fn->push_back(std::move(fd));
11198 }
11199 }
11200 if (resultList || resultSet)
11201 {
11202 if (resultList) resultList->push_back(filePath);
11203 if (resultSet) resultSet->insert(filePath);
11204 }
11205
11206 if (killSet) killSet->insert(fi.absFilePath());
11207 }
11208 }
11209 else if (fi.isDir()) // readable dir
11210 {
11211 readDir(&fi,fnMap,exclSet,patList,
11212 exclPatList,resultList,resultSet,errorIfNotExist,
11213 recursive,killSet,paths);
11214 }
11215 }
11216 }
11217}

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

10357{
10358 QCString fileName;
10359 QCString destName;
10360 int eqPos = tagLine.find('=');
10361 if (eqPos!=-1) // tag command contains a destination
10362 {
10363 fileName = tagLine.left(eqPos).stripWhiteSpace();
10364 destName = tagLine.right(tagLine.length()-eqPos-1).stripWhiteSpace();
10365 if (fileName.isEmpty() || destName.isEmpty()) return;
10366 //printf("insert tagDestination %s->%s\n",qPrint(fi.fileName()),qPrint(destName));
10367 }
10368 else
10369 {
10370 fileName = tagLine;
10371 }
10372
10373 FileInfo fi(fileName.str());
10374 if (!fi.exists() || !fi.isFile())
10375 {
10376 err("Tag file '{}' does not exist or is not a file. Skipping it...\n",fileName);
10377 return;
10378 }
10379
10380 if (Doxygen::tagFileSet.find(fi.absFilePath()) != Doxygen::tagFileSet.end()) return;
10381
10382 Doxygen::tagFileSet.emplace(fi.absFilePath());
10383
10384 if (!destName.isEmpty())
10385 {
10386 Doxygen::tagDestinationMap.emplace(fi.absFilePath(), destName.str());
10387 msg("Reading tag file '{}', location '{}'...\n",fileName,destName);
10388 }
10389 else
10390 {
10391 msg("Reading tag file '{}'...\n",fileName);
10392 }
10393
10394 parseTagFile(root,fi.absFilePath().c_str());
10395}
static StringUnorderedSet tagFileSet
Definition doxygen.h:116
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 1365 of file doxygen.cpp.

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

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

10961{
10962 int sepPos=0;
10963 int oldPos=0;
10964 StringUnorderedSet nonSymlinks;
10965 StringUnorderedSet known;
10966 QCString result(path);
10967 QCString oldPrefix = "/";
10968 do
10969 {
10970#if defined(_WIN32)
10971 // UNC path, skip server and share name
10972 if (sepPos==0 && (result.startsWith("//") || result.startsWith("\\\\")))
10973 sepPos = result.find('/',2);
10974 if (sepPos!=-1)
10975 sepPos = result.find('/',sepPos+1);
10976#else
10977 sepPos = result.find('/',sepPos+1);
10978#endif
10979 QCString prefix = sepPos==-1 ? result : result.left(sepPos);
10980 if (nonSymlinks.find(prefix.str())==nonSymlinks.end())
10981 {
10982 FileInfo fi(prefix.str());
10983 if (fi.isSymLink())
10984 {
10985 QCString target = fi.readLink();
10986 bool isRelative = FileInfo(target.str()).isRelative();
10987 if (isRelative)
10988 {
10989 target = Dir::cleanDirPath(oldPrefix.str()+"/"+target.str());
10990 }
10991 if (sepPos!=-1)
10992 {
10993 if (fi.isDir() && target.length()>0 && target.at(target.length()-1)!='/')
10994 {
10995 target+='/';
10996 }
10997 target+=result.mid(sepPos);
10998 }
10999 result = Dir::cleanDirPath(target.str());
11000 if (known.find(result.str())!=known.end()) return std::string(); // recursive symlink!
11001 known.insert(result.str());
11002 if (isRelative)
11003 {
11004 sepPos = oldPos;
11005 }
11006 else // link to absolute path
11007 {
11008 sepPos = 0;
11009 oldPrefix = "/";
11010 }
11011 }
11012 else
11013 {
11014 nonSymlinks.insert(prefix.str());
11015 oldPrefix = prefix;
11016 }
11017 oldPos = sepPos;
11018 }
11019 }
11020 while (sepPos!=-1);
11021 return Dir::cleanDirPath(result.str());
11022}
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 4801 of file doxygen.cpp.

4802{
4803 // For a statement like 'using X = T<A>', add a template instance 'T<A>' as a symbol, so it can
4804 // be used to match arguments (see issue #11111)
4805 AUTO_TRACE();
4806 QCString ttype = md->typeString();
4807 ttype.stripPrefix("typedef ");
4808 int ti=ttype.find('<');
4809 if (ti!=-1)
4810 {
4811 QCString templateClassName = ttype.left(ti);
4812 SymbolResolver resolver(root->fileDef());
4813 ClassDefMutable *baseClass = resolver.resolveClassMutable(scope ? scope : Doxygen::globalScope,
4814 templateClassName, true, true);
4815 AUTO_TRACE_ADD("templateClassName={} baseClass={}",templateClassName,baseClass?baseClass->name():"<none>");
4816 if (baseClass)
4817 {
4818 const ArgumentList &tl = baseClass->templateArguments();
4819 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,templateClassName.str());
4821 baseClass,
4822 ttype.mid(ti),
4823 templateNames,
4824 baseClass->isArtificial());
4825 }
4826 }
4827}

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

9860{
9861 for (const auto &si : SectionManager::instance())
9862 {
9863 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
9864 // qPrint(si->label),si->definition?qPrint(si->definition->name()):"<none>",
9865 // qPrint(si->fileName));
9866 PageDef *pd=nullptr;
9867
9868 // hack: the items of a todo/test/bug/deprecated list are all fragments from
9869 // different files, so the resulting section's all have the wrong file
9870 // name (not from the todo/test/bug/deprecated list, but from the file in
9871 // which they are defined). We correct this here by looking at the
9872 // generated section labels!
9874 {
9875 QCString label="_"+rl->listName(); // "_todo", "_test", ...
9876 if (si->label().left(label.length())==label)
9877 {
9878 si->setFileName(rl->listName());
9879 si->setGenerated(TRUE);
9880 break;
9881 }
9882 }
9883
9884 //printf("start: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9885 if (!si->generated())
9886 {
9887 // if this section is in a page and the page is in a group, then we
9888 // have to adjust the link file name to point to the group.
9889 if (!si->fileName().isEmpty() &&
9890 (pd=Doxygen::pageLinkedMap->find(si->fileName())) &&
9891 pd->getGroupDef())
9892 {
9893 si->setFileName(pd->getGroupDef()->getOutputFileBase());
9894 }
9895
9896 if (si->definition())
9897 {
9898 // TODO: there should be one function in Definition that returns
9899 // the file to link to, so we can avoid the following tests.
9900 const GroupDef *gd=nullptr;
9901 if (si->definition()->definitionType()==Definition::TypeMember)
9902 {
9903 gd = (toMemberDef(si->definition()))->getGroupDef();
9904 }
9905
9906 if (gd)
9907 {
9908 si->setFileName(gd->getOutputFileBase());
9909 }
9910 else
9911 {
9912 //si->fileName=si->definition->getOutputFileBase();
9913 //printf("Setting si->fileName to %s\n",qPrint(si->fileName));
9914 }
9915 }
9916 }
9917 //printf("end: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9918 }
9919}
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 10183 of file doxygen.cpp.

10184{
10185 std::string oldDir = Dir::currentDirPath();
10186 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10189 {
10190 err("failed to run html help compiler on {}\n", HtmlHelp::hhpFileName);
10191 }
10192 Dir::setCurrent(oldDir);
10193}
@ 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 10195 of file doxygen.cpp.

10196{
10197 QCString args = Qhp::qhpFileName + " -o \"" + Qhp::getQchFileName() + "\"";
10198 std::string oldDir = Dir::currentDirPath();
10199 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10200
10201 QCString qhgLocation=Config_getString(QHG_LOCATION);
10202 if (Debug::isFlagSet(Debug::Qhp)) // produce info for debugging
10203 {
10204 // run qhelpgenerator -v and extract the Qt version used
10205 QCString cmd=qhgLocation+ " -v 2>&1";
10206 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10207 FILE *f=Portable::popen(cmd,"r");
10208 if (!f)
10209 {
10210 err("could not execute {}\n",qhgLocation);
10211 }
10212 else
10213 {
10214 const size_t bufSize = 1024;
10215 char inBuf[bufSize+1];
10216 size_t numRead=fread(inBuf,1,bufSize,f);
10217 inBuf[numRead] = '\0';
10218 Debug::print(Debug::Qhp,0,"{}",inBuf);
10220
10221 int qtVersion=0;
10222 static const reg::Ex versionReg(R"(Qt (\d+)\.(\d+)\.(\d+))");
10224 std::string s = inBuf;
10225 if (reg::search(s,match,versionReg))
10226 {
10227 qtVersion = 10000*QCString(match[1].str()).toInt() +
10228 100*QCString(match[2].str()).toInt() +
10229 QCString(match[3].str()).toInt();
10230 }
10231 if (qtVersion>0 && (qtVersion<60000 || qtVersion >= 60205))
10232 {
10233 // dump the output of qhelpgenerator -c file.qhp
10234 // Qt<6 or Qt>=6.2.5 or higher, see https://bugreports.qt.io/browse/QTBUG-101070
10235 cmd=qhgLocation+ " -c " + Qhp::qhpFileName + " 2>&1";
10236 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10237 f=Portable::popen(cmd,"r");
10238 if (!f)
10239 {
10240 err("could not execute {}\n",qhgLocation);
10241 }
10242 else
10243 {
10244 std::string output;
10245 while ((numRead=fread(inBuf,1,bufSize,f))>0)
10246 {
10247 inBuf[numRead] = '\0';
10248 output += inBuf;
10249 }
10251 Debug::print(Debug::Qhp,0,"{}",output);
10252 }
10253 }
10254 }
10255 }
10256
10257 if (Portable::system(qhgLocation, args, FALSE))
10258 {
10259 err("failed to run qhelpgenerator on {}\n",Qhp::qhpFileName);
10260 }
10261 Dir::setCurrent(oldDir);
10262}
@ 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 5974 of file doxygen.cpp.

5975{
5976 bool result=FALSE;
5977 //printf("> scopeIsTemplate(%s)\n",qPrint(d?d->name():"null"));
5979 {
5980 auto cd = toClassDef(d);
5981 result = cd->templateArguments().hasParameters() || cd->templateMaster()!=nullptr ||
5983 }
5984 //printf("< scopeIsTemplate=%d\n",result);
5985 return result;
5986}

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

Referenced by addMemberFunction(), and scopeIsTemplate().

◆ searchInputFiles()

void searchInputFiles ( )

Definition at line 12198 of file doxygen.cpp.

12199{
12200 StringUnorderedSet killSet;
12201
12202 const StringVector &exclPatterns = Config_getList(EXCLUDE_PATTERNS);
12203 bool alwaysRecursive = Config_getBool(RECURSIVE);
12204 StringUnorderedSet excludeNameSet;
12205
12206 // gather names of all files in the include path
12207 g_s.begin("Searching for include files...\n");
12208 killSet.clear();
12209 const StringVector &includePathList = Config_getList(INCLUDE_PATH);
12210 for (const auto &s : includePathList)
12211 {
12212 size_t plSize = Config_getList(INCLUDE_FILE_PATTERNS).size();
12213 const StringVector &pl = plSize==0 ? Config_getList(FILE_PATTERNS) :
12214 Config_getList(INCLUDE_FILE_PATTERNS);
12215 readFileOrDirectory(s, // s
12217 nullptr, // exclSet
12218 &pl, // patList
12219 &exclPatterns, // exclPatList
12220 nullptr, // resultList
12221 nullptr, // resultSet
12222 false, // INCLUDE_PATH isn't recursive
12223 TRUE, // errorIfNotExist
12224 &killSet); // killSet
12225 }
12226 g_s.end();
12227
12228 g_s.begin("Searching for example files...\n");
12229 killSet.clear();
12230 const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
12231 for (const auto &s : examplePathList)
12232 {
12233 readFileOrDirectory(s, // s
12235 nullptr, // exclSet
12236 &Config_getList(EXAMPLE_PATTERNS), // patList
12237 nullptr, // exclPatList
12238 nullptr, // resultList
12239 nullptr, // resultSet
12240 (alwaysRecursive || Config_getBool(EXAMPLE_RECURSIVE)), // recursive
12241 TRUE, // errorIfNotExist
12242 &killSet); // killSet
12243 }
12244 g_s.end();
12245
12246 g_s.begin("Searching for images...\n");
12247 killSet.clear();
12248 const StringVector &imagePathList=Config_getList(IMAGE_PATH);
12249 for (const auto &s : imagePathList)
12250 {
12251 readFileOrDirectory(s, // s
12253 nullptr, // exclSet
12254 nullptr, // patList
12255 nullptr, // exclPatList
12256 nullptr, // resultList
12257 nullptr, // resultSet
12258 alwaysRecursive, // recursive
12259 TRUE, // errorIfNotExist
12260 &killSet); // killSet
12261 }
12262 g_s.end();
12263
12264 g_s.begin("Searching for dot files...\n");
12265 killSet.clear();
12266 const StringVector &dotFileList=Config_getList(DOTFILE_DIRS);
12267 for (const auto &s : dotFileList)
12268 {
12269 readFileOrDirectory(s, // s
12271 nullptr, // exclSet
12272 nullptr, // patList
12273 nullptr, // exclPatList
12274 nullptr, // resultList
12275 nullptr, // resultSet
12276 alwaysRecursive, // recursive
12277 TRUE, // errorIfNotExist
12278 &killSet); // killSet
12279 }
12280 g_s.end();
12281
12282 g_s.begin("Searching for msc files...\n");
12283 killSet.clear();
12284 const StringVector &mscFileList=Config_getList(MSCFILE_DIRS);
12285 for (const auto &s : mscFileList)
12286 {
12287 readFileOrDirectory(s, // s
12289 nullptr, // exclSet
12290 nullptr, // patList
12291 nullptr, // exclPatList
12292 nullptr, // resultList
12293 nullptr, // resultSet
12294 alwaysRecursive, // recursive
12295 TRUE, // errorIfNotExist
12296 &killSet); // killSet
12297 }
12298 g_s.end();
12299
12300 g_s.begin("Searching for dia files...\n");
12301 killSet.clear();
12302 const StringVector &diaFileList=Config_getList(DIAFILE_DIRS);
12303 for (const auto &s : diaFileList)
12304 {
12305 readFileOrDirectory(s, // s
12307 nullptr, // exclSet
12308 nullptr, // patList
12309 nullptr, // exclPatList
12310 nullptr, // resultList
12311 nullptr, // resultSet
12312 alwaysRecursive, // recursive
12313 TRUE, // errorIfNotExist
12314 &killSet); // killSet
12315 }
12316 g_s.end();
12317
12318 g_s.begin("Searching for plantuml files...\n");
12319 killSet.clear();
12320 const StringVector &plantUmlFileList=Config_getList(PLANTUMLFILE_DIRS);
12321 for (const auto &s : plantUmlFileList)
12322 {
12323 readFileOrDirectory(s, // s
12325 nullptr, // exclSet
12326 nullptr, // patList
12327 nullptr, // exclPatList
12328 nullptr, // resultList
12329 nullptr, // resultSet
12330 alwaysRecursive, // recursive
12331 TRUE, // errorIfNotExist
12332 &killSet); // killSet
12333 }
12334 g_s.end();
12335
12336 g_s.begin("Searching for files to exclude\n");
12337 const StringVector &excludeList = Config_getList(EXCLUDE);
12338 for (const auto &s : excludeList)
12339 {
12340 readFileOrDirectory(s, // s
12341 nullptr, // fnDict
12342 nullptr, // exclSet
12343 &Config_getList(FILE_PATTERNS), // patList
12344 nullptr, // exclPatList
12345 nullptr, // resultList
12346 &excludeNameSet, // resultSet
12347 alwaysRecursive, // recursive
12348 FALSE); // errorIfNotExist
12349 }
12350 g_s.end();
12351
12352 /**************************************************************************
12353 * Determine Input Files *
12354 **************************************************************************/
12355
12356 g_s.begin("Searching INPUT for files to process...\n");
12357 killSet.clear();
12358 Doxygen::inputPaths.clear();
12359 const StringVector &inputList=Config_getList(INPUT);
12360 for (const auto &s : inputList)
12361 {
12362 QCString path = s;
12363 size_t l = path.length();
12364 if (l>0)
12365 {
12366 // strip trailing slashes
12367 if (path.at(l-1)=='\\' || path.at(l-1)=='/') path=path.left(l-1);
12368
12370 path, // s
12372 &excludeNameSet, // exclSet
12373 &Config_getList(FILE_PATTERNS), // patList
12374 &exclPatterns, // exclPatList
12375 &g_inputFiles, // resultList
12376 nullptr, // resultSet
12377 alwaysRecursive, // recursive
12378 TRUE, // errorIfNotExist
12379 &killSet, // killSet
12380 &Doxygen::inputPaths); // paths
12381 }
12382 }
12383
12384 // Sort the FileDef objects by full path to get a predictable ordering over multiple runs
12385 std::stable_sort(Doxygen::inputNameLinkedMap->begin(),
12387 [](const auto &f1,const auto &f2)
12388 {
12389 return qstricmp_sort(f1->fullName(),f2->fullName())<0;
12390 });
12391 for (auto &fileName : *Doxygen::inputNameLinkedMap)
12392 {
12393 if (fileName->size()>1)
12394 {
12395 std::stable_sort(fileName->begin(),fileName->end(),[](const auto &f1,const auto &f2)
12396 {
12397 return qstricmp_sort(f1->absFilePath(),f2->absFilePath())<0;
12398 });
12399 }
12400 }
12401 if (Doxygen::inputNameLinkedMap->empty())
12402 {
12403 warn_uncond("No files to be processed, please check your settings, in particular INPUT, FILE_PATTERNS, and RECURSIVE\n");
12404 }
12405 g_s.end();
12406}
static StringUnorderedSet inputPaths
Definition doxygen.h:103
void readFileOrDirectory(const QCString &s, FileNameLinkedMap *fnMap, StringUnorderedSet *exclSet, const StringVector *patList, const StringVector *exclPatList, StringVector *resultList, StringUnorderedSet *resultSet, bool recursive, bool errorIfNotExist, StringUnorderedSet *killSet, StringUnorderedSet *paths)

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

Referenced by parseInput().

◆ setAnonymousEnumType()

void setAnonymousEnumType ( )
static

Definition at line 9005 of file doxygen.cpp.

9006{
9007 for (const auto &cd : *Doxygen::classLinkedMap)
9008 {
9009 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9010 if (cdm)
9011 {
9012 cdm->setAnonymousEnumType();
9013 }
9014 }
9015}
virtual void setAnonymousEnumType()=0

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

Referenced by parseInput().

◆ sortMemberLists()

void sortMemberLists ( )
static

Definition at line 8910 of file doxygen.cpp.

8911{
8912 // sort class member lists
8913 for (const auto &cd : *Doxygen::classLinkedMap)
8914 {
8915 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8916 if (cdm)
8917 {
8918 cdm->sortMemberLists();
8919 }
8920 }
8921
8922 // sort namespace member lists
8923 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8924 {
8926 if (ndm)
8927 {
8928 ndm->sortMemberLists();
8929 }
8930 }
8931
8932 // sort file member lists
8933 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8934 {
8935 for (const auto &fd : *fn)
8936 {
8937 fd->sortMemberLists();
8938 }
8939 }
8940
8941 // sort group member lists
8942 for (const auto &gd : *Doxygen::groupLinkedMap)
8943 {
8944 gd->sortMemberLists();
8945 }
8946
8948}
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 12067 of file doxygen.cpp.

12068{
12069 signal(SIGINT,SIG_DFL); // Re-register signal handler for default action
12070 Dir thisDir;
12071 msg("Cleaning up...\n");
12072 if (!Doxygen::filterDBFileName.isEmpty())
12073 {
12074 thisDir.remove(Doxygen::filterDBFileName.str());
12075 }
12076 killpg(0,SIGINT);
12078 exitTracing();
12079 exit(1);
12080}

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

6078{
6079 auto dstIt = dst.begin();
6080 for (const Argument &sa : src)
6081 {
6082 QCString dstType = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.type.str());
6083 QCString dstArray = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.array.str());
6084 if (dstIt == dst.end())
6085 {
6086 Argument da = sa;
6087 da.type = dstType;
6088 da.array = dstArray;
6089 dst.push_back(da);
6090 dstIt = dst.end();
6091 }
6092 else
6093 {
6094 Argument da = *dstIt;
6095 da.type = dstType;
6096 da.array = dstArray;
6097 ++dstIt;
6098 }
6099 }
6100 dst.setConstSpecifier(src.constSpecifier());
6101 dst.setVolatileSpecifier(src.volatileSpecifier());
6102 dst.setPureSpecifier(src.pureSpecifier());
6104 srcTempArgLists,dstTempArgLists,
6105 src.trailingReturnType().str()));
6106 dst.setIsDeleted(src.isDeleted());
6107 dst.setRefQualifier(src.refQualifier());
6108 dst.setNoParameters(src.noParameters());
6109 //printf("substituteTemplatesInArgList: replacing %s with %s\n",
6110 // qPrint(argListToString(src)),qPrint(argListToString(dst))
6111 // );
6112}
iterator end()
Definition arguments.h:94
void setPureSpecifier(bool b)
Definition arguments.h:121
void push_back(const Argument &a)
Definition arguments.h:102
void setConstSpecifier(bool b)
Definition arguments.h:119
void setRefQualifier(RefQualifierType t)
Definition arguments.h:126
void setIsDeleted(bool b)
Definition arguments.h:125
iterator begin()
Definition arguments.h:93
void setNoParameters(bool b)
Definition arguments.h:127
void setVolatileSpecifier(bool b)
Definition arguments.h:120
static QCString substituteTemplatesInString(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const std::string &src)
Definition doxygen.cpp:5988
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 5988 of file doxygen.cpp.

5993{
5994 std::string dst;
5995 static const reg::Ex re(R"(\a\w*)");
5996 reg::Iterator it(src,re);
5998 //printf("type=%s\n",qPrint(sa->type));
5999 size_t p=0;
6000 for (; it!=end ; ++it) // for each word in srcType
6001 {
6002 const auto &match = *it;
6003 size_t i = match.position();
6004 size_t l = match.length();
6005 bool found=FALSE;
6006 dst+=src.substr(p,i-p);
6007 std::string name=match.str();
6008
6009 auto srcIt = srcTempArgLists.begin();
6010 auto dstIt = dstTempArgLists.begin();
6011 while (srcIt!=srcTempArgLists.end() && !found)
6012 {
6013 const ArgumentList *tdAli = nullptr;
6014 std::vector<Argument>::const_iterator tdaIt;
6015 if (dstIt!=dstTempArgLists.end())
6016 {
6017 tdAli = &(*dstIt);
6018 tdaIt = tdAli->begin();
6019 ++dstIt;
6020 }
6021
6022 const ArgumentList &tsaLi = *srcIt;
6023 for (auto tsaIt = tsaLi.begin(); tsaIt!=tsaLi.end() && !found; ++tsaIt)
6024 {
6025 Argument tsa = *tsaIt;
6026 const Argument *tda = nullptr;
6027 if (tdAli && tdaIt!=tdAli->end())
6028 {
6029 tda = &(*tdaIt);
6030 ++tdaIt;
6031 }
6032 //if (tda) printf("tsa=%s|%s tda=%s|%s\n",
6033 // qPrint(tsa.type),qPrint(tsa.name),
6034 // qPrint(tda->type),qPrint(tda->name));
6035 if (name==tsa.name.str())
6036 {
6037 if (tda && tda->name.isEmpty())
6038 {
6039 QCString tdaName = tda->name;
6040 QCString tdaType = tda->type;
6041 int vc=0;
6042 if (tdaType.startsWith("class ")) vc=6;
6043 else if (tdaType.startsWith("typename ")) vc=9;
6044 if (vc>0) // convert type=="class T" to type=="class" name=="T"
6045 {
6046 tdaName = tdaType.mid(vc);
6047 }
6048 if (!tdaName.isEmpty())
6049 {
6050 name=tdaName.str(); // substitute
6051 found=TRUE;
6052 }
6053 }
6054 }
6055 }
6056
6057 //printf(" srcList='%s' dstList='%s faList='%s'\n",
6058 // qPrint(argListToString(srclali.current())),
6059 // qPrint(argListToString(dstlali.current())),
6060 // funcTempArgList ? qPrint(argListToString(funcTempArgList)) : "<none>");
6061 ++srcIt;
6062 }
6063 dst+=name;
6064 p=i+l;
6065 }
6066 dst+=src.substr(p);
6067 //printf(" substituteTemplatesInString(%s)=%s\n",
6068 // qPrint(src),qPrint(dst));
6069 return dst;
6070}

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

4314{
4315 AUTO_TRACE();
4316
4317 // find matching function declaration and definitions.
4318 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4319 {
4320 //printf("memberName=%s count=%zu\n",qPrint(mn->memberName()),mn->size());
4321 /* find a matching function declaration and definition for this function */
4322 for (const auto &imdec : *mn)
4323 {
4324 MemberDefMutable *mdec = toMemberDefMutable(imdec.get());
4325 if (mdec &&
4326 (mdec->isPrototype() ||
4327 (mdec->isVariable() && mdec->isExternal())
4328 ))
4329 {
4330 for (const auto &imdef : *mn)
4331 {
4332 MemberDefMutable *mdef = toMemberDefMutable(imdef.get());
4333 if (mdef && mdec!=mdef &&
4334 mdec->getNamespaceDef()==mdef->getNamespaceDef())
4335 {
4337 }
4338 }
4339 }
4340 }
4341 }
4342}
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 4346 of file doxygen.cpp.

4347{
4348 AUTO_TRACE();
4349 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4350 {
4351 MemberDefMutable *mdef=nullptr,*mdec=nullptr;
4352 /* find a matching function declaration and definition for this function */
4353 for (const auto &imd : *mn)
4354 {
4355 MemberDefMutable *md = toMemberDefMutable(imd.get());
4356 if (md)
4357 {
4358 if (md->isPrototype())
4359 mdec=md;
4360 else if (md->isVariable() && md->isExternal())
4361 mdec=md;
4362
4363 if (md->isFunction() && !md->isStatic() && !md->isPrototype())
4364 mdef=md;
4365 else if (md->isVariable() && !md->isExternal() && !md->isStatic())
4366 mdef=md;
4367 }
4368
4369 if (mdef && mdec) break;
4370 }
4371 if (mdef && mdec)
4372 {
4373 const ArgumentList &mdefAl = mdef->argumentList();
4374 const ArgumentList &mdecAl = mdec->argumentList();
4375 if (
4376 matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdef->typeString(),const_cast<ArgumentList*>(&mdefAl),
4377 mdec->getOuterScope(),mdec->getFileDef(),mdec->typeString(),const_cast<ArgumentList*>(&mdecAl),
4378 TRUE,mdef->getLanguage()
4379 )
4380 ) /* match found */
4381 {
4382 AUTO_TRACE_ADD("merging references for mdec={} mdef={}",mdec->name(),mdef->name());
4383 mdef->mergeReferences(mdec);
4384 mdec->mergeReferences(mdef);
4385 mdef->mergeReferencedBy(mdec);
4386 mdec->mergeReferencedBy(mdef);
4387 }
4388 }
4389 }
4390}
virtual void mergeReferencedBy(const Definition *other)=0
virtual void mergeReferences(const Definition *other)=0

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

Referenced by parseInput().

◆ transferRelatedFunctionDocumentation()

void transferRelatedFunctionDocumentation ( )
static

Definition at line 4394 of file doxygen.cpp.

4395{
4396 AUTO_TRACE();
4397 // find match between function declaration and definition for
4398 // related functions
4399 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4400 {
4401 /* find a matching function declaration and definition for this function */
4402 // for each global function
4403 for (const auto &imd : *mn)
4404 {
4405 MemberDefMutable *md = toMemberDefMutable(imd.get());
4406 if (md)
4407 {
4408 //printf(" Function '%s'\n",qPrint(md->name()));
4409 MemberName *rmn = Doxygen::memberNameLinkedMap->find(md->name());
4410 if (rmn) // check if there is a member with the same name
4411 {
4412 //printf(" Member name found\n");
4413 // for each member with the same name
4414 for (const auto &irmd : *rmn)
4415 {
4416 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
4417 //printf(" Member found: related='%d'\n",rmd->isRelated());
4418 if (rmd &&
4419 (rmd->isRelated() || rmd->isForeign()) && // related function
4420 matchArguments2( md->getOuterScope(), md->getFileDef(), md->typeString(), &md->argumentList(),
4421 rmd->getOuterScope(),rmd->getFileDef(),rmd->typeString(),&rmd->argumentList(),
4422 TRUE,md->getLanguage()
4423 )
4424 )
4425 {
4426 AUTO_TRACE_ADD("Found related member '{}'",md->name());
4427 if (rmd->relatedAlso())
4428 md->setRelatedAlso(rmd->relatedAlso());
4429 else if (rmd->isForeign())
4430 md->makeForeign();
4431 else
4432 md->makeRelated();
4433 }
4434 }
4435 }
4436 }
4437 }
4438 }
4439}
virtual bool isForeign() const =0
virtual ClassDef * relatedAlso() const =0
virtual void setRelatedAlso(ClassDef *cd)=0
virtual void makeForeign()=0

References MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, Doxygen::functionNameLinkedMap, MemberDef::getFileDef(), Definition::getLanguage(), Definition::getOuterScope(), MemberDef::isForeign(), MemberDef::isRelated(), MemberDefMutable::makeForeign(), MemberDefMutable::makeRelated(), matchArguments2(), Doxygen::memberNameLinkedMap, Definition::name(), MemberDef::relatedAlso(), MemberDefMutable::setRelatedAlso(), toMemberDefMutable(), TRUE, and MemberDef::typeString().

Referenced by parseInput().

◆ transferStaticInstanceInitializers()

void transferStaticInstanceInitializers ( )

Definition at line 4443 of file doxygen.cpp.

4444{
4445 AUTO_TRACE();
4446 for (const auto &[qualifiedName,bodyInfo] : Doxygen::staticInitMap)
4447 {
4448 size_t i=qualifiedName.rfind("::");
4449 if (i!=std::string::npos)
4450 {
4451 QCString scope = qualifiedName.substr(0,i);
4452 QCString name = qualifiedName.substr(i+2);
4453 MemberName *mn = Doxygen::memberNameLinkedMap->find(name);
4454 if (mn)
4455 {
4456 for (const auto &imd : *mn)
4457 {
4458 MemberDefMutable *md = toMemberDefMutable(imd.get());
4459 if (md && md->qualifiedName().str()==qualifiedName && md->isVariable())
4460 {
4461 AUTO_TRACE_ADD("found static member {} body [{}..{}]\n",
4462 md->qualifiedName(),bodyInfo.startLine,bodyInfo.endLine);
4463 md->setBodySegment(bodyInfo.defLine,
4464 bodyInfo.startLine,
4465 bodyInfo.endLine);
4466 }
4467 }
4468 }
4469 }
4470 }
4471}

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

7996{
7997 for (const auto &g : root->groups)
7998 {
7999 const GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
8000 if (gd)
8001 {
8002 MemberList *ml = gd->getMemberList(MemberListType::DecEnumMembers());
8003 if (ml)
8004 {
8005 MemberDefMutable *md = toMemberDefMutable(ml->find(name));
8006 if (md)
8007 {
8008 addEnumDocs(root,md);
8009 return TRUE;
8010 }
8011 }
8012 }
8013 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
8014 {
8015 warn(root->fileName, root->startLine,
8016 "Found non-existing group '{}' for the command '{}', ignoring command",
8017 g.groupname, Grouping::getGroupPriName( g.pri )
8018 );
8019 }
8020 }
8021
8022 return FALSE;
8023}
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 11310 of file doxygen.cpp.

11311{
11313 msg("Doxygen version {0}\nCopyright Dimitri van Heesch 1997-2025\n\n"
11314 "You can use Doxygen in a number of ways:\n\n"
11315 "1) Use Doxygen to generate a template configuration file*:\n"
11316 " {1} [-s] -g [configName]\n\n"
11317 "2) Use Doxygen to update an old configuration file*:\n"
11318 " {1} [-s] -u [configName]\n\n"
11319 "3) Use Doxygen to generate documentation using an existing "
11320 "configuration file*:\n"
11321 " {1} [configName]\n\n"
11322 "4) Use Doxygen to generate a template file controlling the layout of the\n"
11323 " generated documentation:\n"
11324 " {1} -l [layoutFileName]\n\n"
11325 " In case layoutFileName is omitted DoxygenLayout.xml will be used as filename.\n"
11326 " If - is used for layoutFileName Doxygen will write to standard output.\n\n"
11327 "5) Use Doxygen to generate a template style sheet file for RTF, HTML or Latex.\n"
11328 " RTF: {1} -w rtf styleSheetFile\n"
11329 " HTML: {1}-w html headerFile footerFile styleSheetFile [configFile]\n"
11330 " LaTeX: {1} -w latex headerFile footerFile styleSheetFile [configFile]\n\n"
11331 "6) Use Doxygen to generate a rtf extensions file\n"
11332 " {1} -e rtf extensionsFile\n\n"
11333 " If - is used for extensionsFile Doxygen will write to standard output.\n\n"
11334 "7) Use Doxygen to compare the used configuration file with the template configuration file\n"
11335 " {1} -x [configFile]\n\n"
11336 " Use Doxygen to compare the used configuration file with the template configuration file\n"
11337 " without replacing the environment variables or CMake type replacement variables\n"
11338 " {1} -x_noenv [configFile]\n\n"
11339 "8) Use Doxygen to show a list of built-in emojis.\n"
11340 " {1} -f emoji outputFileName\n\n"
11341 " If - is used for outputFileName Doxygen will write to standard output.\n\n"
11342 "*) If -s is specified the comments of the configuration items in the config file will be omitted.\n"
11343 " If configName is omitted 'Doxyfile' will be used as a default.\n"
11344 " If - is used for configFile Doxygen will write / read the configuration to /from standard output / input.\n\n"
11345 "If -q is used for a Doxygen documentation run, Doxygen will see this as if QUIET=YES has been set.\n\n"
11346 "-v print version string, -V print extended version information\n"
11347 "-h,-? prints usage help information\n"
11348 "{1} -d prints additional usage flags for debugging purposes\n",versionString,name);
11349}

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

Referenced by readConfiguration().

◆ version()

void version ( const bool extended)
static

Definition at line 11282 of file doxygen.cpp.

11283{
11285 QCString versionString = getFullVersion();
11286 msg("{}\n",versionString);
11287 if (extended)
11288 {
11289 QCString extVers;
11290 if (!extVers.isEmpty()) extVers+= ", ";
11291 extVers += "sqlite3 ";
11292 extVers += sqlite3_libversion();
11293#if USE_LIBCLANG
11294 if (!extVers.isEmpty()) extVers+= ", ";
11295 extVers += "clang support ";
11296 extVers += CLANG_VERSION_STRING;
11297#endif
11298 if (!extVers.isEmpty())
11299 {
11300 int lastComma = extVers.findRev(',');
11301 if (lastComma != -1) extVers = extVers.replace(lastComma,1," and");
11302 msg(" with {}.\n",extVers);
11303 }
11304 }
11305}
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 8358 of file doxygen.cpp.

8359{
8360 // for each member name
8361 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8362 {
8363 // for each member definition
8364 for (const auto &imd : *mn)
8365 {
8366 MemberDefMutable *md = toMemberDefMutable(imd.get());
8367 if (md)
8368 {
8370 }
8371 }
8372 }
8373 // for each member name
8374 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8375 {
8376 // for each member definition
8377 for (const auto &imd : *mn)
8378 {
8379 MemberDefMutable *md = toMemberDefMutable(imd.get());
8380 if (md)
8381 {
8383 }
8384 }
8385 }
8386}
static void correctMemberProperties(MemberDefMutable *md)

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

Referenced by parseInput().

◆ warnUndocumentedNamespaces()

void warnUndocumentedNamespaces ( )
static

Definition at line 5322 of file doxygen.cpp.

5323{
5324 AUTO_TRACE();
5325 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5326 {
5327 if (!nd->hasDocumentation())
5328 {
5329 if ((guessSection(nd->getDefFileName()).isHeader() ||
5330 nd->getLanguage() == SrcLangExt::Fortran) && // Fortran doesn't have header files.
5331 !Config_getBool(HIDE_UNDOC_NAMESPACES) // undocumented namespaces are visible
5332 )
5333 {
5334 warn_undoc(nd->getDefFileName(),nd->getDefLine(), "{} {} is not documented.",
5335 nd->getLanguage() == SrcLangExt::Fortran ? "Module" : "Namespace",
5336 nd->name());
5337 }
5338 }
5339 }
5340}

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

Referenced by parseInput().

◆ writeTagFile()

void writeTagFile ( )
static

Definition at line 12083 of file doxygen.cpp.

12084{
12085 QCString generateTagFile = Config_getString(GENERATE_TAGFILE);
12086 if (generateTagFile.isEmpty()) return;
12087
12088 std::ofstream f = Portable::openOutputStream(generateTagFile);
12089 if (!f.is_open())
12090 {
12091 err("cannot open tag file {} for writing\n", generateTagFile);
12092 return;
12093 }
12094 TextStream tagFile(&f);
12095 tagFile << "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>\n";
12096 tagFile << "<tagfile doxygen_version=\"" << getDoxygenVersion() << "\"";
12097 std::string gitVersion = getGitVersion();
12098 if (!gitVersion.empty())
12099 {
12100 tagFile << " doxygen_gitid=\"" << gitVersion << "\"";
12101 }
12102 tagFile << ">\n";
12103
12104 // for each file
12105 for (const auto &fn : *Doxygen::inputNameLinkedMap)
12106 {
12107 for (const auto &fd : *fn)
12108 {
12109 if (fd->isLinkableInProject()) fd->writeTagFile(tagFile);
12110 }
12111 }
12112 // for each class
12113 for (const auto &cd : *Doxygen::classLinkedMap)
12114 {
12115 ClassDefMutable *cdm = toClassDefMutable(cd.get());
12116 if (cdm && cdm->isLinkableInProject())
12117 {
12118 cdm->writeTagFile(tagFile);
12119 }
12120 }
12121 // for each concept
12122 for (const auto &cd : *Doxygen::conceptLinkedMap)
12123 {
12124 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
12125 if (cdm && cdm->isLinkableInProject())
12126 {
12127 cdm->writeTagFile(tagFile);
12128 }
12129 }
12130 // for each namespace
12131 for (const auto &nd : *Doxygen::namespaceLinkedMap)
12132 {
12134 if (ndm && nd->isLinkableInProject())
12135 {
12136 ndm->writeTagFile(tagFile);
12137 }
12138 }
12139 // for each group
12140 for (const auto &gd : *Doxygen::groupLinkedMap)
12141 {
12142 if (gd->isLinkableInProject()) gd->writeTagFile(tagFile);
12143 }
12144 // for each module
12145 for (const auto &mod : ModuleManager::instance().modules())
12146 {
12147 if (mod->isLinkableInProject()) mod->writeTagFile(tagFile);
12148 }
12149 // for each page
12150 for (const auto &pd : *Doxygen::pageLinkedMap)
12151 {
12152 if (pd->isLinkableInProject()) pd->writeTagFile(tagFile);
12153 }
12154 // for each directory
12155 for (const auto &dd : *Doxygen::dirLinkedMap)
12156 {
12157 if (dd->isLinkableInProject()) dd->writeTagFile(tagFile);
12158 }
12159 if (Doxygen::mainPage) Doxygen::mainPage->writeTagFile(tagFile);
12160
12161 tagFile << "</tagfile>\n";
12162}
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 2190 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().