1503524acc73f2f8280080ca0d200377406001b65Ted Kremenek//===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==// 2503524acc73f2f8280080ca0d200377406001b65Ted Kremenek// 3503524acc73f2f8280080ca0d200377406001b65Ted Kremenek// The LLVM Compiler Infrastructure 4503524acc73f2f8280080ca0d200377406001b65Ted Kremenek// 5503524acc73f2f8280080ca0d200377406001b65Ted Kremenek// This file is distributed under the University of Illinois Open Source 6503524acc73f2f8280080ca0d200377406001b65Ted Kremenek// License. See LICENSE.TXT for details. 7503524acc73f2f8280080ca0d200377406001b65Ted Kremenek// 8503524acc73f2f8280080ca0d200377406001b65Ted Kremenek//===----------------------------------------------------------------------===// 9503524acc73f2f8280080ca0d200377406001b65Ted Kremenek// 10503524acc73f2f8280080ca0d200377406001b65Ted Kremenek// This file defines the RecordLayout interface. 11503524acc73f2f8280080ca0d200377406001b65Ted Kremenek// 12503524acc73f2f8280080ca0d200377406001b65Ted Kremenek//===----------------------------------------------------------------------===// 13503524acc73f2f8280080ca0d200377406001b65Ted Kremenek 14503524acc73f2f8280080ca0d200377406001b65Ted Kremenek#include "clang/AST/ASTContext.h" 15503524acc73f2f8280080ca0d200377406001b65Ted Kremenek#include "clang/AST/RecordLayout.h" 162fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman#include "clang/Basic/TargetInfo.h" 17503524acc73f2f8280080ca0d200377406001b65Ted Kremenek 18503524acc73f2f8280080ca0d200377406001b65Ted Kremenekusing namespace clang; 19503524acc73f2f8280080ca0d200377406001b65Ted Kremenek 20503524acc73f2f8280080ca0d200377406001b65Ted Kremenekvoid ASTRecordLayout::Destroy(ASTContext &Ctx) { 21503524acc73f2f8280080ca0d200377406001b65Ted Kremenek if (FieldOffsets) 22503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Ctx.Deallocate(FieldOffsets); 2342f81e674ba420406d9efb8b52d4e59e613ebceaArgyrios Kyrtzidis if (CXXInfo) { 24503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Ctx.Deallocate(CXXInfo); 2542f81e674ba420406d9efb8b52d4e59e613ebceaArgyrios Kyrtzidis CXXInfo->~CXXRecordLayoutInfo(); 2642f81e674ba420406d9efb8b52d4e59e613ebceaArgyrios Kyrtzidis } 27503524acc73f2f8280080ca0d200377406001b65Ted Kremenek this->~ASTRecordLayout(); 28503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Ctx.Deallocate(this); 29503524acc73f2f8280080ca0d200377406001b65Ted Kremenek} 30503524acc73f2f8280080ca0d200377406001b65Ted Kremenek 315f022d82696c84e4d127c558871d68ac6273274eKen DyckASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size, 32dac54c124e302d6f028ea5723c425b7f66fc7c71Ken Dyck CharUnits alignment, CharUnits datasize, 334ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const uint64_t *fieldoffsets, 344ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad unsigned fieldcount) 35441c6239c6df8c759bacf6510efbfd434b647066John McCall : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0), 36503524acc73f2f8280080ca0d200377406001b65Ted Kremenek FieldCount(fieldcount), CXXInfo(0) { 37503524acc73f2f8280080ca0d200377406001b65Ted Kremenek if (FieldCount > 0) { 38503524acc73f2f8280080ca0d200377406001b65Ted Kremenek FieldOffsets = new (Ctx) uint64_t[FieldCount]; 39bb9357cf8f9b79fdf9af4613748d5dc4929c72d3Benjamin Kramer memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets)); 40503524acc73f2f8280080ca0d200377406001b65Ted Kremenek } 41503524acc73f2f8280080ca0d200377406001b65Ted Kremenek} 42503524acc73f2f8280080ca0d200377406001b65Ted Kremenek 43503524acc73f2f8280080ca0d200377406001b65Ted Kremenek// Constructor for C++ records. 444ba2a17694148e16eaa8d3917f657ffcd3667be4Jay FoadASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, 45dac54c124e302d6f028ea5723c425b7f66fc7c71Ken Dyck CharUnits size, CharUnits alignment, 46441c6239c6df8c759bacf6510efbfd434b647066John McCall bool hasOwnVFPtr, CharUnits vbptroffset, 47227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman CharUnits datasize, 48147b5ddc6c8618a9d70a83f90de409e444ae705bAnders Carlsson const uint64_t *fieldoffsets, 49147b5ddc6c8618a9d70a83f90de409e444ae705bAnders Carlsson unsigned fieldcount, 505c3633fa57f27b0909ab5767715c4e66b8920165Ken Dyck CharUnits nonvirtualsize, 5168cf1a5a01ba43ed56a8624632fd65e0804430acKen Dyck CharUnits nonvirtualalign, 52a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits SizeOfLargestEmptySubobject, 5328fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson const CXXRecordDecl *PrimaryBase, 540b9fb2f6b4845bfe5e25b576ae8f2ffa284f9cb1Anders Carlsson bool IsPrimaryBaseVirtual, 55147b5ddc6c8618a9d70a83f90de409e444ae705bAnders Carlsson const BaseOffsetsMapTy& BaseOffsets, 56441c6239c6df8c759bacf6510efbfd434b647066John McCall const VBaseOffsetsMapTy& VBaseOffsets) 57441c6239c6df8c759bacf6510efbfd434b647066John McCall : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0), 58503524acc73f2f8280080ca0d200377406001b65Ted Kremenek FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo) 59503524acc73f2f8280080ca0d200377406001b65Ted Kremenek{ 60503524acc73f2f8280080ca0d200377406001b65Ted Kremenek if (FieldCount > 0) { 61503524acc73f2f8280080ca0d200377406001b65Ted Kremenek FieldOffsets = new (Ctx) uint64_t[FieldCount]; 62bb9357cf8f9b79fdf9af4613748d5dc4929c72d3Benjamin Kramer memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets)); 63503524acc73f2f8280080ca0d200377406001b65Ted Kremenek } 64503524acc73f2f8280080ca0d200377406001b65Ted Kremenek 650b9fb2f6b4845bfe5e25b576ae8f2ffa284f9cb1Anders Carlsson CXXInfo->PrimaryBase.setPointer(PrimaryBase); 660b9fb2f6b4845bfe5e25b576ae8f2ffa284f9cb1Anders Carlsson CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual); 67503524acc73f2f8280080ca0d200377406001b65Ted Kremenek CXXInfo->NonVirtualSize = nonvirtualsize; 68503524acc73f2f8280080ca0d200377406001b65Ted Kremenek CXXInfo->NonVirtualAlign = nonvirtualalign; 69c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject; 70147b5ddc6c8618a9d70a83f90de409e444ae705bAnders Carlsson CXXInfo->BaseOffsets = BaseOffsets; 71147b5ddc6c8618a9d70a83f90de409e444ae705bAnders Carlsson CXXInfo->VBaseOffsets = VBaseOffsets; 72441c6239c6df8c759bacf6510efbfd434b647066John McCall CXXInfo->HasOwnVFPtr = hasOwnVFPtr; 732fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman CXXInfo->VBPtrOffset = vbptroffset; 74b6ee4b0146266ff7ce37c7d0a0c036bda50aa813Anders Carlsson 75b6ee4b0146266ff7ce37c7d0a0c036bda50aa813Anders Carlsson#ifndef NDEBUG 76b6ee4b0146266ff7ce37c7d0a0c036bda50aa813Anders Carlsson if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) { 772fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman if (isPrimaryBaseVirtual()) { 782fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman // Microsoft ABI doesn't have primary virtual base 792fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman if (Ctx.getTargetInfo().getCXXABI() != CXXABI_Microsoft) { 803069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson assert(getVBaseClassOffset(PrimaryBase).isZero() && 81b6ee4b0146266ff7ce37c7d0a0c036bda50aa813Anders Carlsson "Primary virtual base must be at offset 0!"); 822fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman } 832fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman } else { 84d4f5198ae07d9a4958d8191bac694ded12173ad9Benjamin Kramer assert(getBaseClassOffset(PrimaryBase).isZero() && 85b6ee4b0146266ff7ce37c7d0a0c036bda50aa813Anders Carlsson "Primary base must be at offset 0!"); 862fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman } 87b6ee4b0146266ff7ce37c7d0a0c036bda50aa813Anders Carlsson } 88b6ee4b0146266ff7ce37c7d0a0c036bda50aa813Anders Carlsson#endif 89503524acc73f2f8280080ca0d200377406001b65Ted Kremenek} 90