Cppcheck
token.h
Go to the documentation of this file.
1 /*
2  * Cppcheck - A tool for static C/C++ code analysis
3  * Copyright (C) 2007-2024 Cppcheck team.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 //---------------------------------------------------------------------------
20 #ifndef tokenH
21 #define tokenH
22 //---------------------------------------------------------------------------
23 
24 #include "config.h"
25 #include "mathlib.h"
26 #include "templatesimplifier.h"
27 #include "utils.h"
28 #include "vfvalue.h"
29 
30 #include <cassert>
31 #include <cstdint>
32 #include <cstddef>
33 #include <functional>
34 #include <list>
35 #include <memory>
36 #include <ostream>
37 #include <set>
38 #include <string>
39 #include <utility>
40 #include <vector>
41 
42 struct Enumerator;
43 class Function;
44 class Scope;
45 class Settings;
46 class Type;
47 class ValueType;
48 class Variable;
49 class ConstTokenRange;
50 class Token;
51 struct TokensFrontBack;
52 
53 struct ScopeInfo2 {
54  ScopeInfo2(std::string name_, const Token *bodyEnd_, std::set<std::string> usingNamespaces_ = std::set<std::string>()) : name(std::move(name_)), bodyEnd(bodyEnd_), usingNamespaces(std::move(usingNamespaces_)) {}
55  std::string name;
56  const Token* const bodyEnd{};
57  std::set<std::string> usingNamespaces;
58 };
59 
61 
62 struct TokenImpl {
63  nonneg int mVarId{};
66  nonneg int mColumn{};
67  nonneg int mExprId{};
68 
69  /**
70  * A value from 0-100 that provides a rough idea about where in the token
71  * list this token is located.
72  */
74 
75  /**
76  * Token index. Position in token list
77  */
78  nonneg int mIndex{};
79 
80  /** Bitfield bit count. */
81  unsigned char mBits{};
82 
83  // AST..
87 
88  // symbol database information
89  const Scope* mScope{};
90  union {
93  const ::Type* mType;
95  };
96 
97  // original name like size_t
98  std::string* mOriginalName{};
99 
100  // If this token came from a macro replacement list, this is the name of that macro
101  std::string mMacroName;
102 
103  // ValueType
105 
106  // ValueFlow
107  std::list<ValueFlow::Value>* mValues{};
108  static const std::list<ValueFlow::Value> mEmptyValueList;
109 
110  // Pointer to a template in the template simplifier
111  std::set<TemplateSimplifier::TokenAndName*>* mTemplateSimplifierPointers{};
112 
113  // Pointer to the object representing this token's scope
114  std::shared_ptr<ScopeInfo2> mScopeInfo;
115 
116  // __cppcheck_in_range__
118  enum Type { LOW, HIGH } type = LOW;
121  };
123 
124  // For memoization, to speed up parsing of huge arrays #8897
126 
128 
131 
132  TokenImpl() : mFunction(nullptr) {}
133 
134  ~TokenImpl();
135 };
136 
137 /// @addtogroup Core
138 /// @{
139 
140 /**
141  * @brief The token list that the TokenList generates is a linked-list of this class.
142  *
143  * Tokens are stored as strings. The "if", "while", etc are stored in plain text.
144  * The reason the Token class is needed (instead of using the string class) is that some extra functionality is also needed for tokens:
145  * - location of the token is stored (fileIndex, linenr, column)
146  * - functions for classifying the token (isName, isNumber, isBoolean, isStandardType)
147  *
148  * The Token class also has other functions for management of token list, matching tokens, etc.
149  */
151  friend class TestToken;
152 
153 private:
155 
156 public:
157  Token(const Token &) = delete;
158  Token& operator=(const Token &) = delete;
159 
160  enum Type {
161  eVariable, eType, eFunction, eKeyword, eName, // Names: Variable (varId), Type (typeId, later), Function (FuncId, later), Language keyword, Name (unknown identifier)
162  eNumber, eString, eChar, eBoolean, eLiteral, eEnumerator, // Literals: Number, String, Character, Boolean, User defined literal (C++11), Enumerator
163  eArithmeticalOp, eComparisonOp, eAssignmentOp, eLogicalOp, eBitOp, eIncDecOp, eExtendedOp, // Operators: Arithmetical, Comparison, Assignment, Logical, Bitwise, ++/--, Extended
164  eBracket, // {, }, <, >: < and > only if link() is set. Otherwise they are comparison operators.
165  eLambda, // A function without a name
166  eEllipsis, // "..."
168  eNone
169  };
170 
171  explicit Token(TokensFrontBack &tokensFrontBack);
172  // for usage in CheckIO::ArgumentInfo only
173  explicit Token(const Token *tok);
174  ~Token();
175 
176  ConstTokenRange until(const Token * t) const;
177 
178  template<typename T>
179  void str(T&& s) {
180  mStr = s;
181  mImpl->mVarId = 0;
182 
183  update_property_info();
184  }
185 
186  /**
187  * Concatenate two (quoted) strings. Automatically cuts of the last/first character.
188  * Example: "hello ""world" -> "hello world". Used by the token simplifier.
189  */
190  void concatStr(std::string const& b);
191 
192  const std::string &str() const {
193  return mStr;
194  }
195 
196  /**
197  * Unlink and delete the next 'count' tokens.
198  */
199  void deleteNext(nonneg int count = 1);
200 
201  /**
202  * Unlink and delete the previous 'count' tokens.
203  */
204  void deletePrevious(nonneg int count = 1);
205 
206  /**
207  * Swap the contents of this token with the next token.
208  */
209  void swapWithNext();
210 
211  /**
212  * @return token in given index, related to this token.
213  * For example index 1 would return next token, and 2
214  * would return next from that one.
215  */
216  const Token *tokAt(int index) const;
217  Token *tokAt(int index);
218 
219  /**
220  * @return the link to the token in given index, related to this token.
221  * For example index 1 would return the link to next token.
222  */
223  const Token *linkAt(int index) const;
224  Token *linkAt(int index);
225 
226  /**
227  * @return String of the token in given index, related to this token.
228  * If that token does not exist, an empty string is being returned.
229  */
230  const std::string &strAt(int index) const;
231 
232  /**
233  * Match given token (or list of tokens) to a pattern list.
234  *
235  * Possible patterns
236  * "someRandomText" If token contains "someRandomText".
237  * @note Use Match() if you want to use flags in patterns
238  *
239  * The patterns can be also combined to compare to multiple tokens at once
240  * by separating tokens with a space, e.g.
241  * ") void {" will return true if first token is ')' next token
242  * is "void" and token after that is '{'. If even one of the tokens does
243  * not match its pattern, false is returned.
244  *
245  * @param tok List of tokens to be compared to the pattern
246  * @param pattern The pattern against which the tokens are compared,
247  * e.g. "const" or ") void {".
248  * @return true if given token matches with given pattern
249  * false if given token does not match with given pattern
250  */
251  template<size_t count>
252  static bool simpleMatch(const Token *tok, const char (&pattern)[count]) {
253  return simpleMatch(tok, pattern, count-1);
254  }
255 
256  static bool simpleMatch(const Token *tok, const char pattern[], size_t pattern_len);
257 
258  /**
259  * Match given token (or list of tokens) to a pattern list.
260  *
261  * Possible patterns
262  * - "%any%" any token
263  * - "%assign%" a assignment operand
264  * - "%bool%" true or false
265  * - "%char%" Any token enclosed in &apos;-character.
266  * - "%comp%" Any token such that isComparisonOp() returns true.
267  * - "%cop%" Any token such that isConstOp() returns true.
268  * - "%name%" any token which is a name, variable or type e.g. "hello" or "int". Also matches keywords.
269  * - "%num%" Any numeric token, e.g. "23"
270  * - "%op%" Any token such that isOp() returns true.
271  * - "%or%" A bitwise-or operator '|'
272  * - "%oror%" A logical-or operator '||'
273  * - "%type%" Anything that can be a variable type, e.g. "int". Also matches keywords.
274  * - "%str%" Any token starting with &quot;-character (C-string).
275  * - "%var%" Match with token with varId > 0
276  * - "%varid%" Match with parameter varid
277  * - "[abc]" Any of the characters 'a' or 'b' or 'c'
278  * - "int|void|char" Any of the strings, int, void or char
279  * - "int|void|char|" Any of the strings, int, void or char or no token
280  * - "!!else" No tokens or any token that is not "else".
281  * - "someRandomText" If token contains "someRandomText".
282  *
283  * multi-compare patterns such as "int|void|char" can contain %%or%, %%oror% and %%op%
284  * it is recommended to put such an %%cmd% as the first pattern.
285  * For example: "%var%|%num%|)" means yes to a variable, a number or ')'.
286  *
287  * The patterns can be also combined to compare to multiple tokens at once
288  * by separating tokens with a space, e.g.
289  * ") const|void {" will return true if first token is ')' next token is either
290  * "const" or "void" and token after that is '{'. If even one of the tokens does not
291  * match its pattern, false is returned.
292  *
293  * @param tok List of tokens to be compared to the pattern
294  * @param pattern The pattern against which the tokens are compared,
295  * e.g. "const" or ") const|volatile| {".
296  * @param varid if %%varid% is given in the pattern the Token::varId
297  * will be matched against this argument
298  * @return true if given token matches with given pattern
299  * false if given token does not match with given pattern
300  */
301  static bool Match(const Token *tok, const char pattern[], nonneg int varid = 0);
302 
303  /**
304  * @return length of C-string.
305  *
306  * Should be called for %%str%% tokens only.
307  *
308  * @param tok token with C-string
309  **/
310  static nonneg int getStrLength(const Token *tok);
311 
312  /**
313  * @return array length of C-string.
314  *
315  * Should be called for %%str%% tokens only.
316  *
317  * @param tok token with C-string
318  **/
319  static nonneg int getStrArraySize(const Token *tok);
320 
321  /**
322  * @return sizeof of C-string.
323  *
324  * Should be called for %%str%% tokens only.
325  *
326  * @param tok token with C-string
327  * @param settings Settings
328  **/
329  static nonneg int getStrSize(const Token *tok, const Settings & settings);
330 
331  const ValueType *valueType() const {
332  return mImpl->mValueType;
333  }
334  void setValueType(ValueType *vt);
335 
336  const ValueType *argumentType() const {
337  const Token *top = this;
338  while (top && !Token::Match(top->astParent(), ",|("))
339  top = top->astParent();
340  return top ? top->mImpl->mValueType : nullptr;
341  }
342 
344  return mTokType;
345  }
347  mTokType = t;
348 
349  const bool memoizedIsName = (mTokType == eName || mTokType == eType || mTokType == eVariable ||
350  mTokType == eFunction || mTokType == eKeyword || mTokType == eBoolean ||
351  mTokType == eEnumerator); // TODO: "true"/"false" aren't really a name...
352  setFlag(fIsName, memoizedIsName);
353 
354  const bool memoizedIsLiteral = (mTokType == eNumber || mTokType == eString || mTokType == eChar ||
355  mTokType == eBoolean || mTokType == eLiteral || mTokType == eEnumerator);
356  setFlag(fIsLiteral, memoizedIsLiteral);
357  }
358  bool isKeyword() const {
359  return mTokType == eKeyword;
360  }
361  bool isName() const {
362  return getFlag(fIsName);
363  }
364  bool isNameOnly() const {
365  return mFlags == fIsName && mTokType == eName;
366  }
367  bool isUpperCaseName() const;
368  bool isLiteral() const {
369  return getFlag(fIsLiteral);
370  }
371  bool isNumber() const {
372  return mTokType == eNumber;
373  }
374  bool isEnumerator() const {
375  return mTokType == eEnumerator;
376  }
377  bool isVariable() const {
378  return mTokType == eVariable;
379  }
380  bool isOp() const {
381  return (isConstOp() ||
382  isAssignmentOp() ||
383  mTokType == eIncDecOp);
384  }
385  bool isConstOp() const {
386  return (isArithmeticalOp() ||
387  mTokType == eLogicalOp ||
388  mTokType == eComparisonOp ||
389  mTokType == eBitOp);
390  }
391  bool isExtendedOp() const {
392  return isConstOp() ||
393  mTokType == eExtendedOp;
394  }
395  bool isArithmeticalOp() const {
396  return mTokType == eArithmeticalOp;
397  }
398  bool isComparisonOp() const {
399  return mTokType == eComparisonOp;
400  }
401  bool isAssignmentOp() const {
402  return mTokType == eAssignmentOp;
403  }
404  bool isBoolean() const {
405  return mTokType == eBoolean;
406  }
407  bool isIncDecOp() const {
408  return mTokType == eIncDecOp;
409  }
410  bool isBinaryOp() const {
411  return astOperand1() != nullptr && astOperand2() != nullptr;
412  }
413  bool isUnaryOp(const std::string &s) const {
414  return s == mStr && astOperand1() != nullptr && astOperand2() == nullptr;
415  }
416  bool isUnaryPreOp() const;
417 
418  uint64_t flags() const {
419  return mFlags;
420  }
421  void flags(const uint64_t flags_) {
422  mFlags = flags_;
423  }
424  bool isUnsigned() const {
425  return getFlag(fIsUnsigned);
426  }
427  void isUnsigned(const bool sign) {
428  setFlag(fIsUnsigned, sign);
429  }
430  bool isSigned() const {
431  return getFlag(fIsSigned);
432  }
433  void isSigned(const bool sign) {
434  setFlag(fIsSigned, sign);
435  }
436  // cppcheck-suppress unusedFunction
437  bool isPointerCompare() const {
438  return getFlag(fIsPointerCompare);
439  }
440  void isPointerCompare(const bool b) {
441  setFlag(fIsPointerCompare, b);
442  }
443  bool isLong() const {
444  return getFlag(fIsLong);
445  }
446  void isLong(bool size) {
447  setFlag(fIsLong, size);
448  }
449  bool isStandardType() const {
450  return getFlag(fIsStandardType);
451  }
452  void isStandardType(const bool b) {
453  setFlag(fIsStandardType, b);
454  }
455  bool isExpandedMacro() const {
456  return !mImpl->mMacroName.empty();
457  }
458  bool isCast() const {
459  return getFlag(fIsCast);
460  }
461  void isCast(bool c) {
462  setFlag(fIsCast, c);
463  }
464  bool isAttributeConstructor() const {
465  return getFlag(fIsAttributeConstructor);
466  }
467  void isAttributeConstructor(const bool ac) {
468  setFlag(fIsAttributeConstructor, ac);
469  }
470  bool isAttributeDestructor() const {
471  return getFlag(fIsAttributeDestructor);
472  }
473  void isAttributeDestructor(const bool value) {
474  setFlag(fIsAttributeDestructor, value);
475  }
476  bool isAttributeUnused() const {
477  return getFlag(fIsAttributeUnused);
478  }
480  setFlag(fIsAttributeUnused, unused);
481  }
482  bool isAttributeUsed() const {
483  return getFlag(fIsAttributeUsed);
484  }
485  void isAttributeUsed(const bool unused) {
486  setFlag(fIsAttributeUsed, unused);
487  }
488  bool isAttributePure() const {
489  return getFlag(fIsAttributePure);
490  }
491  void isAttributePure(const bool value) {
492  setFlag(fIsAttributePure, value);
493  }
494  bool isAttributeConst() const {
495  return getFlag(fIsAttributeConst);
496  }
497  void isAttributeConst(bool value) {
498  setFlag(fIsAttributeConst, value);
499  }
500  bool isAttributeNoreturn() const {
501  return getFlag(fIsAttributeNoreturn);
502  }
503  void isAttributeNoreturn(const bool value) {
504  setFlag(fIsAttributeNoreturn, value);
505  }
506  bool isAttributeNothrow() const {
507  return getFlag(fIsAttributeNothrow);
508  }
509  void isAttributeNothrow(const bool value) {
510  setFlag(fIsAttributeNothrow, value);
511  }
512  bool isAttributeExport() const {
513  return getFlag(fIsAttributeExport);
514  }
515  void isAttributeExport(const bool value) {
516  setFlag(fIsAttributeExport, value);
517  }
518  bool isAttributePacked() const {
519  return getFlag(fIsAttributePacked);
520  }
521  void isAttributePacked(const bool value) {
522  setFlag(fIsAttributePacked, value);
523  }
524  bool isAttributeNodiscard() const {
525  return getFlag(fIsAttributeNodiscard);
526  }
527  void isAttributeNodiscard(const bool value) {
528  setFlag(fIsAttributeNodiscard, value);
529  }
530  bool isAttributeMaybeUnused() const {
531  return getFlag(fIsAttributeMaybeUnused);
532  }
533  void isAttributeMaybeUnused(const bool value) {
534  setFlag(fIsAttributeMaybeUnused, value);
535  }
537  mImpl->setCppcheckAttribute(type, value);
538  }
540  return mImpl->getCppcheckAttribute(type, value);
541  }
542  // cppcheck-suppress unusedFunction
543  bool hasCppcheckAttributes() const {
544  return nullptr != mImpl->mCppcheckAttributes;
545  }
546  bool isControlFlowKeyword() const {
547  return getFlag(fIsControlFlowKeyword);
548  }
549  bool isOperatorKeyword() const {
550  return getFlag(fIsOperatorKeyword);
551  }
552  void isOperatorKeyword(const bool value) {
553  setFlag(fIsOperatorKeyword, value);
554  }
555  bool isComplex() const {
556  return getFlag(fIsComplex);
557  }
558  void isComplex(const bool value) {
559  setFlag(fIsComplex, value);
560  }
561  bool isEnumType() const {
562  return getFlag(fIsEnumType);
563  }
564  void isEnumType(const bool value) {
565  setFlag(fIsEnumType, value);
566  }
567  bool isAtAddress() const {
568  return getFlag(fAtAddress);
569  }
570  void isAtAddress(bool b) {
571  setFlag(fAtAddress, b);
572  }
573  bool isIncompleteVar() const {
574  return getFlag(fIncompleteVar);
575  }
576  void isIncompleteVar(bool b) {
577  setFlag(fIncompleteVar, b);
578  }
579 
580  bool isSimplifiedTypedef() const {
581  return getFlag(fIsSimplifiedTypedef);
582  }
583  void isSimplifiedTypedef(bool b) {
584  setFlag(fIsSimplifiedTypedef, b);
585  }
586 
587  bool isIncompleteConstant() const {
588  return getFlag(fIsIncompleteConstant);
589  }
590  void isIncompleteConstant(bool b) {
591  setFlag(fIsIncompleteConstant, b);
592  }
593 
594  bool isConstexpr() const {
595  return getFlag(fConstexpr);
596  }
597  void isConstexpr(bool b) {
598  setFlag(fConstexpr, b);
599  }
600 
601  bool isExternC() const {
602  return getFlag(fExternC);
603  }
604  void isExternC(bool b) {
605  setFlag(fExternC, b);
606  }
607 
608  bool isSplittedVarDeclComma() const {
609  return getFlag(fIsSplitVarDeclComma);
610  }
611  void isSplittedVarDeclComma(bool b) {
612  setFlag(fIsSplitVarDeclComma, b);
613  }
614 
615  bool isSplittedVarDeclEq() const {
616  return getFlag(fIsSplitVarDeclEq);
617  }
618  void isSplittedVarDeclEq(bool b) {
619  setFlag(fIsSplitVarDeclEq, b);
620  }
621 
622  bool isImplicitInt() const {
623  return getFlag(fIsImplicitInt);
624  }
625  void isImplicitInt(bool b) {
626  setFlag(fIsImplicitInt, b);
627  }
628 
629  bool isInline() const {
630  return getFlag(fIsInline);
631  }
632  void isInline(bool b) {
633  setFlag(fIsInline, b);
634  }
635 
636  bool isAtomic() const {
637  return getFlag(fIsAtomic);
638  }
639  void isAtomic(bool b) {
640  setFlag(fIsAtomic, b);
641  }
642 
643  bool isRestrict() const {
644  return getFlag(fIsRestrict);
645  }
646  void isRestrict(bool b) {
647  setFlag(fIsRestrict, b);
648  }
649 
650  bool isRemovedVoidParameter() const {
651  return getFlag(fIsRemovedVoidParameter);
652  }
653  void setRemovedVoidParameter(bool b) {
654  setFlag(fIsRemovedVoidParameter, b);
655  }
656 
657  bool isTemplate() const {
658  return getFlag(fIsTemplate);
659  }
660  void isTemplate(bool b) {
661  setFlag(fIsTemplate, b);
662  }
663 
664  bool isSimplifiedScope() const {
665  return getFlag(fIsSimplifedScope);
666  }
667  void isSimplifiedScope(bool b) {
668  setFlag(fIsSimplifedScope, b);
669  }
670 
671  bool isFinalType() const {
672  return getFlag(fIsFinalType);
673  }
674  void isFinalType(bool b) {
675  setFlag(fIsFinalType, b);
676  }
677 
678  bool isInitComma() const {
679  return getFlag(fIsInitComma);
680  }
681  void isInitComma(bool b) {
682  setFlag(fIsInitComma, b);
683  }
684 
685  // cppcheck-suppress unusedFunction
686  bool isBitfield() const {
687  return mImpl->mBits > 0;
688  }
689  unsigned char bits() const {
690  return mImpl->mBits;
691  }
692  const std::set<TemplateSimplifier::TokenAndName*>* templateSimplifierPointers() const {
693  return mImpl->mTemplateSimplifierPointers;
694  }
695  std::set<TemplateSimplifier::TokenAndName*>* templateSimplifierPointers() {
696  return mImpl->mTemplateSimplifierPointers;
697  }
699  if (!mImpl->mTemplateSimplifierPointers)
700  mImpl->mTemplateSimplifierPointers = new std::set<TemplateSimplifier::TokenAndName*>;
701  mImpl->mTemplateSimplifierPointers->insert(tokenAndName);
702  }
703  void setBits(const unsigned char b) {
704  mImpl->mBits = b;
705  }
706 
707  bool isUtf8() const {
708  return (((mTokType == eString) && isPrefixStringCharLiteral(mStr, '"', "u8")) ||
709  ((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', "u8")));
710  }
711 
712  bool isUtf16() const {
713  return (((mTokType == eString) && isPrefixStringCharLiteral(mStr, '"', "u")) ||
714  ((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', "u")));
715  }
716 
717  bool isUtf32() const {
718  return (((mTokType == eString) && isPrefixStringCharLiteral(mStr, '"', "U")) ||
719  ((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', "U")));
720  }
721 
722  bool isCChar() const {
723  return (((mTokType == eString) && isPrefixStringCharLiteral(mStr, '"', emptyString)) ||
724  ((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', emptyString) && mStr.length() == 3));
725  }
726 
727  bool isCMultiChar() const {
728  return (((mTokType == eChar) && isPrefixStringCharLiteral(mStr, '\'', emptyString)) &&
729  (mStr.length() > 3));
730  }
731  /**
732  * @brief Is current token a template argument?
733  *
734  * Original code:
735  *
736  * template<class C> struct S {
737  * C x;
738  * };
739  * S<int> s;
740  *
741  * Resulting code:
742  *
743  * struct S<int> {
744  * int x ; // <- "int" is a template argument
745  * }
746  * S<int> s;
747  */
748  bool isTemplateArg() const {
749  return getFlag(fIsTemplateArg);
750  }
751  void isTemplateArg(const bool value) {
752  setFlag(fIsTemplateArg, value);
753  }
754 
755  std::string getMacroName() const {
756  return mImpl->mMacroName;
757  }
758  void setMacroName(std::string name) {
759  mImpl->mMacroName = std::move(name);
760  }
761 
762  template<size_t count>
763  static const Token *findsimplematch(const Token * const startTok, const char (&pattern)[count]) {
764  return findsimplematch(startTok, pattern, count-1);
765  }
766  static const Token *findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len);
767 
768  template<size_t count>
769  static const Token *findsimplematch(const Token * const startTok, const char (&pattern)[count], const Token * const end) {
770  return findsimplematch(startTok, pattern, count-1, end);
771  }
772  static const Token *findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end);
773 
774  static const Token *findmatch(const Token * const startTok, const char pattern[], const nonneg int varId = 0);
775  static const Token *findmatch(const Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId = 0);
776 
777  template<size_t count>
778  static Token *findsimplematch(Token * const startTok, const char (&pattern)[count]) {
779  return findsimplematch(startTok, pattern, count-1);
780  }
781  static Token *findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len);
782  template<size_t count>
783  static Token *findsimplematch(Token * const startTok, const char (&pattern)[count], const Token * const end) {
784  return findsimplematch(startTok, pattern, count-1, end);
785  }
786  static Token *findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end);
787 
788  static Token *findmatch(Token * const startTok, const char pattern[], const nonneg int varId = 0);
789  static Token *findmatch(Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId = 0);
790 
791 private:
792  /**
793  * Needle is build from multiple alternatives. If one of
794  * them is equal to haystack, return value is 1. If there
795  * are no matches, but one alternative to needle is empty
796  * string, return value is 0. If needle was not found, return
797  * value is -1.
798  *
799  * @param tok Current token (needle)
800  * @param haystack e.g. "one|two" or "|one|two"
801  * @param varid optional varid of token
802  * @return 1 if needle is found from the haystack
803  * 0 if needle was empty string
804  * -1 if needle was not found
805  */
806  static int multiCompare(const Token *tok, const char *haystack, nonneg int varid);
807 
808 public:
809  nonneg int fileIndex() const {
810  return mImpl->mFileIndex;
811  }
812  void fileIndex(nonneg int indexOfFile) {
813  mImpl->mFileIndex = indexOfFile;
814  }
815 
816  nonneg int linenr() const {
817  return mImpl->mLineNumber;
818  }
819  void linenr(nonneg int lineNumber) {
820  mImpl->mLineNumber = lineNumber;
821  }
822 
823  nonneg int column() const {
824  return mImpl->mColumn;
825  }
826  void column(nonneg int c) {
827  mImpl->mColumn = c;
828  }
829 
830  Token* next() {
831  return mNext;
832  }
833 
834  const Token* next() const {
835  return mNext;
836  }
837 
838  /**
839  * Delete tokens between begin and end. E.g. if begin = 1
840  * and end = 5, tokens 2,3 and 4 would be erased.
841  *
842  * @param begin Tokens after this will be erased.
843  * @param end Tokens before this will be erased.
844  */
845  static void eraseTokens(Token *begin, const Token *end);
846 
847  /**
848  * Insert new token after this token. This function will handle
849  * relations between next and previous token also.
850  * @param tokenStr String for the new token.
851  * @param originalNameStr String used for Token::originalName().
852  * @param prepend Insert the new token before this token when it's not
853  * the first one on the tokens list.
854  */
855  Token* insertToken(const std::string& tokenStr, const std::string& originalNameStr = emptyString, const std::string& macroNameStr = emptyString, bool prepend = false);
856 
857  Token* insertTokenBefore(const std::string& tokenStr, const std::string& originalNameStr = emptyString, const std::string& macroNameStr = emptyString)
858  {
859  return insertToken(tokenStr, originalNameStr, macroNameStr, true);
860  }
861 
863  return mPrevious;
864  }
865 
866  const Token* previous() const {
867  return mPrevious;
868  }
869 
870  nonneg int varId() const {
871  return mImpl->mVarId;
872  }
873  void varId(nonneg int id) {
874  mImpl->mVarId = id;
875  if (id != 0) {
876  tokType(eVariable);
877  isStandardType(false);
878  } else {
879  update_property_info();
880  }
881  }
882 
883  nonneg int exprId() const {
884  if (mImpl->mExprId)
885  return mImpl->mExprId;
886  return mImpl->mVarId;
887  }
888  void exprId(nonneg int id) {
889  mImpl->mExprId = id;
890  }
891 
893  {
894  assert(mImpl->mExprId > 0);
895  mImpl->mExprId |= 1 << efIsUnique;
896  }
897 
898  bool isUniqueExprId() const
899  {
900  return (mImpl->mExprId & (1 << efIsUnique)) != 0;
901  }
902 
903  /**
904  * For debugging purposes, prints token and all tokens
905  * followed by it.
906  * @param title Title for the printout or use default parameter or 0
907  * for no title.
908  */
909  void printOut(const char *title = nullptr) const;
910 
911  /**
912  * For debugging purposes, prints token and all tokens
913  * followed by it.
914  * @param title Title for the printout or use default parameter or 0
915  * for no title.
916  * @param fileNames Prints out file name instead of file index.
917  * File index should match the index of the string in this vector.
918  */
919  void printOut(const char *title, const std::vector<std::string> &fileNames) const;
920 
921  /**
922  * print out tokens - used for debugging
923  */
924  void printLines(int lines=5) const;
925 
926  /**
927  * Replace token replaceThis with tokens between start and end,
928  * including start and end. The replaceThis token is deleted.
929  * @param replaceThis This token will be deleted.
930  * @param start This will be in the place of replaceThis
931  * @param end This is also in the place of replaceThis
932  */
933  static void replace(Token *replaceThis, Token *start, Token *end);
934 
936  bool varid = false;
937  bool exprid = false;
938  bool idtype = false; // distinguish varid / exprid
939  bool attributes = false;
940  bool macro = false;
941  bool linenumbers = false;
942  bool linebreaks = false;
943  bool files = false;
945  stringifyOptions options;
946  options.attributes = true;
947  options.macro = true;
948  options.linenumbers = true;
949  options.linebreaks = true;
950  options.files = true;
951  return options;
952  }
953  // cppcheck-suppress unusedFunction
955  stringifyOptions options = forDebug();
956  options.varid = true;
957  return options;
958  }
960  stringifyOptions options = forDebug();
961  options.exprid = true;
962  return options;
963  }
965  stringifyOptions options = forDebug();
966  options.exprid = true;
967  options.varid = true;
968  options.idtype = true;
969  return options;
970  }
971  };
972 
973  std::string stringify(const stringifyOptions& options) const;
974 
975  /**
976  * Stringify a token
977  * @param varid Print varids. (Style: "varname\@id")
978  * @param attributes Print attributes of tokens like "unsigned" in front of it.
979  * @param macro Prints $ in front of the token if it was expanded from a macro.
980  */
981  std::string stringify(bool varid, bool attributes, bool macro) const;
982 
983  std::string stringifyList(const stringifyOptions& options, const std::vector<std::string>* fileNames = nullptr, const Token* end = nullptr) const;
984  std::string stringifyList(const Token* end, bool attributes = true) const;
985  std::string stringifyList(bool varid = false) const;
986 
987  /**
988  * Stringify a list of token, from current instance on.
989  * @param varid Print varids. (Style: "varname\@id")
990  * @param attributes Print attributes of tokens like "unsigned" in front of it.
991  * @param linenumbers Print line number in front of each line
992  * @param linebreaks Insert "\\n" into string when line number changes
993  * @param files print Files as numbers or as names (if fileNames is given)
994  * @param fileNames Vector of filenames. Used (if given) to print filenames as strings instead of numbers.
995  * @param end Stringification ends before this token is reached. 0 to stringify until end of list.
996  * @return Stringified token list as a string
997  */
998  std::string stringifyList(bool varid, bool attributes, bool linenumbers, bool linebreaks, bool files, const std::vector<std::string>* fileNames = nullptr, const Token* end = nullptr) const;
999 
1000  /**
1001  * Remove the contents for this token from the token list.
1002  *
1003  * The contents are replaced with the contents of the next token and
1004  * the next token is unlinked and deleted from the token list.
1005  *
1006  * So this token will still be valid after the 'deleteThis()'.
1007  */
1008  void deleteThis();
1009 
1010  /**
1011  * Create link to given token
1012  * @param linkToToken The token where this token should link
1013  * to.
1014  */
1015  void link(Token *linkToToken) {
1016  mLink = linkToToken;
1017  if (mStr == "<" || mStr == ">")
1018  update_property_info();
1019  }
1020 
1021  /**
1022  * Return token where this token links to.
1023  * Supported links are:
1024  * "{" <-> "}"
1025  * "(" <-> ")"
1026  * "[" <-> "]"
1027  *
1028  * @return The token where this token links to.
1029  */
1030  const Token* link() const {
1031  return mLink;
1032  }
1033 
1035  return mLink;
1036  }
1037 
1038  /**
1039  * Associate this token with given scope
1040  * @param s Scope to be associated
1041  */
1042  void scope(const Scope *s) {
1043  mImpl->mScope = s;
1044  }
1045 
1046  /**
1047  * @return a pointer to the scope containing this token.
1048  */
1049  const Scope *scope() const {
1050  return mImpl->mScope;
1051  }
1052 
1053  /**
1054  * Associate this token with given function
1055  * @param f Function to be associated
1056  */
1057  void function(const Function *f);
1058 
1059  /**
1060  * @return a pointer to the Function associated with this token.
1061  */
1062  const Function *function() const {
1063  return mTokType == eFunction || mTokType == eLambda ? mImpl->mFunction : nullptr;
1064  }
1065 
1066  /**
1067  * Associate this token with given variable
1068  * @param v Variable to be associated
1069  */
1070  void variable(const Variable *v) {
1071  mImpl->mVariable = v;
1072  if (v || mImpl->mVarId)
1073  tokType(eVariable);
1074  else if (mTokType == eVariable)
1075  tokType(eName);
1076  }
1077 
1078  /**
1079  * @return a pointer to the variable associated with this token.
1080  */
1081  const Variable *variable() const {
1082  return mTokType == eVariable ? mImpl->mVariable : nullptr;
1083  }
1084 
1085  /**
1086  * Associate this token with given type
1087  * @param t Type to be associated
1088  */
1089  void type(const ::Type *t);
1090 
1091  /**
1092  * @return a pointer to the type associated with this token.
1093  */
1094  const ::Type *type() const {
1095  return mTokType == eType ? mImpl->mType : nullptr;
1096  }
1097 
1098  static const ::Type* typeOf(const Token* tok, const Token** typeTok = nullptr);
1099 
1100  /**
1101  * @return the declaration associated with this token.
1102  * @param pointedToType return the pointed-to type?
1103  */
1104  static std::pair<const Token*, const Token*> typeDecl(const Token* tok, bool pointedToType = false);
1105 
1106  static std::string typeStr(const Token* tok);
1107 
1108  /**
1109  * @return a pointer to the Enumerator associated with this token.
1110  */
1111  const Enumerator *enumerator() const {
1112  return mTokType == eEnumerator ? mImpl->mEnumerator : nullptr;
1113  }
1114 
1115  /**
1116  * Associate this token with given enumerator
1117  * @param e Enumerator to be associated
1118  */
1119  void enumerator(const Enumerator *e) {
1120  mImpl->mEnumerator = e;
1121  if (e)
1122  tokType(eEnumerator);
1123  else if (mTokType == eEnumerator)
1124  tokType(eName);
1125  }
1126 
1127  /**
1128  * Links two elements against each other.
1129  **/
1130  static void createMutualLinks(Token *begin, Token *end);
1131 
1132  /**
1133  * This can be called only for tokens that are strings, else
1134  * the assert() is called. If Token is e.g. '"hello"', this will return
1135  * 'hello' (removing the double quotes).
1136  * @return String value
1137  */
1138  std::string strValue() const;
1139 
1140  /**
1141  * Move srcStart and srcEnd tokens and all tokens between them
1142  * into new a location. Only links between tokens are changed.
1143  * @param srcStart This is the first token to be moved
1144  * @param srcEnd The last token to be moved
1145  * @param newLocation srcStart will be placed after this token.
1146  */
1147  static void move(Token *srcStart, Token *srcEnd, Token *newLocation);
1148 
1149  /** Get progressValue (0 - 100) */
1150  nonneg int progressValue() const {
1151  return mImpl->mProgressValue;
1152  }
1153 
1154  /** Calculate progress values for all tokens */
1155  static void assignProgressValues(Token *tok);
1156 
1157  /**
1158  * @return the first token of the next argument. Does only work on argument
1159  * lists. Requires that Tokenizer::createLinks2() has been called before.
1160  * Returns 0, if there is no next argument.
1161  */
1162  const Token* nextArgument() const;
1163  Token *nextArgument();
1164 
1165  /**
1166  * @return the first token of the next argument. Does only work on argument
1167  * lists. Should be used only before Tokenizer::createLinks2() was called.
1168  * Returns 0, if there is no next argument.
1169  */
1170  const Token* nextArgumentBeforeCreateLinks2() const;
1171 
1172  /**
1173  * @return the first token of the next template argument. Does only work on template argument
1174  * lists. Requires that Tokenizer::createLinks2() has been called before.
1175  * Returns 0, if there is no next argument.
1176  */
1177  const Token* nextTemplateArgument() const;
1178 
1179  /**
1180  * Returns the closing bracket of opening '<'. Should only be used if link()
1181  * is unavailable.
1182  * @return closing '>', ')', ']' or '}'. if no closing bracket is found, NULL is returned
1183  */
1184  const Token* findClosingBracket() const;
1185  Token* findClosingBracket();
1186 
1187  const Token* findOpeningBracket() const;
1188  Token* findOpeningBracket();
1189 
1190  /**
1191  * @return the original name.
1192  */
1193  const std::string & originalName() const {
1194  return mImpl->mOriginalName ? *mImpl->mOriginalName : emptyString;
1195  }
1196 
1197  const std::list<ValueFlow::Value>& values() const {
1198  return mImpl->mValues ? *mImpl->mValues : TokenImpl::mEmptyValueList;
1199  }
1200 
1201  /**
1202  * Sets the original name.
1203  */
1204  template<typename T>
1205  void originalName(T&& name) {
1206  if (!mImpl->mOriginalName)
1207  mImpl->mOriginalName = new std::string(name);
1208  else
1209  *mImpl->mOriginalName = name;
1210  }
1211 
1212  bool hasKnownIntValue() const;
1213  bool hasKnownValue() const;
1214  bool hasKnownValue(ValueFlow::Value::ValueType t) const;
1215  bool hasKnownSymbolicValue(const Token* tok) const;
1216 
1217  const ValueFlow::Value* getKnownValue(ValueFlow::Value::ValueType t) const;
1219  return mImpl->mValues->front().intvalue;
1220  }
1221 
1222  const ValueFlow::Value* getValue(const MathLib::bigint val) const;
1223 
1224  const ValueFlow::Value* getMaxValue(bool condition, MathLib::bigint path = 0) const;
1225  const ValueFlow::Value* getMinValue(bool condition, MathLib::bigint path = 0) const;
1226 
1227  const ValueFlow::Value* getMovedValue() const;
1228 
1229  const ValueFlow::Value * getValueLE(const MathLib::bigint val, const Settings &settings) const;
1230  const ValueFlow::Value * getValueGE(const MathLib::bigint val, const Settings &settings) const;
1231 
1232  const ValueFlow::Value * getInvalidValue(const Token *ftok, nonneg int argnr, const Settings &settings) const;
1233 
1234  const ValueFlow::Value* getContainerSizeValue(const MathLib::bigint val) const;
1235 
1236  const Token *getValueTokenMaxStrLength() const;
1237  const Token *getValueTokenMinStrSize(const Settings &settings, MathLib::bigint* path = nullptr) const;
1238 
1239  /** Add token value. Return true if value is added. */
1240  bool addValue(const ValueFlow::Value &value);
1241 
1242  void removeValues(std::function<bool(const ValueFlow::Value &)> pred) {
1243  if (mImpl->mValues)
1244  mImpl->mValues->remove_if(std::move(pred));
1245  }
1246 
1247  nonneg int index() const {
1248  return mImpl->mIndex;
1249  }
1250 
1251  void assignIndexes();
1252 
1253 private:
1254 
1255  void next(Token *nextToken) {
1256  mNext = nextToken;
1257  }
1258  void previous(Token *previousToken) {
1259  mPrevious = previousToken;
1260  }
1261 
1262  /** used by deleteThis() to take data from token to delete */
1263  void takeData(Token *fromToken);
1264 
1265  /**
1266  * Works almost like strcmp() except returns only true or false and
1267  * if str has empty space &apos; &apos; character, that character is handled
1268  * as if it were &apos;\\0&apos;
1269  */
1270  static bool firstWordEquals(const char *str, const char *word);
1271 
1272  /**
1273  * Works almost like strchr() except
1274  * if str has empty space &apos; &apos; character, that character is handled
1275  * as if it were &apos;\\0&apos;
1276  */
1277  static const char *chrInFirstWord(const char *str, char c);
1278 
1279  std::string mStr;
1280 
1281  Token* mNext{};
1282  Token* mPrevious{};
1283  Token* mLink{};
1284 
1285  enum : uint64_t {
1286  fIsUnsigned = (1ULL << 0),
1287  fIsSigned = (1ULL << 1),
1288  fIsPointerCompare = (1ULL << 2),
1289  fIsLong = (1ULL << 3),
1290  fIsStandardType = (1ULL << 4),
1291  //fIsExpandedMacro = (1ULL << 5),
1292  fIsCast = (1ULL << 6),
1293  fIsAttributeConstructor = (1ULL << 7), // __attribute__((constructor)) __attribute__((constructor(priority)))
1294  fIsAttributeDestructor = (1ULL << 8), // __attribute__((destructor)) __attribute__((destructor(priority)))
1295  fIsAttributeUnused = (1ULL << 9), // __attribute__((unused))
1296  fIsAttributePure = (1ULL << 10), // __attribute__((pure))
1297  fIsAttributeConst = (1ULL << 11), // __attribute__((const))
1298  fIsAttributeNoreturn = (1ULL << 12), // __attribute__((noreturn)), __declspec(noreturn)
1299  fIsAttributeNothrow = (1ULL << 13), // __attribute__((nothrow)), __declspec(nothrow)
1300  fIsAttributeUsed = (1ULL << 14), // __attribute__((used))
1301  fIsAttributePacked = (1ULL << 15), // __attribute__((packed))
1302  fIsAttributeExport = (1ULL << 16), // __attribute__((__visibility__("default"))), __declspec(dllexport)
1303  fIsAttributeMaybeUnused = (1ULL << 17), // [[maybe_unused]]
1304  fIsAttributeNodiscard = (1ULL << 18), // __attribute__ ((warn_unused_result)), [[nodiscard]]
1305  fIsControlFlowKeyword = (1ULL << 19), // if/switch/while/...
1306  fIsOperatorKeyword = (1ULL << 20), // operator=, etc
1307  fIsComplex = (1ULL << 21), // complex/_Complex type
1308  fIsEnumType = (1ULL << 22), // enumeration type
1309  fIsName = (1ULL << 23),
1310  fIsLiteral = (1ULL << 24),
1311  fIsTemplateArg = (1ULL << 25),
1312  fAtAddress = (1ULL << 26), // @ 0x4000
1313  fIncompleteVar = (1ULL << 27),
1314  fConstexpr = (1ULL << 28),
1315  fExternC = (1ULL << 29),
1316  fIsSplitVarDeclComma = (1ULL << 30), // set to true when variable declarations are split up ('int a,b;' => 'int a; int b;')
1317  fIsSplitVarDeclEq = (1ULL << 31), // set to true when variable declaration with initialization is split up ('int a=5;' => 'int a; a=5;')
1318  fIsImplicitInt = (1ULL << 32), // Is "int" token implicitly added?
1319  fIsInline = (1ULL << 33), // Is this a inline type
1320  fIsTemplate = (1ULL << 34),
1321  fIsSimplifedScope = (1ULL << 35), // scope added when simplifying e.g. if (int i = ...; ...)
1322  fIsRemovedVoidParameter = (1ULL << 36), // A void function parameter has been removed
1323  fIsIncompleteConstant = (1ULL << 37),
1324  fIsRestrict = (1ULL << 38), // Is this a restrict pointer type
1325  fIsAtomic = (1ULL << 39), // Is this a _Atomic declaration
1326  fIsSimplifiedTypedef = (1ULL << 40),
1327  fIsFinalType = (1ULL << 41), // Is this a type with final specifier
1328  fIsInitComma = (1ULL << 42), // Is this comma located inside some {..}. i.e: {1,2,3,4}
1329  };
1330 
1331  enum : uint64_t {
1332  efMaxSize = sizeof(nonneg int) * 8,
1333  efIsUnique = efMaxSize - 2,
1334  };
1335 
1336  Token::Type mTokType = eNone;
1337 
1338  uint64_t mFlags{};
1339 
1340  TokenImpl* mImpl{};
1341 
1342  /**
1343  * Get specified flag state.
1344  * @param flag_ flag to get state of
1345  * @return true if flag set or false in flag not set
1346  */
1347  bool getFlag(uint64_t flag_) const {
1348  return ((mFlags & flag_) != 0);
1349  }
1350 
1351  /**
1352  * Set specified flag state.
1353  * @param flag_ flag to set state
1354  * @param state_ new state of flag
1355  */
1356  void setFlag(uint64_t flag_, bool state_) {
1357  mFlags = state_ ? mFlags | flag_ : mFlags & ~flag_;
1358  }
1359 
1360  /** Updates internal property cache like _isName or _isBoolean.
1361  Called after any mStr() modification. */
1362  void update_property_info();
1363 
1364  /** Update internal property cache about isStandardType() */
1365  void update_property_isStandardType();
1366 
1367  /** Update internal property cache about string and char literals */
1368  void update_property_char_string_literal();
1369 
1370  /** Internal helper function to avoid excessive string allocations */
1371  void astStringVerboseRecursive(std::string& ret, const nonneg int indent1 = 0, const nonneg int indent2 = 0) const;
1372 
1373 public:
1374  void astOperand1(Token *tok);
1375  void astOperand2(Token *tok);
1376  void astParent(Token* tok);
1377 
1379  return mImpl->mAstOperand1;
1380  }
1381  const Token * astOperand1() const {
1382  return mImpl->mAstOperand1;
1383  }
1385  return mImpl->mAstOperand2;
1386  }
1387  const Token * astOperand2() const {
1388  return mImpl->mAstOperand2;
1389  }
1391  return mImpl->mAstParent;
1392  }
1393  const Token * astParent() const {
1394  return mImpl->mAstParent;
1395  }
1397  if (!astParent())
1398  return nullptr;
1399  if (this == astParent()->astOperand1())
1400  return astParent()->astOperand2();
1401  if (this == astParent()->astOperand2())
1402  return astParent()->astOperand1();
1403  return nullptr;
1404 
1405  }
1406  const Token * astSibling() const {
1407  if (!astParent())
1408  return nullptr;
1409  if (this == astParent()->astOperand1())
1410  return astParent()->astOperand2();
1411  if (this == astParent()->astOperand2())
1412  return astParent()->astOperand1();
1413  return nullptr;
1414 
1415  }
1417  Token *ret = this;
1418  while (ret->mImpl->mAstParent)
1419  ret = ret->mImpl->mAstParent;
1420  return ret;
1421  }
1422 
1423  const Token *astTop() const {
1424  const Token *ret = this;
1425  while (ret->mImpl->mAstParent)
1426  ret = ret->mImpl->mAstParent;
1427  return ret;
1428  }
1429 
1430  std::pair<const Token *, const Token *> findExpressionStartEndTokens() const;
1431 
1432  /**
1433  * Is current token a calculation? Only true for operands.
1434  * For '*' and '&' tokens it is looked up if this is a
1435  * dereference or address-of. A dereference or address-of is not
1436  * counted as a calculation.
1437  * @return returns true if current token is a calculation
1438  */
1439  bool isCalculation() const;
1440 
1442  delete mImpl->mValues;
1443  mImpl->mValues = nullptr;
1444  }
1445 
1446  std::string astString(const char *sep = "") const {
1447  std::string ret;
1448  if (mImpl->mAstOperand1)
1449  ret = mImpl->mAstOperand1->astString(sep);
1450  if (mImpl->mAstOperand2)
1451  ret += mImpl->mAstOperand2->astString(sep);
1452  return ret + sep + mStr;
1453  }
1454 
1455  std::string astStringVerbose() const;
1456 
1457  std::string astStringZ3() const;
1458 
1459  std::string expressionString() const;
1460 
1461  void printAst(bool verbose, bool xml, const std::vector<std::string> &fileNames, std::ostream &out) const;
1462 
1463  void printValueFlow(bool xml, std::ostream &out) const;
1464 
1465  void scopeInfo(std::shared_ptr<ScopeInfo2> newScopeInfo);
1466  std::shared_ptr<ScopeInfo2> scopeInfo() const;
1467 
1468  void setCpp11init(bool cpp11init) const {
1469  mImpl->mCpp11init=cpp11init ? TokenImpl::Cpp11init::CPP11INIT : TokenImpl::Cpp11init::NOINIT;
1470  }
1472  return mImpl->mCpp11init;
1473  }
1474 
1476  return mImpl->mDebug;
1477  }
1479  mImpl->mDebug = td;
1480  }
1481 
1482  bool isCpp() const;
1483 
1484  bool isC() const;
1485 };
1486 
1487 Token* findTypeEnd(Token* tok);
1489 const Token* findLambdaEndScope(const Token* tok);
1490 
1491 /// @}
1492 //---------------------------------------------------------------------------
1493 #endif // tokenH
static int sign(const T v)
long long bigint
Definition: mathlib.h:68
This is just a container for general settings so that we don't need to pass individual values to func...
Definition: settings.h:95
Token and its full scopename.
The token list that the TokenList generates is a linked-list of this class.
Definition: token.h:150
void isTemplate(bool b)
Definition: token.h:660
bool isRemovedVoidParameter() const
Definition: token.h:650
void str(T &&s)
Definition: token.h:179
Token(const Token &)=delete
std::string mStr
Definition: token.h:1279
void isAttributeNodiscard(const bool value)
Definition: token.h:527
nonneg int index() const
Definition: token.h:1247
bool isUtf16() const
Definition: token.h:712
Token * astTop()
Definition: token.h:1416
void isFinalType(bool b)
Definition: token.h:674
std::string astString(const char *sep="") const
Definition: token.h:1446
void isIncompleteConstant(bool b)
Definition: token.h:590
static Token * findsimplematch(Token *const startTok, const char(&pattern)[count], const Token *const end)
Definition: token.h:783
void next(Token *nextToken)
Definition: token.h:1255
static bool Match(const Token *tok, const char pattern[], nonneg int varid=0)
Match given token (or list of tokens) to a pattern list.
Definition: token.cpp:722
void isComplex(const bool value)
Definition: token.h:558
bool isConstexpr() const
Definition: token.h:594
Token * link()
Definition: token.h:1034
bool isSimplifiedScope() const
Definition: token.h:664
void exprId(nonneg int id)
Definition: token.h:888
void isAttributeUsed(const bool unused)
Definition: token.h:485
nonneg int exprId() const
Definition: token.h:883
void isEnumType(const bool value)
Definition: token.h:564
void isSigned(const bool sign)
Definition: token.h:433
bool isEnumerator() const
Definition: token.h:374
bool isKeyword() const
Definition: token.h:358
unsigned char bits() const
Definition: token.h:689
bool isCChar() const
Definition: token.h:722
void setMacroName(std::string name)
Definition: token.h:758
const std::string & originalName() const
Definition: token.h:1193
void isCast(bool c)
Definition: token.h:461
void fileIndex(nonneg int indexOfFile)
Definition: token.h:812
const Token * previous() const
Definition: token.h:866
void setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint value)
Definition: token.h:536
bool isName() const
Definition: token.h:361
bool isAttributeUsed() const
Definition: token.h:482
Token * astOperand1()
Definition: token.h:1378
bool isTemplate() const
Definition: token.h:657
uint64_t flags() const
Definition: token.h:418
TokenImpl::Cpp11init isCpp11init() const
Definition: token.h:1471
bool isUnsigned() const
Definition: token.h:424
void isAttributePure(const bool value)
Definition: token.h:491
bool isEnumType() const
Definition: token.h:561
MathLib::bigint getKnownIntValue() const
Definition: token.h:1218
void removeValues(std::function< bool(const ValueFlow::Value &)> pred)
Definition: token.h:1242
bool isSimplifiedTypedef() const
Definition: token.h:580
const Token * astSibling() const
Definition: token.h:1406
bool isExpandedMacro() const
Definition: token.h:455
void varId(nonneg int id)
Definition: token.h:873
bool isBitfield() const
Definition: token.h:686
static Token * findsimplematch(Token *const startTok, const char(&pattern)[count])
Definition: token.h:778
bool isTemplateArg() const
Is current token a template argument?
Definition: token.h:748
void isAttributeUnused(bool unused)
Definition: token.h:479
void previous(Token *previousToken)
Definition: token.h:1258
const Token * astOperand1() const
Definition: token.h:1381
Token * astOperand2()
Definition: token.h:1384
void setTokenDebug(TokenDebug td)
Definition: token.h:1478
void isAttributeNothrow(const bool value)
Definition: token.h:509
void isSimplifiedTypedef(bool b)
Definition: token.h:583
void templateSimplifierPointer(TemplateSimplifier::TokenAndName *tokenAndName)
Definition: token.h:698
bool isArithmeticalOp() const
Definition: token.h:395
const Token * link() const
Return token where this token links to.
Definition: token.h:1030
void linenr(nonneg int lineNumber)
Definition: token.h:819
void isAttributeExport(const bool value)
Definition: token.h:515
bool isIncompleteVar() const
Definition: token.h:573
const Token * astParent() const
Definition: token.h:1393
static const Token * findsimplematch(const Token *const startTok, const char(&pattern)[count], const Token *const end)
Definition: token.h:769
void column(nonneg int c)
Definition: token.h:826
bool isExtendedOp() const
Definition: token.h:391
void setUniqueExprId()
Definition: token.h:892
bool isPointerCompare() const
Definition: token.h:437
void isAttributeDestructor(const bool value)
Definition: token.h:473
bool isBoolean() const
Definition: token.h:404
void isSimplifiedScope(bool b)
Definition: token.h:667
bool isAttributeDestructor() const
Definition: token.h:470
void isImplicitInt(bool b)
Definition: token.h:625
nonneg int progressValue() const
Get progressValue (0 - 100)
Definition: token.h:1150
bool isNameOnly() const
Definition: token.h:364
const Scope * scope() const
Definition: token.h:1049
bool isControlFlowKeyword() const
Definition: token.h:546
void isPointerCompare(const bool b)
Definition: token.h:440
void setBits(const unsigned char b)
Definition: token.h:703
const Token * astOperand2() const
Definition: token.h:1387
bool isUniqueExprId() const
Definition: token.h:898
void isExternC(bool b)
Definition: token.h:604
bool isFinalType() const
Definition: token.h:671
bool isImplicitInt() const
Definition: token.h:622
bool isUtf32() const
Definition: token.h:717
const ValueType * valueType() const
Definition: token.h:331
bool isAttributeUnused() const
Definition: token.h:476
void isConstexpr(bool b)
Definition: token.h:597
void enumerator(const Enumerator *e)
Associate this token with given enumerator.
Definition: token.h:1119
const Enumerator * enumerator() const
Definition: token.h:1111
const Token * astTop() const
Definition: token.h:1423
TokensFrontBack & mTokensFrontBack
Definition: token.h:154
bool isNumber() const
Definition: token.h:371
bool isCMultiChar() const
Definition: token.h:727
bool isExternC() const
Definition: token.h:601
void flags(const uint64_t flags_)
Definition: token.h:421
void isAttributeConstructor(const bool ac)
Definition: token.h:467
nonneg int varId() const
Definition: token.h:870
void isAttributeNoreturn(const bool value)
Definition: token.h:503
std::set< TemplateSimplifier::TokenAndName * > * templateSimplifierPointers()
Definition: token.h:695
void isRestrict(bool b)
Definition: token.h:646
const std::string & str() const
Definition: token.h:192
bool isSigned() const
Definition: token.h:430
void setFlag(uint64_t flag_, bool state_)
Set specified flag state.
Definition: token.h:1356
bool isCast() const
Definition: token.h:458
bool isSplittedVarDeclComma() const
Definition: token.h:608
void isAtomic(bool b)
Definition: token.h:639
bool isUnaryOp(const std::string &s) const
Definition: token.h:413
const ValueType * argumentType() const
Definition: token.h:336
bool isIncDecOp() const
Definition: token.h:407
bool isLiteral() const
Definition: token.h:368
bool isAttributeNodiscard() const
Definition: token.h:524
bool isAttributeExport() const
Definition: token.h:512
bool isOperatorKeyword() const
Definition: token.h:549
void clearValueFlow()
Definition: token.h:1441
void isIncompleteVar(bool b)
Definition: token.h:576
bool isIncompleteConstant() const
Definition: token.h:587
const ::Type * type() const
Definition: token.h:1094
bool isAttributeConstructor() const
Definition: token.h:464
bool isInitComma() const
Definition: token.h:678
void setRemovedVoidParameter(bool b)
Definition: token.h:653
void originalName(T &&name)
Sets the original name.
Definition: token.h:1205
void isInitComma(bool b)
Definition: token.h:681
const std::set< TemplateSimplifier::TokenAndName * > * templateSimplifierPointers() const
Definition: token.h:692
Token & operator=(const Token &)=delete
TokenDebug getTokenDebug() const
Definition: token.h:1475
bool isOp() const
Definition: token.h:380
Token * astParent()
Definition: token.h:1390
void isInline(bool b)
Definition: token.h:632
void setCpp11init(bool cpp11init) const
Definition: token.h:1468
static const Token * findsimplematch(const Token *const startTok, const char(&pattern)[count])
Definition: token.h:763
void isAttributeConst(bool value)
Definition: token.h:497
Token * insertTokenBefore(const std::string &tokenStr, const std::string &originalNameStr=emptyString, const std::string &macroNameStr=emptyString)
Definition: token.h:857
bool isConstOp() const
Definition: token.h:385
bool hasCppcheckAttributes() const
Definition: token.h:543
const Variable * variable() const
Definition: token.h:1081
bool getFlag(uint64_t flag_) const
Get specified flag state.
Definition: token.h:1347
Token::Type tokType() const
Definition: token.h:343
void astOperand2(Token *tok)
Definition: token.cpp:1502
void isOperatorKeyword(const bool value)
Definition: token.h:552
void scope(const Scope *s)
Associate this token with given scope.
Definition: token.h:1042
bool isLong() const
Definition: token.h:443
void link(Token *linkToToken)
Create link to given token.
Definition: token.h:1015
void tokType(Token::Type t)
Definition: token.h:346
Type
Definition: token.h:160
@ eOther
Definition: token.h:167
@ eArithmeticalOp
Definition: token.h:163
@ eLambda
Definition: token.h:165
@ eBoolean
Definition: token.h:162
@ eEllipsis
Definition: token.h:166
@ eBracket
Definition: token.h:164
@ eFunction
Definition: token.h:161
void isAttributeMaybeUnused(const bool value)
Definition: token.h:533
void isAtAddress(bool b)
Definition: token.h:570
Token * previous()
Definition: token.h:862
void isAttributePacked(const bool value)
Definition: token.h:521
void isSplittedVarDeclEq(bool b)
Definition: token.h:618
void isUnsigned(const bool sign)
Definition: token.h:427
void isTemplateArg(const bool value)
Definition: token.h:751
bool isBinaryOp() const
Definition: token.h:410
bool isComplex() const
Definition: token.h:555
bool isAssignmentOp() const
Definition: token.h:401
bool isSplittedVarDeclEq() const
Definition: token.h:615
void isLong(bool size)
Definition: token.h:446
const Token * next() const
Definition: token.h:834
void isStandardType(const bool b)
Definition: token.h:452
nonneg int linenr() const
Definition: token.h:816
bool isUtf8() const
Definition: token.h:707
Token * astSibling()
Definition: token.h:1396
bool isStandardType() const
Definition: token.h:449
void variable(const Variable *v)
Associate this token with given variable.
Definition: token.h:1070
bool isAttributeMaybeUnused() const
Definition: token.h:530
bool isRestrict() const
Definition: token.h:643
bool isComparisonOp() const
Definition: token.h:398
Token * next()
Definition: token.h:830
bool isInline() const
Definition: token.h:629
const std::list< ValueFlow::Value > & values() const
Definition: token.h:1197
bool isAttributeNoreturn() const
Definition: token.h:500
bool isAttributeConst() const
Definition: token.h:494
bool isVariable() const
Definition: token.h:377
bool isAtomic() const
Definition: token.h:636
static bool simpleMatch(const Token *tok, const char(&pattern)[count])
Match given token (or list of tokens) to a pattern list.
Definition: token.h:252
nonneg int fileIndex() const
Definition: token.h:809
void isSplittedVarDeclComma(bool b)
Definition: token.h:611
bool isAttributePacked() const
Definition: token.h:518
bool isAttributeNothrow() const
Definition: token.h:506
TokenImpl * mImpl
Definition: token.h:1340
std::string getMacroName() const
Definition: token.h:755
nonneg int column() const
Definition: token.h:823
bool isAttributePure() const
Definition: token.h:488
bool getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint &value) const
Definition: token.h:539
void astParent(Token *tok)
Definition: token.cpp:1471
bool isAtAddress() const
Definition: token.h:567
Information about a class type.
Value type.
Information about a member variable.
static const std::string emptyString
Definition: config.h:127
#define CPPCHECKLIB
Definition: config.h:35
#define nonneg
Definition: config.h:138
static void replace(std::string &source, const std::unordered_map< std::string, std::string > &substitutionMap)
Token * findTypeEnd(Token *tok)
Definition: token.cpp:2708
Token * findLambdaEndScope(Token *tok)
Definition: token.cpp:2720
std::vector< MathLib::bigint > getMinValue(const ValuePtr< InferModel > &model, const std::list< ValueFlow::Value > &values)
Definition: infer.cpp:377
std::vector< MathLib::bigint > getMaxValue(const ValuePtr< InferModel > &model, const std::list< ValueFlow::Value > &values)
Definition: infer.cpp:383
std::string name
Definition: token.h:55
const Token *const bodyEnd
Definition: token.h:56
ScopeInfo2(std::string name_, const Token *bodyEnd_, std::set< std::string > usingNamespaces_=std::set< std::string >())
Definition: token.h:54
std::set< std::string > usingNamespaces
Definition: token.h:57
MathLib::bigint value
Definition: token.h:119
enum TokenImpl::CppcheckAttributes::Type type
CppcheckAttributes * next
Definition: token.h:120
std::list< ValueFlow::Value > * mValues
Definition: token.h:107
nonneg int mVarId
Definition: token.h:63
Cpp11init
Definition: token.h:125
std::string mMacroName
Definition: token.h:101
nonneg int mFileIndex
Definition: token.h:64
const Function * mFunction
Definition: token.h:91
const Enumerator * mEnumerator
Definition: token.h:94
std::string * mOriginalName
Definition: token.h:98
nonneg int mLineNumber
Definition: token.h:65
~TokenImpl()
Definition: token.cpp:2662
static const std::list< ValueFlow::Value > mEmptyValueList
Definition: token.h:108
unsigned char mBits
Bitfield bit count.
Definition: token.h:81
ValueType * mValueType
Definition: token.h:104
nonneg int mProgressValue
A value from 0-100 that provides a rough idea about where in the token list this token is located.
Definition: token.h:73
Token * mAstOperand1
Definition: token.h:84
nonneg int mExprId
Definition: token.h:67
const Variable * mVariable
Definition: token.h:92
std::set< TemplateSimplifier::TokenAndName * > * mTemplateSimplifierPointers
Definition: token.h:111
CppcheckAttributes * mCppcheckAttributes
Definition: token.h:122
const ::Type * mType
Definition: token.h:93
const Scope * mScope
Definition: token.h:89
Token * mAstOperand2
Definition: token.h:85
std::shared_ptr< ScopeInfo2 > mScopeInfo
Definition: token.h:114
TokenDebug mDebug
Definition: token.h:127
void setCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint value)
Definition: token.cpp:2682
nonneg int mIndex
Token index.
Definition: token.h:78
enum TokenImpl::Cpp11init mCpp11init
bool getCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint &value) const
Definition: token.cpp:2698
nonneg int mColumn
Definition: token.h:66
TokenImpl()
Definition: token.h:132
Token * mAstParent
Definition: token.h:86
static stringifyOptions forDebugExprId()
Definition: token.h:959
static stringifyOptions forDebugVarId()
Definition: token.h:954
static stringifyOptions forPrintOut()
Definition: token.h:964
static stringifyOptions forDebug()
Definition: token.h:944
This struct stores pointers to the front and back tokens of the list this token is in.
Definition: tokenlist.h:46
TokenDebug
Definition: token.h:60
static UNUSED void unused()
static bool isPrefixStringCharLiteral(const std::string &str, char q, const std::string &p)
Definition: utils.h:126