diff options
-rw-r--r-- | clang/include/clang/AST/Expr.h | 1 | ||||
-rw-r--r-- | clang/include/clang/AST/ExprCXX.h | 33 | ||||
-rw-r--r-- | clang/include/clang/AST/StmtNodes.def | 9 | ||||
-rw-r--r-- | clang/lib/AST/Expr.cpp | 6 | ||||
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 4 | ||||
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 4 | ||||
-rw-r--r-- | clang/lib/AST/StmtSerialization.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 3 |
9 files changed, 74 insertions, 24 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 49796ccbc0b..bc6c454ca17 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -223,7 +223,6 @@ public: Func, Function, PrettyFunction, - CXXThis, ObjCSuper // super }; diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 61d25e9a97b..73ef6160a66 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -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. diff --git a/clang/include/clang/AST/StmtNodes.def b/clang/include/clang/AST/StmtNodes.def index 33d02703e4b..4382fb427b6 100644 --- a/clang/include/clang/AST/StmtNodes.def +++ b/clang/include/clang/AST/StmtNodes.def @@ -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) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 85129b483b4..171f7dbde2e 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -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; } diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 82626d864ad..0eead3ca552 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -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() { diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 51f4f518076..34aefc2c4c2 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -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"; diff --git a/clang/lib/AST/StmtSerialization.cpp b/clang/lib/AST/StmtSerialization.cpp index 5f87b68dba5..aefaee38a42 100644 --- a/clang/lib/AST/StmtSerialization.cpp +++ b/clang/lib/AST/StmtSerialization.cpp @@ -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); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 33fc52b71dc..e4321f53ff0 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -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()); } } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index fde28529b71..d012473c25d 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -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); } |