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

9094{
9095 list.push_back(cd);
9096 for (const auto &innerCdi : cd->getClasses())
9097 {
9098 ClassDefMutable *innerCd = toClassDefMutable(innerCdi);
9099 if (innerCd)
9100 {
9101 AUTO_TRACE("innerCd={} isLinkable={} isImplicitTemplateInstance={} protectLevelVisible={} embeddedInOuterScope={}",
9102 innerCd->name(),innerCd->isLinkableInProject(),innerCd->isImplicitTemplateInstance(),protectionLevelVisible(innerCd->protection()),
9103 innerCd->isEmbeddedInOuterScope());
9104 }
9105 if (innerCd && innerCd->isLinkableInProject() && !innerCd->isImplicitTemplateInstance() &&
9106 protectionLevelVisible(innerCd->protection()) &&
9107 !innerCd->isEmbeddedInOuterScope()
9108 )
9109 {
9110 list.push_back(innerCd);
9111 addClassAndNestedClasses(list,innerCd);
9112 }
9113 }
9114}
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:9093
bool protectionLevelVisible(Protection prot)
Definition util.cpp:5876

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

Referenced by addClassAndNestedClasses(), and generateClassDocs().

◆ addClassToContext()

void addClassToContext ( const Entry * root)
static

Definition at line 931 of file doxygen.cpp.

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

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

Referenced by buildClassDocList(), and buildClassList().

◆ addConceptToContext()

void addConceptToContext ( const Entry * root)
static

Definition at line 1152 of file doxygen.cpp.

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

