mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
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
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user