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 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()

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

Definition at line 9069 of file doxygen.cpp.

9070{
9071 list.push_back(cd);
9072 for (const auto &innerCdi : cd->getClasses())
9073 {
9074 ClassDefMutable *innerCd = toClassDefMutable(innerCdi);
9075 if (innerCd)
9076 {
9077 AUTO_TRACE("innerCd={} isLinkable={} isImplicitTemplateInstance={} protectLevelVisible={} embeddedInOuterScope={}",
9078 innerCd->name(),innerCd->isLinkableInProject(),innerCd->isImplicitTemplateInstance(),protectionLevelVisible(innerCd->protection()),
9079 innerCd->isEmbeddedInOuterScope());
9080 }
9081 if (innerCd && innerCd->isLinkableInProject() && !innerCd->isImplicitTemplateInstance() &&
9082 protectionLevelVisible(innerCd->protection()) &&
9083 !innerCd->isEmbeddedInOuterScope()
9084 )
9085 {
9086 list.push_back(innerCd);
9087 addClassAndNestedClasses(list,innerCd);
9088 }
9089 }
9090}
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:9069
bool protectionLevelVisible(Protection prot)
Definition util.cpp:6426

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()

static void addClassToContext ( const Entry * root)
static

Definition at line 931 of file doxygen.cpp.

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

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(), CSharp, Entry::doc, Entry::docFile, Entry::docLine, ArgumentList::empty(), Entry::endBodyLine, extractNamespaceName(), FALSE, Entry::fileDef(), Entry::fileName, TagInfo::fileName, QCString::find(), QCString::findRev(), getClassMutable(), getTemplateArgumentsFromName(), Definition::hasDocumentation(), Entry::hidden, Entry::id, FileDef::insertClass(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), EntryType::isCompound(), QCString::isEmpty(), ClassDef::isForwardDeclared(), EntryType::isScope(), Entry::isStatic, Java, 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()

static void addConceptToContext ( const Entry * root)
static

Definition at line 1151 of file doxygen.cpp.

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

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

Referenced by buildConceptDocList(), and buildConceptList().

◆ addDefineDoc()

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

Definition at line 9455 of file doxygen.cpp.

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

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

Referenced by findDefineDocumentation().

◆ addEnumDocs()

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

Definition at line 7897 of file doxygen.cpp.

7898{
7899 AUTO_TRACE();
7900 // documentation outside a compound overrides the documentation inside it
7901 {
7902 md->setDocumentation(root->doc,root->docFile,root->docLine);
7903 md->setDocsForDefinition(!root->proto);
7904 }
7905
7906 // brief descriptions inside a compound override the documentation
7907 // outside it
7908 {
7909 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7910 }
7911
7912 if (md->inbodyDocumentation().isEmpty() || !root->parent()->name.isEmpty())
7913 {
7915 }
7916
7917 if (root->mGrpId!=-1 && md->getMemberGroupId()==-1)
7918 {
7919 md->setMemberGroupId(root->mGrpId);
7920 }
7921
7923 md->setRefItems(root->sli);
7924
7925 const GroupDef *gd=md->getGroupDef();
7926 if (gd==nullptr && !root->groups.empty()) // member not grouped but out-of-line documentation is
7927 {
7928 addMemberToGroups(root,md);
7929 }
7931}
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()

static void addEnumValuesToEnums ( const Entry * root)
static

Definition at line 7647 of file doxygen.cpp.

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

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addEnumValuesToEnums(), AUTO_TRACE, AUTO_TRACE_ADD, buildScopeFromQualifiedName(), Entry::children(), Cpp, createMemberDef(), CSharp, 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(), Java, Entry::lang, QCString::left(), QCString::length(), MemberDefMutable::makeRelated(), mangleCSharpGenericName(), Member, Doxygen::memberNameLinkedMap, mergeScopes(), QCString::mid(), Definition::name(), Entry::name, Normal, 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(), TRUE, and XML.

Referenced by addEnumValuesToEnums(), and parseInput().

◆ addGlobalFunction()

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

Definition at line 3773 of file doxygen.cpp.

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

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

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(), Private, Entry::protection, qPrint(), showFileDefMatches(), QCString::sprintf(), Entry::startLine, stripFromIncludePath(), QCString::stripWhiteSpace(), TRUE, and warn.

Referenced by addClassToContext(), and addConceptToContext().

◆ addInterfaceOrServiceToServiceOrSingleton()

static void addInterfaceOrServiceToServiceOrSingleton ( const Entry * root,
ClassDefMutable * cd,
QCString const & rname )
static

Definition at line 3523 of file doxygen.cpp.

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

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(), Member, Doxygen::memberNameLinkedMap, Entry::metaData, Entry::mGrpId, Normal, Protected, Entry::protection, Entry::proto, Public, 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()

static void addListReferences ( )
static

Definition at line 5441 of file doxygen.cpp.

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

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()

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

Definition at line 6075 of file doxygen.cpp.

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

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, Member, 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()

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

Definition at line 5524 of file doxygen.cpp.

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

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

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

◆ addMemberFunction()

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

Definition at line 6128 of file doxygen.cpp.

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

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(), ObjC, Entry::parent(), QCString::prepend(), Entry::protection, MemberDef::protection(), ClassDef::qualifiedNameWithTemplateParameters(), replaceAnonymousScopes(), rightScopeMatch(), scopeIsTemplate(), Entry::section, MemberDefMutable::setDefinitionTemplateParameterLists(), ArgumentList::size(), Entry::startLine, stripAnonymousNamespaceScope(), QCString::stripPrefix(), stripTemplateSpecifiersFromScope(), substitute(), substituteTemplatesInArgList(), Entry::tArgLists, tempArgListToString(), MemberDef::templateArguments(), toMemberDefMutable(), TRUE, MemberDef::typeString(), Entry::virt, MemberDef::virtualness(), warn, and warn_line().

Referenced by findMember().

◆ addMemberSpecialization()

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

Definition at line 6472 of file doxygen.cpp.

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

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, Member, 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()

static void addMembersToIndex ( )
static

Definition at line 8091 of file doxygen.cpp.

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

static void addMembersToMemberGroup ( )
static

Definition at line 9199 of file doxygen.cpp.

9200{
9201 // for each class
9202 for (const auto &cd : *Doxygen::classLinkedMap)
9203 {
9204 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9205 if (cdm)
9206 {
9208 }
9209 }
9210 // for each file
9211 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9212 {
9213 for (const auto &fd : *fn)
9214 {
9215 fd->addMembersToMemberGroup();
9216 }
9217 }
9218 // for each namespace
9219 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9220 {
9222 if (ndm)
9223 {
9225 }
9226 }
9227 // for each group
9228 for (const auto &gd : *Doxygen::groupLinkedMap)
9229 {
9230 gd->addMembersToMemberGroup();
9231 }
9233}
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()

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

Definition at line 3637 of file doxygen.cpp.

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

References addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, QCString::at(), AUTO_TRACE, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, Config_getBool, Cpp, createMemberDef(), DCOP, Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Entry::exception, Entry::fileDef(), Entry::fileName, QCString::find(), Foreign, 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(), Member, Doxygen::memberNameLinkedMap, MemberOf, Entry::metaData, Entry::mGrpId, Entry::mtype, PHP, Entry::proto, MemberName::push_back(), ClassDef::qualifiedNameWithTemplateParameters(), Entry::qualifiers, Related, 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()

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

Definition at line 6534 of file doxygen.cpp.

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

static 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()

static 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:65
QCString groupname
name of the group
Definition types.h:95

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()

static void addSourceReferences ( )
static

Definition at line 8726 of file doxygen.cpp.

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

static void addToIndices ( )
static

Definition at line 8133 of file doxygen.cpp.

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

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, QCString::str(), and TRUE.

Referenced by parseInput().

◆ addVariable()

static void addVariable ( const Entry * root,
int isFuncPtr = -1 )
static

Definition at line 3100 of file doxygen.cpp.

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

References addVariableToClass(), addVariableToFile(), Entry::args, QCString::at(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::bodyLine, buildScopeFromQualifiedName(), computeQualifiedIndex(), Config_getBool, CSharp, Dictionary, Entry::endBodyLine, EnumValue, Event, FALSE, QCString::find(), findFunctionPtr(), Foreign, Friend, getClass(), getClassMutable(), QCString::isEmpty(), EntryType::isScope(), Entry::lang, QCString::left(), QCString::length(), mangleCSharpGenericName(), Member, MemberOf, mergeScopes(), Entry::mGrpId, QCString::mid(), Entry::mtype, Entry::name, Entry::parent(), QCString::prepend(), Property, Entry::protection, Public, Related, 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()

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 )
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 &&
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 std::string init = root->initializer.str();
2548 mmd->setInitializer(init.c_str());
2549 mmd->setMaxInitLines(root->initLines);
2550 mmd->setMemberGroupId(root->mGrpId);
2551 mmd->setMemberSpecifiers(root->spec);
2552 mmd->setVhdlSpecifiers(root->vhdlSpec);
2553 mmd->setReadAccessor(root->read);
2554 mmd->setWriteAccessor(root->write);
2556 mmd->setHidden(root->hidden);
2557 mmd->setArtificial(root->artificial);
2558 mmd->setLanguage(root->lang);
2559 mmd->setId(root->id);
2560 addMemberToGroups(root,md.get());
2562 mmd->setBodyDef(root->fileDef());
2563 mmd->addQualifiers(root->qualifiers);
2564
2565 AUTO_TRACE_ADD("Adding new member to class '{}'",cd->name());
2566 cd->insertMember(md.get());
2567 mmd->setRefItems(root->sli);
2568
2569 cd->insertUsedFile(root->fileDef());
2570 root->markAsProcessed();
2571
2572 if (mtype==MemberType::Typedef)
2573 {
2574 resolveTemplateInstanceInType(root,cd,md.get());
2575 }
2576
2577 // add the member to the global list
2578 MemberDef *result = md.get();
2579 mn = Doxygen::memberNameLinkedMap->add(name);
2580 mn->push_back(std::move(md));
2581
2582 return result;
2583}
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:4774
@ Python
Definition types.h:52

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(), CSharp, 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, Java, Entry::lang, Entry::markAsProcessed(), Member, Doxygen::memberNameLinkedMap, MemberDef::memberType(), Entry::metaData, Entry::mGrpId, Entry::mtype, Definition::name(), Normal, ObjC, Property, Entry::protection, MemberName::push_back(), Python, 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()

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

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

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

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()

static 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()

static void buildClassDocList ( const Entry * root)
static

Definition at line 1137 of file doxygen.cpp.

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

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

Referenced by buildClassDocList(), and parseInput().

◆ buildClassList()

static void buildClassList ( const Entry * root)
static

Definition at line 1127 of file doxygen.cpp.

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

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

Referenced by buildClassList(), and parseInput().

◆ buildCompleteMemberLists()

static void buildCompleteMemberLists ( )
static

Definition at line 8470 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ buildConceptDocList()

static void buildConceptDocList ( const Entry * root)
static

Definition at line 1286 of file doxygen.cpp.

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

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

Referenced by buildConceptDocList(), and parseInput().

◆ buildConceptList()

static void buildConceptList ( const Entry * root)
static

Definition at line 1276 of file doxygen.cpp.

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

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

Referenced by buildConceptList(), and parseInput().

◆ buildDefineList()

static void buildDefineList ( )
static

Definition at line 8805 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ buildDictionaryList()

static void buildDictionaryList ( const Entry * root)
static

Definition at line 3472 of file doxygen.cpp.

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

References addVariable(), AUTO_TRACE, buildDictionaryList(), Entry::children(), QCString::find(), QCString::isEmpty(), Entry::name, Entry::section, and Entry::type.

Referenced by buildDictionaryList(), and parseInput().

◆ buildExampleList()

static void buildExampleList ( Entry * root)
static

Definition at line 9872 of file doxygen.cpp.

9873{
9874 if ((root->section.isExample() || root->section.isExampleLineno()) && !root->name.isEmpty())
9875 {
9876 if (Doxygen::exampleLinkedMap->find(root->name))
9877 {
9878 warn(root->fileName,root->startLine,"Example {} was already documented. Ignoring documentation found here.",root->name);
9879 }
9880 else
9881 {
9882 PageDef *pd = Doxygen::exampleLinkedMap->add(root->name,
9883 createPageDef(root->fileName,root->startLine,
9884 root->name,root->brief+root->doc+root->inbodyDocs,root->args));
9885 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9886 pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE));
9888 pd->setLanguage(root->lang);
9889 pd->setShowLineNo(root->section.isExampleLineno());
9890
9891 //we don't add example to groups
9892 //addExampleToGroups(root,pd);
9893 }
9894 }
9895 for (const auto &e : root->children()) buildExampleList(e.get());
9896}
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:9872
std::unique_ptr< PageDef > createPageDef(const QCString &f, int l, const QCString &n, const QCString &d, const QCString &t)
Definition pagedef.cpp:79
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:4004

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()

static void buildFileList ( const Entry * root)
static

Definition at line 496 of file doxygen.cpp.

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

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()

static void buildFunctionList ( const Entry * root)
static

Definition at line 3881 of file doxygen.cpp.

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

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(), CSharp, Entry::doc, Entry::docFile, Entry::docLine, Definition::documentation(), Duplicate, ArgumentList::empty(), Entry::endBodyLine, FALSE, Entry::fileDef(), Entry::fileName, QCString::find(), QCString::findRev(), found, 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()

static 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()

static 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:174

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()

static void buildInterfaceAndServiceList ( const Entry * root)
static

Definition at line 3585 of file doxygen.cpp.

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

References addInterfaceOrServiceToServiceOrSingleton(), Entry::args, AUTO_TRACE, Entry::bodyLine, buildInterfaceAndServiceList(), Entry::children(), ClassDef::compoundType(), Entry::docFile, Entry::fileName, getClassMutable(), IDL, 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, Unknown, and warn.

Referenced by buildInterfaceAndServiceList(), and parseInput().

◆ buildListOfUsingDecls()

static 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()

static 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);
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:6360

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, Definition::TypeNamespace, and Unknown.

Referenced by buildNamespaceList(), and parseInput().

◆ buildPageList()

static void buildPageList ( Entry * root)
static

Definition at line 9628 of file doxygen.cpp.

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

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()

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

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

Definition at line 705 of file doxygen.cpp.

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

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()

static void buildSequenceList ( const Entry * root)
static

Definition at line 3454 of file doxygen.cpp.

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

References addVariable(), AUTO_TRACE, buildSequenceList(), Entry::children(), QCString::find(), QCString::isEmpty(), Entry::name, Entry::section, and Entry::type.

Referenced by buildSequenceList(), and parseInput().

◆ buildTypedefList()

static void buildTypedefList ( const Entry * root)
static

Definition at line 3355 of file doxygen.cpp.

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

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(), found, 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()

static void buildVarList ( const Entry * root)
static

Definition at line 3491 of file doxygen.cpp.

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

11848{
11849 AUTO_TRACE();
11850
11855}
void initWarningFormat()
Definition message.cpp:218
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()

static void checkMarkdownMainfile ( )
static

Definition at line 12322 of file doxygen.cpp.

12323{
12324 if (Config_getBool(MARKDOWN_SUPPORT))
12325 {
12326 QCString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
12327 if (mdfileAsMainPage.isEmpty()) return;
12328 FileInfo fi(mdfileAsMainPage.data());
12329 if (!fi.exists())
12330 {
12331 warn_uncond("Specified markdown mainpage '{}' does not exist\n",mdfileAsMainPage);
12332 return;
12333 }
12334 bool ambig = false;
12335 if (findFileDef(Doxygen::inputNameLinkedMap,fi.absFilePath(),ambig)==nullptr)
12336 {
12337 warn_uncond("Specified markdown mainpage '{}' has not been defined as input file\n",mdfileAsMainPage);
12338 return;
12339 }
12340 }
12341}
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()

static void checkPageRelations ( )
static

Definition at line 9767 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ cleanUpDoxygen()

void cleanUpDoxygen ( )

Definition at line 11373 of file doxygen.cpp.

11374{
11378
11379 delete Doxygen::indexList;
11388 Doxygen::mainPage.reset();
11392 Doxygen::globalScope = nullptr;
11394 delete theTranslator;
11395 delete g_outputList;
11396
11401 delete Doxygen::dirLinkedMap;
11402 delete Doxygen::symbolMap;
11403}
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:175
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:80
void clear()
clears the database
Definition cite.cpp:106
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()

static void combineUsingRelations ( )
static

Definition at line 9174 of file doxygen.cpp.

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

static void compareDoxyfile ( Config::CompareMode diffList)
static

Definition at line 10270 of file doxygen.cpp.

10271{
10272 std::ofstream f;
10273 bool fileOpened=openOutputFile("-",f);
10274 if (fileOpened)
10275 {
10276 TextStream t(&f);
10277 Config::compareDoxyfile(t,diffList);
10278 }
10279 else
10280 {
10281 term("Cannot open stdout for writing\n");
10282 }
10283}
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:6783

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

Referenced by readConfiguration().

◆ computeClassRelations()

static void computeClassRelations ( )
static

Definition at line 5313 of file doxygen.cpp.

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

static int computeIdealCacheParam ( size_t v)
static

Definition at line 11405 of file doxygen.cpp.

11406{
11407 //printf("computeIdealCacheParam(v=%u)\n",v);
11408
11409 int r=0;
11410 while (v!=0) v>>=1,r++;
11411 // r = log2(v)
11412
11413 // convert to a valid cache size value
11414 return std::max(0,std::min(r-16,9));
11415}

Referenced by generateOutput().

◆ computeMemberReferences()

static void computeMemberReferences ( )
static

Definition at line 5407 of file doxygen.cpp.

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

static void computeMemberRelations ( )
static

Definition at line 8413 of file doxygen.cpp.

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

References Doxygen::classLinkedMap, and computeMemberRelationsForBaseClass().

Referenced by parseInput().

◆ computeMemberRelationsForBaseClass()

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

Definition at line 8333 of file doxygen.cpp.

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

Referenced by computeMemberRelations(), and computeMemberRelationsForBaseClass().

◆ computePageRelations()

static void computePageRelations ( Entry * root)
static

Definition at line 9737 of file doxygen.cpp.

9738{
9739 if ((root->section.isPageDoc() || root->section.isMainpageDoc()) && !root->name.isEmpty())
9740 {
9741 PageDef *pd = root->section.isPageDoc() ?
9742 Doxygen::pageLinkedMap->find(root->name) :
9743 Doxygen::mainPage.get();
9744 if (pd)
9745 {
9746 for (const BaseInfo &bi : root->extends)
9747 {
9748 PageDef *subPd = Doxygen::pageLinkedMap->find(bi.name);
9749 if (pd==subPd)
9750 {
9751 term("page defined {} with label {} is a direct "
9752 "subpage of itself! Please remove this cyclic dependency.\n",
9753 warn_line(pd->docFile(),pd->docLine()),pd->name());
9754 }
9755 else if (subPd)
9756 {
9757 pd->addInnerCompound(subPd);
9758 //printf("*** Added subpage relation: %s->%s\n",
9759 // qPrint(pd->name()),qPrint(subPd->name()));
9760 }
9761 }
9762 }
9763 }
9764 for (const auto &e : root->children()) computePageRelations(e.get());
9765}
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:9737
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()

static void computeTemplateClassRelations ( )
static

Definition at line 5338 of file doxygen.cpp.

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

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()

static void computeTooltipTexts ( )
static

Definition at line 8893 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ computeVerifiedDotPath()

static void computeVerifiedDotPath ( )
static

Definition at line 10198 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ convertToCompoundType()

static 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()

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

Definition at line 10464 of file doxygen.cpp.

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

References copyFile(), err, FileInfo::exists(), FileInfo::fileName(), Doxygen::indexList, and FileInfo::isDir().

Referenced by generateOutput().

◆ copyIcon()

static void copyIcon ( const QCString & outputOption)
static

Definition at line 10439 of file doxygen.cpp.

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

static void copyLatexStyleSheet ( )
static

Definition at line 10330 of file doxygen.cpp.

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

References checkExtension(), Config_getList, Config_getString, copyFile(), err, FileInfo::exists(), FileInfo::fileName(), FileInfo::isDir(), and LATEX_STYLE_EXTENSION.