9483{
9484 md->setDocumentation(root->doc,root->docFile,root->docLine);
9485 md->setDocsForDefinition(!root->proto);
9486 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9487 if (md->inbodyDocumentation().isEmpty())
9488 {
9490 }
9491 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
9492 {
9493 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
9494 md->setBodyDef(root->fileDef());
9495 }
9497 md->setMaxInitLines(root->initLines);
9499 md->setRefItems(root->sli);
9500 md->addQualifiers(root->qualifiers);
9501 if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
9502 addMemberToGroups(root,md);
9504}
virtual int getStartBodyLine() const =0
virtual QCString inbodyDocumentation() const =0
virtual void setInbodyDocumentation(const QCString &d, const QCString &docFile, int docLine)=0
bool proto
prototype ?
Definition entry.h:187
QCString inbodyDocs
documentation inside the body of a function
Definition entry.h:206
int inbodyLine
line number at which the body doc was found
Definition entry.h:207
int initLines
define/variable initializer lines to show
Definition entry.h:184
QCString inbodyFile
file in which the body doc was found
Definition entry.h:208
virtual void setMemberGroupId(int id)=0
virtual void setMaxInitLines(int lines)=0
virtual void setDocsForDefinition(bool b)=0
virtual void addQualifiers(const StringVector &qualifiers)=0
void addMemberToModule(const Entry *root, MemberDef *md)
static void applyMemberOverrideOptions(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:2098
void addMemberToGroups(const Entry *root, MemberDef *md)

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

Referenced by findDefineDocumentation().

◆ addEnumDocs()

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

Definition at line 7912 of file doxygen.cpp.

7913{
7914 AUTO_TRACE();
7915 // documentation outside a compound overrides the documentation inside it
7916 {
7917 md->setDocumentation(root->doc,root->docFile,root->docLine);
7918 md->setDocsForDefinition(!root->proto);
7919 }
7920
7921 // brief descriptions inside a compound override the documentation
7922 // outside it
7923 {
7924 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7925 }
7926
7927 if (md->inbodyDocumentation().isEmpty() || !root->parent()->name.isEmpty())
7928 {
7930 }
7931
7932 if (root->mGrpId!=-1 && md->getMemberGroupId()==-1)
7933 {
7934 md->setMemberGroupId(root->mGrpId);
7935 }
7936
7938 md->setRefItems(root->sli);
7939
7940 const GroupDef *gd=md->getGroupDef();
7941 if (gd==nullptr && !root->groups.empty()) // member not grouped but out-of-line documentation is
7942 {
7943 addMemberToGroups(root,md);
7944 }
7946}
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 7663 of file doxygen.cpp.

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

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addEnumValuesToEnums(), AUTO_TRACE, AUTO_TRACE_ADD, buildScopeFromQualifiedName(), Entry::children(), createMemberDef(), EnumValue, Entry::fileDef(), LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::findRev(), Doxygen::functionNameLinkedMap, MemberDef::getClassDef(), getClassMutable(), MemberDef::getFileDef(), MemberDef::getNamespaceDef(), Definition::getOuterScope(), getResolvedNamespaceMutable(), MemberDefMutable::insertEnumField(), ClassDefMutable::insertMember(), Definition::isAnonymous(), QCString::isEmpty(), MemberDef::isEnumerate(), MemberDef::isEnumValue(), Definition::isLinkable(), EntryType::isScope(), MemberDef::isStrongEnumValue(), Entry::lang, QCString::left(), QCString::length(), MemberDefMutable::makeRelated(), mangleCSharpGenericName(), Doxygen::memberNameLinkedMap, mergeScopes(), QCString::mid(), Definition::name(), Entry::name, Entry::parent(), MemberName::push_back(), Definition::qualifiedName(), Entry::relates, QCString::right(), Entry::section, MemberDefMutable::setEnumClassScope(), MemberDefMutable::setEnumScope(), DefinitionMutable::setOuterScope(), Entry::spec, substitute(), Entry::tagInfo(), toMemberDefMutable(), toNamespaceDefMutable(), and TRUE.

Referenced by addEnumValuesToEnums(), and parseInput().

◆ addGlobalFunction()

void addGlobalFunction ( const Entry * root,
const QCString & rname,
const QCString & sc )
static

Definition at line 3770 of file doxygen.cpp.

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

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

Referenced by buildFunctionList().

◆ addIncludeFile()

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

Definition at line 581 of file doxygen.cpp.

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

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

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

5438{
5439 AUTO_TRACE();
5440 for (const auto &cd : *Doxygen::classLinkedMap)
5441 {
5442 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5443 if (cdm)
5444 {
5445 cdm->addListReferences();
5446 }
5447 }
5448
5449 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5450 {
5451 for (const auto &fd : *fn)
5452 {
5453 fd->addListReferences();
5454 }
5455 }
5456
5457 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5458 {
5460 if (ndm)
5461 {
5462 ndm->addListReferences();
5463 }
5464 }
5465
5466 for (const auto &gd : *Doxygen::groupLinkedMap)
5467 {
5468 gd->addListReferences();
5469 }
5470
5471 for (const auto &pd : *Doxygen::pageLinkedMap)
5472 {
5473 QCString name = pd->getOutputFileBase();
5474 if (pd->getGroupDef())
5475 {
5476 name = pd->getGroupDef()->getOutputFileBase();
5477 }
5478 {
5479 const RefItemVector &xrefItems = pd->xrefListItems();
5480 addRefItem(xrefItems,
5481 name,
5482 theTranslator->trPage(TRUE,TRUE),
5483 name,pd->title(),QCString(),nullptr);
5484 }
5485 }
5486
5487 for (const auto &dd : *Doxygen::dirLinkedMap)
5488 {
5489 QCString name = dd->getOutputFileBase();
5490 //if (dd->getGroupDef())
5491 //{
5492 // name = dd->getGroupDef()->getOutputFileBase();
5493 //}
5494 const RefItemVector &xrefItems = dd->xrefListItems();
5495 addRefItem(xrefItems,
5496 name,
5497 theTranslator->trDir(TRUE,TRUE),
5498 name,dd->displayName(),QCString(),nullptr);
5499 }
5500
5502}
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:4753

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

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

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

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

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

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

◆ addMemberFunction()

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

Definition at line 6127 of file doxygen.cpp.

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

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

Referenced by findMember().

◆ addMemberSpecialization()

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

Definition at line 6483 of file doxygen.cpp.

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

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

8107{
8108 auto &index = Index::instance();
8109 // for each class member name
8110 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8111 {
8112 // for each member definition
8113 for (const auto &md : *mn)
8114 {
8115 index.addClassMemberNameToIndex(md.get());
8116 if (md->getModuleDef())
8117 {
8118 index.addModuleMemberNameToIndex(md.get());
8119 }
8120 }
8121 }
8122 // for each file/namespace function name
8123 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8124 {
8125 // for each member definition
8126 for (const auto &md : *mn)
8127 {
8128 if (md->getNamespaceDef())
8129 {
8130 index.addNamespaceMemberNameToIndex(md.get());
8131 }
8132 else
8133 {
8134 index.addFileMemberNameToIndex(md.get());
8135 }
8136 if (md->getModuleDef())
8137 {
8138 index.addModuleMemberNameToIndex(md.get());
8139 }
8140 }
8141 }
8142
8143 index.sortMemberIndexLists();
8144}
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 9223 of file doxygen.cpp.

9224{
9225 // for each class
9226 for (const auto &cd : *Doxygen::classLinkedMap)
9227 {
9228 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9229 if (cdm)
9230 {
9232 }
9233 }
9234 // for each file
9235 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9236 {
9237 for (const auto &fd : *fn)
9238 {
9239 fd->addMembersToMemberGroup();
9240 }
9241 }
9242 // for each namespace
9243 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9244 {
9246 if (ndm)
9247 {
9249 }
9250 }
9251 // for each group
9252 for (const auto &gd : *Doxygen::groupLinkedMap)
9253 {
9254 gd->addMembersToMemberGroup();
9255 }
9257}
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 3635 of file doxygen.cpp.

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

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

Referenced by addMemberFunction(), and buildFunctionList().

◆ addOverloaded()

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

Definition at line 6545 of file doxygen.cpp.

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

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

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

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

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

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

2437{
2439 QCString scopeSeparator="::";
2440 SrcLangExt lang = cd->getLanguage();
2441 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
2442 {
2443 qualScope = substitute(qualScope,"::",".");
2444 scopeSeparator=".";
2445 }
2446 AUTO_TRACE("class variable: file='{}' type='{}' scope='{}' name='{}' args='{}' prot={} mtype={} lang={} ann={} init='{}'",
2447 root->fileName, type, qualScope, name, args, root->protection, mtype, lang, fromAnnScope, root->initializer.str());
2448
2449 QCString def;
2450 if (!type.isEmpty())
2451 {
2452 if (related!=Relationship::Member || mtype==MemberType::Friend || Config_getBool(HIDE_SCOPE_NAMES))
2453 {
2454 if (root->spec.isAlias()) // turn 'typedef B A' into 'using A'
2455 {
2456 def="using "+name;
2457 }
2458 else
2459 {
2460 def=type+" "+name+args;
2461 }
2462 }
2463 else
2464 {
2465 if (root->spec.isAlias()) // turn 'typedef B C::A' into 'using C::A'
2466 {
2467 def="using "+qualScope+scopeSeparator+name;
2468 }
2469 else
2470 {
2471 def=type+" "+qualScope+scopeSeparator+name+args;
2472 }
2473 }
2474 }
2475 else
2476 {
2477 if (Config_getBool(HIDE_SCOPE_NAMES))
2478 {
2479 def=name+args;
2480 }
2481 else
2482 {
2483 def=qualScope+scopeSeparator+name+args;
2484 }
2485 }
2486 def.stripPrefix("static ");
2487
2488 // see if the member is already found in the same scope
2489 // (this may be the case for a static member that is initialized
2490 // outside the class)
2492 if (mn)
2493 {
2494 for (const auto &imd : *mn)
2495 {
2496 //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n",
2497 // md->getClassDef(),cd,qPrint(type),md->typeString());
2498 MemberDefMutable *md = toMemberDefMutable(imd.get());
2499 if (md &&
2500 md->getClassDef()==cd &&
2501 ((lang==SrcLangExt::Python && type.isEmpty() && !md->typeString().isEmpty()) ||
2503 // member already in the scope
2504 {
2505
2506 if (root->lang==SrcLangExt::ObjC &&
2507 root->mtype==MethodTypes::Property &&
2509 { // Objective-C 2.0 property
2510 // turn variable into a property
2511 md->setProtection(root->protection);
2513 }
2514 addMemberDocs(root,md,def,nullptr,FALSE,root->spec);
2515 AUTO_TRACE_ADD("Member already found!");
2516 return md;
2517 }
2518 }
2519 }
2520
2521 QCString fileName = root->fileName;
2522 if (fileName.isEmpty() && root->tagInfo())
2523 {
2524 fileName = root->tagInfo()->tagName;
2525 }
2526
2527 // new member variable, typedef or enum value
2528 auto md = createMemberDef(
2529 fileName,root->startLine,root->startColumn,
2530 type,name,args,root->exception,
2531 prot,Specifier::Normal,root->isStatic,related,
2532 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
2533 ArgumentList(), root->metaData);
2534 auto mmd = toMemberDefMutable(md.get());
2535 mmd->setTagInfo(root->tagInfo());
2536 mmd->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope())
2537 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
2538 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2539 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2540 mmd->setDefinition(def);
2541 mmd->setBitfields(root->bitfields);
2542 mmd->addSectionsToDefinition(root->anchors);
2543 mmd->setFromAnonymousScope(fromAnnScope);
2544 mmd->setFromAnonymousMember(fromAnnMemb);
2545 //md->setIndentDepth(indentDepth);
2546 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2547 mmd->setInitializer(root->initializer.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:4768

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 const 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 mmd->setInitializer(root->initializer.str());
2773 mmd->setMaxInitLines(root->initLines);
2774 mmd->setMemberGroupId(root->mGrpId);
2775 mmd->setDefinition(def);
2776 mmd->setLanguage(root->lang);
2777 mmd->setId(root->id);
2779 mmd->setExplicitExternal(root->explicitExternal,fileName,root->startLine,root->startColumn);
2780 mmd->addQualifiers(root->qualifiers);
2781 //md->setOuterScope(fd);
2782 if (!root->explicitExternal)
2783 {
2784 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2785 mmd->setBodyDef(fd);
2786 }
2787 addMemberToGroups(root,md.get());
2789
2790 mmd->setRefItems(root->sli);
2791 if (nd && !nd->isAnonymous())
2792 {
2793 mmd->setNamespace(nd);
2794 nd->insertMember(md.get());
2795 }
2796
2797 // add member to the file (we do this even if we have already inserted
2798 // it into the namespace.
2799 if (fd)
2800 {
2801 mmd->setFileDef(fd);
2802 fd->insertMember(md.get());
2803 }
2804
2805 root->markAsProcessed();
2806
2807 if (mtype==MemberType::Typedef)
2808 {
2809 resolveTemplateInstanceInType(root,nd,md.get());
2810 }
2811
2812 // add member definition to the list of globals
2813 MemberDef *result = md.get();
2814 mn = Doxygen::functionNameLinkedMap->add(name);
2815 mn->push_back(std::move(md));
2816
2817
2818
2819 return result;
2820}
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 11894 of file doxygen.cpp.

11895{
11896 AUTO_TRACE();
11897 Doxygen::globalNamespaceDef = createNamespaceDef("<globalScope>",1,1,"<globalScope>");
11907
11908 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11909
11910 /* Set the global html file extension. */
11911 Doxygen::htmlFileExtension = Config_getString(HTML_FILE_EXTENSION);
11912
11913
11915 Config_getBool(CALLER_GRAPH) ||
11916 Config_getBool(REFERENCES_RELATION) ||
11917 Config_getBool(REFERENCED_BY_RELATION);
11918
11919 /**************************************************************************
11920 * Add custom extension mappings
11921 **************************************************************************/
11922
11923 const StringVector &extMaps = Config_getList(EXTENSION_MAPPING);
11924 for (const auto &mapping : extMaps)
11925 {
11926 QCString mapStr = mapping;
11927 int i=mapStr.find('=');
11928 if (i==-1)
11929 {
11930 continue;
11931 }
11932 else
11933 {
11934 QCString ext = mapStr.left(i).stripWhiteSpace().lower();
11935 QCString language = mapStr.mid(i+1).stripWhiteSpace().lower();
11936 if (ext.isEmpty() || language.isEmpty())
11937 {
11938 continue;
11939 }
11940
11941 if (!updateLanguageMapping(ext,language))
11942 {
11943 err("Failed to map file extension '{}' to unsupported language '{}'.\n"
11944 "Check the EXTENSION_MAPPING setting in the config file.\n",
11945 ext,language);
11946 }
11947 else
11948 {
11949 msg("Adding custom extension mapping: '{}' will be treated as language '{}'\n",
11950 ext,language);
11951 }
11952 }
11953 }
11954 // create input file exncodings
11955
11956 // check INPUT_ENCODING
11957 void *cd = portable_iconv_open("UTF-8",Config_getString(INPUT_ENCODING).data());
11958 if (cd==reinterpret_cast<void *>(-1))
11959 {
11960 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
11961 "Check the 'INPUT_ENCODING' setting in the config file!\n",
11962 Config_getString(INPUT_ENCODING),strerror(errno));
11963 }
11964 else
11965 {
11967 }
11968
11969 // check and split INPUT_FILE_ENCODING
11970 const StringVector &fileEncod = Config_getList(INPUT_FILE_ENCODING);
11971 for (const auto &mapping : fileEncod)
11972 {
11973 QCString mapStr = mapping;
11974 int i=mapStr.find('=');
11975 if (i==-1)
11976 {
11977 continue;
11978 }
11979 else
11980 {
11981 QCString pattern = mapStr.left(i).stripWhiteSpace().lower();
11982 QCString encoding = mapStr.mid(i+1).stripWhiteSpace().lower();
11983 if (pattern.isEmpty() || encoding.isEmpty())
11984 {
11985 continue;
11986 }
11987 cd = portable_iconv_open("UTF-8",encoding.data());
11988 if (cd==reinterpret_cast<void *>(-1))
11989 {
11990 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
11991 "Check the 'INPUT_FILE_ENCODING' setting in the config file!\n",
11992 encoding,strerror(errno));
11993 }
11994 else
11995 {
11997 }
11998
11999 Doxygen::inputFileEncodingList.emplace_back(pattern, encoding);
12000 }
12001 }
12002
12003 // add predefined macro name to a dictionary
12004 const StringVector &expandAsDefinedList =Config_getList(EXPAND_AS_DEFINED);
12005 for (const auto &s : expandAsDefinedList)
12006 {
12008 }
12009
12010 // read aliases and store them in a dictionary
12011 readAliases();
12012
12013 // store number of spaces in a tab into Doxygen::spaces
12014 int tabSize = Config_getInt(TAB_SIZE);
12015 Doxygen::spaces.resize(tabSize);
12016 for (int sp=0; sp<tabSize; sp++) Doxygen::spaces.at(sp)=' ';
12017 Doxygen::spaces.at(tabSize)='\0';
12018}
void readAliases()
Definition aliases.cpp:161
static FileNameLinkedMap * plantUmlFileNameLinkedMap
Definition doxygen.h:110
static StringUnorderedSet expandAsDefinedSet
Definition doxygen.h:119
static InputFileEncodingList inputFileEncodingList
Definition doxygen.h:140
static FileNameLinkedMap * dotFileNameLinkedMap
Definition doxygen.h:107
static FileNameLinkedMap * imageNameLinkedMap
Definition doxygen.h:106
static FileNameLinkedMap * mscFileNameLinkedMap
Definition doxygen.h:108
static QCString spaces
Definition doxygen.h:135
static FileNameLinkedMap * diaFileNameLinkedMap
Definition doxygen.h:109
static QCString htmlFileExtension
Definition doxygen.h:122
static std::unique_ptr< NamespaceDef > globalNamespaceDef
Definition doxygen.h:120
static FileNameLinkedMap * includeNameLinkedMap
Definition doxygen.h:102
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:103
Ordered dictionary of FileName objects.
Definition filename.h:73
QCString lower() const
Definition qcstring.h:249
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:172
#define Config_getInt(name)
Definition config.h:34
#define Config_getString(name)
Definition config.h:32
#define Config_getEnum(name)
Definition config.h:35
std::vector< std::string > StringVector
Definition containers.h:33
void setTranslator(OUTPUT_LANGUAGE_t langName)
Definition language.cpp:73
#define msg(fmt,...)
Definition message.h:94
#define err(fmt,...)
Definition message.h:127
#define term(fmt,...)
Definition message.h:137
std::unique_ptr< NamespaceDef > createNamespaceDef(const QCString &defFileName, int defLine, int defColumn, const QCString &name, const QCString &ref, const QCString &refFile, const QCString &type, bool isPublished)
Factory method to create new NamespaceDef instance.
int portable_iconv_close(void *cd)
void * portable_iconv_open(const char *tocode, const char *fromcode)
bool updateLanguageMapping(const QCString &extension, const QCString &language)
Definition util.cpp:5029

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

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

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

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

◆ buildClassDocList()

void buildClassDocList ( const Entry * root)
static

Definition at line 1138 of file doxygen.cpp.

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

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

Referenced by buildClassDocList(), and parseInput().

◆ buildClassList()

void buildClassList ( const Entry * root)
static

Definition at line 1128 of file doxygen.cpp.

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

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

Referenced by buildClassList(), and parseInput().

◆ buildCompleteMemberLists()

void buildCompleteMemberLists ( )
static

Definition at line 8485 of file doxygen.cpp.

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

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

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

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

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

Referenced by buildConceptList(), and parseInput().

◆ buildDefineList()

void buildDefineList ( )
static

Definition at line 8820 of file doxygen.cpp.

8821{
8822 AUTO_TRACE();
8823 for (const auto &s : g_inputFiles)
8824 {
8825 auto it = Doxygen::macroDefinitions.find(s);
8827 {
8828 for (const auto &def : it->second)
8829 {
8830 auto md = createMemberDef(
8831 def.fileName,def.lineNr,def.columnNr,
8832 "#define",def.name,def.args,QCString(),
8833 Protection::Public,Specifier::Normal,FALSE,Relationship::Member,MemberType::Define,
8834 ArgumentList(),ArgumentList(),"");
8835 auto mmd = toMemberDefMutable(md.get());
8836
8837 if (!def.args.isEmpty())
8838 {
8839 mmd->moveArgumentList(stringToArgumentList(SrcLangExt::Cpp, def.args));
8840 }
8841 mmd->setInitializer(def.definition);
8842 mmd->setFileDef(def.fileDef);
8843 mmd->setDefinition("#define "+def.name);
8844
8845 MemberName *mn=Doxygen::functionNameLinkedMap->add(def.name);
8846 if (def.fileDef)
8847 {
8848 const MemberList *defMl = def.fileDef->getMemberList(MemberListType::DocDefineMembers());
8849 if (defMl)
8850 {
8851 const MemberDef *defMd = defMl->findRev(def.name);
8852 if (defMd) // definition already stored
8853 {
8854 mmd->setRedefineCount(defMd->redefineCount()+1);
8855 }
8856 }
8857 def.fileDef->insertMember(md.get());
8858 }
8859 AUTO_TRACE_ADD("adding macro {} with definition {}",def.name,def.definition);
8860 mn->push_back(std::move(md));
8861 }
8862 }
8863 }
8864}
static DefinesPerFileList macroDefinitions
Definition doxygen.h:137
virtual int redefineCount() const =0
A list of MemberDef objects as shown in documentation sections.
Definition memberlist.h:125
const MemberDef * findRev(const QCString &name) const
Definition memberlist.h:106
static StringVector g_inputFiles
Definition doxygen.cpp:187

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

Referenced by parseInput().

◆ buildDictionaryList()

void buildDictionaryList ( const Entry * root)
static

Definition at line 3470 of file doxygen.cpp.

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

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

9903{
9904 if ((root->section.isExample() || root->section.isExampleLineno()) && !root->name.isEmpty())
9905 {
9906 if (Doxygen::exampleLinkedMap->find(root->name))
9907 {
9908 warn(root->fileName,root->startLine,"Example {} was already documented. Ignoring documentation found here.",root->name);
9909 }
9910 else
9911 {
9912 PageDef *pd = Doxygen::exampleLinkedMap->add(root->name,
9913 createPageDef(root->fileName,root->startLine,
9914 root->name,root->brief+root->doc+root->inbodyDocs,root->args));
9915 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9916 pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE));
9918 pd->setLanguage(root->lang);
9919 pd->setShowLineNo(root->section.isExampleLineno());
9920
9921 //we don't add example to groups
9922 //addExampleToGroups(root,pd);
9923 }
9924 }
9925 for (const auto &e : root->children()) buildExampleList(e.get());
9926}
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:9902
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:3441

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

