Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===--- SValVisitor.h - Visitor for SVal subclasses ------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. //  This file defines the SValVisitor, SymExprVisitor, and MemRegionVisitor
  10. //  interfaces, and also FullSValVisitor, which visits all three hierarchies.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H
  15. #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H
  16.  
  17. #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
  18. #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
  19. #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
  20.  
  21. namespace clang {
  22.  
  23. namespace ento {
  24.  
  25. /// SValVisitor - this class implements a simple visitor for SVal
  26. /// subclasses.
  27. template <typename ImplClass, typename RetTy = void> class SValVisitor {
  28. public:
  29.  
  30. #define DISPATCH(NAME, CLASS) \
  31.   return static_cast<ImplClass *>(this)->Visit ## NAME(V.castAs<CLASS>())
  32.  
  33.   RetTy Visit(SVal V) {
  34.     // Dispatch to VisitFooVal for each FooVal.
  35.     // Take namespaces (loc:: and nonloc::) into account.
  36.     switch (V.getBaseKind()) {
  37. #define BASIC_SVAL(Id, Parent) case SVal::Id ## Kind: DISPATCH(Id, Id);
  38. #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
  39.     case SVal::LocKind:
  40.       switch (V.getSubKind()) {
  41. #define LOC_SVAL(Id, Parent) \
  42.       case loc::Id ## Kind: DISPATCH(Loc ## Id, loc :: Id);
  43. #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
  44.       }
  45.       llvm_unreachable("Unknown Loc sub-kind!");
  46.     case SVal::NonLocKind:
  47.       switch (V.getSubKind()) {
  48. #define NONLOC_SVAL(Id, Parent) \
  49.       case nonloc::Id ## Kind: DISPATCH(NonLoc ## Id, nonloc :: Id);
  50. #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
  51.       }
  52.       llvm_unreachable("Unknown NonLoc sub-kind!");
  53.     }
  54.     llvm_unreachable("Unknown SVal kind!");
  55.   }
  56.  
  57. #define BASIC_SVAL(Id, Parent) \
  58.   RetTy Visit ## Id(Id V) { DISPATCH(Parent, Id); }
  59. #define ABSTRACT_SVAL(Id, Parent) \
  60.   BASIC_SVAL(Id, Parent)
  61. #define LOC_SVAL(Id, Parent) \
  62.   RetTy VisitLoc ## Id(loc::Id V) { DISPATCH(Parent, Parent); }
  63. #define NONLOC_SVAL(Id, Parent) \
  64.   RetTy VisitNonLoc ## Id(nonloc::Id V) { DISPATCH(Parent, Parent); }
  65. #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
  66.  
  67.   // Base case, ignore it. :)
  68.   RetTy VisitSVal(SVal V) { return RetTy(); }
  69.  
  70. #undef DISPATCH
  71. };
  72.  
  73. /// SymExprVisitor - this class implements a simple visitor for SymExpr
  74. /// subclasses.
  75. template <typename ImplClass, typename RetTy = void> class SymExprVisitor {
  76. public:
  77.  
  78. #define DISPATCH(CLASS) \
  79.     return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(S))
  80.  
  81.   RetTy Visit(SymbolRef S) {
  82.     // Dispatch to VisitSymbolFoo for each SymbolFoo.
  83.     switch (S->getKind()) {
  84. #define SYMBOL(Id, Parent) \
  85.     case SymExpr::Id ## Kind: DISPATCH(Id);
  86. #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
  87.     }
  88.     llvm_unreachable("Unknown SymExpr kind!");
  89.   }
  90.  
  91.   // If the implementation chooses not to implement a certain visit method, fall
  92.   // back on visiting the superclass.
  93. #define SYMBOL(Id, Parent) RetTy Visit ## Id(const Id *S) { DISPATCH(Parent); }
  94. #define ABSTRACT_SYMBOL(Id, Parent) SYMBOL(Id, Parent)
  95. #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
  96.  
  97.   // Base case, ignore it. :)
  98.   RetTy VisitSymExpr(SymbolRef S) { return RetTy(); }
  99.  
  100. #undef DISPATCH
  101. };
  102.  
  103. /// MemRegionVisitor - this class implements a simple visitor for MemRegion
  104. /// subclasses.
  105. template <typename ImplClass, typename RetTy = void> class MemRegionVisitor {
  106. public:
  107.  
  108. #define DISPATCH(CLASS) \
  109.   return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(R))
  110.  
  111.   RetTy Visit(const MemRegion *R) {
  112.     // Dispatch to VisitFooRegion for each FooRegion.
  113.     switch (R->getKind()) {
  114. #define REGION(Id, Parent) case MemRegion::Id ## Kind: DISPATCH(Id);
  115. #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
  116.     }
  117.     llvm_unreachable("Unknown MemRegion kind!");
  118.   }
  119.  
  120.   // If the implementation chooses not to implement a certain visit method, fall
  121.   // back on visiting the superclass.
  122. #define REGION(Id, Parent) \
  123.   RetTy Visit ## Id(const Id *R) { DISPATCH(Parent); }
  124. #define ABSTRACT_REGION(Id, Parent) \
  125.   REGION(Id, Parent)
  126. #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
  127.  
  128.   // Base case, ignore it. :)
  129.   RetTy VisitMemRegion(const MemRegion *R) { return RetTy(); }
  130.  
  131. #undef DISPATCH
  132. };
  133.  
  134. /// FullSValVisitor - a convenient mixed visitor for all three:
  135. /// SVal, SymExpr and MemRegion subclasses.
  136. template <typename ImplClass, typename RetTy = void>
  137. class FullSValVisitor : public SValVisitor<ImplClass, RetTy>,
  138.                         public SymExprVisitor<ImplClass, RetTy>,
  139.                         public MemRegionVisitor<ImplClass, RetTy> {
  140. public:
  141.   using SValVisitor<ImplClass, RetTy>::Visit;
  142.   using SymExprVisitor<ImplClass, RetTy>::Visit;
  143.   using MemRegionVisitor<ImplClass, RetTy>::Visit;
  144. };
  145.  
  146. } // end namespace ento
  147.  
  148. } // end namespace clang
  149.  
  150. #endif
  151.