Cppcheck
symboldatabase.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 symboldatabaseH
21 #define symboldatabaseH
22 //---------------------------------------------------------------------------
23 
24 #include "config.h"
25 #include "errortypes.h"
26 #include "library.h"
27 #include "mathlib.h"
28 #include "sourcelocation.h"
29 #include "token.h"
30 #include "utils.h"
31 
32 #include <algorithm>
33 #include <cctype>
34 #include <iosfwd>
35 #include <list>
36 #include <map>
37 #include <set>
38 #include <string>
39 #include <utility>
40 #include <vector>
41 
42 class Platform;
43 class ErrorLogger;
44 class Function;
45 class Scope;
46 class Settings;
47 class SymbolDatabase;
48 class Tokenizer;
49 class ValueType;
50 
51 /**
52  * @brief Access control enumerations.
53  */
55 
56 /**
57  * @brief Array dimension information.
58  */
59 struct Dimension {
60  const Token* tok{}; ///< size token
61  MathLib::bigint num{}; ///< (assumed) dimension length when size is a number, 0 if not known
62  bool known = true; ///< Known size
63 };
64 
65 /** @brief Information about a class type. */
67 public:
68  const Token* classDef; ///< Points to "class" token
69  const Scope* classScope;
71  enum class NeedInitialization {
72  Unknown, True, False
73  } needInitialization = NeedInitialization::Unknown;
74 
75  struct BaseInfo {
76  std::string name;
77  const Type* type{};
78  const Token* nameTok{};
79  AccessControl access{}; // public/protected/private
80  bool isVirtual{};
81  // allow ordering within containers
82  bool operator<(const BaseInfo& rhs) const {
83  return this->type < rhs.type;
84  }
85  };
86 
87  struct FriendInfo {
88  const Token* nameStart{};
89  const Token* nameEnd{};
90  const Type* type{};
91  };
92 
93  std::vector<BaseInfo> derivedFrom;
94  std::vector<FriendInfo> friendList;
95 
96  const Token* typeStart{};
97  const Token* typeEnd{};
98  MathLib::bigint sizeOf{};
99 
100  explicit Type(const Token* classDef_ = nullptr, const Scope* classScope_ = nullptr, const Scope* enclosingScope_ = nullptr) :
101  classDef(classDef_),
102  classScope(classScope_),
103  enclosingScope(enclosingScope_) {
104  if (classDef_ && classDef_->str() == "enum")
105  needInitialization = NeedInitialization::True;
106  else if (classDef_ && classDef_->str() == "using") {
107  typeStart = classDef->tokAt(3);
108  typeEnd = typeStart;
109  while (typeEnd->next() && typeEnd->next()->str() != ";") {
110  if (Token::simpleMatch(typeEnd, "decltype ("))
111  typeEnd = typeEnd->linkAt(1);
112  else
113  typeEnd = typeEnd->next();
114  }
115  }
116  }
117 
118  std::string name() const;
119 
120  const std::string& type() const {
121  return classDef ? classDef->str() : emptyString;
122  }
123 
124  bool isClassType() const;
125  bool isEnumType() const;
126  bool isStructType() const;
127  bool isUnionType() const;
128 
129  bool isTypeAlias() const {
130  return classDef && classDef->str() == "using";
131  }
132 
133  const Token *initBaseInfo(const Token *tok, const Token *tok1);
134 
135  const Function* getFunction(const std::string& funcName) const;
136 
137  /**
138  * Check for circulare dependencies, i.e. loops within the class hierarchy
139  * @param ancestors list of ancestors. For internal usage only, clients should not supply this argument.
140  * @return true if there is a circular dependency
141  */
142  bool hasCircularDependencies(std::set<BaseInfo>* ancestors = nullptr) const;
143 
144  /**
145  * Check for dependency
146  * @param ancestor potential ancestor
147  * @return true if there is a dependency
148  */
149  bool findDependency(const Type* ancestor) const;
150 
151  bool isDerivedFrom(const std::string & ancestor) const;
152 };
153 
155  explicit Enumerator(const Scope * scope_) : scope(scope_) {}
156  const Scope * scope;
157  const Token* name{};
159  const Token* start{};
160  const Token* end{};
161  bool value_known{};
162 };
163 
164 /** @brief Information about a member variable. */
166  /** @brief flags mask used to access specific bit. */
167  enum {
168  fIsMutable = (1 << 0), /** @brief mutable variable */
169  fIsStatic = (1 << 1), /** @brief static variable */
170  fIsConst = (1 << 2), /** @brief const variable */
171  fIsExtern = (1 << 3), /** @brief extern variable */
172  fIsClass = (1 << 4), /** @brief user defined type */
173  fIsArray = (1 << 5), /** @brief array variable */
174  fIsPointer = (1 << 6), /** @brief pointer variable */
175  fIsReference = (1 << 7), /** @brief reference variable */
176  fIsRValueRef = (1 << 8), /** @brief rvalue reference variable */
177  fHasDefault = (1 << 9), /** @brief function argument with default value */
178  fIsStlType = (1 << 10), /** @brief STL type ('std::') */
179  fIsStlString = (1 << 11), /** @brief std::string|wstring|basic_string&lt;T&gt;|u16string|u32string */
180  fIsFloatType = (1 << 12), /** @brief Floating point type */
181  fIsVolatile = (1 << 13), /** @brief volatile */
182  fIsSmartPointer = (1 << 14),/** @brief std::shared_ptr|unique_ptr */
183  fIsMaybeUnused = (1 << 15), /** @brief marked [[maybe_unused]] */
184  fIsInit = (1 << 16), /** @brief Is variable initialized in declaration */
185  };
186 
187  /**
188  * Get specified flag state.
189  * @param flag_ flag to get state of
190  * @return true if flag set or false in flag not set
191  */
192  bool getFlag(unsigned int flag_) const {
193  return ((mFlags & flag_) != 0);
194  }
195 
196  /**
197  * Set specified flag state.
198  * @param flag_ flag to set state
199  * @param state_ new state of flag
200  */
201  void setFlag(unsigned int flag_, bool state_) {
202  mFlags = state_ ? mFlags | flag_ : mFlags & ~flag_;
203  }
204 
205  /**
206  * @brief parse and save array dimension information
207  * @param settings Platform settings and library
208  * @param isContainer Is the array container-like?
209  * @return true if array, false if not
210  */
211  bool arrayDimensions(const Settings& settings, bool& isContainer);
212 
213 public:
214  Variable(const Token *name_, const Token *start_, const Token *end_,
215  nonneg int index_, AccessControl access_, const Type *type_,
216  const Scope *scope_, const Settings& settings)
217  : mNameToken(name_),
218  mTypeStartToken(start_),
219  mTypeEndToken(end_),
220  mIndex(index_),
221  mAccess(access_),
222  mFlags(0),
223  mType(type_),
224  mScope(scope_) {
225  evaluate(settings);
226  }
227 
228  Variable(const Token *name_, const std::string &clangType, const Token *typeStart,
229  const Token *typeEnd, nonneg int index_, AccessControl access_,
230  const Type *type_, const Scope *scope_);
231 
232  Variable(const Variable &var, const Scope *scope);
233 
234  Variable(const Variable &var);
235 
236  ~Variable();
237 
238  Variable &operator=(const Variable &var);
239 
240  /**
241  * Get name token.
242  * @return name token
243  */
244  const Token *nameToken() const {
245  return mNameToken;
246  }
247 
248  /**
249  * Get type start token.
250  * The type start token doesn't account 'static' and 'const' qualifiers
251  * E.g.:
252  * static const int * const p = ...;
253  * type start token ^
254  * @return type start token
255  */
256  const Token *typeStartToken() const {
257  return mTypeStartToken;
258  }
259 
260  /**
261  * Get type end token.
262  * The type end token doesn't account the forward 'const' qualifier
263  * E.g.:
264  * static const int * const p = ...;
265  * type end token ^
266  * @return type end token
267  */
268  const Token *typeEndToken() const {
269  return mTypeEndToken;
270  }
271 
272  /**
273  * Get end token of variable declaration
274  * E.g.
275  * int i[2][3] = ...
276  * end token ^
277  * @return variable declaration end token
278  */
279  const Token *declEndToken() const;
280 
281  /**
282  * Get name string.
283  * @return name string
284  */
285  const std::string &name() const {
286  // name may not exist for function arguments
287  if (mNameToken)
288  return mNameToken->str();
289 
290  return emptyString;
291  }
292 
293  /**
294  * Get declaration ID (varId used for variable in its declaration).
295  * @return declaration ID
296  */
297  nonneg int declarationId() const {
298  // name may not exist for function arguments
299  if (mNameToken)
300  return mNameToken->varId();
301 
302  return 0;
303  }
304 
305  /**
306  * Get index of variable in declared order.
307  * @return variable index
308  */
309  nonneg int index() const {
310  return mIndex;
311  }
312 
313  /**
314  * Is variable public.
315  * @return true if public, false if not
316  */
317  bool isPublic() const {
318  return mAccess == AccessControl::Public;
319  }
320 
321  /**
322  * Is variable protected.
323  * @return true if protected, false if not
324  */
325  bool isProtected() const {
326  return mAccess == AccessControl::Protected;
327  }
328 
329  /**
330  * Is variable private.
331  * @return true if private, false if not
332  */
333  bool isPrivate() const {
334  return mAccess == AccessControl::Private;
335  }
336 
337  /**
338  * Is variable global.
339  * @return true if global, false if not
340  */
341  bool isGlobal() const {
342  return mAccess == AccessControl::Global;
343  }
344 
345  /**
346  * Is variable in a namespace.
347  * @return true if in a namespace, false if not
348  */
349  // cppcheck-suppress unusedFunction
350  bool isNamespace() const {
351  return mAccess == AccessControl::Namespace;
352  }
353 
354  /**
355  * Is variable a function argument.
356  * @return true if a function argument, false if not
357  */
358  bool isArgument() const {
359  return mAccess == AccessControl::Argument;
360  }
361 
362  /**
363  * Is variable local.
364  * @return true if local, false if not
365  */
366  bool isLocal() const {
367  return (mAccess == AccessControl::Local) && !isExtern();
368  }
369 
370  /**
371  * Is variable a member of a user-defined type.
372  * @return true if member, false if not or unknown
373  */
374  bool isMember() const;
375 
376  /**
377  * Is variable mutable.
378  * @return true if mutable, false if not
379  */
380  bool isMutable() const {
381  return getFlag(fIsMutable);
382  }
383 
384  /**
385  * Is variable volatile.
386  * @return true if volatile, false if not
387  */
388  bool isVolatile() const {
389  return getFlag(fIsVolatile);
390  }
391 
392  /**
393  * Is variable static.
394  * @return true if static, false if not
395  */
396  bool isStatic() const {
397  return getFlag(fIsStatic);
398  }
399 
400  /**
401  * Is variable extern.
402  * @return true if extern, false if not
403  */
404  bool isExtern() const {
405  return getFlag(fIsExtern);
406  }
407 
408  /**
409  * Is variable const.
410  * @return true if const, false if not
411  */
412  bool isConst() const {
413  return getFlag(fIsConst);
414  }
415 
416  /**
417  * Is variable a throw type.
418  * @return true if throw type, false if not
419  */
420  bool isThrow() const {
421  return mAccess == AccessControl::Throw;
422  }
423 
424  /**
425  * Is variable a user defined (or unknown) type.
426  * @return true if user defined type, false if not
427  */
428  bool isClass() const {
429  return getFlag(fIsClass);
430  }
431 
432  /**
433  * Is variable an array.
434  * @return true if array, false if not
435  */
436  bool isArray() const {
437  return getFlag(fIsArray) && !getFlag(fIsPointer);
438  }
439 
440  /**
441  * Is pointer variable.
442  * @return true if pointer, false otherwise
443  */
444  bool isPointer() const {
445  return getFlag(fIsPointer);
446  }
447 
448  /**
449  * Is variable a pointer to an array
450  * @return true if pointer to array, false otherwise
451  */
452  bool isPointerToArray() const {
453  return isPointer() && getFlag(fIsArray);
454  }
455 
456  /**
457  * Is variable an array of pointers
458  * @return true if array or pointers, false otherwise
459  */
460  bool isPointerArray() const;
461 
462  /**
463  * Is array or pointer variable.
464  * @return true if pointer or array, false otherwise
465  */
466  bool isArrayOrPointer() const {
467  return getFlag(fIsArray) || getFlag(fIsPointer);
468  }
469 
470  /**
471  * Is reference variable.
472  * @return true if reference, false otherwise
473  */
474  bool isReference() const {
475  return getFlag(fIsReference);
476  }
477 
478  /**
479  * Is reference variable.
480  * @return true if reference, false otherwise
481  */
482  bool isRValueReference() const {
483  return getFlag(fIsRValueRef);
484  }
485 
486  /**
487  * Is variable unsigned.
488  * @return true only if variable _is_ unsigned. if the sign is unknown, false is returned.
489  */
490  bool isUnsigned() const;
491 
492  /**
493  * Does variable have a default value.
494  * @return true if has a default falue, false if not
495  */
496  bool hasDefault() const {
497  return getFlag(fHasDefault);
498  }
499 
500  /**
501  * Is variable initialized in its declaration
502  * @return true if variable declaration contains initialization
503  */
504  bool isInit() const {
505  return getFlag(fIsInit);
506  }
507 
508  /**
509  * Get Type pointer of known type.
510  * @return pointer to type if known, NULL if not known
511  */
512  const Type *type() const {
513  return mType;
514  }
515 
516  /**
517  * Get Scope pointer of known type.
518  * @return pointer to type scope if known, NULL if not known
519  */
520  const Scope *typeScope() const {
521  return mType ? mType->classScope : nullptr;
522  }
523 
524  /**
525  * Get Scope pointer of enclosing scope.
526  * @return pointer to enclosing scope
527  */
528  const Scope *scope() const {
529  return mScope;
530  }
531 
532  /**
533  * Get array dimensions.
534  * @return array dimensions vector
535  */
536  const std::vector<Dimension> &dimensions() const {
537  return mDimensions;
538  }
539 
540  /**
541  * Get array dimension length.
542  * @return length of dimension
543  */
544  MathLib::bigint dimension(nonneg int index_) const {
545  return mDimensions.at(index_).num;
546  }
547 
548  /**
549  * Get array dimension known.
550  * @return length of dimension known
551  */
552  bool dimensionKnown(nonneg int index_) const {
553  return mDimensions.at(index_).known;
554  }
555 
556  void setDimensions(const std::vector<Dimension> &dimensions_) {
557  mDimensions = dimensions_;
558  }
559 
560  /**
561  * Checks if the variable is an STL type ('std::')
562  * E.g.:
563  * std::string s;
564  * ...
565  * sVar->isStlType() == true
566  * @return true if it is an stl type and its type matches any of the types in 'stlTypes'
567  */
568  bool isStlType() const {
569  return getFlag(fIsStlType);
570  }
571 
572  /**
573  * Checks if the variable is an STL type ('std::')
574  * E.g.:
575  * std::string s;
576  * ...
577  * sVar->isStlType() == true
578  * @return true if it is an stl type and its type matches any of the types in 'stlTypes'
579  */
580  bool isStlStringType() const {
581  return getFlag(fIsStlString);
582  }
583 
584  bool isStlStringViewType() const;
585 
586  bool isSmartPointer() const {
587  return getFlag(fIsSmartPointer);
588  }
589 
590  const Type* smartPointerType() const;
591  const Type* iteratorType() const;
592 
593  /**
594  * Checks if the variable is of any of the STL types passed as arguments ('std::')
595  * E.g.:
596  * std::string s;
597  * ...
598  * const char *str[] = {"string", "wstring"};
599  * sVar->isStlType(str) == true
600  * @param stlType stl type
601  * @return true if it is an stl type and its type matches any of the types in 'stlTypes'
602  */
603  bool isStlType(const std::string& stlType) const {
604  return isStlType() && stlType==mTypeStartToken->strAt(2);
605  }
606 
607  /**
608  * Checks if the variable is of any of the STL types passed as arguments ('std::')
609  * E.g.:
610  * std::string s;
611  * ...
612  * const std::set<std::string> str = make_container< std::set<std::string> >() << "string" << "wstring";
613  * sVar->isStlType(str) == true
614  * @param stlTypes set of stl types
615  * @return true if it is an stl type and its type matches any of the types in 'stlTypes'
616  */
617  bool isStlType(const std::set<std::string>& stlTypes) const {
618  return isStlType() && stlTypes.find(mTypeStartToken->strAt(2))!=stlTypes.end();
619  }
620 
621  /**
622  * Determine whether it's a floating number type
623  * @return true if the type is known and it's a floating type (float, double and long double) or a pointer/array to it
624  */
625  bool isFloatingType() const {
626  return getFlag(fIsFloatType);
627  }
628 
629  /**
630  * Determine whether it's an enumeration type
631  * @return true if the type is known and it's an enumeration type
632  */
633  bool isEnumType() const {
634  return type() && type()->isEnumType();
635  }
636 
637  bool isMaybeUnused() const {
638  return getFlag(fIsMaybeUnused);
639  }
640 
641  const ValueType *valueType() const {
642  return mValueType;
643  }
644 
645  void setValueType(const ValueType &valueType);
646 
648  return mAccess;
649  }
650 
651  std::string getTypeName() const;
652 
653 private:
654  // only symbol database can change the type
655  friend class SymbolDatabase;
656 
657  /**
658  * Set Type pointer to known type.
659  * @param t type
660  */
661  void type(const Type * t) {
662  mType = t;
663  }
664 
665  /** @brief variable name token */
667 
668  /** @brief variable type start token */
670 
671  /** @brief variable type end token */
673 
674  /** @brief order declared */
676 
677  /** @brief what section is this variable declared in? */
678  AccessControl mAccess; // public/protected/private
679 
680  /** @brief flags */
681  unsigned int mFlags;
682 
683  /** @brief pointer to user defined type info (for known types) */
684  const Type *mType;
685 
686  /** @brief pointer to scope this variable is in */
687  const Scope *mScope;
688 
689  const ValueType* mValueType{};
690 
691  /** @brief array dimensions */
692  std::vector<Dimension> mDimensions;
693 
694  /** @brief fill in information, depending on Tokens given at instantiation */
695  void evaluate(const Settings& settings);
696 };
697 
699  // only symbol database can change this
700  friend class SymbolDatabase;
701 
702  /** @brief flags mask used to access specific bit. */
703  enum {
704  fHasBody = (1 << 0), ///< @brief has implementation
705  fIsInline = (1 << 1), ///< @brief implementation in class definition
706  fIsConst = (1 << 2), ///< @brief is const
707  fHasVirtualSpecifier = (1 << 3), ///< @brief does declaration contain 'virtual' specifier
708  fIsPure = (1 << 4), ///< @brief is pure virtual
709  fIsStatic = (1 << 5), ///< @brief is static
710  fIsStaticLocal = (1 << 6), ///< @brief is static local
711  fIsExtern = (1 << 7), ///< @brief is extern
712  fIsFriend = (1 << 8), ///< @brief is friend
713  fIsExplicit = (1 << 9), ///< @brief is explicit
714  fIsDefault = (1 << 10), ///< @brief is default
715  fIsDelete = (1 << 11), ///< @brief is delete
716  fHasOverrideSpecifier = (1 << 12), ///< @brief does declaration contain 'override' specifier?
717  fHasFinalSpecifier = (1 << 13), ///< @brief does declaration contain 'final' specifier?
718  fIsNoExcept = (1 << 14), ///< @brief is noexcept
719  fIsThrow = (1 << 15), ///< @brief is throw
720  fIsOperator = (1 << 16), ///< @brief is operator
721  fHasLvalRefQual = (1 << 17), ///< @brief has & lvalue ref-qualifier
722  fHasRvalRefQual = (1 << 18), ///< @brief has && rvalue ref-qualifier
723  fIsVariadic = (1 << 19), ///< @brief is variadic
724  fIsVolatile = (1 << 20), ///< @brief is volatile
725  fHasTrailingReturnType = (1 << 21), ///< @brief has trailing return type
726  fIsEscapeFunction = (1 << 22), ///< @brief Function throws or exits
727  fIsInlineKeyword = (1 << 23), ///< @brief Function has "inline" keyword
728  fIsConstexpr = (1 << 24), ///< @brief is constexpr
729  };
730 
731  /**
732  * Get specified flag state.
733  * @param flag flag to get state of
734  * @return true if flag set or false in flag not set
735  */
736  bool getFlag(unsigned int flag) const {
737  return ((mFlags & flag) != 0);
738  }
739 
740  /**
741  * Set specified flag state.
742  * @param flag flag to set state
743  * @param state new state of flag
744  */
745  void setFlag(unsigned int flag, bool state) {
746  mFlags = state ? mFlags | flag : mFlags & ~flag;
747  }
748 
749 public:
750  enum Type { eConstructor, eCopyConstructor, eMoveConstructor, eOperatorEqual, eDestructor, eFunction, eLambda };
751 
752  Function(const Token *tok, const Scope *scope, const Token *tokDef, const Token *tokArgDef);
753  Function(const Token *tokenDef, const std::string &clangType);
754 
755  const std::string &name() const {
756  return tokenDef->str();
757  }
758 
759  std::string fullName() const;
760 
761  nonneg int argCount() const {
762  return argumentList.size();
763  }
764  nonneg int minArgCount() const {
765  return argumentList.size() - initArgCount;
766  }
767  const Variable* getArgumentVar(nonneg int num) const;
769  return initArgCount;
770  }
771  void addArguments(const SymbolDatabase *symbolDatabase, const Scope *scope);
772 
773  /** @brief check if this function is virtual in the base classes */
774  bool isImplicitlyVirtual(bool defaultVal = false) const;
775 
776  std::vector<const Function*> getOverloadedFunctions() const;
777 
778  /** @brief get function in base class that is overridden */
779  const Function *getOverriddenFunction(bool *foundAllBaseClasses = nullptr) const;
780 
781  bool isLambda() const {
782  return type==eLambda;
783  }
784 
785  bool isConstructor() const {
786  return type==eConstructor ||
787  type==eCopyConstructor ||
788  type==eMoveConstructor;
789  }
790 
791  bool isDestructor() const {
792  return type==eDestructor;
793  }
794  bool isAttributeConstructor() const {
795  return tokenDef->isAttributeConstructor();
796  }
797  bool isAttributeDestructor() const {
798  return tokenDef->isAttributeDestructor();
799  }
800  bool isAttributePure() const {
801  return tokenDef->isAttributePure();
802  }
803  bool isAttributeConst() const {
804  return tokenDef->isAttributeConst();
805  }
806  bool isAttributeNoreturn() const {
807  return tokenDef->isAttributeNoreturn();
808  }
809  bool isAttributeNothrow() const {
810  return tokenDef->isAttributeNothrow();
811  }
812  bool isAttributeNodiscard() const {
813  return tokenDef->isAttributeNodiscard();
814  }
815 
816  bool hasBody() const {
817  return getFlag(fHasBody);
818  }
819  bool isInline() const {
820  return getFlag(fIsInline);
821  }
822  bool isConst() const {
823  return getFlag(fIsConst);
824  }
825  bool hasVirtualSpecifier() const {
826  return getFlag(fHasVirtualSpecifier);
827  }
828  bool isPure() const {
829  return getFlag(fIsPure);
830  }
831  bool isStatic() const {
832  return getFlag(fIsStatic);
833  }
834  bool isStaticLocal() const {
835  return getFlag(fIsStaticLocal);
836  }
837  bool isExtern() const {
838  return getFlag(fIsExtern);
839  }
840  bool isFriend() const {
841  return getFlag(fIsFriend);
842  }
843  bool isExplicit() const {
844  return getFlag(fIsExplicit);
845  }
846  bool isDefault() const {
847  return getFlag(fIsDefault);
848  }
849  bool isDelete() const {
850  return getFlag(fIsDelete);
851  }
852  bool isNoExcept() const {
853  return getFlag(fIsNoExcept);
854  }
855  bool isThrow() const {
856  return getFlag(fIsThrow);
857  }
858  bool hasOverrideSpecifier() const {
859  return getFlag(fHasOverrideSpecifier);
860  }
861  bool hasFinalSpecifier() const {
862  return getFlag(fHasFinalSpecifier);
863  }
864  bool isOperator() const {
865  return getFlag(fIsOperator);
866  }
867  bool hasLvalRefQualifier() const {
868  return getFlag(fHasLvalRefQual);
869  }
870  bool hasRvalRefQualifier() const {
871  return getFlag(fHasRvalRefQual);
872  }
873  bool isVariadic() const {
874  return getFlag(fIsVariadic);
875  }
876  bool isVolatile() const {
877  return getFlag(fIsVolatile);
878  }
879  bool hasTrailingReturnType() const {
880  return getFlag(fHasTrailingReturnType);
881  }
882  void hasBody(bool state) {
883  setFlag(fHasBody, state);
884  }
885  bool isInlineKeyword() const {
886  return getFlag(fIsInlineKeyword);
887  }
888 
889  bool isEscapeFunction() const {
890  return getFlag(fIsEscapeFunction);
891  }
892  void isEscapeFunction(bool state) {
893  setFlag(fIsEscapeFunction, state);
894  }
895 
896  bool isConstexpr() const {
897  return getFlag(fIsConstexpr);
898  }
899  void isConstexpr(bool state) {
900  setFlag(fIsConstexpr, state);
901  }
902  bool isSafe(const Settings &settings) const;
903 
904  const Token* tokenDef{}; ///< function name token in class definition
905  const Token* argDef{}; ///< function argument start '(' in class definition
906  const Token* token{}; ///< function name token in implementation
907  const Token* arg{}; ///< function argument start '('
908  const Token* retDef{}; ///< function return type token
909  const ::Type* retType{}; ///< function return type
910  const Scope* functionScope{}; ///< scope of function body
911  const Scope* nestedIn{}; ///< Scope the function is declared in
912  std::list<Variable> argumentList; ///< argument list, must remain list due to clangimport usage!
913  nonneg int initArgCount{}; ///< number of args with default values
914  Type type = eFunction; ///< constructor, destructor, ...
915  const Token* noexceptArg{}; ///< noexcept token
916  const Token* throwArg{}; ///< throw token
917  const Token* templateDef{}; ///< points to 'template <' before function
918  const Token* functionPointerUsage{}; ///< function pointer usage
919  AccessControl access{}; ///< public/protected/private
920 
921  bool argsMatch(const Scope *scope, const Token *first, const Token *second, const std::string &path, nonneg int path_length) const;
922 
923  static bool returnsConst(const Function* function, bool unknown = false);
924 
925  static bool returnsPointer(const Function* function, bool unknown = false);
926  static bool returnsReference(const Function* function, bool unknown = false, bool includeRValueRef = false);
927  static bool returnsStandardType(const Function* function, bool unknown = false);
928 
929  static bool returnsVoid(const Function* function, bool unknown = false);
930 
931  static std::vector<const Token*> findReturns(const Function* f);
932 
933  const Token* returnDefEnd() const {
934  if (this->hasTrailingReturnType())
935  return Token::findmatch(retDef, "{|;");
936  return tokenDef;
937  }
938 
939  /**
940  * @return token to ":" if the function is a constructor
941  * and it contains member initialization otherwise a nullptr is returned
942  */
943  const Token * constructorMemberInitialization() const;
944 
945 private:
946  /** Recursively determine if this function overrides a virtual function in a base class */
947  const Function * getOverriddenFunctionRecursive(const ::Type* baseType, bool *foundAllBaseClasses) const;
948 
949  unsigned int mFlags{};
950 
951  void isInline(bool state) {
952  setFlag(fIsInline, state);
953  }
954  void isConst(bool state) {
955  setFlag(fIsConst, state);
956  }
957  void hasVirtualSpecifier(bool state) {
958  setFlag(fHasVirtualSpecifier, state);
959  }
960  void isPure(bool state) {
961  setFlag(fIsPure, state);
962  }
963  void isStatic(bool state) {
964  setFlag(fIsStatic, state);
965  }
966  void isStaticLocal(bool state) {
967  setFlag(fIsStaticLocal, state);
968  }
969  void isExtern(bool state) {
970  setFlag(fIsExtern, state);
971  }
972  void isFriend(bool state) {
973  setFlag(fIsFriend, state);
974  }
975  void isExplicit(bool state) {
976  setFlag(fIsExplicit, state);
977  }
978  void isDefault(bool state) {
979  setFlag(fIsDefault, state);
980  }
981  void isDelete(bool state) {
982  setFlag(fIsDelete, state);
983  }
984  void isNoExcept(bool state) {
985  setFlag(fIsNoExcept, state);
986  }
987  void isThrow(bool state) {
988  setFlag(fIsThrow, state);
989  }
990  void isOperator(bool state) {
991  setFlag(fIsOperator, state);
992  }
993  void hasLvalRefQualifier(bool state) {
994  setFlag(fHasLvalRefQual, state);
995  }
996  void hasRvalRefQualifier(bool state) {
997  setFlag(fHasRvalRefQual, state);
998  }
999  void isVariadic(bool state) {
1000  setFlag(fIsVariadic, state);
1001  }
1002  void isVolatile(bool state) {
1003  setFlag(fIsVolatile, state);
1004  }
1005  void hasTrailingReturnType(bool state) {
1006  setFlag(fHasTrailingReturnType, state);
1007  }
1008  void isInlineKeyword(bool state) {
1009  setFlag(fIsInlineKeyword, state);
1010  }
1011  const Token *setFlags(const Token *tok1, const Scope *scope);
1012 };
1013 
1015  // let tests access private function for testing
1016  friend class TestSymbolDatabase;
1017 
1018 public:
1019  struct UsingInfo {
1020  const Token *start;
1021  const Scope *scope;
1022  };
1023 
1024  enum ScopeType { eGlobal, eClass, eStruct, eUnion, eNamespace, eFunction, eIf, eElse, eFor, eWhile, eDo, eSwitch, eUnconditional, eTry, eCatch, eLambda, eEnum };
1025 
1026  Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope *nestedIn_);
1027  Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope *nestedIn_, ScopeType type_, const Token *start_);
1028 
1029  const SymbolDatabase* check{};
1030  std::string className;
1031  const Token* classDef{}; ///< class/struct/union/namespace token
1032  const Token* bodyStart{}; ///< '{' token
1033  const Token* bodyEnd{}; ///< '}' token
1034  std::list<Function> functionList;
1035  std::multimap<std::string, const Function *> functionMap;
1036  std::list<Variable> varlist;
1037  const Scope* nestedIn{};
1038  std::vector<Scope *> nestedList;
1039  nonneg int numConstructors{};
1040  nonneg int numCopyOrMoveConstructors{};
1041  std::vector<UsingInfo> usingList;
1042  ScopeType type{};
1043  Type* definedType{};
1044  std::map<std::string, Type*> definedTypesMap;
1045  std::vector<const Token *> bodyStartList;
1046 
1047  // function specific fields
1048  const Scope* functionOf{}; ///< scope this function belongs to
1049  Function* function{}; ///< function info for this function
1050 
1051  // enum specific fields
1052  const Token* enumType{};
1053  bool enumClass{};
1054 
1055  std::vector<Enumerator> enumeratorList;
1056 
1057  void setBodyStartEnd(const Token *start) {
1058  bodyStart = start;
1059  bodyEnd = start ? start->link() : nullptr;
1060  if (start)
1061  bodyStartList.push_back(start);
1062  }
1063 
1064  bool isAnonymous() const {
1065  // TODO: Check if class/struct is anonymous
1066  return className.size() > 9 && startsWith(className,"Anonymous") && std::isdigit(className[9]);
1067  }
1068 
1069  const Enumerator * findEnumerator(const std::string & name) const {
1070  auto it = std::find_if(enumeratorList.cbegin(), enumeratorList.cend(), [&](const Enumerator& i) {
1071  return i.name->str() == name;
1072  });
1073  return it == enumeratorList.end() ? nullptr : &*it;
1074  }
1075 
1076  bool isNestedIn(const Scope * outer) const {
1077  if (!outer)
1078  return false;
1079  if (outer == this)
1080  return true;
1081  const Scope * parent = nestedIn;
1082  while (outer != parent && parent)
1083  parent = parent->nestedIn;
1084  return parent && parent == outer;
1085  }
1086 
1087  static Function* nestedInFunction(const Scope* scope) {
1088  while (scope) {
1089  if (scope->type == Scope::eFunction)
1090  break;
1091  scope = scope->nestedIn;
1092  }
1093  if (!scope)
1094  return nullptr;
1095  return scope->function;
1096  }
1097 
1098  bool isClassOrStruct() const {
1099  return (type == eClass || type == eStruct);
1100  }
1101 
1102  bool isClassOrStructOrUnion() const {
1103  return (type == eClass || type == eStruct || type == eUnion);
1104  }
1105 
1106  bool isExecutable() const {
1107  return type != eClass && type != eStruct && type != eUnion && type != eGlobal && type != eNamespace && type != eEnum;
1108  }
1109 
1110  bool isLoopScope() const {
1111  return type == Scope::ScopeType::eFor || type == Scope::ScopeType::eWhile || type == Scope::ScopeType::eDo;
1112  }
1113 
1114  bool isLocal() const {
1115  return (type == eIf || type == eElse ||
1116  type == eFor || type == eWhile || type == eDo ||
1117  type == eSwitch || type == eUnconditional ||
1118  type == eTry || type == eCatch);
1119  }
1120 
1121  // Is there lambda/inline function(s) in this scope?
1122  bool hasInlineOrLambdaFunction() const;
1123 
1124  /**
1125  * @brief find a function
1126  * @param tok token of function call
1127  * @param requireConst if const refers to a const variable only const methods should be matched
1128  * @return pointer to function if found or NULL if not found
1129  */
1130  const Function *findFunction(const Token *tok, bool requireConst=false) const;
1131 
1132  const Scope *findRecordInNestedList(const std::string & name, bool isC = false) const;
1133  Scope *findRecordInNestedList(const std::string & name, bool isC = false);
1134 
1135  const Type* findType(const std::string& name) const;
1136  Type* findType(const std::string& name);
1137 
1138  /**
1139  * @brief find if name is in nested list
1140  * @param name name of nested scope
1141  */
1142  Scope *findInNestedListRecursive(const std::string & name);
1143 
1144  void addVariable(const Token *token_, const Token *start_,
1145  const Token *end_, AccessControl access_, const Type *type_,
1146  const Scope *scope_, const Settings& settings);
1147 
1148  /** @brief initialize varlist */
1149  void getVariableList(const Settings& settings);
1150 
1151  const Function *getDestructor() const;
1152 
1153  void addFunction(Function func) {
1154  functionList.push_back(std::move(func));
1155 
1156  const Function * back = &functionList.back();
1157 
1158  functionMap.insert(make_pair(back->tokenDef->str(), back));
1159  }
1160 
1161  AccessControl defaultAccess() const;
1162 
1163  /**
1164  * @brief check if statement is variable declaration and add it if it is
1165  * @param tok pointer to start of statement
1166  * @param varaccess access control of statement
1167  * @param settings Settings
1168  * @return pointer to last token
1169  */
1170  const Token *checkVariable(const Token *tok, AccessControl varaccess, const Settings& settings);
1171 
1172  /**
1173  * @brief get variable from name
1174  * @param varname name of variable
1175  * @return pointer to variable
1176  */
1177  const Variable *getVariable(const std::string &varname) const;
1178 
1179  const Token * addEnum(const Token * tok);
1180 
1181  const Scope *findRecordInBase(const std::string &name) const;
1182 
1183  std::vector<const Scope*> findAssociatedScopes() const;
1184 
1185 private:
1186  /**
1187  * @brief helper function for getVariableList()
1188  * @param tok pointer to token to check
1189  * @param vartok populated with pointer to the variable token, if found
1190  * @param typetok populated with pointer to the type token, if found
1191  * @return true if tok points to a variable declaration, false otherwise
1192  */
1193  bool isVariableDeclaration(const Token* const tok, const Token*& vartok, const Token*& typetok) const;
1194 
1195  void findFunctionInBase(const std::string & name, nonneg int args, std::vector<const Function *> & matches) const;
1196 
1197  /** @brief initialize varlist */
1198  void getVariableList(const Settings& settings, const Token *start, const Token *end);
1199 };
1200 
1201 enum class Reference {
1202  None,
1203  LValue,
1204  RValue
1205 };
1206 
1207 /** Value type */
1209 public:
1210  enum Sign { UNKNOWN_SIGN, SIGNED, UNSIGNED } sign = UNKNOWN_SIGN;
1211  enum Type {
1230  LONGDOUBLE
1231  } type = UNKNOWN_TYPE;
1232  nonneg int bits{}; ///< bitfield bitcount
1233  nonneg int pointer{}; ///< 0=>not pointer, 1=>*, 2=>**, 3=>***, etc
1234  nonneg int constness{}; ///< bit 0=data, bit 1=*, bit 2=**
1235  nonneg int volatileness{}; ///< bit 0=data, bit 1=*, bit 2=**
1236  Reference reference = Reference::None; ///< Is the outermost indirection of this type a reference or rvalue
1237  ///< reference or not? pointer=2, Reference=LValue would be a T**&
1238  const Scope* typeScope{}; ///< if the type definition is seen this point out the type scope
1239  const ::Type* smartPointerType{}; ///< Smart pointer type
1240  const Token* smartPointerTypeToken{}; ///< Smart pointer type token
1241  const Library::SmartPointer* smartPointer{}; ///< Smart pointer
1242  const Library::Container* container{}; ///< If the type is a container defined in a cfg file, this is the used
1243  ///< container
1244  const Token* containerTypeToken{}; ///< The container type token. the template argument token that defines the
1245  ///< container element type.
1246  std::string originalTypeName; ///< original type name as written in the source code. eg. this might be "uint8_t"
1247  ///< when type is CHAR.
1248  ErrorPath debugPath; ///< debug path to the type
1249 
1250  ValueType() = default;
1251  ValueType(Sign s, Type t, nonneg int p)
1252  : sign(s),
1253  type(t),
1254  pointer(p)
1255  {}
1256  ValueType(Sign s, Type t, nonneg int p, nonneg int c)
1257  : sign(s),
1258  type(t),
1259  pointer(p),
1260  constness(c)
1261  {}
1262  ValueType(Sign s, Type t, nonneg int p, nonneg int c, nonneg int v)
1263  : sign(s),
1264  type(t),
1265  pointer(p),
1266  constness(c),
1267  volatileness(v)
1268  {}
1269  ValueType(Sign s, Type t, nonneg int p, nonneg int c, std::string otn)
1270  : sign(s),
1271  type(t),
1272  pointer(p),
1273  constness(c),
1274  originalTypeName(std::move(otn))
1275  {}
1276 
1277  static ValueType parseDecl(const Token *type, const Settings &settings);
1278 
1279  static Type typeFromString(const std::string &typestr, bool longType);
1280 
1281  enum class MatchResult { UNKNOWN, SAME, FALLBACK1, FALLBACK2, NOMATCH };
1282  static MatchResult matchParameter(const ValueType *call, const ValueType *func);
1283  static MatchResult matchParameter(const ValueType *call, const Variable *callVar, const Variable *funcVar);
1284 
1285  bool isPrimitive() const {
1286  return (type >= ValueType::Type::BOOL);
1287  }
1288 
1289  bool isIntegral() const {
1290  return (type >= ValueType::Type::BOOL && type <= ValueType::Type::UNKNOWN_INT);
1291  }
1292 
1293  bool isFloat() const {
1294  return (type >= ValueType::Type::FLOAT && type <= ValueType::Type::LONGDOUBLE);
1295  }
1296 
1297  bool fromLibraryType(const std::string &typestr, const Settings &settings);
1298 
1299  bool isEnum() const {
1300  return typeScope && typeScope->type == Scope::eEnum;
1301  }
1302 
1303  bool isConst(nonneg int indirect = 0) const;
1304 
1305  bool isVolatile(nonneg int indirect = 0) const;
1306 
1307  MathLib::bigint typeSize(const Platform &platform, bool p=false) const;
1308 
1309  /// Check if type is the same ignoring const and references
1310  bool isTypeEqual(const ValueType* that) const;
1311 
1312  std::string str() const;
1313  std::string dump() const;
1314 
1315  void setDebugPath(const Token* tok, SourceLocation ctx, const SourceLocation &local = SourceLocation::current());
1316 };
1317 
1318 
1320  friend class TestSymbolDatabase;
1321 public:
1322  SymbolDatabase(Tokenizer& tokenizer, const Settings& settings, ErrorLogger& errorLogger);
1323  ~SymbolDatabase();
1324 
1325  /** @brief Information about all namespaces/classes/structures */
1326  std::list<Scope> scopeList;
1327 
1328  /** @brief Fast access to function scopes */
1329  std::vector<const Scope*> functionScopes;
1330 
1331  /** @brief Fast access to class and struct scopes */
1332  std::vector<const Scope*> classAndStructScopes;
1333 
1334  /** @brief Fast access to types */
1335  std::list<Type> typeList;
1336 
1337  /**
1338  * @brief find a variable type if it's a user defined type
1339  * @param start scope to start looking in
1340  * @param typeTok token containing variable type
1341  * @return pointer to type if found or NULL if not found
1342  */
1343  const Type* findVariableType(const Scope* start, const Token* typeTok) const;
1344 
1345  /**
1346  * @brief find a function
1347  * @param tok token of function call
1348  * @return pointer to function if found or NULL if not found
1349  */
1350  const Function* findFunction(const Token* tok) const;
1351 
1352  /** For unit testing only */
1353  const Scope* findScopeByName(const std::string& name) const;
1354 
1355  const Type* findType(const Token* startTok, const Scope* startScope, bool lookOutside = false) const;
1356  Type* findType(const Token* startTok, Scope* startScope, bool lookOutside = false)
1357  {
1358  return const_cast<Type*>(this->findType(startTok, const_cast<const Scope*>(startScope), lookOutside));
1359  }
1360 
1361  const Scope *findScope(const Token *tok, const Scope *startScope) const;
1362  Scope *findScope(const Token *tok, Scope *startScope) {
1363  return const_cast<Scope *>(this->findScope(tok, const_cast<const Scope *>(startScope)));
1364  }
1365 
1366  // cppcheck-suppress unusedFunction
1367  bool isVarId(nonneg int varid) const {
1368  return varid < mVariableList.size();
1369  }
1370 
1371  const Variable *getVariableFromVarId(nonneg int varId) const {
1372  return mVariableList.at(varId);
1373  }
1374 
1375  const std::vector<const Variable *> & variableList() const {
1376  return mVariableList;
1377  }
1378 
1379  /**
1380  * @brief output a debug message
1381  */
1382  void debugMessage(const Token *tok, const std::string &type, const std::string &msg) const;
1383 
1384  void returnImplicitIntError(const Token *tok) const;
1385 
1386  void printOut(const char * title = nullptr) const;
1387  void printVariable(const Variable *var, const char *indent) const;
1388  void printXml(std::ostream &out) const;
1389 
1390  /*
1391  * @brief Do a sanity check
1392  */
1393  void validate() const;
1394 
1395  /** Set valuetype in provided tokenlist */
1396  void setValueTypeInTokenList(bool reportDebugWarnings, Token *tokens=nullptr);
1397 
1398  /**
1399  * Calculates sizeof value for given type.
1400  * @param type Token which will contain e.g. "int", "*", or string.
1401  * @return sizeof for given type, or 0 if it can't be calculated.
1402  */
1403  nonneg int sizeOfType(const Token *type) const;
1404 
1405  /** Set array dimensions when valueflow analysis is completed */
1406  void setArrayDimensionsUsingValueFlow(); // cppcheck-suppress functionConst // has side effects
1407 
1408  void clangSetVariables(const std::vector<const Variable *> &variableList);
1409  void createSymbolDatabaseExprIds();
1410 
1411 private:
1412  friend class Scope;
1413  friend class Function;
1414 
1415  // Create symboldatabase...
1416  void createSymbolDatabaseFindAllScopes();
1417  void createSymbolDatabaseClassInfo();
1418  void createSymbolDatabaseVariableInfo();
1419  void createSymbolDatabaseCopyAndMoveConstructors();
1420  void createSymbolDatabaseFunctionScopes();
1421  void createSymbolDatabaseClassAndStructScopes();
1422  void createSymbolDatabaseFunctionReturnTypes();
1423  void createSymbolDatabaseNeedInitialization();
1424  void createSymbolDatabaseVariableSymbolTable();
1425  void createSymbolDatabaseSetScopePointers();
1426  void createSymbolDatabaseSetFunctionPointers(bool firstPass); // cppcheck-suppress functionConst // has side effects
1427  void createSymbolDatabaseSetVariablePointers();
1428  // cppcheck-suppress functionConst
1429  void createSymbolDatabaseSetTypePointers();
1430  void createSymbolDatabaseSetSmartPointerType();
1431  void createSymbolDatabaseEnums(); // cppcheck-suppress functionConst // has side effects
1432  void createSymbolDatabaseEscapeFunctions(); // cppcheck-suppress functionConst // has side effects
1433  // cppcheck-suppress functionConst
1434  void createSymbolDatabaseIncompleteVars();
1435 
1436  void debugSymbolDatabase() const;
1437 
1438  void addClassFunction(Scope *&scope, const Token *&tok, const Token *argStart);
1439  static Function *addGlobalFunctionDecl(Scope*& scope, const Token* tok, const Token *argStart, const Token* funcStart);
1440  Function *addGlobalFunction(Scope*& scope, const Token*& tok, const Token *argStart, const Token* funcStart);
1441  void addNewFunction(Scope *&scope, const Token *&tok);
1442  bool isFunction(const Token *tok, const Scope* outerScope, const Token *&funcStart, const Token *&argStart, const Token*& declEnd) const;
1443  const Type *findTypeInNested(const Token *startTok, const Scope *startScope) const;
1444  const Scope *findNamespace(const Token * tok, const Scope * scope) const;
1445  static Function *findFunctionInScope(const Token *func, const Scope *ns, const std::string & path, nonneg int path_length);
1446  static const Type *findVariableTypeInBase(const Scope *scope, const Token *typeTok);
1447 
1448  using MemberIdMap = std::map<unsigned int, unsigned int>;
1449  using VarIdMap = std::map<unsigned int, MemberIdMap>;
1450 
1451  void fixVarId(VarIdMap & varIds, const Token * vartok, Token * membertok, const Variable * membervar);
1452 
1453  /** Whether the token is a keyword as defined in http://en.cppreference.com/w/c/keyword and http://en.cppreference.com/w/cpp/keyword*/
1454  static bool isReservedName(const Token* tok);
1455 
1456  const Enumerator * findEnumerator(const Token * tok, std::set<std::string>& tokensThatAreNotEnumeratorValues) const;
1457 
1458  void setValueType(Token* tok, const ValueType& valuetype, const SourceLocation &loc = SourceLocation::current());
1459  void setValueType(Token* tok, const Variable& var, const SourceLocation &loc = SourceLocation::current());
1460  void setValueType(Token* tok, const Enumerator& enumerator, const SourceLocation &loc = SourceLocation::current());
1461 
1462  void validateExecutableScopes() const;
1463  /**
1464  * @brief Check variable list, e.g. variables w/o scope
1465  */
1466  void validateVariables() const;
1467 
1471 
1472  /** variable symbol table */
1473  std::vector<const Variable *> mVariableList;
1474 
1475  /** list for missing types */
1476  std::list<Type> mBlankTypes;
1477 
1479 };
1480 
1481 
1482 //---------------------------------------------------------------------------
1483 #endif // symboldatabaseH
static int sign(const T v)
This is an interface, which the class responsible of error logging should implement.
Definition: errorlogger.h:214
void isOperator(bool state)
void isDefault(bool state)
bool isInlineKeyword() const
bool isStatic() const
bool isAttributeConst() const
bool isAttributeNodiscard() const
const Token * returnDefEnd() const
bool getFlag(unsigned int flag) const
Get specified flag state.
nonneg int initializedArgCount() const
nonneg int minArgCount() const
bool hasFinalSpecifier() const
void isFriend(bool state)
const std::string & name() const
void hasRvalRefQualifier(bool state)
void isDelete(bool state)
bool isPure() const
void hasBody(bool state)
void hasLvalRefQualifier(bool state)
void isPure(bool state)
bool isAttributeConstructor() const
bool hasRvalRefQualifier() const
bool hasLvalRefQualifier() const
bool isVolatile() const
bool isInline() const
bool hasBody() const
void isInlineKeyword(bool state)
bool isThrow() const
bool isOperator() const
bool isConstexpr() const
bool isExplicit() const
bool isExtern() const
void isInline(bool state)
bool isLambda() const
bool isAttributeNoreturn() const
void hasTrailingReturnType(bool state)
nonneg int argCount() const
bool hasTrailingReturnType() const
bool isDefault() const
void hasVirtualSpecifier(bool state)
bool isVariadic() const
void isExplicit(bool state)
void isEscapeFunction(bool state)
void isExtern(bool state)
bool isEscapeFunction() const
void isNoExcept(bool state)
bool hasOverrideSpecifier() const
bool hasVirtualSpecifier() const
const Token * tokenDef
function name token in class definition
bool isDelete() const
void isVariadic(bool state)
bool isFriend() const
void isThrow(bool state)
bool isAttributeDestructor() const
std::list< Variable > argumentList
argument list, must remain list due to clangimport usage!
void setFlag(unsigned int flag, bool state)
Set specified flag state.
void isConstexpr(bool state)
bool isDestructor() const
bool isConstructor() const
bool isStaticLocal() const
bool isAttributeNothrow() const
void isStaticLocal(bool state)
void isVolatile(bool state)
bool isNoExcept() const
bool isConst() const
void isStatic(bool state)
void isConst(bool state)
bool isAttributePure() const
long long bigint
Definition: mathlib.h:68
Platform settings.
Definition: platform.h:43
std::list< Function > functionList
std::vector< UsingInfo > usingList
std::map< std::string, Type * > definedTypesMap
bool isNestedIn(const Scope *outer) const
std::list< Variable > varlist
std::multimap< std::string, const Function * > functionMap
std::vector< Scope * > nestedList
ScopeType type
static Function * nestedInFunction(const Scope *scope)
std::vector< Enumerator > enumeratorList
Function * function
function info for this function
bool isLoopScope() const
bool isAnonymous() const
std::vector< const Token * > bodyStartList
const Scope * nestedIn
bool isLocal() const
void setBodyStartEnd(const Token *start)
std::string className
const Enumerator * findEnumerator(const std::string &name) const
void addFunction(Function func)
bool isClassOrStructOrUnion() const
bool isExecutable() const
bool isClassOrStruct() const
This is just a container for general settings so that we don't need to pass individual values to func...
Definition: settings.h:95
const Variable * getVariableFromVarId(nonneg int varId) const
std::vector< const Variable * > mVariableList
variable symbol table
const std::vector< const Variable * > & variableList() const
const Settings & mSettings
Tokenizer & mTokenizer
std::list< Type > typeList
Fast access to types.
bool isVarId(nonneg int varid) const
std::map< unsigned int, MemberIdMap > VarIdMap
std::list< Type > mBlankTypes
list for missing types
ValueType::Sign mDefaultSignedness
friend class Function
std::vector< const Scope * > functionScopes
Fast access to function scopes.
std::map< unsigned int, unsigned int > MemberIdMap
std::list< Scope > scopeList
Information about all namespaces/classes/structures.
ErrorLogger & mErrorLogger
Scope * findScope(const Token *tok, Scope *startScope)
Type * findType(const Token *startTok, Scope *startScope, bool lookOutside=false)
std::vector< const Scope * > classAndStructScopes
Fast access to class and struct scopes.
The token list that the TokenList generates is a linked-list of this class.
Definition: token.h:150
void str(T &&s)
Definition: token.h:179
static const Token * findmatch(const Token *const startTok, const char pattern[], const nonneg int varId=0)
Definition: token.cpp:1099
const Token * tokAt(int index) const
Definition: token.cpp:427
void link(Token *linkToToken)
Create link to given token.
Definition: token.h:1015
const Token * linkAt(int index) const
Definition: token.cpp:447
Token * next()
Definition: token.h:830
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
The main purpose is to tokenize the source code.
Definition: tokenize.h:46
Information about a class type.
const Scope * enclosingScope
Type(const Token *classDef_=nullptr, const Scope *classScope_=nullptr, const Scope *enclosingScope_=nullptr)
NeedInitialization
bool isTypeAlias() const
const Token * classDef
Points to "class" token.
std::vector< BaseInfo > derivedFrom
std::vector< FriendInfo > friendList
const Scope * classScope
const std::string & type() const
Value type.
ValueType()=default
ValueType(Sign s, Type t, nonneg int p)
bool isFloat() const
ValueType(Sign s, Type t, nonneg int p, nonneg int c, std::string otn)
bool isIntegral() const
bool isEnum() const
std::string originalTypeName
original type name as written in the source code.
ErrorPath debugPath
debug path to the type
bool isPrimitive() const
ValueType(Sign s, Type t, nonneg int p, nonneg int c, nonneg int v)
ValueType(Sign s, Type t, nonneg int p, nonneg int c)
Information about a member variable.
bool hasDefault() const
Does variable have a default value.
bool isArgument() const
Is variable a function argument.
const Token * mTypeStartToken
variable type start token
void type(const Type *t)
Set Type pointer to known type.
bool isEnumType() const
Determine whether it's an enumeration type.
Variable(const Token *name_, const Token *start_, const Token *end_, nonneg int index_, AccessControl access_, const Type *type_, const Scope *scope_, const Settings &settings)
bool isClass() const
Is variable a user defined (or unknown) type.
const Type * mType
pointer to user defined type info (for known types)
bool isArrayOrPointer() const
Is array or pointer variable.
bool isExtern() const
Is variable extern.
const Token * mNameToken
variable name token
bool isProtected() const
Is variable protected.
bool isReference() const
Is reference variable.
bool dimensionKnown(nonneg int index_) const
Get array dimension known.
nonneg int mIndex
order declared
bool isFloatingType() const
Determine whether it's a floating number type.
bool isMaybeUnused() const
bool isRValueReference() const
Is reference variable.
AccessControl accessControl() const
bool isStlType() const
Checks if the variable is an STL type ('std::') E.g.
bool isLocal() const
Is variable local.
bool isSmartPointer() const
const Type * type() const
Get Type pointer of known type.
const Scope * scope() const
Get Scope pointer of enclosing scope.
bool isPointerToArray() const
Is variable a pointer to an array.
bool isThrow() const
Is variable a throw type.
void setFlag(unsigned int flag_, bool state_)
Set specified flag state.
bool getFlag(unsigned int flag_) const
Get specified flag state.
const Scope * typeScope() const
Get Scope pointer of known type.
bool isGlobal() const
Is variable global.
bool isPublic() const
Is variable public.
const std::string & name() const
Get name string.
const Token * typeEndToken() const
Get type end token.
bool isConst() const
Is variable const.
bool isNamespace() const
Is variable in a namespace.
MathLib::bigint dimension(nonneg int index_) const
Get array dimension length.
bool isArray() const
Is variable an array.
const Token * nameToken() const
Get name token.
AccessControl mAccess
what section is this variable declared in?
nonneg int index() const
Get index of variable in declared order.
unsigned int mFlags
flags
const Scope * mScope
pointer to scope this variable is in
void setDimensions(const std::vector< Dimension > &dimensions_)
bool isPrivate() const
Is variable private.
nonneg int declarationId() const
Get declaration ID (varId used for variable in its declaration).
bool isMutable() const
Is variable mutable.
bool isStlType(const std::set< std::string > &stlTypes) const
Checks if the variable is of any of the STL types passed as arguments ('std::') E....
std::vector< Dimension > mDimensions
array dimensions
const Token * typeStartToken() const
Get type start token.
bool isInit() const
Is variable initialized in its declaration.
bool isVolatile() const
Is variable volatile.
bool isStlType(const std::string &stlType) const
Checks if the variable is of any of the STL types passed as arguments ('std::') E....
const std::vector< Dimension > & dimensions() const
Get array dimensions.
bool isPointer() const
Is pointer variable.
bool isStlStringType() const
Checks if the variable is an STL type ('std::') E.g.
const Token * mTypeEndToken
variable type end token
bool isStatic() const
Is variable static.
const ValueType * valueType() const
static const std::string emptyString
Definition: config.h:127
#define CPPCHECKLIB
Definition: config.h:35
#define nonneg
Definition: config.h:138
std::list< ErrorPathItem > ErrorPath
Definition: errortypes.h:130
static ValueFlow::Value evaluate(const std::string &op, const ValueFlow::Value &lhs, const ValueFlow::Value &rhs)
Array dimension information.
const Token * tok
size token
MathLib::bigint num
(assumed) dimension length when size is a number, 0 if not known
bool known
Known size.
const Scope * scope
Enumerator(const Scope *scope_)
const Scope * scope
const Token * start
static SourceLocation current()
bool operator<(const BaseInfo &rhs) const
std::string name
const Type * type
static const Function * getFunction(const Token *tok)
AccessControl
Access control enumerations.
Reference
static void indent(std::string &str, const nonneg int indent1, const nonneg int indent2)
Definition: token.cpp:1742
bool startsWith(const std::string &str, const char start[], std::size_t startlen)
Definition: utils.h:94