diff options
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 6b5eaa112ce..4a1fb39bb60 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -295,6 +295,13 @@ ASTContext::getTypeInfo(QualType T) { Align = EltInfo.second; break; } + case Type::ObjCInterface: { + ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T); + const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); + Width = Layout.getSize(); + Align = Layout.getAlignment(); + break; + } case Type::Tagged: { if (EnumType *ET = dyn_cast<EnumType>(cast<TagType>(T))) return getTypeInfo(ET->getDecl()->getIntegerType()); @@ -386,6 +393,42 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo, Alignment = std::max(Alignment, FieldAlign); } + +/// getASTObjcInterfaceLayout - Get or compute information about the layout of the +/// specified Objective C, which indicates its size and ivar +/// position information. +const ASTRecordLayout & +ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) { + // Look up this layout, if already laid out, return what we have. + const ASTRecordLayout *&Entry = ASTObjCInterfaces[D]; + if (Entry) return *Entry; + + // Allocate and assign into ASTRecordLayouts here. The "Entry" reference can + // be invalidated (dangle) if the ASTRecordLayouts hashtable is inserted into. + ASTRecordLayout *NewEntry = new ASTRecordLayout(); + Entry = NewEntry; + + NewEntry->InitializeLayout(D->ivar_size()); + bool IsPacked = D->getAttr<PackedAttr>(); + + if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) + NewEntry->SetAlignment(std::max(NewEntry->getAlignment(), + AA->getAlignment())); + + // Layout each ivar sequentially. + unsigned i = 0; + for (ObjCInterfaceDecl::ivar_iterator IVI = D->ivar_begin(), + IVE = D->ivar_end(); IVI != IVE; ++IVI) { + const ObjCIvarDecl* Ivar = (*IVI); + NewEntry->LayoutField(Ivar, i++, false, IsPacked, *this); + } + + // Finally, round the size of the total struct up to the alignment of the + // struct itself. + NewEntry->FinalizeLayout(); + return *NewEntry; +} + /// getASTRecordLayout - Get or compute information about the layout of the /// specified record (struct/union/class), which indicates its size and field /// position information. |