Doxygen
Loading...
Searching...
No Matches
SymbolResolver Class Reference

#include <src/symbolresolver.h>

Classes

struct  Private

Public Types

enum class  ClearScope { All , Classes , Unresolved }
 Clear the type lookup cache for the current thread. More...

Public Member Functions

 SymbolResolver (const FileDef *fileScope=nullptr)
 ~SymbolResolver ()
const ClassDefresolveClass (const Definition *scope, const DString &name, bool maybeUnlinkable=false, bool mayBeHidden=false)
 Find the class definition matching name within the scope set.
ClassDefMutableresolveClassMutable (const Definition *scope, const DString &name, bool mayBeUnlinkable=false, bool mayBeHidden=false)
 Wrapper around resolveClass that returns a mutable interface to the class object or a nullptr if the symbol is immutable.
const DefinitionresolveSymbol (const Definition *scope, const DString &name, const DString &args=DString(), bool checkCV=false, bool insideCode=false, bool onlyLinkable=false)
 Find the symbool definition matching name within the scope set.
int isAccessibleFrom (const Definition *scope, const Definition *item)
 Checks if symbol item is accessible from within scope.
int isAccessibleFromWithExpScope (const Definition *scope, const Definition *item, const DString &explicitScopePart)
 Check if symbol item is accessible from within scope, where it has to match the explicitScopePart.
void setFileScope (const FileDef *fd)
 Sets or updates the file scope using when resolving symbols.
const MemberDefgetTypedef () const
 In case a call to resolveClass() resolves to a type member (e.g. an enum) this method will return it.
DString getTemplateSpec () const
 In case a call to resolveClass() points to a template specialization, the template part is return via this method.
DString getResolvedType () const
 In case a call to resolveClass() points to a typedef or using declaration.

Static Public Member Functions

static void clearTypeLookupCache (ClearScope scope)
static void showCacheUsage ()
 Show usage of the type lookup cache.

Private Attributes

std::unique_ptr< Privatep

Detailed Description

Helper class to find a class definition or check if A symbol is accessible in a given scope.

Definition at line 31 of file symbolresolver.h.

Member Enumeration Documentation

◆ ClearScope

enum class SymbolResolver::ClearScope
strong

Clear the type lookup cache for the current thread.

Enumerator
All 
Classes 
Unresolved 

Definition at line 102 of file symbolresolver.h.

102{ All, Classes, Unresolved };

Constructor & Destructor Documentation

◆ SymbolResolver()

SymbolResolver::SymbolResolver ( const FileDef * fileScope = nullptr)
explicit

Definition at line 1683 of file symbolresolver.cpp.

1684 : p(std::make_unique<Private>(fileScope))
1685{
1686}
std::unique_ptr< Private > p

References p.

◆ ~SymbolResolver()

SymbolResolver::~SymbolResolver ( )

Definition at line 1688 of file symbolresolver.cpp.

1689{
1690}

Member Function Documentation

◆ clearTypeLookupCache()

void SymbolResolver::clearTypeLookupCache ( SymbolResolver::ClearScope scope)
static

Definition at line 1810 of file symbolresolver.cpp.

1811{
1812 auto &cache = getTypeLookupCache();
1813 switch (scope)
1814 {
1815 case ClearScope::All:
1816 cache.clear();
1817 break;
1819 {
1820 StringVector elementsToRemove;
1821 for (const auto &ci : cache)
1822 {
1823 const LookupInfo &li = ci.second;
1824 if (li.definition==nullptr && li.typeDef==nullptr)
1825 {
1826 elementsToRemove.push_back(ci.first);
1827 }
1828 }
1829 for (const auto &k : elementsToRemove)
1830 {
1831 cache.remove(k);
1832 }
1833 }
1834 break;
1836 {
1837 StringVector elementsToRemove;
1838 for (const auto &ci : cache)
1839 {
1840 const LookupInfo &li = ci.second;
1841 if (li.definition)
1842 {
1843 elementsToRemove.push_back(ci.first);
1844 }
1845 }
1846 for (const auto &k : elementsToRemove)
1847 {
1848 cache.remove(k);
1849 }
1850 }
1851 break;
1852 }
1853}
std::vector< std::string > StringVector
Definition containers.h:33
const Definition * definition
Definition doxygen.h:52
const MemberDef * typeDef
Definition doxygen.h:53
static LookupCache & getTypeLookupCache()

