Index: cfe/trunk/lib/Sema/SemaExprMember.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaExprMember.cpp +++ cfe/trunk/lib/Sema/SemaExprMember.cpp @@ -802,16 +802,13 @@ Expr *baseObjectExpr, SourceLocation opLoc) { // First, build the expression that refers to the base object. - - bool baseObjectIsPointer = false; - Qualifiers baseQuals; - + // Case 1: the base of the indirect field is not a field. VarDecl *baseVariable = indirectField->getVarDecl(); CXXScopeSpec EmptySS; if (baseVariable) { assert(baseVariable->getType()->isRecordType()); - + // In principle we could have a member access expression that // accesses an anonymous struct/union that's a static member of // the base object's class. However, under the current standard, @@ -824,68 +821,37 @@ ExprResult result = BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable); if (result.isInvalid()) return ExprError(); - - baseObjectExpr = result.get(); - baseObjectIsPointer = false; - baseQuals = baseObjectExpr->getType().getQualifiers(); - - // Case 2: the base of the indirect field is a field and the user - // wrote a member expression. - } else if (baseObjectExpr) { - // The caller provided the base object expression. Determine - // whether its a pointer and whether it adds any qualifiers to the - // anonymous struct/union fields we're looking into. - QualType objectType = baseObjectExpr->getType(); - - if (const PointerType *ptr = objectType->getAs()) { - baseObjectIsPointer = true; - objectType = ptr->getPointeeType(); - } else { - baseObjectIsPointer = false; - } - baseQuals = objectType.getQualifiers(); - - // Case 3: the base of the indirect field is a field and we should - // build an implicit member access. - } else { - // We've found a member of an anonymous struct/union that is - // inside a non-anonymous struct/union, so in a well-formed - // program our base object expression is "this". - QualType ThisTy = getCurrentThisType(); - if (ThisTy.isNull()) { - Diag(loc, diag::err_invalid_member_use_in_static_method) - << indirectField->getDeclName(); - return ExprError(); - } - - // Our base object expression is "this". - CheckCXXThisCapture(loc); - baseObjectExpr - = new (Context) CXXThisExpr(loc, ThisTy, /*isImplicit=*/ true); - baseObjectIsPointer = true; - baseQuals = ThisTy->castAs()->getPointeeType().getQualifiers(); + + baseObjectExpr = result.get(); } - + + assert((baseVariable || baseObjectExpr) && + "referencing anonymous struct/union without a base variable or " + "expression"); + // Build the implicit member references to the field of the // anonymous struct/union. Expr *result = baseObjectExpr; IndirectFieldDecl::chain_iterator FI = indirectField->chain_begin(), FEnd = indirectField->chain_end(); - - // Build the first member access in the chain with full information. + + // Case 2: the base of the indirect field is a field and the user + // wrote a member expression. if (!baseVariable) { FieldDecl *field = cast(*FI); - + + bool baseObjectIsPointer = baseObjectExpr->getType()->isPointerType(); + // Make a nameInfo that properly uses the anonymous name. DeclarationNameInfo memberNameInfo(field->getDeclName(), loc); - result = BuildFieldReferenceExpr(result, baseObjectIsPointer, - SourceLocation(), EmptySS, field, - foundDecl, memberNameInfo).get(); + // Build the first member access in the chain with full information. + result = + BuildFieldReferenceExpr(result, baseObjectIsPointer, SourceLocation(), + EmptySS, field, foundDecl, memberNameInfo) + .get(); if (!result) return ExprError(); - - // FIXME: check qualified member access } // In all cases, we should now skip the first declaration in the chain.