Referenced by buildExampleList(), and parseInput().

◆ buildFileList()

void buildFileList ( const Entry * root)
static

Definition at line 496 of file doxygen.cpp.

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

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

Referenced by buildFileList(), and parseInput().

◆ buildFunctionList()

void buildFunctionList ( const Entry * root)
static

Definition at line 3878 of file doxygen.cpp.

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

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

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

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

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

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

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

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

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

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

Referenced by buildPageList(), and parseInput().

◆ buildScopeFromQualifiedName()

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

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

Definition at line 705 of file doxygen.cpp.

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

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

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

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

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

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

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

11884{
11885 AUTO_TRACE();
11886
11891}
void initWarningFormat()
Definition message.cpp:236
void postProcess(bool clearHeaderAndFooter, CompareMode compareMode=CompareMode::Full)
void checkAndCorrect(bool quiet, const bool check)
void updateObsolete()

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

Referenced by main().

◆ checkMarkdownMainfile()

void checkMarkdownMainfile ( )
static

Definition at line 12363 of file doxygen.cpp.

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

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

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

Referenced by parseInput().

◆ cleanUpDoxygen()

void cleanUpDoxygen ( )

Definition at line 11409 of file doxygen.cpp.

11410{
11414
11415 delete Doxygen::indexList;
11424 Doxygen::mainPage.reset();
11428 Doxygen::globalScope = nullptr;
11430 delete theTranslator;
11431 delete g_outputList;
11432
11437 delete Doxygen::dirLinkedMap;
11438 delete Doxygen::symbolMap;
11439}
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:111
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 9198 of file doxygen.cpp.

9199{
9200 // for each file
9201 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9202 {
9203 for (const auto &fd : *fn)
9204 {
9205 fd->combineUsingRelations();
9206 }
9207 }
9208
9209 // for each namespace
9210 NamespaceDefSet visitedNamespaces;
9211 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9212 {
9214 if (ndm)
9215 {
9216 ndm->combineUsingRelations(visitedNamespaces);
9217 }
9218 }
9219}
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 10296 of file doxygen.cpp.

10297{
10298 std::ofstream f;
10299 bool fileOpened=openOutputFile("-",f);
10300 if (fileOpened)
10301 {
10302 TextStream t(&f);
10303 Config::compareDoxyfile(t,diffList);
10304 }
10305 else
10306 {
10307 term("Cannot open stdout for writing\n");
10308 }
10309}
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:6233

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

Referenced by readConfiguration().

◆ computeClassRelations()

void computeClassRelations ( )
static

Definition at line 5309 of file doxygen.cpp.

5310{
5311 AUTO_TRACE();
5312 for (const auto &[name,root] : g_classEntries)
5313 {
5314 QCString bName = extractClassName(root);
5315 ClassDefMutable *cd = getClassMutable(bName);
5316 if (cd)
5317 {
5319 }
5320 size_t numMembers = cd ? cd->memberNameInfoLinkedMap().size() : 0;
5321 if ((cd==nullptr || (!cd->hasDocumentation() && !cd->isReference())) && numMembers>0 && !bName.endsWith("::"))
5322 {
5323 if (!root->name.isEmpty() && root->name.find('@')==-1 && // normal name
5324 (guessSection(root->fileName).isHeader() ||
5325 Config_getBool(EXTRACT_LOCAL_CLASSES)) && // not defined in source file
5326 protectionLevelVisible(root->protection) && // hidden by protection
5327 !Config_getBool(HIDE_UNDOC_CLASSES) // undocumented class are visible
5328 )
5329 warn_undoc(root->fileName,root->startLine, "Compound {} is not documented.", root->name);
5330 }
5331 }
5332}
virtual const MemberNameInfoLinkedMap & memberNameInfoLinkedMap() const =0
Returns a dictionary of all members.
size_t size() const
Definition linkedmap.h:210
bool endsWith(const char *s) const
Definition qcstring.h:524
static QCString extractClassName(const Entry *root)
Definition doxygen.cpp:5212
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:4666
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 11441 of file doxygen.cpp.

