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

Go to the source code of this file.

Classes

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

Macros

#define HAS_SIGNALS

Enumerations

enum  FindBaseClassRelation_Mode { TemplateInstances , DocumentedOnly , Undocumented }

Functions

void initResources ()
void clearAll ()
static void addMemberDocs (const Entry *root, MemberDefMutable *md, const QCString &funcDecl, const ArgumentList *al, bool over_load, TypeSpecifier spec)
static void findMember (const Entry *root, const QCString &relates, const QCString &type, const QCString &args, QCString funcDecl, bool overloaded, bool isFunc)
static bool findClassRelation (const Entry *root, Definition *context, ClassDefMutable *cd, const BaseInfo *bi, const TemplateNameMap &templateNames, FindBaseClassRelation_Mode mode, bool isArtificial)
static DefinitionfindScopeFromQualifiedName (NamespaceDefMutable *startScope, const QCString &n, FileDef *fileScope, const TagInfo *tagInfo)
static void resolveTemplateInstanceInType (const Entry *root, const Definition *scope, const MemberDef *md)
static void addPageToContext (PageDef *pd, Entry *root)
static void addRelatedPage (Entry *root)
static void buildGroupListFiltered (const Entry *root, bool additional, bool includeExternal)
static void buildGroupList (const Entry *root)
static void findGroupScope (const Entry *root)
static void organizeSubGroupsFiltered (const Entry *root, bool additional)
static void organizeSubGroups (const Entry *root)
static void buildFileList (const Entry *root)
template<class DefMutable>
static void addIncludeFile (DefMutable *cd, FileDef *ifd, const Entry *root)
QCString stripTemplateSpecifiers (const QCString &s)
static DefinitionbuildScopeFromQualifiedName (const QCString &name_, SrcLangExt lang, const TagInfo *tagInfo)
std::unique_ptr< ArgumentListgetTemplateArgumentsFromName (const QCString &name, const ArgumentLists &tArgLists)
static ClassDef::CompoundType convertToCompoundType (EntryType section, TypeSpecifier specifier)
static void addClassToContext (const Entry *root)
static void buildClassList (const Entry *root)
static void buildClassDocList (const Entry *root)
static void addConceptToContext (const Entry *root)
static void findModuleDocumentation (const Entry *root)
static void buildConceptList (const Entry *root)
static void buildConceptDocList (const Entry *root)
static void distributeConceptGroups ()
static void resolveClassNestingRelations ()
void distributeClassGroupRelations ()
static ClassDefMutablecreateTagLessInstance (const ClassDef *rootCd, const ClassDef *templ, const QCString &fieldName)
static void processTagLessClasses (const ClassDef *rootCd, const ClassDef *cd, ClassDefMutable *tagParentCd, const QCString &prefix, int count)
 Look through the members of class cd and its public members.
static void findTagLessClasses (std::vector< ClassDefMutable * > &candidates, ClassDef *cd)
static void findTagLessClasses ()
static void buildNamespaceList (const Entry *root)
static NamespaceDeffindUsedNamespace (const LinkedRefMap< NamespaceDef > &unl, const QCString &name)
static void findUsingDirectives (const Entry *root)
static void buildListOfUsingDecls (const Entry *root)
static void findUsingDeclarations (const Entry *root, bool filterPythonPackages)
static void applyMemberOverrideOptions (const Entry *root, MemberDefMutable *md)
static void createUsingMemberImportForClass (const Entry *root, ClassDefMutable *cd, const MemberDef *md, const QCString &fileName, const QCString &memName)
static void findUsingDeclImports (const Entry *root)
static void findIncludedUsingDirectives ()
static MemberDefaddVariableToClass (const Entry *root, ClassDefMutable *cd, MemberType mtype, const QCString &type, const QCString &name, const QCString &args, bool fromAnnScope, MemberDef *fromAnnMemb, Protection prot, Relationship related)
static MemberDefaddVariableToFile (const Entry *root, MemberType mtype, const QCString &scope, const QCString &type, const QCString &name, const QCString &args, bool fromAnnScope, MemberDef *fromAnnMemb)
static int findFunctionPtr (const std::string &type, SrcLangExt lang, int *pLength=nullptr)
static bool isVarWithConstructor (const Entry *root)
static int findEndOfTemplate (const QCString &s, size_t startPos)
static void addVariable (const Entry *root, int isFuncPtr=-1)
static void buildTypedefList (const Entry *root)
static void buildSequenceList (const Entry *root)
static void buildDictionaryList (const Entry *root)
static void buildVarList (const Entry *root)
static void addInterfaceOrServiceToServiceOrSingleton (const Entry *root, ClassDefMutable *cd, QCString const &rname)
static void buildInterfaceAndServiceList (const Entry *root)
static void addMethodToClass (const Entry *root, ClassDefMutable *cd, const QCString &rtype, const QCString &rname, const QCString &rargs, bool isFriend, Protection protection, bool stat, Specifier virt, TypeSpecifier spec, const QCString &relates)
static void addGlobalFunction (const Entry *root, const QCString &rname, const QCString &sc)
static void buildFunctionList (const Entry *root)
static void findFriends ()
static void transferFunctionDocumentation ()
static void transferFunctionReferences ()
static void transferRelatedFunctionDocumentation ()
void transferStaticInstanceInitializers ()
static TemplateNameMap getTemplateArgumentsInName (const ArgumentList &templateArguments, const std::string &name)
static ClassDeffindClassWithinClassContext (Definition *context, ClassDef *cd, const QCString &name)
static void findUsedClassesForClass (const Entry *root, Definition *context, ClassDefMutable *masterCd, ClassDefMutable *instanceCd, bool isArtificial, const ArgumentList *actualArgs=nullptr, const TemplateNameMap &templateNames=TemplateNameMap())
static void findBaseClassesForClass (const Entry *root, Definition *context, ClassDefMutable *masterCd, ClassDefMutable *instanceCd, FindBaseClassRelation_Mode mode, bool isArtificial, const ArgumentList *actualArgs=nullptr, const TemplateNameMap &templateNames=TemplateNameMap())
static void findTemplateInstanceRelation (const Entry *root, Definition *context, ClassDefMutable *templateClass, const QCString &templSpec, const TemplateNameMap &templateNames, bool isArtificial)
static bool isRecursiveBaseClass (const QCString &scope, const QCString &name)
static int findTemplateSpecializationPosition (const QCString &name)
static bool isClassSection (const Entry *root)
static void findClassEntries (const Entry *root)
static QCString extractClassName (const Entry *root)
static void findInheritedTemplateInstances ()
static void makeTemplateInstanceRelation (const Entry *root, ClassDefMutable *cd)
static void findUsedTemplateInstances ()
static void warnUndocumentedNamespaces ()
static void computeClassRelations ()
static void computeTemplateClassRelations ()
static void computeMemberReferences ()
static void addListReferences ()
static void generateXRefPages ()
static const ClassDeffindClassDefinition (FileDef *fd, NamespaceDef *nd, const QCString &scopeName)
static bool isEntryInGroupOfMember (const Entry *root, const MemberDef *md, bool allowNoGroup=false)
static bool findGlobalMember (const Entry *root, const QCString &namespaceName, const QCString &type, const QCString &name, const QCString &tempArg, const QCString &, const QCString &decl, TypeSpecifier)
static bool isSpecialization (const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists)
static bool scopeIsTemplate (const Definition *d)
static QCString substituteTemplatesInString (const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const std::string &src)
static void substituteTemplatesInArgList (const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const ArgumentList &src, ArgumentList &dst)
static void addLocalObjCMethod (const Entry *root, const QCString &scopeName, const QCString &funcType, const QCString &funcName, const QCString &funcArgs, const QCString &exceptions, const QCString &funcDecl, TypeSpecifier spec)
static void addMemberFunction (const Entry *root, MemberName *mn, const QCString &scopeName, const QCString &namespaceName, const QCString &className, const QCString &funcTyp, const QCString &funcName, const QCString &funcArgs, const QCString &funcTempList, const QCString &exceptions, const QCString &type, const QCString &args, bool isFriend, TypeSpecifier spec, const QCString &relates, const QCString &funcDecl, bool overloaded, bool isFunc)
static void addMemberSpecialization (const Entry *root, MemberName *mn, ClassDefMutable *cd, const QCString &funcType, const QCString &funcName, const QCString &funcArgs, const QCString &funcDecl, const QCString &exceptions, TypeSpecifier spec)
static void addOverloaded (const Entry *root, MemberName *mn, const QCString &funcType, const QCString &funcName, const QCString &funcArgs, const QCString &funcDecl, const QCString &exceptions, TypeSpecifier spec)
static void insertMemberAlias (Definition *outerScope, const MemberDef *md)
static void filterMemberDocumentation (const Entry *root, const QCString &relates)
static void findMemberDocumentation (const Entry *root)
static void findObjCMethodDefinitions (const Entry *root)
static void findEnums (const Entry *root)
static void addEnumValuesToEnums (const Entry *root)
static void addEnumDocs (const Entry *root, MemberDefMutable *md)
static bool tryAddEnumDocsToGroupMember (const Entry *root, const QCString &name)
static void findEnumDocumentation (const Entry *root)
static void findDEV (const MemberNameLinkedMap &mnsd)
static void findDocumentedEnumValues ()
static void addMembersToIndex ()
static void addToIndices ()
static void vhdlCorrectMemberProperties ()
static void computeMemberRelationsForBaseClass (const ClassDef *cd, const BaseClassDef *bcd)
static void computeMemberRelations ()
static void createTemplateInstanceMembers ()
static void mergeCategories ()
static void buildCompleteMemberLists ()
static void generateFileSources ()
static void generateFileDocs ()
static void addSourceReferences ()
static void buildDefineList ()
static void sortMemberLists ()
static bool isSymbolHidden (const Definition *d)
static void computeTooltipTexts ()
static void setAnonymousEnumType ()
static void countMembers ()
static void generateDocsForClassList (const std::vector< ClassDefMutable * > &classList)
static void addClassAndNestedClasses (std::vector< ClassDefMutable * > &list, ClassDefMutable *cd)
static void generateClassDocs ()
static void generateConceptDocs ()
static void inheritDocumentation ()
static void combineUsingRelations ()
static void addMembersToMemberGroup ()
static void distributeMemberGroupDocumentation ()
static void findSectionsInDocumentation ()
static void flushCachedTemplateRelations ()
static void flushUnresolvedRelations ()
static bool haveEqualFileNames (const Entry *root, const MemberDef *md)
static void addDefineDoc (const Entry *root, MemberDefMutable *md)
static void findDefineDocumentation (Entry *root)
static void findDirDocumentation (const Entry *root)
static void buildPageList (Entry *root)
static void findMainPage (Entry *root)
static void findMainPageTagFiles (Entry *root)
static void computePageRelations (Entry *root)
static void checkPageRelations ()
static void resolveUserReferences ()
static void generatePageDocs ()
static void buildExampleList (Entry *root)
void printNavTree (Entry *root, int indent)
void printSectionsTree ()
static void generateExampleDocs ()
static void generateGroupDocs ()
static void generateNamespaceClassDocs (const ClassLinkedRefMap &classList)
static void generateNamespaceConceptDocs (const ConceptLinkedRefMap &conceptList)
static void generateNamespaceDocs ()
static void runHtmlHelpCompiler ()
static void runQHelpGenerator ()
static void computeVerifiedDotPath ()
static void generateConfigFile (const QCString &configFile, bool shortList, bool updateOnly=FALSE)
static void compareDoxyfile (Config::CompareMode diffList)
static void readTagFile (const std::shared_ptr< Entry > &root, const QCString &tagLine)
static void copyLatexStyleSheet ()
static void copyStyleSheet ()
static void copyLogo (const QCString &outputOption)
static void copyIcon (const QCString &outputOption)
static void copyExtraFiles (const StringVector &files, const QCString &filesOption, const QCString &outputOption)
static void generateDiskNames ()
static std::unique_ptr< OutlineParserInterfacegetParserForFile (const QCString &fn)
static std::shared_ptr< EntryparseFile (OutlineParserInterface &parser, FileDef *fd, const QCString &fn, ClangTUParser *clangParser, bool newTU)
static void parseFilesMultiThreading (const std::shared_ptr< Entry > &root)
 parse the list of input files
static void parseFilesSingleThreading (const std::shared_ptr< Entry > &root)
 parse the list of input files
static std::string resolveSymlink (const std::string &path)
static StringUnorderedSet g_pathsVisited (1009)
static void readDir (FileInfo *fi, FileNameLinkedMap *fnMap, StringUnorderedSet *exclSet, const StringVector *patList, const StringVector *exclPatList, StringVector *resultList, StringUnorderedSet *resultSet, bool errorIfNotExist, bool recursive, StringUnorderedSet *killSet, StringUnorderedSet *paths)
void readFileOrDirectory (const QCString &s, FileNameLinkedMap *fnMap, StringUnorderedSet *exclSet, const StringVector *patList, const StringVector *exclPatList, StringVector *resultList, StringUnorderedSet *resultSet, bool recursive, bool errorIfNotExist, StringUnorderedSet *killSet, StringUnorderedSet *paths)
static void dumpSymbol (TextStream &t, Definition *d)
static void dumpSymbolMap ()
static void devUsage ()
static void version (const bool extended)
static void usage (const QCString &name, const QCString &versionString)
static const char * getArg (int argc, char **argv, int &optInd)
template<class T>
std::function< std::unique_ptr< T >() > make_parser_factory ()
void initDoxygen ()
void cleanUpDoxygen ()
static int computeIdealCacheParam (size_t v)
void readConfiguration (int argc, char **argv)
void checkConfiguration ()
 check and resolve config options
void adjustConfiguration ()
 adjust globals that depend on configuration settings.
static void stopDoxygen (int)
static void writeTagFile ()
static void exitDoxygen () noexcept
static QCString createOutputDirectory (const QCString &baseDirName, const QCString &formatDirName, const char *defaultDirName)
void searchInputFiles ()
static void checkMarkdownMainfile ()
void parseInput ()
void generateOutput ()

Variables

static std::multimap< std::string, const Entry * > g_classEntries
static StringVector g_inputFiles
static OutputListg_outputList = nullptr
static StringSet g_usingDeclarations
static bool g_successfulRun = FALSE
static bool g_dumpSymbolMap = FALSE
static QCString g_commentFileName
static bool g_singleComment =false
static const StringUnorderedSet g_compoundKeywords
class Statistics g_s
static std::unordered_map< std::string, std::vector< ClassDefMutable * > > g_usingClassMap

Macro Definition Documentation

◆ HAS_SIGNALS

#define HAS_SIGNALS

Definition at line 132 of file doxygen.cpp.

Enumeration Type Documentation

◆ FindBaseClassRelation_Mode

Enumerator
TemplateInstances 
DocumentedOnly 
Undocumented 

Definition at line 284 of file doxygen.cpp.

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

Function Documentation

◆ addClassAndNestedClasses()

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

Definition at line 9070 of file doxygen.cpp.

9071{
9072 list.push_back(cd);
9073 for (const auto &innerCdi : cd->getClasses())
9074 {
9075 ClassDefMutable *innerCd = toClassDefMutable(innerCdi);
9076 if (innerCd)
9077 {
9078 AUTO_TRACE("innerCd={} isLinkable={} isImplicitTemplateInstance={} protectLevelVisible={} embeddedInOuterScope={}",
9079 innerCd->name(),innerCd->isLinkableInProject(),innerCd->isImplicitTemplateInstance(),protectionLevelVisible(innerCd->protection()),
9080 innerCd->isEmbeddedInOuterScope());
9081 }
9082 if (innerCd && innerCd->isLinkableInProject() && !innerCd->isImplicitTemplateInstance() &&
9083 protectionLevelVisible(innerCd->protection()) &&
9084 !innerCd->isEmbeddedInOuterScope()
9085 )
9086 {
9087 list.push_back(innerCd);
9088 addClassAndNestedClasses(list,innerCd);
9089 }
9090 }
9091}
virtual Protection protection() const =0
Return the protection level (Public,Protected,Private) in which this compound was found.
virtual bool isEmbeddedInOuterScope() const =0
virtual bool isImplicitTemplateInstance() const =0
virtual ClassLinkedRefMap getClasses() const =0
returns the classes nested into this class
virtual bool isLinkableInProject() const =0
virtual const QCString & name() const =0
ClassDefMutable * toClassDefMutable(Definition *d)
#define AUTO_TRACE(...)
Definition docnode.cpp:46
static void addClassAndNestedClasses(std::vector< ClassDefMutable * > &list, ClassDefMutable *cd)
Definition doxygen.cpp:9070
bool protectionLevelVisible(Protection prot)
Definition util.cpp:6450

References addClassAndNestedClasses(), AUTO_TRACE, ClassDef::getClasses(), ClassDef::isEmbeddedInOuterScope(), ClassDef::isImplicitTemplateInstance(), Definition::isLinkableInProject(), Definition::name(), ClassDef::protection(), protectionLevelVisible(), and toClassDefMutable().

Referenced by addClassAndNestedClasses(), and generateClassDocs().

◆ addClassToContext()

void addClassToContext ( const Entry * root)
static

Definition at line 931 of file doxygen.cpp.

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

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

Referenced by buildClassDocList(), and buildClassList().

◆ addConceptToContext()

void addConceptToContext ( const Entry * root)
static

Definition at line 1151 of file doxygen.cpp.

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

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

Referenced by buildConceptDocList(), and buildConceptList().

◆ addDefineDoc()

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

Definition at line 9461 of file doxygen.cpp.

