- //===- CalledOnceCheck.h - Check 'called once' parameters -------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- //  This file defines a check for function-like parameters that should be 
- //  called exactly one time. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_CALLEDONCECHECK_H 
- #define LLVM_CLANG_ANALYSIS_ANALYSES_CALLEDONCECHECK_H 
-   
- namespace clang { 
-   
- class AnalysisDeclContext; 
- class BlockDecl; 
- class CFG; 
- class Decl; 
- class Expr; 
- class ParmVarDecl; 
- class Stmt; 
-   
- /// Classification of situations when parameter is not called on every path. 
- /// \enum IfThen -- then branch of the if statement has no call. 
- /// \enum IfElse -- else branch of the if statement has no call. 
- /// \enum Switch -- one of the switch cases doesn't have a call. 
- /// \enum SwitchSkipped -- there is no call if none of the cases appies. 
- /// \enum LoopEntered -- no call when the loop is entered. 
- /// \enum LoopSkipped -- no call when the loop is not entered. 
- /// \enum FallbackReason -- fallback case when we were not able to figure out 
- /// the reason. 
- enum class NeverCalledReason { 
-   IfThen, 
-   IfElse, 
-   Switch, 
-   SwitchSkipped, 
-   LoopEntered, 
-   LoopSkipped, 
-   FallbackReason, 
-   LARGEST_VALUE = FallbackReason 
- }; 
-   
- class CalledOnceCheckHandler { 
- public: 
-   CalledOnceCheckHandler() = default; 
-   virtual ~CalledOnceCheckHandler() = default; 
-   
-   /// Called when parameter is called twice. 
-   /// \param Parameter -- parameter that should be called once. 
-   /// \param Call -- call to report the warning. 
-   /// \param PrevCall -- previous call. 
-   /// \param IsCompletionHandler -- true, if parameter is a completion handler. 
-   /// \param Poised -- true, if the second call is guaranteed to happen after 
-   /// the first call. 
-   virtual void handleDoubleCall(const ParmVarDecl *Parameter, const Expr *Call, 
-                                 const Expr *PrevCall, bool IsCompletionHandler, 
-                                 bool Poised) {} 
-   
-   /// Called when parameter is not called at all. 
-   /// \param Parameter -- parameter that should be called once. 
-   /// \param IsCompletionHandler -- true, if parameter is a completion handler. 
-   virtual void handleNeverCalled(const ParmVarDecl *Parameter, 
-                                  bool IsCompletionHandler) {} 
-   
-   /// Called when captured parameter is not called at all. 
-   /// \param Parameter -- parameter that should be called once. 
-   /// \param Where -- declaration that captures \p Parameter 
-   /// \param IsCompletionHandler -- true, if parameter is a completion handler. 
-   virtual void handleCapturedNeverCalled(const ParmVarDecl *Parameter, 
-                                          const Decl *Where, 
-                                          bool IsCompletionHandler) {} 
-   
-   /// Called when parameter is not called on one of the paths. 
-   /// Usually we try to find a statement that is the least common ancestor of 
-   /// the path containing the call and not containing the call.  This helps us 
-   /// to pinpoint a bad path for the user. 
-   /// \param Parameter -- parameter that should be called once. 
-   /// \param Function -- function declaration where the problem occurred. 
-   /// \param Where -- the least common ancestor statement. 
-   /// \param Reason -- a reason describing the path without a call. 
-   /// \param IsCalledDirectly -- true, if parameter actually gets called on 
-   /// the other path.  It is opposed to be used in some other way (added to some 
-   /// collection, passed as a parameter, etc.). 
-   /// \param IsCompletionHandler -- true, if parameter is a completion handler. 
-   virtual void handleNeverCalled(const ParmVarDecl *Parameter, 
-                                  const Decl *Function, const Stmt *Where, 
-                                  NeverCalledReason Reason, 
-                                  bool IsCalledDirectly, 
-                                  bool IsCompletionHandler) {} 
-   
-   /// Called when the block is guaranteed to be called exactly once. 
-   /// It means that we can be stricter with what we report on that block. 
-   /// \param Block -- block declaration that is known to be called exactly once. 
-   virtual void 
-   handleBlockThatIsGuaranteedToBeCalledOnce(const BlockDecl *Block) {} 
-   
-   /// Called when the block has no guarantees about how many times it can get 
-   /// called. 
-   /// It means that we should be more lenient with reporting warnings in it. 
-   /// \param Block -- block declaration in question. 
-   virtual void handleBlockWithNoGuarantees(const BlockDecl *Block) {} 
- }; 
-   
- /// Check given CFG for 'called once' parameter violations. 
- /// 
- /// It traverses the function and tracks how such parameters are used. 
- /// It detects two main violations: 
- ///   * parameter is called twice 
- ///   * parameter is not called 
- /// 
- /// \param AC -- context. 
- /// \param Handler -- a handler for found violations. 
- /// \param CheckConventionalParameters -- true, if we want to check parameters 
- /// not explicitly marked as 'called once', but having the same requirements 
- /// according to conventions. 
- void checkCalledOnceParameters(AnalysisDeclContext &AC, 
-                                CalledOnceCheckHandler &Handler, 
-                                bool CheckConventionalParameters); 
-   
- } // end namespace clang 
-   
- #endif /* LLVM_CLANG_ANALYSIS_ANALYSES_CALLEDONCECHECK_H */ 
-