11442{
11443 //printf("computeIdealCacheParam(v=%u)\n",v);
11444
11445 int r=0;
11446 while (v!=0) v>>=1,r++;
11447 // r = log2(v)
11448
11449 // convert to a valid cache size value
11450 return std::max(0,std::min(r-16,9));
11451}

Referenced by generateOutput().

◆ computeMemberReferences()

void computeMemberReferences ( )
static

Definition at line 5403 of file doxygen.cpp.

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

8429{
8430 for (const auto &cd : *Doxygen::classLinkedMap)
8431 {
8432 if (cd->isLinkable())
8433 {
8434 for (const auto &bcd : cd->baseClasses())
8435 {
8437 }
8438 }
8439 }
8440}
static void computeMemberRelationsForBaseClass(const ClassDef *cd, const BaseClassDef *bcd)
Definition doxygen.cpp:8348

References Doxygen::classLinkedMap, and computeMemberRelationsForBaseClass().

Referenced by parseInput().

◆ computeMemberRelationsForBaseClass()

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

Definition at line 8348 of file doxygen.cpp.

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

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

Referenced by computeMemberRelations(), and computeMemberRelationsForBaseClass().

◆ computePageRelations()

void computePageRelations ( Entry * root)
static

Definition at line 9767 of file doxygen.cpp.

9768{
9769 if ((root->section.isPageDoc() || root->section.isMainpageDoc()) && !root->name.isEmpty())
9770 {
9771 PageDef *pd = root->section.isPageDoc() ?
9772 Doxygen::pageLinkedMap->find(root->name) :
9773 Doxygen::mainPage.get();
9774 if (pd)
9775 {
9776 for (const BaseInfo &bi : root->extends)
9777 {
9778 PageDef *subPd = Doxygen::pageLinkedMap->find(bi.name);
9779 if (pd==subPd)
9780 {
9781 term("page defined {} with label {} is a direct "
9782 "subpage of itself! Please remove this cyclic dependency.\n",
9783 warn_line(pd->docFile(),pd->docLine()),pd->name());
9784 }
9785 else if (subPd)
9786 {
9787 pd->addInnerCompound(subPd);
9788 //printf("*** Added subpage relation: %s->%s\n",
9789 // qPrint(pd->name()),qPrint(subPd->name()));
9790 }
9791 }
9792 }
9793 }
9794 for (const auto &e : root->children()) computePageRelations(e.get());
9795}
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:9767
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 5334 of file doxygen.cpp.

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

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

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

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

Referenced by parseInput().

◆ computeVerifiedDotPath()

void computeVerifiedDotPath ( )
static

Definition at line 10224 of file doxygen.cpp.

10225{
10226 // check dot path
10227 QCString dotPath = Config_getString(DOT_PATH);
10228 if (!dotPath.isEmpty())
10229 {
10230 FileInfo fi(dotPath.str());
10231 if (!(fi.exists() && fi.isFile()) )// not an existing user specified path + exec
10232 {
10233 dotPath = dotPath+"/dot"+Portable::commandExtension();
10234 FileInfo dp(dotPath.str());
10235 if (!dp.exists() || !dp.isFile())
10236 {
10237 warn_uncond("the dot tool could not be found as '{}'\n",dotPath);
10238 dotPath = "dot";
10239 dotPath += Portable::commandExtension();
10240 }
10241 }
10242#if defined(_WIN32) // convert slashes
10243 size_t l=dotPath.length();
10244 for (size_t i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\';
10245#endif
10246 }
10247 else
10248 {
10249 dotPath = "dot";
10250 dotPath += Portable::commandExtension();
10251 }
10252 Doxygen::verifiedDotPath = dotPath;
10254}
static QCString verifiedDotPath
Definition doxygen.h:139
const char * commandExtension()
Definition portable.cpp:462
#define TRACE(...)
Definition trace.h:77

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

Referenced by parseInput().

◆ convertToCompoundType()

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

Definition at line 889 of file doxygen.cpp.

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

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

Referenced by addClassToContext().

◆ copyExtraFiles()

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

Definition at line 10490 of file doxygen.cpp.

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

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

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

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

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

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

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

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

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

8978{
8979 for (const auto &cd : *Doxygen::classLinkedMap)
8980 {
8981 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8982 if (cdm)
8983 {
8984 cdm->countMembers();
8985 }
8986 }
8987
8988 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8989 {
8991 if (ndm)
8992 {
8993 ndm->countMembers();
8994 }
8995 }
8996
8997 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8998 {
8999 for (const auto &fd : *fn)
9000 {
9001 fd->countMembers();
9002 }
9003 }
9004
9005 for (const auto &gd : *Doxygen::groupLinkedMap)
9006 {
9007 gd->countMembers();
9008 }
9009
9010 auto &mm = ModuleManager::instance();
9011 mm.countMembers();
9012}
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 12131 of file doxygen.cpp.

12134{
12135 QCString result = formatDirName;
12136 if (result.isEmpty())
12137 {
12138 result = baseDirName + defaultDirName;
12139 }
12140 else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':'))
12141 {
12142 result.prepend(baseDirName+"/");
12143 }
12144 Dir formatDir(result.str());
12145 if (!formatDir.exists() && !formatDir.mkdir(result.str()))
12146 {
12147 term("Could not create output directory {}\n", result);
12148 }
12149 return result;
12150}
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 1480 of file doxygen.cpp.

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

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

8445{
8446 // for each class
8447 for (const auto &cd : *Doxygen::classLinkedMap)
8448 {
8449 // that is a template
8450 for (const auto &ti : cd->getTemplateInstances())
8451 {
8452 ClassDefMutable *tcdm = toClassDefMutable(ti.classDef);
8453 if (tcdm)
8454 {
8455 tcdm->addMembersToTemplateInstance(cd.get(),cd->templateArguments(),ti.templSpec);
8456 }
8457 }
8458 }
8459}
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 2110 of file doxygen.cpp.

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

11221{
11223 msg("Developer parameters:\n");
11224 msg(" -m dump symbol map\n");
11225 msg(" -b making messages output unbuffered\n");
11226 msg(" -c <file> process input file as a comment block and produce HTML output\n");
11227#if ENABLE_TRACING
11228 msg(" -t [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout)\n");
11229 msg(" -t_time [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout),\n"
11230 " and include time and thread information\n");
11231#endif
11232 msg(" -d <level> enable a debug level, such as (multiple invocations of -d are possible):\n");
11234}
@ 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 1447 of file doxygen.cpp.

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

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

9262{
9263 // for each class
9264 for (const auto &cd : *Doxygen::classLinkedMap)
9265 {
9266 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9267 if (cdm)
9268 {
9270 }
9271 }
9272 // for each file
9273 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9274 {
9275 for (const auto &fd : *fn)
9276 {
9277 fd->distributeMemberGroupDocumentation();
9278 }
9279 }
9280 // for each namespace
9281 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9282 {
9284 if (ndm)
9285 {
9287 }
9288 }
9289 // for each group
9290 for (const auto &gd : *Doxygen::groupLinkedMap)
9291 {
9292 gd->distributeMemberGroupDocumentation();
9293 }
9295}
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 11179 of file doxygen.cpp.

11180{
11181 QCString anchor;
11183 {
11184 MemberDef *md = toMemberDef(d);
11185 anchor=":"+md->anchor();
11186 }
11187 QCString scope;
11188 QCString fn = d->getOutputFileBase();
11191 {
11192 scope = fn;
11193 }
11194 t << "REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
11195 << fn+anchor << "','"
11196 << scope << "','"
11197 << d->name() << "','"
11198 << d->getDefFileName() << "','"
11199 << d->getDefLine()
11200 << "');\n";
11201}
virtual QCString anchor() const =0
virtual QCString getOutputFileBase() const =0
MemberDef * toMemberDef(Definition *d)
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:4850

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

11204{
11205 std::ofstream f = Portable::openOutputStream("symbols.sql");
11206 if (f.is_open())
11207 {
11208 TextStream t(&f);
11209 for (const auto &[name,symList] : *Doxygen::symbolMap)
11210 {
11211 for (const auto &def : symList)
11212 {
11213 dumpSymbol(t,def);
11214 }
11215 }
11216 }
11217}
static void dumpSymbol(TextStream &t, Definition *d)
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:649

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

Referenced by generateOutput().

◆ exitDoxygen()

void exitDoxygen ( )
staticnoexcept

Definition at line 12118 of file doxygen.cpp.

12119{
12120 if (!g_successfulRun) // premature exit
12121 {
12122 Dir thisDir;
12123 msg("Exiting...\n");
12124 if (!Doxygen::filterDBFileName.isEmpty())
12125 {
12126 thisDir.remove(Doxygen::filterDBFileName.str());
12127 }
12128 }
12129}
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 5212 of file doxygen.cpp.

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

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

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

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

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

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

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

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

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

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

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

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

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

