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

Go to the source code of this file.

Classes

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

Macros

#define HAS_SIGNALS

Enumerations

enum  FindBaseClassRelation_Mode { TemplateInstances , DocumentedOnly , Undocumented }

Functions

void initResources ()
void clearAll ()
static void addMemberDocs (const Entry *root, MemberDefMutable *md, const QCString &funcDecl, const ArgumentList *al, bool over_load, TypeSpecifier spec)
static void findMember (const Entry *root, const QCString &relates, const QCString &type, const QCString &args, QCString funcDecl, bool overloaded, bool isFunc)
static bool findClassRelation (const Entry *root, Definition *context, ClassDefMutable *cd, const BaseInfo *bi, const TemplateNameMap &templateNames, FindBaseClassRelation_Mode mode, bool isArtificial)
static DefinitionfindScopeFromQualifiedName (NamespaceDefMutable *startScope, const QCString &n, FileDef *fileScope, const TagInfo *tagInfo)
static void resolveTemplateInstanceInType (const Entry *root, const Definition *scope, const MemberDef *md)
static void addPageToContext (PageDef *pd, Entry *root)
static void addRelatedPage (Entry *root)
static void buildGroupListFiltered (const Entry *root, bool additional, bool includeExternal)
static void buildGroupList (const Entry *root)
static void findGroupScope (const Entry *root)
static void organizeSubGroupsFiltered (const Entry *root, bool additional)
static void organizeSubGroups (const Entry *root)
static void buildFileList (const Entry *root)
template<class DefMutable>
static void addIncludeFile (DefMutable *cd, FileDef *ifd, const Entry *root)
QCString stripTemplateSpecifiers (const QCString &s)
static DefinitionbuildScopeFromQualifiedName (const QCString &name_, SrcLangExt lang, const TagInfo *tagInfo)
std::unique_ptr< ArgumentListgetTemplateArgumentsFromName (const QCString &name, const ArgumentLists &tArgLists)
static ClassDef::CompoundType convertToCompoundType (EntryType section, TypeSpecifier specifier)
static void addClassToContext (const Entry *root)
static void buildClassList (const Entry *root)
static void buildClassDocList (const Entry *root)
static void addConceptToContext (const Entry *root)
static void findModuleDocumentation (const Entry *root)
static void buildConceptList (const Entry *root)
static void buildConceptDocList (const Entry *root)
static void distributeConceptGroups ()
static void resolveClassNestingRelations ()
void distributeClassGroupRelations ()
static 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 ()
template<typename Func>
static void applyToAllDefinitions (Func func)
static void addRequirementReferences ()
static void addListReferences ()
static void generateXRefPages ()
static const ClassDeffindClassDefinition (FileDef *fd, NamespaceDef *nd, const QCString &scopeName)
static bool isEntryInGroupOfMember (const Entry *root, const MemberDef *md, bool allowNoGroup=false)
static bool findGlobalMember (const Entry *root, const QCString &namespaceName, const QCString &type, const QCString &name, const QCString &tempArg, const QCString &, const QCString &decl, TypeSpecifier)
static bool isSpecialization (const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists)
static bool scopeIsTemplate (const Definition *d)
static QCString substituteTemplatesInString (const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const std::string &src)
static void substituteTemplatesInArgList (const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const ArgumentList &src, ArgumentList &dst)
static void addLocalObjCMethod (const Entry *root, const QCString &scopeName, const QCString &funcType, const QCString &funcName, const QCString &funcArgs, const QCString &exceptions, const QCString &funcDecl, TypeSpecifier spec)
static void addMemberFunction (const Entry *root, MemberName *mn, const QCString &scopeName, const QCString &namespaceName, const QCString &className, const QCString &funcTyp, const QCString &funcName, const QCString &funcArgs, const QCString &funcTempList, const QCString &exceptions, const QCString &type, const QCString &args, bool isFriend, TypeSpecifier spec, const QCString &relates, const QCString &funcDecl, bool overloaded, bool isFunc)
static void addMemberSpecialization (const Entry *root, MemberName *mn, ClassDefMutable *cd, const QCString &funcType, const QCString &funcName, const QCString &funcArgs, const QCString &funcDecl, const QCString &exceptions, TypeSpecifier spec)
static void addOverloaded (const Entry *root, MemberName *mn, const QCString &funcType, const QCString &funcName, const QCString &funcArgs, const QCString &funcDecl, const QCString &exceptions, TypeSpecifier spec)
static void insertMemberAlias (Definition *outerScope, const MemberDef *md)
static void filterMemberDocumentation (const Entry *root, const QCString &relates)
static void findMemberDocumentation (const Entry *root)
static void findObjCMethodDefinitions (const Entry *root)
static void findEnums (const Entry *root)
static void addEnumValuesToEnums (const Entry *root)
static void addEnumDocs (const Entry *root, MemberDefMutable *md)
static bool tryAddEnumDocsToGroupMember (const Entry *root, const QCString &name)
static void findEnumDocumentation (const Entry *root)
static void findDEV (const MemberNameLinkedMap &mnsd)
static void findDocumentedEnumValues ()
static void addMembersToIndex ()
static void addToIndices ()
static void vhdlCorrectMemberProperties ()
static void computeMemberRelationsForBaseClass (const ClassDef *cd, const BaseClassDef *bcd)
static void computeMemberRelations ()
static void createTemplateInstanceMembers ()
static void mergeCategories ()
static void buildCompleteMemberLists ()
static void generateFileSources ()
static void generateFileDocs ()
static void addSourceReferences ()
static void buildDefineList ()
static void sortMemberLists ()
static bool isSymbolHidden (const Definition *d)
static void computeTooltipTexts ()
static void setAnonymousEnumType ()
static void countMembers ()
static void generateDocsForClassList (const std::vector< ClassDefMutable * > &classList)
static void addClassAndNestedClasses (std::vector< ClassDefMutable * > &list, ClassDefMutable *cd)
static void generateClassDocs ()
static void generateConceptDocs ()
static void inheritDocumentation ()
static void combineUsingRelations ()
static void addMembersToMemberGroup ()
static void distributeMemberGroupDocumentation ()
static void findSectionsInDocumentation ()
static void flushCachedTemplateRelations ()
static void flushUnresolvedRelations ()
static bool haveEqualFileNames (const Entry *root, const MemberDef *md)
static void addDefineDoc (const Entry *root, MemberDefMutable *md)
static void findDefineDocumentation (Entry *root)
static void findDirDocumentation (const Entry *root)
static void buildRequirementsList (Entry *root)
static void buildPageList (Entry *root)
static void findMainPage (Entry *root)
static void findMainPageTagFiles (Entry *root)
static void computePageRelations (Entry *root)
static void checkPageRelations ()
static void resolveUserReferences ()
static void generatePageDocs ()
static void buildExampleList (Entry *root)
void printNavTree (Entry *root, int indent)
void printSectionsTree ()
static void generateExampleDocs ()
static void generateGroupDocs ()
static void generateNamespaceClassDocs (const ClassLinkedRefMap &classList)
static void generateNamespaceConceptDocs (const ConceptLinkedRefMap &conceptList)
static void generateNamespaceDocs ()
static void runHtmlHelpCompiler ()
static void runQHelpGenerator ()
static void computeVerifiedDotPath ()
static void generateConfigFile (const QCString &configFile, bool shortList, bool updateOnly=FALSE)
static void compareDoxyfile (Config::CompareMode diffList)
static void readTagFile (const std::shared_ptr< Entry > &root, const QCString &tagLine)
static void copyLatexStyleSheet ()
static void copyStyleSheet ()
static void copyLogo (const QCString &outputOption)
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 133 of file doxygen.cpp.

Enumeration Type Documentation

◆ FindBaseClassRelation_Mode

Enumerator
TemplateInstances 
DocumentedOnly 
Undocumented 

Definition at line 285 of file doxygen.cpp.

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

Function Documentation

◆ addClassAndNestedClasses()

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

Definition at line 9166 of file doxygen.cpp.

9167{
9168 list.push_back(cd);
9169 for (const auto &innerCdi : cd->getClasses())
9170 {
9171 ClassDefMutable *innerCd = toClassDefMutable(innerCdi);
9172 if (innerCd)
9173 {
9174 AUTO_TRACE("innerCd={} isLinkable={} isImplicitTemplateInstance={} protectLevelVisible={} embeddedInOuterScope={}",
9175 innerCd->name(),innerCd->isLinkableInProject(),innerCd->isImplicitTemplateInstance(),protectionLevelVisible(innerCd->protection()),
9176 innerCd->isEmbeddedInOuterScope());
9177 }
9178 if (innerCd && innerCd->isLinkableInProject() && !innerCd->isImplicitTemplateInstance() &&
9179 protectionLevelVisible(innerCd->protection()) &&
9180 !innerCd->isEmbeddedInOuterScope()
9181 )
9182 {
9183 list.push_back(innerCd);
9184 addClassAndNestedClasses(list,innerCd);
9185 }
9186 }
9187}
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:47
static void addClassAndNestedClasses(std::vector< ClassDefMutable * > &list, ClassDefMutable *cd)
Definition doxygen.cpp:9166
bool protectionLevelVisible(Protection prot)
Definition util.cpp:5937

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

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

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

Referenced by buildClassDocList(), and buildClassList().

◆ addConceptToContext()

void addConceptToContext ( const Entry * root)
static

Definition at line 1164 of file doxygen.cpp.

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

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

Referenced by buildConceptDocList(), and buildConceptList().

◆ addDefineDoc()

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

Definition at line 9555 of file doxygen.cpp.

9556{
9557 md->setDocumentation(root->doc,root->docFile,root->docLine);
9558 md->setDocsForDefinition(!root->proto);
9559 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9560 if (md->inbodyDocumentation().isEmpty())
9561 {
9563 }
9564 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
9565 {
9566 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
9567 md->setBodyDef(root->fileDef());
9568 }
9570 md->setMaxInitLines(root->initLines);
9572 md->setRefItems(root->sli);
9573 md->setRequirementReferences(root->rqli);
9574 md->addQualifiers(root->qualifiers);
9575 if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
9576 addMemberToGroups(root,md);
9578}
virtual int getStartBodyLine() const =0
virtual QCString inbodyDocumentation() const =0
virtual void setInbodyDocumentation(const QCString &d, const QCString &docFile, int docLine)=0
bool proto
prototype ?
Definition entry.h:188
QCString inbodyDocs
documentation inside the body of a function
Definition entry.h:207
int inbodyLine
line number at which the body doc was found
Definition entry.h:208
int initLines
define/variable initializer lines to show
Definition entry.h:185
QCString inbodyFile
file in which the body doc was found
Definition entry.h:209
virtual void setMemberGroupId(int id)=0
virtual void setMaxInitLines(int lines)=0
virtual void setDocsForDefinition(bool b)=0
virtual void addQualifiers(const StringVector &qualifiers)=0
void addMemberToModule(const Entry *root, MemberDef *md)
static void applyMemberOverrideOptions(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:2149
void addMemberToGroups(const Entry *root, MemberDef *md)

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

Referenced by findDefineDocumentation().

◆ addEnumDocs()

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

Definition at line 7984 of file doxygen.cpp.

7985{
7986 AUTO_TRACE();
7987 // documentation outside a compound overrides the documentation inside it
7988 {
7989 md->setDocumentation(root->doc,root->docFile,root->docLine);
7990 md->setDocsForDefinition(!root->proto);
7991 }
7992
7993 // brief descriptions inside a compound override the documentation
7994 // outside it
7995 {
7996 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7997 }
7998
7999 if (md->inbodyDocumentation().isEmpty() || !root->parent()->name.isEmpty())
8000 {
8002 }
8003
8004 if (root->mGrpId!=-1 && md->getMemberGroupId()==-1)
8005 {
8006 md->setMemberGroupId(root->mGrpId);
8007 }
8008
8010 md->setRefItems(root->sli);
8011 md->setRequirementReferences(root->rqli);
8012
8013 const GroupDef *gd=md->getGroupDef();
8014 if (gd==nullptr && !root->groups.empty()) // member not grouped but out-of-line documentation is
8015 {
8016 addMemberToGroups(root,md);
8017 }
8019}
std::vector< Grouping > groups
list of groups this entry belongs to
Definition entry.h:222
A model of a group of symbols.
Definition groupdef.h:52
virtual GroupDef * getGroupDef()=0
virtual int getMemberGroupId() const =0

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

Referenced by findEnumDocumentation(), and tryAddEnumDocsToGroupMember().

◆ addEnumValuesToEnums()

void addEnumValuesToEnums ( const Entry * root)
static

Definition at line 7734 of file doxygen.cpp.

7735{
7736 if (root->section.isEnum())
7737 // non anonymous enumeration
7738 {
7739 AUTO_TRACE("name={}",root->name);
7740 ClassDefMutable *cd = nullptr;
7741 FileDef *fd = nullptr;
7742 NamespaceDefMutable *nd = nullptr;
7743 MemberNameLinkedMap *mnsd = nullptr;
7744 bool isGlobal = false;
7745 bool isRelated = false;
7746 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
7747
7748 QCString name;
7749 QCString scope;
7750
7751 int i = root->name.findRev("::");
7752 if (i!=-1) // scope is specified
7753 {
7754 scope=root->name.left(i); // extract scope
7755 if (root->lang==SrcLangExt::CSharp)
7756 {
7757 scope = mangleCSharpGenericName(scope);
7758 }
7759 name=root->name.right(root->name.length()-i-2); // extract name
7760 if ((cd=getClassMutable(scope))==nullptr)
7761 {
7763 }
7764 }
7765 else // no scope, check the scope in which the docs where found
7766 {
7767 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7768 {
7769 scope=root->parent()->name;
7770 if (root->lang==SrcLangExt::CSharp)
7771 {
7772 scope = mangleCSharpGenericName(scope);
7773 }
7774 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7775 }
7776 name=root->name;
7777 }
7778
7779 if (!root->relates.isEmpty())
7780 { // related member, prefix user specified scope
7781 isRelated=TRUE;
7782 if (getClassMutable(root->relates)==nullptr && !scope.isEmpty())
7783 scope=mergeScopes(scope,root->relates);
7784 else
7785 scope=root->relates;
7786 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7787 }
7788
7789 if (cd && !name.isEmpty()) // found a enum inside a compound
7790 {
7791 //printf("Enum in class '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
7792 fd=nullptr;
7794 isGlobal=false;
7795 }
7796 else if (nd && !nd->isAnonymous()) // found enum inside namespace
7797 {
7798 //printf("Enum in namespace '%s'::'%s'\n",qPrint(nd->name()),qPrint(name));
7800 isGlobal=true;
7801 }
7802 else // found a global enum
7803 {
7804 fd=root->fileDef();
7805 //printf("Enum in file '%s': '%s'\n",qPrint(fd->name()),qPrint(name));
7807 isGlobal=true;
7808 }
7809
7810 if (!name.isEmpty())
7811 {
7812 //printf("** name=%s\n",qPrint(name));
7813 MemberName *mn = mnsd->find(name); // for all members with this name
7814 if (mn)
7815 {
7816 struct EnumValueInfo
7817 {
7818 EnumValueInfo(const QCString &n,std::unique_ptr<MemberDef> &&md) :
7819 name(n), member(std::move(md)) {}
7820 QCString name;
7821 std::unique_ptr<MemberDef> member;
7822 };
7823 std::vector< EnumValueInfo > extraMembers;
7824 // for each enum in this list
7825 for (const auto &imd : *mn)
7826 {
7827 MemberDefMutable *md = toMemberDefMutable(imd.get());
7828 // use raw pointer in this loop, since we modify mn and can then invalidate mdp.
7829 if (md && md->isEnumerate() && !root->children().empty())
7830 {
7831 AUTO_TRACE_ADD("enum {} with {} children",md->name(),root->children().size());
7832 for (const auto &e : root->children())
7833 {
7834 SrcLangExt sle = root->lang;
7835 bool isJavaLike = sle==SrcLangExt::CSharp || sle==SrcLangExt::Java || sle==SrcLangExt::XML;
7836 if ( isJavaLike || root->spec.isStrong())
7837 {
7838 if (sle == SrcLangExt::Cpp && e->section.isDefine()) continue;
7839 // Unlike classic C/C++ enums, for C++11, C# & Java enum
7840 // values are only visible inside the enum scope, so we must create
7841 // them here and only add them to the enum
7842 //printf("md->qualifiedName()=%s e->name=%s tagInfo=%p name=%s\n",
7843 // qPrint(md->qualifiedName()),qPrint(e->name),(void*)e->tagInfo(),qPrint(e->name));
7844 QCString qualifiedName = root->name;
7845 i = qualifiedName.findRev("::");
7846 if (i!=-1 && sle==SrcLangExt::CSharp)
7847 {
7848 qualifiedName = mangleCSharpGenericName(qualifiedName.left(i))+qualifiedName.mid(i);
7849 }
7850 if (isJavaLike)
7851 {
7852 qualifiedName=substitute(qualifiedName,"::",".");
7853 }
7854 if (md->qualifiedName()==qualifiedName) // enum value scope matches that of the enum
7855 {
7856 QCString fileName = e->fileName;
7857 if (fileName.isEmpty() && e->tagInfo())
7858 {
7859 fileName = e->tagInfo()->tagName;
7860 }
7861 AUTO_TRACE_ADD("strong enum value {}",e->name);
7862 auto fmd = createMemberDef(
7863 fileName,e->startLine,e->startColumn,
7864 e->type,e->name,e->args,QCString(),
7865 e->protection, Specifier::Normal,e->isStatic,Relationship::Member,
7867 auto fmmd = toMemberDefMutable(fmd.get());
7868 NamespaceDef *mnd = md->getNamespaceDef();
7869 if (md->getClassDef())
7870 fmmd->setMemberClass(md->getClassDef());
7871 else if (mnd && (mnd->isLinkable() || mnd->isAnonymous()))
7872 fmmd->setNamespace(mnd);
7873 else if (md->getFileDef())
7874 fmmd->setFileDef(md->getFileDef());
7875 fmmd->setOuterScope(md->getOuterScope());
7876 fmmd->setTagInfo(e->tagInfo());
7877 fmmd->setLanguage(e->lang);
7878 fmmd->setBodySegment(e->startLine,e->bodyLine,e->endBodyLine);
7879 fmmd->setBodyDef(e->fileDef());
7880 fmmd->setId(e->id);
7881 fmmd->setDocumentation(e->doc,e->docFile,e->docLine);
7882 fmmd->setBriefDescription(e->brief,e->briefFile,e->briefLine);
7883 fmmd->addSectionsToDefinition(e->anchors);
7884 fmmd->setInitializer(e->initializer.str());
7885 fmmd->setMaxInitLines(e->initLines);
7886 fmmd->setMemberGroupId(e->mGrpId);
7887 fmmd->setExplicitExternal(e->explicitExternal,fileName,e->startLine,e->startColumn);
7888 fmmd->setRefItems(e->sli);
7889 fmmd->setRequirementReferences(e->rqli);
7890 fmmd->setAnchor();
7891 md->insertEnumField(fmd.get());
7892 fmmd->setEnumScope(md,TRUE);
7893 extraMembers.emplace_back(e->name,std::move(fmd));
7894 }
7895 }
7896 else
7897 {
7898 AUTO_TRACE_ADD("enum value {}",e->name);
7899 //printf("e->name=%s isRelated=%d\n",qPrint(e->name),isRelated);
7900 MemberName *fmn=nullptr;
7901 MemberNameLinkedMap *emnsd = isRelated ? Doxygen::functionNameLinkedMap : mnsd;
7902 if (!e->name.isEmpty() && (fmn=emnsd->find(e->name)))
7903 // get list of members with the same name as the field
7904 {
7905 for (const auto &ifmd : *fmn)
7906 {
7907 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
7908 if (fmd && fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope
7909 {
7910 //printf("found enum value with same name %s in scope %s\n",
7911 // qPrint(fmd->name()),qPrint(fmd->getOuterScope()->name()));
7912 if (nd && !nd->isAnonymous())
7913 {
7914 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7915 {
7916 const NamespaceDef *fnd=fmd->getNamespaceDef();
7917 if (fnd==nd) // enum value is inside a namespace
7918 {
7919 md->insertEnumField(fmd);
7920 fmd->setEnumScope(md);
7921 }
7922 }
7923 }
7924 else if (isGlobal)
7925 {
7926 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7927 {
7928 const FileDef *ffd=fmd->getFileDef();
7929 if (ffd==fd && ffd==md->getFileDef()) // enum value has file scope
7930 {
7931 md->insertEnumField(fmd);
7932 fmd->setEnumScope(md);
7933 }
7934 }
7935 }
7936 else if (isRelated && cd) // reparent enum value to
7937 // match the enum's scope
7938 {
7939 md->insertEnumField(fmd); // add field def to list
7940 fmd->setEnumScope(md); // cross ref with enum name
7941 fmd->setEnumClassScope(cd); // cross ref with enum name
7942 fmd->setOuterScope(cd);
7943 fmd->makeRelated();
7944 cd->insertMember(fmd);
7945 }
7946 else
7947 {
7948 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7949 {
7950 const ClassDef *fcd=fmd->getClassDef();
7951 if (fcd==cd) // enum value is inside a class
7952 {
7953 //printf("Inserting enum field %s in enum scope %s\n",
7954 // qPrint(fmd->name()),qPrint(md->name()));
7955 md->insertEnumField(fmd); // add field def to list
7956 fmd->setEnumScope(md); // cross ref with enum name
7957 }
7958 }
7959 }
7960 }
7961 }
7962 }
7963 }
7964 }
7965 }
7966 }
7967 // move the newly added members into mn
7968 for (auto &e : extraMembers)
7969 {
7970 MemberName *emn=mnsd->add(e.name);
7971 emn->push_back(std::move(e.member));
7972 }
7973 }
7974 }
7975 }
7976 else
7977 {
7978 for (const auto &e : root->children()) addEnumValuesToEnums(e.get());
7979 }
7980}
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:210
T * add(const char *k, Args &&... args)
Definition linkedmap.h:90
const T * find(const std::string &key) const
Definition linkedmap.h:47
virtual const ClassDef * getClassDef() const =0
virtual const FileDef * getFileDef() const =0
virtual bool isStrongEnumValue() const =0
virtual const NamespaceDef * getNamespaceDef() const =0
virtual bool isEnumerate() const =0
virtual bool isEnumValue() const =0
virtual void setEnumScope(MemberDef *md, bool livesInsideEnum=FALSE)=0
virtual void setEnumClassScope(ClassDef *cd)=0
virtual void insertEnumField(MemberDef *md)=0
virtual void makeRelated()=0
void push_back(Ptr &&p)
Definition membername.h:54
Ordered dictionary of MemberName objects.
Definition membername.h:63
An abstract interface of a namespace symbol.
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h: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:7734
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:4575

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

3828{
3829 QCString scope = sc;
3830
3831 // new global function
3833 auto md = createMemberDef(
3834 root->fileName,root->startLine,root->startColumn,
3835 root->type,name,root->args,root->exception,
3836 root->protection,root->virt,root->isStatic,Relationship::Member,
3838 !root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
3839 root->argList,root->metaData);
3840 auto mmd = toMemberDefMutable(md.get());
3841 mmd->setTagInfo(root->tagInfo());
3842 mmd->setLanguage(root->lang);
3843 mmd->setId(root->id);
3844 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3845 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3846 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3847 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
3848 mmd->setDocsForDefinition(!root->proto);
3849 mmd->setTypeConstraints(root->typeConstr);
3850 //md->setBody(root->body);
3851 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3852 FileDef *fd=root->fileDef();
3853 mmd->setBodyDef(fd);
3854 mmd->addSectionsToDefinition(root->anchors);
3855 mmd->setMemberSpecifiers(root->spec);
3856 mmd->setVhdlSpecifiers(root->vhdlSpec);
3857 mmd->setMemberGroupId(root->mGrpId);
3858 mmd->setRequiresClause(root->req);
3859 mmd->setExplicitExternal(root->explicitExternal,root->fileName,root->startLine,root->startColumn);
3860
3861 NamespaceDefMutable *nd = nullptr;
3862 // see if the function is inside a namespace that was not part of
3863 // the name already (in that case nd should be non-zero already)
3864 if (root->parent()->section.isNamespace())
3865 {
3866 //QCString nscope=removeAnonymousScopes(root->parent()->name);
3867 QCString nscope=root->parent()->name;
3868 if (!nscope.isEmpty())
3869 {
3870 nd = getResolvedNamespaceMutable(nscope);
3871 }
3872 }
3873 else if (root->parent()->section.isGroupDoc() && !scope.isEmpty())
3874 {
3876 }
3877
3878 if (!scope.isEmpty())
3879 {
3881 if (sep!="::")
3882 {
3883 scope = substitute(scope,"::",sep);
3884 }
3885 scope+=sep;
3886 }
3887
3888 if (Config_getBool(HIDE_SCOPE_NAMES)) scope = "";
3889 QCString def;
3890 //QCString optArgs = root->argList.empty() ? QCString() : root->args;
3891 if (!root->type.isEmpty())
3892 {
3893 def=root->type+" "+scope+name; //+optArgs;
3894 }
3895 else
3896 {
3897 def=scope+name; //+optArgs;
3898 }
3899 AUTO_TRACE("new non-member function type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
3900 root->type,scope,rname,root->args,root->proto,def);
3901 mmd->setDefinition(def);
3903 mmd->addQualifiers(root->qualifiers);
3904
3905 mmd->setRefItems(root->sli);
3906 mmd->setRequirementReferences(root->rqli);
3907 if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
3908 {
3909 // add member to namespace
3910 mmd->setNamespace(nd);
3911 nd->insertMember(md.get());
3912 }
3913 if (fd)
3914 {
3915 // add member to the file (we do this even if we have already
3916 // inserted it into the namespace)
3917 mmd->setFileDef(fd);
3918 fd->insertMember(md.get());
3919 }
3920
3921 addMemberToGroups(root,md.get());
3923 if (root->relatesType == RelatesType::Simple) // if this is a relatesalso command,
3924 // allow find Member to pick it up
3925 {
3926 root->markAsProcessed(); // Otherwise we have finished with this entry.
3927 }
3928
3929 // add member to the list of file members
3931 mn->push_back(std::move(md));
3932}
VhdlSpecifier vhdlSpec
VHDL specifiers.
Definition entry.h:184
void markAsProcessed() const
Definition entry.h:168
bool explicitExternal
explicitly defined as external?
Definition entry.h:187
RelatesType relatesType
how relates is handled
Definition entry.h:211
QCString type
member type
Definition entry.h:174
QCString exception
throw specification
Definition entry.h:215
ArgumentList argList
member arguments as a list
Definition entry.h:195
Specifier virt
virtualness of the entry
Definition entry.h:192
virtual void insertMember(MemberDef *md)=0
virtual void insertMember(MemberDef *md)=0
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h: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:5897

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::rqli, Entry::section, DefinitionMutable::setBodyDef(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, substitute(), Entry::tagInfo(), Entry::tArgLists, toMemberDefMutable(), Entry::type, Entry::typeConstr, Entry::vhdlSpec, and Entry::virt.

Referenced by buildFunctionList().

◆ addIncludeFile()

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

Definition at line 588 of file doxygen.cpp.

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

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

3580{
3581 FileDef *fd = root->fileDef();
3582 enum MemberType type = root->section.isExportedInterface() ? MemberType::Interface : MemberType::Service;
3583 QCString fileName = root->fileName;
3584 if (fileName.isEmpty() && root->tagInfo())
3585 {
3586 fileName = root->tagInfo()->tagName;
3587 }
3588 auto md = createMemberDef(
3589 fileName, root->startLine, root->startColumn, root->type, rname,
3590 "", "", root->protection, root->virt, root->isStatic, Relationship::Member,
3591 type, ArgumentList(), root->argList, root->metaData);
3592 auto mmd = toMemberDefMutable(md.get());
3593 mmd->setTagInfo(root->tagInfo());
3594 mmd->setMemberClass(cd);
3595 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3596 mmd->setDocsForDefinition(false);
3597 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3598 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3599 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3600 mmd->setMemberSpecifiers(root->spec);
3601 mmd->setVhdlSpecifiers(root->vhdlSpec);
3602 mmd->setMemberGroupId(root->mGrpId);
3603 mmd->setTypeConstraints(root->typeConstr);
3604 mmd->setLanguage(root->lang);
3605 mmd->setBodyDef(fd);
3606 mmd->setFileDef(fd);
3607 mmd->addSectionsToDefinition(root->anchors);
3608 QCString const def = root->type + " " + rname;
3609 mmd->setDefinition(def);
3611 mmd->addQualifiers(root->qualifiers);
3612
3613 AUTO_TRACE("Interface member: fileName='{}' type='{}' name='{}' mtype='{}' prot={} virt={} state={} proto={} def='{}'",
3614 fileName,root->type,rname,type,root->protection,root->virt,root->isStatic,root->proto,def);
3615
3616 // add member to the class cd
3617 cd->insertMember(md.get());
3618 // also add the member as a "base" (to get nicer diagrams)
3619 // "optional" interface/service get Protected which turns into dashed line
3620 BaseInfo base(rname,
3621 root->spec.isOptional() ? Protection::Protected : Protection::Public, Specifier::Normal);
3622 TemplateNameMap templateNames;
3623 findClassRelation(root,cd,cd,&base,templateNames,DocumentedOnly,true) ||
3624 findClassRelation(root,cd,cd,&base,templateNames,Undocumented,true);
3625 // add file to list of used files
3626 cd->insertUsedFile(fd);
3627
3628 addMemberToGroups(root,md.get());
3630 root->markAsProcessed();
3631 mmd->setRefItems(root->sli);
3632 mmd->setRequirementReferences(root->rqli);
3633
3634 // add member to the global list of all members
3635 MemberName *mn = Doxygen::memberNameLinkedMap->add(rname);
3636 mn->push_back(std::move(md));
3637}
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:4898
This class stores information about an inheritance relation.
Definition entry.h:91
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::rqli, 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 5562 of file doxygen.cpp.

5563{
5564 AUTO_TRACE();
5565 applyToAllDefinitions([](auto* obj) { obj->addListReferences(); });
5566}
static void applyToAllDefinitions(Func func)
Definition doxygen.cpp:5497

References applyToAllDefinitions(), and AUTO_TRACE.

Referenced by parseInput().

◆ addLocalObjCMethod()

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

Definition at line 6140 of file doxygen.cpp.

6145{
6146 AUTO_TRACE();
6147 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
6148 ClassDefMutable *cd=nullptr;
6149 if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClassMutable(scopeName)))
6150 {
6151 AUTO_TRACE_ADD("Local objective C method '{}' scopeName='{}'",root->name,scopeName);
6152 auto md = createMemberDef(
6153 root->fileName,root->startLine,root->startColumn,
6154 funcType,funcName,funcArgs,exceptions,
6155 root->protection,root->virt,root->isStatic,Relationship::Member,
6157 auto mmd = toMemberDefMutable(md.get());
6158 mmd->setTagInfo(root->tagInfo());
6159 mmd->setLanguage(root->lang);
6160 mmd->setId(root->id);
6161 mmd->makeImplementationDetail();
6162 mmd->setMemberClass(cd);
6163 mmd->setDefinition(funcDecl);
6165 mmd->addQualifiers(root->qualifiers);
6166 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6167 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6168 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6169 mmd->setDocsForDefinition(!root->proto);
6170 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6171 mmd->addSectionsToDefinition(root->anchors);
6172 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6173 FileDef *fd=root->fileDef();
6174 mmd->setBodyDef(fd);
6175 mmd->setMemberSpecifiers(spec);
6176 mmd->setVhdlSpecifiers(root->vhdlSpec);
6177 mmd->setMemberGroupId(root->mGrpId);
6178 cd->insertMember(md.get());
6179 cd->insertUsedFile(fd);
6180 mmd->setRefItems(root->sli);
6181 mmd->setRequirementReferences(root->rqli);
6182
6184 mn->push_back(std::move(md));
6185 }
6186 else
6187 {
6188 // local objective C method found for class without interface
6189 }
6190}

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, Entry::rqli, DefinitionMutable::setBodyDef(), Entry::sli, Entry::startColumn, Entry::startLine, Entry::tagInfo(), toMemberDefMutable(), Entry::vhdlSpec, and Entry::virt.

Referenced by addMemberFunction(), and findMember().

◆ addMemberDocs()

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

Definition at line 5585 of file doxygen.cpp.

5591{
5592 if (md==nullptr) return;
5593 AUTO_TRACE("scope='{}' name='{}' args='{}' funcDecl='{}' mSpec={}",
5594 root->parent()->name,md->name(),md->argsString(),funcDecl,spec);
5595 if (!root->section.isDoc()) // @fn or @var does not need to specify the complete definition, so don't overwrite it
5596 {
5597 QCString fDecl=funcDecl;
5598 // strip extern specifier
5599 fDecl.stripPrefix("extern ");
5600 md->setDefinition(fDecl);
5601 }
5603 md->addQualifiers(root->qualifiers);
5605 const NamespaceDef *nd=md->getNamespaceDef();
5606 QCString fullName;
5607 if (cd)
5608 fullName = cd->name();
5609 else if (nd)
5610 fullName = nd->name();
5611
5612 if (!fullName.isEmpty()) fullName+="::";
5613 fullName+=md->name();
5614 FileDef *rfd=root->fileDef();
5615
5616 // TODO determine scope based on root not md
5617 Definition *rscope = md->getOuterScope();
5618
5619 const ArgumentList &mdAl = md->argumentList();
5620 if (al)
5621 {
5622 ArgumentList mergedAl = *al;
5623 //printf("merging arguments (1) docs=%d\n",root->doc.isEmpty());
5624 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedAl,!root->doc.isEmpty());
5625 }
5626 else
5627 {
5628 if (
5629 matchArguments2( md->getOuterScope(), md->getFileDef(),md->typeString(),const_cast<ArgumentList*>(&mdAl),
5630 rscope,rfd,root->type,&root->argList,
5631 TRUE, root->lang
5632 )
5633 )
5634 {
5635 //printf("merging arguments (2)\n");
5636 ArgumentList mergedArgList = root->argList;
5637 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.isEmpty());
5638 }
5639 }
5640 if (over_load) // the \overload keyword was used
5641 {
5643 if (!root->doc.isEmpty())
5644 {
5645 doc+="<p>";
5646 doc+=root->doc;
5647 }
5648 md->setDocumentation(doc,root->docFile,root->docLine);
5650 md->setDocsForDefinition(!root->proto);
5651 }
5652 else
5653 {
5654 //printf("overwrite!\n");
5655 md->setDocumentation(root->doc,root->docFile,root->docLine);
5656 md->setDocsForDefinition(!root->proto);
5657
5658 //printf("overwrite!\n");
5659 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
5660
5661 if (
5662 (md->inbodyDocumentation().isEmpty() ||
5663 !root->parent()->name.isEmpty()
5664 ) && !root->inbodyDocs.isEmpty()
5665 )
5666 {
5668 }
5669 }
5670
5671 //printf("initializer: '%s'(isEmpty=%d) '%s'(isEmpty=%d)\n",
5672 // qPrint(md->initializer()),md->initializer().isEmpty(),
5673 // qPrint(root->initializer),root->initializer.isEmpty()
5674 // );
5675 std::string rootInit = root->initializer.str();
5676 if (md->initializer().isEmpty() && !rootInit.empty())
5677 {
5678 //printf("setInitializer\n");
5679 md->setInitializer(rootInit);
5680 }
5681 if (md->requiresClause().isEmpty() && !root->req.isEmpty())
5682 {
5683 md->setRequiresClause(root->req);
5684 }
5685
5686 md->setMaxInitLines(root->initLines);
5687
5688 if (rfd)
5689 {
5690 if ((md->getStartBodyLine()==-1 && root->bodyLine!=-1)
5691 )
5692 {
5693 //printf("Setting new body segment [%d,%d]\n",root->bodyLine,root->endBodyLine);
5694 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
5695 md->setBodyDef(rfd);
5696 }
5697
5698 md->setRefItems(root->sli);
5699 md->setRequirementReferences(root->rqli);
5700 }
5701
5703 md->addQualifiers(root->qualifiers);
5704
5705 md->mergeMemberSpecifiers(spec);
5707 addMemberToGroups(root,md);
5709 if (cd) cd->insertUsedFile(rfd);
5710 //printf("root->mGrpId=%d\n",root->mGrpId);
5711 if (root->mGrpId!=-1)
5712 {
5713 if (md->getMemberGroupId()!=-1)
5714 {
5715 if (md->getMemberGroupId()!=root->mGrpId)
5716 {
5717 warn(root->fileName,root->startLine,
5718 "member {} belongs to two different groups. The second one found here will be ignored.",
5719 md->name()
5720 );
5721 }
5722 }
5723 else // set group id
5724 {
5725 //printf("setMemberGroupId=%d md=%s\n",root->mGrpId,qPrint(md->name()));
5726 md->setMemberGroupId(root->mGrpId);
5727 }
5728 }
5729 md->addQualifiers(root->qualifiers);
5730}
constexpr bool isDoc() const noexcept
Definition types.h:827
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:1998
void mergeArguments(ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
Definition util.cpp:2098
QCString getOverloadDocs()
Definition util.cpp:4070

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

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

◆ addMemberFunction()

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

Definition at line 6194 of file doxygen.cpp.

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

6560{
6561 AUTO_TRACE("funcType={} funcName={} funcArgs={} funcDecl={} spec={}",funcType,funcName,funcArgs,funcDecl,spec);
6562 MemberDef *declMd=nullptr;
6563 for (const auto &md : *mn)
6564 {
6565 if (md->getClassDef()==cd)
6566 {
6567 // TODO: we should probably also check for matching arguments
6568 declMd = md.get();
6569 break;
6570 }
6571 }
6573 ArgumentList tArgList;
6574 // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6575 auto md = createMemberDef(
6576 root->fileName,root->startLine,root->startColumn,
6577 funcType,funcName,funcArgs,exceptions,
6578 declMd ? declMd->protection() : root->protection,
6579 root->virt,root->isStatic,Relationship::Member,
6580 mtype,tArgList,root->argList,root->metaData);
6581 auto mmd = toMemberDefMutable(md.get());
6582 //printf("new specialized member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6583 mmd->setTagInfo(root->tagInfo());
6584 mmd->setLanguage(root->lang);
6585 mmd->setId(root->id);
6586 mmd->setMemberClass(cd);
6587 mmd->setTemplateSpecialization(TRUE);
6588 mmd->setTypeConstraints(root->typeConstr);
6589 mmd->setDefinition(funcDecl);
6591 mmd->addQualifiers(root->qualifiers);
6592 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6593 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6594 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6595 mmd->setDocsForDefinition(!root->proto);
6596 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6597 mmd->addSectionsToDefinition(root->anchors);
6598 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6599 FileDef *fd=root->fileDef();
6600 mmd->setBodyDef(fd);
6601 mmd->setMemberSpecifiers(spec);
6602 mmd->setVhdlSpecifiers(root->vhdlSpec);
6603 mmd->setMemberGroupId(root->mGrpId);
6604 cd->insertMember(md.get());
6605 mmd->setRefItems(root->sli);
6606 mmd->setRequirementReferences(root->rqli);
6607
6608 mn->push_back(std::move(md));
6609}

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, Entry::rqli, DefinitionMutable::setBodyDef(), Entry::sli, Entry::startColumn, Entry::startLine, Entry::tagInfo(), toMemberDefMutable(), TRUE, Entry::typeConstr, Entry::vhdlSpec, and Entry::virt.

Referenced by findMember().

◆ addMembersToIndex()

void addMembersToIndex ( )
static

Definition at line 8179 of file doxygen.cpp.

8180{
8181 auto &index = Index::instance();
8182 // for each class member name
8183 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8184 {
8185 // for each member definition
8186 for (const auto &md : *mn)
8187 {
8188 index.addClassMemberNameToIndex(md.get());
8189 if (md->getModuleDef())
8190 {
8191 index.addModuleMemberNameToIndex(md.get());
8192 }
8193 }
8194 }
8195 // for each file/namespace function name
8196 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8197 {
8198 // for each member definition
8199 for (const auto &md : *mn)
8200 {
8201 if (md->getNamespaceDef())
8202 {
8203 index.addNamespaceMemberNameToIndex(md.get());
8204 }
8205 else
8206 {
8207 index.addFileMemberNameToIndex(md.get());
8208 }
8209 if (md->getModuleDef())
8210 {
8211 index.addModuleMemberNameToIndex(md.get());
8212 }
8213 }
8214 }
8215
8216 index.sortMemberIndexLists();
8217}
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 9296 of file doxygen.cpp.

9297{
9298 // for each class
9299 for (const auto &cd : *Doxygen::classLinkedMap)
9300 {
9301 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9302 if (cdm)
9303 {
9305 }
9306 }
9307 // for each file
9308 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9309 {
9310 for (const auto &fd : *fn)
9311 {
9312 fd->addMembersToMemberGroup();
9313 }
9314 }
9315 // for each namespace
9316 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9317 {
9319 if (ndm)
9320 {
9322 }
9323 }
9324 // for each group
9325 for (const auto &gd : *Doxygen::groupLinkedMap)
9326 {
9327 gd->addMembersToMemberGroup();
9328 }
9330}
virtual void addMembersToMemberGroup()=0
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:114
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:113
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 3691 of file doxygen.cpp.

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

6616{
6617 // for unique overloaded member we allow the class to be
6618 // omitted, this is to be Qt compatible. Using this should
6619 // however be avoided, because it is error prone
6620 bool sameClass=false;
6621 if (mn->size()>0)
6622 {
6623 // check if all members with the same name are also in the same class
6624 sameClass = std::equal(mn->begin()+1,mn->end(),mn->begin(),
6625 [](const auto &md1,const auto &md2)
6626 { return md1->getClassDef()->name()==md2->getClassDef()->name(); });
6627 }
6628 if (sameClass)
6629 {
6630 MemberDefMutable *mdm = toMemberDefMutable(mn->front().get());
6631 ClassDefMutable *cd = mdm ? mdm->getClassDefMutable() : nullptr;
6632 if (cd==nullptr) return;
6633
6635 if (root->mtype==MethodTypes::Signal) mtype=MemberType::Signal;
6636 else if (root->mtype==MethodTypes::Slot) mtype=MemberType::Slot;
6637 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType::DCOP;
6638
6639 // new overloaded member function
6640 std::unique_ptr<ArgumentList> tArgList =
6641 getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6642 //printf("new related member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6643 auto md = createMemberDef(
6644 root->fileName,root->startLine,root->startColumn,
6645 funcType,funcName,funcArgs,exceptions,
6646 root->protection,root->virt,root->isStatic,Relationship::Related,
6647 mtype,tArgList ? *tArgList : ArgumentList(),root->argList,root->metaData);
6648 auto mmd = toMemberDefMutable(md.get());
6649 mmd->setTagInfo(root->tagInfo());
6650 mmd->setLanguage(root->lang);
6651 mmd->setId(root->id);
6652 mmd->setTypeConstraints(root->typeConstr);
6653 mmd->setMemberClass(cd);
6654 mmd->setDefinition(funcDecl);
6656 mmd->addQualifiers(root->qualifiers);
6658 doc+="<p>";
6659 doc+=root->doc;
6660 mmd->setDocumentation(doc,root->docFile,root->docLine);
6661 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6662 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6663 mmd->setDocsForDefinition(!root->proto);
6664 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6665 mmd->addSectionsToDefinition(root->anchors);
6666 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6667 FileDef *fd=root->fileDef();
6668 mmd->setBodyDef(fd);
6669 mmd->setMemberSpecifiers(spec);
6670 mmd->setVhdlSpecifiers(root->vhdlSpec);
6671 mmd->setMemberGroupId(root->mGrpId);
6672 cd->insertMember(md.get());
6673 cd->insertUsedFile(fd);
6674 mmd->setRefItems(root->sli);
6675 mmd->setRequirementReferences(root->rqli);
6676
6677 mn->push_back(std::move(md));
6678 }
6679}
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, Entry::rqli, 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 310 of file doxygen.cpp.

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

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

