2010-11-13 08:08:45 +01:00
/*
* Cppcheck - A tool for static C / C + + code analysis
2021-03-21 20:58:32 +01:00
* Copyright ( C ) 2007 - 2021 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"
2017-03-05 02:09:52 +01:00
# include "library.h"
2017-05-27 04:33:47 +02:00
# include "mathlib.h"
# include "token.h"
2020-04-13 13:44:48 +02:00
# include "utils.h"
2011-01-18 07:32:06 +01:00
2021-04-03 21:30:50 +02:00
# include <cctype>
2017-05-27 04:33:47 +02:00
# include <cstddef>
# include <list>
# include <map>
# include <set>
# include <string>
# 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 {
2019-03-15 19:00:42 +01: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 ( ) :
2019-07-23 14:29:02 +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 ( ) :
2015-11-29 13:23:13 +01: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
2017-08-09 20:00:26 +02:00
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 ;
while ( typeEnd - > next ( ) & & typeEnd - > next ( ) - > str ( ) ! = " ; " )
typeEnd = typeEnd - > next ( ) ;
}
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
/**
2018-02-04 20:53:43 +01:00
* Check for circulare dependencies , i . e . loops within the class hierarchy
2015-09-04 15:12:40 +02:00
* @ param ancestors list of ancestors . For internal usage only , clients should not supply this argument .
2014-03-29 12:21:35 +01:00
* @ 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
/**
2015-07-01 00:04:01 +02:00
* Check for dependency
2015-09-04 15:12:40 +02:00
* @ param ancestor potential ancestor
2015-07-01 00:04:01 +02:00
* @ 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 :
explicit Enumerator ( const Scope * scope_ ) : scope ( scope_ ) , name ( nullptr ) , value ( 0 ) , start ( nullptr ) , end ( nullptr ) , value_known ( false ) { }
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
2012-05-11 17:56:47 +02:00
* @ return true if array , false if not
*/
2019-03-15 19:00:42 +01:00
bool arrayDimensions ( const Settings * settings ) ;
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_ ) ,
2018-06-16 16:03:36 +02:00
mTypeStartToken ( start_ ) ,
mTypeEndToken ( end_ ) ,
2018-06-16 16:11:40 +02:00
mIndex ( index_ ) ,
2018-06-16 16:12:27 +02:00
mAccess ( access_ ) ,
2018-06-16 16:14:34 +02:00
mFlags ( 0 ) ,
2018-06-16 20:25:54 +02:00
mType ( type_ ) ,
2018-06-20 10:00:15 +02:00
mScope ( scope_ ) ,
mValueType ( nullptr ) {
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
}
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
/**
* 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 ) ;
}
2019-07-07 21:52:49 +02:00
const Type * smartPointerType ( ) const ;
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
/**
* Determine whether it ' s a floating number type
2014-08-09 11:44:55 +02:00
* @ 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-05-24 18:35:49 +02:00
*/
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
/**
* Determine whether it ' s an enumeration type
* @ return true if the type is known and it ' s an enumeration type
*/
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
2018-06-20 10:00:15 +02:00
ValueType * mValueType ;
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
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 ) ;
}
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 ) ;
}
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
std : : list < 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, ...
AccessControl access ; ///< public/protected/private
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
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 ) ;
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 ) ;
}
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 ;
2011-01-17 18:29:19 +01:00
std : : list < Scope * > nestedList ;
2019-07-22 11:25:51 +02:00
nonneg int numConstructors ;
nonneg int numCopyOrMoveConstructors ;
2012-12-20 06:53:04 +01:00
std : : list < 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 ;
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-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 {
2019-09-19 20:29:33 +02:00
for ( const Enumerator & i : enumeratorList ) {
if ( i . name - > str ( ) = = name )
return & i ;
2016-04-22 06:02:54 +02:00
}
return nullptr ;
}
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
2011-01-17 07:21:59 +01:00
/**
* @ brief find if name is in nested list
2011-01-21 07:42:41 +01:00
* @ param name name of nested scope
2011-01-17 07:21:59 +01:00
*/
2013-01-03 22:37:19 +01:00
Scope * findInNestedList ( const std : : string & name ) ;
2011-01-17 07:21:59 +01:00
2013-01-03 22:37:19 +01:00
const Scope * findRecordInNestedList ( const std : : string & name ) 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
2015-01-02 21:38:19 +01:00
void addFunction ( const Function & func ) {
functionList . push_back ( func ) ;
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 ;
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 ;
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 ;
2019-05-01 16:34:28 +02:00
enum Type { UNKNOWN_TYPE , NONSTD , RECORD , CONTAINER , ITERATOR , VOID , BOOL , CHAR , SHORT , WCHAR_T , INT , LONG , LONGLONG , UNKNOWN_INT , FLOAT , DOUBLE , LONGDOUBLE } type ;
2019-07-22 11:25:51 +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=**
2020-09-03 18:44:44 +02:00
Reference reference = Reference : : None ; ///< Is the outermost indirection of this type a reference or rvalue reference or not? pointer=2, Reference=LValue would be a T**&
2018-04-24 13:03:32 +02:00
const Scope * typeScope ; ///< if the type definition is seen this point out the type scope
2019-07-07 21:52:49 +02:00
const : : Type * smartPointerType ; ///< Smart pointer type
2019-09-30 21:04:43 +02:00
const Token * smartPointerTypeToken ; ///< Smart pointer type token
2018-04-24 13:03:32 +02:00
const Library : : Container * container ; ///< If the type is a container defined in a cfg file, this is the used container
const Token * containerTypeToken ; ///< The container type token. the template argument token that defines the container element type.
std : : string originalTypeName ; ///< original type name as written in the source code. eg. this might be "uint8_t" when type is CHAR.
2017-03-22 02:55:22 +01:00
2019-09-30 21:04:43 +02:00
ValueType ( )
: sign ( UNKNOWN_SIGN ) ,
type ( UNKNOWN_TYPE ) ,
bits ( 0 ) ,
pointer ( 0U ) ,
constness ( 0U ) ,
typeScope ( nullptr ) ,
smartPointerType ( nullptr ) ,
smartPointerTypeToken ( nullptr ) ,
container ( nullptr ) ,
containerTypeToken ( nullptr )
{ }
ValueType ( enum Sign s , enum Type t , nonneg int p )
: sign ( s ) ,
type ( t ) ,
bits ( 0 ) ,
pointer ( p ) ,
constness ( 0U ) ,
typeScope ( nullptr ) ,
smartPointerType ( nullptr ) ,
smartPointerTypeToken ( nullptr ) ,
container ( nullptr ) ,
containerTypeToken ( nullptr )
{ }
ValueType ( enum Sign s , enum Type t , nonneg int p , nonneg int c )
: sign ( s ) ,
type ( t ) ,
bits ( 0 ) ,
pointer ( p ) ,
constness ( c ) ,
typeScope ( nullptr ) ,
smartPointerType ( nullptr ) ,
smartPointerTypeToken ( nullptr ) ,
container ( nullptr ) ,
containerTypeToken ( nullptr )
{ }
ValueType ( enum Sign s , enum Type t , nonneg int p , nonneg int c , const std : : string & otn )
: sign ( s ) ,
type ( t ) ,
bits ( 0 ) ,
pointer ( p ) ,
constness ( c ) ,
typeScope ( nullptr ) ,
smartPointerType ( nullptr ) ,
smartPointerTypeToken ( nullptr ) ,
container ( nullptr ) ,
containerTypeToken ( nullptr ) ,
originalTypeName ( otn )
{ }
2021-01-27 20:03:42 +01:00
ValueType ( const ValueType & vt )
: sign ( vt . sign )
, type ( vt . type )
, bits ( vt . bits )
, pointer ( vt . pointer )
, constness ( vt . constness )
, reference ( vt . reference )
, typeScope ( vt . typeScope )
, smartPointerType ( vt . smartPointerType )
, smartPointerTypeToken ( vt . smartPointerTypeToken )
, container ( vt . container )
, containerTypeToken ( vt . containerTypeToken )
, originalTypeName ( vt . originalTypeName )
{ }
2017-03-22 02:55:22 +01:00
static ValueType parseDecl ( const Token * type , const Settings * settings ) ;
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
}
bool fromLibraryType ( const std : : string & typestr , const Settings * settings ) ;
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
2017-03-22 02:55:22 +01:00
std : : string str ( ) const ;
2017-04-16 09:11:20 +02:00
std : : string dump ( ) const ;
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 :
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
/** @brief Information about all namespaces/classes/structrues */
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
2013-01-03 22:37:19 +01:00
const Scope * findScopeByName ( const std : : string & name ) const ;
2012-02-24 20:45:56 +01:00
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 * findType ( const Token * startTok , const Scope * startScope ) const ;
2017-09-14 23:44:59 +02:00
Type * findType ( const Token * startTok , Scope * startScope ) const {
return const_cast < Type * > ( this - > findType ( startTok , const_cast < const Scope * > ( startScope ) ) ) ;
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 ;
2014-11-20 14:20:09 +01:00
Scope * findScope ( const Token * tok , Scope * startScope ) const {
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 ( ) ;
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 ( ) ;
2019-08-05 07:18:06 +02:00
void createSymbolDatabaseIncompleteVars ( ) ;
2017-01-01 11:34:05 +01:00
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
2017-03-30 10:07:58 +02:00
typedef std : : map < unsigned int , unsigned int > MemberIdMap ;
typedef std : : map < unsigned int , MemberIdMap > VarIdMap ;
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 ;
2016-04-22 06:02:54 +02:00
const Enumerator * findEnumerator ( const Token * tok ) const ;
2017-03-22 02:55:22 +01:00
void setValueType ( Token * tok , const ValueType & valuetype ) ;
void setValueType ( Token * tok , const Variable & var ) ;
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 setValueType ( Token * tok , const Enumerator & enumerator ) ;
2017-03-22 02:55:22 +01:00
2018-06-16 16:10:28 +02:00
const Tokenizer * mTokenizer ;
const Settings * mSettings ;
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 ;
2017-10-18 18:01:36 +02:00
/** "negative cache" list of tokens that we find are not enumeration values */
2018-06-17 17:20:16 +02:00
mutable std : : set < std : : string > mTokensThatAreNotEnumeratorValues ;
2015-10-04 19:42:58 +02:00
} ;
2013-09-04 20:59:49 +02:00
//---------------------------------------------------------------------------
# endif // symboldatabaseH