зеркало из https://github.com/microsoft/clang-1.git
Retain complete source information for the type after the '~' in a
CXXPseudoDestructorExpr. Update template instantiation for pseudo-destructor expressions to use this source information and to make use of Sema::BuildPseudoDestructorExpr when the base expression is dependent or refers to a scalar type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97079 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
396a9f235e
Коммит
26d4ac97fb
|
@ -1048,10 +1048,7 @@ class CXXPseudoDestructorExpr : public Expr {
|
|||
SourceLocation ColonColonLoc;
|
||||
|
||||
/// \brief The type being destroyed.
|
||||
QualType DestroyedType;
|
||||
|
||||
/// \brief The location of the type after the '~'.
|
||||
SourceLocation DestroyedTypeLoc;
|
||||
TypeSourceInfo *DestroyedType;
|
||||
|
||||
public:
|
||||
CXXPseudoDestructorExpr(ASTContext &Context,
|
||||
|
@ -1060,20 +1057,20 @@ public:
|
|||
SourceRange QualifierRange,
|
||||
TypeSourceInfo *ScopeType,
|
||||
SourceLocation ColonColonLoc,
|
||||
QualType DestroyedType,
|
||||
SourceLocation DestroyedTypeLoc)
|
||||
TypeSourceInfo *DestroyedType)
|
||||
: Expr(CXXPseudoDestructorExprClass,
|
||||
Context.getPointerType(Context.getFunctionType(Context.VoidTy, 0, 0,
|
||||
false, 0, false,
|
||||
false, 0, 0, false,
|
||||
CC_Default)),
|
||||
/*isTypeDependent=*/false,
|
||||
/*isTypeDependent=*/(Base->isTypeDependent() ||
|
||||
DestroyedType->getType()->isDependentType()),
|
||||
/*isValueDependent=*/Base->isValueDependent()),
|
||||
Base(static_cast<Stmt *>(Base)), IsArrow(isArrow),
|
||||
OperatorLoc(OperatorLoc), Qualifier(Qualifier),
|
||||
QualifierRange(QualifierRange),
|
||||
ScopeType(ScopeType), ColonColonLoc(ColonColonLoc),
|
||||
DestroyedType(DestroyedType), DestroyedTypeLoc(DestroyedTypeLoc) { }
|
||||
DestroyedType(DestroyedType) { }
|
||||
|
||||
void setBase(Expr *E) { Base = E; }
|
||||
Expr *getBase() const { return cast<Expr>(Base); }
|
||||
|
@ -1110,21 +1107,20 @@ public:
|
|||
/// \p T may also be a scalar type and, therefore, cannot be part of a
|
||||
/// nested-name-specifier. It is stored as the "scope type" of the pseudo-
|
||||
/// destructor expression.
|
||||
TypeSourceInfo *getScopeTypeLoc() const { return ScopeType; }
|
||||
TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; }
|
||||
|
||||
/// \brief Retrieve the location of the '::' in a qualified pseudo-destructor
|
||||
/// expression.
|
||||
SourceLocation getColonColonLoc() const { return ColonColonLoc; }
|
||||
|
||||
/// \brief Retrieve the type that is being destroyed.
|
||||
QualType getDestroyedType() const { return DestroyedType; }
|
||||
QualType getDestroyedType() const { return DestroyedType->getType(); }
|
||||
|
||||
/// \brief Retrieve the location of the type being destroyed.
|
||||
SourceLocation getDestroyedTypeLoc() const { return DestroyedTypeLoc; }
|
||||
/// \brief Retrieve the source location information for the type
|
||||
/// being destroyed.
|
||||
TypeSourceInfo *getDestroyedTypeInfo() const { return DestroyedType; }
|
||||
|
||||
virtual SourceRange getSourceRange() const {
|
||||
return SourceRange(Base->getLocStart(), DestroyedTypeLoc);
|
||||
}
|
||||
virtual SourceRange getSourceRange() const;
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CXXPseudoDestructorExprClass;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/TypeLoc.h"
|
||||
using namespace clang;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -121,6 +122,12 @@ Stmt::child_iterator CXXPseudoDestructorExpr::child_end() {
|
|||
return &Base + 1;
|
||||
}
|
||||
|
||||
SourceRange CXXPseudoDestructorExpr::getSourceRange() const {
|
||||
return SourceRange(Base->getLocStart(),
|
||||
DestroyedType->getTypeLoc().getSourceRange().getEnd());
|
||||
}
|
||||
|
||||
|
||||
// UnresolvedLookupExpr
|
||||
UnresolvedLookupExpr *
|
||||
UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
|
||||
|
|
|
@ -2932,13 +2932,15 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
|
|||
|
||||
// FIXME: We've lost the precise spelling of the type by going through
|
||||
// DeclarationName. Can we do better?
|
||||
TypeSourceInfo *DestroyedTypeInfo
|
||||
= Context.getTrivialTypeSourceInfo(MemberName.getCXXNameType(),
|
||||
MemberLoc);
|
||||
return Owned(new (Context) CXXPseudoDestructorExpr(Context, BaseExpr,
|
||||
IsArrow, OpLoc,
|
||||
(NestedNameSpecifier *) SS.getScopeRep(),
|
||||
SS.getRange(),
|
||||
0, SourceLocation(),
|
||||
MemberName.getCXXNameType(),
|
||||
MemberLoc));
|
||||
DestroyedTypeInfo));
|
||||
}
|
||||
|
||||
// Handle access to Objective-C instance variables, such as "Obj->ivar" and
|
||||
|
|
|
@ -2433,9 +2433,9 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
|
|||
const CXXScopeSpec &SS,
|
||||
TypeSourceInfo *ScopeTypeInfo,
|
||||
SourceLocation CCLoc,
|
||||
TypeSourceInfo *DestructedTypeLoc,
|
||||
TypeSourceInfo *DestructedTypeInfo,
|
||||
bool HasTrailingLParen) {
|
||||
assert(DestructedTypeLoc && "No destructed type in pseudo-destructor expr?");
|
||||
assert(DestructedTypeInfo && "No destructed type in pseudo-destructor expr?");
|
||||
|
||||
// C++ [expr.pseudo]p2:
|
||||
// The left-hand side of the dot operator shall be of scalar type. The
|
||||
|
@ -2467,18 +2467,18 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
|
|||
// C++ [expr.pseudo]p2:
|
||||
// [...] The cv-unqualified versions of the object type and of the type
|
||||
// designated by the pseudo-destructor-name shall be the same type.
|
||||
QualType DestructedType = DestructedTypeLoc->getType();
|
||||
QualType DestructedType = DestructedTypeInfo->getType();
|
||||
SourceLocation DestructedTypeStart
|
||||
= DestructedTypeLoc->getTypeLoc().getSourceRange().getBegin();
|
||||
= DestructedTypeInfo->getTypeLoc().getSourceRange().getBegin();
|
||||
if (!DestructedType->isDependentType() && !ObjectType->isDependentType() &&
|
||||
!Context.hasSameUnqualifiedType(DestructedType, ObjectType)) {
|
||||
Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
|
||||
<< ObjectType << DestructedType << BaseE->getSourceRange()
|
||||
<< DestructedTypeLoc->getTypeLoc().getSourceRange();
|
||||
<< DestructedTypeInfo->getTypeLoc().getSourceRange();
|
||||
|
||||
// Recover by
|
||||
DestructedType = ObjectType;
|
||||
DestructedTypeLoc = Context.getTrivialTypeSourceInfo(ObjectType,
|
||||
DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType,
|
||||
DestructedTypeStart);
|
||||
}
|
||||
|
||||
|
@ -2513,13 +2513,12 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
|
|||
SS.getRange(),
|
||||
ScopeTypeInfo,
|
||||
CCLoc,
|
||||
DestructedType,
|
||||
DestructedTypeStart));
|
||||
DestructedTypeInfo));
|
||||
if (HasTrailingLParen)
|
||||
return move(Result);
|
||||
|
||||
return DiagnoseDtorReference(
|
||||
DestructedTypeLoc->getTypeLoc().getSourceRange().getBegin(),
|
||||
DestructedTypeInfo->getTypeLoc().getSourceRange().getBegin(),
|
||||
move(Result));
|
||||
}
|
||||
|
||||
|
|
|
@ -884,28 +884,11 @@ public:
|
|||
OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
|
||||
SourceLocation OperatorLoc,
|
||||
bool isArrow,
|
||||
SourceLocation DestroyedTypeLoc,
|
||||
QualType DestroyedType,
|
||||
NestedNameSpecifier *Qualifier,
|
||||
SourceRange QualifierRange) {
|
||||
CXXScopeSpec SS;
|
||||
if (Qualifier) {
|
||||
SS.setRange(QualifierRange);
|
||||
SS.setScopeRep(Qualifier);
|
||||
}
|
||||
|
||||
QualType BaseType = ((Expr*) Base.get())->getType();
|
||||
|
||||
DeclarationName Name
|
||||
= SemaRef.Context.DeclarationNames.getCXXDestructorName(
|
||||
SemaRef.Context.getCanonicalType(DestroyedType));
|
||||
|
||||
return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
|
||||
OperatorLoc, isArrow,
|
||||
SS, /*FIXME: FirstQualifier*/ 0,
|
||||
Name, DestroyedTypeLoc,
|
||||
/*TemplateArgs*/ 0);
|
||||
}
|
||||
SourceRange QualifierRange,
|
||||
TypeSourceInfo *ScopeType,
|
||||
SourceLocation CCLoc,
|
||||
TypeSourceInfo *DestroyedType);
|
||||
|
||||
/// \brief Build a new unary operator expression.
|
||||
///
|
||||
|
@ -4694,27 +4677,35 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
|
|||
if (E->getQualifier() && !Qualifier)
|
||||
return SemaRef.ExprError();
|
||||
|
||||
QualType DestroyedType;
|
||||
{
|
||||
TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
|
||||
DestroyedType = getDerived().TransformType(E->getDestroyedType());
|
||||
if (DestroyedType.isNull())
|
||||
// FIXME: Object type!
|
||||
TypeSourceInfo *DestroyedTypeInfo
|
||||
= getDerived().TransformType(E->getDestroyedTypeInfo());
|
||||
if (!DestroyedTypeInfo)
|
||||
return SemaRef.ExprError();
|
||||
|
||||
// FIXME: Object type!
|
||||
TypeSourceInfo *ScopeTypeInfo = 0;
|
||||
if (E->getScopeTypeInfo()) {
|
||||
ScopeTypeInfo = getDerived().TransformType(E->getScopeTypeInfo());
|
||||
if (!ScopeTypeInfo)
|
||||
return SemaRef.ExprError();
|
||||
}
|
||||
|
||||
if (!getDerived().AlwaysRebuild() &&
|
||||
Base.get() == E->getBase() &&
|
||||
Qualifier == E->getQualifier() &&
|
||||
DestroyedType == E->getDestroyedType())
|
||||
ScopeTypeInfo == E->getScopeTypeInfo() &&
|
||||
DestroyedTypeInfo == E->getDestroyedTypeInfo())
|
||||
return SemaRef.Owned(E->Retain());
|
||||
|
||||
return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
|
||||
E->getOperatorLoc(),
|
||||
E->isArrow(),
|
||||
E->getDestroyedTypeLoc(),
|
||||
DestroyedType,
|
||||
Qualifier,
|
||||
E->getQualifierRange());
|
||||
E->getQualifierRange(),
|
||||
ScopeTypeInfo,
|
||||
E->getColonColonLoc(),
|
||||
DestroyedTypeInfo);
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
|
@ -5755,6 +5746,50 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
|
|||
return move(Result);
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
Sema::OwningExprResult
|
||||
TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(ExprArg Base,
|
||||
SourceLocation OperatorLoc,
|
||||
bool isArrow,
|
||||
NestedNameSpecifier *Qualifier,
|
||||
SourceRange QualifierRange,
|
||||
TypeSourceInfo *ScopeType,
|
||||
SourceLocation CCLoc,
|
||||
TypeSourceInfo *DestroyedType) {
|
||||
CXXScopeSpec SS;
|
||||
if (Qualifier) {
|
||||
SS.setRange(QualifierRange);
|
||||
SS.setScopeRep(Qualifier);
|
||||
}
|
||||
|
||||
Expr *BaseE = (Expr *)Base.get();
|
||||
QualType BaseType = BaseE->getType();
|
||||
if (BaseE->isTypeDependent() ||
|
||||
(!isArrow && !BaseType->getAs<RecordType>()) ||
|
||||
(isArrow && BaseType->getAs<PointerType>() &&
|
||||
!BaseType->getAs<PointerType>()->getAs<RecordType>())) {
|
||||
// This pseudo-destructor expression is still a pseudo-destructor.
|
||||
return SemaRef.BuildPseudoDestructorExpr(move(Base), OperatorLoc,
|
||||
isArrow? tok::arrow : tok::period,
|
||||
SS, ScopeType, CCLoc,
|
||||
DestroyedType,
|
||||
/*FIXME?*/true);
|
||||
}
|
||||
|
||||
DeclarationName Name
|
||||
= SemaRef.Context.DeclarationNames.getCXXDestructorName(
|
||||
SemaRef.Context.getCanonicalType(DestroyedType->getType()));
|
||||
|
||||
// FIXME: the ScopeType should be tacked onto SS.
|
||||
|
||||
return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
|
||||
OperatorLoc, isArrow,
|
||||
SS, /*FIXME: FirstQualifier*/ 0,
|
||||
Name,
|
||||
DestroyedType->getTypeLoc().getSourceRange().getBegin(),
|
||||
/*TemplateArgs*/ 0);
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H
|
||||
|
|
Загрузка…
Ссылка в новой задаче