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

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

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

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

9458{
9459 md->setDocumentation(root->doc,root->docFile,root->docLine);
9460 md->setDocsForDefinition(!root->proto);
9461 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9462 if (md->inbodyDocumentation().isEmpty())
9463 {
9465 }
9466 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
9467 {
9468 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
9469 md->setBodyDef(root->fileDef());
9470 }
9472 md->setMaxInitLines(root->initLines);
9474 md->setRefItems(root->sli);
9475 if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
9476 addMemberToGroups(root,md);
9478}
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 7899 of file doxygen.cpp.

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

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

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addEnumValuesToEnums(), AUTO_TRACE, AUTO_TRACE_ADD, buildScopeFromQualifiedName(), Entry::children(), 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:6326

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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:4777
@ 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 11860 of file doxygen.cpp.

11861{
11862 AUTO_TRACE();
11863 Doxygen::globalNamespaceDef = createNamespaceDef("<globalScope>",1,1,"<globalScope>");
11873
11874 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11875
11876 /* Set the global html file extension. */
11877 Doxygen::htmlFileExtension = Config_getString(HTML_FILE_EXTENSION);
11878
11879
11881 Config_getBool(CALLER_GRAPH) ||
11882 Config_getBool(REFERENCES_RELATION) ||
11883 Config_getBool(REFERENCED_BY_RELATION);
11884
11885 /**************************************************************************
11886 * Add custom extension mappings
11887 **************************************************************************/
11888
11889 const StringVector &extMaps = Config_getList(EXTENSION_MAPPING);
11890 for (const auto &mapping : extMaps)
11891 {
11892 QCString mapStr = mapping.c_str();
11893 int i=mapStr.find('=');
11894 if (i==-1)
11895 {
11896 continue;
11897 }
11898 else
11899 {
11900 QCString ext = mapStr.left(i).stripWhiteSpace().lower();
11901 QCString language = mapStr.mid(i+1).stripWhiteSpace().lower();
11902 if (ext.isEmpty() || language.isEmpty())
11903 {
11904 continue;
11905 }
11906
11907 if (!updateLanguageMapping(ext,language))
11908 {
11909 err("Failed to map file extension '{}' to unsupported language '{}'.\n"
11910 "Check the EXTENSION_MAPPING setting in the config file.\n",
11911 ext,language);
11912 }
11913 else
11914 {
11915 msg("Adding custom extension mapping: '{}' will be treated as language '{}'\n",
11916 ext,language);
11917 }
11918 }
11919 }
11920 // create input file exncodings
11921
11922 // check INPUT_ENCODING
11923 void *cd = portable_iconv_open("UTF-8",Config_getString(INPUT_ENCODING).data());
11924 if (cd==reinterpret_cast<void *>(-1))
11925 {
11926 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
11927 "Check the 'INPUT_ENCODING' setting in the config file!\n",
11928 Config_getString(INPUT_ENCODING),strerror(errno));
11929 }
11930 else
11931 {
11933 }
11934
11935 // check and split INPUT_FILE_ENCODING
11936 const StringVector &fileEncod = Config_getList(INPUT_FILE_ENCODING);
11937 for (const auto &mapping : fileEncod)
11938 {
11939 QCString mapStr = mapping.c_str();
11940 int i=mapStr.find('=');
11941 if (i==-1)
11942 {
11943 continue;
11944 }
11945 else
11946 {
11947 QCString pattern = mapStr.left(i).stripWhiteSpace().lower();
11948 QCString encoding = mapStr.mid(i+1).stripWhiteSpace().lower();
11949 if (pattern.isEmpty() || encoding.isEmpty())
11950 {
11951 continue;
11952 }
11953 cd = portable_iconv_open("UTF-8",encoding.data());
11954 if (cd==reinterpret_cast<void *>(-1))
11955 {
11956 term("unsupported character conversion: '{}'->'UTF-8': {}\n"
11957 "Check the 'INPUT_FILE_ENCODING' setting in the config file!\n",
11958 encoding,strerror(errno));
11959 }
11960 else
11961 {
11963 }
11964
11965 Doxygen::inputFileEncodingList.emplace_back(pattern, encoding);
11966 }
11967 }
11968
11969 // add predefined macro name to a dictionary
11970 const StringVector &expandAsDefinedList =Config_getList(EXPAND_AS_DEFINED);
11971 for (const auto &s : expandAsDefinedList)
11972 {
11973 Doxygen::expandAsDefinedSet.insert(s.c_str());
11974 }
11975
11976 // read aliases and store them in a dictionary
11977 readAliases();
11978
11979 // store number of spaces in a tab into Doxygen::spaces
11980 int tabSize = Config_getInt(TAB_SIZE);
11981 Doxygen::spaces.resize(tabSize);
11982 for (int sp=0; sp<tabSize; sp++) Doxygen::spaces.at(sp)=' ';
11983 Doxygen::spaces.at(tabSize)='\0';
11984}
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:5540

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

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

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

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

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 sameNumTemplateArgs = TRUE;
4023 bool matchingReturnTypes = TRUE;
4024 bool sameRequiresClause = TRUE;
4025 if (!mdTempl.empty() && !root->tArgLists.empty())
4026 {
4027 if (mdTempl.size()!=root->tArgLists.back().size())
4028 {
4029 sameNumTemplateArgs = FALSE;
4030 }
4031 if (md->typeString()!=removeRedundantWhiteSpace(root->type))
4032 {
4033 matchingReturnTypes = FALSE;
4034 }
4035 if (md->requiresClause()!=root->req)
4036 {
4037 sameRequiresClause = FALSE;
4038 }
4039 }
4040 else if (!mdTempl.empty() || !root->tArgLists.empty())
4041 { // if one has template parameters and the other doesn't then that also counts as a
4042 // difference
4043 sameNumTemplateArgs = FALSE;
4044 }
4045
4046 bool staticsInDifferentFiles =
4047 root->isStatic && md->isStatic() && root->fileName!=md->getDefFileName();
4048
4049 if (
4050 matchArguments2(md->getOuterScope(),mfd,&mdAl,
4051 rnd ? rnd : Doxygen::globalScope,rfd,&root->argList,
4052 FALSE,root->lang) &&
4053 sameNumTemplateArgs &&
4054 matchingReturnTypes &&
4055 sameRequiresClause &&
4056 !staticsInDifferentFiles
4057 )
4058 {
4059 GroupDef *gd=nullptr;
4060 if (!root->groups.empty() && !root->groups.front().groupname.isEmpty())
4061 {
4062 gd = Doxygen::groupLinkedMap->find(root->groups.front().groupname);
4063 }
4064 //printf("match!\n");
4065 //printf("mnd=%p rnd=%p nsName=%s rnsName=%s\n",mnd,rnd,qPrint(nsName),qPrint(rnsName));
4066 // see if we need to create a new member
4067 found=(mnd && rnd && nsName==rnsName) || // members are in the same namespace
4068 ((mnd==nullptr && rnd==nullptr && mfd!=nullptr && // no external reference and
4069 mfd->absFilePath()==root->fileName // prototype in the same file
4070 )
4071 );
4072 // otherwise, allow a duplicate global member with the same argument list
4073 if (!found && gd && gd==md->getGroupDef() && nsName==rnsName)
4074 {
4075 // member is already in the group, so we don't want to add it again.
4076 found=TRUE;
4077 }
4078
4079 AUTO_TRACE_ADD("combining function with prototype found={} in namespace '{}'",found,nsName);
4080
4081 if (found)
4082 {
4083 // merge argument lists
4084 ArgumentList mergedArgList = root->argList;
4085 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.isEmpty());
4086 // merge documentation
4087 if (md->documentation().isEmpty() && !root->doc.isEmpty())
4088 {
4089 if (root->proto)
4090 {
4092 }
4093 else
4094 {
4096 }
4097 }
4098
4099 md->setDocumentation(root->doc,root->docFile,root->docLine);
4101 md->setDocsForDefinition(!root->proto);
4102 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
4103 {
4104 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
4105 md->setBodyDef(rfd);
4106 }
4107
4108 if (md->briefDescription().isEmpty() && !root->brief.isEmpty())
4109 {
4110 md->setArgsString(root->args);
4111 }
4112 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
4113
4115
4117 md->addQualifiers(root->qualifiers);
4118
4119 // merge ingroup specifiers
4120 if (md->getGroupDef()==nullptr && !root->groups.empty())
4121 {
4122 addMemberToGroups(root,md);
4123 }
4124 else if (md->getGroupDef()!=nullptr && root->groups.empty())
4125 {
4126 //printf("existing member is grouped, new member not\n");
4127 }
4128 else if (md->getGroupDef()!=nullptr && !root->groups.empty())
4129 {
4130 //printf("both members are grouped\n");
4131 }
4133
4134 // if md is a declaration and root is the corresponding
4135 // definition, then turn md into a definition.
4136 if (md->isPrototype() && !root->proto)
4137 {
4138 md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn());
4139 md->setPrototype(FALSE,root->fileName,root->startLine,root->startColumn);
4140 }
4141 // if md is already the definition, then add the declaration info
4142 else if (!md->isPrototype() && root->proto)
4143 {
4144 md->setDeclFile(root->fileName,root->startLine,root->startColumn);
4145 }
4146 }
4147 }
4148 }
4149 if (found)
4150 {
4151 md_found = md;
4152 break;
4153 }
4154 }
4155 }
4156 if (!found) /* global function is unique with respect to the file */
4157 {
4158 addGlobalFunction(root,rname,scope);
4159 }
4160 else
4161 {
4162 FileDef *fd=root->fileDef();
4163 if (fd)
4164 {
4165 // add member to the file (we do this even if we have already
4166 // inserted it into the namespace)
4167 fd->insertMember(md_found);
4168 }
4169 }
4170
4171 AUTO_TRACE_ADD("unrelated function type='{}' name='{}' args='{}'",root->type,rname,root->args);
4172 }
4173 else
4174 {
4175 AUTO_TRACE_ADD("function '{}' is not processed",rname);
4176 }
4177 }
4178 else if (rname.isEmpty())
4179 {
4180 warn(root->fileName,root->startLine,
4181 "Illegal member name found."
4182 );
4183 }
4184 }
4185 for (const auto &e : root->children()) buildFunctionList(e.get());
4186}
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 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(), 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(), ArgumentList::size(), 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:6300

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

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

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

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

