diff options
Diffstat (limited to 'clang/lib/AST/RecordLayoutBuilder.cpp')
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index d104e3a7690..326a1dcd270 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -663,6 +663,31 @@ void ASTRecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) { Alignment = NewAlignment; } +static const CXXMethodDecl *GetKeyFunction(const CXXRecordDecl *RD) { + if (!RD->isDynamicClass()) + return 0; + + for (CXXRecordDecl::method_iterator I = RD->method_begin(), + E = RD->method_end(); I != E; ++I) { + const CXXMethodDecl *MD = *I; + + if (!MD->isVirtual()) + continue; + + if (MD->isPure()) + continue; + + const FunctionDecl *fn; + if (MD->getBody(fn) && !fn->isOutOfLine()) + continue; + + // We found it. + return MD; + } + + return 0; +} + const ASTRecordLayout * ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx, const RecordDecl *D) { @@ -686,6 +711,8 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx, uint64_t NonVirtualSize = IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize; + const CXXMethodDecl *KeyFunction = GetKeyFunction(cast<CXXRecordDecl>(D)); + return new ASTRecordLayout(Builder.Size, Builder.Alignment, DataSize, Builder.FieldOffsets.data(), Builder.FieldOffsets.size(), @@ -695,7 +722,8 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx, Builder.Bases.data(), Builder.Bases.size(), Builder.VBases.data(), - Builder.VBases.size()); + Builder.VBases.size(), + KeyFunction); } const ASTRecordLayout * |