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

Go to the source code of this file.

Classes

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

Macros

#define HAS_SIGNALS
 

Enumerations

enum  FindBaseClassRelation_Mode { TemplateInstances , DocumentedOnly , Undocumented }
 

Functions

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

Variables

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

Macro Definition Documentation

◆ HAS_SIGNALS

#define HAS_SIGNALS

Definition at line 125 of file doxygen.cpp.

Enumeration Type Documentation

◆ FindBaseClassRelation_Mode

Enumerator
TemplateInstances 
DocumentedOnly 
Undocumented 

Definition at line 277 of file doxygen.cpp.

278{
282};
@ Undocumented
Definition doxygen.cpp:281
@ TemplateInstances
Definition doxygen.cpp:279
@ DocumentedOnly
Definition doxygen.cpp:280

Function Documentation

◆ addClassAndNestedClasses()

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

Definition at line 9018 of file doxygen.cpp.

9019{
9020 list.push_back(cd);
9021 for (const auto &innerCdi : cd->getClasses())
9022 {
9023 ClassDefMutable *innerCd = toClassDefMutable(innerCdi);
9024 if (innerCd && innerCd->isLinkableInProject() && innerCd->templateMaster()==nullptr &&
9025 protectionLevelVisible(innerCd->protection()) &&
9026 !innerCd->isEmbeddedInOuterScope()
9027 )
9028 {
9029 list.push_back(innerCd);
9030 addClassAndNestedClasses(list,innerCd);
9031 }
9032 }
9033}
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 ClassLinkedRefMap getClasses() const =0
returns the classes nested into this class
virtual bool isLinkableInProject() const =0
ClassDefMutable * toClassDefMutable(Definition *d)
static void addClassAndNestedClasses(std::vector< ClassDefMutable * > &list, ClassDefMutable *cd)
Definition doxygen.cpp:9018
bool protectionLevelVisible(Protection prot)
Definition util.cpp:6270

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

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

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

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

9399{
9400 md->setDocumentation(root->doc,root->docFile,root->docLine);
9401 md->setDocsForDefinition(!root->proto);
9402 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9403 if (md->inbodyDocumentation().isEmpty())
9404 {
9406 }
9407 if (md->getStartBodyLine()==-1 && root->bodyLine!=-1)
9408 {
9409 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
9410 md->setBodyDef(root->fileDef());
9411 }
9413 md->setMaxInitLines(root->initLines);
9415 md->setRefItems(root->sli);
9416 if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId);
9417 addMemberToGroups(root,md);
9419}
virtual int getStartBodyLine() const =0
virtual QCString inbodyDocumentation() const =0
virtual void setInbodyDocumentation(const QCString &d, const QCString &docFile, int docLine)=0
bool proto
prototype ?
Definition entry.h:187
QCString inbodyDocs
documentation inside the body of a function
Definition entry.h:206
int inbodyLine
line number at which the body doc was found
Definition entry.h:207
int initLines
define/variable initializer lines to show
Definition entry.h:184
QCString inbodyFile
file in which the body doc was found
Definition entry.h:208
virtual void setMemberGroupId(int id)=0
virtual void setMaxInitLines(int lines)=0
virtual void setDocsForDefinition(bool b)=0
void addMemberToModule(const Entry *root, MemberDef *md)
static void applyMemberOverrideOptions(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:2076
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 7847 of file doxygen.cpp.

7848{
7849 AUTO_TRACE();
7850 // documentation outside a compound overrides the documentation inside it
7851 {
7852 md->setDocumentation(root->doc,root->docFile,root->docLine);
7853 md->setDocsForDefinition(!root->proto);
7854 }
7855
7856 // brief descriptions inside a compound override the documentation
7857 // outside it
7858 {
7859 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7860 }
7861
7862 if (md->inbodyDocumentation().isEmpty() || !root->parent()->name.isEmpty())
7863 {
7865 }
7866
7867 if (root->mGrpId!=-1 && md->getMemberGroupId()==-1)
7868 {
7869 md->setMemberGroupId(root->mGrpId);
7870 }
7871
7873 md->setRefItems(root->sli);
7874
7875 const GroupDef *gd=md->getGroupDef();
7876 if (gd==nullptr && !root->groups.empty()) // member not grouped but out-of-line documentation is
7877 {
7878 addMemberToGroups(root,md);
7879 }
7881}
std::vector< Grouping > groups
list of groups this entry belongs to
Definition entry.h:221
A model of a group of symbols.
Definition groupdef.h:52
virtual GroupDef * getGroupDef()=0
virtual int getMemberGroupId() const =0

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

Referenced by findEnumDocumentation(), and tryAddEnumDocsToGroupMember().

◆ addEnumValuesToEnums()

static void addEnumValuesToEnums ( const Entry * root)
static

Definition at line 7611 of file doxygen.cpp.

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

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

Referenced by addEnumValuesToEnums(), and parseInput().

◆ addGlobalFunction()

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

Definition at line 3744 of file doxygen.cpp.

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

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

Referenced by buildFunctionList().

◆ addIncludeFile()

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

Definition at line 574 of file doxygen.cpp.

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

References FileDef::absFilePath(), QCString::at(), Entry::brief, Config_getBool, Config_getList, Entry::doc, FALSE, Entry::fileName, findFileDef(), FileDef::generateSourceFile(), guessSection(), Entry::includeFile, Entry::includeName, Doxygen::inputNameLinkedMap, QCString::isEmpty(), QCString::length(), QCString::mid(), Definition::name(), Private, Entry::protection, qPrint(), showFileDefMatches(), QCString::sprintf(), Entry::startLine, stripFromIncludePath(), QCString::stripWhiteSpace(), TRUE, and warn.

Referenced by addClassToContext(), and addConceptToContext().

◆ addInterfaceOrServiceToServiceOrSingleton()

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

Definition at line 3494 of file doxygen.cpp.

3498{
3499 FileDef *fd = root->fileDef();
3500 enum MemberType type = root->section.isExportedInterface() ? MemberType::Interface : MemberType::Service;
3501 QCString fileName = root->fileName;
3502 if (fileName.isEmpty() && root->tagInfo())
3503 {
3504 fileName = root->tagInfo()->tagName;
3505 }
3506 auto md = createMemberDef(
3507 fileName, root->startLine, root->startColumn, root->type, rname,
3508 "", "", root->protection, root->virt, root->isStatic, Relationship::Member,
3509 type, ArgumentList(), root->argList, root->metaData);
3510 auto mmd = toMemberDefMutable(md.get());
3511 mmd->setTagInfo(root->tagInfo());
3512 mmd->setMemberClass(cd);
3513 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
3514 mmd->setDocsForDefinition(false);
3515 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
3516 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
3517 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
3518 mmd->setMemberSpecifiers(root->spec);
3519 mmd->setVhdlSpecifiers(root->vhdlSpec);
3520 mmd->setMemberGroupId(root->mGrpId);
3521 mmd->setTypeConstraints(root->typeConstr);
3522 mmd->setLanguage(root->lang);
3523 mmd->setBodyDef(fd);
3524 mmd->setFileDef(fd);
3525 mmd->addSectionsToDefinition(root->anchors);
3526 QCString const def = root->type + " " + rname;
3527 mmd->setDefinition(def);
3529 mmd->addQualifiers(root->qualifiers);
3530
3531 AUTO_TRACE("Interface member: fileName='{}' type='{}' name='{}' mtype='{}' prot={} virt={} state={} proto={} def='{}'",
3532 fileName,root->type,rname,type,root->protection,root->virt,root->isStatic,root->proto,def);
3533
3534 // add member to the class cd
3535 cd->insertMember(md.get());
3536 // also add the member as a "base" (to get nicer diagrams)
3537 // "optional" interface/service get Protected which turns into dashed line
3538 BaseInfo base(rname,
3540 TemplateNameMap templateNames;
3541 findClassRelation(root,cd,cd,&base,templateNames,DocumentedOnly,true) ||
3542 findClassRelation(root,cd,cd,&base,templateNames,Undocumented,true);
3543 // add file to list of used files
3544 cd->insertUsedFile(fd);
3545
3546 addMemberToGroups(root,md.get());
3548 root->markAsProcessed();
3549 mmd->setRefItems(root->sli);
3550
3551 // add member to the global list of all members
3552 MemberName *mn = Doxygen::memberNameLinkedMap->add(rname);
3553 mn->push_back(std::move(md));
3554}
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:4813
This class stores information about an inheritance relation.
Definition entry.h:90
MemberType
Definition types.h:390
@ Interface
Definition types.h:403
@ Service
Definition types.h:404
@ Public
Definition types.h:26
@ Protected
Definition types.h:26

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

Referenced by buildInterfaceAndServiceList().

◆ addListReferences()

static void addListReferences ( )
static

Definition at line 5402 of file doxygen.cpp.

5403{
5404 AUTO_TRACE();
5405 for (const auto &cd : *Doxygen::classLinkedMap)
5406 {
5407 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5408 if (cdm)
5409 {
5410 cdm->addListReferences();
5411 }
5412 }
5413
5414 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5415 {
5416 for (const auto &fd : *fn)
5417 {
5418 fd->addListReferences();
5419 }
5420 }
5421
5422 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5423 {
5425 if (ndm)
5426 {
5427 ndm->addListReferences();
5428 }
5429 }
5430
5431 for (const auto &gd : *Doxygen::groupLinkedMap)
5432 {
5433 gd->addListReferences();
5434 }
5435
5436 for (const auto &pd : *Doxygen::pageLinkedMap)
5437 {
5438 QCString name = pd->getOutputFileBase();
5439 if (pd->getGroupDef())
5440 {
5441 name = pd->getGroupDef()->getOutputFileBase();
5442 }
5443 {
5444 const RefItemVector &xrefItems = pd->xrefListItems();
5445 addRefItem(xrefItems,
5446 name,
5447 theTranslator->trPage(TRUE,TRUE),
5448 name,pd->title(),QCString(),nullptr);
5449 }
5450 }
5451
5452 for (const auto &dd : *Doxygen::dirLinkedMap)
5453 {
5454 QCString name = dd->getOutputFileBase();
5455 //if (dd->getGroupDef())
5456 //{
5457 // name = dd->getGroupDef()->getOutputFileBase();
5458 //}
5459 const RefItemVector &xrefItems = dd->xrefListItems();
5460 addRefItem(xrefItems,
5461 name,
5462 theTranslator->trDir(TRUE,TRUE),
5463 name,dd->displayName(),QCString(),nullptr);
5464 }
5465
5467}
virtual void addListReferences()=0
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:100
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:129
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:114
void addListReferences()
virtual void addListReferences()=0
Translator * theTranslator
Definition language.cpp:71
std::vector< RefItem * > RefItemVector
Definition reflist.h:133
void addRefItem(const RefItemVector &sli, const QCString &key, const QCString &prefix, const QCString &name, const QCString &title, const QCString &args, const Definition *scope)
Definition util.cpp:5146

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

Referenced by parseInput().

◆ addLocalObjCMethod()

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

Definition at line 6036 of file doxygen.cpp.

6041{
6042 AUTO_TRACE();
6043 //printf("scopeName='%s' className='%s'\n",qPrint(scopeName),qPrint(className));
6044 ClassDefMutable *cd=nullptr;
6045 if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClassMutable(scopeName)))
6046 {
6047 AUTO_TRACE_ADD("Local objective C method '{}' scopeName='{}'",root->name,scopeName);
6048 auto md = createMemberDef(
6049 root->fileName,root->startLine,root->startColumn,
6050 funcType,funcName,funcArgs,exceptions,
6051 root->protection,root->virt,root->isStatic,Relationship::Member,
6053 auto mmd = toMemberDefMutable(md.get());
6054 mmd->setTagInfo(root->tagInfo());
6055 mmd->setLanguage(root->lang);
6056 mmd->setId(root->id);
6057 mmd->makeImplementationDetail();
6058 mmd->setMemberClass(cd);
6059 mmd->setDefinition(funcDecl);
6061 mmd->addQualifiers(root->qualifiers);
6062 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6063 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6064 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6065 mmd->setDocsForDefinition(!root->proto);
6066 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6067 mmd->addSectionsToDefinition(root->anchors);
6068 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6069 FileDef *fd=root->fileDef();
6070 mmd->setBodyDef(fd);
6071 mmd->setMemberSpecifiers(spec);
6072 mmd->setVhdlSpecifiers(root->vhdlSpec);
6073 mmd->setMemberGroupId(root->mGrpId);
6074 cd->insertMember(md.get());
6075 cd->insertUsedFile(fd);
6076 mmd->setRefItems(root->sli);
6077
6079 mn->push_back(std::move(md));
6080 }
6081 else
6082 {
6083 // local objective C method found for class without interface
6084 }
6085}

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

Referenced by addMemberFunction(), and findMember().

◆ addMemberDocs()

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

Definition at line 5485 of file doxygen.cpp.

5491{
5492 if (md==nullptr) return;
5493 AUTO_TRACE("scope='{}' name='{}' args='{}' funcDecl='{}' mSpec={}",
5494 root->parent()->name,md->name(),md->argsString(),funcDecl,spec);
5495 if (!root->section.isDoc()) // @fn or @var does not need to specify the complete definition, so don't overwrite it
5496 {
5497 QCString fDecl=funcDecl;
5498 // strip extern specifier
5499 fDecl.stripPrefix("extern ");
5500 md->setDefinition(fDecl);
5501 }
5503 md->addQualifiers(root->qualifiers);
5505 const NamespaceDef *nd=md->getNamespaceDef();
5506 QCString fullName;
5507 if (cd)
5508 fullName = cd->name();
5509 else if (nd)
5510 fullName = nd->name();
5511
5512 if (!fullName.isEmpty()) fullName+="::";
5513 fullName+=md->name();
5514 FileDef *rfd=root->fileDef();
5515
5516 // TODO determine scope based on root not md
5517 Definition *rscope = md->getOuterScope();
5518
5519 const ArgumentList &mdAl = md->argumentList();
5520 if (al)
5521 {
5522 ArgumentList mergedAl = *al;
5523 //printf("merging arguments (1) docs=%d\n",root->doc.isEmpty());
5524 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedAl,!root->doc.isEmpty());
5525 }
5526 else
5527 {
5528 if (
5529 matchArguments2( md->getOuterScope(), md->getFileDef(),const_cast<ArgumentList*>(&mdAl),
5530 rscope,rfd,&root->argList,
5531 TRUE, root->lang
5532 )
5533 )
5534 {
5535 //printf("merging arguments (2)\n");
5536 ArgumentList mergedArgList = root->argList;
5537 mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.isEmpty());
5538 }
5539 }
5540 if (over_load) // the \overload keyword was used
5541 {
5543 if (!root->doc.isEmpty())
5544 {
5545 doc+="<p>";
5546 doc+=root->doc;
5547 }
5548 md->setDocumentation(doc,root->docFile,root->docLine);
5550 md->setDocsForDefinition(!root->proto);
5551 }
5552 else
5553 {
5554 //printf("overwrite!\n");
5555 md->setDocumentation(root->doc,root->docFile,root->docLine);
5556 md->setDocsForDefinition(!root->proto);
5557
5558 //printf("overwrite!\n");
5559 md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
5560
5561 if (
5562 (md->inbodyDocumentation().isEmpty() ||
5563 !root->parent()->name.isEmpty()
5564 ) && !root->inbodyDocs.isEmpty()
5565 )
5566 {
5568 }
5569 }
5570
5571 //printf("initializer: '%s'(isEmpty=%d) '%s'(isEmpty=%d)\n",
5572 // qPrint(md->initializer()),md->initializer().isEmpty(),
5573 // qPrint(root->initializer),root->initializer.isEmpty()
5574 // );
5575 std::string rootInit = root->initializer.str();
5576 if (md->initializer().isEmpty() && !rootInit.empty())
5577 {
5578 //printf("setInitializer\n");
5579 md->setInitializer(rootInit.c_str());
5580 }
5581 if (md->requiresClause().isEmpty() && !root->req.isEmpty())
5582 {
5583 md->setRequiresClause(root->req);
5584 }
5585
5586 md->setMaxInitLines(root->initLines);
5587
5588 if (rfd)
5589 {
5590 if ((md->getStartBodyLine()==-1 && root->bodyLine!=-1)
5591 )
5592 {
5593 //printf("Setting new body segment [%d,%d]\n",root->bodyLine,root->endBodyLine);
5594 md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
5595 md->setBodyDef(rfd);
5596 }
5597
5598 md->setRefItems(root->sli);
5599 }
5600
5602 md->addQualifiers(root->qualifiers);
5603
5604 md->mergeMemberSpecifiers(spec);
5606 addMemberToGroups(root,md);
5608 if (cd) cd->insertUsedFile(rfd);
5609 //printf("root->mGrpId=%d\n",root->mGrpId);
5610 if (root->mGrpId!=-1)
5611 {
5612 if (md->getMemberGroupId()!=-1)
5613 {
5614 if (md->getMemberGroupId()!=root->mGrpId)
5615 {
5616 warn(
5617 root->fileName,root->startLine,
5618 "member %s belongs to two different groups. The second "
5619 "one found here will be ignored.",
5620 qPrint(md->name())
5621 );
5622 }
5623 }
5624 else // set group id
5625 {
5626 //printf("setMemberGroupId=%d md=%s\n",root->mGrpId,qPrint(md->name()));
5627 md->setMemberGroupId(root->mGrpId);
5628 }
5629 }
5630 md->addQualifiers(root->qualifiers);
5631}
bool isDoc() const
Definition types.h:642
virtual QCString requiresClause() const =0
virtual const ArgumentList & argumentList() const =0
virtual QCString argsString() const =0
virtual const QCString & initializer() const =0
virtual void setDefinition(const QCString &d)=0
virtual ClassDefMutable * getClassDefMutable()=0
virtual void setRequiresClause(const QCString &req)=0
virtual void setInitializer(const QCString &i)=0
virtual void mergeMemberSpecifiers(TypeSpecifier s)=0
virtual void addQualifiers(const StringVector &qualifiers)=0
bool stripPrefix(const QCString &prefix)
Definition qcstring.h:198
bool matchArguments2(const Definition *srcScope, const FileDef *srcFileScope, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
Definition util.cpp:1931
void mergeArguments(ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
Definition util.cpp:2025
QCString getOverloadDocs()
Definition util.cpp:4440

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

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

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

Referenced by findMember().

◆ addMemberSpecialization()

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

Definition at line 6432 of file doxygen.cpp.

6442{
6443 AUTO_TRACE("funcType={} funcName={} funcArgs={} funcDecl={} spec={}",funcType,funcName,funcArgs,funcDecl,spec);
6444 MemberDef *declMd=nullptr;
6445 for (const auto &md : *mn)
6446 {
6447 if (md->getClassDef()==cd)
6448 {
6449 // TODO: we should probably also check for matching arguments
6450 declMd = md.get();
6451 break;
6452 }
6453 }
6455 ArgumentList tArgList;
6456 // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6457 auto md = createMemberDef(
6458 root->fileName,root->startLine,root->startColumn,
6459 funcType,funcName,funcArgs,exceptions,
6460 declMd ? declMd->protection() : root->protection,
6462 mtype,tArgList,root->argList,root->metaData);
6463 auto mmd = toMemberDefMutable(md.get());
6464 //printf("new specialized member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6465 mmd->setTagInfo(root->tagInfo());
6466 mmd->setLanguage(root->lang);
6467 mmd->setId(root->id);
6468 mmd->setMemberClass(cd);
6469 mmd->setTemplateSpecialization(TRUE);
6470 mmd->setTypeConstraints(root->typeConstr);
6471 mmd->setDefinition(funcDecl);
6473 mmd->addQualifiers(root->qualifiers);
6474 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
6475 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6476 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6477 mmd->setDocsForDefinition(!root->proto);
6478 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6479 mmd->addSectionsToDefinition(root->anchors);
6480 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6481 FileDef *fd=root->fileDef();
6482 mmd->setBodyDef(fd);
6483 mmd->setMemberSpecifiers(spec);
6484 mmd->setVhdlSpecifiers(root->vhdlSpec);
6485 mmd->setMemberGroupId(root->mGrpId);
6486 cd->insertMember(md.get());
6487 mmd->setRefItems(root->sli);
6488
6489 mn->push_back(std::move(md));
6490}

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

Referenced by findMember().

◆ addMembersToIndex()

static void addMembersToIndex ( )
static

Definition at line 8044 of file doxygen.cpp.

8045{
8046 auto &index = Index::instance();
8047 // for each class member name
8048 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8049 {
8050 // for each member definition
8051 for (const auto &md : *mn)
8052 {
8053 index.addClassMemberNameToIndex(md.get());
8054 if (md->getModuleDef())
8055 {
8056 index.addModuleMemberNameToIndex(md.get());
8057 }
8058 }
8059 }
8060 // for each file/namespace function name
8061 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8062 {
8063 // for each member definition
8064 for (const auto &md : *mn)
8065 {
8066 if (md->getNamespaceDef())
8067 {
8068 index.addNamespaceMemberNameToIndex(md.get());
8069 }
8070 else
8071 {
8072 index.addFileMemberNameToIndex(md.get());
8073 }
8074 if (md->getModuleDef())
8075 {
8076 index.addModuleMemberNameToIndex(md.get());
8077 }
8078 }
8079 }
8080
8081 index.sortMemberIndexLists();
8082}
static Index & instance()
Definition index.cpp:106

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

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

◆ addMembersToMemberGroup()

static void addMembersToMemberGroup ( )
static

Definition at line 9142 of file doxygen.cpp.

9143{
9144 // for each class
9145 for (const auto &cd : *Doxygen::classLinkedMap)
9146 {
9147 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9148 if (cdm)
9149 {
9151 }
9152 }
9153 // for each file
9154 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9155 {
9156 for (const auto &fd : *fn)
9157 {
9158 fd->addMembersToMemberGroup();
9159 }
9160 }
9161 // for each namespace
9162 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9163 {
9165 if (ndm)
9166 {
9168 }
9169 }
9170 // for each group
9171 for (const auto &gd : *Doxygen::groupLinkedMap)
9172 {
9173 gd->addMembersToMemberGroup();
9174 }
9176}
virtual void addMembersToMemberGroup()=0
void addMembersToMemberGroup()
virtual void addMembersToMemberGroup()=0

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

Referenced by parseInput().

◆ addMethodToClass()

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

Definition at line 3608 of file doxygen.cpp.

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

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

Referenced by addMemberFunction(), and buildFunctionList().

◆ addOverloaded()

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

Definition at line 6494 of file doxygen.cpp.

6497{
6498 // for unique overloaded member we allow the class to be
6499 // omitted, this is to be Qt compatible. Using this should
6500 // however be avoided, because it is error prone
6501 bool sameClass=false;
6502 if (mn->size()>0)
6503 {
6504 // check if all members with the same name are also in the same class
6505 sameClass = std::equal(mn->begin()+1,mn->end(),mn->begin(),
6506 [](const auto &md1,const auto &md2)
6507 { return md1->getClassDef()->name()==md2->getClassDef()->name(); });
6508 }
6509 if (sameClass)
6510 {
6511 MemberDefMutable *mdm = toMemberDefMutable(mn->front().get());
6512 ClassDefMutable *cd = mdm ? mdm->getClassDefMutable() : nullptr;
6513 if (cd==nullptr) return;
6514
6517 else if (root->mtype==MethodTypes::Slot) mtype=MemberType::Slot;
6518 else if (root->mtype==MethodTypes::DCOP) mtype=MemberType::DCOP;
6519
6520 // new overloaded member function
6521 std::unique_ptr<ArgumentList> tArgList =
6522 getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists);
6523 //printf("new related member %s args='%s'\n",qPrint(md->name()),qPrint(funcArgs));
6524 auto md = createMemberDef(
6525 root->fileName,root->startLine,root->startColumn,
6526 funcType,funcName,funcArgs,exceptions,
6528 mtype,tArgList ? *tArgList : ArgumentList(),root->argList,root->metaData);
6529 auto mmd = toMemberDefMutable(md.get());
6530 mmd->setTagInfo(root->tagInfo());
6531 mmd->setLanguage(root->lang);
6532 mmd->setId(root->id);
6533 mmd->setTypeConstraints(root->typeConstr);
6534 mmd->setMemberClass(cd);
6535 mmd->setDefinition(funcDecl);
6537 mmd->addQualifiers(root->qualifiers);
6539 doc+="<p>";
6540 doc+=root->doc;
6541 mmd->setDocumentation(doc,root->docFile,root->docLine);
6542 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
6543 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
6544 mmd->setDocsForDefinition(!root->proto);
6545 mmd->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn);
6546 mmd->addSectionsToDefinition(root->anchors);
6547 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
6548 FileDef *fd=root->fileDef();
6549 mmd->setBodyDef(fd);
6550 mmd->setMemberSpecifiers(spec);
6551 mmd->setVhdlSpecifiers(root->vhdlSpec);
6552 mmd->setMemberGroupId(root->mGrpId);
6553 cd->insertMember(md.get());
6554 cd->insertUsedFile(fd);
6555 mmd->setRefItems(root->sli);
6556
6557 mn->push_back(std::move(md));
6558 }
6559}
Ptr & front()
Definition membername.h:51
size_t size() const
Definition membername.h:48
iterator begin()
Definition membername.h:37
iterator end()
Definition membername.h:38

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

Referenced by findMember().

◆ addPageToContext()

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

Definition at line 302 of file doxygen.cpp.

303{
304 if (root->parent()) // add the page to it's scope
305 {
306 QCString scope = root->parent()->name;
307 if (root->parent()->section.isPackageDoc())
308 {
309 scope=substitute(scope,".","::");
310 }
311 scope = stripAnonymousNamespaceScope(scope);
312 scope+="::"+pd->name();
314 if (d)
315 {
316 pd->setPageScope(d);
317 }
318 }
319}
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 321 of file doxygen.cpp.

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

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

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

◆ addSourceReferences()

static void addSourceReferences ( )
static

Definition at line 8676 of file doxygen.cpp.

