]> granicus.if.org Git - clang/commitdiff
When building a qualified reference to a member of an anonymous struct
authorDouglas Gregor <dgregor@apple.com>
Fri, 18 Feb 2011 02:44:58 +0000 (02:44 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 18 Feb 2011 02:44:58 +0000 (02:44 +0000)
or union, place the qualifier on the outermost member reference
expression, which actually contains the entity name.

Fixes PR9188/<rdar://problem/8990184>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125822 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/SemaTemplate/instantiate-anonymous-union.cpp

index 2b1b8b29054f95554556206f1021bab995fe1779..92e671165b548e84607ca706911b416caa56e18b 100644 (file)
@@ -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();
   }
 
index f2862db6bb7f02aa86885c5d7d879333f84752bc..68b233a7fda7d47d04313a27a2ab8543b84d635b 100644 (file)
@@ -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>();
+}