11850{
11851 AUTO_TRACE();
11852
11857}
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 12324 of file doxygen.cpp.

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

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

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

Referenced by parseInput().

◆ cleanUpDoxygen()

void cleanUpDoxygen ( )

Definition at line 11375 of file doxygen.cpp.

11376{
11380
11381 delete Doxygen::indexList;
11390 Doxygen::mainPage.reset();
11394 Doxygen::globalScope = nullptr;
11396 delete theTranslator;
11397 delete g_outputList;
11398
11403 delete Doxygen::dirLinkedMap;
11404 delete Doxygen::symbolMap;
11405}
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 9176 of file doxygen.cpp.

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

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

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

Referenced by readConfiguration().

◆ computeClassRelations()

static void computeClassRelations ( )
static

Definition at line 5316 of file doxygen.cpp.

5317{
5318 AUTO_TRACE();
5319 for (const auto &[name,root] : g_classEntries)
5320 {
5321 QCString bName = extractClassName(root);
5322 ClassDefMutable *cd = getClassMutable(bName);
5323 if (cd)
5324 {
5326 }
5327 size_t numMembers = cd ? cd->memberNameInfoLinkedMap().size() : 0;
5328 if ((cd==nullptr || (!cd->hasDocumentation() && !cd->isReference())) && numMembers>0 && !bName.endsWith("::"))
5329 {
5330 if (!root->name.isEmpty() && root->name.find('@')==-1 && // normal name
5331 (guessSection(root->fileName).isHeader() ||
5332 Config_getBool(EXTRACT_LOCAL_CLASSES)) && // not defined in source file
5333 protectionLevelVisible(root->protection) && // hidden by protection
5334 !Config_getBool(HIDE_UNDOC_CLASSES) // undocumented class are visible
5335 )
5336 warn_undoc(root->fileName,root->startLine, "Compound {} is not documented.", root->name);
5337 }
5338 }
5339}
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:5221
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:4675
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 11407 of file doxygen.cpp.

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

