aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/clang16/lib/AST/Interp/Record.h
blob: 1742cb1cc4ee67ed702e41e52630bdc3ce6e4956 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//===--- Record.h - struct and class metadata for the VM --------*- 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
//
//===----------------------------------------------------------------------===//
//
// A record is part of a program to describe the layout and methods of a struct.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_INTERP_RECORD_H
#define LLVM_CLANG_AST_INTERP_RECORD_H

#include "Descriptor.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"

namespace clang {
namespace interp {
class Program;

/// Structure/Class descriptor.
class Record final {
public:
  /// Describes a record field.
  struct Field {
    const FieldDecl *Decl;
    unsigned Offset;
    Descriptor *Desc;
  };

  /// Describes a base class.
  struct Base {
    const RecordDecl *Decl;
    unsigned Offset;
    Descriptor *Desc;
    Record *R;
  };

  /// Mapping from identifiers to field descriptors.
  using FieldList = llvm::SmallVector<Field, 8>;
  /// Mapping from identifiers to base classes.
  using BaseList = llvm::SmallVector<Base, 8>;
  /// List of virtual base classes.
  using VirtualBaseList = llvm::SmallVector<Base, 2>;

public:
  /// Returns the underlying declaration.
  const RecordDecl *getDecl() const { return Decl; }
  /// Returns the name of the underlying declaration.
  const std::string getName() const { return Decl->getNameAsString(); }
  /// Checks if the record is a union.
  bool isUnion() const { return getDecl()->isUnion(); }
  /// Returns the size of the record.
  unsigned getSize() const { return BaseSize; }
  /// Returns the full size of the record, including records.
  unsigned getFullSize() const { return BaseSize + VirtualSize; }
  /// Returns a field.
  const Field *getField(const FieldDecl *FD) const;
  /// Returns a base descriptor.
  const Base *getBase(const RecordDecl *FD) const;
  /// Returns a virtual base descriptor.
  const Base *getVirtualBase(const RecordDecl *RD) const;
  // Returns the destructor of the record, if any.
  const CXXDestructorDecl *getDestructor() const {
    if (const auto *CXXDecl = dyn_cast<CXXRecordDecl>(Decl))
      return CXXDecl->getDestructor();
    return nullptr;
  }

  using const_field_iter = FieldList::const_iterator;
  llvm::iterator_range<const_field_iter> fields() const {
    return llvm::make_range(Fields.begin(), Fields.end());
  }

  unsigned getNumFields() const { return Fields.size(); }
  const Field *getField(unsigned I) const { return &Fields[I]; }
  Field *getField(unsigned I) { return &Fields[I]; }

  using const_base_iter = BaseList::const_iterator;
  llvm::iterator_range<const_base_iter> bases() const {
    return llvm::make_range(Bases.begin(), Bases.end());
  }

  unsigned getNumBases() const { return Bases.size(); }
  Base *getBase(unsigned I) { return &Bases[I]; }

  using const_virtual_iter = VirtualBaseList::const_iterator;
  llvm::iterator_range<const_virtual_iter> virtual_bases() const {
    return llvm::make_range(VirtualBases.begin(), VirtualBases.end());
  }

  unsigned getNumVirtualBases() const { return VirtualBases.size(); }
  Base *getVirtualBase(unsigned I) { return &VirtualBases[I]; }

private:
  /// Constructor used by Program to create record descriptors.
  Record(const RecordDecl *, BaseList &&Bases, FieldList &&Fields,
         VirtualBaseList &&VirtualBases, unsigned VirtualSize,
         unsigned BaseSize);

private:
  friend class Program;

  /// Original declaration.
  const RecordDecl *Decl;
  /// List of all base classes.
  BaseList Bases;
  /// List of all the fields in the record.
  FieldList Fields;
  /// List o fall virtual bases.
  VirtualBaseList VirtualBases;

  /// Mapping from declarations to bases.
  llvm::DenseMap<const RecordDecl *, Base *> BaseMap;
  /// Mapping from field identifiers to descriptors.
  llvm::DenseMap<const FieldDecl *, Field *> FieldMap;
  /// Mapping from declarations to virtual bases.
  llvm::DenseMap<const RecordDecl *, Base *> VirtualBaseMap;
  /// Size of the structure.
  unsigned BaseSize;
  /// Size of all virtual bases.
  unsigned VirtualSize;
};

} // namespace interp
} // namespace clang

#endif