Referenced by generateOutput().

◆ copyLogo()

static void copyLogo ( const QCString & outputOption)
static

Definition at line 10414 of file doxygen.cpp.

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

References Config_updateString, copyFile(), err, FileInfo::exists(), FileInfo::fileName(), Doxygen::indexList, FileInfo::isDir(), QCString::isEmpty(), projectLogoFile(), and QCString::str().

Referenced by generateOutput().

◆ copyStyleSheet()

static void copyStyleSheet ( )
static

Definition at line 10361 of file doxygen.cpp.

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

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()

static void countMembers ( )
static

Definition at line 8953 of file doxygen.cpp.

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

static QCString createOutputDirectory ( const QCString & baseDirName,
const QCString & formatDirName,
const char * defaultDirName )
static

Definition at line 12090 of file doxygen.cpp.

12093{
12094 QCString result = formatDirName;
12095 if (result.isEmpty())
12096 {
12097 result = baseDirName + defaultDirName;
12098 }
12099 else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':'))
12100 {
12101 result.prepend(baseDirName+"/");
12102 }
12103 Dir formatDir(result.str());
12104 if (!formatDir.exists() && !formatDir.mkdir(result.str()))
12105 {
12106 term("Could not create output directory {}\n", result);
12107 }
12108 return result;
12109}
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()

static 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
A list of MemberDef objects as shown in documentation sections.
Definition memberlist.h:109
QCString removeAnonymousScopes(const QCString &str)
Definition util.cpp:172

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(), Member, 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()

static void createTemplateInstanceMembers ( )
static

Definition at line 8429 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ createUsingMemberImportForClass()

static 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,
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, Member, 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()

static void devUsage ( )
static

Definition at line 11184 of file doxygen.cpp.

11185{
11187 msg("Developer parameters:\n");
11188 msg(" -m dump symbol map\n");
11189 msg(" -b making messages output unbuffered\n");
11190 msg(" -c <file> process input file as a comment block and produce HTML output\n");
11191#if ENABLE_TRACING
11192 msg(" -t [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout)\n");
11193 msg(" -t_time [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout),\n"
11194 " and include time and thread information\n");
11195#endif
11196 msg(" -d <level> enable a debug level, such as (multiple invocations of -d are possible):\n");
11198}
@ 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()

static void distributeConceptGroups ( )
static

Definition at line 1298 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ distributeMemberGroupDocumentation()

static void distributeMemberGroupDocumentation ( )
static

Definition at line 9237 of file doxygen.cpp.

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

static void dumpSymbol ( TextStream & t,
Definition * d )
static

Definition at line 11143 of file doxygen.cpp.

11144{
11145 QCString anchor;
11147 {
11148 MemberDef *md = toMemberDef(d);
11149 anchor=":"+md->anchor();
11150 }
11151 QCString scope;
11152 QCString fn = d->getOutputFileBase();
11155 {
11156 scope = fn;
11157 }
11158 t << "REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
11159 << fn+anchor << "','"
11160 << scope << "','"
11161 << d->name() << "','"
11162 << d->getDefFileName() << "','"
11163 << d->getDefLine()
11164 << "');\n";
11165}
virtual QCString anchor() const =0
virtual QCString getOutputFileBase() const =0
MemberDef * toMemberDef(Definition *d)
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:5399

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()

static void dumpSymbolMap ( )
static

Definition at line 11167 of file doxygen.cpp.

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

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

Referenced by generateOutput().

◆ exitDoxygen()

static void exitDoxygen ( )
staticnoexcept

Definition at line 12077 of file doxygen.cpp.

12078{
12079 if (!g_successfulRun) // premature exit
12080 {
12081 Dir thisDir;
12082 msg("Exiting...\n");
12083 if (!Doxygen::filterDBFileName.isEmpty())
12084 {
12085 thisDir.remove(Doxygen::filterDBFileName.str());
12086 }
12087 }
12088}
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()

static QCString extractClassName ( const Entry * root)
static

Definition at line 5218 of file doxygen.cpp.

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

References CSharp, QCString::find(), Java, Entry::lang, QCString::left(), mangleCSharpGenericName(), Entry::name, stripAnonymousNamespaceScope(), and stripTemplateSpecifiersFromScope().

Referenced by computeClassRelations(), findInheritedTemplateInstances(), and findUsedTemplateInstances().

◆ filterMemberDocumentation()

static void filterMemberDocumentation ( const Entry * root,
const QCString & relates )
static

Definition at line 7264 of file doxygen.cpp.

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

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()

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

Definition at line 4672 of file doxygen.cpp.

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

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()

static const ClassDef * findClassDefinition ( FileDef * fd,
NamespaceDef * nd,
const QCString & scopeName )
static

Definition at line 5674 of file doxygen.cpp.

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

References SymbolResolver::resolveClass().

Referenced by addMemberFunction().

◆ findClassEntries()

static void findClassEntries ( const Entry * root)
static

Builds a dictionary of all entry nodes in the tree starting with root

Definition at line 5209 of file doxygen.cpp.

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

References Entry::children(), findClassEntries(), g_classEntries, isClassSection(), Entry::name, and QCString::str().

Referenced by findClassEntries(), and parseInput().

◆ findClassRelation()

static bool findClassRelation ( const Entry * root,
Definition * context,
ClassDefMutable * cd,
const BaseInfo * bi,
const TemplateNameMap & templateNames,
FindBaseClassRelation_Mode mode,
bool isArtificial )
static

Definition at line 4846 of file doxygen.cpp.

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

References AUTO_TRACE, AUTO_TRACE_ADD, buildScopeFromQualifiedName(), ClassDef::Class, Doxygen::classLinkedMap, QCString::clear(), Config_getBool, createClassDef(), CSharp, DocumentedOnly, end(), QCString::endsWith(), FALSE, Entry::fileDef(), Entry::fileName, findClassWithinClassContext(), QCString::findRev(), findScopeFromQualifiedName(), findTemplateInstanceRelation(), findTemplateSpecializationPosition(), found, getClassMutable(), ClassDef::getFileDef(), SymbolResolver::getTemplateSpec(), SymbolResolver::getTypedef(), Doxygen::globalScope, Doxygen::hiddenClassLinkedMap, IDL, 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, Public, 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()

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

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

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

Referenced by findClassRelation(), and findUsedClassesForClass().

◆ findDefineDocumentation()

static void findDefineDocumentation ( Entry * root)
static

Definition at line 9480 of file doxygen.cpp.

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

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, Member, MemberDef::memberType(), Entry::name, Normal, Entry::parent(), Public, MemberName::push_back(), Entry::section, Entry::startLine, Entry::tagInfo(), TagInfo::tagName, toMemberDefMutable(), and warn.

Referenced by findDefineDocumentation(), and parseInput().

◆ findDEV()

static void findDEV ( const MemberNameLinkedMap & mnsd)
static

Definition at line 8057 of file doxygen.cpp.

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

static void findDirDocumentation ( const Entry * root)
static

Definition at line 9566 of file doxygen.cpp.

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

References addDirToGroups(), 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()

static void findDocumentedEnumValues ( )
static

Definition at line 8083 of file doxygen.cpp.

8084{
8087}
static void findDEV(const MemberNameLinkedMap &mnsd)
Definition doxygen.cpp:8057

References findDEV(), Doxygen::functionNameLinkedMap, and Doxygen::memberNameLinkedMap.

Referenced by parseInput().

◆ findEnumDocumentation()

static void findEnumDocumentation ( const Entry * root)
static

Definition at line 7971 of file doxygen.cpp.

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

References addEnumDocs(), QCString::at(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::children(), Entry::fileDef(), Entry::fileName, findEnumDocumentation(), QCString::findRev(), found, 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()

static void findEnums ( const Entry * root)
static

Definition at line 7472 of file doxygen.cpp.

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

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(), CSharp, Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, Enumeration, FALSE, Entry::fileDef(), Entry::fileName, findEnums(), QCString::findRev(), Foreign, 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(), Member, Doxygen::memberNameLinkedMap, MemberOf, mergeScopes(), Entry::metaData, Entry::mGrpId, Definition::name(), Entry::name, Normal, Entry::parent(), QCString::prepend(), Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, Related, 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()

static void findFriends ( )
static

Definition at line 4187 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ findFunctionPtr()

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

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

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

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

◆ findGlobalMember()

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

Definition at line 5710 of file doxygen.cpp.

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

References addMemberDocs(), Entry::argList, argListToString(), AUTO_TRACE, AUTO_TRACE_ADD, Config_getBool, Duplicate, ArgumentList::empty(), FALSE, Entry::fileDef(), Entry::fileName, LinkedRefMap< T, Hash, KeyEqual, Map >::find(), QCString::find(), QCString::findRev(), found, 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()

static 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()

static 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()

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

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

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

Referenced by parseInput().

◆ findMainPage()

static void findMainPage ( Entry * root)
static

Definition at line 9655 of file doxygen.cpp.

9656{
9657 if (root->section.isMainpageDoc())
9658 {
9659 if (Doxygen::mainPage==nullptr && root->tagInfo()==nullptr)
9660 {
9661 //printf("mainpage: docLine=%d startLine=%d\n",root->docLine,root->startLine);
9662 //printf("Found main page! \n======\n%s\n=======\n",qPrint(root->doc));
9663 QCString title=root->args.stripWhiteSpace();
9664 if (title.isEmpty()) title = Config_getString(PROJECT_NAME);
9665 //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9666 QCString indexName="index";
9668 indexName, root->brief+root->doc+root->inbodyDocs,title);
9669 //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
9670 Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9671 Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1);
9672 Doxygen::mainPage->setFileName(indexName);
9673 Doxygen::mainPage->setLocalToc(root->localToc);
9675
9677 if (si)
9678 {
9679 if (!si->ref().isEmpty()) // we are from a tag file
9680 {
9681 // a page name is a label as well! but should no be double either
9683 Doxygen::mainPage->name(),
9684 indexName,
9685 root->startLine,
9686 Doxygen::mainPage->title(),
9688 0); // level 0
9689 }
9690 else if (si->lineNr() != -1)
9691 {
9692 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {}, line {})",
9693 Doxygen::mainPage->name(),si->fileName(),si->lineNr());
9694 }
9695 else
9696 {
9697 warn(root->fileName,root->startLine,"multiple use of section label '{}' for main page, (first occurrence: {})",
9698 Doxygen::mainPage->name(),si->fileName());
9699 }
9700 }
9701 else
9702 {
9703 // a page name is a label as well! but should no be double either
9705 Doxygen::mainPage->name(),
9706 indexName,
9707 root->startLine,
9708 Doxygen::mainPage->title(),
9710 0); // level 0
9711 }
9712 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9713 }
9714 else if (root->tagInfo()==nullptr)
9715 {
9716 warn(root->fileName,root->startLine,
9717 "found more than one \\mainpage comment block! (first occurrence: {}, line {}), Skipping current block!",
9718 Doxygen::mainPage->docFile(),Doxygen::mainPage->getStartBodyLine());
9719 }
9720 }
9721 for (const auto &e : root->children()) findMainPage(e.get());
9722}
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:154
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:9655

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()