References addPageToContext(), addRelatedPage(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, Entry::args, Entry::brief, Entry::briefFile, Entry::briefLine, Entry::doc, Entry::docFile, Entry::docLine, FALSE, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, Entry::inbodyDocs, QCString::isEmpty(), Entry::lang, Entry::localToc, Entry::name, DefinitionMutable::setBriefDescription(), PageDef::setLocalToc(), Entry::sli, Entry::startLine, and Entry::tagInfo().

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

◆ addRequirementReferences()

void addRequirementReferences ( )
static

Definition at line 5554 of file doxygen.cpp.

5555{
5556 AUTO_TRACE();
5557 applyToAllDefinitions([](auto* obj) { obj->addRequirementReferences(); });
5558}

References applyToAllDefinitions(), and AUTO_TRACE.

Referenced by parseInput().

◆ addSourceReferences()

void addSourceReferences ( )
static

Definition at line 8814 of file doxygen.cpp.

8815{
8816 // add source references for class definitions
8817 for (const auto &cd : *Doxygen::classLinkedMap)
8818 {
8819 const FileDef *fd=cd->getBodyDef();
8820 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8821 {
8822 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8823 }
8824 }
8825 // add source references for concept definitions
8826 for (const auto &cd : *Doxygen::conceptLinkedMap)
8827 {
8828 const FileDef *fd=cd->getBodyDef();
8829 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8830 {
8831 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8832 }
8833 }
8834 // add source references for namespace definitions
8835 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8836 {
8837 const FileDef *fd=nd->getBodyDef();
8838 if (fd && nd->isLinkableInProject() && nd->getStartDefLine()!=-1)
8839 {
8840 const_cast<FileDef*>(fd)->addSourceRef(nd->getStartDefLine(),nd.get(),nullptr);
8841 }
8842 }
8843
8844 // add source references for member names
8845 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8846 {
8847 for (const auto &md : *mn)
8848 {
8849 //printf("class member %s: def=%s body=%d link?=%d\n",
8850 // qPrint(md->name()),
8851 // md->getBodyDef()?qPrint(md->getBodyDef()->name()):"<none>",
8852 // md->getStartBodyLine(),md->isLinkableInProject());
8853 const FileDef *fd=md->getBodyDef();
8854 if (fd &&
8855 md->getStartDefLine()!=-1 &&
8856 md->isLinkableInProject() &&
8858 )
8859 {
8860 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8861 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8862 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8863 }
8864 }
8865 }
8866 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8867 {
8868 for (const auto &md : *mn)
8869 {
8870 const FileDef *fd=md->getBodyDef();
8871 //printf("member %s body=[%d,%d] fd=%p link=%d parseSources=%d\n",
8872 // qPrint(md->name()),
8873 // md->getStartBodyLine(),md->getEndBodyLine(),fd,
8874 // md->isLinkableInProject(),
8875 // Doxygen::parseSourcesNeeded);
8876 if (fd &&
8877 md->getStartDefLine()!=-1 &&
8878 md->isLinkableInProject() &&
8880 )
8881 {
8882 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8883 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8884 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8885 }
8886 }
8887 }
8888}
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 8221 of file doxygen.cpp.

8222{
8223 for (const auto &cd : *Doxygen::classLinkedMap)
8224 {
8225 if (cd->isLinkableInProject())
8226 {
8227 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8228 if (Doxygen::searchIndex.enabled())
8229 {
8230 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
8231 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
8232 }
8233 }
8234 }
8235
8236 for (const auto &cd : *Doxygen::conceptLinkedMap)
8237 {
8238 if (cd->isLinkableInProject())
8239 {
8240 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8241 if (Doxygen::searchIndex.enabled())
8242 {
8243 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
8244 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
8245 }
8246 }
8247 }
8248
8249 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8250 {
8251 if (nd->isLinkableInProject())
8252 {
8253 Doxygen::indexList->addIndexItem(nd.get(),nullptr);
8254 if (Doxygen::searchIndex.enabled())
8255 {
8256 Doxygen::searchIndex.setCurrentDoc(nd.get(),nd->anchor(),FALSE);
8257 Doxygen::searchIndex.addWord(nd->localName(),TRUE);
8258 }
8259 }
8260 }
8261
8262 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8263 {
8264 for (const auto &fd : *fn)
8265 {
8266 if (Doxygen::searchIndex.enabled() && fd->isLinkableInProject())
8267 {
8268 Doxygen::searchIndex.setCurrentDoc(fd.get(),fd->anchor(),FALSE);
8269 Doxygen::searchIndex.addWord(fd->localName(),TRUE);
8270 }
8271 }
8272 }
8273
8274 auto addWordsForTitle = [](const Definition *d,const QCString &anchor,const QCString &title)
8275 {
8276 Doxygen::indexList->addIndexItem(d,nullptr,QCString(),filterTitle(title));
8277 if (Doxygen::searchIndex.enabled())
8278 {
8279 Doxygen::searchIndex.setCurrentDoc(d,anchor,false);
8280 std::string s = title.str();
8281 static const reg::Ex re(R"(\a[\w-]*)");
8282 reg::Iterator it(s,re);
8284 for (; it!=end ; ++it)
8285 {
8286 const auto &match = *it;
8287 std::string matchStr = match.str();
8288 Doxygen::searchIndex.addWord(matchStr,true);
8289 }
8290 }
8291 };
8292
8293 for (const auto &gd : *Doxygen::groupLinkedMap)
8294 {
8295 if (gd->isLinkableInProject())
8296 {
8297 addWordsForTitle(gd.get(),gd->anchor(),gd->groupTitle());
8298 }
8299 }
8300
8301 for (const auto &pd : *Doxygen::pageLinkedMap)
8302 {
8303 if (pd->isLinkableInProject())
8304 {
8305 addWordsForTitle(pd.get(),pd->anchor(),pd->title());
8306 }
8307 }
8308
8310 {
8311 addWordsForTitle(Doxygen::mainPage.get(),Doxygen::mainPage->anchor(),Doxygen::mainPage->title());
8312 }
8313
8314 auto addMemberToSearchIndex = [](const MemberDef *md)
8315 {
8316 if (Doxygen::searchIndex.enabled())
8317 {
8318 Doxygen::searchIndex.setCurrentDoc(md,md->anchor(),FALSE);
8319 QCString ln=md->localName();
8320 QCString qn=md->qualifiedName();
8321 Doxygen::searchIndex.addWord(ln,TRUE);
8322 if (ln!=qn)
8323 {
8324 Doxygen::searchIndex.addWord(qn,TRUE);
8325 if (md->getClassDef())
8326 {
8327 Doxygen::searchIndex.addWord(md->getClassDef()->displayName(),TRUE);
8328 }
8329 if (md->getNamespaceDef())
8330 {
8331 Doxygen::searchIndex.addWord(md->getNamespaceDef()->displayName(),TRUE);
8332 }
8333 }
8334 }
8335 };
8336
8337 auto getScope = [](const MemberDef *md)
8338 {
8339 const Definition *scope = nullptr;
8340 if (md->getGroupDef()) scope = md->getGroupDef();
8341 else if (md->getClassDef()) scope = md->getClassDef();
8342 else if (md->getNamespaceDef()) scope = md->getNamespaceDef();
8343 else if (md->getFileDef()) scope = md->getFileDef();
8344 return scope;
8345 };
8346
8347 auto addMemberToIndices = [addMemberToSearchIndex,getScope](const MemberDef *md)
8348 {
8349 if (md->isLinkableInProject())
8350 {
8351 if (!(md->isEnumerate() && md->isAnonymous()))
8352 {
8353 Doxygen::indexList->addIndexItem(getScope(md),md);
8355 }
8356 if (md->isEnumerate())
8357 {
8358 for (const auto &fmd : md->enumFieldList())
8359 {
8360 Doxygen::indexList->addIndexItem(getScope(fmd),fmd);
8362 }
8363 }
8364 }
8365 };
8366
8367 // for each class member name
8368 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8369 {
8370 // for each member definition
8371 for (const auto &md : *mn)
8372 {
8373 addMemberToIndices(md.get());
8374 }
8375 }
8376 // for each file/namespace function name
8377 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8378 {
8379 // for each member definition
8380 for (const auto &md : *mn)
8381 {
8382 addMemberToIndices(md.get());
8383 }
8384 }
8385}
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:100
static IndexList * indexList
Definition doxygen.h:133
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:99
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:5610

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

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

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

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

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

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

References FileDef::absFilePath(), addMemberDocs(), addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, MemberDef::argsString(), QCString::at(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Entry::explicitExternal, FALSE, Entry::fileDef(), Entry::fileName, QCString::find(), Doxygen::functionNameLinkedMap, getClassMutable(), Definition::getDefColumn(), Definition::getDefFileName(), Definition::getDefLine(), MemberDef::getFileDef(), Definition::getLanguage(), getLanguageSpecificSeparator(), MemberDef::getNamespaceDef(), Definition::getOuterScope(), getResolvedNamespaceMutable(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, Entry::initializer, Entry::initLines, FileDef::insertMember(), NamespaceDefMutable::insertMember(), ModuleManager::instance(), Definition::isAnonymous(), MemberDef::isDefine(), QCString::isEmpty(), MemberDef::isEnumerate(), MemberDef::isExternal(), Entry::isStatic, MemberDef::isStatic(), Entry::lang, Entry::markAsProcessed(), Entry::metaData, Entry::mGrpId, Definition::name(), Entry::name, Entry::protection, MemberName::push_back(), Entry::qualifiers, resolveTemplateInstanceInType(), Entry::rqli, reg::search(), DefinitionMutable::setBriefDescription(), ClassDefMutable::setClassName(), MemberDefMutable::setDeclFile(), DefinitionMutable::setDocumentation(), MemberDefMutable::setExplicitExternal(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), 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 11982 of file doxygen.cpp.

11983{
11984 AUTO_TRACE();
11985 Doxygen::globalNamespaceDef = createNamespaceDef("<globalScope>",1,1,"<globalScope>");
11995
11996 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11997
11998 /* Set the global html file extension. */
11999 Doxygen::htmlFileExtension = Config_getString(HTML_FILE_EXTENSION);
12000
12001
12003 Config_getBool(CALLER_GRAPH) ||
12004 Config_getBool(REFERENCES_RELATION) ||
12005 Config_getBool(REFERENCED_BY_RELATION);
12006
12007 /**************************************************************************
12008 * Add custom extension mappings
12009 **************************************************************************/
12010
12011 const StringVector &extMaps = Config_getList(EXTENSION_MAPPING);
12012 for (const auto &mapping : extMaps)
12013 {
12014 QCString mapStr = mapping;
12015 int i=mapStr.find('=');
12016 if (i==-1)
12017 {
12018 continue;
12019 }
12020 else
12021 {
12022 QCString ext = mapStr.left(i).stripWhiteSpace().lower();
12023 QCString language = mapStr.mid(i+1).stripWhiteSpace().lower();
12024 if (ext.isEmpty() || language.isEmpty())
12025 {
12026 continue;
12027 }
12028
12029 if (!updateLanguageMapping(ext,language))
12030 {
12031 err("Failed to map file extension '{}' to unsupported language '{}'.\n"
12032 "Check the EXTENSION_MAPPING setting in the config file.\n",
12033 ext,language);
12034 }
12035 else
12036 {
12037 msg("Adding custom extension mapping: '{}' will be treated as language '{}'\n",
12038 ext,language);
12039 }
12040 }
12041 }
12042 // create input file exncodings
12043
12044 // check INPUT_ENCODING
12045 void *cd = portable_iconv_open("UTF-8",Config_getString(INPUT_ENCODING).data());
12046 if (cd==reinterpret_cast<void *>(-1))
12047 {
12048 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
12049 "Check the 'INPUT_ENCODING' setting in the config file!\n",
12050 Config_getString(INPUT_ENCODING),strerror(errno));
12051 }
12052 else
12053 {
12055 }
12056
12057 // check and split INPUT_FILE_ENCODING
12058 const StringVector &fileEncod = Config_getList(INPUT_FILE_ENCODING);
12059 for (const auto &mapping : fileEncod)
12060 {
12061 QCString mapStr = mapping;
12062 int i=mapStr.find('=');
12063 if (i==-1)
12064 {
12065 continue;
12066 }
12067 else
12068 {
12069 QCString pattern = mapStr.left(i).stripWhiteSpace().lower();
12070 QCString encoding = mapStr.mid(i+1).stripWhiteSpace().lower();
12071 if (pattern.isEmpty() || encoding.isEmpty())
12072 {
12073 continue;
12074 }
12075 cd = portable_iconv_open("UTF-8",encoding.data());
12076 if (cd==reinterpret_cast<void *>(-1))
12077 {
12078 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
12079 "Check the 'INPUT_FILE_ENCODING' setting in the config file!\n",
12080 encoding,strerror(errno));
12081 }
12082 else
12083 {
12085 }
12086
12087 Doxygen::inputFileEncodingList.emplace_back(pattern, encoding);
12088 }
12089 }
12090
12091 // add predefined macro name to a dictionary
12092 const StringVector &expandAsDefinedList =Config_getList(EXPAND_AS_DEFINED);
12093 for (const auto &s : expandAsDefinedList)
12094 {
12096 }
12097
12098 // read aliases and store them in a dictionary
12099 readAliases();
12100
12101 // store number of spaces in a tab into Doxygen::spaces
12102 int tabSize = Config_getInt(TAB_SIZE);
12103 Doxygen::spaces.resize(tabSize);
12104 for (int sp=0; sp<tabSize; sp++) Doxygen::spaces.at(sp)=' ';
12105 Doxygen::spaces.at(tabSize)='\0';
12106}
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:5086

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

2150{
2151 root->commandOverrides.apply_callGraph ([&](bool b) { md->overrideCallGraph(b); });
2152 root->commandOverrides.apply_callerGraph ([&](bool b) { md->overrideCallerGraph(b); });
2153 root->commandOverrides.apply_referencedByRelation([&](bool b) { md->overrideReferencedByRelation(b); });
2154 root->commandOverrides.apply_referencesRelation ([&](bool b) { md->overrideReferencesRelation(b); });
2155 root->commandOverrides.apply_inlineSource ([&](bool b) { md->overrideInlineSource(b); });
2156 root->commandOverrides.apply_enumValues ([&](bool b) { md->overrideEnumValues(b); });
2157}
virtual void overrideReferencesRelation(bool e)=0
virtual void overrideReferencedByRelation(bool e)=0
virtual void overrideCallGraph(bool e)=0
virtual void overrideInlineSource(bool e)=0
virtual void overrideEnumValues(bool e)=0
virtual void overrideCallerGraph(bool e)=0

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

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

◆ applyToAllDefinitions()

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

Definition at line 5497 of file doxygen.cpp.

5498{
5499 for (const auto &cd : *Doxygen::classLinkedMap)
5500 {
5501 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5502 if (cdm)
5503 {
5504 func(cdm);
5505 }
5506 }
5507
5508 for (const auto &cd : *Doxygen::conceptLinkedMap)
5509 {
5510 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
5511 if (cdm)
5512 {
5513 func(cdm);
5514 }
5515 }
5516
5517 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5518 {
5519 for (const auto &fd : *fn)
5520 {
5521 func(fd.get());
5522 }
5523 }
5524
5525 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5526 {
5528 if (ndm)
5529 {
5530 func(ndm);
5531 }
5532 }
5533
5534 for (const auto &gd : *Doxygen::groupLinkedMap)
5535 {
5536 func(gd.get());
5537 }
5538
5539 for (const auto &pd : *Doxygen::pageLinkedMap)
5540 {
5541 func(pd.get());
5542 }
5543
5544 for (const auto &dd : *Doxygen::dirLinkedMap)
5545 {
5546 func(dd.get());
5547 }
5548
5549 func(&ModuleManager::instance());
5550}
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:128

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

Referenced by addListReferences(), and addRequirementReferences().

◆ buildClassDocList()

void buildClassDocList ( const Entry * root)
static

Definition at line 1150 of file doxygen.cpp.

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

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

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

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

8559{
8560 // merge the member list of base classes into the inherited classes.
8561 for (const auto &cd : *Doxygen::classLinkedMap)
8562 {
8563 if (// !cd->isReference() && // not an external class
8564 cd->subClasses().empty() && // is a root of the hierarchy
8565 !cd->baseClasses().empty()) // and has at least one base class
8566 {
8567 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8568 if (cdm)
8569 {
8570 //printf("*** merging members for %s\n",qPrint(cd->name()));
8571 cdm->mergeMembers();
8572 }
8573 }
8574 }
8575 // now sort the member list of all members for all classes.
8576 for (const auto &cd : *Doxygen::classLinkedMap)
8577 {
8578 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8579 if (cdm)
8580 {
8581 cdm->sortAllMembersList();
8582 }
8583 }
8584}
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 1335 of file doxygen.cpp.

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

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

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

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

Referenced by buildConceptList(), and parseInput().

◆ buildDefineList()

void buildDefineList ( )
static

Definition at line 8893 of file doxygen.cpp.

8894{
8895 AUTO_TRACE();
8896 for (const auto &s : g_inputFiles)
8897 {
8898 auto it = Doxygen::macroDefinitions.find(s);
8900 {
8901 for (const auto &def : it->second)
8902 {
8903 auto md = createMemberDef(
8904 def.fileName,def.lineNr,def.columnNr,
8905 "#define",def.name,def.args,QCString(),
8906 Protection::Public,Specifier::Normal,FALSE,Relationship::Member,MemberType::Define,
8907 ArgumentList(),ArgumentList(),"");
8908 auto mmd = toMemberDefMutable(md.get());
8909
8910 if (!def.args.isEmpty())
8911 {
8912 mmd->moveArgumentList(stringToArgumentList(SrcLangExt::Cpp, def.args));
8913 }
8914 mmd->setInitializer(def.definition);
8915 mmd->setFileDef(def.fileDef);
8916 mmd->setDefinition("#define "+def.name);
8917
8918 MemberName *mn=Doxygen::functionNameLinkedMap->add(def.name);
8919 if (def.fileDef)
8920 {
8921 const MemberList *defMl = def.fileDef->getMemberList(MemberListType::DocDefineMembers());
8922 if (defMl)
8923 {
8924 const MemberDef *defMd = defMl->findRev(def.name);
8925 if (defMd) // definition already stored
8926 {
8927 mmd->setRedefineCount(defMd->redefineCount()+1);
8928 }
8929 }
8930 def.fileDef->insertMember(md.get());
8931 }
8932 AUTO_TRACE_ADD("adding macro {} with definition {}",def.name,def.definition);
8933 mn->push_back(std::move(md));
8934 }
8935 }
8936 }
8937}
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:188

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

3526{
3527 if (!root->name.isEmpty() &&
3528 root->section.isVariable() &&
3529 root->type.find("dictionary<")!=-1 // it's a dictionary
3530 )
3531 {
3532 AUTO_TRACE();
3533 addVariable(root);
3534 }
3535 for (const auto &e : root->children())
3536 if (!e->section.isEnum())
3537 buildDictionaryList(e.get());
3538}
static void buildDictionaryList(const Entry *root)
Definition doxygen.cpp:3525
static void addVariable(const Entry *root, int isFuncPtr=-1)
Definition doxygen.cpp:3152

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

9987{
9988 if ((root->section.isExample() || root->section.isExampleLineno()) && !root->name.isEmpty())
9989 {
9990 if (Doxygen::exampleLinkedMap->find(root->name))
9991 {
9992 warn(root->fileName,root->startLine,"Example {} was already documented. Ignoring documentation found here.",root->name);
9993 }
9994 else
9995 {
9996 PageDef *pd = Doxygen::exampleLinkedMap->add(root->name,
9997 createPageDef(root->fileName,root->startLine,
9998 root->name,root->brief+root->doc+root->inbodyDocs,root->args));
9999 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
10000 pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE));
10002 pd->setLanguage(root->lang);
10003 pd->setShowLineNo(root->section.isExampleLineno());
10004
10005 //we don't add example to groups
10006 //addExampleToGroups(root,pd);
10007 }
10008 }
10009 for (const auto &e : root->children()) buildExampleList(e.get());
10010}
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:9986
std::unique_ptr< PageDef > createPageDef(const QCString &f, int l, const QCString &n, const QCString &d, const QCString &t)
Definition pagedef.cpp:82
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3485

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

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

References GroupDef::addFile(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, Entry::brief, Entry::briefFile, Entry::briefLine, buildFileList(), Entry::children(), Entry::commandOverrides, Config_getBool, GroupDef::containsFile(), Entry::doc, Entry::docFile, Entry::docLine, QCString::ExplicitSize, FALSE, Entry::fileName, findFileDef(), QCString::findRev(), Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Grouping::groupname, Entry::groups, Doxygen::inputNameLinkedMap, QCString::isEmpty(), EntryType::isFile(), QCString::left(), DefinitionMutable::makePartOfGroup(), Entry::name, FileDef::overrideIncludedByGraph(), FileDef::overrideIncludeGraph(), Grouping::pri, qPrint(), Entry::rqli, Entry::section, DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), showFileDefMatches(), Entry::sli, QCString::sprintf(), Entry::startLine, Entry::tagInfo(), and warn.

Referenced by buildFileList(), and parseInput().

◆ buildFunctionList()

void buildFunctionList ( const Entry * root)
static

Definition at line 3936 of file doxygen.cpp.

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

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

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

References buildGroupListFiltered(), FALSE, and TRUE.

Referenced by parseInput().

◆ buildGroupListFiltered()

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

Definition at line 360 of file doxygen.cpp.

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

References DefinitionMutable::addSectionsToDefinition(), Entry::anchors, AUTO_TRACE, AUTO_TRACE_ADD, Entry::brief, Entry::briefFile, Entry::briefLine, buildGroupListFiltered(), Entry::children(), Entry::commandOverrides, createGroupDef(), Entry::doc, Entry::docFile, Entry::docLine, FALSE, Entry::fileName, TagInfo::fileName, Entry::GROUPDOC_NORMAL, Entry::groupDocType, Doxygen::groupLinkedMap, GroupDef::groupTitle(), GroupDef::hasGroupTitle(), Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, QCString::isEmpty(), Entry::lang, QCString::length(), Entry::name, GroupDef::overrideGroupGraph(), Entry::rqli, Entry::section, DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), GroupDef::setGroupTitle(), DefinitionMutable::setInbodyDocumentation(), DefinitionMutable::setLanguage(), DefinitionMutable::setReference(), DefinitionMutable::setRefItems(), DefinitionMutable::setRequirementReferences(), Entry::sli, Entry::startLine, Entry::tagInfo(), TagInfo::tagName, Entry::type, and warn.

Referenced by buildGroupList(), and buildGroupListFiltered().

◆ buildInterfaceAndServiceList()

void buildInterfaceAndServiceList ( const Entry * root)
static

Definition at line 3639 of file doxygen.cpp.