Referenced by generateOutput().

◆ computeMemberReferences()

static void computeMemberReferences ( )
static

Definition at line 5410 of file doxygen.cpp.

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

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

References Doxygen::classLinkedMap, and computeMemberRelationsForBaseClass().

Referenced by parseInput().

◆ computeMemberRelationsForBaseClass()

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

Definition at line 8335 of file doxygen.cpp.

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

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

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

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

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

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

Referenced by parseInput().

◆ computeVerifiedDotPath()

static void computeVerifiedDotPath ( )
static

Definition at line 10200 of file doxygen.cpp.

10201{
10202 // check dot path
10203 QCString dotPath = Config_getString(DOT_PATH);
10204 if (!dotPath.isEmpty())
10205 {
10206 FileInfo fi(dotPath.str());
10207 if (!(fi.exists() && fi.isFile()) )// not an existing user specified path + exec
10208 {
10209 dotPath = dotPath+"/dot"+Portable::commandExtension();
10210 FileInfo dp(dotPath.str());
10211 if (!dp.exists() || !dp.isFile())
10212 {
10213 warn_uncond("the dot tool could not be found as '{}'\n",dotPath);
10214 dotPath = "dot";
10215 dotPath += Portable::commandExtension();
10216 }
10217 }
10218#if defined(_WIN32) // convert slashes
10219 size_t l=dotPath.length();
10220 for (size_t i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\';
10221#endif
10222 }
10223 else
10224 {
10225 dotPath = "dot";
10226 dotPath += Portable::commandExtension();
10227 }
10228 Doxygen::verifiedDotPath = dotPath;
10230}
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 10466 of file doxygen.cpp.

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

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

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

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

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

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

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

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

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

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

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

8432{
8433 // for each class
8434 for (const auto &cd : *Doxygen::classLinkedMap)
8435 {
8436 // that is a template
8437 for (const auto &ti : cd->getTemplateInstances())
8438 {
8439 ClassDefMutable *tcdm = toClassDefMutable(ti.classDef);
8440 if (tcdm)
8441 {
8442 tcdm->addMembersToTemplateInstance(cd.get(),cd->templateArguments(),ti.templSpec);
8443 }
8444 }
8445 }
8446}
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 11186 of file doxygen.cpp.

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

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

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

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

11170{
11171 std::ofstream f = Portable::openOutputStream("symbols.sql");
11172 if (f.is_open())
11173 {
11174 TextStream t(&f);
11175 for (const auto &[name,symList] : *Doxygen::symbolMap)
11176 {
11177 for (const auto &def : symList)
11178 {
11179 dumpSymbol(t,def);
11180 }
11181 }
11182 }
11183}
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 12079 of file doxygen.cpp.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Referenced by findClassRelation(), and findUsedClassesForClass().

◆ findDefineDocumentation()

static void findDefineDocumentation ( Entry * root)
static

Definition at line 9482 of file doxygen.cpp.

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

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

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

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

8086{
8089}
static void findDEV(const MemberNameLinkedMap &mnsd)
Definition doxygen.cpp:8059

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

Referenced by parseInput().

◆ findEnumDocumentation()

static void findEnumDocumentation ( const Entry * root)
static

Definition at line 7973 of file doxygen.cpp.

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

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

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

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

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

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

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

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

Referenced by parseInput().

◆ findMainPage()

static void findMainPage ( Entry * root)
static

Definition at line 9657 of file doxygen.cpp.

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

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

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

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

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

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

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

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

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

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

9278{
9279 // for each class
9280 for (const auto &cd : *Doxygen::classLinkedMap)
9281 {
9282 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9283 if (cdm)
9284 {
9286 }
9287 }
9288 // for each concept
9289 for (const auto &cd : *Doxygen::conceptLinkedMap)
9290 {
9291 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
9292 if (cdm)
9293 {
9295 }
9296 }
9297 // for each file
9298 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9299 {
9300 for (const auto &fd : *fn)
9301 {
9302 fd->findSectionsInDocumentation();
9303 }
9304 }
9305 // for each namespace
9306 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9307 {
9309 if (ndm)
9310 {
9312 }
9313 }
9314 // for each group
9315 for (const auto &gd : *Doxygen::groupLinkedMap)
9316 {
9317 gd->findSectionsInDocumentation();
9318 }
9319 // for each page
9320 for (const auto &pd : *Doxygen::pageLinkedMap)
9321 {
9322 pd->findSectionsInDocumentation();
9323 }
9325 if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
9326}
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 4726 of file doxygen.cpp.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Referenced by generateClassDocs().

◆ generateExampleDocs()

static void generateExampleDocs ( )
static

Definition at line 9942 of file doxygen.cpp.

9943{
9944 g_outputList->disable(OutputType::Man);
9945 for (const auto &pd : *Doxygen::exampleLinkedMap)
9946 {
9947 msg("Generating docs for example {}...\n",pd->name());
9949 if (lang != SrcLangExt::Unknown)
9950 {
9951 QCString ext = getFileNameExtension(pd->name());
9952 auto intf = Doxygen::parserManager->getCodeParser(ext);
9953 intf->resetCodeParserState();
9954 }
9955 QCString n=pd->getOutputFileBase();
9956 startFile(*g_outputList,n,n,pd->name());
9958 g_outputList->docify(pd->name());
9960 g_outputList->startContents();
9961 QCString lineNoOptStr;
9962 if (pd->showLineNo())
9963 {
9964 lineNoOptStr="{lineno}";
9965 }
9966 g_outputList->generateDoc(pd->docFile(), // file
9967 pd->docLine(), // startLine
9968 pd.get(), // context
9969 nullptr, // memberDef
9970 (pd->briefDescription().isEmpty()?"":pd->briefDescription()+"\n\n")+
9971 pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
9972 TRUE, // index words
9973 TRUE, // is example
9974 pd->name(),
9975 FALSE,
9976 FALSE,
9977 Config_getBool(MARKDOWN_SUPPORT)
9978 );
9979 endFile(*g_outputList); // contains g_outputList->endContents()
9980 }
9982}
void startTitle(OutputList &ol, const QCString &fileName, const DefinitionMutable *def)
Definition index.cpp:386
void endFile(OutputList &ol, bool skipNavIndex, bool skipEndContents, const QCString &navPath)
Definition index.cpp:421
void endTitle(OutputList &ol, const QCString &fileName, const QCString &name)
Definition index.cpp:395
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:402
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5645
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5687

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

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

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

Referenced by generateOutput().

◆ generateFileSources()

static void generateFileSources ( )
static

Definition at line 8502 of file doxygen.cpp.

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

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

References g_outputList, and Doxygen::groupLinkedMap.

Referenced by generateOutput().

◆ generateNamespaceClassDocs()

static void generateNamespaceClassDocs ( const ClassLinkedRefMap & classList)
static

Definition at line 10001 of file doxygen.cpp.

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

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

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

Referenced by generateNamespaceDocs().

◆ generateNamespaceDocs()

static void generateNamespaceDocs ( )
static

Definition at line 10087 of file doxygen.cpp.

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

References Config_getBool, g_outputList, generateNamespaceClassDocs(), generateNamespaceConceptDocs(), msg, Doxygen::namespaceLinkedMap, toNamespaceDefMutable(), and NamespaceDefMutable::writeDocumentation().

Referenced by generateOutput().

◆ generateOutput()

void generateOutput ( )

add extra languages for which we can only produce syntax highlighted code

Definition at line 13020 of file doxygen.cpp.

13021{
13022 AUTO_TRACE();
13023 /**************************************************************************
13024 * Initialize output generators *
13025 **************************************************************************/
13026
13027 /// add extra languages for which we can only produce syntax highlighted code
13029
13030 //// dump all symbols
13031 if (g_dumpSymbolMap)
13032 {
13033 dumpSymbolMap();
13034 exit(0);
13035 }
13036
13037 bool generateHtml = Config_getBool(GENERATE_HTML);
13038 bool generateLatex = Config_getBool(GENERATE_LATEX);
13039 bool generateMan = Config_getBool(GENERATE_MAN);
13040 bool generateRtf = Config_getBool(GENERATE_RTF);
13041 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
13042
13043
13045 if (generateHtml)
13046 {
13050 }
13051 if (generateLatex)
13052 {
13055 }
13056 if (generateDocbook)
13057 {
13060 }
13061 if (generateMan)
13062 {
13063 g_outputList->add<ManGenerator>();
13065 }
13066 if (generateRtf)
13067 {
13068 g_outputList->add<RTFGenerator>();
13070 }
13071 if (Config_getBool(USE_HTAGS))
13072 {
13074 QCString htmldir = Config_getString(HTML_OUTPUT);
13075 if (!Htags::execute(htmldir))
13076 err("USE_HTAGS is YES but htags(1) failed. \n");
13077 else if (!Htags::loadFilemap(htmldir))
13078 err("htags(1) ended normally but failed to load the filemap. \n");
13079 }
13080
13081 /**************************************************************************
13082 * Generate documentation *
13083 **************************************************************************/
13084
13085 g_s.begin("Generating style sheet...\n");
13086 //printf("writing style info\n");
13087 g_outputList->writeStyleInfo(0); // write first part
13088 g_s.end();
13089
13090 bool searchEngine = Config_getBool(SEARCHENGINE);
13091 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
13092
13093 g_s.begin("Generating search indices...\n");
13094 if (searchEngine && !serverBasedSearch && generateHtml)
13095 {
13097 }
13098
13099 // generate search indices (need to do this before writing other HTML
13100 // pages as these contain a drop down menu with options depending on
13101 // what categories we find in this function.
13102 if (generateHtml && searchEngine)
13103 {
13104 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
13105 Dir searchDir(searchDirName.str());
13106 if (!searchDir.exists() && !searchDir.mkdir(searchDirName.str()))
13107 {
13108 term("Could not create search results directory '{}' $PWD='{}'\n",
13109 searchDirName,Dir::currentDirPath());
13110 }
13111 HtmlGenerator::writeSearchData(searchDirName);
13112 if (!serverBasedSearch) // client side search index
13113 {
13115 }
13116 }
13117 g_s.end();
13118
13119 // copy static stuff
13120 if (generateHtml)
13121 {
13124 copyLogo(Config_getString(HTML_OUTPUT));
13125 copyIcon(Config_getString(HTML_OUTPUT));
13126 copyExtraFiles(Config_getList(HTML_EXTRA_FILES),"HTML_EXTRA_FILES",Config_getString(HTML_OUTPUT));
13127 }
13128 if (generateLatex)
13129 {
13131 copyLogo(Config_getString(LATEX_OUTPUT));
13132 copyIcon(Config_getString(LATEX_OUTPUT));
13133 copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT));
13134 }
13135 if (generateDocbook)
13136 {
13137 copyLogo(Config_getString(DOCBOOK_OUTPUT));
13138 copyIcon(Config_getString(DOCBOOK_OUTPUT));
13139 }
13140 if (generateRtf)
13141 {
13142 copyLogo(Config_getString(RTF_OUTPUT));
13143 copyIcon(Config_getString(RTF_OUTPUT));
13144 copyExtraFiles(Config_getList(RTF_EXTRA_FILES),"RTF_EXTRA_FILES",Config_getString(RTF_OUTPUT));
13145 }
13146
13148 if (fm.hasFormulas() && generateHtml
13149 && !Config_getBool(USE_MATHJAX))
13150 {
13151 g_s.begin("Generating images for formulas in HTML...\n");
13152 fm.generateImages(Config_getString(HTML_OUTPUT), Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg ?
13154 g_s.end();
13155 }
13156 if (fm.hasFormulas() && generateRtf)
13157 {
13158 g_s.begin("Generating images for formulas in RTF...\n");
13160 g_s.end();
13161 }
13162
13163 if (fm.hasFormulas() && generateDocbook)
13164 {
13165 g_s.begin("Generating images for formulas in Docbook...\n");
13167 g_s.end();
13168 }
13169
13170 g_s.begin("Generating example documentation...\n");
13172 g_s.end();
13173
13174 g_s.begin("Generating file sources...\n");
13176 g_s.end();
13177
13178 g_s.begin("Generating file documentation...\n");
13180 g_s.end();
13181
13182 g_s.begin("Generating page documentation...\n");
13184 g_s.end();
13185
13186 g_s.begin("Generating group documentation...\n");
13188 g_s.end();
13189
13190 g_s.begin("Generating class documentation...\n");
13192 g_s.end();
13193
13194 g_s.begin("Generating concept documentation...\n");
13196 g_s.end();
13197
13198 g_s.begin("Generating module documentation...\n");
13200 g_s.end();
13201
13202 g_s.begin("Generating namespace documentation...\n");
13204 g_s.end();
13205
13206 if (Config_getBool(GENERATE_LEGEND))
13207 {
13208 g_s.begin("Generating graph info page...\n");
13210 g_s.end();
13211 }
13212
13213 g_s.begin("Generating directory documentation...\n");
13215 g_s.end();
13216
13217 if (g_outputList->size()>0)
13218 {
13220 }
13221
13222 g_s.begin("finalizing index lists...\n");
13223 Doxygen::indexList->finalize();
13224 g_s.end();
13225
13226 g_s.begin("writing tag file...\n");
13227 writeTagFile();
13228 g_s.end();
13229
13230 if (Config_getBool(GENERATE_XML))
13231 {
13232 g_s.begin("Generating XML output...\n");
13234 generateXML();
13236 g_s.end();
13237 }
13238 if (Config_getBool(GENERATE_SQLITE3))
13239 {
13240 g_s.begin("Generating SQLITE3 output...\n");
13242 g_s.end();
13243 }
13244
13245 if (Config_getBool(GENERATE_AUTOGEN_DEF))
13246 {
13247 g_s.begin("Generating AutoGen DEF output...\n");
13248 generateDEF();
13249 g_s.end();
13250 }
13251 if (Config_getBool(GENERATE_PERLMOD))
13252 {
13253 g_s.begin("Generating Perl module output...\n");
13255 g_s.end();
13256 }
13257 if (generateHtml && searchEngine && serverBasedSearch)
13258 {
13259 g_s.begin("Generating search index\n");
13260 if (Doxygen::searchIndex.kind()==SearchIndexIntf::Internal) // write own search index
13261 {
13263 Doxygen::searchIndex.write(Config_getString(HTML_OUTPUT)+"/search/search.idx");
13264 }
13265 else // write data for external search index
13266 {
13268 QCString searchDataFile = Config_getString(SEARCHDATA_FILE);
13269 if (searchDataFile.isEmpty())
13270 {
13271 searchDataFile="searchdata.xml";
13272 }
13273 if (!Portable::isAbsolutePath(searchDataFile.data()))
13274 {
13275 searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/");
13276 }
13277 Doxygen::searchIndex.write(searchDataFile);
13278 }
13279 g_s.end();
13280 }
13281
13282 if (generateRtf)
13283 {
13284 g_s.begin("Combining RTF output...\n");
13285 if (!RTFGenerator::preProcessFileInplace(Config_getString(RTF_OUTPUT),"refman.rtf"))
13286 {
13287 err("An error occurred during post-processing the RTF files!\n");
13288 }
13289 g_s.end();
13290 }
13291
13292 g_s.begin("Running plantuml with JAVA...\n");
13294 g_s.end();
13295
13296 if (Config_getBool(HAVE_DOT))
13297 {
13298 g_s.begin("Running dot...\n");
13300 g_s.end();
13301 }
13302
13303 if (generateHtml &&
13304 Config_getBool(GENERATE_HTMLHELP) &&
13305 !Config_getString(HHC_LOCATION).isEmpty())
13306 {
13307 g_s.begin("Running html help compiler...\n");
13309 g_s.end();
13310 }
13311
13312 if ( generateHtml &&
13313 Config_getBool(GENERATE_QHP) &&
13314 !Config_getString(QHG_LOCATION).isEmpty())
13315 {
13316 g_s.begin("Running qhelpgenerator...\n");
13318 g_s.end();
13319 }
13320
13321 g_outputList->cleanup();
13322
13323 msg("type lookup cache used {}/{} hits={} misses={}\n",
13325 Doxygen::typeLookupCache->capacity(),
13327 Doxygen::typeLookupCache->misses());
13328 msg("symbol lookup cache used {}/{} hits={} misses={}\n",
13330 Doxygen::symbolLookupCache->capacity(),
13332 Doxygen::symbolLookupCache->misses());
13333 int typeCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::typeLookupCache->misses()*2/3)); // part of the cache is flushed, hence the 2/3 correction factor
13334 int symbolCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::symbolLookupCache->misses()));
13335 int cacheParam = std::max(typeCacheParam,symbolCacheParam);
13336 if (cacheParam>Config_getInt(LOOKUP_CACHE_SIZE))
13337 {
13338 msg("Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is {} at the cost of higher memory usage.\n",cacheParam);
13339 }
13340
13342 {
13343
13344 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
13345 if (numThreads<1) numThreads=1;
13346 msg("Total elapsed time: {:.6f} seconds\n(of which an average of {:.6f} seconds per thread waiting for external tools to finish)\n",
13347 (static_cast<double>(Debug::elapsedTime())),
13348 Portable::getSysElapsedTime()/static_cast<double>(numThreads)
13349 );
13350 g_s.print();
13351
13353 msg("finished...\n");
13355 }
13356 else
13357 {
13358 msg("finished...\n");
13359 }
13360
13361
13362 /**************************************************************************
13363 * Start cleaning up *
13364 **************************************************************************/
13365
13367
13369 Dir thisDir;
13370 thisDir.remove(Doxygen::filterDBFileName.str());
13372 exitTracing();
13374 delete Doxygen::clangUsrMap;
13376
13377 //dumpDocNodeSizes();
13378}
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:1135
static void writeSearchPage()
Definition htmlgen.cpp:3071
static void writeTabData()
Additional initialization after indices have been created.
Definition htmlgen.cpp:1291
static void writeSearchData(const QCString &dir)
Definition htmlgen.cpp:1329
static void writeExternalSearchPage()
Definition htmlgen.cpp:3162
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:156
void run()
Run plant UML tool for all images.
Definition plantuml.cpp:314
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:9987
static void generateExampleDocs()
Definition doxygen.cpp:9942
static void dumpSymbolMap()
static void generateFileDocs()
Definition doxygen.cpp:8668
static void copyIcon(const QCString &outputOption)
static void generatePageDocs()
Definition doxygen.cpp:9857
static void generateFileSources()
Definition doxygen.cpp:8502
static void copyLogo(const QCString &outputOption)
static void generateClassDocs()
Definition doxygen.cpp:9094
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:9120
void writeGraphInfo(OutputList &ol)
Definition index.cpp:3945
void writeIndexHierarchy(OutputList &ol)
Definition index.cpp:5585
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:5639
void generateXML()
Definition xmlgen.cpp:2178

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

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

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

