diff options
Diffstat (limited to 'lib/AST/Interp/Record.h')
-rw-r--r-- | lib/AST/Interp/Record.h | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/lib/AST/Interp/Record.h b/lib/AST/Interp/Record.h new file mode 100644 index 000000000000..9cdee9003752 --- /dev/null +++ b/lib/AST/Interp/Record.h @@ -0,0 +1,121 @@ +//===--- 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 "Pointer.h" + +namespace clang { +namespace interp { +class Program; + +/// Structure/Class descriptor. +class Record { +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; } + /// 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; + + 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() { return Fields.size(); } + 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() { 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() { 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; + /// Mapping from + /// Size of the structure. + unsigned BaseSize; + /// Size of all virtual bases. + unsigned VirtualSize; +}; + +} // namespace interp +} // namespace clang + +#endif |