3640{
3641 if (root->section.isExportedInterface() || root->section.isIncludedService())
3642 {
3643 AUTO_TRACE("Exported interface/included service: type='{}' scope='{}' name='{}' args='{}'"
3644 " relates='{}' relatesType='{}' file='{}' line={} bodyLine={} #tArgLists={}"
3645 " mGrpId={} spec={} proto={} docFile='{}'",
3646 root->type, root->parent()->name, root->name, root->args,
3647 root->relates, root->relatesType, root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(),
3648 root->mGrpId, root->spec, root->proto, root->docFile);
3649
3651
3652 if (!rname.isEmpty())
3653 {
3654 QCString scope = root->parent()->name;
3655 ClassDefMutable *cd = getClassMutable(scope);
3656 assert(cd);
3657 if (cd && ((ClassDef::Interface == cd->compoundType()) ||
3658 (ClassDef::Service == cd->compoundType()) ||
3660 {
3662 }
3663 else
3664 {
3665 assert(false); // was checked by scanner.l
3666 }
3667 }
3668 else if (rname.isEmpty())
3669 {
3670 warn(root->fileName,root->startLine,
3671 "Illegal member name found.");
3672 }
3673 }
3674 // can only have these in IDL anyway
3675 switch (root->lang)
3676 {
3677 case SrcLangExt::Unknown: // fall through (root node always is Unknown)
3678 case SrcLangExt::IDL:
3679 for (const auto &e : root->children()) buildInterfaceAndServiceList(e.get());
3680 break;
3681 default:
3682 return; // nothing to do here
3683 }
3684}
@ 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:3576
static void buildInterfaceAndServiceList(const Entry *root)
Definition doxygen.cpp:3639

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

2045{
2046 if (root->section.isUsingDecl() &&
2047 !root->parent()->section.isCompound() // not a class/struct member
2048 )
2049 {
2050 QCString name = substitute(root->name,".","::");
2051 g_usingDeclarations.insert(name.str());
2052 }
2053 for (const auto &e : root->children()) buildListOfUsingDecls(e.get());
2054}
static StringSet g_usingDeclarations
Definition doxygen.cpp:190
static void buildListOfUsingDecls(const Entry *root)
Definition doxygen.cpp:2044

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

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

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

Referenced by buildNamespaceList(), and parseInput().

◆ buildPageList()

void buildPageList ( Entry * root)
static

Definition at line 9742 of file doxygen.cpp.

9743{
9744 if (root->section.isPageDoc())
9745 {
9746 if (!root->name.isEmpty())
9747 {
9748 addRelatedPage(root);
9749 }
9750 }
9751 else if (root->section.isMainpageDoc())
9752 {
9753 QCString title=root->args.stripWhiteSpace();
9754 if (title.isEmpty()) title=theTranslator->trMainPage();
9755 //QCString name = Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9756 QCString name = "index";
9757 addRefItem(root->sli,
9758 name,
9759 theTranslator->trPage(TRUE,TRUE),
9760 name,
9761 title,
9762 QCString(),nullptr
9763 );
9764 }
9765 for (const auto &e : root->children()) buildPageList(e.get());
9766}
static void buildPageList(Entry *root)
Definition doxygen.cpp:9742
Translator * theTranslator
Definition language.cpp:71
void addRefItem(const RefItemVector &sli, const QCString &key, const QCString &prefix, const QCString &name, const QCString &title, const QCString &args, const Definition *scope)
Definition util.cpp:4805

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

Referenced by buildPageList(), and parseInput().

◆ buildRequirementsList()

void buildRequirementsList ( Entry * root)
static

Definition at line 9730 of file doxygen.cpp.

9731{
9732 if (root->section.isRequirementDoc())
9733 {
9735 }
9736 for (const auto &e : root->children()) buildRequirementsList(e.get());
9737}
static RequirementManager & instance()
void addRequirement(Entry *e)
static void buildRequirementsList(Entry *root)
Definition doxygen.cpp:9730

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

Referenced by buildRequirementsList(), and parseInput().

◆ buildScopeFromQualifiedName()

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

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

Definition at line 712 of file doxygen.cpp.

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

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

3508{
3509 if (!root->name.isEmpty() &&
3510 root->section.isVariable() &&
3511 root->type.find("sequence<")!=-1 // it's a sequence
3512 )
3513 {
3514 AUTO_TRACE();
3515 addVariable(root);
3516 }
3517 for (const auto &e : root->children())
3518 if (!e->section.isEnum())
3519 buildSequenceList(e.get());
3520}
static void buildSequenceList(const Entry *root)
Definition doxygen.cpp:3507

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

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

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

Referenced by buildTypedefList(), and parseInput().

◆ buildVarList()

void buildVarList ( const Entry * root)
static

Definition at line 3544 of file doxygen.cpp.

3545{
3546 //printf("buildVarList(%s) section=%08x\n",qPrint(rootNav->name()),rootNav->section());
3547 int isFuncPtr=-1;
3548 if (!root->name.isEmpty() &&
3549 (root->type.isEmpty() || g_compoundKeywords.find(root->type.str())==g_compoundKeywords.end()) &&
3550 (
3551 (root->section.isVariable() && // it's a variable
3552 root->type.find("typedef ")==-1 // and not a typedef
3553 ) ||
3554 (root->section.isFunction() && // or maybe a function pointer variable
3555 (isFuncPtr=findFunctionPtr(root->type.str(),root->lang))!=-1
3556 ) ||
3557 (root->section.isFunction() && // class variable initialized by constructor
3559 )
3560 )
3561 ) // documented variable
3562 {
3563 AUTO_TRACE();
3564 addVariable(root,isFuncPtr);
3565 }
3566 for (const auto &e : root->children())
3567 if (!e->section.isEnum())
3568 buildVarList(e.get());
3569}
static void buildVarList(const Entry *root)
Definition doxygen.cpp:3544
static bool isVarWithConstructor(const Entry *root)
Definition doxygen.cpp:2940
static const StringUnorderedSet g_compoundKeywords
Definition doxygen.cpp:199

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

Referenced by buildVarList(), and parseInput().

◆ checkConfiguration()

void checkConfiguration ( )

check and resolve config options

Definition at line 11971 of file doxygen.cpp.

11972{
11973 AUTO_TRACE();
11974
11979}
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 12453 of file doxygen.cpp.

12454{
12455 if (Config_getBool(MARKDOWN_SUPPORT))
12456 {
12457 QCString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
12458 if (mdfileAsMainPage.isEmpty()) return;
12459 FileInfo fi(mdfileAsMainPage.data());
12460 if (!fi.exists())
12461 {
12462 warn_uncond("Specified markdown mainpage '{}' does not exist\n",mdfileAsMainPage);
12463 return;
12464 }
12465 bool ambig = false;
12466 if (findFileDef(Doxygen::inputNameLinkedMap,fi.absFilePath(),ambig)==nullptr)
12467 {
12468 warn_uncond("Specified markdown mainpage '{}' has not been defined as input file\n",mdfileAsMainPage);
12469 return;
12470 }
12471 }
12472}
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 9881 of file doxygen.cpp.

9882{
9883 for (const auto &pd : *Doxygen::pageLinkedMap)
9884 {
9885 Definition *ppd = pd->getOuterScope();
9886 while (ppd)
9887 {
9888 if (ppd==pd.get())
9889 {
9890 term("page defined {} with label {} is a subpage "
9891 "of itself! Please remove this cyclic dependency.\n",
9892 warn_line(pd->docFile(),pd->docLine()),pd->name());
9893 }
9894 ppd=ppd->getOuterScope();
9895 }
9896 }
9897}

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

Referenced by parseInput().

◆ cleanUpDoxygen()

void cleanUpDoxygen ( )

Definition at line 11493 of file doxygen.cpp.

11494{
11498
11499 delete Doxygen::indexList;
11508 Doxygen::mainPage.reset();
11512 Doxygen::globalScope = nullptr;
11514 delete theTranslator;
11515 delete g_outputList;
11516
11521 delete Doxygen::dirLinkedMap;
11522 delete Doxygen::symbolMap;
11523}
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:179
static OutputList * g_outputList
Definition doxygen.cpp:189

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

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

◆ clearAll()

void clearAll ( )

Definition at line 202 of file doxygen.cpp.

203{
204 g_inputFiles.clear();
205 //g_excludeNameDict.clear();
206 //delete g_outputList; g_outputList=nullptr;
207
212 Doxygen::pageLinkedMap->clear();
225 Doxygen::mainPage.reset();
227}
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 9271 of file doxygen.cpp.

9272{
9273 // for each file
9274 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9275 {
9276 for (const auto &fd : *fn)
9277 {
9278 fd->combineUsingRelations();
9279 }
9280 }
9281
9282 // for each namespace
9283 NamespaceDefSet visitedNamespaces;
9284 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9285 {
9287 if (ndm)
9288 {
9289 ndm->combineUsingRelations(visitedNamespaces);
9290 }
9291 }
9292}
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 10380 of file doxygen.cpp.

10381{
10382 std::ofstream f;
10383 bool fileOpened=openOutputFile("-",f);
10384 if (fileOpened)
10385 {
10386 TextStream t(&f);
10387 Config::compareDoxyfile(t,diffList);
10388 }
10389 else
10390 {
10391 term("Cannot open stdout for writing\n");
10392 }
10393}
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:6296

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

Referenced by readConfiguration().

◆ computeClassRelations()

void computeClassRelations ( )
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 = extractClassName(root);
5373 ClassDefMutable *cd = getClassMutable(bName);
5374 if (cd)
5375 {
5377 }
5378 size_t numMembers = cd ? cd->memberNameInfoLinkedMap().size() : 0;
5379 if ((cd==nullptr || (!cd->hasDocumentation() && !cd->isReference())) && numMembers>0 && !bName.endsWith("::"))
5380 {
5381 if (!root->name.isEmpty() && root->name.find('@')==-1 && // normal name
5382 (guessSection(root->fileName).isHeader() ||
5383 Config_getBool(EXTRACT_LOCAL_CLASSES)) && // not defined in source file
5384 protectionLevelVisible(root->protection) && // hidden by protection
5385 !Config_getBool(HIDE_UNDOC_CLASSES) // undocumented class are visible
5386 )
5387 warn_undoc(root->fileName,root->startLine, "Compound {} is not documented.", root->name);
5388 }
5389 }
5390}
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:5270
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:4724
static std::multimap< std::string, const Entry * > g_classEntries
Definition doxygen.cpp:187
#define warn_undoc(file, line, fmt,...)
Definition message.h:102

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

Referenced by parseInput().

◆ computeIdealCacheParam()

int computeIdealCacheParam ( size_t v)
static

Definition at line 11525 of file doxygen.cpp.

11526{
11527 //printf("computeIdealCacheParam(v=%u)\n",v);
11528
11529 int r=0;
11530 while (v!=0)
11531 {
11532 v >>= 1;
11533 r++;
11534 }
11535 // r = log2(v)
11536
11537 // convert to a valid cache size value
11538 return std::max(0,std::min(r-16,9));
11539}

Referenced by generateOutput().

◆ computeMemberReferences()

void computeMemberReferences ( )
static

Definition at line 5461 of file doxygen.cpp.

5462{
5463 AUTO_TRACE();
5464 for (const auto &cd : *Doxygen::classLinkedMap)
5465 {
5466 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5467 if (cdm)
5468 {
5469 cdm->computeAnchors();
5470 }
5471 }
5472 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5473 {
5474 for (const auto &fd : *fn)
5475 {
5476 fd->computeAnchors();
5477 }
5478 }
5479 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5480 {
5482 if (ndm)
5483 {
5484 ndm->computeAnchors();
5485 }
5486 }
5487 for (const auto &gd : *Doxygen::groupLinkedMap)
5488 {
5489 gd->computeAnchors();
5490 }
5491}
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 8501 of file doxygen.cpp.

8502{
8503 for (const auto &cd : *Doxygen::classLinkedMap)
8504 {
8505 if (cd->isLinkable())
8506 {
8507 for (const auto &bcd : cd->baseClasses())
8508 {
8510 }
8511 }
8512 }
8513}
static void computeMemberRelationsForBaseClass(const ClassDef *cd, const BaseClassDef *bcd)
Definition doxygen.cpp:8421

References Doxygen::classLinkedMap, and computeMemberRelationsForBaseClass().

Referenced by parseInput().

◆ computeMemberRelationsForBaseClass()

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

Definition at line 8421 of file doxygen.cpp.

8422{
8423 for (const auto &mn : cd->memberNameInfoLinkedMap()) // for each member in class cd with a unique name
8424 {
8425 for (const auto &imd : *mn) // for each member with a given name
8426 {
8427 MemberDefMutable *md = toMemberDefMutable(imd->memberDef());
8428 if (md && (md->isFunction() || md->isCSharpProperty())) // filter on reimplementable members
8429 {
8430 ClassDef *mbcd = bcd->classDef;
8431 if (mbcd && mbcd->isLinkable()) // filter on linkable classes
8432 {
8433 const auto &bmn = mbcd->memberNameInfoLinkedMap();
8434 const auto &bmni = bmn.find(mn->memberName());
8435 if (bmni) // there are base class members with the same name
8436 {
8437 for (const auto &ibmd : *bmni) // for base class member with that name
8438 {
8439 MemberDefMutable *bmd = toMemberDefMutable(ibmd->memberDef());
8440 if (bmd) // not part of an inline namespace
8441 {
8442 auto lang = bmd->getLanguage();
8443 auto compType = mbcd->compoundType();
8444 if (bmd->virtualness()!=Specifier::Normal ||
8445 lang==SrcLangExt::Python ||
8446 lang==SrcLangExt::Java ||
8447 lang==SrcLangExt::PHP ||
8448 compType==ClassDef::Interface ||
8449 compType==ClassDef::Protocol)
8450 {
8451 const ArgumentList &bmdAl = bmd->argumentList();
8452 const ArgumentList &mdAl = md->argumentList();
8453 //printf(" Base argList='%s'\n Super argList='%s'\n",
8454 // qPrint(argListToString(bmdAl)),
8455 // qPrint(argListToString(mdAl))
8456 // );
8457 if (
8458 lang==SrcLangExt::Python ||
8459 matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),bmd->typeString(),&bmdAl,
8460 md->getOuterScope(), md->getFileDef(), md->typeString(),&mdAl,
8461 TRUE,lang
8462 )
8463 )
8464 {
8465 if (lang==SrcLangExt::Python && md->name().startsWith("__")) continue; // private members do not reimplement
8466 //printf("match!\n");
8467 const MemberDef *rmd = md->reimplements();
8468 if (rmd==nullptr) // not already assigned
8469 {
8470 //printf("%s: setting (new) reimplements member %s\n",qPrint(md->qualifiedName()),qPrint(bmd->qualifiedName()));
8471 md->setReimplements(bmd);
8472 }
8473 //printf("%s: add reimplementedBy member %s\n",qPrint(bmd->qualifiedName()),qPrint(md->qualifiedName()));
8474 bmd->insertReimplementedBy(md);
8475 }
8476 else
8477 {
8478 //printf("no match!\n");
8479 }
8480 }
8481 }
8482 }
8483 }
8484 }
8485 }
8486 }
8487 }
8488
8489 // do also for indirect base classes
8490 for (const auto &bbcd : bcd->classDef->baseClasses())
8491 {
8493 }
8494}
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 9851 of file doxygen.cpp.

9852{
9853 if ((root->section.isPageDoc() || root->section.isMainpageDoc()) && !root->name.isEmpty())
9854 {
9855 PageDef *pd = root->section.isPageDoc() ?
9856 Doxygen::pageLinkedMap->find(root->name) :
9857 Doxygen::mainPage.get();
9858 if (pd)
9859 {
9860 for (const BaseInfo &bi : root->extends)
9861 {
9862 PageDef *subPd = Doxygen::pageLinkedMap->find(bi.name);
9863 if (pd==subPd)
9864 {
9865 term("page defined {} with label {} is a direct "
9866 "subpage of itself! Please remove this cyclic dependency.\n",
9867 warn_line(pd->docFile(),pd->docLine()),pd->name());
9868 }
9869 else if (subPd)
9870 {
9871 pd->addInnerCompound(subPd);
9872 //printf("*** Added subpage relation: %s->%s\n",
9873 // qPrint(pd->name()),qPrint(subPd->name()));
9874 }
9875 }
9876 }
9877 }
9878 for (const auto &e : root->children()) computePageRelations(e.get());
9879}
virtual QCString docFile() const =0
virtual int docLine() const =0
std::vector< BaseInfo > extends
list of base classes
Definition entry.h:221
static void computePageRelations(Entry *root)
Definition doxygen.cpp:9851
QCString name
the name of the base class
Definition entry.h:95

References DefinitionMutable::addInnerCompound(), Entry::children(), computePageRelations(), Definition::docFile(), Definition::docLine(), Entry::extends, QCString::isEmpty(), Doxygen::mainPage, BaseInfo::name, Definition::name(), Entry::name, Doxygen::pageLinkedMap, Entry::section, term, and warn_line().

Referenced by computePageRelations(), and parseInput().

◆ computeTemplateClassRelations()

void computeTemplateClassRelations ( )
static

Definition at line 5392 of file doxygen.cpp.

5393{
5394 AUTO_TRACE();
5395 for (const auto &[name,root] : g_classEntries)
5396 {
5397 QCString bName=stripAnonymousNamespaceScope(root->name);
5400 // strip any anonymous scopes first
5401 if (cd && !cd->getTemplateInstances().empty())
5402 {
5403 AUTO_TRACE_ADD("Template class '{}'",cd->name());
5404 for (const auto &ti : cd->getTemplateInstances()) // for each template instance
5405 {
5406 ClassDefMutable *tcd=toClassDefMutable(ti.classDef);
5407 if (tcd)
5408 {
5409 AUTO_TRACE_ADD("Template instance '{}'",tcd->name());
5410 QCString templSpec = ti.templSpec;
5411 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(tcd->getLanguage(),templSpec);
5412 for (const BaseInfo &bi : root->extends)
5413 {
5414 // check if the base class is a template argument
5415 BaseInfo tbi = bi;
5416 const ArgumentList &tl = cd->templateArguments();
5417 if (!tl.empty())
5418 {
5419 TemplateNameMap baseClassNames = tcd->getTemplateBaseClassNames();
5420 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,bi.name.str());
5421 // for each template name that we inherit from we need to
5422 // substitute the formal with the actual arguments
5423 TemplateNameMap actualTemplateNames;
5424 for (const auto &tn_kv : templateNames)
5425 {
5426 size_t templIndex = tn_kv.second;
5427 Argument actArg;
5428 bool hasActArg=FALSE;
5429 if (templIndex<templArgs->size())
5430 {
5431 actArg=templArgs->at(templIndex);
5432 hasActArg=TRUE;
5433 }
5434 if (hasActArg &&
5435 baseClassNames.find(actArg.type.str())!=baseClassNames.end() &&
5436 actualTemplateNames.find(actArg.type.str())==actualTemplateNames.end()
5437 )
5438 {
5439 actualTemplateNames.emplace(actArg.type.str(),static_cast<int>(templIndex));
5440 }
5441 }
5442
5443 tbi.name = substituteTemplateArgumentsInString(bi.name,tl,templArgs.get());
5444 // find a documented base class in the correct scope
5445 if (!findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE))
5446 {
5447 // no documented base class -> try to find an undocumented one
5448 findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,Undocumented,TRUE);
5449 }
5450 }
5451 }
5452 }
5453 }
5454 }
5455 }
5456}
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:4505
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:4346

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

8991{
8992 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8993 if (numThreads>1)
8994 {
8995 ThreadPool threadPool(numThreads);
8996 std::vector < std::future< void > > results;
8997 // queue the work
8998 for (const auto &[name,symList] : *Doxygen::symbolMap)
8999 {
9000 for (const auto &def : symList)
9001 {
9003 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
9004 {
9005 auto processTooltip = [dm]() {
9006 dm->computeTooltip();
9007 };
9008 results.emplace_back(threadPool.queue(processTooltip));
9009 }
9010 }
9011 }
9012 // wait for the results
9013 for (auto &f : results)
9014 {
9015 f.get();
9016 }
9017 }
9018 else
9019 {
9020 for (const auto &[name,symList] : *Doxygen::symbolMap)
9021 {
9022 for (const auto &def : symList)
9023 {
9025 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
9026 {
9027 dm->computeTooltip();
9028 }
9029 }
9030 }
9031 }
9032}
virtual void computeTooltip()=0
Class managing a pool of worker threads.
Definition threadpool.h:48
static bool isSymbolHidden(const Definition *d)
Definition doxygen.cpp:8983

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

Referenced by parseInput().

◆ computeVerifiedDotPath()

void computeVerifiedDotPath ( )
static

Definition at line 10308 of file doxygen.cpp.

10309{
10310 // check dot path
10311 QCString dotPath = Config_getString(DOT_PATH);
10312 if (!dotPath.isEmpty())
10313 {
10314 FileInfo fi(dotPath.str());
10315 if (!(fi.exists() && fi.isFile()) )// not an existing user specified path + exec
10316 {
10317 dotPath = dotPath+"/dot"+Portable::commandExtension();
10318 FileInfo dp(dotPath.str());
10319 if (!dp.exists() || !dp.isFile())
10320 {
10321 warn_uncond("the dot tool could not be found as '{}'\n",dotPath);
10322 dotPath = "dot";
10323 dotPath += Portable::commandExtension();
10324 }
10325 }
10326#if defined(_WIN32) // convert slashes
10327 size_t l=dotPath.length();
10328 for (size_t i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\';
10329#endif
10330 }
10331 else
10332 {
10333 dotPath = "dot";
10334 dotPath += Portable::commandExtension();
10335 }
10336 Doxygen::verifiedDotPath = dotPath;
10338}
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 896 of file doxygen.cpp.

897{
899
900 if (specifier.isStruct())
902 else if (specifier.isUnion())
903 sec=ClassDef::Union;
904 else if (specifier.isCategory())
906 else if (specifier.isInterface())
908 else if (specifier.isProtocol())
910 else if (specifier.isException())
912 else if (specifier.isService())
914 else if (specifier.isSingleton())
916
917 if (section.isUnionDoc())
918 sec=ClassDef::Union;
919 else if (section.isStructDoc())
921 else if (section.isInterfaceDoc())
923 else if (section.isProtocolDoc())
925 else if (section.isCategoryDoc())
927 else if (section.isExceptionDoc())
929 else if (section.isServiceDoc())
931 else if (section.isSingletonDoc())
933
934 return sec;
935}
@ 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 10574 of file doxygen.cpp.

10575{
10576 for (const auto &fileName : files)
10577 {
10578 if (!fileName.empty())
10579 {
10580 FileInfo fi(fileName);
10581 if (!fi.exists())
10582 {
10583 err("Extra file '{}' specified in {} does not exist!\n", fileName,filesOption);
10584 }
10585 else if (fi.isDir())
10586 {
10587 err("Extra file '{}' specified in {} is a directory, it has to be a file!\n", fileName,filesOption);
10588 }
10589 else
10590 {
10591 QCString destFileName = outputOption+"/"+fi.fileName();
10592 Doxygen::indexList->addImageFile(fi.fileName());
10593 copyFile(fileName, destFileName);
10594 }
10595 }
10596 }
10597}
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:5857

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

10550{
10551 QCString projectIcon = Config_getString(PROJECT_ICON);
10552 if (!projectIcon.isEmpty())
10553 {
10554 FileInfo fi(projectIcon.str());
10555 if (!fi.exists())
10556 {
10557 err("Project icon '{}' specified by PROJECT_ICON does not exist!\n",projectIcon);
10558 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10559 }
10560 else if (fi.isDir())
10561 {
10562 err("Project icon '{}' specified by PROJECT_ICON is a directory, it has to be a file!\n",projectIcon);
10563 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10564 }
10565 else
10566 {
10567 QCString destFileName = outputOption+"/"+fi.fileName();
10568 copyFile(projectIcon,destFileName);
10569 Doxygen::indexList->addImageFile(fi.fileName());
10570 }
10571 }
10572}
#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 10440 of file doxygen.cpp.

10441{
10442 const StringVector &latexExtraStyleSheet = Config_getList(LATEX_EXTRA_STYLESHEET);
10443 for (const auto &sheet : latexExtraStyleSheet)
10444 {
10445 std::string fileName = sheet;
10446 if (!fileName.empty())
10447 {
10448 FileInfo fi(fileName);
10449 if (!fi.exists())
10450 {
10451 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET does not exist!\n",fileName);
10452 }
10453 else if (fi.isDir())
10454 {
10455 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET is a directory, it has to be a file!\n", fileName);
10456 }
10457 else
10458 {
10459 QCString destFileName = Config_getString(LATEX_OUTPUT)+"/"+fi.fileName();
10460 if (!checkExtension(fi.fileName(), LATEX_STYLE_EXTENSION))
10461 {
10462 destFileName += LATEX_STYLE_EXTENSION;
10463 }
10464 copyFile(fileName, destFileName);
10465 }
10466 }
10467 }
10468}
#define LATEX_STYLE_EXTENSION
Definition latexgen.h:22
bool checkExtension(const QCString &fName, const QCString &ext)
Definition util.cpp:4897

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

10525{
10526 QCString projectLogo = projectLogoFile();
10527 if (!projectLogo.isEmpty())
10528 {
10529 FileInfo fi(projectLogo.str());
10530 if (!fi.exists())
10531 {
10532 err("Project logo '{}' specified by PROJECT_LOGO does not exist!\n",projectLogo);
10533 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10534 }
10535 else if (fi.isDir())
10536 {
10537 err("Project logo '{}' specified by PROJECT_LOGO is a directory, it has to be a file!\n",projectLogo);
10538 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10539 }
10540 else
10541 {
10542 QCString destFileName = outputOption+"/"+fi.fileName();
10543 copyFile(projectLogo,destFileName);
10544 Doxygen::indexList->addImageFile(fi.fileName());
10545 }
10546 }
10547}
QCString projectLogoFile()
Definition util.cpp:3121

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

10472{
10473 QCString htmlStyleSheet = Config_getString(HTML_STYLESHEET);
10474 if (!htmlStyleSheet.isEmpty())
10475 {
10476 if (!htmlStyleSheet.startsWith("http:") && !htmlStyleSheet.startsWith("https:"))
10477 {
10478 FileInfo fi(htmlStyleSheet.str());
10479 if (!fi.exists())
10480 {
10481 err("Style sheet '{}' specified by HTML_STYLESHEET does not exist!\n",htmlStyleSheet);
10482 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10483 }
10484 else if (fi.isDir())
10485 {
10486 err("Style sheet '{}' specified by HTML_STYLESHEET is a directory, it has to be a file!\n",htmlStyleSheet);
10487 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10488 }
10489 else
10490 {
10491 QCString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10492 copyFile(htmlStyleSheet,destFileName);
10493 }
10494 }
10495 }
10496 const StringVector &htmlExtraStyleSheet = Config_getList(HTML_EXTRA_STYLESHEET);
10497 for (const auto &sheet : htmlExtraStyleSheet)
10498 {
10499 QCString fileName(sheet);
10500 if (!fileName.isEmpty() && !fileName.startsWith("http:") && !fileName.startsWith("https:"))
10501 {
10502 FileInfo fi(fileName.str());
10503 if (!fi.exists())
10504 {
10505 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET does not exist!\n",fileName);
10506 }
10507 else if (fi.fileName()=="doxygen.css" || fi.fileName()=="tabs.css" || fi.fileName()=="navtree.css")
10508 {
10509 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is already a built-in stylesheet. Please use a different name\n",fi.fileName());
10510 }
10511 else if (fi.isDir())
10512 {
10513 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is a directory, it has to be a file!\n",fileName);
10514 }
10515 else
10516 {
10517 QCString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10518 copyFile(fileName, destFileName);
10519 }
10520 }
10521 }
10522}

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

9051{
9052 for (const auto &cd : *Doxygen::classLinkedMap)
9053 {
9054 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9055 if (cdm)
9056 {
9057 cdm->countMembers();
9058 }
9059 }
9060
9061 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9062 {
9064 if (ndm)
9065 {
9066 ndm->countMembers();
9067 }
9068 }
9069
9070 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9071 {
9072 for (const auto &fd : *fn)
9073 {
9074 fd->countMembers();
9075 }
9076 }
9077
9078 for (const auto &gd : *Doxygen::groupLinkedMap)
9079 {
9080 gd->countMembers();
9081 }
9082
9083 auto &mm = ModuleManager::instance();
9084 mm.countMembers();
9085}
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 12221 of file doxygen.cpp.

12224{
12225 QCString result = formatDirName;
12226 if (result.isEmpty())
12227 {
12228 result = baseDirName + defaultDirName;
12229 }
12230 else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':'))
12231 {
12232 result.prepend(baseDirName+"/");
12233 }
12234 Dir formatDir(result.str());
12235 if (!formatDir.exists() && !formatDir.mkdir(result.str()))
12236 {
12237 term("Could not create output directory {}\n", result);
12238 }
12239 return result;
12240}
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 1528 of file doxygen.cpp.

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

8518{
8519 // for each class
8520 for (const auto &cd : *Doxygen::classLinkedMap)
8521 {
8522 // that is a template
8523 for (const auto &ti : cd->getTemplateInstances())
8524 {
8525 ClassDefMutable *tcdm = toClassDefMutable(ti.classDef);
8526 if (tcdm)
8527 {
8528 tcdm->addMembersToTemplateInstance(cd.get(),cd->templateArguments(),ti.templSpec);
8529 }
8530 }
8531 }
8532}
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 2161 of file doxygen.cpp.

2163{
2164 AUTO_TRACE("creating new member {} for class {}",memName,cd->name());
2165 const ArgumentList &templAl = md->templateArguments();
2166 const ArgumentList &al = md->argumentList();
2167 auto newMd = createMemberDef(
2168 fileName,root->startLine,root->startColumn,
2169 md->typeString(),memName,md->argsString(),
2170 md->excpString(),root->protection,root->virt,
2171 md->isStatic(),Relationship::Member,md->memberType(),
2172 templAl,al,root->metaData
2173 );
2174 auto newMmd = toMemberDefMutable(newMd.get());
2175 newMmd->setMemberClass(cd);
2176 cd->insertMember(newMd.get());
2177 if (!root->doc.isEmpty() || !root->brief.isEmpty())
2178 {
2179 newMmd->setDocumentation(root->doc,root->docFile,root->docLine);
2180 newMmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2181 newMmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2182 }
2183 else
2184 {
2185 newMmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
2186 newMmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
2187 newMmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
2188 }
2189 newMmd->setDefinition(md->definition());
2190 applyMemberOverrideOptions(root,newMmd);
2191 newMmd->addQualifiers(root->qualifiers);
2192 newMmd->setBitfields(md->bitfieldString());
2193 newMmd->addSectionsToDefinition(root->anchors);
2194 newMmd->setBodySegment(md->getDefLine(),md->getStartBodyLine(),md->getEndBodyLine());
2195 newMmd->setBodyDef(md->getBodyDef());
2196 newMmd->setInitializer(md->initializer());
2197 newMmd->setRequiresClause(md->requiresClause());
2198 newMmd->setMaxInitLines(md->initializerLines());
2199 newMmd->setMemberGroupId(root->mGrpId);
2200 newMmd->setMemberSpecifiers(md->getMemberSpecifiers());
2201 newMmd->setVhdlSpecifiers(md->getVhdlSpecifiers());
2202 newMmd->setLanguage(root->lang);
2203 newMmd->setId(root->id);
2204 MemberName *mn = Doxygen::memberNameLinkedMap->add(memName);
2205 mn->push_back(std::move(newMd));
2206}
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 11304 of file doxygen.cpp.

11305{
11307 msg("Developer parameters:\n");
11308 msg(" -m dump symbol map\n");
11309 msg(" -b making messages output unbuffered\n");
11310 msg(" -c <file> process input file as a comment block and produce HTML output\n");
11311#if ENABLE_TRACING
11312 msg(" -t [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout)\n");
11313 msg(" -t_time [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout),\n"
11314 " and include time and thread information\n");
11315#endif
11316 msg(" -d <level> enable a debug level, such as (multiple invocations of -d are possible):\n");
11318}
@ 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 1495 of file doxygen.cpp.

1496{
1497 //bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
1498 //if (!inlineGroupedClasses) return;
1499 //printf("** distributeClassGroupRelations()\n");
1500
1501 ClassDefSet visitedClasses;
1502 for (const auto &cd : *Doxygen::classLinkedMap)
1503 {
1504 //printf("Checking %s\n",qPrint(cd->name()));
1505 // distribute the group to nested classes as well
1506 if (visitedClasses.find(cd.get())==visitedClasses.end() && !cd->partOfGroups().empty())
1507 {
1508 //printf(" Candidate for merging\n");
1509 GroupDef *gd = cd->partOfGroups().front();
1510 for (auto &ncd : cd->getClasses())
1511 {
1513 if (ncdm && ncdm->partOfGroups().empty())
1514 {
1515 //printf(" Adding %s to group '%s'\n",qPrint(ncd->name()),
1516 // gd->groupTitle());
1517 ncdm->makePartOfGroup(gd);
1518 gd->addClass(ncdm);
1519 }
1520 }
1521 visitedClasses.insert(cd.get()); // only visit every class once
1522 }
1523 }
1524}
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 1347 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ distributeMemberGroupDocumentation()

void distributeMemberGroupDocumentation ( )
static

Definition at line 9334 of file doxygen.cpp.

9335{
9336 // for each class
9337 for (const auto &cd : *Doxygen::classLinkedMap)
9338 {
9339 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9340 if (cdm)
9341 {
9343 }
9344 }
9345 // for each file
9346 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9347 {
9348 for (const auto &fd : *fn)
9349 {
9350 fd->distributeMemberGroupDocumentation();
9351 }
9352 }
9353 // for each namespace
9354 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9355 {
9357 if (ndm)
9358 {
9360 }
9361 }
9362 // for each group
9363 for (const auto &gd : *Doxygen::groupLinkedMap)
9364 {
9365 gd->distributeMemberGroupDocumentation();
9366 }
9368}
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 11263 of file doxygen.cpp.

11264{
11265 QCString anchor;
11267 {
11268 MemberDef *md = toMemberDef(d);
11269 anchor=":"+md->anchor();
11270 }
11271 QCString scope;
11272 QCString fn = d->getOutputFileBase();
11275 {
11276 scope = fn;
11277 }
11278 t << "REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
11279 << fn+anchor << "','"
11280 << scope << "','"
11281 << d->name() << "','"
11282 << d->getDefFileName() << "','"
11283 << d->getDefLine()
11284 << "');\n";
11285}
virtual QCString anchor() const =0
virtual QCString getOutputFileBase() const =0
MemberDef * toMemberDef(Definition *d)
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:4902

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

11288{
11289 std::ofstream f = Portable::openOutputStream("symbols.sql");
11290 if (f.is_open())
11291 {
11292 TextStream t(&f);
11293 for (const auto &[name,symList] : *Doxygen::symbolMap)
11294 {
11295 for (const auto &def : symList)
11296 {
11297 dumpSymbol(t,def);
11298 }
11299 }
11300 }
11301}
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 12208 of file doxygen.cpp.

12209{
12210 if (!g_successfulRun) // premature exit
12211 {
12212 Dir thisDir;
12213 msg("Exiting...\n");
12214 if (!Doxygen::filterDBFileName.isEmpty())
12215 {
12216 thisDir.remove(Doxygen::filterDBFileName.str());
12217 }
12218 }
12219}
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:191

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

Referenced by parseInput().

◆ extractClassName()

QCString extractClassName ( const Entry * root)
static

Definition at line 5270 of file doxygen.cpp.

5271{
5272 // strip any anonymous scopes first
5275 int i=0;
5276 if ((root->lang==SrcLangExt::CSharp || root->lang==SrcLangExt::Java) &&
5277 (i=bName.find('<'))!=-1)
5278 {
5279 // a Java/C# generic class looks like a C++ specialization, so we need to strip the
5280 // template part before looking for matches
5281 if (root->lang==SrcLangExt::CSharp)
5282 {
5283 bName = mangleCSharpGenericName(root->name);
5284 }
5285 else
5286 {
5287 bName = bName.left(i);
5288 }
5289 }
5290 return bName;
5291}

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

