<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Aug 25, 2009, at 4:46 PM, Anders Carlsson wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Author: andersca<br>Date: Tue Aug 25 18:46:41 2009<br>New Revision: 80055<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=80055&view=rev">http://llvm.org/viewvc/llvm-project?rev=80055&view=rev</a><br>Log:<br>Parsing of pseudo-destructors.<br></div></blockquote><div><br></div>Cool.</div><div><br><blockquote type="cite"><div>Modified:<br>    cfe/trunk/include/clang/Parse/Action.h<br>    cfe/trunk/lib/Parse/ParseExpr.cpp<br>    cfe/trunk/lib/Sema/Sema.h<br>    cfe/trunk/lib/Sema/SemaExpr.cpp<br>    cfe/trunk/lib/Sema/SemaExprCXX.cpp<br><br>Modified: cfe/trunk/include/clang/Parse/Action.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=80055&r1=80054&r2=80055&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=80055&r1=80054&r2=80055&view=diff</a><br><br>==============================================================================<br>--- cfe/trunk/include/clang/Parse/Action.h (original)<br>+++ cfe/trunk/include/clang/Parse/Action.h Tue Aug 25 18:46:41 2009<br>@@ -1263,7 +1263,16 @@<br>     return ExprEmpty();<br>   }<br><br>-<br>+  virtual OwningExprResult<br>+  ActOnPseudoDtorReferenceExpr(Scope *S, ExprArg Base,<br>+                               SourceLocation OpLoc,<br>+                               tok::TokenKind OpKind,<br>+                               SourceLocation ClassNameLoc,<br>+                               IdentifierInfo *ClassName,<br>+                               const CXXScopeSpec *SS = 0) {<br>+    return ExprEmpty();<br>+  }<br></div></blockquote><div><br></div>No documentation? :)</div><div><br><blockquote type="cite"><div>   /// ActOnFinishFullExpr - Called whenever a full expression has been parsed.<br>   /// (C++ [intro.execution]p12).<br>   virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr) {<br><br>Modified: cfe/trunk/lib/Parse/ParseExpr.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=80055&r1=80054&r2=80055&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=80055&r1=80054&r2=80055&view=diff</a><br><br>==============================================================================<br>--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)<br>+++ cfe/trunk/lib/Parse/ParseExpr.cpp Tue Aug 25 18:46:41 2009<br>@@ -933,18 +933,34 @@<br>         ParseOptionalCXXScopeSpecifier(SS);<br>       }<br><br>-      if (Tok.isNot(tok::identifier)) {<br>+      if (<a href="http://Tok.is">Tok.is</a>(tok::identifier)) {<br>+        if (!LHS.isInvalid())<br>+          LHS = Actions.ActOnMemberReferenceExpr(CurScope, move(LHS), OpLoc,<br>+                                                 OpKind, Tok.getLocation(),<br>+                                                 *Tok.getIdentifierInfo(),<br>+                                                 ObjCImpDecl, &SS);<br>+      } else if (getLang().CPlusPlus && <a href="http://Tok.is">Tok.is</a>(tok::tilde)) {<br>+        // We have a C++ pseudo-destructor.<br>+        <br>+        // Consume the tilde.<br>+        ConsumeToken();<br>+        <br>+        if (!Tok.is(tok::identifier)) {<br>+          Diag(Tok, diag::err_expected_ident);<br>+          return ExprError();<br>+        }<br>+        <br>+        if (!LHS.isInvalid())<br>+          LHS = Actions.ActOnPseudoDtorReferenceExpr(CurScope, move(LHS), <br>+                                                     OpLoc, OpKind,<br>+                                                     Tok.getLocation(), <br>+                                                     Tok.getIdentifierInfo(),<br>+                                                     &SS);<br></div></blockquote><div><br></div><div>There's an oddity in the grammar here that might cause confusion. In particular, something like this:</div><div><br></div><div>  t.~T()</div><div><br></div><div>syntactically looks like both a</div><div><br></div><div>  postfix-expression . pseudo-destructor-name</div><div><br></div><div>and a </div><div><br></div><div>  postfix-expression . template[opt] id-expression</div><div><br></div><div>so both go through the same path in the parser. Whether it is actually a pseudo-destructor or whether it is a call to the destructor is something that semantic analysis determines, which makes the action name ActOnPseudoDtorReferenceExpr a bit misleading. Perhaps we should call it ActOnDestructorReferenceExpr?</div><div><br></div><blockquote type="cite"><div>+Sema::OwningExprResult<br>+Sema::ActOnPseudoDtorReferenceExpr(Scope *S, ExprArg Base,<br>+                                   SourceLocation OpLoc,<br>+                                   tok::TokenKind OpKind,<br>+                                   SourceLocation ClassNameLoc,<br>+                                   IdentifierInfo *ClassName,<br>+                                   const CXXScopeSpec *SS) {<br>+  if (SS && SS->isInvalid())<br>+    return ExprError();<br>+  <br>+  // Since this might be a postfix expression, get rid of ParenListExprs.<br>+  Base = MaybeConvertParenListExprToParenExpr(S, move(Base));<br>+  <br>+  Expr *BaseExpr = Base.takeAs<Expr>();<br>+  assert(BaseExpr && "no record expression");<br>+  <br>+  // Perform default conversions.<br>+  DefaultFunctionArrayConversion(BaseExpr);<br></div></blockquote><br></div><div>Should check here to determine whether the type of Base is a scalar type or pointer to a scalar type (depending on . vs ->), and of course turn this into an actual member reference (e.g., via a call to ActOnMemberReferenceExpr) when the type is a class type.</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">  </span>- Doug</div></body></html>