1a07aba5dSTimm Baeder //===--- Record.cpp - struct and class metadata for the VM ------*- C++ -*-===// 2a07aba5dSTimm Baeder // 3a07aba5dSTimm Baeder // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a07aba5dSTimm Baeder // See https://llvm.org/LICENSE.txt for license information. 5a07aba5dSTimm Baeder // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a07aba5dSTimm Baeder // 7a07aba5dSTimm Baeder //===----------------------------------------------------------------------===// 8a07aba5dSTimm Baeder 9a07aba5dSTimm Baeder #include "Record.h" 10a07aba5dSTimm Baeder #include "clang/AST/ASTContext.h" 11a07aba5dSTimm Baeder 12a07aba5dSTimm Baeder using namespace clang; 13a07aba5dSTimm Baeder using namespace clang::interp; 14a07aba5dSTimm Baeder 15a07aba5dSTimm Baeder Record::Record(const RecordDecl *Decl, BaseList &&SrcBases, 16a07aba5dSTimm Baeder FieldList &&SrcFields, VirtualBaseList &&SrcVirtualBases, 17a07aba5dSTimm Baeder unsigned VirtualSize, unsigned BaseSize) 18a07aba5dSTimm Baeder : Decl(Decl), Bases(std::move(SrcBases)), Fields(std::move(SrcFields)), 19*82ce8296STimm Baeder BaseSize(BaseSize), VirtualSize(VirtualSize), IsUnion(Decl->isUnion()), 20*82ce8296STimm Baeder IsAnonymousUnion(IsUnion && Decl->isAnonymousStructOrUnion()) { 21a07aba5dSTimm Baeder for (Base &V : SrcVirtualBases) 22a07aba5dSTimm Baeder VirtualBases.push_back({V.Decl, V.Offset + BaseSize, V.Desc, V.R}); 23a07aba5dSTimm Baeder 24a07aba5dSTimm Baeder for (Base &B : Bases) 25a07aba5dSTimm Baeder BaseMap[B.Decl] = &B; 26a07aba5dSTimm Baeder for (Field &F : Fields) 27a07aba5dSTimm Baeder FieldMap[F.Decl] = &F; 28a07aba5dSTimm Baeder for (Base &V : VirtualBases) 29a07aba5dSTimm Baeder VirtualBaseMap[V.Decl] = &V; 30a07aba5dSTimm Baeder } 31a07aba5dSTimm Baeder 32a07aba5dSTimm Baeder const std::string Record::getName() const { 33a07aba5dSTimm Baeder std::string Ret; 34a07aba5dSTimm Baeder llvm::raw_string_ostream OS(Ret); 35a07aba5dSTimm Baeder Decl->getNameForDiagnostic(OS, Decl->getASTContext().getPrintingPolicy(), 36a07aba5dSTimm Baeder /*Qualified=*/true); 37a07aba5dSTimm Baeder return Ret; 38a07aba5dSTimm Baeder } 39a07aba5dSTimm Baeder 40a07aba5dSTimm Baeder const Record::Field *Record::getField(const FieldDecl *FD) const { 41a07aba5dSTimm Baeder auto It = FieldMap.find(FD->getFirstDecl()); 42a07aba5dSTimm Baeder assert(It != FieldMap.end() && "Missing field"); 43a07aba5dSTimm Baeder return It->second; 44a07aba5dSTimm Baeder } 45a07aba5dSTimm Baeder 46a07aba5dSTimm Baeder const Record::Base *Record::getBase(const RecordDecl *FD) const { 47a07aba5dSTimm Baeder auto It = BaseMap.find(FD); 48a07aba5dSTimm Baeder assert(It != BaseMap.end() && "Missing base"); 49a07aba5dSTimm Baeder return It->second; 50a07aba5dSTimm Baeder } 51a07aba5dSTimm Baeder 52a07aba5dSTimm Baeder const Record::Base *Record::getBase(QualType T) const { 53a07aba5dSTimm Baeder if (auto *RT = T->getAs<RecordType>()) { 54a07aba5dSTimm Baeder const RecordDecl *RD = RT->getDecl(); 55a07aba5dSTimm Baeder return BaseMap.lookup(RD); 56a07aba5dSTimm Baeder } 57a07aba5dSTimm Baeder return nullptr; 58a07aba5dSTimm Baeder } 59a07aba5dSTimm Baeder 60a07aba5dSTimm Baeder const Record::Base *Record::getVirtualBase(const RecordDecl *FD) const { 61a07aba5dSTimm Baeder auto It = VirtualBaseMap.find(FD); 62a07aba5dSTimm Baeder assert(It != VirtualBaseMap.end() && "Missing virtual base"); 63a07aba5dSTimm Baeder return It->second; 64a07aba5dSTimm Baeder } 65