File: Record.h

package info (click to toggle)
llvm-toolchain-20 1%3A20.1.6-1~exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 2,111,304 kB
  • sloc: cpp: 7,438,677; ansic: 1,393,822; asm: 1,012,926; python: 241,650; f90: 86,635; objc: 75,479; lisp: 42,144; pascal: 17,286; sh: 10,027; ml: 5,082; perl: 4,730; awk: 3,523; makefile: 3,349; javascript: 2,251; xml: 892; fortran: 672
file content (147 lines) | stat: -rw-r--r-- 4,902 bytes parent folder | download | duplicates (2)
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//===--- 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;
    const Descriptor *Desc;
    bool isBitField() const { return Decl->isBitField(); }
    bool isUnnamedBitField() const { return Decl->isUnnamedBitField(); }
  };

  /// Describes a base class.
  struct Base {
    const RecordDecl *Decl;
    unsigned Offset;
    const Descriptor *Desc;
    const 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;
  /// Checks if the record is a union.
  bool isUnion() const { return IsUnion; }
  /// Checks if the record is an anonymous union.
  bool isAnonymousUnion() const { return IsAnonymousUnion; }
  /// 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 base descriptor.
  const Base *getBase(QualType T) 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]; }

  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(); }
  const Base *getBase(unsigned I) const {
    assert(I < getNumBases());
    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(); }
  const Base *getVirtualBase(unsigned I) const { return &VirtualBases[I]; }

  void dump(llvm::raw_ostream &OS, unsigned Indentation = 0,
            unsigned Offset = 0) const;
  void dump() const { dump(llvm::errs()); }

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 *, const Base *> BaseMap;
  /// Mapping from field identifiers to descriptors.
  llvm::DenseMap<const FieldDecl *, const 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;
  /// If this record is a union.
  bool IsUnion;
  /// If this is an anonymous union.
  bool IsAnonymousUnion;
};

} // namespace interp
} // namespace clang

#endif