static void findMainPageTagFiles ( Entry * root)
static

Definition at line 9725 of file doxygen.cpp.

9726{
9727 if (root->section.isMainpageDoc())
9728 {
9729 if (Doxygen::mainPage && root->tagInfo())
9730 {
9731 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9732 }
9733 }
9734 for (const auto &e : root->children()) findMainPageTagFiles(e.get());
9735}
static void findMainPageTagFiles(Entry *root)
Definition doxygen.cpp:9725

References Entry::anchors, Entry::children(), findMainPageTagFiles(), Doxygen::mainPage, Entry::section, and Entry::tagInfo().

Referenced by findMainPageTagFiles(), and parseInput().

◆ findMember()

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

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

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, Duplicate, Entry::endBodyLine, Event, extractNamespaceName(), FALSE, Entry::fileDef(), Entry::fileName, QCString::find(), findGlobalMember(), Foreign, found, 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, MemberOf, mergeScopes(), Entry::metaData, Method, 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, Related, Entry::relatesType, FileDef::removeMember(), removeRedundantWhiteSpace(), QCString::right(), Entry::section, MemberDefMutable::setMemberClass(), Signal, MemberName::size(), Entry::sli, Slot, Entry::spec, Entry::startColumn, Entry::startLine, QCString::startsWith(), QCString::stripPrefix(), stripTemplateSpecifiersFromScope(), QCString::stripWhiteSpace(), substitute(), Entry::tagInfo(), Entry::tArgLists, toMemberDefMutable(), TRUE, Entry::vhdlSpec, Entry::virt, warn, and warn_undoc.

Referenced by filterMemberDocumentation(), and findObjCMethodDefinitions().

◆ findMemberDocumentation()

static void findMemberDocumentation ( const Entry * root)
static

Definition at line 7414 of file doxygen.cpp.

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

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

Referenced by findMemberDocumentation(), and parseInput().

◆ findModuleDocumentation()

static void findModuleDocumentation ( const Entry * root)
static

Definition at line 1266 of file doxygen.cpp.

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

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

Referenced by findModuleDocumentation(), and parseInput().

◆ findObjCMethodDefinitions()

static void findObjCMethodDefinitions ( const Entry * root)
static

Definition at line 7444 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ findScopeFromQualifiedName()

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

Definition at line 774 of file doxygen.cpp.

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

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

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

◆ findSectionsInDocumentation()

static void findSectionsInDocumentation ( )
static

Definition at line 9275 of file doxygen.cpp.

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

References Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, 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]

static 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]

static 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()

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

Definition at line 4723 of file doxygen.cpp.

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

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()

static int findTemplateSpecializationPosition ( const QCString & name)
static

Definition at line 4816 of file doxygen.cpp.

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

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

Referenced by findClassRelation().

◆ findUsedClassesForClass()

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

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

References ClassDefMutable::addUsedByClass(), ClassDefMutable::addUsedClass(), MemberDef::argsString(), AUTO_TRACE, AUTO_TRACE_ADD, ClassDef::Class, Config_getBool, createClassDef(), QCString::endsWith(), extractClassNameFromType(), FALSE, QCString::find(), findClassRelation(), findClassWithinClassContext(), found, Definition::getDefColumn(), Definition::getDefFileName(), Definition::getDefLine(), ClassDef::getFileDef(), Definition::getLanguage(), getTemplateArgumentsInName(), Doxygen::hiddenClassLinkedMap, QCString::isEmpty(), MemberDef::isObjCProperty(), MemberDef::isVariable(), Java, Entry::lang, ClassDefMutable::makeTemplateArgument(), ClassDef::memberNameInfoLinkedMap(), Definition::name(), Normal, normalizeNonTemplateArgumentsInString(), MemberDef::protection(), Public, 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()

static 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()

static void findUsedTemplateInstances ( )
static

Definition at line 5277 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ findUsingDeclarations()

static 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)
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(), Python, SymbolResolver::resolveSymbol(), Entry::section, DefinitionMutable::setArtificial(), DefinitionMutable::setLanguage(), Entry::startLine, substitute(), Entry::tArgLists, toClassDefMutable(), and TRUE.

Referenced by findUsingDeclarations(), and parseInput().

◆ findUsingDeclImports()

static 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,
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:785
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(), Cpp, 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(), Member, ClassDef::memberNameInfoLinkedMap(), Doxygen::memberNameLinkedMap, MemberDef::memberType(), Entry::metaData, Entry::mGrpId, ClassDef::moveTo(), Definition::name(), Entry::name, Entry::parent(), Private, 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()

static 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(), Java, 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()

static void flushCachedTemplateRelations ( )
static

Definition at line 9329 of file doxygen.cpp.

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

static void flushUnresolvedRelations ( )
static

Definition at line 9383 of file doxygen.cpp.

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

static StringUnorderedSet g_pathsVisited ( 1009 )
static

Referenced by readDir(), and readFileOrDirectory().

◆ generateClassDocs()

static void generateClassDocs ( )
static

Definition at line 9092 of file doxygen.cpp.

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

References addClassAndNestedClasses(), Doxygen::classLinkedMap, Definition::definitionType(), generateDocsForClassList(), Definition::getOuterScope(), Doxygen::hiddenClassLinkedMap, toClassDefMutable(), and Definition::TypeClass.

Referenced by generateOutput().

◆ generateConceptDocs()

static void generateConceptDocs ( )
static

Definition at line 9118 of file doxygen.cpp.

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

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

10238{
10239 std::ofstream f;
10240 bool fileOpened=openOutputFile(configFile,f);
10241 bool writeToStdout=configFile=="-";
10242 if (fileOpened)
10243 {
10244 TextStream t(&f);
10245 Config::writeTemplate(t,shortList,updateOnly);
10246 if (!writeToStdout)
10247 {
10248 if (!updateOnly)
10249 {
10250 msg("\n\nConfiguration file '{}' created.\n\n",configFile);
10251 msg("Now edit the configuration file and enter\n\n");
10252 if (configFile!="Doxyfile" && configFile!="doxyfile")
10253 msg(" doxygen {}\n\n",configFile);
10254 else
10255 msg(" doxygen\n\n");
10256 msg("to generate the documentation for your project\n\n");
10257 }
10258 else
10259 {
10260 msg("\n\nConfiguration file '{}' updated.\n\n",configFile);
10261 }
10262 }
10263 }
10264 else
10265 {
10266 term("Cannot open file {} for writing\n",configFile);
10267 }
10268}
void writeTemplate(TextStream &t, bool shortList, bool updateOnly=FALSE)

References FALSE, msg, openOutputFile(), term, and Config::writeTemplate().

Referenced by readConfiguration().

◆ generateDiskNames()

static void generateDiskNames ( )
static

Definition at line 10491 of file doxygen.cpp.

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

static void generateDocsForClassList ( const std::vector< ClassDefMutable * > & classList)
static

Definition at line 8994 of file doxygen.cpp.

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

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

Referenced by generateClassDocs().

◆ generateExampleDocs()

static void generateExampleDocs ( )
static

Definition at line 9940 of file doxygen.cpp.

9941{
9942 g_outputList->disable(OutputType::Man);
9943 for (const auto &pd : *Doxygen::exampleLinkedMap)
9944 {
9945 msg("Generating docs for example {}...\n",pd->name());
9947 if (lang != SrcLangExt::Unknown)
9948 {
9949 QCString ext = getFileNameExtension(pd->name());
9950 auto intf = Doxygen::parserManager->getCodeParser(ext);
9951 intf->resetCodeParserState();
9952 }
9953 QCString n=pd->getOutputFileBase();
9954 startFile(*g_outputList,n,n,pd->name());
9956 g_outputList->docify(pd->name());
9958 g_outputList->startContents();
9959 QCString lineNoOptStr;
9960 if (pd->showLineNo())
9961 {
9962 lineNoOptStr="{lineno}";
9963 }
9964 g_outputList->generateDoc(pd->docFile(), // file
9965 pd->docLine(), // startLine
9966 pd.get(), // context
9967 nullptr, // memberDef
9968 (pd->briefDescription().isEmpty()?"":pd->briefDescription()+"\n\n")+
9969 pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
9970 TRUE, // index words
9971 TRUE, // is example
9972 pd->name(),
9973 FALSE,
9974 FALSE,
9975 Config_getBool(MARKDOWN_SUPPORT)
9976 );
9977 endFile(*g_outputList); // contains g_outputList->endContents()
9978 }
9980}
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:426
void endTitle(OutputList &ol, const QCString &fileName, const QCString &name)
Definition index.cpp:393
void startFile(OutputList &ol, const QCString &name, const QCString &manName, const QCString &title, HighlightedItem hli, bool additionalIndices, const QCString &altSidebarName, int hierarchyLevel)
Definition index.cpp:400
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5705
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5747

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

Referenced by generateOutput().

◆ generateFileDocs()

static void generateFileDocs ( )
static

Definition at line 8666 of file doxygen.cpp.

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

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

Referenced by generateOutput().

◆ generateFileSources()

static void generateFileSources ( )
static

Definition at line 8500 of file doxygen.cpp.

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

References FileDef::absFilePath(), Doxygen::clangAssistedParsing, Config_getInt, Cpp, 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()