8677{
8678 // add source references for class definitions
8679 for (const auto &cd : *Doxygen::classLinkedMap)
8680 {
8681 const FileDef *fd=cd->getBodyDef();
8682 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8683 {
8684 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8685 }
8686 }
8687 // add source references for concept definitions
8688 for (const auto &cd : *Doxygen::conceptLinkedMap)
8689 {
8690 const FileDef *fd=cd->getBodyDef();
8691 if (fd && cd->isLinkableInProject() && cd->getStartDefLine()!=-1)
8692 {
8693 const_cast<FileDef*>(fd)->addSourceRef(cd->getStartDefLine(),cd.get(),nullptr);
8694 }
8695 }
8696 // add source references for namespace definitions
8697 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8698 {
8699 const FileDef *fd=nd->getBodyDef();
8700 if (fd && nd->isLinkableInProject() && nd->getStartDefLine()!=-1)
8701 {
8702 const_cast<FileDef*>(fd)->addSourceRef(nd->getStartDefLine(),nd.get(),nullptr);
8703 }
8704 }
8705
8706 // add source references for member names
8707 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8708 {
8709 for (const auto &md : *mn)
8710 {
8711 //printf("class member %s: def=%s body=%d link?=%d\n",
8712 // qPrint(md->name()),
8713 // md->getBodyDef()?qPrint(md->getBodyDef()->name()):"<none>",
8714 // md->getStartBodyLine(),md->isLinkableInProject());
8715 const FileDef *fd=md->getBodyDef();
8716 if (fd &&
8717 md->getStartDefLine()!=-1 &&
8718 md->isLinkableInProject() &&
8720 )
8721 {
8722 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8723 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8724 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8725 }
8726 }
8727 }
8728 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8729 {
8730 for (const auto &md : *mn)
8731 {
8732 const FileDef *fd=md->getBodyDef();
8733 //printf("member %s body=[%d,%d] fd=%p link=%d parseSources=%d\n",
8734 // qPrint(md->name()),
8735 // md->getStartBodyLine(),md->getEndBodyLine(),fd,
8736 // md->isLinkableInProject(),
8737 // Doxygen::parseSourcesNeeded);
8738 if (fd &&
8739 md->getStartDefLine()!=-1 &&
8740 md->isLinkableInProject() &&
8742 )
8743 {
8744 //printf("Found member '%s' in file '%s' at line '%d' def=%s\n",
8745 // qPrint(md->name()),qPrint(fd->name()),md->getStartBodyLine(),qPrint(md->getOuterScope()->name()));
8746 const_cast<FileDef*>(fd)->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get());
8747 }
8748 }
8749 }
8750}
virtual const FileDef * getBodyDef() const =0
static bool parseSourcesNeeded
Definition doxygen.h:123

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

Referenced by parseInput().

◆ addToIndices()

static void addToIndices ( )
static

Definition at line 8086 of file doxygen.cpp.

8087{
8088 for (const auto &cd : *Doxygen::classLinkedMap)
8089 {
8090 if (cd->isLinkableInProject())
8091 {
8092 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8093 if (Doxygen::searchIndex.enabled())
8094 {
8095 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
8096 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
8097 }
8098 }
8099 }
8100
8101 for (const auto &cd : *Doxygen::conceptLinkedMap)
8102 {
8103 if (cd->isLinkableInProject())
8104 {
8105 Doxygen::indexList->addIndexItem(cd.get(),nullptr);
8106 if (Doxygen::searchIndex.enabled())
8107 {
8108 Doxygen::searchIndex.setCurrentDoc(cd.get(),cd->anchor(),FALSE);
8109 Doxygen::searchIndex.addWord(cd->localName(),TRUE);
8110 }
8111 }
8112 }
8113
8114 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8115 {
8116 if (nd->isLinkableInProject())
8117 {
8118 Doxygen::indexList->addIndexItem(nd.get(),nullptr);
8119 if (Doxygen::searchIndex.enabled())
8120 {
8121 Doxygen::searchIndex.setCurrentDoc(nd.get(),nd->anchor(),FALSE);
8122 Doxygen::searchIndex.addWord(nd->localName(),TRUE);
8123 }
8124 }
8125 }
8126
8127 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8128 {
8129 for (const auto &fd : *fn)
8130 {
8131 if (Doxygen::searchIndex.enabled() && fd->isLinkableInProject())
8132 {
8133 Doxygen::searchIndex.setCurrentDoc(fd.get(),fd->anchor(),FALSE);
8134 Doxygen::searchIndex.addWord(fd->localName(),TRUE);
8135 }
8136 }
8137 }
8138
8139 auto addWordsForTitle = [](const Definition *d,const QCString &anchor,const QCString &title)
8140 {
8141 Doxygen::indexList->addIndexItem(d,nullptr,QCString(),filterTitle(title));
8142 if (Doxygen::searchIndex.enabled())
8143 {
8144 Doxygen::searchIndex.setCurrentDoc(d,anchor,false);
8145 std::string s = title.str();
8146 static const reg::Ex re(R"(\a[\w-]*)");
8147 reg::Iterator it(s,re);
8149 for (; it!=end ; ++it)
8150 {
8151 const auto &match = *it;
8152 std::string matchStr = match.str();
8153 Doxygen::searchIndex.addWord(matchStr.c_str(),true);
8154 }
8155 }
8156 };
8157
8158 for (const auto &gd : *Doxygen::groupLinkedMap)
8159 {
8160 if (gd->isLinkableInProject())
8161 {
8162 addWordsForTitle(gd.get(),gd->anchor(),gd->groupTitle());
8163 }
8164 }
8165
8166 for (const auto &pd : *Doxygen::pageLinkedMap)
8167 {
8168 if (pd->isLinkableInProject())
8169 {
8170 addWordsForTitle(pd.get(),pd->anchor(),pd->title());
8171 }
8172 }
8173
8175 {
8176 addWordsForTitle(Doxygen::mainPage.get(),Doxygen::mainPage->anchor(),Doxygen::mainPage->title());
8177 }
8178
8179 auto addMemberToSearchIndex = [](const MemberDef *md)
8180 {
8181 if (Doxygen::searchIndex.enabled())
8182 {
8183 Doxygen::searchIndex.setCurrentDoc(md,md->anchor(),FALSE);
8184 QCString ln=md->localName();
8185 QCString qn=md->qualifiedName();
8186 Doxygen::searchIndex.addWord(ln,TRUE);
8187 if (ln!=qn)
8188 {
8189 Doxygen::searchIndex.addWord(qn,TRUE);
8190 if (md->getClassDef())
8191 {
8192 Doxygen::searchIndex.addWord(md->getClassDef()->displayName(),TRUE);
8193 }
8194 if (md->getNamespaceDef())
8195 {
8196 Doxygen::searchIndex.addWord(md->getNamespaceDef()->displayName(),TRUE);
8197 }
8198 }
8199 }
8200 };
8201
8202 auto getScope = [](const MemberDef *md)
8203 {
8204 const Definition *scope = nullptr;
8205 if (md->getGroupDef()) scope = md->getGroupDef();
8206 else if (md->getClassDef()) scope = md->getClassDef();
8207 else if (md->getNamespaceDef()) scope = md->getNamespaceDef();
8208 else if (md->getFileDef()) scope = md->getFileDef();
8209 return scope;
8210 };
8211
8212 auto addMemberToIndices = [addMemberToSearchIndex,getScope](const MemberDef *md)
8213 {
8214 if (md->isLinkableInProject())
8215 {
8216 if (!(md->isEnumerate() && md->isAnonymous()))
8217 {
8218 Doxygen::indexList->addIndexItem(getScope(md),md);
8220 }
8221 if (md->isEnumerate())
8222 {
8223 for (const auto &fmd : md->enumFieldList())
8224 {
8225 Doxygen::indexList->addIndexItem(getScope(fmd),fmd);
8227 }
8228 }
8229 }
8230 };
8231
8232 // for each class member name
8233 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8234 {
8235 // for each member definition
8236 for (const auto &md : *mn)
8237 {
8238 addMemberToIndices(md.get());
8239 }
8240 }
8241 // for each file/namespace function name
8242 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8243 {
8244 // for each member definition
8245 for (const auto &md : *mn)
8246 {
8247 addMemberToIndices(md.get());
8248 }
8249 }
8250}
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:101
static IndexList * indexList
Definition doxygen.h:134
static SearchIndexIntf searchIndex
Definition doxygen.h:124
Class representing a regular expression.
Definition regex.h:39
Iterator class to iterator through matches.
Definition regex.h:232
DirIterator end(const DirIterator &) noexcept
Definition dir.cpp:175
bool match(std::string_view str, Match &match, const Ex &re)
Matches a given string str for a match against regular expression re.
Definition regex.cpp:759
static void addMemberToSearchIndex(const MemberDef *md)
QCString filterTitle(const QCString &title)
Definition util.cpp:5921

References addMemberToSearchIndex(), Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, end(), FALSE, filterTitle(), Doxygen::functionNameLinkedMap, Doxygen::groupLinkedMap, Doxygen::indexList, Doxygen::inputNameLinkedMap, Doxygen::mainPage, Doxygen::memberNameLinkedMap, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, Doxygen::searchIndex, QCString::str(), and TRUE.

Referenced by parseInput().

◆ addVariable()

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

Definition at line 3078 of file doxygen.cpp.

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

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

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

◆ addVariableToClass()

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

Definition at line 2404 of file doxygen.cpp.

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

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

Referenced by addVariable().

◆ addVariableToFile()

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

Definition at line 2565 of file doxygen.cpp.

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

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

Referenced by addVariable().

◆ adjustConfiguration()

void adjustConfiguration ( )

adjust globals that depend on configuration settings.

Definition at line 11871 of file doxygen.cpp.

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

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

Referenced by main().

◆ applyMemberOverrideOptions()

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

Definition at line 2076 of file doxygen.cpp.

2077{
2078 root->commandOverrides.apply_callGraph ([&](bool b) { md->overrideCallGraph(b); });
2079 root->commandOverrides.apply_callerGraph ([&](bool b) { md->overrideCallerGraph(b); });
2080 root->commandOverrides.apply_referencedByRelation([&](bool b) { md->overrideReferencedByRelation(b); });
2081 root->commandOverrides.apply_referencesRelation ([&](bool b) { md->overrideReferencesRelation(b); });
2082 root->commandOverrides.apply_inlineSource ([&](bool b) { md->overrideInlineSource(b); });
2083 root->commandOverrides.apply_enumValues ([&](bool b) { md->overrideEnumValues(b); });
2084}
virtual void overrideReferencesRelation(bool e)=0
virtual void overrideReferencedByRelation(bool e)=0
virtual void overrideCallGraph(bool e)=0
virtual void overrideInlineSource(bool e)=0
virtual void overrideEnumValues(bool e)=0
virtual void overrideCallerGraph(bool e)=0

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

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

◆ buildClassDocList()

static void buildClassDocList ( const Entry * root)
static

Definition at line 1115 of file doxygen.cpp.

1116{
1117 if ((root->section.isCompoundDoc()) && !root->name.isEmpty())
1118 {
1119 AUTO_TRACE();
1120 addClassToContext(root);
1121 }
1122 for (const auto &e : root->children()) buildClassDocList(e.get());
1123}
bool isCompoundDoc() const
Definition types.h:641
static void addClassToContext(const Entry *root)
Definition doxygen.cpp:924
static void buildClassDocList(const Entry *root)
Definition doxygen.cpp:1115

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

1106{
1107 if ((root->section.isCompound() || root->section.isObjcImpl()) && !root->name.isEmpty())
1108 {
1109 AUTO_TRACE();
1110 addClassToContext(root);
1111 }
1112 for (const auto &e : root->children()) buildClassList(e.get());
1113}
static void buildClassList(const Entry *root)
Definition doxygen.cpp:1105

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

8421{
8422 // merge the member list of base classes into the inherited classes.
8423 for (const auto &cd : *Doxygen::classLinkedMap)
8424 {
8425 if (// !cd->isReference() && // not an external class
8426 cd->subClasses().empty() && // is a root of the hierarchy
8427 !cd->baseClasses().empty()) // and has at least one base class
8428 {
8429 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8430 if (cdm)
8431 {
8432 //printf("*** merging members for %s\n",qPrint(cd->name()));
8433 cdm->mergeMembers();
8434 }
8435 }
8436 }
8437 // now sort the member list of all members for all classes.
8438 for (const auto &cd : *Doxygen::classLinkedMap)
8439 {
8440 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8441 if (cdm)
8442 {
8443 cdm->sortAllMembersList();
8444 }
8445 }
8446}
virtual void sortAllMembersList()=0
virtual void mergeMembers()=0

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

Referenced by parseInput().

◆ buildConceptDocList()

static void buildConceptDocList ( const Entry * root)
static

Definition at line 1264 of file doxygen.cpp.

1265{
1266 if (root->section.isConceptDoc())
1267 {
1268 AUTO_TRACE();
1269 addConceptToContext(root);
1270 }
1271 for (const auto &e : root->children()) buildConceptDocList(e.get());
1272}
static void addConceptToContext(const Entry *root)
Definition doxygen.cpp:1129
static void buildConceptDocList(const Entry *root)
Definition doxygen.cpp:1264

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

1255{
1256 if (root->section.isConcept())
1257 {
1258 AUTO_TRACE();
1259 addConceptToContext(root);
1260 }
1261 for (const auto &e : root->children()) buildConceptList(e.get());
1262}
static void buildConceptList(const Entry *root)
Definition doxygen.cpp:1254

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

Referenced by buildConceptList(), and parseInput().

◆ buildDefineList()

static void buildDefineList ( )
static

Definition at line 8755 of file doxygen.cpp.

8756{
8757 AUTO_TRACE();
8758 for (const auto &s : g_inputFiles)
8759 {
8760 auto it = Doxygen::macroDefinitions.find(s);
8762 {
8763 for (const auto &def : it->second)
8764 {
8765 auto md = createMemberDef(
8766 def.fileName,def.lineNr,def.columnNr,
8767 "#define",def.name,def.args,QCString(),
8769 ArgumentList(),ArgumentList(),"");
8770 auto mmd = toMemberDefMutable(md.get());
8771
8772 if (!def.args.isEmpty())
8773 {
8774 mmd->moveArgumentList(stringToArgumentList(SrcLangExt::Cpp, def.args));
8775 }
8776 mmd->setInitializer(def.definition);
8777 mmd->setFileDef(def.fileDef);
8778 mmd->setDefinition("#define "+def.name);
8779
8780 MemberName *mn=Doxygen::functionNameLinkedMap->add(def.name);
8781 if (def.fileDef)
8782 {
8783 def.fileDef->insertMember(md.get());
8784 }
8785 AUTO_TRACE_ADD("adding macro {} with definition {}",def.name,def.definition);
8786 mn->push_back(std::move(md));
8787 }
8788 }
8789 }
8790}
static DefinesPerFileList macroDefinitions
Definition doxygen.h:137
static StringVector g_inputFiles
Definition doxygen.cpp:180

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

Referenced by parseInput().

◆ buildDictionaryList()

static void buildDictionaryList ( const Entry * root)
static

Definition at line 3443 of file doxygen.cpp.

3444{
3445 if (!root->name.isEmpty() &&
3446 root->section.isVariable() &&
3447 root->type.find("dictionary<")!=-1 // it's a dictionary
3448 )
3449 {
3450 AUTO_TRACE();
3451 addVariable(root);
3452 }
3453 for (const auto &e : root->children())
3454 if (!e->section.isEnum())
3455 buildDictionaryList(e.get());
3456}
static void buildDictionaryList(const Entry *root)
Definition doxygen.cpp:3443
static void addVariable(const Entry *root, int isFuncPtr=-1)
Definition doxygen.cpp:3078

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

Referenced by buildDictionaryList(), and parseInput().

◆ buildExampleList()

static void buildExampleList ( Entry * root)
static

Definition at line 9823 of file doxygen.cpp.

9824{
9825 if ((root->section.isExample() || root->section.isExampleLineno()) && !root->name.isEmpty())
9826 {
9827 if (Doxygen::exampleLinkedMap->find(root->name))
9828 {
9829 warn(root->fileName,root->startLine,
9830 "Example %s was already documented. Ignoring "
9831 "documentation found here.",
9832 qPrint(root->name)
9833 );
9834 }
9835 else
9836 {
9837 PageDef *pd = Doxygen::exampleLinkedMap->add(root->name,
9838 createPageDef(root->fileName,root->startLine,
9839 root->name,root->brief+root->doc+root->inbodyDocs,root->args));
9840 pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9841 pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE));
9843 pd->setLanguage(root->lang);
9844 pd->setShowLineNo(root->section.isExampleLineno());
9845
9846 //we don't add example to groups
9847 //addExampleToGroups(root,pd);
9848 }
9849 }
9850 for (const auto &e : root->children()) buildExampleList(e.get());
9851}
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:99
virtual void setFileName(const QCString &name)=0
virtual void setShowLineNo(bool)=0
static void buildExampleList(Entry *root)
Definition doxygen.cpp:9823
std::unique_ptr< PageDef > createPageDef(const QCString &f, int l, const QCString &n, const QCString &d, const QCString &t)
Definition pagedef.cpp:79
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3858

References DefinitionMutable::addSectionsToDefinition(), Entry::anchors, Entry::args, Entry::brief, Entry::briefFile, Entry::briefLine, buildExampleList(), Entry::children(), convertNameToFile(), createPageDef(), Entry::doc, Doxygen::exampleLinkedMap, FALSE, Entry::fileName, Entry::inbodyDocs, QCString::isEmpty(), Entry::lang, Definition::name(), Entry::name, 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 489 of file doxygen.cpp.

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

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

Referenced by buildFileList(), and parseInput().

◆ buildFunctionList()

static void buildFunctionList ( const Entry * root)
static

Definition at line 3852 of file doxygen.cpp.

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

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

Referenced by buildFunctionList(), and parseInput().

◆ buildGroupList()

static void buildGroupList ( const Entry * root)
static

Definition at line 418 of file doxygen.cpp.

419{
420 // --- first process only local groups
421 // first process the @defgroups blocks
423 // then process the @addtogroup, @weakgroup blocks
425
426 // --- then also process external groups
427 // first process the @defgroups blocks
429 // then process the @addtogroup, @weakgroup blocks
431}
static void buildGroupListFiltered(const Entry *root, bool additional, bool includeExternal)
Definition doxygen.cpp:349

References buildGroupListFiltered(), FALSE, and TRUE.

Referenced by parseInput().

◆ buildGroupListFiltered()

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

Definition at line 349 of file doxygen.cpp.

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

References DefinitionMutable::addSectionsToDefinition(), Entry::anchors, AUTO_TRACE, AUTO_TRACE_ADD, Entry::brief, Entry::briefFile, Entry::briefLine, buildGroupListFiltered(), Entry::children(), Entry::commandOverrides, createGroupDef(), Entry::doc, Entry::docFile, Entry::docLine, FALSE, Entry::fileName, TagInfo::fileName, Entry::GROUPDOC_NORMAL, Entry::groupDocType, Doxygen::groupLinkedMap, GroupDef::groupTitle(), GroupDef::hasGroupTitle(), Entry::inbodyDocs, Entry::inbodyFile, Entry::inbodyLine, QCString::isEmpty(), Entry::lang, QCString::length(), Entry::name, GroupDef::overrideGroupGraph(), 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().

◆ buildInterfaceAndServiceList()

static void buildInterfaceAndServiceList ( const Entry * root)
static

Definition at line 3556 of file doxygen.cpp.