7351{
7352 AUTO_TRACE("root->type='{}' root->inside='{}' root->name='{}' root->args='{}' section={} root->spec={} root->mGrpId={}",
7353 root->type,root->inside,root->name,root->args,root->section,root->spec,root->mGrpId);
7354 //printf("root->parent()->name=%s\n",qPrint(root->parent()->name));
7355 bool isFunc=TRUE;
7356
7357 QCString type = root->type;
7358 QCString args = root->args;
7359 int i=-1, l=0;
7360 if ( // detect func variable/typedef to func ptr
7361 (i=findFunctionPtr(type.str(),root->lang,&l))!=-1
7362 )
7363 {
7364 //printf("Fixing function pointer!\n");
7365 // fix type and argument
7366 args.prepend(type.right(type.length()-i-l));
7367 type=type.left(i+l);
7368 //printf("Results type=%s,name=%s,args=%s\n",qPrint(type),qPrint(root->name),qPrint(args));
7369 isFunc=FALSE;
7370 }
7371 else if ((type.startsWith("typedef ") && args.find('(')!=-1))
7372 // detect function types marked as functions
7373 {
7374 isFunc=FALSE;
7375 }
7376
7377 //printf("Member %s isFunc=%d\n",qPrint(root->name),isFunc);
7378 if (root->section.isMemberDoc())
7379 {
7380 //printf("Documentation for inline member '%s' found args='%s'\n",
7381 // qPrint(root->name),qPrint(args));
7382 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7383 if (type.isEmpty())
7384 {
7385 findMember(root,
7386 relates,
7387 type,
7388 args,
7389 root->name + args + root->exception,
7390 FALSE,
7391 isFunc);
7392 }
7393 else
7394 {
7395 findMember(root,
7396 relates,
7397 type,
7398 args,
7399 type + " " + root->name + args + root->exception,
7400 FALSE,
7401 isFunc);
7402 }
7403 }
7404 else if (root->section.isOverloadDoc())
7405 {
7406 //printf("Overloaded member %s found\n",qPrint(root->name));
7407 findMember(root,
7408 relates,
7409 type,
7410 args,
7411 root->name,
7412 TRUE,
7413 isFunc);
7414 }
7415 else if
7416 ((root->section.isFunction() // function
7417 ||
7418 (root->section.isVariable() && // variable
7419 !type.isEmpty() && // with a type
7420 g_compoundKeywords.find(type.str())==g_compoundKeywords.end() // that is not a keyword
7421 // (to skip forward declaration of class etc.)
7422 )
7423 )
7424 )
7425 {
7426 //printf("Documentation for member '%s' found args='%s' excp='%s'\n",
7427 // qPrint(root->name),qPrint(args),qPrint(root->exception));
7428 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7429 //printf("Inside=%s\n Relates=%s\n",qPrint(root->inside),qPrint(relates));
7430 if (type=="friend class" || type=="friend struct" ||
7431 type=="friend union")
7432 {
7433 findMember(root,
7434 relates,
7435 type,
7436 args,
7437 type+" "+root->name,
7438 FALSE,FALSE);
7439
7440 }
7441 else if (!type.isEmpty())
7442 {
7443 findMember(root,
7444 relates,
7445 type,
7446 args,
7447 type+" "+ root->inside + root->name + args + root->exception,
7448 FALSE,isFunc);
7449 }
7450 else
7451 {
7452 findMember(root,
7453 relates,
7454 type,
7455 args,
7456 root->inside + root->name + args + root->exception,
7457 FALSE,isFunc);
7458 }
7459 }
7460 else if (root->section.isDefine() && !relates.isEmpty())
7461 {
7462 findMember(root,
7463 relates,
7464 type,
7465 args,
7466 root->name + args,
7467 FALSE,
7468 !args.isEmpty());
7469 }
7470 else if (root->section.isVariableDoc())
7471 {
7472 //printf("Documentation for variable %s found\n",qPrint(root->name));
7473 //if (!relates.isEmpty()) printf(" Relates %s\n",qPrint(relates));
7474 findMember(root,
7475 relates,
7476 type,
7477 args,
7478 root->name,
7479 FALSE,
7480 FALSE);
7481 }
7482 else if (root->section.isExportedInterface() ||
7483 root->section.isIncludedService())
7484 {
7485 findMember(root,
7486 relates,
7487 type,
7488 args,
7489 type + " " + root->name,
7490 FALSE,
7491 FALSE);
7492 }
7493 else
7494 {
7495 // skip section
7496 //printf("skip section\n");
7497 }
7498}
QCString inside
name of the class in which documents are found
Definition entry.h:214
static void findMember(const Entry *root, const QCString &relates, const QCString &type, const QCString &args, QCString funcDecl, bool overloaded, bool isFunc)
Definition doxygen.cpp:6724

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

4734{
4735 AUTO_TRACE("name={}",root->name);
4736 // The base class could ofcouse also be a non-nested class
4737 const ArgumentList &formalArgs = masterCd->templateArguments();
4738 for (const BaseInfo &bi : root->extends)
4739 {
4740 //printf("masterCd=%s bi.name='%s' #actualArgs=%d\n",
4741 // qPrint(masterCd->localName()),qPrint(bi.name),actualArgs ? (int)actualArgs->size() : -1);
4742 TemplateNameMap formTemplateNames;
4743 if (templateNames.empty())
4744 {
4745 formTemplateNames = getTemplateArgumentsInName(formalArgs,bi.name.str());
4746 }
4747 BaseInfo tbi = bi;
4748 tbi.name = substituteTemplateArgumentsInString(bi.name,formalArgs,actualArgs);
4749 //printf("masterCd=%p instanceCd=%p bi->name=%s tbi.name=%s\n",(void*)masterCd,(void*)instanceCd,qPrint(bi.name),qPrint(tbi.name));
4750
4751 if (mode==DocumentedOnly)
4752 {
4753 // find a documented base class in the correct scope
4754 if (!findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,DocumentedOnly,isArtificial))
4755 {
4756 // 1.8.2: decided to show inheritance relations even if not documented,
4757 // we do make them artificial, so they do not appear in the index
4758 //if (!Config_getBool(HIDE_UNDOC_RELATIONS))
4759 bool b = Config_getBool(HIDE_UNDOC_RELATIONS) ? TRUE : isArtificial;
4760 //{
4761 // no documented base class -> try to find an undocumented one
4762 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,Undocumented,b);
4763 //}
4764 }
4765 }
4766 else if (mode==TemplateInstances)
4767 {
4768 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,TemplateInstances,isArtificial);
4769 }
4770 }
4771}

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

5738{
5739 SymbolResolver resolver(fd);
5740 const ClassDef *tcd = resolver.resolveClass(nd,scopeName,true,true);
5741 //printf("findClassDefinition(fd=%s,ns=%s,scopeName=%s)='%s'\n",
5742 // qPrint(fd?fd->name():""),qPrint(nd?nd->name():""),
5743 // qPrint(scopeName),qPrint(tcd?tcd->name():""));
5744 return tcd;
5745}

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

5262{
5263 if (isClassSection(root))
5264 {
5265 g_classEntries.emplace(root->name.str(),root);
5266 }
5267 for (const auto &e : root->children()) findClassEntries(e.get());
5268}
static void findClassEntries(const Entry *root)
Definition doxygen.cpp:5261
static bool isClassSection(const Entry *root)
Definition doxygen.cpp:5239

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

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

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

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

◆ findClassWithinClassContext()

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

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

Definition at line 4533 of file doxygen.cpp.

4534{
4535 ClassDef *result=nullptr;
4536 if (cd==nullptr)
4537 {
4538 return result;
4539 }
4540 FileDef *fd=cd->getFileDef();
4541 SymbolResolver resolver(fd);
4542 if (context && cd!=context)
4543 {
4544 result = const_cast<ClassDef*>(resolver.resolveClass(context,name,true,true));
4545 }
4546 //printf("1. result=%p\n",result);
4547 if (result==nullptr)
4548 {
4549 result = const_cast<ClassDef*>(resolver.resolveClass(cd,name,true,true));
4550 }
4551 //printf("2. result=%p\n",result);
4552 if (result==nullptr) // try direct class, needed for namespaced classes imported via tag files (see bug624095)
4553 {
4554 result = getClass(name);
4555 }
4556 //printf("3. result=%p\n",result);
4557 //printf("** Trying to find %s within context %s class %s result=%s lookup=%p\n",
4558 // qPrint(name),
4559 // context ? qPrint(context->name()) : "<none>",
4560 // cd ? qPrint(cd->name()) : "<none>",
4561 // result ? qPrint(result->name()) : "<none>",
4562 // Doxygen::classLinkedMap->find(name)
4563 // );
4564 return result;
4565}

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

Referenced by findClassRelation(), and findUsedClassesForClass().

◆ findDefineDocumentation()

void findDefineDocumentation ( Entry * root)
static

Definition at line 9582 of file doxygen.cpp.

9583{
9584 if ((root->section.isDefineDoc() || root->section.isDefine()) && !root->name.isEmpty())
9585 {
9586 //printf("found define '%s' '%s' brief='%s' doc='%s'\n",
9587 // qPrint(root->name),qPrint(root->args),qPrint(root->brief),qPrint(root->doc));
9588
9589 if (root->tagInfo() && !root->name.isEmpty()) // define read from a tag file
9590 {
9591 auto md = createMemberDef(root->tagInfo()->tagName,1,1,
9592 "#define",root->name,root->args,QCString(),
9593 Protection::Public,Specifier::Normal,FALSE,Relationship::Member,MemberType::Define,
9594 ArgumentList(),ArgumentList(),"");
9595 auto mmd = toMemberDefMutable(md.get());
9596 mmd->setTagInfo(root->tagInfo());
9597 mmd->setLanguage(root->lang);
9598 mmd->addQualifiers(root->qualifiers);
9599 //printf("Searching for '%s' fd=%p\n",qPrint(filePathName),fd);
9600 mmd->setFileDef(root->parent()->fileDef());
9601 //printf("Adding member=%s\n",qPrint(md->name()));
9603 mn->push_back(std::move(md));
9604 }
9606 if (mn)
9607 {
9608 int count=0;
9609 for (const auto &md : *mn)
9610 {
9611 if (md->memberType()==MemberType::Define) count++;
9612 }
9613 if (count==1)
9614 {
9615 for (const auto &imd : *mn)
9616 {
9617 MemberDefMutable *md = toMemberDefMutable(imd.get());
9618 if (md && md->memberType()==MemberType::Define)
9619 {
9620 addDefineDoc(root,md);
9621 }
9622 }
9623 }
9624 else if (count>1 &&
9625 (!root->doc.isEmpty() ||
9626 !root->brief.isEmpty() ||
9627 root->bodyLine!=-1
9628 )
9629 )
9630 // multiple defines don't know where to add docs
9631 // but maybe they are in different files together with their documentation
9632 {
9633 for (const auto &imd : *mn)
9634 {
9635 MemberDefMutable *md = toMemberDefMutable(imd.get());
9636 if (md && md->memberType()==MemberType::Define)
9637 {
9638 if (haveEqualFileNames(root, md) || isEntryInGroupOfMember(root, md))
9639 // doc and define in the same file or group assume they belong together.
9640 {
9641 addDefineDoc(root,md);
9642 }
9643 }
9644 }
9645 //warn("define {} found in the following files:\n",root->name);
9646 //warn("Cannot determine where to add the documentation found "
9647 // "at line {} of file {}. \n",
9648 // root->startLine,root->fileName);
9649 }
9650 }
9651 else if (!root->doc.isEmpty() || !root->brief.isEmpty()) // define not found
9652 {
9653 bool preEnabled = Config_getBool(ENABLE_PREPROCESSING);
9654 if (preEnabled)
9655 {
9656 warn(root->fileName,root->startLine,"documentation for unknown define {} found.",root->name);
9657 }
9658 else
9659 {
9660 warn(root->fileName,root->startLine, "found documented #define {} but ignoring it because ENABLE_PREPROCESSING is NO.", root->name);
9661 }
9662 }
9663 }
9664 for (const auto &e : root->children()) findDefineDocumentation(e.get());
9665}
static void findDefineDocumentation(Entry *root)
Definition doxygen.cpp:9582
static void addDefineDoc(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:9555
static bool haveEqualFileNames(const Entry *root, const MemberDef *md)
Definition doxygen.cpp:9544
static bool isEntryInGroupOfMember(const Entry *root, const MemberDef *md, bool allowNoGroup=false)
Definition doxygen.cpp:5751

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

8146{
8147 // for each member name
8148 for (const auto &mn : mnsd)
8149 {
8150 // for each member definition
8151 for (const auto &imd : *mn)
8152 {
8153 MemberDefMutable *md = toMemberDefMutable(imd.get());
8154 if (md && md->isEnumerate()) // member is an enum
8155 {
8156 int documentedEnumValues=0;
8157 // for each enum value
8158 for (const auto &fmd : md->enumFieldList())
8159 {
8160 if (fmd->isLinkableInProject()) documentedEnumValues++;
8161 }
8162 // at least one enum value is documented
8163 if (documentedEnumValues>0) md->setDocumentedEnumValues(TRUE);
8164 }
8165 }
8166 }
8167}
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 9669 of file doxygen.cpp.

9670{
9671 if (root->section.isDirDoc())
9672 {
9673 QCString normalizedName = root->name;
9674 normalizedName = substitute(normalizedName,"\\","/");
9675 //printf("root->docFile=%s normalizedName=%s\n",
9676 // qPrint(root->docFile),qPrint(normalizedName));
9677 if (root->docFile==normalizedName) // current dir?
9678 {
9679 int lastSlashPos=normalizedName.findRev('/');
9680 if (lastSlashPos!=-1) // strip file name
9681 {
9682 normalizedName=normalizedName.left(lastSlashPos);
9683 }
9684 }
9685 if (normalizedName.at(normalizedName.length()-1)!='/')
9686 {
9687 normalizedName+='/';
9688 }
9689 DirDef *matchingDir=nullptr;
9690 for (const auto &dir : *Doxygen::dirLinkedMap)
9691 {
9692 //printf("Dir: %s<->%s\n",qPrint(dir->name()),qPrint(normalizedName));
9693 if (dir->name().right(normalizedName.length())==normalizedName)
9694 {
9695 if (matchingDir)
9696 {
9697 warn(root->fileName,root->startLine,
9698 "\\dir command matches multiple directories.\n"
9699 " Applying the command for directory {}\n"
9700 " Ignoring the command for directory {}",
9701 matchingDir->name(),dir->name()
9702 );
9703 }
9704 else
9705 {
9706 matchingDir=dir.get();
9707 }
9708 }
9709 }
9710 if (matchingDir)
9711 {
9712 //printf("Match for with dir %s #anchor=%zu\n",qPrint(matchingDir->name()),root->anchors.size());
9713 matchingDir->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9714 matchingDir->setDocumentation(root->doc,root->docFile,root->docLine);
9715 matchingDir->setRefItems(root->sli);
9716 matchingDir->setRequirementReferences(root->rqli);
9717 matchingDir->addSectionsToDefinition(root->anchors);
9718 root->commandOverrides.apply_directoryGraph([&](bool b) { matchingDir->overrideDirectoryGraph(b); });
9719 addDirToGroups(root,matchingDir);
9720 }
9721 else
9722 {
9723 warn(root->fileName,root->startLine,"No matching directory found for command \\dir {}",normalizedName);
9724 }
9725 }
9726 for (const auto &e : root->children()) findDirDocumentation(e.get());
9727}
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:9669
void addDirToGroups(const Entry *root, DirDef *dd)

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

Referenced by findDirDocumentation(), and parseInput().

◆ findDocumentedEnumValues()

void findDocumentedEnumValues ( )
static

Definition at line 8171 of file doxygen.cpp.

8172{
8175}
static void findDEV(const MemberNameLinkedMap &mnsd)
Definition doxygen.cpp:8145

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

3085{
3086 // locate end of template
3087 size_t e=startPos;
3088 int brCount=1;
3089 int roundCount=0;
3090 size_t len = s.length();
3091 bool insideString=FALSE;
3092 bool insideChar=FALSE;
3093 char pc = 0;
3094 while (e<len && brCount!=0)
3095 {
3096 char c=s.at(e);
3097 switch(c)
3098 {
3099 case '<':
3100 if (!insideString && !insideChar)
3101 {
3102 if (e<len-1 && s.at(e+1)=='<')
3103 e++;
3104 else if (roundCount==0)
3105 brCount++;
3106 }
3107 break;
3108 case '>':
3109 if (!insideString && !insideChar)
3110 {
3111 if (e<len-1 && s.at(e+1)=='>')
3112 e++;
3113 else if (roundCount==0)
3114 brCount--;
3115 }
3116 break;
3117 case '(':
3118 if (!insideString && !insideChar)
3119 roundCount++;
3120 break;
3121 case ')':
3122 if (!insideString && !insideChar)
3123 roundCount--;
3124 break;
3125 case '"':
3126 if (!insideChar)
3127 {
3128 if (insideString && pc!='\\')
3129 insideString=FALSE;
3130 else
3131 insideString=TRUE;
3132 }
3133 break;
3134 case '\'':
3135 if (!insideString)
3136 {
3137 if (insideChar && pc!='\\')
3138 insideChar=FALSE;
3139 else
3140 insideChar=TRUE;
3141 }
3142 break;
3143 }
3144 pc = c;
3145 e++;
3146 }
3147 return brCount==0 ? static_cast<int>(e) : -1;
3148}

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

Referenced by addVariable(), and findClassRelation().

◆ findEnumDocumentation()

void findEnumDocumentation ( const Entry * root)
static

Definition at line 8059 of file doxygen.cpp.

8060{
8061 if (root->section.isEnumDoc() &&
8062 !root->name.isEmpty() &&
8063 root->name.at(0)!='@' // skip anonymous enums
8064 )
8065 {
8066 QCString name;
8067 QCString scope;
8068 int i = root->name.findRev("::");
8069 if (i!=-1) // scope is specified as part of the name
8070 {
8071 name=root->name.right(root->name.length()-i-2); // extract name
8072 scope=root->name.left(i); // extract scope
8073 //printf("Scope='%s' Name='%s'\n",qPrint(scope),qPrint(name));
8074 }
8075 else // just the name
8076 {
8077 name=root->name;
8078 }
8079 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
8080 {
8081 if (!scope.isEmpty()) scope.prepend("::");
8082 scope.prepend(root->parent()->name);
8083 }
8084 const ClassDef *cd = getClass(scope);
8085 const NamespaceDef *nd=Doxygen::namespaceLinkedMap->find(scope);
8086 const FileDef *fd = root->fileDef();
8087 AUTO_TRACE("Found docs for enum with name '{}' and scope '{}' in context '{}' cd='{}', nd='{}' fd='{}'",
8088 name,scope,root->parent()->name,
8089 cd ? cd->name() : QCString("<none>"),
8090 nd ? nd->name() : QCString("<none>"),
8091 fd ? fd->name() : QCString("<none>"));
8092
8093 if (!name.isEmpty())
8094 {
8095 bool found = tryAddEnumDocsToGroupMember(root, name);
8096 if (!found)
8097 {
8098 MemberName *mn = cd ? Doxygen::memberNameLinkedMap->find(name) : Doxygen::functionNameLinkedMap->find(name);
8099 if (mn)
8100 {
8101 for (const auto &imd : *mn)
8102 {
8103 MemberDefMutable *md = toMemberDefMutable(imd.get());
8104 if (md && md->isEnumerate())
8105 {
8106 const ClassDef *mcd = md->getClassDef();
8107 const NamespaceDef *mnd = md->getNamespaceDef();
8108 const FileDef *mfd = md->getFileDef();
8109 if (cd && mcd==cd)
8110 {
8111 AUTO_TRACE_ADD("Match found for class scope");
8112 addEnumDocs(root,md);
8113 found = TRUE;
8114 break;
8115 }
8116 else if (cd==nullptr && mcd==nullptr && nd!=nullptr && mnd==nd)
8117 {
8118 AUTO_TRACE_ADD("Match found for namespace scope");
8119 addEnumDocs(root,md);
8120 found = TRUE;
8121 break;
8122 }
8123 else if (cd==nullptr && nd==nullptr && mcd==nullptr && mnd==nullptr && fd==mfd)
8124 {
8125 AUTO_TRACE_ADD("Match found for global scope");
8126 addEnumDocs(root,md);
8127 found = TRUE;
8128 break;
8129 }
8130 }
8131 }
8132 }
8133 }
8134 if (!found)
8135 {
8136 warn(root->fileName,root->startLine, "Documentation for undefined enum '{}' found.", name);
8137 }
8138 }
8139 }
8140 for (const auto &e : root->children()) findEnumDocumentation(e.get());
8141}
static bool tryAddEnumDocsToGroupMember(const Entry *root, const QCString &name)
Definition doxygen.cpp:8026
static void addEnumDocs(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:7984
static void findEnumDocumentation(const Entry *root)
Definition doxygen.cpp:8059

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

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

Referenced by findEnums(), and parseInput().

◆ findFriends()

void findFriends ( )
static

Definition at line 4241 of file doxygen.cpp.

4242{
4243 AUTO_TRACE();
4244 for (const auto &fn : *Doxygen::functionNameLinkedMap) // for each global function name
4245 {
4246 MemberName *mn = Doxygen::memberNameLinkedMap->find(fn->memberName());
4247 if (mn)
4248 { // there are members with the same name
4249 // for each function with that name
4250 for (const auto &ifmd : *fn)
4251 {
4252 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
4253 // for each member with that name
4254 for (const auto &immd : *mn)
4255 {
4256 MemberDefMutable *mmd = toMemberDefMutable(immd.get());
4257 //printf("Checking for matching arguments
4258 // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n",
4259 // mmd->isRelated(),mmd->isFriend(),mmd->isFunction());
4260 if (fmd && mmd &&
4261 (mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) &&
4262 matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), mmd->typeString(), &mmd->argumentList(),
4263 fmd->getOuterScope(), fmd->getFileDef(), fmd->typeString(), &fmd->argumentList(),
4264 TRUE,mmd->getLanguage()
4265 )
4266
4267 ) // if the member is related and the arguments match then the
4268 // function is actually a friend.
4269 {
4270 AUTO_TRACE_ADD("Merging related global and member '{}' isFriend={} isRelated={} isFunction={}",
4271 mmd->name(),mmd->isFriend(),mmd->isRelated(),mmd->isFunction());
4272 const ArgumentList &mmdAl = mmd->argumentList();
4273 const ArgumentList &fmdAl = fmd->argumentList();
4274 mergeArguments(const_cast<ArgumentList&>(fmdAl),const_cast<ArgumentList&>(mmdAl));
4275
4276 // reset argument lists to add missing default parameters
4277 QCString mmdAlStr = argListToString(mmdAl);
4278 QCString fmdAlStr = argListToString(fmdAl);
4279 mmd->setArgsString(mmdAlStr);
4280 fmd->setArgsString(fmdAlStr);
4281 mmd->moveDeclArgumentList(std::make_unique<ArgumentList>(mmdAl));
4282 fmd->moveDeclArgumentList(std::make_unique<ArgumentList>(fmdAl));
4283 AUTO_TRACE_ADD("friend args='{}' member args='{}'",argListToString(fmd->argumentList()),argListToString(mmd->argumentList()));
4284
4285 if (!fmd->documentation().isEmpty())
4286 {
4287 mmd->setDocumentation(fmd->documentation(),fmd->docFile(),fmd->docLine());
4288 }
4289 else if (!mmd->documentation().isEmpty())
4290 {
4291 fmd->setDocumentation(mmd->documentation(),mmd->docFile(),mmd->docLine());
4292 }
4293 if (mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
4294 {
4295 mmd->setBriefDescription(fmd->briefDescription(),fmd->briefFile(),fmd->briefLine());
4296 }
4297 else if (!mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
4298 {
4299 fmd->setBriefDescription(mmd->briefDescription(),mmd->briefFile(),mmd->briefLine());
4300 }
4301 if (!fmd->inbodyDocumentation().isEmpty())
4302 {
4304 }
4305 else if (!mmd->inbodyDocumentation().isEmpty())
4306 {
4308 }
4309 //printf("body mmd %d fmd %d\n",mmd->getStartBodyLine(),fmd->getStartBodyLine());
4310 if (mmd->getStartBodyLine()==-1 && fmd->getStartBodyLine()!=-1)
4311 {
4312 mmd->setBodySegment(fmd->getDefLine(),fmd->getStartBodyLine(),fmd->getEndBodyLine());
4313 mmd->setBodyDef(fmd->getBodyDef());
4314 //mmd->setBodyMember(fmd);
4315 }
4316 else if (mmd->getStartBodyLine()!=-1 && fmd->getStartBodyLine()==-1)
4317 {
4318 fmd->setBodySegment(mmd->getDefLine(),mmd->getStartBodyLine(),mmd->getEndBodyLine());
4319 fmd->setBodyDef(mmd->getBodyDef());
4320 //fmd->setBodyMember(mmd);
4321 }
4323
4325
4326 mmd->addQualifiers(fmd->getQualifiers());
4327 fmd->addQualifiers(mmd->getQualifiers());
4328
4329 }
4330 }
4331 }
4332 }
4333 }
4334}
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:6861

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

2881{
2882 AUTO_TRACE("type='{}' lang={}",type,lang);
2883 if (lang == SrcLangExt::Fortran || lang == SrcLangExt::VHDL)
2884 {
2885 return -1; // Fortran and VHDL do not have function pointers
2886 }
2887
2888 static const reg::Ex re(R"(\‍([^)]*[*&^][^)]*\))");
2890 size_t i=std::string::npos;
2891 size_t l=0;
2892 if (reg::search(type,match,re)) // contains (...*...) or (...&...) or (...^...)
2893 {
2894 i = match.position();
2895 l = match.length();
2896 }
2897 if (i!=std::string::npos)
2898 {
2899 size_t di = type.find("decltype(");
2900 if (di!=std::string::npos && di<i)
2901 {
2902 i = std::string::npos;
2903 }
2904 }
2905 size_t bb=type.find('<');
2906 size_t be=type.rfind('>');
2907 bool templFp = false;
2908 if (be!=std::string::npos) {
2909 size_t cc_ast = type.find("::*");
2910 size_t cc_amp = type.find("::&");
2911 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>::*)'
2912 }
2913
2914 if (!type.empty() && // return type is non-empty
2915 i!=std::string::npos && // contains (...*...)
2916 type.find("operator")==std::string::npos && // not an operator
2917 (type.find(")(")==std::string::npos || type.find("typedef ")!=std::string::npos) &&
2918 // not a function pointer return type
2919 (!(bb<i && i<be) || templFp) // bug665855: avoid treating "typedef A<void (T*)> type" as a function pointer
2920 )
2921 {
2922 if (pLength) *pLength=static_cast<int>(l);
2923 //printf("findFunctionPtr=%d\n",(int)i);
2924 AUTO_TRACE_EXIT("result={}",i);
2925 return static_cast<int>(i);
2926 }
2927 else
2928 {
2929 //printf("findFunctionPtr=%d\n",-1);
2930 AUTO_TRACE_EXIT("result=-1");
2931 return -1;
2932 }
2933}
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:49

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

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

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

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

2461{
2462 FileDefSet visitedFiles;
2463 // then recursively add using directives found in #include files
2464 // to files that have not been visited.
2465 for (const auto &fn : *Doxygen::inputNameLinkedMap)
2466 {
2467 for (const auto &fd : *fn)
2468 {
2469 //printf("----- adding using directives for file %s\n",qPrint(fd->name()));
2470 fd->addIncludedUsingDirectives(visitedFiles);
2471 }
2472 }
2473}
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 5298 of file doxygen.cpp.

5299{
5300 AUTO_TRACE();
5301 ClassDefSet visitedClasses;
5302 for (const auto &[name,root] : g_classEntries)
5303 {
5304 QCString bName = extractClassName(root);
5305 ClassDefMutable *cdm = getClassMutable(bName);
5306 if (cdm)
5307 {
5309 }
5310 }
5311}

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

Referenced by parseInput().

◆ findMainPage()

void findMainPage ( Entry * root)
static

Definition at line 9769 of file doxygen.cpp.

9770{
9771 if (root->section.isMainpageDoc())
9772 {
9773 if (Doxygen::mainPage==nullptr && root->tagInfo()==nullptr)
9774 {
9775 //printf("mainpage: docLine=%d startLine=%d\n",root->docLine,root->startLine);
9776 //printf("Found main page! \n======\n%s\n=======\n",qPrint(root->doc));
9777 QCString title=root->args.stripWhiteSpace();
9778 if (title.isEmpty()) title = Config_getString(PROJECT_NAME);
9779 //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9780 QCString indexName="index";
9782 indexName, root->brief+root->doc+root->inbodyDocs,title);
9783 //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
9784 Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9785 Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1);
9786 Doxygen::mainPage->setFileName(indexName);
9787 Doxygen::mainPage->setLocalToc(root->localToc);
9789
9791 if (si)
9792 {
9793 if (!si->ref().isEmpty()) // we are from a tag file
9794 {
9795 // a page name is a label as well! but should no be double either
9797 Doxygen::mainPage->name(),
9798 indexName,
9799 root->startLine,
9800 Doxygen::mainPage->title(),
9802 0); // level 0
9803 }
9804 else if (si->lineNr() != -1)
9805 {
9806 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {}, line {})",
9807 Doxygen::mainPage->name(),si->fileName(),si->lineNr());
9808 }
9809 else
9810 {
9811 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {})",
9812 Doxygen::mainPage->name(),si->fileName());
9813 }
9814 }
9815 else
9816 {
9817 // a page name is a label as well! but should no be double either
9819 Doxygen::mainPage->name(),
9820 indexName,
9821 root->startLine,
9822 Doxygen::mainPage->title(),
9824 0); // level 0
9825 }
9826 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9827 }
9828 else if (root->tagInfo()==nullptr)
9829 {
9830 warn(root->fileName,root->startLine,
9831 "found more than one \\mainpage comment block! (first occurrence: {}, line {}), Skipping current block!",
9832 Doxygen::mainPage->docFile(),Doxygen::mainPage->getStartBodyLine());
9833 }
9834 }
9835 for (const auto &e : root->children()) findMainPage(e.get());
9836}
class that provide information about a section.
Definition section.h:58
QCString ref() const
Definition section.h:72
QCString fileName() const
Definition section.h:74
int lineNr() const
Definition section.h:73
SectionInfo * replace(const QCString &label, const QCString &fileName, int lineNr, const QCString &title, SectionType type, int level, const QCString &ref=QCString())
Definition section.h:157
SectionInfo * add(const SectionInfo &si)
Definition section.h:139
static constexpr int Page
Definition section.h:31
static void findMainPage(Entry *root)
Definition doxygen.cpp:9769

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

9840{
9841 if (root->section.isMainpageDoc())
9842 {
9843 if (Doxygen::mainPage && root->tagInfo())
9844 {
9845 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9846 }
9847 }
9848 for (const auto &e : root->children()) findMainPageTagFiles(e.get());
9849}
static void findMainPageTagFiles(Entry *root)
Definition doxygen.cpp:9839

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

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

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::rqli, 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 7500 of file doxygen.cpp.

7501{
7502 if (root->section.isMemberDoc() ||
7503 root->section.isOverloadDoc() ||
7504 root->section.isFunction() ||
7505 root->section.isVariable() ||
7506 root->section.isVariableDoc() ||
7507 root->section.isDefine() ||
7508 root->section.isIncludedService() ||
7509 root->section.isExportedInterface()
7510 )
7511 {
7512 AUTO_TRACE();
7513 if (root->relatesType==RelatesType::Duplicate && !root->relates.isEmpty())
7514 {
7516 }
7518 }
7519 for (const auto &e : root->children())
7520 {
7521 if (!e->section.isEnum())
7522 {
7523 findMemberDocumentation(e.get());
7524 }
7525 }
7526}
static void findMemberDocumentation(const Entry *root)
Definition doxygen.cpp:7500
static void filterMemberDocumentation(const Entry *root, const QCString &relates)
Definition doxygen.cpp:7350

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

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

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

7531{
7532 AUTO_TRACE();
7533 for (const auto &objCImpl : root->children())
7534 {
7535 if (objCImpl->section.isObjcImpl())
7536 {
7537 for (const auto &objCMethod : objCImpl->children())
7538 {
7539 if (objCMethod->section.isFunction())
7540 {
7541 //printf(" Found ObjC method definition %s\n",qPrint(objCMethod->name));
7542 findMember(objCMethod.get(),
7543 objCMethod->relates,
7544 objCMethod->type,
7545 objCMethod->args,
7546 objCMethod->type+" "+objCImpl->name+"::"+objCMethod->name+" "+objCMethod->args,
7547 FALSE,TRUE);
7548 objCMethod->section=EntryType::makeEmpty();
7549 }
7550 }
7551 }
7552 }
7553}

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

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

9373{
9374 // for each class
9375 for (const auto &cd : *Doxygen::classLinkedMap)
9376 {
9377 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9378 if (cdm)
9379 {
9381 }
9382 }
9383 // for each concept
9384 for (const auto &cd : *Doxygen::conceptLinkedMap)
9385 {
9386 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
9387 if (cdm)
9388 {
9390 }
9391 }
9392 // for each file
9393 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9394 {
9395 for (const auto &fd : *fn)
9396 {
9397 fd->findSectionsInDocumentation();
9398 }
9399 }
9400 // for each namespace
9401 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9402 {
9404 if (ndm)
9405 {
9407 }
9408 }
9409 // for each group
9410 for (const auto &gd : *Doxygen::groupLinkedMap)
9411 {
9412 gd->findSectionsInDocumentation();
9413 }
9414 // for each page
9415 for (const auto &pd : *Doxygen::pageLinkedMap)
9416 {
9417 pd->findSectionsInDocumentation();
9418 }
9419 // for each directory
9420 for (const auto &dd : *Doxygen::dirLinkedMap)
9421 {
9422 dd->findSectionsInDocumentation();
9423 }
9425 if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
9426}
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 1695 of file doxygen.cpp.

1696{
1697 std::vector<ClassDefMutable *> candidates;
1698 for (auto &cd : *Doxygen::classLinkedMap)
1699 {
1700 Definition *scope = cd->getOuterScope();
1701 if (scope && scope->definitionType()!=Definition::TypeClass) // that is not nested
1702 {
1703 findTagLessClasses(candidates,cd.get());
1704 }
1705 }
1706
1707 // since processTagLessClasses is potentially adding classes to Doxygen::classLinkedMap
1708 // we need to call it outside of the loop above, otherwise the iterator gets invalidated!
1709 for (auto &cd : candidates)
1710 {
1711 processTagLessClasses(cd,cd,cd,"",0); // process tag less inner struct/classes
1712 }
1713}
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:1614
static void findTagLessClasses()
Definition doxygen.cpp:1695

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

