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

9197{
9198 list.push_back(cd);
9199 for (const auto &innerCdi : cd->getClasses())
9200 {
9201 ClassDefMutable *innerCd = toClassDefMutable(innerCdi);
9202 if (innerCd)
9203 {
9204 AUTO_TRACE("innerCd={} isLinkable={} isImplicitTemplateInstance={} protectLevelVisible={} embeddedInOuterScope={}",
9205 innerCd->name(),innerCd->isLinkableInProject(),innerCd->isImplicitTemplateInstance(),protectionLevelVisible(innerCd->protection()),
9206 innerCd->isEmbeddedInOuterScope());
9207 }
9208 if (innerCd && innerCd->isLinkableInProject() && !innerCd->isImplicitTemplateInstance() &&
9209 protectionLevelVisible(innerCd->protection()) &&
9210 !innerCd->isEmbeddedInOuterScope()
9211 )
9212 {
9213 list.push_back(innerCd);
9214 addClassAndNestedClasses(list,innerCd);
9215 }
9216 }
9217}
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:9196
bool protectionLevelVisible(Protection prot)
Definition util.cpp:5940

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:3681
QCString mangleCSharpGenericName(const QCString &name)
Definition util.cpp:6916
QCString stripTemplateSpecifiersFromScope(const QCString &fullName, bool parentOnly, QCString *pLastScopeStripped, QCString scopeName, bool allowArtificial)
Definition util.cpp:4511

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

9586{
9587 md->setDocumentation(root->doc,root->docFile,root->docLine);
9588 md->setDocsForDefinition(!root->proto);
9589 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9590 if (md->inbodyDocumentation().isEmpty())
9591 {
9593 }
9594 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
9595 {
9596 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
9597 md->setBodyDef(root->fileDef());
9598 }
9600 md->setMaxInitLines(root->initLines);
9602 md->setRefItems(root->sli);
9603 md->setRequirementReferences(root->rqli);
9604 md->addQualifiers(root->qualifiers);
9605 if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
9606 addMemberToGroups(root,md);
9608}
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 8014 of file doxygen.cpp.

8015{
8016 AUTO_TRACE();
8017 // documentation outside a compound overrides the documentation inside it
8018 {
8019 md->setDocumentation(root->doc,root->docFile,root->docLine);
8020 md->setDocsForDefinition(!root->proto);
8021 }
8022
8023 // brief descriptions inside a compound override the documentation
8024 // outside it
8025 {
8026 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
8027 }
8028
8029 if (md->inbodyDocumentation().isEmpty() || !root->parent()->name.isEmpty())
8030 {
8032 }
8033
8034 if (root->mGrpId!=-1 && md->getMemberGroupId()==-1)
8035 {
8036 md->setMemberGroupId(root->mGrpId);
8037 }
8038
8040 md->setRefItems(root->sli);
8041 md->setRequirementReferences(root->rqli);
8042
8043 const GroupDef *gd=md->getGroupDef();
8044 if (gd==nullptr && !root->groups.empty()) // member not grouped but out-of-line documentation is
8045 {
8046 addMemberToGroups(root,md);
8047 }
8049}
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 7764 of file doxygen.cpp.

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

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

3857{
3858 QCString scope = sc;
3859
3860 // new global function
3862 auto md = createMemberDef(
3863 root->fileName,root->startLine,root->startColumn,
3864 root->type,name,root->args,root->exception,
3865 root->protection,root->virt,root->isStatic,Relationship::Member,
3867 !root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
3868 root->argList,root->metaData);
3869 auto mmd = toMemberDefMutable(md.get());
3870 mmd->setTagInfo(root->tagInfo());
3871 mmd->setLanguage(root->lang);
3872 mmd->setId(root->id);
3873 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3874 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3875 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3876 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
3877 mmd->setDocsForDefinition(!root->proto);
3878 mmd->setTypeConstraints(root->typeConstr);
3879 //md->setBody(root->body);
3880 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3881 FileDef *fd=root->fileDef();
3882 mmd->setBodyDef(fd);
3883 mmd->addSectionsToDefinition(root->anchors);
3884 mmd->setMemberSpecifiers(root->spec);
3885 mmd->setVhdlSpecifiers(root->vhdlSpec);
3886 mmd->setMemberGroupId(root->mGrpId);
3887 mmd->setRequiresClause(root->req);
3888 mmd->setExplicitExternal(root->explicitExternal,root->fileName,root->startLine,root->startColumn);
3889
3890 NamespaceDefMutable *nd = nullptr;
3891 // see if the function is inside a namespace that was not part of
3892 // the name already (in that case nd should be non-zero already)
3893 if (root->parent()->section.isNamespace())
3894 {
3895 //QCString nscope=removeAnonymousScopes(root->parent()->name);
3896 QCString nscope=root->parent()->name;
3897 if (!nscope.isEmpty())
3898 {
3899 nd = getResolvedNamespaceMutable(nscope);
3900 }
3901 }
3902 else if (root->parent()->section.isGroupDoc() && !scope.isEmpty())
3903 {
3905 }
3906
3907 if (!scope.isEmpty())
3908 {
3910 if (sep!="::")
3911 {
3912 scope = substitute(scope,"::",sep);
3913 }
3914 scope+=sep;
3915 }
3916
3917 if (Config_getBool(HIDE_SCOPE_NAMES) || root->lang==SrcLangExt::Python) scope = "";
3918 QCString def;
3919 //QCString optArgs = root->argList.empty() ? QCString() : root->args;
3920 if (!root->type.isEmpty())
3921 {
3922 def=root->type+" "+scope+name; //+optArgs;
3923 }
3924 else
3925 {
3926 def=scope+name; //+optArgs;
3927 }
3928 AUTO_TRACE("new non-member function type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
3929 root->type,scope,rname,root->args,root->proto,def);
3930 mmd->setDefinition(def);
3932 mmd->addQualifiers(root->qualifiers);
3933
3934 mmd->setRefItems(root->sli);
3935 mmd->setRequirementReferences(root->rqli);
3936 if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
3937 {
3938 // add member to namespace
3939 mmd->setNamespace(nd);
3940 nd->insertMember(md.get());
3941 }
3942 if (fd)
3943 {
3944 // add member to the file (we do this even if we have already
3945 // inserted it into the namespace)
3946 mmd->setFileDef(fd);
3947 fd->insertMember(md.get());
3948 }
3949
3950 addMemberToGroups(root,md.get());
3952 if (root->relatesType == RelatesType::Simple) // if this is a relatesalso command,
3953 // allow find Member to pick it up
3954 {
3955 root->markAsProcessed(); // Otherwise we have finished with this entry.
3956 }
3957
3958 // add member to the list of file members
3960 mn->push_back(std::move(md));
3961}
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:5900

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

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

3609{
3610 FileDef *fd = root->fileDef();
3611 enum MemberType type = root->section.isExportedInterface() ? MemberType::Interface : MemberType::Service;
3612 QCString fileName = root->fileName;
3613 if (fileName.isEmpty() && root->tagInfo())
3614 {
3615 fileName = root->tagInfo()->tagName;
3616 }
3617 auto md = createMemberDef(
3618 fileName, root->startLine, root->startColumn, root->type, rname,
3619 "", "", root->protection, root->virt, root->isStatic, Relationship::Member,
3620 type, ArgumentList(), root->argList, root->metaData);
3621 auto mmd = toMemberDefMutable(md.get());
3622 mmd->setTagInfo(root->tagInfo());
3623 mmd->setMemberClass(cd);
3624 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3625 mmd->setDocsForDefinition(false);
3626 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3627 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3628 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3629 mmd->setMemberSpecifiers(root->spec);
3630 mmd->setVhdlSpecifiers(root->vhdlSpec);
3631 mmd->setMemberGroupId(root->mGrpId);
3632 mmd->setTypeConstraints(root->typeConstr);
3633 mmd->setLanguage(root->lang);
3634 mmd->setBodyDef(fd);
3635 mmd->setFileDef(fd);
3636 mmd->addSectionsToDefinition(root->anchors);
3637 QCString const def = root->type + " " + rname;
3638 mmd->setDefinition(def);
3640 mmd->addQualifiers(root->qualifiers);
3641
3642 AUTO_TRACE("Interface member: fileName='{}' type='{}' name='{}' mtype='{}' prot={} virt={} state={} proto={} def='{}'",
3643 fileName,root->type,rname,type,root->protection,root->virt,root->isStatic,root->proto,def);
3644
3645 // add member to the class cd
3646 cd->insertMember(md.get());
3647 // also add the member as a "base" (to get nicer diagrams)
3648 // "optional" interface/service get Protected which turns into dashed line
3649 BaseInfo base(rname,
3650 root->spec.isOptional() ? Protection::Protected : Protection::Public, Specifier::Normal);
3651 TemplateNameMap templateNames;
3652 findClassRelation(root,cd,cd,&base,templateNames,DocumentedOnly,true) ||
3653 findClassRelation(root,cd,cd,&base,templateNames,Undocumented,true);
3654 // add file to list of used files
3655 cd->insertUsedFile(fd);
3656
3657 addMemberToGroups(root,md.get());
3659 root->markAsProcessed();
3660 mmd->setRefItems(root->sli);
3661 mmd->setRequirementReferences(root->rqli);
3662
3663 // add member to the global list of all members
3664 MemberName *mn = Doxygen::memberNameLinkedMap->add(rname);
3665 mn->push_back(std::move(md));
3666}
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:4927
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 5591 of file doxygen.cpp.

5592{
5593 AUTO_TRACE();
5594 applyToAllDefinitions([](auto* obj) { obj->addListReferences(); });
5595}
static void applyToAllDefinitions(Func func)
Definition doxygen.cpp:5526

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

6175{
6176 AUTO_TRACE();
6177 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
6178 ClassDefMutable *cd=nullptr;
6179 if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClassMutable(scopeName)))
6180 {
6181 AUTO_TRACE_ADD("Local objective C method '{}' scopeName='{}'",root->name,scopeName);
6182 auto md = createMemberDef(
6183 root->fileName,root->startLine,root->startColumn,
6184 funcType,funcName,funcArgs,exceptions,
6185 root->protection,root->virt,root->isStatic,Relationship::Member,
6187 auto mmd = toMemberDefMutable(md.get());
6188 mmd->setTagInfo(root->tagInfo());
6189 mmd->setLanguage(root->lang);
6190 mmd->setId(root->id);
6191 mmd->makeImplementationDetail();
6192 mmd->setMemberClass(cd);
6193 mmd->setDefinition(funcDecl);
6195 mmd->addQualifiers(root->qualifiers);
6196 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6197 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6198 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6199 mmd->setDocsForDefinition(!root->proto);
6200 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6201 mmd->addSectionsToDefinition(root->anchors);
6202 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6203 FileDef *fd=root->fileDef();
6204 mmd->setBodyDef(fd);
6205 mmd->setMemberSpecifiers(spec);
6206 mmd->setVhdlSpecifiers(root->vhdlSpec);
6207 mmd->setMemberGroupId(root->mGrpId);
6208 cd->insertMember(md.get());
6209 cd->insertUsedFile(fd);
6210 mmd->setRefItems(root->sli);
6211 mmd->setRequirementReferences(root->rqli);
6212
6214 mn->push_back(std::move(md));
6215 }
6216 else
6217 {
6218 // local objective C method found for class without interface
6219 }
6220}

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

5620{
5621 if (md==nullptr) return;
5622 AUTO_TRACE("scope='{}' name='{}' args='{}' funcDecl='{}' mSpec={}",
5623 root->parent()->name,md->name(),md->argsString(),funcDecl,spec);
5624 if (!root->section.isDoc()) // @fn or @var does not need to specify the complete definition, so don't overwrite it
5625 {
5626 QCString fDecl=funcDecl;
5627 // strip extern specifier
5628 fDecl.stripPrefix("extern ");
5629 md->setDefinition(fDecl);
5630 }
5632 md->addQualifiers(root->qualifiers);
5634 const NamespaceDef *nd=md->getNamespaceDef();
5635 QCString fullName;
5636 if (cd)
5637 fullName = cd->name();
5638 else if (nd)
5639 fullName = nd->name();
5640
5641 if (!fullName.isEmpty()) fullName+="::";
5642 fullName+=md->name();
5643 FileDef *rfd=root->fileDef();
5644
5645 // TODO determine scope based on root not md
5646 Definition *rscope = md->getOuterScope();
5647
5648 const ArgumentList &mdAl = md->argumentList();
5649 if (al)
5650 {
5651 ArgumentList mergedAl = *al;
5652 //printf("merging arguments (1) docs=%d\n",root->doc.isEmpty());
5653 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedAl,!root->doc.isEmpty());
5654 }
5655 else
5656 {
5657 if (
5658 matchArguments2( md->getOuterScope(), md->getFileDef(),md->typeString(),const_cast<ArgumentList*>(&mdAl),
5659 rscope,rfd,root->type,&root->argList,
5660 TRUE, root->lang
5661 )
5662 )
5663 {
5664 //printf("merging arguments (2)\n");
5665 ArgumentList mergedArgList = root->argList;
5666 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.isEmpty());
5667 }
5668 }
5669 if (over_load) // the \overload keyword was used
5670 {
5672 if (!root->doc.isEmpty())
5673 {
5674 doc+="<p>";
5675 doc+=root->doc;
5676 }
5677 md->setDocumentation(doc,root->docFile,root->docLine);
5679 md->setDocsForDefinition(!root->proto);
5680 }
5681 else
5682 {
5683 //printf("overwrite!\n");
5684 md->setDocumentation(root->doc,root->docFile,root->docLine);
5685 md->setDocsForDefinition(!root->proto);
5686
5687 //printf("overwrite!\n");
5688 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
5689
5690 if (
5691 (md->inbodyDocumentation().isEmpty() ||
5692 !root->parent()->name.isEmpty()
5693 ) && !root->inbodyDocs.isEmpty()
5694 )
5695 {
5697 }
5698 }
5699
5700 //printf("initializer: '%s'(isEmpty=%d) '%s'(isEmpty=%d)\n",
5701 // qPrint(md->initializer()),md->initializer().isEmpty(),
5702 // qPrint(root->initializer),root->initializer.isEmpty()
5703 // );
5704 std::string rootInit = root->initializer.str();
5705 if (md->initializer().isEmpty() && !rootInit.empty())
5706 {
5707 //printf("setInitializer\n");
5708 md->setInitializer(rootInit);
5709 }
5710 if (md->requiresClause().isEmpty() && !root->req.isEmpty())
5711 {
5712 md->setRequiresClause(root->req);
5713 }
5714
5715 md->setMaxInitLines(root->initLines);
5716
5717 if (rfd)
5718 {
5719 if ((md->getStartBodyLine()==-1 && root->bodyLine!=-1)
5720 )
5721 {
5722 //printf("Setting new body segment [%d,%d]\n",root->bodyLine,root->endBodyLine);
5723 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
5724 md->setBodyDef(rfd);
5725 }
5726
5727 md->setRefItems(root->sli);
5728 md->setRequirementReferences(root->rqli);
5729 }
5730
5732 md->addQualifiers(root->qualifiers);
5733
5734 md->mergeMemberSpecifiers(spec);
5736 addMemberToGroups(root,md);
5738 if (cd) cd->insertUsedFile(rfd);
5739 //printf("root->mGrpId=%d\n",root->mGrpId);
5740 if (root->mGrpId!=-1)
5741 {
5742 if (md->getMemberGroupId()!=-1)
5743 {
5744 if (md->getMemberGroupId()!=root->mGrpId)
5745 {
5746 warn(root->fileName,root->startLine,
5747 "member {} belongs to two different groups. The second one found here will be ignored.",
5748 md->name()
5749 );
5750 }
5751 }
5752 else // set group id
5753 {
5754 //printf("setMemberGroupId=%d md=%s\n",root->mGrpId,qPrint(md->name()));
5755 md->setMemberGroupId(root->mGrpId);
5756 }
5757 }
5758 md->addQualifiers(root->qualifiers);
5759}
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:2001
void mergeArguments(ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
Definition util.cpp:2101
QCString getOverloadDocs()
Definition util.cpp:4073

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

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

6590{
6591 AUTO_TRACE("funcType={} funcName={} funcArgs={} funcDecl={} spec={}",funcType,funcName,funcArgs,funcDecl,spec);
6592 MemberDef *declMd=nullptr;
6593 for (const auto &md : *mn)
6594 {
6595 if (md->getClassDef()==cd)
6596 {
6597 // TODO: we should probably also check for matching arguments
6598 declMd = md.get();
6599 break;
6600 }
6601 }
6603 ArgumentList tArgList;
6604 // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6605 auto md = createMemberDef(
6606 root->fileName,root->startLine,root->startColumn,
6607 funcType,funcName,funcArgs,exceptions,
6608 declMd ? declMd->protection() : root->protection,
6609 root->virt,root->isStatic,Relationship::Member,
6610 mtype,tArgList,root->argList,root->metaData);
6611 auto mmd = toMemberDefMutable(md.get());
6612 //printf("new specialized member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6613 mmd->setTagInfo(root->tagInfo());
6614 mmd->setLanguage(root->lang);
6615 mmd->setId(root->id);
6616 mmd->setMemberClass(cd);
6617 mmd->setTemplateSpecialization(TRUE);
6618 mmd->setTypeConstraints(root->typeConstr);
6619 mmd->setDefinition(funcDecl);
6621 mmd->addQualifiers(root->qualifiers);
6622 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6623 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6624 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6625 mmd->setDocsForDefinition(!root->proto);
6626 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6627 mmd->addSectionsToDefinition(root->anchors);
6628 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6629 FileDef *fd=root->fileDef();
6630 mmd->setBodyDef(fd);
6631 mmd->setMemberSpecifiers(spec);
6632 mmd->setVhdlSpecifiers(root->vhdlSpec);
6633 mmd->setMemberGroupId(root->mGrpId);
6634 cd->insertMember(md.get());
6635 mmd->setRefItems(root->sli);
6636 mmd->setRequirementReferences(root->rqli);
6637
6638 mn->push_back(std::move(md));
6639}

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

8210{
8211 auto &index = Index::instance();
8212 // for each class member name
8213 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8214 {
8215 // for each member definition
8216 for (const auto &md : *mn)
8217 {
8218 index.addClassMemberNameToIndex(md.get());
8219 if (md->getModuleDef())
8220 {
8221 index.addModuleMemberNameToIndex(md.get());
8222 }
8223 }
8224 }
8225 // for each file/namespace function name
8226 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8227 {
8228 // for each member definition
8229 for (const auto &md : *mn)
8230 {
8231 if (md->getNamespaceDef())
8232 {
8233 index.addNamespaceMemberNameToIndex(md.get());
8234 }
8235 else
8236 {
8237 index.addFileMemberNameToIndex(md.get());
8238 }
8239 if (md->getModuleDef())
8240 {
8241 index.addModuleMemberNameToIndex(md.get());
8242 }
8243 }
8244 }
8245
8246 index.sortMemberIndexLists();
8247}
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 9326 of file doxygen.cpp.

9327{
9328 // for each class
9329 for (const auto &cd : *Doxygen::classLinkedMap)
9330 {
9331 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9332 if (cdm)
9333 {
9335 }
9336 }
9337 // for each file
9338 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9339 {
9340 for (const auto &fd : *fn)
9341 {
9342 fd->addMembersToMemberGroup();
9343 }
9344 }
9345 // for each namespace
9346 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9347 {
9349 if (ndm)
9350 {
9352 }
9353 }
9354 // for each group
9355 for (const auto &gd : *Doxygen::groupLinkedMap)
9356 {
9357 gd->addMembersToMemberGroup();
9358 }
9360}
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 3720 of file doxygen.cpp.

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

6646{
6647 // for unique overloaded member we allow the class to be
6648 // omitted, this is to be Qt compatible. Using this should
6649 // however be avoided, because it is error prone
6650 bool sameClass=false;
6651 if (mn->size()>0)
6652 {
6653 // check if all members with the same name are also in the same class
6654 sameClass = std::equal(mn->begin()+1,mn->end(),mn->begin(),
6655 [](const auto &md1,const auto &md2)
6656 { return md1->getClassDef()->name()==md2->getClassDef()->name(); });
6657 }
6658 if (sameClass)
6659 {
6660 MemberDefMutable *mdm = toMemberDefMutable(mn->front().get());
6661 ClassDefMutable *cd = mdm ? mdm->getClassDefMutable() : nullptr;
6662 if (cd==nullptr) return;
6663
6665 if (root->mtype==MethodTypes::Signal) mtype=MemberType::Signal;
6666 else if (root->mtype==MethodTypes::Slot) mtype=MemberType::Slot;
6667 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType::DCOP;
6668
6669 // new overloaded member function
6670 std::unique_ptr<ArgumentList> tArgList =
6671 getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6672 //printf("new related member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6673 auto md = createMemberDef(
6674 root->fileName,root->startLine,root->startColumn,
6675 funcType,funcName,funcArgs,exceptions,
6676 root->protection,root->virt,root->isStatic,Relationship::Related,
6677 mtype,tArgList ? *tArgList : ArgumentList(),root->argList,root->metaData);
6678 auto mmd = toMemberDefMutable(md.get());
6679 mmd->setTagInfo(root->tagInfo());
6680 mmd->setLanguage(root->lang);
6681 mmd->setId(root->id);
6682 mmd->setTypeConstraints(root->typeConstr);
6683 mmd->setMemberClass(cd);
6684 mmd->setDefinition(funcDecl);
6686 mmd->addQualifiers(root->qualifiers);
6688 doc+="<p>";
6689 doc+=root->doc;
6690 mmd->setDocumentation(doc,root->docFile,root->docLine);
6691 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6692 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6693 mmd->setDocsForDefinition(!root->proto);
6694 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6695 mmd->addSectionsToDefinition(root->anchors);
6696 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6697 FileDef *fd=root->fileDef();
6698 mmd->setBodyDef(fd);
6699 mmd->setMemberSpecifiers(spec);
6700 mmd->setVhdlSpecifiers(root->vhdlSpec);
6701 mmd->setMemberGroupId(root->mGrpId);
6702 cd->insertMember(md.get());
6703 cd->insertUsedFile(fd);
6704 mmd->setRefItems(root->sli);
6705 mmd->setRequirementReferences(root->rqli);
6706
6707 mn->push_back(std::move(md));
6708 }
6709}
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 5583 of file doxygen.cpp.

5584{
5585 AUTO_TRACE();
5586 applyToAllDefinitions([](auto* obj) { obj->addRequirementReferences(); });
5587}

References applyToAllDefinitions(), and AUTO_TRACE.

Referenced by parseInput().

◆ addSourceReferences()

void addSourceReferences ( )
static

Definition at line 8844 of file doxygen.cpp.

