Teach __builtin_offsetof to compute the offsets of members of base
classes, since we only warn (not error) on offsetof() for non-POD
types. We store the base path within the OffsetOfExpr itself, then
evaluate the offsets within the constant evaluator.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102571 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 3785848..d8d525e 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -16,6 +16,7 @@
#include "Lookup.h"
#include "AnalysisBasedWarnings.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
@@ -6736,6 +6737,19 @@
return ExprError();
}
+ // If the member was found in a base class, introduce OffsetOfNodes for
+ // the base class indirections.
+ CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+ /*DetectVirtual=*/false);
+ if (IsDerivedFrom(CurrentType,
+ Context.getTypeDeclType(MemberDecl->getParent()),
+ Paths)) {
+ CXXBasePath &Path = Paths.front();
+ for (CXXBasePath::iterator B = Path.begin(), BEnd = Path.end();
+ B != BEnd; ++B)
+ Comps.push_back(OffsetOfNode(B->Base));
+ }
+
if (cast<RecordDecl>(MemberDecl->getDeclContext())->
isAnonymousStructOrUnion()) {
llvm::SmallVector<FieldDecl*, 4> Path;