1679{
1680 for (const auto &icd : cd->getClasses())
1681 {
1682 if (icd->name().find("@")==-1) // process all non-anonymous inner classes
1683 {
1684 findTagLessClasses(candidates,icd);
1685 }
1686 }
1687
1689 if (cdm)
1690 {
1691 candidates.push_back(cdm);
1692 }
1693}

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

4780{
4781 AUTO_TRACE("Derived from template '{}' with parameters '{}' isArtificial={}",
4782 templateClass->name(),templSpec,isArtificial);
4783
4784 QCString tempArgsStr = tempArgListToString(templateClass->templateArguments(),root->lang,false);
4785 bool existingClass = templSpec==tempArgsStr;
4786 if (existingClass) return; // avoid recursion
4787
4788 bool freshInstance=FALSE;
4789 ClassDefMutable *instanceClass = toClassDefMutable(
4790 templateClass->insertTemplateInstance(
4791 root->fileName,root->startLine,root->startColumn,templSpec,freshInstance));
4792 if (instanceClass)
4793 {
4794 if (freshInstance)
4795 {
4796 instanceClass->setArtificial(TRUE);
4797 instanceClass->setLanguage(root->lang);
4798
4799 AUTO_TRACE_ADD("found fresh instance '{}'",instanceClass->name());
4800 instanceClass->setTemplateBaseClassNames(templateNames);
4801
4802 // search for new template instances caused by base classes of
4803 // instanceClass
4804 auto it_pair = g_classEntries.equal_range(templateClass->name().str());
4805 for (auto it=it_pair.first ; it!=it_pair.second ; ++it)
4806 {
4807 const Entry *templateRoot = it->second;
4808 AUTO_TRACE_ADD("template root found '{}' templSpec='{}'",templateRoot->name,templSpec);
4809 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(root->lang,templSpec);
4810 findBaseClassesForClass(templateRoot,context,templateClass,instanceClass,
4811 TemplateInstances,isArtificial,templArgs.get(),templateNames);
4812
4813 findUsedClassesForClass(templateRoot,context,templateClass,instanceClass,
4814 isArtificial,templArgs.get(),templateNames);
4815 }
4816 }
4817 else
4818 {
4819 AUTO_TRACE_ADD("instance already exists");
4820 }
4821 }
4822}
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:4568

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

4869{
4870 if (name.isEmpty()) return 0;
4871 int l = static_cast<int>(name.length());
4872 if (name[l-1]=='>') // search backward to find the matching <, allowing nested <...> and strings.
4873 {
4874 int count=1;
4875 int i=l-2;
4876 char insideQuote=0;
4877 while (count>0 && i>=0)
4878 {
4879 char c = name[i--];
4880 switch (c)
4881 {
4882 case '>': if (!insideQuote) count++; break;
4883 case '<': if (!insideQuote) count--; break;
4884 case '\'': if (!insideQuote) insideQuote=c;
4885 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4886 break;
4887 case '"': if (!insideQuote) insideQuote=c;
4888 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4889 break;
4890 default: break;
4891 }
4892 }
4893 if (i>=0) l=i+1;
4894 }
4895 return l;
4896}

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

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

1890{
1891 NamespaceDef *usingNd =nullptr;
1892 for (auto &und : unl)
1893 {
1894 QCString uScope=und->name()+"::";
1895 usingNd = getResolvedNamespace(uScope+name);
1896 if (usingNd!=nullptr) break;
1897 }
1898 return usingNd;
1899}

References getResolvedNamespace().

Referenced by findUsingDirectives().

◆ findUsedTemplateInstances()

void findUsedTemplateInstances ( )
static

Definition at line 5331 of file doxygen.cpp.

5332{
5333 AUTO_TRACE();
5334 for (const auto &[name,root] : g_classEntries)
5335 {
5336 QCString bName = extractClassName(root);
5337 ClassDefMutable *cdm = getClassMutable(bName);
5338 if (cdm)
5339 {
5340 findUsedClassesForClass(root,cdm,cdm,cdm,TRUE);
5342 cdm->addTypeConstraints();
5343 }
5344 }
5345}
virtual void addTypeConstraints()=0
static void makeTemplateInstanceRelation(const Entry *root, ClassDefMutable *cd)
Definition doxygen.cpp:5313

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

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

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

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

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

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

Referenced by findUsingDirectives(), and parseInput().

◆ flushCachedTemplateRelations()

void flushCachedTemplateRelations ( )
static

Definition at line 9431 of file doxygen.cpp.

9432{
9433 // remove all references to classes from the cache
9434 // as there can be new template instances in the inheritance path
9435 // to this class. Optimization: only remove those classes that
9436 // have inheritance instances as direct or indirect sub classes.
9437 StringVector elementsToRemove;
9438 for (const auto &ci : *Doxygen::typeLookupCache)
9439 {
9440 const LookupInfo &li = ci.second;
9441 if (li.definition)
9442 {
9443 elementsToRemove.push_back(ci.first);
9444 }
9445 }
9446 for (const auto &k : elementsToRemove)
9447 {
9448 Doxygen::typeLookupCache->remove(k);
9449 }
9450
9451 // remove all cached typedef resolutions whose target is a
9452 // template class as this may now be a template instance
9453 // for each global function name
9454 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9455 {
9456 // for each function with that name
9457 for (const auto &ifmd : *fn)
9458 {
9459 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9460 if (fmd && fmd->isTypedefValCached())
9461 {
9462 const ClassDef *cd = fmd->getCachedTypedefVal();
9463 if (cd->isTemplate()) fmd->invalidateTypedefValCache();
9464 }
9465 }
9466 }
9467 // for each class method name
9468 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9469 {
9470 // for each function with that name
9471 for (const auto &imd : *nm)
9472 {
9473 MemberDefMutable *md = toMemberDefMutable(imd.get());
9474 if (md && md->isTypedefValCached())
9475 {
9476 const ClassDef *cd = md->getCachedTypedefVal();
9477 if (cd->isTemplate()) md->invalidateTypedefValCache();
9478 }
9479 }
9480 }
9481}
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 9485 of file doxygen.cpp.

9486{
9487 // Remove all unresolved references to classes from the cache.
9488 // This is needed before resolving the inheritance relations, since
9489 // it would otherwise not find the inheritance relation
9490 // for C in the example below, as B::I was already found to be unresolvable
9491 // (which is correct if you ignore the inheritance relation between A and B).
9492 //
9493 // class A { class I {} };
9494 // class B : public A {};
9495 // class C : public B::I {};
9496
9497 StringVector elementsToRemove;
9498 for (const auto &ci : *Doxygen::typeLookupCache)
9499 {
9500 const LookupInfo &li = ci.second;
9501 if (li.definition==nullptr && li.typeDef==nullptr)
9502 {
9503 elementsToRemove.push_back(ci.first);
9504 }
9505 }
9506 for (const auto &k : elementsToRemove)
9507 {
9508 Doxygen::typeLookupCache->remove(k);
9509 }
9510
9511 // for each global function name
9512 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9513 {
9514 // for each function with that name
9515 for (const auto &ifmd : *fn)
9516 {
9517 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9518 if (fmd)
9519 {
9521 }
9522 }
9523 }
9524 // for each class method name
9525 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9526 {
9527 // for each function with that name
9528 for (const auto &imd : *nm)
9529 {
9530 MemberDefMutable *md = toMemberDefMutable(imd.get());
9531 if (md)
9532 {
9534 }
9535 }
9536 }
9537
9538}
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 9189 of file doxygen.cpp.

9190{
9191 std::vector<ClassDefMutable*> classList;
9192 for (const auto &cdi : *Doxygen::classLinkedMap)
9193 {
9194 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9195 if (cd && (cd->getOuterScope()==nullptr ||
9197 {
9198 addClassAndNestedClasses(classList,cd);
9199 }
9200 }
9201 for (const auto &cdi : *Doxygen::hiddenClassLinkedMap)
9202 {
9203 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9204 if (cd && (cd->getOuterScope()==nullptr ||
9206 {
9207 addClassAndNestedClasses(classList,cd);
9208 }
9209 }
9210 generateDocsForClassList(classList);
9211}
static void generateDocsForClassList(const std::vector< ClassDefMutable * > &classList)
Definition doxygen.cpp:9091

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

9216{
9217 for (const auto &cdi : *Doxygen::conceptLinkedMap)
9218 {
9220
9221 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9222 if (cd &&
9223 (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9224 cd->getOuterScope()==Doxygen::globalScope // only look at global concepts
9225 ) && !cd->isHidden() && cd->isLinkableInProject()
9226 )
9227 {
9228 msg("Generating docs for concept {}...\n",cd->displayName());
9230 }
9231 }
9232}
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 10346 of file doxygen.cpp.

10348{
10349 std::ofstream f;
10350 bool fileOpened=openOutputFile(configFile,f);
10351 bool writeToStdout=configFile=="-";
10352 if (fileOpened)
10353 {
10354 TextStream t(&f);
10355 Config::writeTemplate(t,shortList,updateOnly);
10356 if (!writeToStdout)
10357 {
10358 if (!updateOnly)
10359 {
10360 msg("\n\nConfiguration file '{}' created.\n\n",configFile);
10361 msg("Now edit the configuration file and enter\n\n");
10362 if (configFile!="Doxyfile" && configFile!="doxyfile")
10363 msg(" doxygen {}\n\n",configFile);
10364 else
10365 msg(" doxygen\n\n");
10366 msg("to generate the documentation for your project\n\n");
10367 }
10368 else
10369 {
10370 msg("\n\nConfiguration file '{}' updated.\n\n",configFile);
10371 }
10372 }
10373 }
10374 else
10375 {
10376 term("Cannot open file {} for writing\n",configFile);
10377 }
10378}
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 10601 of file doxygen.cpp.

10602{
10603 for (const auto &fn : *Doxygen::inputNameLinkedMap)
10604 {
10605 struct FileEntry
10606 {
10607 FileEntry(const QCString &p,FileDef *fd) : path(p), fileDef(fd) {}
10608 QCString path;
10609 FileDef *fileDef;
10610 };
10611
10612 // collect the entry for which to compute the longest common prefix (LCP) of the path
10613 std::vector<FileEntry> fileEntries;
10614 for (const auto &fd : *fn)
10615 {
10616 if (!fd->isReference()) // skip external references
10617 {
10618 fileEntries.emplace_back(fd->getPath(),fd.get());
10619 }
10620 }
10621
10622 size_t size = fileEntries.size();
10623
10624 if (size==1) // name if unique, so diskname is simply the name
10625 {
10626 FileDef *fd = fileEntries[0].fileDef;
10627 fd->setDiskName(fn->fileName());
10628 }
10629 else if (size>1) // multiple occurrences of the same file name
10630 {
10631 // sort the array
10632 std::stable_sort(fileEntries.begin(),
10633 fileEntries.end(),
10634 [](const FileEntry &fe1,const FileEntry &fe2)
10635 { return qstricmp_sort(fe1.path,fe2.path)<0; }
10636 );
10637
10638 // since the entries are sorted, the common prefix of the whole array is same
10639 // as the common prefix between the first and last entry
10640 const FileEntry &first = fileEntries[0];
10641 const FileEntry &last = fileEntries[size-1];
10642 int first_path_size = static_cast<int>(first.path.size())-1; // -1 to skip trailing slash
10643 int last_path_size = static_cast<int>(last.path.size())-1; // -1 to skip trailing slash
10644 int j=0;
10645 int i=0;
10646 for (i=0;i<first_path_size && i<last_path_size;i++)
10647 {
10648 if (first.path[i]=='/') j=i;
10649 if (first.path[i]!=last.path[i]) break;
10650 }
10651 if (i==first_path_size && i<last_path_size && last.path[i]=='/')
10652 {
10653 // case first='some/path' and last='some/path/more' => match is 'some/path'
10654 j=first_path_size;
10655 }
10656 else if (i==last_path_size && i<first_path_size && first.path[i]=='/')
10657 {
10658 // case first='some/path/more' and last='some/path' => match is 'some/path'
10659 j=last_path_size;
10660 }
10661
10662 // add non-common part of the path to the name
10663 for (auto &fileEntry : fileEntries)
10664 {
10665 QCString prefix = fileEntry.path.right(fileEntry.path.length()-j-1);
10666 fileEntry.fileDef->setName(prefix+fn->fileName());
10667 //printf("!!!!!!!! non unique disk name=%s:%s\n",qPrint(prefix),fn->fileName());
10668 fileEntry.fileDef->setDiskName(prefix+fn->fileName());
10669 }
10670 }
10671 }
10672}
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 9091 of file doxygen.cpp.

9092{
9093 AUTO_TRACE();
9094 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
9095 if (numThreads>1) // multi threaded processing
9096 {
9097 struct DocContext
9098 {
9099 DocContext(ClassDefMutable *cd_,const OutputList &ol_)
9100 : cd(cd_), ol(ol_) {}
9101 ClassDefMutable *cd;
9102 OutputList ol;
9103 };
9104 ThreadPool threadPool(numThreads);
9105 std::vector< std::future< std::shared_ptr<DocContext> > > results;
9106 for (const auto &cd : classList)
9107 {
9108 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9109 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9110 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9111 )
9112 {
9113 auto ctx = std::make_shared<DocContext>(cd,*g_outputList);
9114 auto processFile = [ctx]()
9115 {
9116 msg("Generating docs for compound {}...\n",ctx->cd->displayName());
9117
9118 // skip external references, anonymous compounds and
9119 // template instances
9120 if (!ctx->cd->isHidden() && !ctx->cd->isEmbeddedInOuterScope() &&
9121 ctx->cd->isLinkableInProject() && !ctx->cd->isImplicitTemplateInstance())
9122 {
9123 ctx->cd->writeDocumentation(ctx->ol);
9124 ctx->cd->writeMemberList(ctx->ol);
9125 }
9126
9127 // even for undocumented classes, the inner classes can be documented.
9128 ctx->cd->writeDocumentationForInnerClasses(ctx->ol);
9129 return ctx;
9130 };
9131 results.emplace_back(threadPool.queue(processFile));
9132 }
9133 }
9134 for (auto &f : results)
9135 {
9136 auto ctx = f.get();
9137 }
9138 }
9139 else // single threaded processing
9140 {
9141 for (const auto &cd : classList)
9142 {
9143 //printf("cd=%s getOuterScope=%p global=%p hidden=%d embeddedInOuterScope=%d\n",
9144 // qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope,cd->isHidden(),cd->isEmbeddedInOuterScope());
9145 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9146 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9147 )
9148 {
9149 // skip external references, anonymous compounds and
9150 // template instances
9151 if ( !cd->isHidden() && !cd->isEmbeddedInOuterScope() &&
9152 cd->isLinkableInProject() && !cd->isImplicitTemplateInstance())
9153 {
9154 msg("Generating docs for compound {}...\n",cd->displayName());
9155
9156 cd->writeDocumentation(*g_outputList);
9157 cd->writeMemberList(*g_outputList);
9158 }
9159 // even for undocumented classes, the inner classes can be documented.
9160 cd->writeDocumentationForInnerClasses(*g_outputList);
9161 }
9162 }
9163 }
9164}

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

Referenced by generateClassDocs().

◆ generateExampleDocs()

void generateExampleDocs ( )
static

Definition at line 10054 of file doxygen.cpp.

10055{
10056 g_outputList->disable(OutputType::Man);
10057 for (const auto &pd : *Doxygen::exampleLinkedMap)
10058 {
10059 msg("Generating docs for example {}...\n",pd->name());
10060 SrcLangExt lang = getLanguageFromFileName(pd->name(), SrcLangExt::Unknown);
10061 if (lang != SrcLangExt::Unknown)
10062 {
10063 QCString ext = getFileNameExtension(pd->name());
10064 auto intf = Doxygen::parserManager->getCodeParser(ext);
10065 intf->resetCodeParserState();
10066 }
10067 QCString n=pd->getOutputFileBase();
10068 startFile(*g_outputList,n,false,n,pd->name());
10070 g_outputList->docify(pd->name());
10072 g_outputList->startContents();
10073 QCString lineNoOptStr;
10074 if (pd->showLineNo())
10075 {
10076 lineNoOptStr="{lineno}";
10077 }
10078 g_outputList->generateDoc(pd->docFile(), // file
10079 pd->docLine(), // startLine
10080 pd.get(), // context
10081 nullptr, // memberDef
10082 (pd->briefDescription().isEmpty()?"":pd->briefDescription()+"\n\n")+
10083 pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
10084 DocOptions()
10085 .setIndexWords(true)
10086 .setExample(pd->name()));
10087 endFile(*g_outputList); // contains g_outputList->endContents()
10088 }
10090}
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:5191
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5233

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

8755{
8756 if (Index::instance().numDocumentedFiles()==0) return;
8757
8758 if (!Doxygen::inputNameLinkedMap->empty())
8759 {
8760 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8761 if (numThreads>1) // multi threaded processing
8762 {
8763 struct DocContext
8764 {
8765 DocContext(FileDef *fd_,const OutputList &ol_)
8766 : fd(fd_), ol(ol_) {}
8767 FileDef *fd;
8768 OutputList ol;
8769 };
8770 ThreadPool threadPool(numThreads);
8771 std::vector< std::future< std::shared_ptr<DocContext> > > results;
8772 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8773 {
8774 for (const auto &fd : *fn)
8775 {
8776 bool doc = fd->isLinkableInProject();
8777 if (doc)
8778 {
8779 auto ctx = std::make_shared<DocContext>(fd.get(),*g_outputList);
8780 auto processFile = [ctx]() {
8781 msg("Generating docs for file {}...\n",ctx->fd->docName());
8782 ctx->fd->writeDocumentation(ctx->ol);
8783 return ctx;
8784 };
8785 results.emplace_back(threadPool.queue(processFile));
8786 }
8787 }
8788 }
8789 for (auto &f : results)
8790 {
8791 auto ctx = f.get();
8792 }
8793 }
8794 else // single threaded processing
8795 {
8796 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8797 {
8798 for (const auto &fd : *fn)
8799 {
8800 bool doc = fd->isLinkableInProject();
8801 if (doc)
8802 {
8803 msg("Generating docs for file {}...\n",fd->docName());
8804 fd->writeDocumentation(*g_outputList);
8805 }
8806 }
8807 }
8808 }
8809 }
8810}

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

Referenced by generateOutput().

◆ generateFileSources()

void generateFileSources ( )
static

Definition at line 8588 of file doxygen.cpp.

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

10096{
10097 for (const auto &gd : *Doxygen::groupLinkedMap)
10098 {
10099 if (!gd->isReference())
10100 {
10101 gd->writeDocumentation(*g_outputList);
10102 }
10103 }
10104}

References g_outputList, and Doxygen::groupLinkedMap.

Referenced by generateOutput().

◆ generateNamespaceClassDocs()

void generateNamespaceClassDocs ( const ClassLinkedRefMap & classList)
static

Definition at line 10109 of file doxygen.cpp.

10110{
10111 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10112 if (numThreads>1) // multi threaded processing
10113 {
10114 struct DocContext
10115 {
10116 DocContext(ClassDefMutable *cdm_,const OutputList &ol_)
10117 : cdm(cdm_), ol(ol_) {}
10118 ClassDefMutable *cdm;
10119 OutputList ol;
10120 };
10121 ThreadPool threadPool(numThreads);
10122 std::vector< std::future< std::shared_ptr<DocContext> > > results;
10123 // for each class in the namespace...
10124 for (const auto &cd : classList)
10125 {
10127 if (cdm)
10128 {
10129 auto ctx = std::make_shared<DocContext>(cdm,*g_outputList);
10130 auto processFile = [ctx]()
10131 {
10132 if ( ( ctx->cdm->isLinkableInProject() &&
10133 !ctx->cdm->isImplicitTemplateInstance()
10134 ) // skip external references, anonymous compounds and
10135 // template instances and nested classes
10136 && !ctx->cdm->isHidden() && !ctx->cdm->isEmbeddedInOuterScope()
10137 )
10138 {
10139 msg("Generating docs for compound {}...\n",ctx->cdm->displayName());
10140 ctx->cdm->writeDocumentation(ctx->ol);
10141 ctx->cdm->writeMemberList(ctx->ol);
10142 }
10143 ctx->cdm->writeDocumentationForInnerClasses(ctx->ol);
10144 return ctx;
10145 };
10146 results.emplace_back(threadPool.queue(processFile));
10147 }
10148 }
10149 // wait for the results
10150 for (auto &f : results)
10151 {
10152 auto ctx = f.get();
10153 }
10154 }
10155 else // single threaded processing
10156 {
10157 // for each class in the namespace...
10158 for (const auto &cd : classList)
10159 {
10161 if (cdm)
10162 {
10163 if ( ( cd->isLinkableInProject() &&
10164 !cd->isImplicitTemplateInstance()
10165 ) // skip external references, anonymous compounds and
10166 // template instances and nested classes
10167 && !cd->isHidden() && !cd->isEmbeddedInOuterScope()
10168 )
10169 {
10170 msg("Generating docs for compound {}...\n",cd->displayName());
10171
10174 }
10176 }
10177 }
10178 }
10179}
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 10181 of file doxygen.cpp.

10182{
10183 // for each concept in the namespace...
10184 for (const auto &cd : conceptList)
10185 {
10187 if ( cdm && cd->isLinkableInProject() && !cd->isHidden())
10188 {
10189 msg("Generating docs for concept {}...\n",cd->name());
10191 }
10192 }
10193}

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

Referenced by generateNamespaceDocs().

◆ generateNamespaceDocs()

void generateNamespaceDocs ( )
static

Definition at line 10195 of file doxygen.cpp.

10196{
10197 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
10198
10199 //writeNamespaceIndex(*g_outputList);
10200
10201 // for each namespace...
10202 for (const auto &nd : *Doxygen::namespaceLinkedMap)
10203 {
10204 if (nd->isLinkableInProject())
10205 {
10207 if (ndm)
10208 {
10209 msg("Generating docs for namespace {}\n",nd->displayName());
10211 }
10212 }
10213
10214 generateNamespaceClassDocs(nd->getClasses());
10215 if (sliceOpt)
10216 {
10217 generateNamespaceClassDocs(nd->getInterfaces());
10218 generateNamespaceClassDocs(nd->getStructs());
10219 generateNamespaceClassDocs(nd->getExceptions());
10220 }
10221 generateNamespaceConceptDocs(nd->getConcepts());
10222 }
10223}
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 13158 of file doxygen.cpp.

13159{
13160 AUTO_TRACE();
13161 /**************************************************************************
13162 * Initialize output generators *
13163 **************************************************************************/
13164
13165 /// add extra languages for which we can only produce syntax highlighted code
13167
13168 //// dump all symbols
13169 if (g_dumpSymbolMap)
13170 {
13171 dumpSymbolMap();
13172 exit(0);
13173 }
13174
13175 bool generateHtml = Config_getBool(GENERATE_HTML);
13176 bool generateLatex = Config_getBool(GENERATE_LATEX);
13177 bool generateMan = Config_getBool(GENERATE_MAN);
13178 bool generateRtf = Config_getBool(GENERATE_RTF);
13179 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
13180
13181
13183 if (generateHtml)
13184 {
13188 }
13189 if (generateLatex)
13190 {
13193 }
13194 if (generateDocbook)
13195 {
13198 }
13199 if (generateMan)
13200 {
13201 g_outputList->add<ManGenerator>();
13203 }
13204 if (generateRtf)
13205 {
13206 g_outputList->add<RTFGenerator>();
13208 }
13209 if (Config_getBool(USE_HTAGS))
13210 {
13212 QCString htmldir = Config_getString(HTML_OUTPUT);
13213 if (!Htags::execute(htmldir))
13214 err("USE_HTAGS is YES but htags(1) failed. \n");
13215 else if (!Htags::loadFilemap(htmldir))
13216 err("htags(1) ended normally but failed to load the filemap. \n");
13217 }
13218
13219 /**************************************************************************
13220 * Generate documentation *
13221 **************************************************************************/
13222
13223 g_s.begin("Generating style sheet...\n");
13224 //printf("writing style info\n");
13225 g_outputList->writeStyleInfo(0); // write first part
13226 g_s.end();
13227
13228 bool searchEngine = Config_getBool(SEARCHENGINE);
13229 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
13230
13231 g_s.begin("Generating search indices...\n");
13232 if (searchEngine && !serverBasedSearch && generateHtml)
13233 {
13235 }
13236
13237 // generate search indices (need to do this before writing other HTML
13238 // pages as these contain a drop down menu with options depending on
13239 // what categories we find in this function.
13240 if (generateHtml && searchEngine)
13241 {
13242 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
13243 Dir searchDir(searchDirName.str());
13244 if (!searchDir.exists() && !searchDir.mkdir(searchDirName.str()))
13245 {
13246 term("Could not create search results directory '{}' $PWD='{}'\n",
13247 searchDirName,Dir::currentDirPath());
13248 }
13249 HtmlGenerator::writeSearchData(searchDirName);
13250 if (!serverBasedSearch) // client side search index
13251 {
13253 }
13254 }
13255 g_s.end();
13256
13257 // copy static stuff
13258 if (generateHtml)
13259 {
13261 copyLogo(Config_getString(HTML_OUTPUT));
13262 copyIcon(Config_getString(HTML_OUTPUT));
13263 copyExtraFiles(Config_getList(HTML_EXTRA_FILES),"HTML_EXTRA_FILES",Config_getString(HTML_OUTPUT));
13264 }
13265 if (generateLatex)
13266 {
13268 copyLogo(Config_getString(LATEX_OUTPUT));
13269 copyIcon(Config_getString(LATEX_OUTPUT));
13270 copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT));
13271 }
13272 if (generateDocbook)
13273 {
13274 copyLogo(Config_getString(DOCBOOK_OUTPUT));
13275 copyIcon(Config_getString(DOCBOOK_OUTPUT));
13276 }
13277 if (generateRtf)
13278 {
13279 copyLogo(Config_getString(RTF_OUTPUT));
13280 copyIcon(Config_getString(RTF_OUTPUT));
13281 copyExtraFiles(Config_getList(RTF_EXTRA_FILES),"RTF_EXTRA_FILES",Config_getString(RTF_OUTPUT));
13282 }
13283
13285 if (fm.hasFormulas() && generateHtml
13286 && !Config_getBool(USE_MATHJAX))
13287 {
13288 g_s.begin("Generating images for formulas in HTML...\n");
13289 fm.generateImages(Config_getString(HTML_OUTPUT), Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg ?
13291 g_s.end();
13292 }
13293 if (fm.hasFormulas() && generateRtf)
13294 {
13295 g_s.begin("Generating images for formulas in RTF...\n");
13297 g_s.end();
13298 }
13299
13300 if (fm.hasFormulas() && generateDocbook)
13301 {
13302 g_s.begin("Generating images for formulas in Docbook...\n");
13304 g_s.end();
13305 }
13306
13307 g_s.begin("Generating example documentation...\n");
13309 g_s.end();
13310
13311 g_s.begin("Generating file sources...\n");
13313 g_s.end();
13314
13315 g_s.begin("Generating file documentation...\n");
13317 g_s.end();
13318
13319 g_s.begin("Generating page documentation...\n");
13321 g_s.end();
13322
13323 g_s.begin("Generating group documentation...\n");
13325 g_s.end();
13326
13327 g_s.begin("Generating class documentation...\n");
13329 g_s.end();
13330
13331 g_s.begin("Generating concept documentation...\n");
13333 g_s.end();
13334
13335 g_s.begin("Generating module documentation...\n");
13337 g_s.end();
13338
13339 g_s.begin("Generating namespace documentation...\n");
13341 g_s.end();
13342
13343 if (Config_getBool(GENERATE_LEGEND))
13344 {
13345 g_s.begin("Generating graph info page...\n");
13347 g_s.end();
13348 }
13349
13350 g_s.begin("Generating directory documentation...\n");
13352 g_s.end();
13353
13354 if (g_outputList->size()>0)
13355 {
13357 }
13358
13359 g_s.begin("finalizing index lists...\n");
13360 Doxygen::indexList->finalize();
13361 g_s.end();
13362
13363 g_s.begin("writing tag file...\n");
13364 writeTagFile();
13365 g_s.end();
13366
13367 if (Config_getBool(GENERATE_XML))
13368 {
13369 g_s.begin("Generating XML output...\n");
13371 generateXML();
13373 g_s.end();
13374 }
13375 if (Config_getBool(GENERATE_SQLITE3))
13376 {
13377 g_s.begin("Generating SQLITE3 output...\n");
13379 g_s.end();
13380 }
13381
13382 if (Config_getBool(GENERATE_AUTOGEN_DEF))
13383 {
13384 g_s.begin("Generating AutoGen DEF output...\n");
13385 generateDEF();
13386 g_s.end();
13387 }
13388 if (Config_getBool(GENERATE_PERLMOD))
13389 {
13390 g_s.begin("Generating Perl module output...\n");
13392 g_s.end();
13393 }
13394 if (generateHtml && searchEngine && serverBasedSearch)
13395 {
13396 g_s.begin("Generating search index\n");
13397 if (Doxygen::searchIndex.kind()==SearchIndexIntf::Internal) // write own search index
13398 {
13400 Doxygen::searchIndex.write(Config_getString(HTML_OUTPUT)+"/search/search.idx");
13401 }
13402 else // write data for external search index
13403 {
13405 QCString searchDataFile = Config_getString(SEARCHDATA_FILE);
13406 if (searchDataFile.isEmpty())
13407 {
13408 searchDataFile="searchdata.xml";
13409 }
13410 if (!Portable::isAbsolutePath(searchDataFile.data()))
13411 {
13412 searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/");
13413 }
13414 Doxygen::searchIndex.write(searchDataFile);
13415 }
13416 g_s.end();
13417 }
13418
13419 if (generateRtf)
13420 {
13421 g_s.begin("Combining RTF output...\n");
13422 if (!RTFGenerator::preProcessFileInplace(Config_getString(RTF_OUTPUT),"refman.rtf"))
13423 {
13424 err("An error occurred during post-processing the RTF files!\n");
13425 }
13426 g_s.end();
13427 }
13428
13429 g_s.begin("Running plantuml with JAVA...\n");
13431 g_s.end();
13432
13433 if (Config_getBool(HAVE_DOT))
13434 {
13435 g_s.begin("Running dot...\n");
13437 g_s.end();
13438 }
13439
13440 if (generateHtml &&
13441 Config_getBool(GENERATE_HTMLHELP) &&
13442 !Config_getString(HHC_LOCATION).isEmpty())
13443 {
13444 g_s.begin("Running html help compiler...\n");
13446 g_s.end();
13447 }
13448
13449 if ( generateHtml &&
13450 Config_getBool(GENERATE_QHP) &&
13451 !Config_getString(QHG_LOCATION).isEmpty())
13452 {
13453 g_s.begin("Running qhelpgenerator...\n");
13455 g_s.end();
13456 }
13457
13458 g_outputList->cleanup();
13460
13461 msg("type lookup cache used {}/{} hits={} misses={}\n",
13463 Doxygen::typeLookupCache->capacity(),
13465 Doxygen::typeLookupCache->misses());
13466 msg("symbol lookup cache used {}/{} hits={} misses={}\n",
13468 Doxygen::symbolLookupCache->capacity(),
13470 Doxygen::symbolLookupCache->misses());
13471 int typeCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::typeLookupCache->misses()*2/3)); // part of the cache is flushed, hence the 2/3 correction factor
13472 int symbolCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::symbolLookupCache->misses()));
13473 int cacheParam = std::max(typeCacheParam,symbolCacheParam);
13474 if (cacheParam>Config_getInt(LOOKUP_CACHE_SIZE))
13475 {
13476 msg("Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is {} at the cost of higher memory usage.\n",cacheParam);
13477 }
13478
13480 {
13481
13482 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
13483 if (numThreads<1) numThreads=1;
13484 msg("Total elapsed time: {:.6f} seconds\n(of which an average of {:.6f} seconds per thread waiting for external tools to finish)\n",
13485 (static_cast<double>(Debug::elapsedTime())),
13486 Portable::getSysElapsedTime()/static_cast<double>(numThreads)
13487 );
13488 g_s.print();
13489
13491 msg("finished...\n");
13493 }
13494 else
13495 {
13496 msg("finished...\n");
13497 }
13498
13499
13500 /**************************************************************************
13501 * Start cleaning up *
13502 **************************************************************************/
13503
13505
13507 Dir thisDir;
13508 thisDir.remove(Doxygen::filterDBFileName.str());
13510 exitTracing();
13512 delete Doxygen::clangUsrMap;
13514
13515 //dumpDocNodeSizes();
13516}
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:1210
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:8754
static void copyIcon(const QCString &outputOption)
static void generatePageDocs()
Definition doxygen.cpp:9969
static void generateFileSources()
Definition doxygen.cpp:8588
static void copyLogo(const QCString &outputOption)
static void generateClassDocs()
Definition doxygen.cpp:9189
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:192
static void generateNamespaceDocs()
static void writeTagFile()
void cleanUpDoxygen()
static void generateConceptDocs()
Definition doxygen.cpp:9215
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:5185
void cleanupInlineGraph()
Definition util.cpp:6990
void generateXML()
Definition xmlgen.cpp:2270

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

9970{
9971 //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageLinkedMap->count());
9972 if (Index::instance().numDocumentedPages()==0) return;
9973 for (const auto &pd : *Doxygen::pageLinkedMap)
9974 {
9975 if (!pd->getGroupDef() && !pd->isReference())
9976 {
9977 msg("Generating docs for page {}...\n",pd->name());
9978 pd->writeDocumentation(*g_outputList);
9979 }
9980 }
9981}

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

Referenced by generateOutput().

◆ generateXRefPages()

void generateXRefPages ( )
static

Definition at line 5571 of file doxygen.cpp.

5572{
5573 AUTO_TRACE();
5575 {
5576 rl->generatePage();
5577 }
5578}
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 11397 of file doxygen.cpp.

11398{
11399 char *s=nullptr;
11400 if (qstrlen(&argv[optInd][2])>0)
11401 s=&argv[optInd][2];
11402 else if (optInd+1<argc && argv[optInd+1][0]!='-')
11403 s=argv[++optInd];
11404 return s;
11405}
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 10678 of file doxygen.cpp.