3557{
3558 if (root->section.isExportedInterface() || root->section.isIncludedService())
3559 {
3560 AUTO_TRACE("Exported interface/included service: type='{}' scope='{}' name='{}' args='{}'"
3561 " relates='{}' relatesType='{}' file='{}' line={} bodyLine={} #tArgLists={}"
3562 " mGrpId={} spec={} proto={} docFile='{}'",
3563 root->type, root->parent()->name, root->name, root->args,
3564 root->relates, root->relatesType, root->fileName, root->startLine, root->bodyLine, root->tArgLists.size(),
3565 root->mGrpId, root->spec, root->proto, root->docFile);
3566
3568
3569 if (!rname.isEmpty())
3570 {
3571 QCString scope = root->parent()->name;
3572 ClassDefMutable *cd = getClassMutable(scope);
3573 assert(cd);
3574 if (cd && ((ClassDef::Interface == cd->compoundType()) ||
3575 (ClassDef::Service == cd->compoundType()) ||
3577 {
3579 }
3580 else
3581 {
3582 assert(false); // was checked by scanner.l
3583 }
3584 }
3585 else if (rname.isEmpty())
3586 {
3587 warn(root->fileName,root->startLine,
3588 "Illegal member name found.");
3589 }
3590 }
3591 // can only have these in IDL anyway
3592 switch (root->lang)
3593 {
3594 case SrcLangExt::Unknown: // fall through (root node always is Unknown)
3595 case SrcLangExt::IDL:
3596 for (const auto &e : root->children()) buildInterfaceAndServiceList(e.get());
3597 break;
3598 default:
3599 return; // nothing to do here
3600 }
3601}
@ Singleton
Definition classdef.h:117
@ Interface
Definition classdef.h:112
virtual CompoundType compoundType() const =0
Returns the type of compound this is, i.e.
static void addInterfaceOrServiceToServiceOrSingleton(const Entry *root, ClassDefMutable *cd, QCString const &rname)
Definition doxygen.cpp:3494
static void buildInterfaceAndServiceList(const Entry *root)
Definition doxygen.cpp:3556
@ Unknown
Definition types.h:43

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

Referenced by buildInterfaceAndServiceList(), and parseInput().

◆ buildListOfUsingDecls()

static void buildListOfUsingDecls ( const Entry * root)
static

Definition at line 1971 of file doxygen.cpp.

1972{
1973 if (root->section.isUsingDecl() &&
1974 !root->parent()->section.isCompound() // not a class/struct member
1975 )
1976 {
1977 QCString name = substitute(root->name,".","::");
1978 g_usingDeclarations.insert(name.str());
1979 }
1980 for (const auto &e : root->children()) buildListOfUsingDecls(e.get());
1981}
static StringSet g_usingDeclarations
Definition doxygen.cpp:182
static void buildListOfUsingDecls(const Entry *root)
Definition doxygen.cpp:1971

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

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

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

Referenced by buildNamespaceList(), and parseInput().

◆ buildPageList()

static void buildPageList ( Entry * root)
static

Definition at line 9579 of file doxygen.cpp.

9580{
9581 if (root->section.isPageDoc())
9582 {
9583 if (!root->name.isEmpty())
9584 {
9585 addRelatedPage(root);
9586 }
9587 }
9588 else if (root->section.isMainpageDoc())
9589 {
9590 QCString title=root->args.stripWhiteSpace();
9591 if (title.isEmpty()) title=theTranslator->trMainPage();
9592 //QCString name = Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9593 QCString name = "index";
9594 addRefItem(root->sli,
9595 name,
9596 "page",
9597 name,
9598 title,
9599 QCString(),nullptr
9600 );
9601 }
9602 for (const auto &e : root->children()) buildPageList(e.get());
9603}
static void buildPageList(Entry *root)
Definition doxygen.cpp:9579

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

Referenced by buildPageList(), and parseInput().

◆ buildScopeFromQualifiedName()

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

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

Definition at line 698 of file doxygen.cpp.

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

References DefinitionMutable::addInnerCompound(), QCString::contains(), createNamespaceDef(), TagInfo::fileName, QCString::find(), getClass(), getScopeFragment(), Doxygen::globalScope, QCString::isEmpty(), QCString::mid(), Doxygen::namespaceLinkedMap, DefinitionMutable::setArtificial(), DefinitionMutable::setLanguage(), DefinitionMutable::setOuterScope(), QCString::stripPrefix(), stripTemplateSpecifiers(), TagInfo::tagName, toDefinition(), toDefinitionMutable(), toNamespaceDefMutable(), and TRUE.

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

◆ buildSequenceList()

static void buildSequenceList ( const Entry * root)
static

Definition at line 3425 of file doxygen.cpp.

3426{
3427 if (!root->name.isEmpty() &&
3428 root->section.isVariable() &&
3429 root->type.find("sequence<")!=-1 // it's a sequence
3430 )
3431 {
3432 AUTO_TRACE();
3433 addVariable(root);
3434 }
3435 for (const auto &e : root->children())
3436 if (!e->section.isEnum())
3437 buildSequenceList(e.get());
3438}
static void buildSequenceList(const Entry *root)
Definition doxygen.cpp:3425

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

Referenced by buildSequenceList(), and parseInput().

◆ buildTypedefList()

static void buildTypedefList ( const Entry * root)
static

Definition at line 3326 of file doxygen.cpp.

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

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

Referenced by buildTypedefList(), and parseInput().

◆ buildVarList()

static void buildVarList ( const Entry * root)
static

Definition at line 3462 of file doxygen.cpp.

3463{
3464 //printf("buildVarList(%s) section=%08x\n",qPrint(rootNav->name()),rootNav->section());
3465 int isFuncPtr=-1;
3466 if (!root->name.isEmpty() &&
3467 (root->type.isEmpty() || g_compoundKeywords.find(root->type.str())==g_compoundKeywords.end()) &&
3468 (
3469 (root->section.isVariable() && // it's a variable
3470 root->type.find("typedef ")==-1 // and not a typedef
3471 ) ||
3472 (root->section.isFunction() && // or maybe a function pointer variable
3473 (isFuncPtr=findFunctionPtr(root->type.str(),root->lang))!=-1
3474 ) ||
3475 (root->section.isFunction() && // class variable initialized by constructor
3477 )
3478 )
3479 ) // documented variable
3480 {
3481 AUTO_TRACE();
3482 addVariable(root,isFuncPtr);
3483 }
3484 for (const auto &e : root->children())
3485 if (!e->section.isEnum())
3486 buildVarList(e.get());
3487}
static void buildVarList(const Entry *root)
Definition doxygen.cpp:3462
static bool isVarWithConstructor(const Entry *root)
Definition doxygen.cpp:2866
static const StringUnorderedSet g_compoundKeywords
Definition doxygen.cpp:191

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

Referenced by buildVarList(), and parseInput().

◆ checkConfiguration()

void checkConfiguration ( )

check and resolve config options

Definition at line 11860 of file doxygen.cpp.

11861{
11862 AUTO_TRACE();
11863
11868}
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 12337 of file doxygen.cpp.

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

9719{
9720 for (const auto &pd : *Doxygen::pageLinkedMap)
9721 {
9722 Definition *ppd = pd->getOuterScope();
9723 while (ppd)
9724 {
9725 if (ppd==pd.get())
9726 {
9727 term("page defined %s with label %s is a subpage "
9728 "of itself! Please remove this cyclic dependency.\n",
9729 qPrint(warn_line(pd->docFile(),pd->docLine())),qPrint(pd->name()));
9730 }
9731 ppd=ppd->getOuterScope();
9732 }
9733 }
9734}

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

Referenced by parseInput().

◆ cleanUpDoxygen()

void cleanUpDoxygen ( )

Definition at line 11386 of file doxygen.cpp.

11387{
11391
11392 delete Doxygen::indexList;
11401 Doxygen::mainPage.reset();
11405 Doxygen::globalScope = nullptr;
11407 delete theTranslator;
11408 delete g_outputList;
11409
11414 delete Doxygen::dirLinkedMap;
11415 delete Doxygen::symbolMap;
11416}
static ParserManager * parserManager
Definition doxygen.h:131
static SymbolMap< Definition > * symbolMap
Definition doxygen.h:125
static FormulaManager & instance()
Definition formula.cpp:54
void clear()
Definition linkedmap.h:212
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:175
static OutputList * g_outputList
Definition doxygen.cpp:181

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

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

◆ clearAll()

void clearAll ( )

Definition at line 194 of file doxygen.cpp.

195{
196 g_inputFiles.clear();
197 //g_excludeNameDict.clear();
198 //delete g_outputList; g_outputList=nullptr;
199
204 Doxygen::pageLinkedMap->clear();
217 Doxygen::mainPage.reset();
219}
static CitationManager & instance()
Definition cite.cpp:80
void clear()
clears the database
Definition cite.cpp:106
static StringMap tagDestinationMap
Definition doxygen.h:116
static ClassLinkedMap * hiddenClassLinkedMap
Definition doxygen.h:97

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

◆ combineUsingRelations()

static void combineUsingRelations ( )
static

Definition at line 9117 of file doxygen.cpp.

9118{
9119 // for each file
9120 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9121 {
9122 for (const auto &fd : *fn)
9123 {
9124 fd->combineUsingRelations();
9125 }
9126 }
9127
9128 // for each namespace
9129 NamespaceDefSet visitedNamespaces;
9130 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9131 {
9133 if (ndm)
9134 {
9135 ndm->combineUsingRelations(visitedNamespaces);
9136 }
9137 }
9138}
virtual void combineUsingRelations(NamespaceDefSet &visitedNamespace)=0
std::unordered_set< const NamespaceDef * > NamespaceDefSet

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

Referenced by parseInput().

◆ compareDoxyfile()

static void compareDoxyfile ( Config::CompareMode diffList)
static

Definition at line 10284 of file doxygen.cpp.

10285{
10286 std::ofstream f;
10287 bool fileOpened=openOutputFile("-",f);
10288 if (fileOpened)
10289 {
10290 TextStream t(&f);
10291 Config::compareDoxyfile(t,diffList);
10292 }
10293 else
10294 {
10295 term("Cannot open stdout for writing\n");
10296 }
10297}
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:6624

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

Referenced by readConfiguration().

◆ computeClassRelations()

static void computeClassRelations ( )
static

Definition at line 5270 of file doxygen.cpp.

5271{
5272 AUTO_TRACE();
5273 for (const auto &[name,root] : g_classEntries)
5274 {
5275 QCString bName = extractClassName(root);
5276 ClassDefMutable *cd = getClassMutable(bName);
5277 if (cd)
5278 {
5280 }
5281 size_t numMembers = cd ? cd->memberNameInfoLinkedMap().size() : 0;
5282 if ((cd==nullptr || (!cd->hasDocumentation() && !cd->isReference())) && numMembers>0 && !bName.endsWith("::"))
5283 {
5284 if (!root->name.isEmpty() && root->name.find('@')==-1 && // normal name
5285 (guessSection(root->fileName).isHeader() ||
5286 Config_getBool(EXTRACT_LOCAL_CLASSES)) && // not defined in source file
5287 protectionLevelVisible(root->protection) && // hidden by protection
5288 !Config_getBool(HIDE_UNDOC_CLASSES) // undocumented class are visible
5289 )
5290 warn_undoc(
5291 root->fileName,root->startLine,
5292 "Compound %s is not documented.",
5293 qPrint(root->name)
5294 );
5295 }
5296 }
5297}
virtual const MemberNameInfoLinkedMap & memberNameInfoLinkedMap() const =0
Returns a dictionary of all members.
size_t size() const
Definition linkedmap.h:210
bool endsWith(const char *s) const
Definition qcstring.h:509
static QCString extractClassName(const Entry *root)
Definition doxygen.cpp:5182
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:4639
static std::multimap< std::string, const Entry * > g_classEntries
Definition doxygen.cpp:179
#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 11418 of file doxygen.cpp.

11419{
11420 //printf("computeIdealCacheParam(v=%u)\n",v);
11421
11422 int r=0;
11423 while (v!=0) v>>=1,r++;
11424 // r = log2(v)
11425
11426 // convert to a valid cache size value
11427 return std::max(0,std::min(r-16,9));
11428}

Referenced by generateOutput().

◆ computeMemberReferences()

static void computeMemberReferences ( )
static

Definition at line 5368 of file doxygen.cpp.

5369{
5370 AUTO_TRACE();
5371 for (const auto &cd : *Doxygen::classLinkedMap)
5372 {
5373 ClassDefMutable *cdm = toClassDefMutable(cd.get());
5374 if (cdm)
5375 {
5376 cdm->computeAnchors();
5377 }
5378 }
5379 for (const auto &fn : *Doxygen::inputNameLinkedMap)
5380 {
5381 for (const auto &fd : *fn)
5382 {
5383 fd->computeAnchors();
5384 }
5385 }
5386 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5387 {
5389 if (ndm)
5390 {
5391 ndm->computeAnchors();
5392 }
5393 }
5394 for (const auto &gd : *Doxygen::groupLinkedMap)
5395 {
5396 gd->computeAnchors();
5397 }
5398}
virtual void computeAnchors()=0
virtual void computeAnchors()=0

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

Referenced by parseInput().

◆ computeMemberRelations()

static void computeMemberRelations ( )
static

Definition at line 8363 of file doxygen.cpp.

8364{
8365 for (const auto &cd : *Doxygen::classLinkedMap)
8366 {
8367 if (cd->isLinkable())
8368 {
8369 for (const auto &bcd : cd->baseClasses())
8370 {
8372 }
8373 }
8374 }
8375}
static void computeMemberRelationsForBaseClass(const ClassDef *cd, const BaseClassDef *bcd)
Definition doxygen.cpp:8286

References Doxygen::classLinkedMap, and computeMemberRelationsForBaseClass().

Referenced by parseInput().

◆ computeMemberRelationsForBaseClass()

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

Definition at line 8286 of file doxygen.cpp.

8287{
8288 for (const auto &mn : cd->memberNameInfoLinkedMap()) // for each member in class cd with a unique name
8289 {
8290 for (const auto &imd : *mn) // for each member with a given name
8291 {
8292 MemberDefMutable *md = toMemberDefMutable(imd->memberDef());
8293 if (md && (md->isFunction() || md->isCSharpProperty())) // filter on reimplementable members
8294 {
8295 ClassDef *mbcd = bcd->classDef;
8296 if (mbcd && mbcd->isLinkable()) // filter on linkable classes
8297 {
8298 const auto &bmn = mbcd->memberNameInfoLinkedMap();
8299 const auto &bmni = bmn.find(mn->memberName());
8300 if (bmni) // there are base class members with the same name
8301 {
8302 for (const auto &ibmd : *bmni) // for base class member with that name
8303 {
8304 MemberDefMutable *bmd = toMemberDefMutable(ibmd->memberDef());
8305 if (bmd) // not part of an inline namespace
8306 {
8307 if (bmd->virtualness()!=Specifier::Normal ||
8309 bmd->getLanguage()==SrcLangExt::Java ||
8310 bmd->getLanguage()==SrcLangExt::PHP ||
8313 {
8314 const ArgumentList &bmdAl = bmd->argumentList();
8315 const ArgumentList &mdAl = md->argumentList();
8316 //printf(" Base argList='%s'\n Super argList='%s'\n",
8317 // qPrint(argListToString(bmdAl)),
8318 // qPrint(argListToString(mdAl))
8319 // );
8320 if (
8322 matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),&bmdAl,
8323 md->getOuterScope(), md->getFileDef(), &mdAl,
8324 TRUE,bmd->getLanguage()
8325 )
8326 )
8327 {
8328 //printf("match!\n");
8329 const MemberDef *rmd = md->reimplements();
8330 if (rmd==nullptr) // not already assigned
8331 {
8332 //printf("%s: setting (new) reimplements member %s\n",qPrint(md->qualifiedName()),qPrint(bmd->qualifiedName()));
8333 md->setReimplements(bmd);
8334 }
8335 //printf("%s: add reimplementedBy member %s\n",qPrint(bmd->qualifiedName()),qPrint(md->qualifiedName()));
8336 bmd->insertReimplementedBy(md);
8337 }
8338 else
8339 {
8340 //printf("no match!\n");
8341 }
8342 }
8343 }
8344 }
8345 }
8346 }
8347 }
8348 }
8349 }
8350
8351 // do also for indirect base classes
8352 for (const auto &bbcd : bcd->classDef->baseClasses())
8353 {
8355 }
8356}
virtual const BaseClassList & baseClasses() const =0
Returns the list of base classes from which this class directly inherits.
virtual bool isCSharpProperty() const =0
virtual bool isFunction() const =0
virtual const MemberDef * reimplements() const =0
virtual void setReimplements(MemberDef *md)=0
virtual void insertReimplementedBy(MemberDef *md)=0
ClassDef * classDef
Class definition that this relation inherits from.
Definition classdef.h:60

References MemberDef::argumentList(), ClassDef::baseClasses(), BaseClassDef::classDef, ClassDef::compoundType(), computeMemberRelationsForBaseClass(), LinkedMap< T, Hash, KeyEqual, Map >::find(), MemberDef::getFileDef(), Definition::getLanguage(), Definition::getOuterScope(), MemberDefMutable::insertReimplementedBy(), ClassDef::Interface, MemberDef::isCSharpProperty(), MemberDef::isFunction(), Definition::isLinkable(), Java, matchArguments2(), ClassDef::memberNameInfoLinkedMap(), 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 9688 of file doxygen.cpp.

9689{
9690 if ((root->section.isPageDoc() || root->section.isMainpageDoc()) && !root->name.isEmpty())
9691 {
9692 PageDef *pd = root->section.isPageDoc() ?
9693 Doxygen::pageLinkedMap->find(root->name) :
9694 Doxygen::mainPage.get();
9695 if (pd)
9696 {
9697 for (const BaseInfo &bi : root->extends)
9698 {
9699 PageDef *subPd = Doxygen::pageLinkedMap->find(bi.name);
9700 if (pd==subPd)
9701 {
9702 term("page defined %s with label %s is a direct "
9703 "subpage of itself! Please remove this cyclic dependency.\n",
9704 qPrint(warn_line(pd->docFile(),pd->docLine())),qPrint(pd->name()));
9705 }
9706 else if (subPd)
9707 {
9708 pd->addInnerCompound(subPd);
9709 //printf("*** Added subpage relation: %s->%s\n",
9710 // qPrint(pd->name()),qPrint(subPd->name()));
9711 }
9712 }
9713 }
9714 }
9715 for (const auto &e : root->children()) computePageRelations(e.get());
9716}
virtual QCString docFile() const =0
virtual int docLine() const =0
std::vector< BaseInfo > extends
list of base classes
Definition entry.h:220
static void computePageRelations(Entry *root)
Definition doxygen.cpp:9688
QCString name
the name of the base class
Definition entry.h:94

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

Referenced by computePageRelations(), and parseInput().

◆ computeTemplateClassRelations()

static void computeTemplateClassRelations ( )
static

Definition at line 5299 of file doxygen.cpp.

5300{
5301 AUTO_TRACE();
5302 for (const auto &[name,root] : g_classEntries)
5303 {
5304 QCString bName=stripAnonymousNamespaceScope(root->name);
5307 // strip any anonymous scopes first
5308 if (cd && !cd->getTemplateInstances().empty())
5309 {
5310 AUTO_TRACE_ADD("Template class '{}'",cd->name());
5311 for (const auto &ti : cd->getTemplateInstances()) // for each template instance
5312 {
5313 ClassDefMutable *tcd=toClassDefMutable(ti.classDef);
5314 if (tcd)
5315 {
5316 AUTO_TRACE_ADD("Template instance '{}'",tcd->name());
5317 QCString templSpec = ti.templSpec;
5318 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(tcd->getLanguage(),templSpec);
5319 for (const BaseInfo &bi : root->extends)
5320 {
5321 // check if the base class is a template argument
5322 BaseInfo tbi = bi;
5323 const ArgumentList &tl = cd->templateArguments();
5324 if (!tl.empty())
5325 {
5326 TemplateNameMap baseClassNames = tcd->getTemplateBaseClassNames();
5327 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,bi.name.str());
5328 // for each template name that we inherit from we need to
5329 // substitute the formal with the actual arguments
5330 TemplateNameMap actualTemplateNames;
5331 for (const auto &tn_kv : templateNames)
5332 {
5333 size_t templIndex = tn_kv.second;
5334 Argument actArg;
5335 bool hasActArg=FALSE;
5336 if (templIndex<templArgs->size())
5337 {
5338 actArg=templArgs->at(templIndex);
5339 hasActArg=TRUE;
5340 }
5341 if (hasActArg &&
5342 baseClassNames.find(actArg.type.str())!=baseClassNames.end() &&
5343 actualTemplateNames.find(actArg.type.str())==actualTemplateNames.end()
5344 )
5345 {
5346 actualTemplateNames.emplace(actArg.type.str(),static_cast<int>(templIndex));
5347 }
5348 }
5349
5350 tbi.name = substituteTemplateArgumentsInString(bi.name,tl,templArgs.get());
5351 // find a documented base class in the correct scope
5352 if (!findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE))
5353 {
5354 // no documented base class -> try to find an undocumented one
5355 findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,Undocumented,TRUE);
5356 }
5357 }
5358 }
5359 }
5360 }
5361 }
5362 }
5363}
virtual const TemplateInstanceList & getTemplateInstances() const =0
Returns a sorted dictionary with all template instances found for this template class.
virtual const TemplateNameMap & getTemplateBaseClassNames() const =0
static TemplateNameMap getTemplateArgumentsInName(const ArgumentList &templateArguments, const std::string &name)
Definition doxygen.cpp:4418
This class contains the information about the argument of a function or template.
Definition arguments.h:27
QCString type
Definition arguments.h:37
QCString substituteTemplateArgumentsInString(const QCString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
Definition util.cpp:4705

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

8844{
8845 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8846 if (numThreads>1)
8847 {
8848 ThreadPool threadPool(numThreads);
8849 std::vector < std::future< void > > results;
8850 // queue the work
8851 for (const auto &[name,symList] : *Doxygen::symbolMap)
8852 {
8853 for (const auto &def : symList)
8854 {
8856 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
8857 {
8858 auto processTooltip = [dm]() {
8859 dm->computeTooltip();
8860 };
8861 results.emplace_back(threadPool.queue(processTooltip));
8862 }
8863 }
8864 }
8865 // wait for the results
8866 for (auto &f : results)
8867 {
8868 f.get();
8869 }
8870 }
8871 else
8872 {
8873 for (const auto &[name,symList] : *Doxygen::symbolMap)
8874 {
8875 for (const auto &def : symList)
8876 {
8878 if (dm && !isSymbolHidden(def) && !def->isArtificial() && def->isLinkableInProject())
8879 {
8880 dm->computeTooltip();
8881 }
8882 }
8883 }
8884 }
8885}
virtual void computeTooltip()=0
Class managing a pool of worker threads.
Definition threadpool.h:48
static bool isSymbolHidden(const Definition *d)
Definition doxygen.cpp:8836

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

Referenced by parseInput().

◆ computeVerifiedDotPath()

static void computeVerifiedDotPath ( )
static

Definition at line 10212 of file doxygen.cpp.

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

References QCString::at(), Portable::commandExtension(), Config_getString, FileInfo::exists(), QCString::isEmpty(), FileInfo::isFile(), QCString::length(), 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 882 of file doxygen.cpp.

883{
885
886 if (specifier.isStruct())
888 else if (specifier.isUnion())
889 sec=ClassDef::Union;
890 else if (specifier.isCategory())
892 else if (specifier.isInterface())
894 else if (specifier.isProtocol())
896 else if (specifier.isException())
898 else if (specifier.isService())
900 else if (specifier.isSingleton())
902
903 if (section.isUnionDoc())
904 sec=ClassDef::Union;
905 else if (section.isStructDoc())
907 else if (section.isInterfaceDoc())
909 else if (section.isProtocolDoc())
911 else if (section.isCategoryDoc())
913 else if (section.isExceptionDoc())
915 else if (section.isServiceDoc())
917 else if (section.isSingletonDoc())
919
920 return sec;
921}
@ 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 10477 of file doxygen.cpp.

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

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

10453{
10454 QCString projectIcon = Config_getString(PROJECT_ICON);
10455 if (!projectIcon.isEmpty())
10456 {
10457 FileInfo fi(projectIcon.str());
10458 if (!fi.exists())
10459 {
10460 err("Project icon '%s' specified by PROJECT_ICON does not exist!\n",qPrint(projectIcon));
10461 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10462 }
10463 else if (fi.isDir())
10464 {
10465 err("Project icon '%s' specified by PROJECT_ICON is a directory, it has to be a file!\n",qPrint(projectIcon));
10466 projectIcon = Config_updateString(PROJECT_ICON,""); // revert to the default
10467 }
10468 else
10469 {
10470 QCString destFileName = outputOption+"/"+fi.fileName();
10471 copyFile(projectIcon,destFileName);
10472 Doxygen::indexList->addImageFile(fi.fileName().c_str());
10473 }
10474 }
10475}
#define Config_updateString(name, value)
Definition config.h:39

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

Referenced by generateOutput().

◆ copyLatexStyleSheet()

static void copyLatexStyleSheet ( )
static

Definition at line 10343 of file doxygen.cpp.

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

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

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

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

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

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

8904{
8905 for (const auto &cd : *Doxygen::classLinkedMap)
8906 {
8907 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8908 if (cdm)
8909 {
8910 cdm->countMembers();
8911 }
8912 }
8913
8914 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8915 {
8917 if (ndm)
8918 {
8919 ndm->countMembers();
8920 }
8921 }
8922
8923 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8924 {
8925 for (const auto &fd : *fn)
8926 {
8927 fd->countMembers();
8928 }
8929 }
8930
8931 for (const auto &gd : *Doxygen::groupLinkedMap)
8932 {
8933 gd->countMembers();
8934 }
8935
8936 auto &mm = ModuleManager::instance();
8937 mm.countMembers();
8938}
virtual void countMembers()=0
virtual void countMembers()=0

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

Referenced by parseInput().

◆ createOutputDirectory()

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

Definition at line 12105 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ createTagLessInstance()

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

Definition at line 1458 of file doxygen.cpp.

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

References DefinitionMutable::addInnerCompound(), Definition::briefDescription(), Definition::briefFile(), Definition::briefLine(), Doxygen::classLinkedMap, ClassDef::compoundType(), createClassDef(), createMemberDef(), Definition::docFile(), Definition::docLine(), Definition::documentation(), QCString::endsWith(), Definition::getBodyDef(), Definition::getDefColumn(), Definition::getDefFileName(), Definition::getDefLine(), Definition::getEndBodyLine(), ClassDef::getFileDef(), Definition::getLanguage(), ClassDef::getMemberList(), Definition::getOuterScope(), Definition::getStartBodyLine(), Doxygen::globalScope, FileDef::insertClass(), ClassDefMutable::insertMember(), QCString::left(), QCString::length(), DefinitionMutable::makePartOfGroup(), Member, Doxygen::memberNameLinkedMap, Definition::name(), Definition::partOfGroups(), MemberName::push_back(), removeAnonymousScopes(), MemberDefMutable::setBitfields(), DefinitionMutable::setBodyDef(), DefinitionMutable::setBodySegment(), DefinitionMutable::setBriefDescription(), DefinitionMutable::setDocumentation(), ClassDefMutable::setFileDef(), DefinitionMutable::setInbodyDocumentation(), MemberDefMutable::setInitializer(), DefinitionMutable::setLanguage(), MemberDefMutable::setMaxInitLines(), MemberDefMutable::setMemberClass(), MemberDefMutable::setMemberGroupId(), MemberDefMutable::setMemberSpecifiers(), DefinitionMutable::setOuterScope(), MemberDefMutable::setRequiresClause(), MemberDefMutable::setVhdlSpecifiers(), toClassDefMutable(), toDefinitionMutable(), and toMemberDefMutable().

Referenced by processTagLessClasses().

◆ createTemplateInstanceMembers()

static void createTemplateInstanceMembers ( )
static

Definition at line 8379 of file doxygen.cpp.

8380{
8381 // for each class
8382 for (const auto &cd : *Doxygen::classLinkedMap)
8383 {
8384 // that is a template
8385 for (const auto &ti : cd->getTemplateInstances())
8386 {
8387 ClassDefMutable *tcdm = toClassDefMutable(ti.classDef);
8388 if (tcdm)
8389 {
8390 tcdm->addMembersToTemplateInstance(cd.get(),cd->templateArguments(),ti.templSpec);
8391 }
8392 }
8393 }
8394}
virtual void addMembersToTemplateInstance(const ClassDef *cd, const ArgumentList &templateArguments, const QCString &templSpec)=0

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

Referenced by parseInput().

◆ createUsingMemberImportForClass()

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

Definition at line 2088 of file doxygen.cpp.

2090{
2091 AUTO_TRACE("creating new member {} for class {}",memName,cd->name());
2092 const ArgumentList &templAl = md->templateArguments();
2093 const ArgumentList &al = md->argumentList();
2094 auto newMd = createMemberDef(
2095 fileName,root->startLine,root->startColumn,
2096 md->typeString(),memName,md->argsString(),
2097 md->excpString(),root->protection,root->virt,
2099 templAl,al,root->metaData
2100 );
2101 auto newMmd = toMemberDefMutable(newMd.get());
2102 newMmd->setMemberClass(cd);
2103 cd->insertMember(newMd.get());
2104 if (!root->doc.isEmpty() || !root->brief.isEmpty())
2105 {
2106 newMmd->setDocumentation(root->doc,root->docFile,root->docLine);
2107 newMmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
2108 newMmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
2109 }
2110 else
2111 {
2112 newMmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
2113 newMmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
2114 newMmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
2115 }
2116 newMmd->setDefinition(md->definition());
2117 applyMemberOverrideOptions(root,newMmd);
2118 newMmd->addQualifiers(root->qualifiers);
2119 newMmd->setBitfields(md->bitfieldString());
2120 newMmd->addSectionsToDefinition(root->anchors);
2121 newMmd->setBodySegment(md->getDefLine(),md->getStartBodyLine(),md->getEndBodyLine());
2122 newMmd->setBodyDef(md->getBodyDef());
2123 newMmd->setInitializer(md->initializer());
2124 newMmd->setRequiresClause(md->requiresClause());
2125 newMmd->setMaxInitLines(md->initializerLines());
2126 newMmd->setMemberGroupId(root->mGrpId);
2127 newMmd->setMemberSpecifiers(md->getMemberSpecifiers());
2128 newMmd->setVhdlSpecifiers(md->getVhdlSpecifiers());
2129 newMmd->setLanguage(root->lang);
2130 newMmd->setId(root->id);
2131 MemberName *mn = Doxygen::memberNameLinkedMap->add(memName);
2132 mn->push_back(std::move(newMd));
2133}
virtual int inbodyLine() const =0
virtual QCString inbodyFile() const =0
virtual QCString definition() const =0
virtual QCString excpString() const =0
virtual VhdlSpecifier getVhdlSpecifiers() const =0
virtual QCString bitfieldString() const =0
virtual TypeSpecifier getMemberSpecifiers() const =0
virtual int initializerLines() const =0

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

Referenced by findUsingDeclImports().

◆ devUsage()

static void devUsage ( )
static

Definition at line 11197 of file doxygen.cpp.

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

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

Referenced by readConfiguration().

◆ distributeClassGroupRelations()

void distributeClassGroupRelations ( )

Definition at line 1425 of file doxygen.cpp.

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

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

9181{
9182 // for each class
9183 for (const auto &cd : *Doxygen::classLinkedMap)
9184 {
9185 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9186 if (cdm)
9187 {
9189 }
9190 }
9191 // for each file
9192 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9193 {
9194 for (const auto &fd : *fn)
9195 {
9196 fd->distributeMemberGroupDocumentation();
9197 }
9198 }
9199 // for each namespace
9200 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9201 {
9203 if (ndm)
9204 {
9206 }
9207 }
9208 // for each group
9209 for (const auto &gd : *Doxygen::groupLinkedMap)
9210 {
9211 gd->distributeMemberGroupDocumentation();
9212 }
9214}
virtual void distributeMemberGroupDocumentation()=0
void distributeMemberGroupDocumentation()
virtual void distributeMemberGroupDocumentation()=0

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

Referenced by parseInput().

◆ dumpSymbol()

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

Definition at line 11156 of file doxygen.cpp.

11157{
11158 QCString anchor;
11160 {
11161 MemberDef *md = toMemberDef(d);
11162 anchor=":"+md->anchor();
11163 }
11164 QCString scope;
11165 QCString fn = d->getOutputFileBase();
11168 {
11169 scope = fn;
11170 }
11171 t << "REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
11172 << fn+anchor << "','"
11173 << scope << "','"
11174 << d->name() << "','"
11175 << d->getDefFileName() << "','"
11176 << d->getDefLine()
11177 << "');\n";
11178}
virtual QCString anchor() const =0
virtual QCString getOutputFileBase() const =0
MemberDef * toMemberDef(Definition *d)
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:5243

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

11181{
11182 std::ofstream f = Portable::openOutputStream("symbols.sql");
11183 if (f.is_open())
11184 {
11185 TextStream t(&f);
11186 for (const auto &[name,symList] : *Doxygen::symbolMap)
11187 {
11188 for (const auto &def : symList)
11189 {
11190 dumpSymbol(t,def);
11191 }
11192 }
11193 }
11194}
static void dumpSymbol(TextStream &t, Definition *d)
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:665

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

Referenced by generateOutput().

◆ exitDoxygen()

static void exitDoxygen ( )
staticnoexcept

Definition at line 12092 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ extractClassName()

static QCString extractClassName ( const Entry * root)
static

Definition at line 5182 of file doxygen.cpp.

5183{
5184 // strip any anonymous scopes first
5187 int i=0;
5188 if ((root->lang==SrcLangExt::CSharp || root->lang==SrcLangExt::Java) &&
5189 (i=bName.find('<'))!=-1)
5190 {
5191 // a Java/C# generic class looks like a C++ specialization, so we need to strip the
5192 // template part before looking for matches
5193 bName=bName.left(i);
5194 }
5195 return bName;
5196}

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

7233{
7234 AUTO_TRACE("root->type='{}' root->inside='{}' root->name='{}' root->args='{}' section={} root->spec={} root->mGrpId={}",
7235 root->type,root->inside,root->name,root->args,root->section,root->spec,root->mGrpId);
7236 //printf("root->parent()->name=%s\n",qPrint(root->parent()->name));
7237 bool isFunc=TRUE;
7238
7239 QCString type = root->type;
7240 QCString args = root->args;
7241 int i=-1, l=0;
7242 if ( // detect func variable/typedef to func ptr
7243 (i=findFunctionPtr(type.str(),root->lang,&l))!=-1
7244 )
7245 {
7246 //printf("Fixing function pointer!\n");
7247 // fix type and argument
7248 args.prepend(type.right(type.length()-i-l));
7249 type=type.left(i+l);
7250 //printf("Results type=%s,name=%s,args=%s\n",qPrint(type),qPrint(root->name),qPrint(args));
7251 isFunc=FALSE;
7252 }
7253 else if ((type.startsWith("typedef ") && args.find('(')!=-1))
7254 // detect function types marked as functions
7255 {
7256 isFunc=FALSE;
7257 }
7258
7259 //printf("Member %s isFunc=%d\n",qPrint(root->name),isFunc);
7260 if (root->section.isMemberDoc())
7261 {
7262 //printf("Documentation for inline member '%s' found args='%s'\n",
7263 // qPrint(root->name),qPrint(args));
7264 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7265 if (type.isEmpty())
7266 {
7267 findMember(root,
7268 relates,
7269 type,
7270 args,
7271 root->name + args + root->exception,
7272 FALSE,
7273 isFunc);
7274 }
7275 else
7276 {
7277 findMember(root,
7278 relates,
7279 type,
7280 args,
7281 type + " " + root->name + args + root->exception,
7282 FALSE,
7283 isFunc);
7284 }
7285 }
7286 else if (root->section.isOverloadDoc())
7287 {
7288 //printf("Overloaded member %s found\n",qPrint(root->name));
7289 findMember(root,
7290 relates,
7291 type,
7292 args,
7293 root->name,
7294 TRUE,
7295 isFunc);
7296 }
7297 else if
7298 ((root->section.isFunction() // function
7299 ||
7300 (root->section.isVariable() && // variable
7301 !type.isEmpty() && // with a type
7302 g_compoundKeywords.find(type.str())==g_compoundKeywords.end() // that is not a keyword
7303 // (to skip forward declaration of class etc.)
7304 )
7305 )
7306 )
7307 {
7308 //printf("Documentation for member '%s' found args='%s' excp='%s'\n",
7309 // qPrint(root->name),qPrint(args),qPrint(root->exception));
7310 //if (relates.length()) printf(" Relates %s\n",qPrint(relates));
7311 //printf("Inside=%s\n Relates=%s\n",qPrint(root->inside),qPrint(relates));
7312 if (type=="friend class" || type=="friend struct" ||
7313 type=="friend union")
7314 {
7315 findMember(root,
7316 relates,
7317 type,
7318 args,
7319 type+" "+root->name,
7320 FALSE,FALSE);
7321
7322 }
7323 else if (!type.isEmpty())
7324 {
7325 findMember(root,
7326 relates,
7327 type,
7328 args,
7329 type+" "+ root->inside + root->name + args + root->exception,
7330 FALSE,isFunc);
7331 }
7332 else
7333 {
7334 findMember(root,
7335 relates,
7336 type,
7337 args,
7338 root->inside + root->name + args + root->exception,
7339 FALSE,isFunc);
7340 }
7341 }
7342 else if (root->section.isDefine() && !relates.isEmpty())
7343 {
7344 findMember(root,
7345 relates,
7346 type,
7347 args,
7348 root->name + args,
7349 FALSE,
7350 !args.isEmpty());
7351 }
7352 else if (root->section.isVariableDoc())
7353 {
7354 //printf("Documentation for variable %s found\n",qPrint(root->name));
7355 //if (!relates.isEmpty()) printf(" Relates %s\n",qPrint(relates));
7356 findMember(root,
7357 relates,
7358 type,
7359 args,
7360 root->name,
7361 FALSE,
7362 FALSE);
7363 }
7364 else if (root->section.isExportedInterface() ||
7365 root->section.isIncludedService())
7366 {
7367 findMember(root,
7368 relates,
7369 type,
7370 args,
7371 type + " " + root->name,
7372 FALSE,
7373 FALSE);
7374 }
7375 else
7376 {
7377 // skip section
7378 //printf("skip section\n");
7379 }
7380}
QCString inside
name of the class in which documents are found
Definition entry.h:213
static void findMember(const Entry *root, const QCString &relates, const QCString &type, const QCString &args, QCString funcDecl, bool overloaded, bool isFunc)
Definition doxygen.cpp:6604

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

4649{
4650 AUTO_TRACE("name={}",root->name);
4651 // The base class could ofcouse also be a non-nested class
4652 const ArgumentList &formalArgs = masterCd->templateArguments();
4653 for (const BaseInfo &bi : root->extends)
4654 {
4655 //printf("masterCd=%s bi.name='%s' #actualArgs=%d\n",
4656 // qPrint(masterCd->localName()),qPrint(bi.name),actualArgs ? (int)actualArgs->size() : -1);
4657 TemplateNameMap formTemplateNames;
4658 if (templateNames.empty())
4659 {
4660 formTemplateNames = getTemplateArgumentsInName(formalArgs,bi.name.str());
4661 }
4662 BaseInfo tbi = bi;
4663 tbi.name = substituteTemplateArgumentsInString(bi.name,formalArgs,actualArgs);
4664 //printf("masterCd=%p instanceCd=%p bi->name=%s tbi.name=%s\n",(void*)masterCd,(void*)instanceCd,qPrint(bi.name),qPrint(tbi.name));
4665
4666 if (mode==DocumentedOnly)
4667 {
4668 // find a documented base class in the correct scope
4669 if (!findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,DocumentedOnly,isArtificial))
4670 {
4671 // 1.8.2: decided to show inheritance relations even if not documented,
4672 // we do make them artificial, so they do not appear in the index
4673 //if (!Config_getBool(HIDE_UNDOC_RELATIONS))
4674 bool b = Config_getBool(HIDE_UNDOC_RELATIONS) ? TRUE : isArtificial;
4675 //{
4676 // no documented base class -> try to find an undocumented one
4677 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,Undocumented,b);
4678 //}
4679 }
4680 }
4681 else if (mode==TemplateInstances)
4682 {
4683 findClassRelation(root,context,instanceCd,&tbi,formTemplateNames,TemplateInstances,isArtificial);
4684 }
4685 }
4686}

References AUTO_TRACE, Config_getBool, DocumentedOnly, Entry::extends, findClassRelation(), getTemplateArgumentsInName(), BaseInfo::name, Entry::name, QCString::str(), substituteTemplateArgumentsInString(), ClassDef::templateArguments(), TemplateInstances, TRUE, and Undocumented.

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

◆ findClassDefinition()

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

Definition at line 5637 of file doxygen.cpp.

5639{
5640 SymbolResolver resolver(fd);
5641 const ClassDef *tcd = resolver.resolveClass(nd,scopeName,true,true);
5642 return tcd;
5643}
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 5173 of file doxygen.cpp.

5174{
5175 if (isClassSection(root))
5176 {
5177 g_classEntries.emplace(root->name.str(),root);
5178 }
5179 for (const auto &e : root->children()) findClassEntries(e.get());
5180}
static void findClassEntries(const Entry *root)
Definition doxygen.cpp:5173
static bool isClassSection(const Entry *root)
Definition doxygen.cpp:5151

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

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

References AUTO_TRACE, AUTO_TRACE_ADD, buildScopeFromQualifiedName(), ClassDef::Class, Doxygen::classLinkedMap, QCString::clear(), Config_getBool, createClassDef(), DocumentedOnly, end(), QCString::endsWith(), FALSE, Entry::fileDef(), Entry::fileName, findClassWithinClassContext(), QCString::findRev(), findScopeFromQualifiedName(), findTemplateInstanceRelation(), findTemplateSpecializationPosition(), found, getClassMutable(), ClassDef::getFileDef(), SymbolResolver::getTemplateSpec(), SymbolResolver::getTypedef(), Doxygen::globalScope, Doxygen::hiddenClassLinkedMap, IDL, ClassDefMutable::insertBaseClass(), ClassDefMutable::insertSubClass(), ClassDefMutable::insertUsedFile(), Definition::isArtificial(), ClassDef::isBaseClass(), 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 addInterfaceOrServiceToServiceOrSingleton(), computeTemplateClassRelations(), findBaseClassesForClass(), and findUsedClassesForClass().

◆ findClassWithinClassContext()

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

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

Definition at line 4446 of file doxygen.cpp.

4447{
4448 ClassDef *result=nullptr;
4449 if (cd==nullptr)
4450 {
4451 return result;
4452 }
4453 FileDef *fd=cd->getFileDef();
4454 SymbolResolver resolver(fd);
4455 if (context && cd!=context)
4456 {
4457 result = const_cast<ClassDef*>(resolver.resolveClass(context,name,true,true));
4458 }
4459 //printf("1. result=%p\n",result);
4460 if (result==nullptr)
4461 {
4462 result = const_cast<ClassDef*>(resolver.resolveClass(cd,name,true,true));
4463 }
4464 //printf("2. result=%p\n",result);
4465 if (result==nullptr) // try direct class, needed for namespaced classes imported via tag files (see bug624095)
4466 {
4467 result = getClass(name);
4468 }
4469 //printf("3. result=%p\n",result);
4470 //printf("** Trying to find %s within context %s class %s result=%s lookup=%p\n",
4471 // qPrint(name),
4472 // context ? qPrint(context->name()) : "<none>",
4473 // cd ? qPrint(cd->name()) : "<none>",
4474 // result ? qPrint(result->name()) : "<none>",
4475 // Doxygen::classLinkedMap->find(name)
4476 // );
4477 return result;
4478}

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

Referenced by findClassRelation(), and findUsedClassesForClass().

◆ findDefineDocumentation()

static void findDefineDocumentation ( Entry * root)
static

Definition at line 9423 of file doxygen.cpp.

9424{
9425 if ((root->section.isDefineDoc() || root->section.isDefine()) && !root->name.isEmpty())
9426 {
9427 //printf("found define '%s' '%s' brief='%s' doc='%s'\n",
9428 // qPrint(root->name),qPrint(root->args),qPrint(root->brief),qPrint(root->doc));
9429
9430 if (root->tagInfo() && !root->name.isEmpty()) // define read from a tag file
9431 {
9432 auto md = createMemberDef(root->tagInfo()->tagName,1,1,
9433 "#define",root->name,root->args,QCString(),
9435 ArgumentList(),ArgumentList(),"");
9436 auto mmd = toMemberDefMutable(md.get());
9437 mmd->setTagInfo(root->tagInfo());
9438 mmd->setLanguage(root->lang);
9439 //printf("Searching for '%s' fd=%p\n",qPrint(filePathName),fd);
9440 mmd->setFileDef(root->parent()->fileDef());
9441 //printf("Adding member=%s\n",qPrint(md->name()));
9443 mn->push_back(std::move(md));
9444 }
9446 if (mn)
9447 {
9448 int count=0;
9449 for (const auto &md : *mn)
9450 {
9451 if (md->memberType()==MemberType::Define) count++;
9452 }
9453 if (count==1)
9454 {
9455 for (const auto &imd : *mn)
9456 {
9457 MemberDefMutable *md = toMemberDefMutable(imd.get());
9458 if (md && md->memberType()==MemberType::Define)
9459 {
9460 addDefineDoc(root,md);
9461 }
9462 }
9463 }
9464 else if (count>1 &&
9465 (!root->doc.isEmpty() ||
9466 !root->brief.isEmpty() ||
9467 root->bodyLine!=-1
9468 )
9469 )
9470 // multiple defines don't know where to add docs
9471 // but maybe they are in different files together with their documentation
9472 {
9473 for (const auto &imd : *mn)
9474 {
9475 MemberDefMutable *md = toMemberDefMutable(imd.get());
9476 if (md && md->memberType()==MemberType::Define)
9477 {
9478 if (haveEqualFileNames(root, md) || isEntryInGroupOfMember(root, md))
9479 // doc and define in the same file or group assume they belong together.
9480 {
9481 addDefineDoc(root,md);
9482 }
9483 }
9484 }
9485 //warn("define %s found in the following files:\n",qPrint(root->name));
9486 //warn("Cannot determine where to add the documentation found "
9487 // "at line %d of file %s. \n",
9488 // root->startLine,qPrint(root->fileName));
9489 }
9490 }
9491 else if (!root->doc.isEmpty() || !root->brief.isEmpty()) // define not found
9492 {
9493 bool preEnabled = Config_getBool(ENABLE_PREPROCESSING);
9494 if (preEnabled)
9495 {
9496 warn(root->fileName,root->startLine,
9497 "documentation for unknown define %s found.",
9498 qPrint(root->name)
9499 );
9500 }
9501 else
9502 {
9503 warn(root->fileName,root->startLine,
9504 "found documented #define %s but ignoring it because "
9505 "ENABLE_PREPROCESSING is NO.",
9506 qPrint(root->name)
9507 );
9508 }
9509 }
9510 }
9511 for (const auto &e : root->children()) findDefineDocumentation(e.get());
9512}
static void findDefineDocumentation(Entry *root)
Definition doxygen.cpp:9423
static void addDefineDoc(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:9398
static bool haveEqualFileNames(const Entry *root, const MemberDef *md)
Definition doxygen.cpp:9385
static bool isEntryInGroupOfMember(const Entry *root, const MemberDef *md, bool allowNoGroup=false)
Definition doxygen.cpp:5649

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

Referenced by findDefineDocumentation(), and parseInput().

◆ findDEV()

static void findDEV ( const MemberNameLinkedMap & mnsd)
static

Definition at line 8010 of file doxygen.cpp.

8011{
8012 // for each member name
8013 for (const auto &mn : mnsd)
8014 {
8015 // for each member definition
8016 for (const auto &imd : *mn)
8017 {
8018 MemberDefMutable *md = toMemberDefMutable(imd.get());
8019 if (md && md->isEnumerate()) // member is an enum
8020 {
8021 int documentedEnumValues=0;
8022 // for each enum value
8023 for (const auto &fmd : md->enumFieldList())
8024 {
8025 if (fmd->isLinkableInProject()) documentedEnumValues++;
8026 }
8027 // at least one enum value is documented
8028 if (documentedEnumValues>0) md->setDocumentedEnumValues(TRUE);
8029 }
8030 }
8031 }
8032}
virtual const MemberVector & enumFieldList() const =0
virtual void setDocumentedEnumValues(bool value)=0

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

Referenced by findDocumentedEnumValues().

◆ findDirDocumentation()

static void findDirDocumentation ( const Entry * root)
static

Definition at line 9516 of file doxygen.cpp.

9517{
9518 if (root->section.isDirDoc())
9519 {
9520 QCString normalizedName = root->name;
9521 normalizedName = substitute(normalizedName,"\\","/");
9522 //printf("root->docFile=%s normalizedName=%s\n",
9523 // qPrint(root->docFile),qPrint(normalizedName));
9524 if (root->docFile==normalizedName) // current dir?
9525 {
9526 int lastSlashPos=normalizedName.findRev('/');
9527 if (lastSlashPos!=-1) // strip file name
9528 {
9529 normalizedName=normalizedName.left(lastSlashPos);
9530 }
9531 }
9532 if (normalizedName.at(normalizedName.length()-1)!='/')
9533 {
9534 normalizedName+='/';
9535 }
9536 DirDef *matchingDir=nullptr;
9537 for (const auto &dir : *Doxygen::dirLinkedMap)
9538 {
9539 //printf("Dir: %s<->%s\n",qPrint(dir->name()),qPrint(normalizedName));
9540 if (dir->name().right(normalizedName.length())==normalizedName)
9541 {
9542 if (matchingDir)
9543 {
9544 warn(root->fileName,root->startLine,
9545 "\\dir command matches multiple directories.\n"
9546 " Applying the command for directory %s\n"
9547 " Ignoring the command for directory %s",
9548 qPrint(matchingDir->name()),qPrint(dir->name())
9549 );
9550 }
9551 else
9552 {
9553 matchingDir=dir.get();
9554 }
9555 }
9556 }
9557 if (matchingDir)
9558 {
9559 //printf("Match for with dir %s\n",qPrint(matchingDir->name()));
9560 matchingDir->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9561 matchingDir->setDocumentation(root->doc,root->docFile,root->docLine);
9562 matchingDir->setRefItems(root->sli);
9563 root->commandOverrides.apply_directoryGraph([&](bool b) { matchingDir->overrideDirectoryGraph(b); });
9564 addDirToGroups(root,matchingDir);
9565 }
9566 else
9567 {
9568 warn(root->fileName,root->startLine,"No matching "
9569 "directory found for command \\dir %s",qPrint(normalizedName));
9570 }
9571 }
9572 for (const auto &e : root->children()) findDirDocumentation(e.get());
9573}
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:9516
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 8036 of file doxygen.cpp.

8037{
8040}
static void findDEV(const MemberNameLinkedMap &mnsd)
Definition doxygen.cpp:8010

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

Referenced by parseInput().

◆ findEnumDocumentation()

static void findEnumDocumentation ( const Entry * root)
static

Definition at line 7921 of file doxygen.cpp.

7922{
7923 if (root->section.isEnumDoc() &&
7924 !root->name.isEmpty() &&
7925 root->name.at(0)!='@' // skip anonymous enums
7926 )
7927 {
7928 QCString name;
7929 QCString scope;
7930 int i = root->name.findRev("::");
7931 if (i!=-1) // scope is specified as part of the name
7932 {
7933 name=root->name.right(root->name.length()-i-2); // extract name
7934 scope=root->name.left(i); // extract scope
7935 //printf("Scope='%s' Name='%s'\n",qPrint(scope),qPrint(name));
7936 }
7937 else // just the name
7938 {
7939 name=root->name;
7940 }
7941 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7942 {
7943 if (!scope.isEmpty()) scope.prepend("::");
7944 scope.prepend(root->parent()->name);
7945 }
7946 const ClassDef *cd = getClass(scope);
7947 const NamespaceDef *nd=Doxygen::namespaceLinkedMap->find(scope);
7948 const FileDef *fd = root->fileDef();
7949 AUTO_TRACE("Found docs for enum with name '{}' and scope '{}' in context '{}' cd='{}', nd='{}' fd='{}'",
7950 name,scope,root->parent()->name,
7951 cd ? cd->name() : QCString("<none>"),
7952 nd ? nd->name() : QCString("<none>"),
7953 fd ? fd->name() : QCString("<none>"));
7954
7955 if (!name.isEmpty())
7956 {
7957 bool found = tryAddEnumDocsToGroupMember(root, name);
7958 if (!found)
7959 {
7960 MemberName *mn = cd ? Doxygen::memberNameLinkedMap->find(name) : Doxygen::functionNameLinkedMap->find(name);
7961 if (mn)
7962 {
7963 for (const auto &imd : *mn)
7964 {
7965 MemberDefMutable *md = toMemberDefMutable(imd.get());
7966 if (md && md->isEnumerate())
7967 {
7968 const ClassDef *mcd = md->getClassDef();
7969 const NamespaceDef *mnd = md->getNamespaceDef();
7970 const FileDef *mfd = md->getFileDef();
7971 if (cd && mcd==cd)
7972 {
7973 AUTO_TRACE_ADD("Match found for class scope");
7974 addEnumDocs(root,md);
7975 found = TRUE;
7976 break;
7977 }
7978 else if (cd==nullptr && mcd==nullptr && nd!=nullptr && mnd==nd)
7979 {
7980 AUTO_TRACE_ADD("Match found for namespace scope");
7981 addEnumDocs(root,md);
7982 found = TRUE;
7983 break;
7984 }
7985 else if (cd==nullptr && nd==nullptr && mcd==nullptr && mnd==nullptr && fd==mfd)
7986 {
7987 AUTO_TRACE_ADD("Match found for global scope");
7988 addEnumDocs(root,md);
7989 found = TRUE;
7990 break;
7991 }
7992 }
7993 }
7994 }
7995 }
7996 if (!found)
7997 {
7998 warn(root->fileName,root->startLine,
7999 "Documentation for undefined enum '%s' found.",
8000 qPrint(name)
8001 );
8002 }
8003 }
8004 }
8005 for (const auto &e : root->children()) findEnumDocumentation(e.get());
8006}
static bool tryAddEnumDocsToGroupMember(const Entry *root, const QCString &name)
Definition doxygen.cpp:7888
static void addEnumDocs(const Entry *root, MemberDefMutable *md)
Definition doxygen.cpp:7847
static void findEnumDocumentation(const Entry *root)
Definition doxygen.cpp:7921

References addEnumDocs(), QCString::at(), AUTO_TRACE, AUTO_TRACE_ADD, Entry::children(), Entry::fileDef(), Entry::fileName, findEnumDocumentation(), QCString::findRev(), found, Doxygen::functionNameLinkedMap, getClass(), MemberDef::getClassDef(), MemberDef::getFileDef(), MemberDef::getNamespaceDef(), QCString::isEmpty(), MemberDef::isEnumerate(), EntryType::isScope(), QCString::left(), QCString::length(), Doxygen::memberNameLinkedMap, Definition::name(), Entry::name, Doxygen::namespaceLinkedMap, Entry::parent(), QCString::prepend(), 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 7440 of file doxygen.cpp.

7441{
7442 if (root->section.isEnum())
7443 {
7444 AUTO_TRACE("name={}",root->name);
7445 ClassDefMutable *cd = nullptr;
7446 FileDef *fd = nullptr;
7447 NamespaceDefMutable *nd = nullptr;
7448 MemberNameLinkedMap *mnsd = nullptr;
7449 bool isGlobal = false;
7450 bool isRelated = false;
7451 bool isMemberOf = false;
7452 //printf("Found enum with name '%s' relates=%s\n",qPrint(root->name),qPrint(root->relates));
7453
7454 QCString name;
7455 QCString scope;
7456
7457 int i = root->name.findRev("::");
7458 if (i!=-1) // scope is specified
7459 {
7460 scope=root->name.left(i); // extract scope
7461 name=root->name.right(root->name.length()-i-2); // extract name
7462 if ((cd=getClassMutable(scope))==nullptr)
7463 {
7465 }
7466 }
7467 else // no scope, check the scope in which the docs where found
7468 {
7469 if (root->parent()->section.isScope() && !root->parent()->name.isEmpty()) // found enum docs inside a compound
7470 {
7471 scope=root->parent()->name;
7472 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7473 }
7474 name=root->name;
7475 }
7476
7477 if (!root->relates.isEmpty())
7478 { // related member, prefix user specified scope
7479 isRelated=TRUE;
7480 isMemberOf=(root->relatesType==RelatesType::MemberOf);
7481 if (getClass(root->relates)==nullptr && !scope.isEmpty())
7482 scope=mergeScopes(scope,root->relates);
7483 else
7484 scope=root->relates;
7485 if ((cd=getClassMutable(scope))==nullptr) nd=getResolvedNamespaceMutable(scope);
7486 }
7487
7488 if (cd && !name.isEmpty()) // found a enum inside a compound
7489 {
7490 //printf("Enum '%s'::'%s'\n",qPrint(cd->name()),qPrint(name));
7491 fd=nullptr;
7493 isGlobal=false;
7494 }
7495 else if (nd) // found enum inside namespace
7496 {
7498 isGlobal=true;
7499 }
7500 else // found a global enum
7501 {
7502 fd=root->fileDef();
7504 isGlobal=true;
7505 }
7506
7507 if (!name.isEmpty())
7508 {
7509 // new enum type
7510 AUTO_TRACE_ADD("new enum {} at line {} of {}",name,root->bodyLine,root->fileName);
7511 auto md = createMemberDef(
7512 root->fileName,root->startLine,root->startColumn,
7513 QCString(),name,QCString(),QCString(),
7518 auto mmd = toMemberDefMutable(md.get());
7519 mmd->setTagInfo(root->tagInfo());
7520 mmd->setLanguage(root->lang);
7521 mmd->setId(root->id);
7522 if (!isGlobal) mmd->setMemberClass(cd); else mmd->setFileDef(fd);
7523 mmd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
7524 mmd->setBodyDef(root->fileDef());
7525 mmd->setMemberSpecifiers(root->spec);
7526 mmd->setVhdlSpecifiers(root->vhdlSpec);
7527 mmd->setEnumBaseType(root->args);
7528 //printf("Enum %s definition at line %d of %s: protection=%d scope=%s\n",
7529 // qPrint(root->name),root->bodyLine,qPrint(root->fileName),root->protection,cd?qPrint(cd->name()):"<none>");
7530 mmd->addSectionsToDefinition(root->anchors);
7531 mmd->setMemberGroupId(root->mGrpId);
7533 mmd->addQualifiers(root->qualifiers);
7534 //printf("%s::setRefItems(%zu)\n",qPrint(md->name()),root->sli.size());
7535 mmd->setRefItems(root->sli);
7536 //printf("found enum %s nd=%p\n",qPrint(md->name()),nd);
7537 bool defSet=FALSE;
7538
7539 QCString baseType = root->args;
7540 if (!baseType.isEmpty())
7541 {
7542 baseType.prepend(" : ");
7543 }
7544
7545 if (nd)
7546 {
7547 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES))
7548 {
7549 mmd->setDefinition(name+baseType);
7550 }
7551 else
7552 {
7553 mmd->setDefinition(nd->name()+"::"+name+baseType);
7554 }
7555 //printf("definition=%s\n",md->definition());
7556 defSet=TRUE;
7557 mmd->setNamespace(nd);
7558 nd->insertMember(md.get());
7559 }
7560
7561 // even if we have already added the enum to a namespace, we still
7562 // also want to add it to other appropriate places such as file
7563 // or class.
7564 if (isGlobal && (nd==nullptr || !nd->isAnonymous()))
7565 {
7566 if (!defSet) mmd->setDefinition(name+baseType);
7567 if (fd==nullptr && root->parent())
7568 {
7569 fd=root->parent()->fileDef();
7570 }
7571 if (fd)
7572 {
7573 mmd->setFileDef(fd);
7574 fd->insertMember(md.get());
7575 }
7576 }
7577 else if (cd)
7578 {
7579 if (isRelated || Config_getBool(HIDE_SCOPE_NAMES))
7580 {
7581 mmd->setDefinition(name+baseType);
7582 }
7583 else
7584 {
7585 mmd->setDefinition(cd->name()+"::"+name+baseType);
7586 }
7587 cd->insertMember(md.get());
7588 cd->insertUsedFile(fd);
7589 }
7590 mmd->setDocumentation(root->doc,root->docFile,root->docLine);
7591 mmd->setDocsForDefinition(!root->proto);
7592 mmd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
7593 mmd->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
7594
7595 //printf("Adding member=%s\n",qPrint(md->name()));
7596 addMemberToGroups(root,md.get());
7598
7599 MemberName *mn = mnsd->add(name);
7600 mn->push_back(std::move(md));
7601 }
7602 }
7603 else
7604 {
7605 for (const auto &e : root->children()) findEnums(e.get());
7606 }
7607}
static void findEnums(const Entry *root)
Definition doxygen.cpp:7440
@ Enumeration
Definition types.h:395

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

Referenced by findEnums(), and parseInput().

◆ findFriends()

static void findFriends ( )
static

Definition at line 4154 of file doxygen.cpp.

4155{
4156 AUTO_TRACE();
4157 for (const auto &fn : *Doxygen::functionNameLinkedMap) // for each global function name
4158 {
4159 MemberName *mn = Doxygen::memberNameLinkedMap->find(fn->memberName());
4160 if (mn)
4161 { // there are members with the same name
4162 // for each function with that name
4163 for (const auto &ifmd : *fn)
4164 {
4165 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
4166 // for each member with that name
4167 for (const auto &immd : *mn)
4168 {
4169 MemberDefMutable *mmd = toMemberDefMutable(immd.get());
4170 //printf("Checking for matching arguments
4171 // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n",
4172 // mmd->isRelated(),mmd->isFriend(),mmd->isFunction());
4173 if (fmd && mmd &&
4174 (mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) &&
4175 matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), &mmd->argumentList(),
4176 fmd->getOuterScope(), fmd->getFileDef(), &fmd->argumentList(),
4177 TRUE,mmd->getLanguage()
4178 )
4179
4180 ) // if the member is related and the arguments match then the
4181 // function is actually a friend.
4182 {
4183 AUTO_TRACE_ADD("Merging related global and member '{}' isFriend={} isRelated={} isFunction={}",
4184 mmd->name(),mmd->isFriend(),mmd->isRelated(),mmd->isFunction());
4185 const ArgumentList &mmdAl = mmd->argumentList();
4186 const ArgumentList &fmdAl = fmd->argumentList();
4187 mergeArguments(const_cast<ArgumentList&>(fmdAl),const_cast<ArgumentList&>(mmdAl));
4188
4189 // reset argument lists to add missing default parameters
4190 QCString mmdAlStr = argListToString(mmdAl);
4191 QCString fmdAlStr = argListToString(fmdAl);
4192 mmd->setArgsString(mmdAlStr);
4193 fmd->setArgsString(fmdAlStr);
4194 mmd->moveDeclArgumentList(std::make_unique<ArgumentList>(mmdAl));
4195 fmd->moveDeclArgumentList(std::make_unique<ArgumentList>(fmdAl));
4196 AUTO_TRACE_ADD("friend args='{}' member args='{}'",argListToString(fmd->argumentList()),argListToString(mmd->argumentList()));
4197
4198 if (!fmd->documentation().isEmpty())
4199 {
4200 mmd->setDocumentation(fmd->documentation(),fmd->docFile(),fmd->docLine());
4201 }
4202 else if (!mmd->documentation().isEmpty())
4203 {
4204 fmd->setDocumentation(mmd->documentation(),mmd->docFile(),mmd->docLine());
4205 }
4206 if (mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
4207 {
4208 mmd->setBriefDescription(fmd->briefDescription(),fmd->briefFile(),fmd->briefLine());
4209 }
4210 else if (!mmd->briefDescription().isEmpty() && !fmd->briefDescription().isEmpty())
4211 {
4212 fmd->setBriefDescription(mmd->briefDescription(),mmd->briefFile(),mmd->briefLine());
4213 }
4214 if (!fmd->inbodyDocumentation().isEmpty())
4215 {
4217 }
4218 else if (!mmd->inbodyDocumentation().isEmpty())
4219 {
4221 }
4222 //printf("body mmd %d fmd %d\n",mmd->getStartBodyLine(),fmd->getStartBodyLine());
4223 if (mmd->getStartBodyLine()==-1 && fmd->getStartBodyLine()!=-1)
4224 {
4225 mmd->setBodySegment(fmd->getDefLine(),fmd->getStartBodyLine(),fmd->getEndBodyLine());
4226 mmd->setBodyDef(fmd->getBodyDef());
4227 //mmd->setBodyMember(fmd);
4228 }
4229 else if (mmd->getStartBodyLine()!=-1 && fmd->getStartBodyLine()==-1)
4230 {
4231 fmd->setBodySegment(mmd->getDefLine(),mmd->getStartBodyLine(),mmd->getEndBodyLine());
4232 fmd->setBodyDef(mmd->getBodyDef());
4233 //fmd->setBodyMember(mmd);
4234 }
4236
4238
4239 mmd->addQualifiers(fmd->getQualifiers());
4240 fmd->addQualifiers(mmd->getQualifiers());
4241
4242 }
4243 }
4244 }
4245 }
4246 }
4247}
virtual bool isFriend() const =0
virtual bool isRelated() const =0
virtual StringVector getQualifiers() const =0
virtual bool isDocsForDefinition() const =0
void mergeMemberOverrideOptions(MemberDefMutable *md1, MemberDefMutable *md2)
Definition util.cpp:7189

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

Referenced by parseInput().

◆ findFunctionPtr()

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

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

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

Definition at line 2806 of file doxygen.cpp.

2807{
2808 AUTO_TRACE("type='{}' lang={}",type,lang);
2809 if (lang == SrcLangExt::Fortran || lang == SrcLangExt::VHDL)
2810 {
2811 return -1; // Fortran and VHDL do not have function pointers
2812 }
2813
2814 static const reg::Ex re(R"(\‍([^)]*[*&^][^)]*\))");
2816 size_t i=std::string::npos;
2817 size_t l=0;
2818 if (reg::search(type,match,re)) // contains (...*...) or (...&...) or (...^...)
2819 {
2820 i = match.position();
2821 l = match.length();
2822 }
2823 if (i!=std::string::npos)
2824 {
2825 size_t di = type.find("decltype(");
2826 if (di!=std::string::npos && di<i)
2827 {
2828 i = std::string::npos;
2829 }
2830 }
2831 size_t bb=type.find('<');
2832 size_t be=type.rfind('>');
2833 bool templFp = false;
2834 if (be!=std::string::npos) {
2835 size_t cc_ast = type.find("::*");
2836 size_t cc_amp = type.find("::&");
2837 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>::*)'
2838 }
2839
2840 if (!type.empty() && // return type is non-empty
2841 i!=std::string::npos && // contains (...*...)
2842 type.find("operator")==std::string::npos && // not an operator
2843 (type.find(")(")==std::string::npos || type.find("typedef ")!=std::string::npos) &&
2844 // not a function pointer return type
2845 (!(bb<i && i<be) || templFp) // bug665855: avoid treating "typedef A<void (T*)> type" as a function pointer
2846 )
2847 {
2848 if (pLength) *pLength=static_cast<int>(l);
2849 //printf("findFunctionPtr=%d\n",(int)i);
2850 AUTO_TRACE_EXIT("result={}",i);
2851 return static_cast<int>(i);
2852 }
2853 else
2854 {
2855 //printf("findFunctionPtr=%d\n",-1);
2856 AUTO_TRACE_EXIT("result=-1");
2857 return -1;
2858 }
2859}
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:48
@ Fortran
Definition types.h:53

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

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

◆ findGlobalMember()

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

Definition at line 5673 of file doxygen.cpp.

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

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

Referenced by findMember().

◆ findGroupScope()

static void findGroupScope ( const Entry * root)
static

Definition at line 433 of file doxygen.cpp.

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

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

Referenced by findGroupScope(), and parseInput().

◆ findIncludedUsingDirectives()

static void findIncludedUsingDirectives ( )
static

Definition at line 2387 of file doxygen.cpp.

2388{
2389 FileDefSet visitedFiles;
2390 // then recursively add using directives found in #include files
2391 // to files that have not been visited.
2392 for (const auto &fn : *Doxygen::inputNameLinkedMap)
2393 {
2394 for (const auto &fd : *fn)
2395 {
2396 //printf("----- adding using directives for file %s\n",qPrint(fd->name()));
2397 fd->addIncludedUsingDirectives(visitedFiles);
2398 }
2399 }
2400}
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 5203 of file doxygen.cpp.

5204{
5205 AUTO_TRACE();
5206 ClassDefSet visitedClasses;
5207 for (const auto &[name,root] : g_classEntries)
5208 {
5209 QCString bName = extractClassName(root);
5210 ClassDefMutable *cdm = getClassMutable(bName);
5211 if (cdm)
5212 {
5214 }
5215 }
5216}

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

Referenced by parseInput().

◆ findMainPage()

static void findMainPage ( Entry * root)
static

Definition at line 9606 of file doxygen.cpp.

9607{
9608 if (root->section.isMainpageDoc())
9609 {
9610 if (Doxygen::mainPage==nullptr && root->tagInfo()==nullptr)
9611 {
9612 //printf("mainpage: docLine=%d startLine=%d\n",root->docLine,root->startLine);
9613 //printf("Found main page! \n======\n%s\n=======\n",qPrint(root->doc));
9614 QCString title=root->args.stripWhiteSpace();
9615 if (title.isEmpty()) title = Config_getString(PROJECT_NAME);
9616 //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
9617 QCString indexName="index";
9619 indexName, root->brief+root->doc+root->inbodyDocs,title);
9620 //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
9621 Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
9622 Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1);
9623 Doxygen::mainPage->setFileName(indexName);
9624 Doxygen::mainPage->setLocalToc(root->localToc);
9626
9628 if (si)
9629 {
9630 if (!si->ref().isEmpty()) // we are from a tag file
9631 {
9632 // a page name is a label as well! but should no be double either
9634 Doxygen::mainPage->name(),
9635 indexName,
9636 root->startLine,
9637 Doxygen::mainPage->title(),
9639 0); // level 0
9640 }
9641 else if (si->lineNr() != -1)
9642 {
9643 warn(root->fileName,root->startLine,"multiple use of section label '%s' for main page, (first occurrence: %s, line %d)",
9644 qPrint(Doxygen::mainPage->name()),qPrint(si->fileName()),si->lineNr());
9645 }
9646 else
9647 {
9648 warn(root->fileName,root->startLine,"multiple use of section label '%s' for main page, (first occurrence: %s)",
9649 qPrint(Doxygen::mainPage->name()),qPrint(si->fileName()));
9650 }
9651 }
9652 else
9653 {
9654 // a page name is a label as well! but should no be double either
9656 Doxygen::mainPage->name(),
9657 indexName,
9658 root->startLine,
9659 Doxygen::mainPage->title(),
9661 0); // level 0
9662 }
9663 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9664 }
9665 else if (root->tagInfo()==nullptr)
9666 {
9667 warn(root->fileName,root->startLine,
9668 "found more than one \\mainpage comment block! (first occurrence: %s, line %d), Skipping current block!",
9669 qPrint(Doxygen::mainPage->docFile()),Doxygen::mainPage->getStartBodyLine());
9670 }
9671 }
9672 for (const auto &e : root->children()) findMainPage(e.get());
9673}
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:9606

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

9677{
9678 if (root->section.isMainpageDoc())
9679 {
9680 if (Doxygen::mainPage && root->tagInfo())
9681 {
9682 Doxygen::mainPage->addSectionsToDefinition(root->anchors);
9683 }
9684 }
9685 for (const auto &e : root->children()) findMainPageTagFiles(e.get());
9686}
static void findMainPageTagFiles(Entry *root)
Definition doxygen.cpp:9676

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

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

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

Referenced by filterMemberDocumentation(), and findObjCMethodDefinitions().

◆ findMemberDocumentation()

static void findMemberDocumentation ( const Entry * root)
static

Definition at line 7382 of file doxygen.cpp.

7383{
7384 if (root->section.isMemberDoc() ||
7385 root->section.isOverloadDoc() ||
7386 root->section.isFunction() ||
7387 root->section.isVariable() ||
7388 root->section.isVariableDoc() ||
7389 root->section.isDefine() ||
7390 root->section.isIncludedService() ||
7391 root->section.isExportedInterface()
7392 )
7393 {
7394 AUTO_TRACE();
7395 if (root->relatesType==RelatesType::Duplicate && !root->relates.isEmpty())
7396 {
7398 }
7400 }
7401 for (const auto &e : root->children())
7402 {
7403 if (!e->section.isEnum())
7404 {
7405 findMemberDocumentation(e.get());
7406 }
7407 }
7408}
static void findMemberDocumentation(const Entry *root)
Definition doxygen.cpp:7382
static void filterMemberDocumentation(const Entry *root, const QCString &relates)
Definition doxygen.cpp:7232

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

1245{
1246 if (root->section.isModuleDoc())
1247 {
1248 AUTO_TRACE();
1250 }
1251 for (const auto &e : root->children()) findModuleDocumentation(e.get());
1252}
void addDocs(const Entry *root)
static void findModuleDocumentation(const Entry *root)
Definition doxygen.cpp:1244

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

7413{
7414 AUTO_TRACE();
7415 for (const auto &objCImpl : root->children())
7416 {
7417 if (objCImpl->section.isObjcImpl())
7418 {
7419 for (const auto &objCMethod : objCImpl->children())
7420 {
7421 if (objCMethod->section.isFunction())
7422 {
7423 //Printf(" Found ObjC method definition %s\n",qPrint(objCMethod->name));
7424 findMember(objCMethod.get(),
7425 objCMethod->relates,
7426 objCMethod->type,
7427 objCMethod->args,
7428 objCMethod->type+" "+objCImpl->name+"::"+objCMethod->name+" "+objCMethod->args,
7429 FALSE,TRUE);
7430 objCMethod->section=EntryType::makeEmpty();
7431 }
7432 }
7433 }
7434 }
7435}

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

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

9219{
9220 // for each class
9221 for (const auto &cd : *Doxygen::classLinkedMap)
9222 {
9223 ClassDefMutable *cdm = toClassDefMutable(cd.get());
9224 if (cdm)
9225 {
9227 }
9228 }
9229 // for each concept
9230 for (const auto &cd : *Doxygen::conceptLinkedMap)
9231 {
9232 ConceptDefMutable *cdm = toConceptDefMutable(cd.get());
9233 if (cdm)
9234 {
9236 }
9237 }
9238 // for each file
9239 for (const auto &fn : *Doxygen::inputNameLinkedMap)
9240 {
9241 for (const auto &fd : *fn)
9242 {
9243 fd->findSectionsInDocumentation();
9244 }
9245 }
9246 // for each namespace
9247 for (const auto &nd : *Doxygen::namespaceLinkedMap)
9248 {
9250 if (ndm)
9251 {
9253 }
9254 }
9255 // for each group
9256 for (const auto &gd : *Doxygen::groupLinkedMap)
9257 {
9258 gd->findSectionsInDocumentation();
9259 }
9260 // for each page
9261 for (const auto &pd : *Doxygen::pageLinkedMap)
9262 {
9263 pd->findSectionsInDocumentation();
9264 }
9266 if (Doxygen::mainPage) Doxygen::mainPage->findSectionsInDocumentation();
9267}
virtual void findSectionsInDocumentation()=0
virtual void findSectionsInDocumentation()=0
void findSectionsInDocumentation()
virtual void findSectionsInDocumentation()=0

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

Referenced by parseInput().

◆ findTagLessClasses() [1/2]

static void findTagLessClasses ( )
static

Definition at line 1625 of file doxygen.cpp.

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

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

1609{
1610 for (const auto &icd : cd->getClasses())
1611 {
1612 if (icd->name().find("@")==-1) // process all non-anonymous inner classes
1613 {
1614 findTagLessClasses(candidates,icd);
1615 }
1616 }
1617
1619 if (cdm)
1620 {
1621 candidates.push_back(cdm);
1622 }
1623}

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

4695{
4696 AUTO_TRACE("Derived from template '{}' with parameters '{}' isArtificial={}",
4697 templateClass->name(),templSpec,isArtificial);
4698
4699 QCString tempArgsStr = tempArgListToString(templateClass->templateArguments(),root->lang,false);
4700 bool existingClass = templSpec==tempArgsStr;
4701 if (existingClass) return; // avoid recursion
4702
4703 bool freshInstance=FALSE;
4704 ClassDefMutable *instanceClass = toClassDefMutable(
4705 templateClass->insertTemplateInstance(
4706 root->fileName,root->startLine,root->startColumn,templSpec,freshInstance));
4707 if (instanceClass)
4708 {
4709 instanceClass->setArtificial(TRUE);
4710 instanceClass->setLanguage(root->lang);
4711
4712 if (freshInstance)
4713 {
4714 AUTO_TRACE_ADD("found fresh instance '{}'",instanceClass->name());
4715 instanceClass->setTemplateBaseClassNames(templateNames);
4716
4717 // search for new template instances caused by base classes of
4718 // instanceClass
4719 auto it_pair = g_classEntries.equal_range(templateClass->name().str());
4720 for (auto it=it_pair.first ; it!=it_pair.second ; ++it)
4721 {
4722 const Entry *templateRoot = it->second;
4723 AUTO_TRACE_ADD("template root found '{}' templSpec='{}'",templateRoot->name,templSpec);
4724 std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(root->lang,templSpec);
4725 findBaseClassesForClass(templateRoot,context,templateClass,instanceClass,
4726 TemplateInstances,isArtificial,templArgs.get(),templateNames);
4727
4728 findUsedClassesForClass(templateRoot,context,templateClass,instanceClass,
4729 isArtificial,templArgs.get(),templateNames);
4730 }
4731 }
4732 else
4733 {
4734 AUTO_TRACE_ADD("instance already exists");
4735 }
4736 }
4737}
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:4481

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(), and resolveTemplateInstanceInType().

◆ findTemplateSpecializationPosition()

static int findTemplateSpecializationPosition ( const QCString & name)
static

Definition at line 4783 of file doxygen.cpp.

4784{
4785 if (name.isEmpty()) return 0;
4786 int l = static_cast<int>(name.length());
4787 if (name[l-1]=='>') // search backward to find the matching <, allowing nested <...> and strings.
4788 {
4789 int count=1;
4790 int i=l-2;
4791 char insideQuote=0;
4792 while (count>0 && i>=0)
4793 {
4794 char c = name[i--];
4795 switch (c)
4796 {
4797 case '>': if (!insideQuote) count++; break;
4798 case '<': if (!insideQuote) count--; break;
4799 case '\'': if (!insideQuote) insideQuote=c;
4800 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4801 break;
4802 case '"': if (!insideQuote) insideQuote=c;
4803 else if (insideQuote==c && (i<0 || name[i]!='\\')) insideQuote=0;
4804 break;
4805 default: break;
4806 }
4807 }
4808 if (i>=0) l=i+1;
4809 }
4810 return l;
4811}

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

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

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

Referenced by findTemplateInstanceRelation(), and findUsedTemplateInstances().

◆ findUsedNamespace()

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

Definition at line 1816 of file doxygen.cpp.

1818{
1819 NamespaceDef *usingNd =nullptr;
1820 for (auto &und : unl)
1821 {
1822 QCString uScope=und->name()+"::";
1823 usingNd = getResolvedNamespace(uScope+name);
1824 if (usingNd!=nullptr) break;
1825 }
1826 return usingNd;
1827}

References getResolvedNamespace().

Referenced by findUsingDirectives().

◆ findUsedTemplateInstances()

static void findUsedTemplateInstances ( )
static

Definition at line 5234 of file doxygen.cpp.

5235{
5236 AUTO_TRACE();
5237 for (const auto &[name,root] : g_classEntries)
5238 {
5239 QCString bName = extractClassName(root);
5240 ClassDefMutable *cdm = getClassMutable(bName);
5241 if (cdm)
5242 {
5243 findUsedClassesForClass(root,cdm,cdm,cdm,TRUE);
5245 cdm->addTypeConstraints();
5246 }
5247 }
5248}
virtual void addTypeConstraints()=0
static void makeTemplateInstanceRelation(const Entry *root, ClassDefMutable *cd)
Definition doxygen.cpp:5218

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

Referenced by parseInput().

◆ findUsingDeclarations()

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

Definition at line 1984 of file doxygen.cpp.

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

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

Referenced by findUsingDeclarations(), and parseInput().

◆ findUsingDeclImports()

static void findUsingDeclImports ( const Entry * root)
static

Definition at line 2137 of file doxygen.cpp.

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

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

Referenced by findUsingDeclImports(), and parseInput().

◆ findUsingDirectives()

static void findUsingDirectives ( const Entry * root)
static

Definition at line 1829 of file doxygen.cpp.

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

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

Referenced by findUsingDirectives(), and parseInput().

◆ flushCachedTemplateRelations()

static void flushCachedTemplateRelations ( )
static

Definition at line 9272 of file doxygen.cpp.

9273{
9274 // remove all references to classes from the cache
9275 // as there can be new template instances in the inheritance path
9276 // to this class. Optimization: only remove those classes that
9277 // have inheritance instances as direct or indirect sub classes.
9278 StringVector elementsToRemove;
9279 for (const auto &ci : *Doxygen::typeLookupCache)
9280 {
9281 const LookupInfo &li = ci.second;
9282 if (li.definition)
9283 {
9284 elementsToRemove.push_back(ci.first);
9285 }
9286 }
9287 for (const auto &k : elementsToRemove)
9288 {
9289 Doxygen::typeLookupCache->remove(k);
9290 }
9291
9292 // remove all cached typedef resolutions whose target is a
9293 // template class as this may now be a template instance
9294 // for each global function name
9295 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9296 {
9297 // for each function with that name
9298 for (const auto &ifmd : *fn)
9299 {
9300 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9301 if (fmd && fmd->isTypedefValCached())
9302 {
9303 const ClassDef *cd = fmd->getCachedTypedefVal();
9304 if (cd->isTemplate()) fmd->invalidateTypedefValCache();
9305 }
9306 }
9307 }
9308 // for each class method name
9309 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9310 {
9311 // for each function with that name
9312 for (const auto &imd : *nm)
9313 {
9314 MemberDefMutable *md = toMemberDefMutable(imd.get());
9315 if (md && md->isTypedefValCached())
9316 {
9317 const ClassDef *cd = md->getCachedTypedefVal();
9318 if (cd->isTemplate()) md->invalidateTypedefValCache();
9319 }
9320 }
9321 }
9322}
virtual bool isTemplate() const =0
Returns TRUE if this class is a template.
static Cache< std::string, LookupInfo > * typeLookupCache
Definition doxygen.h:127
virtual const ClassDef * getCachedTypedefVal() const =0
virtual bool isTypedefValCached() const =0
virtual void invalidateTypedefValCache()=0
const Definition * definition
Definition doxygen.h:60

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

Referenced by parseInput().

◆ flushUnresolvedRelations()

static void flushUnresolvedRelations ( )
static

Definition at line 9326 of file doxygen.cpp.

9327{
9328 // Remove all unresolved references to classes from the cache.
9329 // This is needed before resolving the inheritance relations, since
9330 // it would otherwise not find the inheritance relation
9331 // for C in the example below, as B::I was already found to be unresolvable
9332 // (which is correct if you ignore the inheritance relation between A and B).
9333 //
9334 // class A { class I {} };
9335 // class B : public A {};
9336 // class C : public B::I {};
9337
9338 StringVector elementsToRemove;
9339 for (const auto &ci : *Doxygen::typeLookupCache)
9340 {
9341 const LookupInfo &li = ci.second;
9342 if (li.definition==nullptr && li.typeDef==nullptr)
9343 {
9344 elementsToRemove.push_back(ci.first);
9345 }
9346 }
9347 for (const auto &k : elementsToRemove)
9348 {
9349 Doxygen::typeLookupCache->remove(k);
9350 }
9351
9352 // for each global function name
9353 for (const auto &fn : *Doxygen::functionNameLinkedMap)
9354 {
9355 // for each function with that name
9356 for (const auto &ifmd : *fn)
9357 {
9358 MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9359 if (fmd)
9360 {
9362 }
9363 }
9364 }
9365 // for each class method name
9366 for (const auto &nm : *Doxygen::memberNameLinkedMap)
9367 {
9368 // for each function with that name
9369 for (const auto &imd : *nm)
9370 {
9371 MemberDefMutable *md = toMemberDefMutable(imd.get());
9372 if (md)
9373 {
9375 }
9376 }
9377 }
9378
9379}
virtual void invalidateCachedArgumentTypes()=0
const MemberDef * typeDef
Definition doxygen.h:61

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

Referenced by parseInput().

◆ g_pathsVisited()

static StringUnorderedSet g_pathsVisited ( 1009 )
static

Referenced by readDir(), and readFileOrDirectory().

◆ generateClassDocs()

static void generateClassDocs ( )
static

Definition at line 9035 of file doxygen.cpp.