9462{
9463 md->setDocumentation(root->doc,root->docFile,root->docLine);
9464 md->setDocsForDefinition(!root->proto);
9465 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9466 if (md->inbodyDocumentation().isEmpty())
9467 {
9469 }
9470 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
9471 {
9472 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
9473 md->setBodyDef(root->fileDef());
9474 }
9476 md->setMaxInitLines(root->initLines);
9478 md->setRefItems(root->sli);
9479 if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
9480 addMemberToGroups(root,md);
9482}
virtual int getStartBodyLine() const =0
virtual QCString inbodyDocumentation() const =0
virtual void setInbodyDocumentation(const QCString &d, const QCString &docFile, int docLine)=0
bool proto
prototype ?
Definition entry.h:187
QCString inbodyDocs
documentation inside the body of a function
Definition entry.h:206
int inbodyLine
line number at which the body doc was found
Definition entry.h:207
int initLines
define/variable initializer lines to show
Definition entry.h:184
QCString inbodyFile
file in which the body doc was found
Definition entry.h:208
virtual void setMemberGroupId(int id)=0
virtual void setMaxInitLines(int lines)=0
virtual void setDocsForDefinition(bool b)=0
void addMemberToModule(const Entry *root, MemberDef *md)
static void applyMemberOverrideOptions(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:2097
void addMemberToGroups(const Entry *root, MemberDef *md)

References addMemberToGroups(), ModuleManager::addMemberToModule(), 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, DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setMaxInitLines(), MemberDefMutable::setMemberGroupId(), DefinitionMutable::setRefItems(), Entry::sli, and Entry::startLine.

Referenced by findDefineDocumentation().

◆ addEnumDocs()

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

Definition at line 7898 of file doxygen.cpp.

7899{
7900 AUTO_TRACE();
7901 // documentation outside a compound overrides the documentation inside it
7902 {
7903 md->setDocumentation(root->doc,root->docFile,root->docLine);
7904 md->setDocsForDefinition(!root->proto);
7905 }
7906
7907 // brief descriptions inside a compound override the documentation
7908 // outside it
7909 {
7910 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7911 }
7912
7913 if (md->inbodyDocumentation().isEmpty() || !root->parent()->name.isEmpty())
7914 {
7916 }
7917
7918 if (root->mGrpId!=-1 && md->getMemberGroupId()==-1)
7919 {
7920 md->setMemberGroupId(root->mGrpId);
7921 }
7922
7924 md->setRefItems(root->sli);
7925
7926 const GroupDef *gd=md->getGroupDef();
7927 if (gd==nullptr && !root->groups.empty()) // member not grouped but out-of-line documentation is
7928 {
7929 addMemberToGroups(root,md);
7930 }
7932}
std::vector< Grouping > groups
list of groups this entry belongs to
Definition entry.h:221
A model of a group of symbols.
Definition groupdef.h:52
virtual GroupDef * getGroupDef()=0
virtual int getMemberGroupId() const =0

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

Referenced by findEnumDocumentation(), and tryAddEnumDocsToGroupMember().

◆ addEnumValuesToEnums()

void addEnumValuesToEnums ( const Entry * root)
static

Definition at line 7648 of file doxygen.cpp.

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

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

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

References addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, Entry::args, QCString::at(), AUTO_TRACE, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Entry::exception, Entry::explicitExternal, Entry::fileDef(), Entry::fileName, Function, Doxygen::functionNameLinkedMap, getLanguageSpecificSeparator(), getResolvedNamespaceMutable(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, FileDef::insertMember(), NamespaceDefMutable::insertMember(), ModuleManager::instance(), QCString::isEmpty(), Entry::isStatic, Entry::lang, Entry::markAsProcessed(), Entry::metaData, Entry::mGrpId, Definition::name(), Entry::name, Entry::parent(), Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, Entry::relatesType, removeRedundantWhiteSpace(), Entry::req, Entry::section, DefinitionMutable::setBodyDef(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, substitute(), Entry::tagInfo(), Entry::tArgLists, toMemberDefMutable(), Entry::type, Entry::typeConstr, Entry::vhdlSpec, and Entry::virt.

Referenced by buildFunctionList().

◆ addIncludeFile()

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

Definition at line 581 of file doxygen.cpp.

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

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

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

References addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, AUTO_TRACE, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, DocumentedOnly, Entry::endBodyLine, Entry::fileDef(), Entry::fileName, findClassRelation(), Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), Interface, QCString::isEmpty(), Entry::isStatic, Entry::lang, Entry::markAsProcessed(), Doxygen::memberNameLinkedMap, Entry::metaData, Entry::mGrpId, Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, Entry::section, Service, Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, Entry::tagInfo(), TagInfo::tagName, toMemberDefMutable(), Entry::type, Entry::typeConstr, Undocumented, Entry::vhdlSpec, and Entry::virt.

Referenced by buildInterfaceAndServiceList().

◆ addListReferences()

void addListReferences ( )
static

Definition at line 5442 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ addLocalObjCMethod()

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

Definition at line 6076 of file doxygen.cpp.

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

References Entry::anchors, applyMemberOverrideOptions(), Entry::argList, AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Entry::fileDef(), Entry::fileName, Function, getClassMutable(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), Entry::isStatic, Entry::lang, Doxygen::memberNameLinkedMap, Entry::metaData, Entry::mGrpId, Entry::name, Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, DefinitionMutable::setBodyDef(), Entry::sli, Entry::startColumn, Entry::startLine, Entry::tagInfo(), toMemberDefMutable(), Entry::vhdlSpec, and Entry::virt.

Referenced by addMemberFunction(), and findMember().

◆ addMemberDocs()

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

Definition at line 5525 of file doxygen.cpp.

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

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

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

◆ addMemberFunction()

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

Definition at line 6129 of file doxygen.cpp.

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

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

Referenced by findMember().

◆ addMemberSpecialization()

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

Definition at line 6473 of file doxygen.cpp.

6483{
6484 AUTO_TRACE("funcType={} funcName={} funcArgs={} funcDecl={} spec={}",funcType,funcName,funcArgs,funcDecl,spec);
6485 MemberDef *declMd=nullptr;
6486 for (const auto &md : *mn)
6487 {
6488 if (md->getClassDef()==cd)
6489 {
6490 // TODO: we should probably also check for matching arguments
6491 declMd = md.get();
6492 break;
6493 }
6494 }
6496 ArgumentList tArgList;
6497 // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6498 auto md = createMemberDef(
6499 root->fileName,root->startLine,root->startColumn,
6500 funcType,funcName,funcArgs,exceptions,
6501 declMd ? declMd->protection() : root->protection,
6502 root->virt,root->isStatic,Relationship::Member,
6503 mtype,tArgList,root->argList,root->metaData);
6504 auto mmd = toMemberDefMutable(md.get());
6505 //printf("new specialized member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6506 mmd->setTagInfo(root->tagInfo());
6507 mmd->setLanguage(root->lang);
6508 mmd->setId(root->id);
6509 mmd->setMemberClass(cd);
6510 mmd->setTemplateSpecialization(TRUE);
6511 mmd->setTypeConstraints(root->typeConstr);
6512 mmd->setDefinition(funcDecl);
6514 mmd->addQualifiers(root->qualifiers);
6515 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6516 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6517 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6518 mmd->setDocsForDefinition(!root->proto);
6519 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6520 mmd->addSectionsToDefinition(root->anchors);
6521 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6522 FileDef *fd=root->fileDef();
6523 mmd->setBodyDef(fd);
6524 mmd->setMemberSpecifiers(spec);
6525 mmd->setVhdlSpecifiers(root->vhdlSpec);
6526 mmd->setMemberGroupId(root->mGrpId);
6527 cd->insertMember(md.get());
6528 mmd->setRefItems(root->sli);
6529
6530 mn->push_back(std::move(md));
6531}

References Entry::anchors, applyMemberOverrideOptions(), Entry::argList, AUTO_TRACE, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Entry::fileDef(), Entry::fileName, Function, Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), Entry::isStatic, Entry::lang, Entry::metaData, Entry::mGrpId, Entry::protection, MemberDef::protection(), Entry::proto, MemberName::push_back(), Entry::qualifiers, DefinitionMutable::setBodyDef(), Entry::sli, Entry::startColumn, Entry::startLine, Entry::tagInfo(), toMemberDefMutable(), TRUE, Entry::typeConstr, Entry::vhdlSpec, and Entry::virt.

Referenced by findMember().

◆ addMembersToIndex()

void addMembersToIndex ( )
static

Definition at line 8092 of file doxygen.cpp.

8093{
8094 auto &index = Index::instance();
8095 // for each class member name
8096 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8097 {
8098 // for each member definition
8099 for (const auto &md : *mn)
8100 {
8101 index.addClassMemberNameToIndex(md.get());
8102 if (md->getModuleDef())
8103 {
8104 index.addModuleMemberNameToIndex(md.get());
8105 }
8106 }
8107 }
8108 // for each file/namespace function name
8109 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8110 {
8111 // for each member definition
8112 for (const auto &md : *mn)
8113 {
8114 if (md->getNamespaceDef())
8115 {
8116 index.addNamespaceMemberNameToIndex(md.get());
8117 }
8118 else
8119 {
8120 index.addFileMemberNameToIndex(md.get());
8121 }
8122 if (md->getModuleDef())
8123 {
8124 index.addModuleMemberNameToIndex(md.get());
8125 }
8126 }
8127 }
8128
8129 index.sortMemberIndexLists();
8130}
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 9200 of file doxygen.cpp.

9201{
9202 // for each class
9203 for (const auto &cd : *Doxygen::classLinkedMap)
9204 {
9205 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9206 if (cdm)
9207 {
9209 }
9210 }
9211 // for each file
9212 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9213 {
9214 for (const auto &fd : *fn)
9215 {
9216 fd->addMembersToMemberGroup();
9217 }
9218 }
9219 // for each namespace
9220 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9221 {
9223 if (ndm)
9224 {
9226 }
9227 }
9228 // for each group
9229 for (const auto &gd : *Doxygen::groupLinkedMap)
9230 {
9231 gd->addMembersToMemberGroup();
9232 }
9234}
virtual void addMembersToMemberGroup()=0
void addMembersToMemberGroup()
virtual void addMembersToMemberGroup()=0

References ClassDefMutable::addMembersToMemberGroup(), ModuleManager::addMembersToMemberGroup(), NamespaceDefMutable::addMembersToMemberGroup(), Doxygen::classLinkedMap, Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), Doxygen::namespaceLinkedMap, toClassDefMutable(), and toNamespaceDefMutable().

Referenced by parseInput().

◆ addMethodToClass()

void addMethodToClass ( const Entry * root,
ClassDefMutable * cd,
const QCString & rtype,
const QCString & rname,
const QCString & rargs,
bool isFriend,
Protection protection,
bool stat,
Specifier virt,
TypeSpecifier spec,
const QCString & relates )
static

Definition at line 3636 of file doxygen.cpp.

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

References addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, QCString::at(), AUTO_TRACE, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, createMemberDef(), DCOP, Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Entry::exception, Entry::fileDef(), Entry::fileName, QCString::find(), Friend, Function, Definition::getLanguage(), getLanguageSpecificSeparator(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), QCString::isEmpty(), Entry::lang, QCString::left(), Entry::markAsProcessed(), Doxygen::memberNameLinkedMap, Entry::metaData, Entry::mGrpId, Entry::mtype, Entry::proto, MemberName::push_back(), ClassDef::qualifiedNameWithTemplateParameters(), Entry::qualifiers, Entry::relatesType, removeRedundantWhiteSpace(), Entry::req, Signal, Entry::sli, Slot, Entry::startColumn, Entry::startLine, QCString::startsWith(), QCString::stripPrefix(), substitute(), Entry::tagInfo(), TagInfo::tagName, Entry::tArgLists, toMemberDefMutable(), Entry::typeConstr, and Entry::vhdlSpec.

Referenced by addMemberFunction(), and buildFunctionList().

◆ addOverloaded()

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

Definition at line 6535 of file doxygen.cpp.

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

References Entry::anchors, applyMemberOverrideOptions(), Entry::argList, MemberName::begin(), Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, createMemberDef(), DCOP, Entry::doc, Entry::docFile, Entry::docLine, MemberName::end(), Entry::endBodyLine, Entry::fileDef(), Entry::fileName, MemberName::front(), Function, MemberDefMutable::getClassDefMutable(), getOverloadDocs(), getTemplateArgumentsFromName(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), Entry::isStatic, Entry::lang, Entry::metaData, Entry::mGrpId, Entry::mtype, Definition::name(), Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, DefinitionMutable::setBodyDef(), Signal, MemberName::size(), Entry::sli, Slot, Entry::startColumn, Entry::startLine, Entry::tagInfo(), Entry::tArgLists, toMemberDefMutable(), Entry::typeConstr, Entry::vhdlSpec, and Entry::virt.

Referenced by findMember().

◆ addPageToContext()

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

Definition at line 309 of file doxygen.cpp.

310{
311 if (root->parent()) // add the page to it's scope
312 {
313 QCString scope = root->parent()->name;
314 if (root->parent()->section.isPackageDoc())
315 {
316 scope=substitute(scope,".","::");
317 }
318 scope = stripAnonymousNamespaceScope(scope);
319 scope+="::"+pd->name();
321 if (d)
322 {
323 pd->setPageScope(d);
324 }
325 }
326}
virtual void setPageScope(Definition *)=0

References findScopeFromQualifiedName(), Doxygen::globalScope, Definition::name(), Entry::name, Entry::parent(), Entry::section, PageDef::setPageScope(), stripAnonymousNamespaceScope(), substitute(), and Entry::tagInfo().

Referenced by addRelatedPage(), and findMainPage().

◆ addRelatedPage()

void addRelatedPage ( Entry * root)
static

Definition at line 328 of file doxygen.cpp.

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

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

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

◆ addSourceReferences()

void addSourceReferences ( )
static

Definition at line 8727 of file doxygen.cpp.

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

References Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Doxygen::functionNameLinkedMap, FileDef::generateSourceFile(), Definition::getBodyDef(), Definition::getStartDefLine(), Definition::isLinkableInProject(), Doxygen::memberNameLinkedMap, Doxygen::namespaceLinkedMap, and Doxygen::parseSourcesNeeded.

Referenced by parseInput().

◆ addToIndices()

void addToIndices ( )
static

Definition at line 8134 of file doxygen.cpp.

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

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

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

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

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

◆ addVariableToClass()

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

Definition at line 2425 of file doxygen.cpp.

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