10679{
10680 QCString fileName=fn;
10681 QCString extension;
10682 int sep = fileName.findRev('/');
10683 int ei = fileName.findRev('.');
10684 if (ei!=-1 && (sep==-1 || ei>sep)) // matches dir/file.ext but not dir.1/file
10685 {
10686 extension=fileName.right(fileName.length()-ei);
10687 }
10688 else
10689 {
10690 extension = ".no_extension";
10691 }
10692
10693 return Doxygen::parserManager->getOutlineParser(extension);
10694}

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

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

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

4506{
4507 std::map<std::string,int> templateNames;
4508 int count=0;
4509 for (const Argument &arg : templateArguments)
4510 {
4511 static const reg::Ex re(R"(\a[\w:]*)");
4512 reg::Iterator it(name,re);
4514 for (; it!=end ; ++it)
4515 {
4516 const auto &match = *it;
4517 std::string n = match.str();
4518 if (n==arg.name.str())
4519 {
4520 if (templateNames.find(n)==templateNames.end())
4521 {
4522 templateNames.emplace(n,count);
4523 }
4524 }
4525 }
4526 }
4527 return templateNames;
4528}

References end().

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

◆ haveEqualFileNames()

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

Definition at line 9544 of file doxygen.cpp.

9545{
9546 if (const FileDef *fd = md->getFileDef())
9547 {
9548 return fd->absFilePath() == root->fileName;
9549 }
9550 return false;
9551}

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

Referenced by findDefineDocumentation().

◆ inheritDocumentation()

void inheritDocumentation ( )
static

Definition at line 9236 of file doxygen.cpp.

9237{
9238 for (const auto &mn : *Doxygen::memberNameLinkedMap)
9239 {
9240 for (const auto &imd : *mn)
9241 {
9242 MemberDefMutable *md = toMemberDefMutable(imd.get());
9243 //static int count=0;
9244 //printf("%04d Member '%s'\n",count++,qPrint(md->qualifiedName()));
9245 if (md && md->documentation().isEmpty() && md->briefDescription().isEmpty())
9246 { // no documentation yet
9247 const MemberDef *bmd = md->reimplements();
9248 while (bmd && bmd->documentation().isEmpty() &&
9249 bmd->briefDescription().isEmpty()
9250 )
9251 { // search up the inheritance tree for a documentation member
9252 //printf("bmd=%s class=%s\n",qPrint(bmd->name()),qPrint(bmd->getClassDef()->name()));
9253 bmd = bmd->reimplements();
9254 }
9255 if (bmd) // copy the documentation from the reimplemented member
9256 {
9257 md->setInheritsDocsFrom(bmd);
9258 md->setDocumentation(bmd->documentation(),bmd->docFile(),bmd->docLine());
9260 md->setBriefDescription(bmd->briefDescription(),bmd->briefFile(),bmd->briefLine());
9261 md->copyArgumentNames(bmd);
9263 }
9264 }
9265 }
9266 }
9267}
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 11424 of file doxygen.cpp.

11425{
11426 initResources();
11427 QCString lang = Portable::getenv("LC_ALL");
11428 if (!lang.isEmpty()) Portable::setenv("LANG",lang);
11429 std::setlocale(LC_ALL,"");
11430 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
11431 std::setlocale(LC_NUMERIC,"C");
11432
11434
11458
11459 // register any additional parsers here...
11460
11462
11463#if USE_LIBCLANG
11465#endif
11474 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
11475 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
11476 //Doxygen::tagDestinationDict.setAutoDelete(TRUE);
11478
11479 // initialization of these globals depends on
11480 // configuration switches so we need to postpone these
11481 Doxygen::globalScope = nullptr;
11490
11491}
static void startTimer()
Definition debug.cpp:195
A linked map of directories.
Definition dirdef.h:175
A list of index interfaces.
Definition indexlist.h:64
Manages programming language parsers.
Definition parserintf.h:183
std::function< std::unique_ptr< T >() > make_parser_factory()
void initResources()
std::unordered_map< std::string, const Definition * > ClangUsrMap
Definition doxygen.h:82
void setenv(const QCString &variable, const QCString &value)
Definition portable.cpp:287
QCString getenv(const QCString &variable)
Definition portable.cpp:322
void initDefaultExtensionMapping()
Definition util.cpp:5118

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

6682{
6683 if (outerScope && outerScope!=Doxygen::globalScope)
6684 {
6685 auto aliasMd = createMemberDefAlias(outerScope,md);
6686 if (outerScope->definitionType()==Definition::TypeClass)
6687 {
6688 ClassDefMutable *cdm = toClassDefMutable(outerScope);
6689 if (cdm)
6690 {
6691 cdm->insertMember(aliasMd.get());
6692 }
6693 }
6694 else if (outerScope->definitionType()==Definition::TypeNamespace)
6695 {
6696 NamespaceDefMutable *ndm = toNamespaceDefMutable(outerScope);
6697 if (ndm)
6698 {
6699 ndm->insertMember(aliasMd.get());
6700 }
6701 }
6702 else if (outerScope->definitionType()==Definition::TypeFile)
6703 {
6704 toFileDef(outerScope)->insertMember(aliasMd.get());
6705 }
6706 if (aliasMd)
6707 {
6708 Doxygen::functionNameLinkedMap->add(md->name())->push_back(std::move(aliasMd));
6709 }
6710 }
6711}
FileDef * toFileDef(Definition *d)
Definition filedef.cpp:1967

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

5240{
5241 if ( !root->name.isEmpty() )
5242 {
5243 if (root->section.isCompound())
5244 // is it a compound (class, struct, union, interface ...)
5245 {
5246 return TRUE;
5247 }
5248 else if (root->section.isCompoundDoc())
5249 // is it a documentation block with inheritance info.
5250 {
5251 bool hasExtends = !root->extends.empty();
5252 if (hasExtends) return TRUE;
5253 }
5254 }
5255 return FALSE;
5256}

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

5752{
5753 const GroupDef *gd = md->getGroupDef();
5754 if (!gd)
5755 {
5756 return allowNoGroup;
5757 }
5758
5759 for (const auto &g : root->groups)
5760 {
5761 if (g.groupname == gd->name())
5762 {
5763 return true; // matching group
5764 }
5765 }
5766
5767 return false;
5768}

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

4857{
4858 QCString n=name;
4859 int index=n.find('<');
4860 if (index!=-1)
4861 {
4862 n=n.left(index);
4863 }
4864 bool result = rightScopeMatch(scope,n);
4865 return result;
4866}

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

Referenced by findClassRelation().

◆ isSpecialization()

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

Definition at line 5982 of file doxygen.cpp.

5986{
5987 auto srcIt = srcTempArgLists.begin();
5988 auto dstIt = dstTempArgLists.begin();
5989 while (srcIt!=srcTempArgLists.end() && dstIt!=dstTempArgLists.end())
5990 {
5991 if ((*srcIt).size()!=(*dstIt).size()) return TRUE;
5992 ++srcIt;
5993 ++dstIt;
5994 }
5995 return FALSE;
5996}

References FALSE, and TRUE.

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

◆ isSymbolHidden()

bool isSymbolHidden ( const Definition * d)
static

Definition at line 8983 of file doxygen.cpp.

8984{
8985 bool hidden = d->isHidden();
8986 const Definition *parent = d->getOuterScope();
8987 return parent ? hidden || isSymbolHidden(parent) : hidden;
8988}
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:1328

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

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

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

11420{
11421 return []() { return std::make_unique<T>(); };
11422}

Referenced by initDoxygen().

◆ makeTemplateInstanceRelation()

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

Definition at line 5313 of file doxygen.cpp.

5314{
5315 AUTO_TRACE("root->name={} cd={}",root->name,cd->name());
5316 int i = root->name.find('<');
5317 int j = root->name.findRev('>');
5318 int k = root->name.find("::",j+1); // A<T::B> => ok, A<T>::B => nok
5319 if (i!=-1 && j!=-1 && k==-1 && root->lang!=SrcLangExt::CSharp && root->lang!=SrcLangExt::Java)
5320 {
5321 ClassDefMutable *master = getClassMutable(root->name.left(i));
5322 if (master && master!=cd && !cd->templateMaster())
5323 {
5324 AUTO_TRACE_ADD("class={} master={}",cd->name(),cd->templateMaster()?cd->templateMaster()->name():"<none>",master->name());
5325 cd->setTemplateMaster(master);
5326 master->insertExplicitTemplateInstance(cd,root->name.mid(i));
5327 }
5328 }
5329}
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 8536 of file doxygen.cpp.

8537{
8538 AUTO_TRACE();
8539 // merge members of categories into the class they extend
8540 for (const auto &cd : *Doxygen::classLinkedMap)
8541 {
8542 int i=cd->name().find('(');
8543 if (i!=-1) // it is an Objective-C category
8544 {
8545 QCString baseName=cd->name().left(i);
8546 ClassDefMutable *baseClass=toClassDefMutable(Doxygen::classLinkedMap->find(baseName));
8547 if (baseClass)
8548 {
8549 AUTO_TRACE_ADD("merging members of category {} into {}",cd->name(),baseClass->name());
8550 baseClass->mergeCategory(cd.get());
8551 }
8552 }
8553 }
8554}
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 490 of file doxygen.cpp.

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

References FALSE, organizeSubGroupsFiltered(), and TRUE.

Referenced by parseInput().

◆ organizeSubGroupsFiltered()

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

Definition at line 471 of file doxygen.cpp.

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

10699{
10700 QCString fileName=fn;
10701 AUTO_TRACE("fileName={}",fileName);
10702 QCString extension;
10703 int ei = fileName.findRev('.');
10704 if (ei!=-1)
10705 {
10706 extension=fileName.right(fileName.length()-ei);
10707 }
10708 else
10709 {
10710 extension = ".no_extension";
10711 }
10712
10713 FileInfo fi(fileName.str());
10714 std::string preBuf;
10715
10716 if (Config_getBool(ENABLE_PREPROCESSING) &&
10717 parser.needsPreprocessing(extension))
10718 {
10719 Preprocessor preprocessor;
10720 const StringVector &includePath = Config_getList(INCLUDE_PATH);
10721 for (const auto &s : includePath)
10722 {
10723 std::string absPath = FileInfo(s).absFilePath();
10724 preprocessor.addSearchDir(absPath);
10725 }
10726 std::string inBuf;
10727 msg("Preprocessing {}...\n",fn);
10728 readInputFile(fileName,inBuf);
10729 addTerminalCharIfMissing(inBuf,'\n');
10730 preprocessor.processFile(fileName,inBuf,preBuf);
10731 }
10732 else // no preprocessing
10733 {
10734 msg("Reading {}...\n",fn);
10735 readInputFile(fileName,preBuf);
10736 addTerminalCharIfMissing(preBuf,'\n');
10737 }
10738
10739 std::string convBuf;
10740 convBuf.reserve(preBuf.size()+1024);
10741
10742 // convert multi-line C++ comments to C style comments
10743 convertCppComments(preBuf,convBuf,fileName.str());
10744
10745 std::shared_ptr<Entry> fileRoot = std::make_shared<Entry>();
10746 // use language parse to parse the file
10747 if (clangParser)
10748 {
10749 if (newTU) clangParser->parse();
10750 clangParser->switchToFile(fd);
10751 }
10752 parser.parseInput(fileName,convBuf.data(),fileRoot,clangParser);
10753 fileRoot->setFileDef(fd);
10754 return fileRoot;
10755}
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:5530

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

10759{
10760 AUTO_TRACE();
10761#if USE_LIBCLANG
10763 {
10764 StringUnorderedSet processedFiles;
10765
10766 // create a dictionary with files to process
10767 StringUnorderedSet filesToProcess;
10768 for (const auto &s : g_inputFiles)
10769 {
10770 filesToProcess.insert(s);
10771 }
10772
10773 std::mutex processedFilesLock;
10774 // process source files (and their include dependencies)
10775 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10776 msg("Processing input using {} threads.\n",numThreads);
10777 ThreadPool threadPool(numThreads);
10778 using FutureType = std::vector< std::shared_ptr<Entry> >;
10779 std::vector< std::future< FutureType > > results;
10780 for (const auto &s : g_inputFiles)
10781 {
10782 bool ambig = false;
10783 QCString qs = s;
10785 ASSERT(fd!=nullptr);
10786 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp) // this is a source file
10787 {
10788 // lambda representing the work to executed by a thread
10789 auto processFile = [qs,&filesToProcess,&processedFilesLock,&processedFiles]() {
10790 bool ambig_l = false;
10791 std::vector< std::shared_ptr<Entry> > roots;
10793 auto clangParser = ClangParser::instance()->createTUParser(fd_l);
10794 auto parser = getParserForFile(qs);
10795 auto fileRoot { parseFile(*parser.get(),fd_l,qs,clangParser.get(),true) };
10796 roots.push_back(fileRoot);
10797
10798 // Now process any include files in the same translation unit
10799 // first. When libclang is used this is much more efficient.
10800 for (auto incFile : clangParser->filesInSameTU())
10801 {
10802 QCString qincFile = incFile;
10803 if (filesToProcess.find(incFile)!=filesToProcess.end())
10804 {
10805 bool needsToBeProcessed = false;
10806 {
10807 std::lock_guard<std::mutex> lock(processedFilesLock);
10808 needsToBeProcessed = processedFiles.find(incFile)==processedFiles.end();
10809 if (needsToBeProcessed) processedFiles.insert(incFile);
10810 }
10811 if (qincFile!=qs && needsToBeProcessed)
10812 {
10813 FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,qincFile,ambig_l);
10814 if (ifd && !ifd->isReference())
10815 {
10816 //printf(" Processing %s in same translation unit as %s\n",incFile,qPrint(s));
10817 fileRoot = parseFile(*parser.get(),ifd,qincFile,clangParser.get(),false);
10818 roots.push_back(fileRoot);
10819 }
10820 }
10821 }
10822 }
10823 return roots;
10824 };
10825 // dispatch the work and collect the future results
10826 results.emplace_back(threadPool.queue(processFile));
10827 }
10828 }
10829 // synchronize with the Entry result lists produced and add them to the root
10830 for (auto &f : results)
10831 {
10832 auto l = f.get();
10833 for (auto &e : l)
10834 {
10835 root->moveToSubEntryAndKeep(e);
10836 }
10837 }
10838 // process remaining files
10839 results.clear();
10840 for (const auto &s : g_inputFiles)
10841 {
10842 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
10843 {
10844 // lambda representing the work to executed by a thread
10845 auto processFile = [s]() {
10846 bool ambig = false;
10847 QCString qs = s;
10848 std::vector< std::shared_ptr<Entry> > roots;
10850 auto parser { getParserForFile(qs) };
10851 bool useClang = getLanguageFromFileName(qs)==SrcLangExt::Cpp;
10852 if (useClang)
10853 {
10854 auto clangParser = ClangParser::instance()->createTUParser(fd);
10855 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10856 roots.push_back(fileRoot);
10857 }
10858 else
10859 {
10860 auto fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10861 roots.push_back(fileRoot);
10862 }
10863 return roots;
10864 };
10865 results.emplace_back(threadPool.queue(processFile));
10866 }
10867 }
10868 // synchronize with the Entry result lists produced and add them to the root
10869 for (auto &f : results)
10870 {
10871 auto l = f.get();
10872 for (auto &e : l)
10873 {
10874 root->moveToSubEntryAndKeep(e);
10875 }
10876 }
10877 }
10878 else // normal processing
10879#endif
10880 {
10881 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10882 msg("Processing input using {} threads.\n",numThreads);
10883 ThreadPool threadPool(numThreads);
10884 using FutureType = std::shared_ptr<Entry>;
10885 std::vector< std::future< FutureType > > results;
10886 for (const auto &s : g_inputFiles)
10887 {
10888 // lambda representing the work to executed by a thread
10889 auto processFile = [s]() {
10890 bool ambig = false;
10891 QCString qs = s;
10893 auto parser = getParserForFile(qs);
10894 auto fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10895 return fileRoot;
10896 };
10897 // dispatch the work and collect the future results
10898 results.emplace_back(threadPool.queue(processFile));
10899 }
10900 // synchronize with the Entry results produced and add them to the root
10901 for (auto &f : results)
10902 {
10903 root->moveToSubEntryAndKeep(f.get());
10904 }
10905 }
10906}
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 10909 of file doxygen.cpp.

10910{
10911 AUTO_TRACE();
10912#if USE_LIBCLANG
10914 {
10915 StringUnorderedSet processedFiles;
10916
10917 // create a dictionary with files to process
10918 StringUnorderedSet filesToProcess;
10919 for (const auto &s : g_inputFiles)
10920 {
10921 filesToProcess.insert(s);
10922 }
10923
10924 // process source files (and their include dependencies)
10925 for (const auto &s : g_inputFiles)
10926 {
10927 bool ambig = false;
10928 QCString qs =s;
10930 ASSERT(fd!=nullptr);
10931 if (fd->isSource() && !fd->isReference() && getLanguageFromFileName(qs)==SrcLangExt::Cpp) // this is a source file
10932 {
10933 auto clangParser = ClangParser::instance()->createTUParser(fd);
10934 auto parser { getParserForFile(qs) };
10935 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10936 root->moveToSubEntryAndKeep(fileRoot);
10937 processedFiles.insert(s);
10938
10939 // Now process any include files in the same translation unit
10940 // first. When libclang is used this is much more efficient.
10941 for (auto incFile : clangParser->filesInSameTU())
10942 {
10943 //printf(" file %s\n",qPrint(incFile));
10944 if (filesToProcess.find(incFile)!=filesToProcess.end() && // file need to be processed
10945 processedFiles.find(incFile)==processedFiles.end()) // and is not processed already
10946 {
10948 if (ifd && !ifd->isReference())
10949 {
10950 //printf(" Processing %s in same translation unit as %s\n",qPrint(incFile),qPrint(qs));
10951 fileRoot = parseFile(*parser.get(),ifd,incFile,clangParser.get(),false);
10952 root->moveToSubEntryAndKeep(fileRoot);
10953 processedFiles.insert(incFile);
10954 }
10955 }
10956 }
10957 }
10958 }
10959 // process remaining files
10960 for (const auto &s : g_inputFiles)
10961 {
10962 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
10963 {
10964 bool ambig = false;
10965 QCString qs = s;
10967 if (getLanguageFromFileName(qs)==SrcLangExt::Cpp) // not yet processed
10968 {
10969 auto clangParser = ClangParser::instance()->createTUParser(fd);
10970 auto parser { getParserForFile(qs) };
10971 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10972 root->moveToSubEntryAndKeep(fileRoot);
10973 }
10974 else
10975 {
10976 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
10977 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10978 root->moveToSubEntryAndKeep(fileRoot);
10979 }
10980 processedFiles.insert(s);
10981 }
10982 }
10983 }
10984 else // normal processing
10985#endif
10986 {
10987 for (const auto &s : g_inputFiles)
10988 {
10989 bool ambig = false;
10990 QCString qs = s;
10992 ASSERT(fd!=nullptr);
10993 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
10994 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
10995 root->moveToSubEntryAndKeep(std::move(fileRoot));
10996 }
10997 }
10998}

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

12475{
12476 AUTO_TRACE();
12477 std::atexit(exitDoxygen);
12478
12479 Portable::correctPath(Config_getList(EXTERNAL_TOOL_PATH));
12480
12481#if USE_LIBCLANG
12482 Doxygen::clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
12483#endif
12484
12485 // we would like to show the versionString earlier, but we first have to handle the configuration file
12486 // to know the value of the QUIET setting.
12487 QCString versionString = getFullVersion();
12488 msg("Doxygen version used: {}\n",versionString);
12489
12491
12492 /**************************************************************************
12493 * Make sure the output directory exists
12494 **************************************************************************/
12495 QCString outputDirectory = Config_getString(OUTPUT_DIRECTORY);
12496 if (!g_singleComment)
12497 {
12498 if (outputDirectory.isEmpty())
12499 {
12500 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,Dir::currentDirPath());
12501 }
12502 else
12503 {
12504 Dir dir(outputDirectory.str());
12505 if (!dir.exists())
12506 {
12507 dir.setPath(Dir::currentDirPath());
12508 if (!dir.mkdir(outputDirectory.str()))
12509 {
12510 term("tag OUTPUT_DIRECTORY: Output directory '{}' does not "
12511 "exist and cannot be created\n",outputDirectory);
12512 }
12513 else
12514 {
12515 msg("Notice: Output directory '{}' does not exist. "
12516 "I have created it for you.\n", outputDirectory);
12517 }
12518 dir.setPath(outputDirectory.str());
12519 }
12520 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,dir.absPath());
12521 }
12522 }
12523 AUTO_TRACE_ADD("outputDirectory={}",outputDirectory);
12524
12525 /**************************************************************************
12526 * Initialize global lists and dictionaries
12527 **************************************************************************/
12528
12529 // also scale lookup cache with SYMBOL_CACHE_SIZE
12530 int cacheSize = Config_getInt(LOOKUP_CACHE_SIZE);
12531 if (cacheSize<0) cacheSize=0;
12532 if (cacheSize>9) cacheSize=9;
12533 uint32_t lookupSize = 65536 << cacheSize;
12536
12537#ifdef HAS_SIGNALS
12538 signal(SIGINT, stopDoxygen);
12539#endif
12540
12541 uint32_t pid = Portable::pid();
12542 Doxygen::filterDBFileName.sprintf("doxygen_filterdb_%d.tmp",pid);
12543 Doxygen::filterDBFileName.prepend(outputDirectory+"/");
12544
12545 /**************************************************************************
12546 * Check/create output directories *
12547 **************************************************************************/
12548
12549 bool generateHtml = Config_getBool(GENERATE_HTML);
12550 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
12551 bool generateXml = Config_getBool(GENERATE_XML);
12552 bool generateLatex = Config_getBool(GENERATE_LATEX);
12553 bool generateRtf = Config_getBool(GENERATE_RTF);
12554 bool generateMan = Config_getBool(GENERATE_MAN);
12555 bool generateSql = Config_getBool(GENERATE_SQLITE3);
12556 QCString htmlOutput;
12557 QCString docbookOutput;
12558 QCString xmlOutput;
12559 QCString latexOutput;
12560 QCString rtfOutput;
12561 QCString manOutput;
12562 QCString sqlOutput;
12563
12564 if (!g_singleComment)
12565 {
12566 if (generateHtml)
12567 {
12568 htmlOutput = createOutputDirectory(outputDirectory,Config_getString(HTML_OUTPUT),"/html");
12569 Config_updateString(HTML_OUTPUT,htmlOutput);
12570
12571 QCString sitemapUrl = Config_getString(SITEMAP_URL);
12572 bool generateSitemap = !sitemapUrl.isEmpty();
12573 if (generateSitemap && !sitemapUrl.endsWith("/"))
12574 {
12575 Config_updateString(SITEMAP_URL,sitemapUrl+"/");
12576 }
12577
12578 // add HTML indexers that are enabled
12579 bool generateHtmlHelp = Config_getBool(GENERATE_HTMLHELP);
12580 bool generateEclipseHelp = Config_getBool(GENERATE_ECLIPSEHELP);
12581 bool generateQhp = Config_getBool(GENERATE_QHP);
12582 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
12583 bool generateDocSet = Config_getBool(GENERATE_DOCSET);
12584 if (generateEclipseHelp) Doxygen::indexList->addIndex<EclipseHelp>();
12585 if (generateHtmlHelp) Doxygen::indexList->addIndex<HtmlHelp>();
12586 if (generateQhp) Doxygen::indexList->addIndex<Qhp>();
12587 if (generateSitemap) Doxygen::indexList->addIndex<Sitemap>();
12588 if (generateTreeView) Doxygen::indexList->addIndex<FTVHelp>(TRUE);
12589 if (generateDocSet) Doxygen::indexList->addIndex<DocSets>();
12590 Doxygen::indexList->addIndex<Crawlmap>();
12591 Doxygen::indexList->initialize();
12592 }
12593
12594 if (generateDocbook)
12595 {
12596 docbookOutput = createOutputDirectory(outputDirectory,Config_getString(DOCBOOK_OUTPUT),"/docbook");
12597 Config_updateString(DOCBOOK_OUTPUT,docbookOutput);
12598 }
12599
12600 if (generateXml)
12601 {
12602 xmlOutput = createOutputDirectory(outputDirectory,Config_getString(XML_OUTPUT),"/xml");
12603 Config_updateString(XML_OUTPUT,xmlOutput);
12604 }
12605
12606 if (generateLatex)
12607 {
12608 latexOutput = createOutputDirectory(outputDirectory,Config_getString(LATEX_OUTPUT), "/latex");
12609 Config_updateString(LATEX_OUTPUT,latexOutput);
12610 }
12611
12612 if (generateRtf)
12613 {
12614 rtfOutput = createOutputDirectory(outputDirectory,Config_getString(RTF_OUTPUT),"/rtf");
12615 Config_updateString(RTF_OUTPUT,rtfOutput);
12616 }
12617
12618 if (generateMan)
12619 {
12620 manOutput = createOutputDirectory(outputDirectory,Config_getString(MAN_OUTPUT),"/man");
12621 Config_updateString(MAN_OUTPUT,manOutput);
12622 }
12623
12624 if (generateSql)
12625 {
12626 sqlOutput = createOutputDirectory(outputDirectory,Config_getString(SQLITE3_OUTPUT),"/sqlite3");
12627 Config_updateString(SQLITE3_OUTPUT,sqlOutput);
12628 }
12629 }
12630
12631 if (Config_getBool(HAVE_DOT))
12632 {
12633 QCString curFontPath = Config_getString(DOT_FONTPATH);
12634 if (curFontPath.isEmpty())
12635 {
12636 Portable::getenv("DOTFONTPATH");
12637 QCString newFontPath = ".";
12638 if (!curFontPath.isEmpty())
12639 {
12640 newFontPath+=Portable::pathListSeparator();
12641 newFontPath+=curFontPath;
12642 }
12643 Portable::setenv("DOTFONTPATH",qPrint(newFontPath));
12644 }
12645 else
12646 {
12647 Portable::setenv("DOTFONTPATH",qPrint(curFontPath));
12648 }
12649 }
12650
12651 /**************************************************************************
12652 * Handle layout file *
12653 **************************************************************************/
12654
12656 QCString layoutFileName = Config_getString(LAYOUT_FILE);
12657 bool defaultLayoutUsed = FALSE;
12658 if (layoutFileName.isEmpty())
12659 {
12660 layoutFileName = Config_updateString(LAYOUT_FILE,"DoxygenLayout.xml");
12661 defaultLayoutUsed = TRUE;
12662 }
12663 AUTO_TRACE_ADD("defaultLayoutUsed={}, layoutFileName={}",defaultLayoutUsed,layoutFileName);
12664
12665 FileInfo fi(layoutFileName.str());
12666 if (fi.exists())
12667 {
12668 msg("Parsing layout file {}...\n",layoutFileName);
12669 LayoutDocManager::instance().parse(layoutFileName);
12670 }
12671 else if (!defaultLayoutUsed)
12672 {
12673 warn_uncond("failed to open layout file '{}' for reading! Using default settings.\n",layoutFileName);
12674 }
12675 printLayout();
12676
12677 /**************************************************************************
12678 * Read and preprocess input *
12679 **************************************************************************/
12680
12681 // prevent search in the output directories
12682 StringVector exclPatterns = Config_getList(EXCLUDE_PATTERNS);
12683 if (generateHtml) exclPatterns.push_back(htmlOutput.str());
12684 if (generateDocbook) exclPatterns.push_back(docbookOutput.str());
12685 if (generateXml) exclPatterns.push_back(xmlOutput.str());
12686 if (generateLatex) exclPatterns.push_back(latexOutput.str());
12687 if (generateRtf) exclPatterns.push_back(rtfOutput.str());
12688 if (generateMan) exclPatterns.push_back(manOutput.str());
12689 Config_updateList(EXCLUDE_PATTERNS,exclPatterns);
12690
12691 if (!g_singleComment)
12692 {
12694
12696 }
12697
12698 // Notice: the order of the function calls below is very important!
12699
12700 if (generateHtml && !Config_getBool(USE_MATHJAX))
12701 {
12703 }
12704 if (generateRtf)
12705 {
12707 }
12708 if (generateDocbook)
12709 {
12711 }
12712
12714
12715 /**************************************************************************
12716 * Handle Tag Files *
12717 **************************************************************************/
12718
12719 std::shared_ptr<Entry> root = std::make_shared<Entry>();
12720
12721 if (!g_singleComment)
12722 {
12723 msg("Reading and parsing tag files\n");
12724 const StringVector &tagFileList = Config_getList(TAGFILES);
12725 for (const auto &s : tagFileList)
12726 {
12727 readTagFile(root,s.c_str());
12728 }
12729 }
12730
12731 /**************************************************************************
12732 * Parse source files *
12733 **************************************************************************/
12734
12735 addSTLSupport(root);
12736
12737 g_s.begin("Parsing files\n");
12738 if (g_singleComment)
12739 {
12740 //printf("Parsing comment %s\n",qPrint(g_commentFileName));
12741 if (g_commentFileName=="-")
12742 {
12743 std::string text = fileToString(g_commentFileName).str();
12744 addTerminalCharIfMissing(text,'\n');
12745 generateHtmlForComment("stdin.md",text);
12746 }
12747 else if (FileInfo(g_commentFileName.str()).isFile())
12748 {
12749 std::string text;
12751 addTerminalCharIfMissing(text,'\n');
12753 }
12754 else
12755 {
12756 }
12758 exit(0);
12759 }
12760 else
12761 {
12762 if (Config_getInt(NUM_PROC_THREADS)==1)
12763 {
12765 }
12766 else
12767 {
12769 }
12770 }
12771 g_s.end();
12772
12773 /**************************************************************************
12774 * Gather information *
12775 **************************************************************************/
12776
12777 g_s.begin("Building macro definition list...\n");
12779 g_s.end();
12780
12781 g_s.begin("Building group list...\n");
12782 buildGroupList(root.get());
12783 organizeSubGroups(root.get());
12784 g_s.end();
12785
12786 g_s.begin("Building directory list...\n");
12788 findDirDocumentation(root.get());
12789 g_s.end();
12790
12791 g_s.begin("Building namespace list...\n");
12792 buildNamespaceList(root.get());
12793 findUsingDirectives(root.get());
12794 g_s.end();
12795
12796 g_s.begin("Building file list...\n");
12797 buildFileList(root.get());
12798 g_s.end();
12799
12800 g_s.begin("Building class list...\n");
12801 buildClassList(root.get());
12802 g_s.end();
12803
12804 g_s.begin("Building concept list...\n");
12805 buildConceptList(root.get());
12806 g_s.end();
12807
12808 // build list of using declarations here (global list)
12809 buildListOfUsingDecls(root.get());
12810 g_s.end();
12811
12812 g_s.begin("Computing nesting relations for classes...\n");
12814 g_s.end();
12815 // 1.8.2-20121111: no longer add nested classes to the group as well
12816 //distributeClassGroupRelations();
12817
12818 // calling buildClassList may result in cached relations that
12819 // become invalid after resolveClassNestingRelations(), that's why
12820 // we need to clear the cache here
12821 Doxygen::typeLookupCache->clear();
12822 // we don't need the list of using declaration anymore
12823 g_usingDeclarations.clear();
12824
12825 g_s.begin("Associating documentation with classes...\n");
12826 buildClassDocList(root.get());
12827 g_s.end();
12828
12829 g_s.begin("Associating documentation with concepts...\n");
12830 buildConceptDocList(root.get());
12832 g_s.end();
12833
12834 g_s.begin("Associating documentation with modules...\n");
12835 findModuleDocumentation(root.get());
12836 g_s.end();
12837
12838 g_s.begin("Building example list...\n");
12839 buildExampleList(root.get());
12840 g_s.end();
12841
12842 g_s.begin("Searching for enumerations...\n");
12843 findEnums(root.get());
12844 g_s.end();
12845
12846 // Since buildVarList calls isVarWithConstructor
12847 // and this calls getResolvedClass we need to process
12848 // typedefs first so the relations between classes via typedefs
12849 // are properly resolved. See bug 536385 for an example.
12850 g_s.begin("Searching for documented typedefs...\n");
12851 buildTypedefList(root.get());
12852 g_s.end();
12853
12854 if (Config_getBool(OPTIMIZE_OUTPUT_SLICE))
12855 {
12856 g_s.begin("Searching for documented sequences...\n");
12857 buildSequenceList(root.get());
12858 g_s.end();
12859
12860 g_s.begin("Searching for documented dictionaries...\n");
12861 buildDictionaryList(root.get());
12862 g_s.end();
12863 }
12864
12865 g_s.begin("Searching for members imported via using declarations...\n");
12866 // this should be after buildTypedefList in order to properly import
12867 // used typedefs
12868 findUsingDeclarations(root.get(),TRUE); // do for python packages first
12869 findUsingDeclarations(root.get(),FALSE); // then the rest
12870 g_s.end();
12871
12872 g_s.begin("Searching for included using directives...\n");
12874 g_s.end();
12875
12876 g_s.begin("Searching for documented variables...\n");
12877 buildVarList(root.get());
12878 g_s.end();
12879
12880 g_s.begin("Building interface member list...\n");
12881 buildInterfaceAndServiceList(root.get()); // UNO IDL
12882
12883 g_s.begin("Building member list...\n"); // using class info only !
12884 buildFunctionList(root.get());
12885 g_s.end();
12886
12887 g_s.begin("Searching for friends...\n");
12888 findFriends();
12889 g_s.end();
12890
12891 g_s.begin("Searching for documented defines...\n");
12892 findDefineDocumentation(root.get());
12893 g_s.end();
12894
12895 g_s.begin("Computing class inheritance relations...\n");
12896 findClassEntries(root.get());
12898 g_s.end();
12899
12900 g_s.begin("Computing class usage relations...\n");
12902 g_s.end();
12903
12904 if (Config_getBool(INLINE_SIMPLE_STRUCTS))
12905 {
12906 g_s.begin("Searching for tag less structs...\n");
12908 g_s.end();
12909 }
12910
12911 g_s.begin("Flushing cached template relations that have become invalid...\n");
12913 g_s.end();
12914
12915 g_s.begin("Warn for undocumented namespaces...\n");
12917 g_s.end();
12918
12919 g_s.begin("Computing class relations...\n");
12922 if (Config_getBool(OPTIMIZE_OUTPUT_VHDL))
12923 {
12925 }
12927 g_classEntries.clear();
12928 g_s.end();
12929
12930 g_s.begin("Add enum values to enums...\n");
12931 addEnumValuesToEnums(root.get());
12932 findEnumDocumentation(root.get());
12933 g_s.end();
12934
12935 g_s.begin("Searching for member function documentation...\n");
12936 findObjCMethodDefinitions(root.get());
12937 findMemberDocumentation(root.get()); // may introduce new members !
12938 findUsingDeclImports(root.get()); // may introduce new members !
12939 g_usingClassMap.clear();
12943 g_s.end();
12944
12945 // moved to after finding and copying documentation,
12946 // as this introduces new members see bug 722654
12947 g_s.begin("Creating members for template instances...\n");
12949 g_s.end();
12950
12951 g_s.begin("Building page list...\n");
12952 buildPageList(root.get());
12953 g_s.end();
12954
12955 g_s.begin("Building requirements list...\n");
12956 buildRequirementsList(root.get());
12957 g_s.end();
12958
12959 g_s.begin("Search for main page...\n");
12960 findMainPage(root.get());
12961 findMainPageTagFiles(root.get());
12962 g_s.end();
12963
12964 g_s.begin("Computing page relations...\n");
12965 computePageRelations(root.get());
12967 g_s.end();
12968
12969 g_s.begin("Determining the scope of groups...\n");
12970 findGroupScope(root.get());
12971 g_s.end();
12972
12973 g_s.begin("Computing module relations...\n");
12974 auto &mm = ModuleManager::instance();
12975 mm.resolvePartitions();
12976 mm.resolveImports();
12977 mm.collectExportedSymbols();
12978 g_s.end();
12979
12980 auto memberNameComp = [](const MemberNameLinkedMap::Ptr &n1,const MemberNameLinkedMap::Ptr &n2)
12981 {
12982 return qstricmp_sort(n1->memberName().data()+getPrefixIndex(n1->memberName()),
12983 n2->memberName().data()+getPrefixIndex(n2->memberName())
12984 )<0;
12985 };
12986
12987 auto classComp = [](const ClassLinkedMap::Ptr &c1,const ClassLinkedMap::Ptr &c2)
12988 {
12989 if (Config_getBool(SORT_BY_SCOPE_NAME))
12990 {
12991 return qstricmp_sort(c1->name(), c2->name())<0;
12992 }
12993 else
12994 {
12995 int i = qstricmp_sort(c1->className(), c2->className());
12996 return i==0 ? qstricmp_sort(c1->name(), c2->name())<0 : i<0;
12997 }
12998 };
12999
13000 auto namespaceComp = [](const NamespaceLinkedMap::Ptr &n1,const NamespaceLinkedMap::Ptr &n2)
13001 {
13002 return qstricmp_sort(n1->name(),n2->name())<0;
13003 };
13004
13005 auto conceptComp = [](const ConceptLinkedMap::Ptr &c1,const ConceptLinkedMap::Ptr &c2)
13006 {
13007 return qstricmp_sort(c1->name(),c2->name())<0;
13008 };
13009
13010 g_s.begin("Sorting lists...\n");
13011 std::stable_sort(Doxygen::memberNameLinkedMap->begin(),
13013 memberNameComp);
13014 std::stable_sort(Doxygen::functionNameLinkedMap->begin(),
13016 memberNameComp);
13017 std::stable_sort(Doxygen::hiddenClassLinkedMap->begin(),
13019 classComp);
13020 std::stable_sort(Doxygen::classLinkedMap->begin(),
13022 classComp);
13023 std::stable_sort(Doxygen::conceptLinkedMap->begin(),
13025 conceptComp);
13026 std::stable_sort(Doxygen::namespaceLinkedMap->begin(),
13028 namespaceComp);
13029 g_s.end();
13030
13031 g_s.begin("Determining which enums are documented\n");
13033 g_s.end();
13034
13035 g_s.begin("Computing member relations...\n");
13038 g_s.end();
13039
13040 g_s.begin("Building full member lists recursively...\n");
13042 g_s.end();
13043
13044 g_s.begin("Adding members to member groups.\n");
13046 g_s.end();
13047
13048 if (Config_getBool(DISTRIBUTE_GROUP_DOC))
13049 {
13050 g_s.begin("Distributing member group documentation.\n");
13052 g_s.end();
13053 }
13054
13055 g_s.begin("Computing member references...\n");
13057 g_s.end();
13058
13059 if (Config_getBool(INHERIT_DOCS))
13060 {
13061 g_s.begin("Inheriting documentation...\n");
13063 g_s.end();
13064 }
13065
13066
13067 // compute the shortest possible names of all files
13068 // without losing the uniqueness of the file names.
13069 g_s.begin("Generating disk names...\n");
13071 g_s.end();
13072
13073 g_s.begin("Adding source references...\n");
13075 g_s.end();
13076
13077 g_s.begin("Adding xrefitems...\n");
13080 g_s.end();
13081
13082 g_s.begin("Adding requirements...\n");
13085 g_s.end();
13086
13087 g_s.begin("Sorting member lists...\n");
13089 g_s.end();
13090
13091 g_s.begin("Setting anonymous enum type...\n");
13093 g_s.end();
13094
13095 g_s.begin("Computing dependencies between directories...\n");
13097 g_s.end();
13098
13099 g_s.begin("Generating citations page...\n");
13101 g_s.end();
13102
13103 g_s.begin("Counting members...\n");
13104 countMembers();
13105 g_s.end();
13106
13107 g_s.begin("Counting data structures...\n");
13109 g_s.end();
13110
13111 g_s.begin("Resolving user defined references...\n");
13113 g_s.end();
13114
13115 g_s.begin("Finding anchors and sections in the documentation...\n");
13117 g_s.end();
13118
13119 g_s.begin("Transferring function references...\n");
13121 g_s.end();
13122
13123 g_s.begin("Combining using relations...\n");
13125 g_s.end();
13126
13128 g_s.begin("Adding members to index pages...\n");
13130 addToIndices();
13131 g_s.end();
13132
13133 g_s.begin("Correcting members for VHDL...\n");
13135 g_s.end();
13136
13137 g_s.begin("Computing tooltip texts...\n");
13139 g_s.end();
13140
13141 if (Config_getBool(SORT_GROUP_NAMES))
13142 {
13143 std::stable_sort(Doxygen::groupLinkedMap->begin(),
13145 [](const auto &g1,const auto &g2)
13146 { return g1->groupTitle() < g2->groupTitle(); });
13147
13148 for (const auto &gd : *Doxygen::groupLinkedMap)
13149 {
13150 gd->sortSubGroups();
13151 }
13152 }
13153
13154 printNavTree(root.get(),0);
13156}
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:1119
void computeDirDependencies()
Definition dirdef.cpp:1193
static void findInheritedTemplateInstances()
Definition doxygen.cpp:5298
void printNavTree(Entry *root, int indent)
static void buildGroupList(const Entry *root)
Definition doxygen.cpp:431
static void flushCachedTemplateRelations()
Definition doxygen.cpp:9431
static void computeTemplateClassRelations()
Definition doxygen.cpp:5392
void printSectionsTree()
static void generateXRefPages()
Definition doxygen.cpp:5571
static void warnUndocumentedNamespaces()
Definition doxygen.cpp:5347
static void resolveClassNestingRelations()
Definition doxygen.cpp:1380
static void vhdlCorrectMemberProperties()
Definition doxygen.cpp:8389
static void stopDoxygen(int)
static void computeMemberReferences()
Definition doxygen.cpp:5461
static void transferRelatedFunctionDocumentation()
Definition doxygen.cpp:4419
static void addMembersToMemberGroup()
Definition doxygen.cpp:9296
static void distributeConceptGroups()
Definition doxygen.cpp:1347
static void transferFunctionDocumentation()
Definition doxygen.cpp:4338
static void setAnonymousEnumType()
Definition doxygen.cpp:9036
static void sortMemberLists()
Definition doxygen.cpp:8941
static void createTemplateInstanceMembers()
Definition doxygen.cpp:8517
void transferStaticInstanceInitializers()
Definition doxygen.cpp:4468
static void findObjCMethodDefinitions(const Entry *root)
Definition doxygen.cpp:7530
static void distributeMemberGroupDocumentation()
Definition doxygen.cpp:9334
static void resolveUserReferences()
Definition doxygen.cpp:9901
static void readTagFile(const std::shared_ptr< Entry > &root, const QCString &tagLine)
static void findIncludedUsingDirectives()
Definition doxygen.cpp:2460
static void countMembers()
Definition doxygen.cpp:9050
static void organizeSubGroups(const Entry *root)
Definition doxygen.cpp:490
void searchInputFiles()
static void findFriends()
Definition doxygen.cpp:4241
static void addListReferences()
Definition doxygen.cpp:5562
static void exitDoxygen() noexcept
static void addMembersToIndex()
Definition doxygen.cpp:8179
static void addSourceReferences()
Definition doxygen.cpp:8814
static void inheritDocumentation()
Definition doxygen.cpp:9236
static void flushUnresolvedRelations()
Definition doxygen.cpp:9485
static QCString g_commentFileName
Definition doxygen.cpp:193
static void findDocumentedEnumValues()
Definition doxygen.cpp:8171
static void generateDiskNames()
static void addToIndices()
Definition doxygen.cpp:8221
static void computeClassRelations()
Definition doxygen.cpp:5367
static void checkPageRelations()
Definition doxygen.cpp:9881
static QCString createOutputDirectory(const QCString &baseDirName, const QCString &formatDirName, const char *defaultDirName)
static void addRequirementReferences()
Definition doxygen.cpp:5554
static void computeVerifiedDotPath()
static bool g_singleComment
Definition doxygen.cpp:194
static void findSectionsInDocumentation()
Definition doxygen.cpp:9372
static void mergeCategories()
Definition doxygen.cpp:8536
static void findUsedTemplateInstances()
Definition doxygen.cpp:5331
static void computeTooltipTexts()
Definition doxygen.cpp:8990
static void parseFilesSingleThreading(const std::shared_ptr< Entry > &root)
parse the list of input files
static void buildCompleteMemberLists()
Definition doxygen.cpp:8558
static void combineUsingRelations()
Definition doxygen.cpp:9271
static void checkMarkdownMainfile()
static void parseFilesMultiThreading(const std::shared_ptr< Entry > &root)
parse the list of input files
static void transferFunctionReferences()
Definition doxygen.cpp:4371
static void buildDefineList()
Definition doxygen.cpp:8893
static void computeMemberRelations()
Definition doxygen.cpp:8501
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:1471
int getPrefixIndex(const QCString &name)
Definition util.cpp:3212