static void generateGroupDocs ( )
static

Definition at line 9985 of file doxygen.cpp.

9986{
9987 for (const auto &gd : *Doxygen::groupLinkedMap)
9988 {
9989 if (!gd->isReference())
9990 {
9991 gd->writeDocumentation(*g_outputList);
9992 }
9993 }
9994}

References g_outputList, and Doxygen::groupLinkedMap.

Referenced by generateOutput().

◆ generateNamespaceClassDocs()

static void generateNamespaceClassDocs ( const ClassLinkedRefMap & classList)
static

Definition at line 9999 of file doxygen.cpp.

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

static void generateNamespaceConceptDocs ( const ConceptLinkedRefMap & conceptList)
static

Definition at line 10071 of file doxygen.cpp.

10072{
10073 // for each concept in the namespace...
10074 for (const auto &cd : conceptList)
10075 {
10077 if ( cdm && cd->isLinkableInProject() && !cd->isHidden())
10078 {
10079 msg("Generating docs for concept {}...\n",cd->name());
10081 }
10082 }
10083}

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

Referenced by generateNamespaceDocs().

◆ generateNamespaceDocs()

static void generateNamespaceDocs ( )
static

Definition at line 10085 of file doxygen.cpp.

10086{
10087 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
10088
10089 //writeNamespaceIndex(*g_outputList);
10090
10091 // for each namespace...
10092 for (const auto &nd : *Doxygen::namespaceLinkedMap)
10093 {
10094 if (nd->isLinkableInProject())
10095 {
10097 if (ndm)
10098 {
10099 msg("Generating docs for namespace {}\n",nd->displayName());
10101 }
10102 }
10103
10104 generateNamespaceClassDocs(nd->getClasses());
10105 if (sliceOpt)
10106 {
10107 generateNamespaceClassDocs(nd->getInterfaces());
10108 generateNamespaceClassDocs(nd->getStructs());
10109 generateNamespaceClassDocs(nd->getExceptions());
10110 }
10111 generateNamespaceConceptDocs(nd->getConcepts());
10112 }
10113}
virtual void writeDocumentation(OutputList &ol)=0
static void generateNamespaceConceptDocs(const ConceptLinkedRefMap &conceptList)
static void generateNamespaceClassDocs(const ClassLinkedRefMap &classList)
Definition doxygen.cpp:9999

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

13019{
13020 AUTO_TRACE();
13021 /**************************************************************************
13022 * Initialize output generators *
13023 **************************************************************************/
13024
13025 /// add extra languages for which we can only produce syntax highlighted code
13027
13028 //// dump all symbols
13029 if (g_dumpSymbolMap)
13030 {
13031 dumpSymbolMap();
13032 exit(0);
13033 }
13034
13035 bool generateHtml = Config_getBool(GENERATE_HTML);
13036 bool generateLatex = Config_getBool(GENERATE_LATEX);
13037 bool generateMan = Config_getBool(GENERATE_MAN);
13038 bool generateRtf = Config_getBool(GENERATE_RTF);
13039 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
13040
13041
13043 if (generateHtml)
13044 {
13048 }
13049 if (generateLatex)
13050 {
13053 }
13054 if (generateDocbook)
13055 {
13058 }
13059 if (generateMan)
13060 {
13061 g_outputList->add<ManGenerator>();
13063 }
13064 if (generateRtf)
13065 {
13066 g_outputList->add<RTFGenerator>();
13068 }
13069 if (Config_getBool(USE_HTAGS))
13070 {
13072 QCString htmldir = Config_getString(HTML_OUTPUT);
13073 if (!Htags::execute(htmldir))
13074 err("USE_HTAGS is YES but htags(1) failed. \n");
13075 else if (!Htags::loadFilemap(htmldir))
13076 err("htags(1) ended normally but failed to load the filemap. \n");
13077 }
13078
13079 /**************************************************************************
13080 * Generate documentation *
13081 **************************************************************************/
13082
13083 g_s.begin("Generating style sheet...\n");
13084 //printf("writing style info\n");
13085 g_outputList->writeStyleInfo(0); // write first part
13086 g_s.end();
13087
13088 bool searchEngine = Config_getBool(SEARCHENGINE);
13089 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
13090
13091 g_s.begin("Generating search indices...\n");
13092 if (searchEngine && !serverBasedSearch && generateHtml)
13093 {
13095 }
13096
13097 // generate search indices (need to do this before writing other HTML
13098 // pages as these contain a drop down menu with options depending on
13099 // what categories we find in this function.
13100 if (generateHtml && searchEngine)
13101 {
13102 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
13103 Dir searchDir(searchDirName.str());
13104 if (!searchDir.exists() && !searchDir.mkdir(searchDirName.str()))
13105 {
13106 term("Could not create search results directory '{}' $PWD='{}'\n",
13107 searchDirName,Dir::currentDirPath());
13108 }
13109 HtmlGenerator::writeSearchData(searchDirName);
13110 if (!serverBasedSearch) // client side search index
13111 {
13113 }
13114 }
13115 g_s.end();
13116
13117 // copy static stuff
13118 if (generateHtml)
13119 {
13122 copyLogo(Config_getString(HTML_OUTPUT));
13123 copyIcon(Config_getString(HTML_OUTPUT));
13124 copyExtraFiles(Config_getList(HTML_EXTRA_FILES),"HTML_EXTRA_FILES",Config_getString(HTML_OUTPUT));
13125 }
13126 if (generateLatex)
13127 {
13129 copyLogo(Config_getString(LATEX_OUTPUT));
13130 copyIcon(Config_getString(LATEX_OUTPUT));
13131 copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT));
13132 }
13133 if (generateDocbook)
13134 {
13135 copyLogo(Config_getString(DOCBOOK_OUTPUT));
13136 copyIcon(Config_getString(DOCBOOK_OUTPUT));
13137 }
13138 if (generateRtf)
13139 {
13140 copyLogo(Config_getString(RTF_OUTPUT));
13141 copyIcon(Config_getString(RTF_OUTPUT));
13142 copyExtraFiles(Config_getList(RTF_EXTRA_FILES),"RTF_EXTRA_FILES",Config_getString(RTF_OUTPUT));
13143 }
13144
13146 if (fm.hasFormulas() && generateHtml
13147 && !Config_getBool(USE_MATHJAX))
13148 {
13149 g_s.begin("Generating images for formulas in HTML...\n");
13150 fm.generateImages(Config_getString(HTML_OUTPUT), Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg ?
13152 g_s.end();
13153 }
13154 if (fm.hasFormulas() && generateRtf)
13155 {
13156 g_s.begin("Generating images for formulas in RTF...\n");
13158 g_s.end();
13159 }
13160
13161 if (fm.hasFormulas() && generateDocbook)
13162 {
13163 g_s.begin("Generating images for formulas in Docbook...\n");
13165 g_s.end();
13166 }
13167
13168 g_s.begin("Generating example documentation...\n");
13170 g_s.end();
13171
13172 g_s.begin("Generating file sources...\n");
13174 g_s.end();
13175
13176 g_s.begin("Generating file documentation...\n");
13178 g_s.end();
13179
13180 g_s.begin("Generating page documentation...\n");
13182 g_s.end();
13183
13184 g_s.begin("Generating group documentation...\n");
13186 g_s.end();
13187
13188 g_s.begin("Generating class documentation...\n");
13190 g_s.end();
13191
13192 g_s.begin("Generating concept documentation...\n");
13194 g_s.end();
13195
13196 g_s.begin("Generating module documentation...\n");
13198 g_s.end();
13199
13200 g_s.begin("Generating namespace documentation...\n");
13202 g_s.end();
13203
13204 if (Config_getBool(GENERATE_LEGEND))
13205 {
13206 g_s.begin("Generating graph info page...\n");
13208 g_s.end();
13209 }
13210
13211 g_s.begin("Generating directory documentation...\n");
13213 g_s.end();
13214
13215 if (g_outputList->size()>0)
13216 {
13218 }
13219
13220 g_s.begin("finalizing index lists...\n");
13221 Doxygen::indexList->finalize();
13222 g_s.end();
13223
13224 g_s.begin("writing tag file...\n");
13225 writeTagFile();
13226 g_s.end();
13227
13228 if (Config_getBool(GENERATE_XML))
13229 {
13230 g_s.begin("Generating XML output...\n");
13232 generateXML();
13234 g_s.end();
13235 }
13236 if (Config_getBool(GENERATE_SQLITE3))
13237 {
13238 g_s.begin("Generating SQLITE3 output...\n");
13240 g_s.end();
13241 }
13242
13243 if (Config_getBool(GENERATE_AUTOGEN_DEF))
13244 {
13245 g_s.begin("Generating AutoGen DEF output...\n");
13246 generateDEF();
13247 g_s.end();
13248 }
13249 if (Config_getBool(GENERATE_PERLMOD))
13250 {
13251 g_s.begin("Generating Perl module output...\n");
13253 g_s.end();
13254 }
13255 if (generateHtml && searchEngine && serverBasedSearch)
13256 {
13257 g_s.begin("Generating search index\n");
13258 if (Doxygen::searchIndex.kind()==SearchIndexIntf::Internal) // write own search index
13259 {
13261 Doxygen::searchIndex.write(Config_getString(HTML_OUTPUT)+"/search/search.idx");
13262 }
13263 else // write data for external search index
13264 {
13266 QCString searchDataFile = Config_getString(SEARCHDATA_FILE);
13267 if (searchDataFile.isEmpty())
13268 {
13269 searchDataFile="searchdata.xml";
13270 }
13271 if (!Portable::isAbsolutePath(searchDataFile.data()))
13272 {
13273 searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/");
13274 }
13275 Doxygen::searchIndex.write(searchDataFile);
13276 }
13277 g_s.end();
13278 }
13279
13280 if (generateRtf)
13281 {
13282 g_s.begin("Combining RTF output...\n");
13283 if (!RTFGenerator::preProcessFileInplace(Config_getString(RTF_OUTPUT),"refman.rtf"))
13284 {
13285 err("An error occurred during post-processing the RTF files!\n");
13286 }
13287 g_s.end();
13288 }
13289
13290 g_s.begin("Running plantuml with JAVA...\n");
13292 g_s.end();
13293
13294 if (Config_getBool(HAVE_DOT))
13295 {
13296 g_s.begin("Running dot...\n");
13298 g_s.end();
13299 }
13300
13301 if (generateHtml &&
13302 Config_getBool(GENERATE_HTMLHELP) &&
13303 !Config_getString(HHC_LOCATION).isEmpty())
13304 {
13305 g_s.begin("Running html help compiler...\n");
13307 g_s.end();
13308 }
13309
13310 if ( generateHtml &&
13311 Config_getBool(GENERATE_QHP) &&
13312 !Config_getString(QHG_LOCATION).isEmpty())
13313 {
13314 g_s.begin("Running qhelpgenerator...\n");
13316 g_s.end();
13317 }
13318
13319 g_outputList->cleanup();
13320
13321 msg("type lookup cache used {}/{} hits={} misses={}\n",
13323 Doxygen::typeLookupCache->capacity(),
13325 Doxygen::typeLookupCache->misses());
13326 msg("symbol lookup cache used {}/{} hits={} misses={}\n",
13328 Doxygen::symbolLookupCache->capacity(),
13330 Doxygen::symbolLookupCache->misses());
13331 int typeCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::typeLookupCache->misses()*2/3)); // part of the cache is flushed, hence the 2/3 correction factor
13332 int symbolCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::symbolLookupCache->misses()));
13333 int cacheParam = std::max(typeCacheParam,symbolCacheParam);
13334 if (cacheParam>Config_getInt(LOOKUP_CACHE_SIZE))
13335 {
13336 msg("Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is {} at the cost of higher memory usage.\n",cacheParam);
13337 }
13338
13340 {
13341
13342 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
13343 if (numThreads<1) numThreads=1;
13344 msg("Total elapsed time: {:.6f} seconds\n(of which an average of {:.6f} seconds per thread waiting for external tools to finish)\n",
13345 (static_cast<double>(Debug::elapsedTime())),
13346 Portable::getSysElapsedTime()/static_cast<double>(numThreads)
13347 );
13348 g_s.print();
13349
13351 msg("finished...\n");
13353 }
13354 else
13355 {
13356 msg("finished...\n");
13357 }
13358
13359
13360 /**************************************************************************
13361 * Start cleaning up *
13362 **************************************************************************/
13363
13365
13367 Dir thisDir;
13368 thisDir.remove(Doxygen::filterDBFileName.str());
13370 exitTracing();
13372 delete Doxygen::clangUsrMap;
13374
13375 //dumpDocNodeSizes();
13376}
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
static double elapsedTime()
Definition debug.cpp:201
static void setFlag(const DebugMask mask)
Definition debug.cpp:117
static std::string currentDirPath()
Definition dir.cpp:340
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
static void generateTreeViewImages()
Definition ftvhelp.cpp:851
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:95
static void init()
Definition htmlgen.cpp:1136
static void writeSearchPage()
Definition htmlgen.cpp:3094
static void writeTabData()
Additional initialization after indices have been created.
Definition htmlgen.cpp:1292
static void writeSearchData(const QCString &dir)
Definition htmlgen.cpp:1330
static void writeExternalSearchPage()
Definition htmlgen.cpp:3194
Generator for LaTeX output.
Definition latexgen.h:94
static void init()
Definition latexgen.cpp:628
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:157
void run()
Run plant UML tool for all images.
Definition plantuml.cpp:315
Generator for RTF output.
Definition rtfgen.h:80
static void init()
Definition rtfgen.cpp:458
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:2458
void generateDEF()
Definition defgen.cpp:525
void generateDirDocs(OutputList &ol)
Definition dirdef.cpp:1146
static void copyLatexStyleSheet()
static void runQHelpGenerator()
class Statistics g_s
static void copyStyleSheet()
static void generateGroupDocs()
Definition doxygen.cpp:9985
static void generateExampleDocs()
Definition doxygen.cpp:9940
static void dumpSymbolMap()
static void generateFileDocs()
Definition doxygen.cpp:8666
static void copyIcon(const QCString &outputOption)
static void generatePageDocs()
Definition doxygen.cpp:9855
static void generateFileSources()
Definition doxygen.cpp:8500
static void copyLogo(const QCString &outputOption)
static void generateClassDocs()
Definition doxygen.cpp:9092
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:9118
void writeGraphInfo(OutputList &ol)
Definition index.cpp:4000
void writeIndexHierarchy(OutputList &ol)
Definition index.cpp:5648
void finishWarnExit()
Definition message.cpp:276
void deinit()
bool isAbsolutePath(const QCString &fileName)
Definition portable.cpp:514
double getSysElapsedTime()
Definition portable.cpp:98
void generatePerlMod()
void finalizeSearchIndexer()
void createJavaScriptSearchIndex()
void writeJavaScriptSearchIndex()
void generateSqlite3()
static bool execute(const QCString &htmldir)
Definition htags.cpp:38
static bool loadFilemap(const QCString &htmldir)
Definition htags.cpp:107
void exitTracing()
Definition trace.cpp:52
void addCodeOnlyMappings()
Definition util.cpp:5699
void generateXML()
Definition xmlgen.cpp:2198

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(), FTVHelp::generateTreeViewImages(), 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()