References addMemberDocs(), addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::artificial, AUTO_TRACE, AUTO_TRACE_ADD, Entry::bitfields, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Entry::exception, FALSE, Entry::fileDef(), Entry::fileName, Friend, MemberDef::getClassDef(), Definition::getLanguage(), Entry::hidden, Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, Entry::initializer, Entry::initLines, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), QCString::isEmpty(), Entry::isStatic, Entry::lang, Entry::markAsProcessed(), Doxygen::memberNameLinkedMap, MemberDef::memberType(), Entry::metaData, Entry::mGrpId, Entry::mtype, Definition::name(), Property, Entry::protection, MemberName::push_back(), ClassDef::qualifiedNameWithTemplateParameters(), Entry::qualifiers, Entry::read, ClassDefMutable::reclassifyMember(), removeRedundantWhiteSpace(), resolveTemplateInstanceInType(), MemberDefMutable::setProtection(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, TextStream::str(), QCString::stripPrefix(), substitute(), Entry::tagInfo(), TagInfo::tagName, Entry::tArgLists, toMemberDefMutable(), Typedef, MemberDef::typeString(), Variable, Entry::vhdlSpec, and Entry::write.

Referenced by addVariable().

◆ addVariableToFile()

MemberDef * addVariableToFile ( const Entry * root,
MemberType mtype,
const QCString & scope,
const QCString & type,
const QCString & name,
const QCString & args,
bool fromAnnScope,
MemberDef * fromAnnMemb )
static

Definition at line 2586 of file doxygen.cpp.

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

References FileDef::absFilePath(), addMemberDocs(), addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, MemberDef::argsString(), QCString::at(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Entry::explicitExternal, FALSE, Entry::fileDef(), Entry::fileName, QCString::find(), Doxygen::functionNameLinkedMap, getClassMutable(), Definition::getDefColumn(), Definition::getDefFileName(), Definition::getDefLine(), MemberDef::getFileDef(), Definition::getLanguage(), getLanguageSpecificSeparator(), MemberDef::getNamespaceDef(), Definition::getOuterScope(), getResolvedNamespaceMutable(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, Entry::initializer, Entry::initLines, FileDef::insertMember(), NamespaceDefMutable::insertMember(), ModuleManager::instance(), Definition::isAnonymous(), MemberDef::isDefine(), QCString::isEmpty(), MemberDef::isEnumerate(), MemberDef::isExternal(), Entry::isStatic, MemberDef::isStatic(), Entry::lang, Entry::markAsProcessed(), Entry::metaData, Entry::mGrpId, Definition::name(), Entry::name, Entry::protection, MemberName::push_back(), Entry::qualifiers, resolveTemplateInstanceInType(), reg::search(), DefinitionMutable::setBriefDescription(), ClassDefMutable::setClassName(), MemberDefMutable::setDeclFile(), DefinitionMutable::setDocumentation(), MemberDefMutable::setExplicitExternal(), DefinitionMutable::setRefItems(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, QCString::str(), TextStream::str(), QCString::stripPrefix(), Entry::tagInfo(), TagInfo::tagName, Entry::tArgLists, toMemberDefMutable(), Typedef, and Entry::vhdlSpec.

Referenced by addVariable().

◆ adjustConfiguration()

void adjustConfiguration ( )

adjust globals that depend on configuration settings.

Definition at line 11864 of file doxygen.cpp.

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

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

Referenced by main().

◆ applyMemberOverrideOptions()

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

Definition at line 2097 of file doxygen.cpp.

2098{
2099 root->commandOverrides.apply_callGraph ([&](bool b) { md->overrideCallGraph(b); });
2100 root->commandOverrides.apply_callerGraph ([&](bool b) { md->overrideCallerGraph(b); });
2101 root->commandOverrides.apply_referencedByRelation([&](bool b) { md->overrideReferencedByRelation(b); });
2102 root->commandOverrides.apply_referencesRelation ([&](bool b) { md->overrideReferencesRelation(b); });
2103 root->commandOverrides.apply_inlineSource ([&](bool b) { md->overrideInlineSource(b); });
2104 root->commandOverrides.apply_enumValues ([&](bool b) { md->overrideEnumValues(b); });
2105}
virtual void overrideReferencesRelation(bool e)=0
virtual void overrideReferencedByRelation(bool e)=0
virtual void overrideCallGraph(bool e)=0
virtual void overrideInlineSource(bool e)=0
virtual void overrideEnumValues(bool e)=0
virtual void overrideCallerGraph(bool e)=0

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

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

◆ buildClassDocList()

void buildClassDocList ( const Entry * root)
static

Definition at line 1137 of file doxygen.cpp.

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

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

Referenced by buildClassDocList(), and parseInput().

◆ buildClassList()

void buildClassList ( const Entry * root)
static

Definition at line 1127 of file doxygen.cpp.

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

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

Referenced by buildClassList(), and parseInput().

◆ buildCompleteMemberLists()

void buildCompleteMemberLists ( )
static

Definition at line 8471 of file doxygen.cpp.

8472{
8473 // merge the member list of base classes into the inherited classes.
8474 for (const auto &cd : *Doxygen::classLinkedMap)
8475 {
8476 if (// !cd->isReference() && // not an external class
8477 cd->subClasses().empty() && // is a root of the hierarchy
8478 !cd->baseClasses().empty()) // and has at least one base class
8479 {
8480 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8481 if (cdm)
8482 {
8483 //printf("*** merging members for %s\n",qPrint(cd->name()));
8484 cdm->mergeMembers();
8485 }
8486 }
8487 }
8488 // now sort the member list of all members for all classes.
8489 for (const auto &cd : *Doxygen::classLinkedMap)
8490 {
8491 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8492 if (cdm)
8493 {
8494 cdm->sortAllMembersList();
8495 }
8496 }
8497}
virtual void sortAllMembersList()=0
virtual void mergeMembers()=0

References Doxygen::classLinkedMap, ClassDefMutable::mergeMembers(), ClassDefMutable::sortAllMembersList(), and toClassDefMutable().

Referenced by parseInput().

◆ buildConceptDocList()

void buildConceptDocList ( const Entry * root)
static

Definition at line 1286 of file doxygen.cpp.

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

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

Referenced by buildConceptDocList(), and parseInput().

◆ buildConceptList()

void buildConceptList ( const Entry * root)
static

Definition at line 1276 of file doxygen.cpp.

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

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

Referenced by buildConceptList(), and parseInput().

◆ buildDefineList()

void buildDefineList ( )
static

Definition at line 8806 of file doxygen.cpp.

8807{
8808 AUTO_TRACE();
8809 for (const auto &s : g_inputFiles)
8810 {
8811 auto it = Doxygen::macroDefinitions.find(s);
8813 {
8814 for (const auto &def : it->second)
8815 {
8816 auto md = createMemberDef(
8817 def.fileName,def.lineNr,def.columnNr,
8818 "#define",def.name,def.args,QCString(),
8819 Protection::Public,Specifier::Normal,FALSE,Relationship::Member,MemberType::Define,
8820 ArgumentList(),ArgumentList(),"");
8821 auto mmd = toMemberDefMutable(md.get());
8822
8823 if (!def.args.isEmpty())
8824 {
8825 mmd->moveArgumentList(stringToArgumentList(SrcLangExt::Cpp, def.args));
8826 }
8827 mmd->setInitializer(def.definition);
8828 mmd->setFileDef(def.fileDef);
8829 mmd->setDefinition("#define "+def.name);
8830
8831 MemberName *mn=Doxygen::functionNameLinkedMap->add(def.name);
8832 if (def.fileDef)
8833 {
8834 def.fileDef->insertMember(md.get());
8835 }
8836 AUTO_TRACE_ADD("adding macro {} with definition {}",def.name,def.definition);
8837 mn->push_back(std::move(md));
8838 }
8839 }
8840 }
8841}
static DefinesPerFileList macroDefinitions
Definition doxygen.h:137
static StringVector g_inputFiles
Definition doxygen.cpp:187

References AUTO_TRACE, AUTO_TRACE_ADD, createMemberDef(), Define, end(), FALSE, Doxygen::functionNameLinkedMap, g_inputFiles, Doxygen::macroDefinitions, MemberName::push_back(), stringToArgumentList(), and toMemberDefMutable().

Referenced by parseInput().

◆ buildDictionaryList()

void buildDictionaryList ( const Entry * root)
static

Definition at line 3471 of file doxygen.cpp.

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

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

9880{
9881 if ((root->section.isExample() || root->section.isExampleLineno()) && !root->name.isEmpty())
9882 {
9883 if (Doxygen::exampleLinkedMap->find(root->name))
9884 {
9885 warn(root->fileName,root->startLine,"Example {} was already documented. Ignoring documentation found here.",root->name);
9886 }
9887 else
9888 {
9889 PageDef *pd = Doxygen::exampleLinkedMap->add(root->name,
9890 createPageDef(root->fileName,root->startLine,
9891 root->name,root->brief+root->doc+root->inbodyDocs,root->args));
9892 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9893 pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE));
9895 pd->setLanguage(root->lang);
9896 pd->setShowLineNo(root->section.isExampleLineno());
9897
9898 //we don't add example to groups
9899 //addExampleToGroups(root,pd);
9900 }
9901 }
9902 for (const auto &e : root->children()) buildExampleList(e.get());
9903}
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:99
virtual void setFileName(const QCString &name)=0
virtual void setShowLineNo(bool)=0
static void buildExampleList(Entry *root)
Definition doxygen.cpp:9879
std::unique_ptr< PageDef > createPageDef(const QCString &f, int l, const QCString &n, const QCString &d, const QCString &t)
Definition pagedef.cpp:80
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:4017

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

Referenced by buildExampleList(), and parseInput().

◆ buildFileList()

void buildFileList ( const Entry * root)
static

Definition at line 496 of file doxygen.cpp.

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

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

Referenced by buildFileList(), and parseInput().

◆ buildFunctionList()

void buildFunctionList ( const Entry * root)
static

Definition at line 3880 of file doxygen.cpp.

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

References FileDef::absFilePath(), addGlobalFunction(), addMemberToGroups(), ModuleManager::addMemberToModule(), addMethodToClass(), MemberDefMutable::addQualifiers(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, Entry::args, MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Definition::briefDescription(), Entry::briefFile, Entry::briefLine, buildFunctionList(), buildScopeFromQualifiedName(), Entry::children(), computeQualifiedIndex(), Entry::doc, Entry::docFile, Entry::docLine, Definition::documentation(), ArgumentList::empty(), Entry::endBodyLine, FALSE, Entry::fileDef(), Entry::fileName, QCString::find(), QCString::findRev(), Doxygen::functionNameLinkedMap, getClassMutable(), Definition::getDefColumn(), Definition::getDefFileName(), Definition::getDefLine(), MemberDef::getFileDef(), MemberDef::getGroupDef(), ClassDef::getMemberByName(), MemberDef::getNamespaceDef(), Definition::getOuterScope(), getResolvedNamespace(), Definition::getStartBodyLine(), Doxygen::globalScope, Doxygen::groupLinkedMap, Entry::groups, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, FileDef::insertMember(), ModuleManager::instance(), EntryType::isCompound(), QCString::isEmpty(), MemberDef::isPrototype(), Entry::isStatic, MemberDef::isStatic(), Entry::lang, QCString::left(), leftScopeMatch(), QCString::length(), mangleCSharpGenericName(), matchArguments2(), matchTemplateArguments(), mergeArguments(), Entry::mGrpId, QCString::mid(), MemberDefMutable::moveArgumentList(), MemberDefMutable::moveDeclArgumentList(), Definition::name(), Entry::name, Entry::parent(), QCString::prepend(), Entry::protection, Entry::proto, Entry::qualifiers, Entry::relates, Entry::relatesType, removeRedundantWhiteSpace(), Entry::req, MemberDef::requiresClause(), QCString::right(), Entry::section, MemberDefMutable::setArgsString(), DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), MemberDefMutable::setDeclFile(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setPrototype(), Entry::spec, Entry::startColumn, Entry::startLine, QCString::startsWith(), stringToArgumentList(), stripTemplateSpecifiersFromScope(), Entry::tagInfo(), Entry::tArgLists, MemberDef::templateArguments(), toMemberDefMutable(), TRUE, Entry::type, MemberDef::typeString(), Entry::virt, and warn.

Referenced by buildFunctionList(), and parseInput().

◆ buildGroupList()

void buildGroupList ( const Entry * root)
static

Definition at line 425 of file doxygen.cpp.

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

References buildGroupListFiltered(), FALSE, and TRUE.

Referenced by parseInput().

◆ buildGroupListFiltered()

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

Definition at line 356 of file doxygen.cpp.

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

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

Referenced by buildGroupList(), and buildGroupListFiltered().

◆ buildInterfaceAndServiceList()

void buildInterfaceAndServiceList ( const Entry * root)
static

Definition at line 3584 of file doxygen.cpp.

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

References addInterfaceOrServiceToServiceOrSingleton(), Entry::args, AUTO_TRACE, Entry::bodyLine, buildInterfaceAndServiceList(), Entry::children(), ClassDef::compoundType(), Entry::docFile, Entry::fileName, getClassMutable(), ClassDef::Interface, QCString::isEmpty(), Entry::lang, Entry::mGrpId, Entry::name, Entry::parent(), Entry::proto, Entry::relates, Entry::relatesType, removeRedundantWhiteSpace(), Entry::section, ClassDef::Service, ClassDef::Singleton, Entry::spec, Entry::startLine, Entry::tArgLists, Entry::type, and warn.

Referenced by buildInterfaceAndServiceList(), and parseInput().

◆ buildListOfUsingDecls()

void buildListOfUsingDecls ( const Entry * root)
static

Definition at line 1992 of file doxygen.cpp.

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

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

Referenced by buildListOfUsingDecls(), and parseInput().

◆ buildNamespaceList()

void buildNamespaceList ( const Entry * root)
static

Definition at line 1670 of file doxygen.cpp.

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

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

Referenced by buildNamespaceList(), and parseInput().

◆ buildPageList()

void buildPageList ( Entry * root)
static

Definition at line 9635 of file doxygen.cpp.

9636{
9637 if (root->section.isPageDoc())
9638 {
9639 if (!root->name.isEmpty())
9640 {
9641 addRelatedPage(root);
9642 }
9643 }
9644 else if (root->section.isMainpageDoc())
9645 {
9646 QCString title=root->args.stripWhiteSpace();
9647 if (title.isEmpty()) title=theTranslator->trMainPage();
9648 //QCString name = Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9649 QCString name = "index";
9650 addRefItem(root->sli,
9651 name,
9652 "page",
9653 name,
9654 title,
9655 QCString(),nullptr
9656 );
9657 }
9658 for (const auto &e : root->children()) buildPageList(e.get());
9659}
static void buildPageList(Entry *root)
Definition doxygen.cpp:9635

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

Referenced by buildPageList(), and parseInput().

◆ buildScopeFromQualifiedName()

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

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

Definition at line 705 of file doxygen.cpp.

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

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

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

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

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

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

Referenced by buildTypedefList(), and parseInput().

◆ buildVarList()

void buildVarList ( const Entry * root)
static

Definition at line 3490 of file doxygen.cpp.

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

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

Referenced by buildVarList(), and parseInput().

◆ checkConfiguration()

void checkConfiguration ( )

check and resolve config options

Definition at line 11853 of file doxygen.cpp.

11854{
11855 AUTO_TRACE();
11856
11861}
void initWarningFormat()
Definition message.cpp:237
void postProcess(bool clearHeaderAndFooter, CompareMode compareMode=CompareMode::Full)
void checkAndCorrect(bool quiet, const bool check)
void updateObsolete()

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

Referenced by main().

◆ checkMarkdownMainfile()

void checkMarkdownMainfile ( )
static

Definition at line 12333 of file doxygen.cpp.

12334{
12335 if (Config_getBool(MARKDOWN_SUPPORT))
12336 {
12337 QCString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
12338 if (mdfileAsMainPage.isEmpty()) return;
12339 FileInfo fi(mdfileAsMainPage.data());
12340 if (!fi.exists())
12341 {
12342 warn_uncond("Specified markdown mainpage '{}' does not exist\n",mdfileAsMainPage);
12343 return;
12344 }
12345 bool ambig = false;
12346 if (findFileDef(Doxygen::inputNameLinkedMap,fi.absFilePath(),ambig)==nullptr)
12347 {
12348 warn_uncond("Specified markdown mainpage '{}' has not been defined as input file\n",mdfileAsMainPage);
12349 return;
12350 }
12351 }
12352}
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 9774 of file doxygen.cpp.

9775{
9776 for (const auto &pd : *Doxygen::pageLinkedMap)
9777 {
9778 Definition *ppd = pd->getOuterScope();
9779 while (ppd)
9780 {
9781 if (ppd==pd.get())
9782 {
9783 term("page defined {} with label {} is a subpage "
9784 "of itself! Please remove this cyclic dependency.\n",
9785 warn_line(pd->docFile(),pd->docLine()),pd->name());
9786 }
9787 ppd=ppd->getOuterScope();
9788 }
9789 }
9790}

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

Referenced by parseInput().

◆ cleanUpDoxygen()

void cleanUpDoxygen ( )

Definition at line 11379 of file doxygen.cpp.

11380{
11384
11385 delete Doxygen::indexList;
11394 Doxygen::mainPage.reset();
11398 Doxygen::globalScope = nullptr;
11400 delete theTranslator;
11401 delete g_outputList;
11402
11407 delete Doxygen::dirLinkedMap;
11408 delete Doxygen::symbolMap;
11409}
static ParserManager * parserManager
Definition doxygen.h:131
static SymbolMap< Definition > * symbolMap
Definition doxygen.h:125
static FormulaManager & instance()
Definition formula.cpp:54
void clear()
Definition linkedmap.h:212
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:178
static OutputList * g_outputList
Definition doxygen.cpp:188

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

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

◆ clearAll()

void clearAll ( )

Definition at line 201 of file doxygen.cpp.

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

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

◆ combineUsingRelations()

void combineUsingRelations ( )
static

Definition at line 9175 of file doxygen.cpp.

9176{
9177 // for each file
9178 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9179 {
9180 for (const auto &fd : *fn)
9181 {
9182 fd->combineUsingRelations();
9183 }
9184 }
9185
9186 // for each namespace
9187 NamespaceDefSet visitedNamespaces;
9188 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9189 {
9191 if (ndm)
9192 {
9193 ndm->combineUsingRelations(visitedNamespaces);
9194 }
9195 }
9196}
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 10276 of file doxygen.cpp.

10277{
10278 std::ofstream f;
10279 bool fileOpened=openOutputFile("-",f);
10280 if (fileOpened)
10281 {
10282 TextStream t(&f);
10283 Config::compareDoxyfile(t,diffList);
10284 }
10285 else
10286 {
10287 term("Cannot open stdout for writing\n");
10288 }
10289}
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:6807

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

Referenced by readConfiguration().

◆ computeClassRelations()

void computeClassRelations ( )
static

Definition at line 5314 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ computeIdealCacheParam()

int computeIdealCacheParam ( size_t v)
static

Definition at line 11411 of file doxygen.cpp.

11412{
11413 //printf("computeIdealCacheParam(v=%u)\n",v);
11414
11415 int r=0;
11416 while (v!=0) v>>=1,r++;
11417 // r = log2(v)
11418
11419 // convert to a valid cache size value
11420 return std::max(0,std::min(r-16,9));
11421}

Referenced by generateOutput().

◆ computeMemberReferences()

void computeMemberReferences ( )
static

Definition at line 5408 of file doxygen.cpp.

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

8415{
8416 for (const auto &cd : *Doxygen::classLinkedMap)
8417 {
8418 if (cd->isLinkable())
8419 {
8420 for (const auto &bcd : cd->baseClasses())
8421 {
8423 }
8424 }
8425 }
8426}
static void computeMemberRelationsForBaseClass(const ClassDef *cd, const BaseClassDef *bcd)
Definition doxygen.cpp:8334

References Doxygen::classLinkedMap, and computeMemberRelationsForBaseClass().

Referenced by parseInput().

◆ computeMemberRelationsForBaseClass()

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

Definition at line 8334 of file doxygen.cpp.

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

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

Referenced by computeMemberRelations(), and computeMemberRelationsForBaseClass().

◆ computePageRelations()

void computePageRelations ( Entry * root)
static

Definition at line 9744 of file doxygen.cpp.

9745{
9746 if ((root->section.isPageDoc() || root->section.isMainpageDoc()) && !root->name.isEmpty())
9747 {
9748 PageDef *pd = root->section.isPageDoc() ?
9749 Doxygen::pageLinkedMap->find(root->name) :
9750 Doxygen::mainPage.get();
9751 if (pd)
9752 {
9753 for (const BaseInfo &bi : root->extends)
9754 {
9755 PageDef *subPd = Doxygen::pageLinkedMap->find(bi.name);
9756 if (pd==subPd)
9757 {
9758 term("page defined {} with label {} is a direct "
9759 "subpage of itself! Please remove this cyclic dependency.\n",
9760 warn_line(pd->docFile(),pd->docLine()),pd->name());
9761 }
9762 else if (subPd)
9763 {
9764 pd->addInnerCompound(subPd);
9765 //printf("*** Added subpage relation: %s->%s\n",
9766 // qPrint(pd->name()),qPrint(subPd->name()));
9767 }
9768 }
9769 }
9770 }
9771 for (const auto &e : root->children()) computePageRelations(e.get());
9772}
virtual QCString docFile() const =0
virtual int docLine() const =0
std::vector< BaseInfo > extends
list of base classes
Definition entry.h:220
static void computePageRelations(Entry *root)
Definition doxygen.cpp:9744
QCString name
the name of the base class
Definition entry.h:94

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

Referenced by computePageRelations(), and parseInput().

◆ computeTemplateClassRelations()

void computeTemplateClassRelations ( )
static

Definition at line 5339 of file doxygen.cpp.

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

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

8895{
8896 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8897 if (numThreads>1)
8898 {
8899 ThreadPool threadPool(numThreads);
8900 std::vector < std::future< void > > results;
8901 // queue the work
8902 for (const auto &[name,symList] : *Doxygen::symbolMap)
8903 {
8904 for (const auto &def : symList)
8905 {
8907 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
8908 {
8909 auto processTooltip = [dm]() {
8910 dm->computeTooltip();
8911 };
8912 results.emplace_back(threadPool.queue(processTooltip));
8913 }
8914 }
8915 }
8916 // wait for the results
8917 for (auto &f : results)
8918 {
8919 f.get();
8920 }
8921 }
8922 else
8923 {
8924 for (const auto &[name,symList] : *Doxygen::symbolMap)
8925 {
8926 for (const auto &def : symList)
8927 {
8929 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
8930 {
8931 dm->computeTooltip();
8932 }
8933 }
8934 }
8935 }
8936}
virtual void computeTooltip()=0
Class managing a pool of worker threads.
Definition threadpool.h:48
static bool isSymbolHidden(const Definition *d)
Definition doxygen.cpp:8887

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

Referenced by parseInput().

◆ computeVerifiedDotPath()

void computeVerifiedDotPath ( )
static

Definition at line 10204 of file doxygen.cpp.

10205{
10206 // check dot path
10207 QCString dotPath = Config_getString(DOT_PATH);
10208 if (!dotPath.isEmpty())
10209 {
10210 FileInfo fi(dotPath.str());
10211 if (!(fi.exists() && fi.isFile()) )// not an existing user specified path + exec
10212 {
10213 dotPath = dotPath+"/dot"+Portable::commandExtension();
10214 FileInfo dp(dotPath.str());
10215 if (!dp.exists() || !dp.isFile())
10216 {
10217 warn_uncond("the dot tool could not be found as '{}'\n",dotPath);
10218 dotPath = "dot";
10219 dotPath += Portable::commandExtension();
10220 }
10221 }
10222#if defined(_WIN32) // convert slashes
10223 size_t l=dotPath.length();
10224 for (size_t i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\';
10225#endif
10226 }
10227 else
10228 {
10229 dotPath = "dot";
10230 dotPath += Portable::commandExtension();
10231 }
10232 Doxygen::verifiedDotPath = dotPath;
10234}
static QCString verifiedDotPath
Definition doxygen.h:139
const char * commandExtension()
Definition portable.cpp:478
#define TRACE(...)
Definition trace.h:77

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

Referenced by parseInput().

◆ convertToCompoundType()

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

Definition at line 889 of file doxygen.cpp.

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

References ClassDef::Category, ClassDef::Class, ClassDef::Exception, ClassDef::Interface, ClassDef::Protocol, ClassDef::Service, ClassDef::Singleton, ClassDef::Struct, and ClassDef::Union.

Referenced by addClassToContext().

◆ copyExtraFiles()

void copyExtraFiles ( const StringVector & files,
const QCString & filesOption,
const QCString & outputOption )
static

Definition at line 10470 of file doxygen.cpp.

10471{
10472 for (const auto &fileName : files)
10473 {
10474 if (!fileName.empty())
10475 {
10476 FileInfo fi(fileName);
10477 if (!fi.exists())
10478 {
10479 err("Extra file '{}' specified in {} does not exist!\n", fileName,filesOption);
10480 }
10481 else if (fi.isDir())
10482 {
10483 err("Extra file '{}' specified in {} is a directory, it has to be a file!\n", fileName,filesOption);
10484 }
10485 else
10486 {
10487 QCString destFileName = outputOption+"/"+fi.fileName();
10488 Doxygen::indexList->addImageFile(fi.fileName().c_str());
10489 copyFile(QCString(fileName), destFileName);
10490 }
10491 }
10492 }
10493}
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:6370

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

10446{
10447 QCString projectIcon = Config_getString(PROJECT_ICON);
10448 if (!projectIcon.isEmpty())
10449 {
10450 FileInfo fi(projectIcon.str());
10451 if (!fi.exists())
10452 {
10453 err("Project icon '{}' specified by PROJECT_ICON does not exist!\n",projectIcon);
10454 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10455 }
10456 else if (fi.isDir())
10457 {
10458 err("Project icon '{}' specified by PROJECT_ICON is a directory, it has to be a file!\n",projectIcon);
10459 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10460 }
10461 else
10462 {
10463 QCString destFileName = outputOption+"/"+fi.fileName();
10464 copyFile(projectIcon,destFileName);
10465 Doxygen::indexList->addImageFile(fi.fileName().c_str());
10466 }
10467 }
10468}
#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 10336 of file doxygen.cpp.

10337{
10338 const StringVector &latexExtraStyleSheet = Config_getList(LATEX_EXTRA_STYLESHEET);
10339 for (const auto &sheet : latexExtraStyleSheet)
10340 {
10341 std::string fileName = sheet;
10342 if (!fileName.empty())
10343 {
10344 FileInfo fi(fileName);
10345 if (!fi.exists())
10346 {
10347 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET does not exist!\n",fileName);
10348 }
10349 else if (fi.isDir())
10350 {
10351 err("Style sheet '{}' specified by LATEX_EXTRA_STYLESHEET is a directory, it has to be a file!\n", fileName);
10352 }
10353 else
10354 {
10355 QCString destFileName = Config_getString(LATEX_OUTPUT)+"/"+fi.fileName();
10356 if (!checkExtension(fi.fileName().c_str(), LATEX_STYLE_EXTENSION))
10357 {
10358 destFileName += LATEX_STYLE_EXTENSION;
10359 }
10360 copyFile(QCString(fileName), destFileName);
10361 }
10362 }
10363 }
10364}
#define LATEX_STYLE_EXTENSION
Definition latexgen.h:22
bool checkExtension(const QCString &fName, const QCString &ext)
Definition util.cpp:5407

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

10421{
10422 QCString projectLogo = projectLogoFile();
10423 if (!projectLogo.isEmpty())
10424 {
10425 FileInfo fi(projectLogo.str());
10426 if (!fi.exists())
10427 {
10428 err("Project logo '{}' specified by PROJECT_LOGO does not exist!\n",projectLogo);
10429 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10430 }
10431 else if (fi.isDir())
10432 {
10433 err("Project logo '{}' specified by PROJECT_LOGO is a directory, it has to be a file!\n",projectLogo);
10434 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
10435 }
10436 else
10437 {
10438 QCString destFileName = outputOption+"/"+fi.fileName();
10439 copyFile(projectLogo,destFileName);
10440 Doxygen::indexList->addImageFile(fi.fileName().c_str());
10441 }
10442 }
10443}
QCString projectLogoFile()
Definition util.cpp:3658

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

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

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

8955{
8956 for (const auto &cd : *Doxygen::classLinkedMap)
8957 {
8958 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8959 if (cdm)
8960 {
8961 cdm->countMembers();
8962 }
8963 }
8964
8965 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8966 {
8968 if (ndm)
8969 {
8970 ndm->countMembers();
8971 }
8972 }
8973
8974 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8975 {
8976 for (const auto &fd : *fn)
8977 {
8978 fd->countMembers();
8979 }
8980 }
8981
8982 for (const auto &gd : *Doxygen::groupLinkedMap)
8983 {
8984 gd->countMembers();
8985 }
8986
8987 auto &mm = ModuleManager::instance();
8988 mm.countMembers();
8989}
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 12101 of file doxygen.cpp.

12104{
12105 QCString result = formatDirName;
12106 if (result.isEmpty())
12107 {
12108 result = baseDirName + defaultDirName;
12109 }
12110 else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':'))
12111 {
12112 result.prepend(baseDirName+"/");
12113 }
12114 Dir formatDir(result.str());
12115 if (!formatDir.exists() && !formatDir.mkdir(result.str()))
12116 {
12117 term("Could not create output directory {}\n", result);
12118 }
12119 return result;
12120}
Class representing a directory in the file system.
Definition dir.h:75

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

Referenced by parseInput().

◆ createTagLessInstance()

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

Definition at line 1479 of file doxygen.cpp.

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

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

8431{
8432 // for each class
8433 for (const auto &cd : *Doxygen::classLinkedMap)
8434 {
8435 // that is a template
8436 for (const auto &ti : cd->getTemplateInstances())
8437 {
8438 ClassDefMutable *tcdm = toClassDefMutable(ti.classDef);
8439 if (tcdm)
8440 {
8441 tcdm->addMembersToTemplateInstance(cd.get(),cd->templateArguments(),ti.templSpec);
8442 }
8443 }
8444 }
8445}
virtual void addMembersToTemplateInstance(const ClassDef *cd, const ArgumentList &templateArguments, const QCString &templSpec)=0

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

Referenced by parseInput().

◆ createUsingMemberImportForClass()

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

Definition at line 2109 of file doxygen.cpp.

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

References Entry::anchors, applyMemberOverrideOptions(), MemberDef::argsString(), MemberDef::argumentList(), AUTO_TRACE, MemberDef::bitfieldString(), Entry::brief, Definition::briefDescription(), Definition::briefFile(), Entry::briefFile, Definition::briefLine(), Entry::briefLine, createMemberDef(), MemberDef::definition(), Entry::doc, Definition::docFile(), Entry::docFile, Definition::docLine(), Entry::docLine, Definition::documentation(), MemberDef::excpString(), Definition::getBodyDef(), Definition::getDefLine(), Definition::getEndBodyLine(), MemberDef::getMemberSpecifiers(), Definition::getStartBodyLine(), MemberDef::getVhdlSpecifiers(), Entry::id, Entry::inbodyDocs, Definition::inbodyDocumentation(), Definition::inbodyFile(), Entry::inbodyFile, Definition::inbodyLine(), Entry::inbodyLine, MemberDef::initializer(), MemberDef::initializerLines(), ClassDefMutable::insertMember(), QCString::isEmpty(), MemberDef::isStatic(), Entry::lang, Doxygen::memberNameLinkedMap, MemberDef::memberType(), Entry::metaData, Entry::mGrpId, Definition::name(), Entry::protection, MemberName::push_back(), Entry::qualifiers, MemberDef::requiresClause(), Entry::startColumn, Entry::startLine, MemberDef::templateArguments(), toMemberDefMutable(), MemberDef::typeString(), and Entry::virt.

Referenced by findUsingDeclImports().

◆ devUsage()

void devUsage ( )
static

Definition at line 11190 of file doxygen.cpp.

11191{
11193 msg("Developer parameters:\n");
11194 msg(" -m dump symbol map\n");
11195 msg(" -b making messages output unbuffered\n");
11196 msg(" -c <file> process input file as a comment block and produce HTML output\n");
11197#if ENABLE_TRACING
11198 msg(" -t [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout)\n");
11199 msg(" -t_time [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout),\n"
11200 " and include time and thread information\n");
11201#endif
11202 msg(" -d <level> enable a debug level, such as (multiple invocations of -d are possible):\n");
11204}
@ Time
Definition debug.h:35
static void printFlags()
Definition debug.cpp:137
static void clearFlag(const DebugMask mask)
Definition debug.cpp:122

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

Referenced by readConfiguration().

◆ distributeClassGroupRelations()

void distributeClassGroupRelations ( )

Definition at line 1446 of file doxygen.cpp.

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

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

◆ distributeConceptGroups()

void distributeConceptGroups ( )
static

Definition at line 1298 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ distributeMemberGroupDocumentation()

void distributeMemberGroupDocumentation ( )
static

Definition at line 9238 of file doxygen.cpp.

9239{
9240 // for each class
9241 for (const auto &cd : *Doxygen::classLinkedMap)
9242 {
9243 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9244 if (cdm)
9245 {
9247 }
9248 }
9249 // for each file
9250 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9251 {
9252 for (const auto &fd : *fn)
9253 {
9254 fd->distributeMemberGroupDocumentation();
9255 }
9256 }
9257 // for each namespace
9258 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9259 {
9261 if (ndm)
9262 {
9264 }
9265 }
9266 // for each group
9267 for (const auto &gd : *Doxygen::groupLinkedMap)
9268 {
9269 gd->distributeMemberGroupDocumentation();
9270 }
9272}
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 11149 of file doxygen.cpp.

11150{
11151 QCString anchor;
11153 {
11154 MemberDef *md = toMemberDef(d);
11155 anchor=":"+md->anchor();
11156 }
11157 QCString scope;
11158 QCString fn = d->getOutputFileBase();
11161 {
11162 scope = fn;
11163 }
11164 t << "REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
11165 << fn+anchor << "','"
11166 << scope << "','"
11167 << d->name() << "','"
11168 << d->getDefFileName() << "','"
11169 << d->getDefLine()
11170 << "');\n";
11171}
virtual QCString anchor() const =0
virtual QCString getOutputFileBase() const =0
MemberDef * toMemberDef(Definition *d)
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:5412

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

11174{
11175 std::ofstream f = Portable::openOutputStream("symbols.sql");
11176 if (f.is_open())
11177 {
11178 TextStream t(&f);
11179 for (const auto &[name,symList] : *Doxygen::symbolMap)
11180 {
11181 for (const auto &def : symList)
11182 {
11183 dumpSymbol(t,def);
11184 }
11185 }
11186 }
11187}
static void dumpSymbol(TextStream &t, Definition *d)
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:665

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

Referenced by generateOutput().

◆ exitDoxygen()

void exitDoxygen ( )
staticnoexcept

Definition at line 12088 of file doxygen.cpp.

12089{
12090 if (!g_successfulRun) // premature exit
12091 {
12092 Dir thisDir;
12093 msg("Exiting...\n");
12094 if (!Doxygen::filterDBFileName.isEmpty())
12095 {
12096 thisDir.remove(Doxygen::filterDBFileName.str());
12097 }
12098 }
12099}
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:314
static QCString filterDBFileName
Definition doxygen.h:133
static bool g_successfulRun
Definition doxygen.cpp:190

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

Referenced by parseInput().

◆ extractClassName()

QCString extractClassName ( const Entry * root)
static

Definition at line 5217 of file doxygen.cpp.

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

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

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

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

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

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

5677{
5678 SymbolResolver resolver(fd);
5679 const ClassDef *tcd = resolver.resolveClass(nd,scopeName,true,true);
5680 return tcd;
5681}

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

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

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

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

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

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

◆ findClassWithinClassContext()

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

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

Definition at line 4478 of file doxygen.cpp.

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

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

Referenced by findClassRelation(), and findUsedClassesForClass().

◆ findDefineDocumentation()

void findDefineDocumentation ( Entry * root)
static

Definition at line 9486 of file doxygen.cpp.

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

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

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

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

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

Referenced by findDirDocumentation(), and parseInput().

◆ findDocumentedEnumValues()

void findDocumentedEnumValues ( )
static

Definition at line 8084 of file doxygen.cpp.

8085{
8088}
static void findDEV(const MemberNameLinkedMap &mnsd)
Definition doxygen.cpp:8058

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

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

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

Referenced by addVariable(), and findClassRelation().

◆ findEnumDocumentation()

void findEnumDocumentation ( const Entry * root)
static

Definition at line 7972 of file doxygen.cpp.

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

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

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

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::args, AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, buildScopeFromQualifiedName(), Entry::children(), Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Enumeration, FALSE, Entry::fileDef(), Entry::fileName, findEnums(), QCString::findRev(), Doxygen::functionNameLinkedMap, getClass(), getClassMutable(), getResolvedNamespaceMutable(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), FileDef::insertMember(), NamespaceDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), Definition::isAnonymous(), QCString::isEmpty(), EntryType::isScope(), Entry::lang, QCString::left(), QCString::length(), mangleCSharpGenericName(), Doxygen::memberNameLinkedMap, mergeScopes(), Entry::metaData, Entry::mGrpId, Definition::name(), Entry::name, Entry::parent(), QCString::prepend(), Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, Entry::relates, Entry::relatesType, QCString::right(), Entry::section, Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, Entry::tagInfo(), toMemberDefMutable(), toNamespaceDefMutable(), TRUE, and Entry::vhdlSpec.

Referenced by findEnums(), and parseInput().

◆ findFriends()

void findFriends ( )
static

Definition at line 4186 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ findFunctionPtr()

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

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

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

Definition at line 2827 of file doxygen.cpp.

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

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

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

◆ findGlobalMember()

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

Definition at line 5711 of file doxygen.cpp.

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

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

Referenced by findMember().

◆ findGroupScope()

void findGroupScope ( const Entry * root)
static

Definition at line 440 of file doxygen.cpp.

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

References Entry::children(), findGroupScope(), findScopeFromQualifiedName(), Doxygen::globalScope, Doxygen::groupLinkedMap, QCString::isEmpty(), Definition::name(), Entry::name, Entry::parent(), Entry::section, GroupDef::setGroupScope(), stripAnonymousNamespaceScope(), substitute(), and Entry::tagInfo().

Referenced by findGroupScope(), and parseInput().

◆ findIncludedUsingDirectives()

void findIncludedUsingDirectives ( )
static

Definition at line 2408 of file doxygen.cpp.

2409{
2410 FileDefSet visitedFiles;
2411 // then recursively add using directives found in #include files
2412 // to files that have not been visited.
2413 for (const auto &fn : *Doxygen::inputNameLinkedMap)
2414 {
2415 for (const auto &fd : *fn)
2416 {
2417 //printf("----- adding using directives for file %s\n",qPrint(fd->name()));
2418 fd->addIncludedUsingDirectives(visitedFiles);
2419 }
2420 }
2421}
std::unordered_set< const FileDef * > FileDefSet
Definition filedef.h:44

References Doxygen::inputNameLinkedMap.

Referenced by parseInput().

◆ findInheritedTemplateInstances()

void findInheritedTemplateInstances ( )
static

Using the dictionary build by findClassEntries(), this function will look for additional template specialization that exists as inheritance relations only. These instances will be added to the template they are derived from.

Definition at line 5245 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ findMainPage()

void findMainPage ( Entry * root)
static

Definition at line 9662 of file doxygen.cpp.

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

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

9733{
9734 if (root->section.isMainpageDoc())
9735 {
9736 if (Doxygen::mainPage && root->tagInfo())
9737 {
9738 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9739 }
9740 }
9741 for (const auto &e : root->children()) findMainPageTagFiles(e.get());
9742}
static void findMainPageTagFiles(Entry *root)
Definition doxygen.cpp:9732

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

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

References addLocalObjCMethod(), addMemberDocs(), addMemberFunction(), addMemberSpecialization(), addMemberToGroups(), ModuleManager::addMemberToModule(), addOverloaded(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, argListToString(), MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, QCString::clear(), Config_getBool, createMemberDef(), DCOP, Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Event, extractNamespaceName(), FALSE, Entry::fileDef(), Entry::fileName, QCString::find(), findGlobalMember(), Function, Doxygen::functionNameLinkedMap, Definition::getBodyDef(), getClass(), getClassMutable(), Definition::getDefLine(), Definition::getEndBodyLine(), MemberDef::getFileDef(), Definition::getOuterScope(), Definition::getStartBodyLine(), FileDef::getUsedNamespaces(), Doxygen::globalScope, Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), insertMemberAlias(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), MemberDef::isDefine(), QCString::isEmpty(), MemberDef::isEnumerate(), EntryType::isScope(), Entry::isStatic, MemberDef::isStrong(), Entry::lang, QCString::left(), QCString::length(), MemberDefMutable::makeRelated(), matchArguments2(), Doxygen::memberNameLinkedMap, mergeScopes(), Entry::metaData, Entry::mGrpId, MemberDef::moveTo(), Entry::mtype, Definition::name(), Entry::name, Doxygen::namespaceLinkedMap, Entry::parent(), parseFuncDecl(), QCString::prepend(), Property, Entry::protection, Entry::proto, MemberName::push_back(), ClassDef::qualifiedNameWithTemplateParameters(), Entry::qualifiers, Entry::relatesType, FileDef::removeMember(), removeRedundantWhiteSpace(), QCString::right(), Entry::section, MemberDefMutable::setMemberClass(), Signal, MemberName::size(), Entry::sli, Slot, Entry::spec, Entry::startColumn, Entry::startLine, QCString::startsWith(), QCString::stripPrefix(), stripTemplateSpecifiersFromScope(), QCString::stripWhiteSpace(), substitute(), Entry::tagInfo(), Entry::tArgLists, toMemberDefMutable(), TRUE, Entry::vhdlSpec, Entry::virt, warn, and warn_undoc.

Referenced by filterMemberDocumentation(), and findObjCMethodDefinitions().

◆ findMemberDocumentation()

void findMemberDocumentation ( const Entry * root)
static

Definition at line 7415 of file doxygen.cpp.

7416{
7417 if (root->section.isMemberDoc() ||
7418 root->section.isOverloadDoc() ||
7419 root->section.isFunction() ||
7420 root->section.isVariable() ||
7421 root->section.isVariableDoc() ||
7422 root->section.isDefine() ||
7423 root->section.isIncludedService() ||
7424 root->section.isExportedInterface()
7425 )
7426 {
7427 AUTO_TRACE();
7428 if (root->relatesType==RelatesType::Duplicate && !root->relates.isEmpty())
7429 {
7431 }
7433 }
7434 for (const auto &e : root->children())
7435 {
7436 if (!e->section.isEnum())
7437 {
7438 findMemberDocumentation(e.get());
7439 }
7440 }
7441}
static void findMemberDocumentation(const Entry *root)
Definition doxygen.cpp:7415
static void filterMemberDocumentation(const Entry *root, const QCString &relates)
Definition doxygen.cpp:7265

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

Referenced by findMemberDocumentation(), and parseInput().

◆ findModuleDocumentation()

void findModuleDocumentation ( const Entry * root)
static

Definition at line 1266 of file doxygen.cpp.

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

References ModuleManager::addDocs(), AUTO_TRACE, Entry::children(), findModuleDocumentation(), ModuleManager::instance(), and Entry::section.

Referenced by findModuleDocumentation(), and parseInput().

◆ findObjCMethodDefinitions()

void findObjCMethodDefinitions ( const Entry * root)
static

Definition at line 7445 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ findScopeFromQualifiedName()

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

Definition at line 774 of file doxygen.cpp.

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

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

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

◆ findSectionsInDocumentation()

void findSectionsInDocumentation ( )
static

Definition at line 9276 of file doxygen.cpp.

9277{
9278 // for each class
9279 for (const auto &cd : *Doxygen::classLinkedMap)
9280 {
9281 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9282 if (cdm)
9283 {
9285 }
9286 }
9287 // for each concept
9288 for (const auto &cd : *Doxygen::conceptLinkedMap)
9289 {
9290 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
9291 if (cdm)
9292 {
9294 }
9295 }
9296 // for each file
9297 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9298 {
9299 for (const auto &fd : *fn)
9300 {
9301 fd->findSectionsInDocumentation();
9302 }
9303 }
9304 // for each namespace
9305 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9306 {
9308 if (ndm)
9309 {
9311 }
9312 }
9313 // for each group
9314 for (const auto &gd : *Doxygen::groupLinkedMap)
9315 {
9316 gd->findSectionsInDocumentation();
9317 }
9318 // for each page
9319 for (const auto &pd : *Doxygen::pageLinkedMap)
9320 {
9321 pd->findSectionsInDocumentation();
9322 }
9323 // for each directory
9324 for (const auto &dd : *Doxygen::dirLinkedMap)
9325 {
9326 dd->findSectionsInDocumentation();
9327 }
9329 if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
9330}
virtual void findSectionsInDocumentation()=0
virtual void findSectionsInDocumentation()=0
void findSectionsInDocumentation()
virtual void findSectionsInDocumentation()=0

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

Referenced by parseInput().

◆ findTagLessClasses() [1/2]

void findTagLessClasses ( )
static

Definition at line 1646 of file doxygen.cpp.

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

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

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

◆ findTagLessClasses() [2/2]

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

Definition at line 1629 of file doxygen.cpp.

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

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

◆ findTemplateInstanceRelation()

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

Definition at line 4722 of file doxygen.cpp.

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

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

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

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

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

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

Referenced by findTemplateInstanceRelation(), and findUsedTemplateInstances().

◆ findUsedNamespace()

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

Definition at line 1837 of file doxygen.cpp.

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

References getResolvedNamespace().

Referenced by findUsingDirectives().

◆ findUsedTemplateInstances()

void findUsedTemplateInstances ( )
static

Definition at line 5278 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ findUsingDeclarations()

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

Definition at line 2005 of file doxygen.cpp.

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

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

Referenced by findUsingDeclarations(), and parseInput().

◆ findUsingDeclImports()

void findUsingDeclImports ( const Entry * root)
static

Definition at line 2158 of file doxygen.cpp.

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

References DefinitionMutable::addInnerCompound(), FileDef::addUsingDeclaration(), NamespaceDefMutable::addUsingDeclaration(), Entry::anchors, applyMemberOverrideOptions(), MemberDef::argsString(), MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, MemberDef::bitfieldString(), Entry::brief, Definition::briefDescription(), Definition::briefFile(), Entry::briefFile, Definition::briefLine(), Entry::briefLine, Entry::children(), Doxygen::classLinkedMap, ClassDef::containsOverload(), createClassDefAlias(), createMemberDef(), createMemberDefAlias(), createUsingMemberImportForClass(), ClassDef::deepCopy(), MemberDef::definition(), Definition::definitionType(), Entry::doc, Definition::docFile(), Entry::docFile, Definition::docLine(), Entry::docLine, Definition::documentation(), MemberDef::excpString(), Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::findRev(), findUsingDeclImports(), Doxygen::functionNameLinkedMap, g_usingClassMap, Definition::getBodyDef(), getClassMutable(), Definition::getDefLine(), Definition::getEndBodyLine(), MemberDef::getMemberSpecifiers(), getResolvedNamespace(), Definition::getStartBodyLine(), MemberDef::getVhdlSpecifiers(), Entry::id, Entry::inbodyDocs, Definition::inbodyDocumentation(), Definition::inbodyFile(), Entry::inbodyFile, Definition::inbodyLine(), Entry::inbodyLine, MemberDef::initializer(), MemberDef::initializerLines(), FileDef::insertClass(), FileDef::insertMember(), NamespaceDefMutable::insertMember(), EntryType::isCompound(), QCString::isEmpty(), MemberDef::isStatic(), Entry::lang, QCString::left(), QCString::length(), Definition::localName(), ClassDef::memberNameInfoLinkedMap(), Doxygen::memberNameLinkedMap, MemberDef::memberType(), Entry::metaData, Entry::mGrpId, ClassDef::moveTo(), Definition::name(), Entry::name, Entry::parent(), Entry::protection, MemberDef::protection(), MemberName::push_back(), Definition::qualifiedName(), Entry::qualifiers, removeRedundantWhiteSpace(), MemberDef::requiresClause(), SymbolResolver::resolveClass(), SymbolResolver::resolveSymbol(), QCString::right(), Entry::section, DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), ClassDefMutable::setFileDef(), Entry::startColumn, Entry::startLine, QCString::startsWith(), QCString::str(), stripAnonymousNamespaceScope(), stripTemplateSpecifiersFromScope(), Entry::tagInfo(), TagInfo::tagName, MemberDef::templateArguments(), toClassDef(), toClassDefMutable(), toMemberDef(), toMemberDefMutable(), toNamespaceDefMutable(), Definition::TypeClass, Definition::TypeMember, MemberDef::typeString(), and Entry::virt.