Referenced by generateOutput().

◆ generateXRefPages()

static void generateXRefPages ( )
static

Definition at line 5513 of file doxygen.cpp.

5514{
5515 AUTO_TRACE();
5517 {
5518 rl->generatePage();
5519 }
5520}
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 11279 of file doxygen.cpp.

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

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

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

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

References end().

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

◆ haveEqualFileNames()

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

Definition at line 9444 of file doxygen.cpp.

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

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

Referenced by findDefineDocumentation().

◆ inheritDocumentation()

static void inheritDocumentation ( )
static

Definition at line 9141 of file doxygen.cpp.

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

11307{
11308 initResources();
11309 QCString lang = Portable::getenv("LC_ALL");
11310 if (!lang.isEmpty()) Portable::setenv("LANG",lang);
11311 std::setlocale(LC_ALL,"");
11312 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
11313 std::setlocale(LC_NUMERIC,"C");
11314
11316
11340
11341 // register any additional parsers here...
11342
11344
11345#if USE_LIBCLANG
11347#endif
11356 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
11357 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
11358 //Doxygen::tagDestinationDict.setAutoDelete(TRUE);
11360
11361 // initialization of these globals depends on
11362 // configuration switches so we need to postpone these
11363 Doxygen::globalScope = nullptr;
11372
11373}
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:5572

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

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

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

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

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

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

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

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