static void generatePageDocs ( )
static

Definition at line 9855 of file doxygen.cpp.

9856{
9857 //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageLinkedMap->count());
9858 if (Index::instance().numDocumentedPages()==0) return;
9859 for (const auto &pd : *Doxygen::pageLinkedMap)
9860 {
9861 if (!pd->getGroupDef() && !pd->isReference())
9862 {
9863 msg("Generating docs for page {}...\n",pd->name());
9864 pd->writeDocumentation(*g_outputList);
9865 }
9866 }
9867}

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

Referenced by generateOutput().

◆ generateXRefPages()

static void generateXRefPages ( )
static

Definition at line 5510 of file doxygen.cpp.

5511{
5512 AUTO_TRACE();
5514 {
5515 rl->generatePage();
5516 }
5517}
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()

static const char * getArg ( int argc,
char ** argv,
int & optInd )
static

Definition at line 11277 of file doxygen.cpp.

11278{
11279 char *s=nullptr;
11280 if (qstrlen(&argv[optInd][2])>0)
11281 s=&argv[optInd][2];
11282 else if (optInd+1<argc && argv[optInd+1][0]!='-')
11283 s=argv[++optInd];
11284 return s;
11285}
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()

static std::unique_ptr< OutlineParserInterface > getParserForFile ( const QCString & fn)
static

Definition at line 10568 of file doxygen.cpp.

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

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()

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

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

References end().

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

◆ haveEqualFileNames()

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

Definition at line 9442 of file doxygen.cpp.

9443{
9444 const FileDef *fd = md->getFileDef();
9445 if (!fd)
9446 {
9447 return FALSE;
9448 }
9449
9450 return fd->absFilePath() == root->fileName;
9451}

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

Referenced by findDefineDocumentation().

◆ inheritDocumentation()

static void inheritDocumentation ( )
static

Definition at line 9139 of file doxygen.cpp.

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

11305{
11306 initResources();
11307 QCString lang = Portable::getenv("LC_ALL");
11308 if (!lang.isEmpty()) Portable::setenv("LANG",lang);
11309 std::setlocale(LC_ALL,"");
11310 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
11311 std::setlocale(LC_NUMERIC,"C");
11312
11314
11338
11339 // register any additional parsers here...
11340
11342
11343#if USE_LIBCLANG
11345#endif
11354 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
11355 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
11356 //Doxygen::tagDestinationDict.setAutoDelete(TRUE);
11358
11359 // initialization of these globals depends on
11360 // configuration switches so we need to postpone these
11361 Doxygen::globalScope = nullptr;
11370
11371}
static void startTimer()
Definition debug.cpp:196
A linked map of directories.
Definition dirdef.h:172
A list of index interfaces.
Definition indexlist.h:63
Manages programming language parsers.
Definition parserintf.h:147
std::function< std::unique_ptr< T >() > make_parser_factory()
void initResources()
std::unordered_map< std::string, const Definition * > ClangUsrMap
Definition doxygen.h:83
void setenv(const QCString &variable, const QCString &value)
Definition portable.cpp:303
QCString getenv(const QCString &variable)
Definition portable.cpp:338
void initDefaultExtensionMapping()
Definition util.cpp:5632

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()

static void insertMemberAlias ( Definition * outerScope,
const MemberDef * md )
static

Definition at line 6601 of file doxygen.cpp.

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

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()

static bool isClassSection ( const Entry * root)
static

Definition at line 5187 of file doxygen.cpp.

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

References Entry::extends, FALSE, EntryType::isCompound(), EntryType::isCompoundDoc(), QCString::isEmpty(), Entry::name, Entry::section, and TRUE.

Referenced by findClassEntries().

◆ isEntryInGroupOfMember()

static bool isEntryInGroupOfMember ( const Entry * root,
const MemberDef * md,
bool allowNoGroup = false )
static

Definition at line 5686 of file doxygen.cpp.

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

References MemberDef::getGroupDef(), Entry::groups, and Definition::name().

Referenced by findDefineDocumentation(), and findGlobalMember().

◆ isRecursiveBaseClass()

static bool isRecursiveBaseClass ( const QCString & scope,
const QCString & name )
static

Definition at line 4804 of file doxygen.cpp.

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

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

Referenced by findClassRelation().

◆ isSpecialization()

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

Definition at line 5917 of file doxygen.cpp.

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

References FALSE, and TRUE.

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

◆ isSymbolHidden()

static bool isSymbolHidden ( const Definition * d)
static

Definition at line 8886 of file doxygen.cpp.

8887{
8888 bool hidden = d->isHidden();
8889 const Definition *parent = d->getOuterScope();
8890 return parent ? hidden || isSymbolHidden(parent) : hidden;
8891}
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:1324

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

Referenced by computeTooltipTexts(), and isSymbolHidden().

◆ isVarWithConstructor()

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