Referenced by findClassRelation(), and findUsedClassesForClass().

◆ findDefineDocumentation()

void findDefineDocumentation ( Entry * root)
static

Definition at line 9508 of file doxygen.cpp.

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

References addDefineDoc(), Entry::args, Entry::bodyLine, Entry::brief, Entry::children(), Config_getBool, createMemberDef(), Define, Entry::doc, FALSE, Entry::fileDef(), Entry::fileName, findDefineDocumentation(), Doxygen::functionNameLinkedMap, haveEqualFileNames(), QCString::isEmpty(), isEntryInGroupOfMember(), Entry::lang, MemberDef::memberType(), Entry::name, Entry::parent(), MemberName::push_back(), Entry::qualifiers, Entry::section, Entry::startLine, Entry::tagInfo(), TagInfo::tagName, toMemberDefMutable(), and warn.

Referenced by findDefineDocumentation(), and parseInput().

◆ findDEV()

void findDEV ( const MemberNameLinkedMap & mnsd)
static

Definition at line 8072 of file doxygen.cpp.

8073{
8074 // for each member name
8075 for (const auto &mn : mnsd)
8076 {
8077 // for each member definition
8078 for (const auto &imd : *mn)
8079 {
8080 MemberDefMutable *md = toMemberDefMutable(imd.get());
8081 if (md && md->isEnumerate()) // member is an enum
8082 {
8083 int documentedEnumValues=0;
8084 // for each enum value
8085 for (const auto &fmd : md->enumFieldList())
8086 {
8087 if (fmd->isLinkableInProject()) documentedEnumValues++;
8088 }
8089 // at least one enum value is documented
8090 if (documentedEnumValues>0) md->setDocumentedEnumValues(TRUE);
8091 }
8092 }
8093 }
8094}
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 9595 of file doxygen.cpp.

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

8099{
8102}
static void findDEV(const MemberNameLinkedMap &mnsd)
Definition doxygen.cpp:8072

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

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

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

Referenced by addVariable(), and findClassRelation().

◆ findEnumDocumentation()

void findEnumDocumentation ( const Entry * root)
static

Definition at line 7986 of file doxygen.cpp.

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

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

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

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

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

Referenced by parseInput().

◆ findFunctionPtr()

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

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

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

Definition at line 2826 of file doxygen.cpp.

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

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

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

Referenced by findMember().

◆ findGroupScope()

void findGroupScope ( const Entry * root)
static

Definition at line 440 of file doxygen.cpp.

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

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

Referenced by findGroupScope(), and parseInput().

◆ findIncludedUsingDirectives()

void findIncludedUsingDirectives ( )
static

Definition at line 2409 of file doxygen.cpp.

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

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

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

Referenced by parseInput().

◆ findMainPage()

void findMainPage ( Entry * root)
static

Definition at line 9685 of file doxygen.cpp.

9686{
9687 if (root->section.isMainpageDoc())
9688 {
9689 if (Doxygen::mainPage==nullptr && root->tagInfo()==nullptr)
9690 {
9691 //printf("mainpage: docLine=%d startLine=%d\n",root->docLine,root->startLine);
9692 //printf("Found main page! \n======\n%s\n=======\n",qPrint(root->doc));
9693 QCString title=root->args.stripWhiteSpace();
9694 if (title.isEmpty()) title = Config_getString(PROJECT_NAME);
9695 //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9696 QCString indexName="index";
9698 indexName, root->brief+root->doc+root->inbodyDocs,title);
9699 //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
9700 Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9701 Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1);
9702 Doxygen::mainPage->setFileName(indexName);
9703 Doxygen::mainPage->setLocalToc(root->localToc);
9705
9707 if (si)
9708 {
9709 if (!si->ref().isEmpty()) // we are from a tag file
9710 {
9711 // a page name is a label as well! but should no be double either
9713 Doxygen::mainPage->name(),
9714 indexName,
9715 root->startLine,
9716 Doxygen::mainPage->title(),
9718 0); // level 0
9719 }
9720 else if (si->lineNr() != -1)
9721 {
9722 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {}, line {})",
9723 Doxygen::mainPage->name(),si->fileName(),si->lineNr());
9724 }
9725 else
9726 {
9727 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {})",
9728 Doxygen::mainPage->name(),si->fileName());
9729 }
9730 }
9731 else
9732 {
9733 // a page name is a label as well! but should no be double either
9735 Doxygen::mainPage->name(),
9736 indexName,
9737 root->startLine,
9738 Doxygen::mainPage->title(),
9740 0); // level 0
9741 }
9742 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9743 }
9744 else if (root->tagInfo()==nullptr)
9745 {
9746 warn(root->fileName,root->startLine,
9747 "found more than one \\mainpage comment block! (first occurrence: {}, line {}), Skipping current block!",
9748 Doxygen::mainPage->docFile(),Doxygen::mainPage->getStartBodyLine());
9749 }
9750 }
9751 for (const auto &e : root->children()) findMainPage(e.get());
9752}
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:9685

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

9756{
9757 if (root->section.isMainpageDoc())
9758 {
9759 if (Doxygen::mainPage && root->tagInfo())
9760 {
9761 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9762 }
9763 }
9764 for (const auto &e : root->children()) findMainPageTagFiles(e.get());
9765}
static void findMainPageTagFiles(Entry *root)
Definition doxygen.cpp:9755

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

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

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

Referenced by filterMemberDocumentation(), and findObjCMethodDefinitions().

◆ findMemberDocumentation()

void findMemberDocumentation ( const Entry * root)
static

Definition at line 7430 of file doxygen.cpp.

7431{
7432 if (root->section.isMemberDoc() ||
7433 root->section.isOverloadDoc() ||
7434 root->section.isFunction() ||
7435 root->section.isVariable() ||
7436 root->section.isVariableDoc() ||
7437 root->section.isDefine() ||
7438 root->section.isIncludedService() ||
7439 root->section.isExportedInterface()
7440 )
7441 {
7442 AUTO_TRACE();
7443 if (root->relatesType==RelatesType::Duplicate && !root->relates.isEmpty())
7444 {
7446 }
7448 }
7449 for (const auto &e : root->children())
7450 {
7451 if (!e->section.isEnum())
7452 {
7453 findMemberDocumentation(e.get());
7454 }
7455 }
7456}
static void findMemberDocumentation(const Entry *root)
Definition doxygen.cpp:7430
static void filterMemberDocumentation(const Entry *root, const QCString &relates)
Definition doxygen.cpp:7280

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

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

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

7461{
7462 AUTO_TRACE();
7463 for (const auto &objCImpl : root->children())
7464 {
7465 if (objCImpl->section.isObjcImpl())
7466 {
7467 for (const auto &objCMethod : objCImpl->children())
7468 {
7469 if (objCMethod->section.isFunction())
7470 {
7471 //printf(" Found ObjC method definition %s\n",qPrint(objCMethod->name));
7472 findMember(objCMethod.get(),
7473 objCMethod->relates,
7474 objCMethod->type,
7475 objCMethod->args,
7476 objCMethod->type+" "+objCImpl->name+"::"+objCMethod->name+" "+objCMethod->args,
7477 FALSE,TRUE);
7478 objCMethod->section=EntryType::makeEmpty();
7479 }
7480 }
7481 }
7482 }
7483}

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

Referenced by parseInput().

◆ findScopeFromQualifiedName()

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

Definition at line 774 of file doxygen.cpp.

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

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

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

◆ findSectionsInDocumentation()

void findSectionsInDocumentation ( )
static

Definition at line 9299 of file doxygen.cpp.

9300{
9301 // for each class
9302 for (const auto &cd : *Doxygen::classLinkedMap)
9303 {
9304 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9305 if (cdm)
9306 {
9308 }
9309 }
9310 // for each concept
9311 for (const auto &cd : *Doxygen::conceptLinkedMap)
9312 {
9313 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
9314 if (cdm)
9315 {
9317 }
9318 }
9319 // for each file
9320 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9321 {
9322 for (const auto &fd : *fn)
9323 {
9324 fd->findSectionsInDocumentation();
9325 }
9326 }
9327 // for each namespace
9328 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9329 {
9331 if (ndm)
9332 {
9334 }
9335 }
9336 // for each group
9337 for (const auto &gd : *Doxygen::groupLinkedMap)
9338 {
9339 gd->findSectionsInDocumentation();
9340 }
9341 // for each page
9342 for (const auto &pd : *Doxygen::pageLinkedMap)
9343 {
9344 pd->findSectionsInDocumentation();
9345 }
9346 // for each directory
9347 for (const auto &dd : *Doxygen::dirLinkedMap)
9348 {
9349 dd->findSectionsInDocumentation();
9350 }
9352 if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
9353}
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 1647 of file doxygen.cpp.

1648{
1649 std::vector<ClassDefMutable *> candidates;
1650 for (auto &cd : *Doxygen::classLinkedMap)
1651 {
1652 Definition *scope = cd->getOuterScope();
1653 if (scope && scope->definitionType()!=Definition::TypeClass) // that is not nested
1654 {
1655 findTagLessClasses(candidates,cd.get());
1656 }
1657 }
1658
1659 // since processTagLessClasses is potentially adding classes to Doxygen::classLinkedMap
1660 // we need to call it outside of the loop above, otherwise the iterator gets invalidated!
1661 for (auto &cd : candidates)
1662 {
1663 processTagLessClasses(cd,cd,cd,"",0); // process tag less inner struct/classes
1664 }
1665}
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:1566
static void findTagLessClasses()
Definition doxygen.cpp:1647

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

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

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

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

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

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

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

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

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

