<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">

<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<style>
<!--
 /* Font Definitions */
 @font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page Section1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.Section1
        {page:Section1;}
-->
</style>
<!--[if gte mso 9]><xml>
 <o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
 <o:shapelayout v:ext="edit">
  <o:idmap v:ext="edit" data="1" />
 </o:shapelayout></xml><![endif]-->
</head>

<body lang=EN-GB link=blue vlink=purple>

<div class=Section1>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Thank you very much for the quick turnaround. I’ve rebuilt and
the error messages have come back.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p> </o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Peter<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p> </o:p></span></p>

<div style='border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt'>

<div>

<div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'>

<p class=MsoNormal><b><span lang=EN-US style='font-size:10.0pt;font-family:
"Tahoma","sans-serif"'>From:</span></b><span lang=EN-US style='font-size:10.0pt;
font-family:"Tahoma","sans-serif"'> Kaelyn Takata [mailto:rikka@google.com] <br>
<b>Sent:</b> 02 December 2014 23:36<br>
<b>To:</b> Peter Smith<br>
<b>Cc:</b> cfe-commits@cs.uiuc.edu<br>
<b>Subject:</b> Re: r222464 - Wire up delayed typo correction to
DiagnoseEmptyLookup and set up<o:p></o:p></span></p>

</div>

</div>

<p class=MsoNormal><o:p> </o:p></p>

<div>

<p class=MsoNormal>It should be fixed in r223177.<o:p></o:p></p>

</div>

<div>

<p class=MsoNormal><o:p> </o:p></p>

<div>

<p class=MsoNormal>On Tue, Dec 2, 2014 at 2:13 PM, Kaelyn Takata <<a
href="mailto:rikka@google.com" target="_blank">rikka@google.com</a>> wrote:<o:p></o:p></p>

<div>

<p class=MsoNormal>Yeah I can investigate it. Looks like another situation
where TypoExprs (part of the delayed typo correction) are going undiagnosed but
for which there were no existing tests covering the associated code paths.
Thanks for coming up with a reduced test case!<o:p></o:p></p>

</div>

<div>

<div>

<div>

<p class=MsoNormal><o:p> </o:p></p>

<div>

<p class=MsoNormal>On Tue, Dec 2, 2014 at 8:16 AM, Peter Smith <<a
href="mailto:peter.smith@arm.com" target="_blank">peter.smith@arm.com</a>>
wrote:<o:p></o:p></p>

<div>

<div>

<p class=MsoNormal>Hello,<br>
<br>
I believe that this commit is causing some error messages that were<br>
previously emitted to be suppressed.<br>
<br>
The following testcase:<br>
// C++03 14.1:14 A template parameter shall not be used in its own default<br>
argument<br>
template <int I = (1*I)> struct S {};<br>
S<1> s;<br>
// C++03 14.1:13a The scope of a template-parameter extends from its point<br>
of declaration until the end of its template.<br>
template <int I1 = I2, int I2 = 1> struct T {};<br>
T<0, 1> t;<br>
<br>
When compiled with clang built prior to this commit; the output was:<br>
testcase.cpp:2:22: error: use of undeclared identifier 'I'<br>
template <int I = (1*I)> struct S {};<br>
                     ^<br>
testcase.cpp:5:20: error: use of undeclared identifier 'I2'<br>
template <int I1 = I2, int I2 = 1> struct T {};<br>
                   ^<br>
2 errors generated.<br>
<br>
After the commit no errors are generated.<br>
<br>
I'm assuming that this was an unexpected side-effect? Would it be possible<br>
for you to investigate?<br>
<br>
My apologies for taking so long to track these down into reproducible test<br>
case.<br>
<br>
Thanks in advance<br>
<br>
Peter<br>
<br>
> -----Original Message-----<br>
> From: <a href="mailto:cfe-commits-bounces@cs.uiuc.edu" target="_blank">cfe-commits-bounces@cs.uiuc.edu</a>
[mailto:<a href="mailto:cfe-commits-" target="_blank">cfe-commits-</a><br>
> <a href="mailto:bounces@cs.uiuc.edu" target="_blank">bounces@cs.uiuc.edu</a>]
On Behalf Of Kaelyn Takata<br>
> Sent: 20 November 2014 22:07<br>
> To: <a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><o:p></o:p></p>

</div>

</div>

<div>

<div>

<p class=MsoNormal>> Subject: r222464 - Wire up delayed typo correction to
DiagnoseEmptyLookup<br>
> and set up<br>
><br>
> Author: rikka<br>
> Date: Thu Nov 20 16:06:40 2014<br>
> New Revision: 222464<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=222464&view=rev"
target="_blank">http://llvm.org/viewvc/llvm-project?rev=222464&view=rev</a><br>
> Log:<br>
> Wire up delayed typo correction to DiagnoseEmptyLookup and set up<br>
> Sema::ActOnIdExpression to use the new functionality.<br>
><br>
> Among other things, this allows recovery in several cases where it<br>
> wasn't possible before (e.g. correcting a mistyped static_cast<>).<br>
><br>
> Modified:<br>
>     cfe/trunk/include/clang/Parse/Parser.h<br>
>     cfe/trunk/include/clang/Sema/Sema.h<br>
>     cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp<br>
>     cfe/trunk/lib/Parse/ParseDecl.cpp<br>
>     cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
>     cfe/trunk/lib/Parse/ParseExpr.cpp<br>
>     cfe/trunk/lib/Parse/ParseExprCXX.cpp<br>
>     cfe/trunk/lib/Parse/ParseObjc.cpp<br>
>     cfe/trunk/lib/Parse/ParseOpenMP.cpp<br>
>     cfe/trunk/lib/Parse/ParseStmt.cpp<br>
>     cfe/trunk/lib/Sema/SemaExpr.cpp<br>
>     cfe/trunk/lib/Sema/SemaStmt.cpp<br>
>     cfe/trunk/test/FixIt/fixit-unrecoverable.cpp<br>
>     cfe/trunk/test/SemaCXX/typo-correction.cpp<br>
>     cfe/trunk/test/SemaTemplate/crash-10438657.cpp<br>
><br>
> Modified: cfe/trunk/include/clang/Parse/Parser.h<o:p></o:p></p>

</div>

</div>

<p class=MsoNormal>> URL: <a href="http://llvm.org/viewvc/llvm-"
target="_blank">http://llvm.org/viewvc/llvm-</a><br>
><br>
project/cfe/trunk/include/clang/Parse/Parser.h?rev=222464&r1=222463&r2=22246<br>
> 4&view=diff<br>
><br>
============================================================================<br>
> ==<o:p></o:p></p>

<div>

<div>

<p class=MsoNormal>> --- cfe/trunk/include/clang/Parse/Parser.h (original)<br>
> +++ cfe/trunk/include/clang/Parse/Parser.h Thu Nov 20 16:06:40 2014<br>
> @@ -334,6 +334,15 @@ private:<br>
>    /// For typos, give a fixit to '='<br>
>    bool isTokenEqualOrEqualTypo();<br>
><br>
> +  /// \brief Return the current token to the token stream and make
the<br>
> given<br>
> +  /// token the current token.<br>
> +  void UnconsumeToken(Token &Consumed) {<br>
> +      Token Next = Tok;<br>
> +      PP.EnterToken(Consumed);<br>
> +      ConsumeToken();<br>
> +      PP.EnterToken(Next);<br>
> +  }<br>
> +<br>
>    /// ConsumeAnyToken - Dispatch to the right Consume* method
based on<br>
the<br>
>    /// current token type.  This should only be used in
cases where the<br>
type<br>
> of<br>
>    /// the token really isn't known, e.g. in error recovery.<br>
> @@ -1396,6 +1405,8 @@ private:<br>
><br>
><br>
//===--------------------------------------------------------------------<br>
> ===//<br>
>    // C++ Expressions<br>
> +  ExprResult tryParseCXXIdExpression(CXXScopeSpec &SS, bool<br>
> isAddressOfOperand,<br>
> +                   
                 Token
&Replacement);<br>
>    ExprResult ParseCXXIdExpression(bool isAddressOfOperand =
false);<br>
><br>
>    bool areTokensAdjacent(const Token &A, const Token
&B);<br>
><br>
> Modified: cfe/trunk/include/clang/Sema/Sema.h<o:p></o:p></p>

</div>

</div>

<p class=MsoNormal>> URL: <a href="http://llvm.org/viewvc/llvm-"
target="_blank">http://llvm.org/viewvc/llvm-</a><br>
><br>
project/cfe/trunk/include/clang/Sema/Sema.h?rev=222464&r1=222463&r2=222464&v<br>
> iew=diff<br>
><br>
============================================================================<br>
> ==<br>
> --- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
> +++ cfe/trunk/include/clang/Sema/Sema.h Thu Nov 20 16:06:40 2014<br>
> @@ -3463,7 +3463,7 @@ public:<br>
>        Scope *S, CXXScopeSpec &SS, SourceLocation
TemplateKWLoc,<br>
>        UnqualifiedId &Id, bool HasTrailingLParen,
bool IsAddressOfOperand,<br>
>       
std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr,<br>
> -      bool IsInlineAsmIdentifier = false);<br>
> +      bool IsInlineAsmIdentifier = false, Token
*KeywordReplacement =<br>
> nullptr);<br>
><br>
>    void DecomposeUnqualifiedId(const UnqualifiedId &Id,<br>
>                   
            TemplateArgumentListInfo &Buffer,<br>
> @@ -3474,7 +3474,7 @@ public:<br>
>    DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS,
LookupResult &R,<br>
>                   
    std::unique_ptr<CorrectionCandidateCallback> CCC,<br>
>                   
    TemplateArgumentListInfo *ExplicitTemplateArgs =<br>
> nullptr,<br>
> -                   
  ArrayRef<Expr *> Args = None);<br>
> +                   
  ArrayRef<Expr *> Args = None, TypoExpr **Out =<br>
> nullptr);<br>
><br>
>    ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope
*S,<br>
>                   
              IdentifierInfo *II,<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