2889{
2890 bool result = false;
2891 bool typeIsClass = false;
2892 bool typePtrType = false;
2893 QCString type;
2894 Definition *ctx = nullptr;
2895 FileDef *fd = root->fileDef();
2896 SymbolResolver resolver(fd);
2897
2898 AUTO_TRACE("isVarWithConstructor({})",root->name);
2899 if (root->parent()->section.isCompound())
2900 { // inside a class
2901 result=FALSE;
2902 AUTO_TRACE_EXIT("inside class: result={}",result);
2903 return result;
2904 }
2905 else if ((fd != nullptr) && (fd->name().endsWith(".c") || fd->name().endsWith(".h")))
2906 { // inside a .c file
2907 result=FALSE;
2908 AUTO_TRACE_EXIT("inside C file: result={}",result);
2909 return result;
2910 }
2911 if (root->type.isEmpty())
2912 {
2913 result=FALSE;
2914 AUTO_TRACE_EXIT("no type: result={}",result);
2915 return result;
2916 }
2917 if (!root->parent()->name.isEmpty())
2918 {
2919 ctx=Doxygen::namespaceLinkedMap->find(root->parent()->name);
2920 }
2921 type = root->type;
2922 // remove qualifiers
2923 findAndRemoveWord(type,"const");
2924 findAndRemoveWord(type,"static");
2925 findAndRemoveWord(type,"volatile");
2926 typePtrType = type.find('*')!=-1 || type.find('&')!=-1;
2927 if (!typePtrType)
2928 {
2929 typeIsClass = resolver.resolveClass(ctx,type)!=nullptr;
2930 int ti=0;
2931 if (!typeIsClass && (ti=type.find('<'))!=-1)
2932 {
2933 typeIsClass=resolver.resolveClass(ctx,type.left(ti))!=nullptr;
2934 }
2935 }
2936 if (typeIsClass) // now we still have to check if the arguments are
2937 // types or values. Since we do not have complete type info
2938 // we need to rely on heuristics :-(
2939 {
2940 if (root->argList.empty())
2941 {
2942 result=FALSE; // empty arg list -> function prototype.
2943 AUTO_TRACE_EXIT("empty arg list: result={}",result);
2944 return result;
2945 }
2946 for (const Argument &a : root->argList)
2947 {
2948 static const reg::Ex initChars(R"([\d"'&*!^]+)");
2950 if (!a.name.isEmpty() || !a.defval.isEmpty())
2951 {
2952 std::string name = a.name.str();
2953 if (reg::search(name,match,initChars) && match.position()==0)
2954 {
2955 result=TRUE;
2956 }
2957 else
2958 {
2959 result=FALSE; // arg has (type,name) pair -> function prototype
2960 }
2961 AUTO_TRACE_EXIT("function prototype: result={}",result);
2962 return result;
2963 }
2964 if (!a.type.isEmpty() &&
2965 (a.type.at(a.type.length()-1)=='*' ||
2966 a.type.at(a.type.length()-1)=='&'))
2967 // type ends with * or & => pointer or reference
2968 {
2969 result=FALSE;
2970 AUTO_TRACE_EXIT("pointer or reference: result={}",result);
2971 return result;
2972 }
2973 if (a.type.isEmpty() || resolver.resolveClass(ctx,a.type)!=nullptr)
2974 {
2975 result=FALSE; // arg type is a known type
2976 AUTO_TRACE_EXIT("known type: result={}",result);
2977 return result;
2978 }
2979 if (checkIfTypedef(ctx,fd,a.type))
2980 {
2981 result=FALSE; // argument is a typedef
2982 AUTO_TRACE_EXIT("typedef: result={}",result);
2983 return result;
2984 }
2985 std::string atype = a.type.str();
2986 if (reg::search(atype,match,initChars) && match.position()==0)
2987 {
2988 result=TRUE; // argument type starts with typical initializer char
2989 AUTO_TRACE_EXIT("argument with init char: result={}",result);
2990 return result;
2991 }
2992 std::string resType=resolveTypeDef(ctx,a.type).str();
2993 if (resType.empty()) resType=atype;
2994 static const reg::Ex idChars(R"(\a\w*)");
2995 if (reg::search(resType,match,idChars) && match.position()==0) // resType starts with identifier
2996 {
2997 resType=match.str();
2998 if (resType=="int" || resType=="long" ||
2999 resType=="float" || resType=="double" ||
3000 resType=="char" || resType=="void" ||
3001 resType=="signed" || resType=="unsigned" ||
3002 resType=="const" || resType=="volatile" )
3003 {
3004 result=FALSE; // type keyword -> function prototype
3005 AUTO_TRACE_EXIT("type keyword: result={}",result);
3006 return result;
3007 }
3008 }
3009 }
3010 result=TRUE;
3011 }
3012
3013 AUTO_TRACE_EXIT("end: result={}",result);
3014 return result;
3015}
3016
3017//--------------------------------------------------------------------------------------
3018
3019/*! Searches for the end of a template in prototype \a s starting from
3020 * character position \a startPos. If the end was found the position
3021 * of the closing > is returned, otherwise -1 is returned.
3022 *
3023 * Handles exotic cases such as
3024 * \code
3025 * Class<(id<0)>
3026 * Class<bits<<2>
3027 * Class<"<">
3028 * Class<'<'>
3029 * Class<(")<")>
3030 * \endcode
3031 */
3032static int findEndOfTemplate(const QCString &s,size_t startPos)
3033{
3034 // locate end of template
3035 size_t e=startPos;
3036 int brCount=1;
3037 int roundCount=0;
3038 size_t len = s.length();
3039 bool insideString=FALSE;
3040 bool insideChar=FALSE;
3041 char pc = 0;
3042 while (e<len && brCount!=0)
3043 {
3044 char c=s.at(e);
3045 switch(c)
3046 {
3047 case '<':
3048 if (!insideString && !insideChar)
3049 {
3050 if (e<len-1 && s.at(e+1)=='<')
3051 e++;
3052 else if (roundCount==0)
3053 brCount++;
3054 }
3055 break;
3056 case '>':
3057 if (!insideString && !insideChar)
3058 {
3059 if (e<len-1 && s.at(e+1)=='>')
3060 e++;
3061 else if (roundCount==0)
3062 brCount--;
3063 }
3064 break;
3065 case '(':
3066 if (!insideString && !insideChar)
3067 roundCount++;
3068 break;
3069 case ')':
3070 if (!insideString && !insideChar)
3071 roundCount--;
3072 break;
3073 case '"':
3074 if (!insideChar)
3075 {
3076 if (insideString && pc!='\\')
3077 insideString=FALSE;
3078 else
3079 insideString=TRUE;
3080 }
3081 break;
3082 case '\'':
3083 if (!insideString)
3084 {
3085 if (insideChar && pc!='\\')
3086 insideChar=FALSE;
3087 else
3088 insideChar=TRUE;
3089 }
3090 break;
3091 }
3092 pc = c;
3093 e++;
3094 }
3095 return brCount==0 ? static_cast<int>(e) : -1;
3096}
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:5809
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:5481

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

11300{
11301 return []() { return std::make_unique<T>(); };
11302}

Referenced by initDoxygen().

◆ makeTemplateInstanceRelation()

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

Definition at line 5261 of file doxygen.cpp.

5262{
5263 AUTO_TRACE("root->name={} cd={}",root->name,cd->name());
5264 int i = root->name.find('<');
5265 if (i!=-1 && root->lang!=SrcLangExt::CSharp && root->lang!=SrcLangExt::Java)
5266 {
5267 ClassDefMutable *master = getClassMutable(root->name.left(i));
5268 if (master && master!=cd && !cd->templateMaster())
5269 {
5270 AUTO_TRACE_ADD("class={} master={}",cd->name(),cd->templateMaster()?cd->templateMaster()->name():"<none>",master->name());
5271 cd->setTemplateMaster(master);
5272 master->insertExplicitTemplateInstance(cd,root->name.mid(i));
5273 }
5274 }
5275}
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, CSharp, QCString::find(), getClassMutable(), ClassDefMutable::insertExplicitTemplateInstance(), Java, Entry::lang, QCString::left(), QCString::mid(), Definition::name(), Entry::name, ClassDefMutable::setTemplateMaster(), and ClassDef::templateMaster().

Referenced by findUsedTemplateInstances().

◆ mergeCategories()

static void mergeCategories ( )
static

Definition at line 8448 of file doxygen.cpp.

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

static 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()

static 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()

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

Definition at line 10586 of file doxygen.cpp.

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

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()

static void parseFilesMultiThreading ( const std::shared_ptr< Entry > & root)
static

parse the list of input files

Definition at line 10648 of file doxygen.cpp.

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

static void parseFilesSingleThreading ( const std::shared_ptr< Entry > & root)
static

parse the list of input files

Definition at line 10795 of file doxygen.cpp.

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

References ASSERT, AUTO_TRACE, Doxygen::clangAssistedParsing, Cpp, 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 12343 of file doxygen.cpp.

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

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

9902{
9904 {
9905 QCString indentStr;
9906 indentStr.fill(' ',indent);
9907 Debug::print(Debug::Entries,0,"{}{} at {}:{} (sec={}, spec={})\n",
9908 indentStr.isEmpty()?"":indentStr,
9909 root->name.isEmpty()?"<empty>":root->name,
9910 root->fileName,root->startLine,
9911 root->section.to_string(),
9912 root->spec.to_string());
9913 for (const auto &e : root->children())
9914 {
9915 printNavTree(e.get(),indent+2);
9916 }
9917 }
9918}
@ 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:643
void fill(char c, int len=-1)
Fills a string with a predefined character.
Definition qcstring.h:180
std::string to_string() const
Definition types.h:520

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

9925{
9927 {
9928 for (const auto &si : SectionManager::instance())
9929 {
9930 Debug::print(Debug::Sections,0,"Section = {}, file = {}, title = {}, type = {}, ref = {}\n",
9931 si->label(),si->fileName(),si->title(),si->type().level(),si->ref());
9932 }
9933 }
9934}
@ Sections
Definition debug.h:48

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

Referenced by parseInput().

◆ processTagLessClasses()

static 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:444
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 11417 of file doxygen.cpp.

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

References FileInfo::absFilePath(), Config::checkAndCorrect(), cleanUpDoxygen(), compareDoxyfile(), Config::Compressed, Config::CompressedNoEnv, Config_getBool, Config_getEnum, Config_updateBool, QCString::data(), devUsage(), err, FileInfo::exists(), Config::Full, g_commentFileName, g_dumpSymbolMap, g_singleComment, generateConfigFile(), getArg(), Config::init(), initTracing(), EmojiEntityMapper::instance(), QCString::isEmpty(), 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()

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 )
static