References All, Classes, LookupInfo::definition, getTypeLookupCache(), LookupInfo::typeDef, and Unresolved.

Referenced by flushCachedTemplateRelations(), flushUnresolvedRelations(), and parseInput().

◆ getResolvedType()

DString SymbolResolver::getResolvedType ( ) const

In case a call to resolveClass() points to a typedef or using declaration.

The type name it resolved to is returned via this method.

Definition at line 1805 of file symbolresolver.cpp.

1806{
1807 return p->resolvedType;
1808}

References p.

Referenced by getCanonicalTypeForIdentifier().

◆ getTemplateSpec()

DString SymbolResolver::getTemplateSpec ( ) const

In case a call to resolveClass() points to a template specialization, the template part is return via this method.

Definition at line 1800 of file symbolresolver.cpp.

1801{
1802 return p->templateSpec;
1803}

References p.

Referenced by findClassRelation(), and getCanonicalTypeForIdentifier().

◆ getTypedef()

const MemberDef * SymbolResolver::getTypedef ( ) const

In case a call to resolveClass() resolves to a type member (e.g. an enum) this method will return it.

Definition at line 1795 of file symbolresolver.cpp.

1796{
1797 return p->typeDef;
1798}

References p.

Referenced by findClassRelation(), getCanonicalTypeForIdentifier(), and linkifyText().

◆ isAccessibleFrom()

int SymbolResolver::isAccessibleFrom ( const Definition * scope,
const Definition * item )

Checks if symbol item is accessible from within scope.

Returns
-1 if item is not accessible or a number indicating how many scope levels up the nearest match was found.

Definition at line 1764 of file symbolresolver.cpp.

1765{
1766 AUTO_TRACE("scope={} item={}",
1767 scope?scope->name():DString(), item?item->name():DString());
1768 p->reset();
1769 VisitedKeys visitedKeys;
1770 AccessStack accessStack;
1771 int result = p->isAccessibleFrom(visitedKeys,accessStack,scope,item);
1772 AUTO_TRACE_EXIT("result={}",result);
1773 return result;
1774}
virtual const DString & name() const =0
#define AUTO_TRACE(...)
Definition docnode.cpp:51
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:53
StringVector VisitedKeys

References AUTO_TRACE, AUTO_TRACE_EXIT, Definition::name(), and p.

Referenced by resolveTypeDef().

◆ isAccessibleFromWithExpScope()

int SymbolResolver::isAccessibleFromWithExpScope ( const Definition * scope,
const Definition * item,
const DString & explicitScopePart )

Check if symbol item is accessible from within scope, where it has to match the explicitScopePart.

Returns
-1 if item is not accessible or a number indicating how many scope levels up the nearest match was found.

Definition at line 1776 of file symbolresolver.cpp.

1778{
1779 AUTO_TRACE("scope={} item={} explicitScopePart={}",
1780 scope?scope->name():DString(), item?item->name():DString(), explicitScopePart);
1781 p->reset();
1782 VisitedKeys visitedKeys;
1783 VisitedNamespaces visitedNamespaces;
1784 AccessStack accessStack;
1785 int result = p->isAccessibleFromWithExpScope(visitedKeys,visitedNamespaces,accessStack,scope,item,explicitScopePart);
1786 AUTO_TRACE_EXIT("result={}",result);
1787 return result;
1788}
std::unordered_map< std::string, const Definition * > VisitedNamespaces

References AUTO_TRACE, AUTO_TRACE_EXIT, Definition::name(), and p.

Referenced by getMemberFromSymbol().

◆ resolveClass()

const ClassDef * SymbolResolver::resolveClass ( const Definition * scope,
const DString & name,
bool maybeUnlinkable = false,
bool mayBeHidden = false )

Find the class definition matching name within the scope set.

Parameters
scopeThe scope to search from.
nameThe name of the symbol.
maybeUnlinkableinclude unlinkable symbols in the search.
mayBeHiddeninclude hidden symbols in the search.
Note
As a result of this call the getters getTypedef(), getTemplateSpec(), and getResolvedType() are set as well.

Definition at line 1693 of file symbolresolver.cpp.

