зеркало из https://github.com/microsoft/clang-1.git
Create a new expression class, CXXThisExpr, to handle the C++ 'this' primary expression. Remove CXXThis from PredefinedExpr
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58695 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
eb704f22ef
Коммит
796da18402
|
@ -223,7 +223,6 @@ public:
|
|||
Func,
|
||||
Function,
|
||||
PrettyFunction,
|
||||
CXXThis,
|
||||
ObjCSuper // super
|
||||
};
|
||||
|
||||
|
|
|
@ -154,6 +154,39 @@ public:
|
|||
virtual child_iterator child_end();
|
||||
};
|
||||
|
||||
/// CXXThisExpr - Represents the "this" expression in C++, which is a
|
||||
/// pointer to the object on which the current member function is
|
||||
/// executing (C++ [expr.prim]p3). Example:
|
||||
///
|
||||
/// @code
|
||||
/// class Foo {
|
||||
/// public:
|
||||
/// void bar();
|
||||
/// void test() { this->bar(); }
|
||||
/// };
|
||||
/// @endcode
|
||||
class CXXThisExpr : public Expr {
|
||||
SourceLocation Loc;
|
||||
|
||||
public:
|
||||
CXXThisExpr(SourceLocation L, QualType Type)
|
||||
: Expr(CXXThisExprClass, Type), Loc(L) { }
|
||||
|
||||
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CXXThisExprClass;
|
||||
}
|
||||
static bool classof(const CXXThisExpr *) { return true; }
|
||||
|
||||
// Iterators
|
||||
virtual child_iterator child_begin();
|
||||
virtual child_iterator child_end();
|
||||
|
||||
virtual void EmitImpl(llvm::Serializer& S) const;
|
||||
static CXXThisExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
|
||||
};
|
||||
|
||||
/// CXXThrowExpr - [C++ 15] C++ Throw Expression. This handles
|
||||
/// 'throw' and 'throw' assignment-expression. When
|
||||
/// assignment-expression isn't present, Op will be null.
|
||||
|
|
|
@ -97,10 +97,11 @@ STMT(63, CXXReinterpretCastExpr , CXXNamedCastExpr)
|
|||
STMT(64, CXXConstCastExpr , CXXNamedCastExpr)
|
||||
STMT(65, CXXFunctionalCastExpr , Expr)
|
||||
STMT(66, CXXBoolLiteralExpr , Expr)
|
||||
STMT(67, CXXThrowExpr , Expr)
|
||||
STMT(68, CXXDefaultArgExpr , Expr)
|
||||
STMT(69, CXXZeroInitValueExpr , Expr)
|
||||
STMT(70, CXXConditionDeclExpr , DeclRefExpr)
|
||||
STMT(67, CXXThisExpr , Expr)
|
||||
STMT(68, CXXThrowExpr , Expr)
|
||||
STMT(69, CXXDefaultArgExpr , Expr)
|
||||
STMT(70, CXXZeroInitValueExpr , Expr)
|
||||
STMT(71, CXXConditionDeclExpr , DeclRefExpr)
|
||||
|
||||
// Obj-C Expressions.
|
||||
STMT(80, ObjCStringLiteral , Expr)
|
||||
|
|
|
@ -417,9 +417,7 @@ Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
|
|||
case ObjCPropertyRefExprClass: // FIXME: check if read-only property.
|
||||
return LV_Valid;
|
||||
case PredefinedExprClass:
|
||||
return (cast<PredefinedExpr>(this)->getIdentType()
|
||||
== PredefinedExpr::CXXThis
|
||||
? LV_InvalidExpression : LV_Valid);
|
||||
return LV_Valid;
|
||||
case VAArgExprClass:
|
||||
return LV_Valid;
|
||||
case CXXDefaultArgExprClass:
|
||||
|
@ -439,6 +437,8 @@ Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const {
|
|||
if (cast<ExplicitCastExpr>(this)->getTypeAsWritten()->isReferenceType())
|
||||
return LV_Valid;
|
||||
break;
|
||||
case CXXThisExprClass:
|
||||
return LV_InvalidExpression;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,10 @@ Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
|
|||
return child_iterator();
|
||||
}
|
||||
|
||||
// CXXThisExpr
|
||||
Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); }
|
||||
Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); }
|
||||
|
||||
// CXXThrowExpr
|
||||
Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; }
|
||||
Stmt::child_iterator CXXThrowExpr::child_end() {
|
||||
|
|
|
@ -839,6 +839,10 @@ void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
|
|||
OS << (Node->getValue() ? "true" : "false");
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
|
||||
OS << "this";
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
|
||||
if (Node->getSubExpr() == 0)
|
||||
OS << "throw";
|
||||
|
|
|
@ -212,7 +212,10 @@ Stmt* Stmt::Create(Deserializer& D, ASTContext& C) {
|
|||
|
||||
case CXXConstCastExprClass:
|
||||
return CXXConstCastExpr::CreateImpl(D, C, SC);
|
||||
|
||||
|
||||
case CXXThisExprClass:
|
||||
return CXXThisExpr::CreateImpl(D, C);
|
||||
|
||||
case CXXZeroInitValueExprClass:
|
||||
return CXXZeroInitValueExpr::CreateImpl(D, C);
|
||||
}
|
||||
|
@ -1329,6 +1332,17 @@ CXXNamedCastExpr::CreateImpl(Deserializer& D, ASTContext& C, StmtClass SC) {
|
|||
}
|
||||
}
|
||||
|
||||
void CXXThisExpr::EmitImpl(llvm::Serializer& S) const {
|
||||
S.Emit(getType());
|
||||
S.Emit(Loc);
|
||||
}
|
||||
|
||||
CXXThisExpr* CXXThisExpr::CreateImpl(llvm::Deserializer& D, ASTContext&) {
|
||||
QualType Ty = QualType::ReadVal(D);
|
||||
SourceLocation Loc = SourceLocation::ReadVal(D);
|
||||
return new CXXThisExpr(Loc, Ty);
|
||||
}
|
||||
|
||||
void CXXZeroInitValueExpr::EmitImpl(Serializer& S) const {
|
||||
S.Emit(getType());
|
||||
S.Emit(TyBeginLoc);
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace {
|
|||
|
||||
bool VisitExpr(Expr *Node);
|
||||
bool VisitDeclRefExpr(DeclRefExpr *DRE);
|
||||
bool VisitPredefinedExpr(PredefinedExpr *PE);
|
||||
bool VisitCXXThisExpr(CXXThisExpr *ThisE);
|
||||
};
|
||||
|
||||
/// VisitExpr - Visit all of the children of this expression.
|
||||
|
@ -88,18 +88,14 @@ namespace {
|
|||
return false;
|
||||
}
|
||||
|
||||
/// VisitPredefinedExpr - Visit a predefined expression, which could
|
||||
/// refer to "this".
|
||||
bool CheckDefaultArgumentVisitor::VisitPredefinedExpr(PredefinedExpr *PE) {
|
||||
if (PE->getIdentType() == PredefinedExpr::CXXThis) {
|
||||
// C++ [dcl.fct.default]p8:
|
||||
// The keyword this shall not be used in a default argument of a
|
||||
// member function.
|
||||
return S->Diag(PE->getSourceRange().getBegin(),
|
||||
diag::err_param_default_argument_references_this,
|
||||
PE->getSourceRange());
|
||||
}
|
||||
return false;
|
||||
/// VisitCXXThisExpr - Visit a C++ "this" expression.
|
||||
bool CheckDefaultArgumentVisitor::VisitCXXThisExpr(CXXThisExpr *ThisE) {
|
||||
// C++ [dcl.fct.default]p8:
|
||||
// The keyword this shall not be used in a default argument of a
|
||||
// member function.
|
||||
return S->Diag(ThisE->getSourceRange().getBegin(),
|
||||
diag::err_param_default_argument_references_this,
|
||||
ThisE->getSourceRange());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -708,8 +708,7 @@ Action::ExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
|
|||
|
||||
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext))
|
||||
if (MD->isInstance())
|
||||
return new PredefinedExpr(ThisLoc, MD->getThisType(Context),
|
||||
PredefinedExpr::CXXThis);
|
||||
return new CXXThisExpr(ThisLoc, MD->getThisType(Context));
|
||||
|
||||
return Diag(ThisLoc, diag::err_invalid_this_use);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче