From 7e3f0e4e0df371cb56732f5bd6995e34a4cf3089 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Tue, 25 Aug 2009 23:46:41 +0000 Subject: [PATCH] Parsing of pseudo-destructors. llvm-svn: 80055 --- clang/include/clang/Parse/Action.h | 11 +++++++++- clang/lib/Parse/ParseExpr.cpp | 32 ++++++++++++++++++++++-------- clang/lib/Sema/Sema.h | 8 ++++++++ clang/lib/Sema/SemaExpr.cpp | 1 - clang/lib/Sema/SemaExprCXX.cpp | 24 ++++++++++++++++++++++ 5 files changed, 66 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 3287e634eb3b..0146298c724b 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -1263,7 +1263,16 @@ public: return ExprEmpty(); } - + virtual OwningExprResult + ActOnPseudoDtorReferenceExpr(Scope *S, ExprArg Base, + SourceLocation OpLoc, + tok::TokenKind OpKind, + SourceLocation ClassNameLoc, + IdentifierInfo *ClassName, + const CXXScopeSpec *SS = 0) { + return ExprEmpty(); + } + /// ActOnFinishFullExpr - Called whenever a full expression has been parsed. /// (C++ [intro.execution]p12). virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr) { diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 7303f57ddeab..16d3511dd7fd 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -933,18 +933,34 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { ParseOptionalCXXScopeSpecifier(SS); } - if (Tok.isNot(tok::identifier)) { + if (Tok.is(tok::identifier)) { + if (!LHS.isInvalid()) + LHS = Actions.ActOnMemberReferenceExpr(CurScope, move(LHS), OpLoc, + OpKind, Tok.getLocation(), + *Tok.getIdentifierInfo(), + ObjCImpDecl, &SS); + } else if (getLang().CPlusPlus && Tok.is(tok::tilde)) { + // We have a C++ pseudo-destructor. + + // Consume the tilde. + ConsumeToken(); + + if (!Tok.is(tok::identifier)) { + Diag(Tok, diag::err_expected_ident); + return ExprError(); + } + + if (!LHS.isInvalid()) + LHS = Actions.ActOnPseudoDtorReferenceExpr(CurScope, move(LHS), + OpLoc, OpKind, + Tok.getLocation(), + Tok.getIdentifierInfo(), + &SS); + } else { Diag(Tok, diag::err_expected_ident); return ExprError(); } - if (!LHS.isInvalid()) { - LHS = Actions.ActOnMemberReferenceExpr(CurScope, move(LHS), OpLoc, - OpKind, Tok.getLocation(), - *Tok.getIdentifierInfo(), - ObjCImpDecl, &SS); - } - if (getLang().CPlusPlus) Actions.ActOnCXXExitMemberScope(CurScope, MemberSS); diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 9db3fae036a5..7a11a6030221 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1921,6 +1921,14 @@ public: TypeTy *Ty, SourceLocation RParen); + virtual OwningExprResult + ActOnPseudoDtorReferenceExpr(Scope *S, ExprArg Base, + SourceLocation OpLoc, + tok::TokenKind OpKind, + SourceLocation ClassNameLoc, + IdentifierInfo *ClassName, + const CXXScopeSpec *SS = 0); + /// MaybeCreateCXXExprWithTemporaries - If the list of temporaries is /// non-empty, will create a new CXXExprWithTemporaries expression. /// Otherwise, just returs the passed in expression. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index f6ad2a6c692a..b670cf7a280e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1958,7 +1958,6 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, tok::TokenKind OpKind, SourceLocation MemberLoc, IdentifierInfo &Member, DeclPtrTy ObjCImpDecl, const CXXScopeSpec *SS) { - // FIXME: handle the CXXScopeSpec for proper lookup of qualified-ids if (SS && SS->isInvalid()) return ExprError(); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index aefec6a7a689..a714f327d4dc 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1682,11 +1682,35 @@ Expr *Sema::MaybeCreateCXXExprWithTemporaries(Expr *SubExpr, return E; } +Sema::OwningExprResult +Sema::ActOnPseudoDtorReferenceExpr(Scope *S, ExprArg Base, + SourceLocation OpLoc, + tok::TokenKind OpKind, + SourceLocation ClassNameLoc, + IdentifierInfo *ClassName, + const CXXScopeSpec *SS) { + if (SS && SS->isInvalid()) + return ExprError(); + + // Since this might be a postfix expression, get rid of ParenListExprs. + Base = MaybeConvertParenListExprToParenExpr(S, move(Base)); + + Expr *BaseExpr = Base.takeAs(); + assert(BaseExpr && "no record expression"); + + // Perform default conversions. + DefaultFunctionArrayConversion(BaseExpr); + + QualType BaseType = BaseExpr->getType(); + return ExprError(); +} + Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) { Expr *FullExpr = Arg.takeAs(); if (FullExpr) FullExpr = MaybeCreateCXXExprWithTemporaries(FullExpr, /*ShouldDestroyTemps=*/true); + return Owned(FullExpr); }