llvm/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h

//===- CallEvent.h - Wrapper for all function and method calls --*- 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
//
//===----------------------------------------------------------------------===//
//
/// \file This file defines CallEvent and its subclasses, which represent path-
/// sensitive instances of different kinds of function and method calls
/// (C, C++, and Objective-C).
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H

#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <limits>
#include <optional>
#include <utility>

namespace clang {

class LocationContext;
class ProgramPoint;
class ProgramPointTag;
class StackFrameContext;

namespace ento {

enum CallEventKind {};

class CallEvent;

template <typename T = CallEvent>
class CallEventRef : public IntrusiveRefCntPtr<const T> {};

/// \class RuntimeDefinition
/// Defines the runtime definition of the called function.
///
/// Encapsulates the information we have about which Decl will be used
/// when the call is executed on the given path. When dealing with dynamic
/// dispatch, the information is based on DynamicTypeInfo and might not be
/// precise.
class RuntimeDefinition {};

/// Represents an abstract call to a function or method along a
/// particular path.
///
/// CallEvents are created through the factory methods of CallEventManager.
///
/// CallEvents should always be cheap to create and destroy. In order for
/// CallEventManager to be able to re-use CallEvent-sized memory blocks,
/// subclasses of CallEvent may not add any data members to the base class.
/// Use the "Data" and "Location" fields instead.
class CallEvent {};

/// Represents a call to any sort of function that might have a
/// FunctionDecl.
class AnyFunctionCall : public CallEvent {};

/// Represents a C function or static C++ member function call.
///
/// Example: \c fun()
class SimpleFunctionCall : public AnyFunctionCall {};

/// Represents a call to a block.
///
/// Example: <tt>^{ statement-body }()</tt>
class BlockCall : public CallEvent {};

/// Represents a non-static C++ member function call, no matter how
/// it is written.
class CXXInstanceCall : public AnyFunctionCall {};

/// Represents a static C++ operator call.
///
/// "A" in this example.
/// However, "B" and "C" are represented by SimpleFunctionCall.
/// \code
///   struct S {
///     int pad;
///     static void operator()(int x, int y);
///   };
///   S s{10};
///   void (*fptr)(int, int) = &S::operator();
///
///   s(1, 2);  // A
///   S::operator()(1, 2);  // B
///   fptr(1, 2); // C
/// \endcode
class CXXStaticOperatorCall : public SimpleFunctionCall {};

/// Represents a non-static C++ member function call.
///
/// Example: \c obj.fun()
class CXXMemberCall : public CXXInstanceCall {};

/// Represents a C++ overloaded operator call where the operator is
/// implemented as a non-static member function.
///
/// Example: <tt>iter + 1</tt>
class CXXMemberOperatorCall : public CXXInstanceCall {};

/// Represents an implicit call to a C++ destructor.
///
/// This can occur at the end of a scope (for automatic objects), at the end
/// of a full-expression (for temporaries), or as part of a delete.
class CXXDestructorCall : public CXXInstanceCall {};

/// Represents any constructor invocation. This includes regular constructors
/// and inherited constructors.
class AnyCXXConstructorCall : public AnyFunctionCall {};

/// Represents a call to a C++ constructor.
///
/// Example: \c T(1)
class CXXConstructorCall : public AnyCXXConstructorCall {};

/// Represents a call to a C++ inherited constructor.
///
/// Example: \c class T : public S { using S::S; }; T(1);
///
// Note, it is difficult to model the parameters. This is one of the reasons
// why we skip analysis of inheriting constructors as top-level functions.
// CXXInheritedCtorInitExpr doesn't take arguments and doesn't model parameter
// initialization because there is none: the arguments in the outer
// CXXConstructExpr directly initialize the parameters of the base class
// constructor, and no copies are made. (Making a copy of the parameter is
// incorrect, at least if it's done in an observable way.) The derived class
// constructor doesn't even exist in the formal model.
/// E.g., in:
///
/// struct X { X *p = this; ~X() {} };
/// struct A { A(X x) : b(x.p == &x) {} bool b; };
/// struct B : A { using A::A; };
/// B b = X{};
///
/// ... b.b is initialized to true.
class CXXInheritedConstructorCall : public AnyCXXConstructorCall {};

/// Represents the memory allocation call in a C++ new-expression.
///
/// This is a call to "operator new".
class CXXAllocatorCall : public AnyFunctionCall {};

/// Represents the memory deallocation call in a C++ delete-expression.
///
/// This is a call to "operator delete".
// FIXME: CXXDeleteExpr isn't present for custom delete operators, or even for
// some those that are in the standard library, like the no-throw or align_val
// versions.
// Some pointers:
// http://lists.llvm.org/pipermail/cfe-dev/2020-April/065080.html
// clang/test/Analysis/cxx-dynamic-memory-analysis-order.cpp
// clang/unittests/StaticAnalyzer/CallEventTest.cpp
class CXXDeallocatorCall : public AnyFunctionCall {};

/// Represents the ways an Objective-C message send can occur.
//
// Note to maintainers: OCM_Message should always be last, since it does not
// need to fit in the Data field's low bits.
enum ObjCMessageKind {};

/// Represents any expression that calls an Objective-C method.
///
/// This includes all of the kinds listed in ObjCMessageKind.
class ObjCMethodCall : public CallEvent {};

/// Manages the lifetime of CallEvent objects.
///
/// CallEventManager provides a way to create arbitrary CallEvents "on the
/// stack" as if they were value objects by keeping a cache of CallEvent-sized
/// memory blocks. The CallEvents created by CallEventManager are only valid
/// for the lifetime of the OwnedCallEvent that holds them; right now these
/// objects cannot be copied and ownership cannot be transferred.
class CallEventManager {};

template <typename T>
CallEventRef<T> CallEvent::cloneWithState(ProgramStateRef NewState) const {}

inline void CallEvent::Release() const {}

} // namespace ento

} // namespace clang

namespace llvm {

// Support isa<>, cast<>, and dyn_cast<> for CallEventRef.
simplify_type<clang::ento::CallEventRef<T>>;

} // namespace llvm

#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H