diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-11-03 19:44:04 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-11-03 19:44:04 +0000 |
commit | 2d1c21414199a7452f122598189363a3922605b1 (patch) | |
tree | 927e5c12e6a452e070293b13047f49a08db4a140 /lib/Sema/SemaExpr.cpp | |
parent | 6c94a6d77f456f23ecd4c2061e6413786b5e6571 (diff) |
Replace the code that parses member access expressions after "." or
"->" with a use of ParseUnqualifiedId. Collapse
ActOnMemberReferenceExpr, ActOnDestructorReferenceExpr (both of them),
ActOnOverloadedOperatorReferenceExpr,
ActOnConversionOperatorReferenceExpr, and
ActOnMemberTemplateIdReferenceExpr into a single, new action
ActOnMemberAccessExpr that does the same thing more cleanly (and can
keep more source-location information).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85930 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 73 |
1 files changed, 66 insertions, 7 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 63d39a05e4..f71fb643f9 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2479,13 +2479,72 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, return ExprError(); } -Action::OwningExprResult -Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, - tok::TokenKind OpKind, SourceLocation MemberLoc, - IdentifierInfo &Member, - DeclPtrTy ObjCImpDecl, const CXXScopeSpec *SS) { - return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, MemberLoc, - DeclarationName(&Member), ObjCImpDecl, SS); +Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg Base, + SourceLocation OpLoc, + tok::TokenKind OpKind, + const CXXScopeSpec &SS, + UnqualifiedId &Member, + DeclPtrTy ObjCImpDecl, + bool HasTrailingLParen) { + if (Member.getKind() == UnqualifiedId::IK_TemplateId) { + TemplateName Template + = TemplateName::getFromVoidPointer(Member.TemplateId->Template); + + // FIXME: We're going to end up looking up the template based on its name, + // twice! + DeclarationName Name; + if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl()) + Name = ActualTemplate->getDeclName(); + else if (OverloadedFunctionDecl *Ovl = Template.getAsOverloadedFunctionDecl()) + Name = Ovl->getDeclName(); + else + Name = Template.getAsDependentTemplateName()->getName(); + + // Translate the parser's template argument list in our AST format. + ASTTemplateArgsPtr TemplateArgsPtr(*this, + Member.TemplateId->getTemplateArgs(), + Member.TemplateId->getTemplateArgIsType(), + Member.TemplateId->NumArgs); + + llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs; + translateTemplateArguments(TemplateArgsPtr, + Member.TemplateId->getTemplateArgLocations(), + TemplateArgs); + TemplateArgsPtr.release(); + + // Do we have the save the actual template name? We might need it... + return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, + Member.TemplateId->TemplateNameLoc, + Name, true, Member.TemplateId->LAngleLoc, + TemplateArgs.data(), TemplateArgs.size(), + Member.TemplateId->RAngleLoc, DeclPtrTy(), + &SS); + } + + // FIXME: We lose a lot of source information by mapping directly to the + // DeclarationName. + OwningExprResult Result + = BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, + Member.getSourceRange().getBegin(), + GetNameFromUnqualifiedId(Member), + ObjCImpDecl, &SS); + + if (Result.isInvalid() || HasTrailingLParen || + Member.getKind() != UnqualifiedId::IK_DestructorName) + 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(Member.getSourceRange().getEnd()); + 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 Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, |