diff options
author | David Blaikie <dblaikie@gmail.com> | 2011-12-16 16:03:09 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2011-12-16 16:03:09 +0000 |
commit | 91ec7894ec186dd36f509682f00486c98d8228ed (patch) | |
tree | cd1be2e88bce92c22296a1293f3de6e570deadad /lib/Sema/SemaExprCXX.cpp | |
parent | 6b65d4a9cc5aed96a7f1a36e75dd9c4adb164e0b (diff) |
Support decltype in pseudo destructors and dependent destructor calls.
Reviewed by Eli Friedman.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146738 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 83 |
1 files changed, 50 insertions, 33 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index e7e6b892e5..eaa330b183 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -28,6 +28,7 @@ #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" +#include "TypeLocBuilder.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; @@ -4313,37 +4314,45 @@ ExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc, /*RPLoc*/ ExpectedLParenLoc); } -ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base, - SourceLocation OpLoc, - tok::TokenKind OpKind, - const CXXScopeSpec &SS, - TypeSourceInfo *ScopeTypeInfo, - SourceLocation CCLoc, - SourceLocation TildeLoc, - PseudoDestructorTypeStorage Destructed, - bool HasTrailingLParen) { - TypeSourceInfo *DestructedTypeInfo = Destructed.getTypeSourceInfo(); - +static bool CheckArrow(Sema& S, QualType& ObjectType, Expr *Base, + tok::TokenKind& OpKind, SourceLocation OpLoc) { // C++ [expr.pseudo]p2: // The left-hand side of the dot operator shall be of scalar type. The // left-hand side of the arrow operator shall be of pointer to scalar type. // This scalar type is the object type. - QualType ObjectType = Base->getType(); if (OpKind == tok::arrow) { if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) { ObjectType = Ptr->getPointeeType(); } else if (!Base->isTypeDependent()) { // The user wrote "p->" when she probably meant "p."; fix it. - Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) + S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) << ObjectType << true << FixItHint::CreateReplacement(OpLoc, "."); - if (isSFINAEContext()) - return ExprError(); + if (S.isSFINAEContext()) + return true; OpKind = tok::period; } } + return false; +} + +ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base, + SourceLocation OpLoc, + tok::TokenKind OpKind, + const CXXScopeSpec &SS, + TypeSourceInfo *ScopeTypeInfo, + SourceLocation CCLoc, + SourceLocation TildeLoc, + PseudoDestructorTypeStorage Destructed, + bool HasTrailingLParen) { + TypeSourceInfo *DestructedTypeInfo = Destructed.getTypeSourceInfo(); + + QualType ObjectType = Base->getType(); + if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc)) + return ExprError(); + if (!ObjectType->isDependentType() && !ObjectType->isScalarType()) { Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar) << ObjectType << Base->getSourceRange(); @@ -4442,25 +4451,9 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) && "Invalid second type name in pseudo-destructor"); - // C++ [expr.pseudo]p2: - // The left-hand side of the dot operator shall be of scalar type. The - // left-hand side of the arrow operator shall be of pointer to scalar type. - // This scalar type is the object type. QualType ObjectType = Base->getType(); - if (OpKind == tok::arrow) { - if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) { - ObjectType = Ptr->getPointeeType(); - } else if (!ObjectType->isDependentType()) { - // The user wrote "p->" when she probably meant "p."; fix it. - Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) - << ObjectType << true - << FixItHint::CreateReplacement(OpLoc, "."); - if (isSFINAEContext()) - return ExprError(); - - OpKind = tok::period; - } - } + if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc)) + return ExprError(); // Compute the object type that we should use for name lookup purposes. Only // record types and dependent types matter. @@ -4580,6 +4573,30 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, Destructed, HasTrailingLParen); } +ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, + SourceLocation OpLoc, + tok::TokenKind OpKind, + SourceLocation TildeLoc, + const DeclSpec& DS, + bool HasTrailingLParen) { + + QualType ObjectType = Base->getType(); + if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc)) + return ExprError(); + + QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc()); + + TypeLocBuilder TLB; + DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T); + DecltypeTL.setNameLoc(DS.getTypeSpecTypeLoc()); + TypeSourceInfo *DestructedTypeInfo = TLB.getTypeSourceInfo(Context, T); + PseudoDestructorTypeStorage Destructed(DestructedTypeInfo); + + return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, CXXScopeSpec(), + 0, SourceLocation(), TildeLoc, + Destructed, HasTrailingLParen); +} + ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, CXXMethodDecl *Method, bool HadMultipleCandidates) { |