]> granicus.if.org Git - clang/commitdiff
Create a new expression class, CXXThisExpr, to handle the C++ 'this' primary expressi...
authorDouglas Gregor <dgregor@apple.com>
Tue, 4 Nov 2008 14:32:21 +0000 (14:32 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 4 Nov 2008 14:32:21 +0000 (14:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58695 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
include/clang/AST/ExprCXX.h
include/clang/AST/StmtNodes.def
lib/AST/Expr.cpp
lib/AST/ExprCXX.cpp
lib/AST/StmtPrinter.cpp
lib/AST/StmtSerialization.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExprCXX.cpp

index 49796ccbc0b8199d6acb097a54ac5e244ab66c2f..bc6c454ca1778d2f46921c7159d61b4d546ad0cd 100644 (file)
@@ -223,7 +223,6 @@ public:
     Func,
     Function,
     PrettyFunction,
-    CXXThis,
     ObjCSuper // super
   };
   
index 61d25e9a97b35ab590edc68ad2f292b84b399aa2..73ef6160a66283b0de9273f2db7095f4e8284cd2 100644 (file)
@@ -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.
index 33d02703e4be4d59d077188d0fd26d04b1194d14..4382fb427b6f3990c17770e9108426d81b9718d7 100644 (file)
@@ -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)
index 85129b483b4f00238dd19b41c9c7ff809da54864..171f7dbde2e49b34d942ac8eb1a3ee3235a2a012 100644 (file)
@@ -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;
   }
index 82626d864adbb42806de1f8c6b294c8535df4e76..0eead3ca55264997f9e109071f9e4c2097d8fa88 100644 (file)
@@ -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() {
index 51f4f518076540e7f2ea0bc5c18fa3c4f3755fb2..34aefc2c4c2ab68f1e7b68af16288e3c8c8fa6e7 100644 (file)
@@ -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";
index 5f87b68dba5f6627f8b2d0cb17724106a7390879..aefaee38a4225bbe9f7130fbaece36b0d38e50fe 100644 (file)
@@ -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);
index 33fc52b71dca6374586a430373dbb9b15832ebfc..e4321f53ff0a2a67a582798239c569c311fa58b0 100644 (file)
@@ -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());
   }
 }
 
index fde28529b71b65b5e3c789ba46353d309f6fbd0a..d012473c25dc18d16b30740d78c598cb237a4cb8 100644 (file)
@@ -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);
 }