brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · 8245eef Raw
152 lines · c
1//===--- Record.h - struct and class metadata for the VM --------*- 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-exception6//7//===----------------------------------------------------------------------===//8//9// A record is part of a program to describe the layout and methods of a struct.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_AST_INTERP_RECORD_H14#define LLVM_CLANG_AST_INTERP_RECORD_H15 16#include "Descriptor.h"17#include "clang/AST/Decl.h"18#include "clang/AST/DeclCXX.h"19 20namespace clang {21namespace interp {22class Program;23 24/// Structure/Class descriptor.25class Record final {26public:27  /// Describes a record field.28  struct Field {29    const FieldDecl *Decl;30    unsigned Offset;31    const Descriptor *Desc;32    bool isBitField() const { return Decl->isBitField(); }33    bool isUnnamedBitField() const { return Decl->isUnnamedBitField(); }34  };35 36  /// Describes a base class.37  struct Base {38    const RecordDecl *Decl;39    unsigned Offset;40    const Descriptor *Desc;41    const Record *R;42  };43 44  /// Mapping from identifiers to field descriptors.45  using FieldList = llvm::SmallVector<Field, 8>;46  /// Mapping from identifiers to base classes.47  using BaseList = llvm::SmallVector<Base, 8>;48  /// List of virtual base classes.49  using VirtualBaseList = llvm::SmallVector<Base, 2>;50 51public:52  /// Returns the underlying declaration.53  const RecordDecl *getDecl() const { return Decl; }54  /// Returns the name of the underlying declaration.55  std::string getName() const;56  /// Checks if the record is a union.57  bool isUnion() const { return IsUnion; }58  /// Checks if the record is an anonymous union.59  bool isAnonymousUnion() const { return IsAnonymousUnion; }60  /// Returns the size of the record.61  unsigned getSize() const { return BaseSize; }62  /// Returns the full size of the record, including records.63  unsigned getFullSize() const { return BaseSize + VirtualSize; }64  /// Returns a field.65  const Field *getField(const FieldDecl *FD) const;66  /// Returns a base descriptor.67  const Base *getBase(const RecordDecl *FD) const;68  /// Returns a base descriptor.69  const Base *getBase(QualType T) const;70  /// Returns a virtual base descriptor.71  const Base *getVirtualBase(const RecordDecl *RD) const;72  /// Returns the destructor of the record, if any.73  const CXXDestructorDecl *getDestructor() const {74    if (const auto *CXXDecl = dyn_cast<CXXRecordDecl>(Decl))75      return CXXDecl->getDestructor();76    return nullptr;77  }78 79  /// Returns true for anonymous unions and records80  /// with no destructor or for those with a trivial destructor.81  bool hasTrivialDtor() const;82 83  using const_field_iter = FieldList::const_iterator;84  llvm::iterator_range<const_field_iter> fields() const {85    return llvm::make_range(Fields.begin(), Fields.end());86  }87 88  unsigned getNumFields() const { return Fields.size(); }89  const Field *getField(unsigned I) const { return &Fields[I]; }90 91  using const_base_iter = BaseList::const_iterator;92  llvm::iterator_range<const_base_iter> bases() const {93    return llvm::make_range(Bases.begin(), Bases.end());94  }95 96  unsigned getNumBases() const { return Bases.size(); }97  const Base *getBase(unsigned I) const {98    assert(I < getNumBases());99    return &Bases[I];100  }101 102  using const_virtual_iter = VirtualBaseList::const_iterator;103  llvm::iterator_range<const_virtual_iter> virtual_bases() const {104    return llvm::make_range(VirtualBases.begin(), VirtualBases.end());105  }106 107  unsigned getNumVirtualBases() const { return VirtualBases.size(); }108  const Base *getVirtualBase(unsigned I) const { return &VirtualBases[I]; }109 110  void dump(llvm::raw_ostream &OS, unsigned Indentation = 0,111            unsigned Offset = 0) const;112  void dump() const { dump(llvm::errs()); }113 114private:115  /// Constructor used by Program to create record descriptors.116  Record(const RecordDecl *, BaseList &&Bases, FieldList &&Fields,117         VirtualBaseList &&VirtualBases, unsigned VirtualSize,118         unsigned BaseSize);119 120private:121  friend class Program;122 123  /// Original declaration.124  const RecordDecl *Decl;125  /// List of all base classes.126  BaseList Bases;127  /// List of all the fields in the record.128  FieldList Fields;129  /// List o fall virtual bases.130  VirtualBaseList VirtualBases;131 132  /// Mapping from declarations to bases.133  llvm::DenseMap<const RecordDecl *, const Base *> BaseMap;134  /// Mapping from field identifiers to descriptors.135  llvm::DenseMap<const FieldDecl *, const Field *> FieldMap;136  /// Mapping from declarations to virtual bases.137  llvm::DenseMap<const RecordDecl *, Base *> VirtualBaseMap;138  /// Size of the structure.139  unsigned BaseSize;140  /// Size of all virtual bases.141  unsigned VirtualSize;142  /// If this record is a union.143  bool IsUnion;144  /// If this is an anonymous union.145  bool IsAnonymousUnion;146};147 148} // namespace interp149} // namespace clang150 151#endif152