8845{
8846 // add source references for class definitions
8847 for (const auto &cd : *Doxygen::classLinkedMap)
8848 {
8849 const FileDef *fd=cd->getBodyDef();
8850 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8851 {
8852 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8853 }
8854 }
8855 // add source references for concept definitions
8856 for (const auto &cd : *Doxygen::conceptLinkedMap)
8857 {
8858 const FileDef *fd=cd->getBodyDef();
8859 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8860 {
8861 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8862 }
8863 }
8864 // add source references for namespace definitions
8865 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8866 {
8867 const FileDef *fd=nd->getBodyDef();
8868 if (fd && nd->isLinkableInProject() && nd->getStartDefLine()!=-1)
8869 {
8870 const_cast<FileDef*>(fd)->addSourceRef(nd->getStartDefLine(),nd.get(),nullptr);
8871 }
8872 }
8873
8874 // add source references for member names
8875 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8876 {
8877 for (const auto &md : *mn)
8878 {
8879 //printf("class member %s: def=%s body=%d link?=%d\n",
8880 // qPrint(md->name()),
8881 // md->getBodyDef()?qPrint(md->getBodyDef()->name()):"<none>",
8882 // md->getStartBodyLine(),md->isLinkableInProject());
8883 const FileDef *fd=md->getBodyDef();
8884 if (fd &&
8885 md->getStartDefLine()!=-1 &&
8886 md->isLinkableInProject() &&
8888 )
8889 {
8890 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8891 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8892 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8893 }
8894 }
8895 }
8896 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8897 {
8898 for (const auto &md : *mn)
8899 {
8900 const FileDef *fd=md->getBodyDef();
8901 //printf("member %s body=[%d,%d] fd=%p link=%d parseSources=%d\n",
8902 // qPrint(md->name()),
8903 // md->getStartBodyLine(),md->getEndBodyLine(),fd,
8904 // md->isLinkableInProject(),
8905 // Doxygen::parseSourcesNeeded);
8906 if (fd &&
8907 md->getStartDefLine()!=-1 &&
8908 md->isLinkableInProject() &&
8910 )
8911 {
8912 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8913 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8914 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8915 }
8916 }
8917 }
8918}
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 8251 of file doxygen.cpp.

8252{
8253 for (const auto &cd : *Doxygen::classLinkedMap)
8254 {
8255 if (cd->isLinkableInProject())
8256 {
8257 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8258 if (Doxygen::searchIndex.enabled())
8259 {
8260 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
8261 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
8262 }
8263 }
8264 }
8265
8266 for (const auto &cd : *Doxygen::conceptLinkedMap)
8267 {
8268 if (cd->isLinkableInProject())
8269 {
8270 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8271 if (Doxygen::searchIndex.enabled())
8272 {
8273 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
8274 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
8275 }
8276 }
8277 }
8278
8279 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8280 {
8281 if (nd->isLinkableInProject())
8282 {
8283 Doxygen::indexList->addIndexItem(nd.get(),nullptr);
8284 if (Doxygen::searchIndex.enabled())
8285 {
8286 Doxygen::searchIndex.setCurrentDoc(nd.get(),nd->anchor(),FALSE);
8287 Doxygen::searchIndex.addWord(nd->localName(),TRUE);
8288 }
8289 }
8290 }
8291
8292 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8293 {
8294 for (const auto &fd : *fn)
8295 {
8296 if (Doxygen::searchIndex.enabled() && fd->isLinkableInProject())
8297 {
8298 Doxygen::searchIndex.setCurrentDoc(fd.get(),fd->anchor(),FALSE);
8299 Doxygen::searchIndex.addWord(fd->localName(),TRUE);
8300 }
8301 }
8302 }
8303
8304 auto addWordsForTitle = [](const Definition *d,const QCString &anchor,const QCString &title)
8305 {
8306 Doxygen::indexList->addIndexItem(d,nullptr,QCString(),filterTitle(title));
8307 if (Doxygen::searchIndex.enabled())
8308 {
8309 Doxygen::searchIndex.setCurrentDoc(d,anchor,false);
8310 std::string s = title.str();
8311 static const reg::Ex re(R"(\a[\w-]*)");
8312 reg::Iterator it(s,re);
8314 for (; it!=end ; ++it)
8315 {
8316 const auto &match = *it;
8317 std::string matchStr = match.str();
8318 Doxygen::searchIndex.addWord(matchStr,true);
8319 }
8320 }
8321 };
8322
8323 for (const auto &gd : *Doxygen::groupLinkedMap)
8324 {
8325 if (gd->isLinkableInProject())
8326 {
8327 addWordsForTitle(gd.get(),gd->anchor(),gd->groupTitle());
8328 }
8329 }
8330
8331 for (const auto &pd : *Doxygen::pageLinkedMap)
8332 {
8333 if (pd->isLinkableInProject())
8334 {
8335 addWordsForTitle(pd.get(),pd->anchor(),pd->title());
8336 }
8337 }
8338
8340 {
8341 addWordsForTitle(Doxygen::mainPage.get(),Doxygen::mainPage->anchor(),Doxygen::mainPage->title());
8342 }
8343
8344 auto addMemberToSearchIndex = [](const MemberDef *md)
8345 {
8346 if (Doxygen::searchIndex.enabled())
8347 {
8348 Doxygen::searchIndex.setCurrentDoc(md,md->anchor(),FALSE);
8349 QCString ln=md->localName();
8350 QCString qn=md->qualifiedName();
8351 Doxygen::searchIndex.addWord(ln,TRUE);
8352 if (ln!=qn)
8353 {
8354 Doxygen::searchIndex.addWord(qn,TRUE);
8355 if (md->getClassDef())
8356 {
8357 Doxygen::searchIndex.addWord(md->getClassDef()->displayName(),TRUE);
8358 }
8359 if (md->getNamespaceDef())
8360 {
8361 Doxygen::searchIndex.addWord(md->getNamespaceDef()->displayName(),TRUE);
8362 }
8363 }
8364 }
8365 };
8366
8367 auto getScope = [](const MemberDef *md)
8368 {
8369 const Definition *scope = nullptr;
8370 if (md->getGroupDef()) scope = md->getGroupDef();
8371 else if (md->getClassDef()) scope = md->getClassDef();
8372 else if (md->getNamespaceDef()) scope = md->getNamespaceDef();
8373 else if (md->getFileDef()) scope = md->getFileDef();
8374 return scope;
8375 };
8376
8377 auto addMemberToIndices = [addMemberToSearchIndex,getScope](const MemberDef *md)
8378 {
8379 if (md->isLinkableInProject())
8380 {
8381 if (!(md->isEnumerate() && md->isAnonymous()))
8382 {
8383 Doxygen::indexList->addIndexItem(getScope(md),md);
8385 }
8386 if (md->isEnumerate())
8387 {
8388 for (const auto &fmd : md->enumFieldList())
8389 {
8390 Doxygen::indexList->addIndexItem(getScope(fmd),fmd);
8392 }
8393 }
8394 }
8395 };
8396
8397 // for each class member name
8398 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8399 {
8400 // for each member definition
8401 for (const auto &md : *mn)
8402 {
8403 addMemberToIndices(md.get());
8404 }
8405 }
8406 // for each file/namespace function name
8407 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8408 {
8409 // for each member definition
8410 for (const auto &md : *mn)
8411 {
8412 addMemberToIndices(md.get());
8413 }
8414 }
8415}
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:5613

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

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

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 if (lang==SrcLangExt::Python)
2508 {
2509 def="type "+name+args;
2510 }
2511 else
2512 {
2513 def="using "+name;
2514 }
2515 }
2516 else
2517 {
2518 def=type+" "+name+args;
2519 }
2520 }
2521 else
2522 {
2523 if (root->spec.isAlias()) // turn 'typedef B C::A' into 'using C::A'
2524 {
2525 if (lang==SrcLangExt::Python)
2526 {
2527 def="type "+qualScope+scopeSeparator+name+args;
2528 }
2529 else
2530 {
2531 def="using "+qualScope+scopeSeparator+name;
2532 }
2533 }
2534 else
2535 {
2536 def=type+" "+qualScope+scopeSeparator+name+args;
2537 }
2538 }
2539 }
2540 else
2541 {
2542 if (Config_getBool(HIDE_SCOPE_NAMES))
2543 {
2544 def=name+args;
2545 }
2546 else
2547 {
2548 def=qualScope+scopeSeparator+name+args;
2549 }
2550 }
2551 def.stripPrefix("static ");
2552
2553 // see if the member is already found in the same scope
2554 // (this may be the case for a static member that is initialized
2555 // outside the class)
2557 if (mn)
2558 {
2559 for (const auto &imd : *mn)
2560 {
2561 //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n",
2562 // md->getClassDef(),cd,qPrint(type),md->typeString());
2563 MemberDefMutable *md = toMemberDefMutable(imd.get());
2564 if (md &&
2565 md->getClassDef()==cd &&
2566 ((lang==SrcLangExt::Python && type.isEmpty() && !md->typeString().isEmpty()) ||
2568 // member already in the scope
2569 {
2570
2571 if (root->lang==SrcLangExt::ObjC &&
2572 root->mtype==MethodTypes::Property &&
2574 { // Objective-C 2.0 property
2575 // turn variable into a property
2576 md->setProtection(root->protection);
2578 }
2579 addMemberDocs(root,md,def,nullptr,FALSE,root->spec);
2580 AUTO_TRACE_ADD("Member already found!");
2581 return md;
2582 }
2583 }
2584 }
2585
2586 QCString fileName = root->fileName;
2587 if (fileName.isEmpty() && root->tagInfo())
2588 {
2589 fileName = root->tagInfo()->tagName;
2590 }
2591
2592 // new member variable, typedef or enum value
2593 auto md = createMemberDef(
2594 fileName,root->startLine,root->startColumn,
2595 type,name,args,root->exception,
2596 prot,Specifier::Normal,root->isStatic,related,
2597 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
2598 ArgumentList(), root->metaData);
2599 auto mmd = toMemberDefMutable(md.get());
2600 mmd->setTagInfo(root->tagInfo());
2601 mmd->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope())
2602 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
2603 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2604 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2605 mmd->setDefinition(def);
2606 mmd->setBitfields(root->bitfields);
2607 mmd->addSectionsToDefinition(root->anchors);
2608 mmd->setFromAnonymousScope(fromAnnScope);
2609 mmd->setFromAnonymousMember(fromAnnMemb);
2610 //md->setIndentDepth(indentDepth);
2611 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2612 mmd->setInitializer(root->initializer.str());
2613 mmd->setMaxInitLines(root->initLines);
2614 mmd->setMemberGroupId(root->mGrpId);
2615 mmd->setMemberSpecifiers(root->spec);
2616 mmd->setVhdlSpecifiers(root->vhdlSpec);
2617 mmd->setReadAccessor(root->read);
2618 mmd->setWriteAccessor(root->write);
2620 mmd->setHidden(root->hidden);
2621 mmd->setArtificial(root->artificial);
2622 mmd->setLanguage(root->lang);
2623 mmd->setId(root->id);
2624 addMemberToGroups(root,md.get());
2626 mmd->setBodyDef(root->fileDef());
2627 mmd->addQualifiers(root->qualifiers);
2628
2629 AUTO_TRACE_ADD("Adding new member to class '{}'",cd->name());
2630 cd->insertMember(md.get());
2631 mmd->setRefItems(root->sli);
2632 mmd->setRequirementReferences(root->rqli);
2633
2634 cd->insertUsedFile(root->fileDef());
2635 root->markAsProcessed();
2636
2637 if (mtype==MemberType::Typedef)
2638 {
2639 resolveTemplateInstanceInType(root,cd,md.get());
2640 }
2641
2642 // add the member to the global list
2643 MemberDef *result = md.get();
2644 mn = Doxygen::memberNameLinkedMap->add(name);
2645 mn->push_back(std::move(md));
2646
2647 return result;
2648}
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:4855

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

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

12013{
12014 AUTO_TRACE();
12015 Doxygen::globalNamespaceDef = createNamespaceDef("<globalScope>",1,1,"<globalScope>");
12025
12026 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
12027
12028 /* Set the global html file extension. */
12029 Doxygen::htmlFileExtension = Config_getString(HTML_FILE_EXTENSION);
12030
12031
12033 Config_getBool(CALLER_GRAPH) ||
12034 Config_getBool(REFERENCES_RELATION) ||
12035 Config_getBool(REFERENCED_BY_RELATION);
12036
12037 /**************************************************************************
12038 * Add custom extension mappings
12039 **************************************************************************/
12040
12041 const StringVector &extMaps = Config_getList(EXTENSION_MAPPING);
12042 for (const auto &mapping : extMaps)
12043 {
12044 QCString mapStr = mapping;
12045 int i=mapStr.find('=');
12046 if (i==-1)
12047 {
12048 continue;
12049 }
12050 else
12051 {
12052 QCString ext = mapStr.left(i).stripWhiteSpace().lower();
12053 QCString language = mapStr.mid(i+1).stripWhiteSpace().lower();
12054 if (ext.isEmpty() || language.isEmpty())
12055 {
12056 continue;
12057 }
12058
12059 if (!updateLanguageMapping(ext,language))
12060 {
12061 err("Failed to map file extension '{}' to unsupported language '{}'.\n"
12062 "Check the EXTENSION_MAPPING setting in the config file.\n",
12063 ext,language);
12064 }
12065 else
12066 {
12067 msg("Adding custom extension mapping: '{}' will be treated as language '{}'\n",
12068 ext,language);
12069 }
12070 }
12071 }
12072 // create input file exncodings
12073
12074 // check INPUT_ENCODING
12075 void *cd = portable_iconv_open("UTF-8",Config_getString(INPUT_ENCODING).data());
12076 if (cd==reinterpret_cast<void *>(-1))
12077 {
12078 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
12079 "Check the 'INPUT_ENCODING' setting in the config file!\n",
12080 Config_getString(INPUT_ENCODING),strerror(errno));
12081 }
12082 else
12083 {
12085 }
12086
12087 // check and split INPUT_FILE_ENCODING
12088 const StringVector &fileEncod = Config_getList(INPUT_FILE_ENCODING);
12089 for (const auto &mapping : fileEncod)
12090 {
12091 QCString mapStr = mapping;
12092 int i=mapStr.find('=');
12093 if (i==-1)
12094 {
12095 continue;
12096 }
12097 else
12098 {
12099 QCString pattern = mapStr.left(i).stripWhiteSpace().lower();
12100 QCString encoding = mapStr.mid(i+1).stripWhiteSpace().lower();
12101 if (pattern.isEmpty() || encoding.isEmpty())
12102 {
12103 continue;
12104 }
12105 cd = portable_iconv_open("UTF-8",encoding.data());
12106 if (cd==reinterpret_cast<void *>(-1))
12107 {
12108 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
12109 "Check the 'INPUT_FILE_ENCODING' setting in the config file!\n",
12110 encoding,strerror(errno));
12111 }
12112 else
12113 {
12115 }
12116
12117 Doxygen::inputFileEncodingList.emplace_back(pattern, encoding);
12118 }
12119 }
12120
12121 // add predefined macro name to a dictionary
12122 const StringVector &expandAsDefinedList =Config_getList(EXPAND_AS_DEFINED);
12123 for (const auto &s : expandAsDefinedList)
12124 {
12126 }
12127
12128 // read aliases and store them in a dictionary
12129 readAliases();
12130
12131 // store number of spaces in a tab into Doxygen::spaces
12132 int tabSize = Config_getInt(TAB_SIZE);
12133 Doxygen::spaces.resize(tabSize);
12134 for (int sp=0; sp<tabSize; sp++) Doxygen::spaces.at(sp)=' ';
12135 Doxygen::spaces.at(tabSize)='\0';
12136}
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:5089

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

5527{
5528 for (const auto &cd : *Doxygen::classLinkedMap)
5529 {
5530 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5531 if (cdm)
5532 {
5533 func(cdm);
5534 }
5535 }
5536
5537 for (const auto &cd : *Doxygen::conceptLinkedMap)
5538 {
5539 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
5540 if (cdm)
5541 {
5542 func(cdm);
5543 }
5544 }
5545
5546 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5547 {
5548 for (const auto &fd : *fn)
5549 {
5550 func(fd.get());
5551 }
5552 }
5553
5554 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5555 {
5557 if (ndm)
5558 {
5559 func(ndm);
5560 }
5561 }
5562
5563 for (const auto &gd : *Doxygen::groupLinkedMap)
5564 {
5565 func(gd.get());
5566 }
5567
5568 for (const auto &pd : *Doxygen::pageLinkedMap)
5569 {
5570 func(pd.get());
5571 }
5572
5573 for (const auto &dd : *Doxygen::dirLinkedMap)
5574 {
5575 func(dd.get());
5576 }
5577
5578 func(&ModuleManager::instance());
5579}
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 8588 of file doxygen.cpp.

8589{
8590 // merge the member list of base classes into the inherited classes.
8591 for (const auto &cd : *Doxygen::classLinkedMap)
8592 {
8593 if (// !cd->isReference() && // not an external class
8594 cd->subClasses().empty() && // is a root of the hierarchy
8595 !cd->baseClasses().empty()) // and has at least one base class
8596 {
8597 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8598 if (cdm)
8599 {
8600 //printf("*** merging members for %s\n",qPrint(cd->name()));
8601 cdm->mergeMembers();
8602 }
8603 }
8604 }
8605 // now sort the member list of all members for all classes.
8606 for (const auto &cd : *Doxygen::classLinkedMap)
8607 {
8608 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8609 if (cdm)
8610 {
8611 cdm->sortAllMembersList();
8612 }
8613 }
8614}
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 8923 of file doxygen.cpp.

8924{
8925 AUTO_TRACE();
8926 for (const auto &s : g_inputFiles)
8927 {
8928 auto it = Doxygen::macroDefinitions.find(s);
8930 {
8931 for (const auto &def : it->second)
8932 {
8933 auto md = createMemberDef(
8934 def.fileName,def.lineNr,def.columnNr,
8935 "#define",def.name,def.args,QCString(),
8936 Protection::Public,Specifier::Normal,FALSE,Relationship::Member,MemberType::Define,
8937 ArgumentList(),ArgumentList(),"");
8938 auto mmd = toMemberDefMutable(md.get());
8939
8940 if (!def.args.isEmpty())
8941 {
8942 mmd->moveArgumentList(stringToArgumentList(SrcLangExt::Cpp, def.args));
8943 }
8944 mmd->setInitializer(def.definition);
8945 mmd->setFileDef(def.fileDef);
8946 mmd->setDefinition("#define "+def.name);
8947
8948 MemberName *mn=Doxygen::functionNameLinkedMap->add(def.name);
8949 if (def.fileDef)
8950 {
8951 const MemberList *defMl = def.fileDef->getMemberList(MemberListType::DocDefineMembers());
8952 if (defMl)
8953 {
8954 const MemberDef *defMd = defMl->findRev(def.name);
8955 if (defMd) // definition already stored
8956 {
8957 mmd->setRedefineCount(defMd->redefineCount()+1);
8958 }
8959 }
8960 def.fileDef->insertMember(md.get());
8961 }
8962 AUTO_TRACE_ADD("adding macro {} with definition {}",def.name,def.definition);
8963 mn->push_back(std::move(md));
8964 }
8965 }
8966 }
8967}
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 3554 of file doxygen.cpp.

3555{
3556 if (!root->name.isEmpty() &&
3557 root->section.isVariable() &&
3558 root->type.find("dictionary<")!=-1 // it's a dictionary
3559 )
3560 {
3561 AUTO_TRACE();
3562 addVariable(root);
3563 }
3564 for (const auto &e : root->children())
3565 if (!e->section.isEnum())
3566 buildDictionaryList(e.get());
3567}
static void buildDictionaryList(const Entry *root)
Definition doxygen.cpp:3554
static void addVariable(const Entry *root, int isFuncPtr=-1)
Definition doxygen.cpp:3180

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

10017{
10018 if ((root->section.isExample() || root->section.isExampleLineno()) && !root->name.isEmpty())
10019 {
10020 if (Doxygen::exampleLinkedMap->find(root->name))
10021 {
10022 warn(root->fileName,root->startLine,"Example {} was already documented. Ignoring documentation found here.",root->name);
10023 }
10024 else
10025 {
10026 PageDef *pd = Doxygen::exampleLinkedMap->add(root->name,
10027 createPageDef(root->fileName,root->startLine,
10028 root->name,root->brief+root->doc+root->inbodyDocs,root->args));
10029 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
10030 pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE));
10032 pd->setLanguage(root->lang);
10033 pd->setShowLineNo(root->section.isExampleLineno());
10034
10035 //we don't add example to groups
10036 //addExampleToGroups(root,pd);
10037 }
10038 }
10039 for (const auto &e : root->children()) buildExampleList(e.get());
10040}
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:98
virtual void setFileName(const QCString &name)=0
virtual void setShowLineNo(bool)=0
static void buildExampleList(Entry *root)
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:3488

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

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

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

3669{
3670 if (root->section.isExportedInterface() || root->section.isIncludedService())
3671 {
3672 AUTO_TRACE("Exported interface/included service: type='{}' scope='{}' name='{}' args='{}'"
3673 " relates='{}' relatesType='{}' file='{}' line={} bodyLine={} #tArgLists={}"
3674 " mGrpId={} spec={} proto={} docFile='{}'",
3675 root->type, root->parent()->name, root->name, root->args,
3676 root->relates, root->relatesType, root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(),
3677 root->mGrpId, root->spec, root->proto, root->docFile);
3678
3680
3681 if (!rname.isEmpty())
3682 {
3683 QCString scope = root->parent()->name;
3684 ClassDefMutable *cd = getClassMutable(scope);
3685 assert(cd);
3686 if (cd && ((ClassDef::Interface == cd->compoundType()) ||
3687 (ClassDef::Service == cd->compoundType()) ||
3689 {
3691 }
3692 else
3693 {
3694 assert(false); // was checked by scanner.l
3695 }
3696 }
3697 else if (rname.isEmpty())
3698 {
3699 warn(root->fileName,root->startLine,
3700 "Illegal member name found.");
3701 }
3702 }
3703 // can only have these in IDL anyway
3704 switch (root->lang)
3705 {
3706 case SrcLangExt::Unknown: // fall through (root node always is Unknown)
3707 case SrcLangExt::IDL:
3708 for (const auto &e : root->children()) buildInterfaceAndServiceList(e.get());
3709 break;
3710 default:
3711 return; // nothing to do here
3712 }
3713}
@ 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:3605
static void buildInterfaceAndServiceList(const Entry *root)
Definition doxygen.cpp:3668

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

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

9773{
9774 if (root->section.isPageDoc())
9775 {
9776 if (!root->name.isEmpty())
9777 {
9778 addRelatedPage(root);
9779 }
9780 }
9781 else if (root->section.isMainpageDoc())
9782 {
9783 QCString title=root->args.stripWhiteSpace();
9784 if (title.isEmpty()) title=theTranslator->trMainPage();
9785 //QCString name = Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9786 QCString name = "index";
9787 addRefItem(root->sli,
9788 name,
9789 theTranslator->trPage(TRUE,TRUE),
9790 name,
9791 title,
9792 QCString(),nullptr
9793 );
9794 }
9795 for (const auto &e : root->children()) buildPageList(e.get());
9796}
static void buildPageList(Entry *root)
Definition doxygen.cpp:9772
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:4808

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

9761{
9762 if (root->section.isRequirementDoc())
9763 {
9765 }
9766 for (const auto &e : root->children()) buildRequirementsList(e.get());
9767}
static RequirementManager & instance()
void addRequirement(Entry *e)
static void buildRequirementsList(Entry *root)
Definition doxygen.cpp:9760

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

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

3537{
3538 if (!root->name.isEmpty() &&
3539 root->section.isVariable() &&
3540 root->type.find("sequence<")!=-1 // it's a sequence
3541 )
3542 {
3543 AUTO_TRACE();
3544 addVariable(root);
3545 }
3546 for (const auto &e : root->children())
3547 if (!e->section.isEnum())
3548 buildSequenceList(e.get());
3549}
static void buildSequenceList(const Entry *root)
Definition doxygen.cpp:3536

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

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

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

3574{
3575 //printf("buildVarList(%s) section=%08x\n",qPrint(rootNav->name()),rootNav->section());
3576 int isFuncPtr=-1;
3577 if (!root->name.isEmpty() &&
3578 (root->type.isEmpty() || g_compoundKeywords.find(root->type.str())==g_compoundKeywords.end()) &&
3579 (
3580 (root->section.isVariable() && // it's a variable
3581 root->type.find("typedef ")==-1 // and not a typedef
3582 ) ||
3583 (root->section.isFunction() && // or maybe a function pointer variable
3584 (isFuncPtr=findFunctionPtr(root->type.str(),root->lang))!=-1
3585 ) ||
3586 (root->section.isFunction() && // class variable initialized by constructor
3588 )
3589 )
3590 ) // documented variable
3591 {
3592 AUTO_TRACE();
3593 addVariable(root,isFuncPtr);
3594 }
3595 for (const auto &e : root->children())
3596 if (!e->section.isEnum())
3597 buildVarList(e.get());
3598}
static void buildVarList(const Entry *root)
Definition doxygen.cpp:3573
static bool isVarWithConstructor(const Entry *root)
Definition doxygen.cpp:2968
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 12001 of file doxygen.cpp.

12002{
12003 AUTO_TRACE();
12004
12009}
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 12483 of file doxygen.cpp.

12484{
12485 if (Config_getBool(MARKDOWN_SUPPORT))
12486 {
12487 QCString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
12488 if (mdfileAsMainPage.isEmpty()) return;
12489 FileInfo fi(mdfileAsMainPage.data());
12490 if (!fi.exists())
12491 {
12492 warn_uncond("Specified markdown mainpage '{}' does not exist\n",mdfileAsMainPage);
12493 return;
12494 }
12495 bool ambig = false;
12496 if (findFileDef(Doxygen::inputNameLinkedMap,fi.absFilePath(),ambig)==nullptr)
12497 {
12498 warn_uncond("Specified markdown mainpage '{}' has not been defined as input file\n",mdfileAsMainPage);
12499 return;
12500 }
12501 }
12502}
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 9911 of file doxygen.cpp.

9912{
9913 for (const auto &pd : *Doxygen::pageLinkedMap)
9914 {
9915 Definition *ppd = pd->getOuterScope();
9916 while (ppd)
9917 {
9918 if (ppd==pd.get())
9919 {
9920 term("page defined {} with label {} is a subpage "
9921 "of itself! Please remove this cyclic dependency.\n",
9922 warn_line(pd->docFile(),pd->docLine()),pd->name());
9923 }
9924 ppd=ppd->getOuterScope();
9925 }
9926 }
9927}

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

Referenced by parseInput().

◆ cleanUpDoxygen()

void cleanUpDoxygen ( )

Definition at line 11523 of file doxygen.cpp.

11524{
11528
11529 delete Doxygen::indexList;
11538 Doxygen::mainPage.reset();
11542 Doxygen::globalScope = nullptr;
11544 delete theTranslator;
11545 delete g_outputList;
11546
11551 delete Doxygen::dirLinkedMap;
11552 delete Doxygen::symbolMap;
11553}
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 9301 of file doxygen.cpp.

9302{
9303 // for each file
9304 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9305 {
9306 for (const auto &fd : *fn)
9307 {
9308 fd->combineUsingRelations();
9309 }
9310 }
9311
9312 // for each namespace
9313 NamespaceDefSet visitedNamespaces;
9314 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9315 {
9317 if (ndm)
9318 {
9319 ndm->combineUsingRelations(visitedNamespaces);
9320 }
9321 }
9322}
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 10410 of file doxygen.cpp.

10411{
10412 std::ofstream f;
10413 bool fileOpened=openOutputFile("-",f);
10414 if (fileOpened)
10415 {
10416 TextStream t(&f);
10417 Config::compareDoxyfile(t,diffList);
10418 }
10419 else
10420 {
10421 term("Cannot open stdout for writing\n");
10422 }
10423}
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:6299

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

Referenced by readConfiguration().

◆ computeClassRelations()

void computeClassRelations ( )
static

Definition at line 5396 of file doxygen.cpp.

5397{
5398 AUTO_TRACE();
5399 for (const auto &[name,root] : g_classEntries)
5400 {
5401 QCString bName = extractClassName(root);
5402 ClassDefMutable *cd = getClassMutable(bName);
5403 if (cd)
5404 {
5406 }
5407 size_t numMembers = cd ? cd->memberNameInfoLinkedMap().size() : 0;
5408 if ((cd==nullptr || (!cd->hasDocumentation() && !cd->isReference())) && numMembers>0 && !bName.endsWith("::"))
5409 {
5410 if (!root->name.isEmpty() && root->name.find('@')==-1 && // normal name
5411 (guessSection(root->fileName).isHeader() ||
5412 Config_getBool(EXTRACT_LOCAL_CLASSES)) && // not defined in source file
5413 protectionLevelVisible(root->protection) && // hidden by protection
5414 !Config_getBool(HIDE_UNDOC_CLASSES) // undocumented class are visible
5415 )
5416 warn_undoc(root->fileName,root->startLine, "Compound {} is not documented.", root->name);
5417 }
5418 }
5419}
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:5299
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:4753
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 11555 of file doxygen.cpp.

11556{
11557 //printf("computeIdealCacheParam(v=%u)\n",v);
11558
11559 int r=0;
11560 while (v!=0)
11561 {
11562 v >>= 1;
11563 r++;
11564 }
11565 // r = log2(v)
11566
11567 // convert to a valid cache size value
11568 return std::max(0,std::min(r-16,9));
11569}

Referenced by generateOutput().

◆ computeMemberReferences()

void computeMemberReferences ( )
static

Definition at line 5490 of file doxygen.cpp.

5491{
5492 AUTO_TRACE();
5493 for (const auto &cd : *Doxygen::classLinkedMap)
5494 {
5495 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5496 if (cdm)
5497 {
5498 cdm->computeAnchors();
5499 }
5500 }
5501 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5502 {
5503 for (const auto &fd : *fn)
5504 {
5505 fd->computeAnchors();
5506 }
5507 }
5508 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5509 {
5511 if (ndm)
5512 {
5513 ndm->computeAnchors();
5514 }
5515 }
5516 for (const auto &gd : *Doxygen::groupLinkedMap)
5517 {
5518 gd->computeAnchors();
5519 }
5520}
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 8531 of file doxygen.cpp.

8532{
8533 for (const auto &cd : *Doxygen::classLinkedMap)
8534 {
8535 if (cd->isLinkable())
8536 {
8537 for (const auto &bcd : cd->baseClasses())
8538 {
8540 }
8541 }
8542 }
8543}
static void computeMemberRelationsForBaseClass(const ClassDef *cd, const BaseClassDef *bcd)
Definition doxygen.cpp:8451

References Doxygen::classLinkedMap, and computeMemberRelationsForBaseClass().

Referenced by parseInput().

◆ computeMemberRelationsForBaseClass()

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

Definition at line 8451 of file doxygen.cpp.

8452{
8453 for (const auto &mn : cd->memberNameInfoLinkedMap()) // for each member in class cd with a unique name
8454 {
8455 for (const auto &imd : *mn) // for each member with a given name
8456 {
8457 MemberDefMutable *md = toMemberDefMutable(imd->memberDef());
8458 if (md && (md->isFunction() || md->isCSharpProperty())) // filter on reimplementable members
8459 {
8460 ClassDef *mbcd = bcd->classDef;
8461 if (mbcd && mbcd->isLinkable()) // filter on linkable classes
8462 {
8463 const auto &bmn = mbcd->memberNameInfoLinkedMap();
8464 const auto &bmni = bmn.find(mn->memberName());
8465 if (bmni) // there are base class members with the same name
8466 {
8467 for (const auto &ibmd : *bmni) // for base class member with that name
8468 {
8469 MemberDefMutable *bmd = toMemberDefMutable(ibmd->memberDef());
8470 if (bmd) // not part of an inline namespace
8471 {
8472 auto lang = bmd->getLanguage();
8473 auto compType = mbcd->compoundType();
8474 if (bmd->virtualness()!=Specifier::Normal ||
8475 lang==SrcLangExt::Python ||
8476 lang==SrcLangExt::Java ||
8477 lang==SrcLangExt::PHP ||
8478 compType==ClassDef::Interface ||
8479 compType==ClassDef::Protocol)
8480 {
8481 const ArgumentList &bmdAl = bmd->argumentList();
8482 const ArgumentList &mdAl = md->argumentList();
8483 //printf(" Base argList='%s'\n Super argList='%s'\n",
8484 // qPrint(argListToString(bmdAl)),
8485 // qPrint(argListToString(mdAl))
8486 // );
8487 if (
8488 lang==SrcLangExt::Python ||
8489 matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),bmd->typeString(),&bmdAl,
8490 md->getOuterScope(), md->getFileDef(), md->typeString(),&mdAl,
8491 TRUE,lang
8492 )
8493 )
8494 {
8495 if (lang==SrcLangExt::Python && md->name().startsWith("__")) continue; // private members do not reimplement
8496 //printf("match!\n");
8497 const MemberDef *rmd = md->reimplements();
8498 if (rmd==nullptr) // not already assigned
8499 {
8500 //printf("%s: setting (new) reimplements member %s\n",qPrint(md->qualifiedName()),qPrint(bmd->qualifiedName()));
8501 md->setReimplements(bmd);
8502 }
8503 //printf("%s: add reimplementedBy member %s\n",qPrint(bmd->qualifiedName()),qPrint(md->qualifiedName()));
8504 bmd->insertReimplementedBy(md);
8505 }
8506 else
8507 {
8508 //printf("no match!\n");
8509 }
8510 }
8511 }
8512 }
8513 }
8514 }
8515 }
8516 }
8517 }
8518
8519 // do also for indirect base classes
8520 for (const auto &bbcd : bcd->classDef->baseClasses())
8521 {
8523 }
8524}
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 9881 of file doxygen.cpp.

9882{
9883 if ((root->section.isPageDoc() || root->section.isMainpageDoc()) && !root->name.isEmpty())
9884 {
9885 PageDef *pd = root->section.isPageDoc() ?
9886 Doxygen::pageLinkedMap->find(root->name) :
9887 Doxygen::mainPage.get();
9888 if (pd)
9889 {
9890 for (const BaseInfo &bi : root->extends)
9891 {
9892 PageDef *subPd = Doxygen::pageLinkedMap->find(bi.name);
9893 if (pd==subPd)
9894 {
9895 term("page defined {} with label {} is a direct "
9896 "subpage of itself! Please remove this cyclic dependency.\n",
9897 warn_line(pd->docFile(),pd->docLine()),pd->name());
9898 }
9899 else if (subPd)
9900 {
9901 pd->addInnerCompound(subPd);
9902 //printf("*** Added subpage relation: %s->%s\n",
9903 // qPrint(pd->name()),qPrint(subPd->name()));
9904 }
9905 }
9906 }
9907 }
9908 for (const auto &e : root->children()) computePageRelations(e.get());
9909}
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:9881
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 5421 of file doxygen.cpp.

5422{
5423 AUTO_TRACE();
5424 for (const auto &[name,root] : g_classEntries)
5425 {
5426 QCString bName=stripAnonymousNamespaceScope(root->name);
5429 // strip any anonymous scopes first
5430 if (cd && !cd->getTemplateInstances().empty())
5431 {
5432 AUTO_TRACE_ADD("Template class '{}'",cd->name());
5433 for (const auto &ti : cd->getTemplateInstances()) // for each template instance
5434 {
5435 ClassDefMutable *tcd=toClassDefMutable(ti.classDef);
5436 if (tcd)
5437 {
5438 AUTO_TRACE_ADD("Template instance '{}'",tcd->name());
5439 QCString templSpec = ti.templSpec;
5440 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(tcd->getLanguage(),templSpec);
5441 for (const BaseInfo &bi : root->extends)
5442 {
5443 // check if the base class is a template argument
5444 BaseInfo tbi = bi;
5445 const ArgumentList &tl = cd->templateArguments();
5446 if (!tl.empty())
5447 {
5448 TemplateNameMap baseClassNames = tcd->getTemplateBaseClassNames();
5449 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,bi.name.str());
5450 // for each template name that we inherit from we need to
5451 // substitute the formal with the actual arguments
5452 TemplateNameMap actualTemplateNames;
5453 for (const auto &tn_kv : templateNames)
5454 {
5455 size_t templIndex = tn_kv.second;
5456 Argument actArg;
5457 bool hasActArg=FALSE;
5458 if (templIndex<templArgs->size())
5459 {
5460 actArg=templArgs->at(templIndex);
5461 hasActArg=TRUE;
5462 }
5463 if (hasActArg &&
5464 baseClassNames.find(actArg.type.str())!=baseClassNames.end() &&
5465 actualTemplateNames.find(actArg.type.str())==actualTemplateNames.end()
5466 )
5467 {
5468 actualTemplateNames.emplace(actArg.type.str(),static_cast<int>(templIndex));
5469 }
5470 }
5471
5472 tbi.name = substituteTemplateArgumentsInString(bi.name,tl,templArgs.get());
5473 // find a documented base class in the correct scope
5474 if (!findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE))
5475 {
5476 // no documented base class -> try to find an undocumented one
5477 findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,Undocumented,TRUE);
5478 }
5479 }
5480 }
5481 }
5482 }
5483 }
5484 }
5485}
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:4534
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:4349

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

9021{
9022 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
9023 if (numThreads>1)
9024 {
9025 ThreadPool threadPool(numThreads);
9026 std::vector < std::future< void > > results;
9027 // queue the work
9028 for (const auto &[name,symList] : *Doxygen::symbolMap)
9029 {
9030 for (const auto &def : symList)
9031 {
9033 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
9034 {
9035 auto processTooltip = [dm]() {
9036 dm->computeTooltip();
9037 };
9038 results.emplace_back(threadPool.queue(processTooltip));
9039 }
9040 }
9041 }
9042 // wait for the results
9043 for (auto &f : results)
9044 {
9045 f.get();
9046 }
9047 }
9048 else
9049 {
9050 for (const auto &[name,symList] : *Doxygen::symbolMap)
9051 {
9052 for (const auto &def : symList)
9053 {
9055 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
9056 {
9057 dm->computeTooltip();
9058 }
9059 }
9060 }
9061 }
9062}
virtual void computeTooltip()=0
Class managing a pool of worker threads.
Definition threadpool.h:48
static bool isSymbolHidden(const Definition *d)
Definition doxygen.cpp:9013

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

Referenced by parseInput().

◆ computeVerifiedDotPath()

void computeVerifiedDotPath ( )
static

Definition at line 10338 of file doxygen.cpp.

10339{
10340 // check dot path
10341 QCString dotPath = Config_getString(DOT_PATH);
10342 if (!dotPath.isEmpty())
10343 {
10344 FileInfo fi(dotPath.str());
10345 if (!(fi.exists() && fi.isFile()) )// not an existing user specified path + exec
10346 {
10347 dotPath = dotPath+"/dot"+Portable::commandExtension();
10348 FileInfo dp(dotPath.str());
10349 if (!dp.exists() || !dp.isFile())
10350 {
10351 warn_uncond("the dot tool could not be found as '{}'\n",dotPath);
10352 dotPath = "dot";
10353 dotPath += Portable::commandExtension();
10354 }
10355 }
10356#if defined(_WIN32) // convert slashes
10357 size_t l=dotPath.length();
10358 for (size_t i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\';
10359#endif
10360 }
10361 else
10362 {
10363 dotPath = "dot";
10364 dotPath += Portable::commandExtension();
10365 }
10366 Doxygen::verifiedDotPath = dotPath;
10368}
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 10604 of file doxygen.cpp.

10605{
10606 for (const auto &fileName : files)
10607 {
10608 if (!fileName.empty())
10609 {
10610 FileInfo fi(fileName);
10611 if (!fi.exists())
10612 {
10613 err("Extra file '{}' specified in {} does not exist!\n", fileName,filesOption);
10614 }
10615 else if (fi.isDir())
10616 {
10617 err("Extra file '{}' specified in {} is a directory, it has to be a file!\n", fileName,filesOption);
10618 }
10619 else
10620 {
10621 QCString destFileName = outputOption+"/"+fi.fileName();
10622 Doxygen::indexList->addImageFile(fi.fileName());
10623 copyFile(fileName, destFileName);
10624 }
10625 }
10626 }
10627}
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:5860

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

10580{
10581 QCString projectIcon = Config_getString(PROJECT_ICON);
10582 if (!projectIcon.isEmpty())
10583 {
10584 FileInfo fi(projectIcon.str());
10585 if (!fi.exists())
10586 {
10587 err("Project icon '{}' specified by PROJECT_ICON does not exist!\n",projectIcon);
10588 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10589 }
10590 else if (fi.isDir())
10591 {
10592 err("Project icon '{}' specified by PROJECT_ICON is a directory, it has to be a file!\n",projectIcon);
10593 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10594 }
10595 else
10596 {
10597 QCString destFileName = outputOption+"/"+fi.fileName();
10598 copyFile(projectIcon,destFileName);
10599 Doxygen::indexList->addImageFile(fi.fileName());
10600 }
10601 }
10602}
#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 10470 of file doxygen.cpp.

10471{
10472 const StringVector &latexExtraStyleSheet = Config_getList(LATEX_EXTRA_STYLESHEET);
10473 for (const auto &sheet : latexExtraStyleSheet)
10474 {
10475 std::string fileName = sheet;
10476 if (!fileName.empty())
10477 {
10478 FileInfo fi(fileName);
10479 if (!fi.exists())
10480 {
10481 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET does not exist!\n",fileName);
10482 }
10483 else if (fi.isDir())
10484 {
10485 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET is a directory, it has to be a file!\n", fileName);
10486 }
10487 else
10488 {
10489 QCString destFileName = Config_getString(LATEX_OUTPUT)+"/"+fi.fileName();
10490 if (!checkExtension(fi.fileName(), LATEX_STYLE_EXTENSION))
10491 {
10492 destFileName += LATEX_STYLE_EXTENSION;
10493 }
10494 copyFile(fileName, destFileName);
10495 }
10496 }
10497 }
10498}
#define LATEX_STYLE_EXTENSION
Definition latexgen.h:22
bool checkExtension(const QCString &fName, const QCString &ext)
Definition util.cpp:4900

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

10555{
10556 QCString projectLogo = projectLogoFile();
10557 if (!projectLogo.isEmpty())
10558 {
10559 FileInfo fi(projectLogo.str());
10560 if (!fi.exists())
10561 {
10562 err("Project logo '{}' specified by PROJECT_LOGO does not exist!\n",projectLogo);
10563 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10564 }
10565 else if (fi.isDir())
10566 {
10567 err("Project logo '{}' specified by PROJECT_LOGO is a directory, it has to be a file!\n",projectLogo);
10568 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10569 }
10570 else
10571 {
10572 QCString destFileName = outputOption+"/"+fi.fileName();
10573 copyFile(projectLogo,destFileName);
10574 Doxygen::indexList->addImageFile(fi.fileName());
10575 }
10576 }
10577}
QCString projectLogoFile()
Definition util.cpp:3124

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

10502{
10503 QCString htmlStyleSheet = Config_getString(HTML_STYLESHEET);
10504 if (!htmlStyleSheet.isEmpty())
10505 {
10506 if (!htmlStyleSheet.startsWith("http:") && !htmlStyleSheet.startsWith("https:"))
10507 {
10508 FileInfo fi(htmlStyleSheet.str());
10509 if (!fi.exists())
10510 {
10511 err("Style sheet '{}' specified by HTML_STYLESHEET does not exist!\n",htmlStyleSheet);
10512 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10513 }
10514 else if (fi.isDir())
10515 {
10516 err("Style sheet '{}' specified by HTML_STYLESHEET is a directory, it has to be a file!\n",htmlStyleSheet);
10517 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
10518 }
10519 else
10520 {
10521 QCString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10522 copyFile(htmlStyleSheet,destFileName);
10523 }
10524 }
10525 }
10526 const StringVector &htmlExtraStyleSheet = Config_getList(HTML_EXTRA_STYLESHEET);
10527 for (const auto &sheet : htmlExtraStyleSheet)
10528 {
10529 QCString fileName(sheet);
10530 if (!fileName.isEmpty() && !fileName.startsWith("http:") && !fileName.startsWith("https:"))
10531 {
10532 FileInfo fi(fileName.str());
10533 if (!fi.exists())
10534 {
10535 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET does not exist!\n",fileName);
10536 }
10537 else if (fi.fileName()=="doxygen.css" || fi.fileName()=="tabs.css" || fi.fileName()=="navtree.css")
10538 {
10539 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is already a built-in stylesheet. Please use a different name\n",fi.fileName());
10540 }
10541 else if (fi.isDir())
10542 {
10543 err("Style sheet '{}' specified by HTML_EXTRA_STYLESHEET is a directory, it has to be a file!\n",fileName);
10544 }
10545 else
10546 {
10547 QCString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
10548 copyFile(fileName, destFileName);
10549 }
10550 }
10551 }
10552}

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

9081{
9082 for (const auto &cd : *Doxygen::classLinkedMap)
9083 {
9084 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9085 if (cdm)
9086 {
9087 cdm->countMembers();
9088 }
9089 }
9090
9091 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9092 {
9094 if (ndm)
9095 {
9096 ndm->countMembers();
9097 }
9098 }
9099
9100 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9101 {
9102 for (const auto &fd : *fn)
9103 {
9104 fd->countMembers();
9105 }
9106 }
9107
9108 for (const auto &gd : *Doxygen::groupLinkedMap)
9109 {
9110 gd->countMembers();
9111 }
9112
9113 auto &mm = ModuleManager::instance();
9114 mm.countMembers();
9115}
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 12251 of file doxygen.cpp.

12254{
12255 QCString result = formatDirName;
12256 if (result.isEmpty())
12257 {
12258 result = baseDirName + defaultDirName;
12259 }
12260 else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':'))
12261 {
12262 result.prepend(baseDirName+"/");
12263 }
12264 Dir formatDir(result.str());
12265 if (!formatDir.exists() && !formatDir.mkdir(result.str()))
12266 {
12267 term("Could not create output directory {}\n", result);
12268 }
12269 return result;
12270}
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 8547 of file doxygen.cpp.

8548{
8549 // for each class
8550 for (const auto &cd : *Doxygen::classLinkedMap)
8551 {
8552 // that is a template
8553 for (const auto &ti : cd->getTemplateInstances())
8554 {
8555 ClassDefMutable *tcdm = toClassDefMutable(ti.classDef);
8556 if (tcdm)
8557 {
8558 tcdm->addMembersToTemplateInstance(cd.get(),cd->templateArguments(),ti.templSpec);
8559 }
8560 }
8561 }
8562}
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 11334 of file doxygen.cpp.

11335{
11337 msg("Developer parameters:\n");
11338 msg(" -m dump symbol map\n");
11339 msg(" -b making messages output unbuffered\n");
11340 msg(" -c <file> process input file as a comment block and produce HTML output\n");
11341#if ENABLE_TRACING
11342 msg(" -t [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout)\n");
11343 msg(" -t_time [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout),\n"
11344 " and include time and thread information\n");
11345#endif
11346 msg(" -d <level> enable a debug level, such as (multiple invocations of -d are possible):\n");
11348}
@ 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 9364 of file doxygen.cpp.

9365{
9366 // for each class
9367 for (const auto &cd : *Doxygen::classLinkedMap)
9368 {
9369 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9370 if (cdm)
9371 {
9373 }
9374 }
9375 // for each file
9376 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9377 {
9378 for (const auto &fd : *fn)
9379 {
9380 fd->distributeMemberGroupDocumentation();
9381 }
9382 }
9383 // for each namespace
9384 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9385 {
9387 if (ndm)
9388 {
9390 }
9391 }
9392 // for each group
9393 for (const auto &gd : *Doxygen::groupLinkedMap)
9394 {
9395 gd->distributeMemberGroupDocumentation();
9396 }
9398}
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 11293 of file doxygen.cpp.

11294{
11295 QCString anchor;
11297 {
11298 MemberDef *md = toMemberDef(d);
11299 anchor=":"+md->anchor();
11300 }
11301 QCString scope;
11302 QCString fn = d->getOutputFileBase();
11305 {
11306 scope = fn;
11307 }
11308 t << "REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
11309 << fn+anchor << "','"
11310 << scope << "','"
11311 << d->name() << "','"
11312 << d->getDefFileName() << "','"
11313 << d->getDefLine()
11314 << "');\n";
11315}
virtual QCString anchor() const =0
virtual QCString getOutputFileBase() const =0
MemberDef * toMemberDef(Definition *d)
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:4905

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

11318{
11319 std::ofstream f = Portable::openOutputStream("symbols.sql");
11320 if (f.is_open())
11321 {
11322 TextStream t(&f);
11323 for (const auto &[name,symList] : *Doxygen::symbolMap)
11324 {
11325 for (const auto &def : symList)
11326 {
11327 dumpSymbol(t,def);
11328 }
11329 }
11330 }
11331}
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 12238 of file doxygen.cpp.

12239{
12240 if (!g_successfulRun) // premature exit
12241 {
12242 Dir thisDir;
12243 msg("Exiting...\n");
12244 if (!Doxygen::filterDBFileName.isEmpty())
12245 {
12246 thisDir.remove(Doxygen::filterDBFileName.str());
12247 }
12248 }
12249}
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 5299 of file doxygen.cpp.

5300{
5301 // strip any anonymous scopes first
5304 int i=0;
5305 if ((root->lang==SrcLangExt::CSharp || root->lang==SrcLangExt::Java) &&
5306 (i=bName.find('<'))!=-1)
5307 {
5308 // a Java/C# generic class looks like a C++ specialization, so we need to strip the
5309 // template part before looking for matches
5310 if (root->lang==SrcLangExt::CSharp)
5311 {
5312 bName = mangleCSharpGenericName(root->name);
5313 }
5314 else
5315 {
5316 bName = bName.left(i);
5317 }
5318 }
5319 return bName;
5320}

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

7381{
7382 AUTO_TRACE("root->type='{}' root->inside='{}' root->name='{}' root->args='{}' section={} root->spec={} root->mGrpId={}",
7383 root->type,root->inside,root->name,root->args,root->section,root->spec,root->mGrpId);
7384 //printf("root->parent()->name=%s\n",qPrint(root->parent()->name));
7385 bool isFunc=TRUE;
7386
7387 QCString type = root->type;
7388 QCString args = root->args;
7389 int i=-1, l=0;
7390 if ( // detect func variable/typedef to func ptr
7391 (i=findFunctionPtr(type.str(),root->lang,&l))!=-1
7392 )
7393 {
7394 //printf("Fixing function pointer!\n");
7395 // fix type and argument
7396 args.prepend(type.right(type.length()-i-l));
7397 type=type.left(i+l);
7398 //printf("Results type=%s,name=%s,args=%s\n",qPrint(type),qPrint(root->name),qPrint(args));
7399 isFunc=FALSE;
7400 }
7401 else if ((type.startsWith("typedef ") && args.find('(')!=-1))
7402 // detect function types marked as functions
7403 {
7404 isFunc=FALSE;
7405 }
7406
7407 //printf("Member %s isFunc=%d\n",qPrint(root->name),isFunc);
7408 if (root->section.isMemberDoc())
7409 {
7410 //printf("Documentation for inline member '%s' found args='%s'\n",
7411 // qPrint(root->name),qPrint(args));
7412 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7413 if (type.isEmpty())
7414 {
7415 findMember(root,
7416 relates,
7417 type,
7418 args,
7419 root->name + args + root->exception,
7420 FALSE,
7421 isFunc);
7422 }
7423 else
7424 {
7425 findMember(root,
7426 relates,
7427 type,
7428 args,
7429 type + " " + root->name + args + root->exception,
7430 FALSE,
7431 isFunc);
7432 }
7433 }
7434 else if (root->section.isOverloadDoc())
7435 {
7436 //printf("Overloaded member %s found\n",qPrint(root->name));
7437 findMember(root,
7438 relates,
7439 type,
7440 args,
7441 root->name,
7442 TRUE,
7443 isFunc);
7444 }
7445 else if
7446 ((root->section.isFunction() // function
7447 ||
7448 (root->section.isVariable() && // variable
7449 !type.isEmpty() && // with a type
7450 g_compoundKeywords.find(type.str())==g_compoundKeywords.end() // that is not a keyword
7451 // (to skip forward declaration of class etc.)
7452 )
7453 )
7454 )
7455 {
7456 //printf("Documentation for member '%s' found args='%s' excp='%s'\n",
7457 // qPrint(root->name),qPrint(args),qPrint(root->exception));
7458 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7459 //printf("Inside=%s\n Relates=%s\n",qPrint(root->inside),qPrint(relates));
7460 if (type=="friend class" || type=="friend struct" ||
7461 type=="friend union")
7462 {
7463 findMember(root,
7464 relates,
7465 type,
7466 args,
7467 type+" "+root->name,
7468 FALSE,FALSE);
7469
7470 }
7471 else if (!type.isEmpty())
7472 {
7473 findMember(root,
7474 relates,
7475 type,
7476 args,
7477 type+" "+ root->inside + root->name + args + root->exception,
7478 FALSE,isFunc);
7479 }
7480 else
7481 {
7482 findMember(root,
7483 relates,
7484 type,
7485 args,
7486 root->inside + root->name + args + root->exception,
7487 FALSE,isFunc);
7488 }
7489 }
7490 else if (root->section.isDefine() && !relates.isEmpty())
7491 {
7492 findMember(root,
7493 relates,
7494 type,
7495 args,
7496 root->name + args,
7497 FALSE,
7498 !args.isEmpty());
7499 }
7500 else if (root->section.isVariableDoc())
7501 {
7502 //printf("Documentation for variable %s found\n",qPrint(root->name));
7503 //if (!relates.isEmpty()) printf(" Relates %s\n",qPrint(relates));
7504 findMember(root,
7505 relates,
7506 type,
7507 args,
7508 root->name,
7509 FALSE,
7510 FALSE);
7511 }
7512 else if (root->section.isExportedInterface() ||
7513 root->section.isIncludedService())
7514 {
7515 findMember(root,
7516 relates,
7517 type,
7518 args,
7519 type + " " + root->name,
7520 FALSE,
7521 FALSE);
7522 }
7523 else
7524 {
7525 // skip section
7526 //printf("skip section\n");
7527 }
7528}
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:6754

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

4763{
4764 AUTO_TRACE("name={}",root->name);
4765 // The base class could ofcouse also be a non-nested class
4766 const ArgumentList &formalArgs = masterCd->templateArguments();
4767 for (const BaseInfo &bi : root->extends)
4768 {
4769 //printf("masterCd=%s bi.name='%s' #actualArgs=%d\n",
4770 // qPrint(masterCd->localName()),qPrint(bi.name),actualArgs ? (int)actualArgs->size() : -1);
4771 TemplateNameMap formTemplateNames;
4772 if (templateNames.empty())
4773 {
4774 formTemplateNames = getTemplateArgumentsInName(formalArgs,bi.name.str());
4775 }
4776 BaseInfo tbi = bi;
4777 tbi.name = substituteTemplateArgumentsInString(bi.name,formalArgs,actualArgs);
4778 //printf("masterCd=%p instanceCd=%p bi->name=%s tbi.name=%s\n",(void*)masterCd,(void*)instanceCd,qPrint(bi.name),qPrint(tbi.name));
4779
4780 if (mode==DocumentedOnly)
4781 {
4782 // find a documented base class in the correct scope
4783 if (!findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,DocumentedOnly,isArtificial))
4784 {
4785 // 1.8.2: decided to show inheritance relations even if not documented,
4786 // we do make them artificial, so they do not appear in the index
4787 //if (!Config_getBool(HIDE_UNDOC_RELATIONS))
4788 bool b = Config_getBool(HIDE_UNDOC_RELATIONS) ? TRUE : isArtificial;
4789 //{
4790 // no documented base class -> try to find an undocumented one
4791 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,Undocumented,b);
4792 //}
4793 }
4794 }
4795 else if (mode==TemplateInstances)
4796 {
4797 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,TemplateInstances,isArtificial);
4798 }
4799 }
4800}

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

5767{
5768 SymbolResolver resolver(fd);
5769 const ClassDef *tcd = resolver.resolveClass(nd,scopeName,true,true);
5770 //printf("findClassDefinition(fd=%s,ns=%s,scopeName=%s)='%s'\n",
5771 // qPrint(fd?fd->name():""),qPrint(nd?nd->name():""),
5772 // qPrint(scopeName),qPrint(tcd?tcd->name():""));
5773 return tcd;
5774}

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

5291{
5292 if (isClassSection(root))
5293 {
5294 g_classEntries.emplace(root->name.str(),root);
5295 }
5296 for (const auto &e : root->children()) findClassEntries(e.get());
5297}
static void findClassEntries(const Entry *root)
Definition doxygen.cpp:5290
static bool isClassSection(const Entry *root)
Definition doxygen.cpp:5268

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

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

4563{
4564 ClassDef *result=nullptr;
4565 if (cd==nullptr)
4566 {
4567 return result;
4568 }
4569 FileDef *fd=cd->getFileDef();
4570 SymbolResolver resolver(fd);
4571 if (context && cd!=context)
4572 {
4573 result = const_cast<ClassDef*>(resolver.resolveClass(context,name,true,true));
4574 }
4575 //printf("1. result=%p\n",result);
4576 if (result==nullptr)
4577 {
4578 result = const_cast<ClassDef*>(resolver.resolveClass(cd,name,true,true));
4579 }
4580 //printf("2. result=%p\n",result);
4581 if (result==nullptr) // try direct class, needed for namespaced classes imported via tag files (see bug624095)
4582 {
4583 result = getClass(name);
4584 }
4585 //printf("3. result=%p\n",result);
4586 //printf("** Trying to find %s within context %s class %s result=%s lookup=%p\n",
4587 // qPrint(name),
4588 // context ? qPrint(context->name()) : "<none>",
4589 // cd ? qPrint(cd->name()) : "<none>",
4590 // result ? qPrint(result->name()) : "<none>",
4591 // Doxygen::classLinkedMap->find(name)
4592 // );
4593 return result;
4594}

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

Referenced by findClassRelation(), and findUsedClassesForClass().

◆ findDefineDocumentation()

void findDefineDocumentation ( Entry * root)
static

Definition at line 9612 of file doxygen.cpp.

9613{
9614 if ((root->section.isDefineDoc() || root->section.isDefine()) && !root->name.isEmpty())
9615 {
9616 //printf("found define '%s' '%s' brief='%s' doc='%s'\n",
9617 // qPrint(root->name),qPrint(root->args),qPrint(root->brief),qPrint(root->doc));
9618
9619 if (root->tagInfo() && !root->name.isEmpty()) // define read from a tag file
9620 {
9621 auto md = createMemberDef(root->tagInfo()->tagName,1,1,
9622 "#define",root->name,root->args,QCString(),
9623 Protection::Public,Specifier::Normal,FALSE,Relationship::Member,MemberType::Define,
9624 ArgumentList(),ArgumentList(),"");
9625 auto mmd = toMemberDefMutable(md.get());
9626 mmd->setTagInfo(root->tagInfo());
9627 mmd->setLanguage(root->lang);
9628 mmd->addQualifiers(root->qualifiers);
9629 //printf("Searching for '%s' fd=%p\n",qPrint(filePathName),fd);
9630 mmd->setFileDef(root->parent()->fileDef());
9631 //printf("Adding member=%s\n",qPrint(md->name()));
9633 mn->push_back(std::move(md));
9634 }
9636 if (mn)
9637 {
9638 int count=0;
9639 for (const auto &md : *mn)
9640 {
9641 if (md->memberType()==MemberType::Define) count++;
9642 }
9643 if (count==1)
9644 {
9645 for (const auto &imd : *mn)
9646 {
9647 MemberDefMutable *md = toMemberDefMutable(imd.get());
9648 if (md && md->memberType()==MemberType::Define)
9649 {
9650 addDefineDoc(root,md);
9651 }
9652 }
9653 }
9654 else if (count>1 &&
9655 (!root->doc.isEmpty() ||
9656 !root->brief.isEmpty() ||
9657 root->bodyLine!=-1
9658 )
9659 )
9660 // multiple defines don't know where to add docs
9661 // but maybe they are in different files together with their documentation
9662 {
9663 for (const auto &imd : *mn)
9664 {
9665 MemberDefMutable *md = toMemberDefMutable(imd.get());
9666 if (md && md->memberType()==MemberType::Define)
9667 {
9668 if (haveEqualFileNames(root, md) || isEntryInGroupOfMember(root, md))
9669 // doc and define in the same file or group assume they belong together.
9670 {
9671 addDefineDoc(root,md);
9672 }
9673 }
9674 }
9675 //warn("define {} found in the following files:\n",root->name);
9676 //warn("Cannot determine where to add the documentation found "
9677 // "at line {} of file {}. \n",
9678 // root->startLine,root->fileName);
9679 }
9680 }
9681 else if (!root->doc.isEmpty() || !root->brief.isEmpty()) // define not found
9682 {
9683 bool preEnabled = Config_getBool(ENABLE_PREPROCESSING);
9684 if (preEnabled)
9685 {
9686 warn(root->fileName,root->startLine,"documentation for unknown define {} found.",root->name);
9687 }
9688 else
9689 {
9690 warn(root->fileName,root->startLine, "found documented #define {} but ignoring it because ENABLE_PREPROCESSING is NO.", root->name);
9691 }
9692 }
9693 }
9694 for (const auto &e : root->children()) findDefineDocumentation(e.get());
9695}
static void findDefineDocumentation(Entry *root)
Definition doxygen.cpp:9612
static void addDefineDoc(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:9585
static bool haveEqualFileNames(const Entry *root, const MemberDef *md)
Definition doxygen.cpp:9574
static bool isEntryInGroupOfMember(const Entry *root, const MemberDef *md, bool allowNoGroup=false)
Definition doxygen.cpp:5780

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

8176{
8177 // for each member name
8178 for (const auto &mn : mnsd)
8179 {
8180 // for each member definition
8181 for (const auto &imd : *mn)
8182 {
8183 MemberDefMutable *md = toMemberDefMutable(imd.get());
8184 if (md && md->isEnumerate()) // member is an enum
8185 {
8186 int documentedEnumValues=0;
8187 // for each enum value
8188 for (const auto &fmd : md->enumFieldList())
8189 {
8190 if (fmd->isLinkableInProject()) documentedEnumValues++;
8191 }
8192 // at least one enum value is documented
8193 if (documentedEnumValues>0) md->setDocumentedEnumValues(TRUE);
8194 }
8195 }
8196 }
8197}
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 9699 of file doxygen.cpp.

9700{
9701 if (root->section.isDirDoc())
9702 {
9703 QCString normalizedName = root->name;
9704 normalizedName = substitute(normalizedName,"\\","/");
9705 //printf("root->docFile=%s normalizedName=%s\n",
9706 // qPrint(root->docFile),qPrint(normalizedName));
9707 if (root->docFile==normalizedName) // current dir?
9708 {
9709 int lastSlashPos=normalizedName.findRev('/');
9710 if (lastSlashPos!=-1) // strip file name
9711 {
9712 normalizedName=normalizedName.left(lastSlashPos);
9713 }
9714 }
9715 if (normalizedName.at(normalizedName.length()-1)!='/')
9716 {
9717 normalizedName+='/';
9718 }
9719 DirDef *matchingDir=nullptr;
9720 for (const auto &dir : *Doxygen::dirLinkedMap)
9721 {
9722 //printf("Dir: %s<->%s\n",qPrint(dir->name()),qPrint(normalizedName));
9723 if (dir->name().right(normalizedName.length())==normalizedName)
9724 {
9725 if (matchingDir)
9726 {
9727 warn(root->fileName,root->startLine,
9728 "\\dir command matches multiple directories.\n"
9729 " Applying the command for directory {}\n"
9730 " Ignoring the command for directory {}",
9731 matchingDir->name(),dir->name()
9732 );
9733 }
9734 else
9735 {
9736 matchingDir=dir.get();
9737 }
9738 }
9739 }
9740 if (matchingDir)
9741 {
9742 //printf("Match for with dir %s #anchor=%zu\n",qPrint(matchingDir->name()),root->anchors.size());
9743 matchingDir->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9744 matchingDir->setDocumentation(root->doc,root->docFile,root->docLine);
9745 matchingDir->setRefItems(root->sli);
9746 matchingDir->setRequirementReferences(root->rqli);
9747 matchingDir->addSectionsToDefinition(root->anchors);
9748 root->commandOverrides.apply_directoryGraph([&](bool b) { matchingDir->overrideDirectoryGraph(b); });
9749 addDirToGroups(root,matchingDir);
9750 }
9751 else
9752 {
9753 warn(root->fileName,root->startLine,"No matching directory found for command \\dir {}",normalizedName);
9754 }
9755 }
9756 for (const auto &e : root->children()) findDirDocumentation(e.get());
9757}
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:9699
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 8201 of file doxygen.cpp.

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

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

3113{
3114 // locate end of template
3115 size_t e=startPos;
3116 int brCount=1;
3117 int roundCount=0;
3118 size_t len = s.length();
3119 bool insideString=FALSE;
3120 bool insideChar=FALSE;
3121 char pc = 0;
3122 while (e<len && brCount!=0)
3123 {
3124 char c=s.at(e);
3125 switch(c)
3126 {
3127 case '<':
3128 if (!insideString && !insideChar)
3129 {
3130 if (e<len-1 && s.at(e+1)=='<')
3131 e++;
3132 else if (roundCount==0)
3133 brCount++;
3134 }
3135 break;
3136 case '>':
3137 if (!insideString && !insideChar)
3138 {
3139 if (e<len-1 && s.at(e+1)=='>')
3140 e++;
3141 else if (roundCount==0)
3142 brCount--;
3143 }
3144 break;
3145 case '(':
3146 if (!insideString && !insideChar)
3147 roundCount++;
3148 break;
3149 case ')':
3150 if (!insideString && !insideChar)
3151 roundCount--;
3152 break;
3153 case '"':
3154 if (!insideChar)
3155 {
3156 if (insideString && pc!='\\')
3157 insideString=FALSE;
3158 else
3159 insideString=TRUE;
3160 }
3161 break;
3162 case '\'':
3163 if (!insideString)
3164 {
3165 if (insideChar && pc!='\\')
3166 insideChar=FALSE;
3167 else
3168 insideChar=TRUE;
3169 }
3170 break;
3171 }
3172 pc = c;
3173 e++;
3174 }
3175 return brCount==0 ? static_cast<int>(e) : -1;
3176}

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

Referenced by addVariable(), and findClassRelation().

◆ findEnumDocumentation()

void findEnumDocumentation ( const Entry * root)
static

Definition at line 8089 of file doxygen.cpp.

8090{
8091 if (root->section.isEnumDoc() &&
8092 !root->name.isEmpty() &&
8093 root->name.at(0)!='@' // skip anonymous enums
8094 )
8095 {
8096 QCString name;
8097 QCString scope;
8098 int i = root->name.findRev("::");
8099 if (i!=-1) // scope is specified as part of the name
8100 {
8101 name=root->name.right(root->name.length()-i-2); // extract name
8102 scope=root->name.left(i); // extract scope
8103 //printf("Scope='%s' Name='%s'\n",qPrint(scope),qPrint(name));
8104 }
8105 else // just the name
8106 {
8107 name=root->name;
8108 }
8109 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
8110 {
8111 if (!scope.isEmpty()) scope.prepend("::");
8112 scope.prepend(root->parent()->name);
8113 }
8114 const ClassDef *cd = getClass(scope);
8115 const NamespaceDef *nd=Doxygen::namespaceLinkedMap->find(scope);
8116 const FileDef *fd = root->fileDef();
8117 AUTO_TRACE("Found docs for enum with name '{}' and scope '{}' in context '{}' cd='{}', nd='{}' fd='{}'",
8118 name,scope,root->parent()->name,
8119 cd ? cd->name() : QCString("<none>"),
8120 nd ? nd->name() : QCString("<none>"),
8121 fd ? fd->name() : QCString("<none>"));
8122
8123 if (!name.isEmpty())
8124 {
8125 bool found = tryAddEnumDocsToGroupMember(root, name);
8126 if (!found)
8127 {
8128 MemberName *mn = cd ? Doxygen::memberNameLinkedMap->find(name) : Doxygen::functionNameLinkedMap->find(name);
8129 if (mn)
8130 {
8131 for (const auto &imd : *mn)
8132 {
8133 MemberDefMutable *md = toMemberDefMutable(imd.get());
8134 if (md && md->isEnumerate())
8135 {
8136 const ClassDef *mcd = md->getClassDef();
8137 const NamespaceDef *mnd = md->getNamespaceDef();
8138 const FileDef *mfd = md->getFileDef();
8139 if (cd && mcd==cd)
8140 {
8141 AUTO_TRACE_ADD("Match found for class scope");
8142 addEnumDocs(root,md);
8143 found = TRUE;
8144 break;
8145 }
8146 else if (cd==nullptr && mcd==nullptr && nd!=nullptr && mnd==nd)
8147 {
8148 AUTO_TRACE_ADD("Match found for namespace scope");
8149 addEnumDocs(root,md);
8150 found = TRUE;
8151 break;
8152 }
8153 else if (cd==nullptr && nd==nullptr && mcd==nullptr && mnd==nullptr && fd==mfd)
8154 {
8155 AUTO_TRACE_ADD("Match found for global scope");
8156 addEnumDocs(root,md);
8157 found = TRUE;
8158 break;
8159 }
8160 }
8161 }
8162 }
8163 }
8164 if (!found)
8165 {
8166 warn(root->fileName,root->startLine, "Documentation for undefined enum '{}' found.", name);
8167 }
8168 }
8169 }
8170 for (const auto &e : root->children()) findEnumDocumentation(e.get());
8171}
static bool tryAddEnumDocsToGroupMember(const Entry *root, const QCString &name)
Definition doxygen.cpp:8056
static void addEnumDocs(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:8014
static void findEnumDocumentation(const Entry *root)
Definition doxygen.cpp:8089

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

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

4271{
4272 AUTO_TRACE();
4273 for (const auto &fn : *Doxygen::functionNameLinkedMap) // for each global function name
4274 {
4275 MemberName *mn = Doxygen::memberNameLinkedMap->find(fn->memberName());
4276 if (mn)
4277 { // there are members with the same name
4278 // for each function with that name
4279 for (const auto &ifmd : *fn)
4280 {
4281 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
4282 // for each member with that name
4283 for (const auto &immd : *mn)
4284 {
4285 MemberDefMutable *mmd = toMemberDefMutable(immd.get());
4286 //printf("Checking for matching arguments
4287 // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n",
4288 // mmd->isRelated(),mmd->isFriend(),mmd->isFunction());
4289 if (fmd && mmd &&
4290 (mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) &&
4291 matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), mmd->typeString(), &mmd->argumentList(),
4292 fmd->getOuterScope(), fmd->getFileDef(), fmd->typeString(), &fmd->argumentList(),
4293 TRUE,mmd->getLanguage()
4294 )
4295
4296 ) // if the member is related and the arguments match then the
4297 // function is actually a friend.
4298 {
4299 AUTO_TRACE_ADD("Merging related global and member '{}' isFriend={} isRelated={} isFunction={}",
4300 mmd->name(),mmd->isFriend(),mmd->isRelated(),mmd->isFunction());
4301 const ArgumentList &mmdAl = mmd->argumentList();
4302 const ArgumentList &fmdAl = fmd->argumentList();
4303 mergeArguments(const_cast<ArgumentList&>(fmdAl),const_cast<ArgumentList&>(mmdAl));
4304
4305 // reset argument lists to add missing default parameters
4306 QCString mmdAlStr = argListToString(mmdAl);
4307 QCString fmdAlStr = argListToString(fmdAl);
4308 mmd->setArgsString(mmdAlStr);
4309 fmd->setArgsString(fmdAlStr);
4310 mmd->moveDeclArgumentList(std::make_unique<ArgumentList>(mmdAl));
4311 fmd->moveDeclArgumentList(std::make_unique<ArgumentList>(fmdAl));
4312 AUTO_TRACE_ADD("friend args='{}' member args='{}'",argListToString(fmd->argumentList()),argListToString(mmd->argumentList()));
4313
4314 if (!fmd->documentation().isEmpty())
4315 {
4316 mmd->setDocumentation(fmd->documentation(),fmd->docFile(),fmd->docLine());
4317 }
4318 else if (!mmd->documentation().isEmpty())
4319 {
4320 fmd->setDocumentation(mmd->documentation(),mmd->docFile(),mmd->docLine());
4321 }
4322 if (mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
4323 {
4324 mmd->setBriefDescription(fmd->briefDescription(),fmd->briefFile(),fmd->briefLine());
4325 }
4326 else if (!mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
4327 {
4328 fmd->setBriefDescription(mmd->briefDescription(),mmd->briefFile(),mmd->briefLine());
4329 }
4330 if (!fmd->inbodyDocumentation().isEmpty())
4331 {
4333 }
4334 else if (!mmd->inbodyDocumentation().isEmpty())
4335 {
4337 }
4338 //printf("body mmd %d fmd %d\n",mmd->getStartBodyLine(),fmd->getStartBodyLine());
4339 if (mmd->getStartBodyLine()==-1 && fmd->getStartBodyLine()!=-1)
4340 {
4341 mmd->setBodySegment(fmd->getDefLine(),fmd->getStartBodyLine(),fmd->getEndBodyLine());
4342 mmd->setBodyDef(fmd->getBodyDef());
4343 //mmd->setBodyMember(fmd);
4344 }
4345 else if (mmd->getStartBodyLine()!=-1 && fmd->getStartBodyLine()==-1)
4346 {
4347 fmd->setBodySegment(mmd->getDefLine(),mmd->getStartBodyLine(),mmd->getEndBodyLine());
4348 fmd->setBodyDef(mmd->getBodyDef());
4349 //fmd->setBodyMember(mmd);
4350 }
4352
4354
4355 mmd->addQualifiers(fmd->getQualifiers());
4356 fmd->addQualifiers(mmd->getQualifiers());
4357
4358 }
4359 }
4360 }
4361 }
4362 }
4363}
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:6864

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

2909{
2910 AUTO_TRACE("type='{}' lang={}",type,lang);
2911 if (lang == SrcLangExt::Fortran || lang == SrcLangExt::VHDL)
2912 {
2913 return -1; // Fortran and VHDL do not have function pointers
2914 }
2915
2916 static const reg::Ex re(R"(\‍([^)]*[*&^][^)]*\))");
2918 size_t i=std::string::npos;
2919 size_t l=0;
2920 if (reg::search(type,match,re)) // contains (...*...) or (...&...) or (...^...)
2921 {
2922 i = match.position();
2923 l = match.length();
2924 }
2925 if (i!=std::string::npos)
2926 {
2927 size_t di = type.find("decltype(");
2928 if (di!=std::string::npos && di<i)
2929 {
2930 i = std::string::npos;
2931 }
2932 }
2933 size_t bb=type.find('<');
2934 size_t be=type.rfind('>');
2935 bool templFp = false;
2936 if (be!=std::string::npos) {
2937 size_t cc_ast = type.find("::*");
2938 size_t cc_amp = type.find("::&");
2939 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>::*)'
2940 }
2941
2942 if (!type.empty() && // return type is non-empty
2943 i!=std::string::npos && // contains (...*...)
2944 type.find("operator")==std::string::npos && // not an operator
2945 (type.find(")(")==std::string::npos || type.find("typedef ")!=std::string::npos) &&
2946 // not a function pointer return type
2947 (!(bb<i && i<be) || templFp) // bug665855: avoid treating "typedef A<void (T*)> type" as a function pointer
2948 )
2949 {
2950 if (pLength) *pLength=static_cast<int>(l);
2951 //printf("findFunctionPtr=%d\n",(int)i);
2952 AUTO_TRACE_EXIT("result={}",i);
2953 return static_cast<int>(i);
2954 }
2955 else
2956 {
2957 //printf("findFunctionPtr=%d\n",-1);
2958 AUTO_TRACE_EXIT("result=-1");
2959 return -1;
2960 }
2961}
#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 5804 of file doxygen.cpp.

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

5328{
5329 AUTO_TRACE();
5330 ClassDefSet visitedClasses;
5331 for (const auto &[name,root] : g_classEntries)
5332 {
5333 QCString bName = extractClassName(root);
5334 ClassDefMutable *cdm = getClassMutable(bName);
5335 if (cdm)
5336 {
5338 }
5339 }
5340}

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

Referenced by parseInput().

◆ findMainPage()

void findMainPage ( Entry * root)
static

Definition at line 9799 of file doxygen.cpp.

9800{
9801 if (root->section.isMainpageDoc())
9802 {
9803 if (Doxygen::mainPage==nullptr && root->tagInfo()==nullptr)
9804 {
9805 //printf("mainpage: docLine=%d startLine=%d\n",root->docLine,root->startLine);
9806 //printf("Found main page! \n======\n%s\n=======\n",qPrint(root->doc));
9807 QCString title=root->args.stripWhiteSpace();
9808 if (title.isEmpty()) title = Config_getString(PROJECT_NAME);
9809 //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9810 QCString indexName="index";
9812 indexName, root->brief+root->doc+root->inbodyDocs,title);
9813 //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
9814 Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9815 Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1);
9816 Doxygen::mainPage->setFileName(indexName);
9817 Doxygen::mainPage->setLocalToc(root->localToc);
9819
9821 if (si)
9822 {
9823 if (!si->ref().isEmpty()) // we are from a tag file
9824 {
9825 // a page name is a label as well! but should no be double either
9827 Doxygen::mainPage->name(),
9828 indexName,
9829 root->startLine,
9830 Doxygen::mainPage->title(),
9832 0); // level 0
9833 }
9834 else if (si->lineNr() != -1)
9835 {
9836 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {}, line {})",
9837 Doxygen::mainPage->name(),si->fileName(),si->lineNr());
9838 }
9839 else
9840 {
9841 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {})",
9842 Doxygen::mainPage->name(),si->fileName());
9843 }
9844 }
9845 else
9846 {
9847 // a page name is a label as well! but should no be double either
9849 Doxygen::mainPage->name(),
9850 indexName,
9851 root->startLine,
9852 Doxygen::mainPage->title(),
9854 0); // level 0
9855 }
9856 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9857 }
9858 else if (root->tagInfo()==nullptr)
9859 {
9860 warn(root->fileName,root->startLine,
9861 "found more than one \\mainpage comment block! (first occurrence: {}, line {}), Skipping current block!",
9862 Doxygen::mainPage->docFile(),Doxygen::mainPage->getStartBodyLine());
9863 }
9864 }
9865 for (const auto &e : root->children()) findMainPage(e.get());
9866}
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:9799

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

9870{
9871 if (root->section.isMainpageDoc())
9872 {
9873 if (Doxygen::mainPage && root->tagInfo())
9874 {
9875 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9876 }
9877 }
9878 for (const auto &e : root->children()) findMainPageTagFiles(e.get());
9879}
static void findMainPageTagFiles(Entry *root)
Definition doxygen.cpp:9869

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

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

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

7531{
7532 if (root->section.isMemberDoc() ||
7533 root->section.isOverloadDoc() ||
7534 root->section.isFunction() ||
7535 root->section.isVariable() ||
7536 root->section.isVariableDoc() ||
7537 root->section.isDefine() ||
7538 root->section.isIncludedService() ||
7539 root->section.isExportedInterface()
7540 )
7541 {
7542 AUTO_TRACE();
7543 if (root->relatesType==RelatesType::Duplicate && !root->relates.isEmpty())
7544 {
7546 }
7548 }
7549 for (const auto &e : root->children())
7550 {
7551 if (!e->section.isEnum())
7552 {
7553 findMemberDocumentation(e.get());
7554 }
7555 }
7556}
static void findMemberDocumentation(const Entry *root)
Definition doxygen.cpp:7530
static void filterMemberDocumentation(const Entry *root, const QCString &relates)
Definition doxygen.cpp:7380

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

7561{
7562 AUTO_TRACE();
7563 for (const auto &objCImpl : root->children())
7564 {
7565 if (objCImpl->section.isObjcImpl())
7566 {
7567 for (const auto &objCMethod : objCImpl->children())
7568 {
7569 if (objCMethod->section.isFunction())
7570 {
7571 //printf(" Found ObjC method definition %s\n",qPrint(objCMethod->name));
7572 findMember(objCMethod.get(),
7573 objCMethod->relates,
7574 objCMethod->type,
7575 objCMethod->args,
7576 objCMethod->type+" "+objCImpl->name+"::"+objCMethod->name+" "+objCMethod->args,
7577 FALSE,TRUE);
7578 objCMethod->section=EntryType::makeEmpty();
7579 }
7580 }
7581 }
7582 }
7583}

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

9403{
9404 // for each class
9405 for (const auto &cd : *Doxygen::classLinkedMap)
9406 {
9407 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9408 if (cdm)
9409 {
9411 }
9412 }
9413 // for each concept
9414 for (const auto &cd : *Doxygen::conceptLinkedMap)
9415 {
9416 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
9417 if (cdm)
9418 {
9420 }
9421 }
9422 // for each file
9423 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9424 {
9425 for (const auto &fd : *fn)
9426 {
9427 fd->findSectionsInDocumentation();
9428 }
9429 }
9430 // for each namespace
9431 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9432 {
9434 if (ndm)
9435 {
9437 }
9438 }
9439 // for each group
9440 for (const auto &gd : *Doxygen::groupLinkedMap)
9441 {
9442 gd->findSectionsInDocumentation();
9443 }
9444 // for each page
9445 for (const auto &pd : *Doxygen::pageLinkedMap)
9446 {
9447 pd->findSectionsInDocumentation();
9448 }
9449 // for each directory
9450 for (const auto &dd : *Doxygen::dirLinkedMap)
9451 {
9452 dd->findSectionsInDocumentation();
9453 }
9455 if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
9456}
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 4804 of file doxygen.cpp.

4809{
4810 AUTO_TRACE("Derived from template '{}' with parameters '{}' isArtificial={}",
4811 templateClass->name(),templSpec,isArtificial);
4812
4813 QCString tempArgsStr = tempArgListToString(templateClass->templateArguments(),root->lang,false);
4814 bool existingClass = templSpec==tempArgsStr;
4815 if (existingClass) return; // avoid recursion
4816
4817 bool freshInstance=FALSE;
4818 ClassDefMutable *instanceClass = toClassDefMutable(
4819 templateClass->insertTemplateInstance(
4820 root->fileName,root->startLine,root->startColumn,templSpec,freshInstance));
4821 if (instanceClass)
4822 {
4823 if (freshInstance)
4824 {
4825 instanceClass->setArtificial(TRUE);
4826 instanceClass->setLanguage(root->lang);
4827
4828 AUTO_TRACE_ADD("found fresh instance '{}'",instanceClass->name());
4829 instanceClass->setTemplateBaseClassNames(templateNames);
4830
4831 // search for new template instances caused by base classes of
4832 // instanceClass
4833 auto it_pair = g_classEntries.equal_range(templateClass->name().str());
4834 for (auto it=it_pair.first ; it!=it_pair.second ; ++it)
4835 {
4836 const Entry *templateRoot = it->second;
4837 AUTO_TRACE_ADD("template root found '{}' templSpec='{}'",templateRoot->name,templSpec);
4838 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(root->lang,templSpec);
4839 findBaseClassesForClass(templateRoot,context,templateClass,instanceClass,
4840 TemplateInstances,isArtificial,templArgs.get(),templateNames);
4841
4842 findUsedClassesForClass(templateRoot,context,templateClass,instanceClass,
4843 isArtificial,templArgs.get(),templateNames);
4844 }
4845 }
4846 else
4847 {
4848 AUTO_TRACE_ADD("instance already exists");
4849 }
4850 }
4851}
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:4597

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

4898{
4899 if (name.isEmpty()) return 0;
4900 int l = static_cast<int>(name.length());
4901 if (name[l-1]=='>') // search backward to find the matching <, allowing nested <...> and strings.
4902 {
4903 int count=1;
4904 int i=l-2;
4905 char insideQuote=0;
4906 while (count>0 && i>=0)
4907 {
4908 char c = name[i--];
4909 switch (c)
4910 {
4911 case '>': if (!insideQuote) count++; break;
4912 case '<': if (!insideQuote) count--; break;
4913 case '\'': if (!insideQuote) insideQuote=c;
4914 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4915 break;
4916 case '"': if (!insideQuote) insideQuote=c;
4917 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4918 break;
4919 default: break;
4920 }
4921 }
4922 if (i>=0) l=i+1;
4923 }
4924 return l;
4925}

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

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

5361{
5362 AUTO_TRACE();
5363 for (const auto &[name,root] : g_classEntries)
5364 {
5365 QCString bName = extractClassName(root);
5366 ClassDefMutable *cdm = getClassMutable(bName);
5367 if (cdm)
5368 {
5369 findUsedClassesForClass(root,cdm,cdm,cdm,TRUE);
5371 cdm->addTypeConstraints();
5372 }
5373 }
5374}
virtual void addTypeConstraints()=0
static void makeTemplateInstanceRelation(const Entry *root, ClassDefMutable *cd)
Definition doxygen.cpp:5342

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

9462{
9463 // remove all references to classes from the cache
9464 // as there can be new template instances in the inheritance path
9465 // to this class. Optimization: only remove those classes that
9466 // have inheritance instances as direct or indirect sub classes.
9467 StringVector elementsToRemove;
9468 for (const auto &ci : *Doxygen::typeLookupCache)
9469 {
9470 const LookupInfo &li = ci.second;
9471 if (li.definition)
9472 {
9473 elementsToRemove.push_back(ci.first);
9474 }
9475 }
9476 for (const auto &k : elementsToRemove)
9477 {
9478 Doxygen::typeLookupCache->remove(k);
9479 }
9480
9481 // remove all cached typedef resolutions whose target is a
9482 // template class as this may now be a template instance
9483 // for each global function name
9484 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9485 {
9486 // for each function with that name
9487 for (const auto &ifmd : *fn)
9488 {
9489 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9490 if (fmd && fmd->isTypedefValCached())
9491 {
9492 const ClassDef *cd = fmd->getCachedTypedefVal();
9493 if (cd->isTemplate()) fmd->invalidateTypedefValCache();
9494 }
9495 }
9496 }
9497 // for each class method name
9498 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9499 {
9500 // for each function with that name
9501 for (const auto &imd : *nm)
9502 {
9503 MemberDefMutable *md = toMemberDefMutable(imd.get());
9504 if (md && md->isTypedefValCached())
9505 {
9506 const ClassDef *cd = md->getCachedTypedefVal();
9507 if (cd->isTemplate()) md->invalidateTypedefValCache();
9508 }
9509 }
9510 }
9511}
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 9515 of file doxygen.cpp.

9516{
9517 // Remove all unresolved references to classes from the cache.
9518 // This is needed before resolving the inheritance relations, since
9519 // it would otherwise not find the inheritance relation
9520 // for C in the example below, as B::I was already found to be unresolvable
9521 // (which is correct if you ignore the inheritance relation between A and B).
9522 //
9523 // class A { class I {} };
9524 // class B : public A {};
9525 // class C : public B::I {};
9526
9527 StringVector elementsToRemove;
9528 for (const auto &ci : *Doxygen::typeLookupCache)
9529 {
9530 const LookupInfo &li = ci.second;
9531 if (li.definition==nullptr && li.typeDef==nullptr)
9532 {
9533 elementsToRemove.push_back(ci.first);
9534 }
9535 }
9536 for (const auto &k : elementsToRemove)
9537 {
9538 Doxygen::typeLookupCache->remove(k);
9539 }
9540
9541 // for each global function name
9542 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9543 {
9544 // for each function with that name
9545 for (const auto &ifmd : *fn)
9546 {
9547 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9548 if (fmd)
9549 {
9551 }
9552 }
9553 }
9554 // for each class method name
9555 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9556 {
9557 // for each function with that name
9558 for (const auto &imd : *nm)
9559 {
9560 MemberDefMutable *md = toMemberDefMutable(imd.get());
9561 if (md)
9562 {
9564 }
9565 }
9566 }
9567
9568}
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 9219 of file doxygen.cpp.

9220{
9221 std::vector<ClassDefMutable*> classList;
9222 for (const auto &cdi : *Doxygen::classLinkedMap)
9223 {
9224 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9225 if (cd && (cd->getOuterScope()==nullptr ||
9227 {
9228 addClassAndNestedClasses(classList,cd);
9229 }
9230 }
9231 for (const auto &cdi : *Doxygen::hiddenClassLinkedMap)
9232 {
9233 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9234 if (cd && (cd->getOuterScope()==nullptr ||
9236 {
9237 addClassAndNestedClasses(classList,cd);
9238 }
9239 }
9240 generateDocsForClassList(classList);
9241}
static void generateDocsForClassList(const std::vector< ClassDefMutable * > &classList)
Definition doxygen.cpp:9121

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

9246{
9247 for (const auto &cdi : *Doxygen::conceptLinkedMap)
9248 {
9250
9251 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9252 if (cd &&
9253 (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9254 cd->getOuterScope()==Doxygen::globalScope // only look at global concepts
9255 ) && !cd->isHidden() && cd->isLinkableInProject()
9256 )
9257 {
9258 msg("Generating docs for concept {}...\n",cd->displayName());
9260 }
9261 }
9262}
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 10376 of file doxygen.cpp.

10378{
10379 std::ofstream f;
10380 bool fileOpened=openOutputFile(configFile,f);
10381 bool writeToStdout=configFile=="-";
10382 if (fileOpened)
10383 {
10384 TextStream t(&f);
10385 Config::writeTemplate(t,shortList,updateOnly);
10386 if (!writeToStdout)
10387 {
10388 if (!updateOnly)
10389 {
10390 msg("\n\nConfiguration file '{}' created.\n\n",configFile);
10391 msg("Now edit the configuration file and enter\n\n");
10392 if (configFile!="Doxyfile" && configFile!="doxyfile")
10393 msg(" doxygen {}\n\n",configFile);
10394 else
10395 msg(" doxygen\n\n");
10396 msg("to generate the documentation for your project\n\n");
10397 }
10398 else
10399 {
10400 msg("\n\nConfiguration file '{}' updated.\n\n",configFile);
10401 }
10402 }
10403 }
10404 else
10405 {
10406 term("Cannot open file {} for writing\n",configFile);
10407 }
10408}
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 10631 of file doxygen.cpp.

10632{
10633 for (const auto &fn : *Doxygen::inputNameLinkedMap)
10634 {
10635 struct FileEntry
10636 {
10637 FileEntry(const QCString &p,FileDef *fd) : path(p), fileDef(fd) {}
10638 QCString path;
10639 FileDef *fileDef;
10640 };
10641
10642 // collect the entry for which to compute the longest common prefix (LCP) of the path
10643 std::vector<FileEntry> fileEntries;
10644 for (const auto &fd : *fn)
10645 {
10646 if (!fd->isReference()) // skip external references
10647 {
10648 fileEntries.emplace_back(fd->getPath(),fd.get());
10649 }
10650 }
10651
10652 size_t size = fileEntries.size();
10653
10654 if (size==1) // name if unique, so diskname is simply the name
10655 {
10656 FileDef *fd = fileEntries[0].fileDef;
10657 fd->setDiskName(fn->fileName());
10658 }
10659 else if (size>1) // multiple occurrences of the same file name
10660 {
10661 // sort the array
10662 std::stable_sort(fileEntries.begin(),
10663 fileEntries.end(),
10664 [](const FileEntry &fe1,const FileEntry &fe2)
10665 { return qstricmp_sort(fe1.path,fe2.path)<0; }
10666 );
10667
10668 // since the entries are sorted, the common prefix of the whole array is same
10669 // as the common prefix between the first and last entry
10670 const FileEntry &first = fileEntries[0];
10671 const FileEntry &last = fileEntries[size-1];
10672 int first_path_size = static_cast<int>(first.path.size())-1; // -1 to skip trailing slash
10673 int last_path_size = static_cast<int>(last.path.size())-1; // -1 to skip trailing slash
10674 int j=0;
10675 int i=0;
10676 for (i=0;i<first_path_size && i<last_path_size;i++)
10677 {
10678 if (first.path[i]=='/') j=i;
10679 if (first.path[i]!=last.path[i]) break;
10680 }
10681 if (i==first_path_size && i<last_path_size && last.path[i]=='/')
10682 {
10683 // case first='some/path' and last='some/path/more' => match is 'some/path'
10684 j=first_path_size;
10685 }
10686 else if (i==last_path_size && i<first_path_size && first.path[i]=='/')
10687 {
10688 // case first='some/path/more' and last='some/path' => match is 'some/path'
10689 j=last_path_size;
10690 }
10691
10692 // add non-common part of the path to the name
10693 for (auto &fileEntry : fileEntries)
10694 {
10695 QCString prefix = fileEntry.path.right(fileEntry.path.length()-j-1);
10696 fileEntry.fileDef->setName(prefix+fn->fileName());
10697 //printf("!!!!!!!! non unique disk name=%s:%s\n",qPrint(prefix),fn->fileName());
10698 fileEntry.fileDef->setDiskName(prefix+fn->fileName());
10699 }
10700 }
10701 }
10702}
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 9121 of file doxygen.cpp.

9122{
9123 AUTO_TRACE();
9124 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
9125 if (numThreads>1) // multi threaded processing
9126 {
9127 struct DocContext
9128 {
9129 DocContext(ClassDefMutable *cd_,const OutputList &ol_)
9130 : cd(cd_), ol(ol_) {}
9131 ClassDefMutable *cd;
9132 OutputList ol;
9133 };
9134 ThreadPool threadPool(numThreads);
9135 std::vector< std::future< std::shared_ptr<DocContext> > > results;
9136 for (const auto &cd : classList)
9137 {
9138 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9139 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9140 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9141 )
9142 {
9143 auto ctx = std::make_shared<DocContext>(cd,*g_outputList);
9144 auto processFile = [ctx]()
9145 {
9146 msg("Generating docs for compound {}...\n",ctx->cd->displayName());
9147
9148 // skip external references, anonymous compounds and
9149 // template instances
9150 if (!ctx->cd->isHidden() && !ctx->cd->isEmbeddedInOuterScope() &&
9151 ctx->cd->isLinkableInProject() && !ctx->cd->isImplicitTemplateInstance())
9152 {
9153 ctx->cd->writeDocumentation(ctx->ol);
9154 ctx->cd->writeMemberList(ctx->ol);
9155 }
9156
9157 // even for undocumented classes, the inner classes can be documented.
9158 ctx->cd->writeDocumentationForInnerClasses(ctx->ol);
9159 return ctx;
9160 };
9161 results.emplace_back(threadPool.queue(processFile));
9162 }
9163 }
9164 for (auto &f : results)
9165 {
9166 auto ctx = f.get();
9167 }
9168 }
9169 else // single threaded processing
9170 {
9171 for (const auto &cd : classList)
9172 {
9173 //printf("cd=%s getOuterScope=%p global=%p hidden=%d embeddedInOuterScope=%d\n",
9174 // qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope,cd->isHidden(),cd->isEmbeddedInOuterScope());
9175 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9176 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9177 )
9178 {
9179 // skip external references, anonymous compounds and
9180 // template instances
9181 if ( !cd->isHidden() && !cd->isEmbeddedInOuterScope() &&
9182 cd->isLinkableInProject() && !cd->isImplicitTemplateInstance())
9183 {
9184 msg("Generating docs for compound {}...\n",cd->displayName());
9185
9186 cd->writeDocumentation(*g_outputList);
9187 cd->writeMemberList(*g_outputList);
9188 }
9189 // even for undocumented classes, the inner classes can be documented.
9190 cd->writeDocumentationForInnerClasses(*g_outputList);
9191 }
9192 }
9193 }
9194}

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

Referenced by generateClassDocs().

◆ generateExampleDocs()

void generateExampleDocs ( )
static

Definition at line 10084 of file doxygen.cpp.

10085{
10086 g_outputList->disable(OutputType::Man);
10087 for (const auto &pd : *Doxygen::exampleLinkedMap)
10088 {
10089 msg("Generating docs for example {}...\n",pd->name());
10090 SrcLangExt lang = getLanguageFromFileName(pd->name(), SrcLangExt::Unknown);
10091 if (lang != SrcLangExt::Unknown)
10092 {
10093 QCString ext = getFileNameExtension(pd->name());
10094 auto intf = Doxygen::parserManager->getCodeParser(ext);
10095 intf->resetCodeParserState();
10096 }
10097 QCString n=pd->getOutputFileBase();
10098 startFile(*g_outputList,n,false,n,pd->name());
10100 g_outputList->docify(pd->name());
10102 g_outputList->startContents();
10103 QCString lineNoOptStr;
10104 if (pd->showLineNo())
10105 {
10106 lineNoOptStr="{lineno}";
10107 }
10108 g_outputList->generateDoc(pd->docFile(), // file
10109 pd->docLine(), // startLine
10110 pd.get(), // context
10111 nullptr, // memberDef
10112 (pd->briefDescription().isEmpty()?"":pd->briefDescription()+"\n\n")+
10113 pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
10114 DocOptions()
10115 .setIndexWords(true)
10116 .setExample(pd->name()));
10117 endFile(*g_outputList); // contains g_outputList->endContents()
10118 }
10120}
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:5194
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5236

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

8785{
8786 if (Index::instance().numDocumentedFiles()==0) return;
8787
8788 if (!Doxygen::inputNameLinkedMap->empty())
8789 {
8790 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8791 if (numThreads>1) // multi threaded processing
8792 {
8793 struct DocContext
8794 {
8795 DocContext(FileDef *fd_,const OutputList &ol_)
8796 : fd(fd_), ol(ol_) {}
8797 FileDef *fd;
8798 OutputList ol;
8799 };
8800 ThreadPool threadPool(numThreads);
8801 std::vector< std::future< std::shared_ptr<DocContext> > > results;
8802 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8803 {
8804 for (const auto &fd : *fn)
8805 {
8806 bool doc = fd->isLinkableInProject();
8807 if (doc)
8808 {
8809 auto ctx = std::make_shared<DocContext>(fd.get(),*g_outputList);
8810 auto processFile = [ctx]() {
8811 msg("Generating docs for file {}...\n",ctx->fd->docName());
8812 ctx->fd->writeDocumentation(ctx->ol);
8813 return ctx;
8814 };
8815 results.emplace_back(threadPool.queue(processFile));
8816 }
8817 }
8818 }
8819 for (auto &f : results)
8820 {
8821 auto ctx = f.get();
8822 }
8823 }
8824 else // single threaded processing
8825 {
8826 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8827 {
8828 for (const auto &fd : *fn)
8829 {
8830 bool doc = fd->isLinkableInProject();
8831 if (doc)
8832 {
8833 msg("Generating docs for file {}...\n",fd->docName());
8834 fd->writeDocumentation(*g_outputList);
8835 }
8836 }
8837 }
8838 }
8839 }
8840}

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

Referenced by generateOutput().

◆ generateFileSources()

void generateFileSources ( )
static

Definition at line 8618 of file doxygen.cpp.

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

10126{
10127 for (const auto &gd : *Doxygen::groupLinkedMap)
10128 {
10129 if (!gd->isReference())
10130 {
10131 gd->writeDocumentation(*g_outputList);
10132 }
10133 }
10134}

References g_outputList, and Doxygen::groupLinkedMap.

Referenced by generateOutput().

◆ generateNamespaceClassDocs()

void generateNamespaceClassDocs ( const ClassLinkedRefMap & classList)
static

Definition at line 10139 of file doxygen.cpp.

10140{
10141 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10142 if (numThreads>1) // multi threaded processing
10143 {
10144 struct DocContext
10145 {
10146 DocContext(ClassDefMutable *cdm_,const OutputList &ol_)
10147 : cdm(cdm_), ol(ol_) {}
10148 ClassDefMutable *cdm;
10149 OutputList ol;
10150 };
10151 ThreadPool threadPool(numThreads);
10152 std::vector< std::future< std::shared_ptr<DocContext> > > results;
10153 // for each class in the namespace...
10154 for (const auto &cd : classList)
10155 {
10157 if (cdm)
10158 {
10159 auto ctx = std::make_shared<DocContext>(cdm,*g_outputList);
10160 auto processFile = [ctx]()
10161 {
10162 if ( ( ctx->cdm->isLinkableInProject() &&
10163 !ctx->cdm->isImplicitTemplateInstance()
10164 ) // skip external references, anonymous compounds and
10165 // template instances and nested classes
10166 && !ctx->cdm->isHidden() && !ctx->cdm->isEmbeddedInOuterScope()
10167 )
10168 {
10169 msg("Generating docs for compound {}...\n",ctx->cdm->displayName());
10170 ctx->cdm->writeDocumentation(ctx->ol);
10171 ctx->cdm->writeMemberList(ctx->ol);
10172 }
10173 ctx->cdm->writeDocumentationForInnerClasses(ctx->ol);
10174 return ctx;
10175 };
10176 results.emplace_back(threadPool.queue(processFile));
10177 }
10178 }
10179 // wait for the results
10180 for (auto &f : results)
10181 {
10182 auto ctx = f.get();
10183 }
10184 }
10185 else // single threaded processing
10186 {
10187 // for each class in the namespace...
10188 for (const auto &cd : classList)
10189 {
10191 if (cdm)
10192 {
10193 if ( ( cd->isLinkableInProject() &&
10194 !cd->isImplicitTemplateInstance()
10195 ) // skip external references, anonymous compounds and
10196 // template instances and nested classes
10197 && !cd->isHidden() && !cd->isEmbeddedInOuterScope()
10198 )
10199 {
10200 msg("Generating docs for compound {}...\n",cd->displayName());
10201
10204 }
10206 }
10207 }
10208 }
10209}
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 10211 of file doxygen.cpp.

10212{
10213 // for each concept in the namespace...
10214 for (const auto &cd : conceptList)
10215 {
10217 if ( cdm && cd->isLinkableInProject() && !cd->isHidden())
10218 {
10219 msg("Generating docs for concept {}...\n",cd->name());
10221 }
10222 }
10223}

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

Referenced by generateNamespaceDocs().

◆ generateNamespaceDocs()

void generateNamespaceDocs ( )
static

Definition at line 10225 of file doxygen.cpp.

10226{
10227 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
10228
10229 //writeNamespaceIndex(*g_outputList);
10230
10231 // for each namespace...
10232 for (const auto &nd : *Doxygen::namespaceLinkedMap)
10233 {
10234 if (nd->isLinkableInProject())
10235 {
10237 if (ndm)
10238 {
10239 msg("Generating docs for namespace {}\n",nd->displayName());
10241 }
10242 }
10243
10244 generateNamespaceClassDocs(nd->getClasses());
10245 if (sliceOpt)
10246 {
10247 generateNamespaceClassDocs(nd->getInterfaces());
10248 generateNamespaceClassDocs(nd->getStructs());
10249 generateNamespaceClassDocs(nd->getExceptions());
10250 }
10251 generateNamespaceConceptDocs(nd->getConcepts());
10252 }
10253}
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 13188 of file doxygen.cpp.

13189{
13190 AUTO_TRACE();
13191 /**************************************************************************
13192 * Initialize output generators *
13193 **************************************************************************/
13194
13195 /// add extra languages for which we can only produce syntax highlighted code
13197
13198 //// dump all symbols
13199 if (g_dumpSymbolMap)
13200 {
13201 dumpSymbolMap();
13202 exit(0);
13203 }
13204
13205 bool generateHtml = Config_getBool(GENERATE_HTML);
13206 bool generateLatex = Config_getBool(GENERATE_LATEX);
13207 bool generateMan = Config_getBool(GENERATE_MAN);
13208 bool generateRtf = Config_getBool(GENERATE_RTF);
13209 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
13210
13211
13213 if (generateHtml)
13214 {
13218 }
13219 if (generateLatex)
13220 {
13223 }
13224 if (generateDocbook)
13225 {
13228 }
13229 if (generateMan)
13230 {
13231 g_outputList->add<ManGenerator>();
13233 }
13234 if (generateRtf)
13235 {
13236 g_outputList->add<RTFGenerator>();
13238 }
13239 if (Config_getBool(USE_HTAGS))
13240 {
13242 QCString htmldir = Config_getString(HTML_OUTPUT);
13243 if (!Htags::execute(htmldir))
13244 err("USE_HTAGS is YES but htags(1) failed. \n");
13245 else if (!Htags::loadFilemap(htmldir))
13246 err("htags(1) ended normally but failed to load the filemap. \n");
13247 }
13248
13249 /**************************************************************************
13250 * Generate documentation *
13251 **************************************************************************/
13252
13253 g_s.begin("Generating style sheet...\n");
13254 //printf("writing style info\n");
13255 g_outputList->writeStyleInfo(0); // write first part
13256 g_s.end();
13257
13258 bool searchEngine = Config_getBool(SEARCHENGINE);
13259 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
13260
13261 g_s.begin("Generating search indices...\n");
13262 if (searchEngine && !serverBasedSearch && generateHtml)
13263 {
13265 }
13266
13267 // generate search indices (need to do this before writing other HTML
13268 // pages as these contain a drop down menu with options depending on
13269 // what categories we find in this function.
13270 if (generateHtml && searchEngine)
13271 {
13272 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
13273 Dir searchDir(searchDirName.str());
13274 if (!searchDir.exists() && !searchDir.mkdir(searchDirName.str()))
13275 {
13276 term("Could not create search results directory '{}' $PWD='{}'\n",
13277 searchDirName,Dir::currentDirPath());
13278 }
13279 HtmlGenerator::writeSearchData(searchDirName);
13280 if (!serverBasedSearch) // client side search index
13281 {
13283 }
13284 }
13285 g_s.end();
13286
13287 // copy static stuff
13288 if (generateHtml)
13289 {
13291 copyLogo(Config_getString(HTML_OUTPUT));
13292 copyIcon(Config_getString(HTML_OUTPUT));
13293 copyExtraFiles(Config_getList(HTML_EXTRA_FILES),"HTML_EXTRA_FILES",Config_getString(HTML_OUTPUT));
13294 }
13295 if (generateLatex)
13296 {
13298 copyLogo(Config_getString(LATEX_OUTPUT));
13299 copyIcon(Config_getString(LATEX_OUTPUT));
13300 copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT));
13301 }
13302 if (generateDocbook)
13303 {
13304 copyLogo(Config_getString(DOCBOOK_OUTPUT));
13305 copyIcon(Config_getString(DOCBOOK_OUTPUT));
13306 }
13307 if (generateRtf)
13308 {
13309 copyLogo(Config_getString(RTF_OUTPUT));
13310 copyIcon(Config_getString(RTF_OUTPUT));
13311 copyExtraFiles(Config_getList(RTF_EXTRA_FILES),"RTF_EXTRA_FILES",Config_getString(RTF_OUTPUT));
13312 }
13313
13315 if (fm.hasFormulas() && generateHtml
13316 && !Config_getBool(USE_MATHJAX))
13317 {
13318 g_s.begin("Generating images for formulas in HTML...\n");
13319 fm.generateImages(Config_getString(HTML_OUTPUT), Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg ?
13321 g_s.end();
13322 }
13323 if (fm.hasFormulas() && generateRtf)
13324 {
13325 g_s.begin("Generating images for formulas in RTF...\n");
13327 g_s.end();
13328 }
13329
13330 if (fm.hasFormulas() && generateDocbook)
13331 {
13332 g_s.begin("Generating images for formulas in Docbook...\n");
13334 g_s.end();
13335 }
13336
13337 g_s.begin("Generating example documentation...\n");
13339 g_s.end();
13340
13341 g_s.begin("Generating file sources...\n");
13343 g_s.end();
13344
13345 g_s.begin("Generating file documentation...\n");
13347 g_s.end();
13348
13349 g_s.begin("Generating page documentation...\n");
13351 g_s.end();
13352
13353 g_s.begin("Generating group documentation...\n");
13355 g_s.end();
13356
13357 g_s.begin("Generating class documentation...\n");
13359 g_s.end();
13360
13361 g_s.begin("Generating concept documentation...\n");
13363 g_s.end();
13364
13365 g_s.begin("Generating module documentation...\n");
13367 g_s.end();
13368
13369 g_s.begin("Generating namespace documentation...\n");
13371 g_s.end();
13372
13373 if (Config_getBool(GENERATE_LEGEND))
13374 {
13375 g_s.begin("Generating graph info page...\n");
13377 g_s.end();
13378 }
13379
13380 g_s.begin("Generating directory documentation...\n");
13382 g_s.end();
13383
13384 if (g_outputList->size()>0)
13385 {
13387 }
13388
13389 g_s.begin("finalizing index lists...\n");
13390 Doxygen::indexList->finalize();
13391 g_s.end();
13392
13393 g_s.begin("writing tag file...\n");
13394 writeTagFile();
13395 g_s.end();
13396
13397 if (Config_getBool(GENERATE_XML))
13398 {
13399 g_s.begin("Generating XML output...\n");
13401 generateXML();
13403 g_s.end();
13404 }
13405 if (Config_getBool(GENERATE_SQLITE3))
13406 {
13407 g_s.begin("Generating SQLITE3 output...\n");
13409 g_s.end();
13410 }
13411
13412 if (Config_getBool(GENERATE_AUTOGEN_DEF))
13413 {
13414 g_s.begin("Generating AutoGen DEF output...\n");
13415 generateDEF();
13416 g_s.end();
13417 }
13418 if (Config_getBool(GENERATE_PERLMOD))
13419 {
13420 g_s.begin("Generating Perl module output...\n");
13422 g_s.end();
13423 }
13424 if (generateHtml && searchEngine && serverBasedSearch)
13425 {
13426 g_s.begin("Generating search index\n");
13427 if (Doxygen::searchIndex.kind()==SearchIndexIntf::Internal) // write own search index
13428 {
13430 Doxygen::searchIndex.write(Config_getString(HTML_OUTPUT)+"/search/search.idx");
13431 }
13432 else // write data for external search index
13433 {
13435 QCString searchDataFile = Config_getString(SEARCHDATA_FILE);
13436 if (searchDataFile.isEmpty())
13437 {
13438 searchDataFile="searchdata.xml";
13439 }
13440 if (!Portable::isAbsolutePath(searchDataFile.data()))
13441 {
13442 searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/");
13443 }
13444 Doxygen::searchIndex.write(searchDataFile);
13445 }
13446 g_s.end();
13447 }
13448
13449 if (generateRtf)
13450 {
13451 g_s.begin("Combining RTF output...\n");
13452 if (!RTFGenerator::preProcessFileInplace(Config_getString(RTF_OUTPUT),"refman.rtf"))
13453 {
13454 err("An error occurred during post-processing the RTF files!\n");
13455 }
13456 g_s.end();
13457 }
13458
13459 g_s.begin("Running plantuml with JAVA...\n");
13461 g_s.end();
13462
13463 if (Config_getBool(HAVE_DOT))
13464 {
13465 g_s.begin("Running dot...\n");
13467 g_s.end();
13468 }
13469
13470 if (generateHtml &&
13471 Config_getBool(GENERATE_HTMLHELP) &&
13472 !Config_getString(HHC_LOCATION).isEmpty())
13473 {
13474 g_s.begin("Running html help compiler...\n");
13476 g_s.end();
13477 }
13478
13479 if ( generateHtml &&
13480 Config_getBool(GENERATE_QHP) &&
13481 !Config_getString(QHG_LOCATION).isEmpty())
13482 {
13483 g_s.begin("Running qhelpgenerator...\n");
13485 g_s.end();
13486 }
13487
13488 g_outputList->cleanup();
13490
13491 msg("type lookup cache used {}/{} hits={} misses={}\n",
13493 Doxygen::typeLookupCache->capacity(),
13495 Doxygen::typeLookupCache->misses());
13496 msg("symbol lookup cache used {}/{} hits={} misses={}\n",
13498 Doxygen::symbolLookupCache->capacity(),
13500 Doxygen::symbolLookupCache->misses());
13501 int typeCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::typeLookupCache->misses()*2/3)); // part of the cache is flushed, hence the 2/3 correction factor
13502 int symbolCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::symbolLookupCache->misses()));
13503 int cacheParam = std::max(typeCacheParam,symbolCacheParam);
13504 if (cacheParam>Config_getInt(LOOKUP_CACHE_SIZE))
13505 {
13506 msg("Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is {} at the cost of higher memory usage.\n",cacheParam);
13507 }
13508
13510 {
13511
13512 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
13513 if (numThreads<1) numThreads=1;
13514 msg("Total elapsed time: {:.6f} seconds\n(of which an average of {:.6f} seconds per thread waiting for external tools to finish)\n",
13515 (static_cast<double>(Debug::elapsedTime())),
13516 Portable::getSysElapsedTime()/static_cast<double>(numThreads)
13517 );
13518 g_s.print();
13519
13521 msg("finished...\n");
13523 }
13524 else
13525 {
13526 msg("finished...\n");
13527 }
13528
13529
13530 /**************************************************************************
13531 * Start cleaning up *
13532 **************************************************************************/
13533
13535
13537 Dir thisDir;
13538 thisDir.remove(Doxygen::filterDBFileName.str());
13540 exitTracing();
13542 delete Doxygen::clangUsrMap;
13544
13545 //dumpDocNodeSizes();
13546}
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:1197
static void writeSearchPage()
Definition htmlgen.cpp:3197
static void writeTabData()
Additional initialization after indices have been created.
Definition htmlgen.cpp:1357
static void writeSearchData(const QCString &dir)
Definition htmlgen.cpp:1366
static void writeExternalSearchPage()
Definition htmlgen.cpp:3296
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:8784
static void copyIcon(const QCString &outputOption)
static void generatePageDocs()
Definition doxygen.cpp:9999
static void generateFileSources()
Definition doxygen.cpp:8618
static void copyLogo(const QCString &outputOption)
static void generateClassDocs()
Definition doxygen.cpp:9219
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:9245
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:5188
void cleanupInlineGraph()
Definition util.cpp:6993
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 9999 of file doxygen.cpp.

10000{
10001 //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageLinkedMap->count());
10002 if (Index::instance().numDocumentedPages()==0) return;
10003 for (const auto &pd : *Doxygen::pageLinkedMap)
10004 {
10005 if (!pd->getGroupDef() && !pd->isReference())
10006 {
10007 msg("Generating docs for page {}...\n",pd->name());
10008 pd->writeDocumentation(*g_outputList);
10009 }
10010 }
10011}

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

Referenced by generateOutput().

◆ generateXRefPages()

void generateXRefPages ( )
static

Definition at line 5600 of file doxygen.cpp.

5601{
5602 AUTO_TRACE();
5604 {
5605 rl->generatePage();
5606 }
5607}
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 11427 of file doxygen.cpp.

11428{
11429 char *s=nullptr;
11430 if (qstrlen(&argv[optInd][2])>0)
11431 s=&argv[optInd][2];
11432 else if (optInd+1<argc && argv[optInd+1][0]!='-')
11433 s=argv[++optInd];
11434 return s;
11435}
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 10708 of file doxygen.cpp.

10709{
10710 QCString fileName=fn;
10711 QCString extension;
10712 int sep = fileName.findRev('/');
10713 int ei = fileName.findRev('.');
10714 if (ei!=-1 && (sep==-1 || ei>sep)) // matches dir/file.ext but not dir.1/file
10715 {
10716 extension=fileName.right(fileName.length()-ei);
10717 }
10718 else
10719 {
10720 extension = ".no_extension";
10721 }
10722
10723 return Doxygen::parserManager->getOutlineParser(extension);
10724}

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

4535{
4536 std::map<std::string,int> templateNames;
4537 int count=0;
4538 for (const Argument &arg : templateArguments)
4539 {
4540 static const reg::Ex re(R"(\a[\w:]*)");
4541 reg::Iterator it(name,re);
4543 for (; it!=end ; ++it)
4544 {
4545 const auto &match = *it;
4546 std::string n = match.str();
4547 if (n==arg.name.str())
4548 {
4549 if (templateNames.find(n)==templateNames.end())
4550 {
4551 templateNames.emplace(n,count);
4552 }
4553 }
4554 }
4555 }
4556 return templateNames;
4557}

References end().

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

◆ haveEqualFileNames()

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

Definition at line 9574 of file doxygen.cpp.

9575{
9576 if (const FileDef *fd = md->getFileDef())
9577 {
9578 return fd->absFilePath() == root->fileName;
9579 }
9580 return false;
9581}

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

Referenced by findDefineDocumentation().

◆ inheritDocumentation()

void inheritDocumentation ( )
static

Definition at line 9266 of file doxygen.cpp.

9267{
9268 for (const auto &mn : *Doxygen::memberNameLinkedMap)
9269 {
9270 for (const auto &imd : *mn)
9271 {
9272 MemberDefMutable *md = toMemberDefMutable(imd.get());
9273 //static int count=0;
9274 //printf("%04d Member '%s'\n",count++,qPrint(md->qualifiedName()));
9275 if (md && md->documentation().isEmpty() && md->briefDescription().isEmpty())
9276 { // no documentation yet
9277 const MemberDef *bmd = md->reimplements();
9278 while (bmd && bmd->documentation().isEmpty() &&
9279 bmd->briefDescription().isEmpty()
9280 )
9281 { // search up the inheritance tree for a documentation member
9282 //printf("bmd=%s class=%s\n",qPrint(bmd->name()),qPrint(bmd->getClassDef()->name()));
9283 bmd = bmd->reimplements();
9284 }
9285 if (bmd) // copy the documentation from the reimplemented member
9286 {
9287 md->setInheritsDocsFrom(bmd);
9288 md->setDocumentation(bmd->documentation(),bmd->docFile(),bmd->docLine());
9290 md->setBriefDescription(bmd->briefDescription(),bmd->briefFile(),bmd->briefLine());
9291 md->copyArgumentNames(bmd);
9293 }
9294 }
9295 }
9296 }
9297}
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 11454 of file doxygen.cpp.

11455{
11456 initResources();
11457 QCString lang = Portable::getenv("LC_ALL");
11458 if (!lang.isEmpty()) Portable::setenv("LANG",lang);
11459 std::setlocale(LC_ALL,"");
11460 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
11461 std::setlocale(LC_NUMERIC,"C");
11462
11464
11488
11489 // register any additional parsers here...
11490
11492
11493#if USE_LIBCLANG
11495#endif
11504 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
11505 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
11506 //Doxygen::tagDestinationDict.setAutoDelete(TRUE);
11508
11509 // initialization of these globals depends on
11510 // configuration switches so we need to postpone these
11511 Doxygen::globalScope = nullptr;
11520
11521}
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:5121

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

6712{
6713 if (outerScope && outerScope!=Doxygen::globalScope)
6714 {
6715 auto aliasMd = createMemberDefAlias(outerScope,md);
6716 if (outerScope->definitionType()==Definition::TypeClass)
6717 {
6718 ClassDefMutable *cdm = toClassDefMutable(outerScope);
6719 if (cdm)
6720 {
6721 cdm->insertMember(aliasMd.get());
6722 }
6723 }
6724 else if (outerScope->definitionType()==Definition::TypeNamespace)
6725 {
6726 NamespaceDefMutable *ndm = toNamespaceDefMutable(outerScope);
6727 if (ndm)
6728 {
6729 ndm->insertMember(aliasMd.get());
6730 }
6731 }
6732 else if (outerScope->definitionType()==Definition::TypeFile)
6733 {
6734 toFileDef(outerScope)->insertMember(aliasMd.get());
6735 }
6736 if (aliasMd)
6737 {
6738 Doxygen::functionNameLinkedMap->add(md->name())->push_back(std::move(aliasMd));
6739 }
6740 }
6741}
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 5268 of file doxygen.cpp.

5269{
5270 if ( !root->name.isEmpty() )
5271 {
5272 if (root->section.isCompound())
5273 // is it a compound (class, struct, union, interface ...)
5274 {
5275 return TRUE;
5276 }
5277 else if (root->section.isCompoundDoc())
5278 // is it a documentation block with inheritance info.
5279 {
5280 bool hasExtends = !root->extends.empty();
5281 if (hasExtends) return TRUE;
5282 }
5283 }
5284 return FALSE;
5285}

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

5781{
5782 const GroupDef *gd = md->getGroupDef();
5783 if (!gd)
5784 {
5785 return allowNoGroup;
5786 }
5787
5788 for (const auto &g : root->groups)
5789 {
5790 if (g.groupname == gd->name())
5791 {
5792 return true; // matching group
5793 }
5794 }
5795
5796 return false;
5797}

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

4886{
4887 QCString n=name;
4888 int index=n.find('<');
4889 if (index!=-1)
4890 {
4891 n=n.left(index);
4892 }
4893 bool result = rightScopeMatch(scope,n);
4894 return result;
4895}

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

Referenced by findClassRelation().

◆ isSpecialization()

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

Definition at line 6012 of file doxygen.cpp.

6016{
6017 auto srcIt = srcTempArgLists.begin();
6018 auto dstIt = dstTempArgLists.begin();
6019 while (srcIt!=srcTempArgLists.end() && dstIt!=dstTempArgLists.end())
6020 {
6021 if ((*srcIt).size()!=(*dstIt).size()) return TRUE;
6022 ++srcIt;
6023 ++dstIt;
6024 }
6025 return FALSE;
6026}

References FALSE, and TRUE.

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

◆ isSymbolHidden()

bool isSymbolHidden ( const Definition * d)
static

Definition at line 9013 of file doxygen.cpp.

9014{
9015 bool hidden = d->isHidden();
9016 const Definition *parent = d->getOuterScope();
9017 return parent ? hidden || isSymbolHidden(parent) : hidden;
9018}
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:1327

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

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

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

11450{
11451 return []() { return std::make_unique<T>(); };
11452}

Referenced by initDoxygen().

◆ makeTemplateInstanceRelation()

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

Definition at line 5342 of file doxygen.cpp.

5343{
5344 AUTO_TRACE("root->name={} cd={}",root->name,cd->name());
5345 int i = root->name.find('<');
5346 int j = root->name.findRev('>');
5347 int k = root->name.find("::",j+1); // A<T::B> => ok, A<T>::B => nok
5348 if (i!=-1 && j!=-1 && k==-1 && root->lang!=SrcLangExt::CSharp && root->lang!=SrcLangExt::Java)
5349 {
5350 ClassDefMutable *master = getClassMutable(root->name.left(i));
5351 if (master && master!=cd && !cd->templateMaster())
5352 {
5353 AUTO_TRACE_ADD("class={} master={}",cd->name(),cd->templateMaster()?cd->templateMaster()->name():"<none>",master->name());
5354 cd->setTemplateMaster(master);
5355 master->insertExplicitTemplateInstance(cd,root->name.mid(i));
5356 }
5357 }
5358}
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 8566 of file doxygen.cpp.

8567{
8568 AUTO_TRACE();
8569 // merge members of categories into the class they extend
8570 for (const auto &cd : *Doxygen::classLinkedMap)
8571 {
8572 int i=cd->name().find('(');
8573 if (i!=-1) // it is an Objective-C category
8574 {
8575 QCString baseName=cd->name().left(i);
8576 ClassDefMutable *baseClass=toClassDefMutable(Doxygen::classLinkedMap->find(baseName));
8577 if (baseClass)
8578 {
8579 AUTO_TRACE_ADD("merging members of category {} into {}",cd->name(),baseClass->name());
8580 baseClass->mergeCategory(cd.get());
8581 }
8582 }
8583 }
8584}
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 10726 of file doxygen.cpp.

10729{
10730 QCString fileName=fn;
10731 AUTO_TRACE("fileName={}",fileName);
10732 QCString extension;
10733 int ei = fileName.findRev('.');
10734 if (ei!=-1)
10735 {
10736 extension=fileName.right(fileName.length()-ei);
10737 }
10738 else
10739 {
10740 extension = ".no_extension";
10741 }
10742
10743 FileInfo fi(fileName.str());
10744 std::string preBuf;
10745
10746 if (Config_getBool(ENABLE_PREPROCESSING) &&
10747 parser.needsPreprocessing(extension))
10748 {
10749 Preprocessor preprocessor;
10750 const StringVector &includePath = Config_getList(INCLUDE_PATH);
10751 for (const auto &s : includePath)
10752 {
10753 std::string absPath = FileInfo(s).absFilePath();
10754 preprocessor.addSearchDir(absPath);
10755 }
10756 std::string inBuf;
10757 msg("Preprocessing {}...\n",fn);
10758 readInputFile(fileName,inBuf);
10759 addTerminalCharIfMissing(inBuf,'\n');
10760 preprocessor.processFile(fileName,inBuf,preBuf);
10761 }
10762 else // no preprocessing
10763 {
10764 msg("Reading {}...\n",fn);
10765 readInputFile(fileName,preBuf);
10766 addTerminalCharIfMissing(preBuf,'\n');
10767 }
10768
10769 std::string convBuf;
10770 convBuf.reserve(preBuf.size()+1024);
10771
10772 // convert multi-line C++ comments to C style comments
10773 convertCppComments(preBuf,convBuf,fileName.str());
10774
10775 std::shared_ptr<Entry> fileRoot = std::make_shared<Entry>();
10776 // use language parse to parse the file
10777 if (clangParser)
10778 {
10779 if (newTU) clangParser->parse();
10780 clangParser->switchToFile(fd);
10781 }
10782 parser.parseInput(fileName,convBuf.data(),fileRoot,clangParser);
10783 fileRoot->setFileDef(fd);
10784 return fileRoot;
10785}
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:4156
void addSearchDir(const QCString &dir)
Definition pre.l:4138
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:5533

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

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

10940{
10941 AUTO_TRACE();
10942#if USE_LIBCLANG
10944 {
10945 StringUnorderedSet processedFiles;
10946
10947 // create a dictionary with files to process
10948 StringUnorderedSet filesToProcess;
10949 for (const auto &s : g_inputFiles)
10950 {
10951 filesToProcess.insert(s);
10952 }
10953
10954 // process source files (and their include dependencies)
10955 for (const auto &s : g_inputFiles)
10956 {
10957 bool ambig = false;
10958 QCString qs =s;
10960 ASSERT(fd!=nullptr);
10961 if (fd->isSource() && !fd->isReference() && getLanguageFromFileName(qs)==SrcLangExt::Cpp) // this is a source file
10962 {
10963 auto clangParser = ClangParser::instance()->createTUParser(fd);
10964 auto parser { getParserForFile(qs) };
10965 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
10966 root->moveToSubEntryAndKeep(fileRoot);
10967 processedFiles.insert(s);
10968
10969 // Now process any include files in the same translation unit
10970 // first. When libclang is used this is much more efficient.
10971 for (auto incFile : clangParser->filesInSameTU())
10972 {
10973 //printf(" file %s\n",qPrint(incFile));
10974 if (filesToProcess.find(incFile)!=filesToProcess.end() && // file need to be processed
10975 processedFiles.find(incFile)==processedFiles.end()) // and is not processed already
10976 {
10978 if (ifd && !ifd->isReference())
10979 {
10980 //printf(" Processing %s in same translation unit as %s\n",qPrint(incFile),qPrint(qs));
10981 fileRoot = parseFile(*parser.get(),ifd,incFile,clangParser.get(),false);
10982 root->moveToSubEntryAndKeep(fileRoot);
10983 processedFiles.insert(incFile);
10984 }
10985 }
10986 }
10987 }
10988 }
10989 // process remaining files
10990 for (const auto &s : g_inputFiles)
10991 {
10992 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
10993 {
10994 bool ambig = false;
10995 QCString qs = s;
10997 if (getLanguageFromFileName(qs)==SrcLangExt::Cpp) // not yet processed
10998 {
10999 auto clangParser = ClangParser::instance()->createTUParser(fd);
11000 auto parser { getParserForFile(qs) };
11001 auto fileRoot = parseFile(*parser.get(),fd,qs,clangParser.get(),true);
11002 root->moveToSubEntryAndKeep(fileRoot);
11003 }
11004 else
11005 {
11006 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
11007 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
11008 root->moveToSubEntryAndKeep(fileRoot);
11009 }
11010 processedFiles.insert(s);
11011 }
11012 }
11013 }
11014 else // normal processing
11015#endif
11016 {
11017 for (const auto &s : g_inputFiles)
11018 {
11019 bool ambig = false;
11020 QCString qs = s;
11022 ASSERT(fd!=nullptr);
11023 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(qs) };
11024 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,qs,nullptr,true);
11025 root->moveToSubEntryAndKeep(std::move(fileRoot));
11026 }
11027 }
11028}

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

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

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

10046{
10048 {
10049 QCString indentStr;
10050 indentStr.fill(' ',indent);
10051 Debug::print(Debug::Entries,0,"{}{} at {}:{} (sec={}, spec={})\n",
10052 indentStr.isEmpty()?"":indentStr,
10053 root->name.isEmpty()?"<empty>":root->name,
10054 root->fileName,root->startLine,
10055 root->section.to_string(),
10056 root->spec.to_string());
10057 for (const auto &e : root->children())
10058 {
10059 printNavTree(e.get(),indent+2);
10060 }
10061 }
10062}
@ 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 10068 of file doxygen.cpp.

10069{
10071 {
10072 for (const auto &si : SectionManager::instance())
10073 {
10074 Debug::print(Debug::Sections,0,"Section = {}, file = {}, title = {}, type = {}, ref = {}\n",
10075 si->label(),si->fileName(),si->title(),si->type().level(),si->ref());
10076 }
10077 }
10078}
@ 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 11571 of file doxygen.cpp.

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

11116{
11117 std::string dirName = fi->absFilePath();
11118 if (paths && !dirName.empty())
11119 {
11120 paths->insert(dirName);
11121 }
11122 //printf("%s isSymLink()=%d\n",qPrint(dirName),fi->isSymLink());
11123 if (fi->isSymLink())
11124 {
11125 dirName = resolveSymlink(dirName);
11126 if (dirName.empty())
11127 {
11128 //printf("RECURSIVE SYMLINK: %s\n",qPrint(dirName));
11129 return; // recursive symlink
11130 }
11131 }
11132
11133 if (g_pathsVisited.find(dirName)!=g_pathsVisited.end())
11134 {
11135 //printf("PATH ALREADY VISITED: %s\n",qPrint(dirName));
11136 return; // already visited path
11137 }
11138 g_pathsVisited.insert(dirName);
11139
11140 Dir dir(dirName);
11141 msg("Searching for files in directory {}\n", fi->absFilePath());
11142 //printf("killSet=%p count=%d\n",killSet,killSet ? (int)killSet->count() : -1);
11143
11144 StringVector dirResultList;
11145
11146 for (const auto &dirEntry : dir.iterator())
11147 {
11148 FileInfo cfi(dirEntry.path());
11149 auto checkPatterns = [&]() -> bool
11150 {
11151 return (patList==nullptr || patternMatch(cfi,*patList)) &&
11152 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
11153 (killSet==nullptr || killSet->find(cfi.absFilePath())==killSet->end());
11154 };
11155
11156 if (exclSet==nullptr || exclSet->find(cfi.absFilePath())==exclSet->end())
11157 { // file should not be excluded
11158 //printf("killSet->find(%s)\n",qPrint(cfi->absFilePath()));
11159 if (Config_getBool(EXCLUDE_SYMLINKS) && cfi.isSymLink())
11160 {
11161 }
11162 else if (!cfi.exists() || !cfi.isReadable())
11163 {
11164 if (errorIfNotExist && checkPatterns())
11165 {
11166 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",cfi.absFilePath());
11167 }
11168 }
11169 else if (cfi.isFile() && checkPatterns())
11170 {
11171 std::string name=cfi.fileName();
11172 std::string path=cfi.dirPath()+"/";
11173 std::string fullName=path+name;
11174 if (fnMap)
11175 {
11176 auto fd = createFileDef(path,name);
11177 FileName *fn=nullptr;
11178 if (!name.empty())
11179 {
11180 fn = fnMap->add(name,fullName);
11181 fn->push_back(std::move(fd));
11182 }
11183 }
11184 dirResultList.push_back(fullName);
11185 if (resultSet) resultSet->insert(fullName);
11186 if (killSet) killSet->insert(fullName);
11187 }
11188 else if (recursive &&
11189 cfi.isDir() &&
11190 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
11191 cfi.fileName().at(0)!='.') // skip "." ".." and ".dir"
11192 {
11193 FileInfo acfi(cfi.absFilePath());
11194 readDir(&acfi,fnMap,exclSet,
11195 patList,exclPatList,&dirResultList,resultSet,errorIfNotExist,
11196 recursive,killSet,paths);
11197 }
11198 }
11199 }
11200 if (resultList && !dirResultList.empty())
11201 {
11202 // sort the resulting list to make the order platform independent.
11203 std::stable_sort(dirResultList.begin(),
11204 dirResultList.end(),
11205 [](const auto &f1,const auto &f2) { return qstricmp_sort(f1.c_str(),f2.c_str())<0; });
11206
11207 // append the sorted results to resultList
11208 resultList->insert(resultList->end(), dirResultList.begin(), dirResultList.end());
11209 }
11210}
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:5687

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

11229{
11230 //printf("killSet count=%d\n",killSet ? (int)killSet->size() : -1);
11231 // strip trailing slashes
11232 if (s.isEmpty()) return;
11233
11234 g_pathsVisited.clear();
11235
11236 FileInfo fi(s.str());
11237 //printf("readFileOrDirectory(%s)\n",s);
11238 {
11239 if (exclSet==nullptr || exclSet->find(fi.absFilePath())==exclSet->end())
11240 {
11241 if (Config_getBool(EXCLUDE_SYMLINKS) && fi.isSymLink())
11242 {
11243 }
11244 else if (!fi.exists() || !fi.isReadable())
11245 {
11246 if (errorIfNotExist)
11247 {
11248 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",s);
11249 }
11250 }
11251 else if (fi.isFile())
11252 {
11253 std::string dirPath = fi.dirPath(true);
11254 std::string filePath = fi.absFilePath();
11255 if (paths && !dirPath.empty())
11256 {
11257 paths->insert(dirPath);
11258 }
11259 //printf("killSet.find(%s)=%d\n",qPrint(fi.absFilePath()),killSet.find(fi.absFilePath())!=killSet.end());
11260 if (killSet==nullptr || killSet->find(filePath)==killSet->end())
11261 {
11262 std::string name=fi.fileName();
11263 if (fnMap)
11264 {
11265 auto fd = createFileDef(dirPath+"/",name);
11266 if (!name.empty())
11267 {
11268 FileName *fn = fnMap->add(name,filePath);
11269 fn->push_back(std::move(fd));
11270 }
11271 }
11272 if (resultList || resultSet)
11273 {
11274 if (resultList) resultList->push_back(filePath);
11275 if (resultSet) resultSet->insert(filePath);
11276 }
11277
11278 if (killSet) killSet->insert(fi.absFilePath());
11279 }
11280 }
11281 else if (fi.isDir()) // readable dir
11282 {
11283 readDir(&fi,fnMap,exclSet,patList,
11284 exclPatList,resultList,resultSet,errorIfNotExist,
11285 recursive,killSet,paths);
11286 }
11287 }
11288 }
11289}

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

10429{
10430 QCString fileName;
10431 QCString destName;
10432 int eqPos = tagLine.find('=');
10433 if (eqPos!=-1) // tag command contains a destination
10434 {
10435 fileName = tagLine.left(eqPos).stripWhiteSpace();
10436 destName = tagLine.right(tagLine.length()-eqPos-1).stripWhiteSpace();
10437 if (fileName.isEmpty() || destName.isEmpty()) return;
10438 //printf("insert tagDestination %s->%s\n",qPrint(fi.fileName()),qPrint(destName));
10439 }
10440 else
10441 {
10442 fileName = tagLine;
10443 }
10444
10445 FileInfo fi(fileName.str());
10446 if (!fi.exists() || !fi.isFile())
10447 {
10448 err("Tag file '{}' does not exist or is not a file. Skipping it...\n",fileName);
10449 return;
10450 }
10451
10452 if (Doxygen::tagFileSet.find(fi.absFilePath()) != Doxygen::tagFileSet.end()) return;
10453
10454 Doxygen::tagFileSet.emplace(fi.absFilePath());
10455
10456 if (!destName.isEmpty())
10457 {
10458 Doxygen::tagDestinationMap.emplace(fi.absFilePath(), destName.str());
10459 msg("Reading tag file '{}', location '{}'...\n",fileName,destName);
10460 }
10461 else
10462 {
10463 msg("Reading tag file '{}'...\n",fileName);
10464 }
10465
10466 parseTagFile(root,fi.absFilePath().c_str());
10467}
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 11032 of file doxygen.cpp.

11033{
11034 int sepPos=0;
11035 int oldPos=0;
11036 StringUnorderedSet nonSymlinks;
11037 StringUnorderedSet known;
11038 QCString result(path);
11039 QCString oldPrefix = "/";
11040 do
11041 {
11042#if defined(_WIN32)
11043 // UNC path, skip server and share name
11044 if (sepPos==0 && (result.startsWith("//") || result.startsWith("\\\\")))
11045 sepPos = result.find('/',2);
11046 if (sepPos!=-1)
11047 sepPos = result.find('/',sepPos+1);
11048#else
11049 sepPos = result.find('/',sepPos+1);
11050#endif
11051 QCString prefix = sepPos==-1 ? result : result.left(sepPos);
11052 if (nonSymlinks.find(prefix.str())==nonSymlinks.end())
11053 {
11054 FileInfo fi(prefix.str());
11055 if (fi.isSymLink())
11056 {
11057 QCString target = fi.readLink();
11058 bool isRelative = FileInfo(target.str()).isRelative();
11059 if (isRelative)
11060 {
11061 target = Dir::cleanDirPath(oldPrefix.str()+"/"+target.str());
11062 }
11063 if (sepPos!=-1)
11064 {
11065 if (fi.isDir() && target.length()>0 && target.at(target.length()-1)!='/')
11066 {
11067 target+='/';
11068 }
11069 target+=result.mid(sepPos);
11070 }
11071 result = Dir::cleanDirPath(target.str());
11072 if (known.find(result.str())!=known.end()) return std::string(); // recursive symlink!
11073 known.insert(result.str());
11074 if (isRelative)
11075 {
11076 sepPos = oldPos;
11077 }
11078 else // link to absolute path
11079 {
11080 sepPos = 0;
11081 oldPrefix = "/";
11082 }
11083 }
11084 else
11085 {
11086 nonSymlinks.insert(prefix.str());
11087 oldPrefix = prefix;
11088 }
11089 oldPos = sepPos;
11090 }
11091 }
11092 while (sepPos!=-1);
11093 return Dir::cleanDirPath(result.str());
11094}
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 4855 of file doxygen.cpp.

4856{
4857 // For a statement like 'using X = T<A>', add a template instance 'T<A>' as a symbol, so it can
4858 // be used to match arguments (see issue #11111)
4859 AUTO_TRACE();
4860 QCString ttype = md->typeString();
4861 ttype.stripPrefix("typedef ");
4862 int ti=ttype.find('<');
4863 if (ti!=-1)
4864 {
4865 QCString templateClassName = ttype.left(ti);
4866 SymbolResolver resolver(root->fileDef());
4867 ClassDefMutable *baseClass = resolver.resolveClassMutable(scope ? scope : Doxygen::globalScope,
4868 templateClassName, true, true);
4869 AUTO_TRACE_ADD("templateClassName={} baseClass={}",templateClassName,baseClass?baseClass->name():"<none>");
4870 if (baseClass)
4871 {
4872 const ArgumentList &tl = baseClass->templateArguments();
4873 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,templateClassName.str());
4875 baseClass,
4876 ttype.mid(ti),
4877 templateNames,
4878 baseClass->isArtificial());
4879 }
4880 }
4881}

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