1697{
1698 AUTO_TRACE("scope={} name={} mayBeUnlinkable={} mayBeHidden={}",
1699 scope?scope->name():DString(), name, mayBeUnlinkable, mayBeHidden);
1700 p->reset();
1701
1702 auto lang = scope ? scope->getLanguage() :
1703 p->fileScope() ? p->fileScope()->getLanguage() :
1704 SrcLangExt::Cpp; // fallback to C++
1705
1706 if (scope==nullptr ||
1709 ) ||
1710 (name.stripWhiteSpace().startsWith("::")) ||
1711 ((lang==SrcLangExt::Java || lang==SrcLangExt::CSharp) && DString(name).find("::")!=DString::npos)
1712 )
1713 {
1715 }
1716 const ClassDef *result=nullptr;
1717 if (Config_getBool(OPTIMIZE_OUTPUT_VHDL))
1718 {
1719 result = getClass(name);
1720 }
1721 else
1722 {
1723 VisitedKeys visitedKeys;
1724 DString lookupName = lang==SrcLangExt::CSharp ? mangleCSharpGenericName(name) : name;
1725 AUTO_TRACE_ADD("lookup={}",lookupName);
1726 result = p->getResolvedTypeRec(getTypeLookupCache(),visitedKeys,scope,lookupName,&p->typeDef,&p->templateSpec,&p->resolvedType);
1727 if (result==nullptr) // for nested classes imported via tag files, the scope may not
1728 // present, so we check the class name directly as well.
1729 // See also bug701314
1730 {
1731 result = getClass(lookupName);
1732 }
1733 }
1734 if (!mayBeUnlinkable && result && !result->isLinkable())
1735 {
1736 if (!mayBeHidden || !result->isHidden())
1737 {
1738 AUTO_TRACE_ADD("hiding symbol {}",result->name());
1739 result=nullptr; // don't link to artificial/hidden classes unless explicitly allowed
1740 }
1741 }
1742 AUTO_TRACE_EXIT("result={}",result?result->name():DString());
1743 return result;
1744}
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
Definition dstring.h:182
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition dstring.h:341
bool startsWith(const char *s) const
Definition dstring.h:604
virtual SrcLangExt getLanguage() const =0
Returns the programming language this definition was written in.
virtual bool isLinkable() const =0
virtual DefType definitionType() const =0
virtual bool isHidden() const =0
static NamespaceDefMutable * globalScope
Definition doxygen.h:114
ClassDef * getClass(const DString &n)
#define Config_getBool(name)
Definition config.h:33
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:52
DString mangleCSharpGenericName(const DString &name)
Definition util.cpp:5321

References AUTO_TRACE, AUTO_TRACE_ADD, AUTO_TRACE_EXIT, Config_getBool, Definition::definitionType(), getClass(), Definition::getLanguage(), getTypeLookupCache(), Doxygen::globalScope, Definition::isHidden(), Definition::isLinkable(), mangleCSharpGenericName(), Definition::name(), DString::npos, p, DString::startsWith(), DString::stripWhiteSpace(), Definition::TypeClass, and Definition::TypeNamespace.

Referenced by findClassDefinition(), findClassWithinClassContext(), findUsingDeclImports(), getCanonicalTypeForIdentifier(), isVarWithConstructor(), linkifyText(), normalizeNonTemplateArgumentsInString(), and resolveClassMutable().

◆ resolveClassMutable()

ClassDefMutable * SymbolResolver::resolveClassMutable ( const Definition * scope,
const DString & name,
bool mayBeUnlinkable = false,
bool mayBeHidden = false )
inline

Wrapper around resolveClass that returns a mutable interface to the class object or a nullptr if the symbol is immutable.

Definition at line 57 of file symbolresolver.h.

61 {
62 return toClassDefMutable(const_cast<ClassDef*>(resolveClass(scope,name,mayBeUnlinkable,mayBeHidden)));
63 }
const ClassDef * resolveClass(const Definition *scope, const DString &name, bool maybeUnlinkable=false, bool mayBeHidden=false)
Find the class definition matching name within the scope set.
ClassDefMutable * toClassDefMutable(Definition *d)

References resolveClass(), and toClassDefMutable().

Referenced by ClassDefImpl::addTypeConstraint(), findClassRelation(), findUsedClassesForClass(), and resolveTemplateInstanceInType().

◆ resolveSymbol()

