20 #ifndef symboldatabaseH
21 #define symboldatabaseH
73 } needInitialization = NeedInitialization::Unknown;
83 return this->type < rhs.
type;
100 explicit Type(
const Token* classDef_ =
nullptr,
const Scope* classScope_ =
nullptr,
const Scope* enclosingScope_ =
nullptr) :
102 classScope(classScope_),
103 enclosingScope(enclosingScope_) {
104 if (classDef_ && classDef_->str() ==
"enum")
105 needInitialization = NeedInitialization::True;
106 else if (classDef_ && classDef_->str() ==
"using") {
107 typeStart = classDef->
tokAt(3);
109 while (typeEnd->next() && typeEnd->next()->str() !=
";") {
111 typeEnd = typeEnd->
linkAt(1);
113 typeEnd = typeEnd->
next();
118 std::string name()
const;
120 const std::string&
type()
const {
124 bool isClassType()
const;
125 bool isEnumType()
const;
126 bool isStructType()
const;
127 bool isUnionType()
const;
130 return classDef && classDef->
str() ==
"using";
142 bool hasCircularDependencies(std::set<BaseInfo>* ancestors =
nullptr)
const;
149 bool findDependency(
const Type* ancestor)
const;
151 bool isDerivedFrom(
const std::string & ancestor)
const;
168 fIsMutable = (1 << 0),
169 fIsStatic = (1 << 1),
171 fIsExtern = (1 << 3),
174 fIsPointer = (1 << 6),
175 fIsReference = (1 << 7),
176 fIsRValueRef = (1 << 8),
177 fHasDefault = (1 << 9),
178 fIsStlType = (1 << 10),
179 fIsStlString = (1 << 11),
180 fIsFloatType = (1 << 12),
181 fIsVolatile = (1 << 13),
182 fIsSmartPointer = (1 << 14),
183 fIsMaybeUnused = (1 << 15),
193 return ((mFlags & flag_) != 0);
201 void setFlag(
unsigned int flag_,
bool state_) {
202 mFlags = state_ ? mFlags | flag_ : mFlags & ~flag_;
211 bool arrayDimensions(
const Settings& settings,
bool& isContainer);
218 mTypeStartToken(start_),
257 return mTypeStartToken;
269 return mTypeEndToken;
279 const Token *declEndToken()
const;
285 const std::string &
name()
const {
288 return mNameToken->str();
300 return mNameToken->varId();
374 bool isMember()
const;
381 return getFlag(fIsMutable);
389 return getFlag(fIsVolatile);
397 return getFlag(fIsStatic);
405 return getFlag(fIsExtern);
413 return getFlag(fIsConst);
429 return getFlag(fIsClass);
437 return getFlag(fIsArray) && !getFlag(fIsPointer);
445 return getFlag(fIsPointer);
453 return isPointer() && getFlag(fIsArray);
460 bool isPointerArray()
const;
467 return getFlag(fIsArray) || getFlag(fIsPointer);
475 return getFlag(fIsReference);
483 return getFlag(fIsRValueRef);
490 bool isUnsigned()
const;
497 return getFlag(fHasDefault);
505 return getFlag(fIsInit);
521 return mType ? mType->classScope :
nullptr;
545 return mDimensions.at(index_).num;
553 return mDimensions.at(index_).known;
557 mDimensions = dimensions_;
569 return getFlag(fIsStlType);
581 return getFlag(fIsStlString);
584 bool isStlStringViewType()
const;
587 return getFlag(fIsSmartPointer);
590 const Type* smartPointerType()
const;
591 const Type* iteratorType()
const;
604 return isStlType() && stlType==mTypeStartToken->strAt(2);
617 bool isStlType(
const std::set<std::string>& stlTypes)
const {
618 return isStlType() && stlTypes.find(mTypeStartToken->strAt(2))!=stlTypes.end();
626 return getFlag(fIsFloatType);
634 return type() && type()->isEnumType();
638 return getFlag(fIsMaybeUnused);
645 void setValueType(
const ValueType &valueType);
651 std::string getTypeName()
const;
705 fIsInline = (1 << 1),
707 fHasVirtualSpecifier = (1 << 3),
709 fIsStatic = (1 << 5),
710 fIsStaticLocal = (1 << 6),
711 fIsExtern = (1 << 7),
712 fIsFriend = (1 << 8),
713 fIsExplicit = (1 << 9),
714 fIsDefault = (1 << 10),
715 fIsDelete = (1 << 11),
716 fHasOverrideSpecifier = (1 << 12),
717 fHasFinalSpecifier = (1 << 13),
718 fIsNoExcept = (1 << 14),
719 fIsThrow = (1 << 15),
720 fIsOperator = (1 << 16),
721 fHasLvalRefQual = (1 << 17),
722 fHasRvalRefQual = (1 << 18),
723 fIsVariadic = (1 << 19),
724 fIsVolatile = (1 << 20),
725 fHasTrailingReturnType = (1 << 21),
726 fIsEscapeFunction = (1 << 22),
727 fIsInlineKeyword = (1 << 23),
728 fIsConstexpr = (1 << 24),
737 return ((mFlags & flag) != 0);
746 mFlags = state ? mFlags | flag : mFlags & ~flag;
750 enum Type {
eConstructor, eCopyConstructor, eMoveConstructor, eOperatorEqual, eDestructor, eFunction, eLambda };
753 Function(
const Token *tokenDef,
const std::string &clangType);
755 const std::string &
name()
const {
756 return tokenDef->str();
759 std::string fullName()
const;
762 return argumentList.size();
765 return argumentList.size() - initArgCount;
774 bool isImplicitlyVirtual(
bool defaultVal =
false)
const;
776 std::vector<const Function*> getOverloadedFunctions()
const;
779 const Function *getOverriddenFunction(
bool *foundAllBaseClasses =
nullptr)
const;
782 return type==eLambda;
786 return type==eConstructor ||
787 type==eCopyConstructor ||
788 type==eMoveConstructor;
792 return type==eDestructor;
795 return tokenDef->isAttributeConstructor();
798 return tokenDef->isAttributeDestructor();
801 return tokenDef->isAttributePure();
804 return tokenDef->isAttributeConst();
807 return tokenDef->isAttributeNoreturn();
810 return tokenDef->isAttributeNothrow();
813 return tokenDef->isAttributeNodiscard();
817 return getFlag(fHasBody);
820 return getFlag(fIsInline);
823 return getFlag(fIsConst);
826 return getFlag(fHasVirtualSpecifier);
829 return getFlag(fIsPure);
832 return getFlag(fIsStatic);
835 return getFlag(fIsStaticLocal);
838 return getFlag(fIsExtern);
841 return getFlag(fIsFriend);
844 return getFlag(fIsExplicit);
847 return getFlag(fIsDefault);
850 return getFlag(fIsDelete);
853 return getFlag(fIsNoExcept);
856 return getFlag(fIsThrow);
859 return getFlag(fHasOverrideSpecifier);
862 return getFlag(fHasFinalSpecifier);
865 return getFlag(fIsOperator);
868 return getFlag(fHasLvalRefQual);
871 return getFlag(fHasRvalRefQual);
874 return getFlag(fIsVariadic);
877 return getFlag(fIsVolatile);
880 return getFlag(fHasTrailingReturnType);
883 setFlag(fHasBody, state);
886 return getFlag(fIsInlineKeyword);
890 return getFlag(fIsEscapeFunction);
893 setFlag(fIsEscapeFunction, state);
897 return getFlag(fIsConstexpr);
900 setFlag(fIsConstexpr, state);
902 bool isSafe(
const Settings &settings)
const;
909 const ::Type* retType{};
918 const Token* functionPointerUsage{};
921 bool argsMatch(
const Scope *scope,
const Token *first,
const Token *second,
const std::string &path,
nonneg int path_length)
const;
923 static bool returnsConst(
const Function*
function,
bool unknown =
false);
925 static bool returnsPointer(
const Function*
function,
bool unknown =
false);
926 static bool returnsReference(
const Function*
function,
bool unknown =
false,
bool includeRValueRef =
false);
927 static bool returnsStandardType(
const Function*
function,
bool unknown =
false);
929 static bool returnsVoid(
const Function*
function,
bool unknown =
false);
931 static std::vector<const Token*> findReturns(
const Function* f);
934 if (this->hasTrailingReturnType())
943 const Token * constructorMemberInitialization()
const;
947 const Function * getOverriddenFunctionRecursive(const ::Type* baseType,
bool *foundAllBaseClasses)
const;
949 unsigned int mFlags{};
952 setFlag(fIsInline, state);
955 setFlag(fIsConst, state);
958 setFlag(fHasVirtualSpecifier, state);
961 setFlag(fIsPure, state);
964 setFlag(fIsStatic, state);
967 setFlag(fIsStaticLocal, state);
970 setFlag(fIsExtern, state);
973 setFlag(fIsFriend, state);
976 setFlag(fIsExplicit, state);
979 setFlag(fIsDefault, state);
982 setFlag(fIsDelete, state);
985 setFlag(fIsNoExcept, state);
988 setFlag(fIsThrow, state);
991 setFlag(fIsOperator, state);
994 setFlag(fHasLvalRefQual, state);
997 setFlag(fHasRvalRefQual, state);
1000 setFlag(fIsVariadic, state);
1003 setFlag(fIsVolatile, state);
1006 setFlag(fHasTrailingReturnType, state);
1009 setFlag(fIsInlineKeyword, state);
1016 friend class TestSymbolDatabase;
1024 enum ScopeType { eGlobal, eClass, eStruct, eUnion, eNamespace, eFunction, eIf, eElse, eFor, eWhile, eDo, eSwitch, eUnconditional, eTry,
eCatch, eLambda, eEnum };
1059 bodyEnd = start ? start->
link() :
nullptr;
1061 bodyStartList.push_back(start);
1066 return className.size() > 9 &&
startsWith(className,
"Anonymous") && std::isdigit(className[9]);
1070 auto it = std::find_if(enumeratorList.cbegin(), enumeratorList.cend(), [&](
const Enumerator& i) {
1071 return i.name->str() == name;
1073 return it == enumeratorList.end() ? nullptr : &*it;
1081 const Scope * parent = nestedIn;
1082 while (outer != parent && parent)
1084 return parent && parent == outer;
1099 return (type == eClass || type == eStruct);
1103 return (type == eClass || type == eStruct || type == eUnion);
1107 return type != eClass && type != eStruct && type != eUnion && type != eGlobal && type != eNamespace && type != eEnum;
1111 return type == Scope::ScopeType::eFor || type == Scope::ScopeType::eWhile || type == Scope::ScopeType::eDo;
1115 return (type == eIf || type == eElse ||
1116 type == eFor || type == eWhile || type == eDo ||
1117 type == eSwitch || type == eUnconditional ||
1118 type == eTry || type == eCatch);
1122 bool hasInlineOrLambdaFunction()
const;
1130 const Function *findFunction(
const Token *tok,
bool requireConst=
false)
const;
1132 const Scope *findRecordInNestedList(
const std::string & name,
bool isC =
false)
const;
1133 Scope *findRecordInNestedList(
const std::string & name,
bool isC =
false);
1135 const Type* findType(
const std::string& name)
const;
1136 Type* findType(
const std::string& name);
1142 Scope *findInNestedListRecursive(
const std::string & name);
1144 void addVariable(
const Token *token_,
const Token *start_,
1149 void getVariableList(
const Settings& settings);
1151 const Function *getDestructor()
const;
1154 functionList.push_back(std::move(func));
1156 const Function * back = &functionList.back();
1158 functionMap.insert(make_pair(back->
tokenDef->
str(), back));
1177 const Variable *getVariable(
const std::string &varname)
const;
1181 const Scope *findRecordInBase(
const std::string &name)
const;
1183 std::vector<const Scope*> findAssociatedScopes()
const;
1193 bool isVariableDeclaration(
const Token*
const tok,
const Token*& vartok,
const Token*& typetok)
const;
1195 void findFunctionInBase(
const std::string & name,
nonneg int args, std::vector<const Function *> & matches)
const;
1198 void getVariableList(
const Settings& settings,
const Token *start,
const Token *end);
1210 enum Sign { UNKNOWN_SIGN, SIGNED, UNSIGNED }
sign = UNKNOWN_SIGN;
1231 } type = UNKNOWN_TYPE;
1239 const ::Type* smartPointerType{};
1274 originalTypeName(std::move(otn))
1279 static Type typeFromString(
const std::string &typestr,
bool longType);
1281 enum class MatchResult { UNKNOWN, SAME, FALLBACK1, FALLBACK2, NOMATCH };
1286 return (type >= ValueType::Type::BOOL);
1290 return (type >= ValueType::Type::BOOL && type <= ValueType::Type::UNKNOWN_INT);
1294 return (type >= ValueType::Type::FLOAT && type <= ValueType::Type::LONGDOUBLE);
1297 bool fromLibraryType(
const std::string &typestr,
const Settings &settings);
1303 bool isConst(
nonneg int indirect = 0)
const;
1305 bool isVolatile(
nonneg int indirect = 0)
const;
1310 bool isTypeEqual(
const ValueType* that)
const;
1312 std::string str()
const;
1313 std::string dump()
const;
1320 friend class TestSymbolDatabase;
1343 const Type* findVariableType(
const Scope* start,
const Token* typeTok)
const;
1353 const Scope* findScopeByName(
const std::string& name)
const;
1355 const Type* findType(
const Token* startTok,
const Scope* startScope,
bool lookOutside =
false)
const;
1358 return const_cast<Type*
>(this->findType(startTok,
const_cast<const Scope*
>(startScope), lookOutside));
1361 const Scope *findScope(
const Token *tok,
const Scope *startScope)
const;
1363 return const_cast<Scope *
>(this->findScope(tok,
const_cast<const Scope *
>(startScope)));
1368 return varid < mVariableList.size();
1372 return mVariableList.at(varId);
1376 return mVariableList;
1382 void debugMessage(
const Token *tok,
const std::string &type,
const std::string &msg)
const;
1384 void returnImplicitIntError(
const Token *tok)
const;
1386 void printOut(
const char * title =
nullptr)
const;
1387 void printVariable(
const Variable *var,
const char *
indent)
const;
1388 void printXml(std::ostream &out)
const;
1393 void validate()
const;
1396 void setValueTypeInTokenList(
bool reportDebugWarnings,
Token *tokens=
nullptr);
1406 void setArrayDimensionsUsingValueFlow();
1408 void clangSetVariables(
const std::vector<const Variable *> &variableList);
1409 void createSymbolDatabaseExprIds();
1416 void createSymbolDatabaseFindAllScopes();
1417 void createSymbolDatabaseClassInfo();
1418 void createSymbolDatabaseVariableInfo();
1419 void createSymbolDatabaseCopyAndMoveConstructors();
1420 void createSymbolDatabaseFunctionScopes();
1421 void createSymbolDatabaseClassAndStructScopes();
1422 void createSymbolDatabaseFunctionReturnTypes();
1423 void createSymbolDatabaseNeedInitialization();
1424 void createSymbolDatabaseVariableSymbolTable();
1425 void createSymbolDatabaseSetScopePointers();
1426 void createSymbolDatabaseSetFunctionPointers(
bool firstPass);
1427 void createSymbolDatabaseSetVariablePointers();
1429 void createSymbolDatabaseSetTypePointers();
1430 void createSymbolDatabaseSetSmartPointerType();
1431 void createSymbolDatabaseEnums();
1432 void createSymbolDatabaseEscapeFunctions();
1434 void createSymbolDatabaseIncompleteVars();
1436 void debugSymbolDatabase()
const;
1438 void addClassFunction(
Scope *&scope,
const Token *&tok,
const Token *argStart);
1441 void addNewFunction(
Scope *&scope,
const Token *&tok);
1442 bool isFunction(
const Token *tok,
const Scope* outerScope,
const Token *&funcStart,
const Token *&argStart,
const Token*& declEnd)
const;
1443 const Type *findTypeInNested(
const Token *startTok,
const Scope *startScope)
const;
1444 const Scope *findNamespace(
const Token * tok,
const Scope * scope)
const;
1445 static Function *findFunctionInScope(
const Token *func,
const Scope *ns,
const std::string & path,
nonneg int path_length);
1446 static const Type *findVariableTypeInBase(
const Scope *scope,
const Token *typeTok);
1454 static bool isReservedName(
const Token* tok);
1456 const Enumerator * findEnumerator(
const Token * tok, std::set<std::string>& tokensThatAreNotEnumeratorValues)
const;
1462 void validateExecutableScopes()
const;
1466 void validateVariables()
const;
static int sign(const T v)
This is an interface, which the class responsible of error logging should implement.
void isOperator(bool state)
void isDefault(bool state)
bool isInlineKeyword() const
bool isAttributeConst() const
bool isAttributeNodiscard() const
const Token * returnDefEnd() const
bool getFlag(unsigned int flag) const
Get specified flag state.
nonneg int initializedArgCount() const
nonneg int minArgCount() const
bool hasFinalSpecifier() const
void isFriend(bool state)
const std::string & name() const
void hasRvalRefQualifier(bool state)
void isDelete(bool state)
void hasLvalRefQualifier(bool state)
bool isAttributeConstructor() const
bool hasRvalRefQualifier() const
bool hasLvalRefQualifier() const
void isInlineKeyword(bool state)
void isInline(bool state)
bool isAttributeNoreturn() const
void hasTrailingReturnType(bool state)
nonneg int argCount() const
bool hasTrailingReturnType() const
void hasVirtualSpecifier(bool state)
void isExplicit(bool state)
void isEscapeFunction(bool state)
void isExtern(bool state)
bool isEscapeFunction() const
void isNoExcept(bool state)
bool hasOverrideSpecifier() const
bool hasVirtualSpecifier() const
const Token * tokenDef
function name token in class definition
void isVariadic(bool state)
bool isAttributeDestructor() const
std::list< Variable > argumentList
argument list, must remain list due to clangimport usage!
void setFlag(unsigned int flag, bool state)
Set specified flag state.
void isConstexpr(bool state)
bool isDestructor() const
bool isConstructor() const
bool isStaticLocal() const
bool isAttributeNothrow() const
void isStaticLocal(bool state)
void isVolatile(bool state)
void isStatic(bool state)
bool isAttributePure() const
std::list< Function > functionList
std::vector< UsingInfo > usingList
std::map< std::string, Type * > definedTypesMap
bool isNestedIn(const Scope *outer) const
std::list< Variable > varlist
std::multimap< std::string, const Function * > functionMap
std::vector< Scope * > nestedList
static Function * nestedInFunction(const Scope *scope)
std::vector< Enumerator > enumeratorList
Function * function
function info for this function
std::vector< const Token * > bodyStartList
void setBodyStartEnd(const Token *start)
const Enumerator * findEnumerator(const std::string &name) const
void addFunction(Function func)
bool isClassOrStructOrUnion() const
bool isExecutable() const
bool isClassOrStruct() const
This is just a container for general settings so that we don't need to pass individual values to func...
const Variable * getVariableFromVarId(nonneg int varId) const
std::vector< const Variable * > mVariableList
variable symbol table
const std::vector< const Variable * > & variableList() const
const Settings & mSettings
std::list< Type > typeList
Fast access to types.
bool isVarId(nonneg int varid) const
std::map< unsigned int, MemberIdMap > VarIdMap
std::list< Type > mBlankTypes
list for missing types
ValueType::Sign mDefaultSignedness
std::vector< const Scope * > functionScopes
Fast access to function scopes.
std::map< unsigned int, unsigned int > MemberIdMap
std::list< Scope > scopeList
Information about all namespaces/classes/structures.
ErrorLogger & mErrorLogger
Scope * findScope(const Token *tok, Scope *startScope)
Type * findType(const Token *startTok, Scope *startScope, bool lookOutside=false)
std::vector< const Scope * > classAndStructScopes
Fast access to class and struct scopes.
The token list that the TokenList generates is a linked-list of this class.
static const Token * findmatch(const Token *const startTok, const char pattern[], const nonneg int varId=0)
const Token * tokAt(int index) const
void link(Token *linkToToken)
Create link to given token.
const Token * linkAt(int index) const
static bool simpleMatch(const Token *tok, const char(&pattern)[count])
Match given token (or list of tokens) to a pattern list.
The main purpose is to tokenize the source code.
Information about a class type.
const Scope * enclosingScope
Type(const Token *classDef_=nullptr, const Scope *classScope_=nullptr, const Scope *enclosingScope_=nullptr)
const Token * classDef
Points to "class" token.
std::vector< BaseInfo > derivedFrom
std::vector< FriendInfo > friendList
const std::string & type() const
ValueType(Sign s, Type t, nonneg int p)
ValueType(Sign s, Type t, nonneg int p, nonneg int c, std::string otn)
std::string originalTypeName
original type name as written in the source code.
ErrorPath debugPath
debug path to the type
ValueType(Sign s, Type t, nonneg int p, nonneg int c, nonneg int v)
ValueType(Sign s, Type t, nonneg int p, nonneg int c)
Information about a member variable.
bool hasDefault() const
Does variable have a default value.
bool isArgument() const
Is variable a function argument.
const Token * mTypeStartToken
variable type start token
void type(const Type *t)
Set Type pointer to known type.
bool isEnumType() const
Determine whether it's an enumeration type.
Variable(const Token *name_, const Token *start_, const Token *end_, nonneg int index_, AccessControl access_, const Type *type_, const Scope *scope_, const Settings &settings)
bool isClass() const
Is variable a user defined (or unknown) type.
const Type * mType
pointer to user defined type info (for known types)
bool isArrayOrPointer() const
Is array or pointer variable.
bool isExtern() const
Is variable extern.
const Token * mNameToken
variable name token
bool isProtected() const
Is variable protected.
bool isReference() const
Is reference variable.
bool dimensionKnown(nonneg int index_) const
Get array dimension known.
nonneg int mIndex
order declared
bool isFloatingType() const
Determine whether it's a floating number type.
bool isMaybeUnused() const
bool isRValueReference() const
Is reference variable.
AccessControl accessControl() const
bool isStlType() const
Checks if the variable is an STL type ('std::') E.g.
bool isLocal() const
Is variable local.
bool isSmartPointer() const
const Type * type() const
Get Type pointer of known type.
const Scope * scope() const
Get Scope pointer of enclosing scope.
bool isPointerToArray() const
Is variable a pointer to an array.
bool isThrow() const
Is variable a throw type.
void setFlag(unsigned int flag_, bool state_)
Set specified flag state.
bool getFlag(unsigned int flag_) const
Get specified flag state.
const Scope * typeScope() const
Get Scope pointer of known type.
bool isGlobal() const
Is variable global.
bool isPublic() const
Is variable public.
const std::string & name() const
Get name string.
const Token * typeEndToken() const
Get type end token.
bool isConst() const
Is variable const.
bool isNamespace() const
Is variable in a namespace.
MathLib::bigint dimension(nonneg int index_) const
Get array dimension length.
bool isArray() const
Is variable an array.
const Token * nameToken() const
Get name token.
AccessControl mAccess
what section is this variable declared in?
nonneg int index() const
Get index of variable in declared order.
const Scope * mScope
pointer to scope this variable is in
void setDimensions(const std::vector< Dimension > &dimensions_)
bool isPrivate() const
Is variable private.
nonneg int declarationId() const
Get declaration ID (varId used for variable in its declaration).
bool isMutable() const
Is variable mutable.
bool isStlType(const std::set< std::string > &stlTypes) const
Checks if the variable is of any of the STL types passed as arguments ('std::') E....
std::vector< Dimension > mDimensions
array dimensions
const Token * typeStartToken() const
Get type start token.
bool isInit() const
Is variable initialized in its declaration.
bool isVolatile() const
Is variable volatile.
bool isStlType(const std::string &stlType) const
Checks if the variable is of any of the STL types passed as arguments ('std::') E....
const std::vector< Dimension > & dimensions() const
Get array dimensions.
bool isPointer() const
Is pointer variable.
bool isStlStringType() const
Checks if the variable is an STL type ('std::') E.g.
const Token * mTypeEndToken
variable type end token
bool isStatic() const
Is variable static.
const ValueType * valueType() const
static const std::string emptyString
std::list< ErrorPathItem > ErrorPath
static ValueFlow::Value evaluate(const std::string &op, const ValueFlow::Value &lhs, const ValueFlow::Value &rhs)
Array dimension information.
const Token * tok
size token
MathLib::bigint num
(assumed) dimension length when size is a number, 0 if not known
Enumerator(const Scope *scope_)
static SourceLocation current()
bool operator<(const BaseInfo &rhs) const
static const Function * getFunction(const Token *tok)
AccessControl
Access control enumerations.
static void indent(std::string &str, const nonneg int indent1, const nonneg int indent2)
bool startsWith(const std::string &str, const char start[], std::size_t startlen)