StorageLocation.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===-- StorageLocation.h ---------------------------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines classes that represent elements of the local variable store
  15. // and of the heap during dataflow analysis.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_STORAGELOCATION_H
  19. #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_STORAGELOCATION_H
  20. #include "clang/AST/Decl.h"
  21. #include "clang/AST/Type.h"
  22. #include "llvm/ADT/DenseMap.h"
  23. namespace clang {
  24. namespace dataflow {
  25. /// Base class for elements of the local variable store and of the heap.
  26. ///
  27. /// Each storage location holds a value. The mapping from storage locations to
  28. /// values is stored in the environment.
  29. class StorageLocation {
  30. public:
  31. enum class Kind { Scalar, Aggregate };
  32. StorageLocation(Kind LocKind, QualType Type) : LocKind(LocKind), Type(Type) {}
  33. // Non-copyable because addresses of storage locations are used as their
  34. // identities throughout framework and user code. The framework is responsible
  35. // for construction and destruction of storage locations.
  36. StorageLocation(const StorageLocation &) = delete;
  37. StorageLocation &operator=(const StorageLocation &) = delete;
  38. virtual ~StorageLocation() = default;
  39. Kind getKind() const { return LocKind; }
  40. QualType getType() const { return Type; }
  41. private:
  42. Kind LocKind;
  43. QualType Type;
  44. };
  45. /// A storage location that is not subdivided further for the purposes of
  46. /// abstract interpretation. For example: `int`, `int*`, `int&`.
  47. class ScalarStorageLocation final : public StorageLocation {
  48. public:
  49. explicit ScalarStorageLocation(QualType Type)
  50. : StorageLocation(Kind::Scalar, Type) {}
  51. static bool classof(const StorageLocation *Loc) {
  52. return Loc->getKind() == Kind::Scalar;
  53. }
  54. };
  55. /// A storage location which is subdivided into smaller storage locations that
  56. /// can be traced independently by abstract interpretation. For example: a
  57. /// struct with public members. The child map is flat, so when used for a struct
  58. /// or class type, all accessible members of base struct and class types are
  59. /// directly accesible as children of this location.
  60. /// FIXME: Currently, the storage location of unions is modelled the same way as
  61. /// that of structs or classes. Eventually, we need to change this modelling so
  62. /// that all of the members of a given union have the same storage location.
  63. class AggregateStorageLocation final : public StorageLocation {
  64. public:
  65. explicit AggregateStorageLocation(QualType Type)
  66. : AggregateStorageLocation(
  67. Type, llvm::DenseMap<const ValueDecl *, StorageLocation *>()) {}
  68. AggregateStorageLocation(
  69. QualType Type,
  70. llvm::DenseMap<const ValueDecl *, StorageLocation *> Children)
  71. : StorageLocation(Kind::Aggregate, Type), Children(std::move(Children)) {}
  72. static bool classof(const StorageLocation *Loc) {
  73. return Loc->getKind() == Kind::Aggregate;
  74. }
  75. /// Returns the child storage location for `D`.
  76. StorageLocation &getChild(const ValueDecl &D) const {
  77. auto It = Children.find(&D);
  78. assert(It != Children.end());
  79. return *It->second;
  80. }
  81. private:
  82. llvm::DenseMap<const ValueDecl *, StorageLocation *> Children;
  83. };
  84. } // namespace dataflow
  85. } // namespace clang
  86. #endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_STORAGELOCATION_H
  87. #ifdef __GNUC__
  88. #pragma GCC diagnostic pop
  89. #endif