const Definition * SymbolResolver::resolveSymbol ( const Definition * scope,
const DString & name,
const DString & args = DString(),
bool checkCV = false,
bool insideCode = false,
bool onlyLinkable = false )

Find the symbool definition matching name within the scope set.

Parameters
scopeThe scope to search from.
nameThe name of the symbol.
argsArgument list associated with the symbol (for functions)
checkCVCheck const/volatile qualifiers (for methods)
insideCodeIs the symbol found in a code fragment
onlyLinkableOnly search linkable definitions

Definition at line 1746 of file symbolresolver.cpp.

1752{
1753 AUTO_TRACE("scope={} name={} args={} checkCV={} insideCode={}",
1754 scope?scope->name():DString(), name, args, checkCV, insideCode);
1755 p->reset();
1756 if (scope==nullptr) scope=Doxygen::globalScope;
1757 VisitedKeys visitedKeys;
1758 const Definition *result = p->getResolvedSymbolRec(getSymbolLookupCache(),visitedKeys,scope,name,args,checkCV,insideCode,onlyLinkable,&p->typeDef,&p->templateSpec,&p->resolvedType);
1759 AUTO_TRACE_EXIT("result={}{}", qPrint(result?result->qualifiedName():DString()),
1760 qPrint(result && result->definitionType()==Definition::TypeMember ? toMemberDef(result)->argsString() : DString()));
1761 return result;
1762}
DString()=default
virtual DString qualifiedName() const =0
const char * qPrint(const char *s)
Definition dstring.h:787
MemberDef * toMemberDef(Definition *d)
static LookupCache & getSymbolLookupCache()

References AUTO_TRACE, AUTO_TRACE_EXIT, Definition::definitionType(), DString::DString(), getSymbolLookupCache(), Doxygen::globalScope, Definition::name(), p, qPrint(), Definition::qualifiedName(), toMemberDef(), and Definition::TypeMember.

Referenced by findUsingDeclarations(), findUsingDeclImports(), getDefs(), and linkifyText().

◆ setFileScope()

void SymbolResolver::setFileScope ( const FileDef * fd)

Sets or updates the file scope using when resolving symbols.

Definition at line 1790 of file symbolresolver.cpp.

1791{
1792 p->setFileScope(fileScope);
1793}

References p.

Referenced by getDefs().

◆ showCacheUsage()

void SymbolResolver::showCacheUsage ( )
static

Show usage of the type lookup cache.

Definition at line 1871 of file symbolresolver.cpp.

1872{
1873 // merge the stats of the main thread
1876
1877 std::lock_guard lock1(g_typeCacheStatistics.mutex);
1878 std::lock_guard lock2(g_symbolCacheStatistics.mutex);
1879
1880 msg("type lookup cache used {}/{} hits={} misses={}\n",
1885 msg("symbol lookup cache used {}/{} hits={} misses={}\n",
1890 int typeCacheParam = computeIdealCacheParam(static_cast<size_t>(g_typeCacheStatistics.misses*2/3)); // part of the cache is flushed, hence the 2/3 correction factor
1891 int symbolCacheParam = computeIdealCacheParam(static_cast<size_t>(g_symbolCacheStatistics.misses*2/3)); // part of the cache is flushed, hence the 2/3 correction factor
1892 int cacheParam = std::max(typeCacheParam,symbolCacheParam);
1893 if (cacheParam>Config_getInt(LOOKUP_CACHE_SIZE))
1894 {
1895 msg("Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is {} at the cost of higher memory usage.\n",cacheParam);
1896 }
1897}
#define Config_getInt(name)
Definition config.h:34
#define msg(fmt,...)
Definition message.h:94
static void mergeStatistics(CacheStatistics &stats, LookupCache &cache)
static int computeIdealCacheParam(size_t v)
static CacheStatistics g_symbolCacheStatistics
static CacheStatistics g_typeCacheStatistics

References CacheStatistics::capacity, computeIdealCacheParam(), Config_getInt, g_symbolCacheStatistics, g_typeCacheStatistics, getSymbolLookupCache(), getTypeLookupCache(), CacheStatistics::hits, mergeStatistics(), CacheStatistics::misses, msg, CacheStatistics::mutex, and CacheStatistics::size.

Referenced by generateOutput().

Member Data Documentation

◆ p


The documentation for this class was generated from the following files: