[cfe-commits] [patch] Better diagnostics in for-range expressions.

Richard Smith richard at metafoo.co.uk
Thu Aug 16 15:14:39 PDT 2012


On Thu, Aug 16, 2012 at 2:56 PM, Sam Panzer <panzer at google.com> wrote:

> Here's the next update for this patch.
>
>
> On Wed, Aug 15, 2012 at 4:29 PM, Richard Smith <richard at metafoo.co.uk>wrote:
>
[...]

> > +  if (CXXRecordDecl *D = RangeType->getAsCXXRecordDecl()) {
>
> > +    // - if _RangeT is a class type, the unqualified-ids begin and end
>> are
>> > +    //   looked up in the scope of class _RangeT as if by class member
>> access
>> > +    //   lookup (3.4.5), and if either (or both) finds at least one
>> > +    //   declaration, begin-expr and end-expr are __range.begin() and
>> > +    //   __range.end(), respectively;
>> > +    SemaRef.LookupQualifiedName(BeginMemberLookup, D);
>> > +    SemaRef.LookupQualifiedName(EndMemberLookup, D);
>> > +
>> > +    if (BeginMemberLookup.empty() != EndMemberLookup.empty()) {
>> > +      *BEF = BeginMemberLookup.empty() ? Sema::BEF_end :
>> Sema::BEF_begin;
>> > +      return Sema::FRS_BeginEndMismatch;
>>
>> Can you just issue the diagnostic directly here? I don't think we should
>> attempt recovery in this case. (My "If there's a viable begin() but lookup
>> for end() fails" comment was intended to apply to this case too.)
>>
>>
> Yes, though this means that I have two "diagnostic emitted" error codes:
> one which needs the type and which of begin/end failed to be noted, and a
> second which needs no extra diagnostics.
>

I think previously I suggested that you should emit note_for_range_type
directly in BuildForRangeBeginEndCall; that still seems like the best way
to address this. I would also suggest that you don't emit the note in the
case where FinishForRangeVarDecl fails, since in that case we've already
emitted a diagnostic explaining what we're doing.


> > +    }
>> > +  } else {
>> > +    // - otherwise, begin-expr and end-expr are begin(__range) and
>> > +    //   end(__range), respectively, where begin and end are looked up
>> with
>> > +    //   argument-dependent lookup (3.4.2). For the purposes of this
>> name
>> > +    //   lookup, namespace std is an associated namespace.
>> > +
>> > +  }
>> > +
>>  > +  *BEF = Sema::BEF_begin;
>> > +  Sema::ForRangeStatus RangeStatus =
>> > +      SemaRef.BuildForRangeBeginEndCall(S, ColonLoc, ColonLoc,
>> BeginVar,
>> > +                                        Sema::BEF_begin, BeginNameInfo,
>> > +                                        BeginMemberLookup,
>> CandidateSet,
>> > +                                        BeginRange, BeginExpr);
>> > +  if (RangeStatus != Sema::FRS_Success)
>> > +    return RangeStatus;
>> > +
>> > +  *BEF = Sema::BEF_end;
>> > +  RangeStatus =
>> > +      SemaRef.BuildForRangeBeginEndCall(S, ColonLoc, ColonLoc, EndVar,
>> > +                                        Sema::BEF_end, EndNameInfo,
>> > +                                        EndMemberLookup, CandidateSet,
>> > +                                        EndRange, EndExpr);
>> > +  return RangeStatus;
>> > +}
>> > +
>> > +/// Speculatively attempt to dereference an invalid range expression.
>> > +/// This function will not emit diagnostics, but returns StmtError if
>> > +/// an error occurs.
>> > +static StmtResult RetryWithDereferencedRange(Sema &SemaRef, Scope *S,
>>
>> Please include something about ForRange in this function name.
>>
>
> How about RebuildForRangeWithDereference?
>

SGTM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120816/6daaaa2d/attachment.html>


More information about the cfe-commits mailing list