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:
Douglas Gregor 2010-02-24 23:40:28 +00:00
Родитель 396a9f235e
Коммит 26d4ac97fb
5 изменённых файлов: 98 добавлений и 59 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -2431,11 +2431,11 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
const CXXScopeSpec &SS,
TypeSourceInfo *ScopeTypeInfo,
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);
}
NestedNameSpecifier *Qualifier,
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