xref: /freebsd/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/RecordOps.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===-- RecordOps.h ---------------------------------------------*- 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 //  Operations on records (structs, classes, and unions).
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_RECORDOPS_H
14 #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_RECORDOPS_H
15 
16 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
17 #include "clang/Analysis/FlowSensitive/StorageLocation.h"
18 
19 namespace clang {
20 namespace dataflow {
21 
22 /// Copies a record (struct, class, or union) from `Src` to `Dst`.
23 ///
24 /// This performs a deep copy, i.e. it copies every field (including synthetic
25 /// fields) and recurses on fields of record type.
26 ///
27 /// If there is a `RecordValue` associated with `Dst` in the environment, this
28 /// function creates a new `RecordValue` and associates it with `Dst`; clients
29 /// need to be aware of this and must not assume that the `RecordValue`
30 /// associated with `Dst` remains the same after the call.
31 ///
32 /// Requirements:
33 ///
34 ///  Either:
35 ///    - `Src` and `Dest` must have the same canonical unqualified type, or
36 ///    - The type of `Src` must be derived from `Dest`, or
37 ///    - The type of `Dest` must be derived from `Src` (in this case, any fields
38 ///      that are only present in `Dest` are not overwritten).
39 void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst,
40                 Environment &Env);
41 
42 /// Returns whether the records `Loc1` and `Loc2` are equal.
43 ///
44 /// Values for `Loc1` are retrieved from `Env1`, and values for `Loc2` are
45 /// retrieved from `Env2`. A convenience overload retrieves values for `Loc1`
46 /// and `Loc2` from the same environment.
47 ///
48 /// This performs a deep comparison, i.e. it compares every field (including
49 /// synthetic fields) and recurses on fields of record type. Fields of reference
50 /// type compare equal if they refer to the same storage location.
51 ///
52 /// Note on how to interpret the result:
53 /// - If this returns true, the records are guaranteed to be equal at runtime.
54 /// - If this returns false, the records may still be equal at runtime; our
55 ///   analysis merely cannot guarantee that they will be equal.
56 ///
57 /// Requirements:
58 ///
59 ///  `Src` and `Dst` must have the same canonical unqualified type.
60 bool recordsEqual(const RecordStorageLocation &Loc1, const Environment &Env1,
61                   const RecordStorageLocation &Loc2, const Environment &Env2);
62 
recordsEqual(const RecordStorageLocation & Loc1,const RecordStorageLocation & Loc2,const Environment & Env)63 inline bool recordsEqual(const RecordStorageLocation &Loc1,
64                          const RecordStorageLocation &Loc2,
65                          const Environment &Env) {
66   return recordsEqual(Loc1, Env, Loc2, Env);
67 }
68 
69 } // namespace dataflow
70 } // namespace clang
71 
72 #endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_RECORDOPS_H
73