><br>
project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=222464&r1=222463&r<br>
> 2=222464&view=diff<br>
><br>
============================================================================<br>
> ==<br>
> --- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Thu Nov 20 16:06:40 2014<br>
> @@ -336,6 +336,7 @@ void Parser::ParseLexedMethodDeclaration<br>
>          DefArgResult = ParseBraceInitializer();<br>
>        } else<br>
>          DefArgResult =
ParseAssignmentExpression();<br>
> +      DefArgResult =
Actions.CorrectDelayedTyposInExpr(DefArgResult);<br>
>        if (DefArgResult.isInvalid())<br>
>         
Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param,<br>
>                   
                     
       EqualLoc);<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
><br>
project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=222464&r1=222463&r2=222464&vie<br>
> w=diff<br>
><br>
============================================================================<br>
> ==<br>
> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Nov 20 16:06:40 2014<br>
> @@ -302,7 +302,8 @@ unsigned Parser::ParseAttributeArgsCommo<br>
>          Unevaluated.reset(<br>
>              new
EnterExpressionEvaluationContext(Actions,<br>
> Sema::Unevaluated));<br>
><br>
> -      ExprResult ArgExpr(ParseAssignmentExpression());<br>
> +      ExprResult ArgExpr(<br>
> +<br>
Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()));<br>
>        if (ArgExpr.isInvalid()) {<br>
>          SkipUntil(tok::r_paren, StopAtSemi);<br>
>          return 0;<br>
> @@ -5566,6 +5567,7 @@ void Parser::ParseParameterDeclarationCl<br>
>              DefArgResult =
ParseBraceInitializer();<br>
>            } else<br>
>              DefArgResult =
ParseAssignmentExpression();<br>
> +          DefArgResult =
Actions.CorrectDelayedTyposInExpr(DefArgResult);<br>
>            if (DefArgResult.isInvalid()) {<br>
>              Actions.ActOnParamDefaultArgumentError(Param,
EqualLoc);<br>
>              SkipUntil(tok::comma,
tok::r_paren, StopAtSemi |<br>
> StopBeforeMatch);<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
><br>
project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=222464&r1=222463&r2=222464&<br>
> view=diff<br>
><br>
============================================================================<br>
> ==<br>
> --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Nov 20 16:06:40 2014<br>
> @@ -796,7 +796,7 @@ SourceLocation Parser::ParseDecltypeSpec<br>
>        //   The operand of the decltype
specifier is an unevaluated<br>
operand.<br>
>        EnterExpressionEvaluationContext Unevaluated(Actions,<br>
> Sema::Unevaluated,<br>
><br>
> nullptr,/*IsDecltype=*/true);<br>
> -      Result = ParseExpression();<br>
> +      Result =
Actions.CorrectDelayedTyposInExpr(ParseExpression());<br>
>        if (Result.isInvalid()) {<br>
>          DS.SetTypeSpecError();<br>
>          if (SkipUntil(tok::r_paren, StopAtSemi |
StopBeforeMatch)) {<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseExpr.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
><br>
project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=222464&r1=222463&r2=222464&vie<br>
> w=diff<br>
><br>
============================================================================<br>
> ==<o:p></o:p></p>

<div>

<div>

<p class=MsoNormal>> --- cfe/trunk/lib/Parse/ParseExpr.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseExpr.cpp Thu Nov 20 16:06:40 2014<br>
> @@ -277,6 +277,7 @@ Parser::ParseRHSOfBinaryExpression(ExprR<br>
>          // 'logical-OR-expression' as we might
expect.<br>
>          TernaryMiddle = ParseExpression();<br>
>          if (TernaryMiddle.isInvalid()) {<br>
> +         
Actions.CorrectDelayedTyposInExpr(LHS);<br>
>            LHS = ExprError();<br>
>            TernaryMiddle = nullptr;<br>
>          }<br>
> @@ -345,9 +346,11 @@ Parser::ParseRHSOfBinaryExpression(ExprR<br>
>      else<br>
>        RHS = ParseCastExpression(false);<br>
><br>
> -    if (RHS.isInvalid())<br>
> +    if (RHS.isInvalid()) {<br>
> +      Actions.CorrectDelayedTyposInExpr(LHS);<br>
>        LHS = ExprError();<br>
> -<br>
> +    }<br>
> +<br>
>      // Remember the precedence of this operator and get
the precedence of<br>
> the<br>
>      // operator immediately to the right of the RHS.<br>
>      prec::Level ThisPrec = NextTokPrec;<br>
> @@ -376,8 +379,10 @@ Parser::ParseRHSOfBinaryExpression(ExprR<br>
>                   
          static_cast<prec::Level>(ThisPrec +<br>
> !isRightAssoc));<br>
>        RHSIsInitList = false;<br>
><br>
> -      if (RHS.isInvalid())<br>
> +      if (RHS.isInvalid()) {<br>
> +        Actions.CorrectDelayedTyposInExpr(LHS);<br>
>          LHS = ExprError();<br>
> +      }<br>
><br>
>        NextTokPrec = getBinOpPrecedence(Tok.getKind(),<br>
> GreaterThanIsOperator,<br>
>                   
                   
 getLangOpts().CPlusPlus11);<br>
> @@ -413,7 +418,9 @@ Parser::ParseRHSOfBinaryExpression(ExprR<br>
>          LHS =
Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,<br>
>                   
                     
 LHS.get(), TernaryMiddle.get(),<br>
>                   
                     
 RHS.get());<br>
> -    }<br>
> +    } else<br>
> +      // Ensure potential typos in the RHS aren't left
undiagnosed.<br>
> +      Actions.CorrectDelayedTyposInExpr(RHS);<br>
>    }<br>
>  }<br>
><br>
> @@ -441,7 +448,7 @@ class CastExpressionIdValidator : public<br>
>   public:<br>
>    CastExpressionIdValidator(bool AllowTypes, bool
AllowNonTypes)<br>
>        : AllowNonTypes(AllowNonTypes) {<br>
> -    WantTypeSpecifiers = AllowTypes;<br>
> +    WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes;<br>
>    }<br>
><br>
>    bool ValidateCandidate(const TypoCorrection &candidate)
override {<br>
> @@ -899,13 +906,20 @@ ExprResult Parser::ParseCastExpression(b<br>
>      UnqualifiedId Name;<br>
>      CXXScopeSpec ScopeSpec;<br>
>      SourceLocation TemplateKWLoc;<br>
> +    Token Replacement;<br>
>      auto Validator = llvm::make_unique<CastExpressionIdValidator>(<br>
>          isTypeCast != NotTypeCast, isTypeCast !=
IsTypeCast);<br>
>      Validator->IsAddressOfOperand = isAddressOfOperand;<br>
>      Name.setIdentifier(&II, ILoc);<br>
> -    Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec,<br>
> TemplateKWLoc,<br>
> -                   
                Name,
Tok.is(tok::l_paren),<br>
> -                   
                isAddressOfOperand,<br>
> std::move(Validator));<br>
> +    Res = Actions.ActOnIdExpression(<br>
> +        getCurScope(), ScopeSpec, TemplateKWLoc,
Name,<br>
> Tok.is(tok::l_paren),<br>
> +        isAddressOfOperand, std::move(Validator),<br>
> +        /*IsInlineAsmIdentifier=*/false,
&Replacement);<br>
> +    if (!Res.isInvalid() && !Res.get()) {<br>
> +      UnconsumeToken(Replacement);<br>
> +      return ParseCastExpression(isUnaryExpression,
isAddressOfOperand,<br>
> +                   
             NotCastExpr, isTypeCast);<br>
> +    }<br>
>      break;<br>
>    }<br>
>    case tok::char_constant:     // constant:
character-constant<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp<o:p></o:p></p>

</div>

</div>

<p class=MsoNormal>> URL: <a href="http://llvm.org/viewvc/llvm-"
target="_blank">http://llvm.org/viewvc/llvm-</a><br>
><br>
project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=222464&r1=222463&r2=222464&<br>
> view=diff<br>
><br>
============================================================================<br>
> ==<o:p></o:p></p>

<div>

<div>

<p class=MsoNormal>> --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Nov 20 16:06:40 2014<br>
> @@ -567,6 +567,28 @@ bool Parser::ParseOptionalCXXScopeSpecif<br>
>    return false;<br>
>  }<br>
><br>
> +ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS, bool<br>
> isAddressOfOperand,<br>
> +                   
                     
 Token &Replacement) {<br>
> +  SourceLocation TemplateKWLoc;<br>
> +  UnqualifiedId Name;<br>
> +  if (ParseUnqualifiedId(SS,<br>
> +                   
     /*EnteringContext=*/false,<br>
> +                   
     /*AllowDestructorName=*/false,<br>
> +                   
     /*AllowConstructorName=*/false,<br>
> +                   
     /*ObjectType=*/ParsedType(), TemplateKWLoc,<br>
Name))<br>
> +    return ExprError();<br>
> +<br>
> +  // This is only the direct operand of an & operator if it is
not<br>
> +  // followed by a postfix-expression suffix.<br>
> +  if (isAddressOfOperand &&
isPostfixExpressionSuffixStart())<br>
> +    isAddressOfOperand = false;<br>
> +<br>
> +  return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc,<br>
Name,<br>
> +                   
               Tok.is(tok::l_paren),<br>
> isAddressOfOperand,<br>
> +                   
               nullptr,<br>
> /*IsInlineAsmIdentifier=*/false,<br>
> +                   
               &Replacement);<br>
