diff options
-rw-r--r-- | include/clang/AST/ASTContext.h | 6 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 8 | ||||
-rw-r--r-- | lib/AST/RecordLayoutBuilder.cpp | 24 | ||||
-rw-r--r-- | test/SemaCXX/empty-class-layout.cpp | 11 |
4 files changed, 37 insertions, 12 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index d9b0e79dbc..bdd87be369 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -889,9 +889,9 @@ public: return dyn_cast_or_null<IncompleteArrayType>(getAsArrayType(T)); } - /// getBaseElementType - Returns the innermost element type of a variable - /// length array type. For example, will return "int" for int[m][n] - QualType getBaseElementType(const VariableArrayType *VAT); + /// getBaseElementType - Returns the innermost element type of an array type. + /// For example, will return "int" for int[m][n] + QualType getBaseElementType(const ArrayType *VAT); /// getBaseElementType - Returns the innermost element type of a type /// (which needn't actually be an array type). diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 2654a0e735..41e8d3604e 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2407,11 +2407,11 @@ QualType ASTContext::getBaseElementType(QualType QT) { } } -QualType ASTContext::getBaseElementType(const VariableArrayType *VAT) { - QualType ElemTy = VAT->getElementType(); +QualType ASTContext::getBaseElementType(const ArrayType *AT) { + QualType ElemTy = AT->getElementType(); - if (const VariableArrayType *VAT = getAsVariableArrayType(ElemTy)) - return getBaseElementType(VAT); + if (const ArrayType *AT = getAsArrayType(ElemTy)) + return getBaseElementType(AT); return ElemTy; } diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 38c3e37352..09a2eff54c 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -254,12 +254,32 @@ bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD, bool ASTRecordLayoutBuilder::canPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) const { - if (const RecordType *RT = dyn_cast<RecordType>(FD->getType())) { + QualType T = FD->getType(); + if (const RecordType *RT = T->getAs<RecordType>()) { if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) return canPlaceRecordAtOffset(RD, Offset); } - // FIXME: Arrays. + if (const ConstantArrayType *AT = Ctx.getAsConstantArrayType(T)) { + QualType ElemTy = Ctx.getBaseElementType(AT); + const RecordType *RT = ElemTy->getAs<RecordType>(); + if (!RT) + return true; + const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); + if (!RD) + return true; + + const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD); + + uint64_t NumElements = Ctx.getConstantArrayElementCount(AT); + unsigned ElementOffset = Offset; + for (uint64_t I = 0; I != NumElements; ++I) { + if (!canPlaceRecordAtOffset(RD, ElementOffset)) + return false; + + ElementOffset += Info.getSize(); + } + } return true; } diff --git a/test/SemaCXX/empty-class-layout.cpp b/test/SemaCXX/empty-class-layout.cpp index 625e3ee903..fbe2cbe6b4 100644 --- a/test/SemaCXX/empty-class-layout.cpp +++ b/test/SemaCXX/empty-class-layout.cpp @@ -18,9 +18,14 @@ struct F : E { }; struct G : E, F { }; SA(3, sizeof(G) == 2); -struct H { H(); }; +struct Empty { Empty(); }; -struct I : H { - H h; +struct I : Empty { + Empty e; }; SA(4, sizeof(I) == 2); + +struct J : Empty { + Empty e[2]; +}; +SA(5, sizeof(J) == 3);
\ No newline at end of file |