Definition at line 10957 of file doxygen.cpp.

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

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

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

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()

static void readTagFile ( const std::shared_ptr< Entry > & root,
const QCString & tagLine )
static

Definition at line 10288 of file doxygen.cpp.

10289{
10290 QCString fileName;
10291 QCString destName;
10292 int eqPos = tagLine.find('=');
10293 if (eqPos!=-1) // tag command contains a destination
10294 {
10295 fileName = tagLine.left(eqPos).stripWhiteSpace();
10296 destName = tagLine.right(tagLine.length()-eqPos-1).stripWhiteSpace();
10297 if (fileName.isEmpty() || destName.isEmpty()) return;
10298 //printf("insert tagDestination %s->%s\n",qPrint(fi.fileName()),qPrint(destName));
10299 }
10300 else
10301 {
10302 fileName = tagLine;
10303 }
10304
10305 FileInfo fi(fileName.str());
10306 if (!fi.exists() || !fi.isFile())
10307 {
10308 err("Tag file '{}' does not exist or is not a file. Skipping it...\n",fileName);
10309 return;
10310 }
10311
10312 if (Doxygen::tagFileSet.find(fi.absFilePath().c_str()) != Doxygen::tagFileSet.end()) return;
10313
10314 Doxygen::tagFileSet.emplace(fi.absFilePath());
10315
10316 if (!destName.isEmpty())
10317 {
10318 Doxygen::tagDestinationMap.emplace(fi.absFilePath(), destName.str());
10319 msg("Reading tag file '{}', location '{}'...\n",fileName,destName);
10320 }
10321 else
10322 {
10323 msg("Reading tag file '{}'...\n",fileName);
10324 }
10325
10326 parseTagFile(root,fi.absFilePath().c_str());
10327}
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()

static void resolveClassNestingRelations ( )
static

create the scope artificially

Definition at line 1331 of file doxygen.cpp.

1332{
1333 ClassDefSet visitedClasses;
1334
1335 bool done=FALSE;
1336 //int iteration=0;
1337 while (!done)
1338 {
1339 done=TRUE;
1340 //++iteration;
1341 struct ClassAlias
1342 {
1343 ClassAlias(const QCString &name,std::unique_ptr<ClassDef> cd,DefinitionMutable *ctx) :
1344 aliasFullName(name),aliasCd(std::move(cd)), aliasContext(ctx) {}
1345 QCString aliasFullName;
1346 std::unique_ptr<ClassDef> aliasCd;
1347 DefinitionMutable *aliasContext;
1348 };
1349 std::vector<ClassAlias> aliases;
1350 for (const auto &icd : *Doxygen::classLinkedMap)
1351 {
1352 ClassDefMutable *cd = toClassDefMutable(icd.get());
1353 if (cd && visitedClasses.find(icd.get())==visitedClasses.end())
1354 {
1355 QCString name = stripAnonymousNamespaceScope(icd->name());
1356 //printf("processing=%s, iteration=%d\n",qPrint(cd->name()),iteration);
1357 // also add class to the correct structural context
1359 name,icd->getFileDef(),nullptr);
1360 if (d)
1361 {
1362 //printf("****** adding %s to scope %s in iteration %d\n",qPrint(cd->name()),qPrint(d->name()),iteration);
1364 if (dm)
1365 {
1366 dm->addInnerCompound(cd);
1367 }
1368 cd->setOuterScope(d);
1369
1370 // for inline namespace add an alias of the class to the outer scope
1372 {
1374 //printf("nd->isInline()=%d\n",nd->isInline());
1375 if (nd && nd->isInline())
1376 {
1377 d = d->getOuterScope();
1378 if (d)
1379 {
1380 dm = toDefinitionMutable(d);
1381 if (dm)
1382 {
1383 auto aliasCd = createClassDefAlias(d,cd);
1384 QCString aliasFullName = d->qualifiedName()+"::"+aliasCd->localName();
1385 aliases.emplace_back(aliasFullName,std::move(aliasCd),dm);
1386 //printf("adding %s to %s as %s\n",qPrint(aliasCd->name()),qPrint(d->name()),qPrint(aliasFullName));
1387 }
1388 }
1389 }
1390 else
1391 {
1392 break;
1393 }
1394 }
1395
1396 visitedClasses.insert(icd.get());
1397 done=FALSE;
1398 }
1399 //else
1400 //{
1401 // printf("****** ignoring %s: scope not (yet) found in iteration %d\n",qPrint(cd->name()),iteration);
1402 //}
1403 }
1404 }
1405 // add aliases
1406 for (auto &alias : aliases)
1407 {
1408 ClassDef *aliasCd = Doxygen::classLinkedMap->add(alias.aliasFullName,std::move(alias.aliasCd));
1409 if (aliasCd)
1410 {
1411 alias.aliasContext->addInnerCompound(aliasCd);
1412 }
1413 }
1414 }
1415
1416 //give warnings for unresolved compounds
1417 for (const auto &icd : *Doxygen::classLinkedMap)
1418 {
1419 ClassDefMutable *cd = toClassDefMutable(icd.get());
1420 if (cd && visitedClasses.find(icd.get())==visitedClasses.end())
1421 {
1423 //printf("processing unresolved=%s, iteration=%d\n",qPrint(cd->name()),iteration);
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 "Internal inconsistency: scope for class {} not "
1440 "found!",name
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(), stripAnonymousNamespaceScope(), toClassDefMutable(), toDefinitionMutable(), toNamespaceDef(), TRUE, Definition::TypeNamespace, and warn.

Referenced by parseInput().

◆ resolveSymlink()

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

Definition at line 10885 of file doxygen.cpp.

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

static void resolveTemplateInstanceInType ( const Entry * root,
const Definition * scope,
const MemberDef * md )
static

Definition at line 4774 of file doxygen.cpp.

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

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()

static void resolveUserReferences ( )
static

Definition at line 9787 of file doxygen.cpp.

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

static void runHtmlHelpCompiler ( )
static

Definition at line 10115 of file doxygen.cpp.

10116{
10117 std::string oldDir = Dir::currentDirPath();
10118 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10121 {
10122 err("failed to run html help compiler on {}\n", HtmlHelp::hhpFileName);
10123 }
10124 Dir::setCurrent(oldDir);
10125}
@ ExtCmd
Definition debug.h:36
static bool setCurrent(const std::string &path)
Definition dir.cpp:348
static const QCString hhpFileName
Definition htmlhelp.h:88
int system(const QCString &command, const QCString &args, bool commandHasConsole=true)
Definition portable.cpp:106
void setShortDir()
Definition portable.cpp:570

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

Referenced by generateOutput().

◆ runQHelpGenerator()

static void runQHelpGenerator ( )
static

Definition at line 10127 of file doxygen.cpp.

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

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

Referenced by generateOutput().

◆ scopeIsTemplate()

static bool scopeIsTemplate ( const Definition * d)
static

Definition at line 5933 of file doxygen.cpp.

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

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

Referenced by addMemberFunction(), and scopeIsTemplate().

◆ searchInputFiles()

void searchInputFiles ( )

Definition at line 12111 of file doxygen.cpp.

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

static void setAnonymousEnumType ( )
static

Definition at line 8939 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ sortMemberLists()

static void sortMemberLists ( )
static

Definition at line 8844 of file doxygen.cpp.

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

static void stopDoxygen ( int )
static

Definition at line 11985 of file doxygen.cpp.

11986{
11987 signal(SIGINT,SIG_DFL); // Re-register signal handler for default action
11988 Dir thisDir;
11989 msg("Cleaning up...\n");
11990 if (!Doxygen::filterDBFileName.isEmpty())
11991 {
11992 thisDir.remove(Doxygen::filterDBFileName.str());
11993 }
11994 killpg(0,SIGINT);
11996 exitTracing();
11997 exit(1);
11998}

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()

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

Definition at line 6031 of file doxygen.cpp.

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

static QCString substituteTemplatesInString ( const ArgumentLists & srcTempArgLists,
const ArgumentLists & dstTempArgLists,
const std::string & src )
static

Definition at line 5947 of file doxygen.cpp.

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

References ArgumentList::begin(), ArgumentList::end(), end(), FALSE, found, QCString::isEmpty(), QCString::mid(), Argument::name, QCString::startsWith(), QCString::str(), TRUE, and Argument::type.

Referenced by substituteTemplatesInArgList().

◆ transferFunctionDocumentation()

static void transferFunctionDocumentation ( )
static

Definition at line 4284 of file doxygen.cpp.

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

static void transferFunctionReferences ( )
static

Definition at line 4317 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ transferRelatedFunctionDocumentation()

static void transferRelatedFunctionDocumentation ( )
static

Definition at line 4365 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ transferStaticInstanceInitializers()

void transferStaticInstanceInitializers ( )

Definition at line 4414 of file doxygen.cpp.

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

References AUTO_TRACE, AUTO_TRACE_ADD, MemberDef::isVariable(), Doxygen::memberNameLinkedMap, Definition::qualifiedName(), DefinitionMutable::setBodySegment(), Doxygen::staticInitMap, QCString::str(), and toMemberDefMutable().

Referenced by parseInput().

◆ tryAddEnumDocsToGroupMember()

static bool tryAddEnumDocsToGroupMember ( const Entry * root,
const QCString & name )
static

Definition at line 7938 of file doxygen.cpp.

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

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

Referenced by findEnumDocumentation().

◆ usage()

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

Definition at line 11232 of file doxygen.cpp.

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

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

Referenced by readConfiguration().

◆ version()

static void version ( const bool extended)
static

Definition at line 11204 of file doxygen.cpp.

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

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

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

◆ vhdlCorrectMemberProperties()

static void vhdlCorrectMemberProperties ( )
static

Definition at line 8301 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ warnUndocumentedNamespaces()

static void warnUndocumentedNamespaces ( )
static

Definition at line 5293 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ writeTagFile()

static void writeTagFile ( )
static

Definition at line 12001 of file doxygen.cpp.

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

References Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Config_getString, 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().