Referenced by findClassRelation().

◆ isSpecialization()

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

Definition at line 5920 of file doxygen.cpp.

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

References FALSE, and TRUE.

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

◆ isSymbolHidden()

static bool isSymbolHidden ( const Definition * d)
static

Definition at line 8888 of file doxygen.cpp.

8889{
8890 bool hidden = d->isHidden();
8891 const Definition *parent = d->getOuterScope();
8892 return parent ? hidden || isSymbolHidden(parent) : hidden;
8893}
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:39
QCString defval
Definition arguments.h:41
bool checkIfTypedef(const Definition *scope, const FileDef *fileScope, const QCString &n)
Definition util.cpp:5749
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:5421

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

11302{
11303 return []() { return std::make_unique<T>(); };
11304}

Referenced by initDoxygen().

◆ makeTemplateInstanceRelation()

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

Definition at line 5264 of file doxygen.cpp.

5265{
5266 AUTO_TRACE("root->name={} cd={}",root->name,cd->name());
5267 int i = root->name.find('<');
5268 if (i!=-1 && root->lang!=SrcLangExt::CSharp && root->lang!=SrcLangExt::Java)
5269 {
5270 ClassDefMutable *master = getClassMutable(root->name.left(i));
5271 if (master && master!=cd && !cd->templateMaster())
5272 {
5273 AUTO_TRACE_ADD("class={} master={}",cd->name(),cd->templateMaster()?cd->templateMaster()->name():"<none>",master->name());
5274 cd->setTemplateMaster(master);
5275 master->insertExplicitTemplateInstance(cd,root->name.mid(i));
5276 }
5277 }
5278}
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 8450 of file doxygen.cpp.

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

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

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

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

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

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

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

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

9904{
9906 {
9907 QCString indentStr;
9908 indentStr.fill(' ',indent);
9909 Debug::print(Debug::Entries,0,"{}{} at {}:{} (sec={}, spec={})\n",
9910 indentStr.isEmpty()?"":indentStr,
9911 root->name.isEmpty()?"<empty>":root->name,
9912 root->fileName,root->startLine,
9913 root->section.to_string(),
9914 root->spec.to_string());
9915 for (const auto &e : root->children())
9916 {
9917 printNavTree(e.get(),indent+2);
9918 }
9919 }
9920}
@ 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 9926 of file doxygen.cpp.

9927{
9929 {
9930 for (const auto &si : SectionManager::instance())
9931 {
9932 Debug::print(Debug::Sections,0,"Section = {}, file = {}, title = {}, type = {}, ref = {}\n",
9933 si->label(),si->fileName(),si->title(),si->type().level(),si->ref());
9934 }
9935 }
9936}
@ 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 11419 of file doxygen.cpp.

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

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

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

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

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

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

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

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

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

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

10118{
10119 std::string oldDir = Dir::currentDirPath();
10120 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10123 {
10124 err("failed to run html help compiler on {}\n", HtmlHelp::hhpFileName);
10125 }
10126 Dir::setCurrent(oldDir);
10127}
@ 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 10129 of file doxygen.cpp.

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

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

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

