summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-02-18 02:44:58 +0000
committerDouglas Gregor <dgregor@apple.com>2011-02-18 02:44:58 +0000
commite10f36db2f32987562079c83b2e1b66e7575258c (patch)
treedd5d12fdef957a5df3c5b414268927621c015533
parenta7ced2cb4caa71ff09a4674bf4c7d9890eefb5e9 (diff)
downloadbcm5719-llvm-e10f36db2f32987562079c83b2e1b66e7575258c.tar.gz
bcm5719-llvm-e10f36db2f32987562079c83b2e1b66e7575258c.zip
When building a qualified reference to a member of an anonymous struct
or union, place the qualifier on the outermost member reference expression, which actually contains the entity name. Fixes PR9188/<rdar://problem/8990184>. llvm-svn: 125822
-rw-r--r--clang/lib/Sema/SemaExpr.cpp13
-rw-r--r--clang/test/SemaTemplate/instantiate-anonymous-union.cpp21
2 files changed, 28 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2b1b8b29054..92e671165b5 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1004,6 +1004,7 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
// Case 1: the base of the indirect field is not a field.
VarDecl *baseVariable = indirectField->getVarDecl();
+ CXXScopeSpec EmptySS;
if (baseVariable) {
assert(baseVariable->getType()->isRecordType());
@@ -1017,7 +1018,7 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
DeclarationNameInfo baseNameInfo(DeclarationName(), loc);
ExprResult result =
- BuildDeclarationNameExpr(SS, baseNameInfo, baseVariable);
+ BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable);
if (result.isInvalid()) return ExprError();
baseObjectExpr = result.take();
@@ -1078,7 +1079,7 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
result = BuildFieldReferenceExpr(*this, result, baseObjectIsPointer,
- SS, field, foundDecl,
+ EmptySS, field, foundDecl,
memberNameInfo).take();
baseObjectIsPointer = false;
@@ -1088,16 +1089,16 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
// In all cases, we should now skip the first declaration in the chain.
++FI;
- for (; FI != FEnd; FI++) {
- FieldDecl *field = cast<FieldDecl>(*FI);
+ while (FI != FEnd) {
+ FieldDecl *field = cast<FieldDecl>(*FI++);
// FIXME: these are somewhat meaningless
DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
DeclAccessPair foundDecl = DeclAccessPair::make(field, field->getAccess());
- CXXScopeSpec memberSS;
result = BuildFieldReferenceExpr(*this, result, /*isarrow*/ false,
- memberSS, field, foundDecl, memberNameInfo)
+ (FI == FEnd? SS : EmptySS), field,
+ foundDecl, memberNameInfo)
.take();
}
diff --git a/clang/test/SemaTemplate/instantiate-anonymous-union.cpp b/clang/test/SemaTemplate/instantiate-anonymous-union.cpp
index f2862db6bb7..68b233a7fda 100644
--- a/clang/test/SemaTemplate/instantiate-anonymous-union.cpp
+++ b/clang/test/SemaTemplate/instantiate-anonymous-union.cpp
@@ -66,3 +66,24 @@ namespace PR7402 {
X x(42.0);
}
+
+namespace PR9188 {
+ struct X0 {
+ union {
+ int member;
+ };
+ };
+
+ static union {
+ int global;
+ };
+
+ struct X1 : X0 {
+ template<typename T>
+ int f() {
+ return this->X0::member + PR9188::global;
+ }
+ };
+
+ template int X1::f<int>();
+}
OpenPOWER on IntegriCloud