> +}<br>
> +<br>
>  /// ParseCXXIdExpression - Handle id-expression.<br>
>  ///<br>
>  ///       id-expression:<br>
> @@ -617,24 +639,17 @@ ExprResult Parser::ParseCXXIdExpression(<br>
>    CXXScopeSpec SS;<br>
>    ParseOptionalCXXScopeSpecifier(SS, ParsedType(),<br>
> /*EnteringContext=*/false);<br>
><br>
> -  SourceLocation TemplateKWLoc;<br>
> -  UnqualifiedId Name;<br>
> -  if (ParseUnqualifiedId(SS,<br>
> -                   
     /*EnteringContext=*/false,<br>
> -                   
     /*AllowDestructorName=*/false,<br>
> -                   
     /*AllowConstructorName=*/false,<br>
> -                   
     /*ObjectType=*/ ParsedType(),<br>
> -                   
     TemplateKWLoc,<br>
> -                   
     Name))<br>
> -    return ExprError();<br>
> -<br>
> -  // This is only the direct operand of an & operator if it is
not<br>
> -  // followed by a postfix-expression suffix.<br>
> -  if (isAddressOfOperand &&
isPostfixExpressionSuffixStart())<br>
> -    isAddressOfOperand = false;<br>
> -<br>
> -  return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc,<br>
Name,<br>
> -                   
               Tok.is(tok::l_paren),<br>
> isAddressOfOperand);<br>
> +  Token Replacement;<br>
> +  ExprResult Result = tryParseCXXIdExpression(SS,
isAddressOfOperand,<br>
> Replacement);<br>
> +  if (Result.isUnset()) {<br>
> +    // If the ExprResult is valid but null, then typo
correction<br>
suggested<br>
> a<br>
> +    // keyword replacement that needs to be reparsed.<br>
> +    UnconsumeToken(Replacement);<br>
> +    Result = tryParseCXXIdExpression(SS, isAddressOfOperand,<br>
Replacement);<br>
> +  }<br>
> +  assert(!Result.isUnset() && "Typo correction
suggested a keyword<br>
> replacement "<br>
> +                   
          "for a previous keyword
suggestion");<br>
> +  return Result;<br>
>  }<br>
><br>
>  /// ParseLambdaExpression - Parse a C++11 lambda expression.<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseObjc.cpp<o:p></o:p></p>