Referenced by addMemberFunction(), and scopeIsTemplate().

◆ searchInputFiles()

void searchInputFiles ( )

Definition at line 12113 of file doxygen.cpp.

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

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

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

Referenced by parseInput().

◆ sortMemberLists()

static void sortMemberLists ( )
static

Definition at line 8846 of file doxygen.cpp.

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

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

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

6040{
6041 auto dstIt = dst.begin();
6042 for (const Argument &sa : src)
6043 {
6044 QCString dstType = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.type.str());
6045 QCString dstArray = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.array.str());
6046 if (dstIt == dst.end())
6047 {
6048 Argument da = sa;
6049 da.type = dstType;
6050 da.array = dstArray;
6051 dst.push_back(da);
6052 dstIt = dst.end();
6053 }
6054 else
6055 {
6056 Argument da = *dstIt;
6057 da.type = dstType;
6058 da.array = dstArray;
6059 ++dstIt;
6060 }
6061 }
6062 dst.setConstSpecifier(src.constSpecifier());
6063 dst.setVolatileSpecifier(src.volatileSpecifier());
6064 dst.setPureSpecifier(src.pureSpecifier());
6066 srcTempArgLists,dstTempArgLists,
6067 src.trailingReturnType().str()));
6068 dst.setIsDeleted(src.isDeleted());
6069 dst.setRefQualifier(src.refQualifier());
6070 dst.setNoParameters(src.noParameters());
6071 //printf("substituteTemplatesInArgList: replacing %s with %s\n",
6072 // qPrint(argListToString(src)),qPrint(argListToString(dst))
6073 // );
6074}
iterator end()
Definition arguments.h:87
void setTrailingReturnType(const QCString &s)
Definition arguments.h:115
void setPureSpecifier(bool b)
Definition arguments.h:114
void push_back(const Argument &a)
Definition arguments.h:95
void setConstSpecifier(bool b)
Definition arguments.h:112
void setRefQualifier(RefQualifierType t)
Definition arguments.h:117
void setIsDeleted(bool b)
Definition arguments.h:116
iterator begin()
Definition arguments.h:86
void setNoParameters(bool b)
Definition arguments.h:118
void setVolatileSpecifier(bool b)
Definition arguments.h:113
static QCString substituteTemplatesInString(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const std::string &src)
Definition doxygen.cpp:5950
QCString array
Definition arguments.h:40

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

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

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

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

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

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

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

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

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

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

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

