diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-02-18 02:44:58 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-02-18 02:44:58 +0000 |
commit | e10f36db2f32987562079c83b2e1b66e7575258c (patch) | |
tree | dd5d12fdef957a5df3c5b414268927621c015533 | |
parent | a7ced2cb4caa71ff09a4674bf4c7d9890eefb5e9 (diff) | |
download | bcm5719-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.cpp | 13 | ||||
-rw-r--r-- | clang/test/SemaTemplate/instantiate-anonymous-union.cpp | 21 |
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>(); +} |