2008-12-18 22:28:57 +01:00
/*
2009-01-21 21:04:20 +01:00
* Cppcheck - A tool for static C / C + + code analysis
2015-01-03 12:14:58 +01:00
* Copyright ( C ) 2007 - 2015 Daniel Marjamäki and Cppcheck team .
2008-12-18 22:28:57 +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
2009-09-27 17:08:31 +02:00
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
2008-12-18 22:28:57 +01:00
*/
2013-09-04 20:59:49 +02:00
//---------------------------------------------------------------------------
# ifndef tokenH
# define tokenH
//---------------------------------------------------------------------------
2008-12-18 22:28:57 +01:00
2014-01-04 20:57:02 +01:00
# include <list>
2008-12-18 22:28:57 +01:00
# include <string>
2009-11-27 23:04:04 +01:00
# include <vector>
2012-04-16 19:51:07 +02:00
# include <ostream>
2012-06-10 14:19:09 +02:00
# include "config.h"
2014-01-04 20:57:02 +01:00
# include "valueflow.h"
2014-01-20 06:49:45 +01:00
# include "mathlib.h"
2008-12-18 22:28:57 +01:00
2012-08-11 20:47:11 +02:00
class Scope ;
2013-01-31 06:41:18 +01:00
class Function ;
class Variable ;
2014-04-02 06:49:28 +02:00
class Settings ;
2012-08-11 20:47:11 +02:00
2009-07-17 10:49:01 +02:00
/// @addtogroup Core
/// @{
2009-07-13 13:35:33 +02:00
/**
2012-05-05 18:33:26 +02:00
* @ brief The token list that the TokenList generates is a linked - list of this class .
2009-07-13 13:35:33 +02:00
*
* Tokens are stored as strings . The " if " , " while " , etc are stored in plain text .
* The reason the Token class is needed ( instead of using the string class ) is that some extra functionality is also needed for tokens :
* - location of the token is stored ( linenr , fileIndex )
* - functions for classifying the token ( isName , isNumber , isBoolean , isStandardType )
*
* The Token class also has other functions for management of token list , matching tokens , etc .
*/
2012-06-10 14:19:09 +02:00
class CPPCHECKLIB Token {
2010-01-06 20:19:27 +01:00
private :
Token * * tokensBack ;
// Not implemented..
2009-01-03 21:29:20 +01:00
Token ( ) ;
2012-12-01 02:16:03 +01:00
Token ( const Token & ) ;
Token operator = ( const Token & ) ;
2010-01-06 20:19:27 +01:00
public :
2012-04-23 21:05:26 +02:00
enum Type {
2014-06-04 22:33:08 +02:00
eVariable , eType , eFunction , eKeyword , eName , // Names: Variable (varId), Type (typeId, later), Function (FuncId, later), Language keyword, Name (unknown identifier)
2012-04-23 21:05:26 +02:00
eNumber , eString , eChar , eBoolean , eLiteral , // Literals: Number, String, Character, User defined literal (C++11)
2012-04-26 23:04:55 +02:00
eArithmeticalOp , eComparisonOp , eAssignmentOp , eLogicalOp , eBitOp , eIncDecOp , eExtendedOp , // Operators: Arithmetical, Comparison, Assignment, Logical, Bitwise, ++/--, Extended
eBracket , // {, }, <, >: < and > only if link() is set. Otherwise they are comparison operators.
2012-04-23 21:05:26 +02:00
eOther ,
eNone
} ;
2011-10-28 22:10:19 +02:00
explicit Token ( Token * * tokensBack ) ;
2009-01-03 21:29:20 +01:00
~ Token ( ) ;
2009-06-14 08:55:23 +02:00
2014-04-02 18:04:20 +02:00
template < typename T >
2014-11-20 14:20:09 +01:00
void str ( T & & s ) {
2014-04-02 18:04:20 +02:00
_str = s ;
_varId = 0 ;
update_property_info ( ) ;
}
2008-12-18 22:28:57 +01:00
2011-10-23 21:21:42 +02:00
/**
2011-10-23 22:46:55 +02:00
* Concatenate two ( quoted ) strings . Automatically cuts of the last / first character .
* Example : " hello " " world " - > " hello world " . Used by the token simplifier .
2011-10-23 21:21:42 +02:00
*/
2009-03-28 20:33:55 +01:00
void concatStr ( std : : string const & b ) ;
2014-11-20 14:20:09 +01:00
const std : : string & str ( ) const {
2009-01-05 16:49:57 +01:00
return _str ;
}
2008-12-18 22:28:57 +01:00
/**
2011-12-07 23:36:11 +01:00
* Unlink and delete the next ' index ' tokens .
2008-12-18 22:28:57 +01:00
*/
2011-12-07 23:36:11 +01:00
void deleteNext ( unsigned long index = 1 ) ;
2008-12-18 22:28:57 +01:00
2014-12-27 10:53:26 +01:00
/**
* Swap the contents of this token with the next token .
*/
void swapWithNext ( ) ;
2008-12-18 22:28:57 +01:00
/**
2014-04-27 09:32:02 +02:00
* @ return token in given index , related to this token .
2008-12-18 22:28:57 +01:00
* For example index 1 would return next token , and 2
* would return next from that one .
*/
2009-01-03 21:29:20 +01:00
const Token * tokAt ( int index ) const ;
2014-11-20 14:20:09 +01:00
Token * tokAt ( int index ) {
2013-01-03 22:26:20 +01:00
return const_cast < Token * > ( static_cast < const Token * > ( this ) - > tokAt ( index ) ) ;
}
2008-12-18 22:28:57 +01:00
2011-11-11 21:55:37 +01:00
/**
2014-04-27 09:32:02 +02:00
* @ return the link to the token in given index , related to this token .
2011-11-11 21:55:37 +01:00
* For example index 1 would return the link to next token .
*/
const Token * linkAt ( int index ) const ;
2014-11-20 14:20:09 +01:00
Token * linkAt ( int index ) {
2013-01-03 22:26:20 +01:00
return const_cast < Token * > ( static_cast < const Token * > ( this ) - > linkAt ( index ) ) ;
}
2011-11-11 21:55:37 +01:00
2014-04-27 09:32:02 +02:00
/**
* @ return String of the token in given index , related to this token .
2014-07-11 09:33:09 +02:00
* If that token does not exist , an empty string is being returned .
2014-04-27 09:32:02 +02:00
*/
2011-11-14 09:16:47 +01:00
const std : : string & strAt ( int index ) const ;
2008-12-18 22:28:57 +01:00
2008-12-23 22:51:54 +01:00
/**
* Match given token ( or list of tokens ) to a pattern list .
*
* Possible patterns
* " someRandomText " If token contains " someRandomText " .
* @ note Use Match ( ) if you want to use flags in patterns
*
* The patterns can be also combined to compare to multiple tokens at once
* by separating tokens with a space , e . g .
* " ) void { " will return true if first token is ' ) ' next token
* is " void " and token after that is ' { ' . If even one of the tokens does
* not match its pattern , false is returned .
*
* @ param tok List of tokens to be compared to the pattern
* @ param pattern The pattern against which the tokens are compared ,
* e . g . " const " or " ) void { " .
* @ return true if given token matches with given pattern
* false if given token does not match with given pattern
*/
2009-01-03 21:29:20 +01:00
static bool simpleMatch ( const Token * tok , const char pattern [ ] ) ;
2008-12-22 00:28:09 +01:00
2008-12-18 22:28:57 +01:00
/**
* Match given token ( or list of tokens ) to a pattern list .
*
* Possible patterns
2010-03-13 22:16:06 +01:00
* - " %any% " any token
2015-01-31 10:50:39 +01:00
* - " %name% " any token which is a name , variable or type e . g . " hello " or " int "
2010-03-13 22:16:06 +01:00
* - " %type% " Anything that can be a variable type , e . g . " int " , but not " delete " .
* - " %num% " Any numeric token , e . g . " 23 "
* - " %bool% " true or false
2012-11-04 16:34:32 +01:00
* - " %char% " Any token enclosed in & apos ; - character .
2012-12-01 01:31:35 +01:00
* - " %comp% " Any token such that isComparisonOp ( ) returns true .
2010-03-13 22:16:06 +01:00
* - " %str% " Any token starting with & quot ; - character ( C - string ) .
2015-01-31 10:50:39 +01:00
* - " %var% " Match with token with varId > 0
2010-03-13 22:16:06 +01:00
* - " %varid% " Match with parameter varid
2013-03-01 11:47:50 +01:00
* - " %op% " Any token such that isOp ( ) returns true .
2013-03-01 11:43:59 +01:00
* - " %cop% " Any token such that isConstOp ( ) returns true .
2010-10-25 03:14:21 +02:00
* - " %or% " A bitwise - or operator ' | '
* - " %oror% " A logical - or operator ' | | '
2010-03-13 22:16:06 +01:00
* - " [abc] " Any of the characters ' a ' or ' b ' or ' c '
* - " int|void|char " Any of the strings , int , void or char
* - " int|void|char| " Any of the strings , int , void or char or empty string
* - " !!else " No tokens or any token that is not " else " .
* - " someRandomText " If token contains " someRandomText " .
2008-12-18 22:28:57 +01:00
*
2014-01-01 20:46:00 +01:00
* multi - compare patterns such as " int|void|char " can contain % % or % , % % oror % and % % op %
* but it is not recommended to put such an % % cmd % as the first pattern .
2011-11-05 19:24:21 +01:00
*
2014-01-01 20:46:00 +01:00
* It ' s possible to use multi - compare patterns with all the other % % cmds % ,
* except for % % varid % , and normal names , but the % % cmds % should be put as
2012-12-01 02:16:03 +01:00
* the first patterns in the list , then the normal names .
* For example : " %var%|%num%|) " means yes to a variable , a number or ' ) ' .
*
2014-01-01 20:46:00 +01:00
* @ todo Make it possible to use the % % cmds % and the normal names in the
2012-12-01 02:16:03 +01:00
* multicompare list without an order .
2012-11-17 20:25:12 +01:00
*
2008-12-18 22:28:57 +01:00
* The patterns can be also combined to compare to multiple tokens at once
* by separating tokens with a space , e . g .
* " ) const|void { " will return true if first token is ' ) ' next token is either
* " const " or " void " and token after that is ' { ' . If even one of the tokens does not
* match its pattern , false is returned .
*
* @ param tok List of tokens to be compared to the pattern
2008-12-23 22:51:54 +01:00
* @ param pattern The pattern against which the tokens are compared ,
* e . g . " const " or " ) const|volatile| { " .
2014-01-01 20:46:00 +01:00
* @ param varid if % % varid % is given in the pattern the Token : : varId
2012-12-01 02:16:03 +01:00
* will be matched against this argument
2008-12-18 22:28:57 +01:00
* @ return true if given token matches with given pattern
* false if given token does not match with given pattern
*/
2009-01-06 00:06:51 +01:00
static bool Match ( const Token * tok , const char pattern [ ] , unsigned int varid = 0 ) ;
2008-12-18 22:28:57 +01:00
2009-08-30 13:07:10 +02:00
/**
2014-04-27 09:32:02 +02:00
* @ return length of C - string .
2009-08-30 13:07:10 +02:00
*
2014-01-01 20:46:00 +01:00
* Should be called for % % str % % tokens only .
2009-08-30 13:07:10 +02:00
*
* @ param tok token with C - string
* */
2011-11-22 21:14:14 +01:00
static std : : size_t getStrLength ( const Token * tok ) ;
2014-08-01 13:12:18 +02:00
/**
* @ return sizeof of C - string .
*
* Should be called for % % str % % tokens only .
*
* @ param tok token with C - string
* */
static std : : size_t getStrSize ( const Token * tok ) ;
2009-08-30 13:07:10 +02:00
2013-01-13 20:52:38 +01:00
/**
2014-04-27 09:32:02 +02:00
* @ return char of C - string at index ( possible escaped " \\ n " )
2013-01-13 20:52:38 +01:00
*
2014-01-01 20:46:00 +01:00
* Should be called for % % str % % tokens only .
2013-01-13 20:52:38 +01:00
*
* @ param tok token with C - string
* @ param index position of character
* */
static std : : string getCharAt ( const Token * tok , std : : size_t index ) ;
2014-11-20 14:20:09 +01:00
Type type ( ) const {
2012-04-23 21:05:26 +02:00
return _type ;
2009-08-23 17:17:57 +02:00
}
2014-11-20 14:20:09 +01:00
void type ( Type t ) {
2012-04-23 21:05:26 +02:00
_type = t ;
2011-03-08 02:04:25 +01:00
}
2014-11-20 14:20:09 +01:00
void isKeyword ( bool kwd ) {
2014-06-04 22:33:08 +02:00
if ( kwd )
_type = eKeyword ;
else if ( _type = = eKeyword )
_type = eName ;
}
2014-11-20 14:20:09 +01:00
bool isKeyword ( ) const {
2014-06-04 22:33:08 +02:00
return _type = = eKeyword ;
}
2014-11-20 14:20:09 +01:00
bool isName ( ) const {
2014-06-04 22:33:08 +02:00
return _type = = eName | | _type = = eType | | _type = = eVariable | | _type = = eFunction | | _type = = eKeyword | |
2012-04-23 21:05:26 +02:00
_type = = eBoolean ; // TODO: "true"/"false" aren't really a name...
2009-08-23 17:17:57 +02:00
}
2012-06-21 19:00:53 +02:00
bool isUpperCaseName ( ) const ;
2014-11-20 14:20:09 +01:00
bool isLiteral ( ) const {
2013-05-03 06:50:48 +02:00
return _type = = eNumber | | _type = = eString | | _type = = eChar | |
_type = = eBoolean | | _type = = eLiteral ;
}
2014-11-20 14:20:09 +01:00
bool isNumber ( ) const {
2012-04-23 21:05:26 +02:00
return _type = = eNumber ;
2011-03-08 02:04:25 +01:00
}
2014-11-20 14:20:09 +01:00
bool isOp ( ) const {
2013-02-28 21:50:29 +01:00
return ( isConstOp ( ) | |
isAssignmentOp ( ) | |
_type = = eIncDecOp ) ;
}
2014-11-20 14:20:09 +01:00
bool isConstOp ( ) const {
2011-04-09 15:54:36 +02:00
return ( isArithmeticalOp ( ) | |
2012-04-23 21:05:26 +02:00
_type = = eLogicalOp | |
2012-04-26 23:04:55 +02:00
_type = = eComparisonOp | |
2012-04-23 21:05:26 +02:00
_type = = eBitOp ) ;
2011-04-08 19:40:22 +02:00
}
2014-11-20 14:20:09 +01:00
bool isExtendedOp ( ) const {
2013-02-28 21:50:29 +01:00
return isConstOp ( ) | |
2012-04-23 21:05:26 +02:00
_type = = eExtendedOp ;
2011-04-08 19:40:22 +02:00
}
2014-11-20 14:20:09 +01:00
bool isArithmeticalOp ( ) const {
2013-02-28 21:50:29 +01:00
return _type = = eArithmeticalOp ;
}
2014-11-20 14:20:09 +01:00
bool isComparisonOp ( ) const {
2012-11-13 18:30:33 +01:00
return _type = = eComparisonOp ;
}
2014-11-20 14:20:09 +01:00
bool isAssignmentOp ( ) const {
2012-04-23 21:05:26 +02:00
return _type = = eAssignmentOp ;
2011-04-09 20:36:05 +02:00
}
2014-11-20 14:20:09 +01:00
bool isBoolean ( ) const {
2012-04-23 21:05:26 +02:00
return _type = = eBoolean ;
2011-03-08 02:04:25 +01:00
}
2012-04-23 21:05:26 +02:00
2014-11-20 14:20:09 +01:00
unsigned int flags ( ) const {
2014-05-06 06:35:48 +02:00
return _flags ;
}
2014-11-20 14:20:09 +01:00
void flags ( unsigned int flags_ ) {
2014-05-06 06:35:48 +02:00
_flags = flags_ ;
}
2014-11-20 14:20:09 +01:00
bool isUnsigned ( ) const {
2014-05-06 06:35:48 +02:00
return getFlag ( fIsUnsigned ) ;
2010-03-28 15:56:13 +02:00
}
2014-11-20 14:20:09 +01:00
void isUnsigned ( bool sign ) {
2014-05-06 06:35:48 +02:00
setFlag ( fIsUnsigned , sign ) ;
2010-03-28 15:56:13 +02:00
}
2014-11-20 14:20:09 +01:00
bool isSigned ( ) const {
2014-05-06 06:35:48 +02:00
return getFlag ( fIsSigned ) ;
2010-03-28 15:56:13 +02:00
}
2014-11-20 14:20:09 +01:00
void isSigned ( bool sign ) {
2014-05-06 06:35:48 +02:00
setFlag ( fIsSigned , sign ) ;
2010-03-28 15:56:13 +02:00
}
2014-11-20 14:20:09 +01:00
bool isPointerCompare ( ) const {
2014-05-06 06:35:48 +02:00
return getFlag ( fIsPointerCompare ) ;
2011-07-07 15:14:33 +02:00
}
2014-11-20 14:20:09 +01:00
void isPointerCompare ( bool b ) {
2014-05-06 06:35:48 +02:00
setFlag ( fIsPointerCompare , b ) ;
2011-07-07 15:14:33 +02:00
}
2014-11-20 14:20:09 +01:00
bool isLong ( ) const {
2014-05-06 06:35:48 +02:00
return getFlag ( fIsLong ) ;
2010-03-28 15:56:13 +02:00
}
2014-11-20 14:20:09 +01:00
void isLong ( bool size ) {
2014-05-06 06:35:48 +02:00
setFlag ( fIsLong , size ) ;
2010-03-28 15:56:13 +02:00
}
2014-11-20 14:20:09 +01:00
bool isStandardType ( ) const {
2014-05-06 06:35:48 +02:00
return getFlag ( fIsStandardType ) ;
}
2014-11-20 14:20:09 +01:00
void isStandardType ( bool b ) {
2014-05-06 06:35:48 +02:00
setFlag ( fIsStandardType , b ) ;
2012-04-16 15:28:38 +02:00
}
2014-11-20 14:20:09 +01:00
bool isExpandedMacro ( ) const {
2014-05-06 06:35:48 +02:00
return getFlag ( fIsExpandedMacro ) ;
2011-12-18 13:33:23 +01:00
}
2014-11-20 14:20:09 +01:00
void isExpandedMacro ( bool m ) {
2014-05-06 06:35:48 +02:00
setFlag ( fIsExpandedMacro , m ) ;
2011-12-18 13:33:23 +01:00
}
2014-12-24 10:35:40 +01:00
bool isCast ( ) const {
return getFlag ( fIsCast ) ;
2014-12-23 16:16:14 +01:00
}
2014-12-24 10:35:40 +01:00
void isCast ( bool c ) {
setFlag ( fIsCast , c ) ;
2014-12-23 16:16:14 +01:00
}
2014-11-20 14:20:09 +01:00
bool isAttributeConstructor ( ) const {
2014-05-06 06:35:48 +02:00
return getFlag ( fIsAttributeConstructor ) ;
2013-08-30 06:27:46 +02:00
}
2014-11-20 14:20:09 +01:00
void isAttributeConstructor ( bool ac ) {
2014-05-06 06:35:48 +02:00
setFlag ( fIsAttributeConstructor , ac ) ;
2013-08-30 06:27:46 +02:00
}
2014-11-20 14:20:09 +01:00
bool isAttributeDestructor ( ) const {
2014-05-06 06:35:48 +02:00
return getFlag ( fIsAttributeDestructor ) ;
2014-03-14 05:40:17 +01:00
}
2014-11-20 14:20:09 +01:00
void isAttributeDestructor ( bool value ) {
2014-05-06 06:35:48 +02:00
setFlag ( fIsAttributeDestructor , value ) ;
2014-03-14 05:40:17 +01:00
}
2014-11-20 14:20:09 +01:00
bool isAttributeUnused ( ) const {
2014-05-06 06:35:48 +02:00
return getFlag ( fIsAttributeUnused ) ;
2013-08-30 06:27:46 +02:00
}
2014-11-20 14:20:09 +01:00
void isAttributeUnused ( bool unused ) {
2014-05-06 06:35:48 +02:00
setFlag ( fIsAttributeUnused , unused ) ;
2013-08-30 06:27:46 +02:00
}
2014-11-20 14:20:09 +01:00
bool isAttributeUsed ( ) const {
2014-08-06 11:13:58 +02:00
return getFlag ( fIsAttributeUsed ) ;
}
2014-11-20 14:20:09 +01:00
void isAttributeUsed ( bool unused ) {
2014-08-06 11:13:58 +02:00
setFlag ( fIsAttributeUsed , unused ) ;
}
2014-11-20 14:20:09 +01:00
bool isAttributePure ( ) const {
2014-05-06 06:35:48 +02:00
return getFlag ( fIsAttributePure ) ;
2014-03-14 05:40:17 +01:00
}
2014-11-20 14:20:09 +01:00
void isAttributePure ( bool value ) {
2014-05-06 06:35:48 +02:00
setFlag ( fIsAttributePure , value ) ;
2014-03-14 05:40:17 +01:00
}
2014-11-20 14:20:09 +01:00
bool isAttributeConst ( ) const {
2014-05-06 06:35:48 +02:00
return getFlag ( fIsAttributeConst ) ;
2014-03-14 05:40:17 +01:00
}
2014-11-20 14:20:09 +01:00
void isAttributeConst ( bool value ) {
2014-05-06 06:35:48 +02:00
setFlag ( fIsAttributeConst , value ) ;
2014-03-14 05:40:17 +01:00
}
2014-12-24 12:50:51 +01:00
bool isAttributeNoreturn ( ) const {
return getFlag ( fIsAttributeNoreturn ) ;
}
void isAttributeNoreturn ( bool value ) {
setFlag ( fIsAttributeNoreturn , value ) ;
}
2014-11-20 14:20:09 +01:00
bool isAttributeNothrow ( ) const {
2014-05-06 06:35:48 +02:00
return getFlag ( fIsAttributeNothrow ) ;
2014-04-20 20:40:55 +02:00
}
2014-11-20 14:20:09 +01:00
void isAttributeNothrow ( bool value ) {
2014-05-06 06:35:48 +02:00
setFlag ( fIsAttributeNothrow , value ) ;
2014-04-20 20:40:55 +02:00
}
2011-12-18 13:33:23 +01:00
2011-10-27 10:54:50 +02:00
static const Token * findsimplematch ( const Token * tok , const char pattern [ ] ) ;
static const Token * findsimplematch ( const Token * tok , const char pattern [ ] , const Token * end ) ;
2009-01-06 00:06:51 +01:00
static const Token * findmatch ( const Token * tok , const char pattern [ ] , unsigned int varId = 0 ) ;
2010-07-26 16:46:37 +02:00
static const Token * findmatch ( const Token * tok , const char pattern [ ] , const Token * end , unsigned int varId = 0 ) ;
2014-11-20 14:20:09 +01:00
static Token * findsimplematch ( Token * tok , const char pattern [ ] ) {
2013-01-03 22:26:20 +01:00
return const_cast < Token * > ( findsimplematch ( static_cast < const Token * > ( tok ) , pattern ) ) ;
}
2014-11-20 14:20:09 +01:00
static Token * findsimplematch ( Token * tok , const char pattern [ ] , const Token * end ) {
2013-01-03 22:26:20 +01:00
return const_cast < Token * > ( findsimplematch ( static_cast < const Token * > ( tok ) , pattern , end ) ) ;
}
2014-11-20 14:20:09 +01:00
static Token * findmatch ( Token * tok , const char pattern [ ] , unsigned int varId = 0 ) {
2013-01-03 22:26:20 +01:00
return const_cast < Token * > ( findmatch ( static_cast < const Token * > ( tok ) , pattern , varId ) ) ;
}
2014-11-20 14:20:09 +01:00
static Token * findmatch ( Token * tok , const char pattern [ ] , const Token * end , unsigned int varId = 0 ) {
2013-01-03 22:26:20 +01:00
return const_cast < Token * > ( findmatch ( static_cast < const Token * > ( tok ) , pattern , end , varId ) ) ;
}
2008-12-18 22:28:57 +01:00
/**
* Needle is build from multiple alternatives . If one of
* them is equal to haystack , return value is 1. If there
* are no matches , but one alternative to needle is empty
* string , return value is 0. If needle was not found , return
* value is - 1.
*
2014-06-26 17:32:24 +02:00
* @ param needle Current token
2009-01-27 20:30:01 +01:00
* @ param haystack e . g . " one|two " or " |one|two "
2014-11-16 19:40:04 +01:00
* @ param varid optional varid of token
2008-12-18 22:28:57 +01:00
* @ return 1 if needle is found from the haystack
* 0 if needle was empty string
* - 1 if needle was not found
*/
2014-06-26 18:17:05 +02:00
static int multiCompare ( const Token * needle , const char * haystack , unsigned int varid ) ;
2008-12-18 22:28:57 +01:00
2014-11-20 14:20:09 +01:00
unsigned int linenr ( ) const {
2009-08-23 17:17:57 +02:00
return _linenr ;
}
2014-11-20 14:20:09 +01:00
void linenr ( unsigned int lineNumber ) {
2010-04-06 21:53:05 +02:00
_linenr = lineNumber ;
2009-08-23 17:17:57 +02:00
}
2008-12-18 22:28:57 +01:00
2014-11-20 14:20:09 +01:00
unsigned int fileIndex ( ) const {
2009-08-23 17:17:57 +02:00
return _fileIndex ;
}
2014-11-20 14:20:09 +01:00
void fileIndex ( unsigned int indexOfFile ) {
2010-04-06 21:53:05 +02:00
_fileIndex = indexOfFile ;
2009-08-23 17:17:57 +02:00
}
2008-12-18 22:28:57 +01:00
2014-11-20 14:20:09 +01:00
Token * next ( ) const {
2009-08-23 17:17:57 +02:00
return _next ;
}
2008-12-18 22:28:57 +01:00
/**
* Delete tokens between begin and end . E . g . if begin = 1
* and end = 5 , tokens 2 , 3 and 4 would be erased .
*
* @ param begin Tokens after this will be erased .
* @ param end Tokens before this will be erased .
*/
2009-01-05 16:49:57 +01:00
static void eraseTokens ( Token * begin , const Token * end ) ;
2008-12-18 22:28:57 +01:00
/**
* Insert new token after this token . This function will handle
* relations between next and previous token also .
2010-04-09 21:40:37 +02:00
* @ param tokenStr String for the new token .
2012-11-20 02:58:19 +01:00
* @ param prepend Insert the new token before this token when it ' s not
* the first one on the tokens list .
2008-12-18 22:28:57 +01:00
*/
2012-12-27 11:51:12 +01:00
void insertToken ( const std : : string & tokenStr , bool prepend = false ) ;
2008-12-18 22:28:57 +01:00
2013-09-24 06:43:03 +02:00
void insertToken ( const std : : string & tokenStr , const std : : string & originalNameStr , bool prepend = false ) ;
2014-11-20 14:20:09 +01:00
Token * previous ( ) const {
2009-08-23 17:17:57 +02:00
return _previous ;
}
2008-12-18 22:28:57 +01:00
2014-11-20 14:20:09 +01:00
unsigned int varId ( ) const {
2009-08-23 17:17:57 +02:00
return _varId ;
}
2014-11-20 14:20:09 +01:00
void varId ( unsigned int id ) {
2009-08-23 17:17:57 +02:00
_varId = id ;
2012-08-24 14:25:17 +02:00
if ( id ! = 0 )
_type = eVariable ;
2012-08-26 10:04:22 +02:00
else
update_property_info ( ) ;
2009-08-23 17:17:57 +02:00
}
2008-12-18 22:28:57 +01:00
/**
* For debugging purposes , prints token and all tokens
* followed by it .
* @ param title Title for the printout or use default parameter or 0
* for no title .
*/
2014-02-16 11:47:52 +01:00
void printOut ( const char * title = nullptr ) const ;
2008-12-18 22:28:57 +01:00
2009-11-27 23:04:04 +01:00
/**
* For debugging purposes , prints token and all tokens
* followed by it .
* @ param title Title for the printout or use default parameter or 0
* for no title .
* @ param fileNames Prints out file name instead of file index .
* File index should match the index of the string in this vector .
*/
void printOut ( const char * title , const std : : vector < std : : string > & fileNames ) const ;
2009-01-26 23:26:50 +01:00
/**
* Replace token replaceThis with tokens between start and end ,
* including start and end . The replaceThis token is deleted .
2009-06-20 11:54:49 +02:00
* @ param replaceThis This token will be deleted .
2009-01-26 23:26:50 +01:00
* @ param start This will be in the place of replaceThis
* @ param end This is also in the place of replaceThis
*/
static void replace ( Token * replaceThis , Token * start , Token * end ) ;
2012-04-16 19:51:07 +02:00
/**
* Stringify a token
* @ param os The result is shifted into that output stream
* @ param varid Print varids . ( Style : " varname@id " )
* @ param attributes Print attributes of tokens like " unsigned " in front of it .
2014-09-29 14:50:00 +02:00
* @ param macro Prints $ in front of the token if it was expanded from a macro .
2012-04-16 19:51:07 +02:00
*/
2014-09-29 14:50:00 +02:00
void stringify ( std : : ostream & os , bool varid , bool attributes , bool macro ) const ;
2012-04-16 19:51:07 +02:00
/**
* Stringify a list of token , from current instance on .
* @ param varid Print varids . ( Style : " varname@id " )
* @ param attributes Print attributes of tokens like " unsigned " in front of it .
* @ param linenumbers Print line number in front of each line
2014-04-27 09:32:02 +02:00
* @ param linebreaks Insert " \\ n " into string when line number changes
2012-04-16 19:51:07 +02:00
* @ param files print Files as numbers or as names ( if fileNames is given )
* @ param fileNames Vector of filenames . Used ( if given ) to print filenames as strings instead of numbers .
* @ param end Stringification ends before this token is reached . 0 to stringify until end of list .
* @ return Stringified token list as a string
*/
std : : string stringifyList ( bool varid , bool attributes , bool linenumbers , bool linebreaks , bool files , const std : : vector < std : : string > * fileNames = 0 , const Token * end = 0 ) const ;
std : : string stringifyList ( const Token * end , bool attributes = true ) const ;
std : : string stringifyList ( bool varid = false ) const ;
2009-02-13 07:25:29 +01:00
2009-03-13 00:07:05 +01:00
/**
2011-10-16 08:25:11 +02:00
* Remove the contents for this token from the token list .
*
* The contents are replaced with the contents of the next token and
* the next token is unlinked and deleted from the token list .
*
* So this token will still be valid after the ' deleteThis ( ) ' .
2009-03-13 00:07:05 +01:00
*/
void deleteThis ( ) ;
2009-03-13 22:25:56 +01:00
/**
* Create link to given token
2010-06-14 07:54:41 +02:00
* @ param linkToToken The token where this token should link
2009-03-13 22:25:56 +01:00
* to .
*/
2014-11-20 14:20:09 +01:00
void link ( Token * linkToToken ) {
2010-04-06 21:53:05 +02:00
_link = linkToToken ;
2012-08-27 06:33:56 +02:00
if ( _str = = " < " | | _str = = " > " )
2012-08-26 10:23:16 +02:00
update_property_info ( ) ;
2009-08-23 17:17:57 +02:00
}
2009-03-13 22:25:56 +01:00
/**
* Return token where this token links to .
* Supported links are :
* " { " < - > " } "
2011-10-16 08:25:11 +02:00
* " ( " < - > " ) "
* " [ " < - > " ] "
2009-03-13 22:25:56 +01:00
*
* @ return The token where this token links to .
*/
2014-11-20 14:20:09 +01:00
Token * link ( ) const {
2009-08-23 17:17:57 +02:00
return _link ;
}
2009-03-13 22:25:56 +01:00
2012-08-11 20:47:11 +02:00
/**
* Associate this token with given scope
2012-10-19 11:29:05 +02:00
* @ param s Scope to be associated
2012-08-11 20:47:11 +02:00
*/
2014-11-20 14:20:09 +01:00
void scope ( const Scope * s ) {
2012-08-12 17:04:37 +02:00
_scope = s ;
2012-08-11 20:47:11 +02:00
}
/**
2014-04-27 09:32:02 +02:00
* @ return a pointer to the scope containing this token .
2012-08-11 20:47:11 +02:00
*/
2014-11-20 14:20:09 +01:00
const Scope * scope ( ) const {
2012-08-11 20:47:11 +02:00
return _scope ;
}
2013-01-31 06:41:18 +01:00
/**
* Associate this token with given function
* @ param f Function to be associated
*/
2014-11-20 14:20:09 +01:00
void function ( const Function * f ) {
2013-01-31 06:41:18 +01:00
_function = f ;
2013-03-05 17:50:01 +01:00
if ( f )
_type = eFunction ;
else if ( _type = = eFunction )
_type = eName ;
2013-01-31 06:41:18 +01:00
}
/**
2014-04-27 09:32:02 +02:00
* @ return a pointer to the Function associated with this token .
2013-01-31 06:41:18 +01:00
*/
2014-11-20 14:20:09 +01:00
const Function * function ( ) const {
2013-03-05 17:50:01 +01:00
return _type = = eFunction ? _function : 0 ;
2013-01-31 06:41:18 +01:00
}
/**
* Associate this token with given variable
* @ param v Variable to be associated
*/
2014-11-20 14:20:09 +01:00
void variable ( const Variable * v ) {
2013-01-31 06:41:18 +01:00
_variable = v ;
2013-03-05 17:50:01 +01:00
if ( v | | _varId )
_type = eVariable ;
else if ( _type = = eVariable )
_type = eName ;
2013-01-31 06:41:18 +01:00
}
/**
2014-04-27 09:32:02 +02:00
* @ return a pointer to the variable associated with this token .
2013-01-31 06:41:18 +01:00
*/
2014-11-20 14:20:09 +01:00
const Variable * variable ( ) const {
2013-03-05 17:50:01 +01:00
return _type = = eVariable ? _variable : 0 ;
2013-01-31 06:41:18 +01:00
}
2009-08-22 16:22:50 +02:00
/**
* Links two elements against each other .
* */
static void createMutualLinks ( Token * begin , Token * end ) ;
2009-09-12 22:54:47 +02:00
/**
* This can be called only for tokens that are strings , else
* the assert ( ) is called . If Token is e . g . ' " hello " ' , this will return
* ' hello ' ( removing the double quotes ) .
* @ return String value
*/
2009-09-13 10:02:23 +02:00
std : : string strValue ( ) const ;
2009-09-12 22:54:47 +02:00
2009-11-27 22:21:13 +01:00
/**
2011-11-11 21:55:37 +01:00
* Move srcStart and srcEnd tokens and all tokens between them
2009-11-27 22:21:13 +01:00
* into new a location . Only links between tokens are changed .
* @ param srcStart This is the first token to be moved
* @ param srcEnd The last token to be moved
* @ param newLocation srcStart will be placed after this token .
*/
static void move ( Token * srcStart , Token * srcEnd , Token * newLocation ) ;
2010-08-03 16:36:21 +02:00
/** Get progressValue */
2014-11-20 14:20:09 +01:00
unsigned int progressValue ( ) const {
2010-08-03 16:36:21 +02:00
return _progressValue ;
}
/** Calculate progress values for all tokens */
2014-05-20 21:55:08 +02:00
static void assignProgressValues ( Token * tok ) ;
2010-08-03 16:36:21 +02:00
2011-10-23 11:23:48 +02:00
/**
2014-04-27 09:32:02 +02:00
* @ return the first token of the next argument . Does only work on argument
2014-08-20 14:57:00 +02:00
* lists . Requires that Tokenizer : : createLinks2 ( ) has been called before .
* Returns 0 , if there is no next argument .
2011-10-23 11:23:48 +02:00
*/
2011-12-07 21:15:00 +01:00
Token * nextArgument ( ) const ;
2011-10-23 11:23:48 +02:00
2014-08-20 14:57:00 +02:00
/**
* @ return the first token of the next argument . Does only work on argument
* lists . Should be used only before Tokenizer : : createLinks2 ( ) was called .
* Returns 0 , if there is no next argument .
*/
Token * nextArgumentBeforeCreateLinks2 ( ) const ;
2015-01-03 20:35:33 +01:00
/**
* @ return the first token of the next template argument . Does only work on template argument
* lists . Requires that Tokenizer : : createLinks2 ( ) has been called before .
* Returns 0 , if there is no next argument .
*/
Token * nextTemplateArgument ( ) const ;
2012-04-18 16:02:03 +02:00
/**
* Returns the closing bracket of opening ' < ' . Should only be used if link ( )
* is unavailable .
2013-07-31 10:30:20 +02:00
* @ return closing ' > ' , ' ) ' , ' ] ' or ' } ' . if no closing bracket is found , NULL is returned
2012-04-18 16:02:03 +02:00
*/
2013-07-31 10:30:20 +02:00
const Token * findClosingBracket ( ) const ;
Token * findClosingBracket ( ) ;
2012-04-18 16:02:03 +02:00
2013-08-31 06:26:39 +02:00
/**
2014-04-27 09:32:02 +02:00
* @ return the original name .
2013-08-31 06:26:39 +02:00
*/
2014-11-20 14:20:09 +01:00
const std : : string & originalName ( ) const {
2014-06-26 10:57:39 +02:00
return _originalName ? * _originalName : emptyString ;
2013-08-31 06:26:39 +02:00
}
/**
* Sets the original name .
*/
2014-04-02 18:04:20 +02:00
template < typename T >
2014-11-20 14:20:09 +01:00
void originalName ( T & & name ) {
2014-06-26 10:57:39 +02:00
if ( ! _originalName )
_originalName = new std : : string ( name ) ;
else
* _originalName = name ;
2013-08-31 06:26:39 +02:00
}
2014-01-04 20:57:02 +01:00
/** Values of token */
2014-01-08 12:27:36 +01:00
std : : list < ValueFlow : : Value > values ;
2014-01-04 20:57:02 +01:00
2014-11-20 14:20:09 +01:00
const ValueFlow : : Value * getValue ( const MathLib : : bigint val ) const {
2014-01-20 06:49:45 +01:00
std : : list < ValueFlow : : Value > : : const_iterator it ;
for ( it = values . begin ( ) ; it ! = values . end ( ) ; + + it ) {
2014-08-03 20:11:22 +02:00
if ( it - > intvalue = = val & & ! it - > tokvalue )
2014-01-20 06:49:45 +01:00
return & ( * it ) ;
}
return NULL ;
}
2014-11-20 14:20:09 +01:00
const ValueFlow : : Value * getMaxValue ( bool condition ) const {
2014-02-16 11:47:52 +01:00
const ValueFlow : : Value * ret = nullptr ;
2014-01-21 16:58:23 +01:00
std : : list < ValueFlow : : Value > : : const_iterator it ;
for ( it = values . begin ( ) ; it ! = values . end ( ) ; + + it ) {
2014-08-03 20:11:22 +02:00
if ( it - > tokvalue )
continue ;
2014-01-21 16:58:23 +01:00
if ( ( ! ret | | it - > intvalue > ret - > intvalue ) & &
( ( it - > condition ! = NULL ) = = condition ) )
ret = & ( * it ) ;
}
return ret ;
}
2014-04-02 06:49:28 +02:00
const ValueFlow : : Value * getValueLE ( const MathLib : : bigint val , const Settings * settings ) const ;
const ValueFlow : : Value * getValueGE ( const MathLib : : bigint val , const Settings * settings ) const ;
2014-08-04 08:25:10 +02:00
const Token * getValueTokenMaxStrLength ( ) const ;
const Token * getValueTokenMinStrSize ( ) const ;
2014-08-03 20:11:22 +02:00
2014-08-05 06:24:23 +02:00
const Token * getValueTokenDeadPointer ( ) const ;
2008-12-18 22:28:57 +01:00
private :
2014-01-21 16:58:23 +01:00
2014-11-20 14:20:09 +01:00
void next ( Token * nextToken ) {
2010-04-06 21:53:05 +02:00
_next = nextToken ;
2009-08-23 17:17:57 +02:00
}
2014-11-20 14:20:09 +01:00
void previous ( Token * previousToken ) {
2010-04-06 21:53:05 +02:00
_previous = previousToken ;
2009-08-23 17:17:57 +02:00
}
2008-12-18 22:28:57 +01:00
2009-08-16 22:28:17 +02:00
/**
2012-04-16 15:28:38 +02:00
* Works almost like strcmp ( ) except returns only true or false and
2010-03-13 22:16:06 +01:00
* if str has empty space & apos ; & apos ; character , that character is handled
* as if it were & apos ; \ \ 0 & apos ;
2009-08-16 22:28:17 +02:00
*/
2012-04-16 15:28:38 +02:00
static bool firstWordEquals ( const char * str , const char * word ) ;
2009-08-16 22:28:17 +02:00
/**
* Works almost like strchr ( ) except
2010-03-13 22:16:06 +01:00
* if str has empty space & apos ; & apos ; character , that character is handled
* as if it were & apos ; \ \ 0 & apos ;
2009-08-16 22:28:17 +02:00
*/
static const char * chrInFirstWord ( const char * str , char c ) ;
2014-06-26 10:57:39 +02:00
std : : string _str ;
2009-08-16 22:28:17 +02:00
2011-10-24 02:52:55 +02:00
Token * _next ;
Token * _previous ;
Token * _link ;
2012-08-11 20:47:11 +02:00
2013-01-31 06:41:18 +01:00
// symbol database information
const Scope * _scope ;
2013-03-05 17:50:01 +01:00
union {
const Function * _function ;
const Variable * _variable ;
} ;
2012-08-11 20:47:11 +02:00
2012-05-14 20:46:23 +02:00
unsigned int _varId ;
unsigned int _fileIndex ;
unsigned int _linenr ;
/**
* A value from 0 - 100 that provides a rough idea about where in the token
* list this token is located .
*/
unsigned int _progressValue ;
2011-10-24 02:52:55 +02:00
2012-04-23 21:05:26 +02:00
Type _type ;
2014-05-06 06:35:48 +02:00
enum {
fIsUnsigned = ( 1 < < 0 ) ,
fIsSigned = ( 1 < < 1 ) ,
fIsPointerCompare = ( 1 < < 2 ) ,
fIsLong = ( 1 < < 3 ) ,
fIsStandardType = ( 1 < < 4 ) ,
fIsExpandedMacro = ( 1 < < 5 ) ,
2014-12-24 10:35:40 +01:00
fIsCast = ( 1 < < 6 ) ,
2014-12-23 16:16:14 +01:00
fIsAttributeConstructor = ( 1 < < 7 ) , // __attribute__((constructor)) __attribute__((constructor(priority)))
fIsAttributeDestructor = ( 1 < < 8 ) , // __attribute__((destructor)) __attribute__((destructor(priority)))
fIsAttributeUnused = ( 1 < < 9 ) , // __attribute__((unused))
fIsAttributePure = ( 1 < < 10 ) , // __attribute__((pure))
fIsAttributeConst = ( 1 < < 11 ) , // __attribute__((const))
2015-01-09 20:18:09 +01:00
fIsAttributeNoreturn = ( 1 < < 12 ) , // __attribute__((noreturn)), __declspec(noreturn)
fIsAttributeNothrow = ( 1 < < 13 ) , // __attribute__((nothrow)), __declspec(nothrow)
fIsAttributeUsed = ( 1 < < 14 ) // __attribute__((used))
2014-05-06 06:35:48 +02:00
} ;
unsigned int _flags ;
/**
* Get specified flag state .
* @ param flag_ flag to get state of
* @ return true if flag set or false in flag not set
*/
2014-11-20 14:20:09 +01:00
bool getFlag ( unsigned int flag_ ) const {
2014-05-06 06:35:48 +02:00
return bool ( ( _flags & flag_ ) ! = 0 ) ;
}
/**
* Set specified flag state .
* @ param flag_ flag to set state
* @ param state_ new state of flag
*/
2014-11-20 14:20:09 +01:00
void setFlag ( unsigned int flag_ , bool state_ ) {
2014-05-06 06:35:48 +02:00
_flags = state_ ? _flags | flag_ : _flags & ~ flag_ ;
}
2010-08-05 21:40:04 +02:00
2011-10-23 20:38:03 +02:00
/** Updates internal property cache like _isName or _isBoolean.
Called after any _str ( ) modification . */
void update_property_info ( ) ;
2011-11-09 21:45:59 +01:00
/** Update internal property cache about isStandardType() */
void update_property_isStandardType ( ) ;
2012-12-15 20:21:09 +01:00
// AST..
Token * _astOperand1 ;
Token * _astOperand2 ;
Token * _astParent ;
2013-08-31 06:26:39 +02:00
// original name like size_t
2014-06-26 10:57:39 +02:00
std : : string * _originalName ;
2013-08-31 06:26:39 +02:00
2012-12-15 20:21:09 +01:00
public :
void astOperand1 ( Token * tok ) ;
void astOperand2 ( Token * tok ) ;
2014-11-20 14:20:09 +01:00
const Token * astOperand1 ( ) const {
2012-12-15 20:21:09 +01:00
return _astOperand1 ;
}
2014-11-20 14:20:09 +01:00
const Token * astOperand2 ( ) const {
2012-12-15 20:21:09 +01:00
return _astOperand2 ;
}
2014-11-20 14:20:09 +01:00
const Token * astParent ( ) const {
2013-12-12 15:33:31 +01:00
return _astParent ;
}
2014-11-20 14:20:09 +01:00
const Token * astTop ( ) const {
2012-12-15 20:21:09 +01:00
const Token * ret = this ;
while ( ret - > _astParent )
ret = ret - > _astParent ;
return ret ;
}
2013-12-28 11:02:39 +01:00
/**
* Is current token a calculation ? Only true for operands .
* For ' * ' and ' & ' tokens it is looked up if this is a
* dereference or address - of . A dereference or address - of is not
* counted as a calculation .
* @ return returns true if current token is a calculation
*/
bool isCalculation ( ) const ;
2014-11-20 14:20:09 +01:00
void clearAst ( ) {
2013-11-07 14:38:08 +01:00
_astOperand1 = _astOperand2 = _astParent = NULL ;
}
2014-11-20 14:20:09 +01:00
std : : string astString ( const char * sep = " " ) const {
2012-12-15 20:21:09 +01:00
std : : string ret ;
if ( _astOperand1 )
2013-11-02 18:37:35 +01:00
ret = _astOperand1 - > astString ( sep ) ;
2012-12-15 20:21:09 +01:00
if ( _astOperand2 )
2013-11-02 18:37:35 +01:00
ret + = _astOperand2 - > astString ( sep ) ;
return ret + sep + _str ;
2012-12-15 20:21:09 +01:00
}
2013-11-02 18:37:35 +01:00
2014-02-24 17:22:29 +01:00
std : : string astStringVerbose ( const unsigned int indent1 , const unsigned int indent2 ) const ;
2014-01-17 18:37:49 +01:00
std : : string expressionString ( ) const ;
2014-07-14 15:51:45 +02:00
void printAst ( bool verbose , bool xml , std : : ostream & out ) const ;
2014-01-18 09:58:32 +01:00
2014-07-14 15:51:45 +02:00
void printValueFlow ( bool xml , std : : ostream & out ) const ;
2008-12-18 22:28:57 +01:00
} ;
2009-07-17 10:49:01 +02:00
/// @}
2013-09-04 20:59:49 +02:00
//---------------------------------------------------------------------------
# endif // tokenH