9036{
9037 std::vector<ClassDefMutable*> classList;
9038 for (const auto &cdi : *Doxygen::classLinkedMap)
9039 {
9040 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9041 if (cd && (cd->getOuterScope()==nullptr ||
9043 {
9044 addClassAndNestedClasses(classList,cd);
9045 }
9046 }
9047 for (const auto &cdi : *Doxygen::hiddenClassLinkedMap)
9048 {
9049 ClassDefMutable *cd = toClassDefMutable(cdi.get());
9050 if (cd && (cd->getOuterScope()==nullptr ||
9052 {
9053 addClassAndNestedClasses(classList,cd);
9054 }
9055 }
9056 generateDocsForClassList(classList);
9057}
static void generateDocsForClassList(const std::vector< ClassDefMutable * > &classList)
Definition doxygen.cpp:8944

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

9062{
9063 for (const auto &cdi : *Doxygen::conceptLinkedMap)
9064 {
9066
9067 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
9068 if (cd &&
9069 (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9070 cd->getOuterScope()==Doxygen::globalScope // only look at global concepts
9071 ) && !cd->isHidden() && cd->isLinkableInProject()
9072 )
9073 {
9074 msg("Generating docs for concept %s...\n",qPrint(cd->displayName()));
9076 }
9077 }
9078}
virtual void writeDocumentation(OutputList &ol)=0
virtual bool isHidden() const =0
virtual QCString displayName(bool includeScope=TRUE) const =0

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

10252{
10253 std::ofstream f;
10254 bool fileOpened=openOutputFile(configFile,f);
10255 bool writeToStdout=configFile=="-";
10256 if (fileOpened)
10257 {
10258 TextStream t(&f);
10259 Config::writeTemplate(t,shortList,updateOnly);
10260 if (!writeToStdout)
10261 {
10262 if (!updateOnly)
10263 {
10264 msg("\n\nConfiguration file '%s' created.\n\n",qPrint(configFile));
10265 msg("Now edit the configuration file and enter\n\n");
10266 if (configFile!="Doxyfile" && configFile!="doxyfile")
10267 msg(" doxygen %s\n\n",qPrint(configFile));
10268 else
10269 msg(" doxygen\n\n");
10270 msg("to generate the documentation for your project\n\n");
10271 }
10272 else
10273 {
10274 msg("\n\nConfiguration file '%s' updated.\n\n",qPrint(configFile));
10275 }
10276 }
10277 }
10278 else
10279 {
10280 term("Cannot open file %s for writing\n",qPrint(configFile));
10281 }
10282}
void writeTemplate(TextStream &t, bool shortList, bool updateOnly=FALSE)

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

Referenced by readConfiguration().

◆ generateDiskNames()

static void generateDiskNames ( )
static

Definition at line 10504 of file doxygen.cpp.

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

References Doxygen::inputNameLinkedMap, prefix, and FileDef::setDiskName().

Referenced by parseInput().

◆ generateDocsForClassList()

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

Definition at line 8944 of file doxygen.cpp.

8945{
8946 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8947 if (numThreads>1) // multi threaded processing
8948 {
8949 struct DocContext
8950 {
8951 DocContext(ClassDefMutable *cd_,const OutputList &ol_)
8952 : cd(cd_), ol(ol_) {}
8953 ClassDefMutable *cd;
8954 OutputList ol;
8955 };
8956 ThreadPool threadPool(numThreads);
8957 std::vector< std::future< std::shared_ptr<DocContext> > > results;
8958 for (const auto &cd : classList)
8959 {
8960 //printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
8961 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
8962 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
8963 )
8964 {
8965 auto ctx = std::make_shared<DocContext>(cd,*g_outputList);
8966 auto processFile = [ctx]()
8967 {
8968 msg("Generating docs for compound %s...\n",qPrint(ctx->cd->displayName()));
8969
8970 // skip external references, anonymous compounds and
8971 // template instances
8972 if (!ctx->cd->isHidden() && !ctx->cd->isEmbeddedInOuterScope() &&
8973 ctx->cd->isLinkableInProject() && ctx->cd->templateMaster()==nullptr)
8974 {
8975 ctx->cd->writeDocumentation(ctx->ol);
8976 ctx->cd->writeMemberList(ctx->ol);
8977 }
8978
8979 // even for undocumented classes, the inner classes can be documented.
8980 ctx->cd->writeDocumentationForInnerClasses(ctx->ol);
8981 return ctx;
8982 };
8983 results.emplace_back(threadPool.queue(processFile));
8984 }
8985 }
8986 for (auto &f : results)
8987 {
8988 auto ctx = f.get();
8989 }
8990 }
8991 else // single threaded processing
8992 {
8993 for (const auto &cd : classList)
8994 {
8995 //printf("cd=%s getOuterScope=%p global=%p hidden=%d embeddedInOuterScope=%d\n",
8996 // qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope,cd->isHidden(),cd->isEmbeddedInOuterScope());
8997 if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
8998 cd->getOuterScope()==Doxygen::globalScope // only look at global classes
8999 )
9000 {
9001 // skip external references, anonymous compounds and
9002 // template instances
9003 if ( !cd->isHidden() && !cd->isEmbeddedInOuterScope() &&
9004 cd->isLinkableInProject() && cd->templateMaster()==nullptr)
9005 {
9006 msg("Generating docs for compound %s...\n",qPrint(cd->displayName()));
9007
9008 cd->writeDocumentation(*g_outputList);
9009 cd->writeMemberList(*g_outputList);
9010 }
9011 // even for undocumented classes, the inner classes can be documented.
9012 cd->writeDocumentationForInnerClasses(*g_outputList);
9013 }
9014 }
9015 }
9016}

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

Referenced by generateClassDocs().

◆ generateExampleDocs()

static void generateExampleDocs ( )
static

Definition at line 9954 of file doxygen.cpp.

9955{
9956 g_outputList->disable(OutputType::Man);
9957 for (const auto &pd : *Doxygen::exampleLinkedMap)
9958 {
9959 msg("Generating docs for example %s...\n",qPrint(pd->name()));
9961 if (lang != SrcLangExt::Unknown)
9962 {
9963 QCString ext = getFileNameExtension(pd->name());
9964 auto intf = Doxygen::parserManager->getCodeParser(ext);
9965 intf->resetCodeParserState();
9966 }
9967 QCString n=pd->getOutputFileBase();
9968 startFile(*g_outputList,n,n,pd->name());
9970 g_outputList->docify(pd->name());
9972 g_outputList->startContents();
9973 QCString lineNoOptStr;
9974 if (pd->showLineNo())
9975 {
9976 lineNoOptStr="{lineno}";
9977 }
9978 g_outputList->generateDoc(pd->docFile(), // file
9979 pd->docLine(), // startLine
9980 pd.get(), // context
9981 nullptr, // memberDef
9982 (pd->briefDescription().isEmpty()?"":pd->briefDescription()+"\n\n")+
9983 pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
9984 TRUE, // index words
9985 TRUE, // is example
9986 pd->name(),
9987 FALSE,
9988 FALSE,
9989 Config_getBool(MARKDOWN_SUPPORT)
9990 );
9991 endFile(*g_outputList); // contains g_outputList->endContents()
9992 }
9994}
void startTitle(OutputList &ol, const QCString &fileName, const DefinitionMutable *def)
Definition index.cpp:386
void endFile(OutputList &ol, bool skipNavIndex, bool skipEndContents, const QCString &navPath)
Definition index.cpp:421
void endTitle(OutputList &ol, const QCString &fileName, const QCString &name)
Definition index.cpp:395
void startFile(OutputList &ol, const QCString &name, const QCString &manName, const QCString &title, HighlightedItem hli, bool additionalIndices, const QCString &altSidebarName, int hierarchyLevel)
Definition index.cpp:402
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5549
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5591

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

Referenced by generateOutput().

◆ generateFileDocs()

static void generateFileDocs ( )
static

Definition at line 8616 of file doxygen.cpp.

8617{
8618 if (Index::instance().numDocumentedFiles()==0) return;
8619
8620 if (!Doxygen::inputNameLinkedMap->empty())
8621 {
8622 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8623 if (numThreads>1) // multi threaded processing
8624 {
8625 struct DocContext
8626 {
8627 DocContext(FileDef *fd_,const OutputList &ol_)
8628 : fd(fd_), ol(ol_) {}
8629 FileDef *fd;
8630 OutputList ol;
8631 };
8632 ThreadPool threadPool(numThreads);
8633 std::vector< std::future< std::shared_ptr<DocContext> > > results;
8634 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8635 {
8636 for (const auto &fd : *fn)
8637 {
8638 bool doc = fd->isLinkableInProject();
8639 if (doc)
8640 {
8641 auto ctx = std::make_shared<DocContext>(fd.get(),*g_outputList);
8642 auto processFile = [ctx]() {
8643 msg("Generating docs for file %s...\n",qPrint(ctx->fd->docName()));
8644 ctx->fd->writeDocumentation(ctx->ol);
8645 return ctx;
8646 };
8647 results.emplace_back(threadPool.queue(processFile));
8648 }
8649 }
8650 }
8651 for (auto &f : results)
8652 {
8653 auto ctx = f.get();
8654 }
8655 }
8656 else // single threaded processing
8657 {
8658 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8659 {
8660 for (const auto &fd : *fn)
8661 {
8662 bool doc = fd->isLinkableInProject();
8663 if (doc)
8664 {
8665 msg("Generating docs for file %s...\n",qPrint(fd->docName()));
8666 fd->writeDocumentation(*g_outputList);
8667 }
8668 }
8669 }
8670 }
8671 }
8672}

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

Referenced by generateOutput().

◆ generateFileSources()

static void generateFileSources ( )
static

Definition at line 8450 of file doxygen.cpp.

8451{
8452 auto processSourceFile = [](FileDef *fd,OutputList &ol,ClangTUParser *parser)
8453 {
8454 bool showSources = fd->generateSourceFile() && !Htags::useHtags; // sources need to be shown in the output
8455 bool parseSources = !fd->isReference() && Doxygen::parseSourcesNeeded; // we needed to parse the sources even if we do not show them
8456 if (showSources)
8457 {
8458 msg("Generating code for file %s...\n",qPrint(fd->docName()));
8459 fd->writeSourceHeader(ol);
8460 fd->writeSourceBody(ol,parser);
8461 fd->writeSourceFooter(ol);
8462 }
8463 else if (parseSources)
8464 {
8465 msg("Parsing code for file %s...\n",qPrint(fd->docName()));
8466 fd->parseSource(parser);
8467 }
8468 };
8469 if (!Doxygen::inputNameLinkedMap->empty())
8470 {
8471#if USE_LIBCLANG
8473 {
8474 StringUnorderedSet processedFiles;
8475
8476 // create a dictionary with files to process
8477 StringUnorderedSet filesToProcess;
8478
8479 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8480 {
8481 for (const auto &fd : *fn)
8482 {
8483 filesToProcess.insert(fd->absFilePath().str());
8484 }
8485 }
8486 // process source files (and their include dependencies)
8487 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8488 {
8489 for (const auto &fd : *fn)
8490 {
8491 if (fd->isSource() && !fd->isReference() && fd->getLanguage()==SrcLangExt::Cpp &&
8492 (fd->generateSourceFile() ||
8494 )
8495 )
8496 {
8497 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8498 clangParser->parse();
8499 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8500
8501 for (auto incFile : clangParser->filesInSameTU())
8502 {
8503 if (filesToProcess.find(incFile)!=filesToProcess.end() && // part of input
8504 fd->absFilePath()!=QCString(incFile) && // not same file
8505 processedFiles.find(incFile)==processedFiles.end()) // not yet marked as processed
8506 {
8507 StringVector moreFiles;
8508 bool ambig = false;
8509 FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile.c_str(),ambig);
8510 if (ifd && !ifd->isReference())
8511 {
8512 processSourceFile(ifd,*g_outputList,clangParser.get());
8513 processedFiles.insert(incFile);
8514 }
8515 }
8516 }
8517 processedFiles.insert(fd->absFilePath().str());
8518 }
8519 }
8520 }
8521 // process remaining files
8522 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8523 {
8524 for (const auto &fd : *fn)
8525 {
8526 if (processedFiles.find(fd->absFilePath().str())==processedFiles.end()) // not yet processed
8527 {
8528 if (fd->getLanguage()==SrcLangExt::Cpp) // C/C++ file, use clang parser
8529 {
8530 auto clangParser = ClangParser::instance()->createTUParser(fd.get());
8531 clangParser->parse();
8532 processSourceFile(fd.get(),*g_outputList,clangParser.get());
8533 }
8534 else // non C/C++ file, use built-in parser
8535 {
8536 processSourceFile(fd.get(),*g_outputList,nullptr);
8537 }
8538 }
8539 }
8540 }
8541 }
8542 else
8543#endif
8544 {
8545 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
8546 if (numThreads>1)
8547 {
8548 msg("Generating code files using %zu threads.\n",numThreads);
8549 struct SourceContext
8550 {
8551 SourceContext(FileDef *fd_,bool gen_,const OutputList &ol_)
8552 : fd(fd_), generateSourceFile(gen_), ol(ol_) {}
8553 FileDef *fd;
8554 bool generateSourceFile;
8555 OutputList ol;
8556 };
8557 ThreadPool threadPool(numThreads);
8558 std::vector< std::future< std::shared_ptr<SourceContext> > > results;
8559 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8560 {
8561 for (const auto &fd : *fn)
8562 {
8563 bool generateSourceFile = fd->generateSourceFile() && !Htags::useHtags;
8564 auto ctx = std::make_shared<SourceContext>(fd.get(),generateSourceFile,*g_outputList);
8565 auto processFile = [ctx]()
8566 {
8567 if (ctx->generateSourceFile)
8568 {
8569 msg("Generating code for file %s...\n",qPrint(ctx->fd->docName()));
8570 }
8571 else
8572 {
8573 msg("Parsing code for file %s...\n",qPrint(ctx->fd->docName()));
8574 }
8575 StringVector filesInSameTu;
8576 ctx->fd->getAllIncludeFilesRecursively(filesInSameTu);
8577 if (ctx->generateSourceFile) // sources need to be shown in the output
8578 {
8579 ctx->fd->writeSourceHeader(ctx->ol);
8580 ctx->fd->writeSourceBody(ctx->ol,nullptr);
8581 ctx->fd->writeSourceFooter(ctx->ol);
8582 }
8583 else if (!ctx->fd->isReference() && Doxygen::parseSourcesNeeded)
8584 // we needed to parse the sources even if we do not show them
8585 {
8586 ctx->fd->parseSource(nullptr);
8587 }
8588 return ctx;
8589 };
8590 results.emplace_back(threadPool.queue(processFile));
8591 }
8592 }
8593 for (auto &f : results)
8594 {
8595 auto ctx = f.get();
8596 }
8597 }
8598 else // single threaded version
8599 {
8600 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8601 {
8602 for (const auto &fd : *fn)
8603 {
8604 StringVector filesInSameTu;
8605 fd->getAllIncludeFilesRecursively(filesInSameTu);
8606 processSourceFile(fd.get(),*g_outputList,nullptr);
8607 }
8608 }
8609 }
8610 }
8611 }
8612}
std::unique_ptr< ClangTUParser > createTUParser(const FileDef *fd) const
static ClangParser * instance()
Returns the one and only instance of the class.
Clang parser object for a single translation unit, which consists of a source file and the directly o...
Definition clangparser.h:25
static bool clangAssistedParsing
Definition doxygen.h:138
virtual void writeSourceHeader(OutputList &ol)=0
virtual bool isSource() const =0
virtual void parseSource(ClangTUParser *clangParser)=0
virtual void getAllIncludeFilesRecursively(StringVector &incFiles) const =0
virtual void writeSourceFooter(OutputList &ol)=0
virtual void writeSourceBody(OutputList &ol, ClangTUParser *clangParser)=0
virtual const QCString & docName() const =0
Class representing a list of output generators that are written to in parallel.
Definition outputlist.h:314
std::unordered_set< std::string > StringUnorderedSet
Definition containers.h:29
static bool useHtags
Definition htags.h:23

References FileDef::absFilePath(), Doxygen::clangAssistedParsing, Config_getInt, Cpp, ClangParser::createTUParser(), FileDef::docName(), QCString::find(), findFileDef(), g_outputList, FileDef::generateSourceFile(), FileDef::getAllIncludeFilesRecursively(), Definition::getLanguage(), Doxygen::inputNameLinkedMap, ClangParser::instance(), Definition::isReference(), FileDef::isSource(), msg(), FileDef::parseSource(), Doxygen::parseSourcesNeeded, 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 9999 of file doxygen.cpp.

10000{
10001 for (const auto &gd : *Doxygen::groupLinkedMap)
10002 {
10003 if (!gd->isReference())
10004 {
10005 gd->writeDocumentation(*g_outputList);
10006 }
10007 }
10008}

References g_outputList, and Doxygen::groupLinkedMap.

Referenced by generateOutput().

◆ generateNamespaceClassDocs()

static void generateNamespaceClassDocs ( const ClassLinkedRefMap & classList)
static

Definition at line 10013 of file doxygen.cpp.

10014{
10015 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
10016 if (numThreads>1) // multi threaded processing
10017 {
10018 struct DocContext
10019 {
10020 DocContext(ClassDefMutable *cdm_,const OutputList &ol_)
10021 : cdm(cdm_), ol(ol_) {}
10022 ClassDefMutable *cdm;
10023 OutputList ol;
10024 };
10025 ThreadPool threadPool(numThreads);
10026 std::vector< std::future< std::shared_ptr<DocContext> > > results;
10027 // for each class in the namespace...
10028 for (const auto &cd : classList)
10029 {
10031 if (cdm)
10032 {
10033 auto ctx = std::make_shared<DocContext>(cdm,*g_outputList);
10034 auto processFile = [ctx]()
10035 {
10036 if ( ( ctx->cdm->isLinkableInProject() &&
10037 ctx->cdm->templateMaster()==nullptr
10038 ) // skip external references, anonymous compounds and
10039 // template instances and nested classes
10040 && !ctx->cdm->isHidden() && !ctx->cdm->isEmbeddedInOuterScope()
10041 )
10042 {
10043 msg("Generating docs for compound %s...\n",qPrint(ctx->cdm->displayName()));
10044 ctx->cdm->writeDocumentation(ctx->ol);
10045 ctx->cdm->writeMemberList(ctx->ol);
10046 }
10047 ctx->cdm->writeDocumentationForInnerClasses(ctx->ol);
10048 return ctx;
10049 };
10050 results.emplace_back(threadPool.queue(processFile));
10051 }
10052 }
10053 // wait for the results
10054 for (auto &f : results)
10055 {
10056 auto ctx = f.get();
10057 }
10058 }
10059 else // single threaded processing
10060 {
10061 // for each class in the namespace...
10062 for (const auto &cd : classList)
10063 {
10065 if (cdm)
10066 {
10067 if ( ( cd->isLinkableInProject() &&
10068 cd->templateMaster()==nullptr
10069 ) // skip external references, anonymous compounds and
10070 // template instances and nested classes
10071 && !cd->isHidden() && !cd->isEmbeddedInOuterScope()
10072 )
10073 {
10074 msg("Generating docs for compound %s...\n",qPrint(cd->displayName()));
10075
10078 }
10080 }
10081 }
10082 }
10083}
virtual void writeDocumentation(OutputList &ol) const =0
virtual void writeMemberList(OutputList &ol) const =0
virtual void writeDocumentationForInnerClasses(OutputList &ol) const =0

References Config_getInt, g_outputList, msg(), qPrint(), ThreadPool::queue(), toClassDefMutable(), ClassDef::writeDocumentation(), ClassDef::writeDocumentationForInnerClasses(), and ClassDef::writeMemberList().

Referenced by generateNamespaceDocs().

◆ generateNamespaceConceptDocs()

static void generateNamespaceConceptDocs ( const ConceptLinkedRefMap & conceptList)
static

Definition at line 10085 of file doxygen.cpp.

10086{
10087 // for each concept in the namespace...
10088 for (const auto &cd : conceptList)
10089 {
10091 if ( cdm && cd->isLinkableInProject() && !cd->isHidden())
10092 {
10093 msg("Generating docs for concept %s...\n",qPrint(cd->name()));
10095 }
10096 }
10097}

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

Referenced by generateNamespaceDocs().

◆ generateNamespaceDocs()

static void generateNamespaceDocs ( )
static

Definition at line 10099 of file doxygen.cpp.

10100{
10101 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
10102
10103 //writeNamespaceIndex(*g_outputList);
10104
10105 // for each namespace...
10106 for (const auto &nd : *Doxygen::namespaceLinkedMap)
10107 {
10108 if (nd->isLinkableInProject())
10109 {
10111 if (ndm)
10112 {
10113 msg("Generating docs for namespace %s\n",qPrint(nd->displayName()));
10115 }
10116 }
10117
10118 generateNamespaceClassDocs(nd->getClasses());
10119 if (sliceOpt)
10120 {
10121 generateNamespaceClassDocs(nd->getInterfaces());
10122 generateNamespaceClassDocs(nd->getStructs());
10123 generateNamespaceClassDocs(nd->getExceptions());
10124 }
10125 generateNamespaceConceptDocs(nd->getConcepts());
10126 }
10127}
virtual void writeDocumentation(OutputList &ol)=0
static void generateNamespaceConceptDocs(const ConceptLinkedRefMap &conceptList)
static void generateNamespaceClassDocs(const ClassLinkedRefMap &classList)

References Config_getBool, g_outputList, generateNamespaceClassDocs(), generateNamespaceConceptDocs(), msg(), Doxygen::namespaceLinkedMap, 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 13033 of file doxygen.cpp.

13034{
13035 AUTO_TRACE();
13036 /**************************************************************************
13037 * Initialize output generators *
13038 **************************************************************************/
13039
13040 /// add extra languages for which we can only produce syntax highlighted code
13042
13043 //// dump all symbols
13044 if (g_dumpSymbolMap)
13045 {
13046 dumpSymbolMap();
13047 exit(0);
13048 }
13049
13050 bool generateHtml = Config_getBool(GENERATE_HTML);
13051 bool generateLatex = Config_getBool(GENERATE_LATEX);
13052 bool generateMan = Config_getBool(GENERATE_MAN);
13053 bool generateRtf = Config_getBool(GENERATE_RTF);
13054 bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
13055
13056
13058 if (generateHtml)
13059 {
13063 }
13064 if (generateLatex)
13065 {
13068 }
13069 if (generateDocbook)
13070 {
13073 }
13074 if (generateMan)
13075 {
13076 g_outputList->add<ManGenerator>();
13078 }
13079 if (generateRtf)
13080 {
13081 g_outputList->add<RTFGenerator>();
13083 }
13084 if (Config_getBool(USE_HTAGS))
13085 {
13087 QCString htmldir = Config_getString(HTML_OUTPUT);
13088 if (!Htags::execute(htmldir))
13089 err("USE_HTAGS is YES but htags(1) failed. \n");
13090 else if (!Htags::loadFilemap(htmldir))
13091 err("htags(1) ended normally but failed to load the filemap. \n");
13092 }
13093
13094 /**************************************************************************
13095 * Generate documentation *
13096 **************************************************************************/
13097
13098 g_s.begin("Generating style sheet...\n");
13099 //printf("writing style info\n");
13100 g_outputList->writeStyleInfo(0); // write first part
13101 g_s.end();
13102
13103 bool searchEngine = Config_getBool(SEARCHENGINE);
13104 bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
13105
13106 g_s.begin("Generating search indices...\n");
13107 if (searchEngine && !serverBasedSearch && generateHtml)
13108 {
13110 }
13111
13112 // generate search indices (need to do this before writing other HTML
13113 // pages as these contain a drop down menu with options depending on
13114 // what categories we find in this function.
13115 if (generateHtml && searchEngine)
13116 {
13117 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
13118 Dir searchDir(searchDirName.str());
13119 if (!searchDir.exists() && !searchDir.mkdir(searchDirName.str()))
13120 {
13121 term("Could not create search results directory '%s' $PWD='%s'\n",
13122 qPrint(searchDirName),Dir::currentDirPath().c_str());
13123 }
13124 HtmlGenerator::writeSearchData(searchDirName);
13125 if (!serverBasedSearch) // client side search index
13126 {
13128 }
13129 }
13130 g_s.end();
13131
13132 // copy static stuff
13133 if (generateHtml)
13134 {
13137 copyLogo(Config_getString(HTML_OUTPUT));
13138 copyIcon(Config_getString(HTML_OUTPUT));
13139 copyExtraFiles(Config_getList(HTML_EXTRA_FILES),"HTML_EXTRA_FILES",Config_getString(HTML_OUTPUT));
13140 }
13141 if (generateLatex)
13142 {
13144 copyLogo(Config_getString(LATEX_OUTPUT));
13145 copyIcon(Config_getString(LATEX_OUTPUT));
13146 copyExtraFiles(Config_getList(LATEX_EXTRA_FILES),"LATEX_EXTRA_FILES",Config_getString(LATEX_OUTPUT));
13147 }
13148 if (generateDocbook)
13149 {
13150 copyLogo(Config_getString(DOCBOOK_OUTPUT));
13151 copyIcon(Config_getString(DOCBOOK_OUTPUT));
13152 }
13153 if (generateRtf)
13154 {
13155 copyLogo(Config_getString(RTF_OUTPUT));
13156 copyIcon(Config_getString(RTF_OUTPUT));
13157 copyExtraFiles(Config_getList(RTF_EXTRA_FILES),"RTF_EXTRA_FILES",Config_getString(RTF_OUTPUT));
13158 }
13159
13161 if (fm.hasFormulas() && generateHtml
13162 && !Config_getBool(USE_MATHJAX))
13163 {
13164 g_s.begin("Generating images for formulas in HTML...\n");
13165 fm.generateImages(Config_getString(HTML_OUTPUT), Config_getEnum(HTML_FORMULA_FORMAT)==HTML_FORMULA_FORMAT_t::svg ?
13167 g_s.end();
13168 }
13169 if (fm.hasFormulas() && generateRtf)
13170 {
13171 g_s.begin("Generating images for formulas in RTF...\n");
13173 g_s.end();
13174 }
13175
13176 if (fm.hasFormulas() && generateDocbook)
13177 {
13178 g_s.begin("Generating images for formulas in Docbook...\n");
13180 g_s.end();
13181 }
13182
13183 g_s.begin("Generating example documentation...\n");
13185 g_s.end();
13186
13187 g_s.begin("Generating file sources...\n");
13189 g_s.end();
13190
13191 g_s.begin("Generating file documentation...\n");
13193 g_s.end();
13194
13195 g_s.begin("Generating page documentation...\n");
13197 g_s.end();
13198
13199 g_s.begin("Generating group documentation...\n");
13201 g_s.end();
13202
13203 g_s.begin("Generating class documentation...\n");
13205 g_s.end();
13206
13207 g_s.begin("Generating concept documentation...\n");
13209 g_s.end();
13210
13211 g_s.begin("Generating module documentation...\n");
13213 g_s.end();
13214
13215 g_s.begin("Generating namespace documentation...\n");
13217 g_s.end();
13218
13219 if (Config_getBool(GENERATE_LEGEND))
13220 {
13221 g_s.begin("Generating graph info page...\n");
13223 g_s.end();
13224 }
13225
13226 g_s.begin("Generating directory documentation...\n");
13228 g_s.end();
13229
13230 if (g_outputList->size()>0)
13231 {
13233 }
13234
13235 g_s.begin("finalizing index lists...\n");
13236 Doxygen::indexList->finalize();
13237 g_s.end();
13238
13239 g_s.begin("writing tag file...\n");
13240 writeTagFile();
13241 g_s.end();
13242
13243 if (Config_getBool(GENERATE_XML))
13244 {
13245 g_s.begin("Generating XML output...\n");
13247 generateXML();
13249 g_s.end();
13250 }
13251 if (Config_getBool(GENERATE_SQLITE3))
13252 {
13253 g_s.begin("Generating SQLITE3 output...\n");
13255 g_s.end();
13256 }
13257
13258 if (Config_getBool(GENERATE_AUTOGEN_DEF))
13259 {
13260 g_s.begin("Generating AutoGen DEF output...\n");
13261 generateDEF();
13262 g_s.end();
13263 }
13264 if (Config_getBool(GENERATE_PERLMOD))
13265 {
13266 g_s.begin("Generating Perl module output...\n");
13268 g_s.end();
13269 }
13270 if (generateHtml && searchEngine && serverBasedSearch)
13271 {
13272 g_s.begin("Generating search index\n");
13273 if (Doxygen::searchIndex.kind()==SearchIndexIntf::Internal) // write own search index
13274 {
13276 Doxygen::searchIndex.write(Config_getString(HTML_OUTPUT)+"/search/search.idx");
13277 }
13278 else // write data for external search index
13279 {
13281 QCString searchDataFile = Config_getString(SEARCHDATA_FILE);
13282 if (searchDataFile.isEmpty())
13283 {
13284 searchDataFile="searchdata.xml";
13285 }
13286 if (!Portable::isAbsolutePath(searchDataFile.data()))
13287 {
13288 searchDataFile.prepend(Config_getString(OUTPUT_DIRECTORY)+"/");
13289 }
13290 Doxygen::searchIndex.write(searchDataFile);
13291 }
13292 g_s.end();
13293 }
13294
13295 if (generateRtf)
13296 {
13297 g_s.begin("Combining RTF output...\n");
13298 if (!RTFGenerator::preProcessFileInplace(Config_getString(RTF_OUTPUT),"refman.rtf"))
13299 {
13300 err("An error occurred during post-processing the RTF files!\n");
13301 }
13302 g_s.end();
13303 }
13304
13305 g_s.begin("Running plantuml with JAVA...\n");
13307 g_s.end();
13308
13309 if (Config_getBool(HAVE_DOT))
13310 {
13311 g_s.begin("Running dot...\n");
13313 g_s.end();
13314 }
13315
13316 if (generateHtml &&
13317 Config_getBool(GENERATE_HTMLHELP) &&
13318 !Config_getString(HHC_LOCATION).isEmpty())
13319 {
13320 g_s.begin("Running html help compiler...\n");
13322 g_s.end();
13323 }
13324
13325 if ( generateHtml &&
13326 Config_getBool(GENERATE_QHP) &&
13327 !Config_getString(QHG_LOCATION).isEmpty())
13328 {
13329 g_s.begin("Running qhelpgenerator...\n");
13331 g_s.end();
13332 }
13333
13334 g_outputList->cleanup();
13335
13336 msg("type lookup cache used %zu/%zu hits=%" PRIu64 " misses=%" PRIu64 "\n",
13338 Doxygen::typeLookupCache->capacity(),
13340 Doxygen::typeLookupCache->misses());
13341 msg("symbol lookup cache used %zu/%zu hits=%" PRIu64 " misses=%" PRIu64 "\n",
13343 Doxygen::symbolLookupCache->capacity(),
13345 Doxygen::symbolLookupCache->misses());
13346 int typeCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::typeLookupCache->misses()*2/3)); // part of the cache is flushed, hence the 2/3 correction factor
13347 int symbolCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::symbolLookupCache->misses()));
13348 int cacheParam = std::max(typeCacheParam,symbolCacheParam);
13349 if (cacheParam>Config_getInt(LOOKUP_CACHE_SIZE))
13350 {
13351 msg("Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is %d at the cost of higher memory usage.\n",cacheParam);
13352 }
13353
13355 {
13356
13357 std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
13358 if (numThreads<1) numThreads=1;
13359 msg("Total elapsed time: %.6f seconds\n(of which an average of %.6f seconds per thread waiting for external tools to finish)\n",
13360 (static_cast<double>(Debug::elapsedTime())),
13361 Portable::getSysElapsedTime()/static_cast<double>(numThreads)
13362 );
13363 g_s.print();
13364
13366 msg("finished...\n");
13368 }
13369 else
13370 {
13371 msg("finished...\n");
13372 }
13373
13374
13375 /**************************************************************************
13376 * Start cleaning up *
13377 **************************************************************************/
13378
13380
13382 Dir thisDir;
13383 thisDir.remove(Doxygen::filterDBFileName.str());
13385 exitTracing();
13387 delete Doxygen::clangUsrMap;
13389
13390 //dumpDocNodeSizes();
13391}
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:135
static double elapsedTime()
Definition debug.cpp:204
static void setFlag(const DebugMask mask)
Definition debug.cpp:120
static std::string currentDirPath()
Definition dir.cpp:340
static void init()
bool run()
Definition dot.cpp:128
static DotManager * instance()
Definition dot.cpp:78
static Cache< std::string, LookupInfo > * symbolLookupCache
Definition doxygen.h:128
static bool generatingXmlOutput
Definition doxygen.h:136
static ClangUsrMap * clangUsrMap
Definition doxygen.h:126
static void generateTreeViewImages()
Definition ftvhelp.cpp:851
bool hasFormulas() const
Definition formula.cpp:720
void generateImages(const QCString &outputDir, Format format, HighDPI hd=HighDPI::Off)
Definition formula.cpp:636
Generator for HTML output.
Definition htmlgen.h:95
static void init()
Definition htmlgen.cpp:1135
static void writeSearchPage()
Definition htmlgen.cpp:3071
static void writeTabData()
Additional initialization after indices have been created.
Definition htmlgen.cpp:1291
static void writeSearchData(const QCString &dir)
Definition htmlgen.cpp:1329
static void writeExternalSearchPage()
Definition htmlgen.cpp:3162
Generator for LaTeX output.
Definition latexgen.h:94
static void init()
Definition latexgen.cpp:628
Generator for Man page output.
Definition mangen.h:69
static void init()
Definition mangen.cpp:272
void writeDocumentation(OutputList &ol)
static PlantumlManager & instance()
Definition plantuml.cpp:156
void run()
Run plant UML tool for all images.
Definition plantuml.cpp:314
Generator for RTF output.
Definition rtfgen.h:80
static void init()
Definition rtfgen.cpp:458
static bool preProcessFileInplace(const QCString &path, const QCString &name)
This is an API to a VERY brittle RTF preprocessor that combines nested RTF files.
Definition rtfgen.cpp:2457
void generateDEF()
Definition defgen.cpp:525
void generateDirDocs(OutputList &ol)
Definition dirdef.cpp:1146
static void copyLatexStyleSheet()
static void runQHelpGenerator()
class Statistics g_s
static void copyStyleSheet()
static void generateGroupDocs()
Definition doxygen.cpp:9999
static void generateExampleDocs()
Definition doxygen.cpp:9954
static void dumpSymbolMap()
static void generateFileDocs()
Definition doxygen.cpp:8616
static void copyIcon(const QCString &outputOption)
static void generatePageDocs()
Definition doxygen.cpp:9806
static void generateFileSources()
Definition doxygen.cpp:8450
static void copyLogo(const QCString &outputOption)
static void generateClassDocs()
Definition doxygen.cpp:9035
static int computeIdealCacheParam(size_t v)
static void copyExtraFiles(const StringVector &files, const QCString &filesOption, const QCString &outputOption)
static void runHtmlHelpCompiler()
static bool g_dumpSymbolMap
Definition doxygen.cpp:184
static void generateNamespaceDocs()
static void writeTagFile()
void cleanUpDoxygen()
static void generateConceptDocs()
Definition doxygen.cpp:9061
void writeGraphInfo(OutputList &ol)
Definition index.cpp:3946
void writeIndexHierarchy(OutputList &ol)
Definition index.cpp:5587
void finishWarnExit()
Definition message.cpp:310
void deinit()
bool isAbsolutePath(const QCString &fileName)
Definition portable.cpp:514
double getSysElapsedTime()
Definition portable.cpp:98
void generatePerlMod()
void finalizeSearchIndexer()
void createJavaScriptSearchIndex()
void writeJavaScriptSearchIndex()
void generateSqlite3()
static bool execute(const QCString &htmldir)
Definition htags.cpp:38
static bool loadFilemap(const QCString &htmldir)
Definition htags.cpp:107
void exitTracing()
Definition trace.cpp:52
void addCodeOnlyMappings()
Definition util.cpp:5543
void generateXML()
Definition xmlgen.cpp:2178

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

Referenced by main().

◆ generatePageDocs()

static void generatePageDocs ( )
static

Definition at line 9806 of file doxygen.cpp.

9807{
9808 //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageLinkedMap->count());
9809 if (Index::instance().numDocumentedPages()==0) return;
9810 for (const auto &pd : *Doxygen::pageLinkedMap)
9811 {
9812 if (!pd->getGroupDef() && !pd->isReference())
9813 {
9814 msg("Generating docs for page %s...\n",qPrint(pd->name()));
9815 pd->writeDocumentation(*g_outputList);
9816 }
9817 }
9818}

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

Referenced by generateOutput().

◆ generateXRefPages()

static void generateXRefPages ( )
static

Definition at line 5471 of file doxygen.cpp.

5472{
5473 AUTO_TRACE();
5475 {
5476 rl->generatePage();
5477 }
5478}
std::unique_ptr< RefList > Ptr
Definition linkedmap.h:38
static RefListManager & instance()
Definition reflist.h:121

References AUTO_TRACE, and RefListManager::instance().

Referenced by parseInput().

◆ getArg()

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

Definition at line 11290 of file doxygen.cpp.

11291{
11292 char *s=nullptr;
11293 if (qstrlen(&argv[optInd][2])>0)
11294 s=&argv[optInd][2];
11295 else if (optInd+1<argc && argv[optInd+1][0]!='-')
11296 s=argv[++optInd];
11297 return s;
11298}
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 10581 of file doxygen.cpp.

10582{
10583 QCString fileName=fn;
10584 QCString extension;
10585 int sep = fileName.findRev('/');
10586 int ei = fileName.findRev('.');
10587 if (ei!=-1 && (sep==-1 || ei>sep)) // matches dir/file.ext but not dir.1/file
10588 {
10589 extension=fileName.right(fileName.length()-ei);
10590 }
10591 else
10592 {
10593 extension = ".no_extension";
10594 }
10595
10596 return Doxygen::parserManager->getOutlineParser(extension);
10597}

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

Referenced by parseFilesMultiThreading(), and parseFilesSingleThreading().

◆ getTemplateArgumentsFromName()

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

Definition at line 852 of file doxygen.cpp.

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

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

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

◆ getTemplateArgumentsInName()

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

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

Definition at line 4418 of file doxygen.cpp.

4419{
4420 std::map<std::string,int> templateNames;
4421 int count=0;
4422 for (const Argument &arg : templateArguments)
4423 {
4424 static const reg::Ex re(R"(\a[\w:]*)");
4425 reg::Iterator it(name,re);
4427 for (; it!=end ; ++it)
4428 {
4429 const auto &match = *it;
4430 std::string n = match.str();
4431 if (n==arg.name.str())
4432 {
4433 if (templateNames.find(n)==templateNames.end())
4434 {
4435 templateNames.emplace(n,count);
4436 }
4437 }
4438 }
4439 }
4440 return templateNames;
4441}

References end().

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

◆ haveEqualFileNames()

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

Definition at line 9385 of file doxygen.cpp.

9386{
9387 const FileDef *fd = md->getFileDef();
9388 if (!fd)
9389 {
9390 return FALSE;
9391 }
9392
9393 return fd->absFilePath() == root->fileName;
9394}

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

Referenced by findDefineDocumentation().

◆ inheritDocumentation()

static void inheritDocumentation ( )
static

Definition at line 9082 of file doxygen.cpp.

9083{
9084 for (const auto &mn : *Doxygen::memberNameLinkedMap)
9085 {
9086 for (const auto &imd : *mn)
9087 {
9088 MemberDefMutable *md = toMemberDefMutable(imd.get());
9089 //static int count=0;
9090 //printf("%04d Member '%s'\n",count++,qPrint(md->qualifiedName()));
9091 if (md && md->documentation().isEmpty() && md->briefDescription().isEmpty())
9092 { // no documentation yet
9093 const MemberDef *bmd = md->reimplements();
9094 while (bmd && bmd->documentation().isEmpty() &&
9095 bmd->briefDescription().isEmpty()
9096 )
9097 { // search up the inheritance tree for a documentation member
9098 //printf("bmd=%s class=%s\n",qPrint(bmd->name()),qPrint(bmd->getClassDef()->name()));
9099 bmd = bmd->reimplements();
9100 }
9101 if (bmd) // copy the documentation from the reimplemented member
9102 {
9103 md->setInheritsDocsFrom(bmd);
9104 md->setDocumentation(bmd->documentation(),bmd->docFile(),bmd->docLine());
9106 md->setBriefDescription(bmd->briefDescription(),bmd->briefFile(),bmd->briefLine());
9107 md->copyArgumentNames(bmd);
9109 }
9110 }
9111 }
9112 }
9113}
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 11317 of file doxygen.cpp.

11318{
11319 initResources();
11320 QCString lang = Portable::getenv("LC_ALL");
11321 if (!lang.isEmpty()) Portable::setenv("LANG",lang);
11322 std::setlocale(LC_ALL,"");
11323 std::setlocale(LC_CTYPE,"C"); // to get isspace(0xA0)==0, needed for UTF-8
11324 std::setlocale(LC_NUMERIC,"C");
11325
11327
11351
11352 // register any additional parsers here...
11353
11355
11356#if USE_LIBCLANG
11358#endif
11367 Doxygen::pageLinkedMap = new PageLinkedMap; // all doc pages
11368 Doxygen::exampleLinkedMap = new PageLinkedMap; // all examples
11369 //Doxygen::tagDestinationDict.setAutoDelete(TRUE);
11371
11372 // initialization of these globals depends on
11373 // configuration switches so we need to postpone these
11374 Doxygen::globalScope = nullptr;
11383
11384}
static void startTimer()
Definition debug.cpp:199
A linked map of directories.
Definition dirdef.h:172
A list of index interfaces.
Definition indexlist.h:63
Manages programming language parsers.
Definition parserintf.h:147
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:83
void setenv(const QCString &variable, const QCString &value)
Definition portable.cpp:303
QCString getenv(const QCString &variable)
Definition portable.cpp:338
void initDefaultExtensionMapping()
Definition util.cpp:5476

References Doxygen::clangUsrMap, Doxygen::classLinkedMap, Doxygen::conceptLinkedMap, Doxygen::diaFileNameLinkedMap, Doxygen::dirLinkedMap, Doxygen::dotFileNameLinkedMap, Doxygen::exampleLinkedMap, Doxygen::exampleNameLinkedMap, Doxygen::functionNameLinkedMap, Portable::getenv(), Doxygen::globalScope, Doxygen::groupLinkedMap, Doxygen::hiddenClassLinkedMap, Doxygen::imageNameLinkedMap, Doxygen::includeNameLinkedMap, Doxygen::indexList, initDefaultExtensionMapping(), initResources(), Doxygen::inputNameLinkedMap, QCString::isEmpty(), make_parser_factory(), Doxygen::memberNameLinkedMap, Doxygen::mscFileNameLinkedMap, Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, Doxygen::parserManager, Doxygen::plantUmlFileNameLinkedMap, Portable::setenv(), Debug::startTimer(), and Doxygen::symbolMap.

Referenced by main().

◆ initResources()

void initResources ( )
extern

Referenced by initDoxygen().

◆ insertMemberAlias()

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

Definition at line 6561 of file doxygen.cpp.

6562{
6563 if (outerScope && outerScope!=Doxygen::globalScope)
6564 {
6565 auto aliasMd = createMemberDefAlias(outerScope,md);
6566 if (outerScope->definitionType()==Definition::TypeClass)
6567 {
6568 ClassDefMutable *cdm = toClassDefMutable(outerScope);
6569 if (cdm)
6570 {
6571 cdm->insertMember(aliasMd.get());
6572 }
6573 }
6574 else if (outerScope->definitionType()==Definition::TypeNamespace)
6575 {
6576 NamespaceDefMutable *ndm = toNamespaceDefMutable(outerScope);
6577 if (ndm)
6578 {
6579 ndm->insertMember(aliasMd.get());
6580 }
6581 }
6582 else if (outerScope->definitionType()==Definition::TypeFile)
6583 {
6584 toFileDef(outerScope)->insertMember(aliasMd.get());
6585 }
6586 if (aliasMd)
6587 {
6588 Doxygen::functionNameLinkedMap->add(md->name())->push_back(std::move(aliasMd));
6589 }
6590 }
6591}
FileDef * toFileDef(Definition *d)
Definition filedef.cpp:1894

References createMemberDefAlias(), Definition::definitionType(), Doxygen::functionNameLinkedMap, Doxygen::globalScope, ClassDefMutable::insertMember(), FileDef::insertMember(), NamespaceDefMutable::insertMember(), Definition::name(), toClassDefMutable(), toFileDef(), toNamespaceDefMutable(), Definition::TypeClass, Definition::TypeFile, and Definition::TypeNamespace.

Referenced by findMember().

◆ isClassSection()

static bool isClassSection ( const Entry * root)
static

Definition at line 5151 of file doxygen.cpp.

5152{
5153 if ( !root->name.isEmpty() )
5154 {
5155 if (root->section.isCompound())
5156 // is it a compound (class, struct, union, interface ...)
5157 {
5158 return TRUE;
5159 }
5160 else if (root->section.isCompoundDoc())
5161 // is it a documentation block with inheritance info.
5162 {
5163 bool hasExtends = !root->extends.empty();
5164 if (hasExtends) return TRUE;
5165 }
5166 }
5167 return FALSE;
5168}

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

5650{
5651 const GroupDef *gd = md->getGroupDef();
5652 if (!gd)
5653 {
5654 return allowNoGroup;
5655 }
5656
5657 for (const auto &g : root->groups)
5658 {
5659 if (g.groupname == gd->name())
5660 {
5661 return true; // matching group
5662 }
5663 }
5664
5665 return false;
5666}

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

4772{
4773 QCString n=name;
4774 int index=n.find('<');
4775 if (index!=-1)
4776 {
4777 n=n.left(index);
4778 }
4779 bool result = rightScopeMatch(scope,n);
4780 return result;
4781}

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

Referenced by findClassRelation().

◆ isSpecialization()

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

Definition at line 5881 of file doxygen.cpp.

5885{
5886 auto srcIt = srcTempArgLists.begin();
5887 auto dstIt = dstTempArgLists.begin();
5888 while (srcIt!=srcTempArgLists.end() && dstIt!=dstTempArgLists.end())
5889 {
5890 if ((*srcIt).size()!=(*dstIt).size()) return TRUE;
5891 ++srcIt;
5892 ++dstIt;
5893 }
5894 return FALSE;
5895}

References FALSE, and TRUE.

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

◆ isSymbolHidden()

static bool isSymbolHidden ( const Definition * d)
static

Definition at line 8836 of file doxygen.cpp.

8837{
8838 bool hidden = d->isHidden();
8839 const Definition *parent = d->getOuterScope();
8840 return parent ? hidden || isSymbolHidden(parent) : hidden;
8841}
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Definition docnode.h:1324

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

Referenced by computeTooltipTexts(), and isSymbolHidden().

◆ isVarWithConstructor()

static bool isVarWithConstructor ( const Entry * root)
static

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

Definition at line 2866 of file doxygen.cpp.

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

References Entry::argList, QCString::at(), AUTO_TRACE, AUTO_TRACE_EXIT, checkIfTypedef(), Argument::defval, ArgumentList::empty(), QCString::endsWith(), FALSE, Entry::fileDef(), QCString::find(), findAndRemoveWord(), EntryType::isCompound(), QCString::isEmpty(), QCString::left(), QCString::length(), Argument::name, Definition::name(), Entry::name, Doxygen::namespaceLinkedMap, Entry::parent(), SymbolResolver::resolveClass(), resolveTypeDef(), reg::search(), Entry::section, QCString::str(), TRUE, Argument::type, and Entry::type.

Referenced by buildVarList().

◆ make_parser_factory()

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

Definition at line 11312 of file doxygen.cpp.

11313{
11314 return []() { return std::make_unique<T>(); };
11315}

Referenced by initDoxygen().

◆ makeTemplateInstanceRelation()

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

Definition at line 5218 of file doxygen.cpp.

5219{
5220 AUTO_TRACE("root->name={} cd={}",root->name,cd->name());
5221 int i = root->name.find('<');
5222 if (i!=-1)
5223 {
5224 ClassDefMutable *master = getClassMutable(root->name.left(i));
5225 if (master && master!=cd && !cd->templateMaster())
5226 {
5227 AUTO_TRACE_ADD("class={} master={}",cd->name(),cd->templateMaster()?cd->templateMaster()->name():"<none>",master->name());
5228 cd->setTemplateMaster(master);
5229 master->insertExplicitTemplateInstance(cd,root->name.mid(i));
5230 }
5231 }
5232}
virtual void insertExplicitTemplateInstance(ClassDef *instance, const QCString &spec)=0
virtual void setTemplateMaster(const ClassDef *tm)=0

References AUTO_TRACE, AUTO_TRACE_ADD, QCString::find(), getClassMutable(), ClassDefMutable::insertExplicitTemplateInstance(), QCString::left(), QCString::mid(), Definition::name(), Entry::name, ClassDefMutable::setTemplateMaster(), and ClassDef::templateMaster().

Referenced by findUsedTemplateInstances().

◆ mergeCategories()

static void mergeCategories ( )
static

Definition at line 8398 of file doxygen.cpp.

8399{
8400 AUTO_TRACE();
8401 // merge members of categories into the class they extend
8402 for (const auto &cd : *Doxygen::classLinkedMap)
8403 {
8404 int i=cd->name().find('(');
8405 if (i!=-1) // it is an Objective-C category
8406 {
8407 QCString baseName=cd->name().left(i);
8408 ClassDefMutable *baseClass=toClassDefMutable(Doxygen::classLinkedMap->find(baseName));
8409 if (baseClass)
8410 {
8411 AUTO_TRACE_ADD("merging members of category {} into {}",cd->name(),baseClass->name());
8412 baseClass->mergeCategory(cd.get());
8413 }
8414 }
8415 }
8416}
virtual void mergeCategory(ClassDef *category)=0

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

Referenced by parseInput().

◆ organizeSubGroups()

static void organizeSubGroups ( const Entry * root)
static

Definition at line 477 of file doxygen.cpp.

478{
479 //printf("Defining groups\n");
480 // first process the @defgroups blocks
482 //printf("Additional groups\n");
483 // then process the @addtogroup, @weakgroup blocks
485}
static void organizeSubGroupsFiltered(const Entry *root, bool additional)
Definition doxygen.cpp:458

References FALSE, organizeSubGroupsFiltered(), and TRUE.

Referenced by parseInput().

◆ organizeSubGroupsFiltered()

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

Definition at line 458 of file doxygen.cpp.

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

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

Referenced by organizeSubGroups(), and organizeSubGroupsFiltered().

◆ parseFile()

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

Definition at line 10599 of file doxygen.cpp.

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

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

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

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

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

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

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

Referenced by main().

◆ printLayout()

void printLayout ( )

Definition at line 9894 of file doxygen.cpp.

9895{
9896 bool extraIndent = false;
9897 Debug::print(Debug::Layout,0,"Part: Navigation index\n");
9898 for (const auto &e : LayoutDocManager::instance().rootNavEntry()->children())
9899 {
9900 printNavLayout(e.get(),2);
9901 }
9902
9903 for (int i = 0; i < LayoutDocManager::NrParts; i++)
9904 {
9906 for (const auto &lde : LayoutDocManager::instance().docEntries(static_cast<LayoutDocManager::LayoutPart>(i)))
9907 {
9908 if (const LayoutDocEntrySimple *ldes = dynamic_cast<const LayoutDocEntrySimple*>(lde.get()))
9909 {
9910 if (lde->kind() == LayoutDocEntry::MemberDeclEnd || lde->kind() == LayoutDocEntry::MemberDefEnd) extraIndent = false;
9911 Debug::print(Debug::Layout,0," %skind: %s, visible=%d\n",
9912 extraIndent? " " : "",qPrint(lde->entryToString()), ldes->visible());
9913 if (lde->kind() == LayoutDocEntry::MemberDeclStart || lde->kind() == LayoutDocEntry::MemberDefStart) extraIndent = true;
9914 }
9915 else if (const LayoutDocEntryMemberDecl *lmdecl = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get()))
9916 {
9917 Debug::print(Debug::Layout,0," %scomplex kind: %s, type: %s\n",
9918 extraIndent? " " : "",qPrint(lde->entryToString()),qPrint(lmdecl->type.to_string()));
9919 }
9920 else if (const LayoutDocEntryMemberDef *lmdef = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get()))
9921 {
9922 Debug::print(Debug::Layout,0," %scomplex kind: %s, type: %s\n",
9923 extraIndent? " " : "",qPrint(lde->entryToString()),qPrint(lmdef->type.to_string()));
9924 }
9925 else
9926 {
9927 // should not happen
9928 Debug::print(Debug::Layout,0," %snot handled kind: %s\n",extraIndent? " " : "",qPrint(lde->entryToString()));
9929 }
9930 }
9931 }
9932}
@ Layout
Definition debug.h:49
static void print(DebugMask mask, int prio, const char *fmt,...)
Definition debug.cpp:81
static std::string partToString(int k)
Definition layout.h:244
void printNavLayout(LayoutNavEntry *root, int indent)
Definition doxygen.cpp:9875
Represents of a member declaration list with configurable title and subtitle.
Definition layout.h:109
Represents of a member definition list with configurable title.
Definition layout.h:125
Represents of a piece of a documentation page without configurable parts.
Definition layout.h:88

References LayoutDocManager::instance(), Debug::Layout, LayoutDocManager::partToString(), Debug::print(), printNavLayout(), and qPrint().

Referenced by parseInput().

◆ printNavLayout()

void printNavLayout ( LayoutNavEntry * root,
int indent )

Definition at line 9875 of file doxygen.cpp.

9876{
9878 {
9879 QCString indentStr;
9880 indentStr.fill(' ',indent);
9881 Debug::print(Debug::Layout,0,"%skind=%s visible=%d title='%s'\n",
9882 indentStr.isEmpty()?"":qPrint(indentStr),
9883 qPrint(root->navToString()),
9884 root->visible(),
9885 qPrint(root->title())
9886 );
9887 for (const auto &e : root->children())
9888 {
9889 printNavLayout(e.get(),indent+2);
9890 }
9891 }
9892}
void fill(char c, int len=-1)
Fills a string with a predefined character.
Definition qcstring.h:180
QCString title() const
Definition layout.h:199
bool visible()
Definition layout.h:203
const LayoutNavEntryList & children() const
Definition layout.h:209
std::string navToString()
Definition layout.h:182

