Change getRedeclContext() to support enumerations as another kind of transparent context in C.
This change fixes PR15071 and ensures that enumerators redefined in a struct cannot conflict with enumerators defined outside of the struct.
llvm-svn: 345073
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index f5de359..f65d306 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -1724,8 +1724,18 @@
DeclContext *DeclContext::getRedeclContext() {
DeclContext *Ctx = this;
- // Skip through transparent contexts.
- while (Ctx->isTransparentContext())
+
+ // In C, a record type is the redeclaration context for its fields only. If
+ // we arrive at a record context after skipping anything else, we should skip
+ // the record as well. Currently, this means skipping enumerations because
+ // they're the only transparent context that can exist within a struct or
+ // union.
+ bool SkipRecords = getDeclKind() == Decl::Kind::Enum &&
+ !getParentASTContext().getLangOpts().CPlusPlus;
+
+ // Skip through contexts to get to the redeclaration context. Transparent
+ // contexts are always skipped.
+ while ((SkipRecords && Ctx->isRecord()) || Ctx->isTransparentContext())
Ctx = Ctx->getParent();
return Ctx;
}