References Dir::absPath(), addEnumValuesToEnums(), addListReferences(), addMembersToIndex(), addMembersToMemberGroup(), addRequirementReferences(), 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(), buildRequirementsList(), 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(), RequirementManager::generatePage(), generateXRefPages(), Portable::getenv(), getPrefixIndex(), Doxygen::groupLinkedMap, Doxygen::hiddenClassLinkedMap, Doxygen::indexList, inheritDocumentation(), LayoutDocManager::init(), FormulaManager::initFromRepository(), initSearchIndexer(), CitationManager::instance(), FormulaManager::instance(), Index::instance(), LayoutDocManager::instance(), ModuleManager::instance(), RequirementManager::instance(), QCString::isEmpty(), FileInfo::isFile(), Doxygen::memberNameLinkedMap, mergeCategories(), Dir::mkdir(), msg, Doxygen::namespaceLinkedMap, organizeSubGroups(), LayoutDocManager::parse(), parseFilesMultiThreading(), parseFilesSingleThreading(), Portable::pathListSeparator(), Portable::pid(), printLayout(), printNavTree(), printSectionsTree(), qPrint(), qstricmp_sort(), readInputFile(), readTagFile(), resolveClassNestingRelations(), resolveUserReferences(), searchInputFiles(), setAnonymousEnumType(), Portable::setenv(), Dir::setPath(), sortMemberLists(), stopDoxygen(), QCString::str(), 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 10015 of file doxygen.cpp.

10016{
10018 {
10019 QCString indentStr;
10020 indentStr.fill(' ',indent);
10021 Debug::print(Debug::Entries,0,"{}{} at {}:{} (sec={}, spec={})\n",
10022 indentStr.isEmpty()?"":indentStr,
10023 root->name.isEmpty()?"<empty>":root->name,
10024 root->fileName,root->startLine,
10025 root->section.to_string(),
10026 root->spec.to_string());
10027 for (const auto &e : root->children())
10028 {
10029 printNavTree(e.get(),indent+2);
10030 }
10031 }
10032}
@ 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:828
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 10038 of file doxygen.cpp.

10039{
10041 {
10042 for (const auto &si : SectionManager::instance())
10043 {
10044 Debug::print(Debug::Sections,0,"Section = {}, file = {}, title = {}, type = {}, ref = {}\n",
10045 si->label(),si->fileName(),si->title(),si->type().level(),si->ref());
10046 }
10047 }
10048}
@ 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 1614 of file doxygen.cpp.

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

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

11542{
11543 QCString versionString = getFullVersion();
11544
11545 // helper that calls \a func to write to file \a fileName via a TextStream
11546 auto writeFile = [](const char *fileName,std::function<void(TextStream&)> func) -> bool
11547 {
11548 std::ofstream f;
11549 if (openOutputFile(fileName,f))
11550 {
11551 TextStream t(&f);
11552 func(t);
11553 return true;
11554 }
11555 return false;
11556 };
11557
11558
11559 /**************************************************************************
11560 * Handle arguments *
11561 **************************************************************************/
11562
11563 int optInd=1;
11564 QCString configName;
11565 QCString traceName;
11566 bool genConfig=false;
11567 bool shortList=false;
11568 bool traceTiming=false;
11570 bool updateConfig=false;
11571 bool quiet = false;
11572 while (optInd<argc && argv[optInd][0]=='-' &&
11573 (isalpha(argv[optInd][1]) || argv[optInd][1]=='?' ||
11574 argv[optInd][1]=='-')
11575 )
11576 {
11577 switch(argv[optInd][1])
11578 {
11579 case 'g':
11580 {
11581 genConfig=TRUE;
11582 }
11583 break;
11584 case 'l':
11585 {
11586 QCString layoutName;
11587 if (optInd+1>=argc)
11588 {
11589 layoutName="DoxygenLayout.xml";
11590 }
11591 else
11592 {
11593 layoutName=argv[optInd+1];
11594 }
11595 writeDefaultLayoutFile(layoutName);
11597 exit(0);
11598 }
11599 break;
11600 case 'c':
11601 if (optInd+1>=argc) // no file name given
11602 {
11603 msg("option \"-c\" is missing the file name to read\n");
11604 devUsage();
11606 exit(1);
11607 }
11608 else
11609 {
11610 g_commentFileName=argv[optInd+1];
11611 optInd++;
11612 }
11613 g_singleComment=true;
11614 quiet=true;
11615 break;
11616 case 'd':
11617 {
11618 QCString debugLabel=getArg(argc,argv,optInd);
11619 if (debugLabel.isEmpty())
11620 {
11621 devUsage();
11623 exit(0);
11624 }
11625 int retVal = Debug::setFlagStr(debugLabel);
11626 if (!retVal)
11627 {
11628 msg("option \"-d\" has unknown debug specifier: \"{}\".\n",debugLabel);
11629 devUsage();
11631 exit(1);
11632 }
11633 }
11634 break;
11635 case 't':
11636 {
11637#if ENABLE_TRACING
11638 if (!strcmp(argv[optInd]+1,"t_time"))
11639 {
11640 traceTiming = true;
11641 }
11642 else if (!strcmp(argv[optInd]+1,"t"))
11643 {
11644 traceTiming = false;
11645 }
11646 else
11647 {
11648 err("option should be \"-t\" or \"-t_time\", found: \"{}\".\n",argv[optInd]);
11650 exit(1);
11651 }
11652 if (optInd+1>=argc || argv[optInd+1][0] == '-') // no file name given
11653 {
11654 traceName="stdout";
11655 }
11656 else
11657 {
11658 traceName=argv[optInd+1];
11659 optInd++;
11660 }
11661#else
11662 err("support for option \"-t\" has not been compiled in (use a debug build or a release build with tracing enabled).\n");
11664 exit(1);
11665#endif
11666 }
11667 break;
11668 case 'x':
11669 if (!strcmp(argv[optInd]+1,"x_noenv")) diffList=Config::CompareMode::CompressedNoEnv;
11670 else if (!strcmp(argv[optInd]+1,"x")) diffList=Config::CompareMode::Compressed;
11671 else
11672 {
11673 err("option should be \"-x\" or \"-x_noenv\", found: \"{}\".\n",argv[optInd]);
11675 exit(1);
11676 }
11677 break;
11678 case 's':
11679 shortList=TRUE;
11680 break;
11681 case 'u':
11682 updateConfig=TRUE;
11683 break;
11684 case 'e':
11685 {
11686 QCString formatName=getArg(argc,argv,optInd);
11687 if (formatName.isEmpty())
11688 {
11689 err("option \"-e\" is missing format specifier rtf.\n");
11691 exit(1);
11692 }
11693 if (qstricmp(formatName.data(),"rtf")==0)
11694 {
11695 if (optInd+1>=argc)
11696 {
11697 err("option \"-e rtf\" is missing an extensions file name\n");
11699 exit(1);
11700 }
11701 writeFile(argv[optInd+1],RTFGenerator::writeExtensionsFile);
11703 exit(0);
11704 }
11705 err("option \"-e\" has invalid format specifier.\n");
11707 exit(1);
11708 }
11709 break;
11710 case 'f':
11711 {
11712 QCString listName=getArg(argc,argv,optInd);
11713 if (listName.isEmpty())
11714 {
11715 err("option \"-f\" is missing list specifier.\n");
11717 exit(1);
11718 }
11719 if (qstricmp(listName.data(),"emoji")==0)
11720 {
11721 if (optInd+1>=argc)
11722 {
11723 err("option \"-f emoji\" is missing an output file name\n");
11725 exit(1);
11726 }
11727 writeFile(argv[optInd+1],[](TextStream &t) { EmojiEntityMapper::instance().writeEmojiFile(t); });
11729 exit(0);
11730 }
11731 err("option \"-f\" has invalid list specifier.\n");
11733 exit(1);
11734 }
11735 break;
11736 case 'w':
11737 {
11738 QCString formatName=getArg(argc,argv,optInd);
11739 if (formatName.isEmpty())
11740 {
11741 err("option \"-w\" is missing format specifier rtf, html or latex\n");
11743 exit(1);
11744 }
11745 if (qstricmp(formatName.data(),"rtf")==0)
11746 {
11747 if (optInd+1>=argc)
11748 {
11749 err("option \"-w rtf\" is missing a style sheet file name\n");
11751 exit(1);
11752 }
11753 if (!writeFile(argv[optInd+1],RTFGenerator::writeStyleSheetFile))
11754 {
11755 err("error opening RTF style sheet file {}!\n",argv[optInd+1]);
11757 exit(1);
11758 }
11760 exit(0);
11761 }
11762 else if (qstricmp(formatName.data(),"html")==0)
11763 {
11764 Config::init();
11765 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11766 // explicit config file mentioned or default found on disk
11767 {
11768 QCString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? QCString("Doxyfile") : QCString("doxyfile"));
11769 if (!Config::parse(df)) // parse the config file
11770 {
11771 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
11773 exit(1);
11774 }
11775 }
11776 if (optInd+3>=argc)
11777 {
11778 err("option \"-w html\" does not have enough arguments\n");
11780 exit(1);
11781 }
11785 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11786 writeFile(argv[optInd+1],[&](TextStream &t) { HtmlGenerator::writeHeaderFile(t,argv[optInd+3]); });
11787 writeFile(argv[optInd+2],HtmlGenerator::writeFooterFile);
11788 writeFile(argv[optInd+3],HtmlGenerator::writeStyleSheetFile);
11790 exit(0);
11791 }
11792 else if (qstricmp(formatName.data(),"latex")==0)
11793 {
11794 Config::init();
11795 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11796 {
11797 QCString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? QCString("Doxyfile") : QCString("doxyfile"));
11798 if (!Config::parse(df))
11799 {
11800 err("error opening or reading configuration file {}!\n",argv[optInd+4]);
11802 exit(1);
11803 }
11804 }
11805 if (optInd+3>=argc)
11806 {
11807 err("option \"-w latex\" does not have enough arguments\n");
11809 exit(1);
11810 }
11814 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11815 writeFile(argv[optInd+1],LatexGenerator::writeHeaderFile);
11816 writeFile(argv[optInd+2],LatexGenerator::writeFooterFile);
11817 writeFile(argv[optInd+3],LatexGenerator::writeStyleSheetFile);
11819 exit(0);
11820 }
11821 else
11822 {
11823 err("Illegal format specifier \"{}\": should be one of rtf, html or latex\n",formatName);
11825 exit(1);
11826 }
11827 }
11828 break;
11829 case 'm':
11831 break;
11832 case 'v':
11833 version(false);
11835 exit(0);
11836 break;
11837 case 'V':
11838 version(true);
11840 exit(0);
11841 break;
11842 case '-':
11843 if (qstrcmp(&argv[optInd][2],"help")==0)
11844 {
11845 usage(argv[0],versionString);
11846 exit(0);
11847 }
11848 else if (qstrcmp(&argv[optInd][2],"version")==0)
11849 {
11850 version(false);
11852 exit(0);
11853 }
11854 else if ((qstrcmp(&argv[optInd][2],"Version")==0) ||
11855 (qstrcmp(&argv[optInd][2],"VERSION")==0))
11856 {
11857 version(true);
11859 exit(0);
11860 }
11861 else
11862 {
11863 err("Unknown option \"-{}\"\n",&argv[optInd][1]);
11864 usage(argv[0],versionString);
11865 exit(1);
11866 }
11867 break;
11868 case 'b':
11869 setvbuf(stdout,nullptr,_IONBF,0);
11870 break;
11871 case 'q':
11872 quiet = true;
11873 break;
11874 case 'h':
11875 case '?':
11876 usage(argv[0],versionString);
11877 exit(0);
11878 break;
11879 default:
11880 err("Unknown option \"-{:c}\"\n",argv[optInd][1]);
11881 usage(argv[0],versionString);
11882 exit(1);
11883 }
11884 optInd++;
11885 }
11886
11887 /**************************************************************************
11888 * Parse or generate the config file *
11889 **************************************************************************/
11890
11891 initTracing(traceName.data(),traceTiming);
11892 TRACE("Doxygen version used: {}",getFullVersion());
11893 Config::init();
11894
11895 FileInfo configFileInfo1("Doxyfile"),configFileInfo2("doxyfile");
11896 if (optInd>=argc)
11897 {
11898 if (configFileInfo1.exists())
11899 {
11900 configName="Doxyfile";
11901 }
11902 else if (configFileInfo2.exists())
11903 {
11904 configName="doxyfile";
11905 }
11906 else if (genConfig)
11907 {
11908 configName="Doxyfile";
11909 }
11910 else
11911 {
11912 err("Doxyfile not found and no input file specified!\n");
11913 usage(argv[0],versionString);
11914 exit(1);
11915 }
11916 }
11917 else
11918 {
11919 FileInfo fi(argv[optInd]);
11920 if (fi.exists() || qstrcmp(argv[optInd],"-")==0 || genConfig)
11921 {
11922 configName=argv[optInd];
11923 }
11924 else
11925 {
11926 err("configuration file {} not found!\n",argv[optInd]);
11927 usage(argv[0],versionString);
11928 exit(1);
11929 }
11930 }
11931
11932 if (genConfig)
11933 {
11934 generateConfigFile(configName,shortList);
11936 exit(0);
11937 }
11938
11939 if (!Config::parse(configName,updateConfig,diffList))
11940 {
11941 err("could not open or read configuration file {}!\n",configName);
11943 exit(1);
11944 }
11945
11946 if (diffList!=Config::CompareMode::Full)
11947 {
11949 compareDoxyfile(diffList);
11951 exit(0);
11952 }
11953
11954 if (updateConfig)
11955 {
11957 generateConfigFile(configName,shortList,TRUE);
11959 exit(0);
11960 }
11961
11962 /* Perlmod wants to know the path to the config file.*/
11963 FileInfo configFileInfo(configName.str());
11964 setPerlModDoxyfile(configFileInfo.absFilePath());
11965
11966 /* handle -q option */
11967 if (quiet) Config_updateBool(QUIET,TRUE);
11968}
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 11074 of file doxygen.cpp.

11086{
11087 std::string dirName = fi->absFilePath();
11088 if (paths && !dirName.empty())
11089 {
11090 paths->insert(dirName);
11091 }
11092 //printf("%s isSymLink()=%d\n",qPrint(dirName),fi->isSymLink());
11093 if (fi->isSymLink())
11094 {
11095 dirName = resolveSymlink(dirName);
11096 if (dirName.empty())
11097 {
11098 //printf("RECURSIVE SYMLINK: %s\n",qPrint(dirName));
11099 return; // recursive symlink
11100 }
11101 }
11102
11103 if (g_pathsVisited.find(dirName)!=g_pathsVisited.end())
11104 {
11105 //printf("PATH ALREADY VISITED: %s\n",qPrint(dirName));
11106 return; // already visited path
11107 }
11108 g_pathsVisited.insert(dirName);
11109
11110 Dir dir(dirName);
11111 msg("Searching for files in directory {}\n", fi->absFilePath());
11112 //printf("killSet=%p count=%d\n",killSet,killSet ? (int)killSet->count() : -1);
11113
11114 StringVector dirResultList;
11115
11116 for (const auto &dirEntry : dir.iterator())
11117 {
11118 FileInfo cfi(dirEntry.path());
11119 auto checkPatterns = [&]() -> bool
11120 {
11121 return (patList==nullptr || patternMatch(cfi,*patList)) &&
11122 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
11123 (killSet==nullptr || killSet->find(cfi.absFilePath())==killSet->end());
11124 };
11125
11126 if (exclSet==nullptr || exclSet->find(cfi.absFilePath())==exclSet->end())
11127 { // file should not be excluded
11128 //printf("killSet->find(%s)\n",qPrint(cfi->absFilePath()));
11129 if (Config_getBool(EXCLUDE_SYMLINKS) && cfi.isSymLink())
11130 {
11131 }
11132 else if (!cfi.exists() || !cfi.isReadable())
11133 {
11134 if (errorIfNotExist && checkPatterns())
11135 {
11136 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",cfi.absFilePath());
11137 }
11138 }
11139 else if (cfi.isFile() && checkPatterns())
11140 {
11141 std::string name=cfi.fileName();
11142 std::string path=cfi.dirPath()+"/";
11143 std::string fullName=path+name;
11144 if (fnMap)
11145 {
11146 auto fd = createFileDef(path,name);
11147 FileName *fn=nullptr;
11148 if (!name.empty())
11149 {
11150 fn = fnMap->add(name,fullName);
11151 fn->push_back(std::move(fd));
11152 }
11153 }
11154 dirResultList.push_back(fullName);
11155 if (resultSet) resultSet->insert(fullName);
11156 if (killSet) killSet->insert(fullName);
11157 }
11158 else if (recursive &&
11159 cfi.isDir() &&
11160 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
11161 cfi.fileName().at(0)!='.') // skip "." ".." and ".dir"
11162 {
11163 FileInfo acfi(cfi.absFilePath());
11164 readDir(&acfi,fnMap,exclSet,
11165 patList,exclPatList,&dirResultList,resultSet,errorIfNotExist,
11166 recursive,killSet,paths);
11167 }
11168 }
11169 }
11170 if (resultList && !dirResultList.empty())
11171 {
11172 // sort the resulting list to make the order platform independent.
11173 std::stable_sort(dirResultList.begin(),
11174 dirResultList.end(),
11175 [](const auto &f1,const auto &f2) { return qstricmp_sort(f1.c_str(),f2.c_str())<0; });
11176
11177 // append the sorted results to resultList
11178 resultList->insert(resultList->end(), dirResultList.begin(), dirResultList.end());
11179 }
11180}
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:269
bool patternMatch(const FileInfo &fi, const StringVector &patList)
Definition util.cpp:5684

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

11199{
11200 //printf("killSet count=%d\n",killSet ? (int)killSet->size() : -1);
11201 // strip trailing slashes
11202 if (s.isEmpty()) return;
11203
11204 g_pathsVisited.clear();
11205
11206 FileInfo fi(s.str());
11207 //printf("readFileOrDirectory(%s)\n",s);
11208 {
11209 if (exclSet==nullptr || exclSet->find(fi.absFilePath())==exclSet->end())
11210 {
11211 if (Config_getBool(EXCLUDE_SYMLINKS) && fi.isSymLink())
11212 {
11213 }
11214 else if (!fi.exists() || !fi.isReadable())
11215 {
11216 if (errorIfNotExist)
11217 {
11218 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",s);
11219 }
11220 }
11221 else if (fi.isFile())
11222 {
11223 std::string dirPath = fi.dirPath(true);
11224 std::string filePath = fi.absFilePath();
11225 if (paths && !dirPath.empty())
11226 {
11227 paths->insert(dirPath);
11228 }
11229 //printf("killSet.find(%s)=%d\n",qPrint(fi.absFilePath()),killSet.find(fi.absFilePath())!=killSet.end());
11230 if (killSet==nullptr || killSet->find(filePath)==killSet->end())
11231 {
11232 std::string name=fi.fileName();
11233 if (fnMap)
11234 {
11235 auto fd = createFileDef(dirPath+"/",name);
11236 if (!name.empty())
11237 {
11238 FileName *fn = fnMap->add(name,filePath);
11239 fn->push_back(std::move(fd));
11240 }
11241 }
11242 if (resultList || resultSet)
11243 {
11244 if (resultList) resultList->push_back(filePath);
11245 if (resultSet) resultSet->insert(filePath);
11246 }
11247
11248 if (killSet) killSet->insert(fi.absFilePath());
11249 }
11250 }
11251 else if (fi.isDir()) // readable dir
11252 {
11253 readDir(&fi,fnMap,exclSet,patList,
11254 exclPatList,resultList,resultSet,errorIfNotExist,
11255 recursive,killSet,paths);
11256 }
11257 }
11258 }
11259}

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

10399{
10400 QCString fileName;
10401 QCString destName;
10402 int eqPos = tagLine.find('=');
10403 if (eqPos!=-1) // tag command contains a destination
10404 {
10405 fileName = tagLine.left(eqPos).stripWhiteSpace();
10406 destName = tagLine.right(tagLine.length()-eqPos-1).stripWhiteSpace();
10407 if (fileName.isEmpty() || destName.isEmpty()) return;
10408 //printf("insert tagDestination %s->%s\n",qPrint(fi.fileName()),qPrint(destName));
10409 }
10410 else
10411 {
10412 fileName = tagLine;
10413 }
10414
10415 FileInfo fi(fileName.str());
10416 if (!fi.exists() || !fi.isFile())
10417 {
10418 err("Tag file '{}' does not exist or is not a file. Skipping it...\n",fileName);
10419 return;
10420 }
10421
10422 if (Doxygen::tagFileSet.find(fi.absFilePath()) != Doxygen::tagFileSet.end()) return;
10423
10424 Doxygen::tagFileSet.emplace(fi.absFilePath());
10425
10426 if (!destName.isEmpty())
10427 {
10428 Doxygen::tagDestinationMap.emplace(fi.absFilePath(), destName.str());
10429 msg("Reading tag file '{}', location '{}'...\n",fileName,destName);
10430 }
10431 else
10432 {
10433 msg("Reading tag file '{}'...\n",fileName);
10434 }
10435
10436 parseTagFile(root,fi.absFilePath().c_str());
10437}
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 1380 of file doxygen.cpp.

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

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

11003{
11004 int sepPos=0;
11005 int oldPos=0;
11006 StringUnorderedSet nonSymlinks;
11007 StringUnorderedSet known;
11008 QCString result(path);
11009 QCString oldPrefix = "/";
11010 do
11011 {
11012#if defined(_WIN32)
11013 // UNC path, skip server and share name
11014 if (sepPos==0 && (result.startsWith("//") || result.startsWith("\\\\")))
11015 sepPos = result.find('/',2);
11016 if (sepPos!=-1)
11017 sepPos = result.find('/',sepPos+1);
11018#else
11019 sepPos = result.find('/',sepPos+1);
11020#endif
11021 QCString prefix = sepPos==-1 ? result : result.left(sepPos);
11022 if (nonSymlinks.find(prefix.str())==nonSymlinks.end())
11023 {
11024 FileInfo fi(prefix.str());
11025 if (fi.isSymLink())
11026 {
11027 QCString target = fi.readLink();
11028 bool isRelative = FileInfo(target.str()).isRelative();
11029 if (isRelative)
11030 {
11031 target = Dir::cleanDirPath(oldPrefix.str()+"/"+target.str());
11032 }
11033 if (sepPos!=-1)
11034 {
11035 if (fi.isDir() && target.length()>0 && target.at(target.length()-1)!='/')
11036 {
11037 target+='/';
11038 }
11039 target+=result.mid(sepPos);
11040 }
11041 result = Dir::cleanDirPath(target.str());
11042 if (known.find(result.str())!=known.end()) return std::string(); // recursive symlink!
11043 known.insert(result.str());
11044 if (isRelative)
11045 {
11046 sepPos = oldPos;
11047 }
11048 else // link to absolute path
11049 {
11050 sepPos = 0;
11051 oldPrefix = "/";
11052 }
11053 }
11054 else
11055 {
11056 nonSymlinks.insert(prefix.str());
11057 oldPrefix = prefix;
11058 }
11059 oldPos = sepPos;
11060 }
11061 }
11062 while (sepPos!=-1);
11063 return Dir::cleanDirPath(result.str());
11064}
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 4826 of file doxygen.cpp.

4827{
4828 // For a statement like 'using X = T<A>', add a template instance 'T<A>' as a symbol, so it can
4829 // be used to match arguments (see issue #11111)
4830 AUTO_TRACE();
4831 QCString ttype = md->typeString();
4832 ttype.stripPrefix("typedef ");
4833 int ti=ttype.find('<');
4834 if (ti!=-1)
4835 {
4836 QCString templateClassName = ttype.left(ti);
4837 SymbolResolver resolver(root->fileDef());
4838 ClassDefMutable *baseClass = resolver.resolveClassMutable(scope ? scope : Doxygen::globalScope,
4839 templateClassName, true, true);
4840 AUTO_TRACE_ADD("templateClassName={} baseClass={}",templateClassName,baseClass?baseClass->name():"<none>");
4841 if (baseClass)
4842 {
4843 const ArgumentList &tl = baseClass->templateArguments();
4844 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,templateClassName.str());
4846 baseClass,
4847 ttype.mid(ti),
4848 templateNames,
4849 baseClass->isArtificial());
4850 }
4851 }
4852}

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