References LayoutNavEntry::children(), QCString::fill(), QCString::isEmpty(), Debug::isFlagSet(), Debug::Layout, LayoutNavEntry::navToString(), Debug::print(), printNavLayout(), qPrint(), LayoutNavEntry::title(), and LayoutNavEntry::visible().

Referenced by printLayout(), and printNavLayout().

◆ printNavTree()

void printNavTree ( Entry * root,
int indent )

Definition at line 9856 of file doxygen.cpp.

9857{
9859 {
9860 QCString indentStr;
9861 indentStr.fill(' ',indent);
9862 Debug::print(Debug::Entries,0,"%s%s at %s:%d (sec=%s, spec=%s)\n",
9863 indentStr.isEmpty()?"":qPrint(indentStr),
9864 root->name.isEmpty()?"<empty>":qPrint(root->name),
9865 qPrint(root->fileName),root->startLine,
9866 root->section.to_string().c_str(),
9867 root->spec.to_string().c_str());
9868 for (const auto &e : root->children())
9869 {
9870 printNavTree(e.get(),indent+2);
9871 }
9872 }
9873}
@ Entries
Definition debug.h:46
std::string to_string() const
Definition types.h:643
std::string to_string() const
Definition types.h:520

References Entry::children(), Debug::Entries, Entry::fileName, QCString::fill(), QCString::isEmpty(), Debug::isFlagSet(), Entry::name, Debug::print(), printNavTree(), 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 9937 of file doxygen.cpp.

9938{
9940 {
9941 for (const auto &si : SectionManager::instance())
9942 {
9943 Debug::print(Debug::Sections,0,"Section = %s, file = %s, title = %s, type = %d, ref = %s\n",
9944 qPrint(si->label()),qPrint(si->fileName()),qPrint(si->title()),
9945 si->type(),qPrint(si->ref()));
9946 }
9947 }
9948}
@ Sections
Definition debug.h:47

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

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

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

Referenced by findTagLessClasses(), and processTagLessClasses().

◆ readConfiguration()

void readConfiguration ( int argc,
char ** argv )

Definition at line 11430 of file doxygen.cpp.

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

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

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

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

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

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

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

References FileInfo::absFilePath(), err, FileInfo::exists(), QCString::find(), QCString::isEmpty(), FileInfo::isFile(), QCString::left(), QCString::length(), msg(), parseTagFile(), 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 1309 of file doxygen.cpp.

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

References DefinitionMutable::addInnerCompound(), buildScopeFromQualifiedName(), Doxygen::classLinkedMap, createClassDefAlias(), Definition::definitionType(), FALSE, findScopeFromQualifiedName(), Definition::getDefFileName(), Definition::getDefLine(), Definition::getLanguage(), Definition::getOuterScope(), Doxygen::globalScope, QCString::isEmpty(), NamespaceDef::isInline(), Definition::name(), 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 10898 of file doxygen.cpp.

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

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

Referenced by readDir().

◆ resolveTemplateInstanceInType()

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

Definition at line 4741 of file doxygen.cpp.

4742{
4743 // For a statement like 'using X = T<A>', add a template instance 'T<A>' as a symbol, so it can
4744 // be used to match arguments (see issue #11111)
4745 AUTO_TRACE();
4746 QCString ttype = md->typeString();
4747 ttype.stripPrefix("typedef ");
4748 int ti=ttype.find('<');
4749 if (ti!=-1)
4750 {
4751 QCString templateClassName = ttype.left(ti);
4752 SymbolResolver resolver(root->fileDef());
4753 ClassDefMutable *baseClass = resolver.resolveClassMutable(scope ? scope : Doxygen::globalScope,
4754 templateClassName, true, true);
4755 AUTO_TRACE_ADD("templateClassName={} baseClass={}",templateClassName,baseClass?baseClass->name():"<none>");
4756 if (baseClass)
4757 {
4758 const ArgumentList &tl = baseClass->templateArguments();
4759 TemplateNameMap templateNames = getTemplateArgumentsInName(tl,templateClassName.str());
4761 baseClass,
4762 ttype.mid(ti),
4763 templateNames,
4764 baseClass->isArtificial());
4765 }
4766 }
4767}

References AUTO_TRACE, AUTO_TRACE_ADD, Entry::fileDef(), QCString::find(), findTemplateInstanceRelation(), Definition::getOuterScope(), getTemplateArgumentsInName(), Doxygen::globalScope, Definition::isArtificial(), QCString::left(), QCString::mid(), Definition::name(), SymbolResolver::resolveClassMutable(), QCString::str(), QCString::stripPrefix(), ClassDef::templateArguments(), and MemberDef::typeString().

Referenced by addVariableToClass(), and addVariableToFile().

◆ resolveUserReferences()

static void resolveUserReferences ( )
static

Definition at line 9738 of file doxygen.cpp.

9739{
9740 for (const auto &si : SectionManager::instance())
9741 {
9742 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
9743 // qPrint(si->label),si->definition?qPrint(si->definition->name()):"<none>",
9744 // qPrint(si->fileName));
9745 PageDef *pd=nullptr;
9746
9747 // hack: the items of a todo/test/bug/deprecated list are all fragments from
9748 // different files, so the resulting section's all have the wrong file
9749 // name (not from the todo/test/bug/deprecated list, but from the file in
9750 // which they are defined). We correct this here by looking at the
9751 // generated section labels!
9753 {
9754 QCString label="_"+rl->listName(); // "_todo", "_test", ...
9755 if (si->label().left(label.length())==label)
9756 {
9757 si->setFileName(rl->listName());
9758 si->setGenerated(TRUE);
9759 break;
9760 }
9761 }
9762
9763 //printf("start: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9764 if (!si->generated())
9765 {
9766 // if this section is in a page and the page is in a group, then we
9767 // have to adjust the link file name to point to the group.
9768 if (!si->fileName().isEmpty() &&
9769 (pd=Doxygen::pageLinkedMap->find(si->fileName())) &&
9770 pd->getGroupDef())
9771 {
9772 si->setFileName(pd->getGroupDef()->getOutputFileBase());
9773 }
9774
9775 if (si->definition())
9776 {
9777 // TODO: there should be one function in Definition that returns
9778 // the file to link to, so we can avoid the following tests.
9779 const GroupDef *gd=nullptr;
9780 if (si->definition()->definitionType()==Definition::TypeMember)
9781 {
9782 gd = (toMemberDef(si->definition()))->getGroupDef();
9783 }
9784
9785 if (gd)
9786 {
9787 si->setFileName(gd->getOutputFileBase());
9788 }
9789 else
9790 {
9791 //si->fileName=si->definition->getOutputFileBase();
9792 //printf("Setting si->fileName to %s\n",qPrint(si->fileName));
9793 }
9794 }
9795 }
9796 //printf("end: si->label=%s si->fileName=%s\n",qPrint(si->label),qPrint(si->fileName));
9797 }
9798}
virtual const GroupDef * getGroupDef() const =0

References PageDef::getGroupDef(), Definition::getOutputFileBase(), RefListManager::instance(), SectionManager::instance(), QCString::length(), Doxygen::pageLinkedMap, toMemberDef(), TRUE, and Definition::TypeMember.

Referenced by parseInput().

◆ runHtmlHelpCompiler()

static void runHtmlHelpCompiler ( )
static

Definition at line 10129 of file doxygen.cpp.

10130{
10131 std::string oldDir = Dir::currentDirPath();
10132 Dir::setCurrent(Config_getString(HTML_OUTPUT).str());
10135 {
10136 err("failed to run html help compiler on %s\n", qPrint(HtmlHelp::hhpFileName));
10137 }
10138 Dir::setCurrent(oldDir);
10139}
@ 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:570

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

Referenced by generateOutput().

◆ runQHelpGenerator()

static void runQHelpGenerator ( )
static

Definition at line 10141 of file doxygen.cpp.

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

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

Referenced by generateOutput().

◆ scopeIsTemplate()

static bool scopeIsTemplate ( const Definition * d)
static

Definition at line 5897 of file doxygen.cpp.

5898{
5899 bool result=FALSE;
5901 {
5902 result = !(toClassDef(d))->templateArguments().empty() ||
5904 }
5905 return result;
5906}

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

Referenced by addMemberFunction(), and scopeIsTemplate().

◆ searchInputFiles()

void searchInputFiles ( )

Definition at line 12126 of file doxygen.cpp.

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

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

Referenced by parseInput().

◆ setAnonymousEnumType()

static void setAnonymousEnumType ( )
static

Definition at line 8889 of file doxygen.cpp.

8890{
8891 for (const auto &cd : *Doxygen::classLinkedMap)
8892 {
8893 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8894 if (cdm)
8895 {
8896 cdm->setAnonymousEnumType();
8897 }
8898 }
8899}
virtual void setAnonymousEnumType()=0

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

Referenced by parseInput().

◆ sortMemberLists()

static void sortMemberLists ( )
static

Definition at line 8794 of file doxygen.cpp.

8795{
8796 // sort class member lists
8797 for (const auto &cd : *Doxygen::classLinkedMap)
8798 {
8799 ClassDefMutable *cdm = toClassDefMutable(cd.get());
8800 if (cdm)
8801 {
8802 cdm->sortMemberLists();
8803 }
8804 }
8805
8806 // sort namespace member lists
8807 for (const auto &nd : *Doxygen::namespaceLinkedMap)
8808 {
8810 if (ndm)
8811 {
8812 ndm->sortMemberLists();
8813 }
8814 }
8815
8816 // sort file member lists
8817 for (const auto &fn : *Doxygen::inputNameLinkedMap)
8818 {
8819 for (const auto &fd : *fn)
8820 {
8821 fd->sortMemberLists();
8822 }
8823 }
8824
8825 // sort group member lists
8826 for (const auto &gd : *Doxygen::groupLinkedMap)
8827 {
8828 gd->sortMemberLists();
8829 }
8830
8832}
virtual void sortMemberLists()=0
void sortMemberLists()
virtual void sortMemberLists()=0

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

Referenced by parseInput().

◆ stopDoxygen()

static void stopDoxygen ( int )
static

Definition at line 11998 of file doxygen.cpp.

11999{
12000 signal(SIGINT,SIG_DFL); // Re-register signal handler for default action
12001 Dir thisDir;
12002 msg("Cleaning up...\n");
12003 if (!Doxygen::filterDBFileName.isEmpty())
12004 {
12005 thisDir.remove(Doxygen::filterDBFileName.str());
12006 }
12007 killpg(0,SIGINT);
12009 exitTracing();
12010 exit(1);
12011}

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

Referenced by parseInput().

◆ stripTemplateSpecifiers()

QCString stripTemplateSpecifiers ( const QCString & s)

Definition at line 671 of file doxygen.cpp.

672{
673 size_t l = s.length();
674 int count=0;
675 int round=0;
676 QCString result;
677 for (size_t i=0;i<l;i++)
678 {
679 char c=s.at(i);
680 if (c=='(') round++;
681 else if (c==')' && round>0) round--;
682 else if (c=='<' && round==0) count++;
683 if (count==0)
684 {
685 result+=c;
686 }
687 if (c=='>' && round==0 && count>0) count--;
688 }
689 //printf("stripTemplateSpecifiers(%s)=%s\n",qPrint(s),qPrint(result));
690 return result;
691}

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

5998{
5999 auto dstIt = dst.begin();
6000 for (const Argument &sa : src)
6001 {
6002 QCString dstType = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.type.str());
6003 QCString dstArray = substituteTemplatesInString(srcTempArgLists,dstTempArgLists,sa.array.str());
6004 if (dstIt == dst.end())
6005 {
6006 Argument da = sa;
6007 da.type = dstType;
6008 da.array = dstArray;
6009 dst.push_back(da);
6010 dstIt = dst.end();
6011 }
6012 else
6013 {
6014 Argument da = *dstIt;
6015 da.type = dstType;
6016 da.array = dstArray;
6017 ++dstIt;
6018 }
6019 }
6020 dst.setConstSpecifier(src.constSpecifier());
6021 dst.setVolatileSpecifier(src.volatileSpecifier());
6022 dst.setPureSpecifier(src.pureSpecifier());
6024 srcTempArgLists,dstTempArgLists,
6025 src.trailingReturnType().str()));
6026 dst.setIsDeleted(src.isDeleted());
6027 dst.setRefQualifier(src.refQualifier());
6028 dst.setNoParameters(src.noParameters());
6029 //printf("substituteTemplatesInArgList: replacing %s with %s\n",
6030 // qPrint(argListToString(src)),qPrint(argListToString(dst))
6031 // );
6032}
iterator end()
Definition arguments.h:87
void setTrailingReturnType(const QCString &s)
Definition arguments.h:115
void setPureSpecifier(bool b)
Definition arguments.h:114
void push_back(const Argument &a)
Definition arguments.h:95
void setConstSpecifier(bool b)
Definition arguments.h:112
void setRefQualifier(RefQualifierType t)
Definition arguments.h:117
void setIsDeleted(bool b)
Definition arguments.h:116
iterator begin()
Definition arguments.h:86
void setNoParameters(bool b)
Definition arguments.h:118
void setVolatileSpecifier(bool b)
Definition arguments.h:113
static QCString substituteTemplatesInString(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists, const std::string &src)
Definition doxygen.cpp:5908
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 5908 of file doxygen.cpp.

5913{
5914 std::string dst;
5915 static const reg::Ex re(R"(\a\w*)");
5916 reg::Iterator it(src,re);
5918 //printf("type=%s\n",qPrint(sa->type));
5919 size_t p=0;
5920 for (; it!=end ; ++it) // for each word in srcType
5921 {
5922 const auto &match = *it;
5923 size_t i = match.position();
5924 size_t l = match.length();
5925 bool found=FALSE;
5926 dst+=src.substr(p,i-p);
5927 std::string name=match.str();
5928
5929 auto srcIt = srcTempArgLists.begin();
5930 auto dstIt = dstTempArgLists.begin();
5931 while (srcIt!=srcTempArgLists.end() && !found)
5932 {
5933 const ArgumentList *tdAli = nullptr;
5934 std::vector<Argument>::const_iterator tdaIt;
5935 if (dstIt!=dstTempArgLists.end())
5936 {
5937 tdAli = &(*dstIt);
5938 tdaIt = tdAli->begin();
5939 ++dstIt;
5940 }
5941
5942 const ArgumentList &tsaLi = *srcIt;
5943 for (auto tsaIt = tsaLi.begin(); tsaIt!=tsaLi.end() && !found; ++tsaIt)
5944 {
5945 Argument tsa = *tsaIt;
5946 const Argument *tda = nullptr;
5947 if (tdAli && tdaIt!=tdAli->end())
5948 {
5949 tda = &(*tdaIt);
5950 ++tdaIt;
5951 }
5952 //if (tda) printf("tsa=%s|%s tda=%s|%s\n",
5953 // qPrint(tsa.type),qPrint(tsa.name),
5954 // qPrint(tda->type),qPrint(tda->name));
5955 if (name==tsa.name.str())
5956 {
5957 if (tda && tda->name.isEmpty())
5958 {
5959 QCString tdaName = tda->name;
5960 QCString tdaType = tda->type;
5961 int vc=0;
5962 if (tdaType.startsWith("class ")) vc=6;
5963 else if (tdaType.startsWith("typename ")) vc=9;
5964 if (vc>0) // convert type=="class T" to type=="class" name=="T"
5965 {
5966 tdaName = tdaType.mid(vc);
5967 }
5968 if (!tdaName.isEmpty())
5969 {
5970 name=tdaName.str(); // substitute
5971 found=TRUE;
5972 }
5973 }
5974 }
5975 }
5976
5977 //printf(" srcList='%s' dstList='%s faList='%s'\n",
5978 // qPrint(argListToString(srclali.current())),
5979 // qPrint(argListToString(dstlali.current())),
5980 // funcTempArgList ? qPrint(argListToString(funcTempArgList)) : "<none>");
5981 ++srcIt;
5982 }
5983 dst+=name;
5984 p=i+l;
5985 }
5986 dst+=src.substr(p);
5987 //printf(" substituteTemplatesInString(%s)=%s\n",
5988 // qPrint(src),qPrint(dst));
5989 return QCString(dst);
5990}

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

4252{
4253 AUTO_TRACE();
4254
4255 // find matching function declaration and definitions.
4256 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4257 {
4258 //printf("memberName=%s count=%zu\n",qPrint(mn->memberName()),mn->size());
4259 /* find a matching function declaration and definition for this function */
4260 for (const auto &imdec : *mn)
4261 {
4262 MemberDefMutable *mdec = toMemberDefMutable(imdec.get());
4263 if (mdec &&
4264 (mdec->isPrototype() ||
4265 (mdec->isVariable() && mdec->isExternal())
4266 ))
4267 {
4268 for (const auto &imdef : *mn)
4269 {
4270 MemberDefMutable *mdef = toMemberDefMutable(imdef.get());
4271 if (mdef && mdec!=mdef &&
4272 mdec->getNamespaceDef()==mdef->getNamespaceDef())
4273 {
4275 }
4276 }
4277 }
4278 }
4279 }
4280}
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 4284 of file doxygen.cpp.

4285{
4286 AUTO_TRACE();
4287 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4288 {
4289 MemberDefMutable *mdef=nullptr,*mdec=nullptr;
4290 /* find a matching function declaration and definition for this function */
4291 for (const auto &imd : *mn)
4292 {
4293 MemberDefMutable *md = toMemberDefMutable(imd.get());
4294 if (md)
4295 {
4296 if (md->isPrototype())
4297 mdec=md;
4298 else if (md->isVariable() && md->isExternal())
4299 mdec=md;
4300
4301 if (md->isFunction() && !md->isStatic() && !md->isPrototype())
4302 mdef=md;
4303 else if (md->isVariable() && !md->isExternal() && !md->isStatic())
4304 mdef=md;
4305 }
4306
4307 if (mdef && mdec) break;
4308 }
4309 if (mdef && mdec)
4310 {
4311 const ArgumentList &mdefAl = mdef->argumentList();
4312 const ArgumentList &mdecAl = mdec->argumentList();
4313 if (
4314 matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),const_cast<ArgumentList*>(&mdefAl),
4315 mdec->getOuterScope(),mdec->getFileDef(),const_cast<ArgumentList*>(&mdecAl),
4316 TRUE,mdef->getLanguage()
4317 )
4318 ) /* match found */
4319 {
4320 AUTO_TRACE_ADD("merging references for mdec={} mdef={}",mdec->name(),mdef->name());
4321 mdef->mergeReferences(mdec);
4322 mdec->mergeReferences(mdef);
4323 mdef->mergeReferencedBy(mdec);
4324 mdec->mergeReferencedBy(mdef);
4325 }
4326 }
4327 }
4328}
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 4332 of file doxygen.cpp.

4333{
4334 AUTO_TRACE();
4335 // find match between function declaration and definition for
4336 // related functions
4337 for (const auto &mn : *Doxygen::functionNameLinkedMap)
4338 {
4339 /* find a matching function declaration and definition for this function */
4340 // for each global function
4341 for (const auto &imd : *mn)
4342 {
4343 MemberDefMutable *md = toMemberDefMutable(imd.get());
4344 if (md)
4345 {
4346 //printf(" Function '%s'\n",qPrint(md->name()));
4347 MemberName *rmn = Doxygen::memberNameLinkedMap->find(md->name());
4348 if (rmn) // check if there is a member with the same name
4349 {
4350 //printf(" Member name found\n");
4351 // for each member with the same name
4352 for (const auto &irmd : *rmn)
4353 {
4354 MemberDefMutable *rmd = toMemberDefMutable(irmd.get());
4355 //printf(" Member found: related='%d'\n",rmd->isRelated());
4356 if (rmd &&
4357 (rmd->isRelated() || rmd->isForeign()) && // related function
4359 rmd->getOuterScope(),rmd->getFileDef(),&rmd->argumentList(),
4360 TRUE,md->getLanguage()
4361 )
4362 )
4363 {
4364 AUTO_TRACE_ADD("Found related member '{}'",md->name());
4365 if (rmd->relatedAlso())
4366 md->setRelatedAlso(rmd->relatedAlso());
4367 else if (rmd->isForeign())
4368 md->makeForeign();
4369 else
4370 md->makeRelated();
4371 }
4372 }
4373 }
4374 }
4375 }
4376 }
4377}
virtual bool isForeign() const =0
virtual ClassDef * relatedAlso() const =0
virtual void setRelatedAlso(ClassDef *cd)=0
virtual void makeForeign()=0

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

Referenced by parseInput().

◆ transferStaticInstanceInitializers()

void transferStaticInstanceInitializers ( )

Definition at line 4381 of file doxygen.cpp.

4382{
4383 AUTO_TRACE();
4384 for (const auto &[qualifiedName,bodyInfo] : Doxygen::staticInitMap)
4385 {
4386 size_t i=qualifiedName.rfind("::");
4387 if (i!=std::string::npos)
4388 {
4389 QCString scope = qualifiedName.substr(0,i);
4390 QCString name = qualifiedName.substr(i+2);
4391 MemberName *mn = Doxygen::memberNameLinkedMap->find(name);
4392 if (mn)
4393 {
4394 for (const auto &imd : *mn)
4395 {
4396 MemberDefMutable *md = toMemberDefMutable(imd.get());
4397 if (md && md->qualifiedName().str()==qualifiedName && md->isVariable())
4398 {
4399 AUTO_TRACE_ADD("found static member {} body [{}..{}]\n",
4400 md->qualifiedName(),bodyInfo.startLine,bodyInfo.endLine);
4401 md->setBodySegment(bodyInfo.defLine,
4402 bodyInfo.startLine,
4403 bodyInfo.endLine);
4404 }
4405 }
4406 }
4407 }
4408 }
4409}

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

Referenced by parseInput().

◆ tryAddEnumDocsToGroupMember()

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

Definition at line 7888 of file doxygen.cpp.

7889{
7890 for (const auto &g : root->groups)
7891 {
7892 const GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
7893 if (gd)
7894 {
7895 MemberList *ml = gd->getMemberList(MemberListType::DecEnumMembers());
7896 if (ml)
7897 {
7898 MemberDefMutable *md = toMemberDefMutable(ml->find(name));
7899 if (md)
7900 {
7901 addEnumDocs(root,md);
7902 return TRUE;
7903 }
7904 }
7905 }
7906 else if (!gd && g.pri == Grouping::GROUPING_INGROUP)
7907 {
7908 warn(root->fileName, root->startLine,
7909 "Found non-existing group '%s' for the command '%s', ignoring command",
7910 qPrint(g.groupname), Grouping::getGroupPriName( g.pri )
7911 );
7912 }
7913 }
7914
7915 return FALSE;
7916}
virtual MemberList * getMemberList(MemberListType lt) const =0
MemberDef * find(const QCString &name)
Definition memberlist.h:92

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

Referenced by findEnumDocumentation().

◆ usage()

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

Definition at line 11245 of file doxygen.cpp.

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

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

Referenced by readConfiguration().

◆ version()

static void version ( const bool extended)
static

Definition at line 11217 of file doxygen.cpp.

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

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

Referenced by readConfiguration().

◆ vhdlCorrectMemberProperties()

static void vhdlCorrectMemberProperties ( )
static

Definition at line 8254 of file doxygen.cpp.

8255{
8256 // for each member name
8257 for (const auto &mn : *Doxygen::memberNameLinkedMap)
8258 {
8259 // for each member definition
8260 for (const auto &imd : *mn)
8261 {
8262 MemberDefMutable *md = toMemberDefMutable(imd.get());
8263 if (md)
8264 {
8266 }
8267 }
8268 }
8269 // for each member name
8270 for (const auto &mn : *Doxygen::functionNameLinkedMap)
8271 {
8272 // for each member definition
8273 for (const auto &imd : *mn)
8274 {
8275 MemberDefMutable *md = toMemberDefMutable(imd.get());
8276 if (md)
8277 {
8279 }
8280 }
8281 }
8282}
static void correctMemberProperties(MemberDefMutable *md)

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

Referenced by parseInput().

◆ warnUndocumentedNamespaces()

static void warnUndocumentedNamespaces ( )
static

Definition at line 5250 of file doxygen.cpp.

5251{
5252 AUTO_TRACE();
5253 for (const auto &nd : *Doxygen::namespaceLinkedMap)
5254 {
5255 if (!nd->hasDocumentation())
5256 {
5257 if ((guessSection(nd->getDefFileName()).isHeader() ||
5258 nd->getLanguage() == SrcLangExt::Fortran) && // Fortran doesn't have header files.
5259 !Config_getBool(HIDE_UNDOC_NAMESPACES) // undocumented namespaces are visible
5260 )
5261 {
5262 warn_undoc(nd->getDefFileName(),nd->getDefLine(), "%s %s is not documented.",
5263 nd->getLanguage() == SrcLangExt::Fortran ? "Module" : "Namespace",
5264 qPrint(nd->name()));
5265 }
5266 }
5267 }
5268}

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

Referenced by parseInput().

◆ writeTagFile()

static void writeTagFile ( )
static

Definition at line 12014 of file doxygen.cpp.

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

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

Referenced by generateOutput().

Variable Documentation

◆ g_classEntries

◆ g_commentFileName

QCString g_commentFileName
static

Definition at line 185 of file doxygen.cpp.

Referenced by parseInput(), and readConfiguration().

◆ g_compoundKeywords

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

Definition at line 191 of file doxygen.cpp.

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

Referenced by buildVarList(), and filterMemberDocumentation().

◆ g_dumpSymbolMap

bool g_dumpSymbolMap = FALSE
static

Definition at line 184 of file doxygen.cpp.

Referenced by generateOutput(), and readConfiguration().

◆ g_inputFiles

◆ g_outputList

◆ g_s

◆ g_singleComment

bool g_singleComment =false
static

Definition at line 186 of file doxygen.cpp.

Referenced by parseInput(), and readConfiguration().

◆ g_successfulRun

bool g_successfulRun = FALSE
static

Definition at line 183 of file doxygen.cpp.

Referenced by exitDoxygen(), and generateOutput().

◆ g_usingClassMap

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

Definition at line 2135 of file doxygen.cpp.

Referenced by findUsingDeclImports(), and parseInput().

◆ g_usingDeclarations

StringSet g_usingDeclarations
static

Definition at line 182 of file doxygen.cpp.

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