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 <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 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 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 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 findEndOfTemplate (const QCString &s, size_t startPos)
 
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 findUsedTemplateInstances ()
 
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 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 const StringUnorderedSet g_compoundKeywords
 
class Statistics g_s
 

Macro Definition Documentation

◆ HAS_SIGNALS

#define HAS_SIGNALS

Definition at line 124 of file doxygen.cpp.

Enumeration Type Documentation

◆ FindBaseClassRelation_Mode

Enumerator
TemplateInstances 
DocumentedOnly 
Undocumented 

Definition at line 271 of file doxygen.cpp.

272{
276};
@ Undocumented
Definition doxygen.cpp:275
@ TemplateInstances
Definition doxygen.cpp:273
@ DocumentedOnly
Definition doxygen.cpp:274

Function Documentation

◆ addClassAndNestedClasses()

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

Definition at line 8548 of file doxygen.cpp.

8549{
8550 list.push_back(cd);
8551 for (const auto &innerCdi : cd->getClasses())
8552 {
8553 ClassDefMutable *innerCd = toClassDefMutable(innerCdi);
8554 if (innerCd && innerCd->isLinkableInProject() && innerCd->templateMaster()==nullptr &&
8555 protectionLevelVisible(innerCd->protection()) &&
8556 !innerCd->isEmbeddedInOuterScope()
8557 )
8558 {
8559 list.push_back(innerCd);
8560 addClassAndNestedClasses(list,innerCd);
8561 }
8562 }
8563}
virtual Protection protection() const =0
Return the protection level (Public,Protected,Private) in which this compound was found.
virtual bool isEmbeddedInOuterScope() const =0
virtual const ClassDef * templateMaster() const =0
Returns the template master of which this class is an instance.
virtual bool isLinkableInProject() const =0
ClassDefMutable * toClassDefMutable(Definition *d)
static void addClassAndNestedClasses(std::vector< ClassDefMutable * > &list, ClassDefMutable *cd)
Definition doxygen.cpp:8548
bool protectionLevelVisible(Protection prot)
Definition util.cpp:6192

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

Referenced by addClassAndNestedClasses(), and generateClassDocs().

◆ addClassToContext()

static void addClassToContext ( const Entry * root)
static

Definition at line 916 of file doxygen.cpp.

917{
918 AUTO_TRACE("name={}",root->name);
919 FileDef *fd = root->fileDef();
920
921 QCString scName;
922 if (root->parent()->section.isScope())
923 {
924 scName=root->parent()->name;
925 }
926 // name without parent's scope
927 QCString fullName = root->name;
928
929 // strip off any template parameters (but not those for specializations)
930 fullName=stripTemplateSpecifiersFromScope(fullName);
931
932 // name with scope (if not present already)
933 QCString qualifiedName = fullName;
934 if (!scName.isEmpty() && !leftScopeMatch(fullName,scName))
935 {
936 qualifiedName.prepend(scName+"::");
937 }
938
939 // see if we already found the class before
940 ClassDefMutable *cd = getClassMutable(qualifiedName);
941
942 AUTO_TRACE_ADD("Found class with name '{}', qualifiedName '{}'", cd ? cd->name() : root->name, qualifiedName);
943
944 if (cd)
945 {
946 fullName=cd->name();
947 AUTO_TRACE_ADD("Existing class '{}'",cd->name());
948 //if (cd->templateArguments()==0)
949 //{
950 // //printf("existing ClassDef tempArgList=%p specScope=%s\n",root->tArgList,qPrint(root->scopeSpec));
951 // cd->setTemplateArguments(tArgList);
952 //}
953
954 cd->setDocumentation(root->doc,root->docFile,root->docLine);
955 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
956 root->commandOverrides.apply_collaborationGraph([&](bool b ) { cd->overrideCollaborationGraph(b); });
957 root->commandOverrides.apply_inheritanceGraph ([&](CLASS_GRAPH_t gt) { cd->overrideInheritanceGraph(gt); });
958
959 if (!root->spec.isForwardDecl() && cd->isForwardDeclared())
960 {
961 cd->setDefFile(root->fileName,root->startLine,root->startColumn);
962 if (root->bodyLine!=-1)
963 {
964 cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
965 cd->setBodyDef(fd);
966 }
967 }
968
969 if (cd->templateArguments().empty() || (cd->isForwardDeclared() && !root->spec.isForwardDecl()))
970 {
971 // this happens if a template class declared with @class is found
972 // before the actual definition or if a forward declaration has different template
973 // parameter names.
974 std::unique_ptr<ArgumentList> tArgList = getTemplateArgumentsFromName(cd->name(),root->tArgLists);
975 if (tArgList)
976 {
977 cd->setTemplateArguments(*tArgList);
978 }
979 }
980 if (cd->requiresClause().isEmpty() && !root->req.isEmpty())
981 {
982 cd->setRequiresClause(root->req);
983 }
984
986
987 cd->setMetaData(root->metaData);
988 }
989 else // new class
990 {
992
993 QCString className;
994 QCString namespaceName;
995 extractNamespaceName(fullName,className,namespaceName);
996
997 AUTO_TRACE_ADD("New class: fullname '{}' namespace '{}' name='{}' brief='{}' docs='{}'",
998 fullName, namespaceName, className, Trace::trunc(root->brief), Trace::trunc(root->doc));
999
1000 QCString tagName;
1001 QCString refFileName;
1002 const TagInfo *tagInfo = root->tagInfo();
1003 if (tagInfo)
1004 {
1005 tagName = tagInfo->tagName;
1006 refFileName = tagInfo->fileName;
1007 if (fullName.find("::")!=-1)
1008 // symbols imported via tag files may come without the parent scope,
1009 // so we artificially create it here
1010 {
1011 buildScopeFromQualifiedName(fullName,root->lang,tagInfo);
1012 }
1013 }
1014 std::unique_ptr<ArgumentList> tArgList;
1015 int i=0;
1016 if ((root->lang==SrcLangExt::CSharp || root->lang==SrcLangExt::Java) && (i=fullName.findRev('<'))!=-1)
1017 {
1018 // a Java/C# generic class looks like a C++ specialization, so we need to split the
1019 // name and template arguments here
1020 tArgList = stringToArgumentList(root->lang,fullName.mid(i));
1021 fullName=fullName.left(i);
1022 }
1023 else
1024 {
1025 tArgList = getTemplateArgumentsFromName(fullName,root->tArgLists);
1026 }
1027 // add class to the list
1028 cd = toClassDefMutable(
1029 Doxygen::classLinkedMap->add(fullName,
1030 createClassDef(tagInfo?tagName:root->fileName,root->startLine,root->startColumn,
1031 fullName,sec,tagName,refFileName,TRUE,root->spec.isEnum()) ));
1032 if (cd)
1033 {
1034 AUTO_TRACE_ADD("New class '{}' type={} #tArgLists={} tagInfo={} hidden={} artificial={}",
1035 fullName,cd->compoundTypeString(),root->tArgLists.size(),
1036 fmt::ptr(tagInfo),root->hidden,root->artificial);
1037 cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1038 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1039 cd->setLanguage(root->lang);
1040 cd->setId(root->id);
1041 cd->setHidden(root->hidden);
1042 cd->setArtificial(root->artificial);
1043 cd->setClassSpecifier(root->spec);
1044 cd->addQualifiers(root->qualifiers);
1045 cd->setTypeConstraints(root->typeConstr);
1046 root->commandOverrides.apply_collaborationGraph([&](bool b ) { cd->overrideCollaborationGraph(b); });
1047 root->commandOverrides.apply_inheritanceGraph ([&](CLASS_GRAPH_t gt) { cd->overrideInheritanceGraph(gt); });
1048
1049 if (tArgList)
1050 {
1051 cd->setTemplateArguments(*tArgList);
1052 }
1053 cd->setRequiresClause(root->req);
1054 cd->setProtection(root->protection);
1055 cd->setIsStatic(root->isStatic);
1056
1057 // file definition containing the class cd
1058 cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1059 cd->setBodyDef(fd);
1060
1061 cd->setMetaData(root->metaData);
1062
1063 cd->insertUsedFile(fd);
1064 }
1065 else
1066 {
1067 AUTO_TRACE_ADD("Class {} not added, already exists as alias", fullName);
1068 }
1069 }
1070
1071 if (cd)
1072 {
1074 if (!root->subGrouping) cd->setSubGrouping(FALSE);
1075 if (!root->spec.isForwardDecl())
1076 {
1077 if (cd->hasDocumentation())
1078 {
1079 addIncludeFile(cd,fd,root);
1080 }
1081 if (fd && root->section.isCompound())
1082 {
1083 AUTO_TRACE_ADD("Inserting class {} in file {} (root->fileName='{}')", cd->name(), fd->name(), root->fileName);
1084 cd->setFileDef(fd);
1085 fd->insertClass(cd);
1086 }
1087 }
1088 addClassToGroups(root,cd);
1090 cd->setRefItems(root->sli);
1091 }
1092}
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 const QCString & name() 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:87
bool subGrouping
automatically group class members?
Definition entry.h:187
QCString metaData
Slice metadata.
Definition entry.h:232
int docLine
line number at which the documentation was found
Definition entry.h:200
ArgumentList typeConstr
where clause (C#) for type constraints
Definition entry.h:214
int endBodyLine
line number where the definition ends
Definition entry.h:217
const TagInfo * tagInfo() const
Definition entry.h:176
QCString id
libclang id
Definition entry.h:230
ArgumentLists tArgLists
template argument declarations
Definition entry.h:194
SrcLangExt lang
programming language in which this entry was found
Definition entry.h:226
Entry * parent() const
Definition entry.h:133
int startColumn
start column of entry in the source
Definition entry.h:224
std::vector< const SectionInfo * > anchors
list of anchors defined in this entry
Definition entry.h:221
QCString fileName
file this entry was extracted from
Definition entry.h:222
CommandOverrides commandOverrides
store info for commands whose default can be overridden
Definition entry.h:189
int startLine
start line of entry in the source
Definition entry.h:223
QCString req
C++20 requires clause.
Definition entry.h:233
QCString name
member name
Definition entry.h:173
EntryType section
entry type (see Sections);
Definition entry.h:171
QCString briefFile
file in which the brief desc. was found
Definition entry.h:204
int bodyLine
line number of the body in the source
Definition entry.h:215
std::vector< std::string > qualifiers
qualifiers specified with the qualifier command
Definition entry.h:234
QCString doc
documentation block (partly parsed)
Definition entry.h:199
RefItemVector sli
special lists (test/todo/bug/deprecated/..) this entry is in
Definition entry.h:225
QCString docFile
file in which the documentation was found
Definition entry.h:201
Protection protection
class protection
Definition entry.h:179
bool artificial
Artificially introduced item.
Definition entry.h:228
bool hidden
does this represent an entity that is hidden from the output
Definition entry.h:227
QCString brief
brief description (doc block)
Definition entry.h:202
int briefLine
line number at which the brief desc. was found
Definition entry.h:203
FileDef * fileDef() const
Definition entry.h:168
bool isStatic
static ?
Definition entry.h:184
TypeSpecifier spec
class/member specifiers
Definition entry.h:181
ENTRY_TYPES bool isCompound() const
Definition types.h:529
bool isScope() const
Definition types.h:530
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:94
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
QCString & prepend(const char *s)
Definition qcstring.h:398
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:219
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:143
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:91
QCString left(size_t len) const
Definition qcstring.h:207
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:405
ClassDefMutable * getClassMutable(const QCString &key)
Definition classdef.h:461
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
#define AUTO_TRACE(...)
Definition docnode.cpp:46
static void addIncludeFile(DefMutable *cd, FileDef *ifd, const Entry *root)
Definition doxygen.cpp:567
static ClassDef::CompoundType convertToCompoundType(EntryType section, TypeSpecifier specifier)
Definition doxygen.cpp:874
std::unique_ptr< ArgumentList > getTemplateArgumentsFromName(const QCString &name, const ArgumentLists &tArgLists)
Definition doxygen.cpp:844
static Definition * buildScopeFromQualifiedName(const QCString &name_, SrcLangExt lang, const TagInfo *tagInfo)
Definition doxygen.cpp:691
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:102
QCString fileName
Definition entry.h:104
QCString tagName
Definition entry.h:103
bool leftScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:891
void extractNamespaceName(const QCString &scopeName, QCString &className, QCString &namespaceName, bool allowEmptyClass)
Definition util.cpp:3990
QCString stripTemplateSpecifiersFromScope(const QCString &fullName, bool parentOnly, QCString *pLastScopeStripped, QCString scopeName, bool allowArtificial)
Definition util.cpp:4795

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(), 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 1121 of file doxygen.cpp.

1122{
1123 AUTO_TRACE();
1124 FileDef *fd = root->fileDef();
1125
1126 QCString scName;
1127 if (root->parent()->section.isScope())
1128 {
1129 scName=root->parent()->name;
1130 }
1131
1132 // name with scope (if not present already)
1133 QCString qualifiedName = root->name;
1134 if (!scName.isEmpty() && !leftScopeMatch(qualifiedName,scName))
1135 {
1136 qualifiedName.prepend(scName+"::");
1137 }
1138
1139 // see if we already found the concept before
1140 ConceptDefMutable *cd = getConceptMutable(qualifiedName);
1141
1142 AUTO_TRACE_ADD("Found concept with name '{}' (qualifiedName='{}')", cd ? cd->name() : root->name, qualifiedName);
1143
1144 if (cd)
1145 {
1146 qualifiedName=cd->name();
1147 AUTO_TRACE_ADD("Existing concept '{}'",cd->name());
1148
1149 cd->setDocumentation(root->doc,root->docFile,root->docLine);
1150 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1151
1152 addIncludeFile(cd,fd,root);
1153 }
1154 else // new concept
1155 {
1156 QCString className;
1157 QCString namespaceName;
1158 extractNamespaceName(qualifiedName,className,namespaceName);
1159
1160 AUTO_TRACE_ADD("New concept: fullname '{}' namespace '{}' name='{}' brief='{}' docs='{}'",
1161 qualifiedName,namespaceName,className,root->brief,root->doc);
1162
1163 QCString tagName;
1164 QCString refFileName;
1165 const TagInfo *tagInfo = root->tagInfo();
1166 if (tagInfo)
1167 {
1168 tagName = tagInfo->tagName;
1169 refFileName = tagInfo->fileName;
1170 if (qualifiedName.find("::")!=-1)
1171 // symbols imported via tag files may come without the parent scope,
1172 // so we artificially create it here
1173 {
1174 buildScopeFromQualifiedName(qualifiedName,root->lang,tagInfo);
1175 }
1176 }
1177 std::unique_ptr<ArgumentList> tArgList = getTemplateArgumentsFromName(qualifiedName,root->tArgLists);
1178 // add concept to the list
1180 Doxygen::conceptLinkedMap->add(qualifiedName,
1181 createConceptDef(tagInfo?tagName:root->fileName,root->startLine,root->startColumn,
1182 qualifiedName,tagName,refFileName)));
1183 if (cd)
1184 {
1185 AUTO_TRACE_ADD("New concept '{}' #tArgLists={} tagInfo={}",
1186 qualifiedName,root->tArgLists.size(),fmt::ptr(tagInfo));
1187 cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1188 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1189 cd->setLanguage(root->lang);
1190 cd->setId(root->id);
1191 cd->setHidden(root->hidden);
1192 cd->setGroupId(root->mGrpId);
1193 if (tArgList)
1194 {
1195 cd->setTemplateArguments(*tArgList);
1196 }
1197 cd->setInitializer(root->initializer.str().c_str());
1198 // file definition containing the class cd
1199 cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1200 cd->setBodyDef(fd);
1201 addIncludeFile(cd,fd,root);
1202
1203 // also add namespace to the correct structural context
1204 Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,qualifiedName,nullptr,tagInfo);
1206 {
1208 if (dm)
1209 {
1210 dm->addInnerCompound(cd);
1211 }
1212 cd->setOuterScope(d);
1213 }
1214 }
1215 else
1216 {
1217 AUTO_TRACE_ADD("Concept '{}' not added, already exists (as alias)", qualifiedName);
1218 }
1219 }
1220
1221 if (cd)
1222 {
1224 if (fd)
1225 {
1226 AUTO_TRACE_ADD("Inserting concept '{}' in file '{}' (root->fileName='{}')", cd->name(), fd->name(), root->fileName);
1227 cd->setFileDef(fd);
1228 fd->insertConcept(cd);
1229 }
1230 addConceptToGroups(root,cd);
1232 cd->setRefItems(root->sli);
1233 }
1234}
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:89
static NamespaceDefMutable * globalScope
Definition doxygen.h:111
TextStream initializer
initial value (for variables)
Definition entry.h:196
int mGrpId
member group id
Definition entry.h:218
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:91
DefinitionMutable * toDefinitionMutable(Definition *d)
static Definition * findScopeFromQualifiedName(NamespaceDefMutable *startScope, const QCString &n, FileDef *fileScope, const TagInfo *tagInfo)
Definition doxygen.cpp:759
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 8928 of file doxygen.cpp.

8929{
8930 md->setDocumentation(root->doc,root->docFile,root->docLine);
8931 md->setDocsForDefinition(!root->proto);
8932 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
8933 if (md->inbodyDocumentation().isEmpty())
8934 {
8936 }
8937 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
8938 {
8939 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
8940 md->setBodyDef(root->fileDef());
8941 }
8943 md->setMaxInitLines(root->initLines);
8945 md->setRefItems(root->sli);
8946 if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
8947 addMemberToGroups(root,md);
8949}
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:186
QCString inbodyDocs
documentation inside the body of a function
Definition entry.h:205
int inbodyLine
line number at which the body doc was found
Definition entry.h:206
int initLines
define/variable initializer lines to show
Definition entry.h:183
QCString inbodyFile
file in which the body doc was found
Definition entry.h:207
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:2056
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 7377 of file doxygen.cpp.

7378{
7379 AUTO_TRACE();
7380 // documentation outside a compound overrides the documentation inside it
7381 {
7382 md->setDocumentation(root->doc,root->docFile,root->docLine);
7383 md->setDocsForDefinition(!root->proto);
7384 }
7385
7386 // brief descriptions inside a compound override the documentation
7387 // outside it
7388 {
7389 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7390 }
7391
7392 if (md->inbodyDocumentation().isEmpty() || !root->parent()->name.isEmpty())
7393 {
7395 }
7396
7397 if (root->mGrpId!=-1 && md->getMemberGroupId()==-1)
7398 {
7399 md->setMemberGroupId(root->mGrpId);
7400 }
7401
7403 md->setRefItems(root->sli);
7404
7405 const GroupDef *gd=md->getGroupDef();
7406 if (gd==nullptr && !root->groups.empty()) // member not grouped but out-of-line documentation is
7407 {
7408 addMemberToGroups(root,md);
7409 }
7411}
std::vector< Grouping > groups
list of groups this entry belongs to
Definition entry.h:220
A model of a group of symbols.
Definition groupdef.h:52
virtual const GroupDef * getGroupDef() const =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 7146 of file doxygen.cpp.

7147{
7148 if (root->section.isEnum())
7149 // non anonymous enumeration
7150 {
7151 ClassDefMutable *cd = nullptr;
7152 FileDef *fd = nullptr;
7153 NamespaceDefMutable *nd = nullptr;
7154 MemberNameLinkedMap *mnsd = nullptr;
7155 bool isGlobal = false;
7156 bool isRelated = false;
7157 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
7158
7159 QCString name;
7160 QCString scope;
7161
7162 int i = root->name.findRev("::");
7163 if (i!=-1) // scope is specified
7164 {
7165 scope=root->name.left(i); // extract scope
7166 name=root->name.right(root->name.length()-i-2); // extract name
7167 if ((cd=getClassMutable(scope))==nullptr)
7168 {
7170 }
7171 }
7172 else // no scope, check the scope in which the docs where found
7173 {
7174 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7175 {
7176 scope=root->parent()->name;
7177 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7178 }
7179 name=root->name;
7180 }
7181
7182 if (!root->relates.isEmpty())
7183 { // related member, prefix user specified scope
7184 isRelated=TRUE;
7185 if (getClassMutable(root->relates)==nullptr && !scope.isEmpty())
7186 scope=mergeScopes(scope,root->relates);
7187 else
7188 scope=root->relates;
7189 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7190 }
7191
7192 if (cd && !name.isEmpty()) // found a enum inside a compound
7193 {
7194 //printf("Enum in class '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
7195 fd=nullptr;
7197 isGlobal=false;
7198 }
7199 else if (nd && !nd->isAnonymous()) // found enum inside namespace
7200 {
7201 //printf("Enum in namespace '%s'::'%s'\n",qPrint(nd->name()),qPrint(name));
7203 isGlobal=true;
7204 }
7205 else // found a global enum
7206 {
7207 fd=root->fileDef();
7208 //printf("Enum in file '%s': '%s'\n",qPrint(fd->name()),qPrint(name));
7210 isGlobal=true;
7211 }
7212
7213 if (!name.isEmpty())
7214 {
7215 //printf("** name=%s\n",qPrint(name));
7216 MemberName *mn = mnsd->find(name); // for all members with this name
7217 if (mn)
7218 {
7219 struct EnumValueInfo
7220 {
7221 EnumValueInfo(const QCString &n,std::unique_ptr<MemberDef> &&md) :
7222 name(n), member(std::move(md)) {}
7223 QCString name;
7224 std::unique_ptr<MemberDef> member;
7225 };
7226 std::vector< EnumValueInfo > extraMembers;
7227 // for each enum in this list
7228 for (const auto &imd : *mn)
7229 {
7230 MemberDefMutable *md = toMemberDefMutable(imd.get());
7231 // use raw pointer in this loop, since we modify mn and can then invalidate mdp.
7232 if (md && md->isEnumerate() && !root->children().empty())
7233 {
7234 //printf(" enum with %zu children\n",root->children().size());
7235 for (const auto &e : root->children())
7236 {
7237 SrcLangExt sle = root->lang;
7238 bool isJavaLike = sle==SrcLangExt::CSharp || sle==SrcLangExt::Java || sle==SrcLangExt::XML;
7239 if ( isJavaLike || root->spec.isStrong())
7240 {
7241 // Unlike classic C/C++ enums, for C++11, C# & Java enum
7242 // values are only visible inside the enum scope, so we must create
7243 // them here and only add them to the enum
7244 //printf("md->qualifiedName()=%s e->name=%s tagInfo=%p name=%s\n",
7245 // qPrint(md->qualifiedName()),qPrint(e->name),(void*)e->tagInfo(),qPrint(e->name));
7246 QCString qualifiedName = root->name;
7247 if (isJavaLike)
7248 {
7249 qualifiedName=substitute(qualifiedName,"::",".");
7250 }
7251 if (md->qualifiedName()==qualifiedName) // enum value scope matches that of the enum
7252 {
7253 QCString fileName = e->fileName;
7254 if (fileName.isEmpty() && e->tagInfo())
7255 {
7256 fileName = e->tagInfo()->tagName;
7257 }
7258 auto fmd = createMemberDef(
7259 fileName,e->startLine,e->startColumn,
7260 e->type,e->name,e->args,QCString(),
7261 e->protection, Specifier::Normal,e->isStatic,Relationship::Member,
7263 auto fmmd = toMemberDefMutable(fmd.get());
7264 NamespaceDef *mnd = md->getNamespaceDef();
7265 if (md->getClassDef())
7266 fmmd->setMemberClass(md->getClassDef());
7267 else if (mnd && (mnd->isLinkable() || mnd->isAnonymous()))
7268 fmmd->setNamespace(mnd);
7269 else if (md->getFileDef())
7270 fmmd->setFileDef(md->getFileDef());
7271 fmmd->setOuterScope(md->getOuterScope());
7272 fmmd->setTagInfo(e->tagInfo());
7273 fmmd->setLanguage(e->lang);
7274 fmmd->setId(e->id);
7275 fmmd->setDocumentation(e->doc,e->docFile,e->docLine);
7276 fmmd->setBriefDescription(e->brief,e->briefFile,e->briefLine);
7277 fmmd->addSectionsToDefinition(e->anchors);
7278 std::string init = e->initializer.str();
7279 fmmd->setInitializer(init.c_str());
7280 fmmd->setMaxInitLines(e->initLines);
7281 fmmd->setMemberGroupId(e->mGrpId);
7282 fmmd->setExplicitExternal(e->explicitExternal,fileName,e->startLine,e->startColumn);
7283 fmmd->setRefItems(e->sli);
7284 fmmd->setAnchor();
7285 md->insertEnumField(fmd.get());
7286 fmmd->setEnumScope(md,TRUE);
7287 extraMembers.emplace_back(e->name,std::move(fmd));
7288 }
7289 }
7290 else
7291 {
7292 //printf("e->name=%s isRelated=%d\n",qPrint(e->name),isRelated);
7293 MemberName *fmn=nullptr;
7294 MemberNameLinkedMap *emnsd = isRelated ? Doxygen::functionNameLinkedMap : mnsd;
7295 if (!e->name.isEmpty() && (fmn=emnsd->find(e->name)))
7296 // get list of members with the same name as the field
7297 {
7298 for (const auto &ifmd : *fmn)
7299 {
7300 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
7301 if (fmd && fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope
7302 {
7303 //printf("found enum value with same name %s in scope %s\n",
7304 // qPrint(fmd->name()),qPrint(fmd->getOuterScope()->name()));
7305 if (nd && !nd->isAnonymous())
7306 {
7307 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7308 {
7309 const NamespaceDef *fnd=fmd->getNamespaceDef();
7310 if (fnd==nd) // enum value is inside a namespace
7311 {
7312 md->insertEnumField(fmd);
7313 fmd->setEnumScope(md);
7314 }
7315 }
7316 }
7317 else if (isGlobal)
7318 {
7319 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7320 {
7321 const FileDef *ffd=fmd->getFileDef();
7322 if (ffd==fd && ffd==md->getFileDef()) // enum value has file scope
7323 {
7324 md->insertEnumField(fmd);
7325 fmd->setEnumScope(md);
7326 }
7327 }
7328 }
7329 else if (isRelated && cd) // reparent enum value to
7330 // match the enum's scope
7331 {
7332 md->insertEnumField(fmd); // add field def to list
7333 fmd->setEnumScope(md); // cross ref with enum name
7334 fmd->setEnumClassScope(cd); // cross ref with enum name
7335 fmd->setOuterScope(cd);
7336 fmd->makeRelated();
7337 cd->insertMember(fmd);
7338 }
7339 else
7340 {
7341 if (!fmd->isStrongEnumValue()) // only non strong enum values can be globally added
7342 {
7343 const ClassDef *fcd=fmd->getClassDef();
7344 if (fcd==cd) // enum value is inside a class
7345 {
7346 //printf("Inserting enum field %s in enum scope %s\n",
7347 // qPrint(fmd->name()),qPrint(md->name()));
7348 md->insertEnumField(fmd); // add field def to list
7349 fmd->setEnumScope(md); // cross ref with enum name
7350 }
7351 }
7352 }
7353 }
7354 }
7355 }
7356 }
7357 }
7358 }
7359 }
7360 // move the newly added members into mn
7361 for (auto &e : extraMembers)
7362 {
7363 MemberName *emn=mnsd->add(e.name);
7364 emn->push_back(std::move(e.member));
7365 }
7366 }
7367 }
7368 }
7369 else
7370 {
7371 for (const auto &e : root->children()) addEnumValuesToEnums(e.get());
7372 }
7373}
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:102
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:101
const std::vector< std::shared_ptr< Entry > > & children() const
Definition entry.h:138
QCString relates
related class (doc block)
Definition entry.h:208
T * add(const char *k, Args &&... args)
Adds a new object to the ordered vector if it was not added already.
Definition linkedmap.h:90
const T * find(const std::string &key) const
Find an object given the key.
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 setEnumClassScope(ClassDef *cd)=0
virtual void setEnumScope(const MemberDef *md, bool livesInsideEnum=FALSE)=0
virtual void insertEnumField(MemberDef *md)=0
virtual void makeRelated()=0
void push_back(Ptr &&p)
Definition membername.h:53
Ordered dictionary of MemberName objects.
Definition membername.h:62
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:146
QCString right(size_t len) const
Definition qcstring.h:212
static void addEnumValuesToEnums(const Entry *root)
Definition doxygen.cpp:7146
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
@ MemberType_EnumValue
Definition types.h:287
SrcLangExt
Language as given by extension.
Definition types.h:42
QCString mergeScopes(const QCString &leftScope, const QCString &rightScope)
Definition util.cpp:4862

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addEnumValuesToEnums(), buildScopeFromQualifiedName(), Entry::children(), createMemberDef(), CSharp, 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(), Member, Doxygen::memberNameLinkedMap, MemberType_EnumValue, mergeScopes(), 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().

◆ addIncludeFile()

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

Definition at line 567 of file doxygen.cpp.

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

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

◆ addListReferences()

static void addListReferences ( )
static

Definition at line 4985 of file doxygen.cpp.

4986{
4987 AUTO_TRACE();
4988 for (const auto &cd : *Doxygen::classLinkedMap)
4989 {
4990 ClassDefMutable *cdm = toClassDefMutable(cd.get());
4991 if (cdm)
4992 {
4993 cdm->addListReferences();
4994 }
4995 }
4996
4997 for (const auto &fn : *Doxygen::inputNameLinkedMap)
4998 {
4999 for (const auto &fd : *fn)
5000 {
5001 fd->addListReferences();
5002 }
5003 }
5004
5005 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5006 {
5008 if (ndm)
5009 {
5010 ndm->addListReferences();
5011 }
5012 }
5013
5014 for (const auto &gd : *Doxygen::groupLinkedMap)
5015 {
5016 gd->addListReferences();
5017 }
5018
5019 for (const auto &pd : *Doxygen::pageLinkedMap)
5020 {
5021 QCString name = pd->getOutputFileBase();
5022 if (pd->getGroupDef())
5023 {
5024 name = pd->getGroupDef()->getOutputFileBase();
5025 }
5026 {
5027 const RefItemVector &xrefItems = pd->xrefListItems();
5028 addRefItem(xrefItems,
5029 name,
5031 name,pd->title(),QCString(),nullptr);
5032 }
5033 }
5034
5035 for (const auto &dd : *Doxygen::dirLinkedMap)
5036 {
5037 QCString name = dd->getOutputFileBase();
5038 //if (dd->getGroupDef())
5039 //{
5040 // name = dd->getGroupDef()->getOutputFileBase();
5041 //}
5042 const RefItemVector &xrefItems = dd->xrefListItems();
5043 addRefItem(xrefItems,
5044 name,
5046 name,dd->displayName(),QCString(),nullptr);
5047 }
5048
5050}
virtual void addListReferences()=0
This class serves as a namespace for global variables used by doxygen.
Definition doxygen.h:85
void addListReferences()
virtual void addListReferences()=0
virtual QCString trDir(bool first_capital, bool singular)=0
virtual QCString trPage(bool first_capital, bool singular)=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:5074

References ClassDefMutable::addListReferences(), FileDef::addListReferences(), GroupDef::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(), Translator::trDir(), Translator::trPage(), 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 5619 of file doxygen.cpp.

5624{
5625 AUTO_TRACE();
5626 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
5627 ClassDefMutable *cd=nullptr;
5628 if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClassMutable(scopeName)))
5629 {
5630 AUTO_TRACE_ADD("Local objective C method '{}' scopeName='{}'",root->name,scopeName);
5631 auto md = createMemberDef(
5632 root->fileName,root->startLine,root->startColumn,
5633 funcType,funcName,funcArgs,exceptions,
5634 root->protection,root->virt,root->isStatic,Relationship::Member,
5636 auto mmd = toMemberDefMutable(md.get());
5637 mmd->setTagInfo(root->tagInfo());
5638 mmd->setLanguage(root->lang);
5639 mmd->setId(root->id);
5640 mmd->makeImplementationDetail();
5641 mmd->setMemberClass(cd);
5642 mmd->setDefinition(funcDecl);
5644 mmd->addQualifiers(root->qualifiers);
5645 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
5646 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
5647 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
5648 mmd->setDocsForDefinition(!root->proto);
5649 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
5650 mmd->addSectionsToDefinition(root->anchors);
5651 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
5652 FileDef *fd=root->fileDef();
5653 mmd->setBodyDef(fd);
5654 mmd->setMemberSpecifiers(spec);
5655 mmd->setVhdlSpecifiers(root->vhdlSpec);
5656 mmd->setMemberGroupId(root->mGrpId);
5657 cd->insertMember(md.get());
5658 cd->insertUsedFile(fd);
5659 mmd->setRefItems(root->sli);
5660
5662 mn->push_back(std::move(md));
5663 }
5664 else
5665 {
5666 // local objective C method found for class without interface
5667 }
5668}
VhdlSpecifier vhdlSpec
VHDL specifiers.
Definition entry.h:182
ArgumentList argList
member arguments as a list
Definition entry.h:193
Specifier virt
virtualness of the entry
Definition entry.h:190
@ MemberType_Function
Definition types.h:283

References LinkedMap< T, Hash, KeyEqual, Map >::add(), MemberDefMutable::addQualifiers(), DefinitionMutable::addSectionsToDefinition(), 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, getClassMutable(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), Entry::isStatic, Entry::lang, MemberDefMutable::makeImplementationDetail(), Member, Doxygen::memberNameLinkedMap, MemberType_Function, Entry::metaData, Entry::mGrpId, Entry::name, Entry::protection, Entry::proto, MemberName::push_back(), Entry::qualifiers, DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), MemberDefMutable::setDefinition(), MemberDefMutable::setDocsForDefinition(), DefinitionMutable::setDocumentation(), DefinitionMutable::setId(), DefinitionMutable::setInbodyDocumentation(), DefinitionMutable::setLanguage(), MemberDefMutable::setMemberClass(), MemberDefMutable::setMemberGroupId(), MemberDefMutable::setMemberSpecifiers(), MemberDefMutable::setPrototype(), DefinitionMutable::setRefItems(), MemberDefMutable::setTagInfo(), MemberDefMutable::setVhdlSpecifiers(), 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 5068 of file doxygen.cpp.

5074{
5075 if (md==nullptr) return;
5076 AUTO_TRACE("scope='{}' name='{}' args='{}' funcDecl='{}' mSpec={}",
5077 root->parent()->name,md->name(),md->argsString(),funcDecl,spec);
5078 if (!root->section.isDoc()) // @fn or @var does not need to specify the complete definition, so don't overwrite it
5079 {
5080 QCString fDecl=funcDecl;
5081 // strip extern specifier
5082 fDecl.stripPrefix("extern ");
5083 md->setDefinition(fDecl);
5084 }
5086 md->addQualifiers(root->qualifiers);
5088 const NamespaceDef *nd=md->getNamespaceDef();
5089 QCString fullName;
5090 if (cd)
5091 fullName = cd->name();
5092 else if (nd)
5093 fullName = nd->name();
5094
5095 if (!fullName.isEmpty()) fullName+="::";
5096 fullName+=md->name();
5097 FileDef *rfd=root->fileDef();
5098
5099 // TODO determine scope based on root not md
5100 Definition *rscope = md->getOuterScope();
5101
5102 const ArgumentList &mdAl = md->argumentList();
5103 if (al)
5104 {
5105 ArgumentList mergedAl = *al;
5106 //printf("merging arguments (1) docs=%d\n",root->doc.isEmpty());
5107 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedAl,!root->doc.isEmpty());
5108 }
5109 else
5110 {
5111 if (
5112 matchArguments2( md->getOuterScope(), md->getFileDef(),const_cast<ArgumentList*>(&mdAl),
5113 rscope,rfd,&root->argList,
5114 TRUE, root->lang
5115 )
5116 )
5117 {
5118 //printf("merging arguments (2)\n");
5119 ArgumentList mergedArgList = root->argList;
5120 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.isEmpty());
5121 }
5122 }
5123 if (over_load) // the \overload keyword was used
5124 {
5126 if (!root->doc.isEmpty())
5127 {
5128 doc+="<p>";
5129 doc+=root->doc;
5130 }
5131 md->setDocumentation(doc,root->docFile,root->docLine);
5133 md->setDocsForDefinition(!root->proto);
5134 }
5135 else
5136 {
5137 //printf("overwrite!\n");
5138 md->setDocumentation(root->doc,root->docFile,root->docLine);
5139 md->setDocsForDefinition(!root->proto);
5140
5141 //printf("overwrite!\n");
5142 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
5143
5144 if (
5145 (md->inbodyDocumentation().isEmpty() ||
5146 !root->parent()->name.isEmpty()
5147 ) && !root->inbodyDocs.isEmpty()
5148 )
5149 {
5151 }
5152 }
5153
5154 //printf("initializer: '%s'(isEmpty=%d) '%s'(isEmpty=%d)\n",
5155 // qPrint(md->initializer()),md->initializer().isEmpty(),
5156 // qPrint(root->initializer),root->initializer.isEmpty()
5157 // );
5158 std::string rootInit = root->initializer.str();
5159 if (md->initializer().isEmpty() && !rootInit.empty())
5160 {
5161 //printf("setInitializer\n");
5162 md->setInitializer(rootInit.c_str());
5163 }
5164 if (md->requiresClause().isEmpty() && !root->req.isEmpty())
5165 {
5166 md->setRequiresClause(root->req);
5167 }
5168
5169 md->setMaxInitLines(root->initLines);
5170
5171 if (rfd)
5172 {
5173 if ((md->getStartBodyLine()==-1 && root->bodyLine!=-1)
5174 )
5175 {
5176 //printf("Setting new body segment [%d,%d]\n",root->bodyLine,root->endBodyLine);
5177 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
5178 md->setBodyDef(rfd);
5179 }
5180
5181 md->setRefItems(root->sli);
5182 }
5183
5185 md->addQualifiers(root->qualifiers);
5186
5187 md->mergeMemberSpecifiers(spec);
5189 addMemberToGroups(root,md);
5191 if (cd) cd->insertUsedFile(rfd);
5192 //printf("root->mGrpId=%d\n",root->mGrpId);
5193 if (root->mGrpId!=-1)
5194 {
5195 if (md->getMemberGroupId()!=-1)
5196 {
5197 if (md->getMemberGroupId()!=root->mGrpId)
5198 {
5199 warn(
5200 root->fileName,root->startLine,
5201 "member %s belongs to two different groups. The second "
5202 "one found here will be ignored.",
5203 qPrint(md->name())
5204 );
5205 }
5206 }
5207 else // set group id
5208 {
5209 //printf("setMemberGroupId=%d md=%s\n",root->mGrpId,qPrint(md->name()));
5210 md->setMemberGroupId(root->mGrpId);
5211 }
5212 }
5213 md->addQualifiers(root->qualifiers);
5214}
bool isDoc() const
Definition types.h:533
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:191
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:1923
void mergeArguments(ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
Definition util.cpp:2017
QCString getOverloadDocs()
Definition util.cpp:4379

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, qPrint(), 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 5672 of file doxygen.cpp.

5690{
5691 AUTO_TRACE();
5692 QCString funcType = funcTyp;
5693 int count=0;
5694 int noMatchCount=0;
5695 bool memFound=FALSE;
5696 for (const auto &imd : *mn)
5697 {
5698 MemberDefMutable *md = toMemberDefMutable(imd.get());
5699 if (md==nullptr) continue;
5701 if (cd==nullptr) continue;
5702 //AUTO_TRACE_ADD("member definition found, scope needed='{}' scope='{}' args='{}' fileName='{}'",
5703 // scopeName, cd->name(), md->argsString(), root->fileName);
5704 FileDef *fd=root->fileDef();
5705 NamespaceDef *nd=nullptr;
5706 if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName);
5707
5708 //printf("scopeName %s->%s\n",qPrint(scopeName),
5709 // qPrint(stripTemplateSpecifiersFromScope(scopeName,FALSE)));
5710
5711 // if the member we are searching for is an enum value that is part of
5712 // a "strong" enum, we need to look into the fields of the enum for a match
5713 int enumNamePos=0;
5714 if (md->isEnumValue() && (enumNamePos=className.findRev("::"))!=-1)
5715 {
5716 QCString enumName = className.mid(enumNamePos+2);
5717 QCString fullScope = className.left(enumNamePos);
5718 if (!namespaceName.isEmpty()) fullScope.prepend(namespaceName+"::");
5719 if (fullScope==cd->name())
5720 {
5721 MemberName *enumMn=Doxygen::memberNameLinkedMap->find(enumName);
5722 //printf("enumMn(%s)=%p\n",qPrint(className),(void*)enumMn);
5723 if (enumMn)
5724 {
5725 for (const auto &emd : *enumMn)
5726 {
5727 memFound = emd->isStrong() && md->getEnumScope()==emd.get();
5728 if (memFound)
5729 {
5730 addMemberDocs(root,md,funcDecl,nullptr,overloaded,spec);
5731 count++;
5732 }
5733 if (memFound) break;
5734 }
5735 }
5736 }
5737 }
5738 if (memFound) break;
5739
5740 const ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
5741 if (tcd==nullptr && cd && stripAnonymousNamespaceScope(cd->name())==scopeName)
5742 {
5743 // don't be fooled by anonymous scopes
5744 tcd=cd;
5745 }
5746 //printf("Looking for %s inside nd=%s result=%p (%s) cd=%p\n",
5747 // qPrint(scopeName),nd?qPrint(nd->name()):"<none>",tcd,tcd?qPrint(tcd->name()):"",cd);
5748
5749 if (cd && tcd==cd) // member's classes match
5750 {
5751 AUTO_TRACE_ADD("class definition '{}' found",cd->name());
5752
5753 // get the template parameter lists found at the member declaration
5754 ArgumentLists declTemplArgs = cd->getTemplateParameterLists();
5755 const ArgumentList &templAl = md->templateArguments();
5756 if (!templAl.empty())
5757 {
5758 declTemplArgs.push_back(templAl);
5759 }
5760
5761 // get the template parameter lists found at the member definition
5762 const ArgumentLists &defTemplArgs = root->tArgLists;
5763 //printf("defTemplArgs=%p\n",defTemplArgs);
5764
5765 // do we replace the decl argument lists with the def argument lists?
5766 bool substDone=FALSE;
5767 ArgumentList argList;
5768
5769 /* substitute the occurrences of class template names in the
5770 * argument list before matching
5771 */
5772 const ArgumentList &mdAl = md->argumentList();
5773 if (declTemplArgs.size()>0 && declTemplArgs.size()==defTemplArgs.size())
5774 {
5775 /* the function definition has template arguments
5776 * and the class definition also has template arguments, so
5777 * we must substitute the template names of the class by that
5778 * of the function definition before matching.
5779 */
5780 substituteTemplatesInArgList(declTemplArgs,defTemplArgs,mdAl,argList);
5781
5782 substDone=TRUE;
5783 }
5784 else /* no template arguments, compare argument lists directly */
5785 {
5786 argList = mdAl;
5787 }
5788
5789 AUTO_TRACE_ADD("matching '{}'<=>'{}' className='{}' namespaceName='{}'",
5790 argListToString(argList,TRUE),argListToString(root->argList,TRUE),className,namespaceName);
5791
5792 bool matching=
5793 md->isVariable() || md->isTypedef() || // needed for function pointers
5795 md->getClassDef(),md->getFileDef(),&argList,
5796 cd,fd,&root->argList,
5797 TRUE,root->lang);
5798
5799 if (md->getLanguage()==SrcLangExt::ObjC && md->isVariable() && root->section.isFunction())
5800 {
5801 matching = FALSE; // don't match methods and attributes with the same name
5802 }
5803
5804 // for template member we also need to check the return type
5805 if (!md->templateArguments().empty() && !root->tArgLists.empty())
5806 {
5807 QCString memType = md->typeString();
5808 memType.stripPrefix("static "); // see bug700696
5810 className+"::",""); // see bug700693 & bug732594
5812 className+"::",""); // see bug758900
5813 AUTO_TRACE_ADD("Comparing return types '{}'<->'{}' #args {}<->{}",
5814 md->typeString(),funcType,md->templateArguments().size(),root->tArgLists.back().size());
5815 if (md->templateArguments().size()!=root->tArgLists.back().size() || memType!=funcType)
5816 {
5817 //printf(" ---> no matching\n");
5818 matching = FALSE;
5819 }
5820 }
5821 else if (defTemplArgs.size()>declTemplArgs.size())
5822 {
5823 // avoid matching a non-template function in a template class against a
5824 // template function with the same name and parameters, see issue #10184
5825 substDone = false;
5826 matching = false;
5827 }
5828 bool rootIsUserDoc = root->section.isMemberDoc();
5829 bool classIsTemplate = scopeIsTemplate(md->getClassDef());
5830 bool mdIsTemplate = md->templateArguments().hasParameters();
5831 bool classOrMdIsTemplate = mdIsTemplate || classIsTemplate;
5832 bool rootIsTemplate = !root->tArgLists.empty();
5833 //printf("classIsTemplate=%d mdIsTemplate=%d rootIsTemplate=%d\n",classIsTemplate,mdIsTemplate,rootIsTemplate);
5834 if (!rootIsUserDoc && // don't check out-of-line @fn references, see bug722457
5835 (mdIsTemplate || rootIsTemplate) && // either md or root is a template
5836 ((classOrMdIsTemplate && !rootIsTemplate) || (!classOrMdIsTemplate && rootIsTemplate))
5837 )
5838 {
5839 // Method with template return type does not match method without return type
5840 // even if the parameters are the same. See also bug709052
5841 AUTO_TRACE_ADD("Comparing return types: template v.s. non-template");
5842 matching = FALSE;
5843 }
5844
5845 AUTO_TRACE_ADD("Match results of matchArguments2='{}' substDone='{}'",matching,substDone);
5846
5847 if (substDone) // found a new argument list
5848 {
5849 if (matching) // replace member's argument list
5850 {
5852 md->moveArgumentList(std::make_unique<ArgumentList>(argList));
5853 }
5854 else // no match
5855 {
5856 if (!funcTempList.isEmpty() &&
5857 isSpecialization(declTemplArgs,defTemplArgs))
5858 {
5859 // check if we are dealing with a partial template
5860 // specialization. In this case we add it to the class
5861 // even though the member arguments do not match.
5862
5863 addMethodToClass(root,cd,type,md->name(),args,isFriend,
5864 md->protection(),md->isStatic(),md->virtualness(),spec,relates);
5865 return;
5866 }
5867 }
5868 }
5869 if (matching)
5870 {
5871 addMemberDocs(root,md,funcDecl,nullptr,overloaded,spec);
5872 count++;
5873 memFound=TRUE;
5874 }
5875 }
5876 else if (cd && cd!=tcd) // we did find a class with the same name as cd
5877 // but in a different namespace
5878 {
5879 noMatchCount++;
5880 }
5881
5882 if (memFound) break;
5883 }
5884 if (count==0 && root->parent() && root->parent()->section.isObjcImpl())
5885 {
5886 addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec);
5887 return;
5888 }
5889 if (count==0 && !(isFriend && funcType=="class"))
5890 {
5891 int candidates=0;
5892 const ClassDef *ecd = nullptr, *ucd = nullptr;
5893 MemberDef *emd = nullptr, *umd = nullptr;
5894 //printf("Assume template class\n");
5895 for (const auto &md : *mn)
5896 {
5897 MemberDef *cmd=md.get();
5899 ClassDefMutable *ccd=cdmdm ? cdmdm->getClassDefMutable() : nullptr;
5900 //printf("ccd->name()==%s className=%s\n",qPrint(ccd->name()),qPrint(className));
5901 if (ccd!=nullptr && rightScopeMatch(ccd->name(),className))
5902 {
5903 const ArgumentList &templAl = md->templateArguments();
5904 if (!root->tArgLists.empty() && !templAl.empty() &&
5905 root->tArgLists.back().size()<=templAl.size())
5906 {
5907 AUTO_TRACE_ADD("add template specialization");
5908 addMethodToClass(root,ccd,type,md->name(),args,isFriend,
5909 root->protection,root->isStatic,root->virt,spec,relates);
5910 return;
5911 }
5914 { // exact argument list match -> remember
5915 ucd = ecd = ccd;
5916 umd = emd = cmd;
5917 AUTO_TRACE_ADD("new candidate className='{}' scope='{}' args='{}': exact match",
5918 className,ccd->name(),md->argsString());
5919 }
5920 else // arguments do not match, but member name and scope do -> remember
5921 {
5922 ucd = ccd;
5923 umd = cmd;
5924 AUTO_TRACE_ADD("new candidate className='{}' scope='{}' args='{}': no match",
5925 className,ccd->name(),md->argsString());
5926 }
5927 candidates++;
5928 }
5929 }
5930 bool strictProtoMatching = Config_getBool(STRICT_PROTO_MATCHING);
5931 if (!strictProtoMatching)
5932 {
5933 if (candidates==1 && ucd && umd)
5934 {
5935 // we didn't find an actual match on argument lists, but there is only 1 member with this
5936 // name in the same scope, so that has to be the one.
5937 addMemberDocs(root,toMemberDefMutable(umd),funcDecl,nullptr,overloaded,spec);
5938 return;
5939 }
5940 else if (candidates>1 && ecd && emd)
5941 {
5942 // we didn't find a unique match using type resolution,
5943 // but one of the matches has the exact same signature so
5944 // we take that one.
5945 addMemberDocs(root,toMemberDefMutable(emd),funcDecl,nullptr,overloaded,spec);
5946 return;
5947 }
5948 }
5949
5950 QCString warnMsg = "no ";
5951 if (noMatchCount>1) warnMsg+="uniquely ";
5952 warnMsg+="matching class member found for \n";
5953
5954 for (const ArgumentList &al : root->tArgLists)
5955 {
5956 warnMsg+=" template ";
5957 warnMsg+=tempArgListToString(al,root->lang);
5958 warnMsg+='\n';
5959 }
5960
5961 QCString fullFuncDecl=funcDecl;
5962 if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE);
5963
5964 warnMsg+=" ";
5965 warnMsg+=fullFuncDecl;
5966
5967 if (candidates>0 || noMatchCount>=1)
5968 {
5969 warnMsg+="\nPossible candidates:";
5970
5971 NamespaceDef *nd=nullptr;
5972 if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName);
5973 FileDef *fd=root->fileDef();
5974
5975 for (const auto &md : *mn)
5976 {
5977 const ClassDef *cd=md->getClassDef();
5978 const ClassDef *tcd=findClassDefinition(fd,nd,scopeName);
5979 if (tcd==nullptr && cd && stripAnonymousNamespaceScope(cd->name())==scopeName)
5980 {
5981 // don't be fooled by anonymous scopes
5982 tcd=cd;
5983 }
5984 if (cd!=nullptr && (rightScopeMatch(cd->name(),className) || (cd!=tcd)))
5985 {
5986 warnMsg+='\n';
5987 const ArgumentList &templAl = md->templateArguments();
5988 warnMsg+=" '";
5989 if (templAl.hasParameters())
5990 {
5991 warnMsg+="template ";
5992 warnMsg+=tempArgListToString(templAl,root->lang);
5993 warnMsg+='\n';
5994 warnMsg+=" ";
5995 }
5996 if (!md->typeString().isEmpty())
5997 {
5998 warnMsg+=md->typeString();
5999 warnMsg+=' ';
6000 }
6002 if (!qScope.isEmpty())
6003 warnMsg+=qScope+"::"+md->name();
6004 warnMsg+=md->argsString();
6005 warnMsg+="' " + warn_line(md->getDefFileName(),md->getDefLine());
6006 }
6007 }
6008 }
6009 warn(root->fileName,root->startLine,"%s",qPrint(warnMsg));
6010 }
6011}
std::vector< ArgumentList > ArgumentLists
Definition arguments.h:138
bool hasParameters() const
Definition arguments.h:69
size_t size() const
Definition arguments.h:93
void push_back(const Argument &a)
Definition arguments.h:95
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:5464
static void substituteTemplatesInArgList(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const ArgumentList &src, ArgumentList &dst)
Definition doxygen.cpp:5575
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:5619
static void addMemberDocs(const Entry *root, MemberDefMutable *md, const QCString &funcDecl, const ArgumentList *al, bool over_load, TypeSpecifier spec)
Definition doxygen.cpp:5068
static bool scopeIsTemplate(const Definition *d)
Definition doxygen.cpp:5480
static const ClassDef * findClassDefinition(FileDef *fd, NamespaceDef *nd, const QCString &scopeName)
Definition doxygen.cpp:5220
QCString warn_line(const QCString &file, int line)
Definition message.cpp:198
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:1218
QCString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:1173
bool rightScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:880

References addLocalObjCMethod(), addMemberDocs(), Entry::argList, argListToString(), MemberDef::argsString(), MemberDef::argumentList(), AUTO_TRACE, AUTO_TRACE_ADD, Config_getBool, ArgumentList::empty(), FALSE, Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), findClassDefinition(), QCString::findRev(), MemberDef::getClassDef(), MemberDefMutable::getClassDefMutable(), Definition::getDefFileName(), Definition::getDefLine(), 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(), ArgumentList::push_back(), qPrint(), ClassDef::qualifiedNameWithTemplateParameters(), 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 6015 of file doxygen.cpp.

6025{
6026 AUTO_TRACE("funcType={} funcName={} funcArgs={} funcDecl={} spec={}",funcType,funcName,funcArgs,funcDecl,spec);
6027 MemberDef *declMd=nullptr;
6028 for (const auto &md : *mn)
6029 {
6030 if (md->getClassDef()==cd)
6031 {
6032 // TODO: we should probably also check for matching arguments
6033 declMd = md.get();
6034 break;
6035 }
6036 }
6038 ArgumentList tArgList;
6039 // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6040 auto md = createMemberDef(
6041 root->fileName,root->startLine,root->startColumn,
6042 funcType,funcName,funcArgs,exceptions,
6043 declMd ? declMd->protection() : root->protection,
6044 root->virt,root->isStatic,Relationship::Member,
6045 mtype,tArgList,root->argList,root->metaData);
6046 auto mmd = toMemberDefMutable(md.get());
6047 //printf("new specialized member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6048 mmd->setTagInfo(root->tagInfo());
6049 mmd->setLanguage(root->lang);
6050 mmd->setId(root->id);
6051 mmd->setMemberClass(cd);
6052 mmd->setTemplateSpecialization(TRUE);
6053 mmd->setTypeConstraints(root->typeConstr);
6054 mmd->setDefinition(funcDecl);
6056 mmd->addQualifiers(root->qualifiers);
6057 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6058 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6059 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6060 mmd->setDocsForDefinition(!root->proto);
6061 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6062 mmd->addSectionsToDefinition(root->anchors);
6063 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6064 FileDef *fd=root->fileDef();
6065 mmd->setBodyDef(fd);
6066 mmd->setMemberSpecifiers(spec);
6067 mmd->setVhdlSpecifiers(root->vhdlSpec);
6068 mmd->setMemberGroupId(root->mGrpId);
6069 cd->insertMember(md.get());
6070 mmd->setRefItems(root->sli);
6071
6072 mn->push_back(std::move(md));
6073}
MemberType
Definition types.h:281
Relationship
Kind of member relationship.
Definition types.h:38

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, MemberDef::getClassDef(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), Entry::isStatic, Entry::lang, Member, MemberType_Function, 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 7574 of file doxygen.cpp.

7575{
7576 auto &index = Index::instance();
7577 // for each class member name
7578 for (const auto &mn : *Doxygen::memberNameLinkedMap)
7579 {
7580 // for each member definition
7581 for (const auto &md : *mn)
7582 {
7583 index.addClassMemberNameToIndex(md.get());
7584 if (md->getModuleDef())
7585 {
7586 index.addModuleMemberNameToIndex(md.get());
7587 }
7588 }
7589 }
7590 // for each file/namespace function name
7591 for (const auto &mn : *Doxygen::functionNameLinkedMap)
7592 {
7593 // for each member definition
7594 for (const auto &md : *mn)
7595 {
7596 if (md->getNamespaceDef())
7597 {
7598 index.addNamespaceMemberNameToIndex(md.get());
7599 }
7600 else
7601 {
7602 index.addFileMemberNameToIndex(md.get());
7603 }
7604 if (md->getModuleDef())
7605 {
7606 index.addModuleMemberNameToIndex(md.get());
7607 }
7608 }
7609 }
7610
7611 index.sortMemberIndexLists();
7612}
static Index & instance()
Definition index.cpp:106

References Doxygen::functionNameLinkedMap, MemberDef::getModuleDef(), MemberDef::getNamespaceDef(), Index::instance(), and Doxygen::memberNameLinkedMap.

Referenced by addMembersToIndex(), parseInput(), writeClassTree(), writeDirHierarchy(), writeDirTreeNode(), and writeGroupTreeNode().

◆ addMembersToMemberGroup()

static void addMembersToMemberGroup ( )
static

Definition at line 8672 of file doxygen.cpp.

8673{
8674 // for each class
8675 for (const auto &cd : *Doxygen::classLinkedMap)
8676 {
8677 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8678 if (cdm)
8679 {
8681 }
8682 }
8683 // for each file
8684 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8685 {
8686 for (const auto &fd : *fn)
8687 {
8688 fd->addMembersToMemberGroup();
8689 }
8690 }
8691 // for each namespace
8692 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8693 {
8695 if (ndm)
8696 {
8698 }
8699 }
8700 // for each group
8701 for (const auto &gd : *Doxygen::groupLinkedMap)
8702 {
8703 gd->addMembersToMemberGroup();
8704 }
8706}
virtual void addMembersToMemberGroup()=0
void addMembersToMemberGroup()
virtual void addMembersToMemberGroup()=0

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

Referenced by parseInput().

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

6080{
6081 // for unique overloaded member we allow the class to be
6082 // omitted, this is to be Qt compatible. Using this should
6083 // however be avoided, because it is error prone
6084 bool sameClass=false;
6085 if (mn->size()>0)
6086 {
6087 // check if all members with the same name are also in the same class
6088 sameClass = std::equal(mn->begin()+1,mn->end(),mn->begin(),
6089 [](const auto &md1,const auto &md2)
6090 { return md1->getClassDef()->name()==md2->getClassDef()->name(); });
6091 }
6092 if (sameClass)
6093 {
6094 MemberDefMutable *mdm = toMemberDefMutable(mn->front().get());
6095 ClassDefMutable *cd = mdm ? mdm->getClassDefMutable() : nullptr;
6096 if (cd==nullptr) return;
6097
6100 else if (root->mtype==MethodTypes::Slot) mtype=MemberType_Slot;
6101 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType_DCOP;
6102
6103 // new overloaded member function
6104 std::unique_ptr<ArgumentList> tArgList =
6105 getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6106 //printf("new related member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6107 auto md = createMemberDef(
6108 root->fileName,root->startLine,root->startColumn,
6109 funcType,funcName,funcArgs,exceptions,
6111 mtype,tArgList ? *tArgList : ArgumentList(),root->argList,root->metaData);
6112 auto mmd = toMemberDefMutable(md.get());
6113 mmd->setTagInfo(root->tagInfo());
6114 mmd->setLanguage(root->lang);
6115 mmd->setId(root->id);
6116 mmd->setTypeConstraints(root->typeConstr);
6117 mmd->setMemberClass(cd);
6118 mmd->setDefinition(funcDecl);
6120 mmd->addQualifiers(root->qualifiers);
6122 doc+="<p>";
6123 doc+=root->doc;
6124 mmd->setDocumentation(doc,root->docFile,root->docLine);
6125 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6126 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6127 mmd->setDocsForDefinition(!root->proto);
6128 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6129 mmd->addSectionsToDefinition(root->anchors);
6130 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6131 FileDef *fd=root->fileDef();
6132 mmd->setBodyDef(fd);
6133 mmd->setMemberSpecifiers(spec);
6134 mmd->setVhdlSpecifiers(root->vhdlSpec);
6135 mmd->setMemberGroupId(root->mGrpId);
6136 cd->insertMember(md.get());
6137 cd->insertUsedFile(fd);
6138 mmd->setRefItems(root->sli);
6139
6140 mn->push_back(std::move(md));
6141 }
6142}
MethodTypes mtype
signal, slot, (dcop) method, or property?
Definition entry.h:180
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
@ MemberType_Slot
Definition types.h:289
@ MemberType_Signal
Definition types.h:288
@ MemberType_DCOP
Definition types.h:291

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(), MemberDefMutable::getClassDefMutable(), getOverloadDocs(), getTemplateArgumentsFromName(), Entry::id, Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), Entry::isStatic, Entry::lang, MemberType_DCOP, MemberType_Function, MemberType_Signal, MemberType_Slot, 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 295 of file doxygen.cpp.

296{
297 if (root->parent()) // add the page to it's scope
298 {
299 QCString scope = root->parent()->name;
300 if (root->parent()->section.isPackageDoc())
301 {
302 scope=substitute(scope,".","::");
303 }
304 scope = stripAnonymousNamespaceScope(scope);
305 scope+="::"+pd->name();
307 if (d)
308 {
309 pd->setPageScope(d);
310 }
311 }
312}
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 314 of file doxygen.cpp.

315{
316 GroupDef *gd=nullptr;
317 for (const Grouping &g : root->groups)
318 {
319 if (!g.groupname.isEmpty() && (gd=Doxygen::groupLinkedMap->find(g.groupname))) break;
320 }
321 //printf("---> addRelatedPage() %s gd=%p\n",qPrint(root->name),gd);
322 QCString doc=root->doc+root->inbodyDocs;
323
324 PageDef *pd = addRelatedPage(root->name,root->args,doc,
325 root->docFile,
326 root->docLine,
327 root->startLine,
328 root->sli,
329 gd,root->tagInfo(),
330 FALSE,
331 root->lang
332 );
333 if (pd)
334 {
335 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
337 pd->setLocalToc(root->localToc);
338 addPageToContext(pd,root);
339 }
340}
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:104
LocalToc localToc
Definition entry.h:231
QCString args
member argument string
Definition entry.h:191
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:314
static void addPageToContext(PageDef *pd, Entry *root)
Definition doxygen.cpp:295
Grouping info.
Definition types.h:65

References addPageToContext(), addRelatedPage(), DefinitionMutable::addSectionsToDefinition(), Entry::anchors, Entry::args, Entry::brief, Entry::briefFile, Entry::briefLine, Entry::doc, Entry::docFile, Entry::docLine, FALSE, LinkedMap< T, Hash, KeyEqual, Map >::find(), Doxygen::groupLinkedMap, Entry::groups, Entry::inbodyDocs, 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 8206 of file doxygen.cpp.

8207{
8208 // add source references for class definitions
8209 for (const auto &cd : *Doxygen::classLinkedMap)
8210 {
8211 const FileDef *fd=cd->getBodyDef();
8212 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8213 {
8214 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8215 }
8216 }
8217 // add source references for concept definitions
8218 for (const auto &cd : *Doxygen::conceptLinkedMap)
8219 {
8220 const FileDef *fd=cd->getBodyDef();
8221 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8222 {
8223 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8224 }
8225 }
8226 // add source references for namespace definitions
8227 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8228 {
8229 const FileDef *fd=nd->getBodyDef();
8230 if (fd && nd->isLinkableInProject() && nd->getStartDefLine()!=-1)
8231 {
8232 const_cast<FileDef*>(fd)->addSourceRef(nd->getStartDefLine(),nd.get(),nullptr);
8233 }
8234 }
8235
8236 // add source references for member names
8237 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8238 {
8239 for (const auto &md : *mn)
8240 {
8241 //printf("class member %s: def=%s body=%d link?=%d\n",
8242 // qPrint(md->name()),
8243 // md->getBodyDef()?qPrint(md->getBodyDef()->name()):"<none>",
8244 // md->getStartBodyLine(),md->isLinkableInProject());
8245 const FileDef *fd=md->getBodyDef();
8246 if (fd &&
8247 md->getStartDefLine()!=-1 &&
8248 md->isLinkableInProject() &&
8250 )
8251 {
8252 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8253 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8254 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8255 }
8256 }
8257 }
8258 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8259 {
8260 for (const auto &md : *mn)
8261 {
8262 const FileDef *fd=md->getBodyDef();
8263 //printf("member %s body=[%d,%d] fd=%p link=%d parseSources=%d\n",
8264 // qPrint(md->name()),
8265 // md->getStartBodyLine(),md->getEndBodyLine(),fd,
8266 // md->isLinkableInProject(),
8267 // Doxygen::parseSourcesNeeded);
8268 if (fd &&
8269 md->getStartDefLine()!=-1 &&
8270 md->isLinkableInProject() &&
8272 )
8273 {
8274 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8275 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8276 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8277 }
8278 }
8279 }
8280}
virtual const FileDef * getBodyDef() const =0
static bool parseSourcesNeeded
Definition doxygen.h:113

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

Referenced by parseInput().

◆ addToIndices()

static void addToIndices ( )
static

Definition at line 7616 of file doxygen.cpp.

7617{
7618 for (const auto &cd : *Doxygen::classLinkedMap)
7619 {
7620 if (cd->isLinkableInProject())
7621 {
7622 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
7623 if (Doxygen::searchIndex.enabled())
7624 {
7625 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
7626 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
7627 }
7628 }
7629 }
7630
7631 for (const auto &cd : *Doxygen::conceptLinkedMap)
7632 {
7633 if (cd->isLinkableInProject())
7634 {
7635 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
7636 if (Doxygen::searchIndex.enabled())
7637 {
7638 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
7639 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
7640 }
7641 }
7642 }
7643
7644 for (const auto &nd : *Doxygen::namespaceLinkedMap)
7645 {
7646 if (nd->isLinkableInProject())
7647 {
7648 Doxygen::indexList->addIndexItem(nd.get(),nullptr);
7649 if (Doxygen::searchIndex.enabled())
7650 {
7651 Doxygen::searchIndex.setCurrentDoc(nd.get(),nd->anchor(),FALSE);
7652 Doxygen::searchIndex.addWord(nd->localName(),TRUE);
7653 }
7654 }
7655 }
7656
7657 for (const auto &fn : *Doxygen::inputNameLinkedMap)
7658 {
7659 for (const auto &fd : *fn)
7660 {
7661 if (Doxygen::searchIndex.enabled() && fd->isLinkableInProject())
7662 {
7663 Doxygen::searchIndex.setCurrentDoc(fd.get(),fd->anchor(),FALSE);
7664 Doxygen::searchIndex.addWord(fd->localName(),TRUE);
7665 }
7666 }
7667 }
7668
7669 auto addWordsForTitle = [](const Definition *d,const QCString &anchor,const QCString &title)
7670 {
7672 if (Doxygen::searchIndex.enabled())
7673 {
7674 Doxygen::searchIndex.setCurrentDoc(d,anchor,false);
7675 std::string s = title.str();
7676 static const reg::Ex re(R"(\a[\w-]*)");
7677 reg::Iterator it(s,re);
7679 for (; it!=end ; ++it)
7680 {
7681 const auto &match = *it;
7682 std::string matchStr = match.str();
7683 Doxygen::searchIndex.addWord(matchStr.c_str(),true);
7684 }
7685 }
7686 };
7687
7688 for (const auto &gd : *Doxygen::groupLinkedMap)
7689 {
7690 if (gd->isLinkableInProject())
7691 {
7692 addWordsForTitle(gd.get(),gd->anchor(),gd->groupTitle());
7693 }
7694 }
7695
7696 for (const auto &pd : *Doxygen::pageLinkedMap)
7697 {
7698 if (pd->isLinkableInProject())
7699 {
7700 addWordsForTitle(pd.get(),pd->anchor(),pd->title());
7701 }
7702 }
7703
7705 {
7706 addWordsForTitle(Doxygen::mainPage.get(),Doxygen::mainPage->anchor(),Doxygen::mainPage->title());
7707 }
7708
7709 auto addMemberToSearchIndex = [](const MemberDef *md)
7710 {
7711 if (Doxygen::searchIndex.enabled())
7712 {
7713 Doxygen::searchIndex.setCurrentDoc(md,md->anchor(),FALSE);
7714 QCString ln=md->localName();
7715 QCString qn=md->qualifiedName();
7717 if (ln!=qn)
7718 {
7720 if (md->getClassDef())
7721 {
7722 Doxygen::searchIndex.addWord(md->getClassDef()->displayName(),TRUE);
7723 }
7724 if (md->getNamespaceDef())
7725 {
7726 Doxygen::searchIndex.addWord(md->getNamespaceDef()->displayName(),TRUE);
7727 }
7728 }
7729 }
7730 };
7731
7732 auto getScope = [](const MemberDef *md)
7733 {
7734 const Definition *scope = nullptr;
7735 if (md->getGroupDef()) scope = md->getGroupDef();
7736 else if (md->getClassDef()) scope = md->getClassDef();
7737 else if (md->getNamespaceDef()) scope = md->getNamespaceDef();
7738 else if (md->getFileDef()) scope = md->getFileDef();
7739 return scope;
7740 };
7741
7742 auto addMemberToIndices = [addMemberToSearchIndex,getScope](const MemberDef *md)
7743 {
7744 if (md->isLinkableInProject())
7745 {
7746 if (!(md->isEnumerate() && md->isAnonymous()))
7747 {
7748 Doxygen::indexList->addIndexItem(getScope(md),md);
7750 }
7751 if (md->isEnumerate())
7752 {
7753 for (const auto &fmd : md->enumFieldList())
7754 {
7755 Doxygen::indexList->addIndexItem(getScope(fmd),fmd);
7757 }
7758 }
7759 }
7760 };
7761
7762 // for each class member name
7763 for (const auto &mn : *Doxygen::memberNameLinkedMap)
7764 {
7765 // for each member definition
7766 for (const auto &md : *mn)
7767 {
7768 addMemberToIndices(md.get());
7769 }
7770 }
7771 // for each file/namespace function name
7772 for (const auto &mn : *Doxygen::functionNameLinkedMap)
7773 {
7774 // for each member definition
7775 for (const auto &md : *mn)
7776 {
7777 addMemberToIndices(md.get());
7778 }
7779 }
7780}
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:92
static IndexList * indexList
Definition doxygen.h:124
static SearchIndexIntf searchIndex
Definition doxygen.h:114
void addIndexItem(const Definition *context, const MemberDef *md, const QCString &sectionAnchor=QCString(), const QCString &title=QCString())
Definition indexlist.h:120
void addWord(const QCString &word, bool hiPriority)
void setCurrentDoc(const Definition *ctx, const QCString &anchor, bool isSourceFile)
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:5843

References IndexList::addIndexItem(), addMemberToSearchIndex(), SearchIndexIntf::addWord(), Definition::anchor(), Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Definition::displayName(), end(), MemberDef::enumFieldList(), FALSE, filterTitle(), Doxygen::functionNameLinkedMap, MemberDef::getClassDef(), MemberDef::getFileDef(), MemberDef::getGroupDef(), MemberDef::getNamespaceDef(), Doxygen::groupLinkedMap, GroupDef::groupTitle(), Doxygen::indexList, Doxygen::inputNameLinkedMap, Definition::isAnonymous(), MemberDef::isEnumerate(), Definition::isLinkableInProject(), Definition::localName(), Doxygen::mainPage, Doxygen::memberNameLinkedMap, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, Definition::qualifiedName(), Doxygen::searchIndex, SearchIndexIntf::setCurrentDoc(), and TRUE.

Referenced by parseInput().

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

2192{
2194 QCString scopeSeparator="::";
2195 SrcLangExt lang = cd->getLanguage();
2196 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
2197 {
2198 qualScope = substitute(qualScope,"::",".");
2199 scopeSeparator=".";
2200 }
2201 AUTO_TRACE("class variable: file='{}' type='{}' scope='{}' name='{}' args='{}' prot={} mtype={} lang={} ann={} init='{}'",
2202 root->fileName, type, qualScope, name, args, root->protection, mtype, lang, fromAnnScope, root->initializer.str());
2203
2204 QCString def;
2205 if (!type.isEmpty())
2206 {
2207 if (related!=Relationship::Member || mtype==MemberType_Friend || Config_getBool(HIDE_SCOPE_NAMES))
2208 {
2209 if (root->spec.isAlias()) // turn 'typedef B A' into 'using A'
2210 {
2211 def="using "+name;
2212 }
2213 else
2214 {
2215 def=type+" "+name+args;
2216 }
2217 }
2218 else
2219 {
2220 if (root->spec.isAlias()) // turn 'typedef B C::A' into 'using C::A'
2221 {
2222 def="using "+qualScope+scopeSeparator+name;
2223 }
2224 else
2225 {
2226 def=type+" "+qualScope+scopeSeparator+name+args;
2227 }
2228 }
2229 }
2230 else
2231 {
2232 if (Config_getBool(HIDE_SCOPE_NAMES))
2233 {
2234 def=name+args;
2235 }
2236 else
2237 {
2238 def=qualScope+scopeSeparator+name+args;
2239 }
2240 }
2241 def.stripPrefix("static ");
2242
2243 // see if the member is already found in the same scope
2244 // (this may be the case for a static member that is initialized
2245 // outside the class)
2247 if (mn)
2248 {
2249 for (const auto &imd : *mn)
2250 {
2251 //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n",
2252 // md->getClassDef(),cd,qPrint(type),md->typeString());
2253 MemberDefMutable *md = toMemberDefMutable(imd.get());
2254 if (md &&
2255 md->getClassDef()==cd &&
2257 // member already in the scope
2258 {
2259
2260 if (root->lang==SrcLangExt::ObjC &&
2263 { // Objective-C 2.0 property
2264 // turn variable into a property
2265 md->setProtection(root->protection);
2267 }
2268 addMemberDocs(root,md,def,nullptr,FALSE,root->spec);
2269 AUTO_TRACE_ADD("Member already found!");
2270 return md;
2271 }
2272 }
2273 }
2274
2275 QCString fileName = root->fileName;
2276 if (fileName.isEmpty() && root->tagInfo())
2277 {
2278 fileName = root->tagInfo()->tagName;
2279 }
2280
2281 // new member variable, typedef or enum value
2282 auto md = createMemberDef(
2283 fileName,root->startLine,root->startColumn,
2284 type,name,args,root->exception,
2285 prot,Specifier::Normal,root->isStatic,related,
2286 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
2287 ArgumentList(), root->metaData);
2288 auto mmd = toMemberDefMutable(md.get());
2289 mmd->setTagInfo(root->tagInfo());
2290 mmd->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope())
2291 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
2292 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2293 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2294 mmd->setDefinition(def);
2295 mmd->setBitfields(root->bitfields);
2296 mmd->addSectionsToDefinition(root->anchors);
2297 mmd->setFromAnonymousScope(fromAnnScope);
2298 mmd->setFromAnonymousMember(fromAnnMemb);
2299 //md->setIndentDepth(indentDepth);
2300 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2301 std::string init = root->initializer.str();
2302 mmd->setInitializer(init.c_str());
2303 mmd->setMaxInitLines(root->initLines);
2304 mmd->setMemberGroupId(root->mGrpId);
2305 mmd->setMemberSpecifiers(root->spec);
2306 mmd->setVhdlSpecifiers(root->vhdlSpec);
2307 mmd->setReadAccessor(root->read);
2308 mmd->setWriteAccessor(root->write);
2310 mmd->setHidden(root->hidden);
2311 mmd->setArtificial(root->artificial);
2312 mmd->setLanguage(root->lang);
2313 mmd->setId(root->id);
2314 addMemberToGroups(root,md.get());
2316 mmd->setBodyDef(root->fileDef());
2317 mmd->addQualifiers(root->qualifiers);
2318
2319 AUTO_TRACE_ADD("Adding new member to class '{}'",cd->name());
2320 cd->insertMember(md.get());
2321 mmd->setRefItems(root->sli);
2322
2323 cd->insertUsedFile(root->fileDef());
2324 root->markAsProcessed();
2325
2326 // add the member to the global list
2327 MemberDef *result = md.get();
2329 mn->push_back(std::move(md));
2330
2331 return result;
2332}
virtual void reclassifyMember(MemberDefMutable *md, MemberType t)=0
QCString bitfields
member's bit fields
Definition entry.h:192
void markAsProcessed() const
Definition entry.h:166
QCString write
property write accessor
Definition entry.h:211
QCString exception
throw specification
Definition entry.h:213
QCString read
property read accessor
Definition entry.h:210
virtual MemberType memberType() const =0
virtual void setProtection(Protection p)=0
@ MemberType_Friend
Definition types.h:290
@ MemberType_Variable
Definition types.h:284
@ MemberType_Property
Definition types.h:292
QCString removeRedundantWhiteSpace(const QCString &s)
Definition util.cpp:577

References LinkedMap< T, Hash, KeyEqual, Map >::add(), 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, LinkedMap< T, Hash, KeyEqual, Map >::find(), 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(), MemberType_Friend, MemberType_Property, MemberType_Variable, Entry::metaData, Entry::mGrpId, Entry::mtype, Definition::name(), Normal, ObjC, Property, Entry::protection, MemberName::push_back(), ClassDef::qualifiedNameWithTemplateParameters(), Entry::qualifiers, Entry::read, ClassDefMutable::reclassifyMember(), removeRedundantWhiteSpace(), MemberDefMutable::setProtection(), Entry::sli, Entry::spec, Entry::startColumn, Entry::startLine, TextStream::str(), QCString::stripPrefix(), substitute(), Entry::tagInfo(), TagInfo::tagName, Entry::tArgLists, toMemberDefMutable(), MemberDef::typeString(), Entry::vhdlSpec, and Entry::write.

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

2345{
2346 AUTO_TRACE("global variable: file='{}' type='{}' scope='{}' name='{}' args='{}' prot={} mtype={} lang={} init='{}'",
2347 root->fileName, type, scope, name, args, root->protection, mtype, root->lang, root->initializer.str());
2348
2349 FileDef *fd = root->fileDef();
2350
2351 // see if we have a typedef that should hide a struct or union
2352 if (mtype==MemberType_Typedef && Config_getBool(TYPEDEF_HIDES_STRUCT))
2353 {
2354 QCString ttype = type;
2355 ttype.stripPrefix("typedef ");
2356 if (ttype.stripPrefix("struct ") || ttype.stripPrefix("union "))
2357 {
2358 static const reg::Ex re(R"(\a\w*)");
2360 std::string typ = ttype.str();
2361 if (reg::search(typ,match,re))
2362 {
2363 QCString typeValue = match.str();
2364 ClassDefMutable *cd = getClassMutable(typeValue);
2365 if (cd)
2366 {
2367 // this typedef should hide compound name cd, so we
2368 // change the name that is displayed from cd.
2369 cd->setClassName(name);
2370 cd->setDocumentation(root->doc,root->docFile,root->docLine);
2371 cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2372 return nullptr;
2373 }
2374 }
2375 }
2376 }
2377
2378 // see if the function is inside a namespace
2379 NamespaceDefMutable *nd = nullptr;
2380 if (!scope.isEmpty())
2381 {
2382 if (scope.find('@')!=-1) return nullptr; // anonymous scope!
2383 nd = getResolvedNamespaceMutable(scope);
2384 }
2385 QCString def;
2386
2387 // determine the definition of the global variable
2388 if (nd && !nd->isAnonymous() &&
2389 !Config_getBool(HIDE_SCOPE_NAMES)
2390 )
2391 // variable is inside a namespace, so put the scope before the name
2392 {
2393 SrcLangExt lang = nd->getLanguage();
2395
2396 if (!type.isEmpty())
2397 {
2398 if (root->spec.isAlias()) // turn 'typedef B NS::A' into 'using NS::A'
2399 {
2400 def="using "+nd->name()+sep+name;
2401 }
2402 else // normal member
2403 {
2404 def=type+" "+nd->name()+sep+name+args;
2405 }
2406 }
2407 else
2408 {
2409 def=nd->name()+sep+name+args;
2410 }
2411 }
2412 else
2413 {
2414 if (!type.isEmpty() && !root->name.isEmpty())
2415 {
2416 if (name.at(0)=='@') // dummy variable representing anonymous union
2417 {
2418 def=type;
2419 }
2420 else
2421 {
2422 if (root->spec.isAlias()) // turn 'typedef B A' into 'using A'
2423 {
2424 def="using "+root->name;
2425 }
2426 else // normal member
2427 {
2428 def=type+" "+name+args;
2429 }
2430 }
2431 }
2432 else
2433 {
2434 def=name+args;
2435 }
2436 }
2437 def.stripPrefix("static ");
2438
2440 if (mn)
2441 {
2442 //QCString nscope=removeAnonymousScopes(scope);
2443 //NamespaceDef *nd=nullptr;
2444 //if (!nscope.isEmpty())
2445 if (!scope.isEmpty())
2446 {
2447 nd = getResolvedNamespaceMutable(scope);
2448 }
2449 for (const auto &imd : *mn)
2450 {
2451 MemberDefMutable *md = toMemberDefMutable(imd.get());
2452 if (md &&
2453 ((nd==nullptr && md->getNamespaceDef()==nullptr && md->getFileDef() &&
2454 root->fileName==md->getFileDef()->absFilePath()
2455 ) // both variable names in the same file
2456 || (nd!=nullptr && md->getNamespaceDef()==nd) // both in same namespace
2457 )
2458 && !md->isDefine() // function style #define's can be "overloaded" by typedefs or variables
2459 && !md->isEnumerate() // in C# an enum value and enum can have the same name
2460 )
2461 // variable already in the scope
2462 {
2463 bool isPHPArray = md->getLanguage()==SrcLangExt::PHP &&
2464 md->argsString()!=args &&
2465 args.find('[')!=-1;
2466 bool staticsInDifferentFiles =
2467 root->isStatic && md->isStatic() &&
2468 root->fileName!=md->getDefFileName();
2469
2470 if (md->getFileDef() &&
2471 !isPHPArray && // not a php array
2472 !staticsInDifferentFiles
2473 )
2474 // not a php array variable
2475 {
2476 AUTO_TRACE_ADD("variable already found: scope='{}'",md->getOuterScope()->name());
2477 addMemberDocs(root,md,def,nullptr,FALSE,root->spec);
2478 md->setRefItems(root->sli);
2479 // if md is a variable forward declaration and root is the definition that
2480 // turn md into the definition
2481 if (!root->explicitExternal && md->isExternal())
2482 {
2483 md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn());
2485 }
2486 // if md is the definition and root point at a declaration, then add the
2487 // declaration info
2488 else if (root->explicitExternal && !md->isExternal())
2489 {
2490 md->setDeclFile(root->fileName,root->startLine,root->startColumn);
2491 }
2492 return md;
2493 }
2494 }
2495 }
2496 }
2497
2498 QCString fileName = root->fileName;
2499 if (fileName.isEmpty() && root->tagInfo())
2500 {
2501 fileName = root->tagInfo()->tagName;
2502 }
2503
2504 AUTO_TRACE_ADD("new variable, namespace='{}'",nd?nd->name():QCString("<global>"));
2505 // new global variable, enum value or typedef
2506 auto md = createMemberDef(
2507 fileName,root->startLine,root->startColumn,
2508 type,name,args,QCString(),
2510 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
2511 root->argList, root->metaData);
2512 auto mmd = toMemberDefMutable(md.get());
2513 mmd->setTagInfo(root->tagInfo());
2514 mmd->setMemberSpecifiers(root->spec);
2515 mmd->setVhdlSpecifiers(root->vhdlSpec);
2516 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
2517 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2518 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2519 mmd->addSectionsToDefinition(root->anchors);
2520 mmd->setFromAnonymousScope(fromAnnScope);
2521 mmd->setFromAnonymousMember(fromAnnMemb);
2522 std::string init = root->initializer.str();
2523 mmd->setInitializer(init.c_str());
2524 mmd->setMaxInitLines(root->initLines);
2525 mmd->setMemberGroupId(root->mGrpId);
2526 mmd->setDefinition(def);
2527 mmd->setLanguage(root->lang);
2528 mmd->setId(root->id);
2530 mmd->setExplicitExternal(root->explicitExternal,fileName,root->startLine,root->startColumn);
2531 mmd->addQualifiers(root->qualifiers);
2532 //md->setOuterScope(fd);
2533 if (!root->explicitExternal)
2534 {
2535 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
2536 mmd->setBodyDef(fd);
2537 }
2538 addMemberToGroups(root,md.get());
2540
2541 mmd->setRefItems(root->sli);
2542 if (nd && !nd->isAnonymous())
2543 {
2544 mmd->setNamespace(nd);
2545 nd->insertMember(md.get());
2546 }
2547
2548 // add member to the file (we do this even if we have already inserted
2549 // it into the namespace.
2550 if (fd)
2551 {
2552 mmd->setFileDef(fd);
2553 fd->insertMember(md.get());
2554 }
2555
2556 root->markAsProcessed();
2557
2558 // add member definition to the list of globals
2559 MemberDef *result = md.get();
2561 mn->push_back(std::move(md));
2562
2563 return result;
2564}
virtual void setClassName(const QCString &name)=0
virtual int getDefColumn() const =0
bool explicitExternal
explicitly defined as external?
Definition entry.h:185
virtual void insertMember(MemberDef *md)=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
virtual void insertMember(MemberDef *md)=0
const std::string & str() const
Definition qcstring.h:517
Object representing the matching results.
Definition regex.h:153
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
@ MemberType_Typedef
Definition types.h:285
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
Definition util.cpp:6152

References FileDef::absFilePath(), LinkedMap< T, Hash, KeyEqual, Map >::add(), 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, LinkedMap< T, Hash, KeyEqual, Map >::find(), 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, MemberType_Typedef, Entry::metaData, Entry::mGrpId, Definition::name(), Entry::name, Normal, PHP, Entry::protection, MemberName::push_back(), Entry::qualifiers, 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(), and Entry::vhdlSpec.

◆ adjustConfiguration()

void adjustConfiguration ( )

adjust globals that depend on configuration settings.

Definition at line 11316 of file doxygen.cpp.

11317{
11318 AUTO_TRACE();
11319 Doxygen::globalNamespaceDef = createNamespaceDef("<globalScope>",1,1,"<globalScope>");
11328
11329 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11330
11331 /* Set the global html file extension. */
11332 Doxygen::htmlFileExtension = Config_getString(HTML_FILE_EXTENSION);
11333
11334
11336 Config_getBool(CALLER_GRAPH) ||
11337 Config_getBool(REFERENCES_RELATION) ||
11338 Config_getBool(REFERENCED_BY_RELATION);
11339
11340 /**************************************************************************
11341 * Add custom extension mappings
11342 **************************************************************************/
11343
11344 const StringVector &extMaps = Config_getList(EXTENSION_MAPPING);
11345 for (const auto &mapping : extMaps)
11346 {
11347 QCString mapStr = mapping.c_str();
11348 int i=mapStr.find('=');
11349 if (i==-1)
11350 {
11351 continue;
11352 }
11353 else
11354 {
11355 QCString ext = mapStr.left(i).stripWhiteSpace().lower();
11356 QCString language = mapStr.mid(i+1).stripWhiteSpace().lower();
11357 if (ext.isEmpty() || language.isEmpty())
11358 {
11359 continue;
11360 }
11361
11362 if (!updateLanguageMapping(ext,language))
11363 {
11364 err("Failed to map file extension '%s' to unsupported language '%s'.\n"
11365 "Check the EXTENSION_MAPPING setting in the config file.\n",
11366 qPrint(ext),qPrint(language));
11367 }
11368 else
11369 {
11370 msg("Adding custom extension mapping: '%s' will be treated as language '%s'\n",
11371 qPrint(ext),qPrint(language));
11372 }
11373 }
11374 }
11375 // create input file exncodings
11376
11377 // check INPUT_ENCODING
11378 void *cd = portable_iconv_open("UTF-8",Config_getString(INPUT_ENCODING).data());
11379 if (cd==reinterpret_cast<void *>(-1))
11380 {
11381 term("unsupported character conversion: '%s'->'%s': %s\n"
11382 "Check the 'INPUT_ENCODING' setting in the config file!\n",
11383 qPrint(Config_getString(INPUT_ENCODING)),qPrint("UTF-8"),strerror(errno));
11384 }
11385 else
11386 {
11388 }
11389
11390 // check and split INPUT_FILE_ENCODING
11391 const StringVector &fileEncod = Config_getList(INPUT_FILE_ENCODING);
11392 for (const auto &mapping : fileEncod)
11393 {
11394 QCString mapStr = mapping.c_str();
11395 int i=mapStr.find('=');
11396 if (i==-1)
11397 {
11398 continue;
11399 }
11400 else
11401 {
11402 QCString pattern = mapStr.left(i).stripWhiteSpace().lower();
11403 QCString encoding = mapStr.mid(i+1).stripWhiteSpace().lower();
11404 if (pattern.isEmpty() || encoding.isEmpty())
11405 {
11406 continue;
11407 }
11408 cd = portable_iconv_open("UTF-8",encoding.data());
11409 if (cd==reinterpret_cast<void *>(-1))
11410 {
11411 term("unsupported character conversion: '%s'->'%s': %s\n"
11412 "Check the 'INPUT_FILE_ENCODING' setting in the config file!\n",
11413 qPrint(encoding),qPrint("UTF-8"),strerror(errno));
11414 }
11415 else
11416 {
11418 }
11419
11420 Doxygen::inputFileEncodingList.emplace_back(pattern, encoding);
11421 }
11422 }
11423
11424 // add predefined macro name to a dictionary
11425 const StringVector &expandAsDefinedList =Config_getList(EXPAND_AS_DEFINED);
11426 for (const auto &s : expandAsDefinedList)
11427 {
11428 Doxygen::expandAsDefinedSet.insert(s.c_str());
11429 }
11430
11431 // read aliases and store them in a dictionary
11432 readAliases();
11433
11434 // store number of spaces in a tab into Doxygen::spaces
11435 int tabSize = Config_getInt(TAB_SIZE);
11436 Doxygen::spaces.resize(tabSize);
11437 for (int sp=0; sp<tabSize; sp++) Doxygen::spaces.at(sp)=' ';
11438 Doxygen::spaces.at(tabSize)='\0';
11439}
void readAliases()
Definition aliases.cpp:169
static StringUnorderedSet expandAsDefinedSet
Definition doxygen.h:109
static InputFileEncodingList inputFileEncodingList
Definition doxygen.h:131
static FileNameLinkedMap * dotFileNameLinkedMap
Definition doxygen.h:98
static FileNameLinkedMap * imageNameLinkedMap
Definition doxygen.h:97
static FileNameLinkedMap * mscFileNameLinkedMap
Definition doxygen.h:99
static QCString spaces
Definition doxygen.h:125
static FileNameLinkedMap * diaFileNameLinkedMap
Definition doxygen.h:100
static QCString htmlFileExtension
Definition doxygen.h:112
static std::unique_ptr< NamespaceDef > globalNamespaceDef
Definition doxygen.h:110
static FileNameLinkedMap * includeNameLinkedMap
Definition doxygen.h:93
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:94
Ordered dictionary of FileName objects.
Definition filename.h:73
QCString lower() const
Definition qcstring.h:227
void resize(size_t newlen)
Definition qcstring.h:160
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:152
#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
void msg(const char *fmt,...)
Definition message.cpp:98
#define err(fmt,...)
Definition message.h:84
#define term(fmt,...)
Definition message.h:94
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:5367

References QCString::at(), 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, portable_iconv_close(), portable_iconv_open(), qPrint(), readAliases(), QCString::resize(), 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 2056 of file doxygen.cpp.

2057{
2058 root->commandOverrides.apply_callGraph ([&](bool b) { md->overrideCallGraph(b); });
2059 root->commandOverrides.apply_callerGraph ([&](bool b) { md->overrideCallerGraph(b); });
2060 root->commandOverrides.apply_referencedByRelation([&](bool b) { md->overrideReferencedByRelation(b); });
2061 root->commandOverrides.apply_referencesRelation ([&](bool b) { md->overrideReferencesRelation(b); });
2062 root->commandOverrides.apply_inlineSource ([&](bool b) { md->overrideInlineSource(b); });
2063}
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 overrideCallerGraph(bool e)=0

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

Referenced by addDefineDoc(), addLocalObjCMethod(), addMemberDocs(), addMemberSpecialization(), addOverloaded(), addVariableToClass(), addVariableToFile(), findEnums(), findMember(), and findUsingDeclImports().

◆ buildClassDocList()

static void buildClassDocList ( const Entry * root)
static

Definition at line 1107 of file doxygen.cpp.

1108{
1109 if ((root->section.isCompoundDoc()) && !root->name.isEmpty())
1110 {
1111 AUTO_TRACE();
1112 addClassToContext(root);
1113 }
1114 for (const auto &e : root->children()) buildClassDocList(e.get());
1115}
bool isCompoundDoc() const
Definition types.h:532
static void addClassToContext(const Entry *root)
Definition doxygen.cpp:916
static void buildClassDocList(const Entry *root)
Definition doxygen.cpp:1107

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

1098{
1099 if ((root->section.isCompound() || root->section.isObjcImpl()) && !root->name.isEmpty())
1100 {
1101 AUTO_TRACE();
1102 addClassToContext(root);
1103 }
1104 for (const auto &e : root->children()) buildClassList(e.get());
1105}
static void buildClassList(const Entry *root)
Definition doxygen.cpp:1097

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

7951{
7952 // merge the member list of base classes into the inherited classes.
7953 for (const auto &cd : *Doxygen::classLinkedMap)
7954 {
7955 if (// !cd->isReference() && // not an external class
7956 cd->subClasses().empty() && // is a root of the hierarchy
7957 !cd->baseClasses().empty()) // and has at least one base class
7958 {
7959 ClassDefMutable *cdm = toClassDefMutable(cd.get());
7960 if (cdm)
7961 {
7962 //printf("*** merging members for %s\n",qPrint(cd->name()));
7963 cdm->mergeMembers();
7964 }
7965 }
7966 }
7967 // now sort the member list of all members for all classes.
7968 for (const auto &cd : *Doxygen::classLinkedMap)
7969 {
7970 ClassDefMutable *cdm = toClassDefMutable(cd.get());
7971 if (cdm)
7972 {
7973 cdm->sortAllMembersList();
7974 }
7975 }
7976}
virtual void sortAllMembersList()=0
virtual void mergeMembers()=0

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

Referenced by parseInput().

◆ buildConceptDocList()

static void buildConceptDocList ( const Entry * root)
static

Definition at line 1256 of file doxygen.cpp.

1257{
1258 if (root->section.isConceptDoc())
1259 {
1260 AUTO_TRACE();
1261 addConceptToContext(root);
1262 }
1263 for (const auto &e : root->children()) buildConceptDocList(e.get());
1264}
static void addConceptToContext(const Entry *root)
Definition doxygen.cpp:1121
static void buildConceptDocList(const Entry *root)
Definition doxygen.cpp:1256

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

1247{
1248 if (root->section.isConcept())
1249 {
1250 AUTO_TRACE();
1251 addConceptToContext(root);
1252 }
1253 for (const auto &e : root->children()) buildConceptList(e.get());
1254}
static void buildConceptList(const Entry *root)
Definition doxygen.cpp:1246

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

Referenced by buildConceptList(), and parseInput().

◆ buildDefineList()

static void buildDefineList ( )
static

Definition at line 8285 of file doxygen.cpp.

8286{
8287 AUTO_TRACE();
8288 for (const auto &s : g_inputFiles)
8289 {
8290 auto it = Doxygen::macroDefinitions.find(s);
8292 {
8293 for (const auto &def : it->second)
8294 {
8295 auto md = createMemberDef(
8296 def.fileName,def.lineNr,def.columnNr,
8297 "#define",def.name,def.args,QCString(),
8299 ArgumentList(),ArgumentList(),"");
8300 auto mmd = toMemberDefMutable(md.get());
8301
8302 if (!def.args.isEmpty())
8303 {
8304 mmd->moveArgumentList(stringToArgumentList(SrcLangExt::Cpp, def.args));
8305 }
8306 mmd->setInitializer(def.definition);
8307 mmd->setFileDef(def.fileDef);
8308 mmd->setDefinition("#define "+def.name);
8309
8311 if (def.fileDef)
8312 {
8313 def.fileDef->insertMember(md.get());
8314 }
8315 AUTO_TRACE_ADD("adding macro {} with definition {}",def.name,def.definition);
8316 mn->push_back(std::move(md));
8317 }
8318 }
8319 }
8320}
static DefinesPerFileList macroDefinitions
Definition doxygen.h:127
static StringVector g_inputFiles
Definition doxygen.cpp:179
@ MemberType_Define
Definition types.h:282

References LinkedMap< T, Hash, KeyEqual, Map >::add(), AUTO_TRACE, AUTO_TRACE_ADD, Cpp, createMemberDef(), end(), FALSE, Doxygen::functionNameLinkedMap, g_inputFiles, QCString::isEmpty(), Doxygen::macroDefinitions, Member, MemberType_Define, MemberDefMutable::moveArgumentList(), Normal, Public, MemberName::push_back(), MemberDefMutable::setDefinition(), MemberDefMutable::setFileDef(), MemberDefMutable::setInitializer(), stringToArgumentList(), and toMemberDefMutable().

Referenced by parseInput().

◆ buildExampleList()

static void buildExampleList ( Entry * root)
static

Definition at line 9353 of file doxygen.cpp.

9354{
9355 if ((root->section.isExample() || root->section.isExampleLineno()) && !root->name.isEmpty())
9356 {
9357 if (Doxygen::exampleLinkedMap->find(root->name))
9358 {
9359 warn(root->fileName,root->startLine,
9360 "Example %s was already documented. Ignoring "
9361 "documentation found here.",
9362 qPrint(root->name)
9363 );
9364 }
9365 else
9366 {
9368 createPageDef(root->fileName,root->startLine,
9369 root->name,root->brief+root->doc+root->inbodyDocs,root->args));
9370 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9371 pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE));
9373 pd->setLanguage(root->lang);
9374 pd->setShowLineNo(root->section.isExampleLineno());
9375
9376 //we don't add example to groups
9377 //addExampleToGroups(root,pd);
9378 }
9379 }
9380 for (const auto &e : root->children()) buildExampleList(e.get());
9381}
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:90
virtual void setFileName(const QCString &name)=0
virtual void setShowLineNo(bool)=0
static void buildExampleList(Entry *root)
Definition doxygen.cpp:9353
std::unique_ptr< PageDef > createPageDef(const QCString &f, int l, const QCString &n, const QCString &d, const QCString &t)
Definition pagedef.cpp:77
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3818

References LinkedMap< T, Hash, KeyEqual, Map >::add(), 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, qPrint(), 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 482 of file doxygen.cpp.

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

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, LinkedMap< T, Hash, KeyEqual, Map >::find(), findFileDef(), QCString::findRev(), Grouping::getGroupPriName(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Entry::groups, Doxygen::inputNameLinkedMap, QCString::isEmpty(), EntryType::isFile(), QCString::left(), DefinitionMutable::makePartOfGroup(), Entry::name, FileDef::overrideIncludedByGraph(), FileDef::overrideIncludeGraph(), 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().

◆ buildGroupList()

static void buildGroupList ( const Entry * root)
static

Definition at line 411 of file doxygen.cpp.

412{
413 // --- first process only local groups
414 // first process the @defgroups blocks
416 // then process the @addtogroup, @weakgroup blocks
418
419 // --- then also process external groups
420 // first process the @defgroups blocks
422 // then process the @addtogroup, @weakgroup blocks
424}
static void buildGroupListFiltered(const Entry *root, bool additional, bool includeExternal)
Definition doxygen.cpp:342

References buildGroupListFiltered(), FALSE, and TRUE.

Referenced by parseInput().

◆ buildGroupListFiltered()

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

Definition at line 342 of file doxygen.cpp.

343{
344 if (root->section.isGroupDoc() && !root->name.isEmpty() &&
345 ((!includeExternal && root->tagInfo()==nullptr) ||
346 ( includeExternal && root->tagInfo()!=nullptr))
347 )
348 {
349 AUTO_TRACE("additional={} includeExternal={}",additional,includeExternal);
350 if ((root->groupDocType==Entry::GROUPDOC_NORMAL && !additional) ||
351 (root->groupDocType!=Entry::GROUPDOC_NORMAL && additional))
352 {
354 AUTO_TRACE_ADD("Processing group '{}':'{}' gd={}", root->type,root->name,(void*)gd);
355
356 if (gd)
357 {
358 if ( !gd->hasGroupTitle() )
359 {
360 gd->setGroupTitle( root->type );
361 }
362 else if ( root->type.length() > 0 && root->name != root->type && gd->groupTitle() != root->type )
363 {
364 warn( root->fileName,root->startLine,
365 "group %s: ignoring title \"%s\" that does not match old title \"%s\"",
366 qPrint(root->name), qPrint(root->type), qPrint(gd->groupTitle()) );
367 }
368 gd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
369 gd->setDocumentation( root->doc, root->docFile, root->docLine );
370 gd->setInbodyDocumentation( root->inbodyDocs, root->inbodyFile, root->inbodyLine );
372 gd->setRefItems(root->sli);
373 gd->setLanguage(root->lang);
375 {
376 root->commandOverrides.apply_groupGraph([&](bool b) { gd->overrideGroupGraph(b); });
377 }
378 }
379 else
380 {
381 if (root->tagInfo())
382 {
383 gd = Doxygen::groupLinkedMap->add(root->name,
384 std::unique_ptr<GroupDef>(
385 createGroupDef(root->fileName,root->startLine,root->name,root->type,root->tagInfo()->fileName)));
386 gd->setReference(root->tagInfo()->tagName);
387 }
388 else
389 {
390 gd = Doxygen::groupLinkedMap->add(root->name,
391 std::unique_ptr<GroupDef>(
392 createGroupDef(root->fileName,root->startLine,root->name,root->type)));
393 }
394 gd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
395 // allow empty docs for group
396 gd->setDocumentation(!root->doc.isEmpty() ? root->doc : QCString(" "),root->docFile,root->docLine,FALSE);
397 gd->setInbodyDocumentation( root->inbodyDocs, root->inbodyFile, root->inbodyLine );
399 gd->setRefItems(root->sli);
400 gd->setLanguage(root->lang);
402 {
403 root->commandOverrides.apply_groupGraph([&](bool b) { gd->overrideGroupGraph(b); });
404 }
405 }
406 }
407 }
408 for (const auto &e : root->children()) buildGroupListFiltered(e.get(),additional,includeExternal);
409}
virtual void setReference(const QCString &r)=0
GroupDocType groupDocType
Definition entry.h:229
@ GROUPDOC_NORMAL
defgroup
Definition entry.h:120
QCString type
member type
Definition entry.h:172
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 LinkedMap< T, Hash, KeyEqual, Map >::add(), 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, LinkedMap< T, Hash, KeyEqual, Map >::find(), 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(), qPrint(), 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().

◆ buildListOfUsingDecls()

static void buildListOfUsingDecls ( const Entry * root)
static

Definition at line 1962 of file doxygen.cpp.

1963{
1964 if (root->section.isUsingDecl() &&
1965 !root->parent()->section.isCompound() // not a class/struct member
1966 )
1967 {
1968 QCString name = substitute(root->name,".","::");
1969 g_usingDeclarations.insert(name.str());
1970 }
1971 for (const auto &e : root->children()) buildListOfUsingDecls(e.get());
1972}
static StringSet g_usingDeclarations
Definition doxygen.cpp:181
static void buildListOfUsingDecls(const Entry *root)
Definition doxygen.cpp:1962

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

1641{
1642 if (
1643 (root->section.isNamespace() ||
1644 root->section.isNamespaceDoc() ||
1645 root->section.isPackageDoc()
1646 ) &&
1647 !root->name.isEmpty()
1648 )
1649 {
1650 AUTO_TRACE("name={}",root->name);
1651
1652 QCString fName = root->name;
1653 if (root->section.isPackageDoc())
1654 {
1655 fName=substitute(fName,".","::");
1656 }
1657
1658 QCString fullName = stripAnonymousNamespaceScope(fName);
1659 if (!fullName.isEmpty())
1660 {
1661 AUTO_TRACE_ADD("Found namespace {} in {} at line {}",root->name,root->fileName,root->startLine);
1663 if (ndi) // existing namespace
1664 {
1666 if (nd) // non-inline namespace
1667 {
1668 AUTO_TRACE_ADD("Existing namespace");
1669 nd->setDocumentation(root->doc,root->docFile,root->docLine);
1670 nd->setName(fullName); // change name to match docs
1672 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1674 {
1675 nd->setLanguage(root->lang);
1676 }
1677 if (root->tagInfo()==nullptr && nd->isReference() && !(root->doc.isEmpty() && root->brief.isEmpty()))
1678 // if we previously found namespace nd in a tag file and now we find a
1679 // documented namespace with the same name in the project, then remove
1680 // the tag file reference
1681 {
1682 nd->setReference("");
1683 nd->setFileName(fullName);
1684 }
1685 nd->setMetaData(root->metaData);
1686
1687 // file definition containing the namespace nd
1688 FileDef *fd=root->fileDef();
1689 if (nd->isArtificial())
1690 {
1691 nd->setArtificial(FALSE); // found namespace explicitly, so cannot be artificial
1692 nd->setDefFile(root->fileName,root->startLine,root->startColumn);
1693 }
1694 // insert the namespace in the file definition
1695 if (fd) fd->insertNamespace(nd);
1696 addNamespaceToGroups(root,nd);
1697 nd->setRefItems(root->sli);
1698 }
1699 }
1700 else // fresh namespace
1701 {
1702 QCString tagName;
1703 QCString tagFileName;
1704 const TagInfo *tagInfo = root->tagInfo();
1705 if (tagInfo)
1706 {
1707 tagName = tagInfo->tagName;
1708 tagFileName = tagInfo->fileName;
1709 }
1710 AUTO_TRACE_ADD("new namespace {} lang={} tagName={}",fullName,langToString(root->lang),tagName);
1711 // add namespace to the list
1713 Doxygen::namespaceLinkedMap->add(fullName,
1714 createNamespaceDef(tagInfo?tagName:root->fileName,root->startLine,
1715 root->startColumn,fullName,tagName,tagFileName,
1716 root->type,root->spec.isPublished())));
1717 if (nd)
1718 {
1719 nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
1720 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1722 nd->setHidden(root->hidden);
1723 nd->setArtificial(root->artificial);
1724 nd->setLanguage(root->lang);
1725 nd->setId(root->id);
1726 nd->setMetaData(root->metaData);
1727 nd->setInline(root->spec.isInline());
1728 nd->setExported(root->exported);
1729
1730 addNamespaceToGroups(root,nd);
1731 nd->setRefItems(root->sli);
1732
1733 // file definition containing the namespace nd
1734 FileDef *fd=root->fileDef();
1735 // insert the namespace in the file definition
1736 if (fd) fd->insertNamespace(nd);
1737
1738 // the empty string test is needed for extract all case
1739 nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
1740 nd->insertUsedFile(fd);
1741 nd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
1742 nd->setBodyDef(fd);
1743
1744 // also add namespace to the correct structural context
1745 Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName,nullptr,tagInfo);
1746 AUTO_TRACE_ADD("adding namespace {} to context {}",nd->name(),d ? d->name() : QCString("<none>"));
1747 if (d==nullptr) // we didn't find anything, create the scope artificially
1748 // anyway, so we can at least relate scopes properly.
1749 {
1750 d = buildScopeFromQualifiedName(fullName,nd->getLanguage(),tagInfo);
1752 if (dm)
1753 {
1754 dm->addInnerCompound(nd);
1755 }
1756 nd->setOuterScope(d);
1757 // TODO: Due to the order in which the tag file is written
1758 // a nested class can be found before its parent!
1759 }
1760 else
1761 {
1763 if (dm)
1764 {
1765 dm->addInnerCompound(nd);
1766 }
1767 nd->setOuterScope(d);
1768 // in case of d is an inline namespace, alias insert nd in the part scope of d.
1770 {
1771 NamespaceDef *pnd = toNamespaceDef(d);
1772 if (pnd && pnd->isInline())
1773 {
1774 d = d->getOuterScope();
1775 if (d)
1776 {
1777 dm = toDefinitionMutable(d);
1778 if (dm)
1779 {
1780 auto aliasNd = createNamespaceDefAlias(d,nd);
1781 dm->addInnerCompound(aliasNd.get());
1782 QCString aliasName = aliasNd->name();
1783 AUTO_TRACE_ADD("adding alias {} to {}",aliasName,d->name());
1784 Doxygen::namespaceLinkedMap->add(aliasName,std::move(aliasNd));
1785 }
1786 }
1787 else
1788 {
1789 break;
1790 }
1791 }
1792 else
1793 {
1794 break;
1795 }
1796 }
1797 }
1798 }
1799 }
1800 }
1801 }
1802 for (const auto &e : root->children()) buildNamespaceList(e.get());
1803}
virtual bool isArtificial() const =0
virtual bool isReference() const =0
virtual void setExported(bool b)=0
virtual void setName(const QCString &name)=0
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:105
bool exported
is the symbol exported from a C++20 module
Definition entry.h:188
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:1640
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:6126

References LinkedMap< T, Hash, KeyEqual, Map >::add(), 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, LinkedMap< T, Hash, KeyEqual, Map >::find(), 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 9109 of file doxygen.cpp.

9110{
9111 if (root->section.isPageDoc())
9112 {
9113 if (!root->name.isEmpty())
9114 {
9115 addRelatedPage(root);
9116 }
9117 }
9118 else if (root->section.isMainpageDoc())
9119 {
9120 QCString title=root->args.stripWhiteSpace();
9121 if (title.isEmpty()) title=theTranslator->trMainPage();
9122 //QCString name = Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9123 QCString name = "index";
9124 addRefItem(root->sli,
9125 name,
9126 "page",
9127 name,
9128 title,
9129 QCString(),nullptr
9130 );
9131 }
9132 for (const auto &e : root->children()) buildPageList(e.get());
9133}
virtual QCString trMainPage()=0
static void buildPageList(Entry *root)
Definition doxygen.cpp:9109

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

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

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

References DefinitionMutable::addInnerCompound(), QCString::contains(), createNamespaceDef(), TagInfo::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::find(), getClass(), getScopeFragment(), Doxygen::globalScope, QCString::isEmpty(), QCString::mid(), Doxygen::namespaceLinkedMap, DefinitionMutable::setArtificial(), DefinitionMutable::setLanguage(), DefinitionMutable::setOuterScope(), stripTemplateSpecifiers(), TagInfo::tagName, toDefinition(), toDefinitionMutable(), toNamespaceDefMutable(), and TRUE.

Referenced by addClassToContext(), addConceptToContext(), addEnumValuesToEnums(), buildNamespaceList(), findClassRelation(), findEnums(), findScopeFromQualifiedName(), and resolveClassNestingRelations().

◆ checkConfiguration()

void checkConfiguration ( )

check and resolve config options

Definition at line 11305 of file doxygen.cpp.

11306{
11307 AUTO_TRACE();
11308
11313}
void initWarningFormat()
Definition message.cpp:41
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 11766 of file doxygen.cpp.

11767{
11768 if (Config_getBool(MARKDOWN_SUPPORT))
11769 {
11770 QCString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
11771 if (mdfileAsMainPage.isEmpty()) return;
11772 FileInfo fi(mdfileAsMainPage.data());
11773 if (!fi.exists())
11774 {
11775 warn_uncond("Specified markdown mainpage '%s' does not exist\n",qPrint(mdfileAsMainPage));
11776 return;
11777 }
11778 bool ambig = false;
11779 if (findFileDef(Doxygen::inputNameLinkedMap,fi.absFilePath(),ambig)==nullptr)
11780 {
11781 warn_uncond("Specified markdown mainpage '%s' has not been defined as input file\n",qPrint(mdfileAsMainPage));
11782 return;
11783 }
11784 }
11785}
Minimal replacement for QFileInfo.
Definition fileinfo.h:23
#define warn_uncond(fmt,...)
Definition message.h:79

References FileInfo::absFilePath(), Config_getBool, Config_getString, QCString::data(), FileInfo::exists(), findFileDef(), Doxygen::inputNameLinkedMap, QCString::isEmpty(), qPrint(), and warn_uncond.

Referenced by parseInput().

◆ checkPageRelations()

static void checkPageRelations ( )
static

Definition at line 9248 of file doxygen.cpp.

9249{
9250 for (const auto &pd : *Doxygen::pageLinkedMap)
9251 {
9252 Definition *ppd = pd->getOuterScope();
9253 while (ppd)
9254 {
9255 if (ppd==pd.get())
9256 {
9257 term("page defined %s with label %s is a subpage "
9258 "of itself! Please remove this cyclic dependency.\n",
9259 qPrint(warn_line(pd->docFile(),pd->docLine())),qPrint(pd->name()));
9260 }
9261 ppd=ppd->getOuterScope();
9262 }
9263 }
9264}

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

Referenced by parseInput().

◆ cleanUpDoxygen()

void cleanUpDoxygen ( )

Definition at line 10854 of file doxygen.cpp.

10855{
10859
10860 delete Doxygen::indexList;
10868 Doxygen::mainPage.reset();
10872 Doxygen::globalScope = nullptr;
10874 delete theTranslator;
10875 delete g_outputList;
10876
10881 delete Doxygen::dirLinkedMap;
10882 delete Doxygen::symbolMap;
10883}
static ParserManager * parserManager
Definition doxygen.h:121
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:91
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:119
static SymbolMap< Definition > * symbolMap
Definition doxygen.h:115
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:180

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::symbolMap, and theTranslator.

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

◆ clearAll()

void clearAll ( )

Definition at line 189 of file doxygen.cpp.

190{
191 g_inputFiles.clear();
192 //g_excludeNameDict.clear();
193 //delete g_outputList; g_outputList=nullptr;
194
211 Doxygen::mainPage.reset();
213}
static CitationManager & instance()
Definition cite.cpp:68
void clear()
clears the database
Definition cite.cpp:97
static StringMap tagDestinationMap
Definition doxygen.h:106
static ClassLinkedMap * hiddenClassLinkedMap
Definition doxygen.h:88

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, and Doxygen::tagDestinationMap.

◆ combineUsingRelations()

static void combineUsingRelations ( )
static

Definition at line 8647 of file doxygen.cpp.

8648{
8649 // for each file
8650 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8651 {
8652 for (const auto &fd : *fn)
8653 {
8654 fd->combineUsingRelations();
8655 }
8656 }
8657
8658 // for each namespace
8659 NamespaceDefSet visitedNamespaces;
8660 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8661 {
8663 if (ndm)
8664 {
8665 ndm->combineUsingRelations(visitedNamespaces);
8666 }
8667 }
8668}
virtual void combineUsingRelations(NamespaceDefSet &visitedNamespace)=0
std::unordered_set< const NamespaceDef * > NamespaceDefSet

References FileDef::combineUsingRelations(), NamespaceDefMutable::combineUsingRelations(), Doxygen::inputNameLinkedMap, Doxygen::namespaceLinkedMap, and toNamespaceDefMutable().

Referenced by parseInput().

◆ compareDoxyfile()

static void compareDoxyfile ( Config::CompareMode diffList)
static

Definition at line 9754 of file doxygen.cpp.

9755{
9756 std::ofstream f;
9757 bool fileOpened=openOutputFile("-",f);
9758 if (fileOpened)
9759 {
9760 TextStream t(&f);
9761 Config::compareDoxyfile(t,diffList);
9762 }
9763 else
9764 {
9765 term("Cannot open stdout for writing\n");
9766 }
9767}
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:6646

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

Referenced by readConfiguration().

◆ computeClassRelations()

static void computeClassRelations ( )
static

Definition at line 4853 of file doxygen.cpp.

4854{
4855 AUTO_TRACE();
4856 for (const auto &[name,root] : g_classEntries)
4857 {
4858 QCString bName = extractClassName(root);
4859 ClassDefMutable *cd = getClassMutable(bName);
4860 if (cd)
4861 {
4863 }
4864 size_t numMembers = cd ? cd->memberNameInfoLinkedMap().size() : 0;
4865 if ((cd==nullptr || (!cd->hasDocumentation() && !cd->isReference())) && numMembers>0 && !bName.endsWith("::"))
4866 {
4867 if (!root->name.isEmpty() && root->name.find('@')==-1 && // normal name
4868 (guessSection(root->fileName).isHeader() ||
4869 Config_getBool(EXTRACT_LOCAL_CLASSES)) && // not defined in source file
4870 protectionLevelVisible(root->protection) && // hidden by protection
4871 !Config_getBool(HIDE_UNDOC_CLASSES) // undocumented class are visible
4872 )
4873 warn_undoc(
4874 root->fileName,root->startLine,
4875 "Compound %s is not documented.",
4876 qPrint(root->name)
4877 );
4878 }
4879 }
4880}
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:495
static QCString extractClassName(const Entry *root)
Definition doxygen.cpp:4802
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:4212
static std::multimap< std::string, const Entry * > g_classEntries
Definition doxygen.cpp:178
#define warn_undoc(file, line, fmt,...)
Definition message.h:64

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(), qPrint(), 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 10885 of file doxygen.cpp.

10886{
10887 //printf("computeIdealCacheParam(v=%u)\n",v);
10888
10889 int r=0;
10890 while (v!=0) v>>=1,r++;
10891 // r = log2(v)
10892
10893 // convert to a valid cache size value
10894 return std::max(0,std::min(r-16,9));
10895}

Referenced by generateOutput().

◆ computeMemberReferences()

static void computeMemberReferences ( )
static

Definition at line 4951 of file doxygen.cpp.

4952{
4953 AUTO_TRACE();
4954 for (const auto &cd : *Doxygen::classLinkedMap)
4955 {
4956 ClassDefMutable *cdm = toClassDefMutable(cd.get());
4957 if (cdm)
4958 {
4959 cdm->computeAnchors();
4960 }
4961 }
4962 for (const auto &fn : *Doxygen::inputNameLinkedMap)
4963 {
4964 for (const auto &fd : *fn)
4965 {
4966 fd->computeAnchors();
4967 }
4968 }
4969 for (const auto &nd : *Doxygen::namespaceLinkedMap)
4970 {
4972 if (ndm)
4973 {
4974 ndm->computeAnchors();
4975 }
4976 }
4977 for (const auto &gd : *Doxygen::groupLinkedMap)
4978 {
4979 gd->computeAnchors();
4980 }
4981}
virtual void computeAnchors()=0
virtual void computeAnchors()=0

References AUTO_TRACE, Doxygen::classLinkedMap, ClassDefMutable::computeAnchors(), FileDef::computeAnchors(), GroupDef::computeAnchors(), NamespaceDefMutable::computeAnchors(), Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, Doxygen::namespaceLinkedMap, toClassDefMutable(), and toNamespaceDefMutable().

Referenced by parseInput().

◆ computeMemberRelations()

static void computeMemberRelations ( )
static

Definition at line 7893 of file doxygen.cpp.

7894{
7895 for (const auto &cd : *Doxygen::classLinkedMap)
7896 {
7897 if (cd->isLinkable())
7898 {
7899 for (const auto &bcd : cd->baseClasses())
7900 {
7902 }
7903 }
7904 }
7905}
static void computeMemberRelationsForBaseClass(const ClassDef *cd, const BaseClassDef *bcd)
Definition doxygen.cpp:7816

References ClassDef::baseClasses(), Doxygen::classLinkedMap, computeMemberRelationsForBaseClass(), and Definition::isLinkable().

Referenced by parseInput().

◆ computeMemberRelationsForBaseClass()

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

Definition at line 7816 of file doxygen.cpp.

7817{
7818 for (const auto &mn : cd->memberNameInfoLinkedMap()) // for each member in class cd with a unique name
7819 {
7820 for (const auto &imd : *mn) // for each member with a given name
7821 {
7822 MemberDefMutable *md = toMemberDefMutable(imd->memberDef());
7823 if (md && (md->isFunction() || md->isCSharpProperty())) // filter on reimplementable members
7824 {
7825 ClassDef *mbcd = bcd->classDef;
7826 if (mbcd && mbcd->isLinkable()) // filter on linkable classes
7827 {
7828 const auto &bmn = mbcd->memberNameInfoLinkedMap();
7829 const auto &bmni = bmn.find(mn->memberName());
7830 if (bmni) // there are base class members with the same name
7831 {
7832 for (const auto &ibmd : *bmni) // for base class member with that name
7833 {
7834 MemberDefMutable *bmd = toMemberDefMutable(ibmd->memberDef());
7835 if (bmd) // not part of an inline namespace
7836 {
7837 if (bmd->virtualness()!=Specifier::Normal ||
7839 bmd->getLanguage()==SrcLangExt::Java ||
7840 bmd->getLanguage()==SrcLangExt::PHP ||
7843 {
7844 const ArgumentList &bmdAl = bmd->argumentList();
7845 const ArgumentList &mdAl = md->argumentList();
7846 //printf(" Base argList='%s'\n Super argList='%s'\n",
7847 // qPrint(argListToString(bmdAl)),
7848 // qPrint(argListToString(mdAl))
7849 // );
7850 if (
7852 matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),&bmdAl,
7853 md->getOuterScope(), md->getFileDef(), &mdAl,
7854 TRUE,bmd->getLanguage()
7855 )
7856 )
7857 {
7858 //printf("match!\n");
7859 const MemberDef *rmd = md->reimplements();
7860 if (rmd==nullptr) // not already assigned
7861 {
7862 //printf("%s: setting (new) reimplements member %s\n",qPrint(md->qualifiedName()),qPrint(bmd->qualifiedName()));
7863 md->setReimplements(bmd);
7864 }
7865 //printf("%s: add reimplementedBy member %s\n",qPrint(bmd->qualifiedName()),qPrint(md->qualifiedName()));
7866 bmd->insertReimplementedBy(md);
7867 }
7868 else
7869 {
7870 //printf("no match!\n");
7871 }
7872 }
7873 }
7874 }
7875 }
7876 }
7877 }
7878 }
7879 }
7880
7881 // do also for indirect base classes
7882 for (const auto &bbcd : bcd->classDef->baseClasses())
7883 {
7885 }
7886}
@ Interface
Definition classdef.h:112
virtual CompoundType compoundType() const =0
Returns the type of compound this is, i.e.
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(), MemberName::memberName(), ClassDef::memberNameInfoLinkedMap(), Normal, PHP, ClassDef::Protocol, Python, MemberDef::reimplements(), MemberDefMutable::setReimplements(), toMemberDefMutable(), TRUE, and MemberDef::virtualness().

Referenced by computeMemberRelations(), and computeMemberRelationsForBaseClass().

◆ computePageRelations()

static void computePageRelations ( Entry * root)
static

Definition at line 9218 of file doxygen.cpp.

9219{
9220 if ((root->section.isPageDoc() || root->section.isMainpageDoc()) && !root->name.isEmpty())
9221 {
9222 PageDef *pd = root->section.isPageDoc() ?
9224 Doxygen::mainPage.get();
9225 if (pd)
9226 {
9227 for (const BaseInfo &bi : root->extends)
9228 {
9229 PageDef *subPd = Doxygen::pageLinkedMap->find(bi.name);
9230 if (pd==subPd)
9231 {
9232 term("page defined %s with label %s is a direct "
9233 "subpage of itself! Please remove this cyclic dependency.\n",
9234 qPrint(warn_line(pd->docFile(),pd->docLine())),qPrint(pd->name()));
9235 }
9236 else if (subPd)
9237 {
9238 pd->addInnerCompound(subPd);
9239 //printf("*** Added subpage relation: %s->%s\n",
9240 // qPrint(pd->name()),qPrint(subPd->name()));
9241 }
9242 }
9243 }
9244 }
9245 for (const auto &e : root->children()) computePageRelations(e.get());
9246}
virtual QCString docFile() const =0
virtual int docLine() const =0
static void computePageRelations(Entry *root)
Definition doxygen.cpp:9218
This class stores information about an inheritance relation.
Definition entry.h:89

References DefinitionMutable::addInnerCompound(), Entry::children(), computePageRelations(), Definition::docFile(), Definition::docLine(), Entry::extends, LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::isEmpty(), Doxygen::mainPage, Definition::name(), Entry::name, Doxygen::pageLinkedMap, qPrint(), Entry::section, term, and warn_line().

Referenced by computePageRelations(), and parseInput().

◆ computeTemplateClassRelations()

static void computeTemplateClassRelations ( )
static

Definition at line 4882 of file doxygen.cpp.

4883{
4884 AUTO_TRACE();
4885 for (const auto &[name,root] : g_classEntries)
4886 {
4887 QCString bName=stripAnonymousNamespaceScope(root->name);
4890 // strip any anonymous scopes first
4891 if (cd && !cd->getTemplateInstances().empty())
4892 {
4893 AUTO_TRACE_ADD("Template class '{}'",cd->name());
4894 for (const auto &ti : cd->getTemplateInstances()) // for each template instance
4895 {
4896 ClassDefMutable *tcd=toClassDefMutable(ti.classDef);
4897 if (tcd)
4898 {
4899 AUTO_TRACE_ADD("Template instance '{}'",tcd->name());
4900 QCString templSpec = ti.templSpec;
4901 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(tcd->getLanguage(),templSpec);
4902 for (const BaseInfo &bi : root->extends)
4903 {
4904 // check if the base class is a template argument
4905 BaseInfo tbi = bi;
4906 const ArgumentList &tl = cd->templateArguments();
4907 if (!tl.empty())
4908 {
4909 TemplateNameMap baseClassNames = tcd->getTemplateBaseClassNames();
4910 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,bi.name.str());
4911 // for each template name that we inherit from we need to
4912 // substitute the formal with the actual arguments
4913 TemplateNameMap actualTemplateNames;
4914 for (const auto &tn_kv : templateNames)
4915 {
4916 size_t templIndex = tn_kv.second;
4917 Argument actArg;
4918 bool hasActArg=FALSE;
4919 if (templIndex<templArgs->size())
4920 {
4921 actArg=templArgs->at(templIndex);
4922 hasActArg=TRUE;
4923 }
4924 if (hasActArg &&
4925 baseClassNames.find(actArg.type.str())!=baseClassNames.end() &&
4926 actualTemplateNames.find(actArg.type.str())==actualTemplateNames.end()
4927 )
4928 {
4929 actualTemplateNames.insert(std::make_pair(actArg.type.str(),static_cast<int>(templIndex)));
4930 }
4931 }
4932
4933 tbi.name = substituteTemplateArgumentsInString(bi.name,tl,templArgs.get());
4934 // find a documented base class in the correct scope
4935 if (!findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE))
4936 {
4937 // no documented base class -> try to find an undocumented one
4938 findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,Undocumented,TRUE);
4939 }
4940 }
4941 }
4942 }
4943 }
4944 }
4945 }
4946}
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
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:4433
static TemplateNameMap getTemplateArgumentsInName(const ArgumentList &templateArguments, const std::string &name)
Definition doxygen.cpp:3987
This class contains the information about the argument of a function or template.
Definition arguments.h:27
QCString type
Definition arguments.h:37
QCString name
the name of the base class
Definition entry.h:93
QCString substituteTemplateArgumentsInString(const QCString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
Definition util.cpp:4644

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

8374{
8375 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8376 if (numThreads>1)
8377 {
8378 ThreadPool threadPool(numThreads);
8379 std::vector < std::future< void > > results;
8380 // queue the work
8381 for (const auto &[name,symList] : *Doxygen::symbolMap)
8382 {
8383 for (const auto &def : symList)
8384 {
8386 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
8387 {
8388 auto processTooltip = [dm]() {
8389 dm->computeTooltip();
8390 };
8391 results.emplace_back(threadPool.queue(processTooltip));
8392 }
8393 }
8394 }
8395 // wait for the results
8396 for (auto &f : results)
8397 {
8398 f.get();
8399 }
8400 }
8401 else
8402 {
8403 for (const auto &[name,symList] : *Doxygen::symbolMap)
8404 {
8405 for (const auto &def : symList)
8406 {
8408 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
8409 {
8410 dm->computeTooltip();
8411 }
8412 }
8413 }
8414 }
8415}
virtual void computeTooltip()=0
Class managing a pool of worker threads.
Definition threadpool.h:48
static bool isSymbolHidden(const Definition *d)
Definition doxygen.cpp:8366

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

Referenced by parseInput().

◆ computeVerifiedDotPath()

static void computeVerifiedDotPath ( )
static

Definition at line 9682 of file doxygen.cpp.

9683{
9684 // check dot path
9685 QCString dotPath = Config_getString(DOT_PATH);
9686 if (!dotPath.isEmpty())
9687 {
9688 FileInfo fi(dotPath.str());
9689 if (!(fi.exists() && fi.isFile()) )// not an existing user specified path + exec
9690 {
9691 dotPath = dotPath+"/dot"+Portable::commandExtension();
9692 FileInfo dp(dotPath.str());
9693 if (!dp.exists() || !dp.isFile())
9694 {
9695 warn_uncond("the dot tool could not be found as '%s'\n",qPrint(dotPath));
9696 dotPath = "dot";
9697 dotPath += Portable::commandExtension();
9698 }
9699 }
9700#if defined(_WIN32) // convert slashes
9701 size_t l=dotPath.length();
9702 for (size_t i=0;i<l;i++) if (dotPath.at(i)=='/') dotPath.at(i)='\\';
9703#endif
9704 }
9705 else
9706 {
9707 dotPath = "dot";
9708 dotPath += Portable::commandExtension();
9709 }
9710 Doxygen::verifiedDotPath = dotPath;
9712}
static QCString verifiedDotPath
Definition doxygen.h:129
const char * commandExtension()
Definition portable.cpp:469
#define TRACE(...)
Definition trace.h:77

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

Referenced by parseInput().

◆ convertToCompoundType()

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

Definition at line 874 of file doxygen.cpp.

875{
877
878 if (specifier.isStruct())
880 else if (specifier.isUnion())
881 sec=ClassDef::Union;
882 else if (specifier.isCategory())
884 else if (specifier.isInterface())
886 else if (specifier.isProtocol())
888 else if (specifier.isException())
890 else if (specifier.isService())
892 else if (specifier.isSingleton())
894
895 if (section.isUnionDoc())
896 sec=ClassDef::Union;
897 else if (section.isStructDoc())
899 else if (section.isInterfaceDoc())
901 else if (section.isProtocolDoc())
903 else if (section.isCategoryDoc())
905 else if (section.isExceptionDoc())
907 else if (section.isServiceDoc())
909 else if (section.isSingletonDoc())
911
912 return sec;
913}
@ Singleton
Definition classdef.h:117
@ 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 9948 of file doxygen.cpp.

9949{
9950 for (const auto &fileName : files)
9951 {
9952 if (!fileName.empty())
9953 {
9954 FileInfo fi(fileName);
9955 if (!fi.exists())
9956 {
9957 err("Extra file '%s' specified in %s does not exist!\n", fileName.c_str(),qPrint(filesOption));
9958 }
9959 else if (fi.isDir())
9960 {
9961 err("Extra file '%s' specified in %s is a directory, it has to be a file!\n", fileName.c_str(),qPrint(filesOption));
9962 }
9963 else
9964 {
9965 QCString destFileName = outputOption+"/"+fi.fileName();
9966 Doxygen::indexList->addImageFile(fi.fileName().c_str());
9967 copyFile(QCString(fileName), destFileName);
9968 }
9969 }
9970 }
9971}
void addImageFile(const QCString &name)
Definition indexlist.h:126
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:6092

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

Referenced by generateOutput().

◆ copyIcon()

static void copyIcon ( const QCString & outputOption)
static

Definition at line 9923 of file doxygen.cpp.

9924{
9925 QCString projectIcon = Config_getString(PROJECT_ICON);
9926 if (!projectIcon.isEmpty())
9927 {
9928 FileInfo fi(projectIcon.str());
9929 if (!fi.exists())
9930 {
9931 err("Project icon '%s' specified by PROJECT_ICON does not exist!\n",qPrint(projectIcon));
9932 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
9933 }
9934 else if (fi.isDir())
9935 {
9936 err("Project icon '%s' specified by PROJECT_ICON is a directory, it has to be a file!\n",qPrint(projectIcon));
9937 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
9938 }
9939 else
9940 {
9941 QCString destFileName = outputOption+"/"+fi.fileName();
9942 copyFile(projectIcon,destFileName);
9943 Doxygen::indexList->addImageFile(fi.fileName().c_str());
9944 }
9945 }
9946}
#define Config_updateString(name, value)
Definition config.h:39

References IndexList::addImageFile(), Config_getString, Config_updateString, copyFile(), err, FileInfo::exists(), FileInfo::fileName(), Doxygen::indexList, FileInfo::isDir(), QCString::isEmpty(), qPrint(), and QCString::str().

Referenced by generateOutput().

◆ copyLatexStyleSheet()

static void copyLatexStyleSheet ( )
static

Definition at line 9814 of file doxygen.cpp.

9815{
9816 const StringVector &latexExtraStyleSheet = Config_getList(LATEX_EXTRA_STYLESHEET);
9817 for (const auto &sheet : latexExtraStyleSheet)
9818 {
9819 std::string fileName = sheet;
9820 if (!fileName.empty())
9821 {
9822 FileInfo fi(fileName);
9823 if (!fi.exists())
9824 {
9825 err("Style sheet '%s' specified by LATEX_EXTRA_STYLESHEET does not exist!\n",qPrint(fileName));
9826 }
9827 else if (fi.isDir())
9828 {
9829 err("Style sheet '%s' specified by LATEX_EXTRA_STYLESHEET is a directory, it has to be a file!\n", qPrint(fileName));
9830 }
9831 else
9832 {
9833 QCString destFileName = Config_getString(LATEX_OUTPUT)+"/"+fi.fileName();
9834 if (!checkExtension(fi.fileName().c_str(), LATEX_STYLE_EXTENSION))
9835 {
9836 destFileName += LATEX_STYLE_EXTENSION;
9837 }
9838 copyFile(QCString(fileName), destFileName);
9839 }
9840 }
9841 }
9842}
#define LATEX_STYLE_EXTENSION
Definition latexgen.h:22
bool checkExtension(const QCString &fName, const QCString &ext)
Definition util.cpp:5166

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

Referenced by generateOutput().

◆ copyLogo()

static void copyLogo ( const QCString & outputOption)
static

Definition at line 9898 of file doxygen.cpp.

9899{
9900 QCString projectLogo = projectLogoFile();
9901 if (!projectLogo.isEmpty())
9902 {
9903 FileInfo fi(projectLogo.str());
9904 if (!fi.exists())
9905 {
9906 err("Project logo '%s' specified by PROJECT_LOGO does not exist!\n",qPrint(projectLogo));
9907 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
9908 }
9909 else if (fi.isDir())
9910 {
9911 err("Project logo '%s' specified by PROJECT_LOGO is a directory, it has to be a file!\n",qPrint(projectLogo));
9912 projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
9913 }
9914 else
9915 {
9916 QCString destFileName = outputOption+"/"+fi.fileName();
9917 copyFile(projectLogo,destFileName);
9918 Doxygen::indexList->addImageFile(fi.fileName().c_str());
9919 }
9920 }
9921}
QCString projectLogoFile()
Definition util.cpp:3455

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

Referenced by generateOutput().

◆ copyStyleSheet()

static void copyStyleSheet ( )
static

Definition at line 9845 of file doxygen.cpp.

9846{
9847 QCString htmlStyleSheet = Config_getString(HTML_STYLESHEET);
9848 if (!htmlStyleSheet.isEmpty())
9849 {
9850 if (!htmlStyleSheet.startsWith("http:") && !htmlStyleSheet.startsWith("https:"))
9851 {
9852 FileInfo fi(htmlStyleSheet.str());
9853 if (!fi.exists())
9854 {
9855 err("Style sheet '%s' specified by HTML_STYLESHEET does not exist!\n",qPrint(htmlStyleSheet));
9856 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
9857 }
9858 else if (fi.isDir())
9859 {
9860 err("Style sheet '%s' specified by HTML_STYLESHEET is a directory, it has to be a file!\n",qPrint(htmlStyleSheet));
9861 htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
9862 }
9863 else
9864 {
9865 QCString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
9866 copyFile(htmlStyleSheet,destFileName);
9867 }
9868 }
9869 }
9870 const StringVector &htmlExtraStyleSheet = Config_getList(HTML_EXTRA_STYLESHEET);
9871 for (const auto &sheet : htmlExtraStyleSheet)
9872 {
9873 QCString fileName(sheet);
9874 if (!fileName.isEmpty() && !fileName.startsWith("http:") && !fileName.startsWith("https:"))
9875 {
9876 FileInfo fi(fileName.str());
9877 if (!fi.exists())
9878 {
9879 err("Style sheet '%s' specified by HTML_EXTRA_STYLESHEET does not exist!\n",qPrint(fileName));
9880 }
9881 else if (fi.fileName()=="doxygen.css" || fi.fileName()=="tabs.css" || fi.fileName()=="navtree.css")
9882 {
9883 err("Style sheet %s specified by HTML_EXTRA_STYLESHEET is already a built-in stylesheet. Please use a different name\n",qPrint(fi.fileName()));
9884 }
9885 else if (fi.isDir())
9886 {
9887 err("Style sheet '%s' specified by HTML_EXTRA_STYLESHEET is a directory, it has to be a file!\n",qPrint(fileName));
9888 }
9889 else
9890 {
9891 QCString destFileName = Config_getString(HTML_OUTPUT)+"/"+fi.fileName();
9892 copyFile(QCString(fileName), destFileName);
9893 }
9894 }
9895 }
9896}
bool startsWith(const char *s) const
Definition qcstring.h:483

References Config_getList, Config_getString, Config_updateString, copyFile(), err, FileInfo::exists(), FileInfo::fileName(), FileInfo::isDir(), QCString::isEmpty(), qPrint(), QCString::startsWith(), and QCString::str().

Referenced by generateOutput().

◆ countMembers()

static void countMembers ( )
static

Definition at line 8433 of file doxygen.cpp.

8434{
8435 for (const auto &cd : *Doxygen::classLinkedMap)
8436 {
8437 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8438 if (cdm)
8439 {
8440 cdm->countMembers();
8441 }
8442 }
8443
8444 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8445 {
8447 if (ndm)
8448 {
8449 ndm->countMembers();
8450 }
8451 }
8452
8453 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8454 {
8455 for (const auto &fd : *fn)
8456 {
8457 fd->countMembers();
8458 }
8459 }
8460
8461 for (const auto &gd : *Doxygen::groupLinkedMap)
8462 {
8463 gd->countMembers();
8464 }
8465
8466 auto &mm = ModuleManager::instance();
8467 mm.countMembers();
8468}
virtual void countMembers()=0
virtual void countMembers()=0

References Doxygen::classLinkedMap, ClassDefMutable::countMembers(), FileDef::countMembers(), GroupDef::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 11550 of file doxygen.cpp.

11553{
11554 QCString result = formatDirName;
11555 if (result.isEmpty())
11556 {
11557 result = baseDirName + defaultDirName;
11558 }
11559 else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':'))
11560 {
11561 result.prepend(baseDirName+"/");
11562 }
11563 Dir formatDir(result.str());
11564 if (!formatDir.exists() && !formatDir.mkdir(result.str()))
11565 {
11566 err("Could not create output directory %s\n", qPrint(result));
11568 exit(1);
11569 }
11570 return result;
11571}
Class representing a directory in the file system.
Definition dir.h:75
void cleanUpDoxygen()

References cleanUpDoxygen(), err, Dir::exists(), QCString::isEmpty(), QCString::length(), Dir::mkdir(), QCString::prepend(), qPrint(), and QCString::str().

Referenced by parseInput().

◆ createTagLessInstance()

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

Definition at line 1450 of file doxygen.cpp.

1451{
1452 QCString fullName = removeAnonymousScopes(templ->name());
1453 if (fullName.endsWith("::")) fullName=fullName.left(fullName.length()-2);
1454 fullName+="."+fieldName;
1455
1456 //printf("** adding class %s based on %s\n",qPrint(fullName),qPrint(templ->name()));
1458 Doxygen::classLinkedMap->add(fullName,
1460 templ->getDefLine(),
1461 templ->getDefColumn(),
1462 fullName,
1463 templ->compoundType())));
1464 if (cd)
1465 {
1466 cd->setDocumentation(templ->documentation(),templ->docFile(),templ->docLine()); // copy docs to definition
1467 cd->setBriefDescription(templ->briefDescription(),templ->briefFile(),templ->briefLine());
1468 cd->setLanguage(templ->getLanguage());
1469 cd->setBodySegment(templ->getDefLine(),templ->getStartBodyLine(),templ->getEndBodyLine());
1470 cd->setBodyDef(templ->getBodyDef());
1471
1472 cd->setOuterScope(rootCd->getOuterScope());
1473 if (rootCd->getOuterScope()!=Doxygen::globalScope)
1474 {
1475 DefinitionMutable *outerScope = toDefinitionMutable(rootCd->getOuterScope());
1476 if (outerScope)
1477 {
1478 outerScope->addInnerCompound(cd);
1479 }
1480 }
1481
1482 FileDef *fd = templ->getFileDef();
1483 if (fd)
1484 {
1485 cd->setFileDef(fd);
1486 fd->insertClass(cd);
1487 }
1488 for (const auto &gd : rootCd->partOfGroups())
1489 {
1490 cd->makePartOfGroup(gd);
1491 const_cast<GroupDef*>(gd)->addClass(cd);
1492 }
1493
1495 if (ml)
1496 {
1497 for (const auto &md : *ml)
1498 {
1499 //printf(" Member %s type=%s\n",qPrint(md->name()),md->typeString());
1500 auto newMd = createMemberDef(md->getDefFileName(),md->getDefLine(),md->getDefColumn(),
1501 md->typeString(),md->name(),md->argsString(),md->excpString(),
1502 md->protection(),md->virtualness(),md->isStatic(),Relationship::Member,
1503 md->memberType(),
1504 ArgumentList(),ArgumentList(),"");
1505 MemberDefMutable *imd = toMemberDefMutable(newMd.get());
1506 imd->setMemberClass(cd);
1507 imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
1508 imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
1509 imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
1510 imd->setMemberSpecifiers(md->getMemberSpecifiers());
1511 imd->setVhdlSpecifiers(md->getVhdlSpecifiers());
1512 imd->setMemberGroupId(md->getMemberGroupId());
1513 imd->setInitializer(md->initializer());
1514 imd->setRequiresClause(md->requiresClause());
1515 imd->setMaxInitLines(md->initializerLines());
1516 imd->setBitfields(md->bitfieldString());
1517 imd->setLanguage(md->getLanguage());
1518 cd->insertMember(imd);
1519 MemberName *mn = Doxygen::memberNameLinkedMap->add(md->name());
1520 mn->push_back(std::move(newMd));
1521 }
1522 }
1523 }
1524 return cd;
1525}
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 QCString briefDescription(bool abbreviate=FALSE) const =0
virtual QCString documentation() 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:108
@ MemberListType_pubAttribs
Definition types.h:122
QCString removeAnonymousScopes(const QCString &str)
Definition util.cpp:172

References LinkedMap< T, Hash, KeyEqual, Map >::add(), 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, MemberListType_pubAttribs, 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 7909 of file doxygen.cpp.

7910{
7911 // for each class
7912 for (const auto &cd : *Doxygen::classLinkedMap)
7913 {
7914 // that is a template
7915 for (const auto &ti : cd->getTemplateInstances())
7916 {
7917 ClassDefMutable *tcdm = toClassDefMutable(ti.classDef);
7918 if (tcdm)
7919 {
7920 tcdm->addMembersToTemplateInstance(cd.get(),cd->templateArguments(),ti.templSpec);
7921 }
7922 }
7923 }
7924}
virtual void addMembersToTemplateInstance(const ClassDef *cd, const ArgumentList &templateArguments, const QCString &templSpec)=0

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

Referenced by parseInput().

◆ devUsage()

static void devUsage ( )
static

Definition at line 10668 of file doxygen.cpp.

10669{
10670 msg("Developer parameters:\n");
10671 msg(" -m dump symbol map\n");
10672 msg(" -b making messages output unbuffered\n");
10673#if ENABLE_TRACING
10674 msg(" -t [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout)\n");
10675 msg(" -t_notime [<file|stdout|stderr>] trace debug info to file, stdout, or stderr (default file stdout),\n"
10676 " but without time and thread information\n");
10677#endif
10678 msg(" -d <level> enable a debug level, such as (multiple invocations of -d are possible):\n");
10680}
static void printFlags()
Definition debug.cpp:139

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

Referenced by readConfiguration().

◆ distributeClassGroupRelations()

void distributeClassGroupRelations ( )

Definition at line 1417 of file doxygen.cpp.

1418{
1419 //bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
1420 //if (!inlineGroupedClasses) return;
1421 //printf("** distributeClassGroupRelations()\n");
1422
1423 ClassDefSet visitedClasses;
1424 for (const auto &cd : *Doxygen::classLinkedMap)
1425 {
1426 //printf("Checking %s\n",qPrint(cd->name()));
1427 // distribute the group to nested classes as well
1428 if (visitedClasses.find(cd.get())==visitedClasses.end() && !cd->partOfGroups().empty())
1429 {
1430 //printf(" Candidate for merging\n");
1431 GroupDef *gd = cd->partOfGroups().front();
1432 for (auto &ncd : cd->getClasses())
1433 {
1435 if (ncdm && ncdm->partOfGroups().empty())
1436 {
1437 //printf(" Adding %s to group '%s'\n",qPrint(ncd->name()),
1438 // gd->groupTitle());
1439 ncdm->makePartOfGroup(gd);
1440 gd->addClass(ncdm);
1441 }
1442 }
1443 visitedClasses.insert(cd.get()); // only visit every class once
1444 }
1445 }
1446}
virtual const GroupList & partOfGroups() const =0
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 1268 of file doxygen.cpp.

1269{
1270 AUTO_TRACE();
1271 for (const auto &cd : *Doxygen::conceptLinkedMap)
1272 {
1273 if (cd->groupId()!=DOX_NOGROUP)
1274 {
1275 for (const auto &ocd : *Doxygen::conceptLinkedMap)
1276 {
1277 if (cd!=ocd && cd->groupId()==ocd->groupId() &&
1278 !cd->partOfGroups().empty() && ocd->partOfGroups().empty())
1279 {
1280 ConceptDefMutable *ocdm = toConceptDefMutable(ocd.get());
1281 if (ocdm)
1282 {
1283 for (const auto &gd : cd->partOfGroups())
1284 {
1285 if (gd)
1286 {
1287 AUTO_TRACE_ADD("making concept '{}' part of group '{}'",ocdm->name(),gd->name());
1288 ocdm->makePartOfGroup(gd);
1289 gd->addConcept(ocd.get());
1290 }
1291 }
1292 }
1293 }
1294 }
1295 }
1296 }
1297}
#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 8710 of file doxygen.cpp.

8711{
8712 // for each class
8713 for (const auto &cd : *Doxygen::classLinkedMap)
8714 {
8715 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8716 if (cdm)
8717 {
8719 }
8720 }
8721 // for each file
8722 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8723 {
8724 for (const auto &fd : *fn)
8725 {
8726 fd->distributeMemberGroupDocumentation();
8727 }
8728 }
8729 // for each namespace
8730 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8731 {
8733 if (ndm)
8734 {
8736 }
8737 }
8738 // for each group
8739 for (const auto &gd : *Doxygen::groupLinkedMap)
8740 {
8741 gd->distributeMemberGroupDocumentation();
8742 }
8744}
virtual void distributeMemberGroupDocumentation()=0
void distributeMemberGroupDocumentation()
virtual void distributeMemberGroupDocumentation()=0

References Doxygen::classLinkedMap, ClassDefMutable::distributeMemberGroupDocumentation(), FileDef::distributeMemberGroupDocumentation(), GroupDef::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 10627 of file doxygen.cpp.

10628{
10629 QCString anchor;
10631 {
10632 MemberDef *md = toMemberDef(d);
10633 anchor=":"+md->anchor();
10634 }
10635 QCString scope;
10636 QCString fn = d->getOutputFileBase();
10639 {
10640 scope = fn;
10641 }
10642 t << "REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
10643 << fn+anchor << "','"
10644 << scope << "','"
10645 << d->name() << "','"
10646 << d->getDefFileName() << "','"
10647 << d->getDefLine()
10648 << "');\n";
10649}
virtual QCString anchor() const =0
virtual QCString getOutputFileBase() const =0
MemberDef * toMemberDef(Definition *d)
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:5171

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

10652{
10653 std::ofstream f = Portable::openOutputStream("symbols.sql");
10654 if (f.is_open())
10655 {
10656 TextStream t(&f);
10657 for (const auto &[name,symList] : *Doxygen::symbolMap)
10658 {
10659 for (const auto &def : symList)
10660 {
10661 dumpSymbol(t,def);
10662 }
10663 }
10664 }
10665}
static void dumpSymbol(TextStream &t, Definition *d)
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:638

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

Referenced by generateOutput().

◆ exitDoxygen()

static void exitDoxygen ( )
staticnoexcept

Definition at line 11537 of file doxygen.cpp.

11538{
11539 if (!g_successfulRun) // premature exit
11540 {
11541 Dir thisDir;
11542 msg("Exiting...\n");
11543 if (!Doxygen::filterDBFileName.isEmpty())
11544 {
11545 thisDir.remove(Doxygen::filterDBFileName.str());
11546 }
11547 }
11548}
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:314
static QCString filterDBFileName
Definition doxygen.h:123
static bool g_successfulRun
Definition doxygen.cpp:182

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

Referenced by parseInput().

◆ extractClassName()

static QCString extractClassName ( const Entry * root)
static

Definition at line 4802 of file doxygen.cpp.

4803{
4804 // strip any anonymous scopes first
4807 int i=0;
4808 if ((root->lang==SrcLangExt::CSharp || root->lang==SrcLangExt::Java) &&
4809 (i=bName.find('<'))!=-1)
4810 {
4811 // a Java/C# generic class looks like a C++ specialization, so we need to strip the
4812 // template part before looking for matches
4813 bName=bName.left(i);
4814 }
4815 return bName;
4816}

References CSharp, QCString::find(), Java, Entry::lang, QCString::left(), 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 6769 of file doxygen.cpp.

6770{
6771 AUTO_TRACE("root->type='{}' root->inside='{}' root->name='{}' root->args='{}' section={} root->spec={} root->mGrpId={}",
6772 root->type,root->inside,root->name,root->args,root->section,root->spec,root->mGrpId);
6773 //printf("root->parent()->name=%s\n",qPrint(root->parent()->name));
6774 bool isFunc=TRUE;
6775
6776 QCString type = root->type;
6777 QCString args = root->args;
6778 int i=-1, l=0;
6779 if ( // detect func variable/typedef to func ptr
6780 (i=findFunctionPtr(type.str(),root->lang,&l))!=-1
6781 )
6782 {
6783 //printf("Fixing function pointer!\n");
6784 // fix type and argument
6785 args.prepend(type.right(type.length()-i-l));
6786 type=type.left(i+l);
6787 //printf("Results type=%s,name=%s,args=%s\n",qPrint(type),qPrint(root->name),qPrint(args));
6788 isFunc=FALSE;
6789 }
6790 else if ((type.startsWith("typedef ") && args.find('(')!=-1))
6791 // detect function types marked as functions
6792 {
6793 isFunc=FALSE;
6794 }
6795
6796 //printf("Member %s isFunc=%d\n",qPrint(root->name),isFunc);
6797 if (root->section.isMemberDoc())
6798 {
6799 //printf("Documentation for inline member '%s' found args='%s'\n",
6800 // qPrint(root->name),qPrint(args));
6801 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
6802 if (type.isEmpty())
6803 {
6804 findMember(root,
6805 relates,
6806 type,
6807 args,
6808 root->name + args + root->exception,
6809 FALSE,
6810 isFunc);
6811 }
6812 else
6813 {
6814 findMember(root,
6815 relates,
6816 type,
6817 args,
6818 type + " " + root->name + args + root->exception,
6819 FALSE,
6820 isFunc);
6821 }
6822 }
6823 else if (root->section.isOverloadDoc())
6824 {
6825 //printf("Overloaded member %s found\n",qPrint(root->name));
6826 findMember(root,
6827 relates,
6828 type,
6829 args,
6830 root->name,
6831 TRUE,
6832 isFunc);
6833 }
6834 else if
6835 ((root->section.isFunction() // function
6836 ||
6837 (root->section.isVariable() && // variable
6838 !type.isEmpty() && // with a type
6839 g_compoundKeywords.find(type.str())==g_compoundKeywords.end() // that is not a keyword
6840 // (to skip forward declaration of class etc.)
6841 )
6842 )
6843 )
6844 {
6845 //printf("Documentation for member '%s' found args='%s' excp='%s'\n",
6846 // qPrint(root->name),qPrint(args),qPrint(root->exception));
6847 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
6848 //printf("Inside=%s\n Relates=%s\n",qPrint(root->inside),qPrint(relates));
6849 if (type=="friend class" || type=="friend struct" ||
6850 type=="friend union")
6851 {
6852 findMember(root,
6853 relates,
6854 type,
6855 args,
6856 type+" "+root->name,
6857 FALSE,FALSE);
6858
6859 }
6860 else if (!type.isEmpty())
6861 {
6862 findMember(root,
6863 relates,
6864 type,
6865 args,
6866 type+" "+ root->inside + root->name + args + root->exception,
6867 FALSE,isFunc);
6868 }
6869 else
6870 {
6871 findMember(root,
6872 relates,
6873 type,
6874 args,
6875 root->inside + root->name + args + root->exception,
6876 FALSE,isFunc);
6877 }
6878 }
6879 else if (root->section.isDefine() && !relates.isEmpty())
6880 {
6881 findMember(root,
6882 relates,
6883 type,
6884 args,
6885 root->name + args,
6886 FALSE,
6887 !args.isEmpty());
6888 }
6889 else if (root->section.isVariableDoc())
6890 {
6891 //printf("Documentation for variable %s found\n",qPrint(root->name));
6892 //if (!relates.isEmpty()) printf(" Relates %s\n",qPrint(relates));
6893 findMember(root,
6894 relates,
6895 type,
6896 args,
6897 root->name,
6898 FALSE,
6899 FALSE);
6900 }
6901 else if (root->section.isExportedInterface() ||
6902 root->section.isIncludedService())
6903 {
6904 findMember(root,
6905 relates,
6906 type,
6907 args,
6908 type + " " + root->name,
6909 FALSE,
6910 FALSE);
6911 }
6912 else
6913 {
6914 // skip section
6915 //printf("skip section\n");
6916 }
6917}
QCString inside
name of the class in which documents are found
Definition entry.h:212
static int findFunctionPtr(const std::string &type, SrcLangExt lang, int *pLength=nullptr)
Definition doxygen.cpp:2570
static void findMember(const Entry *root, const QCString &relates, const QCString &type, const QCString &args, QCString funcDecl, bool overloaded, bool isFunc)
Definition doxygen.cpp:6155
static const StringUnorderedSet g_compoundKeywords
Definition doxygen.cpp:186

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

4222{
4223 AUTO_TRACE("name={}",root->name);
4224 // The base class could ofcouse also be a non-nested class
4225 const ArgumentList &formalArgs = masterCd->templateArguments();
4226 for (const BaseInfo &bi : root->extends)
4227 {
4228 //printf("masterCd=%s bi.name='%s' #actualArgs=%d\n",
4229 // qPrint(masterCd->localName()),qPrint(bi.name),actualArgs ? (int)actualArgs->size() : -1);
4230 TemplateNameMap formTemplateNames;
4231 if (templateNames.empty())
4232 {
4233 formTemplateNames = getTemplateArgumentsInName(formalArgs,bi.name.str());
4234 }
4235 BaseInfo tbi = bi;
4236 tbi.name = substituteTemplateArgumentsInString(bi.name,formalArgs,actualArgs);
4237 //printf("masterCd=%p instanceCd=%p bi->name=%s tbi.name=%s\n",(void*)masterCd,(void*)instanceCd,qPrint(bi.name),qPrint(tbi.name));
4238
4239 if (mode==DocumentedOnly)
4240 {
4241 // find a documented base class in the correct scope
4242 if (!findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,DocumentedOnly,isArtificial))
4243 {
4244 // 1.8.2: decided to show inheritance relations even if not documented,
4245 // we do make them artificial, so they do not appear in the index
4246 //if (!Config_getBool(HIDE_UNDOC_RELATIONS))
4247 bool b = Config_getBool(HIDE_UNDOC_RELATIONS) ? TRUE : isArtificial;
4248 //{
4249 // no documented base class -> try to find an undocumented one
4250 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,Undocumented,b);
4251 //}
4252 }
4253 }
4254 else if (mode==TemplateInstances)
4255 {
4256 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,TemplateInstances,isArtificial);
4257 }
4258 }
4259}

References AUTO_TRACE, Config_getBool, DocumentedOnly, Entry::extends, findClassRelation(), getTemplateArgumentsInName(), BaseInfo::name, Entry::name, 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 5220 of file doxygen.cpp.

5222{
5223 SymbolResolver resolver(fd);
5224 const ClassDef *tcd = resolver.resolveClass(nd,scopeName,true,true);
5225 return tcd;
5226}
Helper class to find a class definition or check if A symbol is accessible in a given scope.

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

4794{
4795 if (isClassSection(root))
4796 {
4797 g_classEntries.insert({root->name.str(),root});
4798 }
4799 for (const auto &e : root->children()) findClassEntries(e.get());
4800}
static void findClassEntries(const Entry *root)
Definition doxygen.cpp:4793
static bool isClassSection(const Entry *root)
Definition doxygen.cpp:4771

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

4442{
4443 AUTO_TRACE("name={} base={} isArtificial={}",cd->name(),bi->name,isArtificial);
4444
4445 QCString biName=bi->name;
4446 bool explicitGlobalScope=FALSE;
4447 if (biName.startsWith("::")) // explicit global scope
4448 {
4449 biName=biName.right(biName.length()-2);
4450 explicitGlobalScope=TRUE;
4451 }
4452
4453 Entry *parentNode=root->parent();
4454 bool lastParent=FALSE;
4455 do // for each parent scope, starting with the largest scope
4456 // (in case of nested classes)
4457 {
4458 QCString scopeName= parentNode ? parentNode->name : QCString();
4459 int scopeOffset=explicitGlobalScope ? 0 : static_cast<int>(scopeName.length());
4460 do // try all parent scope prefixes, starting with the largest scope
4461 {
4462 //printf("scopePrefix='%s' biName='%s'\n",
4463 // qPrint(scopeName.left(scopeOffset)),qPrint(biName));
4464
4465 QCString baseClassName=biName;
4466 if (scopeOffset>0)
4467 {
4468 baseClassName.prepend(scopeName.left(scopeOffset)+"::");
4469 }
4470 //QCString stripped;
4471 //baseClassName=stripTemplateSpecifiersFromScope
4472 // (removeRedundantWhiteSpace(baseClassName),TRUE,
4473 // &stripped);
4474 SymbolResolver resolver(cd->getFileDef());
4475 ClassDefMutable *baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
4476 baseClassName,
4477 mode==Undocumented,
4478 true
4479 );
4480 const MemberDef *baseClassTypeDef = resolver.getTypedef();
4481 QCString templSpec = resolver.getTemplateSpec();
4482 //printf("baseClassName=%s baseClass=%p cd=%p explicitGlobalScope=%d\n",
4483 // qPrint(baseClassName),baseClass,cd,explicitGlobalScope);
4484 //printf(" scope='%s' baseClassName='%s' baseClass=%s templSpec=%s\n",
4485 // cd ? qPrint(cd->name()):"<none>",
4486 // qPrint(baseClassName),
4487 // baseClass?qPrint(baseClass->name()):"<none>",
4488 // qPrint(templSpec)
4489 // );
4490 //if (baseClassName.left(root->name.length())!=root->name ||
4491 // baseClassName.at(root->name.length())!='<'
4492 // ) // Check for base class with the same name.
4493 // // If found then look in the outer scope for a match
4494 // // and prevent recursion.
4495 if (!isRecursiveBaseClass(root->name,baseClassName)
4496 || explicitGlobalScope
4497 // sadly isRecursiveBaseClass always true for UNO IDL ifc/svc members
4498 // (i.e. this is needed for addInterfaceOrServiceToServiceOrSingleton)
4499 || (root->lang==SrcLangExt::IDL &&
4500 (root->section.isExportedInterface() ||
4501 root->section.isIncludedService()))
4502 )
4503 {
4504 AUTO_TRACE_ADD("class relation '{}' inherited/used by '{}' found prot={} virt={} templSpec='{}'",
4505 baseClassName, root->name, bi->prot, bi->virt, templSpec);
4506
4507 int i=findTemplateSpecializationPosition(baseClassName);
4508 int si=baseClassName.findRev("::",i);
4509 if (si==-1) si=0;
4510 if (baseClass==nullptr && static_cast<size_t>(i)!=baseClassName.length())
4511 // base class has template specifiers
4512 {
4513 // TODO: here we should try to find the correct template specialization
4514 // but for now, we only look for the unspecialized base class.
4515 int e=findEndOfTemplate(baseClassName,i+1);
4516 //printf("baseClass==0 i=%d e=%d\n",i,e);
4517 if (e!=-1) // end of template was found at e
4518 {
4519 templSpec = removeRedundantWhiteSpace(baseClassName.mid(i,e-i));
4520 baseClassName = baseClassName.left(i)+baseClassName.right(baseClassName.length()-e);
4521 baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
4522 baseClassName,
4523 mode==Undocumented,
4524 true
4525 );
4526 baseClassTypeDef = resolver.getTypedef();
4527 //printf("baseClass=%p -> baseClass=%s templSpec=%s\n",
4528 // baseClass,qPrint(baseClassName),qPrint(templSpec));
4529 }
4530 }
4531 else if (baseClass && !templSpec.isEmpty()) // we have a known class, but also
4532 // know it is a template, so see if
4533 // we can also link to the explicit
4534 // instance (for instance if a class
4535 // derived from a template argument)
4536 {
4537 //printf("baseClass=%s templSpec=%s\n",qPrint(baseClass->name()),qPrint(templSpec));
4538 ClassDefMutable *templClass=getClassMutable(baseClass->name()+templSpec);
4539 if (templClass)
4540 {
4541 // use the template instance instead of the template base.
4542 baseClass = templClass;
4543 templSpec.clear();
4544 }
4545 }
4546
4547 //printf("cd=%p baseClass=%p\n",cd,baseClass);
4548 bool found=baseClass!=nullptr && (baseClass!=cd || mode==TemplateInstances);
4549 //printf("1. found=%d\n",found);
4550 if (!found && si!=-1)
4551 {
4552 // replace any namespace aliases
4553 replaceNamespaceAliases(baseClassName,si);
4554 baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
4555 baseClassName,
4556 mode==Undocumented,
4557 true
4558 );
4559 baseClassTypeDef = resolver.getTypedef();
4560 found=baseClass!=nullptr && baseClass!=cd;
4561 if (found) templSpec = resolver.getTemplateSpec();
4562 }
4563 //printf("2. found=%d\n",found);
4564
4565 if (!found)
4566 {
4567 baseClass=toClassDefMutable(findClassWithinClassContext(context,cd,baseClassName));
4568 //printf("findClassWithinClassContext(%s,%s)=%p\n",
4569 // qPrint(cd->name()),qPrint(baseClassName),baseClass);
4570 found = baseClass!=nullptr && baseClass!=cd;
4571
4572 }
4573 //printf("3. found=%d\n",found);
4574 if (!found)
4575 {
4576 // for PHP the "use A\B as C" construct map class C to A::B, so we lookup
4577 // the class name also in the alias mapping.
4578 auto it = Doxygen::namespaceAliasMap.find(baseClassName.str());
4579 if (it!=Doxygen::namespaceAliasMap.end()) // see if it is indeed a class.
4580 {
4581 baseClass=getClassMutable(it->second.c_str());
4582 found = baseClass!=nullptr && baseClass!=cd;
4583 }
4584 }
4585 bool isATemplateArgument = templateNames.find(biName.str())!=templateNames.end();
4586
4587 //printf("4. found=%d\n",found);
4588 if (found)
4589 {
4590 AUTO_TRACE_ADD("Documented base class '{}' templSpec='{}'",biName,templSpec);
4591 // add base class to this class
4592
4593 // if templSpec is not empty then we should "instantiate"
4594 // the template baseClass. A new ClassDef should be created
4595 // to represent the instance. To be able to add the (instantiated)
4596 // members and documentation of a template class
4597 // (inserted in that template class at a later stage),
4598 // the template should know about its instances.
4599 // the instantiation process, should be done in a recursive way,
4600 // since instantiating a template may introduce new inheritance
4601 // relations.
4602 if (!templSpec.isEmpty() && mode==TemplateInstances)
4603 {
4604 // if baseClass is actually a typedef then we should not
4605 // instantiate it, since typedefs are in a different namespace
4606 // see bug531637 for an example where this would otherwise hang
4607 // doxygen
4608 if (baseClassTypeDef==nullptr)
4609 {
4610 //printf(" => findTemplateInstanceRelation: %s\n",qPrint(baseClass->name()));
4611 findTemplateInstanceRelation(root,context,baseClass,templSpec,templateNames,baseClass->isArtificial());
4612 }
4613 }
4614 else if (mode==DocumentedOnly || mode==Undocumented)
4615 {
4616 //printf(" => insert base class\n");
4617 QCString usedName;
4618 if (baseClassTypeDef || cd->isCSharp())
4619 {
4620 usedName=biName;
4621 //printf("***** usedName=%s templSpec=%s\n",qPrint(usedName),qPrint(templSpec));
4622 }
4623 Protection prot = bi->prot;
4624 if (Config_getBool(SIP_SUPPORT)) prot=Protection::Public;
4625 if (cd!=baseClass && !cd->isSubClass(baseClass) && baseClass->isBaseClass(cd,true,templSpec)==0) // check for recursion, see bug690787
4626 {
4627 cd->insertBaseClass(baseClass,usedName,prot,bi->virt,templSpec);
4628 // add this class as super class to the base class
4629 baseClass->insertSubClass(cd,prot,bi->virt,templSpec);
4630 }
4631 else
4632 {
4633 warn(root->fileName,root->startLine,
4634 "Detected potential recursive class relation "
4635 "between class %s and base class %s!",
4636 qPrint(cd->name()),qPrint(baseClass->name())
4637 );
4638 }
4639 }
4640 return TRUE;
4641 }
4642 else if (mode==Undocumented && (scopeOffset==0 || isATemplateArgument))
4643 {
4644 AUTO_TRACE_ADD("New undocumented base class '{}' baseClassName='{}' templSpec='{}' isArtificial={}",
4645 biName,baseClassName,templSpec,isArtificial);
4646 baseClass=nullptr;
4647 if (isATemplateArgument)
4648 {
4649 baseClass = toClassDefMutable(Doxygen::hiddenClassLinkedMap->find(baseClassName));
4650 if (baseClass==nullptr) // not found (or alias)
4651 {
4652 baseClass= toClassDefMutable(
4653 Doxygen::hiddenClassLinkedMap->add(baseClassName,
4654 createClassDef(root->fileName,root->startLine,root->startColumn,
4655 baseClassName,
4656 ClassDef::Class)));
4657 if (baseClass) // really added (not alias)
4658 {
4659 if (isArtificial) baseClass->setArtificial(TRUE);
4660 baseClass->setLanguage(root->lang);
4661 }
4662 }
4663 }
4664 else
4665 {
4666 baseClass = toClassDefMutable(Doxygen::classLinkedMap->find(baseClassName));
4667 //printf("*** classDDict->find(%s)=%p biName=%s templSpec=%s\n",
4668 // qPrint(baseClassName),baseClass,qPrint(biName),qPrint(templSpec));
4669 if (baseClass==nullptr) // not found (or alias)
4670 {
4671 baseClass = toClassDefMutable(
4672 Doxygen::classLinkedMap->add(baseClassName,
4673 createClassDef(root->fileName,root->startLine,root->startColumn,
4674 baseClassName,
4675 ClassDef::Class)));
4676 if (baseClass) // really added (not alias)
4677 {
4678 if (isArtificial) baseClass->setArtificial(TRUE);
4679 baseClass->setLanguage(root->lang);
4680 si = baseClassName.findRev("::");
4681 if (si!=-1) // class is nested
4682 {
4683 Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),nullptr,root->tagInfo());
4684 if (sd==nullptr || sd==Doxygen::globalScope) // outer scope not found
4685 {
4686 baseClass->setArtificial(TRUE); // see bug678139
4687 }
4688 }
4689 }
4690 }
4691 }
4692 if (baseClass)
4693 {
4694 if (biName.endsWith("-p"))
4695 {
4696 biName="<"+biName.left(biName.length()-2)+">";
4697 }
4698 if (!cd->isSubClass(baseClass) && cd!=baseClass && cd->isBaseClass(baseClass,true,templSpec)==0) // check for recursion
4699 {
4700 // add base class to this class
4701 cd->insertBaseClass(baseClass,biName,bi->prot,bi->virt,templSpec);
4702 // add this class as super class to the base class
4703 baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
4704 }
4705 // the undocumented base was found in this file
4706 baseClass->insertUsedFile(root->fileDef());
4707
4708 Definition *scope = buildScopeFromQualifiedName(baseClass->name(),root->lang,nullptr);
4709 if (scope!=baseClass)
4710 {
4711 baseClass->setOuterScope(scope);
4712 }
4713
4714 if (baseClassName.endsWith("-p"))
4715 {
4717 }
4718 return TRUE;
4719 }
4720 else
4721 {
4722 AUTO_TRACE_ADD("Base class '{}' not created (alias?)",biName);
4723 }
4724 }
4725 else
4726 {
4727 AUTO_TRACE_ADD("Base class '{}' not found",biName);
4728 }
4729 }
4730 else
4731 {
4732 if (mode!=TemplateInstances)
4733 {
4734 warn(root->fileName,root->startLine,
4735 "Detected potential recursive class relation "
4736 "between class %s and base class %s!",
4737 qPrint(root->name),qPrint(baseClassName)
4738 );
4739 }
4740 // for mode==TemplateInstance this case is quite common and
4741 // indicates a relation between a template class and a template
4742 // instance with the same name.
4743 }
4744 if (scopeOffset==0)
4745 {
4746 scopeOffset=-1;
4747 }
4748 else if ((scopeOffset=scopeName.findRev("::",scopeOffset-1))==-1)
4749 {
4750 scopeOffset=0;
4751 }
4752 //printf("new scopeOffset='%d'",scopeOffset);
4753 } while (scopeOffset>=0);
4754
4755 if (parentNode==nullptr)
4756 {
4757 lastParent=TRUE;
4758 }
4759 else
4760 {
4761 parentNode=parentNode->parent();
4762 }
4763 } while (lastParent);
4764
4765 return FALSE;
4766}
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 isCSharp() const =0
Returns TRUE if this class is implemented in C#.
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 StringUnorderedMap namespaceAliasMap
Definition doxygen.h:103
Represents an unstructured piece of information, about an entity found in the sources.
Definition entry.h:115
void clear()
Definition qcstring.h:162
static int findEndOfTemplate(const QCString &s, size_t startPos)
Definition doxygen.cpp:4337
static bool isRecursiveBaseClass(const QCString &scope, const QCString &name)
Definition doxygen.cpp:4312
static void findTemplateInstanceRelation(const Entry *root, Definition *context, ClassDefMutable *templateClass, const QCString &templSpec, const TemplateNameMap &templateNames, bool isArtificial)
Definition doxygen.cpp:4263
static ClassDef * findClassWithinClassContext(Definition *context, ClassDef *cd, const QCString &name)
Definition doxygen.cpp:4015
static int findTemplateSpecializationPosition(const QCString &name)
Definition doxygen.cpp:4403
Protection prot
inheritance type
Definition entry.h:94
Specifier virt
virtualness
Definition entry.h:95
Protection
Protection level of members.
Definition types.h:26
bool found
Definition util.cpp:983
void replaceNamespaceAliases(QCString &scope, size_t i)
Definition util.cpp:5198

References AUTO_TRACE, AUTO_TRACE_ADD, buildScopeFromQualifiedName(), ClassDef::Class, Doxygen::classLinkedMap, QCString::clear(), Config_getBool, createClassDef(), DocumentedOnly, end(), QCString::endsWith(), FALSE, Entry::fileDef(), Entry::fileName, findClassWithinClassContext(), findEndOfTemplate(), QCString::findRev(), findScopeFromQualifiedName(), findTemplateInstanceRelation(), findTemplateSpecializationPosition(), found, getClassMutable(), ClassDef::getFileDef(), SymbolResolver::getTemplateSpec(), SymbolResolver::getTypedef(), Doxygen::globalScope, Doxygen::hiddenClassLinkedMap, IDL, ClassDefMutable::insertBaseClass(), ClassDefMutable::insertSubClass(), ClassDefMutable::insertUsedFile(), Definition::isArtificial(), ClassDef::isBaseClass(), ClassDef::isCSharp(), QCString::isEmpty(), isRecursiveBaseClass(), ClassDef::isSubClass(), Entry::lang, QCString::left(), QCString::length(), QCString::mid(), BaseInfo::name, Definition::name(), Entry::name, Doxygen::namespaceAliasMap, Entry::parent(), QCString::prepend(), BaseInfo::prot, ClassDef::Protocol, Public, qPrint(), 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 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 4015 of file doxygen.cpp.

4016{
4017 ClassDef *result=nullptr;
4018 if (cd==nullptr)
4019 {
4020 return result;
4021 }
4022 FileDef *fd=cd->getFileDef();
4023 SymbolResolver resolver(fd);
4024 if (context && cd!=context)
4025 {
4026 result = const_cast<ClassDef*>(resolver.resolveClass(context,name,true,true));
4027 }
4028 //printf("1. result=%p\n",result);
4029 if (result==nullptr)
4030 {
4031 result = const_cast<ClassDef*>(resolver.resolveClass(cd,name,true,true));
4032 }
4033 //printf("2. result=%p\n",result);
4034 if (result==nullptr) // try direct class, needed for namespaced classes imported via tag files (see bug624095)
4035 {
4036 result = getClass(name);
4037 }
4038 //printf("3. result=%p\n",result);
4039 //printf("** Trying to find %s within context %s class %s result=%s lookup=%p\n",
4040 // qPrint(name),
4041 // context ? qPrint(context->name()) : "<none>",
4042 // cd ? qPrint(cd->name()) : "<none>",
4043 // result ? qPrint(result->name()) : "<none>",
4044 // Doxygen::classLinkedMap->find(name)
4045 // );
4046 return result;
4047}

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

Referenced by findClassRelation(), and findUsedClassesForClass().

◆ findDefineDocumentation()

static void findDefineDocumentation ( Entry * root)
static

Definition at line 8953 of file doxygen.cpp.

8954{
8955 if ((root->section.isDefineDoc() || root->section.isDefine()) && !root->name.isEmpty())
8956 {
8957 //printf("found define '%s' '%s' brief='%s' doc='%s'\n",
8958 // qPrint(root->name),qPrint(root->args),qPrint(root->brief),qPrint(root->doc));
8959
8960 if (root->tagInfo() && !root->name.isEmpty()) // define read from a tag file
8961 {
8962 auto md = createMemberDef(root->tagInfo()->tagName,1,1,
8963 "#define",root->name,root->args,QCString(),
8965 ArgumentList(),ArgumentList(),"");
8966 auto mmd = toMemberDefMutable(md.get());
8967 mmd->setTagInfo(root->tagInfo());
8968 mmd->setLanguage(root->lang);
8969 //printf("Searching for '%s' fd=%p\n",qPrint(filePathName),fd);
8970 mmd->setFileDef(root->parent()->fileDef());
8971 //printf("Adding member=%s\n",qPrint(md->name()));
8973 mn->push_back(std::move(md));
8974 }
8976 if (mn)
8977 {
8978 int count=0;
8979 for (const auto &md : *mn)
8980 {
8981 if (md->memberType()==MemberType_Define) count++;
8982 }
8983 if (count==1)
8984 {
8985 for (const auto &imd : *mn)
8986 {
8987 MemberDefMutable *md = toMemberDefMutable(imd.get());
8988 if (md && md->memberType()==MemberType_Define)
8989 {
8990 addDefineDoc(root,md);
8991 }
8992 }
8993 }
8994 else if (count>1 &&
8995 (!root->doc.isEmpty() ||
8996 !root->brief.isEmpty() ||
8997 root->bodyLine!=-1
8998 )
8999 )
9000 // multiple defines don't know where to add docs
9001 // but maybe they are in different files together with their documentation
9002 {
9003 for (const auto &imd : *mn)
9004 {
9005 MemberDefMutable *md = toMemberDefMutable(imd.get());
9006 if (md && md->memberType()==MemberType_Define)
9007 {
9008 if (haveEqualFileNames(root, md) || isEntryInGroupOfMember(root, md))
9009 // doc and define in the same file or group assume they belong together.
9010 {
9011 addDefineDoc(root,md);
9012 }
9013 }
9014 }
9015 //warn("define %s found in the following files:\n",qPrint(root->name));
9016 //warn("Cannot determine where to add the documentation found "
9017 // "at line %d of file %s. \n",
9018 // root->startLine,qPrint(root->fileName));
9019 }
9020 }
9021 else if (!root->doc.isEmpty() || !root->brief.isEmpty()) // define not found
9022 {
9023 bool preEnabled = Config_getBool(ENABLE_PREPROCESSING);
9024 if (preEnabled)
9025 {
9026 warn(root->fileName,root->startLine,
9027 "documentation for unknown define %s found.",
9028 qPrint(root->name)
9029 );
9030 }
9031 else
9032 {
9033 warn(root->fileName,root->startLine,
9034 "found documented #define %s but ignoring it because "
9035 "ENABLE_PREPROCESSING is NO.",
9036 qPrint(root->name)
9037 );
9038 }
9039 }
9040 }
9041 for (const auto &e : root->children()) findDefineDocumentation(e.get());
9042}
static void findDefineDocumentation(Entry *root)
Definition doxygen.cpp:8953
static void addDefineDoc(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:8928
static bool haveEqualFileNames(const Entry *root, const MemberDef *md)
Definition doxygen.cpp:8915
static bool isEntryInGroupOfMember(const Entry *root, const MemberDef *md, bool allowNoGroup=false)
Definition doxygen.cpp:5232

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addDefineDoc(), Entry::args, Entry::bodyLine, Entry::brief, Entry::children(), Config_getBool, createMemberDef(), Entry::doc, FALSE, Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), findDefineDocumentation(), Doxygen::functionNameLinkedMap, haveEqualFileNames(), QCString::isEmpty(), isEntryInGroupOfMember(), Entry::lang, Member, MemberDef::memberType(), MemberType_Define, Entry::name, Normal, Entry::parent(), Public, MemberName::push_back(), qPrint(), Entry::section, MemberDefMutable::setFileDef(), DefinitionMutable::setLanguage(), MemberDefMutable::setTagInfo(), 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 7540 of file doxygen.cpp.

7541{
7542 // for each member name
7543 for (const auto &mn : mnsd)
7544 {
7545 // for each member definition
7546 for (const auto &imd : *mn)
7547 {
7548 MemberDefMutable *md = toMemberDefMutable(imd.get());
7549 if (md && md->isEnumerate()) // member is an enum
7550 {
7551 int documentedEnumValues=0;
7552 // for each enum value
7553 for (const auto &fmd : md->enumFieldList())
7554 {
7555 if (fmd->isLinkableInProject()) documentedEnumValues++;
7556 }
7557 // at least one enum value is documented
7558 if (documentedEnumValues>0) md->setDocumentedEnumValues(TRUE);
7559 }
7560 }
7561 }
7562}
virtual void setDocumentedEnumValues(bool value)=0

References MemberDef::enumFieldList(), MemberDef::isEnumerate(), Definition::isLinkableInProject(), MemberDefMutable::setDocumentedEnumValues(), toMemberDefMutable(), and TRUE.

Referenced by findDocumentedEnumValues().

◆ findDirDocumentation()

static void findDirDocumentation ( const Entry * root)
static

Definition at line 9046 of file doxygen.cpp.

9047{
9048 if (root->section.isDirDoc())
9049 {
9050 QCString normalizedName = root->name;
9051 normalizedName = substitute(normalizedName,"\\","/");
9052 //printf("root->docFile=%s normalizedName=%s\n",
9053 // qPrint(root->docFile),qPrint(normalizedName));
9054 if (root->docFile==normalizedName) // current dir?
9055 {
9056 int lastSlashPos=normalizedName.findRev('/');
9057 if (lastSlashPos!=-1) // strip file name
9058 {
9059 normalizedName=normalizedName.left(lastSlashPos);
9060 }
9061 }
9062 if (normalizedName.at(normalizedName.length()-1)!='/')
9063 {
9064 normalizedName+='/';
9065 }
9066 DirDef *matchingDir=nullptr;
9067 for (const auto &dir : *Doxygen::dirLinkedMap)
9068 {
9069 //printf("Dir: %s<->%s\n",qPrint(dir->name()),qPrint(normalizedName));
9070 if (dir->name().right(normalizedName.length())==normalizedName)
9071 {
9072 if (matchingDir)
9073 {
9074 warn(root->fileName,root->startLine,
9075 "\\dir command matches multiple directories.\n"
9076 " Applying the command for directory %s\n"
9077 " Ignoring the command for directory %s",
9078 qPrint(matchingDir->name()),qPrint(dir->name())
9079 );
9080 }
9081 else
9082 {
9083 matchingDir=dir.get();
9084 }
9085 }
9086 }
9087 if (matchingDir)
9088 {
9089 //printf("Match for with dir %s\n",qPrint(matchingDir->name()));
9090 matchingDir->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9091 matchingDir->setDocumentation(root->doc,root->docFile,root->docLine);
9092 matchingDir->setRefItems(root->sli);
9093 root->commandOverrides.apply_directoryGraph([&](bool b) { matchingDir->overrideDirectoryGraph(b); });
9094 addDirToGroups(root,matchingDir);
9095 }
9096 else
9097 {
9098 warn(root->fileName,root->startLine,"No matching "
9099 "directory found for command \\dir %s",qPrint(normalizedName));
9100 }
9101 }
9102 for (const auto &e : root->children()) findDirDocumentation(e.get());
9103}
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:9046
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(), qPrint(), 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 7566 of file doxygen.cpp.

7567{
7570}
static void findDEV(const MemberNameLinkedMap &mnsd)
Definition doxygen.cpp:7540

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

Referenced by parseInput().

◆ findEndOfTemplate()

static int findEndOfTemplate ( const QCString & s,
size_t startPos )
static

Searches for the end of a template in prototype s starting from character position startPos. If the end was found the position of the closing > is returned, otherwise -1 is returned.

Handles exotic cases such as

Definition at line 4337 of file doxygen.cpp.

4338{
4339 // locate end of template
4340 size_t e=startPos;
4341 int brCount=1;
4342 int roundCount=0;
4343 size_t len = s.length();
4344 bool insideString=FALSE;
4345 bool insideChar=FALSE;
4346 char pc = 0;
4347 while (e<len && brCount!=0)
4348 {
4349 char c=s.at(e);
4350 switch(c)
4351 {
4352 case '<':
4353 if (!insideString && !insideChar)
4354 {
4355 if (e<len-1 && s.at(e+1)=='<')
4356 e++;
4357 else if (roundCount==0)
4358 brCount++;
4359 }
4360 break;
4361 case '>':
4362 if (!insideString && !insideChar)
4363 {
4364 if (e<len-1 && s.at(e+1)=='>')
4365 e++;
4366 else if (roundCount==0)
4367 brCount--;
4368 }
4369 break;
4370 case '(':
4371 if (!insideString && !insideChar)
4372 roundCount++;
4373 break;
4374 case ')':
4375 if (!insideString && !insideChar)
4376 roundCount--;
4377 break;
4378 case '"':
4379 if (!insideChar)
4380 {
4381 if (insideString && pc!='\\')
4382 insideString=FALSE;
4383 else
4384 insideString=TRUE;
4385 }
4386 break;
4387 case '\'':
4388 if (!insideString)
4389 {
4390 if (insideChar && pc!='\\')
4391 insideChar=FALSE;
4392 else
4393 insideChar=TRUE;
4394 }
4395 break;
4396 }
4397 pc = c;
4398 e++;
4399 }
4400 return brCount==0 ? static_cast<int>(e) : -1;
4401}

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

Referenced by findClassRelation().

◆ findEnumDocumentation()

static void findEnumDocumentation ( const Entry * root)
static

Definition at line 7451 of file doxygen.cpp.

7452{
7453 if (root->section.isEnumDoc() &&
7454 !root->name.isEmpty() &&
7455 root->name.at(0)!='@' // skip anonymous enums
7456 )
7457 {
7458 QCString name;
7459 QCString scope;
7460 int i = root->name.findRev("::");
7461 if (i!=-1) // scope is specified as part of the name
7462 {
7463 name=root->name.right(root->name.length()-i-2); // extract name
7464 scope=root->name.left(i); // extract scope
7465 //printf("Scope='%s' Name='%s'\n",qPrint(scope),qPrint(name));
7466 }
7467 else // just the name
7468 {
7469 name=root->name;
7470 }
7471 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7472 {
7473 if (!scope.isEmpty()) scope.prepend("::");
7474 scope.prepend(root->parent()->name);
7475 }
7476 const ClassDef *cd = getClass(scope);
7478 const FileDef *fd = root->fileDef();
7479 AUTO_TRACE("Found docs for enum with name '{}' and scope '{}' in context '{}' cd='{}', nd='{}' fd='{}'",
7480 name,scope,root->parent()->name,
7481 cd ? cd->name() : QCString("<none>"),
7482 nd ? nd->name() : QCString("<none>"),
7483 fd ? fd->name() : QCString("<none>"));
7484
7485 if (!name.isEmpty())
7486 {
7487 bool found = tryAddEnumDocsToGroupMember(root, name);
7488 if (!found)
7489 {
7491 if (mn)
7492 {
7493 for (const auto &imd : *mn)
7494 {
7495 MemberDefMutable *md = toMemberDefMutable(imd.get());
7496 if (md && md->isEnumerate())
7497 {
7498 const ClassDef *mcd = md->getClassDef();
7499 const NamespaceDef *mnd = md->getNamespaceDef();
7500 const FileDef *mfd = md->getFileDef();
7501 if (cd && mcd==cd)
7502 {
7503 AUTO_TRACE_ADD("Match found for class scope");
7504 addEnumDocs(root,md);
7505 found = TRUE;
7506 break;
7507 }
7508 else if (cd==nullptr && mcd==nullptr && nd!=nullptr && mnd==nd)
7509 {
7510 AUTO_TRACE_ADD("Match found for namespace scope");
7511 addEnumDocs(root,md);
7512 found = TRUE;
7513 break;
7514 }
7515 else if (cd==nullptr && nd==nullptr && mcd==nullptr && mnd==nullptr && fd==mfd)
7516 {
7517 AUTO_TRACE_ADD("Match found for global scope");
7518 addEnumDocs(root,md);
7519 found = TRUE;
7520 break;
7521 }
7522 }
7523 }
7524 }
7525 }
7526 if (!found)
7527 {
7528 warn(root->fileName,root->startLine,
7529 "Documentation for undefined enum '%s' found.",
7530 qPrint(name)
7531 );
7532 }
7533 }
7534 }
7535 for (const auto &e : root->children()) findEnumDocumentation(e.get());
7536}
static bool tryAddEnumDocsToGroupMember(const Entry *root, const QCString &name)
Definition doxygen.cpp:7418
static void addEnumDocs(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:7377
static void findEnumDocumentation(const Entry *root)
Definition doxygen.cpp:7451

References addEnumDocs(), QCString::at(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::children(), Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), 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(), qPrint(), 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 6977 of file doxygen.cpp.

6978{
6979 if (root->section.isEnum())
6980 {
6981 ClassDefMutable *cd = nullptr;
6982 FileDef *fd = nullptr;
6983 NamespaceDefMutable *nd = nullptr;
6984 MemberNameLinkedMap *mnsd = nullptr;
6985 bool isGlobal = false;
6986 bool isRelated = false;
6987 bool isMemberOf = false;
6988 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
6989
6990 QCString name;
6991 QCString scope;
6992
6993 int i = root->name.findRev("::");
6994 if (i!=-1) // scope is specified
6995 {
6996 scope=root->name.left(i); // extract scope
6997 name=root->name.right(root->name.length()-i-2); // extract name
6998 if ((cd=getClassMutable(scope))==nullptr)
6999 {
7001 }
7002 }
7003 else // no scope, check the scope in which the docs where found
7004 {
7005 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7006 {
7007 scope=root->parent()->name;
7008 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7009 }
7010 name=root->name;
7011 }
7012
7013 if (!root->relates.isEmpty())
7014 { // related member, prefix user specified scope
7015 isRelated=TRUE;
7016 isMemberOf=(root->relatesType==RelatesType::MemberOf);
7017 if (getClass(root->relates)==nullptr && !scope.isEmpty())
7018 scope=mergeScopes(scope,root->relates);
7019 else
7020 scope=root->relates;
7021 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7022 }
7023
7024 if (cd && !name.isEmpty()) // found a enum inside a compound
7025 {
7026 //printf("Enum '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
7027 fd=nullptr;
7029 isGlobal=false;
7030 }
7031 else if (nd) // found enum inside namespace
7032 {
7034 isGlobal=true;
7035 }
7036 else // found a global enum
7037 {
7038 fd=root->fileDef();
7040 isGlobal=true;
7041 }
7042
7043 if (!name.isEmpty())
7044 {
7045 // new enum type
7046 auto md = createMemberDef(
7047 root->fileName,root->startLine,root->startColumn,
7048 QCString(),name,QCString(),QCString(),
7050 isMemberOf ? Relationship::Foreign : isRelated ? Relationship::Related : Relationship::Member,
7052 ArgumentList(),ArgumentList(),root->metaData);
7053 auto mmd = toMemberDefMutable(md.get());
7054 mmd->setTagInfo(root->tagInfo());
7055 mmd->setLanguage(root->lang);
7056 mmd->setId(root->id);
7057 if (!isGlobal) mmd->setMemberClass(cd); else mmd->setFileDef(fd);
7058 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
7059 mmd->setBodyDef(root->fileDef());
7060 mmd->setMemberSpecifiers(root->spec);
7061 mmd->setVhdlSpecifiers(root->vhdlSpec);
7062 mmd->setEnumBaseType(root->args);
7063 //printf("Enum %s definition at line %d of %s: protection=%d scope=%s\n",
7064 // qPrint(root->name),root->bodyLine,qPrint(root->fileName),root->protection,cd?qPrint(cd->name()):"<none>");
7065 mmd->addSectionsToDefinition(root->anchors);
7066 mmd->setMemberGroupId(root->mGrpId);
7068 mmd->addQualifiers(root->qualifiers);
7069 //printf("%s::setRefItems(%zu)\n",qPrint(md->name()),root->sli.size());
7070 mmd->setRefItems(root->sli);
7071 //printf("found enum %s nd=%p\n",qPrint(md->name()),nd);
7072 bool defSet=FALSE;
7073
7074 QCString baseType = root->args;
7075 if (!baseType.isEmpty())
7076 {
7077 baseType.prepend(" : ");
7078 }
7079
7080 if (nd)
7081 {
7082 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES))
7083 {
7084 mmd->setDefinition(name+baseType);
7085 }
7086 else
7087 {
7088 mmd->setDefinition(nd->name()+"::"+name+baseType);
7089 }
7090 //printf("definition=%s\n",md->definition());
7091 defSet=TRUE;
7092 mmd->setNamespace(nd);
7093 nd->insertMember(md.get());
7094 }
7095
7096 // even if we have already added the enum to a namespace, we still
7097 // also want to add it to other appropriate places such as file
7098 // or class.
7099 if (isGlobal && (nd==nullptr || !nd->isAnonymous()))
7100 {
7101 if (!defSet) mmd->setDefinition(name+baseType);
7102 if (fd==nullptr && root->parent())
7103 {
7104 fd=root->parent()->fileDef();
7105 }
7106 if (fd)
7107 {
7108 mmd->setFileDef(fd);
7109 fd->insertMember(md.get());
7110 }
7111 }
7112 else if (cd)
7113 {
7114 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES))
7115 {
7116 mmd->setDefinition(name+baseType);
7117 }
7118 else
7119 {
7120 mmd->setDefinition(cd->name()+"::"+name+baseType);
7121 }
7122 cd->insertMember(md.get());
7123 cd->insertUsedFile(fd);
7124 }
7125 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
7126 mmd->setDocsForDefinition(!root->proto);
7127 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7128 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
7129
7130 //printf("Adding member=%s\n",qPrint(md->name()));
7131 addMemberToGroups(root,md.get());
7133
7134 MemberName *mn = mnsd->add(name);
7135 mn->push_back(std::move(md));
7136 }
7137 }
7138 else
7139 {
7140 for (const auto &e : root->children()) findEnums(e.get());
7141 }
7142}
RelatesType relatesType
how relates is handled
Definition entry.h:209
static void findEnums(const Entry *root)
Definition doxygen.cpp:6977
@ MemberType_Enumeration
Definition types.h:286

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addMemberToGroups(), ModuleManager::addMemberToModule(), Entry::anchors, applyMemberOverrideOptions(), Entry::args, Entry::bodyLine, Entry::brief, Entry::briefFile, Entry::briefLine, buildScopeFromQualifiedName(), Entry::children(), Config_getBool, createMemberDef(), Entry::doc, Entry::docFile, Entry::docLine, Entry::endBodyLine, 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(), Member, Doxygen::memberNameLinkedMap, MemberOf, MemberType_Enumeration, 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().

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

2571{
2572 AUTO_TRACE("type='{}' lang={}",type,lang);
2573 if (lang == SrcLangExt::Fortran || lang == SrcLangExt::VHDL)
2574 {
2575 return -1; // Fortran and VHDL do not have function pointers
2576 }
2577
2578 static const reg::Ex re(R"(\‍([^)]*[*&^][^)]*\))");
2580 size_t i=std::string::npos;
2581 size_t l=0;
2582 if (reg::search(type,match,re)) // contains (...*...) or (...&...) or (...^...)
2583 {
2584 i = match.position();
2585 l = match.length();
2586 }
2587 if (i!=std::string::npos)
2588 {
2589 size_t di = type.find("decltype(");
2590 if (di!=std::string::npos && di<i)
2591 {
2592 i = std::string::npos;
2593 }
2594 }
2595 size_t bb=type.find('<');
2596 size_t be=type.rfind('>');
2597 bool templFp = false;
2598 if (be!=std::string::npos) {
2599 size_t cc_ast = type.find("::*");
2600 size_t cc_amp = type.find("::&");
2601 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>::*)'
2602 }
2603
2604 if (!type.empty() && // return type is non-empty
2605 i!=std::string::npos && // contains (...*...)
2606 type.find("operator")==std::string::npos && // not an operator
2607 (type.find(")(")==std::string::npos || type.find("typedef ")!=std::string::npos) &&
2608 // not a function pointer return type
2609 (!(bb<i && i<be) || templFp) // bug665855: avoid treating "typedef A<void (T*)> type" as a function pointer
2610 )
2611 {
2612 if (pLength) *pLength=static_cast<int>(l);
2613 //printf("findFunctionPtr=%d\n",(int)i);
2614 AUTO_TRACE_EXIT("result={}",i);
2615 return static_cast<int>(i);
2616 }
2617 else
2618 {
2619 //printf("findFunctionPtr=%d\n",-1);
2620 AUTO_TRACE_EXIT("result=-1");
2621 return -1;
2622 }
2623}
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:48

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

Referenced by 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 5256 of file doxygen.cpp.

5264{
5265 AUTO_TRACE("namespace='{}' type='{}' name='{}' tempArg='{}' decl='{}'",namespaceName,type,name,tempArg,decl);
5266 QCString n=name;
5267 if (n.isEmpty()) return FALSE;
5268 if (n.find("::")!=-1) return FALSE; // skip undefined class members
5269 MemberName *mn=Doxygen::functionNameLinkedMap->find(n+tempArg); // look in function dictionary
5270 if (mn==nullptr)
5271 {
5272 mn=Doxygen::functionNameLinkedMap->find(n); // try without template arguments
5273 }
5274 if (mn) // function name defined
5275 {
5276 AUTO_TRACE_ADD("Found symbol name");
5277 //int count=0;
5278 bool found=FALSE;
5279 for (const auto &md : *mn)
5280 {
5281 // If the entry has groups, then restrict the search to members which are
5282 // in one of the groups of the entry. If md is not associated with a group yet,
5283 // allow this documentation entry to add the group info.
5284 if (!root->groups.empty() && !isEntryInGroupOfMember(root, md.get(), true))
5285 {
5286 continue;
5287 }
5288
5289 const NamespaceDef *nd=nullptr;
5290 if (md->isAlias() && md->getOuterScope() &&
5291 md->getOuterScope()->definitionType()==Definition::TypeNamespace)
5292 {
5293 nd = toNamespaceDef(md->getOuterScope());
5294 }
5295 else
5296 {
5297 nd = md->getNamespaceDef();
5298 }
5299
5300 // special case for strong enums
5301 int enumNamePos=0;
5302 if (nd && md->isEnumValue() && (enumNamePos=namespaceName.findRev("::"))!=-1)
5303 { // md part of a strong enum in a namespace?
5304 QCString enumName = namespaceName.mid(enumNamePos+2);
5305 if (namespaceName.left(enumNamePos)==nd->name())
5306 {
5308 if (enumMn)
5309 {
5310 for (const auto &emd : *enumMn)
5311 {
5312 found = emd->isStrong() && md->getEnumScope()==emd.get();
5313 if (found)
5314 {
5315 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,nullptr,FALSE,root->spec);
5316 break;
5317 }
5318 }
5319 }
5320 }
5321 if (found)
5322 {
5323 break;
5324 }
5325 }
5326 else if (nd==nullptr && md->isEnumValue()) // md part of global strong enum?
5327 {
5328 MemberName *enumMn=Doxygen::functionNameLinkedMap->find(namespaceName);
5329 if (enumMn)
5330 {
5331 for (const auto &emd : *enumMn)
5332 {
5333 found = emd->isStrong() && md->getEnumScope()==emd.get();
5334 if (found)
5335 {
5336 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,nullptr,FALSE,root->spec);
5337 break;
5338 }
5339 }
5340 }
5341 }
5342
5343 const FileDef *fd=root->fileDef();
5344 //printf("File %s\n",fd ? qPrint(fd->name()) : "<none>");
5346 if (fd)
5347 {
5348 nl = fd->getUsedNamespaces();
5349 }
5350 //printf("NamespaceList %p\n",nl);
5351
5352 // search in the list of namespaces that are imported via a
5353 // using declaration
5354 bool viaUsingDirective = nd && nl.find(nd->qualifiedName())!=nullptr;
5355
5356 if ((namespaceName.isEmpty() && nd==nullptr) || // not in a namespace
5357 (nd && nd->name()==namespaceName) || // or in the same namespace
5358 viaUsingDirective // member in 'using' namespace
5359 )
5360 {
5361 AUTO_TRACE_ADD("Try to add member '{}' to scope '{}'",md->name(),namespaceName);
5362
5363 NamespaceDef *rnd = nullptr;
5364 if (!namespaceName.isEmpty()) rnd = Doxygen::namespaceLinkedMap->find(namespaceName);
5365
5366 const ArgumentList &mdAl = const_cast<const MemberDef *>(md.get())->argumentList();
5367 bool matching=
5368 (mdAl.empty() && root->argList.empty()) ||
5369 md->isVariable() || md->isTypedef() || /* in case of function pointers */
5370 matchArguments2(md->getOuterScope(),const_cast<const MemberDef *>(md.get())->getFileDef(),&mdAl,
5371 rnd ? rnd : Doxygen::globalScope,fd,&root->argList,
5372 FALSE,root->lang);
5373
5374 // for template members we need to check if the number of
5375 // template arguments is the same, otherwise we are dealing with
5376 // different functions.
5377 if (matching && !root->tArgLists.empty())
5378 {
5379 const ArgumentList &mdTempl = md->templateArguments();
5380 if (root->tArgLists.back().size()!=mdTempl.size())
5381 {
5382 matching=FALSE;
5383 }
5384 }
5385
5386 //printf("%s<->%s\n",
5387 // qPrint(argListToString(md->argumentList())),
5388 // qPrint(argListToString(root->argList)));
5389
5390 // For static members we also check if the comment block was found in
5391 // the same file. This is needed because static members with the same
5392 // name can be in different files. Thus it would be wrong to just
5393 // put the comment block at the first syntactically matching member. If
5394 // the comment block belongs to a group of the static member, then add
5395 // the documentation even if it is in a different file.
5396 if (matching && md->isStatic() &&
5397 md->getDefFileName()!=root->fileName &&
5398 mn->size()>1 &&
5399 !isEntryInGroupOfMember(root,md.get()))
5400 {
5401 matching = FALSE;
5402 }
5403
5404 // for template member we also need to check the return type and requires
5405 if (!md->templateArguments().empty() && !root->tArgLists.empty())
5406 {
5407 //printf("Comparing return types '%s'<->'%s'\n",
5408 // md->typeString(),type);
5409 if (md->templateArguments().size()!=root->tArgLists.back().size() ||
5410 md->typeString()!=type ||
5411 md->requiresClause()!=root->req)
5412 {
5413 //printf(" ---> no matching\n");
5414 matching = FALSE;
5415 }
5416 }
5417
5418 if (matching) // add docs to the member
5419 {
5420 AUTO_TRACE_ADD("Match found");
5421 addMemberDocs(root,toMemberDefMutable(md->resolveAlias()),decl,&root->argList,FALSE,root->spec);
5422 found=TRUE;
5423 break;
5424 }
5425 }
5426 }
5427 if (!found && root->relatesType!=RelatesType::Duplicate && root->section.isFunction()) // no match
5428 {
5429 QCString fullFuncDecl=decl;
5430 if (!root->argList.empty()) fullFuncDecl+=argListToString(root->argList,TRUE);
5431 QCString warnMsg =
5432 QCString("no matching file member found for \n")+substitute(fullFuncDecl,"%","%%");
5433 if (mn->size()>0)
5434 {
5435 warnMsg+="\nPossible candidates:";
5436 for (const auto &md : *mn)
5437 {
5438 warnMsg+="\n '";
5439 warnMsg+=substitute(md->declaration(),"%","%%");
5440 warnMsg+="' " + warn_line(md->getDefFileName(),md->getDefLine());
5441 }
5442 }
5443 warn(root->fileName,root->startLine, "%s", qPrint(warnMsg));
5444 }
5445 }
5446 else // got docs for an undefined member!
5447 {
5448 if (root->type!="friend class" &&
5449 root->type!="friend struct" &&
5450 root->type!="friend union" &&
5451 root->type!="friend" &&
5452 (!Config_getBool(TYPEDEF_HIDES_STRUCT) ||
5453 root->type.find("typedef ")==-1)
5454 )
5455 {
5456 warn(root->fileName,root->startLine,
5457 "documented symbol '%s' was not declared or defined.",qPrint(decl)
5458 );
5459 }
5460 }
5461 return TRUE;
5462}
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
find an object given the key.
Definition linkedmap.h:243

References addMemberDocs(), Entry::argList, argListToString(), AUTO_TRACE, AUTO_TRACE_ADD, Config_getBool, MemberDef::declaration(), Definition::definitionType(), Duplicate, ArgumentList::empty(), FALSE, Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), LinkedRefMap< T, Hash, KeyEqual, Map >::find(), QCString::find(), QCString::findRev(), found, Doxygen::functionNameLinkedMap, Definition::getDefFileName(), Definition::getDefLine(), MemberDef::getEnumScope(), MemberDef::getFileDef(), MemberDef::getNamespaceDef(), Definition::getOuterScope(), FileDef::getUsedNamespaces(), Doxygen::globalScope, Entry::groups, Definition::isAlias(), QCString::isEmpty(), isEntryInGroupOfMember(), MemberDef::isEnumValue(), MemberDef::isStatic(), MemberDef::isTypedef(), MemberDef::isVariable(), Entry::lang, QCString::left(), matchArguments2(), QCString::mid(), Definition::name(), Doxygen::namespaceLinkedMap, qPrint(), Definition::qualifiedName(), Entry::relatesType, Entry::req, MemberDef::requiresClause(), MemberDef::resolveAlias(), Entry::section, ArgumentList::size(), MemberName::size(), Entry::spec, Entry::startLine, substitute(), Entry::tArgLists, MemberDef::templateArguments(), toMemberDefMutable(), toNamespaceDef(), TRUE, Entry::type, Definition::TypeNamespace, MemberDef::typeString(), warn, and warn_line().

Referenced by findMember().

◆ findGroupScope()

static void findGroupScope ( const Entry * root)
static

Definition at line 426 of file doxygen.cpp.

427{
428 if (root->section.isGroupDoc() && !root->name.isEmpty() &&
429 root->parent() && !root->parent()->name.isEmpty())
430 {
432 if (gd)
433 {
434 QCString scope = root->parent()->name;
435 if (root->parent()->section.isPackageDoc())
436 {
437 scope=substitute(scope,".","::");
438 }
439 scope = stripAnonymousNamespaceScope(scope);
440 scope+="::"+gd->name();
442 if (d)
443 {
444 gd->setGroupScope(d);
445 }
446 }
447 }
448 for (const auto &e : root->children()) findGroupScope(e.get());
449}
virtual void setGroupScope(Definition *d)=0
static void findGroupScope(const Entry *root)
Definition doxygen.cpp:426

References Entry::children(), LinkedMap< T, Hash, KeyEqual, Map >::find(), 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 2164 of file doxygen.cpp.

2165{
2166 FileDefSet visitedFiles;
2167 // then recursively add using directives found in #include files
2168 // to files that have not been visited.
2169 for (const auto &fn : *Doxygen::inputNameLinkedMap)
2170 {
2171 for (const auto &fd : *fn)
2172 {
2173 //printf("----- adding using directives for file %s\n",qPrint(fd->name()));
2174 fd->addIncludedUsingDirectives(visitedFiles);
2175 }
2176 }
2177}
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 4823 of file doxygen.cpp.

4824{
4825 AUTO_TRACE();
4826 ClassDefSet visitedClasses;
4827 for (const auto &[name,root] : g_classEntries)
4828 {
4829 QCString bName = extractClassName(root);
4830 ClassDefMutable *cdm = getClassMutable(bName);
4831 if (cdm)
4832 {
4834 }
4835 }
4836}

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

Referenced by parseInput().

◆ findMainPage()

static void findMainPage ( Entry * root)
static

Definition at line 9136 of file doxygen.cpp.

9137{
9138 if (root->section.isMainpageDoc())
9139 {
9140 if (Doxygen::mainPage==nullptr && root->tagInfo()==nullptr)
9141 {
9142 //printf("mainpage: docLine=%d startLine=%d\n",root->docLine,root->startLine);
9143 //printf("Found main page! \n======\n%s\n=======\n",qPrint(root->doc));
9144 QCString title=root->args.stripWhiteSpace();
9145 if (title.isEmpty()) title = Config_getString(PROJECT_NAME);
9146 //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9147 QCString indexName="index";
9149 indexName, root->brief+root->doc+root->inbodyDocs,title);
9150 //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
9151 Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9152 Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1);
9153 Doxygen::mainPage->setFileName(indexName);
9154 Doxygen::mainPage->setLocalToc(root->localToc);
9156
9158 if (si)
9159 {
9160 if (!si->ref().isEmpty()) // we are from a tag file
9161 {
9162 // a page name is a label as well! but should no be double either
9164 Doxygen::mainPage->name(),
9165 indexName,
9166 root->startLine,
9167 Doxygen::mainPage->title(),
9169 0); // level 0
9170 }
9171 else if (si->lineNr() != -1)
9172 {
9173 warn(root->fileName,root->startLine,"multiple use of section label '%s' for main page, (first occurrence: %s, line %d)",
9174 qPrint(Doxygen::mainPage->name()),qPrint(si->fileName()),si->lineNr());
9175 }
9176 else
9177 {
9178 warn(root->fileName,root->startLine,"multiple use of section label '%s' for main page, (first occurrence: %s)",
9179 qPrint(Doxygen::mainPage->name()),qPrint(si->fileName()));
9180 }
9181 }
9182 else
9183 {
9184 // a page name is a label as well! but should no be double either
9186 Doxygen::mainPage->name(),
9187 indexName,
9188 root->startLine,
9189 Doxygen::mainPage->title(),
9191 0); // level 0
9192 }
9193 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9194 }
9195 else if (root->tagInfo()==nullptr)
9196 {
9197 warn(root->fileName,root->startLine,
9198 "found more than one \\mainpage comment block! (first occurrence: %s, line %d), Skipping current block!",
9199 qPrint(Doxygen::mainPage->docFile()),Doxygen::mainPage->getStartBodyLine());
9200 }
9201 }
9202 for (const auto &e : root->children()) findMainPage(e.get());
9203}
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())
Replace an existing section with a new one Return a non-owning pointer to the newly added section.
Definition section.h:154
SectionInfo * add(const SectionInfo &si)
Add a new section given the data of an existing section.
Definition section.h:138
static constexpr int Page
Definition section.h:31
static void findMainPage(Entry *root)
Definition doxygen.cpp:9136

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, qPrint(), 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 9206 of file doxygen.cpp.

9207{
9208 if (root->section.isMainpageDoc())
9209 {
9210 if (Doxygen::mainPage && root->tagInfo())
9211 {
9212 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9213 }
9214 }
9215 for (const auto &e : root->children()) findMainPageTagFiles(e.get());
9216}
static void findMainPageTagFiles(Entry *root)
Definition doxygen.cpp:9206

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

6163{
6164 AUTO_TRACE("root='{}' funcDecl='{}' related='{}' overload={} isFunc={} mGrpId={} #tArgList={} spec={} lang={}",
6165 root->name, funcDecl, relates, overloaded, isFunc, root->mGrpId, root->tArgLists.size(),
6166 root->spec, root->lang);
6167
6168 QCString scopeName;
6169 QCString className;
6170 QCString namespaceName;
6171 QCString funcType;
6172 QCString funcName;
6173 QCString funcArgs;
6174 QCString funcTempList;
6175 QCString exceptions;
6176 QCString funcSpec;
6177 bool isRelated=false;
6178 bool isMemberOf=false;
6179 bool isFriend=false;
6180 bool done=false;
6181 TypeSpecifier spec = root->spec;
6182 while (!done)
6183 {
6184 done=true;
6185 if (funcDecl.stripPrefix("friend ")) // treat friends as related members
6186 {
6187 isFriend=true;
6188 done=false;
6189 }
6190 if (funcDecl.stripPrefix("inline "))
6191 {
6192 spec.setInline(true);
6193 done=false;
6194 }
6195 if (funcDecl.stripPrefix("explicit "))
6196 {
6197 spec.setExplicit(true);
6198 done=false;
6199 }
6200 if (funcDecl.stripPrefix("mutable "))
6201 {
6202 spec.setMutable(true);
6203 done=false;
6204 }
6205 if (funcDecl.stripPrefix("virtual "))
6206 {
6207 done=false;
6208 }
6209 }
6210
6211 // delete any ; from the function declaration
6212 int sep=0;
6213 while ((sep=funcDecl.find(';'))!=-1)
6214 {
6215 funcDecl=(funcDecl.left(sep)+funcDecl.right(funcDecl.length()-sep-1)).stripWhiteSpace();
6216 }
6217
6218 // make sure the first character is a space to simplify searching.
6219 if (!funcDecl.isEmpty() && funcDecl[0]!=' ') funcDecl.prepend(" ");
6220
6221 // remove some superfluous spaces
6222 funcDecl= substitute(
6223 substitute(
6224 substitute(funcDecl,"~ ","~"),
6225 ":: ","::"
6226 ),
6227 " ::","::"
6228 ).stripWhiteSpace();
6229
6230 //printf("funcDecl='%s'\n",qPrint(funcDecl));
6231 if (isFriend && funcDecl.startsWith("class "))
6232 {
6233 //printf("friend class\n");
6234 funcDecl=funcDecl.right(funcDecl.length()-6);
6235 funcName = funcDecl;
6236 }
6237 else if (isFriend && funcDecl.startsWith("struct "))
6238 {
6239 funcDecl=funcDecl.right(funcDecl.length()-7);
6240 funcName = funcDecl;
6241 }
6242 else
6243 {
6244 // extract information from the declarations
6245 parseFuncDecl(funcDecl,root->lang,scopeName,funcType,funcName,
6246 funcArgs,funcTempList,exceptions
6247 );
6248 }
6249
6250 // the class name can also be a namespace name, we decide this later.
6251 // if a related class name is specified and the class name could
6252 // not be derived from the function declaration, then use the
6253 // related field.
6254 AUTO_TRACE_ADD("scopeName='{}' className='{}' namespaceName='{}' funcType='{}' funcName='{}' funcArgs='{}'",
6255 scopeName,className,namespaceName,funcType,funcName,funcArgs);
6256 if (!relates.isEmpty())
6257 { // related member, prefix user specified scope
6258 isRelated=TRUE;
6259 isMemberOf=(root->relatesType == RelatesType::MemberOf);
6260 if (getClass(relates)==nullptr && !scopeName.isEmpty())
6261 {
6262 scopeName= mergeScopes(scopeName,relates);
6263 }
6264 else
6265 {
6266 scopeName = relates;
6267 }
6268 }
6269
6270 if (relates.isEmpty() && root->parent() &&
6271 (root->parent()->section.isScope() || root->parent()->section.isObjcImpl()) &&
6272 !root->parent()->name.isEmpty()) // see if we can combine scopeName
6273 // with the scope in which it was found
6274 {
6275 QCString joinedName = root->parent()->name+"::"+scopeName;
6276 if (!scopeName.isEmpty() &&
6277 (getClass(joinedName) || Doxygen::namespaceLinkedMap->find(joinedName)))
6278 {
6279 scopeName = joinedName;
6280 }
6281 else
6282 {
6283 scopeName = mergeScopes(root->parent()->name,scopeName);
6284 }
6285 }
6286 else // see if we can prefix a namespace or class that is used from the file
6287 {
6288 FileDef *fd=root->fileDef();
6289 if (fd)
6290 {
6291 for (const auto &fnd : fd->getUsedNamespaces())
6292 {
6293 QCString joinedName = fnd->name()+"::"+scopeName;
6294 if (Doxygen::namespaceLinkedMap->find(joinedName))
6295 {
6296 scopeName=joinedName;
6297 break;
6298 }
6299 }
6300 }
6301 }
6303 removeRedundantWhiteSpace(scopeName),false,&funcSpec,QCString(),false);
6304
6305 // funcSpec contains the last template specifiers of the given scope.
6306 // If this method does not have any template arguments or they are
6307 // empty while funcSpec is not empty we assume this is a
6308 // specialization of a method. If not, we clear the funcSpec and treat
6309 // this as a normal method of a template class.
6310 if (!(root->tArgLists.size()>0 &&
6311 root->tArgLists.front().size()==0
6312 )
6313 )
6314 {
6315 funcSpec.clear();
6316 }
6317
6318 // split scope into a namespace and a class part
6319 extractNamespaceName(scopeName,className,namespaceName,TRUE);
6320 AUTO_TRACE_ADD("scopeName='{}' className='{}' namespaceName='{}'",scopeName,className,namespaceName);
6321
6322 //namespaceName=removeAnonymousScopes(namespaceName);
6323 if (namespaceName.find('@')!=-1) return; // skip stuff in anonymous namespace...
6324
6325 //printf("namespaceName='%s' className='%s'\n",qPrint(namespaceName),qPrint(className));
6326 // merge class and namespace scopes again
6327 scopeName.clear();
6328 if (!namespaceName.isEmpty())
6329 {
6330 if (className.isEmpty())
6331 {
6332 scopeName=namespaceName;
6333 }
6334 else if (!relates.isEmpty() || // relates command with explicit scope
6335 !getClass(className)) // class name only exists in a namespace
6336 {
6337 scopeName=namespaceName+"::"+className;
6338 }
6339 else
6340 {
6341 scopeName=className;
6342 }
6343 }
6344 else if (!className.isEmpty())
6345 {
6346 scopeName=className;
6347 }
6348 //printf("new scope='%s'\n",qPrint(scopeName));
6349
6350 QCString tempScopeName=scopeName;
6351 ClassDefMutable *cd=getClassMutable(scopeName);
6352 if (cd)
6353 {
6354 if (funcSpec.isEmpty())
6355 {
6356 uint32_t argListIndex=0;
6357 tempScopeName=cd->qualifiedNameWithTemplateParameters(&root->tArgLists,&argListIndex);
6358 }
6359 else
6360 {
6361 tempScopeName=scopeName+funcSpec;
6362 }
6363 }
6364 //printf("scopeName=%s cd=%p root->tArgLists=%p result=%s\n",
6365 // qPrint(scopeName),cd,root->tArgLists,qPrint(tempScopeName));
6366
6367 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
6368 // rebuild the function declaration (needed to get the scope right).
6369 if (!scopeName.isEmpty() && !isRelated && !isFriend && !Config_getBool(HIDE_SCOPE_NAMES))
6370 {
6371 if (!funcType.isEmpty())
6372 {
6373 if (isFunc) // a function -> we use argList for the arguments
6374 {
6375 funcDecl=funcType+" "+tempScopeName+"::"+funcName+funcTempList;
6376 }
6377 else
6378 {
6379 funcDecl=funcType+" "+tempScopeName+"::"+funcName+funcArgs;
6380 }
6381 }
6382 else
6383 {
6384 if (isFunc) // a function => we use argList for the arguments
6385 {
6386 funcDecl=tempScopeName+"::"+funcName+funcTempList;
6387 }
6388 else // variable => add 'argument' list
6389 {
6390 funcDecl=tempScopeName+"::"+funcName+funcArgs;
6391 }
6392 }
6393 }
6394 else // build declaration without scope
6395 {
6396 if (!funcType.isEmpty()) // but with a type
6397 {
6398 if (isFunc) // function => omit argument list
6399 {
6400 funcDecl=funcType+" "+funcName+funcTempList;
6401 }
6402 else // variable => add 'argument' list
6403 {
6404 funcDecl=funcType+" "+funcName+funcArgs;
6405 }
6406 }
6407 else // no type
6408 {
6409 if (isFunc)
6410 {
6411 funcDecl=funcName+funcTempList;
6412 }
6413 else
6414 {
6415 funcDecl=funcName+funcArgs;
6416 }
6417 }
6418 }
6419
6420 if (funcType=="template class" && !funcTempList.isEmpty())
6421 return; // ignore explicit template instantiations
6422
6423 AUTO_TRACE_ADD("Parse results: namespaceName='{}' className=`{}` funcType='{}' funcSpec='{}' "
6424 " funcName='{}' funcArgs='{}' funcTempList='{}' funcDecl='{}' relates='{}'"
6425 " exceptions='{}' isRelated={} isMemberOf={} isFriend={} isFunc={}",
6426 namespaceName, className, funcType, funcSpec,
6427 funcName, funcArgs, funcTempList, funcDecl, relates,
6428 exceptions, isRelated, isMemberOf, isFriend, isFunc);
6429
6430 if (!funcName.isEmpty()) // function name is valid
6431 {
6432 // check if 'className' is actually a scoped enum, in which case we need to
6433 // process it as a global, see issue #6471
6434 bool strongEnum = false;
6435 MemberName *mn=nullptr;
6436 if (!className.isEmpty() && (mn=Doxygen::functionNameLinkedMap->find(className)))
6437 {
6438 for (const auto &imd : *mn)
6439 {
6440 MemberDefMutable *md = toMemberDefMutable(imd.get());
6441 Definition *mdScope = nullptr;
6442 if (md && md->isEnumerate() && md->isStrong() && (mdScope=md->getOuterScope()) &&
6443 // need filter for the correct scope, see issue #9668
6444 ((namespaceName.isEmpty() && mdScope==Doxygen::globalScope) || (mdScope->name()==namespaceName)))
6445 {
6446 AUTO_TRACE_ADD("'{}' is a strong enum! (namespace={} md->getOuterScope()->name()={})",md->name(),namespaceName,md->getOuterScope()->name());
6447 strongEnum = true;
6448 // pass the scope name name as a 'namespace' to the findGlobalMember function
6449 if (!namespaceName.isEmpty())
6450 {
6451 namespaceName+="::"+className;
6452 }
6453 else
6454 {
6455 namespaceName=className;
6456 }
6457 }
6458 }
6459 }
6460
6461 if (funcName.startsWith("operator ")) // strip class scope from cast operator
6462 {
6463 funcName = substitute(funcName,className+"::","");
6464 }
6465 mn = nullptr;
6466 if (!funcTempList.isEmpty()) // try with member specialization
6467 {
6468 mn=Doxygen::memberNameLinkedMap->find(funcName+funcTempList);
6469 }
6470 if (mn==nullptr) // try without specialization
6471 {
6472 mn=Doxygen::memberNameLinkedMap->find(funcName);
6473 }
6474 if (!isRelated && !strongEnum && mn) // function name already found
6475 {
6476 AUTO_TRACE_ADD("member name exists ({} members with this name)",mn->size());
6477 if (!className.isEmpty()) // class name is valid
6478 {
6479 if (funcSpec.isEmpty()) // not a member specialization
6480 {
6481 addMemberFunction(root,mn,scopeName,namespaceName,className,funcType,funcName,
6482 funcArgs,funcTempList,exceptions,
6483 type,args,isFriend,spec,relates,funcDecl,overloaded,isFunc);
6484 }
6485 else if (cd) // member specialization
6486 {
6487 addMemberSpecialization(root,mn,cd,funcType,funcName,funcArgs,funcDecl,exceptions,spec);
6488 }
6489 else
6490 {
6491 //printf("*** Specialized member %s of unknown scope %s%s found!\n",
6492 // qPrint(scopeName),qPrint(funcName),qPrint(funcArgs));
6493 }
6494 }
6495 else if (overloaded) // check if the function belongs to only one class
6496 {
6497 addOverloaded(root,mn,funcType,funcName,funcArgs,funcDecl,exceptions,spec);
6498 }
6499 else // unrelated function with the same name as a member
6500 {
6501 if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec))
6502 {
6503 QCString fullFuncDecl=funcDecl;
6504 if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE);
6505 warn(root->fileName,root->startLine,
6506 "Cannot determine class for function\n%s",
6507 qPrint(fullFuncDecl)
6508 );
6509 }
6510 }
6511 }
6512 else if (isRelated && !relates.isEmpty())
6513 {
6514 AUTO_TRACE_ADD("related function scopeName='{}' className='{}'",scopeName,className);
6515 if (className.isEmpty()) className=relates;
6516 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
6517 if ((cd=getClassMutable(scopeName)))
6518 {
6519 bool newMember=TRUE; // assume we have a new member
6520 MemberDefMutable *mdDefine=nullptr;
6521 {
6522 mn = Doxygen::functionNameLinkedMap->find(funcName);
6523 if (mn)
6524 {
6525 for (const auto &imd : *mn)
6526 {
6527 MemberDefMutable *md = toMemberDefMutable(imd.get());
6528 if (md && md->isDefine())
6529 {
6530 mdDefine = md;
6531 break;
6532 }
6533 }
6534 }
6535 }
6536
6537 FileDef *fd=root->fileDef();
6538
6539 if ((mn=Doxygen::memberNameLinkedMap->find(funcName))==nullptr)
6540 {
6541 mn=Doxygen::memberNameLinkedMap->add(funcName);
6542 }
6543 else
6544 {
6545 // see if we got another member with matching arguments
6546 MemberDefMutable *rmd_found = nullptr;
6547 for (const auto &irmd : *mn)
6548 {
6549 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
6550 if (rmd)
6551 {
6552 const ArgumentList &rmdAl = rmd->argumentList();
6553
6554 newMember=
6555 className!=rmd->getOuterScope()->name() ||
6556 !matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),&rmdAl,
6557 cd,fd,&root->argList,
6558 TRUE,root->lang);
6559 if (!newMember)
6560 {
6561 rmd_found = rmd;
6562 }
6563 }
6564 }
6565 if (rmd_found) // member already exists as rmd -> add docs
6566 {
6567 AUTO_TRACE_ADD("addMemberDocs for related member {}",root->name);
6568 addMemberDocs(root,rmd_found,funcDecl,nullptr,overloaded,spec);
6569 newMember=false;
6570 }
6571 }
6572
6573 if (newMember) // need to create a new member
6574 {
6576 if (mdDefine)
6577 mtype=MemberType_Define;
6578 else if (root->mtype==MethodTypes::Signal)
6579 mtype=MemberType_Signal;
6580 else if (root->mtype==MethodTypes::Slot)
6581 mtype=MemberType_Slot;
6582 else if (root->mtype==MethodTypes::DCOP)
6583 mtype=MemberType_DCOP;
6584
6585 if (mdDefine)
6586 {
6587 mdDefine->setHidden(TRUE);
6588 funcType="#define";
6589 funcArgs=mdDefine->argsString();
6590 funcDecl=funcType + " " + funcName;
6591 }
6592
6593 //printf("New related name '%s' '%d'\n",qPrint(funcName),
6594 // root->argList ? (int)root->argList->count() : -1);
6595
6596 // first note that we pass:
6597 // (root->tArgLists ? root->tArgLists->last() : nullptr)
6598 // for the template arguments for the new "member."
6599 // this accurately reflects the template arguments of
6600 // the related function, which don't have to do with
6601 // those of the related class.
6602 auto md = createMemberDef(
6603 root->fileName,root->startLine,root->startColumn,
6604 funcType,funcName,funcArgs,exceptions,
6605 root->protection,root->virt,
6606 root->isStatic,
6608 mtype,
6609 (!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList()),
6610 funcArgs.isEmpty() ? ArgumentList() : root->argList,
6611 root->metaData);
6612 auto mmd = toMemberDefMutable(md.get());
6613
6614 if (mdDefine)
6615 {
6616 mmd->setInitializer(mdDefine->initializer());
6617 }
6618
6619 //
6620 // we still have the problem that
6621 // MemberDef::writeDocumentation() in memberdef.cpp
6622 // writes the template argument list for the class,
6623 // as if this member is a member of the class.
6624 // fortunately, MemberDef::writeDocumentation() has
6625 // a special mechanism that allows us to totally
6626 // override the set of template argument lists that
6627 // are printed. We use that and set it to the
6628 // template argument lists of the related function.
6629 //
6630 mmd->setDefinitionTemplateParameterLists(root->tArgLists);
6631
6632 mmd->setTagInfo(root->tagInfo());
6633
6634 //printf("Related member name='%s' decl='%s' bodyLine='%d'\n",
6635 // qPrint(funcName),qPrint(funcDecl),root->bodyLine);
6636
6637 // try to find the matching line number of the body from the
6638 // global function list
6639 bool found=FALSE;
6640 if (root->bodyLine==-1)
6641 {
6643 if (rmn)
6644 {
6645 const MemberDefMutable *rmd_found=nullptr;
6646 for (const auto &irmd : *rmn)
6647 {
6648 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
6649 if (rmd)
6650 {
6651 const ArgumentList &rmdAl = rmd->argumentList();
6652 // check for matching argument lists
6653 if (
6654 matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),&rmdAl,
6655 cd,fd,&root->argList,
6656 TRUE,root->lang)
6657 )
6658 {
6659 found=TRUE;
6660 rmd_found = rmd;
6661 break;
6662 }
6663 }
6664 }
6665 if (rmd_found) // member found -> copy line number info
6666 {
6667 mmd->setBodySegment(rmd_found->getDefLine(),rmd_found->getStartBodyLine(),rmd_found->getEndBodyLine());
6668 mmd->setBodyDef(rmd_found->getBodyDef());
6669 //md->setBodyMember(rmd);
6670 }
6671 }
6672 }
6673 if (!found) // line number could not be found or is available in this
6674 // entry
6675 {
6676 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6677 mmd->setBodyDef(fd);
6678 }
6679
6680 //if (root->mGrpId!=-1)
6681 //{
6682 // md->setMemberGroup(memberGroupDict[root->mGrpId]);
6683 //}
6684 mmd->setMemberClass(cd);
6685 mmd->setMemberSpecifiers(spec);
6686 mmd->setVhdlSpecifiers(root->vhdlSpec);
6687 mmd->setDefinition(funcDecl);
6689 mmd->addQualifiers(root->qualifiers);
6690 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6691 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6692 mmd->setDocsForDefinition(!root->proto);
6693 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6694 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6695 mmd->addSectionsToDefinition(root->anchors);
6696 mmd->setMemberGroupId(root->mGrpId);
6697 mmd->setLanguage(root->lang);
6698 mmd->setId(root->id);
6699 //md->setMemberDefTemplateArguments(root->mtArgList);
6700 cd->insertMember(md.get());
6701 cd->insertUsedFile(fd);
6702 mmd->setRefItems(root->sli);
6703 if (root->relatesType==RelatesType::Duplicate) mmd->setRelatedAlso(cd);
6704 if (!mdDefine)
6705 {
6706 addMemberToGroups(root,md.get());
6708 }
6709 //printf("Adding member=%s\n",qPrint(md->name()));
6710 mn->push_back(std::move(md));
6711 }
6713 {
6714 if (!findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec))
6715 {
6716 QCString fullFuncDecl=funcDecl;
6717 if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE);
6718 warn(root->fileName,root->startLine,
6719 "Cannot determine file/namespace for relatedalso function\n%s",
6720 qPrint(fullFuncDecl)
6721 );
6722 }
6723 }
6724 }
6725 else
6726 {
6727 warn_undoc(root->fileName,root->startLine,
6728 "class '%s' for related function '%s' is not "
6729 "documented.",
6730 qPrint(className),qPrint(funcName)
6731 );
6732 }
6733 }
6734 else if (root->parent() && root->parent()->section.isObjcImpl())
6735 {
6736 addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec);
6737 }
6738 else // unrelated not overloaded member found
6739 {
6740 bool globMem = findGlobalMember(root,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl,spec);
6741 if (className.isEmpty() && !globMem)
6742 {
6743 warn(root->fileName,root->startLine,
6744 "class for member '%s' cannot "
6745 "be found.", qPrint(funcName)
6746 );
6747 }
6748 else if (!className.isEmpty() && !globMem)
6749 {
6750 warn(root->fileName,root->startLine,
6751 "member '%s' of class '%s' cannot be found",
6752 qPrint(funcName),qPrint(className));
6753 }
6754 }
6755 }
6756 else
6757 {
6758 // this should not be called
6759 warn(root->fileName,root->startLine,
6760 "member with no name found.");
6761 }
6762 return;
6763}
virtual bool isStrong() const =0
Wrapper class for a number of boolean properties.
Definition types.h:383
void parseFuncDecl(const QCString &decl, const SrcLangExt lang, QCString &clName, QCString &type, QCString &name, QCString &args, QCString &funcTempList, QCString &exceptions)
Definition declinfo.l:312
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:5672
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:6077
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:5256
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:6015
std::string_view stripWhiteSpace(std::string_view s)
Given a string view s, returns a new, narrower view on that string, skipping over any leading or trai...
Definition stringutil.h:72

References LinkedMap< T, Hash, KeyEqual, Map >::add(), addLocalObjCMethod(), addMemberDocs(), addMemberFunction(), addMemberSpecialization(), addMemberToGroups(), ModuleManager::addMemberToModule(), addOverloaded(), Entry::anchors, applyMemberOverrideOptions(), Entry::argList, argListToString(), MemberDef::argsString(), 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, extractNamespaceName(), FALSE, Entry::fileDef(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::find(), findGlobalMember(), Foreign, found, 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, MemberDef::initializer(), ClassDefMutable::insertMember(), ClassDefMutable::insertUsedFile(), ModuleManager::instance(), MemberDef::isDefine(), QCString::isEmpty(), MemberDef::isEnumerate(), EntryType::isScope(), Entry::isStatic, MemberDef::isStrong(), Entry::lang, QCString::left(), QCString::length(), matchArguments2(), Doxygen::memberNameLinkedMap, MemberOf, MemberType_DCOP, MemberType_Define, MemberType_Function, MemberType_Signal, MemberType_Slot, mergeScopes(), Entry::metaData, Entry::mGrpId, Entry::mtype, Definition::name(), Entry::name, Doxygen::namespaceLinkedMap, Entry::parent(), parseFuncDecl(), QCString::prepend(), Entry::protection, Entry::proto, MemberName::push_back(), qPrint(), ClassDef::qualifiedNameWithTemplateParameters(), Entry::qualifiers, Related, Entry::relatesType, removeRedundantWhiteSpace(), QCString::right(), Entry::section, DefinitionMutable::setBodySegment(), DefinitionMutable::setHidden(), Signal, MemberName::size(), Entry::sli, Slot, Entry::spec, Entry::startColumn, Entry::startLine, QCString::startsWith(), QCString::stripPrefix(), stripTemplateSpecifiersFromScope(), QCString::stripWhiteSpace(), 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 6919 of file doxygen.cpp.

6920{
6921 if (root->section.isMemberDoc() ||
6922 root->section.isOverloadDoc() ||
6923 root->section.isFunction() ||
6924 root->section.isVariable() ||
6925 root->section.isVariableDoc() ||
6926 root->section.isDefine() ||
6927 root->section.isIncludedService() ||
6928 root->section.isExportedInterface()
6929 )
6930 {
6931 AUTO_TRACE();
6932 if (root->relatesType==RelatesType::Duplicate && !root->relates.isEmpty())
6933 {
6935 }
6937 }
6938 for (const auto &e : root->children())
6939 {
6940 if (!e->section.isEnum())
6941 {
6942 findMemberDocumentation(e.get());
6943 }
6944 }
6945}
static void findMemberDocumentation(const Entry *root)
Definition doxygen.cpp:6919
static void filterMemberDocumentation(const Entry *root, const QCString &relates)
Definition doxygen.cpp:6769

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

1237{
1238 if (root->section.isModuleDoc())
1239 {
1240 AUTO_TRACE();
1242 }
1243 for (const auto &e : root->children()) findModuleDocumentation(e.get());
1244}
void addDocs(const Entry *root)
static void findModuleDocumentation(const Entry *root)
Definition doxygen.cpp:1236

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

6950{
6951 AUTO_TRACE();
6952 for (const auto &objCImpl : root->children())
6953 {
6954 if (objCImpl->section.isObjcImpl())
6955 {
6956 for (const auto &objCMethod : objCImpl->children())
6957 {
6958 if (objCMethod->section.isFunction())
6959 {
6960 //Printf(" Found ObjC method definition %s\n",qPrint(objCMethod->name));
6961 findMember(objCMethod.get(),
6962 objCMethod->relates,
6963 objCMethod->type,
6964 objCMethod->args,
6965 objCMethod->type+" "+objCImpl->name+"::"+objCMethod->name+" "+objCMethod->args,
6966 FALSE,TRUE);
6967 objCMethod->section=EntryType::makeEmpty();
6968 }
6969 }
6970 }
6971 }
6972}

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

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

8749{
8750 // for each class
8751 for (const auto &cd : *Doxygen::classLinkedMap)
8752 {
8753 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8754 if (cdm)
8755 {
8757 }
8758 }
8759 // for each concept
8760 for (const auto &cd : *Doxygen::conceptLinkedMap)
8761 {
8762 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
8763 if (cdm)
8764 {
8766 }
8767 }
8768 // for each file
8769 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8770 {
8771 for (const auto &fd : *fn)
8772 {
8773 fd->findSectionsInDocumentation();
8774 }
8775 }
8776 // for each namespace
8777 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8778 {
8780 if (ndm)
8781 {
8783 }
8784 }
8785 // for each group
8786 for (const auto &gd : *Doxygen::groupLinkedMap)
8787 {
8788 gd->findSectionsInDocumentation();
8789 }
8790 // for each page
8791 for (const auto &pd : *Doxygen::pageLinkedMap)
8792 {
8793 pd->findSectionsInDocumentation();
8794 }
8796 if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
8797}
virtual void findSectionsInDocumentation()=0
virtual void findSectionsInDocumentation()=0
void findSectionsInDocumentation()
virtual void findSectionsInDocumentation()=0

References Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, ClassDefMutable::findSectionsInDocumentation(), ConceptDefMutable::findSectionsInDocumentation(), FileDef::findSectionsInDocumentation(), GroupDef::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 1616 of file doxygen.cpp.

1617{
1618 std::vector<ClassDefMutable *> candidates;
1619 for (auto &cd : *Doxygen::classLinkedMap)
1620 {
1621 Definition *scope = cd->getOuterScope();
1622 if (scope && scope->definitionType()!=Definition::TypeClass) // that is not nested
1623 {
1624 findTagLessClasses(candidates,cd.get());
1625 }
1626 }
1627
1628 // since processTagLessClasses is potentially adding classes to Doxygen::classLinkedMap
1629 // we need to call it outside of the loop above, otherwise the iterator gets invalidated!
1630 for (auto &cd : candidates)
1631 {
1632 processTagLessClasses(cd,cd,cd,"",0); // process tag less inner struct/classes
1633 }
1634}
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:1536
static void findTagLessClasses()
Definition doxygen.cpp:1616

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

1600{
1601 for (const auto &icd : cd->getClasses())
1602 {
1603 if (icd->name().find("@")==-1) // process all non-anonymous inner classes
1604 {
1605 findTagLessClasses(candidates,icd);
1606 }
1607 }
1608
1610 if (cdm)
1611 {
1612 candidates.push_back(cdm);
1613 }
1614}

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

4268{
4269 AUTO_TRACE("Derived from template '{}' with parameters '{}' isArtificial={}",
4270 templateClass->name(),templSpec,isArtificial);
4271
4272 QCString tempArgsStr = tempArgListToString(templateClass->templateArguments(),root->lang,false);
4273 bool existingClass = templSpec==tempArgsStr;
4274 if (existingClass) return; // avoid recursion
4275
4276 bool freshInstance=FALSE;
4277 ClassDefMutable *instanceClass = toClassDefMutable(
4278 templateClass->insertTemplateInstance(
4279 root->fileName,root->startLine,root->startColumn,templSpec,freshInstance));
4280 if (instanceClass)
4281 {
4282 instanceClass->setArtificial(TRUE);
4283 instanceClass->setLanguage(root->lang);
4284
4285 if (freshInstance)
4286 {
4287 AUTO_TRACE_ADD("found fresh instance '{}'",instanceClass->name());
4288 instanceClass->setTemplateBaseClassNames(templateNames);
4289
4290 // search for new template instances caused by base classes of
4291 // instanceClass
4292 auto it_pair = g_classEntries.equal_range(templateClass->name().str());
4293 for (auto it=it_pair.first ; it!=it_pair.second ; ++it)
4294 {
4295 const Entry *templateRoot = it->second;
4296 AUTO_TRACE_ADD("template root found '{}' templSpec='{}'",templateRoot->name,templSpec);
4297 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(root->lang,templSpec);
4298 findBaseClassesForClass(templateRoot,context,templateClass,instanceClass,
4299 TemplateInstances,isArtificial,templArgs.get(),templateNames);
4300
4301 findUsedClassesForClass(templateRoot,context,templateClass,instanceClass,
4302 isArtificial,templArgs.get(),templateNames);
4303 }
4304 }
4305 else
4306 {
4307 AUTO_TRACE_ADD("instance already exists");
4308 }
4309 }
4310}
virtual ClassDef * insertTemplateInstance(const QCString &fileName, int startLine, int startColumn, const QCString &templSpec, bool &freshInstance) const =0
virtual void setTemplateBaseClassNames(const TemplateNameMap &templateNames)=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:4050

References AUTO_TRACE, AUTO_TRACE_ADD, FALSE, Entry::fileName, findBaseClassesForClass(), findUsedClassesForClass(), g_classEntries, ClassDef::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().

◆ findTemplateSpecializationPosition()

static int findTemplateSpecializationPosition ( const QCString & name)
static

Definition at line 4403 of file doxygen.cpp.

4404{
4405 if (name.isEmpty()) return 0;
4406 int l = static_cast<int>(name.length());
4407 if (name[l-1]=='>') // search backward to find the matching <, allowing nested <...> and strings.
4408 {
4409 int count=1;
4410 int i=l-2;
4411 char insideQuote=0;
4412 while (count>0 && i>=0)
4413 {
4414 char c = name[i--];
4415 switch (c)
4416 {
4417 case '>': if (!insideQuote) count++; break;
4418 case '<': if (!insideQuote) count--; break;
4419 case '\'': if (!insideQuote) insideQuote=c;
4420 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4421 break;
4422 case '"': if (!insideQuote) insideQuote=c;
4423 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4424 break;
4425 default: break;
4426 }
4427 }
4428 if (i>=0) l=i+1;
4429 }
4430 return l;
4431}

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

4058{
4059 AUTO_TRACE();
4060 const ArgumentList &formalArgs = masterCd->templateArguments();
4061 for (auto &mni : masterCd->memberNameInfoLinkedMap())
4062 {
4063 for (auto &mi : *mni)
4064 {
4065 const MemberDef *md=mi->memberDef();
4066 if (md->isVariable() || md->isObjCProperty()) // for each member variable in this class
4067 {
4068 AUTO_TRACE_ADD("Found variable '{}' in class '{}'",md->name(),masterCd->name());
4069 QCString type = normalizeNonTemplateArgumentsInString(md->typeString(),masterCd,formalArgs);
4070 QCString typedefValue = md->getLanguage()==SrcLangExt::Java ? type : resolveTypeDef(masterCd,type);
4071 if (!typedefValue.isEmpty())
4072 {
4073 type = typedefValue;
4074 }
4075 int pos=0;
4076 QCString usedClassName;
4077 QCString templSpec;
4078 bool found=FALSE;
4079 // the type can contain template variables, replace them if present
4080 type = substituteTemplateArgumentsInString(type,formalArgs,actualArgs);
4081
4082 //printf(" template substitution gives=%s\n",qPrint(type));
4083 while (!found && extractClassNameFromType(type,pos,usedClassName,templSpec,root->lang)!=-1)
4084 {
4085 // find the type (if any) that matches usedClassName
4086 SymbolResolver resolver(masterCd->getFileDef());
4087 const ClassDefMutable *typeCd = resolver.resolveClassMutable(masterCd,usedClassName,false,true);
4088 //printf("====> usedClassName=%s -> typeCd=%s\n",
4089 // qPrint(usedClassName),typeCd?qPrint(typeCd->name()):"<none>");
4090 if (typeCd)
4091 {
4092 usedClassName = typeCd->name();
4093 }
4094
4095 int sp=usedClassName.find('<');
4096 if (sp==-1) sp=0;
4097 int si=usedClassName.findRev("::",sp);
4098 if (si!=-1)
4099 {
4100 // replace any namespace aliases
4101 replaceNamespaceAliases(usedClassName,si);
4102 }
4103 // add any template arguments to the class
4104 QCString usedName = removeRedundantWhiteSpace(usedClassName+templSpec);
4105 //printf(" usedName=%s usedClassName=%s templSpec=%s\n",qPrint(usedName),qPrint(usedClassName),qPrint(templSpec));
4106
4107 TemplateNameMap formTemplateNames;
4108 if (templateNames.empty())
4109 {
4110 formTemplateNames = getTemplateArgumentsInName(formalArgs,usedName.str());
4111 }
4113 findClassRelation(root,context,instanceCd,&bi,formTemplateNames,TemplateInstances,isArtificial);
4114
4115 for (const Argument &arg : masterCd->templateArguments())
4116 {
4117 if (arg.name==usedName) // type is a template argument
4118 {
4119 ClassDef *usedCd = Doxygen::hiddenClassLinkedMap->find(usedName);
4120 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4121 if (usedCd==nullptr)
4122 {
4123 usedCdm = toClassDefMutable(
4124 Doxygen::hiddenClassLinkedMap->add(usedName,
4126 masterCd->getDefFileName(),masterCd->getDefLine(),
4127 masterCd->getDefColumn(),
4128 usedName,
4129 ClassDef::Class)));
4130 if (usedCdm)
4131 {
4132 //printf("making %s a template argument!!!\n",qPrint(usedCd->name()));
4133 usedCdm->makeTemplateArgument();
4134 usedCdm->setUsedOnly(TRUE);
4135 usedCdm->setLanguage(masterCd->getLanguage());
4136 usedCd = usedCdm;
4137 }
4138 }
4139 if (usedCd)
4140 {
4141 found=TRUE;
4142 AUTO_TRACE_ADD("case 1: adding used class '{}'", usedCd->name());
4143 instanceCd->addUsedClass(usedCd,md->name(),md->protection());
4144 if (usedCdm)
4145 {
4146 if (isArtificial) usedCdm->setArtificial(TRUE);
4147 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4148 }
4149 }
4150 }
4151 }
4152
4153 if (!found)
4154 {
4155 ClassDef *usedCd=findClassWithinClassContext(context,masterCd,usedName);
4156 //printf("Looking for used class %s: result=%s master=%s\n",
4157 // qPrint(usedName),usedCd?qPrint(usedCd->name()):"<none>",masterCd?qPrint(masterCd->name()):"<none>");
4158
4159 if (usedCd)
4160 {
4161 found=TRUE;
4162 AUTO_TRACE_ADD("case 2: adding used class '{}'", usedCd->name());
4163 instanceCd->addUsedClass(usedCd,md->name(),md->protection()); // class exists
4164 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4165 if (usedCdm)
4166 {
4167 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4168 }
4169 }
4170 }
4171 }
4172 if (!found && !type.isEmpty()) // used class is not documented in any scope
4173 {
4175 ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
4176 if (usedCd==nullptr && !Config_getBool(HIDE_UNDOC_RELATIONS))
4177 {
4178 if (type.endsWith("(*") || type.endsWith("(^")) // type is a function pointer
4179 {
4180 type+=md->argsString();
4181 }
4182 AUTO_TRACE_ADD("New undocumented used class '{}'", type);
4183 usedCdm = toClassDefMutable(
4186 masterCd->getDefFileName(),masterCd->getDefLine(),
4187 masterCd->getDefColumn(),
4188 type,ClassDef::Class)));
4189 if (usedCdm)
4190 {
4191 usedCdm->setUsedOnly(TRUE);
4192 usedCdm->setLanguage(masterCd->getLanguage());
4193 usedCd = usedCdm;
4194 }
4195 }
4196 if (usedCd)
4197 {
4198 AUTO_TRACE_ADD("case 3: adding used class '{}'", usedCd->name());
4199 instanceCd->addUsedClass(usedCd,md->name(),md->protection());
4200 if (usedCdm)
4201 {
4202 if (isArtificial) usedCdm->setArtificial(TRUE);
4203 usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
4204 }
4205 }
4206 }
4207 }
4208 }
4209 }
4210}
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:4579
int extractClassNameFromType(const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt lang)
Definition util.cpp:4505
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, LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::find(), findClassRelation(), findClassWithinClassContext(), QCString::findRev(), 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 1807 of file doxygen.cpp.

1809{
1810 NamespaceDef *usingNd =nullptr;
1811 for (auto &und : unl)
1812 {
1813 QCString uScope=und->name()+"::";
1814 usingNd = getResolvedNamespace(uScope+name);
1815 if (usingNd!=nullptr) break;
1816 }
1817 return usingNd;
1818}

References getResolvedNamespace().

Referenced by findUsingDirectives().

◆ findUsedTemplateInstances()

static void findUsedTemplateInstances ( )
static

Definition at line 4838 of file doxygen.cpp.

4839{
4840 AUTO_TRACE();
4841 for (const auto &[name,root] : g_classEntries)
4842 {
4843 QCString bName = extractClassName(root);
4844 ClassDefMutable *cdm = getClassMutable(bName);
4845 if (cdm)
4846 {
4847 findUsedClassesForClass(root,cdm,cdm,cdm,TRUE);
4848 cdm->addTypeConstraints();
4849 }
4850 }
4851}
virtual void addTypeConstraints()=0

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

Referenced by parseInput().

◆ findUsingDeclarations()

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

Definition at line 1975 of file doxygen.cpp.

1976{
1977 if (root->section.isUsingDecl() &&
1978 !root->parent()->section.isCompound() && // not a class/struct member
1979 (!filterPythonPackages || (root->lang==SrcLangExt::Python && root->fileName.endsWith("__init__.py")))
1980 )
1981 {
1982 AUTO_TRACE("Found using declaration '{}' at line {} of {} inside section {}",
1983 root->name,root->startLine,root->fileName,root->parent()->section);
1984 if (!root->name.isEmpty())
1985 {
1986 ClassDefMutable *usingCd = nullptr;
1987 NamespaceDefMutable *nd = nullptr;
1988 FileDef *fd = root->fileDef();
1989 QCString scName;
1990
1991 // see if the using statement was found inside a namespace or inside
1992 // the global file scope.
1993 if (root->parent()->section.isNamespace())
1994 {
1995 scName=root->parent()->name;
1996 if (!scName.isEmpty())
1997 {
1998 nd = getResolvedNamespaceMutable(scName);
1999 }
2000 }
2001
2002 // Assume the using statement was used to import a class.
2003 // Find the scope in which the 'using' namespace is defined by prepending
2004 // the possible scopes in which the using statement was found, starting
2005 // with the most inner scope and going to the most outer scope (i.e.
2006 // file scope).
2007
2008 QCString name = substitute(root->name,".","::"); //Java/C# scope->internal
2009 usingCd = getClassMutable(name); // try direct lookup first, this is needed to get
2010 // builtin STL classes to properly resolve, e.g.
2011 // vector -> std::vector
2012 if (usingCd==nullptr)
2013 {
2014 SymbolResolver resolver(fd);
2015 usingCd = resolver.resolveClassMutable(nd,name); // try via resolving (see also bug757509)
2016 }
2017 if (usingCd==nullptr)
2018 {
2019 usingCd = toClassDefMutable(Doxygen::hiddenClassLinkedMap->find(name)); // check if it is already hidden
2020 }
2021
2022 if (usingCd==nullptr) // definition not in the input => add an artificial class
2023 {
2024 AUTO_TRACE_ADD("New using class '{}' (sec={})! #tArgLists={}",
2025 name,root->section,root->tArgLists.size());
2026 usingCd = toClassDefMutable(
2028 createClassDef( "<using>",1,1, name, ClassDef::Class)));
2029 if (usingCd)
2030 {
2031 usingCd->setArtificial(TRUE);
2032 usingCd->setLanguage(root->lang);
2033 }
2034 }
2035 else
2036 {
2037 AUTO_TRACE_ADD("Found used class '{}' in scope='{}'",
2038 usingCd->name(), nd ? nd->name(): fd ? fd->name() : QCString("<unknown>"));
2039 }
2040
2041 if (nd)
2042 {
2043 nd->addUsingDeclaration(usingCd);
2044 }
2045 else if (fd)
2046 {
2047 fd->addUsingDeclaration(usingCd);
2048 }
2049 }
2050 }
2051 for (const auto &e : root->children()) findUsingDeclarations(e.get(),filterPythonPackages);
2052}
virtual void addUsingDeclaration(ClassDef *cd)=0
virtual void addUsingDeclaration(ClassDef *cd)=0
static void findUsingDeclarations(const Entry *root, bool filterPythonPackages)
Definition doxygen.cpp:1975

References FileDef::addUsingDeclaration(), NamespaceDefMutable::addUsingDeclaration(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::children(), ClassDef::Class, createClassDef(), QCString::endsWith(), Entry::fileDef(), Entry::fileName, findUsingDeclarations(), getClassMutable(), getResolvedNamespaceMutable(), Doxygen::hiddenClassLinkedMap, EntryType::isCompound(), QCString::isEmpty(), Entry::lang, Definition::name(), Entry::name, Entry::parent(), Python, SymbolResolver::resolveClassMutable(), 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 2067 of file doxygen.cpp.

2068{
2069 if (root->section.isUsingDecl() &&
2070 root->parent()->section.isCompound() // in a class/struct member
2071 )
2072 {
2073 AUTO_TRACE("Found using declaration '{}' inside section {}", root->name, root->parent()->section);
2074 QCString fullName=removeRedundantWhiteSpace(root->parent()->name);
2075 fullName=stripAnonymousNamespaceScope(fullName);
2076 fullName=stripTemplateSpecifiersFromScope(fullName);
2077 ClassDefMutable *cd = getClassMutable(fullName);
2078 if (cd)
2079 {
2080 AUTO_TRACE_ADD("found class '{}'",cd->name());
2081 int i=root->name.find("::");
2082 if (i!=-1)
2083 {
2084 QCString scope=root->name.left(i);
2085 QCString memName=root->name.right(root->name.length()-i-2);
2086 SymbolResolver resolver;
2087 const ClassDef *bcd = resolver.resolveClass(cd,scope); // todo: file in fileScope parameter
2088 if (bcd && bcd!=cd)
2089 {
2090 AUTO_TRACE_ADD("found class '{}' memName='{}'",bcd->name(),memName);
2092 const MemberNameInfo *mni = mnlm.find(memName);
2093 if (mni)
2094 {
2095 for (auto &mi : *mni)
2096 {
2097 const MemberDef *md = mi->memberDef();
2098 if (md && md->protection()!=Protection::Private)
2099 {
2100 AUTO_TRACE_ADD("found member '{}'",mni->memberName());
2101 QCString fileName = root->fileName;
2102 if (fileName.isEmpty() && root->tagInfo())
2103 {
2104 fileName = root->tagInfo()->tagName;
2105 }
2106 const ArgumentList &templAl = md->templateArguments();
2107 const ArgumentList &al = md->argumentList();
2108
2109 if (!cd->containsOverload(md))
2110 {
2111 auto newMd = createMemberDef(
2112 fileName,root->startLine,root->startColumn,
2113 md->typeString(),memName,md->argsString(),
2114 md->excpString(),root->protection,root->virt,
2116 templAl,al,root->metaData
2117 );
2118 auto newMmd = toMemberDefMutable(newMd.get());
2119 newMmd->setMemberClass(cd);
2120 cd->insertMember(newMd.get());
2121 if (!root->doc.isEmpty() || !root->brief.isEmpty())
2122 {
2123 newMmd->setDocumentation(root->doc,root->docFile,root->docLine);
2124 newMmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2125 newMmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2126 }
2127 else
2128 {
2129 newMmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
2130 newMmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
2131 newMmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
2132 }
2133 newMmd->setDefinition(md->definition());
2134 applyMemberOverrideOptions(root,newMmd);
2135 newMmd->addQualifiers(root->qualifiers);
2136 newMmd->setBitfields(md->bitfieldString());
2137 newMmd->addSectionsToDefinition(root->anchors);
2138 newMmd->setBodySegment(md->getDefLine(),md->getStartBodyLine(),md->getEndBodyLine());
2139 newMmd->setBodyDef(md->getBodyDef());
2140 newMmd->setInitializer(md->initializer());
2141 newMmd->setRequiresClause(md->requiresClause());
2142 newMmd->setMaxInitLines(md->initializerLines());
2143 newMmd->setMemberGroupId(root->mGrpId);
2144 newMmd->setMemberSpecifiers(md->getMemberSpecifiers());
2145 newMmd->setVhdlSpecifiers(md->getVhdlSpecifiers());
2146 newMmd->setLanguage(root->lang);
2147 newMmd->setId(root->id);
2149 mn->push_back(std::move(newMd));
2150 }
2151 }
2152 }
2153 }
2154 }
2155 }
2156 }
2157
2158 }
2159 for (const auto &e : root->children()) findUsingDeclImports(e.get());
2160}
virtual bool containsOverload(const MemberDef *md) const =0
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
QCString memberName() const
Definition membername.h:108
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.
static void findUsingDeclImports(const Entry *root)
Definition doxygen.cpp:2067

References LinkedMap< T, Hash, KeyEqual, Map >::add(), 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(), ClassDef::containsOverload(), createMemberDef(), MemberDef::definition(), Entry::doc, Definition::docFile(), Entry::docFile, Definition::docLine(), Entry::docLine, Definition::documentation(), MemberDef::excpString(), Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::find(), findUsingDeclImports(), Definition::getBodyDef(), getClassMutable(), 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(), EntryType::isCompound(), QCString::isEmpty(), MemberDef::isStatic(), Entry::lang, QCString::left(), QCString::length(), Member, MemberNameInfo::memberName(), ClassDef::memberNameInfoLinkedMap(), Doxygen::memberNameLinkedMap, MemberDef::memberType(), Entry::metaData, Entry::mGrpId, Definition::name(), Entry::name, Entry::parent(), Private, Entry::protection, MemberDef::protection(), MemberName::push_back(), Entry::qualifiers, removeRedundantWhiteSpace(), MemberDef::requiresClause(), SymbolResolver::resolveClass(), QCString::right(), Entry::section, Entry::startColumn, Entry::startLine, stripAnonymousNamespaceScope(), stripTemplateSpecifiersFromScope(), Entry::tagInfo(), TagInfo::tagName, MemberDef::templateArguments(), toMemberDefMutable(), MemberDef::typeString(), and Entry::virt.

Referenced by findUsingDeclImports(), and parseInput().

◆ findUsingDirectives()

static void findUsingDirectives ( const Entry * root)
static

Definition at line 1820 of file doxygen.cpp.

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

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, LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::findRev(), findUsedNamespace(), findUsingDirectives(), Definition::getLanguage(), Definition::getOuterScope(), getResolvedNamespace(), getResolvedNamespaceMutable(), FileDef::getUsedNamespaces(), NamespaceDef::getUsedNamespaces(), Doxygen::groupLinkedMap, 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 8802 of file doxygen.cpp.

8803{
8804 // remove all references to classes from the cache
8805 // as there can be new template instances in the inheritance path
8806 // to this class. Optimization: only remove those classes that
8807 // have inheritance instances as direct or indirect sub classes.
8808 StringVector elementsToRemove;
8809 for (const auto &ci : *Doxygen::typeLookupCache)
8810 {
8811 const LookupInfo &li = ci.second;
8812 if (li.definition)
8813 {
8814 elementsToRemove.push_back(ci.first);
8815 }
8816 }
8817 for (const auto &k : elementsToRemove)
8818 {
8820 }
8821
8822 // remove all cached typedef resolutions whose target is a
8823 // template class as this may now be a template instance
8824 // for each global function name
8825 for (const auto &fn : *Doxygen::functionNameLinkedMap)
8826 {
8827 // for each function with that name
8828 for (const auto &ifmd : *fn)
8829 {
8830 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
8831 if (fmd && fmd->isTypedefValCached())
8832 {
8833 const ClassDef *cd = fmd->getCachedTypedefVal();
8834 if (cd->isTemplate()) fmd->invalidateTypedefValCache();
8835 }
8836 }
8837 }
8838 // for each class method name
8839 for (const auto &nm : *Doxygen::memberNameLinkedMap)
8840 {
8841 // for each function with that name
8842 for (const auto &imd : *nm)
8843 {
8844 MemberDefMutable *md = toMemberDefMutable(imd.get());
8845 if (md && md->isTypedefValCached())
8846 {
8847 const ClassDef *cd = md->getCachedTypedefVal();
8848 if (cd->isTemplate()) md->invalidateTypedefValCache();
8849 }
8850 }
8851 }
8852}
void remove(const K &key)
Removes entry key from the cache.
Definition cache.h:91
virtual bool isTemplate() const =0
Returns TRUE if this class is a template.
static Cache< std::string, LookupInfo > * typeLookupCache
Definition doxygen.h:117
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, Cache< K, V >::remove(), toMemberDefMutable(), and Doxygen::typeLookupCache.

Referenced by parseInput().

◆ flushUnresolvedRelations()

static void flushUnresolvedRelations ( )
static

Definition at line 8856 of file doxygen.cpp.

8857{
8858 // Remove all unresolved references to classes from the cache.
8859 // This is needed before resolving the inheritance relations, since
8860 // it would otherwise not find the inheritance relation
8861 // for C in the example below, as B::I was already found to be unresolvable
8862 // (which is correct if you ignore the inheritance relation between A and B).
8863 //
8864 // class A { class I {} };
8865 // class B : public A {};
8866 // class C : public B::I {};
8867
8868 StringVector elementsToRemove;
8869 for (const auto &ci : *Doxygen::typeLookupCache)
8870 {
8871 const LookupInfo &li = ci.second;
8872 if (li.definition==nullptr && li.typeDef==nullptr)
8873 {
8874 elementsToRemove.push_back(ci.first);
8875 }
8876 }
8877 for (const auto &k : elementsToRemove)
8878 {
8880 }
8881
8882 // for each global function name
8883 for (const auto &fn : *Doxygen::functionNameLinkedMap)
8884 {
8885 // for each function with that name
8886 for (const auto &ifmd : *fn)
8887 {
8888 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
8889 if (fmd)
8890 {
8892 }
8893 }
8894 }
8895 // for each class method name
8896 for (const auto &nm : *Doxygen::memberNameLinkedMap)
8897 {
8898 // for each function with that name
8899 for (const auto &imd : *nm)
8900 {
8901 MemberDefMutable *md = toMemberDefMutable(imd.get());
8902 if (md)
8903 {
8905 }
8906 }
8907 }
8908
8909}
virtual void invalidateCachedArgumentTypes()=0
const MemberDef * typeDef
Definition doxygen.h:61

References LookupInfo::definition, Doxygen::functionNameLinkedMap, MemberDefMutable::invalidateCachedArgumentTypes(), Doxygen::memberNameLinkedMap, Cache< K, V >::remove(), 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 8565 of file doxygen.cpp.

8566{
8567 std::vector<ClassDefMutable*> classList;
8568 for (const auto &cdi : *Doxygen::classLinkedMap)
8569 {
8570 ClassDefMutable *cd = toClassDefMutable(cdi.get());
8571 if (cd && (cd->getOuterScope()==nullptr ||
8573 {
8574 addClassAndNestedClasses(classList,cd);
8575 }
8576 }
8577 for (const auto &cdi : *Doxygen::hiddenClassLinkedMap)
8578 {
8579 ClassDefMutable *cd = toClassDefMutable(cdi.get());
8580 if (cd && (cd->getOuterScope()==nullptr ||
8582 {
8583 addClassAndNestedClasses(classList,cd);
8584 }
8585 }
8586 generateDocsForClassList(classList);
8587}
static void generateDocsForClassList(const std::vector< ClassDefMutable * > &classList)
Definition doxygen.cpp:8474

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

8592{
8593 for (const auto &cdi : *Doxygen::conceptLinkedMap)
8594 {
8596
8597 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
8598 if (cd &&
8599 (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
8600 cd->getOuterScope()==Doxygen::globalScope // only look at global concepts
8601 ) && !cd->isHidden() && cd->isLinkableInProject()
8602 )
8603 {
8604 msg("Generating docs for concept %s...\n",qPrint(cd->name()));
8606 }
8607 }
8608}
virtual void writeDocumentation(OutputList &ol)=0
virtual bool isHidden() const =0

References Doxygen::conceptLinkedMap, g_outputList, Definition::getOuterScope(), Doxygen::globalScope, Definition::isHidden(), Definition::isLinkableInProject(), msg(), Definition::name(), qPrint(), 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 9720 of file doxygen.cpp.

9722{
9723 std::ofstream f;
9724 bool fileOpened=openOutputFile(configFile,f);
9725 bool writeToStdout=configFile=="-";
9726 if (fileOpened)
9727 {
9728 TextStream t(&f);
9729 Config::writeTemplate(t,shortList,updateOnly);
9730 if (!writeToStdout)
9731 {
9732 if (!updateOnly)
9733 {
9734 msg("\n\nConfiguration file '%s' created.\n\n",qPrint(configFile));
9735 msg("Now edit the configuration file and enter\n\n");
9736 if (configFile!="Doxyfile" && configFile!="doxyfile")
9737 msg(" doxygen %s\n\n",qPrint(configFile));
9738 else
9739 msg(" doxygen\n\n");
9740 msg("to generate the documentation for your project\n\n");
9741 }
9742 else
9743 {
9744 msg("\n\nConfiguration file '%s' updated.\n\n",qPrint(configFile));
9745 }
9746 }
9747 }
9748 else
9749 {
9750 term("Cannot open file %s for writing\n",qPrint(configFile));
9751 }
9752}
void writeTemplate(TextStream &t, bool shortList, bool updateOnly=FALSE)

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

Referenced by readConfiguration().

◆ generateDiskNames()

static void generateDiskNames ( )
static

Definition at line 9975 of file doxygen.cpp.

9976{
9977 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9978 {
9979 struct FileEntry
9980 {
9981 FileEntry(const QCString &p,FileDef *fd) : path(p), fileDef(fd) {}
9982 QCString path;
9983 FileDef *fileDef;
9984 };
9985
9986 // collect the entry for which to compute the longest common prefix (LCP) of the path
9987 std::vector<FileEntry> fileEntries;
9988 for (const auto &fd : *fn)
9989 {
9990 if (!fd->isReference()) // skip external references
9991 {
9992 fileEntries.emplace_back(fd->getPath(),fd.get());
9993 }
9994 }
9995
9996 size_t size = fileEntries.size();
9997
9998 if (size==1) // name if unique, so diskname is simply the name
9999 {
10000 FileDef *fd = fileEntries[0].fileDef;
10001 fd->setDiskName(fn->fileName());
10002 }
10003 else if (size>1) // multiple occurrences of the same file name
10004 {
10005 // sort the array
10006 std::sort(fileEntries.begin(),
10007 fileEntries.end(),
10008 [](const FileEntry &fe1,const FileEntry &fe2)
10009 { return fe1.path < fe2.path; }
10010 );
10011
10012 // since the entries are sorted, the common prefix of the whole array is same
10013 // as the common prefix between the first and last entry
10014 const FileEntry &first = fileEntries[0];
10015 const FileEntry &last = fileEntries[size-1];
10016 int first_path_size = static_cast<int>(first.path.size())-1; // -1 to skip trailing slash
10017 int last_path_size = static_cast<int>(last.path.size())-1; // -1 to skip trailing slash
10018 int j=0;
10019 int i=0;
10020 for (i=0;i<first_path_size && i<last_path_size;i++)
10021 {
10022 if (first.path[i]=='/') j=i;
10023 if (first.path[i]!=last.path[i]) break;
10024 }
10025 if (i==first_path_size && i<last_path_size && last.path[i]=='/')
10026 {
10027 // case first='some/path' and last='some/path/more' => match is 'some/path'
10028 j=first_path_size;
10029 }
10030 else if (i==last_path_size && i<first_path_size && first.path[i]=='/')
10031 {
10032 // case first='some/path/more' and last='some/path' => match is 'some/path'
10033 j=last_path_size;
10034 }
10035
10036 // add non-common part of the path to the name
10037 for (auto &fileEntry : fileEntries)
10038 {
10039 QCString prefix = fileEntry.path.right(fileEntry.path.length()-j-1);
10040 fileEntry.fileDef->setName(prefix+fn->fileName());
10041 //printf("!!!!!!!! non unique disk name=%s:%s\n",qPrint(prefix),fn->fileName());
10042 fileEntry.fileDef->setDiskName(prefix+fn->fileName());
10043 }
10044 }
10045 }
10046}
constexpr auto prefix
Definition anchor.cpp:44
virtual void setDiskName(const QCString &name)=0

References FileDef::getPath(), Doxygen::inputNameLinkedMap, Definition::isReference(), prefix, QCString::right(), and FileDef::setDiskName().

Referenced by parseInput().

◆ generateDocsForClassList()

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

Definition at line 8474 of file doxygen.cpp.

8475{
8476 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8477 if (numThreads>1) // multi threaded processing
8478 {
8479 struct DocContext
8480 {
8481 DocContext(ClassDefMutable *cd_,const OutputList &ol_)
8482 : cd(cd_), ol(ol_) {}
8483 ClassDefMutable *cd;
8484 OutputList ol;
8485 };
8486 ThreadPool threadPool(numThreads);
8487 std::vector< std::future< std::shared_ptr<DocContext> > > results;
8488 for (const auto &cd : classList)
8489 {
8490 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
8491 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
8492 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
8493 )
8494 {
8495 auto ctx = std::make_shared<DocContext>(cd,*g_outputList);
8496 auto processFile = [ctx]()
8497 {
8498 msg("Generating docs for compound %s...\n",qPrint(ctx->cd->name()));
8499
8500 // skip external references, anonymous compounds and
8501 // template instances
8502 if (!ctx->cd->isHidden() && !ctx->cd->isEmbeddedInOuterScope() &&
8503 ctx->cd->isLinkableInProject() && ctx->cd->templateMaster()==nullptr)
8504 {
8505 ctx->cd->writeDocumentation(ctx->ol);
8506 ctx->cd->writeMemberList(ctx->ol);
8507 }
8508
8509 // even for undocumented classes, the inner classes can be documented.
8510 ctx->cd->writeDocumentationForInnerClasses(ctx->ol);
8511 return ctx;
8512 };
8513 results.emplace_back(threadPool.queue(processFile));
8514 }
8515 }
8516 for (auto &f : results)
8517 {
8518 auto ctx = f.get();
8519 }
8520 }
8521 else // single threaded processing
8522 {
8523 for (const auto &cd : classList)
8524 {
8525 //printf("cd=%s getOuterScope=%p global=%p hidden=%d embeddedInOuterScope=%d\n",
8526 // qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope,cd->isHidden(),cd->isEmbeddedInOuterScope());
8527 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
8528 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
8529 )
8530 {
8531 // skip external references, anonymous compounds and
8532 // template instances
8533 if ( !cd->isHidden() && !cd->isEmbeddedInOuterScope() &&
8534 cd->isLinkableInProject() && cd->templateMaster()==nullptr)
8535 {
8536 msg("Generating docs for compound %s...\n",qPrint(cd->name()));
8537
8538 cd->writeDocumentation(*g_outputList);
8539 cd->writeMemberList(*g_outputList);
8540 }
8541 // even for undocumented classes, the inner classes can be documented.
8542 cd->writeDocumentationForInnerClasses(*g_outputList);
8543 }
8544 }
8545 }
8546}
Class representing a list of output generators that are written to in parallel.
Definition outputlist.h:291

References Config_getInt, g_outputList, Definition::getOuterScope(), Doxygen::globalScope, ClassDef::isEmbeddedInOuterScope(), Definition::isHidden(), Definition::isLinkableInProject(), msg(), Definition::name(), qPrint(), ThreadPool::queue(), ClassDef::templateMaster(), ClassDef::writeDocumentation(), ClassDef::writeDocumentationForInnerClasses(), and ClassDef::writeMemberList().

Referenced by generateClassDocs().

◆ generateExampleDocs()

static void generateExampleDocs ( )
static

Definition at line 9424 of file doxygen.cpp.

9425{
9427 for (const auto &pd : *Doxygen::exampleLinkedMap)
9428 {
9429 msg("Generating docs for example %s...\n",qPrint(pd->name()));
9431 if (lang != SrcLangExt::Unknown)
9432 {
9433 QCString ext = getFileNameExtension(pd->name());
9434 auto intf = Doxygen::parserManager->getCodeParser(ext);
9435 intf->resetCodeParserState();
9436 }
9437 QCString n=pd->getOutputFileBase();
9438 startFile(*g_outputList,n,n,pd->name());
9440 g_outputList->docify(pd->name());
9443 QCString lineNoOptStr;
9444 if (pd->showLineNo())
9445 {
9446 lineNoOptStr="{lineno}";
9447 }
9448 g_outputList->generateDoc(pd->docFile(), // file
9449 pd->docLine(), // startLine
9450 pd.get(), // context
9451 nullptr, // memberDef
9452 (pd->briefDescription().isEmpty()?"":pd->briefDescription()+"\n\n")+
9453 pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
9454 TRUE, // index words
9455 TRUE, // is example
9456 pd->name(),
9457 FALSE,
9458 FALSE,
9459 Config_getBool(MARKDOWN_SUPPORT)
9460 );
9461 endFile(*g_outputList); // contains g_outputList->endContents()
9462 }
9464}
void disable(OutputType o)
void enable(OutputType o)
void docify(const QCString &s)
Definition outputlist.h:415
void generateDoc(const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &docStr, bool indexWords, bool isExample, const QCString &exampleName, bool singleLine, bool linkFromIndex, bool markdownSupport)
void startContents()
Definition outputlist.h:594
std::unique_ptr< CodeParserInterface > getCodeParser(const QCString &extension)
Gets the interface to the parser associated with a given extension.
Definition parserintf.h:216
void startTitle(OutputList &ol, const QCString &fileName, const DefinitionMutable *def)
Definition index.cpp:375
void endFile(OutputList &ol, bool skipNavIndex, bool skipEndContents, const QCString &navPath)
Definition index.cpp:410
void endTitle(OutputList &ol, const QCString &fileName, const QCString &name)
Definition index.cpp:384
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:391
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5472
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5514

References Config_getBool, OutputList::disable(), OutputList::docify(), OutputList::enable(), endFile(), endTitle(), Doxygen::exampleLinkedMap, FALSE, g_outputList, OutputList::generateDoc(), ParserManager::getCodeParser(), getFileNameExtension(), getLanguageFromFileName(), Man, msg(), Doxygen::parserManager, qPrint(), OutputList::startContents(), startFile(), startTitle(), TRUE, and Unknown.

Referenced by generateOutput().

◆ generateFileDocs()

static void generateFileDocs ( )
static

Definition at line 8146 of file doxygen.cpp.

8147{
8148 if (Index::instance().numDocumentedFiles()==0) return;
8149
8150 if (!Doxygen::inputNameLinkedMap->empty())
8151 {
8152 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8153 if (numThreads>1) // multi threaded processing
8154 {
8155 struct DocContext
8156 {
8157 DocContext(FileDef *fd_,const OutputList &ol_)
8158 : fd(fd_), ol(ol_) {}
8159 FileDef *fd;
8160 OutputList ol;
8161 };
8162 ThreadPool threadPool(numThreads);
8163 std::vector< std::future< std::shared_ptr<DocContext> > > results;
8164 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8165 {
8166 for (const auto &fd : *fn)
8167 {
8168 bool doc = fd->isLinkableInProject();
8169 if (doc)
8170 {
8171 auto ctx = std::make_shared<DocContext>(fd.get(),*g_outputList);
8172 auto processFile = [ctx]() {
8173 msg("Generating docs for file %s...\n",qPrint(ctx->fd->docName()));
8174 ctx->fd->writeDocumentation(ctx->ol);
8175 return ctx;
8176 };
8177 results.emplace_back(threadPool.queue(processFile));
8178 }
8179 }
8180 }
8181 for (auto &f : results)
8182 {
8183 auto ctx = f.get();
8184 }
8185 }
8186 else // single threaded processing
8187 {
8188 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8189 {
8190 for (const auto &fd : *fn)
8191 {
8192 bool doc = fd->isLinkableInProject();
8193 if (doc)
8194 {
8195 msg("Generating docs for file %s...\n",qPrint(fd->docName()));
8196 fd->writeDocumentation(*g_outputList);
8197 }
8198 }
8199 }
8200 }
8201 }
8202}

References Config_getInt, FileDef::docName(), g_outputList, Doxygen::inputNameLinkedMap, Index::instance(), Definition::isLinkableInProject(), msg(), qPrint(), ThreadPool::queue(), and FileDef::writeDocumentation().

Referenced by generateOutput().

◆ generateFileSources()

static void generateFileSources ( )
static

Definition at line 7980 of file doxygen.cpp.

7981{
7982 auto processSourceFile = [](FileDef *fd,OutputList &ol,ClangTUParser *parser)
7983 {
7984 bool showSources = fd->generateSourceFile() && !Htags::useHtags; // sources need to be shown in the output
7985 bool parseSources = !fd->isReference() && Doxygen::parseSourcesNeeded; // we needed to parse the sources even if we do not show them
7986 if (showSources)
7987 {
7988 msg("Generating code for file %s...\n",qPrint(fd->docName()));
7989 fd->writeSourceHeader(ol);
7990 fd->writeSourceBody(ol,parser);
7991 fd->writeSourceFooter(ol);
7992 }
7993 else if (parseSources)
7994 {
7995 msg("Parsing code for file %s...\n",qPrint(fd->docName()));
7996 fd->parseSource(parser);
7997 }
7998 };
7999 if (!Doxygen::inputNameLinkedMap->empty())
8000 {
8001#if USE_LIBCLANG
8003 {
8004 StringUnorderedSet processedFiles;
8005
8006 // create a dictionary with files to process
8007 StringUnorderedSet filesToProcess;
8008
8009 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8010 {
8011 for (const auto &fd : *fn)
8012 {
8013 filesToProcess.insert(fd->absFilePath().str());
8014 }
8015 }
8016 // process source files (and their include dependencies)
8017 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8018 {
8019 for (const auto &fd : *fn)
8020 {
8021 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp &&
8022 (fd->generateSourceFile() ||
8024 )
8025 )
8026 {
8027 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8028 clangParser->parse();
8029 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8030
8031 for (auto incFile : clangParser->filesInSameTU())
8032 {
8033 if (filesToProcess.find(incFile)!=filesToProcess.end() && // part of input
8034 fd->absFilePath()!=QCString(incFile) && // not same file
8035 processedFiles.find(incFile)==processedFiles.end()) // not yet marked as processed
8036 {
8037 StringVector moreFiles;
8038 bool ambig = false;
8039 FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile.c_str(),ambig);
8040 if (ifd && !ifd->isReference())
8041 {
8042 processSourceFile(ifd,*g_outputList,clangParser.get());
8043 processedFiles.insert(incFile);
8044 }
8045 }
8046 }
8047 processedFiles.insert(fd->absFilePath().str());
8048 }
8049 }
8050 }
8051 // process remaining files
8052 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8053 {
8054 for (const auto &fd : *fn)
8055 {
8056 if (processedFiles.find(fd->absFilePath().str())==processedFiles.end()) // not yet processed
8057 {
8058 if (fd->getLanguage()==SrcLangExt::Cpp) // C/C++ file, use clang parser
8059 {
8060 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8061 clangParser->parse();
8062 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8063 }
8064 else // non C/C++ file, use built-in parser
8065 {
8066 processSourceFile(fd.get(),*g_outputList,nullptr);
8067 }
8068 }
8069 }
8070 }
8071 }
8072 else
8073#endif
8074 {
8075 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8076 if (numThreads>1)
8077 {
8078 msg("Generating code files using %zu threads.\n",numThreads);
8079 struct SourceContext
8080 {
8081 SourceContext(FileDef *fd_,bool gen_,const OutputList &ol_)
8082 : fd(fd_), generateSourceFile(gen_), ol(ol_) {}
8083 FileDef *fd;
8084 bool generateSourceFile;
8085 OutputList ol;
8086 };
8087 ThreadPool threadPool(numThreads);
8088 std::vector< std::future< std::shared_ptr<SourceContext> > > results;
8089 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8090 {
8091 for (const auto &fd : *fn)
8092 {
8093 bool generateSourceFile = fd->generateSourceFile() && !Htags::useHtags;
8094 auto ctx = std::make_shared<SourceContext>(fd.get(),generateSourceFile,*g_outputList);
8095 auto processFile = [ctx]()
8096 {
8097 if (ctx->generateSourceFile)
8098 {
8099 msg("Generating code for file %s...\n",qPrint(ctx->fd->docName()));
8100 }
8101 else
8102 {
8103 msg("Parsing code for file %s...\n",qPrint(ctx->fd->docName()));
8104 }
8105 StringVector filesInSameTu;
8106 ctx->fd->getAllIncludeFilesRecursively(filesInSameTu);
8107 if (ctx->generateSourceFile) // sources need to be shown in the output
8108 {
8109 ctx->fd->writeSourceHeader(ctx->ol);
8110 ctx->fd->writeSourceBody(ctx->ol,nullptr);
8111 ctx->fd->writeSourceFooter(ctx->ol);
8112 }
8113 else if (!ctx->fd->isReference() && Doxygen::parseSourcesNeeded)
8114 // we needed to parse the sources even if we do not show them
8115 {
8116 ctx->fd->parseSource(nullptr);
8117 }
8118 return ctx;
8119 };
8120 results.emplace_back(threadPool.queue(processFile));
8121 }
8122 }
8123 for (auto &f : results)
8124 {
8125 auto ctx = f.get();
8126 }
8127 }
8128 else // single threaded version
8129 {
8130 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8131 {
8132 for (const auto &fd : *fn)
8133 {
8134 StringVector filesInSameTu;
8135 fd->getAllIncludeFilesRecursively(filesInSameTu);
8136 processSourceFile(fd.get(),*g_outputList,nullptr);
8137 }
8138 }
8139 }
8140 }
8141 }
8142}
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:128
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
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, qPrint(), ThreadPool::queue(), QCString::str(), Htags::useHtags, FileDef::writeSourceBody(), FileDef::writeSourceFooter(), and FileDef::writeSourceHeader().

Referenced by generateOutput().

◆ generateGroupDocs()

static void generateGroupDocs ( )
static

Definition at line 9469 of file doxygen.cpp.

9470{
9471 for (const auto &gd : *Doxygen::groupLinkedMap)
9472 {
9473 if (!gd->isReference())
9474 {
9475 gd->writeDocumentation(*g_outputList);
9476 }
9477 }
9478}

References g_outputList, Doxygen::groupLinkedMap, Definition::isReference(), and GroupDef::writeDocumentation().

Referenced by generateOutput().

◆ generateNamespaceClassDocs()

static void generateNamespaceClassDocs ( const ClassLinkedRefMap & classList)
static

Definition at line 9483 of file doxygen.cpp.

9484{
9485 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
9486 if (numThreads>1) // multi threaded processing
9487 {
9488 struct DocContext
9489 {
9490 DocContext(ClassDefMutable *cdm_,const OutputList &ol_)
9491 : cdm(cdm_), ol(ol_) {}
9492 ClassDefMutable *cdm;
9493 OutputList ol;
9494 };
9495 ThreadPool threadPool(numThreads);
9496 std::vector< std::future< std::shared_ptr<DocContext> > > results;
9497 // for each class in the namespace...
9498 for (const auto &cd : classList)
9499 {
9501 if (cdm)
9502 {
9503 auto ctx = std::make_shared<DocContext>(cdm,*g_outputList);
9504 auto processFile = [ctx]()
9505 {
9506 if ( ( ctx->cdm->isLinkableInProject() &&
9507 ctx->cdm->templateMaster()==nullptr
9508 ) // skip external references, anonymous compounds and
9509 // template instances and nested classes
9510 && !ctx->cdm->isHidden() && !ctx->cdm->isEmbeddedInOuterScope()
9511 )
9512 {
9513 msg("Generating docs for compound %s...\n",qPrint(ctx->cdm->name()));
9514 ctx->cdm->writeDocumentation(ctx->ol);
9515 ctx->cdm->writeMemberList(ctx->ol);
9516 }
9517 ctx->cdm->writeDocumentationForInnerClasses(ctx->ol);
9518 return ctx;
9519 };
9520 results.emplace_back(threadPool.queue(processFile));
9521 }
9522 }
9523 // wait for the results
9524 for (auto &f : results)
9525 {
9526 auto ctx = f.get();
9527 }
9528 }
9529 else // single threaded processing
9530 {
9531 // for each class in the namespace...
9532 for (const auto &cd : classList)
9533 {
9535 if (cdm)
9536 {
9537 if ( ( cd->isLinkableInProject() &&
9538 cd->templateMaster()==nullptr
9539 ) // skip external references, anonymous compounds and
9540 // template instances and nested classes
9541 && !cd->isHidden() && !cd->isEmbeddedInOuterScope()
9542 )
9543 {
9544 msg("Generating docs for compound %s...\n",qPrint(cd->name()));
9545
9548 }
9550 }
9551 }
9552 }
9553}
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, ClassDef::isEmbeddedInOuterScope(), Definition::isHidden(), Definition::isLinkableInProject(), msg(), Definition::name(), qPrint(), ThreadPool::queue(), ClassDef::templateMaster(), toClassDefMutable(), ClassDef::writeDocumentation(), ClassDef::writeDocumentationForInnerClasses(), and ClassDef::writeMemberList().

Referenced by generateNamespaceDocs().

◆ generateNamespaceConceptDocs()

static void generateNamespaceConceptDocs ( const ConceptLinkedRefMap & conceptList)
static

Definition at line 9555 of file doxygen.cpp.

9556{
9557 // for each concept in the namespace...
9558 for (const auto &cd : conceptList)
9559 {
9561 if ( cdm && cd->isLinkableInProject() && !cd->isHidden())
9562 {
9563 msg("Generating docs for concept %s...\n",qPrint(cd->name()));
9565 }
9566 }
9567}

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

Referenced by generateNamespaceDocs().

◆ generateNamespaceDocs()

static void generateNamespaceDocs ( )
static

Definition at line 9569 of file doxygen.cpp.

9570{
9571 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
9572
9573 //writeNamespaceIndex(*g_outputList);
9574
9575 // for each namespace...
9576 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9577 {
9578 if (nd->isLinkableInProject())
9579 {
9581 if (ndm)
9582 {
9583 msg("Generating docs for namespace %s\n",qPrint(nd->name()));
9585 }
9586 }
9587
9588 generateNamespaceClassDocs(nd->getClasses());
9589 if (sliceOpt)
9590 {
9591 generateNamespaceClassDocs(nd->getInterfaces());
9592 generateNamespaceClassDocs(nd->getStructs());
9593 generateNamespaceClassDocs(nd->getExceptions());
9594 }
9595 generateNamespaceConceptDocs(nd->getConcepts());
9596 }
9597}
virtual void writeDocumentation(OutputList &ol)=0
static void generateNamespaceConceptDocs(const ConceptLinkedRefMap &conceptList)
Definition doxygen.cpp:9555
static void generateNamespaceClassDocs(const ClassLinkedRefMap &classList)
Definition doxygen.cpp:9483

References Config_getBool, g_outputList, generateNamespaceClassDocs(), generateNamespaceConceptDocs(), NamespaceDef::getClasses(), NamespaceDef::getConcepts(), NamespaceDef::getExceptions(), NamespaceDef::getInterfaces(), NamespaceDef::getStructs(), Definition::isLinkableInProject(), msg(), Definition::name(), Doxygen::namespaceLinkedMap, qPrint(), 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 12420 of file doxygen.cpp.

12421{
12422 AUTO_TRACE();
12423 /**************************************************************************
12424 * Initialize output generators *
12425 **************************************************************************/
12426
12427 /// add extra languages for which we can only produce syntax highlighted code
12429
12430 //// dump all symbols
12431 if (g_dumpSymbolMap)
12432 {
12433 dumpSymbolMap();
12434 exit(0);
12435 }
12436
12437 bool generateHtml = Config_getBool(GENERATE_HTML);
12438 bool generateLatex = Config_getBool(GENERATE_LATEX);
12439 bool generateMan = Config_getBool(GENERATE_MAN);
12440 bool generateRtf = Config_getBool(GENERATE_RTF);
12441 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
12442
12443
12445 if (generateHtml)
12446 {
12450 }
12451 if (generateLatex)
12452 {
12455 }
12456 if (generateDocbook)
12457 {
12460 }
12461 if (generateMan)
12462 {
12465 }
12466 if (generateRtf)
12467 {
12470 }
12471 if (Config_getBool(USE_HTAGS))
12472 {
12474 QCString htmldir = Config_getString(HTML_OUTPUT);
12475 if (!Htags::execute(htmldir))
12476 err("USE_HTAGS is YES but htags(1) failed. \n");
12477 else if (!Htags::loadFilemap(htmldir))
12478 err("htags(1) ended normally but failed to load the filemap. \n");
12479 }
12480
12481 /**************************************************************************
12482 * Generate documentation *
12483 **************************************************************************/
12484
12485 g_s.begin("Generating style sheet...\n");
12486 //printf("writing style info\n");
12487 g_outputList->writeStyleInfo(0); // write first part
12488 g_s.end();
12489
12490 bool searchEngine = Config_getBool(SEARCHENGINE);
12491 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
12492
12493 g_s.begin("Generating search indices...\n");
12494 if (searchEngine && !serverBasedSearch && generateHtml)
12495 {
12497 }
12498
12499 // generate search indices (need to do this before writing other HTML
12500 // pages as these contain a drop down menu with options depending on
12501 // what categories we find in this function.
12502 if (generateHtml && searchEngine)
12503 {
12504 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
12505 Dir searchDir(searchDirName.str());
12506 if (!searchDir.exists() && !searchDir.mkdir(searchDirName.str()))
12507 {
12508 term("Could not create search results directory '%s' $PWD='%s'\n",
12509 qPrint(searchDirName),Dir::currentDirPath().c_str());
12510 }
12511 HtmlGenerator::writeSearchData(searchDirName);
12512 if (!serverBasedSearch) // client side search index
12513 {
12515 }
12516 }
12517 g_s.end();
12518
12519 // copy static stuff
12520 if (generateHtml)
12521 {
12524 copyLogo(Config_getString(HTML_OUTPUT));
12525 copyIcon(Config_getString(HTML_OUTPUT));
12526 copyExtraFiles(Config_getList(HTML_EXTRA_FILES),"HTML_EXTRA_FILES",Config_getString(HTML_OUTPUT));
12527 }
12528 if (generateLatex)
12529 {
12531 copyLogo(Config_getString(LATEX_OUTPUT));
12532 copyIcon(Config_getString(LATEX_OUTPUT));
12533 copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT));
12534 }
12535 if (generateDocbook)
12536 {
12537 copyLogo(Config_getString(DOCBOOK_OUTPUT));
12538 copyIcon(Config_getString(DOCBOOK_OUTPUT));
12539 }
12540 if (generateRtf)
12541 {
12542 copyLogo(Config_getString(RTF_OUTPUT));
12543 copyIcon(Config_getString(RTF_OUTPUT));
12544 copyExtraFiles(Config_getList(RTF_EXTRA_FILES),"RTF_EXTRA_FILES",Config_getString(RTF_OUTPUT));
12545 }
12546
12548 if (fm.hasFormulas() && generateHtml
12549 && !Config_getBool(USE_MATHJAX))
12550 {
12551 g_s.begin("Generating images for formulas in HTML...\n");
12552 fm.generateImages(Config_getString(HTML_OUTPUT), Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg ?
12553 FormulaManager::Format::Vector : FormulaManager::Format::Bitmap, FormulaManager::HighDPI::On);
12554 g_s.end();
12555 }
12556 if (fm.hasFormulas() && generateRtf)
12557 {
12558 g_s.begin("Generating images for formulas in RTF...\n");
12560 g_s.end();
12561 }
12562
12563 if (fm.hasFormulas() && generateDocbook)
12564 {
12565 g_s.begin("Generating images for formulas in Docbook...\n");
12567 g_s.end();
12568 }
12569
12570 g_s.begin("Generating example documentation...\n");
12572 g_s.end();
12573
12574 g_s.begin("Generating file sources...\n");
12576 g_s.end();
12577
12578 g_s.begin("Generating file documentation...\n");
12580 g_s.end();
12581
12582 g_s.begin("Generating page documentation...\n");
12584 g_s.end();
12585
12586 g_s.begin("Generating group documentation...\n");
12588 g_s.end();
12589
12590 g_s.begin("Generating class documentation...\n");
12592 g_s.end();
12593
12594 g_s.begin("Generating concept documentation...\n");
12596 g_s.end();
12597
12598 g_s.begin("Generating module documentation...\n");
12600 g_s.end();
12601
12602 g_s.begin("Generating namespace documentation...\n");
12604 g_s.end();
12605
12606 if (Config_getBool(GENERATE_LEGEND))
12607 {
12608 g_s.begin("Generating graph info page...\n");
12610 g_s.end();
12611 }
12612
12613 g_s.begin("Generating directory documentation...\n");
12615 g_s.end();
12616
12617 if (g_outputList->size()>0)
12618 {
12620 }
12621
12622 g_s.begin("finalizing index lists...\n");
12624 g_s.end();
12625
12626 g_s.begin("writing tag file...\n");
12627 writeTagFile();
12628 g_s.end();
12629
12630 if (Config_getBool(GENERATE_XML))
12631 {
12632 g_s.begin("Generating XML output...\n");
12634 generateXML();
12636 g_s.end();
12637 }
12638 if (Config_getBool(GENERATE_SQLITE3))
12639 {
12640 g_s.begin("Generating SQLITE3 output...\n");
12642 g_s.end();
12643 }
12644
12645 if (Config_getBool(GENERATE_AUTOGEN_DEF))
12646 {
12647 g_s.begin("Generating AutoGen DEF output...\n");
12648 generateDEF();
12649 g_s.end();
12650 }
12651 if (Config_getBool(GENERATE_PERLMOD))
12652 {
12653 g_s.begin("Generating Perl module output...\n");
12655 g_s.end();
12656 }
12657 if (generateHtml && searchEngine && serverBasedSearch)
12658 {
12659 g_s.begin("Generating search index\n");
12660 if (Doxygen::searchIndex.kind()==SearchIndexIntf::Internal) // write own search index
12661 {
12663 Doxygen::searchIndex.write(Config_getString(HTML_OUTPUT)+"/search/search.idx");
12664 }
12665 else // write data for external search index
12666 {
12668 QCString searchDataFile = Config_getString(SEARCHDATA_FILE);
12669 if (searchDataFile.isEmpty())
12670 {
12671 searchDataFile="searchdata.xml";
12672 }
12673 if (!Portable::isAbsolutePath(searchDataFile.data()))
12674 {
12675 searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/");
12676 }
12677 Doxygen::searchIndex.write(searchDataFile);
12678 }
12679 g_s.end();
12680 }
12681
12682 if (generateRtf)
12683 {
12684 g_s.begin("Combining RTF output...\n");
12685 if (!RTFGenerator::preProcessFileInplace(Config_getString(RTF_OUTPUT),"refman.rtf"))
12686 {
12687 err("An error occurred during post-processing the RTF files!\n");
12688 }
12689 g_s.end();
12690 }
12691
12692 g_s.begin("Running plantuml with JAVA...\n");
12694 g_s.end();
12695
12696 if (Config_getBool(HAVE_DOT))
12697 {
12698 g_s.begin("Running dot...\n");
12700 g_s.end();
12701 }
12702
12703 if (generateHtml &&
12704 Config_getBool(GENERATE_HTMLHELP) &&
12705 !Config_getString(HHC_LOCATION).isEmpty())
12706 {
12707 g_s.begin("Running html help compiler...\n");
12709 g_s.end();
12710 }
12711
12712 if ( generateHtml &&
12713 Config_getBool(GENERATE_QHP) &&
12714 !Config_getString(QHG_LOCATION).isEmpty())
12715 {
12716 g_s.begin("Running qhelpgenerator...\n");
12718 g_s.end();
12719 }
12720
12722
12723 msg("type lookup cache used %zu/%zu hits=%" PRIu64 " misses=%" PRIu64 "\n",
12725 Doxygen::typeLookupCache->capacity(),
12727 Doxygen::typeLookupCache->misses());
12728 msg("symbol lookup cache used %zu/%zu hits=%" PRIu64 " misses=%" PRIu64 "\n",
12730 Doxygen::symbolLookupCache->capacity(),
12732 Doxygen::symbolLookupCache->misses());
12733 int typeCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::typeLookupCache->misses()*2/3)); // part of the cache is flushed, hence the 2/3 correction factor
12734 int symbolCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::symbolLookupCache->misses()));
12735 int cacheParam = std::max(typeCacheParam,symbolCacheParam);
12736 if (cacheParam>Config_getInt(LOOKUP_CACHE_SIZE))
12737 {
12738 msg("Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is %d at the cost of higher memory usage.\n",cacheParam);
12739 }
12740
12742 {
12743
12744 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
12745 if (numThreads<1) numThreads=1;
12746 msg("Total elapsed time: %.6f seconds\n(of which an average of %.6f seconds per thread waiting for external tools to finish)\n",
12747 (static_cast<double>(Debug::elapsedTime())),
12748 Portable::getSysElapsedTime()/static_cast<double>(numThreads)
12749 );
12750 g_s.print();
12751
12753 msg("finished...\n");
12755 }
12756 else
12757 {
12758 msg("finished...\n");
12759 }
12760
12761
12762 /**************************************************************************
12763 * Start cleaning up *
12764 **************************************************************************/
12765
12767
12769 Dir thisDir;
12770 thisDir.remove(Doxygen::filterDBFileName.str());
12772 exitTracing();
12774 delete Doxygen::clangUsrMap;
12776
12777 //dumpDocNodeSizes();
12778}
@ Time
Definition debug.h:34
static void clearFlag(const DebugMask mask)
Definition debug.cpp:124
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:134
static double elapsedTime()
Definition debug.cpp:203
static void setFlag(const DebugMask mask)
Definition debug.cpp:119
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:118
static bool generatingXmlOutput
Definition doxygen.h:126
static ClangUsrMap * clangUsrMap
Definition doxygen.h:116
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:75
static void init()
Definition htmlgen.cpp:1104
static void writeSearchPage()
Definition htmlgen.cpp:3030
static void writeTabData()
Additional initialization after indices have been created.
Definition htmlgen.cpp:1260
static void writeSearchData(const QCString &dir)
Definition htmlgen.cpp:1298
static void writeExternalSearchPage()
Definition htmlgen.cpp:3121
void finalize()
Definition indexlist.h:106
Generator for LaTeX output.
Definition latexgen.h:87
static void init()
Definition latexgen.cpp:587
Generator for Man page output.
Definition mangen.h:62
static void init()
Definition mangen.cpp:237
void writeDocumentation(OutputList &ol)
void add()
Definition outputlist.h:328
size_t size() const
Definition outputlist.h:337
void writeStyleInfo(int part)
Definition outputlist.h:373
void cleanup()
Definition outputlist.h:718
static PlantumlManager & instance()
Definition plantuml.cpp:155
void run()
Run plant UML tool for all images.
Definition plantuml.cpp:309
Generator for RTF output.
Definition rtfgen.h:73
static void init()
Definition rtfgen.cpp:415
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:2398
void write(const QCString &file)
void print()
Definition doxygen.cpp:232
void begin(const char *name)
Definition doxygen.cpp:219
void end()
Definition doxygen.cpp:225
void generateDEF()
Definition defgen.cpp:525
void generateDirDocs(OutputList &ol)
Definition dirdef.cpp:1146
static void copyLatexStyleSheet()
Definition doxygen.cpp:9814
static void runQHelpGenerator()
Definition doxygen.cpp:9611
class Statistics g_s
static void copyStyleSheet()
Definition doxygen.cpp:9845
static void generateGroupDocs()
Definition doxygen.cpp:9469
static void generateExampleDocs()
Definition doxygen.cpp:9424
static void dumpSymbolMap()
static void generateFileDocs()
Definition doxygen.cpp:8146
static void copyIcon(const QCString &outputOption)
Definition doxygen.cpp:9923
static void generatePageDocs()
Definition doxygen.cpp:9336
static void generateFileSources()
Definition doxygen.cpp:7980
static void copyLogo(const QCString &outputOption)
Definition doxygen.cpp:9898
static void generateClassDocs()
Definition doxygen.cpp:8565
static int computeIdealCacheParam(size_t v)
static void copyExtraFiles(const StringVector &files, const QCString &filesOption, const QCString &outputOption)
Definition doxygen.cpp:9948
static void runHtmlHelpCompiler()
Definition doxygen.cpp:9599
static bool g_dumpSymbolMap
Definition doxygen.cpp:183
static void generateNamespaceDocs()
Definition doxygen.cpp:9569
static void writeTagFile()
static void generateConceptDocs()
Definition doxygen.cpp:8591
void writeGraphInfo(OutputList &ol)
Definition index.cpp:3923
void writeIndexHierarchy(OutputList &ol)
Definition index.cpp:5564
void finishWarnExit()
Definition message.cpp:299
void deinit()
bool isAbsolutePath(const QCString &fileName)
Definition portable.cpp:505
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:5466
void generateXML()
Definition xmlgen.cpp:2156

References OutputList::add(), addCodeOnlyMappings(), AUTO_TRACE, Statistics::begin(), FormulaManager::Bitmap, Doxygen::clangUsrMap, OutputList::cleanup(), 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(), Statistics::end(), err, Htags::execute(), Dir::exists(), exitTracing(), FALSE, Doxygen::filterDBFileName, IndexList::finalize(), 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(), Statistics::print(), qPrint(), Dir::remove(), DotManager::run(), PlantumlManager::run(), runHtmlHelpCompiler(), runQHelpGenerator(), Doxygen::searchIndex, Debug::setFlag(), OutputList::size(), QCString::str(), Doxygen::symbolLookupCache, term, Debug::Time, TRUE, Doxygen::typeLookupCache, Htags::useHtags, FormulaManager::Vector, SearchIndexIntf::write(), ModuleManager::writeDocumentation(), HtmlGenerator::writeExternalSearchPage(), writeGraphInfo(), writeIndexHierarchy(), writeJavaScriptSearchIndex(), HtmlGenerator::writeSearchData(), HtmlGenerator::writeSearchPage(), OutputList::writeStyleInfo(), HtmlGenerator::writeTabData(), and writeTagFile().

Referenced by main().

◆ generatePageDocs()

static void generatePageDocs ( )
static

Definition at line 9336 of file doxygen.cpp.

9337{
9338 //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageLinkedMap->count());
9339 if (Index::instance().numDocumentedPages()==0) return;
9340 for (const auto &pd : *Doxygen::pageLinkedMap)
9341 {
9342 if (!pd->getGroupDef() && !pd->isReference())
9343 {
9344 msg("Generating docs for page %s...\n",qPrint(pd->name()));
9345 pd->writeDocumentation(*g_outputList);
9346 }
9347 }
9348}

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

Referenced by generateOutput().

◆ generateXRefPages()

static void generateXRefPages ( )
static

Definition at line 5054 of file doxygen.cpp.

5055{
5056 AUTO_TRACE();
5057 for (RefListManager::Ptr &rl : RefListManager::instance())
5058 {
5059 rl->generatePage();
5060 }
5061}
std::unique_ptr< RefList > Ptr
Definition linkedmap.h:38

References AUTO_TRACE, and RefListManager::instance().

Referenced by parseInput().

◆ getArg()

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

Definition at line 10757 of file doxygen.cpp.

10758{
10759 char *s=nullptr;
10760 if (qstrlen(&argv[optInd][2])>0)
10761 s=&argv[optInd][2];
10762 else if (optInd+1<argc && argv[optInd+1][0]!='-')
10763 s=argv[++optInd];
10764 return s;
10765}
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 10052 of file doxygen.cpp.

10053{
10054 QCString fileName=fn;
10055 QCString extension;
10056 int sep = fileName.findRev('/');
10057 int ei = fileName.findRev('.');
10058 if (ei!=-1 && (sep==-1 || ei>sep)) // matches dir/file.ext but not dir.1/file
10059 {
10060 extension=fileName.right(fileName.length()-ei);
10061 }
10062 else
10063 {
10064 extension = ".no_extension";
10065 }
10066
10067 return Doxygen::parserManager->getOutlineParser(extension);
10068}
std::unique_ptr< OutlineParserInterface > getOutlineParser(const QCString &extension)
Gets the interface to the parser associated with a given extension.
Definition parserintf.h:207

References QCString::findRev(), ParserManager::getOutlineParser(), 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 844 of file doxygen.cpp.

847{
848 // for each scope fragment, check if it is a template and advance through
849 // the list if so.
850 int i=0, p=0;
851 auto alIt = tArgLists.begin();
852 while ((i=name.find("::",p))!=-1 && alIt!=tArgLists.end())
853 {
855 if (nd==nullptr)
856 {
857 ClassDef *cd = getClass(name.left(i));
858 if (cd)
859 {
860 if (!cd->templateArguments().empty())
861 {
862 ++alIt;
863 }
864 }
865 }
866 p=i+2;
867 }
868 return alIt!=tArgLists.end() ?
869 std::make_unique<ArgumentList>(*alIt) :
870 std::unique_ptr<ArgumentList>();
871}

References ArgumentList::empty(), LinkedMap< T, Hash, KeyEqual, Map >::find(), 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 3987 of file doxygen.cpp.

3988{
3989 std::map<std::string,int> templateNames;
3990 int count=0;
3991 for (const Argument &arg : templateArguments)
3992 {
3993 static const reg::Ex re(R"(\a[\w:]*)");
3994 reg::Iterator it(name,re);
3996 for (; it!=end ; ++it)
3997 {
3998 const auto &match = *it;
3999 std::string n = match.str();
4000 if (n==arg.name.str())
4001 {
4002 if (templateNames.find(n)==templateNames.end())
4003 {
4004 templateNames.insert(std::make_pair(n,count));
4005 }
4006 }
4007 }
4008 }
4009 return templateNames;
4010}

References end().

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

◆ haveEqualFileNames()

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

Definition at line 8915 of file doxygen.cpp.

8916{
8917 const FileDef *fd = md->getFileDef();
8918 if (!fd)
8919 {
8920 return FALSE;
8921 }
8922
8923 return fd->absFilePath() == root->fileName;
8924}

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

Referenced by findDefineDocumentation().

◆ inheritDocumentation()

static void inheritDocumentation ( )
static

Definition at line 8612 of file doxygen.cpp.

8613{
8614 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8615 {
8616 for (const auto &imd : *mn)
8617 {
8618 MemberDefMutable *md = toMemberDefMutable(imd.get());
8619 //static int count=0;
8620 //printf("%04d Member '%s'\n",count++,qPrint(md->qualifiedName()));
8621 if (md && md->documentation().isEmpty() && md->briefDescription().isEmpty())
8622 { // no documentation yet
8623 const MemberDef *bmd = md->reimplements();
8624 while (bmd && bmd->documentation().isEmpty() &&
8625 bmd->briefDescription().isEmpty()
8626 )
8627 { // search up the inheritance tree for a documentation member
8628 //printf("bmd=%s class=%s\n",qPrint(bmd->name()),qPrint(bmd->getClassDef()->name()));
8629 bmd = bmd->reimplements();
8630 }
8631 if (bmd) // copy the documentation from the reimplemented member
8632 {
8633 md->setInheritsDocsFrom(bmd);
8634 md->setDocumentation(bmd->documentation(),bmd->docFile(),bmd->docLine());
8636 md->setBriefDescription(bmd->briefDescription(),bmd->briefFile(),bmd->briefLine());
8637 md->copyArgumentNames(bmd);
8639 }
8640 }
8641 }
8642 }
8643}
virtual bool isDocsForDefinition() const =0
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 10784 of file doxygen.cpp.

10785{
10786 initResources();
10787 QCString lang = Portable::getenv("LC_ALL");
10788 if (!lang.isEmpty()) Portable::setenv("LANG",lang);
10789 std::setlocale(LC_ALL,"");
10790 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
10791 std::setlocale(LC_NUMERIC,"C");
10792
10794
10796
10820
10821 // register any additional parsers here...
10822
10824
10825#if USE_LIBCLANG
10827#endif
10836 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
10837 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
10838 //Doxygen::tagDestinationDict.setAutoDelete(TRUE);
10840
10841 // initialisation of these globals depends on
10842 // configuration switches so we need to postpone these
10843 Doxygen::globalScope = nullptr;
10851
10852}
static void startTimer()
Definition debug.cpp:198
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:145
void registerParser(const QCString &name, const OutlineParserFactory &outlineParserFactory, const CodeParserFactory &codeParserFactory)
Registers an additional parser.
Definition parserintf.h:178
Class implementing a symbol map that maps symbol names to objects.
Definition symbolmap.h:32
std::function< std::unique_ptr< T >() > make_parser_factory()
void initResources()
std::unordered_map< std::string, const Definition * > ClangUsrMap
Definition doxygen.h:76
void correct_path()
Correct a possible wrong PATH variable.
Definition portable.cpp:524
void setenv(const QCString &variable, const QCString &value)
Definition portable.cpp:303
QCString getenv(const QCString &variable)
Definition portable.cpp:336
void initDefaultExtensionMapping()
Definition util.cpp:5399

References Doxygen::clangUsrMap, Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Portable::correct_path(), 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, ParserManager::registerParser(), Portable::setenv(), Debug::startTimer(), and Doxygen::symbolMap.

Referenced by main().

◆ initResources()

void initResources ( )
extern

Referenced by initDoxygen().

◆ isClassSection()

static bool isClassSection ( const Entry * root)
static

Definition at line 4771 of file doxygen.cpp.

4772{
4773 if ( !root->name.isEmpty() )
4774 {
4775 if (root->section.isCompound())
4776 // is it a compound (class, struct, union, interface ...)
4777 {
4778 return TRUE;
4779 }
4780 else if (root->section.isCompoundDoc())
4781 // is it a documentation block with inheritance info.
4782 {
4783 bool hasExtends = !root->extends.empty();
4784 if (hasExtends) return TRUE;
4785 }
4786 }
4787 return FALSE;
4788}
std::vector< BaseInfo > extends
list of base classes
Definition entry.h:219

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

5233{
5234 const GroupDef *gd = md->getGroupDef();
5235 if (!gd)
5236 {
5237 return allowNoGroup;
5238 }
5239
5240 for (const auto &g : root->groups)
5241 {
5242 if (g.groupname == gd->name())
5243 {
5244 return true; // matching group
5245 }
5246 }
5247
5248 return false;
5249}

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

4313{
4314 QCString n=name;
4315 int index=n.find('<');
4316 if (index!=-1)
4317 {
4318 n=n.left(index);
4319 }
4320 bool result = rightScopeMatch(scope,n);
4321 return result;
4322}

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

Referenced by findClassRelation().

◆ isSpecialization()

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

Definition at line 5464 of file doxygen.cpp.

5468{
5469 auto srcIt = srcTempArgLists.begin();
5470 auto dstIt = dstTempArgLists.begin();
5471 while (srcIt!=srcTempArgLists.end() && dstIt!=dstTempArgLists.end())
5472 {
5473 if ((*srcIt).size()!=(*dstIt).size()) return TRUE;
5474 ++srcIt;
5475 ++dstIt;
5476 }
5477 return FALSE;
5478}

References FALSE, and TRUE.

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

◆ isSymbolHidden()

static bool isSymbolHidden ( const Definition * d)
static

Definition at line 8366 of file doxygen.cpp.

8367{
8368 bool hidden = d->isHidden();
8369 const Definition *parent = d->getOuterScope();
8370 return parent ? hidden || isSymbolHidden(parent) : hidden;
8371}
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:1292

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

2630{
2631 bool result = false;
2632 bool typeIsClass = false;
2633 bool typePtrType = false;
2634 QCString type;
2635 Definition *ctx = nullptr;
2636 FileDef *fd = root->fileDef();
2637 SymbolResolver resolver(fd);
2638
2639 AUTO_TRACE("isVarWithConstructor({})",root->name);
2640 if (root->parent()->section.isCompound())
2641 { // inside a class
2642 result=FALSE;
2643 AUTO_TRACE_EXIT("inside class: result={}",result);
2644 return result;
2645 }
2646 else if ((fd != nullptr) && (fd->name().endsWith(".c") || fd->name().endsWith(".h")))
2647 { // inside a .c file
2648 result=FALSE;
2649 AUTO_TRACE_EXIT("inside C file: result={}",result);
2650 return result;
2651 }
2652 if (root->type.isEmpty())
2653 {
2654 result=FALSE;
2655 AUTO_TRACE_EXIT("no type: result={}",result);
2656 return result;
2657 }
2658 if (!root->parent()->name.isEmpty())
2659 {
2661 }
2662 type = root->type;
2663 // remove qualifiers
2664 findAndRemoveWord(type,"const");
2665 findAndRemoveWord(type,"static");
2666 findAndRemoveWord(type,"volatile");
2667 typePtrType = type.find('*')!=-1 || type.find('&')!=-1;
2668 if (!typePtrType)
2669 {
2670 typeIsClass = resolver.resolveClass(ctx,type)!=nullptr;
2671 int ti=0;
2672 if (!typeIsClass && (ti=type.find('<'))!=-1)
2673 {
2674 typeIsClass=resolver.resolveClass(ctx,type.left(ti))!=nullptr;
2675 }
2676 }
2677 if (typeIsClass) // now we still have to check if the arguments are
2678 // types or values. Since we do not have complete type info
2679 // we need to rely on heuristics :-(
2680 {
2681 if (root->argList.empty())
2682 {
2683 result=FALSE; // empty arg list -> function prototype.
2684 AUTO_TRACE_EXIT("empty arg list: result={}",result);
2685 return result;
2686 }
2687 for (const Argument &a : root->argList)
2688 {
2689 static const reg::Ex initChars(R"([\d"'&*!^]+)");
2691 if (!a.name.isEmpty() || !a.defval.isEmpty())
2692 {
2693 std::string name = a.name.str();
2694 if (reg::search(name,match,initChars) && match.position()==0)
2695 {
2696 result=TRUE;
2697 }
2698 else
2699 {
2700 result=FALSE; // arg has (type,name) pair -> function prototype
2701 }
2702 AUTO_TRACE_EXIT("function prototype: result={}",result);
2703 return result;
2704 }
2705 if (!a.type.isEmpty() &&
2706 (a.type.at(a.type.length()-1)=='*' ||
2707 a.type.at(a.type.length()-1)=='&'))
2708 // type ends with * or & => pointer or reference
2709 {
2710 result=FALSE;
2711 AUTO_TRACE_EXIT("pointer or reference: result={}",result);
2712 return result;
2713 }
2714 if (a.type.isEmpty() || resolver.resolveClass(ctx,a.type)!=nullptr)
2715 {
2716 result=FALSE; // arg type is a known type
2717 AUTO_TRACE_EXIT("known type: result={}",result);
2718 return result;
2719 }
2720 if (checkIfTypedef(ctx,fd,a.type))
2721 {
2722 result=FALSE; // argument is a typedef
2723 AUTO_TRACE_EXIT("typedef: result={}",result);
2724 return result;
2725 }
2726 std::string atype = a.type.str();
2727 if (reg::search(atype,match,initChars) && match.position()==0)
2728 {
2729 result=TRUE; // argument type starts with typical initializer char
2730 AUTO_TRACE_EXIT("argument with init char: result={}",result);
2731 return result;
2732 }
2733 std::string resType=resolveTypeDef(ctx,a.type).str();
2734 if (resType.empty()) resType=atype;
2735 static const reg::Ex idChars(R"(\a\w*)");
2736 if (reg::search(resType,match,idChars) && match.position()==0) // resType starts with identifier
2737 {
2738 resType=match.str();
2739 if (resType=="int" || resType=="long" ||
2740 resType=="float" || resType=="double" ||
2741 resType=="char" || resType=="void" ||
2742 resType=="signed" || resType=="unsigned" ||
2743 resType=="const" || resType=="volatile" )
2744 {
2745 result=FALSE; // type keyword -> function prototype
2746 AUTO_TRACE_EXIT("type keyword: result={}",result);
2747 return result;
2748 }
2749 }
2750 }
2751 result=TRUE;
2752 }
2753
2754 AUTO_TRACE_EXIT("end: result={}",result);
2755 return result;
2756}
2757
2758static void addVariable(const Entry *root,int isFuncPtr=-1)
2759{
2760 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
2761
2762 AUTO_TRACE("VARIABLE_SEC: type='{}' name='{}' args='{}' bodyLine={} endBodyLine={} mGrpId={} relates='{}'",
2763 root->type, root->name, root->args, root->bodyLine, root->endBodyLine, root->mGrpId, root->relates);
2764 //printf("root->parent->name=%s\n",qPrint(root->parent->name));
2765
2766 QCString type = root->type;
2767 QCString name = root->name;
2768 QCString args = root->args;
2769 if (type.isEmpty() && name.find("operator")==-1 &&
2770 (name.find('*')!=-1 || name.find('&')!=-1))
2771 {
2772 // recover from parse error caused by redundant braces
2773 // like in "int *(var[10]);", which is parsed as
2774 // type="" name="int *" args="(var[10])"
2775
2776 type=name;
2777 std::string sargs = args.str();
2778 static const reg::Ex reName(R"(\a\w*)");
2780 if (reg::search(sargs,match,reName))
2781 {
2782 name = match.str(); // e.g. 'var' in '(var[10])'
2783 sargs = match.suffix().str(); // e.g. '[10]) in '(var[10])'
2784 size_t j = sargs.find(')');
2785 if (j!=std::string::npos) args=sargs.substr(0,j); // extract, e.g '[10]' from '[10])'
2786 }
2787 }
2788 else
2789 {
2790 int i=isFuncPtr;
2791 if (i==-1 && (root->spec.isAlias())==0) i=findFunctionPtr(type.str(),root->lang); // for typedefs isFuncPtr is not yet set
2792 AUTO_TRACE_ADD("functionPtr={}",i!=-1?"yes":"no");
2793 if (i>=0) // function pointer
2794 {
2795 int ai = type.find('[',i);
2796 if (ai>i) // function pointer array
2797 {
2798 args.prepend(type.right(type.length()-ai));
2799 type=type.left(ai);
2800 }
2801 else if (type.find(')',i)!=-1) // function ptr, not variable like "int (*bla)[10]"
2802 {
2803 type=type.left(type.length()-1);
2804 args.prepend(") ");
2805 }
2806 }
2807 }
2808 AUTO_TRACE_ADD("after correction: type='{}' name='{}' args='{}'",type,name,args);
2809
2810 QCString scope;
2811 name=removeRedundantWhiteSpace(name);
2812
2813 // find the scope of this variable
2814 int index = computeQualifiedIndex(name);
2815 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
2816 // grouped members are stored with full scope
2817 {
2818 buildScopeFromQualifiedName(name.left(index+2),root->lang,root->tagInfo());
2819 scope=name.left(index);
2820 name=name.mid(index+2);
2821 }
2822 else
2823 {
2824 Entry *p = root->parent();
2825 while (p->section.isScope())
2826 {
2827 QCString scopeName = p->name;
2828 if (!scopeName.isEmpty())
2829 {
2830 scope.prepend(scopeName);
2831 break;
2832 }
2833 p=p->parent();
2834 }
2835 }
2836
2837 type=type.stripWhiteSpace();
2838 ClassDefMutable *cd=nullptr;
2839 bool isRelated=FALSE;
2840 bool isMemberOf=FALSE;
2841
2842 QCString classScope=stripAnonymousNamespaceScope(scope);
2843 classScope=stripTemplateSpecifiersFromScope(classScope,FALSE);
2844 QCString annScopePrefix=scope.left(scope.length()-classScope.length());
2845
2846 if (name.findRev("::")!=-1)
2847 {
2848 if (type=="friend class" || type=="friend struct" ||
2849 type=="friend union")
2850 {
2851 cd=getClassMutable(scope);
2852 if (cd)
2853 {
2854 addVariableToClass(root, // entry
2855 cd, // class to add member to
2856 MemberType_Friend, // type of member
2857 type, // type value as string
2858 name, // name of the member
2859 args, // arguments as string
2860 FALSE, // from Anonymous scope
2861 nullptr, // anonymous member
2862 Protection::Public, // protection
2863 Relationship::Member // related to a class
2864 );
2865 }
2866 }
2867 if (root->bodyLine!=-1 && root->endBodyLine!=-1) // store the body location for later use
2868 {
2869 Doxygen::staticInitMap.insert(std::make_pair(name.str(),BodyInfo{root->startLine,root->bodyLine,root->endBodyLine}));
2870 }
2871
2872
2873 AUTO_TRACE_ADD("static variable {} body=[{}..{}]",name,root->bodyLine,root->endBodyLine);
2874 return; /* skip this member, because it is a
2875 * static variable definition (always?), which will be
2876 * found in a class scope as well, but then we know the
2877 * correct protection level, so only then it will be
2878 * inserted in the correct list!
2879 */
2880 }
2881
2883 if (type=="@")
2885 else if (type.startsWith("typedef "))
2886 mtype=MemberType_Typedef;
2887 else if (type.startsWith("friend "))
2888 mtype=MemberType_Friend;
2889 else if (root->mtype==MethodTypes::Property)
2890 mtype=MemberType_Property;
2891 else if (root->mtype==MethodTypes::Event)
2892 mtype=MemberType_Event;
2893 else if (type.find("sequence<") != -1)
2894 mtype=sliceOpt ? MemberType_Sequence : MemberType_Typedef;
2895 else if (type.find("dictionary<") != -1)
2896 mtype=sliceOpt ? MemberType_Dictionary : MemberType_Typedef;
2897
2898 if (!root->relates.isEmpty()) // related variable
2899 {
2900 isRelated=TRUE;
2901 isMemberOf=(root->relatesType==RelatesType::MemberOf);
2902 if (getClass(root->relates)==nullptr && !scope.isEmpty())
2903 scope=mergeScopes(scope,root->relates);
2904 else
2905 scope=root->relates;
2906 }
2907
2908 cd=getClassMutable(scope);
2909 if (cd==nullptr && classScope!=scope) cd=getClassMutable(classScope);
2910 if (cd)
2911 {
2912 MemberDef *md=nullptr;
2913
2914 // if cd is an anonymous (=tag less) scope we insert the member
2915 // into a non-anonymous parent scope as well. This is needed to
2916 // be able to refer to it using \var or \fn
2917
2918 //int indentDepth=0;
2919 int si=scope.find('@');
2920 //int anonyScopes = 0;
2921 //bool added=FALSE;
2922
2923 bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS);
2924 Relationship relationship = isMemberOf ? Relationship::Foreign :
2925 isRelated ? Relationship::Related :
2927 if (si!=-1 && !inlineSimpleStructs) // anonymous scope or type
2928 {
2929 QCString pScope;
2930 ClassDefMutable *pcd=nullptr;
2931 pScope = scope.left(std::max(si-2,0)); // scope without tag less parts
2932 if (!pScope.isEmpty())
2933 pScope.prepend(annScopePrefix);
2934 else if (annScopePrefix.length()>2)
2935 pScope=annScopePrefix.left(annScopePrefix.length()-2);
2936 if (name.at(0)!='@')
2937 {
2938 if (!pScope.isEmpty() && (pcd=getClassMutable(pScope)))
2939 {
2940 AUTO_TRACE_ADD("Adding anonymous member to scope '{}'",pScope);
2941 md=addVariableToClass(root, // entry
2942 pcd, // class to add member to
2943 mtype, // member type
2944 type, // type value as string
2945 name, // member name
2946 args, // arguments as string
2947 TRUE, // from anonymous scope
2948 nullptr, // from anonymous member
2949 root->protection,
2950 relationship
2951 );
2952 //added=TRUE;
2953 }
2954 else // anonymous scope inside namespace or file => put variable in the global scope
2955 {
2956 if (mtype==MemberType_Variable)
2957 {
2958 AUTO_TRACE_ADD("Adding anonymous member to global scope '{}'");
2959 md=addVariableToFile(root,mtype,pScope,type,name,args,TRUE,nullptr);
2960 }
2961 //added=TRUE;
2962 }
2963 }
2964 }
2965
2966 addVariableToClass(root, // entry
2967 cd, // class to add member to
2968 mtype, // member type
2969 type, // type value as string
2970 name, // name of the member
2971 args, // arguments as string
2972 FALSE, // from anonymous scope
2973 md, // from anonymous member
2974 root->protection,
2975 relationship
2976 );
2977 }
2978 else if (!name.isEmpty()) // global variable
2979 {
2980 addVariableToFile(root,mtype,scope,type,name,args,FALSE,/*nullptr,*/nullptr);
2981 }
2982
2983}
2984
2985//----------------------------------------------------------------------
2986// Searches the Entry tree for typedef documentation sections.
2987// If found they are stored in their class or in the global list.
2988static void buildTypedefList(const Entry *root)
2989{
2990 //printf("buildVarList(%s)\n",qPrint(rootNav->name()));
2991 if (!root->name.isEmpty() &&
2992 root->section.isVariable() &&
2993 root->type.find("typedef ")!=-1 // its a typedef
2994 )
2995 {
2996 AUTO_TRACE();
2997 addVariable(root);
2998 }
2999 for (const auto &e : root->children())
3000 if (!e->section.isEnum())
3001 buildTypedefList(e.get());
3002}
3003
3004//----------------------------------------------------------------------
3005// Searches the Entry tree for sequence documentation sections.
3006// If found they are stored in the global list.
3007static void buildSequenceList(const Entry *root)
3008{
3009 if (!root->name.isEmpty() &&
3010 root->section.isVariable() &&
3011 root->type.find("sequence<")!=-1 // it's a sequence
3012 )
3013 {
3014 AUTO_TRACE();
3015 addVariable(root);
3016 }
3017 for (const auto &e : root->children())
3018 if (!e->section.isEnum())
3019 buildSequenceList(e.get());
3020}
3021
3022//----------------------------------------------------------------------
3023// Searches the Entry tree for dictionary documentation sections.
3024// If found they are stored in the global list.
3025static void buildDictionaryList(const Entry *root)
3026{
3027 if (!root->name.isEmpty() &&
3028 root->section.isVariable() &&
3029 root->type.find("dictionary<")!=-1 // it's a dictionary
3030 )
3031 {
3032 AUTO_TRACE();
3033 addVariable(root);
3034 }
3035 for (const auto &e : root->children())
3036 if (!e->section.isEnum())
3037 buildDictionaryList(e.get());
3038}
3039
3040//----------------------------------------------------------------------
3041// Searches the Entry tree for Variable documentation sections.
3042// If found they are stored in their class or in the global list.
3043
3044static void buildVarList(const Entry *root)
3045{
3046 //printf("buildVarList(%s) section=%08x\n",qPrint(rootNav->name()),rootNav->section());
3047 int isFuncPtr=-1;
3048 if (!root->name.isEmpty() &&
3049 (root->type.isEmpty() || g_compoundKeywords.find(root->type.str())==g_compoundKeywords.end()) &&
3050 (
3051 (root->section.isVariable() // it's a variable
3052 ) ||
3053 (root->section.isFunction() && // or maybe a function pointer variable
3054 (isFuncPtr=findFunctionPtr(root->type.str(),root->lang))!=-1
3055 ) ||
3056 (root->section.isFunction() && // class variable initialized by constructor
3058 )
3059 )
3060 ) // documented variable
3061 {
3062 AUTO_TRACE();
3063 addVariable(root,isFuncPtr);
3064 }
3065 for (const auto &e : root->children())
3066 if (!e->section.isEnum())
3067 buildVarList(e.get());
3068}
3069
3070//----------------------------------------------------------------------
3071// Searches the Entry tree for Interface sections (UNO IDL only).
3072// If found they are stored in their service or in the global list.
3073//
3074
3075static void addInterfaceOrServiceToServiceOrSingleton(
3076 const Entry *root,
3077 ClassDefMutable *cd,
3078 QCString const& rname)
3079{
3080 FileDef *fd = root->fileDef();
3081 enum MemberType type = root->section.isExportedInterface() ? MemberType_Interface : MemberType_Service;
3082 QCString fileName = root->fileName;
3083 if (fileName.isEmpty() && root->tagInfo())
3084 {
3085 fileName = root->tagInfo()->tagName;
3086 }
3087 auto md = createMemberDef(
3088 fileName, root->startLine, root->startColumn, root->type, rname,
3089 "", "", root->protection, root->virt, root->isStatic, Relationship::Member,
3090 type, ArgumentList(), root->argList, root->metaData);
3091 auto mmd = toMemberDefMutable(md.get());
3092 mmd->setTagInfo(root->tagInfo());
3093 mmd->setMemberClass(cd);
3094 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3095 mmd->setDocsForDefinition(false);
3096 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3097 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3098 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3099 mmd->setMemberSpecifiers(root->spec);
3100 mmd->setVhdlSpecifiers(root->vhdlSpec);
3101 mmd->setMemberGroupId(root->mGrpId);
3102 mmd->setTypeConstraints(root->typeConstr);
3103 mmd->setLanguage(root->lang);
3104 mmd->setBodyDef(fd);
3105 mmd->setFileDef(fd);
3106 mmd->addSectionsToDefinition(root->anchors);
3107 QCString const def = root->type + " " + rname;
3108 mmd->setDefinition(def);
3110 mmd->addQualifiers(root->qualifiers);
3111
3112 AUTO_TRACE("Interface member: fileName='{}' type='{}' name='{}' mtype='{}' prot={} virt={} state={} proto={} def='{}'",
3113 fileName,root->type,rname,type,root->protection,root->virt,root->isStatic,root->proto,def);
3114
3115 // add member to the class cd
3116 cd->insertMember(md.get());
3117 // also add the member as a "base" (to get nicer diagrams)
3118 // "optional" interface/service get Protected which turns into dashed line
3119 BaseInfo base(rname,
3120 root->spec.isOptional() ? Protection::Protected : Protection::Public, Specifier::Normal);
3121 TemplateNameMap templateNames;
3122 findClassRelation(root,cd,cd,&base,templateNames,DocumentedOnly,true) ||
3123 findClassRelation(root,cd,cd,&base,templateNames,Undocumented,true);
3124 // add file to list of used files
3125 cd->insertUsedFile(fd);
3126
3127 addMemberToGroups(root,md.get());
3129 root->markAsProcessed();
3130 mmd->setRefItems(root->sli);
3131
3132 // add member to the global list of all members
3134 mn->push_back(std::move(md));
3135}
3136
3137static void buildInterfaceAndServiceList(const Entry *root)
3138{
3139 if (root->section.isExportedInterface() || root->section.isIncludedService())
3140 {
3141 AUTO_TRACE("Exported interface/included service: type='{}' scope='{}' name='{}' args='{}'"
3142 " relates='{}' relatesType='{}' file='{}' line={} bodyLine={} #tArgLists={}"
3143 " mGrpId={} spec={} proto={} docFile='{}'",
3144 root->type, root->parent()->name, root->name, root->args,
3145 root->relates, root->relatesType, root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(),
3146 root->mGrpId, root->spec, root->proto, root->docFile);
3147
3149
3150 if (!rname.isEmpty())
3151 {
3152 QCString scope = root->parent()->name;
3153 ClassDefMutable *cd = getClassMutable(scope);
3154 assert(cd);
3155 if (cd && ((ClassDef::Interface == cd->compoundType()) ||
3156 (ClassDef::Service == cd->compoundType()) ||
3158 {
3159 addInterfaceOrServiceToServiceOrSingleton(root,cd,rname);
3160 }
3161 else
3162 {
3163 assert(false); // was checked by scanner.l
3164 }
3165 }
3166 else if (rname.isEmpty())
3167 {
3168 warn(root->fileName,root->startLine,
3169 "Illegal member name found.");
3170 }
3171 }
3172 // can only have these in IDL anyway
3173 switch (root->lang)
3174 {
3175 case SrcLangExt::Unknown: // fall through (root node always is Unknown)
3176 case SrcLangExt::IDL:
3177 for (const auto &e : root->children()) buildInterfaceAndServiceList(e.get());
3178 break;
3179 default:
3180 return; // nothing to do here
3181 }
3182}
3183
3184
3185//----------------------------------------------------------------------
3186// Searches the Entry tree for Function sections.
3187// If found they are stored in their class or in the global list.
3188
3189static void addMethodToClass(const Entry *root,ClassDefMutable *cd,
3190 const QCString &rtype,const QCString &rname,const QCString &rargs,
3191 bool isFriend,
3192 Protection protection,bool stat,Specifier virt,TypeSpecifier spec,
3193 const QCString &relates
3194 )
3195{
3196 FileDef *fd=root->fileDef();
3197
3198 QCString type = rtype;
3199 QCString args = rargs;
3200
3202 name.stripPrefix("::");
3203
3205 if (isFriend) mtype=MemberType_Friend;
3206 else if (root->mtype==MethodTypes::Signal) mtype=MemberType_Signal;
3207 else if (root->mtype==MethodTypes::Slot) mtype=MemberType_Slot;
3208 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType_DCOP;
3209
3210 // strip redundant template specifier for constructors
3211 int i = -1;
3212 int j = -1;
3213 if ((fd==nullptr || fd->getLanguage()==SrcLangExt::Cpp) &&
3214 !name.startsWith("operator ") && // not operator
3215 (i=name.find('<'))!=-1 && // containing <
3216 (j=name.find('>'))!=-1 && // or >
3217 (j!=i+2 || name.at(i+1)!='=') // but not the C++20 spaceship operator <=>
3218 )
3219 {
3220 name=name.left(i);
3221 }
3222
3223 QCString fileName = root->fileName;
3224 if (fileName.isEmpty() && root->tagInfo())
3225 {
3226 fileName = root->tagInfo()->tagName;
3227 }
3228
3229 //printf("root->name='%s; args='%s' root->argList='%s'\n",
3230 // qPrint(root->name),qPrint(args),qPrint(argListToString(root->argList))
3231 // );
3232
3233 // adding class member
3234 Relationship relationship = relates.isEmpty() ? Relationship::Member :
3237 auto md = createMemberDef(
3238 fileName,root->startLine,root->startColumn,
3239 type,name,args,root->exception,
3240 protection,virt,
3241 stat && root->relatesType!=RelatesType::MemberOf,
3242 relationship,
3243 mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
3244 root->argList, root->metaData);
3245 auto mmd = toMemberDefMutable(md.get());
3246 mmd->setTagInfo(root->tagInfo());
3247 mmd->setMemberClass(cd);
3248 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3249 mmd->setDocsForDefinition(!root->proto);
3250 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3251 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3252 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3253 mmd->setMemberSpecifiers(spec);
3254 mmd->setVhdlSpecifiers(root->vhdlSpec);
3255 mmd->setMemberGroupId(root->mGrpId);
3256 mmd->setTypeConstraints(root->typeConstr);
3257 mmd->setLanguage(root->lang);
3258 mmd->setRequiresClause(root->req);
3259 mmd->setId(root->id);
3260 mmd->setBodyDef(fd);
3261 mmd->setFileDef(fd);
3262 mmd->addSectionsToDefinition(root->anchors);
3263 QCString def;
3265 SrcLangExt lang = cd->getLanguage();
3266 QCString scopeSeparator=getLanguageSpecificSeparator(lang);
3267 if (scopeSeparator!="::")
3268 {
3269 qualScope = substitute(qualScope,"::",scopeSeparator);
3270 }
3271 if (lang==SrcLangExt::PHP)
3272 {
3273 // for PHP we use Class::method and Namespace\method
3274 scopeSeparator="::";
3275 }
3276// QCString optArgs = root->argList.empty() ? args : QCString();
3277 if (!relates.isEmpty() || isFriend || Config_getBool(HIDE_SCOPE_NAMES))
3278 {
3279 if (!type.isEmpty())
3280 {
3281 def=type+" "+name; //+optArgs;
3282 }
3283 else
3284 {
3285 def=name; //+optArgs;
3286 }
3287 }
3288 else
3289 {
3290 if (!type.isEmpty())
3291 {
3292 def=type+" "+qualScope+scopeSeparator+name; //+optArgs;
3293 }
3294 else
3295 {
3296 def=qualScope+scopeSeparator+name; //+optArgs;
3297 }
3298 }
3299 def.stripPrefix("friend ");
3300 mmd->setDefinition(def);
3302 mmd->addQualifiers(root->qualifiers);
3303
3304 AUTO_TRACE("function member: type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
3305 type, qualScope, rname, args, root->proto, def);
3306
3307 // add member to the class cd
3308 cd->insertMember(md.get());
3309 // add file to list of used files
3310 cd->insertUsedFile(fd);
3311
3312 addMemberToGroups(root,md.get());
3314 root->markAsProcessed();
3315 mmd->setRefItems(root->sli);
3316
3317 // add member to the global list of all members
3318 //printf("Adding member=%s class=%s\n",qPrint(md->name()),qPrint(cd->name()));
3320 mn->push_back(std::move(md));
3321}
3322
3323//------------------------------------------------------------------------------------------
3324
3325static void addGlobalFunction(const Entry *root,const QCString &rname,const QCString &sc)
3326{
3327 QCString scope = sc;
3328
3329 // new global function
3331 auto md = createMemberDef(
3332 root->fileName,root->startLine,root->startColumn,
3333 root->type,name,root->args,root->exception,
3334 root->protection,root->virt,root->isStatic,Relationship::Member,
3336 !root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(),
3337 root->argList,root->metaData);
3338 auto mmd = toMemberDefMutable(md.get());
3339 mmd->setTagInfo(root->tagInfo());
3340 mmd->setLanguage(root->lang);
3341 mmd->setId(root->id);
3342 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3343 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3344 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3345 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
3346 mmd->setDocsForDefinition(!root->proto);
3347 mmd->setTypeConstraints(root->typeConstr);
3348 //md->setBody(root->body);
3349 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3350 FileDef *fd=root->fileDef();
3351 mmd->setBodyDef(fd);
3352 mmd->addSectionsToDefinition(root->anchors);
3353 mmd->setMemberSpecifiers(root->spec);
3354 mmd->setVhdlSpecifiers(root->vhdlSpec);
3355 mmd->setMemberGroupId(root->mGrpId);
3356 mmd->setRequiresClause(root->req);
3357 mmd->setExplicitExternal(root->explicitExternal,root->fileName,root->startLine,root->startColumn);
3358
3359 NamespaceDefMutable *nd = nullptr;
3360 // see if the function is inside a namespace that was not part of
3361 // the name already (in that case nd should be non-zero already)
3362 if (root->parent()->section.isNamespace())
3363 {
3364 //QCString nscope=removeAnonymousScopes(root->parent()->name);
3365 QCString nscope=root->parent()->name;
3366 if (!nscope.isEmpty())
3367 {
3368 nd = getResolvedNamespaceMutable(nscope);
3369 }
3370 }
3371 else if (root->parent()->section.isGroupDoc() && !scope.isEmpty())
3372 {
3374 }
3375
3376 if (!scope.isEmpty())
3377 {
3379 if (sep!="::")
3380 {
3381 scope = substitute(scope,"::",sep);
3382 }
3383 scope+=sep;
3384 }
3385
3386 if (Config_getBool(HIDE_SCOPE_NAMES)) scope = "";
3387 QCString def;
3388 //QCString optArgs = root->argList.empty() ? QCString() : root->args;
3389 if (!root->type.isEmpty())
3390 {
3391 def=root->type+" "+scope+name; //+optArgs;
3392 }
3393 else
3394 {
3395 def=scope+name; //+optArgs;
3396 }
3397 AUTO_TRACE("new non-member function type='{}' scope='{}' name='{}' args='{}' proto={} def='{}'",
3398 root->type,scope,rname,root->args,root->proto,def);
3399 mmd->setDefinition(def);
3401 mmd->addQualifiers(root->qualifiers);
3402
3403 mmd->setRefItems(root->sli);
3404 if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@')
3405 {
3406 // add member to namespace
3407 mmd->setNamespace(nd);
3408 nd->insertMember(md.get());
3409 }
3410 if (fd)
3411 {
3412 // add member to the file (we do this even if we have already
3413 // inserted it into the namespace)
3414 mmd->setFileDef(fd);
3415 fd->insertMember(md.get());
3416 }
3417
3418 addMemberToGroups(root,md.get());
3420 if (root->relatesType == RelatesType::Simple) // if this is a relatesalso command,
3421 // allow find Member to pick it up
3422 {
3423 root->markAsProcessed(); // Otherwise we have finished with this entry.
3424 }
3425
3426 // add member to the list of file members
3428 mn->push_back(std::move(md));
3429}
3430
3431//------------------------------------------------------------------------------------------
3432
3433static void buildFunctionList(const Entry *root)
3434{
3435 if (root->section.isFunction())
3436 {
3437 AUTO_TRACE("member function: type='{}' scope='{}' name='{}' args='{}' relates='{}' relatesType='{}'"
3438 " file='{}' line={} bodyLine={} #tArgLists={} mGrpId={}"
3439 " spec={} proto={} docFile='{}'",
3440 root->type, root->parent()->name, root->name, root->args, root->relates, root->relatesType,
3441 root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(), root->mGrpId,
3442 root->spec, root->proto, root->docFile);
3443
3444 bool isFriend=root->type.find("friend ")!=-1;
3446 //printf("rname=%s\n",qPrint(rname));
3447
3448 QCString scope;
3449 int index = computeQualifiedIndex(rname);
3450 if (index!=-1 && root->parent()->section.isGroupDoc() && root->parent()->tagInfo())
3451 // grouped members are stored with full scope
3452 {
3453 buildScopeFromQualifiedName(rname.left(index+2),root->lang,root->tagInfo());
3454 scope=rname.left(index);
3455 rname=rname.mid(index+2);
3456 }
3457 else
3458 {
3459 scope=root->parent()->name; //stripAnonymousNamespaceScope(root->parent->name);
3460 }
3461 if (!rname.isEmpty() && scope.find('@')==-1)
3462 {
3463 ClassDefMutable *cd=nullptr;
3464 // check if this function's parent is a class
3466
3467 FileDef *rfd=root->fileDef();
3468
3469 int memIndex=rname.findRev("::");
3470
3471 cd=getClassMutable(scope);
3472 if (cd && scope+"::"==rname.left(scope.length()+2)) // found A::f inside A
3473 {
3474 // strip scope from name
3475 rname=rname.right(rname.length()-root->parent()->name.length()-2);
3476 }
3477
3478 bool isMember=FALSE;
3479 if (memIndex!=-1)
3480 {
3481 int ts=rname.find('<');
3482 int te=rname.find('>');
3483 if (memIndex>0 && (ts==-1 || te==-1))
3484 {
3485 // note: the following code was replaced by inMember=TRUE to deal with a
3486 // function rname='X::foo' of class X inside a namespace also called X...
3487 // bug id 548175
3488 //nd = Doxygen::namespaceLinkedMap->find(rname.left(memIndex));
3489 //isMember = nd==nullptr;
3490 //if (nd)
3491 //{
3492 // // strip namespace scope from name
3493 // scope=rname.left(memIndex);
3494 // rname=rname.right(rname.length()-memIndex-2);
3495 //}
3496 isMember = TRUE;
3497 }
3498 else
3499 {
3500 isMember=memIndex<ts || memIndex>te;
3501 }
3502 }
3503
3504 if (!root->parent()->name.isEmpty() && root->parent()->section.isCompound() && cd)
3505 {
3506 AUTO_TRACE_ADD("member '{}' of class '{}'", rname,cd->name());
3507 addMethodToClass(root,cd,root->type,rname,root->args,isFriend,
3508 root->protection,root->isStatic,root->virt,root->spec,root->relates);
3509 }
3510 else if (!root->parent()->section.isCompound() && !root->parent()->section.isObjcImpl() &&
3511 !isMember &&
3512 (root->relates.isEmpty() || root->relatesType==RelatesType::Duplicate) &&
3513 !root->type.startsWith("extern ") && !root->type.startsWith("typedef ")
3514 )
3515 // no member => unrelated function
3516 {
3517 /* check the uniqueness of the function name in the file.
3518 * A file could contain a function prototype and a function definition
3519 * or even multiple function prototypes.
3520 */
3521 bool found=FALSE;
3522 MemberDef *md_found=nullptr;
3524 if (mn)
3525 {
3526 AUTO_TRACE_ADD("function '{}' already found",rname);
3527 for (const auto &imd : *mn)
3528 {
3529 MemberDefMutable *md = toMemberDefMutable(imd.get());
3530 if (md)
3531 {
3532 const NamespaceDef *mnd = md->getNamespaceDef();
3533 NamespaceDef *rnd = nullptr;
3534 //printf("root namespace=%s\n",qPrint(rootNav->parent()->name()));
3535 QCString fullScope = scope;
3536 QCString parentScope = root->parent()->name;
3537 if (!parentScope.isEmpty() && !leftScopeMatch(parentScope,scope))
3538 {
3539 if (!scope.isEmpty()) fullScope.prepend("::");
3540 fullScope.prepend(parentScope);
3541 }
3542 //printf("fullScope=%s\n",qPrint(fullScope));
3543 rnd = getResolvedNamespace(fullScope);
3544 const FileDef *mfd = md->getFileDef();
3545 QCString nsName,rnsName;
3546 if (mnd) nsName = mnd->name();
3547 if (rnd) rnsName = rnd->name();
3548 //printf("matching arguments for %s%s %s%s\n",
3549 // qPrint(md->name()),md->argsString(),qPrint(rname),qPrint(argListToString(root->argList)));
3550 const ArgumentList &mdAl = md->argumentList();
3551 const ArgumentList &mdTempl = md->templateArguments();
3552
3553 // in case of template functions, we need to check if the
3554 // functions have the same number of template parameters
3555 bool sameNumTemplateArgs = TRUE;
3556 bool matchingReturnTypes = TRUE;
3557 bool sameRequiresClause = TRUE;
3558 if (!mdTempl.empty() && !root->tArgLists.empty())
3559 {
3560 if (mdTempl.size()!=root->tArgLists.back().size())
3561 {
3562 sameNumTemplateArgs = FALSE;
3563 }
3564 if (md->typeString()!=removeRedundantWhiteSpace(root->type))
3565 {
3566 matchingReturnTypes = FALSE;
3567 }
3568 if (md->requiresClause()!=root->req)
3569 {
3570 sameRequiresClause = FALSE;
3571 }
3572 }
3573 else if (!mdTempl.empty() || !root->tArgLists.empty())
3574 { // if one has template parameters and the other doesn't then that also counts as a
3575 // difference
3576 sameNumTemplateArgs = FALSE;
3577 }
3578
3579 bool staticsInDifferentFiles =
3580 root->isStatic && md->isStatic() && root->fileName!=md->getDefFileName();
3581
3582 if (
3583 matchArguments2(md->getOuterScope(),mfd,&mdAl,
3584 rnd ? rnd : Doxygen::globalScope,rfd,&root->argList,
3585 FALSE,root->lang) &&
3586 sameNumTemplateArgs &&
3587 matchingReturnTypes &&
3588 sameRequiresClause &&
3589 !staticsInDifferentFiles
3590 )
3591 {
3592 GroupDef *gd=nullptr;
3593 if (!root->groups.empty() && !root->groups.front().groupname.isEmpty())
3594 {
3595 gd = Doxygen::groupLinkedMap->find(root->groups.front().groupname);
3596 }
3597 //printf("match!\n");
3598 //printf("mnd=%p rnd=%p nsName=%s rnsName=%s\n",mnd,rnd,qPrint(nsName),qPrint(rnsName));
3599 // see if we need to create a new member
3600 found=(mnd && rnd && nsName==rnsName) || // members are in the same namespace
3601 ((mnd==nullptr && rnd==nullptr && mfd!=nullptr && // no external reference and
3602 mfd->absFilePath()==root->fileName // prototype in the same file
3603 )
3604 );
3605 // otherwise, allow a duplicate global member with the same argument list
3606 if (!found && gd && gd==md->getGroupDef() && nsName==rnsName)
3607 {
3608 // member is already in the group, so we don't want to add it again.
3609 found=TRUE;
3610 }
3611
3612 AUTO_TRACE_ADD("combining function with prototype found={} in namespace '{}'",found,nsName);
3613
3614 if (found)
3615 {
3616 // merge argument lists
3617 ArgumentList mergedArgList = root->argList;
3618 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.isEmpty());
3619 // merge documentation
3620 if (md->documentation().isEmpty() && !root->doc.isEmpty())
3621 {
3622 if (root->proto)
3623 {
3625 }
3626 else
3627 {
3629 }
3630 }
3631
3632 md->setDocumentation(root->doc,root->docFile,root->docLine);
3634 md->setDocsForDefinition(!root->proto);
3635 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
3636 {
3637 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3638 md->setBodyDef(rfd);
3639 }
3640
3641 if (md->briefDescription().isEmpty() && !root->brief.isEmpty())
3642 {
3643 md->setArgsString(root->args);
3644 }
3645 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3646
3648
3650 md->addQualifiers(root->qualifiers);
3651
3652 // merge ingroup specifiers
3653 if (md->getGroupDef()==nullptr && !root->groups.empty())
3654 {
3655 addMemberToGroups(root,md);
3656 }
3657 else if (md->getGroupDef()!=nullptr && root->groups.empty())
3658 {
3659 //printf("existing member is grouped, new member not\n");
3660 }
3661 else if (md->getGroupDef()!=nullptr && !root->groups.empty())
3662 {
3663 //printf("both members are grouped\n");
3664 }
3666
3667 // if md is a declaration and root is the corresponding
3668 // definition, then turn md into a definition.
3669 if (md->isPrototype() && !root->proto)
3670 {
3671 md->setDeclFile(md->getDefFileName(),md->getDefLine(),md->getDefColumn());
3672 md->setPrototype(FALSE,root->fileName,root->startLine,root->startColumn);
3673 }
3674 // if md is already the definition, then add the declaration info
3675 else if (!md->isPrototype() && root->proto)
3676 {
3677 md->setDeclFile(root->fileName,root->startLine,root->startColumn);
3678 }
3679 }
3680 }
3681 }
3682 if (found)
3683 {
3684 md_found = md;
3685 break;
3686 }
3687 }
3688 }
3689 if (!found) /* global function is unique with respect to the file */
3690 {
3691 addGlobalFunction(root,rname,scope);
3692 }
3693 else
3694 {
3695 FileDef *fd=root->fileDef();
3696 if (fd)
3697 {
3698 // add member to the file (we do this even if we have already
3699 // inserted it into the namespace)
3700 fd->insertMember(md_found);
3701 }
3702 }
3703
3704 AUTO_TRACE_ADD("unrelated function type='{}' name='{}' args='{}'",root->type,rname,root->args);
3705 }
3706 else
3707 {
3708 AUTO_TRACE_ADD("function '{}' is not processed",rname);
3709 }
3710 }
3711 else if (rname.isEmpty())
3712 {
3713 warn(root->fileName,root->startLine,
3714 "Illegal member name found."
3715 );
3716 }
3717 }
3718 for (const auto &e : root->children()) buildFunctionList(e.get());
3719}
3720
3721//----------------------------------------------------------------------
3722
3723static void findFriends()
3724{
3725 AUTO_TRACE();
3726 for (const auto &fn : *Doxygen::functionNameLinkedMap) // for each global function name
3727 {
3728 MemberName *mn = Doxygen::memberNameLinkedMap->find(fn->memberName());
3729 if (mn)
3730 { // there are members with the same name
3731 // for each function with that name
3732 for (const auto &ifmd : *fn)
3733 {
3734 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
3735 // for each member with that name
3736 for (const auto &immd : *mn)
3737 {
3738 MemberDefMutable *mmd = toMemberDefMutable(immd.get());
3739 //printf("Checking for matching arguments
3740 // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n",
3741 // mmd->isRelated(),mmd->isFriend(),mmd->isFunction());
3742 if (fmd && mmd &&
3743 (mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) &&
3744 matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), &mmd->argumentList(),
3745 fmd->getOuterScope(), fmd->getFileDef(), &fmd->argumentList(),
3746 TRUE,mmd->getLanguage()
3747 )
3748
3749 ) // if the member is related and the arguments match then the
3750 // function is actually a friend.
3751 {
3752 AUTO_TRACE_ADD("Merging related global and member '{}' isFriend={} isRelated={} isFunction={}",
3753 mmd->name(),mmd->isFriend(),mmd->isRelated(),mmd->isFunction());
3754 const ArgumentList &mmdAl = mmd->argumentList();
3755 const ArgumentList &fmdAl = fmd->argumentList();
3756 mergeArguments(const_cast<ArgumentList&>(fmdAl),const_cast<ArgumentList&>(mmdAl));
3757
3758 // reset argument lists to add missing default parameters
3759 QCString mmdAlStr = argListToString(mmdAl);
3760 QCString fmdAlStr = argListToString(fmdAl);
3761 mmd->setArgsString(mmdAlStr);
3762 fmd->setArgsString(fmdAlStr);
3763 mmd->moveDeclArgumentList(std::make_unique<ArgumentList>(mmdAl));
3764 fmd->moveDeclArgumentList(std::make_unique<ArgumentList>(fmdAl));
3765 AUTO_TRACE_ADD("friend args='{}' member args='{}'",argListToString(fmd->argumentList()),argListToString(mmd->argumentList()));
3766
3767 if (!fmd->documentation().isEmpty())
3768 {
3769 mmd->setDocumentation(fmd->documentation(),fmd->docFile(),fmd->docLine());
3770 }
3771 else if (!mmd->documentation().isEmpty())
3772 {
3773 fmd->setDocumentation(mmd->documentation(),mmd->docFile(),mmd->docLine());
3774 }
3775 if (mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
3776 {
3777 mmd->setBriefDescription(fmd->briefDescription(),fmd->briefFile(),fmd->briefLine());
3778 }
3779 else if (!mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
3780 {
3781 fmd->setBriefDescription(mmd->briefDescription(),mmd->briefFile(),mmd->briefLine());
3782 }
3783 if (!fmd->inbodyDocumentation().isEmpty())
3784 {
3786 }
3787 else if (!mmd->inbodyDocumentation().isEmpty())
3788 {
3790 }
3791 //printf("body mmd %d fmd %d\n",mmd->getStartBodyLine(),fmd->getStartBodyLine());
3792 if (mmd->getStartBodyLine()==-1 && fmd->getStartBodyLine()!=-1)
3793 {
3794 mmd->setBodySegment(fmd->getDefLine(),fmd->getStartBodyLine(),fmd->getEndBodyLine());
3795 mmd->setBodyDef(fmd->getBodyDef());
3796 //mmd->setBodyMember(fmd);
3797 }
3798 else if (mmd->getStartBodyLine()!=-1 && fmd->getStartBodyLine()==-1)
3799 {
3800 fmd->setBodySegment(mmd->getDefLine(),mmd->getStartBodyLine(),mmd->getEndBodyLine());
3801 fmd->setBodyDef(mmd->getBodyDef());
3802 //fmd->setBodyMember(mmd);
3803 }
3805
3807
3808 mmd->addQualifiers(fmd->getQualifiers());
3809 fmd->addQualifiers(mmd->getQualifiers());
3810
3811 }
3812 }
3813 }
3814 }
static StaticInitMap staticInitMap
Definition doxygen.h:134
virtual bool isFriend() const =0
virtual bool isRelated() const =0
virtual StringVector getQualifiers() 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 addVariable(yyscan_t yyscanner, QCString type, QCString name)
Definition code.l:2274
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:2181
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:2336
static bool isVarWithConstructor(const Entry *root)
Definition doxygen.cpp:2629
Data associated with description found in the body.
Definition definition.h:63
@ MemberType_Sequence
Definition types.h:296
@ MemberType_Interface
Definition types.h:294
@ MemberType_Service
Definition types.h:295
@ MemberType_Dictionary
Definition types.h:297
@ MemberType_Event
Definition types.h:293
Specifier
Virtualness of a member.
Definition types.h:29
bool checkIfTypedef(const Definition *scope, const FileDef *fileScope, const QCString &n)
Definition util.cpp:5576
int computeQualifiedIndex(const QCString &name)
Return the index of the last :: in the string name that is still before the first <.
Definition util.cpp:7149
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:5249
if(strLen >35 &&floatingIndex >30 &&autoBreak)
Definition util.cpp:948
void mergeMemberOverrideOptions(MemberDefMutable *md1, MemberDefMutable *md2)
Definition util.cpp:7177

References Entry::argList, AUTO_TRACE, AUTO_TRACE_EXIT, checkIfTypedef(), ArgumentList::empty(), QCString::endsWith(), FALSE, Entry::fileDef(), LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::find(), findAndRemoveWord(), EntryType::isCompound(), QCString::isEmpty(), QCString::left(), Definition::name(), Entry::name, Doxygen::namespaceLinkedMap, Entry::parent(), SymbolResolver::resolveClass(), resolveTypeDef(), reg::search(), Entry::section, QCString::str(), TRUE, and Entry::type.

◆ make_parser_factory()

template<class T >
std::function< std::unique_ptr< T >() > make_parser_factory ( )

Definition at line 10779 of file doxygen.cpp.

10780{
10781 return []() { return std::make_unique<T>(); };
10782}

Referenced by initDoxygen().

◆ mergeCategories()

static void mergeCategories ( )
static

Definition at line 7928 of file doxygen.cpp.

7929{
7930 // merge members of categories into the class they extend
7931 for (const auto &cd : *Doxygen::classLinkedMap)
7932 {
7933 int i=cd->name().find('(');
7934 if (i!=-1) // it is an Objective-C category
7935 {
7936 QCString baseName=cd->name().left(i);
7937 ClassDefMutable *baseClass=toClassDefMutable(Doxygen::classLinkedMap->find(baseName));
7938 if (baseClass)
7939 {
7940 //printf("*** merging members of category %s into %s\n",
7941 // qPrint(cd->name()),qPrint(baseClass->name()));
7942 baseClass->mergeCategory(cd.get());
7943 }
7944 }
7945 }
7946}
virtual void mergeCategory(ClassDef *category)=0

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

Referenced by parseInput().

◆ organizeSubGroups()

static void organizeSubGroups ( const Entry * root)
static

Definition at line 470 of file doxygen.cpp.

471{
472 //printf("Defining groups\n");
473 // first process the @defgroups blocks
475 //printf("Additional groups\n");
476 // then process the @addtogroup, @weakgroup blocks
478}
static void organizeSubGroupsFiltered(const Entry *root, bool additional)
Definition doxygen.cpp:451

References FALSE, organizeSubGroupsFiltered(), and TRUE.

Referenced by parseInput().

◆ organizeSubGroupsFiltered()

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

Definition at line 451 of file doxygen.cpp.

452{
453 if (root->section.isGroupDoc() && !root->name.isEmpty())
454 {
455 AUTO_TRACE("additional={}",additional);
456 if ((root->groupDocType==Entry::GROUPDOC_NORMAL && !additional) ||
457 (root->groupDocType!=Entry::GROUPDOC_NORMAL && additional))
458 {
460 if (gd)
461 {
462 AUTO_TRACE_ADD("adding {} to group {}",root->name,gd->name());
463 addGroupToGroups(root,gd);
464 }
465 }
466 }
467 for (const auto &e : root->children()) organizeSubGroupsFiltered(e.get(),additional);
468}
void addGroupToGroups(const Entry *root, GroupDef *subGroup)

References addGroupToGroups(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::children(), LinkedMap< T, Hash, KeyEqual, Map >::find(), 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 10070 of file doxygen.cpp.

10073{
10074 QCString fileName=fn;
10075 AUTO_TRACE("fileName={}",fileName);
10076 QCString extension;
10077 int ei = fileName.findRev('.');
10078 if (ei!=-1)
10079 {
10080 extension=fileName.right(fileName.length()-ei);
10081 }
10082 else
10083 {
10084 extension = ".no_extension";
10085 }
10086
10087 FileInfo fi(fileName.str());
10088 std::string preBuf;
10089
10090 if (Config_getBool(ENABLE_PREPROCESSING) &&
10091 parser.needsPreprocessing(extension))
10092 {
10093 Preprocessor preprocessor;
10094 const StringVector &includePath = Config_getList(INCLUDE_PATH);
10095 for (const auto &s : includePath)
10096 {
10097 std::string absPath = FileInfo(s).absFilePath();
10098 preprocessor.addSearchDir(absPath.c_str());
10099 }
10100 std::string inBuf;
10101 msg("Preprocessing %s...\n",qPrint(fn));
10102 readInputFile(fileName,inBuf);
10103 addTerminalCharIfMissing(inBuf,'\n');
10104 preprocessor.processFile(fileName,inBuf,preBuf);
10105 }
10106 else // no preprocessing
10107 {
10108 msg("Reading %s...\n",qPrint(fn));
10109 readInputFile(fileName,preBuf);
10110 addTerminalCharIfMissing(preBuf,'\n');
10111 }
10112
10113 std::string convBuf;
10114 convBuf.reserve(preBuf.size()+1024);
10115
10116 // convert multi-line C++ comments to C style comments
10117 convertCppComments(preBuf,convBuf,fileName.str());
10118
10119 std::shared_ptr<Entry> fileRoot = std::make_shared<Entry>();
10120 // use language parse to parse the file
10121 if (clangParser)
10122 {
10123 if (newTU) clangParser->parse();
10124 clangParser->switchToFile(fd);
10125 }
10126 parser.parseInput(fileName,convBuf.data(),fileRoot,clangParser);
10127 fileRoot->setFileDef(fd);
10128 return fileRoot;
10129}
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:3966
void addSearchDir(const QCString &dir)
Definition pre.l:3948
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:5764

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(), qPrint(), 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 10132 of file doxygen.cpp.

10133{
10134 AUTO_TRACE();
10135#if USE_LIBCLANG
10137 {
10138 StringUnorderedSet processedFiles;
10139
10140 // create a dictionary with files to process
10141 StringUnorderedSet filesToProcess;
10142 for (const auto &s : g_inputFiles)
10143 {
10144 filesToProcess.insert(s);
10145 }
10146
10147 std::mutex processedFilesLock;
10148 // process source files (and their include dependencies)
10149 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10150 msg("Processing input using %zu threads.\n",numThreads);
10151 ThreadPool threadPool(numThreads);
10152 using FutureType = std::vector< std::shared_ptr<Entry> >;
10153 std::vector< std::future< FutureType > > results;
10154 for (const auto &s : g_inputFiles)
10155 {
10156 bool ambig = false;
10157 FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
10158 ASSERT(fd!=nullptr);
10159 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp) // this is a source file
10160 {
10161 // lambda representing the work to executed by a thread
10162 auto processFile = [s,&filesToProcess,&processedFilesLock,&processedFiles]() {
10163 bool ambig_l = false;
10164 std::vector< std::shared_ptr<Entry> > roots;
10165 FileDef *fd_l = findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig_l);
10166 auto clangParser = ClangParser::instance()->createTUParser(fd_l);
10167 auto parser = getParserForFile(s.c_str());
10168 auto fileRoot { parseFile(*parser.get(),fd_l,s.c_str(),clangParser.get(),true) };
10169 roots.push_back(fileRoot);
10170
10171 // Now process any include files in the same translation unit
10172 // first. When libclang is used this is much more efficient.
10173 for (auto incFile : clangParser->filesInSameTU())
10174 {
10175 if (filesToProcess.find(incFile)!=filesToProcess.end())
10176 {
10177 bool needsToBeProcessed = false;
10178 {
10179 std::lock_guard<std::mutex> lock(processedFilesLock);
10180 needsToBeProcessed = processedFiles.find(incFile)==processedFiles.end();
10181 if (needsToBeProcessed) processedFiles.insert(incFile);
10182 }
10183 if (incFile!=s && needsToBeProcessed)
10184 {
10185 FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile.c_str(),ambig_l);
10186 if (ifd && !ifd->isReference())
10187 {
10188 //printf(" Processing %s in same translation unit as %s\n",incFile,s->c_str());
10189 fileRoot = parseFile(*parser.get(),ifd,incFile.c_str(),clangParser.get(),false);
10190 roots.push_back(fileRoot);
10191 }
10192 }
10193 }
10194 }
10195 return roots;
10196 };
10197 // dispatch the work and collect the future results
10198 results.emplace_back(threadPool.queue(processFile));
10199 }
10200 }
10201 // synchronise with the Entry result lists produced and add them to the root
10202 for (auto &f : results)
10203 {
10204 auto l = f.get();
10205 for (auto &e : l)
10206 {
10207 root->moveToSubEntryAndKeep(e);
10208 }
10209 }
10210 // process remaining files
10211 results.clear();
10212 for (const auto &s : g_inputFiles)
10213 {
10214 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
10215 {
10216 // lambda representing the work to executed by a thread
10217 auto processFile = [s]() {
10218 bool ambig = false;
10219 std::vector< std::shared_ptr<Entry> > roots;
10220 FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
10221 auto parser { getParserForFile(s.c_str()) };
10222 bool useClang = getLanguageFromFileName(s.c_str())==SrcLangExt::Cpp;
10223 if (useClang)
10224 {
10225 auto clangParser = ClangParser::instance()->createTUParser(fd);
10226 auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true);
10227 roots.push_back(fileRoot);
10228 }
10229 else
10230 {
10231 auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),nullptr,true);
10232 roots.push_back(fileRoot);
10233 }
10234 return roots;
10235 };
10236 results.emplace_back(threadPool.queue(processFile));
10237 }
10238 }
10239 // synchronise with the Entry result lists produced and add them to the root
10240 for (auto &f : results)
10241 {
10242 auto l = f.get();
10243 for (auto &e : l)
10244 {
10245 root->moveToSubEntryAndKeep(e);
10246 }
10247 }
10248 }
10249 else // normal processing
10250#endif
10251 {
10252 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10253 msg("Processing input using %zu threads.\n",numThreads);
10254 ThreadPool threadPool(numThreads);
10255 using FutureType = std::shared_ptr<Entry>;
10256 std::vector< std::future< FutureType > > results;
10257 for (const auto &s : g_inputFiles)
10258 {
10259 // lambda representing the work to executed by a thread
10260 auto processFile = [s]() {
10261 bool ambig = false;
10262 FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
10263 auto parser = getParserForFile(s.c_str());
10264 auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),nullptr,true);
10265 return fileRoot;
10266 };
10267 // dispatch the work and collect the future results
10268 results.emplace_back(threadPool.queue(processFile));
10269 }
10270 // synchronise with the Entry results produced and add them to the root
10271 for (auto &f : results)
10272 {
10273 root->moveToSubEntryAndKeep(f.get());
10274 }
10275 }
10276}
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 10279 of file doxygen.cpp.

10280{
10281 AUTO_TRACE();
10282#if USE_LIBCLANG
10284 {
10285 StringUnorderedSet processedFiles;
10286
10287 // create a dictionary with files to process
10288 StringUnorderedSet filesToProcess;
10289 for (const auto &s : g_inputFiles)
10290 {
10291 filesToProcess.insert(s);
10292 }
10293
10294 // process source files (and their include dependencies)
10295 for (const auto &s : g_inputFiles)
10296 {
10297 bool ambig = false;
10298 FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
10299 ASSERT(fd!=nullptr);
10300 if (fd->isSource() && !fd->isReference() && getLanguageFromFileName(s.c_str())==SrcLangExt::Cpp) // this is a source file
10301 {
10302 auto clangParser = ClangParser::instance()->createTUParser(fd);
10303 auto parser { getParserForFile(s.c_str()) };
10304 auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true);
10305 root->moveToSubEntryAndKeep(fileRoot);
10306 processedFiles.insert(s);
10307
10308 // Now process any include files in the same translation unit
10309 // first. When libclang is used this is much more efficient.
10310 for (auto incFile : clangParser->filesInSameTU())
10311 {
10312 //printf(" file %s\n",incFile.c_str());
10313 if (filesToProcess.find(incFile)!=filesToProcess.end() && // file need to be processed
10314 processedFiles.find(incFile)==processedFiles.end()) // and is not processed already
10315 {
10316 FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile.c_str(),ambig);
10317 if (ifd && !ifd->isReference())
10318 {
10319 //printf(" Processing %s in same translation unit as %s\n",incFile.c_str(),s.c_str());
10320 fileRoot = parseFile(*parser.get(),ifd,incFile.c_str(),clangParser.get(),false);
10321 root->moveToSubEntryAndKeep(fileRoot);
10322 processedFiles.insert(incFile);
10323 }
10324 }
10325 }
10326 }
10327 }
10328 // process remaining files
10329 for (const auto &s : g_inputFiles)
10330 {
10331 if (processedFiles.find(s)==processedFiles.end()) // not yet processed
10332 {
10333 bool ambig = false;
10334 FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
10335 if (getLanguageFromFileName(s.c_str())==SrcLangExt::Cpp) // not yet processed
10336 {
10337 auto clangParser = ClangParser::instance()->createTUParser(fd);
10338 auto parser { getParserForFile(s.c_str()) };
10339 auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true);
10340 root->moveToSubEntryAndKeep(fileRoot);
10341 }
10342 else
10343 {
10344 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(s.c_str()) };
10345 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,s.c_str(),nullptr,true);
10346 root->moveToSubEntryAndKeep(fileRoot);
10347 }
10348 processedFiles.insert(s);
10349 }
10350 }
10351 }
10352 else // normal processing
10353#endif
10354 {
10355 for (const auto &s : g_inputFiles)
10356 {
10357 bool ambig = false;
10358 FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
10359 ASSERT(fd!=nullptr);
10360 std::unique_ptr<OutlineParserInterface> parser { getParserForFile(s.c_str()) };
10361 std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,s.c_str(),nullptr,true);
10362 root->moveToSubEntryAndKeep(std::move(fileRoot));
10363 }
10364 }
10365}

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

11788{
11789 AUTO_TRACE();
11790 std::atexit(exitDoxygen);
11791
11792#if USE_LIBCLANG
11793 Doxygen::clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
11794#endif
11795
11796 // we would like to show the versionString earlier, but we first have to handle the configuration file
11797 // to know the value of the QUIET setting.
11798 QCString versionString = getFullVersion();
11799 msg("Doxygen version used: %s\n",qPrint(versionString));
11800
11802
11803 /**************************************************************************
11804 * Make sure the output directory exists
11805 **************************************************************************/
11806 QCString outputDirectory = Config_getString(OUTPUT_DIRECTORY);
11807 if (outputDirectory.isEmpty())
11808 {
11809 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,Dir::currentDirPath().c_str());
11810 }
11811 else
11812 {
11813 Dir dir(outputDirectory.str());
11814 if (!dir.exists())
11815 {
11816 dir.setPath(Dir::currentDirPath());
11817 if (!dir.mkdir(outputDirectory.str()))
11818 {
11819 err("tag OUTPUT_DIRECTORY: Output directory '%s' does not "
11820 "exist and cannot be created\n",qPrint(outputDirectory));
11822 exit(1);
11823 }
11824 else
11825 {
11826 msg("Notice: Output directory '%s' does not exist. "
11827 "I have created it for you.\n", qPrint(outputDirectory));
11828 }
11829 dir.setPath(outputDirectory.str());
11830 }
11831 outputDirectory = Config_updateString(OUTPUT_DIRECTORY,dir.absPath().c_str());
11832 }
11833 AUTO_TRACE_ADD("outputDirectory={}",outputDirectory);
11834
11835 /**************************************************************************
11836 * Initialize global lists and dictionaries
11837 **************************************************************************/
11838
11839 // also scale lookup cache with SYMBOL_CACHE_SIZE
11840 int cacheSize = Config_getInt(LOOKUP_CACHE_SIZE);
11841 if (cacheSize<0) cacheSize=0;
11842 if (cacheSize>9) cacheSize=9;
11843 uint32_t lookupSize = 65536 << cacheSize;
11846
11847#ifdef HAS_SIGNALS
11848 signal(SIGINT, stopDoxygen);
11849#endif
11850
11851 uint32_t pid = Portable::pid();
11852 Doxygen::filterDBFileName.sprintf("doxygen_filterdb_%d.tmp",pid);
11853 Doxygen::filterDBFileName.prepend(outputDirectory+"/");
11854
11855 /**************************************************************************
11856 * Check/create output directories *
11857 **************************************************************************/
11858
11859 QCString htmlOutput;
11860 bool generateHtml = Config_getBool(GENERATE_HTML);
11861 if (generateHtml)
11862 {
11863 htmlOutput = createOutputDirectory(outputDirectory,Config_getString(HTML_OUTPUT),"/html");
11864 Config_updateString(HTML_OUTPUT,htmlOutput);
11865
11866 QCString sitemapUrl = Config_getString(SITEMAP_URL);
11867 bool generateSitemap = !sitemapUrl.isEmpty();
11868 if (generateSitemap && !sitemapUrl.endsWith("/"))
11869 {
11870 Config_updateString(SITEMAP_URL,sitemapUrl+"/");
11871 }
11872
11873 // add HTML indexers that are enabled
11874 bool generateHtmlHelp = Config_getBool(GENERATE_HTMLHELP);
11875 bool generateEclipseHelp = Config_getBool(GENERATE_ECLIPSEHELP);
11876 bool generateQhp = Config_getBool(GENERATE_QHP);
11877 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
11878 bool generateDocSet = Config_getBool(GENERATE_DOCSET);
11879 if (generateEclipseHelp) Doxygen::indexList->addIndex<EclipseHelp>();
11880 if (generateHtmlHelp) Doxygen::indexList->addIndex<HtmlHelp>();
11881 if (generateQhp) Doxygen::indexList->addIndex<Qhp>();
11882 if (generateSitemap) Doxygen::indexList->addIndex<Sitemap>();
11883 if (generateTreeView) Doxygen::indexList->addIndex<FTVHelp>(TRUE);
11884 if (generateDocSet) Doxygen::indexList->addIndex<DocSets>();
11887 }
11888
11889 QCString docbookOutput;
11890 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
11891 if (generateDocbook)
11892 {
11893 docbookOutput = createOutputDirectory(outputDirectory,Config_getString(DOCBOOK_OUTPUT),"/docbook");
11894 Config_updateString(DOCBOOK_OUTPUT,docbookOutput);
11895 }
11896
11897 QCString xmlOutput;
11898 bool generateXml = Config_getBool(GENERATE_XML);
11899 if (generateXml)
11900 {
11901 xmlOutput = createOutputDirectory(outputDirectory,Config_getString(XML_OUTPUT),"/xml");
11902 Config_updateString(XML_OUTPUT,xmlOutput);
11903 }
11904
11905 QCString latexOutput;
11906 bool generateLatex = Config_getBool(GENERATE_LATEX);
11907 if (generateLatex)
11908 {
11909 latexOutput = createOutputDirectory(outputDirectory,Config_getString(LATEX_OUTPUT), "/latex");
11910 Config_updateString(LATEX_OUTPUT,latexOutput);
11911 }
11912
11913 QCString rtfOutput;
11914 bool generateRtf = Config_getBool(GENERATE_RTF);
11915 if (generateRtf)
11916 {
11917 rtfOutput = createOutputDirectory(outputDirectory,Config_getString(RTF_OUTPUT),"/rtf");
11918 Config_updateString(RTF_OUTPUT,rtfOutput);
11919 }
11920
11921 QCString manOutput;
11922 bool generateMan = Config_getBool(GENERATE_MAN);
11923 if (generateMan)
11924 {
11925 manOutput = createOutputDirectory(outputDirectory,Config_getString(MAN_OUTPUT),"/man");
11926 Config_updateString(MAN_OUTPUT,manOutput);
11927 }
11928
11929 QCString sqlOutput;
11930 bool generateSql = Config_getBool(GENERATE_SQLITE3);
11931 if (generateSql)
11932 {
11933 sqlOutput = createOutputDirectory(outputDirectory,Config_getString(SQLITE3_OUTPUT),"/sqlite3");
11934 Config_updateString(SQLITE3_OUTPUT,sqlOutput);
11935 }
11936
11937 if (Config_getBool(HAVE_DOT))
11938 {
11939 QCString curFontPath = Config_getString(DOT_FONTPATH);
11940 if (curFontPath.isEmpty())
11941 {
11942 Portable::getenv("DOTFONTPATH");
11943 QCString newFontPath = ".";
11944 if (!curFontPath.isEmpty())
11945 {
11946 newFontPath+=Portable::pathListSeparator();
11947 newFontPath+=curFontPath;
11948 }
11949 Portable::setenv("DOTFONTPATH",qPrint(newFontPath));
11950 }
11951 else
11952 {
11953 Portable::setenv("DOTFONTPATH",qPrint(curFontPath));
11954 }
11955 }
11956
11957
11958
11959 /**************************************************************************
11960 * Handle layout file *
11961 **************************************************************************/
11962
11964 QCString layoutFileName = Config_getString(LAYOUT_FILE);
11965 bool defaultLayoutUsed = FALSE;
11966 if (layoutFileName.isEmpty())
11967 {
11968 layoutFileName = Config_updateString(LAYOUT_FILE,"DoxygenLayout.xml");
11969 defaultLayoutUsed = TRUE;
11970 }
11971 AUTO_TRACE_ADD("defaultLayoutUsed={}, layoutFileName={}",defaultLayoutUsed,layoutFileName);
11972
11973 FileInfo fi(layoutFileName.str());
11974 if (fi.exists())
11975 {
11976 msg("Parsing layout file %s...\n",qPrint(layoutFileName));
11977 LayoutDocManager::instance().parse(layoutFileName);
11978 }
11979 else if (!defaultLayoutUsed)
11980 {
11981 warn_uncond("failed to open layout file '%s' for reading! Using default settings.\n",qPrint(layoutFileName));
11982 }
11983
11984 /**************************************************************************
11985 * Read and preprocess input *
11986 **************************************************************************/
11987
11988 // prevent search in the output directories
11989 StringVector exclPatterns = Config_getList(EXCLUDE_PATTERNS);
11990 if (generateHtml) exclPatterns.push_back(htmlOutput.str());
11991 if (generateDocbook) exclPatterns.push_back(docbookOutput.str());
11992 if (generateXml) exclPatterns.push_back(xmlOutput.str());
11993 if (generateLatex) exclPatterns.push_back(latexOutput.str());
11994 if (generateRtf) exclPatterns.push_back(rtfOutput.str());
11995 if (generateMan) exclPatterns.push_back(manOutput.str());
11996 Config_updateList(EXCLUDE_PATTERNS,exclPatterns);
11997
11999
12001
12002 // Notice: the order of the function calls below is very important!
12003
12004 if (Config_getBool(GENERATE_HTML) && !Config_getBool(USE_MATHJAX))
12005 {
12007 }
12008 if (Config_getBool(GENERATE_RTF))
12009 {
12011 }
12012 if (Config_getBool(GENERATE_DOCBOOK))
12013 {
12015 }
12016
12018
12019 /**************************************************************************
12020 * Handle Tag Files *
12021 **************************************************************************/
12022
12023 std::shared_ptr<Entry> root = std::make_shared<Entry>();
12024 msg("Reading and parsing tag files\n");
12025
12026 const StringVector &tagFileList = Config_getList(TAGFILES);
12027 for (const auto &s : tagFileList)
12028 {
12029 readTagFile(root,s.c_str());
12030 }
12031
12032 /**************************************************************************
12033 * Parse source files *
12034 **************************************************************************/
12035
12036 addSTLSupport(root);
12037
12038 g_s.begin("Parsing files\n");
12039 if (Config_getInt(NUM_PROC_THREADS)==1)
12040 {
12042 }
12043 else
12044 {
12046 }
12047 g_s.end();
12048
12049 /**************************************************************************
12050 * Gather information *
12051 **************************************************************************/
12052
12053 g_s.begin("Building macro definition list...\n");
12055 g_s.end();
12056
12057 g_s.begin("Building group list...\n");
12058 buildGroupList(root.get());
12059 organizeSubGroups(root.get());
12060 g_s.end();
12061
12062 g_s.begin("Building directory list...\n");
12064 findDirDocumentation(root.get());
12065 g_s.end();
12066
12067 g_s.begin("Building namespace list...\n");
12068 buildNamespaceList(root.get());
12069 findUsingDirectives(root.get());
12070 g_s.end();
12071
12072 g_s.begin("Building file list...\n");
12073 buildFileList(root.get());
12074 g_s.end();
12075
12076 g_s.begin("Building class list...\n");
12077 buildClassList(root.get());
12078 g_s.end();
12079
12080 g_s.begin("Building concept list...\n");
12081 buildConceptList(root.get());
12082 g_s.end();
12083
12084 // build list of using declarations here (global list)
12085 buildListOfUsingDecls(root.get());
12086 g_s.end();
12087
12088 g_s.begin("Computing nesting relations for classes...\n");
12090 g_s.end();
12091 // 1.8.2-20121111: no longer add nested classes to the group as well
12092 //distributeClassGroupRelations();
12093
12094 // calling buildClassList may result in cached relations that
12095 // become invalid after resolveClassNestingRelations(), that's why
12096 // we need to clear the cache here
12098 // we don't need the list of using declaration anymore
12099 g_usingDeclarations.clear();
12100
12101 g_s.begin("Associating documentation with classes...\n");
12102 buildClassDocList(root.get());
12103 g_s.end();
12104
12105 g_s.begin("Associating documentation with concepts...\n");
12106 buildConceptDocList(root.get());
12108 g_s.end();
12109
12110 g_s.begin("Associating documentation with modules...\n");
12111 findModuleDocumentation(root.get());
12112 g_s.end();
12113
12114 g_s.begin("Building example list...\n");
12115 buildExampleList(root.get());
12116 g_s.end();
12117
12118 g_s.begin("Searching for enumerations...\n");
12119 findEnums(root.get());
12120 g_s.end();
12121
12122 // Since buildVarList calls isVarWithConstructor
12123 // and this calls getResolvedClass we need to process
12124 // typedefs first so the relations between classes via typedefs
12125 // are properly resolved. See bug 536385 for an example.
12126 g_s.begin("Searching for documented typedefs...\n");
12127 buildTypedefList(root.get());
12128 g_s.end();
12129
12130 if (Config_getBool(OPTIMIZE_OUTPUT_SLICE))
12131 {
12132 g_s.begin("Searching for documented sequences...\n");
12133 buildSequenceList(root.get());
12134 g_s.end();
12135
12136 g_s.begin("Searching for documented dictionaries...\n");
12137 buildDictionaryList(root.get());
12138 g_s.end();
12139 }
12140
12141 g_s.begin("Searching for members imported via using declarations...\n");
12142 // this should be after buildTypedefList in order to properly import
12143 // used typedefs
12144 findUsingDeclarations(root.get(),TRUE); // do for python packages first
12145 findUsingDeclarations(root.get(),FALSE); // then the rest
12146 g_s.end();
12147
12148 g_s.begin("Searching for included using directives...\n");
12150 g_s.end();
12151
12152 g_s.begin("Searching for documented variables...\n");
12153 buildVarList(root.get());
12154 g_s.end();
12155
12156 g_s.begin("Building interface member list...\n");
12157 buildInterfaceAndServiceList(root.get()); // UNO IDL
12158
12159 g_s.begin("Building member list...\n"); // using class info only !
12160 buildFunctionList(root.get());
12161 g_s.end();
12162
12163 g_s.begin("Searching for friends...\n");
12164 findFriends();
12165 g_s.end();
12166
12167 g_s.begin("Searching for documented defines...\n");
12168 findDefineDocumentation(root.get());
12169 g_s.end();
12170
12171 g_s.begin("Computing class inheritance relations...\n");
12172 findClassEntries(root.get());
12174 g_s.end();
12175
12176 g_s.begin("Computing class usage relations...\n");
12178 g_s.end();
12179
12180 if (Config_getBool(INLINE_SIMPLE_STRUCTS))
12181 {
12182 g_s.begin("Searching for tag less structs...\n");
12184 g_s.end();
12185 }
12186
12187 g_s.begin("Flushing cached template relations that have become invalid...\n");
12189 g_s.end();
12190
12191 g_s.begin("Computing class relations...\n");
12194 if (Config_getBool(OPTIMIZE_OUTPUT_VHDL))
12195 {
12197 }
12199 g_classEntries.clear();
12200 g_s.end();
12201
12202 g_s.begin("Add enum values to enums...\n");
12203 addEnumValuesToEnums(root.get());
12204 findEnumDocumentation(root.get());
12205 g_s.end();
12206
12207 g_s.begin("Searching for member function documentation...\n");
12208 findObjCMethodDefinitions(root.get());
12209 findMemberDocumentation(root.get()); // may introduce new members !
12210 findUsingDeclImports(root.get()); // may introduce new members !
12214 g_s.end();
12215
12216 // moved to after finding and copying documentation,
12217 // as this introduces new members see bug 722654
12218 g_s.begin("Creating members for template instances...\n");
12220 g_s.end();
12221
12222 g_s.begin("Building page list...\n");
12223 buildPageList(root.get());
12224 g_s.end();
12225
12226 g_s.begin("Search for main page...\n");
12227 findMainPage(root.get());
12228 findMainPageTagFiles(root.get());
12229 g_s.end();
12230
12231 g_s.begin("Computing page relations...\n");
12232 computePageRelations(root.get());
12234 g_s.end();
12235
12236 g_s.begin("Determining the scope of groups...\n");
12237 findGroupScope(root.get());
12238 g_s.end();
12239
12240 g_s.begin("Computing module relations...\n");
12241 auto &mm = ModuleManager::instance();
12242 mm.resolvePartitions();
12243 mm.resolveImports();
12244 mm.collectExportedSymbols();
12245 g_s.end();
12246
12247 auto memberNameComp = [](const MemberNameLinkedMap::Ptr &n1,const MemberNameLinkedMap::Ptr &n2)
12248 {
12249 return qstricmp(n1->memberName().data()+getPrefixIndex(n1->memberName()),
12250 n2->memberName().data()+getPrefixIndex(n2->memberName())
12251 )<0;
12252 };
12253
12254 auto classComp = [](const ClassLinkedMap::Ptr &c1,const ClassLinkedMap::Ptr &c2)
12255 {
12256 if (Config_getBool(SORT_BY_SCOPE_NAME))
12257 {
12258 return qstricmp(c1->name(), c2->name())<0;
12259 }
12260 else
12261 {
12262 int i = qstricmp(c1->className(), c2->className());
12263 return i==0 ? qstricmp(c1->name(), c2->name())<0 : i<0;
12264 }
12265 };
12266
12267 auto namespaceComp = [](const NamespaceLinkedMap::Ptr &n1,const NamespaceLinkedMap::Ptr &n2)
12268 {
12269 return qstricmp(n1->name(),n2->name())<0;
12270 };
12271
12272 auto conceptComp = [](const ConceptLinkedMap::Ptr &c1,const ConceptLinkedMap::Ptr &c2)
12273 {
12274 return qstricmp(c1->name(),c2->name())<0;
12275 };
12276
12277 g_s.begin("Sorting lists...\n");
12280 memberNameComp);
12283 memberNameComp);
12286 classComp);
12287 std::sort(Doxygen::classLinkedMap->begin(),
12289 classComp);
12290 std::sort(Doxygen::conceptLinkedMap->begin(),
12292 conceptComp);
12295 namespaceComp);
12296 g_s.end();
12297
12298 g_s.begin("Determining which enums are documented\n");
12300 g_s.end();
12301
12302 g_s.begin("Computing member relations...\n");
12305 g_s.end();
12306
12307 g_s.begin("Building full member lists recursively...\n");
12309 g_s.end();
12310
12311 g_s.begin("Adding members to member groups.\n");
12313 g_s.end();
12314
12315 if (Config_getBool(DISTRIBUTE_GROUP_DOC))
12316 {
12317 g_s.begin("Distributing member group documentation.\n");
12319 g_s.end();
12320 }
12321
12322 g_s.begin("Computing member references...\n");
12324 g_s.end();
12325
12326 if (Config_getBool(INHERIT_DOCS))
12327 {
12328 g_s.begin("Inheriting documentation...\n");
12330 g_s.end();
12331 }
12332
12333
12334 // compute the shortest possible names of all files
12335 // without losing the uniqueness of the file names.
12336 g_s.begin("Generating disk names...\n");
12338 g_s.end();
12339
12340 g_s.begin("Adding source references...\n");
12342 g_s.end();
12343
12344 g_s.begin("Adding xrefitems...\n");
12347 g_s.end();
12348
12349 g_s.begin("Sorting member lists...\n");
12351 g_s.end();
12352
12353 g_s.begin("Setting anonymous enum type...\n");
12355 g_s.end();
12356
12357 g_s.begin("Computing dependencies between directories...\n");
12359 g_s.end();
12360
12361 g_s.begin("Generating citations page...\n");
12363 g_s.end();
12364
12365 g_s.begin("Counting members...\n");
12366 countMembers();
12367 g_s.end();
12368
12369 g_s.begin("Counting data structures...\n");
12371 g_s.end();
12372
12373 g_s.begin("Resolving user defined references...\n");
12375 g_s.end();
12376
12377 g_s.begin("Finding anchors and sections in the documentation...\n");
12379 g_s.end();
12380
12381 g_s.begin("Transferring function references...\n");
12383 g_s.end();
12384
12385 g_s.begin("Combining using relations...\n");
12387 g_s.end();
12388
12390 g_s.begin("Adding members to index pages...\n");
12392 addToIndices();
12393 g_s.end();
12394
12395 g_s.begin("Correcting members for VHDL...\n");
12397 g_s.end();
12398
12399 g_s.begin("Computing tooltip texts...\n");
12401 g_s.end();
12402
12403 if (Config_getBool(SORT_GROUP_NAMES))
12404 {
12405 std::sort(Doxygen::groupLinkedMap->begin(),
12407 [](const auto &g1,const auto &g2)
12408 { return g1->groupTitle() < g2->groupTitle(); });
12409
12410 for (const auto &gd : *Doxygen::groupLinkedMap)
12411 {
12412 gd->sortSubGroups();
12413 }
12414 }
12415
12416 printNavTree(root.get(),0);
12418}
Definition cache.h:32
void clear()
Clears all values in the cache.
Definition cache.h:150
void generatePage()
Generate the citations page.
Definition cite.cpp:301
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
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:251
void initialize()
Definition indexlist.h:103
void addIndex(As &&... args)
Add an index generator to the list, using a syntax similar to std::make_unique<T>()
Definition indexlist.h:100
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition layout.cpp:1423
void parse(const QCString &fileName, const char *data=nullptr)
Parses a user provided layout.
Definition layout.cpp:1459
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:4823
void printNavTree(Entry *root, int indent)
Definition doxygen.cpp:9386
static void buildGroupList(const Entry *root)
Definition doxygen.cpp:411
static void flushCachedTemplateRelations()
Definition doxygen.cpp:8802
static void computeTemplateClassRelations()
Definition doxygen.cpp:4882
void printSectionsTree()
Definition doxygen.cpp:9407
static void generateXRefPages()
Definition doxygen.cpp:5054
static void resolveClassNestingRelations()
Definition doxygen.cpp:1301
static void vhdlCorrectMemberProperties()
Definition doxygen.cpp:7784
static void stopDoxygen(int)
static void computeMemberReferences()
Definition doxygen.cpp:4951
static void transferRelatedFunctionDocumentation()
Definition doxygen.cpp:3901
static void addMembersToMemberGroup()
Definition doxygen.cpp:8672
static void distributeConceptGroups()
Definition doxygen.cpp:1268
static void transferFunctionDocumentation()
Definition doxygen.cpp:3820
static void setAnonymousEnumType()
Definition doxygen.cpp:8419
static void sortMemberLists()
Definition doxygen.cpp:8324
static void createTemplateInstanceMembers()
Definition doxygen.cpp:7909
void transferStaticInstanceInitializers()
Definition doxygen.cpp:3950
static void findObjCMethodDefinitions(const Entry *root)
Definition doxygen.cpp:6949
static void distributeMemberGroupDocumentation()
Definition doxygen.cpp:8710
static void resolveUserReferences()
Definition doxygen.cpp:9268
static void readTagFile(const std::shared_ptr< Entry > &root, const QCString &tagLine)
Definition doxygen.cpp:9772
static void findIncludedUsingDirectives()
Definition doxygen.cpp:2164
static void countMembers()
Definition doxygen.cpp:8433
static void organizeSubGroups(const Entry *root)
Definition doxygen.cpp:470
void searchInputFiles()
static void addListReferences()
Definition doxygen.cpp:4985
static void exitDoxygen() noexcept
static void addMembersToIndex()
Definition doxygen.cpp:7574
static void addSourceReferences()
Definition doxygen.cpp:8206
static void inheritDocumentation()
Definition doxygen.cpp:8612
static void flushUnresolvedRelations()
Definition doxygen.cpp:8856
static void findDocumentedEnumValues()
Definition doxygen.cpp:7566
static void generateDiskNames()
Definition doxygen.cpp:9975
static void addToIndices()
Definition doxygen.cpp:7616
static void computeClassRelations()
Definition doxygen.cpp:4853
static void checkPageRelations()
Definition doxygen.cpp:9248
static QCString createOutputDirectory(const QCString &baseDirName, const QCString &formatDirName, const char *defaultDirName)
static void computeVerifiedDotPath()
Definition doxygen.cpp:9682
static void findSectionsInDocumentation()
Definition doxygen.cpp:8748
static void mergeCategories()
Definition doxygen.cpp:7928
static void findUsedTemplateInstances()
Definition doxygen.cpp:4838
static void computeTooltipTexts()
Definition doxygen.cpp:8373
static void parseFilesSingleThreading(const std::shared_ptr< Entry > &root)
parse the list of input files
static void buildCompleteMemberLists()
Definition doxygen.cpp:7950
static void combineUsingRelations()
Definition doxygen.cpp:8647
static void checkMarkdownMainfile()
static void parseFilesMultiThreading(const std::shared_ptr< Entry > &root)
parse the list of input files
static void transferFunctionReferences()
Definition doxygen.cpp:3853
static void buildDefineList()
Definition doxygen.cpp:8285
static void computeMemberRelations()
Definition doxygen.cpp:7893
QCString pathListSeparator()
Definition portable.cpp:391
uint32_t pid()
Definition portable.cpp:265
int qstricmp(const char *s1, const char *s2)
Definition qcstring.cpp:442
void initSearchIndexer()
void addSTLSupport(std::shared_ptr< Entry > &root)
Add stub entries for the most used classes in the standard template library.
int getPrefixIndex(const QCString &name)
Definition util.cpp:3550

References Dir::absPath(), addEnumValuesToEnums(), IndexList::addIndex(), addListReferences(), addMembersToIndex(), addMembersToMemberGroup(), addSourceReferences(), addSTLSupport(), addToIndices(), AUTO_TRACE, AUTO_TRACE_ADD, begin(), Statistics::begin(), buildClassDocList(), buildClassList(), buildCompleteMemberLists(), buildConceptDocList(), buildConceptList(), buildDefineList(), buildDirectories(), buildExampleList(), buildFileList(), buildGroupList(), buildListOfUsingDecls(), buildNamespaceList(), buildPageList(), checkMarkdownMainfile(), checkPageRelations(), FormulaManager::checkRepositories(), Doxygen::clangAssistedParsing, Doxygen::classLinkedMap, cleanUpDoxygen(), Cache< K, V >::clear(), 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, Index::countDataStructures(), countMembers(), createOutputDirectory(), createTemplateInstanceMembers(), Dir::currentDirPath(), distributeConceptGroups(), distributeMemberGroupDocumentation(), end(), Statistics::end(), QCString::endsWith(), err, Dir::exists(), FileInfo::exists(), exitDoxygen(), FALSE, Doxygen::filterDBFileName, findClassEntries(), findDefineDocumentation(), findDirDocumentation(), findDocumentedEnumValues(), findEnumDocumentation(), findEnums(), findGroupScope(), findIncludedUsingDirectives(), findInheritedTemplateInstances(), findMainPage(), findMainPageTagFiles(), findMemberDocumentation(), findModuleDocumentation(), findObjCMethodDefinitions(), findSectionsInDocumentation(), findTagLessClasses(), findUsedTemplateInstances(), findUsingDeclarations(), findUsingDeclImports(), findUsingDirectives(), flushCachedTemplateRelations(), flushUnresolvedRelations(), Doxygen::functionNameLinkedMap, g_classEntries, g_s, g_usingDeclarations, generateDiskNames(), CitationManager::generatePage(), generateXRefPages(), Portable::getenv(), getPrefixIndex(), Doxygen::groupLinkedMap, Doxygen::hiddenClassLinkedMap, Doxygen::indexList, inheritDocumentation(), LayoutDocManager::init(), FormulaManager::initFromRepository(), IndexList::initialize(), initSearchIndexer(), CitationManager::instance(), FormulaManager::instance(), Index::instance(), LayoutDocManager::instance(), ModuleManager::instance(), QCString::isEmpty(), Doxygen::memberNameLinkedMap, mergeCategories(), Dir::mkdir(), msg(), Doxygen::namespaceLinkedMap, organizeSubGroups(), LayoutDocManager::parse(), parseFilesMultiThreading(), parseFilesSingleThreading(), Portable::pathListSeparator(), Portable::pid(), QCString::prepend(), printNavTree(), printSectionsTree(), qPrint(), qstricmp(), readTagFile(), resolveClassNestingRelations(), resolveUserReferences(), searchInputFiles(), setAnonymousEnumType(), Portable::setenv(), Dir::setPath(), sortMemberLists(), GroupDef::sortSubGroups(), QCString::sprintf(), stopDoxygen(), QCString::str(), Doxygen::symbolLookupCache, transferFunctionDocumentation(), transferFunctionReferences(), transferRelatedFunctionDocumentation(), transferStaticInstanceInitializers(), TRUE, Doxygen::typeLookupCache, vhdlCorrectMemberProperties(), and warn_uncond.

Referenced by main().

◆ printNavTree()

void printNavTree ( Entry * root,
int indent )

Definition at line 9386 of file doxygen.cpp.

9387{
9389 {
9390 QCString indentStr;
9391 indentStr.fill(' ',indent);
9392 Debug::print(Debug::Entries,0,"%s%s at %s:%d (sec=%s, spec=%s)\n",
9393 indentStr.isEmpty()?"":qPrint(indentStr),
9394 root->name.isEmpty()?"<empty>":qPrint(root->name),
9395 qPrint(root->fileName),root->startLine,
9396 root->section.to_string().c_str(),
9397 root->spec.to_string().c_str());
9398 for (const auto &e : root->children())
9399 {
9400 printNavTree(e.get(),indent+2);
9401 }
9402 }
9403}
@ Entries
Definition debug.h:46
static void print(DebugMask mask, int prio, const char *fmt,...)
Definition debug.cpp:80
void fill(char c, int len=-1)
Fills a string with a predefined character.
Definition qcstring.h:173

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

Referenced by parseInput(), and printNavTree().

◆ printSectionsTree()

void printSectionsTree ( )

Definition at line 9407 of file doxygen.cpp.

9408{
9410 {
9411 for (const auto &si : SectionManager::instance())
9412 {
9413 Debug::print(Debug::Sections,0,"Section = %s, file = %s, title = %s, type = %d, ref = %s\n",
9414 qPrint(si->label()),qPrint(si->fileName()),qPrint(si->title()),
9415 si->type(),qPrint(si->ref()));
9416 }
9417 }
9418}
@ Sections
Definition debug.h:47
singleton class that owns the list of all sections
Definition section.h:134

References SectionManager::instance(), Debug::isFlagSet(), Debug::print(), qPrint(), 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 1536 of file doxygen.cpp.

1540{
1541 //printf("%d: processTagLessClasses %s\n",count,qPrint(cd->name()));
1542 //printf("checking members for %s\n",qPrint(cd->name()));
1543 if (tagParentCd && !cd->getClasses().empty())
1544 {
1546 if (ml)
1547 {
1548 for (const auto &md : *ml)
1549 {
1550 QCString type = md->typeString();
1551 if (type.find("::@")!=-1) // member of tag less struct/union
1552 {
1553 for (const auto &icd : cd->getClasses())
1554 {
1555 //printf(" member %s: type='%s'\n",qPrint(md->name()),qPrint(type));
1556 //printf(" comparing '%s'<->'%s'\n",qPrint(type),qPrint(icd->name()));
1557 if (type.find(icd->name())!=-1) // matching tag less struct/union
1558 {
1559 QCString name = md->name();
1560 if (md->isAnonymous()) name = "__unnamed" + name.right(name.length()-1)+"__";
1561 if (!prefix.isEmpty()) name.prepend(prefix+".");
1562 //printf(" found %s for class %s\n",qPrint(name),qPrint(cd->name()));
1563 ClassDefMutable *ncd = createTagLessInstance(rootCd,icd,name);
1564 if (ncd)
1565 {
1566 processTagLessClasses(rootCd,icd,ncd,name,count+1);
1567 //printf(" addTagged %s to %s\n",qPrint(ncd->name()),qPrint(tagParentCd->name()));
1568 ncd->setTagLessReference(icd);
1569
1570 // replace tag-less type for generated/original member
1571 // by newly created class name.
1572 // note the difference between changing cd and tagParentCd.
1573 // for the initial call this is the same pointer, but for
1574 // recursive calls cd is the original tag-less struct (of which
1575 // there is only one instance) and tagParentCd is the newly
1576 // generated tagged struct of which there can be multiple instances!
1578 if (pml)
1579 {
1580 for (const auto &pmd : *pml)
1581 {
1583 if (pmdm && pmd->name()==md->name())
1584 {
1585 pmdm->setAccessorType(ncd,substitute(pmd->typeString(),icd->name(),ncd->name()));
1586 //pmd->setType(substitute(pmd->typeString(),icd->name(),ncd->name()));
1587 }
1588 }
1589 }
1590 }
1591 }
1592 }
1593 }
1594 }
1595 }
1596 }
1597}
virtual ClassLinkedRefMap getClasses() const =0
returns the classes nested into this class
virtual void setTagLessReference(const ClassDef *cd)=0
virtual void setAccessorType(ClassDef *cd, const QCString &t)=0
static ClassDefMutable * createTagLessInstance(const ClassDef *rootCd, const ClassDef *templ, const QCString &fieldName)
Definition doxygen.cpp:1450

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

Referenced by findTagLessClasses(), and processTagLessClasses().

◆ readConfiguration()

void readConfiguration ( int argc,
char ** argv )

Definition at line 10897 of file doxygen.cpp.

10898{
10899 QCString versionString = getFullVersion();
10900
10901 // helper that calls \a func to write to file \a fileName via a TextStream
10902 auto writeFile = [](const char *fileName,std::function<void(TextStream&)> func) -> bool
10903 {
10904 std::ofstream f;
10905 if (openOutputFile(fileName,f))
10906 {
10907 TextStream t(&f);
10908 func(t);
10909 return true;
10910 }
10911 return false;
10912 };
10913
10914
10915 /**************************************************************************
10916 * Handle arguments *
10917 **************************************************************************/
10918
10919 int optInd=1;
10920 QCString configName;
10921 QCString traceName;
10922 bool genConfig=false;
10923 bool shortList=false;
10924 bool traceTiming=true;
10926 bool updateConfig=false;
10927 bool quiet = false;
10928 while (optInd<argc && argv[optInd][0]=='-' &&
10929 (isalpha(argv[optInd][1]) || argv[optInd][1]=='?' ||
10930 argv[optInd][1]=='-')
10931 )
10932 {
10933 switch(argv[optInd][1])
10934 {
10935 case 'g':
10936 {
10937 genConfig=TRUE;
10938 }
10939 break;
10940 case 'l':
10941 {
10942 QCString layoutName;
10943 if (optInd+1>=argc)
10944 {
10945 layoutName="DoxygenLayout.xml";
10946 }
10947 else
10948 {
10949 layoutName=argv[optInd+1];
10950 }
10951 writeDefaultLayoutFile(layoutName);
10953 exit(0);
10954 }
10955 break;
10956 case 'd':
10957 {
10958 QCString debugLabel=getArg(argc,argv,optInd);
10959 if (debugLabel.isEmpty())
10960 {
10961 devUsage();
10963 exit(0);
10964 }
10965 int retVal = Debug::setFlagStr(debugLabel);
10966 if (!retVal)
10967 {
10968 err("option \"-d\" has unknown debug specifier: \"%s\".\n",qPrint(debugLabel));
10969 devUsage();
10971 exit(1);
10972 }
10973 }
10974 break;
10975 case 't':
10976 {
10977#if ENABLE_TRACING
10978 if (!strcmp(argv[optInd]+1,"t_notime")) traceTiming = false;
10979 else if (!strcmp(argv[optInd]+1,"t")) traceTiming=true;
10980 else
10981 {
10982 err("option should be \"-t\" or \"-t_notime\", found: \"%s\".\n",argv[optInd]);
10984 exit(1);
10985 }
10986 if (optInd+1>=argc || argv[optInd+1][0] == '-') // no file name given
10987 {
10988 traceName="stdout";
10989 }
10990 else
10991 {
10992 traceName=argv[optInd+1];
10993 optInd++;
10994 }
10995#else
10996 err("support for option \"-t\" has not been compiled in (use a debug build or a release build with tracing enabled).\n");
10998 exit(1);
10999#endif
11000 }
11001 break;
11002 case 'x':
11003 if (!strcmp(argv[optInd]+1,"x_noenv")) diffList=Config::CompareMode::CompressedNoEnv;
11004 else if (!strcmp(argv[optInd]+1,"x")) diffList=Config::CompareMode::Compressed;
11005 else
11006 {
11007 err("option should be \"-x\" or \"-x_noenv\", found: \"%s\".\n",argv[optInd]);
11009 exit(1);
11010 }
11011 break;
11012 case 's':
11013 shortList=TRUE;
11014 break;
11015 case 'u':
11016 updateConfig=TRUE;
11017 break;
11018 case 'e':
11019 {
11020 QCString formatName=getArg(argc,argv,optInd);
11021 if (formatName.isEmpty())
11022 {
11023 err("option \"-e\" is missing format specifier rtf.\n");
11025 exit(1);
11026 }
11027 if (qstricmp(formatName.data(),"rtf")==0)
11028 {
11029 if (optInd+1>=argc)
11030 {
11031 err("option \"-e rtf\" is missing an extensions file name\n");
11033 exit(1);
11034 }
11035 writeFile(argv[optInd+1],RTFGenerator::writeExtensionsFile);
11037 exit(0);
11038 }
11039 err("option \"-e\" has invalid format specifier.\n");
11041 exit(1);
11042 }
11043 break;
11044 case 'f':
11045 {
11046 QCString listName=getArg(argc,argv,optInd);
11047 if (listName.isEmpty())
11048 {
11049 err("option \"-f\" is missing list specifier.\n");
11051 exit(1);
11052 }
11053 if (qstricmp(listName.data(),"emoji")==0)
11054 {
11055 if (optInd+1>=argc)
11056 {
11057 err("option \"-f emoji\" is missing an output file name\n");
11059 exit(1);
11060 }
11061 writeFile(argv[optInd+1],[](TextStream &t) { EmojiEntityMapper::instance().writeEmojiFile(t); });
11063 exit(0);
11064 }
11065 err("option \"-f\" has invalid list specifier.\n");
11067 exit(1);
11068 }
11069 break;
11070 case 'w':
11071 {
11072 QCString formatName=getArg(argc,argv,optInd);
11073 if (formatName.isEmpty())
11074 {
11075 err("option \"-w\" is missing format specifier rtf, html or latex\n");
11077 exit(1);
11078 }
11079 if (qstricmp(formatName.data(),"rtf")==0)
11080 {
11081 if (optInd+1>=argc)
11082 {
11083 err("option \"-w rtf\" is missing a style sheet file name\n");
11085 exit(1);
11086 }
11087 if (!writeFile(argv[optInd+1],RTFGenerator::writeStyleSheetFile))
11088 {
11089 err("error opening RTF style sheet file %s!\n",argv[optInd+1]);
11091 exit(1);
11092 }
11094 exit(0);
11095 }
11096 else if (qstricmp(formatName.data(),"html")==0)
11097 {
11098 Config::init();
11099 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11100 // explicit config file mentioned or default found on disk
11101 {
11102 QCString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? QCString("Doxyfile") : QCString("doxyfile"));
11103 if (!Config::parse(df)) // parse the config file
11104 {
11105 err("error opening or reading configuration file %s!\n",argv[optInd+4]);
11107 exit(1);
11108 }
11109 }
11110 if (optInd+3>=argc)
11111 {
11112 err("option \"-w html\" does not have enough arguments\n");
11114 exit(1);
11115 }
11119 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11120 writeFile(argv[optInd+1],[&](TextStream &t) { HtmlGenerator::writeHeaderFile(t,argv[optInd+3]); });
11121 writeFile(argv[optInd+2],HtmlGenerator::writeFooterFile);
11122 writeFile(argv[optInd+3],HtmlGenerator::writeStyleSheetFile);
11124 exit(0);
11125 }
11126 else if (qstricmp(formatName.data(),"latex")==0)
11127 {
11128 Config::init();
11129 if (optInd+4<argc || FileInfo("Doxyfile").exists() || FileInfo("doxyfile").exists())
11130 {
11131 QCString df = optInd+4<argc ? argv[optInd+4] : (FileInfo("Doxyfile").exists() ? QCString("Doxyfile") : QCString("doxyfile"));
11132 if (!Config::parse(df))
11133 {
11134 err("error opening or reading configuration file %s!\n",argv[optInd+4]);
11136 exit(1);
11137 }
11138 }
11139 if (optInd+3>=argc)
11140 {
11141 err("option \"-w latex\" does not have enough arguments\n");
11143 exit(1);
11144 }
11148 setTranslator(Config_getEnum(OUTPUT_LANGUAGE));
11149 writeFile(argv[optInd+1],LatexGenerator::writeHeaderFile);
11150 writeFile(argv[optInd+2],LatexGenerator::writeFooterFile);
11151 writeFile(argv[optInd+3],LatexGenerator::writeStyleSheetFile);
11153 exit(0);
11154 }
11155 else
11156 {
11157 err("Illegal format specifier \"%s\": should be one of rtf, html or latex\n",qPrint(formatName));
11159 exit(1);
11160 }
11161 }
11162 break;
11163 case 'm':
11165 break;
11166 case 'v':
11167 version(false);
11169 exit(0);
11170 break;
11171 case 'V':
11172 version(true);
11174 exit(0);
11175 break;
11176 case '-':
11177 if (qstrcmp(&argv[optInd][2],"help")==0)
11178 {
11179 usage(argv[0],versionString);
11180 exit(0);
11181 }
11182 else if (qstrcmp(&argv[optInd][2],"version")==0)
11183 {
11184 version(false);
11186 exit(0);
11187 }
11188 else if ((qstrcmp(&argv[optInd][2],"Version")==0) ||
11189 (qstrcmp(&argv[optInd][2],"VERSION")==0))
11190 {
11191 version(true);
11193 exit(0);
11194 }
11195 else
11196 {
11197 err("Unknown option \"-%s\"\n",&argv[optInd][1]);
11198 usage(argv[0],versionString);
11199 exit(1);
11200 }
11201 break;
11202 case 'b':
11203 setvbuf(stdout,nullptr,_IONBF,0);
11204 break;
11205 case 'q':
11206 quiet = true;
11207 break;
11208 case 'h':
11209 case '?':
11210 usage(argv[0],versionString);
11211 exit(0);
11212 break;
11213 default:
11214 err("Unknown option \"-%c\"\n",argv[optInd][1]);
11215 usage(argv[0],versionString);
11216 exit(1);
11217 }
11218 optInd++;
11219 }
11220
11221 /**************************************************************************
11222 * Parse or generate the config file *
11223 **************************************************************************/
11224
11225 initTracing(traceName.data(),traceTiming);
11226 TRACE("Doxygen version used: {}",getFullVersion());
11227 Config::init();
11228
11229 FileInfo configFileInfo1("Doxyfile"),configFileInfo2("doxyfile");
11230 if (optInd>=argc)
11231 {
11232 if (configFileInfo1.exists())
11233 {
11234 configName="Doxyfile";
11235 }
11236 else if (configFileInfo2.exists())
11237 {
11238 configName="doxyfile";
11239 }
11240 else if (genConfig)
11241 {
11242 configName="Doxyfile";
11243 }
11244 else
11245 {
11246 err("Doxyfile not found and no input file specified!\n");
11247 usage(argv[0],versionString);
11248 exit(1);
11249 }
11250 }
11251 else
11252 {
11253 FileInfo fi(argv[optInd]);
11254 if (fi.exists() || qstrcmp(argv[optInd],"-")==0 || genConfig)
11255 {
11256 configName=argv[optInd];
11257 }
11258 else
11259 {
11260 err("configuration file %s not found!\n",argv[optInd]);
11261 usage(argv[0],versionString);
11262 exit(1);
11263 }
11264 }
11265
11266 if (genConfig)
11267 {
11268 generateConfigFile(configName,shortList);
11270 exit(0);
11271 }
11272
11273 if (!Config::parse(configName,updateConfig,diffList))
11274 {
11275 err("could not open or read configuration file %s!\n",qPrint(configName));
11277 exit(1);
11278 }
11279
11280 if (diffList!=Config::CompareMode::Full)
11281 {
11283 compareDoxyfile(diffList);
11285 exit(0);
11286 }
11287
11288 if (updateConfig)
11289 {
11291 generateConfigFile(configName,shortList,TRUE);
11293 exit(0);
11294 }
11295
11296 /* Perlmod wants to know the path to the config file.*/
11297 FileInfo configFileInfo(configName.str());
11298 setPerlModDoxyfile(configFileInfo.absFilePath());
11299
11300 /* handle -q option */
11301 if (quiet) Config_updateBool(QUIET,TRUE);
11302}
static bool setFlagStr(const QCString &label)
Definition debug.cpp:105
static EmojiEntityMapper & instance()
Returns the one and only instance of the Emoji entity mapper.
Definition emoji.cpp:1920
void writeEmojiFile(TextStream &t)
Writes the list of supported emojis to the given file.
Definition emoji.cpp:1941
bool exists() const
Definition fileinfo.cpp:30
static void writeFooterFile(TextStream &t)
Definition htmlgen.cpp:1426
static void writeStyleSheetFile(TextStream &t)
Definition htmlgen.cpp:1414
static void writeHeaderFile(TextStream &t, const QCString &cssname)
Definition htmlgen.cpp:1420
static void writeFooterFile(TextStream &t)
Definition latexgen.cpp:647
static void writeStyleSheetFile(TextStream &t)
Definition latexgen.cpp:653
static void writeHeaderFile(TextStream &t)
Definition latexgen.cpp:641
static void writeStyleSheetFile(TextStream &t)
Definition rtfgen.cpp:348
static void writeExtensionsFile(TextStream &t)
Definition rtfgen.cpp:363
#define Config_updateBool(name, value)
Definition config.h:40
static void generateConfigFile(const QCString &configFile, bool shortList, bool updateOnly=FALSE)
Definition doxygen.cpp:9720
static void compareDoxyfile(Config::CompareMode diffList)
Definition doxygen.cpp:9754
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:1479
CompareMode
Definition config.h:54
bool parse(const QCString &fileName, bool update=FALSE, CompareMode compareMode=CompareMode::Full)
void setPerlModDoxyfile(const QCString &qs)
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_dumpSymbolMap, generateConfigFile(), getArg(), Config::init(), initTracing(), EmojiEntityMapper::instance(), QCString::isEmpty(), openOutputFile(), Config::parse(), Config::postProcess(), qPrint(), 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 10441 of file doxygen.cpp.

10453{
10454 std::string dirName = fi->absFilePath();
10455 if (paths && !dirName.empty())
10456 {
10457 paths->insert(dirName);
10458 }
10459 //printf("%s isSymLink()=%d\n",qPrint(dirName),fi->isSymLink());
10460 if (fi->isSymLink())
10461 {
10462 dirName = resolveSymlink(dirName);
10463 if (dirName.empty())
10464 {
10465 //printf("RECURSIVE SYMLINK: %s\n",qPrint(dirName));
10466 return; // recursive symlink
10467 }
10468 }
10469
10470 if (g_pathsVisited.find(dirName)!=g_pathsVisited.end())
10471 {
10472 //printf("PATH ALREADY VISITED: %s\n",qPrint(dirName));
10473 return; // already visited path
10474 }
10475 g_pathsVisited.insert(dirName);
10476
10477 Dir dir(dirName);
10478 msg("Searching for files in directory %s\n", qPrint(fi->absFilePath()));
10479 //printf("killSet=%p count=%d\n",killSet,killSet ? (int)killSet->count() : -1);
10480
10481 StringVector dirResultList;
10482
10483 for (const auto &dirEntry : dir.iterator())
10484 {
10485 FileInfo cfi(dirEntry.path());
10486 if (exclSet==nullptr || exclSet->find(cfi.absFilePath())==exclSet->end())
10487 { // file should not be excluded
10488 //printf("killSet->find(%s)\n",qPrint(cfi->absFilePath()));
10489 if (Config_getBool(EXCLUDE_SYMLINKS) && cfi.isSymLink())
10490 {
10491 }
10492 else if (!cfi.exists() || !cfi.isReadable())
10493 {
10494 if (errorIfNotExist)
10495 {
10496 warn_uncond("source '%s' is not a readable file or directory... skipping.\n",cfi.absFilePath().c_str());
10497 }
10498 }
10499 else if (cfi.isFile() &&
10500 (patList==nullptr || patternMatch(cfi,*patList)) &&
10501 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
10502 (killSet==nullptr || killSet->find(cfi.absFilePath())==killSet->end())
10503 )
10504 {
10505 std::string name=cfi.fileName();
10506 std::string path=cfi.dirPath()+"/";
10507 std::string fullName=path+name;
10508 if (fnMap)
10509 {
10510 auto fd = createFileDef(QCString(path),QCString(name));
10511 FileName *fn=nullptr;
10512 if (!name.empty())
10513 {
10514 fn = fnMap->add(QCString(name),QCString(fullName));
10515 fn->push_back(std::move(fd));
10516 }
10517 }
10518 dirResultList.push_back(fullName);
10519 if (resultSet) resultSet->insert(fullName);
10520 if (killSet) killSet->insert(fullName);
10521 }
10522 else if (recursive &&
10523 cfi.isDir() &&
10524 (exclPatList==nullptr || !patternMatch(cfi,*exclPatList)) &&
10525 cfi.fileName().at(0)!='.') // skip "." ".." and ".dir"
10526 {
10527 FileInfo acfi(cfi.absFilePath());
10528 readDir(&acfi,fnMap,exclSet,
10529 patList,exclPatList,&dirResultList,resultSet,errorIfNotExist,
10530 recursive,killSet,paths);
10531 }
10532 }
10533 }
10534 if (resultList && !dirResultList.empty())
10535 {
10536 // sort the resulting list to make the order platform independent.
10537 std::sort(dirResultList.begin(),
10538 dirResultList.end(),
10539 [](const auto &f1,const auto &f2) { return qstricmp(f1.c_str(),f2.c_str())<0; });
10540
10541 // append the sorted results to resultList
10542 resultList->insert(resultList->end(), dirResultList.begin(), dirResultList.end());
10543 }
10544}
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:263
bool patternMatch(const FileInfo &fi, const StringVector &patList)
Definition util.cpp:5923

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(), qPrint(), 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 10551 of file doxygen.cpp.

10563{
10564 //printf("killSet count=%d\n",killSet ? (int)killSet->size() : -1);
10565 // strip trailing slashes
10566 if (s.isEmpty()) return;
10567
10568 g_pathsVisited.clear();
10569
10570 FileInfo fi(s.str());
10571 //printf("readFileOrDirectory(%s)\n",s);
10572 {
10573 if (exclSet==nullptr || exclSet->find(fi.absFilePath())==exclSet->end())
10574 {
10575 if (Config_getBool(EXCLUDE_SYMLINKS) && fi.isSymLink())
10576 {
10577 }
10578 else if (!fi.exists() || !fi.isReadable())
10579 {
10580 if (errorIfNotExist)
10581 {
10582 warn_uncond("source '%s' is not a readable file or directory... skipping.\n",qPrint(s));
10583 }
10584 }
10585 else if (fi.isFile())
10586 {
10587 std::string dirPath = fi.dirPath(true);
10588 std::string filePath = fi.absFilePath();
10589 if (paths && !dirPath.empty())
10590 {
10591 paths->insert(dirPath);
10592 }
10593 //printf("killSet.find(%s)=%d\n",qPrint(fi.absFilePath()),killSet.find(fi.absFilePath())!=killSet.end());
10594 if (killSet==nullptr || killSet->find(filePath)==killSet->end())
10595 {
10596 std::string name=fi.fileName();
10597 if (fnMap)
10598 {
10599 auto fd = createFileDef(QCString(dirPath+"/"),QCString(name));
10600 if (!name.empty())
10601 {
10602 FileName *fn = fnMap->add(QCString(name),QCString(filePath));
10603 fn->push_back(std::move(fd));
10604 }
10605 }
10606 if (resultList || resultSet)
10607 {
10608 if (resultList) resultList->push_back(filePath);
10609 if (resultSet) resultSet->insert(filePath);
10610 }
10611
10612 if (killSet) killSet->insert(fi.absFilePath());
10613 }
10614 }
10615 else if (fi.isDir()) // readable dir
10616 {
10617 readDir(&fi,fnMap,exclSet,patList,
10618 exclPatList,resultList,resultSet,errorIfNotExist,
10619 recursive,killSet,paths);
10620 }
10621 }
10622 }
10623}

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(), qPrint(), 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 9772 of file doxygen.cpp.

9773{
9774 QCString fileName;
9775 QCString destName;
9776 int eqPos = tagLine.find('=');
9777 if (eqPos!=-1) // tag command contains a destination
9778 {
9779 fileName = tagLine.left(eqPos).stripWhiteSpace();
9780 destName = tagLine.right(tagLine.length()-eqPos-1).stripWhiteSpace();
9781 if (fileName.isEmpty() || destName.isEmpty()) return;
9782 //printf("insert tagDestination %s->%s\n",qPrint(fi.fileName()),qPrint(destName));
9783 }
9784 else
9785 {
9786 fileName = tagLine;
9787 }
9788
9789 FileInfo fi(fileName.str());
9790 if (!fi.exists() || !fi.isFile())
9791 {
9792 err("Tag file '%s' does not exist or is not a file. Skipping it...\n",
9793 qPrint(fileName));
9794 return;
9795 }
9796
9797 if (Doxygen::tagFileSet.find(fi.absFilePath().c_str()) != Doxygen::tagFileSet.end()) return;
9798
9799 Doxygen::tagFileSet.emplace(fi.absFilePath());
9800
9801 if (!destName.isEmpty())
9802 {
9804 std::make_pair(fi.absFilePath(), destName.str()));
9805 msg("Reading tag file '%s', location '%s'...\n",qPrint(fileName),qPrint(destName));
9806 }
9807 else
9808 msg("Reading tag file '%s'...\n",qPrint(fileName));
9809
9810 parseTagFile(root,fi.absFilePath().c_str());
9811}
static StringUnorderedSet tagFileSet
Definition doxygen.h:107
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(), qPrint(), 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 1301 of file doxygen.cpp.

1302{
1303 ClassDefSet visitedClasses;
1304
1305 bool done=FALSE;
1306 //int iteration=0;
1307 while (!done)
1308 {
1309 done=TRUE;
1310 //++iteration;
1311 struct ClassAlias
1312 {
1313 ClassAlias(const QCString &name,std::unique_ptr<ClassDef> cd,DefinitionMutable *ctx) :
1314 aliasFullName(name),aliasCd(std::move(cd)), aliasContext(ctx) {}
1315 QCString aliasFullName;
1316 std::unique_ptr<ClassDef> aliasCd;
1317 DefinitionMutable *aliasContext;
1318 };
1319 std::vector<ClassAlias> aliases;
1320 for (const auto &icd : *Doxygen::classLinkedMap)
1321 {
1322 ClassDefMutable *cd = toClassDefMutable(icd.get());
1323 if (cd && visitedClasses.find(icd.get())==visitedClasses.end())
1324 {
1325 QCString name = stripAnonymousNamespaceScope(icd->name());
1326 //printf("processing=%s, iteration=%d\n",qPrint(cd->name()),iteration);
1327 // also add class to the correct structural context
1329 name,icd->getFileDef(),nullptr);
1330 if (d)
1331 {
1332 //printf("****** adding %s to scope %s in iteration %d\n",qPrint(cd->name()),qPrint(d->name()),iteration);
1334 if (dm)
1335 {
1336 dm->addInnerCompound(cd);
1337 }
1338 cd->setOuterScope(d);
1339
1340 // for inline namespace add an alias of the class to the outer scope
1342 {
1344 //printf("nd->isInline()=%d\n",nd->isInline());
1345 if (nd && nd->isInline())
1346 {
1347 d = d->getOuterScope();
1348 if (d)
1349 {
1350 dm = toDefinitionMutable(d);
1351 if (dm)
1352 {
1353 auto aliasCd = createClassDefAlias(d,cd);
1354 QCString aliasFullName = d->qualifiedName()+"::"+aliasCd->localName();
1355 aliases.emplace_back(aliasFullName,std::move(aliasCd),dm);
1356 //printf("adding %s to %s as %s\n",qPrint(aliasCd->name()),qPrint(d->name()),qPrint(aliasFullName));
1357 }
1358 }
1359 }
1360 else
1361 {
1362 break;
1363 }
1364 }
1365
1366 visitedClasses.insert(icd.get());
1367 done=FALSE;
1368 }
1369 //else
1370 //{
1371 // printf("****** ignoring %s: scope not (yet) found in iteration %d\n",qPrint(cd->name()),iteration);
1372 //}
1373 }
1374 }
1375 // add aliases
1376 for (auto &alias : aliases)
1377 {
1378 ClassDef *aliasCd = Doxygen::classLinkedMap->add(alias.aliasFullName,std::move(alias.aliasCd));
1379 if (aliasCd)
1380 {
1381 alias.aliasContext->addInnerCompound(aliasCd);
1382 }
1383 }
1384 }
1385
1386 //give warnings for unresolved compounds
1387 for (const auto &icd : *Doxygen::classLinkedMap)
1388 {
1389 ClassDefMutable *cd = toClassDefMutable(icd.get());
1390 if (cd && visitedClasses.find(icd.get())==visitedClasses.end())
1391 {
1393 //printf("processing unresolved=%s, iteration=%d\n",qPrint(cd->name()),iteration);
1394 /// create the scope artificially
1395 // anyway, so we can at least relate scopes properly.
1396 Definition *d = buildScopeFromQualifiedName(name,cd->getLanguage(),nullptr);
1397 if (d && d!=cd && !cd->getDefFileName().isEmpty())
1398 // avoid recursion in case of redundant scopes, i.e: namespace N { class N::C {}; }
1399 // for this case doxygen assumes the existence of a namespace N::N in which C is to be found!
1400 // also avoid warning for stuff imported via a tagfile.
1401 {
1403 if (dm)
1404 {
1405 dm->addInnerCompound(cd);
1406 }
1407 cd->setOuterScope(d);
1408 warn(cd->getDefFileName(),cd->getDefLine(),
1409 "Internal inconsistency: scope for class %s not "
1410 "found!",qPrint(name)
1411 );
1412 }
1413 }
1414 }
1415}
std::unique_ptr< ClassDef > createClassDefAlias(const Definition *newScope, const ClassDef *cd)
Definition classdef.cpp:634

References LinkedMap< T, Hash, KeyEqual, Map >::add(), 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(), qPrint(), 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 10369 of file doxygen.cpp.

10370{
10371 int sepPos=0;
10372 int oldPos=0;
10373 StringUnorderedSet nonSymlinks;
10374 StringUnorderedSet known;
10375 QCString result(path);
10376 QCString oldPrefix = "/";
10377 do
10378 {
10379#if defined(_WIN32)
10380 // UNC path, skip server and share name
10381 if (sepPos==0 && (result.startsWith("//") || result.startsWith("\\\\")))
10382 sepPos = result.find('/',2);
10383 if (sepPos!=-1)
10384 sepPos = result.find('/',sepPos+1);
10385#else
10386 sepPos = result.find('/',sepPos+1);
10387#endif
10388 QCString prefix = sepPos==-1 ? result : result.left(sepPos);
10389 if (nonSymlinks.find(prefix.str())==nonSymlinks.end())
10390 {
10391 FileInfo fi(prefix.str());
10392 if (fi.isSymLink())
10393 {
10394 QCString target = fi.readLink();
10395 bool isRelative = FileInfo(target.str()).isRelative();
10396 if (isRelative)
10397 {
10398 target = Dir::cleanDirPath(oldPrefix.str()+"/"+target.str());
10399 }
10400 if (sepPos!=-1)
10401 {
10402 if (fi.isDir() && target.length()>0 && target.at(target.length()-1)!='/')
10403 {
10404 target+='/';
10405 }
10406 target+=result.mid(sepPos);
10407 }
10408 result = Dir::cleanDirPath(target.str());
10409 if (known.find(result.str())!=known.end()) return std::string(); // recursive symlink!
10410 known.insert(result.str());
10411 if (isRelative)
10412 {
10413 sepPos = oldPos;
10414 }
10415 else // link to absolute path
10416 {
10417 sepPos = 0;
10418 oldPrefix = "/";
10419 }
10420 }
10421 else
10422 {
10423 nonSymlinks.insert(prefix.str());
10424 oldPrefix = prefix;
10425 }
10426 oldPos = sepPos;
10427 }
10428 }
10429 while (sepPos!=-1);
10430 return Dir::cleanDirPath(result.str());
10431}
static std::string cleanDirPath(const std::string &path)
Definition dir.cpp:355
bool isRelative() const
Definition fileinfo.cpp:58
QCString & insert(size_t index, const QCString &s)
Definition qcstring.h:308

References QCString::at(), Dir::cleanDirPath(), QCString::find(), QCString::insert(), FileInfo::isDir(), FileInfo::isRelative(), FileInfo::isSymLink(), QCString::left(), QCString::length(), QCString::mid(), prefix, FileInfo::readLink(), QCString::startsWith(), and QCString::str().

Referenced by readDir().

◆ resolveUserReferences()

static void resolveUserReferences ( )
static

Definition at line 9268 of file doxygen.cpp.

9269{
9270 for (const auto &si : SectionManager::instance())
9271 {
9272 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
9273 // qPrint(si->label),si->definition?qPrint(si->definition->name()):"<none>",
9274 // qPrint(si->fileName));
9275 PageDef *pd=nullptr;
9276
9277 // hack: the items of a todo/test/bug/deprecated list are all fragments from
9278 // different files, so the resulting section's all have the wrong file
9279 // name (not from the todo/test/bug/deprecated list, but from the file in
9280 // which they are defined). We correct this here by looking at the
9281 // generated section labels!
9282 for (const RefListManager::Ptr &rl : RefListManager::instance())
9283 {
9284 QCString label="_"+rl->listName(); // "_todo", "_test", ...
9285 if (si->label().left(label.length())==label)
9286 {
9287 si->setFileName(rl->listName());
9288 si->setGenerated(TRUE);
9289 break;
9290 }
9291 }
9292
9293 //printf("start: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9294 if (!si->generated())
9295 {
9296 // if this section is in a page and the page is in a group, then we
9297 // have to adjust the link file name to point to the group.
9298 if (!si->fileName().isEmpty() &&
9299 (pd=Doxygen::pageLinkedMap->find(si->fileName())) &&
9300 pd->getGroupDef())
9301 {
9302 si->setFileName(pd->getGroupDef()->getOutputFileBase());
9303 }
9304
9305 if (si->definition())
9306 {
9307 // TODO: there should be one function in Definition that returns
9308 // the file to link to, so we can avoid the following tests.
9309 const GroupDef *gd=nullptr;
9310 if (si->definition()->definitionType()==Definition::TypeMember)
9311 {
9312 gd = (toMemberDef(si->definition()))->getGroupDef();
9313 }
9314
9315 if (gd)
9316 {
9317 si->setFileName(gd->getOutputFileBase());
9318 }
9319 else
9320 {
9321 //si->fileName=si->definition->getOutputFileBase();
9322 //printf("Setting si->fileName to %s\n",qPrint(si->fileName));
9323 }
9324 }
9325 }
9326 //printf("end: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9327 }
9328}
virtual const GroupDef * getGroupDef() const =0

References LinkedMap< T, Hash, KeyEqual, Map >::find(), 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 9599 of file doxygen.cpp.

9600{
9601 std::string oldDir = Dir::currentDirPath();
9602 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
9605 {
9606 err("failed to run html help compiler on %s\n", qPrint(HtmlHelp::hhpFileName));
9607 }
9608 Dir::setCurrent(oldDir);
9609}
@ ExtCmd
Definition debug.h:35
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:543

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

9612{
9613 QCString args = Qhp::qhpFileName + " -o \"" + Qhp::getQchFileName() + "\"";
9614 std::string oldDir = Dir::currentDirPath();
9615 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
9616
9617 QCString qhgLocation=Config_getString(QHG_LOCATION);
9618 if (Debug::isFlagSet(Debug::Qhp)) // produce info for debugging
9619 {
9620 // run qhelpgenerator -v and extract the Qt version used
9621 QCString cmd=qhgLocation+ " -v 2>&1";
9622 Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",qPrint(cmd));
9623 FILE *f=Portable::popen(cmd,"r");
9624 if (!f)
9625 {
9626 err("could not execute %s\n",qPrint(qhgLocation));
9627 }
9628 else
9629 {
9630 const size_t bufSize = 1024;
9631 char inBuf[bufSize+1];
9632 size_t numRead=fread(inBuf,1,bufSize,f);
9633 inBuf[numRead] = '\0';
9634 Debug::print(Debug::Qhp,0,inBuf);
9636
9637 int qtVersion=0;
9638 static const reg::Ex versionReg(R"(Qt (\d+)\.(\d+)\.(\d+))");
9640 std::string s = inBuf;
9641 if (reg::search(inBuf,match,versionReg))
9642 {
9643 qtVersion = 10000*QCString(match[1].str()).toInt() +
9644 100*QCString(match[2].str()).toInt() +
9645 QCString(match[3].str()).toInt();
9646 }
9647 if (qtVersion>0 && (qtVersion<60000 || qtVersion >= 60205))
9648 {
9649 // dump the output of qhelpgenerator -c file.qhp
9650 // Qt<6 or Qt>=6.2.5 or higher, see https://bugreports.qt.io/browse/QTBUG-101070
9651 cmd=qhgLocation+ " -c " + Qhp::qhpFileName + " 2>&1";
9652 Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",qPrint(cmd));
9653 f=Portable::popen(cmd,"r");
9654 if (!f)
9655 {
9656 err("could not execute %s\n",qPrint(qhgLocation));
9657 }
9658 else
9659 {
9660 std::string output;
9661 while ((numRead=fread(inBuf,1,bufSize,f))>0)
9662 {
9663 inBuf[numRead] = '\0';
9664 output += inBuf;
9665 }
9667 Debug::print(Debug::Qhp,0,output.c_str());
9668 }
9669 }
9670 }
9671 }
9672
9673 if (Portable::system(qhgLocation, args, FALSE))
9674 {
9675 err("failed to run qhelpgenerator on %s\n",qPrint(Qhp::qhpFileName));
9676 }
9677 Dir::setCurrent(oldDir);
9678}
@ Qhp
Definition debug.h:43
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:439
FILE * popen(const QCString &name, const QCString &type)
Definition portable.cpp:487
int pclose(FILE *stream)
Definition portable.cpp:496

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

Referenced by generateOutput().

◆ scopeIsTemplate()

static bool scopeIsTemplate ( const Definition * d)
static

Definition at line 5480 of file doxygen.cpp.

5481{
5482 bool result=FALSE;
5484 {
5485 result = !(toClassDef(d))->templateArguments().empty() ||
5487 }
5488 return result;
5489}
ClassDef * toClassDef(Definition *d)

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

Referenced by addMemberFunction(), and scopeIsTemplate().

◆ searchInputFiles()

void searchInputFiles ( )

Definition at line 11573 of file doxygen.cpp.

11574{
11575 StringUnorderedSet killSet;
11576
11577 const StringVector &exclPatterns = Config_getList(EXCLUDE_PATTERNS);
11578 bool alwaysRecursive = Config_getBool(RECURSIVE);
11579 StringUnorderedSet excludeNameSet;
11580
11581 // gather names of all files in the include path
11582 g_s.begin("Searching for include files...\n");
11583 killSet.clear();
11584 const StringVector &includePathList = Config_getList(INCLUDE_PATH);
11585 for (const auto &s : includePathList)
11586 {
11587 size_t plSize = Config_getList(INCLUDE_FILE_PATTERNS).size();
11588 const StringVector &pl = plSize==0 ? Config_getList(FILE_PATTERNS) :
11589 Config_getList(INCLUDE_FILE_PATTERNS);
11590 readFileOrDirectory(s.c_str(), // s
11592 nullptr, // exclSet
11593 &pl, // patList
11594 &exclPatterns, // exclPatList
11595 nullptr, // resultList
11596 nullptr, // resultSet
11597 false, // INCLUDE_PATH isn't recursive
11598 TRUE, // errorIfNotExist
11599 &killSet); // killSet
11600 }
11601 g_s.end();
11602
11603 g_s.begin("Searching for example files...\n");
11604 killSet.clear();
11605 const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
11606 for (const auto &s : examplePathList)
11607 {
11608 readFileOrDirectory(s.c_str(), // s
11610 nullptr, // exclSet
11611 &Config_getList(EXAMPLE_PATTERNS), // patList
11612 nullptr, // exclPatList
11613 nullptr, // resultList
11614 nullptr, // resultSet
11615 (alwaysRecursive || Config_getBool(EXAMPLE_RECURSIVE)), // recursive
11616 TRUE, // errorIfNotExist
11617 &killSet); // killSet
11618 }
11619 g_s.end();
11620
11621 g_s.begin("Searching for images...\n");
11622 killSet.clear();
11623 const StringVector &imagePathList=Config_getList(IMAGE_PATH);
11624 for (const auto &s : imagePathList)
11625 {
11626 readFileOrDirectory(s.c_str(), // s
11628 nullptr, // exclSet
11629 nullptr, // patList
11630 nullptr, // exclPatList
11631 nullptr, // resultList
11632 nullptr, // resultSet
11633 alwaysRecursive, // recursive
11634 TRUE, // errorIfNotExist
11635 &killSet); // killSet
11636 }
11637 g_s.end();
11638
11639 g_s.begin("Searching for dot files...\n");
11640 killSet.clear();
11641 const StringVector &dotFileList=Config_getList(DOTFILE_DIRS);
11642 for (const auto &s : dotFileList)
11643 {
11644 readFileOrDirectory(s.c_str(), // s
11646 nullptr, // exclSet
11647 nullptr, // patList
11648 nullptr, // exclPatList
11649 nullptr, // resultList
11650 nullptr, // resultSet
11651 alwaysRecursive, // recursive
11652 TRUE, // errorIfNotExist
11653 &killSet); // killSet
11654 }
11655 g_s.end();
11656
11657 g_s.begin("Searching for msc files...\n");
11658 killSet.clear();
11659 const StringVector &mscFileList=Config_getList(MSCFILE_DIRS);
11660 for (const auto &s : mscFileList)
11661 {
11662 readFileOrDirectory(s.c_str(), // s
11664 nullptr, // exclSet
11665 nullptr, // patList
11666 nullptr, // exclPatList
11667 nullptr, // resultList
11668 nullptr, // resultSet
11669 alwaysRecursive, // recursive
11670 TRUE, // errorIfNotExist
11671 &killSet); // killSet
11672 }
11673 g_s.end();
11674
11675 g_s.begin("Searching for dia files...\n");
11676 killSet.clear();
11677 const StringVector &diaFileList=Config_getList(DIAFILE_DIRS);
11678 for (const auto &s : diaFileList)
11679 {
11680 readFileOrDirectory(s.c_str(), // s
11682 nullptr, // exclSet
11683 nullptr, // patList
11684 nullptr, // exclPatList
11685 nullptr, // resultList
11686 nullptr, // resultSet
11687 alwaysRecursive, // recursive
11688 TRUE, // errorIfNotExist
11689 &killSet); // killSet
11690 }
11691 g_s.end();
11692
11693 g_s.begin("Searching for files to exclude\n");
11694 const StringVector &excludeList = Config_getList(EXCLUDE);
11695 for (const auto &s : excludeList)
11696 {
11697 readFileOrDirectory(s.c_str(), // s
11698 nullptr, // fnDict
11699 nullptr, // exclSet
11700 &Config_getList(FILE_PATTERNS), // patList
11701 nullptr, // exclPatList
11702 nullptr, // resultList
11703 &excludeNameSet, // resultSet
11704 alwaysRecursive, // recursive
11705 FALSE); // errorIfNotExist
11706 }
11707 g_s.end();
11708
11709 /**************************************************************************
11710 * Determine Input Files *
11711 **************************************************************************/
11712
11713 g_s.begin("Searching INPUT for files to process...\n");
11714 killSet.clear();
11715 Doxygen::inputPaths.clear();
11716 const StringVector &inputList=Config_getList(INPUT);
11717 for (const auto &s : inputList)
11718 {
11719 QCString path=s.c_str();
11720 size_t l = path.length();
11721 if (l>0)
11722 {
11723 // strip trailing slashes
11724 if (path.at(l-1)=='\\' || path.at(l-1)=='/') path=path.left(l-1);
11725
11727 path, // s
11729 &excludeNameSet, // exclSet
11730 &Config_getList(FILE_PATTERNS), // patList
11731 &exclPatterns, // exclPatList
11732 &g_inputFiles, // resultList
11733 nullptr, // resultSet
11734 alwaysRecursive, // recursive
11735 TRUE, // errorIfNotExist
11736 &killSet, // killSet
11737 &Doxygen::inputPaths); // paths
11738 }
11739 }
11740
11741 // Sort the FileDef objects by full path to get a predictable ordering over multiple runs
11744 [](const auto &f1,const auto &f2)
11745 {
11746 return qstricmp(f1->fullName(),f2->fullName())<0;
11747 });
11748 for (auto &fileName : *Doxygen::inputNameLinkedMap)
11749 {
11750 if (fileName->size()>1)
11751 {
11752 std::sort(fileName->begin(),fileName->end(),[](const auto &f1,const auto &f2)
11753 {
11754 return qstricmp(f1->absFilePath(),f2->absFilePath())<0;
11755 });
11756 }
11757 }
11758 if (Doxygen::inputNameLinkedMap->empty())
11759 {
11760 warn_uncond("No files to be processed, please check your settings, in particular INPUT, FILE_PATTERNS, and RECURSIVE\n");
11761 }
11762 g_s.end();
11763}
static StringUnorderedSet inputPaths
Definition doxygen.h:95
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(), Statistics::begin(), Config_getBool, Config_getList, Doxygen::diaFileNameLinkedMap, Doxygen::dotFileNameLinkedMap, end(), Statistics::end(), Doxygen::exampleNameLinkedMap, FALSE, g_inputFiles, g_s, Doxygen::imageNameLinkedMap, Doxygen::includeNameLinkedMap, Doxygen::inputNameLinkedMap, Doxygen::inputPaths, QCString::left(), QCString::length(), Doxygen::mscFileNameLinkedMap, qstricmp(), readFileOrDirectory(), QCString::size(), TRUE, and warn_uncond.

Referenced by parseInput().

◆ setAnonymousEnumType()

static void setAnonymousEnumType ( )
static

Definition at line 8419 of file doxygen.cpp.

8420{
8421 for (const auto &cd : *Doxygen::classLinkedMap)
8422 {
8423 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8424 if (cdm)
8425 {
8426 cdm->setAnonymousEnumType();
8427 }
8428 }
8429}
virtual void setAnonymousEnumType()=0

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

Referenced by parseInput().

◆ sortMemberLists()

static void sortMemberLists ( )
static

Definition at line 8324 of file doxygen.cpp.

8325{
8326 // sort class member lists
8327 for (const auto &cd : *Doxygen::classLinkedMap)
8328 {
8329 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8330 if (cdm)
8331 {
8332 cdm->sortMemberLists();
8333 }
8334 }
8335
8336 // sort namespace member lists
8337 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8338 {
8340 if (ndm)
8341 {
8342 ndm->sortMemberLists();
8343 }
8344 }
8345
8346 // sort file member lists
8347 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8348 {
8349 for (const auto &fd : *fn)
8350 {
8351 fd->sortMemberLists();
8352 }
8353 }
8354
8355 // sort group member lists
8356 for (const auto &gd : *Doxygen::groupLinkedMap)
8357 {
8358 gd->sortMemberLists();
8359 }
8360
8362}
virtual void sortMemberLists()=0
void sortMemberLists()
virtual void sortMemberLists()=0

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

Referenced by parseInput().

◆ stopDoxygen()

static void stopDoxygen ( int )
static

Definition at line 11442 of file doxygen.cpp.

11443{
11444 signal(SIGINT,SIG_DFL); // Re-register signal handler for default action
11445 Dir thisDir;
11446 msg("Cleaning up...\n");
11447 if (!Doxygen::filterDBFileName.isEmpty())
11448 {
11449 thisDir.remove(Doxygen::filterDBFileName.str());
11450 }
11451 killpg(0,SIGINT);
11454 exitTracing();
11455 exit(1);
11456}
static volatile bool terminating
Definition doxygen.h:130

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

Referenced by parseInput().

◆ stripTemplateSpecifiers()

QCString stripTemplateSpecifiers ( const QCString & s)

Definition at line 664 of file doxygen.cpp.

665{
666 size_t l = s.length();
667 int count=0;
668 int round=0;
669 QCString result;
670 for (size_t i=0;i<l;i++)
671 {
672 char c=s.at(i);
673 if (c=='(') round++;
674 else if (c==')' && round>0) round--;
675 else if (c=='<' && round==0) count++;
676 if (count==0)
677 {
678 result+=c;
679 }
680 if (c=='>' && round==0 && count>0) count--;
681 }
682 //printf("stripTemplateSpecifiers(%s)=%s\n",qPrint(s),qPrint(result));
683 return result;
684}

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

5581{
5582 auto dstIt = dst.begin();
5583 for (const Argument &sa : src)
5584 {
5585 QCString dstType = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.type.str());
5586 QCString dstArray = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.array.str());
5587 if (dstIt == dst.end())
5588 {
5589 Argument da = sa;
5590 da.type = dstType;
5591 da.array = dstArray;
5592 dst.push_back(da);
5593 dstIt = dst.end();
5594 }
5595 else
5596 {
5597 Argument da = *dstIt;
5598 da.type = dstType;
5599 da.array = dstArray;
5600 ++dstIt;
5601 }
5602 }
5607 srcTempArgLists,dstTempArgLists,
5608 src.trailingReturnType().str()));
5609 dst.setIsDeleted(src.isDeleted());
5610 dst.setRefQualifier(src.refQualifier());
5611 dst.setNoParameters(src.noParameters());
5612 //printf("substituteTemplatesInArgList: replacing %s with %s\n",
5613 // qPrint(argListToString(src)),qPrint(argListToString(dst))
5614 // );
5615}
RefQualifierType refQualifier() const
Definition arguments.h:109
bool noParameters() const
Definition arguments.h:110
bool pureSpecifier() const
Definition arguments.h:106
iterator end()
Definition arguments.h:87
void setTrailingReturnType(const QCString &s)
Definition arguments.h:115
bool isDeleted() const
Definition arguments.h:108
QCString trailingReturnType() const
Definition arguments.h:107
void setPureSpecifier(bool b)
Definition arguments.h:114
bool constSpecifier() const
Definition arguments.h:104
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
bool volatileSpecifier() const
Definition arguments.h:105
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:5491
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 5491 of file doxygen.cpp.

5496{
5497 std::string dst;
5498 static const reg::Ex re(R"(\a\w*)");
5499 reg::Iterator it(src,re);
5501 //printf("type=%s\n",qPrint(sa->type));
5502 size_t p=0;
5503 for (; it!=end ; ++it) // for each word in srcType
5504 {
5505 const auto &match = *it;
5506 size_t i = match.position();
5507 size_t l = match.length();
5508 bool found=FALSE;
5509 dst+=src.substr(p,i-p);
5510 std::string name=match.str();
5511
5512 auto srcIt = srcTempArgLists.begin();
5513 auto dstIt = dstTempArgLists.begin();
5514 while (srcIt!=srcTempArgLists.end() && !found)
5515 {
5516 const ArgumentList *tdAli = nullptr;
5517 std::vector<Argument>::const_iterator tdaIt;
5518 if (dstIt!=dstTempArgLists.end())
5519 {
5520 tdAli = &(*dstIt);
5521 tdaIt = tdAli->begin();
5522 ++dstIt;
5523 }
5524
5525 const ArgumentList &tsaLi = *srcIt;
5526 for (auto tsaIt = tsaLi.begin(); tsaIt!=tsaLi.end() && !found; ++tsaIt)
5527 {
5528 Argument tsa = *tsaIt;
5529 const Argument *tda = nullptr;
5530 if (tdAli && tdaIt!=tdAli->end())
5531 {
5532 tda = &(*tdaIt);
5533 ++tdaIt;
5534 }
5535 //if (tda) printf("tsa=%s|%s tda=%s|%s\n",
5536 // qPrint(tsa.type),qPrint(tsa.name),
5537 // qPrint(tda->type),qPrint(tda->name));
5538 if (name==tsa.name.str())
5539 {
5540 if (tda && tda->name.isEmpty())
5541 {
5542 QCString tdaName = tda->name;
5543 QCString tdaType = tda->type;
5544 int vc=0;
5545 if (tdaType.startsWith("class ")) vc=6;
5546 else if (tdaType.startsWith("typename ")) vc=9;
5547 if (vc>0) // convert type=="class T" to type=="class" name=="T"
5548 {
5549 tdaName = tdaType.mid(vc);
5550 }
5551 if (!tdaName.isEmpty())
5552 {
5553 name=tdaName.str(); // substitute
5554 found=TRUE;
5555 }
5556 }
5557 }
5558 }
5559
5560 //printf(" srcList='%s' dstList='%s faList='%s'\n",
5561 // qPrint(argListToString(srclali.current())),
5562 // qPrint(argListToString(dstlali.current())),
5563 // funcTempArgList ? qPrint(argListToString(funcTempArgList)) : "<none>");
5564 ++srcIt;
5565 }
5566 dst+=name;
5567 p=i+l;
5568 }
5569 dst+=src.substr(p);
5570 //printf(" substituteTemplatesInString(%s)=%s\n",
5571 // qPrint(src),qPrint(dst));
5572 return QCString(dst);
5573}
QCString name
Definition arguments.h:39

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

3821{
3822 AUTO_TRACE();
3823
3824 // find matching function declaration and definitions.
3825 for (const auto &mn : *Doxygen::functionNameLinkedMap)
3826 {
3827 //printf("memberName=%s count=%d\n",mn->memberName(),mn->count());
3828 /* find a matching function declaration and definition for this function */
3829 for (const auto &imdec : *mn)
3830 {
3831 MemberDefMutable *mdec = toMemberDefMutable(imdec.get());
3832 if (mdec &&
3833 (mdec->isPrototype() ||
3834 (mdec->isVariable() && mdec->isExternal())
3835 ))
3836 {
3837 for (const auto &imdef : *mn)
3838 {
3839 MemberDefMutable *mdef = toMemberDefMutable(imdef.get());
3840 if (mdef && mdec!=mdef &&
3841 mdec->getNamespaceDef()==mdef->getNamespaceDef())
3842 {
3844 }
3845 }
3846 }
3847 }
3848 }
3849}
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 3853 of file doxygen.cpp.

3854{
3855 AUTO_TRACE();
3856 for (const auto &mn : *Doxygen::functionNameLinkedMap)
3857 {
3858 MemberDefMutable *mdef=nullptr,*mdec=nullptr;
3859 /* find a matching function declaration and definition for this function */
3860 for (const auto &imd : *mn)
3861 {
3862 MemberDefMutable *md = toMemberDefMutable(imd.get());
3863 if (md)
3864 {
3865 if (md->isPrototype())
3866 mdec=md;
3867 else if (md->isVariable() && md->isExternal())
3868 mdec=md;
3869
3870 if (md->isFunction() && !md->isStatic() && !md->isPrototype())
3871 mdef=md;
3872 else if (md->isVariable() && !md->isExternal() && !md->isStatic())
3873 mdef=md;
3874 }
3875
3876 if (mdef && mdec) break;
3877 }
3878 if (mdef && mdec)
3879 {
3880 const ArgumentList &mdefAl = mdef->argumentList();
3881 const ArgumentList &mdecAl = mdec->argumentList();
3882 if (
3883 matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),const_cast<ArgumentList*>(&mdefAl),
3884 mdec->getOuterScope(),mdec->getFileDef(),const_cast<ArgumentList*>(&mdecAl),
3885 TRUE,mdef->getLanguage()
3886 )
3887 ) /* match found */
3888 {
3889 AUTO_TRACE_ADD("merging references for mdec={} mdef={}",mdec->name(),mdef->name());
3890 mdef->mergeReferences(mdec);
3891 mdec->mergeReferences(mdef);
3892 mdef->mergeReferencedBy(mdec);
3893 mdec->mergeReferencedBy(mdef);
3894 }
3895 }
3896 }
3897}
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 3901 of file doxygen.cpp.

3902{
3903 AUTO_TRACE();
3904 // find match between function declaration and definition for
3905 // related functions
3906 for (const auto &mn : *Doxygen::functionNameLinkedMap)
3907 {
3908 /* find a matching function declaration and definition for this function */
3909 // for each global function
3910 for (const auto &imd : *mn)
3911 {
3912 MemberDefMutable *md = toMemberDefMutable(imd.get());
3913 if (md)
3914 {
3915 //printf(" Function '%s'\n",qPrint(md->name()));
3917 if (rmn) // check if there is a member with the same name
3918 {
3919 //printf(" Member name found\n");
3920 // for each member with the same name
3921 for (const auto &irmd : *rmn)
3922 {
3923 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
3924 //printf(" Member found: related='%d'\n",rmd->isRelated());
3925 if (rmd &&
3926 (rmd->isRelated() || rmd->isForeign()) && // related function
3928 rmd->getOuterScope(),rmd->getFileDef(),&rmd->argumentList(),
3929 TRUE,md->getLanguage()
3930 )
3931 )
3932 {
3933 AUTO_TRACE_ADD("Found related member '{}'",md->name());
3934 if (rmd->relatedAlso())
3935 md->setRelatedAlso(rmd->relatedAlso());
3936 else if (rmd->isForeign())
3937 md->makeForeign();
3938 else
3939 md->makeRelated();
3940 }
3941 }
3942 }
3943 }
3944 }
3945 }
3946}
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, LinkedMap< T, Hash, KeyEqual, Map >::find(), 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 3950 of file doxygen.cpp.

3951{
3952 AUTO_TRACE();
3953 for (const auto &[qualifiedName,bodyInfo] : Doxygen::staticInitMap)
3954 {
3955 size_t i=qualifiedName.rfind("::");
3956 if (i!=std::string::npos)
3957 {
3958 QCString scope = qualifiedName.substr(0,i);
3959 QCString name = qualifiedName.substr(i+2);
3961 if (mn)
3962 {
3963 for (const auto &imd : *mn)
3964 {
3965 MemberDefMutable *md = toMemberDefMutable(imd.get());
3966 if (md && md->qualifiedName().str()==qualifiedName && md->isVariable())
3967 {
3968 AUTO_TRACE_ADD("found static member {} body [{}..{}]\n",
3969 md->qualifiedName(),bodyInfo.startLine,bodyInfo.endLine);
3970 md->setBodySegment(bodyInfo.defLine,
3971 bodyInfo.startLine,
3972 bodyInfo.endLine);
3973 }
3974 }
3975 }
3976 }
3977 }
3978}

References AUTO_TRACE, AUTO_TRACE_ADD, LinkedMap< T, Hash, KeyEqual, Map >::find(), 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 7418 of file doxygen.cpp.

7419{
7420 for (const auto &g : root->groups)
7421 {
7422 const GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
7423 if (gd)
7424 {
7426 if (ml)
7427 {
7428 MemberDefMutable *md = toMemberDefMutable(ml->find(name));
7429 if (md)
7430 {
7431 addEnumDocs(root,md);
7432 return TRUE;
7433 }
7434 }
7435 }
7436 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
7437 {
7438 warn(root->fileName, root->startLine,
7439 "Found non-existing group '%s' for the command '%s', ignoring command",
7440 qPrint(g.groupname), Grouping::getGroupPriName( g.pri )
7441 );
7442 }
7443 }
7444
7445 return FALSE;
7446}
virtual MemberList * getMemberList(MemberListType lt) const =0
MemberDef * find(const QCString &name)
Definition memberlist.h:92
@ MemberListType_decEnumMembers
Definition types.h:156

References addEnumDocs(), FALSE, Entry::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find(), MemberVector::find(), Grouping::getGroupPriName(), GroupDef::getMemberList(), Grouping::GROUPING_INGROUP, Doxygen::groupLinkedMap, Entry::groups, MemberListType_decEnumMembers, qPrint(), Entry::startLine, toMemberDefMutable(), TRUE, and warn.

Referenced by findEnumDocumentation().

◆ usage()

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

Definition at line 10713 of file doxygen.cpp.

10714{
10715 msg("Doxygen version %s\nCopyright Dimitri van Heesch 1997-2021\n\n",qPrint(versionString));
10716 msg("You can use doxygen in a number of ways:\n\n");
10717 msg("1) Use doxygen to generate a template configuration file*:\n");
10718 msg(" %s [-s] -g [configName]\n\n",qPrint(name));
10719 msg("2) Use doxygen to update an old configuration file*:\n");
10720 msg(" %s [-s] -u [configName]\n\n",qPrint(name));
10721 msg("3) Use doxygen to generate documentation using an existing ");
10722 msg("configuration file*:\n");
10723 msg(" %s [configName]\n\n",qPrint(name));
10724 msg("4) Use doxygen to generate a template file controlling the layout of the\n");
10725 msg(" generated documentation:\n");
10726 msg(" %s -l [layoutFileName]\n\n",qPrint(name));
10727 msg(" In case layoutFileName is omitted DoxygenLayout.xml will be used as filename.\n");
10728 msg(" If - is used for layoutFileName doxygen will write to standard output.\n\n");
10729 msg("5) Use doxygen to generate a template style sheet file for RTF, HTML or Latex.\n");
10730 msg(" RTF: %s -w rtf styleSheetFile\n",qPrint(name));
10731 msg(" HTML: %s -w html headerFile footerFile styleSheetFile [configFile]\n",qPrint(name));
10732 msg(" LaTeX: %s -w latex headerFile footerFile styleSheetFile [configFile]\n\n",qPrint(name));
10733 msg("6) Use doxygen to generate a rtf extensions file\n");
10734 msg(" %s -e rtf extensionsFile\n\n",qPrint(name));
10735 msg(" If - is used for extensionsFile doxygen will write to standard output.\n\n");
10736 msg("7) Use doxygen to compare the used configuration file with the template configuration file\n");
10737 msg(" %s -x [configFile]\n\n",qPrint(name));
10738 msg(" Use doxygen to compare the used configuration file with the template configuration file\n");
10739 msg(" without replacing the environment variables or CMake type replacement variables\n");
10740 msg(" %s -x_noenv [configFile]\n\n",qPrint(name));
10741 msg("8) Use doxygen to show a list of built-in emojis.\n");
10742 msg(" %s -f emoji outputFileName\n\n",qPrint(name));
10743 msg(" If - is used for outputFileName doxygen will write to standard output.\n\n");
10744 msg("*) If -s is specified the comments of the configuration items in the config file will be omitted.\n");
10745 msg(" If configName is omitted 'Doxyfile' will be used as a default.\n");
10746 msg(" If - is used for configFile doxygen will write / read the configuration to /from standard output / input.\n\n");
10747 msg("If -q is used for a doxygen documentation run, doxygen will see this as if QUIET=YES has been set.\n\n");
10748 msg("-v print version string, -V print extended version information\n");
10749 msg("-h,-? prints usage help information\n");
10750 msg("%s -d prints additional usage flags for debugging purposes\n",qPrint(name));
10751}

References msg(), and qPrint().

Referenced by readConfiguration().

◆ version()

static void version ( const bool extended)
static

Definition at line 10686 of file doxygen.cpp.

10687{
10688 QCString versionString = getFullVersion();
10689 msg("%s\n",qPrint(versionString));
10690 if (extended)
10691 {
10692 QCString extVers;
10693 if (!extVers.isEmpty()) extVers+= ", ";
10694 extVers += "sqlite3 ";
10695 extVers += sqlite3_libversion();
10696#if USE_LIBCLANG
10697 if (!extVers.isEmpty()) extVers+= ", ";
10698 extVers += "clang support ";
10699 extVers += CLANG_VERSION_STRING;
10700#endif
10701 if (!extVers.isEmpty())
10702 {
10703 int lastComma = extVers.findRev(',');
10704 if (lastComma != -1) extVers = extVers.replace(lastComma,1," and");
10705 msg(" with %s.\n",qPrint(extVers));
10706 }
10707 }
10708}
QCString & replace(size_t index, size_t len, const char *s)
Definition qcstring.cpp:212

References QCString::findRev(), QCString::isEmpty(), msg(), qPrint(), and QCString::replace().

Referenced by readConfiguration().

◆ vhdlCorrectMemberProperties()

static void vhdlCorrectMemberProperties ( )
static

Definition at line 7784 of file doxygen.cpp.

7785{
7786 // for each member name
7787 for (const auto &mn : *Doxygen::memberNameLinkedMap)
7788 {
7789 // for each member definition
7790 for (const auto &imd : *mn)
7791 {
7792 MemberDefMutable *md = toMemberDefMutable(imd.get());
7793 if (md)
7794 {
7796 }
7797 }
7798 }
7799 // for each member name
7800 for (const auto &mn : *Doxygen::functionNameLinkedMap)
7801 {
7802 // for each member definition
7803 for (const auto &imd : *mn)
7804 {
7805 MemberDefMutable *md = toMemberDefMutable(imd.get());
7806 if (md)
7807 {
7809 }
7810 }
7811 }
7812}
static void correctMemberProperties(MemberDefMutable *md)

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

Referenced by parseInput().

◆ writeTagFile()

static void writeTagFile ( )
static

Definition at line 11459 of file doxygen.cpp.

11460{
11461 QCString generateTagFile = Config_getString(GENERATE_TAGFILE);
11462 if (generateTagFile.isEmpty()) return;
11463
11464 std::ofstream f = Portable::openOutputStream(generateTagFile);
11465 if (!f.is_open())
11466 {
11467 err("cannot open tag file %s for writing\n",
11468 qPrint(generateTagFile)
11469 );
11470 return;
11471 }
11472 TextStream tagFile(&f);
11473 tagFile << "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>\n";
11474 tagFile << "<tagfile doxygen_version=\"" << getDoxygenVersion() << "\"";
11475 std::string gitVersion = getGitVersion();
11476 if (!gitVersion.empty())
11477 {
11478 tagFile << " doxygen_gitid=\"" << gitVersion << "\"";
11479 }
11480 tagFile << ">\n";
11481
11482 // for each file
11483 for (const auto &fn : *Doxygen::inputNameLinkedMap)
11484 {
11485 for (const auto &fd : *fn)
11486 {
11487 if (fd->isLinkableInProject()) fd->writeTagFile(tagFile);
11488 }
11489 }
11490 // for each class
11491 for (const auto &cd : *Doxygen::classLinkedMap)
11492 {
11493 ClassDefMutable *cdm = toClassDefMutable(cd.get());
11494 if (cdm && cdm->isLinkableInProject())
11495 {
11496 cdm->writeTagFile(tagFile);
11497 }
11498 }
11499 // for each concept
11500 for (const auto &cd : *Doxygen::conceptLinkedMap)
11501 {
11502 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
11503 if (cdm && cdm->isLinkableInProject())
11504 {
11505 cdm->writeTagFile(tagFile);
11506 }
11507 }
11508 // for each namespace
11509 for (const auto &nd : *Doxygen::namespaceLinkedMap)
11510 {
11512 if (ndm && nd->isLinkableInProject())
11513 {
11514 ndm->writeTagFile(tagFile);
11515 }
11516 }
11517 // for each group
11518 for (const auto &gd : *Doxygen::groupLinkedMap)
11519 {
11520 if (gd->isLinkableInProject()) gd->writeTagFile(tagFile);
11521 }
11522 // for each module
11523 for (const auto &mod : ModuleManager::instance().modules())
11524 {
11525 if (mod->isLinkableInProject()) mod->writeTagFile(tagFile);
11526 }
11527 // for each page
11528 for (const auto &pd : *Doxygen::pageLinkedMap)
11529 {
11530 if (pd->isLinkableInProject()) pd->writeTagFile(tagFile);
11531 }
11532 if (Doxygen::mainPage) Doxygen::mainPage->writeTagFile(tagFile);
11533
11534 tagFile << "</tagfile>\n";
11535}
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, ModuleManager::modules(), Doxygen::namespaceLinkedMap, Portable::openOutputStream(), Doxygen::pageLinkedMap, qPrint(), toClassDefMutable(), toConceptDefMutable(), toNamespaceDefMutable(), ClassDef::writeTagFile(), ConceptDefMutable::writeTagFile(), FileDef::writeTagFile(), GroupDef::writeTagFile(), and NamespaceDefMutable::writeTagFile().

Referenced by generateOutput().

Variable Documentation

◆ g_classEntries

◆ g_compoundKeywords

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

Definition at line 186 of file doxygen.cpp.

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

Referenced by filterMemberDocumentation().

◆ g_dumpSymbolMap

bool g_dumpSymbolMap = FALSE
static

Definition at line 183 of file doxygen.cpp.

Referenced by generateOutput(), and readConfiguration().

◆ g_inputFiles

◆ g_outputList

◆ g_s

◆ g_successfulRun

bool g_successfulRun = FALSE
static

Definition at line 182 of file doxygen.cpp.

Referenced by exitDoxygen(), and generateOutput().

◆ g_usingDeclarations

StringSet g_usingDeclarations
static

Definition at line 181 of file doxygen.cpp.

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