9902{
9903 for (const auto &si : SectionManager::instance())
9904 {
9905 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
9906 // qPrint(si->label),si->definition?qPrint(si->definition->name()):"<none>",
9907 // qPrint(si->fileName));
9908 PageDef *pd=nullptr;
9909
9910 // hack: the items of a todo/test/bug/deprecated list are all fragments from
9911 // different files, so the resulting section's all have the wrong file
9912 // name (not from the todo/test/bug/deprecated list, but from the file in
9913 // which they are defined). We correct this here by looking at the
9914 // generated section labels!
9916 {
9917 QCString label="_"+rl->listName(); // "_todo", "_test", ...
9918 if (si->label().left(label.length())==label)
9919 {
9920 si->setFileName(rl->listName());
9921 si->setGenerated(TRUE);
9922 break;
9923 }
9924 }
9925
9926 //printf("start: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9927 if (!si->generated())
9928 {
9929 // if this section is in a page and the page is in a group, then we
9930 // have to adjust the link file name to point to the group.
9931 if (!si->fileName().isEmpty() &&
9932 (pd=Doxygen::pageLinkedMap->find(si->fileName())) &&
9933 pd->getGroupDef())
9934 {
9935 si->setFileName(pd->getGroupDef()->getOutputFileBase());
9936 }
9937
9938 if (si->definition())
9939 {
9940 // TODO: there should be one function in Definition that returns
9941 // the file to link to, so we can avoid the following tests.
9942 const GroupDef *gd=nullptr;
9943 if (si->definition()->definitionType()==Definition::TypeMember)
9944 {
9945 gd = (toMemberDef(si->definition()))->getGroupDef();
9946 }
9947
9948 if (gd)
9949 {
9950 si->setFileName(gd->getOutputFileBase());
9951 }
9952 else
9953 {
9954 //si->fileName=si->definition->getOutputFileBase();
9955 //printf("Setting si->fileName to %s\n",qPrint(si->fileName));
9956 }
9957 }
9958 }
9959 //printf("end: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9960 }
9961}
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 10225 of file doxygen.cpp.

10226{
10227 std::string oldDir = Dir::currentDirPath();
10228 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10231 {
10232 err("failed to run html help compiler on {}\n", HtmlHelp::hhpFileName);
10233 }
10234 Dir::setCurrent(oldDir);
10235}
@ 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 10237 of file doxygen.cpp.

10238{
10239 QCString args = Qhp::qhpFileName + " -o \"" + Qhp::getQchFileName() + "\"";
10240 std::string oldDir = Dir::currentDirPath();
10241 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10242
10243 QCString qhgLocation=Config_getString(QHG_LOCATION);
10244 if (Debug::isFlagSet(Debug::Qhp)) // produce info for debugging
10245 {
10246 // run qhelpgenerator -v and extract the Qt version used
10247 QCString cmd=qhgLocation+ " -v 2>&1";
10248 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10249 FILE *f=Portable::popen(cmd,"r");
10250 if (!f)
10251 {
10252 err("could not execute {}\n",qhgLocation);
10253 }
10254 else
10255 {
10256 const size_t bufSize = 1024;
10257 char inBuf[bufSize+1];
10258 size_t numRead=fread(inBuf,1,bufSize,f);
10259 inBuf[numRead] = '\0';
10260 Debug::print(Debug::Qhp,0,"{}",inBuf);
10262
10263 int qtVersion=0;
10264 static const reg::Ex versionReg(R"(Qt (\d+)\.(\d+)\.(\d+))");
10266 std::string s = inBuf;
10267 if (reg::search(s,match,versionReg))
10268 {
10269 qtVersion = 10000*QCString(match[1].str()).toInt() +
10270 100*QCString(match[2].str()).toInt() +
10271 QCString(match[3].str()).toInt();
10272 }
10273 if (qtVersion>0 && (qtVersion<60000 || qtVersion >= 60205))
10274 {
10275 // dump the output of qhelpgenerator -c file.qhp
10276 // Qt<6 or Qt>=6.2.5 or higher, see https://bugreports.qt.io/browse/QTBUG-101070
10277 cmd=qhgLocation+ " -c " + Qhp::qhpFileName + " 2>&1";
10278 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10279 f=Portable::popen(cmd,"r");
10280 if (!f)
10281 {
10282 err("could not execute {}\n",qhgLocation);
10283 }
10284 else
10285 {
10286 std::string output;
10287 while ((numRead=fread(inBuf,1,bufSize,f))>0)
10288 {
10289 inBuf[numRead] = '\0';
10290 output += inBuf;
10291 }
10293 Debug::print(Debug::Qhp,0,"{}",output);
10294 }
10295 }
10296 }
10297 }
10298
10299 if (Portable::system(qhgLocation, args, FALSE))
10300 {
10301 err("failed to run qhelpgenerator on {}\n",Qhp::qhpFileName);
10302 }
10303 Dir::setCurrent(oldDir);
10304}
@ 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 5998 of file doxygen.cpp.

5999{
6000 bool result=FALSE;
6001 //printf("> scopeIsTemplate(%s)\n",qPrint(d?d->name():"null"));
6003 {
6004 auto cd = toClassDef(d);
6005 result = cd->templateArguments().hasParameters() || cd->templateMaster()!=nullptr ||
6007 }
6008 //printf("< scopeIsTemplate=%d\n",result);
6009 return result;
6010}

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

Referenced by addMemberFunction(), and scopeIsTemplate().

◆ searchInputFiles()

void searchInputFiles ( )

Definition at line 12242 of file doxygen.cpp.

12243{
12244 StringUnorderedSet killSet;
12245
12246 const StringVector &exclPatterns = Config_getList(EXCLUDE_PATTERNS);
12247 bool alwaysRecursive = Config_getBool(RECURSIVE);
12248 StringUnorderedSet excludeNameSet;
12249
12250 // gather names of all files in the include path
12251 g_s.begin("Searching for include files...\n");
12252 killSet.clear();
12253 const StringVector &includePathList = Config_getList(INCLUDE_PATH);
12254 for (const auto &s : includePathList)
12255 {
12256 size_t plSize = Config_getList(INCLUDE_FILE_PATTERNS).size();
12257 const StringVector &pl = plSize==0 ? Config_getList(FILE_PATTERNS) :
12258 Config_getList(INCLUDE_FILE_PATTERNS);
12259 readFileOrDirectory(s, // s
12261 nullptr, // exclSet
12262 &pl, // patList
12263 &exclPatterns, // exclPatList
12264 nullptr, // resultList
12265 nullptr, // resultSet
12266 false, // INCLUDE_PATH isn't recursive
12267 TRUE, // errorIfNotExist
12268 &killSet); // killSet
12269 }
12270 g_s.end();
12271
12272 g_s.begin("Searching for example files...\n");
12273 killSet.clear();
12274 const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
12275 for (const auto &s : examplePathList)
12276 {
12277 readFileOrDirectory(s, // s
12279 nullptr, // exclSet
12280 &Config_getList(EXAMPLE_PATTERNS), // patList
12281 nullptr, // exclPatList
12282 nullptr, // resultList
12283 nullptr, // resultSet
12284 (alwaysRecursive || Config_getBool(EXAMPLE_RECURSIVE)), // recursive
12285 TRUE, // errorIfNotExist
12286 &killSet); // killSet
12287 }
12288 g_s.end();
12289
12290 g_s.begin("Searching for images...\n");
12291 killSet.clear();
12292 const StringVector &imagePathList=Config_getList(IMAGE_PATH);
12293 for (const auto &s : imagePathList)
12294 {
12295 readFileOrDirectory(s, // s
12297 nullptr, // exclSet
12298 nullptr, // patList
12299 nullptr, // exclPatList
12300 nullptr, // resultList
12301 nullptr, // resultSet
12302 alwaysRecursive, // recursive
12303 TRUE, // errorIfNotExist
12304 &killSet); // killSet
12305 }
12306 g_s.end();
12307
12308 g_s.begin("Searching for dot files...\n");
12309 killSet.clear();
12310 const StringVector &dotFileList=Config_getList(DOTFILE_DIRS);
12311 for (const auto &s : dotFileList)
12312 {
12313 readFileOrDirectory(s, // s
12315 nullptr, // exclSet
12316 nullptr, // patList
12317 nullptr, // exclPatList
12318 nullptr, // resultList
12319 nullptr, // resultSet
12320 alwaysRecursive, // recursive
12321 TRUE, // errorIfNotExist
12322 &killSet); // killSet
12323 }
12324 g_s.end();
12325
12326 g_s.begin("Searching for msc files...\n");
12327 killSet.clear();
12328 const StringVector &mscFileList=Config_getList(MSCFILE_DIRS);
12329 for (const auto &s : mscFileList)
12330 {
12331 readFileOrDirectory(s, // s
12333 nullptr, // exclSet
12334 nullptr, // patList
12335 nullptr, // exclPatList
12336 nullptr, // resultList
12337 nullptr, // resultSet
12338 alwaysRecursive, // recursive
12339 TRUE, // errorIfNotExist
12340 &killSet); // killSet
12341 }
12342 g_s.end();
12343
12344 g_s.begin("Searching for dia files...\n");
12345 killSet.clear();
12346 const StringVector &diaFileList=Config_getList(DIAFILE_DIRS);
12347 for (const auto &s : diaFileList)
12348 {
12349 readFileOrDirectory(s, // s
12351 nullptr, // exclSet
12352 nullptr, // patList
12353 nullptr, // exclPatList
12354 nullptr, // resultList
12355 nullptr, // resultSet
12356 alwaysRecursive, // recursive
12357 TRUE, // errorIfNotExist
12358 &killSet); // killSet
12359 }
12360 g_s.end();
12361
12362 g_s.begin("Searching for plantuml files...\n");
12363 killSet.clear();
12364 const StringVector &plantUmlFileList=Config_getList(PLANTUMLFILE_DIRS);
12365 for (const auto &s : plantUmlFileList)
12366 {
12367 readFileOrDirectory(s, // s
12369 nullptr, // exclSet
12370 nullptr, // patList
12371 nullptr, // exclPatList
12372 nullptr, // resultList
12373 nullptr, // resultSet
12374 alwaysRecursive, // recursive
12375 TRUE, // errorIfNotExist
12376 &killSet); // killSet
12377 }
12378 g_s.end();
12379
12380 g_s.begin("Searching for files to exclude\n");
12381 const StringVector &excludeList = Config_getList(EXCLUDE);
12382 for (const auto &s : excludeList)
12383 {
12384 readFileOrDirectory(s, // s
12385 nullptr, // fnDict
12386 nullptr, // exclSet
12387 &Config_getList(FILE_PATTERNS), // patList
12388 nullptr, // exclPatList
12389 nullptr, // resultList
12390 &excludeNameSet, // resultSet
12391 alwaysRecursive, // recursive
12392 FALSE); // errorIfNotExist
12393 }
12394 g_s.end();
12395
12396 /**************************************************************************
12397 * Determine Input Files *
12398 **************************************************************************/
12399
12400 g_s.begin("Searching INPUT for files to process...\n");
12401 killSet.clear();
12402 Doxygen::inputPaths.clear();
12403 const StringVector &inputList=Config_getList(INPUT);
12404 for (const auto &s : inputList)
12405 {
12406 QCString path = s;
12407 size_t l = path.length();
12408 if (l>0)
12409 {
12410 // strip trailing slashes
12411 if (path.at(l-1)=='\\' || path.at(l-1)=='/') path=path.left(l-1);
12412
12414 path, // s
12416 &excludeNameSet, // exclSet
12417 &Config_getList(FILE_PATTERNS), // patList
12418 &exclPatterns, // exclPatList
12419 &g_inputFiles, // resultList
12420 nullptr, // resultSet
12421 alwaysRecursive, // recursive
12422 TRUE, // errorIfNotExist
12423 &killSet, // killSet
12424 &Doxygen::inputPaths); // paths
12425 }
12426 }
12427
12428 // Sort the FileDef objects by full path to get a predictable ordering over multiple runs
12429 std::stable_sort(Doxygen::inputNameLinkedMap->begin(),
12431 [](const auto &f1,const auto &f2)
12432 {
12433 return qstricmp_sort(f1->fullName(),f2->fullName())<0;
12434 });
12435 for (auto &fileName : *Doxygen::inputNameLinkedMap)
12436 {
12437 if (fileName->size()>1)
12438 {
12439 std::stable_sort(fileName->begin(),fileName->end(),[](const auto &f1,const auto &f2)
12440 {
12441 return qstricmp_sort(f1->absFilePath(),f2->absFilePath())<0;
12442 });
12443 }
12444 }
12445 if (Doxygen::inputNameLinkedMap->empty())
12446 {
12447 warn_uncond("No files to be processed, please check your settings, in particular INPUT, FILE_PATTERNS, and RECURSIVE\n");
12448 }
12449 g_s.end();
12450}
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 9036 of file doxygen.cpp.

9037{
9038 for (const auto &cd : *Doxygen::classLinkedMap)
9039 {
9040 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9041 if (cdm)
9042 {
9043 cdm->setAnonymousEnumType();
9044 }
9045 }
9046}
virtual void setAnonymousEnumType()=0

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

Referenced by parseInput().

◆ sortMemberLists()

void sortMemberLists ( )
static

Definition at line 8941 of file doxygen.cpp.

8942{
8943 // sort class member lists
8944 for (const auto &cd : *Doxygen::classLinkedMap)
8945 {
8946 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8947 if (cdm)
8948 {
8949 cdm->sortMemberLists();
8950 }
8951 }
8952
8953 // sort namespace member lists
8954 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8955 {
8957 if (ndm)
8958 {
8959 ndm->sortMemberLists();
8960 }
8961 }
8962
8963 // sort file member lists
8964 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8965 {
8966 for (const auto &fd : *fn)
8967 {
8968 fd->sortMemberLists();
8969 }
8970 }
8971
8972 // sort group member lists
8973 for (const auto &gd : *Doxygen::groupLinkedMap)
8974 {
8975 gd->sortMemberLists();
8976 }
8977
8979}
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 12109 of file doxygen.cpp.

12110{
12111 signal(SIGINT,SIG_DFL); // Re-register signal handler for default action
12112 Dir thisDir;
12113 msg("Cleaning up...\n");
12114 if (!Doxygen::filterDBFileName.isEmpty())
12115 {
12116 thisDir.remove(Doxygen::filterDBFileName.str());
12117 }
12118 killpg(0,SIGINT);
12120 exitTracing();
12121 exit(1);
12122}

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

Referenced by parseInput().

◆ stripTemplateSpecifiers()

QCString stripTemplateSpecifiers ( const QCString & s)

Definition at line 685 of file doxygen.cpp.

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

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

6102{
6103 auto dstIt = dst.begin();
6104 for (const Argument &sa : src)
6105 {
6106 QCString dstType = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.type.str());
6107 QCString dstArray = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.array.str());
6108 if (dstIt == dst.end())
6109 {
6110 Argument da = sa;
6111 da.type = dstType;
6112 da.array = dstArray;
6113 dst.push_back(da);
6114 dstIt = dst.end();
6115 }
6116 else
6117 {
6118 Argument da = *dstIt;
6119 da.type = dstType;
6120 da.array = dstArray;
6121 ++dstIt;
6122 }
6123 }
6124 dst.setConstSpecifier(src.constSpecifier());
6125 dst.setVolatileSpecifier(src.volatileSpecifier());
6126 dst.setPureSpecifier(src.pureSpecifier());
6128 srcTempArgLists,dstTempArgLists,
6129 src.trailingReturnType().str()));
6130 dst.setIsDeleted(src.isDeleted());
6131 dst.setRefQualifier(src.refQualifier());
6132 dst.setNoParameters(src.noParameters());
6133 //printf("substituteTemplatesInArgList: replacing %s with %s\n",
6134 // qPrint(argListToString(src)),qPrint(argListToString(dst))
6135 // );
6136}
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:6012
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 6012 of file doxygen.cpp.

6017{
6018 std::string dst;
6019 static const reg::Ex re(R"(\a\w*)");
6020 reg::Iterator it(src,re);
6022 //printf("type=%s\n",qPrint(sa->type));
6023 size_t p=0;
6024 for (; it!=end ; ++it) // for each word in srcType
6025 {
6026 const auto &match = *it;
6027 size_t i = match.position();
6028 size_t l = match.length();
6029 bool found=FALSE;
6030 dst+=src.substr(p,i-p);
6031 std::string name=match.str();
6032
6033 auto srcIt = srcTempArgLists.begin();
6034 auto dstIt = dstTempArgLists.begin();
6035 while (srcIt!=srcTempArgLists.end() && !found)
6036 {
6037 const ArgumentList *tdAli = nullptr;
6038 std::vector<Argument>::const_iterator tdaIt;
6039 if (dstIt!=dstTempArgLists.end())
6040 {
6041 tdAli = &(*dstIt);
6042 tdaIt = tdAli->begin();
6043 ++dstIt;
6044 }
6045
6046 const ArgumentList &tsaLi = *srcIt;
6047 for (auto tsaIt = tsaLi.begin(); tsaIt!=tsaLi.end() && !found; ++tsaIt)
6048 {
6049 Argument tsa = *tsaIt;
6050 const Argument *tda = nullptr;
6051 if (tdAli && tdaIt!=tdAli->end())
6052 {
6053 tda = &(*tdaIt);
6054 ++tdaIt;
6055 }
6056 //if (tda) printf("tsa=%s|%s tda=%s|%s\n",
6057 // qPrint(tsa.type),qPrint(tsa.name),
6058 // qPrint(tda->type),qPrint(tda->name));
6059 if (name==tsa.name.str())
6060 {
6061 if (tda && tda->name.isEmpty())
6062 {
6063 QCString tdaName = tda->name;
6064 QCString tdaType = tda->type;
6065 int vc=0;
6066 if (tdaType.startsWith("class ")) vc=6;
6067 else if (tdaType.startsWith("typename ")) vc=9;
6068 if (vc>0) // convert type=="class T" to type=="class" name=="T"
6069 {
6070 tdaName = tdaType.mid(vc);
6071 }
6072 if (!tdaName.isEmpty())
6073 {
6074 name=tdaName.str(); // substitute
6075 found=TRUE;
6076 }
6077 }
6078 }
6079 }
6080
6081 //printf(" srcList='%s' dstList='%s faList='%s'\n",
6082 // qPrint(argListToString(srclali.current())),
6083 // qPrint(argListToString(dstlali.current())),
6084 // funcTempArgList ? qPrint(argListToString(funcTempArgList)) : "<none>");
6085 ++srcIt;
6086 }
6087 dst+=name;
6088 p=i+l;
6089 }
6090 dst+=src.substr(p);
6091 //printf(" substituteTemplatesInString(%s)=%s\n",
6092 // qPrint(src),qPrint(dst));
6093 return dst;
6094}

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

4339{
4340 AUTO_TRACE();
4341
4342 // find matching function declaration and definitions.
4343 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4344 {
4345 //printf("memberName=%s count=%zu\n",qPrint(mn->memberName()),mn->size());
4346 /* find a matching function declaration and definition for this function */
4347 for (const auto &imdec : *mn)
4348 {
4349 MemberDefMutable *mdec = toMemberDefMutable(imdec.get());
4350 if (mdec &&
4351 (mdec->isPrototype() ||
4352 (mdec->isVariable() && mdec->isExternal())
4353 ))
4354 {
4355 for (const auto &imdef : *mn)
4356 {
4357 MemberDefMutable *mdef = toMemberDefMutable(imdef.get());
4358 if (mdef && mdec!=mdef &&
4359 mdec->getNamespaceDef()==mdef->getNamespaceDef())
4360 {
4362 }
4363 }
4364 }
4365 }
4366 }
4367}
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 4371 of file doxygen.cpp.

4372{
4373 AUTO_TRACE();
4374 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4375 {
4376 MemberDefMutable *mdef=nullptr,*mdec=nullptr;
4377 /* find a matching function declaration and definition for this function */
4378 for (const auto &imd : *mn)
4379 {
4380 MemberDefMutable *md = toMemberDefMutable(imd.get());
4381 if (md)
4382 {
4383 if (md->isPrototype())
4384 mdec=md;
4385 else if (md->isVariable() && md->isExternal())
4386 mdec=md;
4387
4388 if (md->isFunction() && !md->isStatic() && !md->isPrototype())
4389 mdef=md;
4390 else if (md->isVariable() && !md->isExternal() && !md->isStatic())
4391 mdef=md;
4392 }
4393
4394 if (mdef && mdec) break;
4395 }
4396 if (mdef && mdec)
4397 {
4398 const ArgumentList &mdefAl = mdef->argumentList();
4399 const ArgumentList &mdecAl = mdec->argumentList();
4400 if (
4401 matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdef->typeString(),const_cast<ArgumentList*>(&mdefAl),
4402 mdec->getOuterScope(),mdec->getFileDef(),mdec->typeString(),const_cast<ArgumentList*>(&mdecAl),
4403 TRUE,mdef->getLanguage()
4404 )
4405 ) /* match found */
4406 {
4407 AUTO_TRACE_ADD("merging references for mdec={} mdef={}",mdec->name(),mdef->name());
4408 mdef->mergeReferences(mdec);
4409 mdec->mergeReferences(mdef);
4410 mdef->mergeReferencedBy(mdec);
4411 mdec->mergeReferencedBy(mdef);
4412 }
4413 }
4414 }
4415}
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 4419 of file doxygen.cpp.

4420{
4421 AUTO_TRACE();
4422 // find match between function declaration and definition for
4423 // related functions
4424 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4425 {
4426 /* find a matching function declaration and definition for this function */
4427 // for each global function
4428 for (const auto &imd : *mn)
4429 {
4430 MemberDefMutable *md = toMemberDefMutable(imd.get());
4431 if (md)
4432 {
4433 //printf(" Function '%s'\n",qPrint(md->name()));
4434 MemberName *rmn = Doxygen::memberNameLinkedMap->find(md->name());
4435 if (rmn) // check if there is a member with the same name
4436 {
4437 //printf(" Member name found\n");
4438 // for each member with the same name
4439 for (const auto &irmd : *rmn)
4440 {
4441 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
4442 //printf(" Member found: related='%d'\n",rmd->isRelated());
4443 if (rmd &&
4444 (rmd->isRelated() || rmd->isForeign()) && // related function
4445 matchArguments2( md->getOuterScope(), md->getFileDef(), md->typeString(), &md->argumentList(),
4446 rmd->getOuterScope(),rmd->getFileDef(),rmd->typeString(),&rmd->argumentList(),
4447 TRUE,md->getLanguage()
4448 )
4449 )
4450 {
4451 AUTO_TRACE_ADD("Found related member '{}'",md->name());
4452 if (rmd->relatedAlso())
4453 md->setRelatedAlso(rmd->relatedAlso());
4454 else if (rmd->isForeign())
4455 md->makeForeign();
4456 else
4457 md->makeRelated();
4458 }
4459 }
4460 }
4461 }
4462 }
4463 }
4464}
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 4468 of file doxygen.cpp.

4469{
4470 AUTO_TRACE();
4471 for (const auto &[qualifiedName,bodyInfo] : Doxygen::staticInitMap)
4472 {
4473 size_t i=qualifiedName.rfind("::");
4474 if (i!=std::string::npos)
4475 {
4476 QCString scope = qualifiedName.substr(0,i);
4477 QCString name = qualifiedName.substr(i+2);
4478 MemberName *mn = Doxygen::memberNameLinkedMap->find(name);
4479 if (mn)
4480 {
4481 for (const auto &imd : *mn)
4482 {
4483 MemberDefMutable *md = toMemberDefMutable(imd.get());
4484 if (md && md->qualifiedName().str()==qualifiedName && md->isVariable())
4485 {
4486 AUTO_TRACE_ADD("found static member {} body [{}..{}]\n",
4487 md->qualifiedName(),bodyInfo.startLine,bodyInfo.endLine);
4488 md->setBodySegment(bodyInfo.defLine,
4489 bodyInfo.startLine,
4490 bodyInfo.endLine);
4491 }
4492 }
4493 }
4494 }
4495 }
4496}

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

8027{
8028 for (const auto &g : root->groups)
8029 {
8030 const GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
8031 if (gd)
8032 {
8033 MemberList *ml = gd->getMemberList(MemberListType::DecEnumMembers());
8034 if (ml)
8035 {
8036 MemberDefMutable *md = toMemberDefMutable(ml->find(name));
8037 if (md)
8038 {
8039 addEnumDocs(root,md);
8040 return TRUE;
8041 }
8042 }
8043 }
8044 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
8045 {
8046 warn(root->fileName, root->startLine,
8047 "Found non-existing group '{}' for the command '{}', ignoring command",
8048 g.groupname, Grouping::getGroupPriName( g.pri )
8049 );
8050 }
8051 }
8052
8053 return FALSE;
8054}
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 11352 of file doxygen.cpp.

11353{
11355 msg("Doxygen version {0}\nCopyright Dimitri van Heesch 1997-2025\n\n"
11356 "You can use Doxygen in a number of ways:\n\n"
11357 "1) Use Doxygen to generate a template configuration file*:\n"
11358 " {1} [-s] -g [configName]\n\n"
11359 "2) Use Doxygen to update an old configuration file*:\n"
11360 " {1} [-s] -u [configName]\n\n"
11361 "3) Use Doxygen to generate documentation using an existing "
11362 "configuration file*:\n"
11363 " {1} [configName]\n\n"
11364 "4) Use Doxygen to generate a template file controlling the layout of the\n"
11365 " generated documentation:\n"
11366 " {1} -l [layoutFileName]\n\n"
11367 " In case layoutFileName is omitted DoxygenLayout.xml will be used as filename.\n"
11368 " If - is used for layoutFileName Doxygen will write to standard output.\n\n"
11369 "5) Use Doxygen to generate a template style sheet file for RTF, HTML or Latex.\n"
11370 " RTF: {1} -w rtf styleSheetFile\n"
11371 " HTML: {1}-w html headerFile footerFile styleSheetFile [configFile]\n"
11372 " LaTeX: {1} -w latex headerFile footerFile styleSheetFile [configFile]\n\n"
11373 "6) Use Doxygen to generate a rtf extensions file\n"
11374 " {1} -e rtf extensionsFile\n\n"
11375 " If - is used for extensionsFile Doxygen will write to standard output.\n\n"
11376 "7) Use Doxygen to compare the used configuration file with the template configuration file\n"
11377 " {1} -x [configFile]\n\n"
11378 " Use Doxygen to compare the used configuration file with the template configuration file\n"
11379 " without replacing the environment variables or CMake type replacement variables\n"
11380 " {1} -x_noenv [configFile]\n\n"
11381 "8) Use Doxygen to show a list of built-in emojis.\n"
11382 " {1} -f emoji outputFileName\n\n"
11383 " If - is used for outputFileName Doxygen will write to standard output.\n\n"
11384 "*) If -s is specified the comments of the configuration items in the config file will be omitted.\n"
11385 " If configName is omitted 'Doxyfile' will be used as a default.\n"
11386 " If - is used for configFile Doxygen will write / read the configuration to /from standard output / input.\n\n"
11387 "If -q is used for a Doxygen documentation run, Doxygen will see this as if QUIET=YES has been set.\n\n"
11388 "-v print version string, -V print extended version information\n"
11389 "-h,-? prints usage help information\n"
11390 "{1} -d prints additional usage flags for debugging purposes\n",versionString,name);
11391}

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

Referenced by readConfiguration().

◆ version()

void version ( const bool extended)
static

Definition at line 11324 of file doxygen.cpp.

11325{
11327 QCString versionString = getFullVersion();
11328 msg("{}\n",versionString);
11329 if (extended)
11330 {
11331 QCString extVers;
11332 if (!extVers.isEmpty()) extVers+= ", ";
11333 extVers += "sqlite3 ";
11334 extVers += sqlite3_libversion();
11335#if USE_LIBCLANG
11336 if (!extVers.isEmpty()) extVers+= ", ";
11337 extVers += "clang support ";
11338 extVers += CLANG_VERSION_STRING;
11339#endif
11340 if (!extVers.isEmpty())
11341 {
11342 int lastComma = extVers.findRev(',');
11343 if (lastComma != -1) extVers = extVers.replace(lastComma,1," and");
11344 msg(" with {}.\n",extVers);
11345 }
11346 }
11347}
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 8389 of file doxygen.cpp.

8390{
8391 // for each member name
8392 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8393 {
8394 // for each member definition
8395 for (const auto &imd : *mn)
8396 {
8397 MemberDefMutable *md = toMemberDefMutable(imd.get());
8398 if (md)
8399 {
8401 }
8402 }
8403 }
8404 // for each member name
8405 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8406 {
8407 // for each member definition
8408 for (const auto &imd : *mn)
8409 {
8410 MemberDefMutable *md = toMemberDefMutable(imd.get());
8411 if (md)
8412 {
8414 }
8415 }
8416 }
8417}
static void correctMemberProperties(MemberDefMutable *md)

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

Referenced by parseInput().

◆ warnUndocumentedNamespaces()

void warnUndocumentedNamespaces ( )
static

Definition at line 5347 of file doxygen.cpp.

5348{
5349 AUTO_TRACE();
5350 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5351 {
5352 if (!nd->hasDocumentation())
5353 {
5354 if ((guessSection(nd->getDefFileName()).isHeader() ||
5355 nd->getLanguage() == SrcLangExt::Fortran) && // Fortran doesn't have header files.
5356 !Config_getBool(HIDE_UNDOC_NAMESPACES) // undocumented namespaces are visible
5357 )
5358 {
5359 warn_undoc(nd->getDefFileName(),nd->getDefLine(), "{} {} is not documented.",
5360 nd->getLanguage() == SrcLangExt::Fortran ? "Module" : "Namespace",
5361 nd->name());
5362 }
5363 }
5364 }
5365}

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

Referenced by parseInput().

◆ writeTagFile()

void writeTagFile ( )
static

Definition at line 12125 of file doxygen.cpp.

12126{
12127 QCString generateTagFile = Config_getString(GENERATE_TAGFILE);
12128 if (generateTagFile.isEmpty()) return;
12129
12130 std::ofstream f = Portable::openOutputStream(generateTagFile);
12131 if (!f.is_open())
12132 {
12133 err("cannot open tag file {} for writing\n", generateTagFile);
12134 return;
12135 }
12136 TextStream tagFile(&f);
12137 tagFile << "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>\n";
12138 tagFile << "<tagfile doxygen_version=\"" << getDoxygenVersion() << "\"";
12139 std::string gitVersion = getGitVersion();
12140 if (!gitVersion.empty())
12141 {
12142 tagFile << " doxygen_gitid=\"" << gitVersion << "\"";
12143 }
12144 tagFile << ">\n";
12145
12146 // for each file
12147 for (const auto &fn : *Doxygen::inputNameLinkedMap)
12148 {
12149 for (const auto &fd : *fn)
12150 {
12151 if (fd->isLinkableInProject()) fd->writeTagFile(tagFile);
12152 }
12153 }
12154 // for each class
12155 for (const auto &cd : *Doxygen::classLinkedMap)
12156 {
12157 ClassDefMutable *cdm = toClassDefMutable(cd.get());
12158 if (cdm && cdm->isLinkableInProject())
12159 {
12160 cdm->writeTagFile(tagFile);
12161 }
12162 }
12163 // for each concept
12164 for (const auto &cd : *Doxygen::conceptLinkedMap)
12165 {
12166 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
12167 if (cdm && cdm->isLinkableInProject())
12168 {
12169 cdm->writeTagFile(tagFile);
12170 }
12171 }
12172 // for each namespace
12173 for (const auto &nd : *Doxygen::namespaceLinkedMap)
12174 {
12176 if (ndm && nd->isLinkableInProject())
12177 {
12178 ndm->writeTagFile(tagFile);
12179 }
12180 }
12181 // for each group
12182 for (const auto &gd : *Doxygen::groupLinkedMap)
12183 {
12184 if (gd->isLinkableInProject()) gd->writeTagFile(tagFile);
12185 }
12186 // for each module
12187 for (const auto &mod : ModuleManager::instance().modules())
12188 {
12189 if (mod->isLinkableInProject()) mod->writeTagFile(tagFile);
12190 }
12191 // for each page
12192 for (const auto &pd : *Doxygen::pageLinkedMap)
12193 {
12194 if (pd->isLinkableInProject()) pd->writeTagFile(tagFile);
12195 }
12196 // for requirements
12198 // for each directory
12199 for (const auto &dd : *Doxygen::dirLinkedMap)
12200 {
12201 if (dd->isLinkableInProject()) dd->writeTagFile(tagFile);
12202 }
12203 if (Doxygen::mainPage) Doxygen::mainPage->writeTagFile(tagFile);
12204
12205 tagFile << "</tagfile>\n";
12206}
virtual void writeTagFile(TextStream &) const =0
virtual void writeTagFile(TextStream &)=0
virtual void writeTagFile(TextStream &)=0
void writeTagFile(TextStream &tagFile)

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

Referenced by generateOutput().

Variable Documentation

◆ g_classEntries

◆ g_commentFileName

QCString g_commentFileName
static

Definition at line 193 of file doxygen.cpp.

Referenced by parseInput(), and readConfiguration().

◆ g_compoundKeywords

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

Definition at line 199 of file doxygen.cpp.

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

Referenced by buildVarList(), and filterMemberDocumentation().

◆ g_dumpSymbolMap

bool g_dumpSymbolMap = FALSE
static

Definition at line 192 of file doxygen.cpp.

Referenced by generateOutput(), and readConfiguration().

◆ g_inputFiles

◆ g_outputList

◆ g_s

◆ g_singleComment

bool g_singleComment =false
static

Definition at line 194 of file doxygen.cpp.

Referenced by parseInput(), and readConfiguration().

◆ g_successfulRun

bool g_successfulRun = FALSE
static

Definition at line 191 of file doxygen.cpp.

Referenced by exitDoxygen(), and generateOutput().

◆ g_usingClassMap

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

Definition at line 2208 of file doxygen.cpp.

Referenced by findUsingDeclImports(), and parseInput().

◆ g_usingDeclarations

StringSet g_usingDeclarations
static

Definition at line 190 of file doxygen.cpp.

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