Referenced by findTemplateInstanceRelation(), and findUsedTemplateInstances().

◆ findUsedNamespace()

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

Definition at line 1838 of file doxygen.cpp.

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

References getResolvedNamespace().

Referenced by findUsingDirectives().

◆ findUsedTemplateInstances()

void findUsedTemplateInstances ( )
static

Definition at line 5273 of file doxygen.cpp.

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

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

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

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

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

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

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

9359{
9360 // remove all references to classes from the cache
9361 // as there can be new template instances in the inheritance path
9362 // to this class. Optimization: only remove those classes that
9363 // have inheritance instances as direct or indirect sub classes.
9364 StringVector elementsToRemove;
9365 for (const auto &ci : *Doxygen::typeLookupCache)
9366 {
9367 const LookupInfo &li = ci.second;
9368 if (li.definition)
9369 {
9370 elementsToRemove.push_back(ci.first);
9371 }
9372 }
9373 for (const auto &k : elementsToRemove)
9374 {
9375 Doxygen::typeLookupCache->remove(k);
9376 }
9377
9378 // remove all cached typedef resolutions whose target is a
9379 // template class as this may now be a template instance
9380 // for each global function name
9381 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9382 {
9383 // for each function with that name
9384 for (const auto &ifmd : *fn)
9385 {
9386 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9387 if (fmd && fmd->isTypedefValCached())
9388 {
9389 const ClassDef *cd = fmd->getCachedTypedefVal();
9390 if (cd->isTemplate()) fmd->invalidateTypedefValCache();
9391 }
9392 }
9393 }
9394 // for each class method name
9395 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9396 {
9397 // for each function with that name
9398 for (const auto &imd : *nm)
9399 {
9400 MemberDefMutable *md = toMemberDefMutable(imd.get());
9401 if (md && md->isTypedefValCached())
9402 {
9403 const ClassDef *cd = md->getCachedTypedefVal();
9404 if (cd->isTemplate()) md->invalidateTypedefValCache();
9405 }
9406 }
9407 }
9408}
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 9412 of file doxygen.cpp.

9413{
9414 // Remove all unresolved references to classes from the cache.
9415 // This is needed before resolving the inheritance relations, since
9416 // it would otherwise not find the inheritance relation
9417 // for C in the example below, as B::I was already found to be unresolvable
9418 // (which is correct if you ignore the inheritance relation between A and B).
9419 //
9420 // class A { class I {} };
9421 // class B : public A {};
9422 // class C : public B::I {};
9423
9424 StringVector elementsToRemove;
9425 for (const auto &ci : *Doxygen::typeLookupCache)
9426 {
9427 const LookupInfo &li = ci.second;
9428 if (li.definition==nullptr && li.typeDef==nullptr)
9429 {
9430 elementsToRemove.push_back(ci.first);
9431 }
9432 }
9433 for (const auto &k : elementsToRemove)
9434 {
9435 Doxygen::typeLookupCache->remove(k);
9436 }
9437
9438 // for each global function name
9439 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9440 {
9441 // for each function with that name
9442 for (const auto &ifmd : *fn)
9443 {
9444 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9445 if (fmd)
9446 {
9448 }
9449 }
9450 }
9451 // for each class method name
9452 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9453 {
9454 // for each function with that name
9455 for (const auto &imd : *nm)
9456 {
9457 MemberDefMutable *md = toMemberDefMutable(imd.get());
9458 if (md)
9459 {
9461 }
9462 }
9463 }
9464
9465}
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 9116 of file doxygen.cpp.

