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 and recurses on
25 /// fields of record type. It also copies properties from the `StructValue`
26 /// associated with `Src` to the `StructValue` associated with `Dst` (if these
27 /// `StructValue`s exist).
28 ///
29 /// If there is a `StructValue` associated with `Dst` in the environment, this
30 /// function creates a new `StructValue` and associates it with `Dst`; clients
31 /// need to be aware of this and must not assume that the `StructValue`
32 /// associated with `Dst` remains the same after the call.
33 ///
34 /// We create a new `StructValue` rather than modifying properties on the old
35 /// `StructValue` because the old `StructValue` may be shared with other
36 /// `Environment`s, and we don't want changes to properties to be visible there.
37 ///
38 /// Requirements:
39 ///
40 ///  `Src` and `Dst` must have the same canonical unqualified type.
41 void copyRecord(AggregateStorageLocation &Src, AggregateStorageLocation &Dst,
42                 Environment &Env);
43 
44 /// Returns whether the records `Loc1` and `Loc2` are equal.
45 ///
46 /// Values for `Loc1` are retrieved from `Env1`, and values for `Loc2` are
47 /// retrieved from `Env2`. A convenience overload retrieves values for `Loc1`
48 /// and `Loc2` from the same environment.
49 ///
50 /// This performs a deep comparison, i.e. it compares every field and recurses
51 /// on fields of record type. Fields of reference type compare equal if they
52 /// refer to the same storage location. If `StructValue`s are associated with
53 /// `Loc1` and `Loc2`, it also compares the properties on those `StructValue`s.
54 ///
55 /// Note on how to interpret the result:
56 /// - If this returns true, the records are guaranteed to be equal at runtime.
57 /// - If this returns false, the records may still be equal at runtime; our
58 ///   analysis merely cannot guarantee that they will be equal.
59 ///
60 /// Requirements:
61 ///
62 ///  `Src` and `Dst` must have the same canonical unqualified type.
63 bool recordsEqual(const AggregateStorageLocation &Loc1, const Environment &Env1,
64                   const AggregateStorageLocation &Loc2,
65                   const Environment &Env2);
66 
67 inline bool recordsEqual(const AggregateStorageLocation &Loc1,
68                          const AggregateStorageLocation &Loc2,
69                          const Environment &Env) {
70   return recordsEqual(Loc1, Env, Loc2, Env);
71 }
72 
73 } // namespace dataflow
74 } // namespace clang
75 
76 #endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_RECORDOPS_H
77