blob: 9cdee9003752e8d9ed005e9dd29b379ad3f6ad29 [file] [log] [blame]
//===--- 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