</div>

</div>

<p class=MsoNormal>> URL: <a href="http://llvm.org/viewvc/llvm-"
target="_blank">http://llvm.org/viewvc/llvm-</a><br>
><br>
project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=222464&r1=222463&r2=222464&vie<br>
> w=diff<br>
><br>
============================================================================<br>
> ==<br>
> --- cfe/trunk/lib/Parse/ParseObjc.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseObjc.cpp Thu Nov 20 16:06:40 2014<br>
> @@ -2170,7 +2170,10 @@ bool Parser::ParseObjCXXMessageReceiver(<br>
>    if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) {<br>
>      //   objc-receiver:<br>
>      //     expression<br>
> -    ExprResult Receiver = ParseExpression();<br>
> +    // Make sure any typos in the receiver are corrected or
diagnosed, so<br>
> that<br>
> +    // proper recovery can happen. FIXME: Perhaps filter the
corrected<br>
expr<br>
> to<br>
> +    // only the things that are valid ObjC receivers?<br>
> +    ExprResult Receiver =<br>
> Actions.CorrectDelayedTyposInExpr(ParseExpression());<br>
>      if (Receiver.isInvalid())<br>
>        return true;<br>
><br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
><br>
project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=222464&r1=222463&r2=222464&v<br>
> iew=diff<br>
><br>
============================================================================<br>
> ==<br>
> --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Thu Nov 20 16:06:40 2014<br>
> @@ -741,7 +741,8 @@ OMPClause *Parser::ParseOpenMPVarListCla<br>
>    if (MustHaveTail) {<br>
>      ColonLoc = Tok.getLocation();<br>
>      ConsumeToken();<br>
> -    ExprResult Tail = ParseAssignmentExpression();<br>
> +    ExprResult Tail =<br>
> +       
Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());<br>
>      if (Tail.isUsable())<br>
>        TailExpr = Tail.get();<br>
>      else<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseStmt.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
><br>
project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=222464&r1=222463&r2=222464&vie<br>
> w=diff<br>
><br>
============================================================================<br>
> ==<br>
> --- cfe/trunk/lib/Parse/ParseStmt.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseStmt.cpp Thu Nov 20 16:06:40 2014<br>
> @@ -642,6 +642,11 @@ StmtResult Parser::ParseCaseStatement(bo<br>
>      ExprResult LHS;<br>
>      if (!MissingCase) {<br>
>        LHS = ParseConstantExpression();<br>
> +      if (!getLangOpts().CPlusPlus11) {<br>
> +        LHS = Actions.CorrectDelayedTyposInExpr(LHS,
[this](class Expr<br>
*E)<br>
> {<br>
> +          return Actions.VerifyIntegerConstantExpression(E);<br>
> +        });<br>
> +      }<br>
>        if (LHS.isInvalid()) {<br>
>          // If constant-expression is parsed
unsuccessfully, recover by<br>
> skipping<br>
>          // current case statement (moving to the
colon that ends it).<br>
> @@ -1562,7 +1567,7 @@ StmtResult Parser::ParseForStatement(Sou<br>
>      }<br>
>    } else {<br>
>      ProhibitAttributes(attrs);<br>
> -    Value = ParseExpression();<br>
> +    Value =
Actions.CorrectDelayedTyposInExpr(ParseExpression());<br>
><br>
>      ForEach = isTokIdentifier_in();<br>
><br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
><br>
project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=222464&r1=222463&r2=222464&view=<br>
> diff<br>
><br>
============================================================================<br>
> ==<o:p></o:p></p>

<div>

<div>

<p class=MsoNormal>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Nov 20 16:06:40 2014<br>
> @@ -1673,6 +1673,40 @@ Sema::DecomposeUnqualifiedId(const Unqua<br>
>    }<br>
>  }<br>
><br>
> +static void emitEmptyLookupTypoDiagnostic(<br>
> +    const TypoCorrection &TC, Sema &SemaRef, const
CXXScopeSpec &SS,<br>
> +    DeclarationName Typo, SourceLocation TypoLoc,
ArrayRef<Expr *> Args,<br>
> +    unsigned DiagnosticID, unsigned DiagnosticSuggestID) {<br>
> +  DeclContext *Ctx =<br>
> +      SS.isEmpty() ? nullptr :
SemaRef.computeDeclContext(SS, false);<br>
> +  if (!TC) {<br>
> +    // Emit a special diagnostic for failed member lookups.<br>
> +    // FIXME: computing the declaration context might fail here
(?)<br>
> +    if (Ctx)<br>
> +      SemaRef.Diag(TypoLoc, diag::err_no_member) <<
Typo << Ctx<br>
> +                   
                     
       << SS.getRange();<br>
> +    else<br>
> +      SemaRef.Diag(TypoLoc, DiagnosticID) << Typo;<br>
> +    return;<br>
> +  }<br>
> +<br>
> +  std::string CorrectedStr = TC.getAsString(SemaRef.getLangOpts());<br>
> +  bool DroppedSpecifier =<br>
> +      TC.WillReplaceSpecifier() &&
Typo.getAsString() == CorrectedStr;<br>
> +  unsigned NoteID =<br>
> +      (TC.getCorrectionDecl() &&<br>
> isa<ImplicitParamDecl>(TC.getCorrectionDecl()))<br>
> +          ? diag::note_implicit_param_decl<br>
> +          : diag::note_previous_decl;<br>
> +  if (!Ctx)<br>
> +    SemaRef.diagnoseTypo(TC, SemaRef.PDiag(DiagnosticSuggestID)
<< Typo,<br>
> +                   
     SemaRef.PDiag(NoteID));<br>
> +  else<br>
> +    SemaRef.diagnoseTypo(TC,
SemaRef.PDiag(diag::err_no_member_suggest)<br>
> +                   
             << Typo << Ctx
<< DroppedSpecifier<br>
> +                   
             << SS.getRange(),<br>
> +                   
     SemaRef.PDiag(NoteID));<br>
> +}<br>
> +<br>
>  /// Diagnose an empty lookup.<br>
>  ///<br>
>  /// \return false if new lookup candidates were found<br>
> @@ -1680,7 +1714,7 @@ bool<br>
>  Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS,
LookupResult &R,<br>
>                   
        std::unique_ptr<CorrectionCandidateCallback><br>
CCC,<br>
>                   
        TemplateArgumentListInfo *ExplicitTemplateArgs,<br>
> -                   
      ArrayRef<Expr *> Args) {<br>
> +                   
      ArrayRef<Expr *> Args, TypoExpr **Out) {<br>
>    DeclarationName Name = R.getLookupName();<br>
><br>
>    unsigned diagnostic = diag::err_undeclared_var_use;<br>
> @@ -1797,8 +1831,22 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXS<br>
><br>
>    // We didn't find anything, so try to correct for a typo.<br>
>    TypoCorrection Corrected;<br>
> -  if (S && (Corrected = CorrectTypo(R.getLookupNameInfo(),<br>
> R.getLookupKind(),<br>
> -                   
                S, &SS,
std::move(CCC),<br>
> CTK_ErrorRecovery))) {<br>
> +  if (S && Out) {<br>
> +    SourceLocation TypoLoc = R.getNameLoc();<br>
> +    assert(!ExplicitTemplateArgs &&<br>
> +           "Diagnosing an empty lookup
with explicit template args!");<br>
> +    *Out = CorrectTypoDelayed(<br>
> +        R.getLookupNameInfo(), R.getLookupKind(), S,
&SS, std::move(CCC),<br>
> +        [=](const TypoCorrection &TC) {<br>
> +          emitEmptyLookupTypoDiagnostic(TC,
*this, SS, Name, TypoLoc,<br>
Args,<br>
> +                   
                   
diagnostic, diagnostic_suggest);<br>
> +        },<br>
> +        nullptr, CTK_ErrorRecovery);<br>
> +    if (*Out)<br>
> +      return true;<br>
> +  } else if (S && (Corrected =<br>
> +                   
   CorrectTypo(R.getLookupNameInfo(),<br>
> R.getLookupKind(), S,<br>
> +                   
               &SS, std::move(CCC),<br>
> CTK_ErrorRecovery))) {<br>
>      std::string
CorrectedStr(Corrected.getAsString(getLangOpts()));<br>
>      bool DroppedSpecifier =<br>
>          Corrected.WillReplaceSpecifier()
&& Name.getAsString() ==<br>
> CorrectedStr;<br>
> @@ -1950,7 +1998,7 @@ Sema::ActOnIdExpression(Scope *S, CXXSco<br>
>                   
      SourceLocation TemplateKWLoc, UnqualifiedId &Id,<br>
>                   
      bool HasTrailingLParen, bool IsAddressOfOperand,<br>
>                   
      std::unique_ptr<CorrectionCandidateCallback> CCC,<br>
> -                   
    bool IsInlineAsmIdentifier) {<br>
> +                   
    bool IsInlineAsmIdentifier, Token<br>
> *KeywordReplacement) {<br>
>    assert(!(IsAddressOfOperand && HasTrailingLParen)
&&<br>
>           "cannot be direct &
operand and have a trailing lparen");<br>
>    if (SS.isInvalid())<br>
> @@ -2062,13 +2110,43 @@ Sema::ActOnIdExpression(Scope *S, CXXSco<br>
><br>
>      // If this name wasn't predeclared and if this is not
a function<br>
>      // call, diagnose the problem.<br>
> -    auto DefaultValidator =<br>
> llvm::make_unique<CorrectionCandidateCallback>();<br>
> +    TypoExpr *TE = nullptr;<br>
> +    auto DefaultValidator =<br>
llvm::make_unique<CorrectionCandidateCallback>(<br>
> +        II, SS.isValid() ? SS.getScopeRep() :
nullptr);<br>
>      DefaultValidator->IsAddressOfOperand =
IsAddressOfOperand;<br>
>      assert((!CCC || CCC->IsAddressOfOperand ==
IsAddressOfOperand) &&<br>
>             "Typo correction
callback misconfigured");<br>
> -    if (DiagnoseEmptyLookup(S, SS, R,<br>
> -                   
        CCC ? std::move(CCC) :<br>
> std::move(DefaultValidator)))<br>
> -      return ExprError();<br>
> +    if (CCC) {<br>
> +      // Make sure the callback knows what the typo being
diagnosed is.<br>
> +      CCC->setTypoName(II);<br>
> +      if (SS.isValid())<br>
> +        CCC->setTypoNNS(SS.getScopeRep());<br>
> +    }<br>
> +    if (DiagnoseEmptyLookup(<br>
> +            S, SS, R, CCC ? std::move(CCC)
: std::move(DefaultValidator),<br>
> +            nullptr, None,
getLangOpts().CPlusPlus ? &TE : nullptr)) {<br>
> +      if (TE && KeywordReplacement) {<br>
> +        auto &State = getTypoExprState(TE);<br>
> +        auto BestTC =
State.Consumer->getNextCorrection();<br>
> +        if (BestTC.isKeyword()) {<br>
> +          auto *II =
BestTC.getCorrectionAsIdentifierInfo();<br>
> +          if (State.DiagHandler)<br>
> +            State.DiagHandler(BestTC);<br>
> +          KeywordReplacement->startToken();<br>
> +         
KeywordReplacement->setKind(II->getTokenID());<br>
> +          KeywordReplacement->setIdentifierInfo(II);<br>
> +          KeywordReplacement-<br>
> >setLocation(BestTC.getCorrectionRange().getBegin());<br>
> +          // Clean up the state associated with
the TypoExpr, since it<br>
has<br>
> +          // now been diagnosed (without a call
to<br>
> CorrectDelayedTyposInExpr).<br>
> +          clearDelayedTypo(TE);<br>
> +          // Signal that a correction to a
keyword was performed by<br>
> returning a<br>
> +          // valid-but-null ExprResult.<br>
> +          return (Expr*)nullptr;<br>
> +        }<br>
> +        State.Consumer->resetCorrectionStream();<br>
> +      }<br>
> +      return TE ? TE : ExprError();<br>
> +    }<br>
><br>
>      assert(!R.empty() &&<br>
>             "DiagnoseEmptyLookup
returned false but added no results");<br>
> @@ -12450,6 +12528,8 @@ void Sema::UpdateMarkingForLValueToRValu<br>
>  }<br>
><br>
>  ExprResult Sema::ActOnConstantExpression(ExprResult Res) {<br>
> +  Res = CorrectDelayedTyposInExpr(Res);<br>
> +<br>
>    if (!Res.isUsable())<br>
>      return Res;<br>
><br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaStmt.cpp<o:p></o:p></p>

</div>

</div>

<p class=MsoNormal>> URL: <a href="http://llvm.org/viewvc/llvm-"
target="_blank">http://llvm.org/viewvc/llvm-</a><br>
><br>
project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=222464&r1=222463&r2=222464&view=<br>
> diff<br>
><br>
============================================================================<br>
> ==<o:p></o:p></p>

<div>

<div>

<p class=MsoNormal>> --- cfe/trunk/lib/Sema/SemaStmt.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Nov 20 16:06:40 2014<br>
> @@ -371,6 +371,23 @@ Sema::ActOnCaseStmt(SourceLocation CaseL<br>
>      return StmtError();<br>
>    }<br>
><br>
> +  ExprResult LHS =<br>
> +      CorrectDelayedTyposInExpr(LHSVal, [this](class Expr
*E) {<br>
> +        if (!getLangOpts().CPlusPlus11)<br>
> +          return
VerifyIntegerConstantExpression(E);<br>
> +        if (Expr *CondExpr =<br>
> +               
getCurFunction()->SwitchStack.back()->getCond()) {<br>
> +          QualType CondType =
CondExpr->getType();<br>
> +          llvm::APSInt TempVal;<br>
> +          return
CheckConvertedConstantExpression(E, CondType, TempVal,<br>
> +                   
                     
              CCEK_CaseValue);<br>
> +        }<br>
> +        return ExprError();<br>
> +      });<br>
> +  if (LHS.isInvalid())<br>
> +    return StmtError();<br>
> +  LHSVal = LHS.get();<br>
> +<br>
>    if (!getLangOpts().CPlusPlus11) {<br>
>      // C99 6.8.4.2p3: The expression shall be an integer
constant.<br>
>      // However, GCC allows any evaluatable integer expression.<br>
> @@ -388,7 +405,7 @@ Sema::ActOnCaseStmt(SourceLocation CaseL<br>
>      }<br>
>    }<br>
><br>
> -  auto LHS = ActOnFinishFullExpr(LHSVal, LHSVal->getExprLoc(),
false,<br>
> +  LHS = ActOnFinishFullExpr(LHSVal, LHSVal->getExprLoc(), false,<br>
>                   
             
 getLangOpts().CPlusPlus11);<br>
>    if (LHS.isInvalid())<br>
>      return StmtError();<br>
><br>
> Modified: cfe/trunk/test/FixIt/fixit-unrecoverable.cpp<br>
> URL: <a
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-"
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-</a><br>
> unrecoverable.cpp?rev=222464&r1=222463&r2=222464&view=diff<br>
><br>
============================================================================<br>
> ==<br>
> --- cfe/trunk/test/FixIt/fixit-unrecoverable.cpp (original)<br>
> +++ cfe/trunk/test/FixIt/fixit-unrecoverable.cpp Thu Nov 20 16:06:40 2014<br>
> @@ -6,7 +6,5 @@<br>
>  // RUN: %clang_cc1 -fsyntax-only -verify %s<br>
><br>
>  float f(int y) {<br>
> -  return static_cst<float>(y); // expected-error{{use of
undeclared<br>
> identifier 'static_cst'; did you mean 'static_cast'?}} \<br>
> -  // expected-error{{for function-style cast or type construction}}<br>
> +  return static_cst<float>(y); // expected-error{{use of
undeclared<br>
> identifier 'static_cst'; did you mean 'static_cast'?}}<br>
>  }<br>
> -<br>
><br>
> Modified: cfe/trunk/test/SemaCXX/typo-correction.cpp<br>
> URL: <a
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/typo-"
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/typo-</a><br>
> correction.cpp?rev=222464&r1=222463&r2=222464&view=diff<br>
><br>
============================================================================<br>
> ==<br>
> --- cfe/trunk/test/SemaCXX/typo-correction.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/typo-correction.cpp Thu Nov 20 16:06:40 2014<br>
> @@ -209,11 +209,12 @@ namespace PR13051 {<br>
>    };<br>
><br>
>    void foo(); // expected-note{{'foo' declared here}}<br>
> -  void g(void(*)());<br>
> -  void g(bool(S<int>::*)() const);<br>
> +  void g(void(*)()); // expected-note{{candidate function not
viable}}<br>
> +  void g(bool(S<int>::*)() const); // expected-note{{candidate
function<br>
not<br>
> viable}}<br>
><br>
>    void test() {<br>
> -    g(&S<int>::tempalte f<int>); //
expected-error{{did you mean<br>
> 'template'?}}<br>
> +    g(&S<int>::tempalte f<int>); //
expected-error{{did you mean<br>
> 'template'?}} \<br>
> +                   
             // expected-error{{no matching
function<br>
> for call to 'g'}}<br>
>      g(&S<int>::opeartor bool); //
expected-error{{did you mean<br>
> 'operator'?}}<br>
>      g(&S<int>::foo); // expected-error{{no
member named 'foo' in<br>
> 'PR13051::S<int>'; did you mean simply 'foo'?}}<br>
>    }<br>
><br>
> Modified: cfe/trunk/test/SemaTemplate/crash-10438657.cpp<br>
> URL:<br>
<a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/crash-"
target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/crash-</a><br>
> 10438657.cpp?rev=222464&r1=222463&r2=222464&view=diff<br>
><br>
============================================================================<br>
> ==<br>
> --- cfe/trunk/test/SemaTemplate/crash-10438657.cpp (original)<br>
> +++ cfe/trunk/test/SemaTemplate/crash-10438657.cpp Thu Nov 20 16:06:40<br>
2014<br>
> @@ -1,6 +1,6 @@<br>
>  // RUN: not %clang_cc1 -fsyntax-only %s 2> %t<br>
>  // RUN: FileCheck %s < %t<br>
> -// CHECK: 10 errors<br>
> +// CHECK: 9 errors<br>
>  template<typename _CharT><br>
>  class collate : public locale::facet {<br>
><br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits"
target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br>
<br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><o:p></o:p></p>

</div>

</div>

</div>

<p class=MsoNormal><o:p> </o:p></p>

</div>

</div>

</div>

</div>

<p class=MsoNormal><o:p> </o:p></p>

</div>

</div>

</div>

</body>

</html>