diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-09-04 18:29:40 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-09-04 18:29:40 +0000 |
commit | bddb73fa1df420fd9e86d005e1782ed343a3154b (patch) | |
tree | 63e2cb58849c59c9f6e39197dfe25da1af5e323f /clang/lib/Sema/SemaExprCXX.cpp | |
parent | 5a522353c3bce98d39d91823ac7e1c8950100db7 (diff) | |
download | bcm5719-llvm-bddb73fa1df420fd9e86d005e1782ed343a3154b.tar.gz bcm5719-llvm-bddb73fa1df420fd9e86d005e1782ed343a3154b.zip |
If a destructor is referenced or a pseudo-destructor expression is
formed without a trailing '(', diagnose the error (these expressions
must be immediately called), emit a fix-it hint, and fix the code.
llvm-svn: 81015
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 4d49f87a9a8..99d80944baa 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1817,16 +1817,17 @@ Sema::ActOnDestructorReferenceExpr(Scope *S, ExprArg Base, tok::TokenKind OpKind, SourceLocation ClassNameLoc, IdentifierInfo *ClassName, - const CXXScopeSpec *SS) { - if (SS && SS->isInvalid()) + const CXXScopeSpec &SS, + bool HasTrailingLParen) { + if (SS.isInvalid()) return ExprError(); QualType BaseType; - if (SS && isUnknownSpecialization(*SS)) - BaseType = Context.getTypenameType((NestedNameSpecifier *)SS->getScopeRep(), + if (isUnknownSpecialization(SS)) + BaseType = Context.getTypenameType((NestedNameSpecifier *)SS.getScopeRep(), ClassName); else { - TypeTy *BaseTy = getTypeName(*ClassName, ClassNameLoc, S, SS); + TypeTy *BaseTy = getTypeName(*ClassName, ClassNameLoc, S, &SS); if (!BaseTy) { Diag(ClassNameLoc, diag::err_ident_in_pseudo_dtor_not_a_type) << ClassName; @@ -1840,8 +1841,23 @@ Sema::ActOnDestructorReferenceExpr(Scope *S, ExprArg Base, DeclarationName DtorName = Context.DeclarationNames.getCXXDestructorName(CanBaseType); - return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, ClassNameLoc, - DtorName, DeclPtrTy(), SS); + OwningExprResult Result + = BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, ClassNameLoc, + DtorName, DeclPtrTy(), &SS); + if (Result.isInvalid() || HasTrailingLParen) + return move(Result); + + // The only way a reference to a destructor can be used is to + // immediately call them. Since the next token is not a '(', produce a + // diagnostic and build the call now. + Expr *E = (Expr *)Result.get(); + SourceLocation ExpectedLParenLoc = PP.getLocForEndOfToken(E->getLocEnd()); + Diag(E->getLocStart(), diag::err_dtor_expr_without_call) + << isa<CXXPseudoDestructorExpr>(E) + << CodeModificationHint::CreateInsertion(ExpectedLParenLoc, "()"); + + return ActOnCallExpr(0, move(Result), ExpectedLParenLoc, + MultiExprArg(*this, 0, 0), 0, ExpectedLParenLoc); } Sema::OwningExprResult |