9117{
9118 std::vector<ClassDefMutable*> classList;
9119 for (const auto &cdi : *Doxygen::classLinkedMap)
9120 {
9121 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9122 if (cd && (cd->getOuterScope()==nullptr ||
9124 {
9125 addClassAndNestedClasses(classList,cd);
9126 }
9127 }
9128 for (const auto &cdi : *Doxygen::hiddenClassLinkedMap)
9129 {
9130 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9131 if (cd && (cd->getOuterScope()==nullptr ||
9133 {
9134 addClassAndNestedClasses(classList,cd);
9135 }
9136 }
9137 generateDocsForClassList(classList);
9138}
static void generateDocsForClassList(const std::vector< ClassDefMutable * > &classList)
Definition doxygen.cpp:9018

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

9143{
9144 for (const auto &cdi : *Doxygen::conceptLinkedMap)
9145 {
9147
9148 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9149 if (cd &&
9150 (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9151 cd->getOuterScope()==Doxygen::globalScope // only look at global concepts
9152 ) && !cd->isHidden() && cd->isLinkableInProject()
9153 )
9154 {
9155 msg("Generating docs for concept {}...\n",cd->displayName());
9157 }
9158 }
9159}
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 10262 of file doxygen.cpp.

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

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

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

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

Referenced by generateClassDocs().

◆ generateExampleDocs()

void generateExampleDocs ( )
static

Definition at line 9970 of file doxygen.cpp.

9971{
9972 g_outputList->disable(OutputType::Man);
9973 for (const auto &pd : *Doxygen::exampleLinkedMap)
9974 {
9975 msg("Generating docs for example {}...\n",pd->name());
9976 SrcLangExt lang = getLanguageFromFileName(pd->name(), SrcLangExt::Unknown);
9977 if (lang != SrcLangExt::Unknown)
9978 {
9979 QCString ext = getFileNameExtension(pd->name());
9980 auto intf = Doxygen::parserManager->getCodeParser(ext);
9981 intf->resetCodeParserState();
9982 }
9983 QCString n=pd->getOutputFileBase();
9984 startFile(*g_outputList,n,false,n,pd->name());
9986 g_outputList->docify(pd->name());
9988 g_outputList->startContents();
9989 QCString lineNoOptStr;
9990 if (pd->showLineNo())
9991 {
9992 lineNoOptStr="{lineno}";
9993 }
9994 g_outputList->generateDoc(pd->docFile(), // file
9995 pd->docLine(), // startLine
9996 pd.get(), // context
9997 nullptr, // memberDef
9998 (pd->briefDescription().isEmpty()?"":pd->briefDescription()+"\n\n")+
9999 pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
10000 DocOptions()
10001 .setIndexWords(true)
10002 .setExample(pd->name()));
10003 endFile(*g_outputList); // contains g_outputList->endContents()
10004 }
10006}
void startTitle(OutputList &ol, const QCString &fileName, const DefinitionMutable *def)
Definition index.cpp:384
void endFile(OutputList &ol, bool skipNavIndex, bool skipEndContents, const QCString &navPath)
Definition index.cpp:427
void endTitle(OutputList &ol, const QCString &fileName, const QCString &name)
Definition index.cpp:394
void startFile(OutputList &ol, const QCString &name, bool isSource, const QCString &manName, const QCString &title, HighlightedItem hli, bool additionalIndices, const QCString &altSidebarName, int hierarchyLevel, const QCString &allMembersFile)
Definition index.cpp:401
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5134
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5176

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

Referenced by generateOutput().

◆ generateFileDocs()

void generateFileDocs ( )
static

Definition at line 8681 of file doxygen.cpp.

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

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

Referenced by generateOutput().

◆ generateFileSources()

void generateFileSources ( )
static

Definition at line 8515 of file doxygen.cpp.

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

References FileDef::absFilePath(), Doxygen::clangAssistedParsing, Config_getInt, ClangParser::createTUParser(), FileDef::docName(), QCString::find(), findFileDef(), g_outputList, FileDef::generateSourceFile(), FileDef::getAllIncludeFilesRecursively(), Definition::getLanguage(), Doxygen::inputNameLinkedMap, ClangParser::instance(), Definition::isReference(), FileDef::isSource(), msg, FileDef::parseSource(), Doxygen::parseSourcesNeeded, ThreadPool::queue(), QCString::str(), Htags::useHtags, FileDef::writeSourceBody(), FileDef::writeSourceFooter(), and FileDef::writeSourceHeader().

Referenced by generateOutput().

◆ generateGroupDocs()

void generateGroupDocs ( )
static

Definition at line 10011 of file doxygen.cpp.

10012{
10013 for (const auto &gd : *Doxygen::groupLinkedMap)
10014 {
10015 if (!gd->isReference())
10016 {
10017 gd->writeDocumentation(*g_outputList);
10018 }
10019 }
10020}

References g_outputList, and Doxygen::groupLinkedMap.

Referenced by generateOutput().

◆ generateNamespaceClassDocs()

void generateNamespaceClassDocs ( const ClassLinkedRefMap & classList)
static

Definition at line 10025 of file doxygen.cpp.

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

10098{
10099 // for each concept in the namespace...
10100 for (const auto &cd : conceptList)
10101 {
10103 if ( cdm && cd->isLinkableInProject() && !cd->isHidden())
10104 {
10105 msg("Generating docs for concept {}...\n",cd->name());
10107 }
10108 }
10109}

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

Referenced by generateNamespaceDocs().

◆ generateNamespaceDocs()

void generateNamespaceDocs ( )
static

Definition at line 10111 of file doxygen.cpp.

10112{
10113 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
10114
10115 //writeNamespaceIndex(*g_outputList);
10116
10117 // for each namespace...
10118 for (const auto &nd : *Doxygen::namespaceLinkedMap)
10119 {
10120 if (nd->isLinkableInProject())
10121 {
10123 if (ndm)
10124 {
10125 msg("Generating docs for namespace {}\n",nd->displayName());
10127 }
10128 }
10129
10130 generateNamespaceClassDocs(nd->getClasses());
10131 if (sliceOpt)
10132 {
10133 generateNamespaceClassDocs(nd->getInterfaces());
10134 generateNamespaceClassDocs(nd->getStructs());
10135 generateNamespaceClassDocs(nd->getExceptions());
10136 }
10137 generateNamespaceConceptDocs(nd->getConcepts());
10138 }
10139}
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 13059 of file doxygen.cpp.

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

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

Referenced by main().

◆ generatePageDocs()

void generatePageDocs ( )
static

Definition at line 9885 of file doxygen.cpp.

9886{
9887 //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageLinkedMap->count());
9888 if (Index::instance().numDocumentedPages()==0) return;
9889 for (const auto &pd : *Doxygen::pageLinkedMap)
9890 {
9891 if (!pd->getGroupDef() && !pd->isReference())
9892 {
9893 msg("Generating docs for page {}...\n",pd->name());
9894 pd->writeDocumentation(*g_outputList);
9895 }
9896 }
9897}

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

Referenced by generateOutput().

◆ generateXRefPages()

void generateXRefPages ( )
static

Definition at line 5506 of file doxygen.cpp.

5507{
5508 AUTO_TRACE();
5510 {
5511 rl->generatePage();
5512 }
5513}
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 11313 of file doxygen.cpp.

11314{
11315 char *s=nullptr;
11316 if (qstrlen(&argv[optInd][2])>0)
11317 s=&argv[optInd][2];
11318 else if (optInd+1<argc && argv[optInd+1][0]!='-')
11319 s=argv[++optInd];
11320 return s;
11321}
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 10594 of file doxygen.cpp.

10595{
10596 QCString fileName=fn;
10597 QCString extension;
10598 int sep = fileName.findRev('/');
10599 int ei = fileName.findRev('.');
10600 if (ei!=-1 && (sep==-1 || ei>sep)) // matches dir/file.ext but not dir.1/file
10601 {
10602 extension=fileName.right(fileName.length()-ei);
10603 }
10604 else
10605 {
10606 extension = ".no_extension";
10607 }
10608
10609 return Doxygen::parserManager->getOutlineParser(extension);
10610}

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

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

References end().

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

◆ haveEqualFileNames()

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

Definition at line 9471 of file doxygen.cpp.

9472{
9473 if (const FileDef *fd = md->getFileDef())
9474 {
9475 return fd->absFilePath() == root->fileName;
9476 }
9477 return false;
9478}

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

Referenced by findDefineDocumentation().

◆ inheritDocumentation()

void inheritDocumentation ( )
static

Definition at line 9163 of file doxygen.cpp.

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

11341{
11342 initResources();
11343 QCString lang = Portable::getenv("LC_ALL");
11344 if (!lang.isEmpty()) Portable::setenv("LANG",lang);
11345 std::setlocale(LC_ALL,"");
11346 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
11347 std::setlocale(LC_NUMERIC,"C");
11348
11350
11374
11375 // register any additional parsers here...
11376
11378
11379#if USE_LIBCLANG
11381#endif
11390 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
11391 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
11392 //Doxygen::tagDestinationDict.setAutoDelete(TRUE);
11394
11395 // initialization of these globals depends on
11396 // configuration switches so we need to postpone these
11397 Doxygen::globalScope = nullptr;
11406
11407}
static void startTimer()
Definition debug.cpp:195
A linked map of directories.
Definition dirdef.h:173
A list of index interfaces.
Definition indexlist.h:64
Manages programming language parsers.
Definition parserintf.h:147
std::function< std::unique_ptr< T >() > make_parser_factory()
void initResources()
std::unordered_map< std::string, const Definition * > ClangUsrMap
Definition doxygen.h:83
void setenv(const QCString &variable, const QCString &value)
Definition portable.cpp:287
QCString getenv(const QCString &variable)
Definition portable.cpp:322
void initDefaultExtensionMapping()
Definition util.cpp:5061

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

6613{
6614 if (outerScope && outerScope!=Doxygen::globalScope)
6615 {
6616 auto aliasMd = createMemberDefAlias(outerScope,md);
6617 if (outerScope->definitionType()==Definition::TypeClass)
6618 {
6619 ClassDefMutable *cdm = toClassDefMutable(outerScope);
6620 if (cdm)
6621 {
6622 cdm->insertMember(aliasMd.get());
6623 }
6624 }
6625 else if (outerScope->definitionType()==Definition::TypeNamespace)
6626 {
6627 NamespaceDefMutable *ndm = toNamespaceDefMutable(outerScope);
6628 if (ndm)
6629 {
6630 ndm->insertMember(aliasMd.get());
6631 }
6632 }
6633 else if (outerScope->definitionType()==Definition::TypeFile)
6634 {
6635 toFileDef(outerScope)->insertMember(aliasMd.get());
6636 }
6637 if (aliasMd)
6638 {
6639 Doxygen::functionNameLinkedMap->add(md->name())->push_back(std::move(aliasMd));
6640 }
6641 }
6642}
FileDef * toFileDef(Definition *d)
Definition filedef.cpp:1956

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

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

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

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

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

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

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

Referenced by findClassRelation().

◆ isSpecialization()

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

Definition at line 5916 of file doxygen.cpp.

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

References FALSE, and TRUE.

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

◆ isSymbolHidden()

bool isSymbolHidden ( const Definition * d)
static

Definition at line 8910 of file doxygen.cpp.

8911{
8912 bool hidden = d->isHidden();
8913 const Definition *parent = d->getOuterScope();
8914 return parent ? hidden || isSymbolHidden(parent) : hidden;
8915}
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 2886 of file doxygen.cpp.

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

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

11336{
11337 return []() { return std::make_unique<T>(); };
11338}

Referenced by initDoxygen().

◆ makeTemplateInstanceRelation()

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

Definition at line 5255 of file doxygen.cpp.

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

8464{
8465 AUTO_TRACE();
8466 // merge members of categories into the class they extend
8467 for (const auto &cd : *Doxygen::classLinkedMap)
8468 {
8469 int i=cd->name().find('(');
8470 if (i!=-1) // it is an Objective-C category
8471 {
8472 QCString baseName=cd->name().left(i);
8473 ClassDefMutable *baseClass=toClassDefMutable(Doxygen::classLinkedMap->find(baseName));
8474 if (baseClass)
8475 {
8476 AUTO_TRACE_ADD("merging members of category {} into {}",cd->name(),baseClass->name());
8477 baseClass->mergeCategory(cd.get());
8478 }
8479 }
8480 }
8481}
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 10612 of file doxygen.cpp.

10615{
10616 QCString fileName=fn;
10617 AUTO_TRACE("fileName={}",fileName);
10618 QCString extension;
10619 int ei = fileName.findRev('.');
10620 if (ei!=-1)
10621 {
10622 extension=fileName.right(fileName.length()-ei);
10623 }
10624 else
10625 {
10626 extension = ".no_extension";
10627 }
10628
10629 FileInfo fi(fileName.str());
10630 std::string preBuf;
10631
10632 if (Config_getBool(ENABLE_PREPROCESSING) &&
10633 parser.needsPreprocessing(extension))
10634 {
10635 Preprocessor preprocessor;
10636 const StringVector &includePath = Config_getList(INCLUDE_PATH);
10637 for (const auto &s : includePath)
10638 {
10639 std::string absPath = FileInfo(s).absFilePath();
10640 preprocessor.addSearchDir(absPath);
10641 }
10642 std::string inBuf;
10643 msg("Preprocessing {}...\n",fn);
10644 readInputFile(fileName,inBuf);
10645 addTerminalCharIfMissing(inBuf,'\n');
10646 preprocessor.processFile(fileName,inBuf,preBuf);
10647 }
10648 else // no preprocessing
10649 {
10650 msg("Reading {}...\n",fn);
10651 readInputFile(fileName,preBuf);
10652 addTerminalCharIfMissing(preBuf,'\n');
10653 }
10654
10655 std::string convBuf;
10656 convBuf.reserve(preBuf.size()+1024);
10657
10658 // convert multi-line C++ comments to C style comments
10659 convertCppComments(preBuf,convBuf,fileName.str());
10660
10661 std::shared_ptr<Entry> fileRoot = std::make_shared<Entry>();
10662 // use language parse to parse the file
10663 if (clangParser)
10664 {
10665 if (newTU) clangParser->parse();
10666 clangParser->switchToFile(fd);
10667 }
10668 parser.parseInput(fileName,convBuf.data(),fileRoot,clangParser);
10669 fileRoot->setFileDef(fd);
10670 return fileRoot;
10671}
void switchToFile(const FileDef *fd)
Switches to another file within the translation unit started with start().
void parse()
Parse the file given at construction time as a translation unit This file should already be preproces...
std::string absFilePath() const
Definition fileinfo.cpp:101
virtual bool needsPreprocessing(const QCString &extension) const =0
Returns TRUE if the language identified by extension needs the C preprocessor to be run before feed t...
virtual void parseInput(const QCString &fileName, const char *fileBuf, const std::shared_ptr< Entry > &root, ClangTUParser *clangParser)=0
Parses a single input file with the goal to build an Entry tree.
void processFile(const QCString &fileName, const std::string &input, std::string &output)
Definition pre.l:4073
void addSearchDir(const QCString &dir)
Definition pre.l:4055
void convertCppComments(const std::string &inBuf, std::string &outBuf, const std::string &fn)
Converts the comments in a file.
void addTerminalCharIfMissing(std::string &s, char c)
Definition stringutil.h:84
bool readInputFile(const QCString &fileName, std::string &contents, bool filter, bool isSourceCode)
read a file name fileName and optionally filter and transcode it
Definition util.cpp:5473

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

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

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

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

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

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

9932{
9934 {
9935 QCString indentStr;
9936 indentStr.fill(' ',indent);
9937 Debug::print(Debug::Entries,0,"{}{} at {}:{} (sec={}, spec={})\n",
9938 indentStr.isEmpty()?"":indentStr,
9939 root->name.isEmpty()?"<empty>":root->name,
9940 root->fileName,root->startLine,
9941 root->section.to_string(),
9942 root->spec.to_string());
9943 for (const auto &e : root->children())
9944 {
9945 printNavTree(e.get(),indent+2);
9946 }
9947 }
9948}
@ 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:825
QCString fill(char c, int len=-1)
Fills a string with a predefined character.
Definition qcstring.h:193
std::string to_string() const
Definition types.h:698

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

Referenced by parseInput(), and printNavTree().

◆ printSectionsTree()

void printSectionsTree ( )

Definition at line 9954 of file doxygen.cpp.

9955{
9957 {
9958 for (const auto &si : SectionManager::instance())
9959 {
9960 Debug::print(Debug::Sections,0,"Section = {}, file = {}, title = {}, type = {}, ref = {}\n",
9961 si->label(),si->fileName(),si->title(),si->type().level(),si->ref());
9962 }
9963 }
9964}
@ 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 1566 of file doxygen.cpp.

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

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

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

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

Referenced by main().

◆ readDir()

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

Definition at line 10990 of file doxygen.cpp.

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

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

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

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

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

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

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

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

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

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

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

10142{
10143 std::string oldDir = Dir::currentDirPath();
10144 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10147 {
10148 err("failed to run html help compiler on {}\n", HtmlHelp::hhpFileName);
10149 }
10150 Dir::setCurrent(oldDir);
10151}
@ ExtCmd
Definition debug.h:36
static bool setCurrent(const std::string &path)
Definition dir.cpp:350
static const QCString hhpFileName
Definition htmlhelp.h:89
int system(const QCString &command, const QCString &args, bool commandHasConsole=true)
Definition portable.cpp:106
void setShortDir()
Definition portable.cpp:554

References Config_getString, Dir::currentDirPath(), err, Debug::ExtCmd, HtmlHelp::hhpFileName, Debug::isFlagSet(), qPrint(), Dir::setCurrent(), Portable::setShortDir(), and Portable::system().

Referenced by generateOutput().

◆ runQHelpGenerator()

void runQHelpGenerator ( )
static

Definition at line 10153 of file doxygen.cpp.

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

References Config_getString, Dir::currentDirPath(), err, Debug::ExtCmd, FALSE, Qhp::getQchFileName(), Debug::isFlagSet(), Portable::pclose(), Portable::popen(), Debug::print(), Debug::Qhp, Qhp::qhpFileName, reg::search(), Dir::setCurrent(), Portable::system(), and QCString::toInt().

Referenced by generateOutput().

◆ scopeIsTemplate()

bool scopeIsTemplate ( const Definition * d)
static

Definition at line 5932 of file doxygen.cpp.

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

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

Referenced by addMemberFunction(), and scopeIsTemplate().

◆ searchInputFiles()

void searchInputFiles ( )

Definition at line 12152 of file doxygen.cpp.

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

8964{
8965 for (const auto &cd : *Doxygen::classLinkedMap)
8966 {
8967 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8968 if (cdm)
8969 {
8970 cdm->setAnonymousEnumType();
8971 }
8972 }
8973}
virtual void setAnonymousEnumType()=0

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

Referenced by parseInput().

◆ sortMemberLists()

void sortMemberLists ( )
static

Definition at line 8868 of file doxygen.cpp.

8869{
8870 // sort class member lists
8871 for (const auto &cd : *Doxygen::classLinkedMap)
8872 {
8873 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8874 if (cdm)
8875 {
8876 cdm->sortMemberLists();
8877 }
8878 }
8879
8880 // sort namespace member lists
8881 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8882 {
8884 if (ndm)
8885 {
8886 ndm->sortMemberLists();
8887 }
8888 }
8889
8890 // sort file member lists
8891 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8892 {
8893 for (const auto &fd : *fn)
8894 {
8895 fd->sortMemberLists();
8896 }
8897 }
8898
8899 // sort group member lists
8900 for (const auto &gd : *Doxygen::groupLinkedMap)
8901 {
8902 gd->sortMemberLists();
8903 }
8904
8906}
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 12021 of file doxygen.cpp.

12022{
12023 signal(SIGINT,SIG_DFL); // Re-register signal handler for default action
12024 Dir thisDir;
12025 msg("Cleaning up...\n");
12026 if (!Doxygen::filterDBFileName.isEmpty())
12027 {
12028 thisDir.remove(Doxygen::filterDBFileName.str());
12029 }
12030 killpg(0,SIGINT);
12032 exitTracing();
12033 exit(1);
12034}

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

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

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

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

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

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

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

Referenced by parseInput().

◆ transferRelatedFunctionDocumentation()

void transferRelatedFunctionDocumentation ( )
static

Definition at line 4361 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ transferStaticInstanceInitializers()

void transferStaticInstanceInitializers ( )

Definition at line 4410 of file doxygen.cpp.

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

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

7954{
7955 for (const auto &g : root->groups)
7956 {
7957 const GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
7958 if (gd)
7959 {
7960 MemberList *ml = gd->getMemberList(MemberListType::DecEnumMembers());
7961 if (ml)
7962 {
7963 MemberDefMutable *md = toMemberDefMutable(ml->find(name));
7964 if (md)
7965 {
7966 addEnumDocs(root,md);
7967 return TRUE;
7968 }
7969 }
7970 }
7971 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
7972 {
7973 warn(root->fileName, root->startLine,
7974 "Found non-existing group '{}' for the command '{}', ignoring command",
7975 g.groupname, Grouping::getGroupPriName( g.pri )
7976 );
7977 }
7978 }
7979
7980 return FALSE;
7981}
virtual MemberList * getMemberList(MemberListType lt) const =0
const MemberDef * find(const QCString &name) const
Definition memberlist.h:93

References addEnumDocs(), FALSE, Entry::fileName, MemberVector::find(), Grouping::getGroupPriName(), GroupDef::getMemberList(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Entry::groups, Entry::startLine, toMemberDefMutable(), TRUE, and warn.

Referenced by findEnumDocumentation().

◆ usage()

void usage ( const QCString & name,
const QCString & versionString )
static

Definition at line 11268 of file doxygen.cpp.

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

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

Referenced by readConfiguration().

◆ version()

void version ( const bool extended)
static

Definition at line 11240 of file doxygen.cpp.

11241{
11243 QCString versionString = getFullVersion();
11244 msg("{}\n",versionString);
11245 if (extended)
11246 {
11247 QCString extVers;
11248 if (!extVers.isEmpty()) extVers+= ", ";
11249 extVers += "sqlite3 ";
11250 extVers += sqlite3_libversion();
11251#if USE_LIBCLANG
11252 if (!extVers.isEmpty()) extVers+= ", ";
11253 extVers += "clang support ";
11254 extVers += CLANG_VERSION_STRING;
11255#endif
11256 if (!extVers.isEmpty())
11257 {
11258 int lastComma = extVers.findRev(',');
11259 if (lastComma != -1) extVers = extVers.replace(lastComma,1," and");
11260 msg(" with {}.\n",extVers);
11261 }
11262 }
11263}
QCString & replace(size_t index, size_t len, const char *s)
Definition qcstring.cpp:217

References Debug::clearFlag(), QCString::findRev(), QCString::isEmpty(), msg, QCString::replace(), and Debug::Time.

Referenced by readConfiguration(), and LayoutParser::startLayout().

◆ vhdlCorrectMemberProperties()

void vhdlCorrectMemberProperties ( )
static

Definition at line 8316 of file doxygen.cpp.

8317{
8318 // for each member name
8319 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8320 {
8321 // for each member definition
8322 for (const auto &imd : *mn)
8323 {
8324 MemberDefMutable *md = toMemberDefMutable(imd.get());
8325 if (md)
8326 {
8328 }
8329 }
8330 }
8331 // for each member name
8332 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8333 {
8334 // for each member definition
8335 for (const auto &imd : *mn)
8336 {
8337 MemberDefMutable *md = toMemberDefMutable(imd.get());
8338 if (md)
8339 {
8341 }
8342 }
8343 }
8344}
static void correctMemberProperties(MemberDefMutable *md)

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

Referenced by parseInput().

◆ warnUndocumentedNamespaces()

void warnUndocumentedNamespaces ( )
static

Definition at line 5289 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ writeTagFile()

void writeTagFile ( )
static

Definition at line 12037 of file doxygen.cpp.

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