2010-11-13 08:08:45 +01:00
|
|
|
/*
|
|
|
|
* Cppcheck - A tool for static C/C++ code analysis
|
2023-01-28 10:16:34 +01:00
|
|
|
* Copyright (C) 2007-2023 Cppcheck team.
|
2010-11-13 08:08:45 +01:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
2013-09-04 20:59:49 +02:00
|
|
|
#ifndef symboldatabaseH
|
|
|
|
#define symboldatabaseH
|
2010-11-13 08:08:45 +01:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2012-06-10 14:19:09 +02:00
|
|
|
#include "config.h"
|
2022-08-14 12:44:19 +02:00
|
|
|
#include "errortypes.h"
|
2017-03-05 02:09:52 +01:00
|
|
|
#include "library.h"
|
2017-05-27 04:33:47 +02:00
|
|
|
#include "mathlib.h"
|
2022-06-15 21:25:55 +02:00
|
|
|
#include "sourcelocation.h"
|
2017-05-27 04:33:47 +02:00
|
|
|
#include "token.h"
|
2011-01-18 07:32:06 +01:00
|
|
|
|
2023-03-02 21:50:14 +01:00
|
|
|
#include <algorithm>
|
2021-04-03 21:30:50 +02:00
|
|
|
#include <cctype>
|
2022-01-27 19:03:20 +01:00
|
|
|
#include <iosfwd>
|
2017-05-27 04:33:47 +02:00
|
|
|
#include <list>
|
|
|
|
#include <map>
|
2022-01-27 19:03:20 +01:00
|
|
|
#include <memory>
|
2017-05-27 04:33:47 +02:00
|
|
|
#include <set>
|
|
|
|
#include <string>
|
2022-04-13 12:24:00 +02:00
|
|
|
#include <type_traits>
|
2017-05-27 04:33:47 +02:00
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
2010-11-13 08:08:45 +01:00
|
|
|
|
2020-04-13 13:44:48 +02:00
|
|
|
namespace cppcheck {
|
|
|
|
class Platform;
|
|
|
|
}
|
|
|
|
|
2017-05-27 04:33:47 +02:00
|
|
|
class ErrorLogger;
|
|
|
|
class Function;
|
2011-01-17 18:29:19 +01:00
|
|
|
class Scope;
|
2017-05-27 04:33:47 +02:00
|
|
|
class Settings;
|
2011-01-17 07:21:59 +01:00
|
|
|
class SymbolDatabase;
|
2017-05-27 04:33:47 +02:00
|
|
|
class Tokenizer;
|
|
|
|
class ValueType;
|
2011-01-17 07:21:59 +01:00
|
|
|
|
|
|
|
/**
|
2011-01-18 07:32:06 +01:00
|
|
|
* @brief Access control enumerations.
|
2011-01-17 07:21:59 +01:00
|
|
|
*/
|
2019-07-23 14:29:02 +02:00
|
|
|
enum class AccessControl { Public, Protected, Private, Global, Namespace, Argument, Local, Throw };
|
2011-01-17 07:21:59 +01:00
|
|
|
|
2011-06-23 04:41:11 +02:00
|
|
|
/**
|
|
|
|
* @brief Array dimension information.
|
|
|
|
*/
|
2011-10-13 20:53:06 +02:00
|
|
|
struct Dimension {
|
2021-08-07 20:51:18 +02:00
|
|
|
Dimension() : tok(nullptr), num(0), known(true) {}
|
2011-08-28 19:32:42 +02:00
|
|
|
|
2019-03-15 19:00:42 +01:00
|
|
|
const Token *tok; ///< size token
|
2018-04-24 13:03:32 +02:00
|
|
|
MathLib::bigint num; ///< (assumed) dimension length when size is a number, 0 if not known
|
|
|
|
bool known; ///< Known size
|
2011-06-23 04:41:11 +02:00
|
|
|
};
|
|
|
|
|
2013-03-05 13:33:38 +01:00
|
|
|
/** @brief Information about a class type. */
|
|
|
|
class CPPCHECKLIB Type {
|
|
|
|
public:
|
2018-04-24 13:03:32 +02:00
|
|
|
const Token* classDef; ///< Points to "class" token
|
2013-03-05 13:33:38 +01:00
|
|
|
const Scope* classScope;
|
|
|
|
const Scope* enclosingScope;
|
2019-08-02 21:14:29 +02:00
|
|
|
enum class NeedInitialization {
|
2013-03-05 13:33:38 +01:00
|
|
|
Unknown, True, False
|
|
|
|
} needInitialization;
|
|
|
|
|
2014-03-29 12:21:35 +01:00
|
|
|
class BaseInfo {
|
|
|
|
public:
|
2014-01-06 08:02:04 +01:00
|
|
|
BaseInfo() :
|
2021-08-07 20:51:18 +02:00
|
|
|
type(nullptr), nameTok(nullptr), access(AccessControl::Public), isVirtual(false) {}
|
2014-01-06 08:02:04 +01:00
|
|
|
|
2013-03-05 15:28:40 +01:00
|
|
|
std::string name;
|
|
|
|
const Type* type;
|
|
|
|
const Token* nameTok;
|
|
|
|
AccessControl access; // public/protected/private
|
|
|
|
bool isVirtual;
|
2014-03-29 12:21:35 +01:00
|
|
|
// allow ordering within containers
|
2014-11-20 14:20:09 +01:00
|
|
|
bool operator<(const BaseInfo& rhs) const {
|
2014-03-29 12:21:35 +01:00
|
|
|
return this->type < rhs.type;
|
|
|
|
}
|
2013-03-05 15:28:40 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
struct FriendInfo {
|
2014-01-06 08:02:04 +01:00
|
|
|
FriendInfo() :
|
2021-08-07 20:51:18 +02:00
|
|
|
nameStart(nullptr), nameEnd(nullptr), type(nullptr) {}
|
2014-01-06 08:02:04 +01:00
|
|
|
|
2013-03-05 15:28:40 +01:00
|
|
|
const Token* nameStart;
|
|
|
|
const Token* nameEnd;
|
|
|
|
const Type* type;
|
|
|
|
};
|
|
|
|
|
|
|
|
std::vector<BaseInfo> derivedFrom;
|
2018-05-14 12:18:59 +02:00
|
|
|
std::vector<FriendInfo> friendList;
|
2013-03-05 15:28:40 +01:00
|
|
|
|
2018-01-10 22:16:18 +01:00
|
|
|
const Token * typeStart;
|
|
|
|
const Token * typeEnd;
|
2020-01-18 11:07:36 +01:00
|
|
|
MathLib::bigint sizeOf;
|
2018-01-10 22:16:18 +01:00
|
|
|
|
2022-06-07 21:15:13 +02:00
|
|
|
explicit Type(const Token* classDef_ = nullptr, const Scope* classScope_ = nullptr, const Scope* enclosingScope_ = nullptr) :
|
2013-03-05 13:33:38 +01:00
|
|
|
classDef(classDef_),
|
|
|
|
classScope(classScope_),
|
|
|
|
enclosingScope(enclosingScope_),
|
2019-08-02 21:14:29 +02:00
|
|
|
needInitialization(NeedInitialization::Unknown),
|
2018-01-10 22:16:18 +01:00
|
|
|
typeStart(nullptr),
|
2020-01-18 11:07:36 +01:00
|
|
|
typeEnd(nullptr),
|
|
|
|
sizeOf(0) {
|
2016-04-22 06:02:54 +02:00
|
|
|
if (classDef_ && classDef_->str() == "enum")
|
2019-08-02 21:14:29 +02:00
|
|
|
needInitialization = NeedInitialization::True;
|
2018-01-10 22:16:18 +01:00
|
|
|
else if (classDef_ && classDef_->str() == "using") {
|
|
|
|
typeStart = classDef->tokAt(3);
|
|
|
|
typeEnd = typeStart;
|
2022-12-18 16:46:04 +01:00
|
|
|
while (typeEnd->next() && typeEnd->next()->str() != ";") {
|
|
|
|
if (Token::simpleMatch(typeEnd, "decltype ("))
|
|
|
|
typeEnd = typeEnd->linkAt(1);
|
|
|
|
else
|
|
|
|
typeEnd = typeEnd->next();
|
|
|
|
}
|
2018-01-10 22:16:18 +01:00
|
|
|
}
|
2013-03-05 13:33:38 +01:00
|
|
|
}
|
|
|
|
|
2016-04-22 06:02:54 +02:00
|
|
|
const std::string& name() const;
|
|
|
|
|
2016-08-04 09:06:32 +02:00
|
|
|
const std::string& type() const {
|
|
|
|
return classDef ? classDef->str() : emptyString;
|
|
|
|
}
|
|
|
|
|
2020-10-02 20:22:09 +02:00
|
|
|
bool isClassType() const;
|
|
|
|
bool isEnumType() const;
|
|
|
|
bool isStructType() const;
|
|
|
|
bool isUnionType() const;
|
2013-03-05 15:28:40 +01:00
|
|
|
|
2018-01-10 22:16:18 +01:00
|
|
|
bool isTypeAlias() const {
|
|
|
|
return classDef && classDef->str() == "using";
|
|
|
|
}
|
|
|
|
|
2013-03-05 15:28:40 +01:00
|
|
|
const Token *initBaseInfo(const Token *tok, const Token *tok1);
|
2013-03-14 17:00:22 +01:00
|
|
|
|
|
|
|
const Function* getFunction(const std::string& funcName) const;
|
2014-03-29 12:21:35 +01:00
|
|
|
|
|
|
|
/**
|
2021-08-07 20:51:18 +02:00
|
|
|
* Check for circulare dependencies, i.e. loops within the class hierarchy
|
|
|
|
* @param ancestors list of ancestors. For internal usage only, clients should not supply this argument.
|
|
|
|
* @return true if there is a circular dependency
|
|
|
|
*/
|
2015-09-04 15:12:40 +02:00
|
|
|
bool hasCircularDependencies(std::set<BaseInfo>* ancestors = nullptr) const;
|
2015-07-01 00:04:01 +02:00
|
|
|
|
2015-07-01 07:50:13 +02:00
|
|
|
/**
|
2021-08-07 20:51:18 +02:00
|
|
|
* Check for dependency
|
|
|
|
* @param ancestor potential ancestor
|
|
|
|
* @return true if there is a dependency
|
|
|
|
*/
|
2015-09-04 15:12:40 +02:00
|
|
|
bool findDependency(const Type* ancestor) const;
|
2016-08-19 19:06:15 +02:00
|
|
|
|
|
|
|
bool isDerivedFrom(const std::string & ancestor) const;
|
2013-03-05 13:33:38 +01:00
|
|
|
};
|
|
|
|
|
2016-04-22 06:02:54 +02:00
|
|
|
class CPPCHECKLIB Enumerator {
|
|
|
|
public:
|
2021-08-07 20:51:18 +02:00
|
|
|
explicit Enumerator(const Scope * scope_) : scope(scope_), name(nullptr), value(0), start(nullptr), end(nullptr), value_known(false) {}
|
2016-04-22 06:02:54 +02:00
|
|
|
const Scope * scope;
|
|
|
|
const Token * name;
|
|
|
|
MathLib::bigint value;
|
|
|
|
const Token * start;
|
|
|
|
const Token * end;
|
|
|
|
bool value_known;
|
|
|
|
};
|
|
|
|
|
2011-01-17 07:21:59 +01:00
|
|
|
/** @brief Information about a member variable. */
|
2012-06-10 14:19:09 +02:00
|
|
|
class CPPCHECKLIB Variable {
|
2011-01-18 07:32:06 +01:00
|
|
|
/** @brief flags mask used to access specific bit. */
|
2011-10-13 20:53:06 +02:00
|
|
|
enum {
|
2019-04-26 11:30:09 +02:00
|
|
|
fIsMutable = (1 << 0), /** @brief mutable variable */
|
|
|
|
fIsStatic = (1 << 1), /** @brief static variable */
|
|
|
|
fIsConst = (1 << 2), /** @brief const variable */
|
|
|
|
fIsExtern = (1 << 3), /** @brief extern variable */
|
|
|
|
fIsClass = (1 << 4), /** @brief user defined type */
|
|
|
|
fIsArray = (1 << 5), /** @brief array variable */
|
|
|
|
fIsPointer = (1 << 6), /** @brief pointer variable */
|
|
|
|
fIsReference = (1 << 7), /** @brief reference variable */
|
|
|
|
fIsRValueRef = (1 << 8), /** @brief rvalue reference variable */
|
|
|
|
fHasDefault = (1 << 9), /** @brief function argument with default value */
|
|
|
|
fIsStlType = (1 << 10), /** @brief STL type ('std::') */
|
|
|
|
fIsStlString = (1 << 11), /** @brief std::string|wstring|basic_string<T>|u16string|u32string */
|
|
|
|
fIsFloatType = (1 << 12), /** @brief Floating point type */
|
|
|
|
fIsVolatile = (1 << 13), /** @brief volatile */
|
2020-04-12 20:35:54 +02:00
|
|
|
fIsSmartPointer = (1 << 14),/** @brief std::shared_ptr|unique_ptr */
|
|
|
|
fIsMaybeUnused = (1 << 15), /** @brief marked [[maybe_unused]] */
|
2020-09-09 16:22:36 +02:00
|
|
|
fIsInit = (1 << 16), /** @brief Is variable initialized in declaration */
|
2011-01-18 07:32:06 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get specified flag state.
|
|
|
|
* @param flag_ flag to get state of
|
|
|
|
* @return true if flag set or false in flag not set
|
|
|
|
*/
|
2015-01-17 16:46:05 +01:00
|
|
|
bool getFlag(unsigned int flag_) const {
|
2018-06-16 16:14:34 +02:00
|
|
|
return ((mFlags & flag_) != 0);
|
2011-01-18 07:32:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set specified flag state.
|
|
|
|
* @param flag_ flag to set state
|
|
|
|
* @param state_ new state of flag
|
|
|
|
*/
|
2015-01-17 16:46:05 +01:00
|
|
|
void setFlag(unsigned int flag_, bool state_) {
|
2018-06-16 16:14:34 +02:00
|
|
|
mFlags = state_ ? mFlags | flag_ : mFlags & ~flag_;
|
2011-01-18 07:32:06 +01:00
|
|
|
}
|
|
|
|
|
2012-05-11 17:56:47 +02:00
|
|
|
/**
|
|
|
|
* @brief parse and save array dimension information
|
2019-03-15 19:00:42 +01:00
|
|
|
* @param settings Platform settings and library
|
2021-11-08 20:31:16 +01:00
|
|
|
* @param isContainer Is the array container-like?
|
2012-05-11 17:56:47 +02:00
|
|
|
* @return true if array, false if not
|
|
|
|
*/
|
2023-03-02 22:05:41 +01:00
|
|
|
bool arrayDimensions(const Settings* settings, bool& isContainer);
|
2012-05-11 17:56:47 +02:00
|
|
|
|
2010-11-13 08:08:45 +01:00
|
|
|
public:
|
2011-02-26 15:08:59 +01:00
|
|
|
Variable(const Token *name_, const Token *start_, const Token *end_,
|
2019-07-22 11:25:51 +02:00
|
|
|
nonneg int index_, AccessControl access_, const Type *type_,
|
2018-06-20 10:00:15 +02:00
|
|
|
const Scope *scope_, const Settings* settings)
|
2018-06-16 15:57:16 +02:00
|
|
|
: mNameToken(name_),
|
2021-08-07 20:51:18 +02:00
|
|
|
mTypeStartToken(start_),
|
|
|
|
mTypeEndToken(end_),
|
|
|
|
mIndex(index_),
|
|
|
|
mAccess(access_),
|
|
|
|
mFlags(0),
|
|
|
|
mType(type_),
|
|
|
|
mScope(scope_),
|
|
|
|
mValueType(nullptr) {
|
2018-06-20 10:00:15 +02:00
|
|
|
evaluate(settings);
|
2011-01-17 07:21:59 +01:00
|
|
|
}
|
2010-11-13 08:08:45 +01:00
|
|
|
|
2021-04-30 16:47:02 +02:00
|
|
|
Variable(const Token *name_, const std::string &clangType, const Token *typeStart,
|
|
|
|
const Token *typeEnd, nonneg int index_, AccessControl access_,
|
|
|
|
const Type *type_, const Scope *scope_);
|
|
|
|
|
2021-01-27 20:03:42 +01:00
|
|
|
Variable(const Variable &var, const Scope *scope);
|
|
|
|
|
|
|
|
Variable(const Variable &var);
|
|
|
|
|
2018-06-20 10:00:15 +02:00
|
|
|
~Variable();
|
|
|
|
|
2021-01-28 13:46:00 +01:00
|
|
|
Variable &operator=(const Variable &var);
|
2021-01-28 12:36:31 +01:00
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/**
|
|
|
|
* Get name token.
|
|
|
|
* @return name token
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
const Token *nameToken() const {
|
2018-06-16 15:57:16 +02:00
|
|
|
return mNameToken;
|
2011-01-18 07:32:06 +01:00
|
|
|
}
|
2010-11-13 08:08:45 +01:00
|
|
|
|
2011-02-20 14:25:42 +01:00
|
|
|
/**
|
|
|
|
* Get type start token.
|
2013-09-29 21:08:07 +02:00
|
|
|
* The type start token doesn't account 'static' and 'const' qualifiers
|
|
|
|
* E.g.:
|
|
|
|
* static const int * const p = ...;
|
|
|
|
* type start token ^
|
2011-02-20 14:25:42 +01:00
|
|
|
* @return type start token
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
const Token *typeStartToken() const {
|
2018-06-16 16:03:36 +02:00
|
|
|
return mTypeStartToken;
|
2011-02-20 14:25:42 +01:00
|
|
|
}
|
|
|
|
|
2011-02-26 15:08:59 +01:00
|
|
|
/**
|
|
|
|
* Get type end token.
|
2013-09-29 21:08:07 +02:00
|
|
|
* The type end token doesn't account the forward 'const' qualifier
|
|
|
|
* E.g.:
|
|
|
|
* static const int * const p = ...;
|
|
|
|
* type end token ^
|
2011-02-26 15:08:59 +01:00
|
|
|
* @return type end token
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
const Token *typeEndToken() const {
|
2018-06-16 16:03:36 +02:00
|
|
|
return mTypeEndToken;
|
2011-02-26 15:08:59 +01:00
|
|
|
}
|
|
|
|
|
2014-10-16 09:11:09 +02:00
|
|
|
/**
|
|
|
|
* Get end token of variable declaration
|
|
|
|
* E.g.
|
|
|
|
* int i[2][3] = ...
|
|
|
|
* end token ^
|
|
|
|
* @return variable declaration end token
|
|
|
|
*/
|
|
|
|
const Token *declEndToken() const;
|
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/**
|
|
|
|
* Get name string.
|
|
|
|
* @return name string
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
const std::string &name() const {
|
2011-02-27 00:34:17 +01:00
|
|
|
// name may not exist for function arguments
|
2018-06-16 15:57:16 +02:00
|
|
|
if (mNameToken)
|
|
|
|
return mNameToken->str();
|
2011-02-27 00:34:17 +01:00
|
|
|
|
2014-06-26 11:44:19 +02:00
|
|
|
return emptyString;
|
2011-01-18 07:32:06 +01:00
|
|
|
}
|
2010-12-02 07:35:01 +01:00
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/**
|
2013-07-20 12:31:04 +02:00
|
|
|
* Get declaration ID (varId used for variable in its declaration).
|
|
|
|
* @return declaration ID
|
2011-01-18 07:32:06 +01:00
|
|
|
*/
|
2019-07-22 11:25:51 +02:00
|
|
|
nonneg int declarationId() const {
|
2011-02-27 00:34:17 +01:00
|
|
|
// name may not exist for function arguments
|
2018-06-16 15:57:16 +02:00
|
|
|
if (mNameToken)
|
|
|
|
return mNameToken->varId();
|
2011-02-27 00:34:17 +01:00
|
|
|
|
|
|
|
return 0;
|
2011-01-18 07:32:06 +01:00
|
|
|
}
|
2010-11-13 08:08:45 +01:00
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/**
|
|
|
|
* Get index of variable in declared order.
|
2013-02-10 07:43:09 +01:00
|
|
|
* @return variable index
|
2011-01-18 07:32:06 +01:00
|
|
|
*/
|
2019-07-22 11:25:51 +02:00
|
|
|
nonneg int index() const {
|
2018-06-16 16:11:40 +02:00
|
|
|
return mIndex;
|
2011-01-18 07:32:06 +01:00
|
|
|
}
|
2010-11-13 08:08:45 +01:00
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/**
|
|
|
|
* Is variable public.
|
|
|
|
* @return true if public, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isPublic() const {
|
2019-07-23 14:29:02 +02:00
|
|
|
return mAccess == AccessControl::Public;
|
2011-01-18 07:32:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Is variable protected.
|
|
|
|
* @return true if protected, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isProtected() const {
|
2019-07-23 14:29:02 +02:00
|
|
|
return mAccess == AccessControl::Protected;
|
2011-01-18 07:32:06 +01:00
|
|
|
}
|
2010-11-13 08:08:45 +01:00
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/**
|
|
|
|
* Is variable private.
|
|
|
|
* @return true if private, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isPrivate() const {
|
2019-07-23 14:29:02 +02:00
|
|
|
return mAccess == AccessControl::Private;
|
2011-01-18 07:32:06 +01:00
|
|
|
}
|
|
|
|
|
2011-02-26 15:08:59 +01:00
|
|
|
/**
|
|
|
|
* Is variable global.
|
|
|
|
* @return true if global, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isGlobal() const {
|
2019-07-23 14:29:02 +02:00
|
|
|
return mAccess == AccessControl::Global;
|
2011-02-26 15:08:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Is variable in a namespace.
|
|
|
|
* @return true if in a namespace, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isNamespace() const {
|
2019-07-23 14:29:02 +02:00
|
|
|
return mAccess == AccessControl::Namespace;
|
2011-02-26 15:08:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Is variable a function argument.
|
|
|
|
* @return true if a function argument, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isArgument() const {
|
2019-07-23 14:29:02 +02:00
|
|
|
return mAccess == AccessControl::Argument;
|
2011-02-26 15:08:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Is variable local.
|
|
|
|
* @return true if local, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isLocal() const {
|
2019-07-23 14:29:02 +02:00
|
|
|
return (mAccess == AccessControl::Local) && !isExtern();
|
2011-02-26 15:08:59 +01:00
|
|
|
}
|
|
|
|
|
2022-07-10 11:33:24 +02:00
|
|
|
/**
|
|
|
|
* Is variable a member of a user-defined type.
|
|
|
|
* @return true if member, false if not or unknown
|
|
|
|
*/
|
|
|
|
bool isMember() const;
|
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/**
|
|
|
|
* Is variable mutable.
|
|
|
|
* @return true if mutable, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isMutable() const {
|
2011-01-18 07:32:06 +01:00
|
|
|
return getFlag(fIsMutable);
|
|
|
|
}
|
|
|
|
|
2016-07-18 12:43:23 +02:00
|
|
|
/**
|
|
|
|
* Is variable volatile.
|
|
|
|
* @return true if volatile, false if not
|
|
|
|
*/
|
|
|
|
bool isVolatile() const {
|
|
|
|
return getFlag(fIsVolatile);
|
|
|
|
}
|
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/**
|
|
|
|
* Is variable static.
|
|
|
|
* @return true if static, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isStatic() const {
|
2011-01-18 07:32:06 +01:00
|
|
|
return getFlag(fIsStatic);
|
|
|
|
}
|
|
|
|
|
2012-06-22 11:23:50 +02:00
|
|
|
/**
|
|
|
|
* Is variable extern.
|
|
|
|
* @return true if extern, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isExtern() const {
|
2012-06-22 11:23:50 +02:00
|
|
|
return getFlag(fIsExtern);
|
|
|
|
}
|
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/**
|
|
|
|
* Is variable const.
|
|
|
|
* @return true if const, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isConst() const {
|
2011-01-18 07:32:06 +01:00
|
|
|
return getFlag(fIsConst);
|
|
|
|
}
|
|
|
|
|
2012-01-26 04:05:29 +01:00
|
|
|
/**
|
|
|
|
* Is variable a throw type.
|
|
|
|
* @return true if throw type, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isThrow() const {
|
2019-07-23 14:29:02 +02:00
|
|
|
return mAccess == AccessControl::Throw;
|
2012-01-26 04:05:29 +01:00
|
|
|
}
|
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/**
|
|
|
|
* Is variable a user defined (or unknown) type.
|
|
|
|
* @return true if user defined type, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isClass() const {
|
2011-01-18 07:32:06 +01:00
|
|
|
return getFlag(fIsClass);
|
|
|
|
}
|
|
|
|
|
2011-02-27 16:21:14 +01:00
|
|
|
/**
|
|
|
|
* Is variable an array.
|
|
|
|
* @return true if array, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isArray() const {
|
2015-08-25 21:19:19 +02:00
|
|
|
return getFlag(fIsArray) && !getFlag(fIsPointer);
|
2011-02-27 16:21:14 +01:00
|
|
|
}
|
|
|
|
|
2011-12-17 19:04:03 +01:00
|
|
|
/**
|
2012-01-26 17:04:25 +01:00
|
|
|
* Is pointer variable.
|
2011-12-17 19:04:03 +01:00
|
|
|
* @return true if pointer, false otherwise
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isPointer() const {
|
2011-12-17 19:04:03 +01:00
|
|
|
return getFlag(fIsPointer);
|
|
|
|
}
|
|
|
|
|
2015-08-25 21:19:19 +02:00
|
|
|
/**
|
|
|
|
* Is variable a pointer to an array
|
|
|
|
* @return true if pointer to array, false otherwise
|
|
|
|
*/
|
|
|
|
bool isPointerToArray() const {
|
|
|
|
return isPointer() && getFlag(fIsArray);
|
|
|
|
}
|
|
|
|
|
2015-08-28 23:06:39 +02:00
|
|
|
/**
|
|
|
|
* Is variable an array of pointers
|
|
|
|
* @return true if array or pointers, false otherwise
|
|
|
|
*/
|
|
|
|
bool isPointerArray() const;
|
|
|
|
|
2013-08-27 05:46:09 +02:00
|
|
|
/**
|
|
|
|
* Is array or pointer variable.
|
|
|
|
* @return true if pointer or array, false otherwise
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isArrayOrPointer() const {
|
2013-08-27 05:46:09 +02:00
|
|
|
return getFlag(fIsArray) || getFlag(fIsPointer);
|
|
|
|
}
|
|
|
|
|
2012-01-26 17:04:25 +01:00
|
|
|
/**
|
|
|
|
* Is reference variable.
|
|
|
|
* @return true if reference, false otherwise
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isReference() const {
|
2012-01-26 17:04:25 +01:00
|
|
|
return getFlag(fIsReference);
|
|
|
|
}
|
|
|
|
|
2013-04-04 18:47:44 +02:00
|
|
|
/**
|
|
|
|
* Is reference variable.
|
|
|
|
* @return true if reference, false otherwise
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isRValueReference() const {
|
2013-04-04 18:47:44 +02:00
|
|
|
return getFlag(fIsRValueRef);
|
|
|
|
}
|
|
|
|
|
2020-01-11 14:00:41 +01:00
|
|
|
/**
|
|
|
|
* Is variable unsigned.
|
|
|
|
* @return true only if variable _is_ unsigned. if the sign is unknown, false is returned.
|
|
|
|
*/
|
|
|
|
bool isUnsigned() const;
|
|
|
|
|
2011-03-31 03:59:43 +02:00
|
|
|
/**
|
|
|
|
* Does variable have a default value.
|
|
|
|
* @return true if has a default falue, false if not
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool hasDefault() const {
|
2011-03-31 03:59:43 +02:00
|
|
|
return getFlag(fHasDefault);
|
|
|
|
}
|
|
|
|
|
2020-09-09 16:22:36 +02:00
|
|
|
/**
|
|
|
|
* Is variable initialized in its declaration
|
|
|
|
* @return true if variable declaration contains initialization
|
|
|
|
*/
|
|
|
|
bool isInit() const {
|
|
|
|
return getFlag(fIsInit);
|
|
|
|
}
|
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/**
|
2013-03-05 13:33:38 +01:00
|
|
|
* Get Type pointer of known type.
|
2011-01-18 07:32:06 +01:00
|
|
|
* @return pointer to type if known, NULL if not known
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
const Type *type() const {
|
2018-06-16 20:25:54 +02:00
|
|
|
return mType;
|
2011-01-18 07:32:06 +01:00
|
|
|
}
|
|
|
|
|
2013-03-05 13:33:38 +01:00
|
|
|
/**
|
|
|
|
* Get Scope pointer of known type.
|
|
|
|
* @return pointer to type scope if known, NULL if not known
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
const Scope *typeScope() const {
|
2018-06-16 20:25:54 +02:00
|
|
|
return mType ? mType->classScope : nullptr;
|
2013-03-05 13:33:38 +01:00
|
|
|
}
|
|
|
|
|
2011-02-26 15:08:59 +01:00
|
|
|
/**
|
|
|
|
* Get Scope pointer of enclosing scope.
|
|
|
|
* @return pointer to enclosing scope
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
const Scope *scope() const {
|
2018-06-16 20:29:17 +02:00
|
|
|
return mScope;
|
2011-02-26 15:08:59 +01:00
|
|
|
}
|
|
|
|
|
2011-06-23 04:41:11 +02:00
|
|
|
/**
|
|
|
|
* Get array dimensions.
|
|
|
|
* @return array dimensions vector
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
const std::vector<Dimension> &dimensions() const {
|
2018-06-16 20:23:58 +02:00
|
|
|
return mDimensions;
|
2011-06-23 04:41:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get array dimension length.
|
|
|
|
* @return length of dimension
|
|
|
|
*/
|
2019-07-22 11:25:51 +02:00
|
|
|
MathLib::bigint dimension(nonneg int index_) const {
|
2018-06-16 20:23:58 +02:00
|
|
|
return mDimensions[index_].num;
|
2011-06-23 04:41:11 +02:00
|
|
|
}
|
|
|
|
|
2013-10-04 17:30:55 +02:00
|
|
|
/**
|
|
|
|
* Get array dimension known.
|
|
|
|
* @return length of dimension known
|
|
|
|
*/
|
2019-07-22 11:25:51 +02:00
|
|
|
bool dimensionKnown(nonneg int index_) const {
|
2018-06-16 20:23:58 +02:00
|
|
|
return mDimensions[index_].known;
|
2013-10-04 17:30:55 +02:00
|
|
|
}
|
|
|
|
|
2014-09-05 12:03:08 +02:00
|
|
|
/**
|
2021-08-07 20:51:18 +02:00
|
|
|
* Checks if the variable is an STL type ('std::')
|
|
|
|
* E.g.:
|
|
|
|
* std::string s;
|
|
|
|
* ...
|
|
|
|
* sVar->isStlType() == true
|
|
|
|
* @return true if it is an stl type and its type matches any of the types in 'stlTypes'
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isStlType() const {
|
2014-09-05 12:03:08 +02:00
|
|
|
return getFlag(fIsStlType);
|
|
|
|
}
|
|
|
|
|
2014-01-28 15:44:56 +01:00
|
|
|
/**
|
|
|
|
* Checks if the variable is an STL type ('std::')
|
|
|
|
* E.g.:
|
|
|
|
* std::string s;
|
|
|
|
* ...
|
|
|
|
* sVar->isStlType() == true
|
|
|
|
* @return true if it is an stl type and its type matches any of the types in 'stlTypes'
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isStlStringType() const {
|
2014-09-05 12:03:08 +02:00
|
|
|
return getFlag(fIsStlString);
|
2014-01-28 15:44:56 +01:00
|
|
|
}
|
|
|
|
|
2019-04-26 11:30:09 +02:00
|
|
|
bool isSmartPointer() const {
|
|
|
|
return getFlag(fIsSmartPointer);
|
|
|
|
}
|
|
|
|
|
2022-07-19 20:42:54 +02:00
|
|
|
const Type* smartPointerType() const;
|
|
|
|
const Type* iteratorType() const;
|
2019-07-07 21:52:49 +02:00
|
|
|
|
2014-01-28 15:44:56 +01:00
|
|
|
/**
|
|
|
|
* Checks if the variable is of any of the STL types passed as arguments ('std::')
|
|
|
|
* E.g.:
|
|
|
|
* std::string s;
|
|
|
|
* ...
|
|
|
|
* const char *str[] = {"string", "wstring"};
|
|
|
|
* sVar->isStlType(str) == true
|
2015-08-14 18:27:03 +02:00
|
|
|
* @param stlType stl type
|
2014-01-28 15:44:56 +01:00
|
|
|
* @return true if it is an stl type and its type matches any of the types in 'stlTypes'
|
|
|
|
*/
|
2015-05-17 20:02:41 +02:00
|
|
|
bool isStlType(const std::string& stlType) const {
|
2018-06-16 16:03:36 +02:00
|
|
|
return isStlType() && stlType==mTypeStartToken->strAt(2);
|
2015-05-17 20:02:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if the variable is of any of the STL types passed as arguments ('std::')
|
|
|
|
* E.g.:
|
|
|
|
* std::string s;
|
|
|
|
* ...
|
|
|
|
* const std::set<std::string> str = make_container< std::set<std::string> >() << "string" << "wstring";
|
|
|
|
* sVar->isStlType(str) == true
|
|
|
|
* @param stlTypes set of stl types
|
|
|
|
* @return true if it is an stl type and its type matches any of the types in 'stlTypes'
|
|
|
|
*/
|
|
|
|
bool isStlType(const std::set<std::string>& stlTypes) const {
|
2018-06-16 16:03:36 +02:00
|
|
|
return isStlType() && stlTypes.find(mTypeStartToken->strAt(2))!=stlTypes.end();
|
2014-01-28 15:44:56 +01:00
|
|
|
}
|
|
|
|
|
2014-05-24 18:35:49 +02:00
|
|
|
/**
|
2021-08-07 20:51:18 +02:00
|
|
|
* Determine whether it's a floating number type
|
|
|
|
* @return true if the type is known and it's a floating type (float, double and long double) or a pointer/array to it
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isFloatingType() const {
|
2014-08-09 11:44:55 +02:00
|
|
|
return getFlag(fIsFloatType);
|
2014-05-24 18:35:49 +02:00
|
|
|
}
|
|
|
|
|
2016-04-22 06:02:54 +02:00
|
|
|
/**
|
2021-08-07 20:51:18 +02:00
|
|
|
* Determine whether it's an enumeration type
|
|
|
|
* @return true if the type is known and it's an enumeration type
|
|
|
|
*/
|
2016-04-22 06:02:54 +02:00
|
|
|
bool isEnumType() const {
|
|
|
|
return type() && type()->isEnumType();
|
|
|
|
}
|
2014-05-24 18:35:49 +02:00
|
|
|
|
2020-04-12 20:35:54 +02:00
|
|
|
bool isMaybeUnused() const {
|
|
|
|
return getFlag(fIsMaybeUnused);
|
|
|
|
}
|
|
|
|
|
2018-06-20 10:00:15 +02:00
|
|
|
const ValueType *valueType() const {
|
|
|
|
return mValueType;
|
2018-04-12 20:23:34 +02:00
|
|
|
}
|
|
|
|
|
2018-06-20 10:00:15 +02:00
|
|
|
void setValueType(const ValueType &valueType);
|
|
|
|
|
2018-11-04 13:29:29 +01:00
|
|
|
AccessControl accessControl() const {
|
|
|
|
return mAccess;
|
|
|
|
}
|
|
|
|
|
2019-11-17 12:08:21 +01:00
|
|
|
std::string getTypeName() const;
|
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
private:
|
2013-08-12 06:21:03 +02:00
|
|
|
// only symbol database can change the type
|
|
|
|
friend class SymbolDatabase;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set Type pointer to known type.
|
|
|
|
* @param t type
|
|
|
|
*/
|
2014-11-20 14:20:09 +01:00
|
|
|
void type(const Type * t) {
|
2018-06-16 20:25:54 +02:00
|
|
|
mType = t;
|
2013-08-12 06:21:03 +02:00
|
|
|
}
|
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/** @brief variable name token */
|
2018-06-16 15:57:16 +02:00
|
|
|
const Token *mNameToken;
|
2011-01-18 07:32:06 +01:00
|
|
|
|
2011-02-20 14:25:42 +01:00
|
|
|
/** @brief variable type start token */
|
2018-06-16 16:03:36 +02:00
|
|
|
const Token *mTypeStartToken;
|
2011-02-20 14:25:42 +01:00
|
|
|
|
2011-02-26 15:08:59 +01:00
|
|
|
/** @brief variable type end token */
|
2018-06-16 16:03:36 +02:00
|
|
|
const Token *mTypeEndToken;
|
2011-02-26 15:08:59 +01:00
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/** @brief order declared */
|
2019-07-22 11:25:51 +02:00
|
|
|
nonneg int mIndex;
|
2011-01-18 07:32:06 +01:00
|
|
|
|
|
|
|
/** @brief what section is this variable declared in? */
|
2018-06-16 16:12:27 +02:00
|
|
|
AccessControl mAccess; // public/protected/private
|
2010-11-16 07:30:55 +01:00
|
|
|
|
2011-01-18 07:32:06 +01:00
|
|
|
/** @brief flags */
|
2018-06-16 16:14:34 +02:00
|
|
|
unsigned int mFlags;
|
2018-04-12 20:23:34 +02:00
|
|
|
|
2011-01-17 07:21:59 +01:00
|
|
|
/** @brief pointer to user defined type info (for known types) */
|
2018-06-16 20:25:54 +02:00
|
|
|
const Type *mType;
|
2011-02-26 15:08:59 +01:00
|
|
|
|
|
|
|
/** @brief pointer to scope this variable is in */
|
2018-06-16 20:29:17 +02:00
|
|
|
const Scope *mScope;
|
2011-06-23 04:41:11 +02:00
|
|
|
|
2022-08-21 17:21:02 +02:00
|
|
|
const ValueType *mValueType;
|
2018-06-20 10:00:15 +02:00
|
|
|
|
2011-06-23 04:41:11 +02:00
|
|
|
/** @brief array dimensions */
|
2018-06-16 20:23:58 +02:00
|
|
|
std::vector<Dimension> mDimensions;
|
2012-05-11 17:56:47 +02:00
|
|
|
|
2012-07-31 23:35:56 +02:00
|
|
|
/** @brief fill in information, depending on Tokens given at instantiation */
|
2018-06-20 10:00:15 +02:00
|
|
|
void evaluate(const Settings* settings);
|
2011-01-17 07:21:59 +01:00
|
|
|
};
|
2010-11-13 08:08:45 +01:00
|
|
|
|
2012-06-10 14:19:09 +02:00
|
|
|
class CPPCHECKLIB Function {
|
2019-10-06 07:21:12 +02:00
|
|
|
// only symbol database can change this
|
|
|
|
friend class SymbolDatabase;
|
|
|
|
|
2015-01-08 05:45:31 +01:00
|
|
|
/** @brief flags mask used to access specific bit. */
|
|
|
|
enum {
|
2018-12-13 06:34:10 +01:00
|
|
|
fHasBody = (1 << 0), ///< @brief has implementation
|
|
|
|
fIsInline = (1 << 1), ///< @brief implementation in class definition
|
|
|
|
fIsConst = (1 << 2), ///< @brief is const
|
2019-07-04 12:32:32 +02:00
|
|
|
fHasVirtualSpecifier = (1 << 3), ///< @brief does declaration contain 'virtual' specifier
|
2018-12-13 06:34:10 +01:00
|
|
|
fIsPure = (1 << 4), ///< @brief is pure virtual
|
|
|
|
fIsStatic = (1 << 5), ///< @brief is static
|
|
|
|
fIsStaticLocal = (1 << 6), ///< @brief is static local
|
|
|
|
fIsExtern = (1 << 7), ///< @brief is extern
|
|
|
|
fIsFriend = (1 << 8), ///< @brief is friend
|
|
|
|
fIsExplicit = (1 << 9), ///< @brief is explicit
|
|
|
|
fIsDefault = (1 << 10), ///< @brief is default
|
|
|
|
fIsDelete = (1 << 11), ///< @brief is delete
|
|
|
|
fHasOverrideSpecifier = (1 << 12), ///< @brief does declaration contain 'override' specifier?
|
|
|
|
fHasFinalSpecifier = (1 << 13), ///< @brief does declaration contain 'final' specifier?
|
|
|
|
fIsNoExcept = (1 << 14), ///< @brief is noexcept
|
|
|
|
fIsThrow = (1 << 15), ///< @brief is throw
|
|
|
|
fIsOperator = (1 << 16), ///< @brief is operator
|
|
|
|
fHasLvalRefQual = (1 << 17), ///< @brief has & lvalue ref-qualifier
|
|
|
|
fHasRvalRefQual = (1 << 18), ///< @brief has && rvalue ref-qualifier
|
|
|
|
fIsVariadic = (1 << 19), ///< @brief is variadic
|
|
|
|
fIsVolatile = (1 << 20), ///< @brief is volatile
|
|
|
|
fHasTrailingReturnType = (1 << 21), ///< @brief has trailing return type
|
2019-08-08 07:46:47 +02:00
|
|
|
fIsEscapeFunction = (1 << 22), ///< @brief Function throws or exits
|
2021-07-18 21:18:07 +02:00
|
|
|
fIsInlineKeyword = (1 << 23), ///< @brief Function has "inline" keyword
|
2021-07-22 07:22:26 +02:00
|
|
|
fIsConstexpr = (1 << 24), ///< @brief is constexpr
|
2015-01-08 05:45:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get specified flag state.
|
|
|
|
* @param flag flag to get state of
|
|
|
|
* @return true if flag set or false in flag not set
|
|
|
|
*/
|
2015-01-17 16:46:05 +01:00
|
|
|
bool getFlag(unsigned int flag) const {
|
2018-06-16 23:11:45 +02:00
|
|
|
return ((mFlags & flag) != 0);
|
2015-01-08 05:45:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set specified flag state.
|
|
|
|
* @param flag flag to set state
|
|
|
|
* @param state new state of flag
|
|
|
|
*/
|
2015-01-17 16:46:05 +01:00
|
|
|
void setFlag(unsigned int flag, bool state) {
|
2018-06-16 23:11:45 +02:00
|
|
|
mFlags = state ? mFlags | flag : mFlags & ~flag;
|
2015-01-08 05:45:31 +01:00
|
|
|
}
|
|
|
|
|
2011-01-17 07:21:59 +01:00
|
|
|
public:
|
2019-07-05 12:30:42 +02:00
|
|
|
enum Type { eConstructor, eCopyConstructor, eMoveConstructor, eOperatorEqual, eDestructor, eFunction, eLambda };
|
2011-01-17 07:21:59 +01:00
|
|
|
|
2018-06-16 16:10:28 +02:00
|
|
|
Function(const Tokenizer *mTokenizer, const Token *tok, const Scope *scope, const Token *tokDef, const Token *tokArgDef);
|
2021-04-30 16:47:02 +02:00
|
|
|
Function(const Token *tokenDef, const std::string &clangType);
|
2018-04-25 12:05:49 +02:00
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
const std::string &name() const {
|
2013-01-01 09:53:40 +01:00
|
|
|
return tokenDef->str();
|
|
|
|
}
|
|
|
|
|
2020-04-27 09:08:50 +02:00
|
|
|
std::string fullName() const;
|
|
|
|
|
2019-07-22 11:25:51 +02:00
|
|
|
nonneg int argCount() const {
|
2011-03-31 03:14:24 +02:00
|
|
|
return argumentList.size();
|
|
|
|
}
|
2019-07-22 11:25:51 +02:00
|
|
|
nonneg int minArgCount() const {
|
2013-02-27 06:59:04 +01:00
|
|
|
return argumentList.size() - initArgCount;
|
|
|
|
}
|
2019-07-22 11:25:51 +02:00
|
|
|
const Variable* getArgumentVar(nonneg int num) const;
|
|
|
|
nonneg int initializedArgCount() const {
|
2012-10-14 17:34:09 +02:00
|
|
|
return initArgCount;
|
|
|
|
}
|
2012-04-27 21:51:13 +02:00
|
|
|
void addArguments(const SymbolDatabase *symbolDatabase, const Scope *scope);
|
2018-04-27 11:12:09 +02:00
|
|
|
|
2012-04-17 19:50:44 +02:00
|
|
|
/** @brief check if this function is virtual in the base classes */
|
|
|
|
bool isImplicitlyVirtual(bool defaultVal = false) const;
|
2011-01-17 07:21:59 +01:00
|
|
|
|
2021-07-18 07:46:31 +02:00
|
|
|
std::vector<const Function*> getOverloadedFunctions() const;
|
|
|
|
|
2018-04-27 11:12:09 +02:00
|
|
|
/** @brief get function in base class that is overridden */
|
2019-01-14 18:36:21 +01:00
|
|
|
const Function *getOverriddenFunction(bool *foundAllBaseClasses = nullptr) const;
|
2018-04-25 12:05:49 +02:00
|
|
|
|
2019-07-05 12:30:42 +02:00
|
|
|
bool isLambda() const {
|
|
|
|
return type==eLambda;
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isConstructor() const {
|
2013-04-10 21:57:22 +02:00
|
|
|
return type==eConstructor ||
|
|
|
|
type==eCopyConstructor ||
|
|
|
|
type==eMoveConstructor;
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isDestructor() const {
|
2013-04-10 21:57:22 +02:00
|
|
|
return type==eDestructor;
|
|
|
|
}
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isAttributeConstructor() const {
|
2014-03-14 05:40:17 +01:00
|
|
|
return tokenDef->isAttributeConstructor();
|
|
|
|
}
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isAttributeDestructor() const {
|
2014-03-14 05:40:17 +01:00
|
|
|
return tokenDef->isAttributeDestructor();
|
|
|
|
}
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isAttributePure() const {
|
2014-03-14 05:40:17 +01:00
|
|
|
return tokenDef->isAttributePure();
|
|
|
|
}
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isAttributeConst() const {
|
2014-03-14 05:40:17 +01:00
|
|
|
return tokenDef->isAttributeConst();
|
|
|
|
}
|
2014-12-24 12:50:51 +01:00
|
|
|
bool isAttributeNoreturn() const {
|
|
|
|
return tokenDef->isAttributeNoreturn();
|
|
|
|
}
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isAttributeNothrow() const {
|
2014-04-20 20:40:55 +02:00
|
|
|
return tokenDef->isAttributeNothrow();
|
|
|
|
}
|
2018-05-29 21:43:56 +02:00
|
|
|
bool isAttributeNodiscard() const {
|
|
|
|
return tokenDef->isAttributeNodiscard();
|
|
|
|
}
|
2013-04-10 21:57:22 +02:00
|
|
|
|
2015-01-08 05:45:31 +01:00
|
|
|
bool hasBody() const {
|
|
|
|
return getFlag(fHasBody);
|
|
|
|
}
|
|
|
|
bool isInline() const {
|
|
|
|
return getFlag(fIsInline);
|
|
|
|
}
|
|
|
|
bool isConst() const {
|
|
|
|
return getFlag(fIsConst);
|
|
|
|
}
|
2019-07-04 12:32:32 +02:00
|
|
|
bool hasVirtualSpecifier() const {
|
|
|
|
return getFlag(fHasVirtualSpecifier);
|
2015-01-08 05:45:31 +01:00
|
|
|
}
|
|
|
|
bool isPure() const {
|
|
|
|
return getFlag(fIsPure);
|
|
|
|
}
|
|
|
|
bool isStatic() const {
|
|
|
|
return getFlag(fIsStatic);
|
|
|
|
}
|
|
|
|
bool isStaticLocal() const {
|
|
|
|
return getFlag(fIsStaticLocal);
|
|
|
|
}
|
|
|
|
bool isExtern() const {
|
|
|
|
return getFlag(fIsExtern);
|
|
|
|
}
|
|
|
|
bool isFriend() const {
|
|
|
|
return getFlag(fIsFriend);
|
|
|
|
}
|
|
|
|
bool isExplicit() const {
|
|
|
|
return getFlag(fIsExplicit);
|
|
|
|
}
|
|
|
|
bool isDefault() const {
|
|
|
|
return getFlag(fIsDefault);
|
|
|
|
}
|
|
|
|
bool isDelete() const {
|
|
|
|
return getFlag(fIsDelete);
|
|
|
|
}
|
|
|
|
bool isNoExcept() const {
|
|
|
|
return getFlag(fIsNoExcept);
|
|
|
|
}
|
|
|
|
bool isThrow() const {
|
|
|
|
return getFlag(fIsThrow);
|
|
|
|
}
|
2018-04-27 14:57:43 +02:00
|
|
|
bool hasOverrideSpecifier() const {
|
|
|
|
return getFlag(fHasOverrideSpecifier);
|
|
|
|
}
|
|
|
|
bool hasFinalSpecifier() const {
|
|
|
|
return getFlag(fHasFinalSpecifier);
|
2018-04-27 11:12:09 +02:00
|
|
|
}
|
2015-01-08 05:45:31 +01:00
|
|
|
bool isOperator() const {
|
|
|
|
return getFlag(fIsOperator);
|
|
|
|
}
|
2016-01-02 18:53:51 +01:00
|
|
|
bool hasLvalRefQualifier() const {
|
|
|
|
return getFlag(fHasLvalRefQual);
|
|
|
|
}
|
|
|
|
bool hasRvalRefQualifier() const {
|
|
|
|
return getFlag(fHasRvalRefQual);
|
|
|
|
}
|
2016-08-02 08:58:11 +02:00
|
|
|
bool isVariadic() const {
|
|
|
|
return getFlag(fIsVariadic);
|
|
|
|
}
|
2018-05-10 07:40:01 +02:00
|
|
|
bool isVolatile() const {
|
|
|
|
return getFlag(fIsVolatile);
|
|
|
|
}
|
2018-12-13 06:34:10 +01:00
|
|
|
bool hasTrailingReturnType() const {
|
|
|
|
return getFlag(fHasTrailingReturnType);
|
|
|
|
}
|
2015-01-08 05:45:31 +01:00
|
|
|
void hasBody(bool state) {
|
|
|
|
setFlag(fHasBody, state);
|
|
|
|
}
|
2021-07-18 21:18:07 +02:00
|
|
|
bool isInlineKeyword() const {
|
|
|
|
return getFlag(fIsInlineKeyword);
|
|
|
|
}
|
2018-04-25 12:05:49 +02:00
|
|
|
|
2019-08-08 07:46:47 +02:00
|
|
|
bool isEscapeFunction() const {
|
|
|
|
return getFlag(fIsEscapeFunction);
|
|
|
|
}
|
|
|
|
void isEscapeFunction(bool state) {
|
|
|
|
setFlag(fIsEscapeFunction, state);
|
|
|
|
}
|
2021-07-22 07:22:26 +02:00
|
|
|
|
|
|
|
bool isConstexpr() const {
|
|
|
|
return getFlag(fIsConstexpr);
|
|
|
|
}
|
|
|
|
void isConstexpr(bool state) {
|
|
|
|
setFlag(fIsConstexpr, state);
|
|
|
|
}
|
2019-07-10 16:59:05 +02:00
|
|
|
bool isSafe(const Settings *settings) const;
|
|
|
|
|
2018-04-25 12:05:49 +02:00
|
|
|
const Token *tokenDef; ///< function name token in class definition
|
|
|
|
const Token *argDef; ///< function argument start '(' in class definition
|
|
|
|
const Token *token; ///< function name token in implementation
|
|
|
|
const Token *arg; ///< function argument start '('
|
|
|
|
const Token *retDef; ///< function return type token
|
|
|
|
const ::Type *retType; ///< function return type
|
|
|
|
const Scope *functionScope; ///< scope of function body
|
|
|
|
const Scope* nestedIn; ///< Scope the function is declared in
|
2022-08-21 17:21:02 +02:00
|
|
|
std::vector<Variable> argumentList; ///< argument list
|
2019-07-22 11:25:51 +02:00
|
|
|
nonneg int initArgCount; ///< number of args with default values
|
2018-04-25 12:05:49 +02:00
|
|
|
Type type; ///< constructor, destructor, ...
|
|
|
|
const Token *noexceptArg; ///< noexcept token
|
|
|
|
const Token *throwArg; ///< throw token
|
2019-07-24 09:59:01 +02:00
|
|
|
const Token *templateDef; ///< points to 'template <' before function
|
2020-09-23 22:10:47 +02:00
|
|
|
const Token *functionPointerUsage; ///< function pointer usage
|
2022-07-24 10:17:11 +02:00
|
|
|
AccessControl access; ///< public/protected/private
|
2018-04-25 12:05:49 +02:00
|
|
|
|
2021-01-18 19:01:04 +01:00
|
|
|
bool argsMatch(const Scope *scope, const Token *first, const Token *second, const std::string &path, nonneg int path_length) const;
|
2018-04-25 12:05:49 +02:00
|
|
|
|
2021-04-30 17:47:08 +02:00
|
|
|
static bool returnsConst(const Function* function, bool unknown = false);
|
|
|
|
|
2019-10-08 09:28:39 +02:00
|
|
|
static bool returnsReference(const Function* function, bool unknown = false);
|
2022-11-27 09:24:19 +01:00
|
|
|
static bool returnsStandardType(const Function* function, bool unknown = false);
|
2021-07-08 13:50:26 +02:00
|
|
|
|
|
|
|
static bool returnsVoid(const Function* function, bool unknown = false);
|
2019-01-23 07:29:16 +01:00
|
|
|
|
2020-05-31 10:10:10 +02:00
|
|
|
static std::vector<const Token*> findReturns(const Function* f);
|
|
|
|
|
2019-05-02 11:04:23 +02:00
|
|
|
const Token* returnDefEnd() const {
|
|
|
|
if (this->hasTrailingReturnType()) {
|
2019-11-10 09:44:04 +01:00
|
|
|
return Token::findmatch(retDef, "{|;");
|
2019-05-02 11:04:23 +02:00
|
|
|
} else {
|
|
|
|
return tokenDef;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-25 12:05:49 +02:00
|
|
|
/**
|
|
|
|
* @return token to ":" if the function is a constructor
|
|
|
|
* and it contains member initialization otherwise a nullptr is returned
|
|
|
|
*/
|
|
|
|
const Token * constructorMemberInitialization() const;
|
|
|
|
|
|
|
|
private:
|
2019-01-14 18:36:21 +01:00
|
|
|
/** Recursively determine if this function overrides a virtual function in a base class */
|
|
|
|
const Function * getOverriddenFunctionRecursive(const ::Type* baseType, bool *foundAllBaseClasses) const;
|
2018-04-25 12:05:49 +02:00
|
|
|
|
2018-06-16 23:11:45 +02:00
|
|
|
unsigned int mFlags;
|
2018-04-25 12:05:49 +02:00
|
|
|
|
2015-01-08 05:45:31 +01:00
|
|
|
void isInline(bool state) {
|
|
|
|
setFlag(fIsInline, state);
|
|
|
|
}
|
|
|
|
void isConst(bool state) {
|
|
|
|
setFlag(fIsConst, state);
|
|
|
|
}
|
2019-07-04 12:32:32 +02:00
|
|
|
void hasVirtualSpecifier(bool state) {
|
|
|
|
setFlag(fHasVirtualSpecifier, state);
|
2015-01-08 05:45:31 +01:00
|
|
|
}
|
|
|
|
void isPure(bool state) {
|
|
|
|
setFlag(fIsPure, state);
|
|
|
|
}
|
|
|
|
void isStatic(bool state) {
|
|
|
|
setFlag(fIsStatic, state);
|
|
|
|
}
|
|
|
|
void isStaticLocal(bool state) {
|
|
|
|
setFlag(fIsStaticLocal, state);
|
|
|
|
}
|
|
|
|
void isExtern(bool state) {
|
|
|
|
setFlag(fIsExtern, state);
|
|
|
|
}
|
|
|
|
void isFriend(bool state) {
|
|
|
|
setFlag(fIsFriend, state);
|
|
|
|
}
|
|
|
|
void isExplicit(bool state) {
|
|
|
|
setFlag(fIsExplicit, state);
|
|
|
|
}
|
|
|
|
void isDefault(bool state) {
|
|
|
|
setFlag(fIsDefault, state);
|
|
|
|
}
|
|
|
|
void isDelete(bool state) {
|
|
|
|
setFlag(fIsDelete, state);
|
|
|
|
}
|
|
|
|
void isNoExcept(bool state) {
|
|
|
|
setFlag(fIsNoExcept, state);
|
|
|
|
}
|
|
|
|
void isThrow(bool state) {
|
|
|
|
setFlag(fIsThrow, state);
|
|
|
|
}
|
|
|
|
void isOperator(bool state) {
|
|
|
|
setFlag(fIsOperator, state);
|
|
|
|
}
|
2016-01-02 18:53:51 +01:00
|
|
|
void hasLvalRefQualifier(bool state) {
|
|
|
|
setFlag(fHasLvalRefQual, state);
|
|
|
|
}
|
|
|
|
void hasRvalRefQualifier(bool state) {
|
|
|
|
setFlag(fHasRvalRefQual, state);
|
|
|
|
}
|
2016-08-02 08:58:11 +02:00
|
|
|
void isVariadic(bool state) {
|
|
|
|
setFlag(fIsVariadic, state);
|
|
|
|
}
|
2018-05-10 07:40:01 +02:00
|
|
|
void isVolatile(bool state) {
|
|
|
|
setFlag(fIsVolatile, state);
|
|
|
|
}
|
2018-12-13 06:34:10 +01:00
|
|
|
void hasTrailingReturnType(bool state) {
|
|
|
|
return setFlag(fHasTrailingReturnType, state);
|
|
|
|
}
|
2021-07-18 21:18:07 +02:00
|
|
|
void isInlineKeyword(bool state) {
|
|
|
|
setFlag(fIsInlineKeyword, state);
|
|
|
|
}
|
2020-11-03 17:52:38 +01:00
|
|
|
const Token *setFlags(const Token *tok1, const Scope *scope);
|
2011-01-17 07:21:59 +01:00
|
|
|
};
|
|
|
|
|
2012-06-10 14:19:09 +02:00
|
|
|
class CPPCHECKLIB Scope {
|
2011-01-17 18:29:19 +01:00
|
|
|
// let tests access private function for testing
|
|
|
|
friend class TestSymbolDatabase;
|
|
|
|
|
2011-01-17 07:21:59 +01:00
|
|
|
public:
|
2012-12-20 06:53:04 +01:00
|
|
|
struct UsingInfo {
|
|
|
|
const Token *start;
|
2013-03-05 18:42:42 +01:00
|
|
|
const Scope *scope;
|
2012-12-20 06:53:04 +01:00
|
|
|
};
|
|
|
|
|
2016-04-22 06:02:54 +02:00
|
|
|
enum ScopeType { eGlobal, eClass, eStruct, eUnion, eNamespace, eFunction, eIf, eElse, eFor, eWhile, eDo, eSwitch, eUnconditional, eTry, eCatch, eLambda, eEnum };
|
2011-01-17 07:21:59 +01:00
|
|
|
|
2013-03-05 18:42:42 +01:00
|
|
|
Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope *nestedIn_);
|
|
|
|
Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope *nestedIn_, ScopeType type_, const Token *start_);
|
2011-01-17 07:21:59 +01:00
|
|
|
|
2013-03-05 18:42:42 +01:00
|
|
|
const SymbolDatabase *check;
|
2011-01-17 07:21:59 +01:00
|
|
|
std::string className;
|
2018-04-24 13:03:32 +02:00
|
|
|
const Token *classDef; ///< class/struct/union/namespace token
|
2018-04-27 22:36:30 +02:00
|
|
|
const Token *bodyStart; ///< '{' token
|
|
|
|
const Token *bodyEnd; ///< '}' token
|
2011-01-17 18:29:19 +01:00
|
|
|
std::list<Function> functionList;
|
2015-01-02 21:38:19 +01:00
|
|
|
std::multimap<std::string, const Function *> functionMap;
|
2011-01-17 18:29:19 +01:00
|
|
|
std::list<Variable> varlist;
|
2013-03-05 18:42:42 +01:00
|
|
|
const Scope *nestedIn;
|
2022-06-08 16:58:57 +02:00
|
|
|
std::vector<Scope *> nestedList;
|
2019-07-22 11:25:51 +02:00
|
|
|
nonneg int numConstructors;
|
|
|
|
nonneg int numCopyOrMoveConstructors;
|
2022-06-08 16:58:57 +02:00
|
|
|
std::vector<UsingInfo> usingList;
|
2012-05-14 20:46:23 +02:00
|
|
|
ScopeType type;
|
2013-03-05 13:33:38 +01:00
|
|
|
Type* definedType;
|
2017-10-15 02:53:41 +02:00
|
|
|
std::map<std::string, Type*> definedTypesMap;
|
2021-08-10 07:00:11 +02:00
|
|
|
std::vector<const Token *> bodyStartList;
|
2011-03-14 02:01:33 +01:00
|
|
|
|
|
|
|
// function specific fields
|
2018-04-24 13:03:32 +02:00
|
|
|
const Scope *functionOf; ///< scope this function belongs to
|
|
|
|
Function *function; ///< function info for this function
|
2011-01-17 07:21:59 +01:00
|
|
|
|
2016-04-22 06:02:54 +02:00
|
|
|
// enum specific fields
|
|
|
|
const Token * enumType;
|
|
|
|
bool enumClass;
|
|
|
|
|
|
|
|
std::vector<Enumerator> enumeratorList;
|
|
|
|
|
2021-08-10 07:00:11 +02:00
|
|
|
void setBodyStartEnd(const Token *start) {
|
|
|
|
bodyStart = start;
|
|
|
|
bodyEnd = start ? start->link() : nullptr;
|
|
|
|
if (start)
|
|
|
|
bodyStartList.push_back(start);
|
|
|
|
}
|
|
|
|
|
2021-03-20 18:53:17 +01:00
|
|
|
bool isAnonymous() const {
|
|
|
|
// TODO: Check if class/struct is anonymous
|
|
|
|
return className.size() > 9 && className.compare(0,9,"Anonymous") == 0 && std::isdigit(className[9]);
|
|
|
|
}
|
|
|
|
|
2016-04-22 06:02:54 +02:00
|
|
|
const Enumerator * findEnumerator(const std::string & name) const {
|
2022-12-30 15:13:47 +01:00
|
|
|
auto it = std::find_if(enumeratorList.cbegin(), enumeratorList.cend(), [&](const Enumerator& i) {
|
2022-10-16 13:46:26 +02:00
|
|
|
return i.name->str() == name;
|
|
|
|
});
|
|
|
|
return it == enumeratorList.end() ? nullptr : &*it;
|
2016-04-22 06:02:54 +02:00
|
|
|
}
|
|
|
|
|
2018-11-10 21:30:01 +01:00
|
|
|
bool isNestedIn(const Scope * outer) const {
|
|
|
|
if (!outer)
|
2018-11-10 16:40:40 +01:00
|
|
|
return false;
|
2018-11-10 21:30:01 +01:00
|
|
|
if (outer == this)
|
2018-11-10 16:40:40 +01:00
|
|
|
return true;
|
|
|
|
const Scope * parent = nestedIn;
|
2018-11-10 21:30:01 +01:00
|
|
|
while (outer != parent && parent)
|
2018-11-10 16:40:40 +01:00
|
|
|
parent = parent->nestedIn;
|
2018-11-10 21:30:01 +01:00
|
|
|
if (parent && parent == outer)
|
2018-11-10 16:40:40 +01:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-09-10 08:02:45 +02:00
|
|
|
static Function* nestedInFunction(const Scope* scope) {
|
2020-09-07 04:59:21 +02:00
|
|
|
while (scope) {
|
2020-09-07 04:58:36 +02:00
|
|
|
if (scope->type == Scope::eFunction)
|
|
|
|
break;
|
|
|
|
scope = scope->nestedIn;
|
|
|
|
}
|
|
|
|
if (!scope)
|
|
|
|
return nullptr;
|
|
|
|
return scope->function;
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isClassOrStruct() const {
|
2011-01-17 18:29:19 +01:00
|
|
|
return (type == eClass || type == eStruct);
|
2011-01-17 07:21:59 +01:00
|
|
|
}
|
|
|
|
|
2017-10-15 11:49:36 +02:00
|
|
|
bool isClassOrStructOrUnion() const {
|
|
|
|
return (type == eClass || type == eStruct || type == eUnion);
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isExecutable() const {
|
2016-04-22 06:02:54 +02:00
|
|
|
return type != eClass && type != eStruct && type != eUnion && type != eGlobal && type != eNamespace && type != eEnum;
|
2012-09-02 14:30:00 +02:00
|
|
|
}
|
|
|
|
|
2020-12-24 22:58:19 +01:00
|
|
|
bool isLoopScope() const {
|
|
|
|
return type == Scope::ScopeType::eFor || type == Scope::ScopeType::eWhile || type == Scope::ScopeType::eDo;
|
|
|
|
}
|
|
|
|
|
2014-11-20 14:20:09 +01:00
|
|
|
bool isLocal() const {
|
2014-07-02 16:16:19 +02:00
|
|
|
return (type == eIf || type == eElse ||
|
2011-02-26 21:53:57 +01:00
|
|
|
type == eFor || type == eWhile || type == eDo ||
|
2012-02-02 16:17:42 +01:00
|
|
|
type == eSwitch || type == eUnconditional ||
|
|
|
|
type == eTry || type == eCatch);
|
2011-02-26 21:53:57 +01:00
|
|
|
}
|
2011-03-12 17:42:58 +01:00
|
|
|
|
2016-05-26 17:42:27 +02:00
|
|
|
// Is there lambda/inline function(s) in this scope?
|
2016-05-26 18:07:56 +02:00
|
|
|
bool hasInlineOrLambdaFunction() const;
|
2016-05-26 17:42:27 +02:00
|
|
|
|
2013-01-28 06:47:48 +01:00
|
|
|
/**
|
|
|
|
* @brief find a function
|
|
|
|
* @param tok token of function call
|
2015-05-23 11:56:11 +02:00
|
|
|
* @param requireConst if const refers to a const variable only const methods should be matched
|
2013-01-28 06:47:48 +01:00
|
|
|
* @return pointer to function if found or NULL if not found
|
|
|
|
*/
|
2015-05-23 11:56:11 +02:00
|
|
|
const Function *findFunction(const Token *tok, bool requireConst=false) const;
|
2013-01-28 06:47:48 +01:00
|
|
|
|
2022-03-12 06:16:29 +01:00
|
|
|
const Scope *findRecordInNestedList(const std::string & name, bool isC = false) const;
|
2014-11-20 14:20:09 +01:00
|
|
|
Scope *findRecordInNestedList(const std::string & name) {
|
2015-08-27 16:14:33 +02:00
|
|
|
return const_cast<Scope *>(const_cast<const Scope *>(this)->findRecordInNestedList(name));
|
2013-01-03 22:37:19 +01:00
|
|
|
}
|
2012-11-30 06:03:58 +01:00
|
|
|
|
2013-03-05 15:28:40 +01:00
|
|
|
const Type* findType(const std::string& name) const;
|
2014-11-20 14:20:09 +01:00
|
|
|
Type* findType(const std::string& name) {
|
2015-08-27 16:14:33 +02:00
|
|
|
return const_cast<Type*>(const_cast<const Scope *>(this)->findType(name));
|
2013-03-05 15:28:40 +01:00
|
|
|
}
|
2013-03-05 13:33:38 +01:00
|
|
|
|
2011-02-03 07:57:10 +01:00
|
|
|
/**
|
|
|
|
* @brief find if name is in nested list
|
|
|
|
* @param name name of nested scope
|
|
|
|
*/
|
2013-01-03 22:37:19 +01:00
|
|
|
Scope *findInNestedListRecursive(const std::string & name);
|
2011-02-03 07:57:10 +01:00
|
|
|
|
2011-02-26 15:08:59 +01:00
|
|
|
void addVariable(const Token *token_, const Token *start_,
|
2013-03-05 13:33:38 +01:00
|
|
|
const Token *end_, AccessControl access_, const Type *type_,
|
2020-03-14 14:41:45 +01:00
|
|
|
const Scope *scope_, const Settings* settings);
|
2011-01-17 07:21:59 +01:00
|
|
|
|
|
|
|
/** @brief initialize varlist */
|
2018-06-20 10:00:15 +02:00
|
|
|
void getVariableList(const Settings* settings);
|
2011-01-17 07:21:59 +01:00
|
|
|
|
2011-01-17 18:29:19 +01:00
|
|
|
const Function *getDestructor() const;
|
2011-01-17 07:21:59 +01:00
|
|
|
|
2022-09-08 09:21:35 +02:00
|
|
|
void addFunction(Function func) {
|
|
|
|
functionList.push_back(std::move(func));
|
2015-01-02 21:38:19 +01:00
|
|
|
|
|
|
|
const Function * back = &functionList.back();
|
|
|
|
|
2018-04-14 15:46:55 +02:00
|
|
|
functionMap.insert(make_pair(back->tokenDef->str(), back));
|
2015-01-02 21:38:19 +01:00
|
|
|
}
|
|
|
|
|
2011-01-17 07:21:59 +01:00
|
|
|
bool hasDefaultConstructor() const;
|
|
|
|
|
2011-02-26 15:08:59 +01:00
|
|
|
AccessControl defaultAccess() const;
|
|
|
|
|
2011-03-06 21:21:42 +01:00
|
|
|
/**
|
|
|
|
* @brief check if statement is variable declaration and add it if it is
|
|
|
|
* @param tok pointer to start of statement
|
|
|
|
* @param varaccess access control of statement
|
2018-06-20 10:00:15 +02:00
|
|
|
* @param settings Settings
|
2011-03-06 21:21:42 +01:00
|
|
|
* @return pointer to last token
|
|
|
|
*/
|
2018-06-20 10:00:15 +02:00
|
|
|
const Token *checkVariable(const Token *tok, AccessControl varaccess, const Settings* settings);
|
2011-03-06 21:21:42 +01:00
|
|
|
|
2011-09-03 03:07:29 +02:00
|
|
|
/**
|
|
|
|
* @brief get variable from name
|
|
|
|
* @param varname name of variable
|
|
|
|
* @return pointer to variable
|
|
|
|
*/
|
|
|
|
const Variable *getVariable(const std::string &varname) const;
|
|
|
|
|
2016-04-22 06:02:54 +02:00
|
|
|
const Token * addEnum(const Token * tok, bool isCpp);
|
|
|
|
|
2021-01-18 19:01:04 +01:00
|
|
|
const Scope *findRecordInBase(const std::string &name) const;
|
|
|
|
|
2021-11-12 20:05:43 +01:00
|
|
|
std::vector<const Scope*> findAssociatedScopes() const;
|
|
|
|
|
2011-01-17 07:21:59 +01:00
|
|
|
private:
|
|
|
|
/**
|
2011-01-17 18:29:19 +01:00
|
|
|
* @brief helper function for getVariableList()
|
2011-01-17 07:21:59 +01:00
|
|
|
* @param tok pointer to token to check
|
|
|
|
* @param vartok populated with pointer to the variable token, if found
|
|
|
|
* @param typetok populated with pointer to the type token, if found
|
|
|
|
* @return true if tok points to a variable declaration, false otherwise
|
|
|
|
*/
|
2016-01-30 14:04:48 +01:00
|
|
|
bool isVariableDeclaration(const Token* const tok, const Token*& vartok, const Token*& typetok) const;
|
2014-11-17 16:04:44 +01:00
|
|
|
|
2019-07-22 11:25:51 +02:00
|
|
|
void findFunctionInBase(const std::string & name, nonneg int args, std::vector<const Function *> & matches) const;
|
2021-08-10 07:00:11 +02:00
|
|
|
|
|
|
|
/** @brief initialize varlist */
|
2021-09-04 11:09:33 +02:00
|
|
|
void getVariableList(const Settings* settings, const Token *start, const Token *end);
|
2011-01-17 07:21:59 +01:00
|
|
|
};
|
|
|
|
|
2020-09-03 18:55:40 +02:00
|
|
|
enum class Reference {
|
2020-09-03 18:44:44 +02:00
|
|
|
None,
|
|
|
|
LValue,
|
|
|
|
RValue
|
|
|
|
};
|
2017-03-22 02:55:22 +01:00
|
|
|
|
|
|
|
/** Value type */
|
|
|
|
class CPPCHECKLIB ValueType {
|
|
|
|
public:
|
|
|
|
enum Sign { UNKNOWN_SIGN, SIGNED, UNSIGNED } sign;
|
2021-08-14 19:00:58 +02:00
|
|
|
enum Type {
|
|
|
|
UNKNOWN_TYPE,
|
2022-03-24 06:35:44 +01:00
|
|
|
POD,
|
2021-08-14 19:00:58 +02:00
|
|
|
NONSTD,
|
|
|
|
RECORD,
|
|
|
|
SMART_POINTER,
|
|
|
|
CONTAINER,
|
|
|
|
ITERATOR,
|
|
|
|
VOID,
|
|
|
|
BOOL,
|
|
|
|
CHAR,
|
|
|
|
SHORT,
|
|
|
|
WCHAR_T,
|
|
|
|
INT,
|
|
|
|
LONG,
|
|
|
|
LONGLONG,
|
|
|
|
UNKNOWN_INT,
|
|
|
|
FLOAT,
|
|
|
|
DOUBLE,
|
|
|
|
LONGDOUBLE
|
|
|
|
} type;
|
2021-07-20 21:30:27 +02:00
|
|
|
nonneg int bits; ///< bitfield bitcount
|
|
|
|
nonneg int pointer; ///< 0=>not pointer, 1=>*, 2=>**, 3=>***, etc
|
|
|
|
nonneg int constness; ///< bit 0=data, bit 1=*, bit 2=**
|
|
|
|
Reference reference = Reference::None; ///< Is the outermost indirection of this type a reference or rvalue
|
2021-07-21 20:13:38 +02:00
|
|
|
///< reference or not? pointer=2, Reference=LValue would be a T**&
|
2021-07-20 21:30:27 +02:00
|
|
|
const Scope* typeScope; ///< if the type definition is seen this point out the type scope
|
|
|
|
const ::Type* smartPointerType; ///< Smart pointer type
|
|
|
|
const Token* smartPointerTypeToken; ///< Smart pointer type token
|
|
|
|
const Library::SmartPointer* smartPointer; ///< Smart pointer
|
|
|
|
const Library::Container* container; ///< If the type is a container defined in a cfg file, this is the used
|
2021-07-21 20:13:38 +02:00
|
|
|
///< container
|
2021-07-20 21:30:27 +02:00
|
|
|
const Token* containerTypeToken; ///< The container type token. the template argument token that defines the
|
2021-07-21 20:13:38 +02:00
|
|
|
///< container element type.
|
2021-07-20 21:30:27 +02:00
|
|
|
std::string originalTypeName; ///< original type name as written in the source code. eg. this might be "uint8_t"
|
2021-07-21 20:13:38 +02:00
|
|
|
///< when type is CHAR.
|
2022-06-15 21:25:55 +02:00
|
|
|
ErrorPath debugPath; ///< debug path to the type
|
2017-03-22 02:55:22 +01:00
|
|
|
|
2019-09-30 21:04:43 +02:00
|
|
|
ValueType()
|
|
|
|
: sign(UNKNOWN_SIGN),
|
2021-08-07 20:51:18 +02:00
|
|
|
type(UNKNOWN_TYPE),
|
|
|
|
bits(0),
|
|
|
|
pointer(0U),
|
|
|
|
constness(0U),
|
|
|
|
typeScope(nullptr),
|
|
|
|
smartPointerType(nullptr),
|
|
|
|
smartPointerTypeToken(nullptr),
|
|
|
|
smartPointer(nullptr),
|
|
|
|
container(nullptr),
|
2022-06-15 21:25:55 +02:00
|
|
|
containerTypeToken(nullptr),
|
|
|
|
debugPath()
|
2019-09-30 21:04:43 +02:00
|
|
|
{}
|
|
|
|
ValueType(enum Sign s, enum Type t, nonneg int p)
|
|
|
|
: sign(s),
|
2021-08-07 20:51:18 +02:00
|
|
|
type(t),
|
|
|
|
bits(0),
|
|
|
|
pointer(p),
|
|
|
|
constness(0U),
|
|
|
|
typeScope(nullptr),
|
|
|
|
smartPointerType(nullptr),
|
|
|
|
smartPointerTypeToken(nullptr),
|
|
|
|
smartPointer(nullptr),
|
|
|
|
container(nullptr),
|
2022-06-15 21:25:55 +02:00
|
|
|
containerTypeToken(nullptr),
|
|
|
|
debugPath()
|
2019-09-30 21:04:43 +02:00
|
|
|
{}
|
|
|
|
ValueType(enum Sign s, enum Type t, nonneg int p, nonneg int c)
|
|
|
|
: sign(s),
|
2021-08-07 20:51:18 +02:00
|
|
|
type(t),
|
|
|
|
bits(0),
|
|
|
|
pointer(p),
|
|
|
|
constness(c),
|
|
|
|
typeScope(nullptr),
|
|
|
|
smartPointerType(nullptr),
|
|
|
|
smartPointerTypeToken(nullptr),
|
|
|
|
smartPointer(nullptr),
|
|
|
|
container(nullptr),
|
2022-06-15 21:25:55 +02:00
|
|
|
containerTypeToken(nullptr),
|
|
|
|
debugPath()
|
2019-09-30 21:04:43 +02:00
|
|
|
{}
|
2022-09-16 18:59:15 +02:00
|
|
|
ValueType(enum Sign s, enum Type t, nonneg int p, nonneg int c, std::string otn)
|
2019-09-30 21:04:43 +02:00
|
|
|
: sign(s),
|
2021-08-07 20:51:18 +02:00
|
|
|
type(t),
|
|
|
|
bits(0),
|
|
|
|
pointer(p),
|
|
|
|
constness(c),
|
|
|
|
typeScope(nullptr),
|
|
|
|
smartPointerType(nullptr),
|
|
|
|
smartPointerTypeToken(nullptr),
|
|
|
|
smartPointer(nullptr),
|
|
|
|
container(nullptr),
|
|
|
|
containerTypeToken(nullptr),
|
2022-09-16 18:59:15 +02:00
|
|
|
originalTypeName(std::move(otn)),
|
2022-06-15 21:25:55 +02:00
|
|
|
debugPath()
|
2019-09-30 21:04:43 +02:00
|
|
|
{}
|
2021-01-27 20:03:42 +01:00
|
|
|
|
2023-03-07 12:22:06 +01:00
|
|
|
static ValueType parseDecl(const Token *type, const Settings &settings, bool isCpp);
|
2017-03-22 02:55:22 +01:00
|
|
|
|
|
|
|
static Type typeFromString(const std::string &typestr, bool longType);
|
|
|
|
|
2019-07-31 12:38:36 +02:00
|
|
|
enum class MatchResult { UNKNOWN, SAME, FALLBACK1, FALLBACK2, NOMATCH };
|
2019-07-29 18:14:06 +02:00
|
|
|
static MatchResult matchParameter(const ValueType *call, const ValueType *func);
|
2019-08-03 10:10:22 +02:00
|
|
|
static MatchResult matchParameter(const ValueType *call, const Variable *callVar, const Variable *funcVar);
|
2019-07-29 18:14:06 +02:00
|
|
|
|
2021-06-03 07:35:50 +02:00
|
|
|
bool isPrimitive() const {
|
|
|
|
return (type >= ValueType::Type::BOOL);
|
|
|
|
}
|
2021-06-03 07:31:46 +02:00
|
|
|
|
2017-03-22 02:55:22 +01:00
|
|
|
bool isIntegral() const {
|
|
|
|
return (type >= ValueType::Type::BOOL && type <= ValueType::Type::UNKNOWN_INT);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isFloat() const {
|
2017-03-23 00:11:40 +01:00
|
|
|
return (type >= ValueType::Type::FLOAT && type <= ValueType::Type::LONGDOUBLE);
|
2017-03-22 02:55:22 +01:00
|
|
|
}
|
|
|
|
|
2023-03-07 12:22:06 +01:00
|
|
|
bool fromLibraryType(const std::string &typestr, const Settings &settings);
|
2017-03-22 02:55:22 +01:00
|
|
|
|
2018-04-05 06:46:48 +02:00
|
|
|
bool isEnum() const {
|
|
|
|
return typeScope && typeScope->type == Scope::eEnum;
|
|
|
|
}
|
|
|
|
|
2020-01-18 17:32:59 +01:00
|
|
|
MathLib::bigint typeSize(const cppcheck::Platform &platform, bool p=false) const;
|
2019-03-17 13:09:15 +01:00
|
|
|
|
2022-05-13 06:51:07 +02:00
|
|
|
/// Check if type is the same ignoring const and references
|
|
|
|
bool isTypeEqual(const ValueType* that) const;
|
|
|
|
|
2017-03-22 02:55:22 +01:00
|
|
|
std::string str() const;
|
2017-04-16 09:11:20 +02:00
|
|
|
std::string dump() const;
|
2022-06-15 21:25:55 +02:00
|
|
|
|
|
|
|
void setDebugPath(const Token* tok, SourceLocation ctx, SourceLocation local = SourceLocation::current());
|
2017-03-22 02:55:22 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-06-10 14:19:09 +02:00
|
|
|
class CPPCHECKLIB SymbolDatabase {
|
2018-04-27 10:24:02 +02:00
|
|
|
friend class TestSymbolDatabase;
|
2011-01-17 07:21:59 +01:00
|
|
|
public:
|
2023-03-07 12:22:06 +01:00
|
|
|
SymbolDatabase(const Tokenizer &tokenizer, const Settings &settings, ErrorLogger *errorLogger);
|
2014-11-02 10:36:52 +01:00
|
|
|
~SymbolDatabase();
|
2010-11-13 08:08:45 +01:00
|
|
|
|
2022-07-10 22:40:05 +02:00
|
|
|
/** @brief Information about all namespaces/classes/structures */
|
2011-03-11 01:43:29 +01:00
|
|
|
std::list<Scope> scopeList;
|
2010-11-13 08:08:45 +01:00
|
|
|
|
2012-10-08 16:15:07 +02:00
|
|
|
/** @brief Fast access to function scopes */
|
2012-10-11 06:12:24 +02:00
|
|
|
std::vector<const Scope *> functionScopes;
|
2012-10-10 20:42:07 +02:00
|
|
|
|
|
|
|
/** @brief Fast access to class and struct scopes */
|
2012-10-11 06:12:24 +02:00
|
|
|
std::vector<const Scope *> classAndStructScopes;
|
2012-10-08 16:15:07 +02:00
|
|
|
|
2013-03-05 13:33:38 +01:00
|
|
|
/** @brief Fast access to types */
|
|
|
|
std::list<Type> typeList;
|
|
|
|
|
2010-12-21 08:13:40 +01:00
|
|
|
/**
|
|
|
|
* @brief find a variable type if it's a user defined type
|
|
|
|
* @param start scope to start looking in
|
2017-05-06 11:57:02 +02:00
|
|
|
* @param typeTok token containing variable type
|
2010-12-21 08:13:40 +01:00
|
|
|
* @return pointer to type if found or NULL if not found
|
|
|
|
*/
|
lib: fix a bunch of warnings about differing function arguments in definition and declaration.
[lib/token.h:72] -> [lib/token.cpp:36]: (style, inconclusive) Function 'Token' argument 1 names different: declaration 'tokensBack' definition 't'.
[lib/token.h:445] -> [lib/token.cpp:497]: (style, inconclusive) Function 'multiCompare' argument 1 names different: declaration 'needle' definition 'tok'.
[lib/checkio.h:73] -> [lib/checkio.cpp:1385]: (style, inconclusive) Function 'ArgumentInfo' argument 3 names different: declaration 'isCPP' definition '_isCPP'.
[lib/checkother.h:216] -> [lib/checkother.cpp:2136]: (style, inconclusive) Function 'checkComparisonFunctionIsAlwaysTrueOrFalseError' argument 2 names different: declaration 'strFunctionName' definition 'functionName'.
[lib/errorlogger.h:214] -> [lib/errorlogger.cpp:51]: (style, inconclusive) Function 'ErrorMessage' argument 2 names different: declaration 'file0' definition 'file0_'.
[lib/errorlogger.h:215] -> [lib/errorlogger.cpp:65]: (style, inconclusive) Function 'ErrorMessage' argument 2 names different: declaration 'file0' definition 'file0_'.
[lib/library.h:327] -> [lib/library.cpp:1043]: (style, inconclusive) Function 'ignorefunction' argument 1 names different: declaration 'function' definition 'functionName'.
[lib/mathlib.h:112] -> [lib/mathlib.cpp:1275]: (style, inconclusive) Function 'isNullValue' argument 1 names different: declaration 'tok' definition 'str'.
[lib/preprocessor.h:91] -> [lib/preprocessor.cpp:122]: (style, inconclusive) Function 'setDirectives' argument 1 names different: declaration 'tokens' definition 'tokens1'.
[lib/symboldatabase.h:860] -> [lib/symboldatabase.cpp:1801]: (style, inconclusive) Function 'argsMatch' argument 1 names different: declaration 'info' definition 'scope'.
[lib/symboldatabase.h:1171] -> [lib/symboldatabase.cpp:2048]: (style, inconclusive) Function 'addClassFunction' argument 1 names different: declaration 'info' definition 'scope'.
[lib/symboldatabase.h:1174] -> [lib/symboldatabase.cpp:2208]: (style, inconclusive) Function 'addNewFunction' argument 1 names different: declaration 'info' definition 'scope'.
[lib/symboldatabase.h:1090] -> [lib/symboldatabase.cpp:3648]: (style, inconclusive) Function 'findVariableType' argument 2 names different: declaration 'type' definition 'typeTok'.
[lib/symboldatabase.h:1101] -> [lib/symboldatabase.cpp:4308]: (style, inconclusive) Function 'findType' argument 1 names different: declaration 'tok' definition 'startTok'.
[lib/symboldatabase.h:1176] -> [lib/symboldatabase.cpp:4349]: (style, inconclusive) Function 'findTypeInNested' argument 1 names different: declaration 'tok' definition 'startTok'.
[lib/symboldatabase.h:1193] -> [lib/symboldatabase.cpp:4501]: (style, inconclusive) Function 'setValueType' argument 2 names different: declaration 'enumerators' definition 'enumerator'.
[lib/path.h:159] -> [lib/path.cpp:247]: (style, inconclusive) Function 'isCPP' argument 1 names different: declaration 'extensionInLowerCase' definition 'path'.
[lib/path.h:145] -> [lib/path.cpp:266]: (style, inconclusive) Function 'acceptFile' argument 1 names different: declaration 'filename' definition 'path'.
2017-04-03 00:06:46 +02:00
|
|
|
const Type *findVariableType(const Scope *start, const Token *typeTok) const;
|
2010-12-21 08:13:40 +01:00
|
|
|
|
2012-10-14 17:30:37 +02:00
|
|
|
/**
|
2013-01-28 06:47:48 +01:00
|
|
|
* @brief find a function
|
2012-10-14 17:30:37 +02:00
|
|
|
* @param tok token of function call
|
|
|
|
* @return pointer to function if found or NULL if not found
|
|
|
|
*/
|
2013-01-28 06:47:48 +01:00
|
|
|
const Function *findFunction(const Token *tok) const;
|
2013-01-01 09:53:40 +01:00
|
|
|
|
2022-01-03 12:40:20 +01:00
|
|
|
/** For unit testing only */
|
2013-01-03 22:37:19 +01:00
|
|
|
const Scope *findScopeByName(const std::string& name) const;
|
2012-02-24 20:45:56 +01:00
|
|
|
|
2022-02-12 08:19:07 +01:00
|
|
|
const Type* findType(const Token *startTok, const Scope *startScope, bool lookOutside = false) const;
|
2023-02-24 21:22:08 +01:00
|
|
|
Type* findType(const Token *startTok, Scope *startScope, bool lookOutside = false) {
|
2022-02-12 08:19:07 +01:00
|
|
|
return const_cast<Type*>(this->findType(startTok, const_cast<const Scope *>(startScope), lookOutside));
|
2013-03-05 13:33:38 +01:00
|
|
|
}
|
|
|
|
|
2012-11-30 06:03:58 +01:00
|
|
|
const Scope *findScope(const Token *tok, const Scope *startScope) const;
|
2023-02-24 21:22:08 +01:00
|
|
|
Scope *findScope(const Token *tok, Scope *startScope) {
|
2015-08-27 16:14:33 +02:00
|
|
|
return const_cast<Scope *>(this->findScope(tok, const_cast<const Scope *>(startScope)));
|
2013-01-03 22:37:19 +01:00
|
|
|
}
|
2012-11-30 06:03:58 +01:00
|
|
|
|
2021-01-22 21:47:24 +01:00
|
|
|
bool isVarId(nonneg int varid) const {
|
|
|
|
return varid < mVariableList.size();
|
|
|
|
}
|
2021-01-21 19:49:37 +01:00
|
|
|
|
2019-07-22 11:25:51 +02:00
|
|
|
const Variable *getVariableFromVarId(nonneg int varId) const {
|
2018-06-16 20:31:47 +02:00
|
|
|
return mVariableList.at(varId);
|
2011-02-26 21:57:16 +01:00
|
|
|
}
|
|
|
|
|
2018-04-28 09:38:33 +02:00
|
|
|
const std::vector<const Variable *> & variableList() const {
|
2018-06-16 20:31:47 +02:00
|
|
|
return mVariableList;
|
2012-01-26 04:48:18 +01:00
|
|
|
}
|
|
|
|
|
2011-03-03 03:08:27 +01:00
|
|
|
/**
|
|
|
|
* @brief output a debug message
|
|
|
|
*/
|
2020-12-31 19:24:16 +01:00
|
|
|
void debugMessage(const Token *tok, const std::string &type, const std::string &msg) const;
|
2011-03-03 03:08:27 +01:00
|
|
|
|
2015-11-29 13:23:13 +01:00
|
|
|
void printOut(const char * title = nullptr) const;
|
2012-01-05 18:22:54 +01:00
|
|
|
void printVariable(const Variable *var, const char *indent) const;
|
2014-07-14 15:51:45 +02:00
|
|
|
void printXml(std::ostream &out) const;
|
2012-01-05 18:22:54 +01:00
|
|
|
|
2012-11-26 16:34:44 +01:00
|
|
|
bool isCPP() const;
|
|
|
|
|
2015-12-05 20:55:26 +01:00
|
|
|
/*
|
|
|
|
* @brief Do a sanity check
|
|
|
|
*/
|
|
|
|
void validate() const;
|
|
|
|
|
2016-02-03 17:08:46 +01:00
|
|
|
void validateExecutableScopes() const;
|
|
|
|
/**
|
|
|
|
* @brief Check variable list, e.g. variables w/o scope
|
|
|
|
*/
|
|
|
|
void validateVariables() const;
|
|
|
|
|
2015-10-04 19:42:58 +02:00
|
|
|
/** Set valuetype in provided tokenlist */
|
2020-04-27 09:08:50 +02:00
|
|
|
void setValueTypeInTokenList(bool reportDebugWarnings, Token *tokens=nullptr);
|
2015-10-04 19:42:58 +02:00
|
|
|
|
2016-07-08 20:53:08 +02:00
|
|
|
/**
|
|
|
|
* Calculates sizeof value for given type.
|
|
|
|
* @param type Token which will contain e.g. "int", "*", or string.
|
|
|
|
* @return sizeof for given type, or 0 if it can't be calculated.
|
|
|
|
*/
|
2019-07-22 11:25:51 +02:00
|
|
|
nonneg int sizeOfType(const Token *type) const;
|
2016-07-08 20:53:08 +02:00
|
|
|
|
2019-03-15 19:00:42 +01:00
|
|
|
/** Set array dimensions when valueflow analysis is completed */
|
|
|
|
void setArrayDimensionsUsingValueFlow();
|
|
|
|
|
2021-04-30 16:47:02 +02:00
|
|
|
void clangSetVariables(const std::vector<const Variable *> &variableList);
|
2021-01-06 11:03:43 +01:00
|
|
|
void createSymbolDatabaseExprIds();
|
2020-01-05 15:12:53 +01:00
|
|
|
|
2010-11-13 08:08:45 +01:00
|
|
|
private:
|
2011-01-17 18:29:19 +01:00
|
|
|
friend class Scope;
|
2015-01-30 21:56:27 +01:00
|
|
|
friend class Function;
|
2010-12-31 10:24:51 +01:00
|
|
|
|
2017-01-01 11:34:05 +01:00
|
|
|
// Create symboldatabase...
|
|
|
|
void createSymbolDatabaseFindAllScopes();
|
|
|
|
void createSymbolDatabaseClassInfo();
|
|
|
|
void createSymbolDatabaseVariableInfo();
|
2018-01-07 14:20:19 +01:00
|
|
|
void createSymbolDatabaseCopyAndMoveConstructors();
|
2017-01-01 11:34:05 +01:00
|
|
|
void createSymbolDatabaseFunctionScopes();
|
|
|
|
void createSymbolDatabaseClassAndStructScopes();
|
|
|
|
void createSymbolDatabaseFunctionReturnTypes();
|
|
|
|
void createSymbolDatabaseNeedInitialization();
|
|
|
|
void createSymbolDatabaseVariableSymbolTable();
|
|
|
|
void createSymbolDatabaseSetScopePointers();
|
2017-03-24 12:19:14 +01:00
|
|
|
void createSymbolDatabaseSetFunctionPointers(bool firstPass);
|
2017-01-01 11:34:05 +01:00
|
|
|
void createSymbolDatabaseSetVariablePointers();
|
2022-03-02 07:46:47 +01:00
|
|
|
// cppcheck-suppress functionConst
|
2017-01-01 11:34:05 +01:00
|
|
|
void createSymbolDatabaseSetTypePointers();
|
2020-02-14 09:40:27 +01:00
|
|
|
void createSymbolDatabaseSetSmartPointerType();
|
2017-01-01 11:34:05 +01:00
|
|
|
void createSymbolDatabaseEnums();
|
2019-08-08 07:46:47 +02:00
|
|
|
void createSymbolDatabaseEscapeFunctions();
|
2022-03-02 07:46:47 +01:00
|
|
|
// cppcheck-suppress functionConst
|
2019-08-05 07:18:06 +02:00
|
|
|
void createSymbolDatabaseIncompleteVars();
|
2017-01-01 11:34:05 +01:00
|
|
|
|
2022-06-15 21:25:55 +02:00
|
|
|
void debugSymbolDatabase() const;
|
|
|
|
|
lib: fix a bunch of warnings about differing function arguments in definition and declaration.
[lib/token.h:72] -> [lib/token.cpp:36]: (style, inconclusive) Function 'Token' argument 1 names different: declaration 'tokensBack' definition 't'.
[lib/token.h:445] -> [lib/token.cpp:497]: (style, inconclusive) Function 'multiCompare' argument 1 names different: declaration 'needle' definition 'tok'.
[lib/checkio.h:73] -> [lib/checkio.cpp:1385]: (style, inconclusive) Function 'ArgumentInfo' argument 3 names different: declaration 'isCPP' definition '_isCPP'.
[lib/checkother.h:216] -> [lib/checkother.cpp:2136]: (style, inconclusive) Function 'checkComparisonFunctionIsAlwaysTrueOrFalseError' argument 2 names different: declaration 'strFunctionName' definition 'functionName'.
[lib/errorlogger.h:214] -> [lib/errorlogger.cpp:51]: (style, inconclusive) Function 'ErrorMessage' argument 2 names different: declaration 'file0' definition 'file0_'.
[lib/errorlogger.h:215] -> [lib/errorlogger.cpp:65]: (style, inconclusive) Function 'ErrorMessage' argument 2 names different: declaration 'file0' definition 'file0_'.
[lib/library.h:327] -> [lib/library.cpp:1043]: (style, inconclusive) Function 'ignorefunction' argument 1 names different: declaration 'function' definition 'functionName'.
[lib/mathlib.h:112] -> [lib/mathlib.cpp:1275]: (style, inconclusive) Function 'isNullValue' argument 1 names different: declaration 'tok' definition 'str'.
[lib/preprocessor.h:91] -> [lib/preprocessor.cpp:122]: (style, inconclusive) Function 'setDirectives' argument 1 names different: declaration 'tokens' definition 'tokens1'.
[lib/symboldatabase.h:860] -> [lib/symboldatabase.cpp:1801]: (style, inconclusive) Function 'argsMatch' argument 1 names different: declaration 'info' definition 'scope'.
[lib/symboldatabase.h:1171] -> [lib/symboldatabase.cpp:2048]: (style, inconclusive) Function 'addClassFunction' argument 1 names different: declaration 'info' definition 'scope'.
[lib/symboldatabase.h:1174] -> [lib/symboldatabase.cpp:2208]: (style, inconclusive) Function 'addNewFunction' argument 1 names different: declaration 'info' definition 'scope'.
[lib/symboldatabase.h:1090] -> [lib/symboldatabase.cpp:3648]: (style, inconclusive) Function 'findVariableType' argument 2 names different: declaration 'type' definition 'typeTok'.
[lib/symboldatabase.h:1101] -> [lib/symboldatabase.cpp:4308]: (style, inconclusive) Function 'findType' argument 1 names different: declaration 'tok' definition 'startTok'.
[lib/symboldatabase.h:1176] -> [lib/symboldatabase.cpp:4349]: (style, inconclusive) Function 'findTypeInNested' argument 1 names different: declaration 'tok' definition 'startTok'.
[lib/symboldatabase.h:1193] -> [lib/symboldatabase.cpp:4501]: (style, inconclusive) Function 'setValueType' argument 2 names different: declaration 'enumerators' definition 'enumerator'.
[lib/path.h:159] -> [lib/path.cpp:247]: (style, inconclusive) Function 'isCPP' argument 1 names different: declaration 'extensionInLowerCase' definition 'path'.
[lib/path.h:145] -> [lib/path.cpp:266]: (style, inconclusive) Function 'acceptFile' argument 1 names different: declaration 'filename' definition 'path'.
2017-04-03 00:06:46 +02:00
|
|
|
void addClassFunction(Scope **scope, const Token **tok, const Token *argStart);
|
2013-08-31 18:58:55 +02:00
|
|
|
Function *addGlobalFunctionDecl(Scope*& scope, const Token* tok, const Token *argStart, const Token* funcStart);
|
2013-01-03 22:37:19 +01:00
|
|
|
Function *addGlobalFunction(Scope*& scope, const Token*& tok, const Token *argStart, const Token* funcStart);
|
lib: fix a bunch of warnings about differing function arguments in definition and declaration.
[lib/token.h:72] -> [lib/token.cpp:36]: (style, inconclusive) Function 'Token' argument 1 names different: declaration 'tokensBack' definition 't'.
[lib/token.h:445] -> [lib/token.cpp:497]: (style, inconclusive) Function 'multiCompare' argument 1 names different: declaration 'needle' definition 'tok'.
[lib/checkio.h:73] -> [lib/checkio.cpp:1385]: (style, inconclusive) Function 'ArgumentInfo' argument 3 names different: declaration 'isCPP' definition '_isCPP'.
[lib/checkother.h:216] -> [lib/checkother.cpp:2136]: (style, inconclusive) Function 'checkComparisonFunctionIsAlwaysTrueOrFalseError' argument 2 names different: declaration 'strFunctionName' definition 'functionName'.
[lib/errorlogger.h:214] -> [lib/errorlogger.cpp:51]: (style, inconclusive) Function 'ErrorMessage' argument 2 names different: declaration 'file0' definition 'file0_'.
[lib/errorlogger.h:215] -> [lib/errorlogger.cpp:65]: (style, inconclusive) Function 'ErrorMessage' argument 2 names different: declaration 'file0' definition 'file0_'.
[lib/library.h:327] -> [lib/library.cpp:1043]: (style, inconclusive) Function 'ignorefunction' argument 1 names different: declaration 'function' definition 'functionName'.
[lib/mathlib.h:112] -> [lib/mathlib.cpp:1275]: (style, inconclusive) Function 'isNullValue' argument 1 names different: declaration 'tok' definition 'str'.
[lib/preprocessor.h:91] -> [lib/preprocessor.cpp:122]: (style, inconclusive) Function 'setDirectives' argument 1 names different: declaration 'tokens' definition 'tokens1'.
[lib/symboldatabase.h:860] -> [lib/symboldatabase.cpp:1801]: (style, inconclusive) Function 'argsMatch' argument 1 names different: declaration 'info' definition 'scope'.
[lib/symboldatabase.h:1171] -> [lib/symboldatabase.cpp:2048]: (style, inconclusive) Function 'addClassFunction' argument 1 names different: declaration 'info' definition 'scope'.
[lib/symboldatabase.h:1174] -> [lib/symboldatabase.cpp:2208]: (style, inconclusive) Function 'addNewFunction' argument 1 names different: declaration 'info' definition 'scope'.
[lib/symboldatabase.h:1090] -> [lib/symboldatabase.cpp:3648]: (style, inconclusive) Function 'findVariableType' argument 2 names different: declaration 'type' definition 'typeTok'.
[lib/symboldatabase.h:1101] -> [lib/symboldatabase.cpp:4308]: (style, inconclusive) Function 'findType' argument 1 names different: declaration 'tok' definition 'startTok'.
[lib/symboldatabase.h:1176] -> [lib/symboldatabase.cpp:4349]: (style, inconclusive) Function 'findTypeInNested' argument 1 names different: declaration 'tok' definition 'startTok'.
[lib/symboldatabase.h:1193] -> [lib/symboldatabase.cpp:4501]: (style, inconclusive) Function 'setValueType' argument 2 names different: declaration 'enumerators' definition 'enumerator'.
[lib/path.h:159] -> [lib/path.cpp:247]: (style, inconclusive) Function 'isCPP' argument 1 names different: declaration 'extensionInLowerCase' definition 'path'.
[lib/path.h:145] -> [lib/path.cpp:266]: (style, inconclusive) Function 'acceptFile' argument 1 names different: declaration 'filename' definition 'path'.
2017-04-03 00:06:46 +02:00
|
|
|
void addNewFunction(Scope **scope, const Token **tok);
|
2016-07-17 15:47:32 +02:00
|
|
|
bool isFunction(const Token *tok, const Scope* outerScope, const Token **funcStart, const Token **argStart, const Token** declEnd) const;
|
lib: fix a bunch of warnings about differing function arguments in definition and declaration.
[lib/token.h:72] -> [lib/token.cpp:36]: (style, inconclusive) Function 'Token' argument 1 names different: declaration 'tokensBack' definition 't'.
[lib/token.h:445] -> [lib/token.cpp:497]: (style, inconclusive) Function 'multiCompare' argument 1 names different: declaration 'needle' definition 'tok'.
[lib/checkio.h:73] -> [lib/checkio.cpp:1385]: (style, inconclusive) Function 'ArgumentInfo' argument 3 names different: declaration 'isCPP' definition '_isCPP'.
[lib/checkother.h:216] -> [lib/checkother.cpp:2136]: (style, inconclusive) Function 'checkComparisonFunctionIsAlwaysTrueOrFalseError' argument 2 names different: declaration 'strFunctionName' definition 'functionName'.
[lib/errorlogger.h:214] -> [lib/errorlogger.cpp:51]: (style, inconclusive) Function 'ErrorMessage' argument 2 names different: declaration 'file0' definition 'file0_'.
[lib/errorlogger.h:215] -> [lib/errorlogger.cpp:65]: (style, inconclusive) Function 'ErrorMessage' argument 2 names different: declaration 'file0' definition 'file0_'.
[lib/library.h:327] -> [lib/library.cpp:1043]: (style, inconclusive) Function 'ignorefunction' argument 1 names different: declaration 'function' definition 'functionName'.
[lib/mathlib.h:112] -> [lib/mathlib.cpp:1275]: (style, inconclusive) Function 'isNullValue' argument 1 names different: declaration 'tok' definition 'str'.
[lib/preprocessor.h:91] -> [lib/preprocessor.cpp:122]: (style, inconclusive) Function 'setDirectives' argument 1 names different: declaration 'tokens' definition 'tokens1'.
[lib/symboldatabase.h:860] -> [lib/symboldatabase.cpp:1801]: (style, inconclusive) Function 'argsMatch' argument 1 names different: declaration 'info' definition 'scope'.
[lib/symboldatabase.h:1171] -> [lib/symboldatabase.cpp:2048]: (style, inconclusive) Function 'addClassFunction' argument 1 names different: declaration 'info' definition 'scope'.
[lib/symboldatabase.h:1174] -> [lib/symboldatabase.cpp:2208]: (style, inconclusive) Function 'addNewFunction' argument 1 names different: declaration 'info' definition 'scope'.
[lib/symboldatabase.h:1090] -> [lib/symboldatabase.cpp:3648]: (style, inconclusive) Function 'findVariableType' argument 2 names different: declaration 'type' definition 'typeTok'.
[lib/symboldatabase.h:1101] -> [lib/symboldatabase.cpp:4308]: (style, inconclusive) Function 'findType' argument 1 names different: declaration 'tok' definition 'startTok'.
[lib/symboldatabase.h:1176] -> [lib/symboldatabase.cpp:4349]: (style, inconclusive) Function 'findTypeInNested' argument 1 names different: declaration 'tok' definition 'startTok'.
[lib/symboldatabase.h:1193] -> [lib/symboldatabase.cpp:4501]: (style, inconclusive) Function 'setValueType' argument 2 names different: declaration 'enumerators' definition 'enumerator'.
[lib/path.h:159] -> [lib/path.cpp:247]: (style, inconclusive) Function 'isCPP' argument 1 names different: declaration 'extensionInLowerCase' definition 'path'.
[lib/path.h:145] -> [lib/path.cpp:266]: (style, inconclusive) Function 'acceptFile' argument 1 names different: declaration 'filename' definition 'path'.
2017-04-03 00:06:46 +02:00
|
|
|
const Type *findTypeInNested(const Token *startTok, const Scope *startScope) const;
|
2014-04-10 16:11:11 +02:00
|
|
|
const Scope *findNamespace(const Token * tok, const Scope * scope) const;
|
2019-07-22 11:25:51 +02:00
|
|
|
Function *findFunctionInScope(const Token *func, const Scope *ns, const std::string & path, nonneg int path_length);
|
2016-08-13 21:25:57 +02:00
|
|
|
const Type *findVariableTypeInBase(const Scope *scope, const Token *typeTok) const;
|
2014-04-10 16:11:11 +02:00
|
|
|
|
2022-07-26 11:10:03 +02:00
|
|
|
using MemberIdMap = std::map<unsigned int, unsigned int>;
|
|
|
|
using VarIdMap = std::map<unsigned int, MemberIdMap>;
|
2017-03-30 10:07:58 +02:00
|
|
|
|
|
|
|
void fixVarId(VarIdMap & varIds, const Token * vartok, Token * membertok, const Variable * membervar);
|
|
|
|
|
2015-05-22 22:18:42 +02:00
|
|
|
/** Whether iName is a keyword as defined in http://en.cppreference.com/w/c/keyword and http://en.cppreference.com/w/cpp/keyword*/
|
|
|
|
bool isReservedName(const std::string& iName) const;
|
|
|
|
|
2022-06-08 16:58:57 +02:00
|
|
|
const Enumerator * findEnumerator(const Token * tok, std::set<std::string>& tokensThatAreNotEnumeratorValues) const;
|
2016-04-22 06:02:54 +02:00
|
|
|
|
2022-06-15 21:25:55 +02:00
|
|
|
void setValueType(Token* tok, const ValueType& valuetype, SourceLocation loc = SourceLocation::current());
|
|
|
|
void setValueType(Token* tok, const Variable& var, SourceLocation loc = SourceLocation::current());
|
|
|
|
void setValueType(Token* tok, const Enumerator& enumerator, SourceLocation loc = SourceLocation::current());
|
2017-03-22 02:55:22 +01:00
|
|
|
|
2023-03-07 12:22:06 +01:00
|
|
|
const Tokenizer &mTokenizer;
|
|
|
|
const Settings &mSettings;
|
2018-06-16 16:10:28 +02:00
|
|
|
ErrorLogger *mErrorLogger;
|
2011-02-26 21:57:16 +01:00
|
|
|
|
|
|
|
/** variable symbol table */
|
2018-06-16 20:31:47 +02:00
|
|
|
std::vector<const Variable *> mVariableList;
|
2013-07-08 11:45:26 +02:00
|
|
|
|
|
|
|
/** list for missing types */
|
2018-06-16 20:33:07 +02:00
|
|
|
std::list<Type> mBlankTypes;
|
2015-05-17 20:02:41 +02:00
|
|
|
|
2018-06-16 23:30:00 +02:00
|
|
|
bool mIsCpp;
|
2018-06-16 23:25:35 +02:00
|
|
|
ValueType::Sign mDefaultSignedness;
|
2015-10-04 19:42:58 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-09-04 20:59:49 +02:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
#endif // symboldatabaseH
|