9932{
9933 for (const auto &si : SectionManager::instance())
9934 {
9935 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
9936 // qPrint(si->label),si->definition?qPrint(si->definition->name()):"<none>",
9937 // qPrint(si->fileName));
9938 PageDef *pd=nullptr;
9939
9940 // hack: the items of a todo/test/bug/deprecated list are all fragments from
9941 // different files, so the resulting section's all have the wrong file
9942 // name (not from the todo/test/bug/deprecated list, but from the file in
9943 // which they are defined). We correct this here by looking at the
9944 // generated section labels!
9946 {
9947 QCString label="_"+rl->listName(); // "_todo", "_test", ...
9948 if (si->label().left(label.length())==label)
9949 {
9950 si->setFileName(rl->listName());
9951 si->setGenerated(TRUE);
9952 break;
9953 }
9954 }
9955
9956 //printf("start: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9957 if (!si->generated())
9958 {
9959 // if this section is in a page and the page is in a group, then we
9960 // have to adjust the link file name to point to the group.
9961 if (!si->fileName().isEmpty() &&
9962 (pd=Doxygen::pageLinkedMap->find(si->fileName())) &&
9963 pd->getGroupDef())
9964 {
9965 si->setFileName(pd->getGroupDef()->getOutputFileBase());
9966 }
9967
9968 if (si->definition())
9969 {
9970 // TODO: there should be one function in Definition that returns
9971 // the file to link to, so we can avoid the following tests.
9972 const GroupDef *gd=nullptr;
9973 if (si->definition()->definitionType()==Definition::TypeMember)
9974 {
9975 gd = (toMemberDef(si->definition()))->getGroupDef();
9976 }
9977
9978 if (gd)
9979 {
9980 si->setFileName(gd->getOutputFileBase());
9981 }
9982 else
9983 {
9984 //si->fileName=si->definition->getOutputFileBase();
9985 //printf("Setting si->fileName to %s\n",qPrint(si->fileName));
9986 }
9987 }
9988 }
9989 //printf("end: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9990 }
9991}
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 10255 of file doxygen.cpp.

10256{
10257 std::string oldDir = Dir::currentDirPath();
10258 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10261 {
10262 err("failed to run html help compiler on {}\n", HtmlHelp::hhpFileName);
10263 }
10264 Dir::setCurrent(oldDir);
10265}
@ 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 10267 of file doxygen.cpp.

10268{
10269 QCString args = Qhp::qhpFileName + " -o \"" + Qhp::getQchFileName() + "\"";
10270 std::string oldDir = Dir::currentDirPath();
10271 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10272
10273 QCString qhgLocation=Config_getString(QHG_LOCATION);
10274 if (Debug::isFlagSet(Debug::Qhp)) // produce info for debugging
10275 {
10276 // run qhelpgenerator -v and extract the Qt version used
10277 QCString cmd=qhgLocation+ " -v 2>&1";
10278 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10279 FILE *f=Portable::popen(cmd,"r");
10280 if (!f)
10281 {
10282 err("could not execute {}\n",qhgLocation);
10283 }
10284 else
10285 {
10286 const size_t bufSize = 1024;
10287 char inBuf[bufSize+1];
10288 size_t numRead=fread(inBuf,1,bufSize,f);
10289 inBuf[numRead] = '\0';
10290 Debug::print(Debug::Qhp,0,"{}",inBuf);
10292
10293 int qtVersion=0;
10294 static const reg::Ex versionReg(R"(Qt (\d+)\.(\d+)\.(\d+))");
10296 std::string s = inBuf;
10297 if (reg::search(s,match,versionReg))
10298 {
10299 qtVersion = 10000*QCString(match[1].str()).toInt() +
10300 100*QCString(match[2].str()).toInt() +
10301 QCString(match[3].str()).toInt();
10302 }
10303 if (qtVersion>0 && (qtVersion<60000 || qtVersion >= 60205))
10304 {
10305 // dump the output of qhelpgenerator -c file.qhp
10306 // Qt<6 or Qt>=6.2.5 or higher, see https://bugreports.qt.io/browse/QTBUG-101070
10307 cmd=qhgLocation+ " -c " + Qhp::qhpFileName + " 2>&1";
10308 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
10309 f=Portable::popen(cmd,"r");
10310 if (!f)
10311 {
10312 err("could not execute {}\n",qhgLocation);
10313 }
10314 else
10315 {
10316 std::string output;
10317 while ((numRead=fread(inBuf,1,bufSize,f))>0)
10318 {
10319 inBuf[numRead] = '\0';
10320 output += inBuf;
10321 }
10323 Debug::print(Debug::Qhp,0,"{}",output);
10324 }
10325 }
10326 }
10327 }
10328
10329 if (Portable::system(qhgLocation, args, FALSE))
10330 {
10331 err("failed to run qhelpgenerator on {}\n",Qhp::qhpFileName);
10332 }
10333 Dir::setCurrent(oldDir);
10334}
@ 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 6028 of file doxygen.cpp.

6029{
6030 bool result=FALSE;
6031 //printf("> scopeIsTemplate(%s)\n",qPrint(d?d->name():"null"));
6033 {
6034 auto cd = toClassDef(d);
6035 result = cd->templateArguments().hasParameters() || cd->templateMaster()!=nullptr ||
6037 }
6038 //printf("< scopeIsTemplate=%d\n",result);
6039 return result;
6040}

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

Referenced by addMemberFunction(), and scopeIsTemplate().

◆ searchInputFiles()

void searchInputFiles ( )

Definition at line 12272 of file doxygen.cpp.

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

9067{
9068 for (const auto &cd : *Doxygen::classLinkedMap)
9069 {
9070 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9071 if (cdm)
9072 {
9073 cdm->setAnonymousEnumType();
9074 }
9075 }
9076}
virtual void setAnonymousEnumType()=0

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

Referenced by parseInput().

◆ sortMemberLists()

void sortMemberLists ( )
static

Definition at line 8971 of file doxygen.cpp.

8972{
8973 // sort class member lists
8974 for (const auto &cd : *Doxygen::classLinkedMap)
8975 {
8976 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8977 if (cdm)
8978 {
8979 cdm->sortMemberLists();
8980 }
8981 }
8982
8983 // sort namespace member lists
8984 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8985 {
8987 if (ndm)
8988 {
8989 ndm->sortMemberLists();
8990 }
8991 }
8992
8993 // sort file member lists
8994 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8995 {
8996 for (const auto &fd : *fn)
8997 {
8998 fd->sortMemberLists();
8999 }
9000 }
9001
9002 // sort group member lists
9003 for (const auto &gd : *Doxygen::groupLinkedMap)
9004 {
9005 gd->sortMemberLists();
9006 }
9007
9009}
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 12139 of file doxygen.cpp.

12140{
12141 signal(SIGINT,SIG_DFL); // Re-register signal handler for default action
12142 Dir thisDir;
12143 msg("Cleaning up...\n");
12144 if (!Doxygen::filterDBFileName.isEmpty())
12145 {
12146 thisDir.remove(Doxygen::filterDBFileName.str());
12147 }
12148 killpg(0,SIGINT);
12150 exitTracing();
12151 exit(1);
12152}

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

6132{
6133 auto dstIt = dst.begin();
6134 for (const Argument &sa : src)
6135 {
6136 QCString dstType = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.type.str());
6137 QCString dstArray = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.array.str());
6138 if (dstIt == dst.end())
6139 {
6140 Argument da = sa;
6141 da.type = dstType;
6142 da.array = dstArray;
6143 dst.push_back(da);
6144 dstIt = dst.end();
6145 }
6146 else
6147 {
6148 Argument da = *dstIt;
6149 da.type = dstType;
6150 da.array = dstArray;
6151 ++dstIt;
6152 }
6153 }
6154 dst.setConstSpecifier(src.constSpecifier());
6155 dst.setVolatileSpecifier(src.volatileSpecifier());
6156 dst.setPureSpecifier(src.pureSpecifier());
6158 srcTempArgLists,dstTempArgLists,
6159 src.trailingReturnType().str()));
6160 dst.setIsDeleted(src.isDeleted());
6161 dst.setRefQualifier(src.refQualifier());
6162 dst.setNoParameters(src.noParameters());
6163 //printf("substituteTemplatesInArgList: replacing %s with %s\n",
6164 // qPrint(argListToString(src)),qPrint(argListToString(dst))
6165 // );
6166}
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:6042
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 6042 of file doxygen.cpp.

6047{
6048 std::string dst;
6049 static const reg::Ex re(R"(\a\w*)");
6050 reg::Iterator it(src,re);
6052 //printf("type=%s\n",qPrint(sa->type));
6053 size_t p=0;
6054 for (; it!=end ; ++it) // for each word in srcType
6055 {
6056 const auto &match = *it;
6057 size_t i = match.position();
6058 size_t l = match.length();
6059 bool found=FALSE;
6060 dst+=src.substr(p,i-p);
6061 std::string name=match.str();
6062
6063 auto srcIt = srcTempArgLists.begin();
6064 auto dstIt = dstTempArgLists.begin();
6065 while (srcIt!=srcTempArgLists.end() && !found)
6066 {
6067 const ArgumentList *tdAli = nullptr;
6068 std::vector<Argument>::const_iterator tdaIt;
6069 if (dstIt!=dstTempArgLists.end())
6070 {
6071 tdAli = &(*dstIt);
6072 tdaIt = tdAli->begin();
6073 ++dstIt;
6074 }
6075
6076 const ArgumentList &tsaLi = *srcIt;
6077 for (auto tsaIt = tsaLi.begin(); tsaIt!=tsaLi.end() && !found; ++tsaIt)
6078 {
6079 Argument tsa = *tsaIt;
6080 const Argument *tda = nullptr;
6081 if (tdAli && tdaIt!=tdAli->end())
6082 {
6083 tda = &(*tdaIt);
6084 ++tdaIt;
6085 }
6086 //if (tda) printf("tsa=%s|%s tda=%s|%s\n",
6087 // qPrint(tsa.type),qPrint(tsa.name),
6088 // qPrint(tda->type),qPrint(tda->name));
6089 if (name==tsa.name.str())
6090 {
6091 if (tda && tda->name.isEmpty())
6092 {
6093 QCString tdaName = tda->name;
6094 QCString tdaType = tda->type;
6095 int vc=0;
6096 if (tdaType.startsWith("class ")) vc=6;
6097 else if (tdaType.startsWith("typename ")) vc=9;
6098 if (vc>0) // convert type=="class T" to type=="class" name=="T"
6099 {
6100 tdaName = tdaType.mid(vc);
6101 }
6102 if (!tdaName.isEmpty())
6103 {
6104 name=tdaName.str(); // substitute
6105 found=TRUE;
6106 }
6107 }
6108 }
6109 }
6110
6111 //printf(" srcList='%s' dstList='%s faList='%s'\n",
6112 // qPrint(argListToString(srclali.current())),
6113 // qPrint(argListToString(dstlali.current())),
6114 // funcTempArgList ? qPrint(argListToString(funcTempArgList)) : "<none>");
6115 ++srcIt;
6116 }
6117 dst+=name;
6118 p=i+l;
6119 }
6120 dst+=src.substr(p);
6121 //printf(" substituteTemplatesInString(%s)=%s\n",
6122 // qPrint(src),qPrint(dst));
6123 return dst;
6124}

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

4368{
4369 AUTO_TRACE();
4370
4371 // find matching function declaration and definitions.
4372 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4373 {
4374 //printf("memberName=%s count=%zu\n",qPrint(mn->memberName()),mn->size());
4375 /* find a matching function declaration and definition for this function */
4376 for (const auto &imdec : *mn)
4377 {
4378 MemberDefMutable *mdec = toMemberDefMutable(imdec.get());
4379 if (mdec &&
4380 (mdec->isPrototype() ||
4381 (mdec->isVariable() && mdec->isExternal())
4382 ))
4383 {
4384 for (const auto &imdef : *mn)
4385 {
4386 MemberDefMutable *mdef = toMemberDefMutable(imdef.get());
4387 if (mdef && mdec!=mdef &&
4388 mdec->getNamespaceDef()==mdef->getNamespaceDef())
4389 {
4391 }
4392 }
4393 }
4394 }
4395 }
4396}
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 4400 of file doxygen.cpp.

4401{
4402 AUTO_TRACE();
4403 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4404 {
4405 MemberDefMutable *mdef=nullptr,*mdec=nullptr;
4406 /* find a matching function declaration and definition for this function */
4407 for (const auto &imd : *mn)
4408 {
4409 MemberDefMutable *md = toMemberDefMutable(imd.get());
4410 if (md)
4411 {
4412 if (md->isPrototype())
4413 mdec=md;
4414 else if (md->isVariable() && md->isExternal())
4415 mdec=md;
4416
4417 if (md->isFunction() && !md->isStatic() && !md->isPrototype())
4418 mdef=md;
4419 else if (md->isVariable() && !md->isExternal() && !md->isStatic())
4420 mdef=md;
4421 }
4422
4423 if (mdef && mdec) break;
4424 }
4425 if (mdef && mdec)
4426 {
4427 const ArgumentList &mdefAl = mdef->argumentList();
4428 const ArgumentList &mdecAl = mdec->argumentList();
4429 if (
4430 matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdef->typeString(),const_cast<ArgumentList*>(&mdefAl),
4431 mdec->getOuterScope(),mdec->getFileDef(),mdec->typeString(),const_cast<ArgumentList*>(&mdecAl),
4432 TRUE,mdef->getLanguage()
4433 )
4434 ) /* match found */
4435 {
4436 AUTO_TRACE_ADD("merging references for mdec={} mdef={}",mdec->name(),mdef->name());
4437 mdef->mergeReferences(mdec);
4438 mdec->mergeReferences(mdef);
4439 mdef->mergeReferencedBy(mdec);
4440 mdec->mergeReferencedBy(mdef);
4441 }
4442 }
4443 }
4444}
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 4448 of file doxygen.cpp.

4449{
4450 AUTO_TRACE();
4451 // find match between function declaration and definition for
4452 // related functions
4453 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4454 {
4455 /* find a matching function declaration and definition for this function */
4456 // for each global function
4457 for (const auto &imd : *mn)
4458 {
4459 MemberDefMutable *md = toMemberDefMutable(imd.get());
4460 if (md)
4461 {
4462 //printf(" Function '%s'\n",qPrint(md->name()));
4463 MemberName *rmn = Doxygen::memberNameLinkedMap->find(md->name());
4464 if (rmn) // check if there is a member with the same name
4465 {
4466 //printf(" Member name found\n");
4467 // for each member with the same name
4468 for (const auto &irmd : *rmn)
4469 {
4470 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
4471 //printf(" Member found: related='%d'\n",rmd->isRelated());
4472 if (rmd &&
4473 (rmd->isRelated() || rmd->isForeign()) && // related function
4474 matchArguments2( md->getOuterScope(), md->getFileDef(), md->typeString(), &md->argumentList(),
4475 rmd->getOuterScope(),rmd->getFileDef(),rmd->typeString(),&rmd->argumentList(),
4476 TRUE,md->getLanguage()
4477 )
4478 )
4479 {
4480 AUTO_TRACE_ADD("Found related member '{}'",md->name());
4481 if (rmd->relatedAlso())
4482 md->setRelatedAlso(rmd->relatedAlso());
4483 else if (rmd->isForeign())
4484 md->makeForeign();
4485 else
4486 md->makeRelated();
4487 }
4488 }
4489 }
4490 }
4491 }
4492 }
4493}
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 4497 of file doxygen.cpp.

4498{
4499 AUTO_TRACE();
4500 for (const auto &[qualifiedName,bodyInfo] : Doxygen::staticInitMap)
4501 {
4502 size_t i=qualifiedName.rfind("::");
4503 if (i!=std::string::npos)
4504 {
4505 QCString scope = qualifiedName.substr(0,i);
4506 QCString name = qualifiedName.substr(i+2);
4507 MemberName *mn = Doxygen::memberNameLinkedMap->find(name);
4508 if (mn)
4509 {
4510 for (const auto &imd : *mn)
4511 {
4512 MemberDefMutable *md = toMemberDefMutable(imd.get());
4513 if (md && md->qualifiedName().str()==qualifiedName && md->isVariable())
4514 {
4515 AUTO_TRACE_ADD("found static member {} body [{}..{}]\n",
4516 md->qualifiedName(),bodyInfo.startLine,bodyInfo.endLine);
4517 md->setBodySegment(bodyInfo.defLine,
4518 bodyInfo.startLine,
4519 bodyInfo.endLine);
4520 }
4521 }
4522 }
4523 }
4524 }
4525}

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

8057{
8058 for (const auto &g : root->groups)
8059 {
8060 const GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
8061 if (gd)
8062 {
8063 MemberList *ml = gd->getMemberList(MemberListType::DecEnumMembers());
8064 if (ml)
8065 {
8066 MemberDefMutable *md = toMemberDefMutable(ml->find(name));
8067 if (md)
8068 {
8069 addEnumDocs(root,md);
8070 return TRUE;
8071 }
8072 }
8073 }
8074 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
8075 {
8076 warn(root->fileName, root->startLine,
8077 "Found non-existing group '{}' for the command '{}', ignoring command",
8078 g.groupname, Grouping::getGroupPriName( g.pri )
8079 );
8080 }
8081 }
8082
8083 return FALSE;
8084}
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 11382 of file doxygen.cpp.

11383{
11385 msg("Doxygen version {0}\nCopyright Dimitri van Heesch 1997-2025\n\n"
11386 "You can use Doxygen in a number of ways:\n\n"
11387 "1) Use Doxygen to generate a template configuration file*:\n"
11388 " {1} [-s] -g [configName]\n\n"
11389 "2) Use Doxygen to update an old configuration file*:\n"
11390 " {1} [-s] -u [configName]\n\n"
11391 "3) Use Doxygen to generate documentation using an existing "
11392 "configuration file*:\n"
11393 " {1} [configName]\n\n"
11394 "4) Use Doxygen to generate a template file controlling the layout of the\n"
11395 " generated documentation:\n"
11396 " {1} -l [layoutFileName]\n\n"
11397 " In case layoutFileName is omitted DoxygenLayout.xml will be used as filename.\n"
11398 " If - is used for layoutFileName Doxygen will write to standard output.\n\n"
11399 "5) Use Doxygen to generate a template style sheet file for RTF, HTML or Latex.\n"
11400 " RTF: {1} -w rtf styleSheetFile\n"
11401 " HTML: {1} -w html headerFile footerFile styleSheetFile [configFile]\n"
11402 " LaTeX: {1} -w latex headerFile footerFile styleSheetFile [configFile]\n\n"
11403 "6) Use Doxygen to generate a rtf extensions file\n"
11404 " {1} -e rtf extensionsFile\n\n"
11405 " If - is used for extensionsFile Doxygen will write to standard output.\n\n"
11406 "7) Use Doxygen to compare the used configuration file with the template configuration file\n"
11407 " {1} -x [configFile]\n\n"
11408 " Use Doxygen to compare the used configuration file with the template configuration file\n"
11409 " without replacing the environment variables or CMake type replacement variables\n"
11410 " {1} -x_noenv [configFile]\n\n"
11411 "8) Use Doxygen to show a list of built-in emojis.\n"
11412 " {1} -f emoji outputFileName\n\n"
11413 " If - is used for outputFileName Doxygen will write to standard output.\n\n"
11414 "*) If -s is specified the comments of the configuration items in the config file will be omitted.\n"
11415 " If configName is omitted 'Doxyfile' will be used as a default.\n"
11416 " If - is used for configFile Doxygen will write / read the configuration to /from standard output / input.\n\n"
11417 "If -q is used for a Doxygen documentation run, Doxygen will see this as if QUIET=YES has been set.\n\n"
11418 "-v print version string, -V print extended version information\n"
11419 "-h,-? prints usage help information\n"
11420 "{1} -d prints additional usage flags for debugging purposes\n",versionString,name);
11421}

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

Referenced by readConfiguration().

◆ version()

void version ( const bool extended)
static

Definition at line 11354 of file doxygen.cpp.

11355{
11357 QCString versionString = getFullVersion();
11358 msg("{}\n",versionString);
11359 if (extended)
11360 {
11361 QCString extVers;
11362 if (!extVers.isEmpty()) extVers+= ", ";
11363 extVers += "sqlite3 ";
11364 extVers += sqlite3_libversion();
11365#if USE_LIBCLANG
11366 if (!extVers.isEmpty()) extVers+= ", ";
11367 extVers += "clang support ";
11368 extVers += CLANG_VERSION_STRING;
11369#endif
11370 if (!extVers.isEmpty())
11371 {
11372 int lastComma = extVers.findRev(',');
11373 if (lastComma != -1) extVers = extVers.replace(lastComma,1," and");
11374 msg(" with {}.\n",extVers);
11375 }
11376 }
11377}
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 8419 of file doxygen.cpp.

8420{
8421 // for each member name
8422 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8423 {
8424 // for each member definition
8425 for (const auto &imd : *mn)
8426 {
8427 MemberDefMutable *md = toMemberDefMutable(imd.get());
8428 if (md)
8429 {
8431 }
8432 }
8433 }
8434 // for each member name
8435 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8436 {
8437 // for each member definition
8438 for (const auto &imd : *mn)
8439 {
8440 MemberDefMutable *md = toMemberDefMutable(imd.get());
8441 if (md)
8442 {
8444 }
8445 }
8446 }
8447}
static void correctMemberProperties(MemberDefMutable *md)

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

Referenced by parseInput().

◆ warnUndocumentedNamespaces()

void warnUndocumentedNamespaces ( )
static

Definition at line 5376 of file doxygen.cpp.

5377{
5378 AUTO_TRACE();
5379 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5380 {
5381 if (!nd->hasDocumentation())
5382 {
5383 if ((guessSection(nd->getDefFileName()).isHeader() ||
5384 nd->getLanguage() == SrcLangExt::Fortran) && // Fortran doesn't have header files.
5385 !Config_getBool(HIDE_UNDOC_NAMESPACES) // undocumented namespaces are visible
5386 )
5387 {
5388 warn_undoc(nd->getDefFileName(),nd->getDefLine(), "{} {} is not documented.",
5389 nd->getLanguage() == SrcLangExt::Fortran ? "Module" : "Namespace",
5390 nd->name());
5391 }
5392 }
5393 }
5394}

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

Referenced by parseInput().

◆ writeTagFile()

void writeTagFile ( )
static

Definition at line 12155 of file doxygen.cpp.

12156{
12157 QCString generateTagFile = Config_getString(GENERATE_TAGFILE);
12158 if (generateTagFile.isEmpty()) return;
12159
12160 std::ofstream f = Portable::openOutputStream(generateTagFile);
12161 if (!f.is_open())
12162 {
12163 err("cannot open tag file {} for writing\n", generateTagFile);
12164 return;
12165 }
12166 TextStream tagFile(&f);
12167 tagFile << "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>\n";
12168 tagFile << "<tagfile doxygen_version=\"" << getDoxygenVersion() << "\"";
12169 std::string gitVersion = getGitVersion();
12170 if (!gitVersion.empty())
12171 {
12172 tagFile << " doxygen_gitid=\"" << gitVersion << "\"";
12173 }
12174 tagFile << ">\n";
12175
12176 // for each file
12177 for (const auto &fn : *Doxygen::inputNameLinkedMap)
12178 {
12179 for (const auto &fd : *fn)
12180 {
12181 if (fd->isLinkableInProject()) fd->writeTagFile(tagFile);
12182 }
12183 }
12184 // for each class
12185 for (const auto &cd : *Doxygen::classLinkedMap)
12186 {
12187 ClassDefMutable *cdm = toClassDefMutable(cd.get());
12188 if (cdm && cdm->isLinkableInProject())
12189 {
12190 cdm->writeTagFile(tagFile);
12191 }
12192 }
12193 // for each concept
12194 for (const auto &cd : *Doxygen::conceptLinkedMap)
12195 {
12196 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
12197 if (cdm && cdm->isLinkableInProject())
12198 {
12199 cdm->writeTagFile(tagFile);
12200 }
12201 }
12202 // for each namespace
12203 for (const auto &nd : *Doxygen::namespaceLinkedMap)
12204 {
12206 if (ndm && nd->isLinkableInProject())
12207 {
12208 ndm->writeTagFile(tagFile);
12209 }
12210 }
12211 // for each group
12212 for (const auto &gd : *Doxygen::groupLinkedMap)
12213 {
12214 if (gd->isLinkableInProject()) gd->writeTagFile(tagFile);
12215 }
12216 // for each module
12217 for (const auto &mod : ModuleManager::instance().modules())
12218 {
12219 if (mod->isLinkableInProject()) mod->writeTagFile(tagFile);
12220 }
12221 // for each page
12222 for (const auto &pd : *Doxygen::pageLinkedMap)
12223 {
12224 if (pd->isLinkableInProject()) pd->writeTagFile(tagFile);
12225 }
12226 // for requirements
12228 // for each directory
12229 for (const auto &dd : *Doxygen::dirLinkedMap)
12230 {
12231 if (dd->isLinkableInProject()) dd->writeTagFile(tagFile);
12232 }
12233 if (Doxygen::mainPage) Doxygen::mainPage->writeTagFile(tagFile);
12234
12235 tagFile << "</tagfile>\n";
12236}
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().