Referenced by readConfiguration().

◆ version()

static void version ( const bool extended)
static

Definition at line 11206 of file doxygen.cpp.

11207{
11209 QCString versionString = getFullVersion();
11210 msg("{}\n",versionString);
11211 if (extended)
11212 {
11213 QCString extVers;
11214 if (!extVers.isEmpty()) extVers+= ", ";
11215 extVers += "sqlite3 ";
11216 extVers += sqlite3_libversion();
11217#if USE_LIBCLANG
11218 if (!extVers.isEmpty()) extVers+= ", ";
11219 extVers += "clang support ";
11220 extVers += CLANG_VERSION_STRING;
11221#endif
11222 if (!extVers.isEmpty())
11223 {
11224 int lastComma = extVers.findRev(',');
11225 if (lastComma != -1) extVers = extVers.replace(lastComma,1," and");
11226 msg(" with {}.\n",extVers);
11227 }
11228 }
11229}
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 8303 of file doxygen.cpp.

8304{
8305 // for each member name
8306 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8307 {
8308 // for each member definition
8309 for (const auto &imd : *mn)
8310 {
8311 MemberDefMutable *md = toMemberDefMutable(imd.get());
8312 if (md)
8313 {
8315 }
8316 }
8317 }
8318 // for each member name
8319 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8320 {
8321 // for each member definition
8322 for (const auto &imd : *mn)
8323 {
8324 MemberDefMutable *md = toMemberDefMutable(imd.get());
8325 if (md)
8326 {
8328 }
8329 }
8330 }
8331}
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 5296 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ writeTagFile()

static void writeTagFile ( )
static

Definition at line 12003 of file doxygen.cpp.

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