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