Referenced by findUsingDeclImports(), and parseInput().

◆ findUsingDirectives()

void findUsingDirectives ( const Entry * root)
static

Definition at line 1850 of file doxygen.cpp.

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

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

Referenced by findUsingDirectives(), and parseInput().

◆ flushCachedTemplateRelations()

void flushCachedTemplateRelations ( )
static

Definition at line 9335 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ flushUnresolvedRelations()

void flushUnresolvedRelations ( )
static

Definition at line 9389 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ g_pathsVisited()

StringUnorderedSet g_pathsVisited ( 1009 )
static

Referenced by readDir(), and readFileOrDirectory().

◆ generateClassDocs()

void generateClassDocs ( )
static

Definition at line 9093 of file doxygen.cpp.

9094{
9095 std::vector<ClassDefMutable*> classList;
9096 for (const auto &cdi : *Doxygen::classLinkedMap)
9097 {
9098 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9099 if (cd && (cd->getOuterScope()==nullptr ||
9101 {
9102 addClassAndNestedClasses(classList,cd);
9103 }
9104 }
9105 for (const auto &cdi : *Doxygen::hiddenClassLinkedMap)
9106 {
9107 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9108 if (cd && (cd->getOuterScope()==nullptr ||
9110 {
9111 addClassAndNestedClasses(classList,cd);
9112 }
9113 }
9114 generateDocsForClassList(classList);
9115}
static void generateDocsForClassList(const std::vector< ClassDefMutable * > &classList)
Definition doxygen.cpp:8995

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

9120{
9121 for (const auto &cdi : *Doxygen::conceptLinkedMap)
9122 {
9124
9125 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9126 if (cd &&
9127 (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9128 cd->getOuterScope()==Doxygen::globalScope // only look at global concepts
9129 ) && !cd->isHidden() && cd->isLinkableInProject()
9130 )
9131 {
9132 msg("Generating docs for concept {}...\n",cd->displayName());
9134 }
9135 }
9136}
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 10242 of file doxygen.cpp.

10244{
10245 std::ofstream f;
10246 bool fileOpened=openOutputFile(configFile,f);
10247 bool writeToStdout=configFile=="-";
10248 if (fileOpened)
10249 {
10250 TextStream t(&f);
10251 Config::writeTemplate(t,shortList,updateOnly);
10252 if (!writeToStdout)
10253 {
10254 if (!updateOnly)
10255 {
10256 msg("\n\nConfiguration file '{}' created.\n\n",configFile);
10257 msg("Now edit the configuration file and enter\n\n");
10258 if (configFile!="Doxyfile" && configFile!="doxyfile")
10259 msg(" doxygen {}\n\n",configFile);
10260 else
10261 msg(" doxygen\n\n");
10262 msg("to generate the documentation for your project\n\n");
10263 }
10264 else
10265 {
10266 msg("\n\nConfiguration file '{}' updated.\n\n",configFile);
10267 }
10268 }
10269 }
10270 else
10271 {
10272 term("Cannot open file {} for writing\n",configFile);
10273 }
10274}
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 10497 of file doxygen.cpp.

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

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

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

Referenced by generateClassDocs().

◆ generateExampleDocs()

void generateExampleDocs ( )
static

Definition at line 9947 of file doxygen.cpp.

9948{
9949 g_outputList->disable(OutputType::Man);
9950 for (const auto &pd : *Doxygen::exampleLinkedMap)
9951 {
9952 msg("Generating docs for example {}...\n",pd->name());
9953 SrcLangExt lang = getLanguageFromFileName(pd->name(), SrcLangExt::Unknown);
9954 if (lang != SrcLangExt::Unknown)
9955 {
9956 QCString ext = getFileNameExtension(pd->name());
9957 auto intf = Doxygen::parserManager->getCodeParser(ext);
9958 intf->resetCodeParserState();
9959 }
9960 QCString n=pd->getOutputFileBase();
9961 startFile(*g_outputList,n,n,pd->name());
9963 g_outputList->docify(pd->name());
9965 g_outputList->startContents();
9966 QCString lineNoOptStr;
9967 if (pd->showLineNo())
9968 {
9969 lineNoOptStr="{lineno}";
9970 }
9971 g_outputList->generateDoc(pd->docFile(), // file
9972 pd->docLine(), // startLine
9973 pd.get(), // context
9974 nullptr, // memberDef
9975 (pd->briefDescription().isEmpty()?"":pd->briefDescription()+"\n\n")+
9976 pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
9977 TRUE, // index words
9978 TRUE, // is example
9979 pd->name(),
9980 FALSE,
9981 FALSE
9982 );
9983 endFile(*g_outputList); // contains g_outputList->endContents()
9984 }
9986}
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, 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:5718
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5760

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

Referenced by generateOutput().

◆ generateFileDocs()

void generateFileDocs ( )
static

Definition at line 8667 of file doxygen.cpp.

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

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

Referenced by generateOutput().

◆ generateFileSources()

void generateFileSources ( )
static

Definition at line 8501 of file doxygen.cpp.

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

9992{
9993 for (const auto &gd : *Doxygen::groupLinkedMap)
9994 {
9995 if (!gd->isReference())
9996 {
9997 gd->writeDocumentation(*g_outputList);
9998 }
9999 }
10000}

References g_outputList, and Doxygen::groupLinkedMap.

Referenced by generateOutput().

◆ generateNamespaceClassDocs()

void generateNamespaceClassDocs ( const ClassLinkedRefMap & classList)
static

Definition at line 10005 of file doxygen.cpp.

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

10078{
10079 // for each concept in the namespace...
10080 for (const auto &cd : conceptList)
10081 {
10083 if ( cdm && cd->isLinkableInProject() && !cd->isHidden())
10084 {
10085 msg("Generating docs for concept {}...\n",cd->name());
10087 }
10088 }
10089}

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

Referenced by generateNamespaceDocs().

◆ generateNamespaceDocs()

void generateNamespaceDocs ( )
static

Definition at line 10091 of file doxygen.cpp.

10092{
10093 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
10094
10095 //writeNamespaceIndex(*g_outputList);
10096
10097 // for each namespace...
10098 for (const auto &nd : *Doxygen::namespaceLinkedMap)
10099 {
10100 if (nd->isLinkableInProject())
10101 {
10103 if (ndm)
10104 {
10105 msg("Generating docs for namespace {}\n",nd->displayName());
10107 }
10108 }
10109
10110 generateNamespaceClassDocs(nd->getClasses());
10111 if (sliceOpt)
10112 {
10113 generateNamespaceClassDocs(nd->getInterfaces());
10114 generateNamespaceClassDocs(nd->getStructs());
10115 generateNamespaceClassDocs(nd->getExceptions());
10116 }
10117 generateNamespaceConceptDocs(nd->getConcepts());
10118 }
10119}
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 13029 of file doxygen.cpp.

13030{
13031 AUTO_TRACE();
13032 /**************************************************************************
13033 * Initialize output generators *
13034 **************************************************************************/
13035
13036 /// add extra languages for which we can only produce syntax highlighted code
13038
13039 //// dump all symbols
13040 if (g_dumpSymbolMap)
13041 {
13042 dumpSymbolMap();
13043 exit(0);
13044 }
13045
13046 bool generateHtml = Config_getBool(GENERATE_HTML);
13047 bool generateLatex = Config_getBool(GENERATE_LATEX);
13048 bool generateMan = Config_getBool(GENERATE_MAN);
13049 bool generateRtf = Config_getBool(GENERATE_RTF);
13050 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
13051
13052
13054 if (generateHtml)
13055 {
13059 }
13060 if (generateLatex)
13061 {
13064 }
13065 if (generateDocbook)
13066 {
13069 }
13070 if (generateMan)
13071 {
13072 g_outputList->add<ManGenerator>();
13074 }
13075 if (generateRtf)
13076 {
13077 g_outputList->add<RTFGenerator>();
13079 }
13080 if (Config_getBool(USE_HTAGS))
13081 {
13083 QCString htmldir = Config_getString(HTML_OUTPUT);
13084 if (!Htags::execute(htmldir))
13085 err("USE_HTAGS is YES but htags(1) failed. \n");
13086 else if (!Htags::loadFilemap(htmldir))
13087 err("htags(1) ended normally but failed to load the filemap. \n");
13088 }
13089
13090 /**************************************************************************
13091 * Generate documentation *
13092 **************************************************************************/
13093
13094 g_s.begin("Generating style sheet...\n");
13095 //printf("writing style info\n");
13096 g_outputList->writeStyleInfo(0); // write first part
13097 g_s.end();
13098
13099 bool searchEngine = Config_getBool(SEARCHENGINE);
13100 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
13101
13102 g_s.begin("Generating search indices...\n");
13103 if (searchEngine && !serverBasedSearch && generateHtml)
13104 {
13106 }
13107
13108 // generate search indices (need to do this before writing other HTML
13109 // pages as these contain a drop down menu with options depending on
13110 // what categories we find in this function.
13111 if (generateHtml && searchEngine)
13112 {
13113 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
13114 Dir searchDir(searchDirName.str());
13115 if (!searchDir.exists() && !searchDir.mkdir(searchDirName.str()))
13116 {
13117 term("Could not create search results directory '{}' $PWD='{}'\n",
13118 searchDirName,Dir::currentDirPath());
13119 }
13120 HtmlGenerator::writeSearchData(searchDirName);
13121 if (!serverBasedSearch) // client side search index
13122 {
13124 }
13125 }
13126 g_s.end();
13127
13128 // copy static stuff
13129 if (generateHtml)
13130 {
13132 copyLogo(Config_getString(HTML_OUTPUT));
13133 copyIcon(Config_getString(HTML_OUTPUT));
13134 copyExtraFiles(Config_getList(HTML_EXTRA_FILES),"HTML_EXTRA_FILES",Config_getString(HTML_OUTPUT));
13135 }
13136 if (generateLatex)
13137 {
13139 copyLogo(Config_getString(LATEX_OUTPUT));
13140 copyIcon(Config_getString(LATEX_OUTPUT));
13141 copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT));
13142 }
13143 if (generateDocbook)
13144 {
13145 copyLogo(Config_getString(DOCBOOK_OUTPUT));
13146 copyIcon(Config_getString(DOCBOOK_OUTPUT));
13147 }
13148 if (generateRtf)
13149 {
13150 copyLogo(Config_getString(RTF_OUTPUT));
13151 copyIcon(Config_getString(RTF_OUTPUT));
13152 copyExtraFiles(Config_getList(RTF_EXTRA_FILES),"RTF_EXTRA_FILES",Config_getString(RTF_OUTPUT));
13153 }
13154
13156 if (fm.hasFormulas() && generateHtml
13157 && !Config_getBool(USE_MATHJAX))
13158 {
13159 g_s.begin("Generating images for formulas in HTML...\n");
13160 fm.generateImages(Config_getString(HTML_OUTPUT), Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg ?
13162 g_s.end();
13163 }
13164 if (fm.hasFormulas() && generateRtf)
13165 {
13166 g_s.begin("Generating images for formulas in RTF...\n");
13168 g_s.end();
13169 }
13170
13171 if (fm.hasFormulas() && generateDocbook)
13172 {
13173 g_s.begin("Generating images for formulas in Docbook...\n");
13175 g_s.end();
13176 }
13177
13178 g_s.begin("Generating example documentation...\n");
13180 g_s.end();
13181
13182 g_s.begin("Generating file sources...\n");
13184 g_s.end();
13185
13186 g_s.begin("Generating file documentation...\n");
13188 g_s.end();
13189
13190 g_s.begin("Generating page documentation...\n");
13192 g_s.end();
13193
13194 g_s.begin("Generating group documentation...\n");
13196 g_s.end();
13197
13198 g_s.begin("Generating class documentation...\n");
13200 g_s.end();
13201
13202 g_s.begin("Generating concept documentation...\n");
13204 g_s.end();
13205
13206 g_s.begin("Generating module documentation...\n");
13208 g_s.end();
13209
13210 g_s.begin("Generating namespace documentation...\n");
13212 g_s.end();
13213
13214 if (Config_getBool(GENERATE_LEGEND))
13215 {
13216 g_s.begin("Generating graph info page...\n");
13218 g_s.end();
13219 }
13220
13221 g_s.begin("Generating directory documentation...\n");
13223 g_s.end();
13224
13225 if (g_outputList->size()>0)
13226 {
13228 }
13229
13230 g_s.begin("finalizing index lists...\n");
13231 Doxygen::indexList->finalize();
13232 g_s.end();
13233
13234 g_s.begin("writing tag file...\n");
13235 writeTagFile();
13236 g_s.end();
13237
13238 if (Config_getBool(GENERATE_XML))
13239 {
13240 g_s.begin("Generating XML output...\n");
13242 generateXML();
13244 g_s.end();
13245 }
13246 if (Config_getBool(GENERATE_SQLITE3))
13247 {
13248 g_s.begin("Generating SQLITE3 output...\n");
13250 g_s.end();
13251 }
13252
13253 if (Config_getBool(GENERATE_AUTOGEN_DEF))
13254 {
13255 g_s.begin("Generating AutoGen DEF output...\n");
13256 generateDEF();
13257 g_s.end();
13258 }
13259 if (Config_getBool(GENERATE_PERLMOD))
13260 {
13261 g_s.begin("Generating Perl module output...\n");
13263 g_s.end();
13264 }
13265 if (generateHtml && searchEngine && serverBasedSearch)
13266 {
13267 g_s.begin("Generating search index\n");
13268 if (Doxygen::searchIndex.kind()==SearchIndexIntf::Internal) // write own search index
13269 {
13271 Doxygen::searchIndex.write(Config_getString(HTML_OUTPUT)+"/search/search.idx");
13272 }
13273 else // write data for external search index
13274 {
13276 QCString searchDataFile = Config_getString(SEARCHDATA_FILE);
13277 if (searchDataFile.isEmpty())
13278 {
13279 searchDataFile="searchdata.xml";
13280 }
13281 if (!Portable::isAbsolutePath(searchDataFile.data()))
13282 {
13283 searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/");
13284 }
13285 Doxygen::searchIndex.write(searchDataFile);
13286 }
13287 g_s.end();
13288 }
13289
13290 if (generateRtf)
13291 {
13292 g_s.begin("Combining RTF output...\n");
13293 if (!RTFGenerator::preProcessFileInplace(Config_getString(RTF_OUTPUT),"refman.rtf"))
13294 {
13295 err("An error occurred during post-processing the RTF files!\n");
13296 }
13297 g_s.end();
13298 }
13299
13300 g_s.begin("Running plantuml with JAVA...\n");
13302 g_s.end();
13303
13304 if (Config_getBool(HAVE_DOT))
13305 {
13306 g_s.begin("Running dot...\n");
13308 g_s.end();
13309 }
13310
13311 if (generateHtml &&
13312 Config_getBool(GENERATE_HTMLHELP) &&
13313 !Config_getString(HHC_LOCATION).isEmpty())
13314 {
13315 g_s.begin("Running html help compiler...\n");
13317 g_s.end();
13318 }
13319
13320 if ( generateHtml &&
13321 Config_getBool(GENERATE_QHP) &&
13322 !Config_getString(QHG_LOCATION).isEmpty())
13323 {
13324 g_s.begin("Running qhelpgenerator...\n");
13326 g_s.end();
13327 }
13328
13329 g_outputList->cleanup();
13330
13331 msg("type lookup cache used {}/{} hits={} misses={}\n",
13333 Doxygen::typeLookupCache->capacity(),
13335 Doxygen::typeLookupCache->misses());
13336 msg("symbol lookup cache used {}/{} hits={} misses={}\n",
13338 Doxygen::symbolLookupCache->capacity(),
13340 Doxygen::symbolLookupCache->misses());
13341 int typeCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::typeLookupCache->misses()*2/3)); // part of the cache is flushed, hence the 2/3 correction factor
13342 int symbolCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::symbolLookupCache->misses()));
13343 int cacheParam = std::max(typeCacheParam,symbolCacheParam);
13344 if (cacheParam>Config_getInt(LOOKUP_CACHE_SIZE))
13345 {
13346 msg("Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is {} at the cost of higher memory usage.\n",cacheParam);
13347 }
13348
13350 {
13351
13352 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
13353 if (numThreads<1) numThreads=1;
13354 msg("Total elapsed time: {:.6f} seconds\n(of which an average of {:.6f} seconds per thread waiting for external tools to finish)\n",
13355 (static_cast<double>(Debug::elapsedTime())),
13356 Portable::getSysElapsedTime()/static_cast<double>(numThreads)
13357 );
13358 g_s.print();
13359
13361 msg("finished...\n");
13363 }
13364 else
13365 {
13366 msg("finished...\n");
13367 }
13368
13369
13370 /**************************************************************************
13371 * Start cleaning up *
13372 **************************************************************************/
13373
13375
13377 Dir thisDir;
13378 thisDir.remove(Doxygen::filterDBFileName.str());
13380 exitTracing();
13382 delete Doxygen::clangUsrMap;
13384
13385 //dumpDocNodeSizes();
13386}
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
static double elapsedTime()
Definition debug.cpp:201
static void setFlag(const DebugMask mask)
Definition debug.cpp:117
static std::string currentDirPath()
Definition dir.cpp:342
static void init()
bool run()
Definition dot.cpp:128
static DotManager * instance()
Definition dot.cpp:78
static Cache< std::string, LookupInfo > * symbolLookupCache
Definition doxygen.h:128
static bool generatingXmlOutput
Definition doxygen.h:136
static ClangUsrMap * clangUsrMap
Definition doxygen.h:126
bool hasFormulas() const
Definition formula.cpp:720
void generateImages(const QCString &outputDir, Format format, HighDPI hd=HighDPI::Off)
Definition formula.cpp:636
Generator for HTML output.
Definition htmlgen.h:96
static void init()
Definition htmlgen.cpp:1160
static void writeSearchPage()
Definition htmlgen.cpp:3123
static void writeTabData()
Additional initialization after indices have been created.
Definition htmlgen.cpp:1311
static void writeSearchData(const QCString &dir)
Definition htmlgen.cpp:1320
static void writeExternalSearchPage()
Definition htmlgen.cpp:3222
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:1176
static void copyLatexStyleSheet()
static void runQHelpGenerator()
class Statistics g_s
static void copyStyleSheet()
static void generateGroupDocs()
Definition doxygen.cpp:9991
static void generateExampleDocs()
Definition doxygen.cpp:9947
static void dumpSymbolMap()
static void generateFileDocs()
Definition doxygen.cpp:8667
static void copyIcon(const QCString &outputOption)
static void generatePageDocs()
Definition doxygen.cpp:9862
static void generateFileSources()
Definition doxygen.cpp:8501
static void copyLogo(const QCString &outputOption)
static void generateClassDocs()
Definition doxygen.cpp:9093
static int computeIdealCacheParam(size_t v)
static void copyExtraFiles(const StringVector &files, const QCString &filesOption, const QCString &outputOption)
static void runHtmlHelpCompiler()
static bool g_dumpSymbolMap
Definition doxygen.cpp:191
static void generateNamespaceDocs()
static void writeTagFile()
void cleanUpDoxygen()
static void generateConceptDocs()
Definition doxygen.cpp:9119
void writeGraphInfo(OutputList &ol)
Definition index.cpp:4063
void writeIndexHierarchy(OutputList &ol)
Definition index.cpp:5761
void finishWarnExit()
Definition message.cpp:295
void deinit()
bool isAbsolutePath(const QCString &fileName)
Definition portable.cpp:514
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:5712
void generateXML()
Definition xmlgen.cpp:2196

