Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:24

0001 //===---- CFGMatchSwitch.h --------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines the `CFGMatchSwitch` abstraction for building a "switch"
0010 //  statement for control flow graph elements. Each case of the switch is
0011 //  defined by an ASTMatcher which is applied on the AST node contained in the
0012 //  input `CFGElement`.
0013 //
0014 //  Currently, the `CFGMatchSwitch` only handles `CFGElement`s of
0015 //  `Kind::Statement` and `Kind::Initializer`.
0016 //
0017 //===----------------------------------------------------------------------===//
0018 
0019 #ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CFGMATCHSWITCH_H_
0020 #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CFGMATCHSWITCH_H_
0021 
0022 #include "clang/AST/ASTContext.h"
0023 #include "clang/AST/Stmt.h"
0024 #include "clang/Analysis/CFG.h"
0025 #include "clang/Analysis/FlowSensitive/MatchSwitch.h"
0026 #include <functional>
0027 #include <utility>
0028 
0029 namespace clang {
0030 namespace dataflow {
0031 
0032 template <typename State, typename Result = void>
0033 using CFGMatchSwitch =
0034     std::function<Result(const CFGElement &, ASTContext &, State &)>;
0035 
0036 /// Collects cases of a "match switch": a collection of matchers paired with
0037 /// callbacks, which together define a switch that can be applied to an AST node
0038 /// contained in a CFG element.
0039 template <typename State, typename Result = void> class CFGMatchSwitchBuilder {
0040 public:
0041   /// Registers an action `A` for `CFGStmt`s that will be triggered by the match
0042   /// of the pattern `M` against the `Stmt` contained in the input `CFGStmt`.
0043   ///
0044   /// Requirements:
0045   ///
0046   ///  `NodeT` should be derived from `Stmt`.
0047   template <typename NodeT>
0048   CFGMatchSwitchBuilder &&
0049   CaseOfCFGStmt(MatchSwitchMatcher<Stmt> M,
0050                 MatchSwitchAction<NodeT, State, Result> A) && {
0051     std::move(StmtBuilder).template CaseOf<NodeT>(M, A);
0052     return std::move(*this);
0053   }
0054 
0055   /// Registers an action `A` for `CFGInitializer`s that will be triggered by
0056   /// the match of the pattern `M` against the `CXXCtorInitializer` contained in
0057   /// the input `CFGInitializer`.
0058   ///
0059   /// Requirements:
0060   ///
0061   ///  `NodeT` should be derived from `CXXCtorInitializer`.
0062   template <typename NodeT>
0063   CFGMatchSwitchBuilder &&
0064   CaseOfCFGInit(MatchSwitchMatcher<CXXCtorInitializer> M,
0065                 MatchSwitchAction<NodeT, State, Result> A) && {
0066     std::move(InitBuilder).template CaseOf<NodeT>(M, A);
0067     return std::move(*this);
0068   }
0069 
0070   CFGMatchSwitch<State, Result> Build() && {
0071     return [StmtMS = std::move(StmtBuilder).Build(),
0072             InitMS = std::move(InitBuilder).Build()](const CFGElement &Element,
0073                                                      ASTContext &Context,
0074                                                      State &S) -> Result {
0075       switch (Element.getKind()) {
0076       case CFGElement::Initializer:
0077         return InitMS(*Element.castAs<CFGInitializer>().getInitializer(),
0078                       Context, S);
0079       case CFGElement::Statement:
0080       case CFGElement::Constructor:
0081       case CFGElement::CXXRecordTypedCall:
0082         return StmtMS(*Element.castAs<CFGStmt>().getStmt(), Context, S);
0083       default:
0084         // FIXME: Handle other kinds of CFGElement.
0085         return Result();
0086       }
0087     };
0088   }
0089 
0090 private:
0091   ASTMatchSwitchBuilder<Stmt, State, Result> StmtBuilder;
0092   ASTMatchSwitchBuilder<CXXCtorInitializer, State, Result> InitBuilder;
0093 };
0094 
0095 } // namespace dataflow
0096 } // namespace clang
0097 
0098 #endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CFGMATCHSWITCH_H_