References addCodeOnlyMappings(), AUTO_TRACE, FormulaManager::Bitmap, Doxygen::clangUsrMap, cleanUpDoxygen(), Debug::clearFlag(), computeIdealCacheParam(), Config_getBool, Config_getEnum, Config_getInt, Config_getList, Config_getString, copyExtraFiles(), copyIcon(), copyLatexStyleSheet(), copyLogo(), copyStyleSheet(), createJavaScriptSearchIndex(), Dir::currentDirPath(), QCString::data(), Config::deinit(), dumpSymbolMap(), Debug::elapsedTime(), err, Htags::execute(), Dir::exists(), exitTracing(), FALSE, Doxygen::filterDBFileName, finalizeSearchIndexer(), finishWarnExit(), g_dumpSymbolMap, g_outputList, g_s, g_successfulRun, generateClassDocs(), generateConceptDocs(), generateDEF(), generateDirDocs(), generateExampleDocs(), generateFileDocs(), generateFileSources(), generateGroupDocs(), FormulaManager::generateImages(), generateNamespaceDocs(), generatePageDocs(), generatePerlMod(), generateSqlite3(), generateXML(), Doxygen::generatingXmlOutput, Portable::getSysElapsedTime(), FormulaManager::hasFormulas(), Doxygen::indexList, DocbookGenerator::init(), HtmlGenerator::init(), LatexGenerator::init(), ManGenerator::init(), RTFGenerator::init(), DotManager::instance(), FormulaManager::instance(), ModuleManager::instance(), PlantumlManager::instance(), SearchIndexIntf::Internal, Portable::isAbsolutePath(), QCString::isEmpty(), Debug::isFlagSet(), Htags::loadFilemap(), Dir::mkdir(), msg, FormulaManager::On, QCString::prepend(), RTFGenerator::preProcessFileInplace(), Dir::remove(), DotManager::run(), PlantumlManager::run(), runHtmlHelpCompiler(), runQHelpGenerator(), Doxygen::searchIndex, Debug::setFlag(), QCString::str(), Doxygen::symbolLookupCache, term, Debug::Time, TRUE, Doxygen::typeLookupCache, Htags::useHtags, FormulaManager::Vector, ModuleManager::writeDocumentation(), HtmlGenerator::writeExternalSearchPage(), writeGraphInfo(), writeIndexHierarchy(), writeJavaScriptSearchIndex(), HtmlGenerator::writeSearchData(), HtmlGenerator::writeSearchPage(), HtmlGenerator::writeTabData(), and writeTagFile().

Referenced by main().

◆ generatePageDocs()

void generatePageDocs ( )
static

Definition at line 9862 of file doxygen.cpp.

9863{
9864 //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageLinkedMap->count());
9865 if (Index::instance().numDocumentedPages()==0) return;
9866 for (const auto &pd : *Doxygen::pageLinkedMap)
9867 {
9868 if (!pd->getGroupDef() && !pd->isReference())
9869 {
9870 msg("Generating docs for page {}...\n",pd->name());
9871 pd->writeDocumentation(*g_outputList);
9872 }
9873 }
9874}

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

Referenced by generateOutput().

◆ generateXRefPages()

void generateXRefPages ( )
static

Definition at line 5511 of file doxygen.cpp.

5512{
5513 AUTO_TRACE();
5515 {
5516 rl->generatePage();
5517 }
5518}
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 11283 of file doxygen.cpp.

11284{
11285 char *s=nullptr;
11286 if (qstrlen(&argv[optInd][2])>0)
11287 s=&argv[optInd][2];
11288 else if (optInd+1<argc && argv[optInd+1][0]!='-')
11289 s=argv[++optInd];
11290 return s;
11291}
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 10574 of file doxygen.cpp.

10575{
10576 QCString fileName=fn;
10577 QCString extension;
10578 int sep = fileName.findRev('/');
10579 int ei = fileName.findRev('.');
10580 if (ei!=-1 && (sep==-1 || ei>sep)) // matches dir/file.ext but not dir.1/file
10581 {
10582 extension=fileName.right(fileName.length()-ei);
10583 }
10584 else
10585 {
10586 extension = ".no_extension";
10587 }
10588
10589 return Doxygen::parserManager->getOutlineParser(extension);
10590}

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

Referenced by parseFilesMultiThreading(), and parseFilesSingleThreading().

◆ getTemplateArgumentsFromName()

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

Definition at line 859 of file doxygen.cpp.

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

References ArgumentList::empty(), QCString::find(), getClass(), QCString::left(), Doxygen::namespaceLinkedMap, and ClassDef::templateArguments().

Referenced by addClassToContext(), addConceptToContext(), and addOverloaded().

◆ getTemplateArgumentsInName()

TemplateNameMap getTemplateArgumentsInName ( const ArgumentList & templateArguments,
const std::string & name )
static

make a dictionary of all template arguments of class cd that are part of the base class name. Example: A template class A with template arguments <R,S,T> that inherits from B<T,T,S> will have T and S in the dictionary.

Definition at line 4450 of file doxygen.cpp.

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

References end().

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

◆ haveEqualFileNames()

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

Definition at line 9448 of file doxygen.cpp.

9449{
9450 const FileDef *fd = md->getFileDef();
9451 if (!fd)
9452 {
9453 return FALSE;
9454 }
9455
9456 return fd->absFilePath() == root->fileName;
9457}

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

Referenced by findDefineDocumentation().

◆ inheritDocumentation()

void inheritDocumentation ( )
static

Definition at line 9140 of file doxygen.cpp.

9141{
9142 for (const auto &mn : *Doxygen::memberNameLinkedMap)
9143 {
9144 for (const auto &imd : *mn)
9145 {
9146 MemberDefMutable *md = toMemberDefMutable(imd.get());
9147 //static int count=0;
9148 //printf("%04d Member '%s'\n",count++,qPrint(md->qualifiedName()));
9149 if (md && md->documentation().isEmpty() && md->briefDescription().isEmpty())
9150 { // no documentation yet
9151 const MemberDef *bmd = md->reimplements();
9152 while (bmd && bmd->documentation().isEmpty() &&
9153 bmd->briefDescription().isEmpty()
9154 )
9155 { // search up the inheritance tree for a documentation member
9156 //printf("bmd=%s class=%s\n",qPrint(bmd->name()),qPrint(bmd->getClassDef()->name()));
9157 bmd = bmd->reimplements();
9158 }
9159 if (bmd) // copy the documentation from the reimplemented member
9160 {
9161 md->setInheritsDocsFrom(bmd);
9162 md->setDocumentation(bmd->documentation(),bmd->docFile(),bmd->docLine());
9164 md->setBriefDescription(bmd->briefDescription(),bmd->briefFile(),bmd->briefLine());
9165 md->copyArgumentNames(bmd);
9167 }
9168 }
9169 }
9170 }
9171}
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 11310 of file doxygen.cpp.

11311{
11312 initResources();
11313 QCString lang = Portable::getenv("LC_ALL");
11314 if (!lang.isEmpty()) Portable::setenv("LANG",lang);
11315 std::setlocale(LC_ALL,"");
11316 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
11317 std::setlocale(LC_NUMERIC,"C");
11318
11320
11344
11345 // register any additional parsers here...
11346
11348
11349#if USE_LIBCLANG
11351#endif
11360 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
11361 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
11362 //Doxygen::tagDestinationDict.setAutoDelete(TRUE);
11364
11365 // initialization of these globals depends on
11366 // configuration switches so we need to postpone these
11367 Doxygen::globalScope = nullptr;
11376
11377}
static void startTimer()
Definition debug.cpp:196
A linked map of directories.
Definition dirdef.h:173
A list of index interfaces.
Definition indexlist.h:64
Manages programming language parsers.
Definition parserintf.h:147
std::function< std::unique_ptr< T >() > make_parser_factory()
void initResources()
std::unordered_map< std::string, const Definition * > ClangUsrMap
Definition doxygen.h:83
void setenv(const QCString &variable, const QCString &value)
Definition portable.cpp:303
QCString getenv(const QCString &variable)
Definition portable.cpp:338
void initDefaultExtensionMapping()
Definition util.cpp:5645

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

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

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

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

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

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

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

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

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

Referenced by findClassRelation().

◆ isSpecialization()

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

Definition at line 5918 of file doxygen.cpp.

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

References FALSE, and TRUE.

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

◆ isSymbolHidden()

bool isSymbolHidden ( const Definition * d)
static

Definition at line 8887 of file doxygen.cpp.

8888{
8889 bool hidden = d->isHidden();
8890 const Definition *parent = d->getOuterScope();
8891 return parent ? hidden || isSymbolHidden(parent) : hidden;
8892}
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Definition docnode.h:1330

References Definition::getOuterScope(), Definition::isHidden(), isSymbolHidden(), and parent().

Referenced by computeTooltipTexts(), and isSymbolHidden().

◆ isVarWithConstructor()

bool isVarWithConstructor ( const Entry * root)
static

Returns TRUE iff type is a class within scope context. Used to detect variable declarations that look like function prototypes.

Definition at line 2887 of file doxygen.cpp.

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

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

11306{
11307 return []() { return std::make_unique<T>(); };
11308}

Referenced by initDoxygen().

◆ makeTemplateInstanceRelation()

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

Definition at line 5260 of file doxygen.cpp.

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

8450{
8451 AUTO_TRACE();
8452 // merge members of categories into the class they extend
8453 for (const auto &cd : *Doxygen::classLinkedMap)
8454 {
8455 int i=cd->name().find('(');
8456 if (i!=-1) // it is an Objective-C category
8457 {
8458 QCString baseName=cd->name().left(i);
8459 ClassDefMutable *baseClass=toClassDefMutable(Doxygen::classLinkedMap->find(baseName));
8460 if (baseClass)
8461 {
8462 AUTO_TRACE_ADD("merging members of category {} into {}",cd->name(),baseClass->name());
8463 baseClass->mergeCategory(cd.get());
8464 }
8465 }
8466 }
8467}
virtual void mergeCategory(ClassDef *category)=0

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

Referenced by parseInput().

◆ organizeSubGroups()

void organizeSubGroups ( const Entry * root)
static

Definition at line 484 of file doxygen.cpp.

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

References FALSE, organizeSubGroupsFiltered(), and TRUE.

Referenced by parseInput().

◆ organizeSubGroupsFiltered()

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

Definition at line 465 of file doxygen.cpp.

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

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

Referenced by organizeSubGroups(), and organizeSubGroupsFiltered().

◆ parseFile()

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

Definition at line 10592 of file doxygen.cpp.

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

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

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

10802{
10803 AUTO_TRACE();
10804#if USE_LIBCLANG
10806 {
10807 StringUnorderedSet processedFiles;
10808
10809 // create a dictionary with files to process
10810 StringUnorderedSet filesToProcess;
10811 for (const auto &s : g_inputFiles)
10812 {
10813 filesToProcess.insert(s);
10814 }
10815
10816 // process source files (and their include dependencies)
10817 for (const auto &s : g_inputFiles)
10818 {
10819 bool ambig = false;
10820 FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
10821 ASSERT(fd!=nullptr);
10822 if (fd->isSource() && !fd->isReference() && getLanguageFromFileName(s.c_str())==SrcLangExt::Cpp) // this is a source file
10823 {
10824 auto clangParser = ClangParser::instance()->createTUParser(fd);
10825 auto parser { getParserForFile(s.c_str()) };
10826 auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true);
10827 root->moveToSubEntryAndKeep(fileRoot);
10828 processedFiles.insert(s);
10829
10830 // Now process any include files in the same translation unit
10831 // first. When libclang is used this is much more efficient.
10832 for (auto incFile : clangParser->filesInSameTU())
10833 {
10834 //printf(" file %s\n",incFile.c_str());
10835 if (filesToProcess.find(incFile)!=filesToProcess.end() && // file need to be processed
10836 processedFiles.find(incFile)==processedFiles.end()) // and is not processed already
10837 {
10838 FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile.c_str(),ambig);
10839 if (ifd && !ifd->isReference())
10840 {
10841 //printf(" Processing %s in same translation unit as %s\n",incFile.c_str(),s.c_str());
10842 fileRoot = parseFile(*parser.get(),ifd,incFile.c_str(),clangParser.get(),false);
10843 root->moveToSubEntryAndKeep(fileRoot);
10844 processedFiles.insert(incFile);
10845 }
10846 }
10847 }
10848 }
10849 }
10850 // process remaining files
10851 for (const auto &s : g_inputFiles)
10852 {
10853 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
10854 {
10855 bool ambig = false;
10856 FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
10857 if (getLanguageFromFileName(s.c_str())==SrcLangExt::Cpp) // not yet processed
10858 {
10859 auto clangParser = ClangParser::instance()->createTUParser(fd);
10860 auto parser { getParserForFile(s.c_str()) };
10861 auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true);
10862 root->moveToSubEntryAndKeep(fileRoot);
10863 }
10864 else
10865 {
10866 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(s.c_str()) };
10867 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,s.c_str(),nullptr,true);
10868 root->moveToSubEntryAndKeep(fileRoot);
10869 }
10870 processedFiles.insert(s);
10871 }
10872 }
10873 }
10874 else // normal processing
10875#endif
10876 {
10877 for (const auto &s : g_inputFiles)
10878 {
10879 bool ambig = false;
10880 FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
10881 ASSERT(fd!=nullptr);
10882 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(s.c_str()) };
10883 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,s.c_str(),nullptr,true);
10884 root->moveToSubEntryAndKeep(std::move(fileRoot));
10885 }
10886 }
10887}

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

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

References Dir::absPath(), addEnumValuesToEnums(), addListReferences(), addMembersToIndex(), addMembersToMemberGroup(), addSourceReferences(), addSTLSupport(), addTerminalCharIfMissing(), addToIndices(), AUTO_TRACE, AUTO_TRACE_ADD, begin(), buildClassDocList(), buildClassList(), buildCompleteMemberLists(), buildConceptDocList(), buildConceptList(), buildDefineList(), buildDictionaryList(), buildDirectories(), buildExampleList(), buildFileList(), buildFunctionList(), buildGroupList(), buildInterfaceAndServiceList(), buildListOfUsingDecls(), buildNamespaceList(), buildPageList(), buildSequenceList(), buildTypedefList(), buildVarList(), checkMarkdownMainfile(), checkPageRelations(), FormulaManager::checkRepositories(), Doxygen::clangAssistedParsing, Doxygen::classLinkedMap, cleanUpDoxygen(), combineUsingRelations(), computeClassRelations(), computeDirDependencies(), computeMemberReferences(), computeMemberRelations(), computePageRelations(), computeTemplateClassRelations(), computeTooltipTexts(), computeVerifiedDotPath(), VhdlDocGen::computeVhdlComponentRelations(), Doxygen::conceptLinkedMap, Config_getBool, Config_getInt, Config_getList, Config_getString, Config_updateList, Config_updateString, Portable::correctPath(), Index::countDataStructures(), countMembers(), createOutputDirectory(), createTemplateInstanceMembers(), Dir::currentDirPath(), distributeConceptGroups(), distributeMemberGroupDocumentation(), end(), QCString::endsWith(), Dir::exists(), FileInfo::exists(), exitDoxygen(), FALSE, fileToString(), Doxygen::filterDBFileName, findClassEntries(), findDefineDocumentation(), findDirDocumentation(), findDocumentedEnumValues(), findEnumDocumentation(), findEnums(), findFriends(), findGroupScope(), findIncludedUsingDirectives(), findInheritedTemplateInstances(), findMainPage(), findMainPageTagFiles(), findMemberDocumentation(), findModuleDocumentation(), findObjCMethodDefinitions(), findSectionsInDocumentation(), findTagLessClasses(), findUsedTemplateInstances(), findUsingDeclarations(), findUsingDeclImports(), findUsingDirectives(), flushCachedTemplateRelations(), flushUnresolvedRelations(), Doxygen::functionNameLinkedMap, g_classEntries, g_commentFileName, g_s, g_singleComment, g_usingClassMap, g_usingDeclarations, generateDiskNames(), generateHtmlForComment(), CitationManager::generatePage(), generateXRefPages(), Portable::getenv(), getPrefixIndex(), Doxygen::groupLinkedMap, Doxygen::hiddenClassLinkedMap, Doxygen::indexList, inheritDocumentation(), LayoutDocManager::init(), FormulaManager::initFromRepository(), initSearchIndexer(), CitationManager::instance(), FormulaManager::instance(), Index::instance(), LayoutDocManager::instance(), ModuleManager::instance(), QCString::isEmpty(), FileInfo::isFile(), Doxygen::memberNameLinkedMap, mergeCategories(), Dir::mkdir(), msg, Doxygen::namespaceLinkedMap, organizeSubGroups(), LayoutDocManager::parse(), parseFilesMultiThreading(), parseFilesSingleThreading(), Portable::pathListSeparator(), Portable::pid(), printLayout(), printNavTree(), printSectionsTree(), qPrint(), qstricmp_sort(), readInputFile(), readTagFile(), resolveClassNestingRelations(), resolveUserReferences(), searchInputFiles(), setAnonymousEnumType(), Portable::setenv(), Dir::setPath(), sortMemberLists(), stopDoxygen(), QCString::str(), Doxygen::symbolLookupCache, term, transferFunctionDocumentation(), transferFunctionReferences(), transferRelatedFunctionDocumentation(), transferStaticInstanceInitializers(), TRUE, Doxygen::typeLookupCache, vhdlCorrectMemberProperties(), warn_uncond, and warnUndocumentedNamespaces().

Referenced by main().

◆ printNavTree()

void printNavTree ( Entry * root,
int indent )

Definition at line 9908 of file doxygen.cpp.

9909{
9911 {
9912 QCString indentStr;
9913 indentStr.fill(' ',indent);
9914 Debug::print(Debug::Entries,0,"{}{} at {}:{} (sec={}, spec={})\n",
9915 indentStr.isEmpty()?"":indentStr,
9916 root->name.isEmpty()?"<empty>":root->name,
9917 root->fileName,root->startLine,
9918 root->section.to_string(),
9919 root->spec.to_string());
9920 for (const auto &e : root->children())
9921 {
9922 printNavTree(e.get(),indent+2);
9923 }
9924 }
9925}
@ Entries
Definition debug.h:47
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
Definition debug.h:76
std::string to_string() const
Definition types.h:805
void fill(char c, int len=-1)
Fills a string with a predefined character.
Definition qcstring.h:180
std::string to_string() const
Definition types.h:682

References Entry::children(), Debug::Entries, Entry::fileName, QCString::fill(), QCString::isEmpty(), Debug::isFlagSet(), Entry::name, Debug::print(), printNavTree(), Entry::section, Entry::spec, Entry::startLine, EntryType::to_string(), and TypeSpecifier::to_string().

Referenced by parseInput(), and printNavTree().

◆ printSectionsTree()

void printSectionsTree ( )

Definition at line 9931 of file doxygen.cpp.

9932{
9934 {
9935 for (const auto &si : SectionManager::instance())
9936 {
9937 Debug::print(Debug::Sections,0,"Section = {}, file = {}, title = {}, type = {}, ref = {}\n",
9938 si->label(),si->fileName(),si->title(),si->type().level(),si->ref());
9939 }
9940 }
9941}
@ Sections
Definition debug.h:48

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

Referenced by parseInput().

◆ processTagLessClasses()

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

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

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

Definition at line 1565 of file doxygen.cpp.

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

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

Referenced by findTagLessClasses(), and processTagLessClasses().

◆ readConfiguration()

void readConfiguration ( int argc,
char ** argv )

Definition at line 11423 of file doxygen.cpp.

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

10975{
10976 std::string dirName = fi->absFilePath();
10977 if (paths && !dirName.empty())
10978 {
10979 paths->insert(dirName);
10980 }
10981 //printf("%s isSymLink()=%d\n",qPrint(dirName),fi->isSymLink());
10982 if (fi->isSymLink())
10983 {
10984 dirName = resolveSymlink(dirName);
10985 if (dirName.empty())
10986 {
10987 //printf("RECURSIVE SYMLINK: %s\n",qPrint(dirName));
10988 return; // recursive symlink
10989 }
10990 }
10991
10992 if (g_pathsVisited.find(dirName)!=g_pathsVisited.end())
10993 {
10994 //printf("PATH ALREADY VISITED: %s\n",qPrint(dirName));
10995 return; // already visited path
10996 }
10997 g_pathsVisited.insert(dirName);
10998
10999 Dir dir(dirName);
11000 msg("Searching for files in directory {}\n", fi->absFilePath());
11001 //printf("killSet=%p count=%d\n",killSet,killSet ? (int)killSet->count() : -1);
11002
11003 StringVector dirResultList;
11004
11005 for (const auto &dirEntry : dir.iterator())
11006 {
11007 FileInfo cfi(dirEntry.path());
11008 if (exclSet==nullptr || exclSet->find(cfi.absFilePath())==exclSet->end())
11009 { // file should not be excluded
11010 //printf("killSet->find(%s)\n",qPrint(cfi->absFilePath()));
11011 if (Config_getBool(EXCLUDE_SYMLINKS) && cfi.isSymLink())
11012 {
11013 }
11014 else if (!cfi.exists() || !cfi.isReadable())
11015 {
11016 if (errorIfNotExist)
11017 {
11018 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",cfi.absFilePath());
11019 }
11020 }
11021 else if (cfi.isFile() &&
11022 (patList==nullptr || patternMatch(cfi,*patList)) &&
11023 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
11024 (killSet==nullptr || killSet->find(cfi.absFilePath())==killSet->end())
11025 )
11026 {
11027 std::string name=cfi.fileName();
11028 std::string path=cfi.dirPath()+"/";
11029 std::string fullName=path+name;
11030 if (fnMap)
11031 {
11032 auto fd = createFileDef(QCString(path),QCString(name));
11033 FileName *fn=nullptr;
11034 if (!name.empty())
11035 {
11036 fn = fnMap->add(QCString(name),QCString(fullName));
11037 fn->push_back(std::move(fd));
11038 }
11039 }
11040 dirResultList.push_back(fullName);
11041 if (resultSet) resultSet->insert(fullName);
11042 if (killSet) killSet->insert(fullName);
11043 }
11044 else if (recursive &&
11045 cfi.isDir() &&
11046 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
11047 cfi.fileName().at(0)!='.') // skip "." ".." and ".dir"
11048 {
11049 FileInfo acfi(cfi.absFilePath());
11050 readDir(&acfi,fnMap,exclSet,
11051 patList,exclPatList,&dirResultList,resultSet,errorIfNotExist,
11052 recursive,killSet,paths);
11053 }
11054 }
11055 }
11056 if (resultList && !dirResultList.empty())
11057 {
11058 // sort the resulting list to make the order platform independent.
11059 std::stable_sort(dirResultList.begin(),
11060 dirResultList.end(),
11061 [](const auto &f1,const auto &f2) { return qstricmp_sort(f1.c_str(),f2.c_str())<0; });
11062
11063 // append the sorted results to resultList
11064 resultList->insert(resultList->end(), dirResultList.begin(), dirResultList.end());
11065 }
11066}
bool isSymLink() const
Definition fileinfo.cpp:77
Class representing all files with a certain base name.
Definition filename.h:30
static StringUnorderedSet g_pathsVisited(1009)
static std::string resolveSymlink(const std::string &path)
static void readDir(FileInfo *fi, FileNameLinkedMap *fnMap, StringUnorderedSet *exclSet, const StringVector *patList, const StringVector *exclPatList, StringVector *resultList, StringUnorderedSet *resultSet, bool errorIfNotExist, bool recursive, StringUnorderedSet *killSet, StringUnorderedSet *paths)
std::unique_ptr< FileDef > createFileDef(const QCString &p, const QCString &n, const QCString &ref, const QCString &dn)
Definition filedef.cpp:268
bool patternMatch(const FileInfo &fi, const StringVector &patList)
Definition util.cpp:6201

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

11085{
11086 //printf("killSet count=%d\n",killSet ? (int)killSet->size() : -1);
11087 // strip trailing slashes
11088 if (s.isEmpty()) return;
11089
11090 g_pathsVisited.clear();
11091
11092 FileInfo fi(s.str());
11093 //printf("readFileOrDirectory(%s)\n",s);
11094 {
11095 if (exclSet==nullptr || exclSet->find(fi.absFilePath())==exclSet->end())
11096 {
11097 if (Config_getBool(EXCLUDE_SYMLINKS) && fi.isSymLink())
11098 {
11099 }
11100 else if (!fi.exists() || !fi.isReadable())
11101 {
11102 if (errorIfNotExist)
11103 {
11104 warn_uncond("source '{}' is not a readable file or directory... skipping.\n",s);
11105 }
11106 }
11107 else if (fi.isFile())
11108 {
11109 std::string dirPath = fi.dirPath(true);
11110 std::string filePath = fi.absFilePath();
11111 if (paths && !dirPath.empty())
11112 {
11113 paths->insert(dirPath);
11114 }
11115 //printf("killSet.find(%s)=%d\n",qPrint(fi.absFilePath()),killSet.find(fi.absFilePath())!=killSet.end());
11116 if (killSet==nullptr || killSet->find(filePath)==killSet->end())
11117 {
11118 std::string name=fi.fileName();
11119 if (fnMap)
11120 {
11121 auto fd = createFileDef(QCString(dirPath+"/"),QCString(name));
11122 if (!name.empty())
11123 {
11124 FileName *fn = fnMap->add(QCString(name),QCString(filePath));
11125 fn->push_back(std::move(fd));
11126 }
11127 }
11128 if (resultList || resultSet)
11129 {
11130 if (resultList) resultList->push_back(filePath);
11131 if (resultSet) resultSet->insert(filePath);
11132 }
11133
11134 if (killSet) killSet->insert(fi.absFilePath());
11135 }
11136 }
11137 else if (fi.isDir()) // readable dir
11138 {
11139 readDir(&fi,fnMap,exclSet,patList,
11140 exclPatList,resultList,resultSet,errorIfNotExist,
11141 recursive,killSet,paths);
11142 }
11143 }
11144 }
11145}

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

10295{
10296 QCString fileName;
10297 QCString destName;
10298 int eqPos = tagLine.find('=');
10299 if (eqPos!=-1) // tag command contains a destination
10300 {
10301 fileName = tagLine.left(eqPos).stripWhiteSpace();
10302 destName = tagLine.right(tagLine.length()-eqPos-1).stripWhiteSpace();
10303 if (fileName.isEmpty() || destName.isEmpty()) return;
10304 //printf("insert tagDestination %s->%s\n",qPrint(fi.fileName()),qPrint(destName));
10305 }
10306 else
10307 {
10308 fileName = tagLine;
10309 }
10310
10311 FileInfo fi(fileName.str());
10312 if (!fi.exists() || !fi.isFile())
10313 {
10314 err("Tag file '{}' does not exist or is not a file. Skipping it...\n",fileName);
10315 return;
10316 }
10317
10318 if (Doxygen::tagFileSet.find(fi.absFilePath().c_str()) != Doxygen::tagFileSet.end()) return;
10319
10320 Doxygen::tagFileSet.emplace(fi.absFilePath());
10321
10322 if (!destName.isEmpty())
10323 {
10324 Doxygen::tagDestinationMap.emplace(fi.absFilePath(), destName.str());
10325 msg("Reading tag file '{}', location '{}'...\n",fileName,destName);
10326 }
10327 else
10328 {
10329 msg("Reading tag file '{}'...\n",fileName);
10330 }
10331
10332 parseTagFile(root,fi.absFilePath().c_str());
10333}
static StringUnorderedSet tagFileSet
Definition doxygen.h:117
void parseTagFile(const std::shared_ptr< Entry > &root, const char *fullName)

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

Referenced by parseInput().

◆ resolveClassNestingRelations()

void resolveClassNestingRelations ( )
static

create the scope artificially

Definition at line 1331 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ resolveSymlink()

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

Definition at line 10891 of file doxygen.cpp.

10892{
10893 int sepPos=0;
10894 int oldPos=0;
10895 StringUnorderedSet nonSymlinks;
10896 StringUnorderedSet known;
10897 QCString result(path);
10898 QCString oldPrefix = "/";
10899 do
10900 {
10901#if defined(_WIN32)
10902 // UNC path, skip server and share name
10903 if (sepPos==0 && (result.startsWith("//") || result.startsWith("\\\\")))
10904 sepPos = result.find('/',2);
10905 if (sepPos!=-1)
10906 sepPos = result.find('/',sepPos+1);
10907#else
10908 sepPos = result.find('/',sepPos+1);
10909#endif
10910 QCString prefix = sepPos==-1 ? result : result.left(sepPos);
10911 if (nonSymlinks.find(prefix.str())==nonSymlinks.end())
10912 {
10913 FileInfo fi(prefix.str());
10914 if (fi.isSymLink())
10915 {
10916 QCString target = fi.readLink();
10917 bool isRelative = FileInfo(target.str()).isRelative();
10918 if (isRelative)
10919 {
10920 target = Dir::cleanDirPath(oldPrefix.str()+"/"+target.str());
10921 }
10922 if (sepPos!=-1)
10923 {
10924 if (fi.isDir() && target.length()>0 && target.at(target.length()-1)!='/')
10925 {
10926 target+='/';
10927 }
10928 target+=result.mid(sepPos);
10929 }
10930 result = Dir::cleanDirPath(target.str());
10931 if (known.find(result.str())!=known.end()) return std::string(); // recursive symlink!
10932 known.insert(result.str());
10933 if (isRelative)
10934 {
10935 sepPos = oldPos;
10936 }
10937 else // link to absolute path
10938 {
10939 sepPos = 0;
10940 oldPrefix = "/";
10941 }
10942 }
10943 else
10944 {
10945 nonSymlinks.insert(prefix.str());
10946 oldPrefix = prefix;
10947 }
10948 oldPos = sepPos;
10949 }
10950 }
10951 while (sepPos!=-1);
10952 return Dir::cleanDirPath(result.str());
10953}
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 4773 of file doxygen.cpp.

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

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

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

10122{
10123 std::string oldDir = Dir::currentDirPath();
10124 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10127 {
10128 err("failed to run html help compiler on {}\n", HtmlHelp::hhpFileName);
10129 }
10130 Dir::setCurrent(oldDir);
10131}
@ 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:570

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

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

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

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

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

Referenced by addMemberFunction(), and scopeIsTemplate().

◆ searchInputFiles()

void searchInputFiles ( )

Definition at line 12122 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ setAnonymousEnumType()

void setAnonymousEnumType ( )
static

Definition at line 8940 of file doxygen.cpp.

8941{
8942 for (const auto &cd : *Doxygen::classLinkedMap)
8943 {
8944 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8945 if (cdm)
8946 {
8947 cdm->setAnonymousEnumType();
8948 }
8949 }
8950}
virtual void setAnonymousEnumType()=0

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

Referenced by parseInput().

◆ sortMemberLists()

void sortMemberLists ( )
static

Definition at line 8845 of file doxygen.cpp.

8846{
8847 // sort class member lists
8848 for (const auto &cd : *Doxygen::classLinkedMap)
8849 {
8850 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8851 if (cdm)
8852 {
8853 cdm->sortMemberLists();
8854 }
8855 }
8856
8857 // sort namespace member lists
8858 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8859 {
8861 if (ndm)
8862 {
8863 ndm->sortMemberLists();
8864 }
8865 }
8866
8867 // sort file member lists
8868 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8869 {
8870 for (const auto &fd : *fn)
8871 {
8872 fd->sortMemberLists();
8873 }
8874 }
8875
8876 // sort group member lists
8877 for (const auto &gd : *Doxygen::groupLinkedMap)
8878 {
8879 gd->sortMemberLists();
8880 }
8881
8883}
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 11991 of file doxygen.cpp.

11992{
11993 signal(SIGINT,SIG_DFL); // Re-register signal handler for default action
11994 Dir thisDir;
11995 msg("Cleaning up...\n");
11996 if (!Doxygen::filterDBFileName.isEmpty())
11997 {
11998 thisDir.remove(Doxygen::filterDBFileName.str());
11999 }
12000 killpg(0,SIGINT);
12002 exitTracing();
12003 exit(1);
12004}

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

Referenced by parseInput().

◆ stripTemplateSpecifiers()

QCString stripTemplateSpecifiers ( const QCString & s)

Definition at line 678 of file doxygen.cpp.

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

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

Referenced by buildScopeFromQualifiedName().

◆ substituteTemplatesInArgList()

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

Definition at line 6032 of file doxygen.cpp.

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

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

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

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

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

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

Referenced by parseInput().

◆ transferRelatedFunctionDocumentation()

void transferRelatedFunctionDocumentation ( )
static

Definition at line 4364 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ transferStaticInstanceInitializers()

void transferStaticInstanceInitializers ( )

Definition at line 4413 of file doxygen.cpp.

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

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

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

11239{
11241 msg("Doxygen version {0}\nCopyright Dimitri van Heesch 1997-2025\n\n"
11242 "You can use Doxygen in a number of ways:\n\n"
11243 "1) Use Doxygen to generate a template configuration file*:\n"
11244 " {1} [-s] -g [configName]\n\n"
11245 "2) Use Doxygen to update an old configuration file*:\n"
11246 " {1} [-s] -u [configName]\n\n"
11247 "3) Use Doxygen to generate documentation using an existing "
11248 "configuration file*:\n"
11249 " {1} [configName]\n\n"
11250 "4) Use Doxygen to generate a template file controlling the layout of the\n"
11251 " generated documentation:\n"
11252 " {1} -l [layoutFileName]\n\n"
11253 " In case layoutFileName is omitted DoxygenLayout.xml will be used as filename.\n"
11254 " If - is used for layoutFileName Doxygen will write to standard output.\n\n"
11255 "5) Use Doxygen to generate a template style sheet file for RTF, HTML or Latex.\n"
11256 " RTF: {1} -w rtf styleSheetFile\n"
11257 " HTML: {1}-w html headerFile footerFile styleSheetFile [configFile]\n"
11258 " LaTeX: {1} -w latex headerFile footerFile styleSheetFile [configFile]\n\n"
11259 "6) Use Doxygen to generate a rtf extensions file\n"
11260 " {1} -e rtf extensionsFile\n\n"
11261 " If - is used for extensionsFile Doxygen will write to standard output.\n\n"
11262 "7) Use Doxygen to compare the used configuration file with the template configuration file\n"
11263 " {1} -x [configFile]\n\n"
11264 " Use Doxygen to compare the used configuration file with the template configuration file\n"
11265 " without replacing the environment variables or CMake type replacement variables\n"
11266 " {1} -x_noenv [configFile]\n\n"
11267 "8) Use Doxygen to show a list of built-in emojis.\n"
11268 " {1} -f emoji outputFileName\n\n"
11269 " If - is used for outputFileName Doxygen will write to standard output.\n\n"
11270 "*) If -s is specified the comments of the configuration items in the config file will be omitted.\n"
11271 " If configName is omitted 'Doxyfile' will be used as a default.\n"
11272 " If - is used for configFile Doxygen will write / read the configuration to /from standard output / input.\n\n"
11273 "If -q is used for a Doxygen documentation run, Doxygen will see this as if QUIET=YES has been set.\n\n"
11274 "-v print version string, -V print extended version information\n"
11275 "-h,-? prints usage help information\n"
11276 "{1} -d prints additional usage flags for debugging purposes\n",versionString,name);
11277}

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

Referenced by readConfiguration().

◆ version()

void version ( const bool extended)
static

Definition at line 11210 of file doxygen.cpp.

11211{
11213 QCString versionString = getFullVersion();
11214 msg("{}\n",versionString);
11215 if (extended)
11216 {
11217 QCString extVers;
11218 if (!extVers.isEmpty()) extVers+= ", ";
11219 extVers += "sqlite3 ";
11220 extVers += sqlite3_libversion();
11221#if USE_LIBCLANG
11222 if (!extVers.isEmpty()) extVers+= ", ";
11223 extVers += "clang support ";
11224 extVers += CLANG_VERSION_STRING;
11225#endif
11226 if (!extVers.isEmpty())
11227 {
11228 int lastComma = extVers.findRev(',');
11229 if (lastComma != -1) extVers = extVers.replace(lastComma,1," and");
11230 msg(" with {}.\n",extVers);
11231 }
11232 }
11233}
QCString & replace(size_t index, size_t len, const char *s)
Definition qcstring.cpp:212

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

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

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

Referenced by parseInput().

◆ warnUndocumentedNamespaces()

void warnUndocumentedNamespaces ( )
static

Definition at line 5294 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ writeTagFile()

void writeTagFile ( )
static

Definition at line 12007 of file doxygen.cpp.

12008{
12009 QCString generateTagFile = Config_getString(GENERATE_TAGFILE);
12010 if (generateTagFile.isEmpty()) return;
12011
12012 std::ofstream f = Portable::openOutputStream(generateTagFile);
12013 if (!f.is_open())
12014 {
12015 err("cannot open tag file {} for writing\n", generateTagFile);
12016 return;
12017 }
12018 TextStream tagFile(&f);
12019 tagFile << "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>\n";
12020 tagFile << "<tagfile doxygen_version=\"" << getDoxygenVersion() << "\"";
12021 std::string gitVersion = getGitVersion();
12022 if (!gitVersion.empty())
12023 {
12024 tagFile << " doxygen_gitid=\"" << gitVersion << "\"";
12025 }
12026 tagFile << ">\n";
12027
12028 // for each file
12029 for (const auto &fn : *Doxygen::inputNameLinkedMap)
12030 {
12031 for (const auto &fd : *fn)
12032 {
12033 if (fd->isLinkableInProject()) fd->writeTagFile(tagFile);
12034 }
12035 }
12036 // for each class
12037 for (const auto &cd : *Doxygen::classLinkedMap)
12038 {
12039 ClassDefMutable *cdm = toClassDefMutable(cd.get());
12040 if (cdm && cdm->isLinkableInProject())
12041 {
12042 cdm->writeTagFile(tagFile);
12043 }
12044 }
12045 // for each concept
12046 for (const auto &cd : *Doxygen::conceptLinkedMap)
12047 {
12048 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
12049 if (cdm && cdm->isLinkableInProject())
12050 {
12051 cdm->writeTagFile(tagFile);
12052 }
12053 }
12054 // for each namespace
12055 for (const auto &nd : *Doxygen::namespaceLinkedMap)
12056 {
12058 if (ndm && nd->isLinkableInProject())
12059 {
12060 ndm->writeTagFile(tagFile);
12061 }
12062 }
12063 // for each group
12064 for (const auto &gd : *Doxygen::groupLinkedMap)
12065 {
12066 if (gd->isLinkableInProject()) gd->writeTagFile(tagFile);
12067 }
12068 // for each module
12069 for (const auto &mod : ModuleManager::instance().modules())
12070 {
12071 if (mod->isLinkableInProject()) mod->writeTagFile(tagFile);
12072 }
12073 // for each page
12074 for (const auto &pd : *Doxygen::pageLinkedMap)
12075 {
12076 if (pd->isLinkableInProject()) pd->writeTagFile(tagFile);
12077 }
12078 // for each directory
12079 for (const auto &dd : *Doxygen::dirLinkedMap)
12080 {
12081 if (dd->isLinkableInProject()) dd->writeTagFile(tagFile);
12082 }
12083 if (Doxygen::mainPage) Doxygen::mainPage->writeTagFile(tagFile);
12084
12085 tagFile << "</tagfile>\n";
12086}
virtual void writeTagFile(TextStream &) const =0
virtual void writeTagFile(TextStream &)=0
virtual void writeTagFile(TextStream &)=0

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

Referenced by generateOutput().

Variable Documentation

◆ g_classEntries

◆ g_commentFileName

QCString g_commentFileName
static

Definition at line 192 of file doxygen.cpp.

Referenced by parseInput(), and readConfiguration().

◆ g_compoundKeywords

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

Definition at line 198 of file doxygen.cpp.

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

Referenced by buildVarList(), and filterMemberDocumentation().

◆ g_dumpSymbolMap

bool g_dumpSymbolMap = FALSE
static

Definition at line 191 of file doxygen.cpp.

Referenced by generateOutput(), and readConfiguration().

◆ g_inputFiles

◆ g_outputList

◆ g_s

◆ g_singleComment

bool g_singleComment =false
static

Definition at line 193 of file doxygen.cpp.

Referenced by parseInput(), and readConfiguration().

◆ g_successfulRun

bool g_successfulRun = FALSE
static

Definition at line 190 of file doxygen.cpp.

Referenced by exitDoxygen(), and generateOutput().

◆ g_usingClassMap

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

Definition at line 2156 of file doxygen.cpp.

Referenced by findUsingDeclImports(), and parseInput().

◆ g_usingDeclarations

StringSet g_usingDeclarations
static

Definition at line 189 of file doxygen.cpp.

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