[cfe-commits] r58264 - in /cfe/trunk: Driver/RewriteObjC.cpp include/clang/AST/Expr.h include/clang/AST/ExprCXX.h include/clang/AST/StmtNodes.def include/clang/Parse/Action.h lib/AST/Expr.cpp lib/AST/ExprCXX.cpp lib/AST/StmtDumper.cpp lib/AST/StmtPrinter.cpp lib/AST/StmtSerialization.cpp lib/Analysis/Environment.cpp lib/Analysis/GRExprEngine.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/Sema.h lib/Sema/SemaChecking.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp test/SemaCXX/return-stack-addr.cpp

Douglas Gregor doug.gregor at gmail.com
Mon Oct 27 12:41:14 PDT 2008


Author: dgregor
Date: Mon Oct 27 14:41:14 2008
New Revision: 58264

URL: http://llvm.org/viewvc/llvm-project?rev=58264&view=rev
Log:
Refactor the expression class hierarchy for casts. Most importantly:
  - CastExpr is the root of all casts
  - ImplicitCastExpr is (still) used for all explicit casts
  - ExplicitCastExpr is now the root of all *explicit* casts
  - ExplicitCCastExpr (new name needed!?) is a C-style cast in C or C++
  - CXXFunctionalCastExpr inherits from ExplicitCastExpr
  - CXXNamedCastExpr inherits from ExplicitCastExpr and is the root of all
    of the C++ named cast expression types (static_cast, dynamic_cast, etc.)
  - Added classes CXXStaticCastExpr, CXXDynamicCastExpr, 
    CXXReinterpretCastExpr, and CXXConstCastExpr to 

Also, fixed returned-stack-addr.cpp, which broke once when we fixed
reinterpret_cast to diagnose double->int* conversions and again when
we eliminated implicit conversions to reference types. The fix is in
both testcase and SemaChecking.cpp.

Most of this patch is simply support for the renaming. There's very
little actual change in semantics.


Modified:
    cfe/trunk/Driver/RewriteObjC.cpp
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/include/clang/AST/StmtNodes.def
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/AST/StmtDumper.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/AST/StmtSerialization.cpp
    cfe/trunk/lib/Analysis/Environment.cpp
    cfe/trunk/lib/Analysis/GRExprEngine.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/SemaCXX/return-stack-addr.cpp

Modified: cfe/trunk/Driver/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteObjC.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/Driver/RewriteObjC.cpp (original)
+++ cfe/trunk/Driver/RewriteObjC.cpp Mon Oct 27 14:41:14 2008
@@ -1057,8 +1057,8 @@
                                           SourceLocation(), II);
       assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
       QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
-      CastExpr *castExpr = new ExplicitCastExpr(castT, IV->getBase(),
-                                                SourceLocation());
+      CastExpr *castExpr = new ExplicitCCastExpr(castT, IV->getBase(), castT,
+                                                 SourceLocation());
       // Don't forget the parens to enforce the proper binding.
       ParenExpr *PE = new ParenExpr(IV->getBase()->getLocStart(),
                                     IV->getBase()->getLocEnd(),
@@ -1099,8 +1099,8 @@
                                           SourceLocation(), II);
       assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
       QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
-      CastExpr *castExpr = new ExplicitCastExpr(castT, IV->getBase(),
-                                                SourceLocation());
+      CastExpr *castExpr = new ExplicitCCastExpr(castT, IV->getBase(), castT,
+                                                 SourceLocation());
       // Don't forget the parens to enforce the proper binding.
       ParenExpr *PE = new ParenExpr(IV->getBase()->getLocStart(),
                                     IV->getBase()->getLocEnd(), castExpr);
@@ -1238,7 +1238,7 @@
     }
   }
   
-  if (ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(S))
+  if (ExplicitCCastExpr *CE = dyn_cast<ExplicitCCastExpr>(S))
     RewriteObjCQualifiedInterfaceTypes(CE);
   
   if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 
@@ -1559,8 +1559,10 @@
   buf += "  _rethrow = objc_exception_extract(&_stack);\n";
   buf += "  if (!_rethrow) objc_exception_try_exit(&_stack);\n";
   buf += "  objc_sync_exit(";
-  Expr *syncExpr = new ExplicitCastExpr(Context->getObjCIdType(), 
-                                        S->getSynchExpr(), SourceLocation());
+  Expr *syncExpr = new ExplicitCCastExpr(Context->getObjCIdType(), 
+                                         S->getSynchExpr(), 
+                                         Context->getObjCIdType(),
+                                         SourceLocation());
   std::string syncExprBufS;
   llvm::raw_string_ostream syncExprBuf(syncExprBufS);
   syncExpr->printPretty(syncExprBuf);
@@ -2186,7 +2188,8 @@
                                  Context->getPointerType(DRE->getType()), 
                                  SourceLocation());
   // cast to NSConstantString *
-  CastExpr *cast = new ExplicitCastExpr(Exp->getType(), Unop, SourceLocation());
+  CastExpr *cast = new ExplicitCCastExpr(Exp->getType(), Unop, 
+                                         Exp->getType(), SourceLocation());
   ReplaceStmt(Exp, cast);
   delete Exp;
   return cast;
@@ -2321,9 +2324,10 @@
                                                    &ClsExprs[0], 
                                                    ClsExprs.size());
       // To turn off a warning, type-cast to 'id'
-      InitExprs.push_back(
-        new ExplicitCastExpr(Context->getObjCIdType(), 
-        Cls, SourceLocation())); // set 'super class', using objc_getClass().
+      InitExprs.push_back( // set 'super class', using objc_getClass().
+        new ExplicitCCastExpr(Context->getObjCIdType(), 
+                              Cls, Context->getObjCIdType(),
+                              SourceLocation())); 
       // struct objc_super
       QualType superType = getSuperStructType();
       Expr *SuperRep;
@@ -2372,10 +2376,11 @@
       llvm::SmallVector<Expr*, 4> InitExprs;
       
       InitExprs.push_back(
-        new ExplicitCastExpr(Context->getObjCIdType(), 
+        new ExplicitCCastExpr(Context->getObjCIdType(), 
                      new DeclRefExpr(CurMethodDef->getSelfDecl(), 
                                      Context->getObjCIdType(),
-                                     SourceLocation()), 
+                                     SourceLocation()),
+                     Context->getObjCIdType(),
                      SourceLocation())); // set the 'receiver'.
       
       llvm::SmallVector<Expr*, 8> ClsExprs;
@@ -2389,8 +2394,9 @@
                                                    ClsExprs.size());
       // To turn off a warning, type-cast to 'id'
       InitExprs.push_back(
-        new ExplicitCastExpr(Context->getObjCIdType(), 
-        Cls, SourceLocation())); // set 'super class', using objc_getClass().
+        // set 'super class', using objc_getClass().
+        new ExplicitCCastExpr(Context->getObjCIdType(), 
+        Cls, Context->getObjCIdType(), SourceLocation())); 
       // struct objc_super
       QualType superType = getSuperStructType();
       Expr *SuperRep;
@@ -2417,10 +2423,11 @@
     } else {
       // Remove all type-casts because it may contain objc-style types; e.g.
       // Foo<Proto> *.
-      while (ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(recExpr))
+      while (ExplicitCCastExpr *CE = dyn_cast<ExplicitCCastExpr>(recExpr))
         recExpr = CE->getSubExpr();
-      recExpr = new ExplicitCastExpr(Context->getObjCIdType(), recExpr,
-                                     SourceLocation());
+      recExpr = new ExplicitCCastExpr(Context->getObjCIdType(), recExpr,
+                                      Context->getObjCIdType(), 
+                                      SourceLocation());
       MsgExprs.push_back(recExpr);
     }
   }
@@ -2441,17 +2448,19 @@
     // Make all implicit casts explicit...ICE comes in handy:-)
     if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
       // Reuse the ICE type, it is exactly what the doctor ordered.
-      userExpr = new ExplicitCastExpr(ICE->getType()->isObjCQualifiedIdType()
+      QualType type = ICE->getType()->isObjCQualifiedIdType()
                                 ? Context->getObjCIdType()
-                                : ICE->getType(), userExpr, SourceLocation());
+                                : ICE->getType();
+      userExpr = new ExplicitCCastExpr(type, userExpr, type, SourceLocation());
     }
     // Make id<P...> cast into an 'id' cast.
-    else if (ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(userExpr)) {
+    else if (ExplicitCCastExpr *CE = dyn_cast<ExplicitCCastExpr>(userExpr)) {
       if (CE->getType()->isObjCQualifiedIdType()) {
-        while ((CE = dyn_cast<ExplicitCastExpr>(userExpr)))
+        while ((CE = dyn_cast<ExplicitCCastExpr>(userExpr)))
           userExpr = CE->getSubExpr();
-        userExpr = new ExplicitCastExpr(Context->getObjCIdType(), 
-                                userExpr, SourceLocation());
+        userExpr = new ExplicitCCastExpr(Context->getObjCIdType(), 
+                                userExpr, Context->getObjCIdType(), 
+                                SourceLocation());
       }
     } 
     MsgExprs.push_back(userExpr);
@@ -2494,8 +2503,9 @@
   // If we don't do this cast, we get the following bizarre warning/note:
   // xx.m:13: warning: function called through a non-compatible type
   // xx.m:13: note: if this code is reached, the program will abort
-  cast = new ExplicitCastExpr(Context->getPointerType(Context->VoidTy), DRE, 
-                      SourceLocation());
+  cast = new ExplicitCCastExpr(Context->getPointerType(Context->VoidTy), DRE, 
+                               Context->getPointerType(Context->VoidTy),
+                               SourceLocation());
     
   // Now do the "normal" pointer to function cast.
   QualType castType = Context->getFunctionType(returnType, 
@@ -2503,7 +2513,7 @@
     // If we don't have a method decl, force a variadic cast.
     Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true, 0);
   castType = Context->getPointerType(castType);
-  cast = new ExplicitCastExpr(castType, cast, SourceLocation());
+  cast = new ExplicitCCastExpr(castType, cast, castType, SourceLocation());
 
   // Don't forget the parens to enforce the proper binding.
   ParenExpr *PE = new ParenExpr(SourceLocation(), SourceLocation(), cast);
@@ -2522,14 +2532,15 @@
     DeclRefExpr *STDRE = new DeclRefExpr(MsgSendStretFlavor, msgSendType, 
                                          SourceLocation());
     // Need to cast objc_msgSend_stret to "void *" (see above comment).
-    cast = new ExplicitCastExpr(Context->getPointerType(Context->VoidTy), STDRE, 
-                        SourceLocation());
+    cast = new ExplicitCCastExpr(Context->getPointerType(Context->VoidTy), STDRE, 
+                                 Context->getPointerType(Context->VoidTy),
+                                 SourceLocation());
     // Now do the "normal" pointer to function cast.
     castType = Context->getFunctionType(returnType, 
       &ArgTypes[0], ArgTypes.size(),
       Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false, 0);
     castType = Context->getPointerType(castType);
-    cast = new ExplicitCastExpr(castType, cast, SourceLocation());
+    cast = new ExplicitCCastExpr(castType, cast, castType, SourceLocation());
     
     // Don't forget the parens to enforce the proper binding.
     PE = new ParenExpr(SourceLocation(), SourceLocation(), cast);

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Mon Oct 27 14:41:14 2008
@@ -771,12 +771,10 @@
   static CompoundLiteralExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
 };
 
-/// CastExpr - Base class for Cast Operators (explicit, implicit, etc.).
-/// Classes that derive from CastExpr are:
-///
-///   ImplicitCastExpr
-///   ExplicitCastExpr
-///
+/// CastExpr - Base class for type casts, including both implicit
+/// casts (ImplicitCastExpr) and explicit casts that have some
+/// representation in the source code (ExplicitCastExpr's derived
+/// classes).
 class CastExpr : public Expr {
   Stmt *Op;
 protected:
@@ -791,6 +789,12 @@
     switch (T->getStmtClass()) {
     case ImplicitCastExprClass:
     case ExplicitCastExprClass:
+    case ExplicitCCastExprClass:
+    case CXXNamedCastExprClass:
+    case CXXStaticCastExprClass:
+    case CXXDynamicCastExprClass:
+    case CXXReinterpretCastExprClass:
+    case CXXConstCastExprClass:
     case CXXFunctionalCastExprClass:
       return true;
     default:
@@ -804,9 +808,10 @@
   virtual child_iterator child_end();
 };
 
-/// ImplicitCastExpr - Allows us to explicitly represent implicit type 
-/// conversions. For example: converting T[]->T*, void f()->void (*f)(), 
-/// float->double, short->int, etc.
+/// ImplicitCastExpr - Allows us to explicitly represent implicit type
+/// conversions, which have no direct representation in the original
+/// source code. For example: converting T[]->T*, void f()->void
+/// (*f)(), float->double, short->int, etc.
 ///
 class ImplicitCastExpr : public CastExpr {
 public:
@@ -826,13 +831,62 @@
   static ImplicitCastExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
 };
 
-/// ExplicitCastExpr - [C99 6.5.4] Cast Operators.
+/// ExplicitCastExpr - An explicit cast written in the source
+/// code. 
 ///
+/// This class is effectively an abstract class, because it provides
+/// the basic representation of an explicitly-written cast without
+/// specifying which kind of cast (C cast, functional cast, static
+/// cast, etc.) was written; specific derived classes represent the
+/// particular style of cast and its location information.
+///
+/// Unlike implicit casts, explicit cast nodes have two different
+/// types: the type that was written into the source code, and the
+/// actual type of the expression as determined by semantic
+/// analysis. These types may differ slightly. For example, in C++ one
+/// can cast to a reference type, which indicates that the resulting
+/// expression will be an lvalue. The reference type, however, will
+/// not be used as the type of the expression.
 class ExplicitCastExpr : public CastExpr {
+  /// TypeAsWritten - The type that this expression is casting to, as
+  /// written in the source code.
+  QualType TypeAsWritten;
+
+protected:
+  ExplicitCastExpr(StmtClass SC, QualType exprTy, Expr *op, QualType writtenTy) : 
+    CastExpr(SC, exprTy, op), TypeAsWritten(writtenTy) {}
+
+public:
+  /// getTypeAsWritten - Returns the type that this expression is
+  /// casting to, as written in the source code.
+  QualType getTypeAsWritten() const { return TypeAsWritten; }
+
+  static bool classof(const Stmt *T) { 
+    switch (T->getStmtClass()) {
+    case ExplicitCastExprClass:
+    case ExplicitCCastExprClass:
+    case CXXFunctionalCastExprClass:
+    case CXXStaticCastExprClass:
+    case CXXDynamicCastExprClass:
+    case CXXReinterpretCastExprClass:
+    case CXXConstCastExprClass:
+      return true;
+    default:
+      return false;
+    }
+  }
+  static bool classof(const ExplicitCastExpr *) { return true; }
+};
+
+/// ExplicitCCastExpr - An explicit cast in C (C99 6.5.4) or a C-style
+/// cast in C++ (C++ [expr.cast]), which uses the syntax
+/// (Type)expr. For example: @c (int)f.
+class ExplicitCCastExpr : public ExplicitCastExpr {
   SourceLocation Loc; // the location of the left paren
 public:
-  ExplicitCastExpr(QualType ty, Expr *op, SourceLocation l) : 
-    CastExpr(ExplicitCastExprClass, ty, op), Loc(l) {}
+  ExplicitCCastExpr(QualType exprTy, Expr *op, QualType writtenTy, 
+                    SourceLocation l) : 
+    ExplicitCastExpr(ExplicitCCastExprClass, exprTy, op, writtenTy), Loc(l) {}
 
   SourceLocation getLParenLoc() const { return Loc; }
   
@@ -840,12 +894,12 @@
     return SourceRange(Loc, getSubExpr()->getSourceRange().getEnd());
   }
   static bool classof(const Stmt *T) { 
-    return T->getStmtClass() == ExplicitCastExprClass; 
+    return T->getStmtClass() == ExplicitCCastExprClass; 
   }
-  static bool classof(const ExplicitCastExpr *) { return true; }
+  static bool classof(const ExplicitCCastExpr *) { return true; }
   
   virtual void EmitImpl(llvm::Serializer& S) const;
-  static ExplicitCastExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
+  static ExplicitCCastExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
 };
 
 class BinaryOperator : public Expr {

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Mon Oct 27 14:41:14 2008
@@ -23,54 +23,112 @@
 // C++ Expressions.
 //===--------------------------------------------------------------------===//
 
-/// CXXCastExpr - [C++ 5.2.7, 5.2.9, 5.2.10, 5.2.11] C++ Cast Operators.
-/// 
-class CXXCastExpr : public Expr {
-public:
-  enum Opcode {
-    DynamicCast,
-    StaticCast,
-    ReinterpretCast,
-    ConstCast
-  };
+/// CXXNamedCastExpr - Abstract class common to all of the C++ "named"
+/// casts, @c static_cast, @c dynamic_cast, @c reinterpret_cast, or @c
+/// const_cast.
+///
+/// This abstract class is inherited by all of the classes
+/// representing "named" casts, e.g., CXXStaticCastExpr,
+/// CXXDynamicCastExpr, CXXReinterpretCastExpr, and CXXConstCastExpr.
+class CXXNamedCastExpr : public ExplicitCastExpr {
 private:
-  QualType Ty;
-  Opcode Opc;
-  Stmt *Op;
   SourceLocation Loc; // the location of the casting op
-public:
-  CXXCastExpr(Opcode op, QualType ty, Expr *expr, SourceLocation l)
-    : Expr(CXXCastExprClass, ty), Ty(ty), Opc(op), Op(expr), Loc(l) {}
 
-  QualType getDestType() const { return Ty; }
-  Expr *getSubExpr() const { return cast<Expr>(Op); }
+protected:
+  CXXNamedCastExpr(StmtClass SC, QualType ty, Expr *op, QualType writtenTy, 
+                   SourceLocation l)
+    : ExplicitCastExpr(SC, ty, op, writtenTy), Loc(l) {}
 
-  Opcode getOpcode() const { return Opc; }
+public:
+  const char *getCastName() const;
 
-  /// getOpcodeStr - Turn an Opcode enum value into the string it represents,
-  /// e.g. "reinterpret_cast".
-  static const char *getOpcodeStr(Opcode Op) {
-    // FIXME: move out of line.
-    switch (Op) {
-    default: assert(0 && "Not a C++ cast expression");
-    case CXXCastExpr::ConstCast:       return "const_cast";
-    case CXXCastExpr::DynamicCast:     return "dynamic_cast";
-    case CXXCastExpr::ReinterpretCast: return "reinterpret_cast";
-    case CXXCastExpr::StaticCast:      return "static_cast";
-    }
-  }
-  
   virtual SourceRange getSourceRange() const {
     return SourceRange(Loc, getSubExpr()->getSourceRange().getEnd());
   }
   static bool classof(const Stmt *T) { 
-    return T->getStmtClass() == CXXCastExprClass;
+    switch (T->getStmtClass()) {
+    case CXXNamedCastExprClass:
+    case CXXStaticCastExprClass:
+    case CXXDynamicCastExprClass:
+    case CXXReinterpretCastExprClass:
+    case CXXConstCastExprClass:
+      return true;
+    default:
+      return false;
+    }
   }
-  static bool classof(const CXXCastExpr *) { return true; }
+  static bool classof(const CXXNamedCastExpr *) { return true; }
       
-  // Iterators
-  virtual child_iterator child_begin();
-  virtual child_iterator child_end();
+  virtual void EmitImpl(llvm::Serializer& S) const;
+  static CXXNamedCastExpr *CreateImpl(llvm::Deserializer& D, ASTContext& C,
+                                      StmtClass SC);
+};
+
+/// CXXStaticCastExpr - A C++ @c static_cast expression (C++ [expr.static.cast]).
+/// 
+/// This expression node represents a C++ static cast, e.g.,
+/// @c static_cast<int>(1.0).
+class CXXStaticCastExpr : public CXXNamedCastExpr {
+public:
+  CXXStaticCastExpr(QualType ty, Expr *op, QualType writtenTy, SourceLocation l)
+    : CXXNamedCastExpr(CXXStaticCastExprClass, ty, op, writtenTy, l) {}
+
+  static bool classof(const Stmt *T) { 
+    return T->getStmtClass() == CXXStaticCastExprClass;
+  }
+  static bool classof(const CXXStaticCastExpr *) { return true; }
+};
+
+/// CXXDynamicCastExpr - A C++ @c dynamic_cast expression
+/// (C++ [expr.dynamic.cast]), which may perform a run-time check to 
+/// determine how to perform the type cast.
+/// 
+/// This expression node represents a dynamic cast, e.g.,
+/// @c dynamic_cast<Derived*>(BasePtr).
+class CXXDynamicCastExpr : public CXXNamedCastExpr {
+public:
+  CXXDynamicCastExpr(QualType ty, Expr *op, QualType writtenTy, SourceLocation l)
+    : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, op, writtenTy, l) {}
+
+  static bool classof(const Stmt *T) { 
+    return T->getStmtClass() == CXXDynamicCastExprClass;
+  }
+  static bool classof(const CXXDynamicCastExpr *) { return true; }
+};
+
+/// CXXReinterpretCastExpr - A C++ @c reinterpret_cast expression (C++
+/// [expr.reinterpret.cast]), which provides a differently-typed view
+/// of a value but performs no actual work at run time.
+/// 
+/// This expression node represents a reinterpret cast, e.g.,
+/// @c reinterpret_cast<int>(VoidPtr).
+class CXXReinterpretCastExpr : public CXXNamedCastExpr {
+public:
+  CXXReinterpretCastExpr(QualType ty, Expr *op, QualType writtenTy, 
+                         SourceLocation l)
+    : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, op, writtenTy, l) {}
+
+  static bool classof(const Stmt *T) { 
+    return T->getStmtClass() == CXXReinterpretCastExprClass;
+  }
+  static bool classof(const CXXReinterpretCastExpr *) { return true; }
+};
+
+/// CXXConstCastExpr - A C++ @c const_cast expression (C++ [expr.const.cast]),
+/// which can remove type qualifiers but does not change the underlying value.
+/// 
+/// This expression node represents a const cast, e.g.,
+/// @c const_cast<char*>(PtrToConstChar).
+class CXXConstCastExpr : public CXXNamedCastExpr {
+public:
+  CXXConstCastExpr(QualType ty, Expr *op, QualType writtenTy, 
+                   SourceLocation l)
+    : CXXNamedCastExpr(CXXConstCastExprClass, ty, op, writtenTy, l) {}
+
+  static bool classof(const Stmt *T) { 
+    return T->getStmtClass() == CXXConstCastExprClass;
+  }
+  static bool classof(const CXXConstCastExpr *) { return true; }
 };
 
 /// CXXBoolLiteralExpr - [C++ 2.13.5] C++ Boolean Literal.
@@ -170,17 +228,17 @@
                                        ASTContext& C);
 };
 
-/// CXXFunctionalCastExpr - [C++ 5.2.3p1] Explicit type conversion
-///                                       (functional notation).
-/// Example: "x = int(0.5);"
-///
-class CXXFunctionalCastExpr : public CastExpr {
+/// CXXFunctionalCastExpr - Represents an explicit C++ type conversion
+/// that uses "functional" notion (C++ [expr.type.conv]). Example: @c
+/// x = int(0.5);
+class CXXFunctionalCastExpr : public ExplicitCastExpr {
   SourceLocation TyBeginLoc;
   SourceLocation RParenLoc;
 public:
-  CXXFunctionalCastExpr(QualType ty, SourceLocation tyBeginLoc, Expr *castExpr,
+  CXXFunctionalCastExpr(QualType ty, QualType writtenTy, 
+                        SourceLocation tyBeginLoc, Expr *castExpr,
                         SourceLocation rParenLoc) : 
-    CastExpr(CXXFunctionalCastExprClass, ty, castExpr),
+    ExplicitCastExpr(CXXFunctionalCastExprClass, ty, castExpr, writtenTy),
     TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
 
   SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }

Modified: cfe/trunk/include/clang/AST/StmtNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtNodes.def?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Mon Oct 27 14:41:14 2008
@@ -77,42 +77,47 @@
 STMT(48, ConditionalOperator   , Expr)
 STMT(49, ImplicitCastExpr      , CastExpr)
 STMT(50, ExplicitCastExpr      , CastExpr)
-STMT(51, CompoundLiteralExpr   , Expr)
-STMT(52, ExtVectorElementExpr  , Expr)
-STMT(53, InitListExpr          , Expr)
-STMT(54, VAArgExpr             , Expr)
+STMT(51, ExplicitCCastExpr     , ExplicitCastExpr)
+STMT(52, CompoundLiteralExpr   , Expr)
+STMT(53, ExtVectorElementExpr  , Expr)
+STMT(54, InitListExpr          , Expr)
+STMT(55, VAArgExpr             , Expr)
 
 // GNU Extensions.
-STMT(55, AddrLabelExpr        , Expr)
-STMT(56, StmtExpr             , Expr)
-STMT(57, TypesCompatibleExpr  , Expr)
-STMT(58, ChooseExpr           , Expr)
+STMT(56, AddrLabelExpr        , Expr)
+STMT(57, StmtExpr             , Expr)
+STMT(58, TypesCompatibleExpr  , Expr)
+STMT(59, ChooseExpr           , Expr)
 
 // C++ Expressions.
-STMT(60, CXXCastExpr          , Expr)
-STMT(61, CXXBoolLiteralExpr   , Expr)
-STMT(62, CXXThrowExpr         , Expr)
-STMT(63, CXXDefaultArgExpr    , Expr)
-STMT(64, CXXFunctionalCastExpr, CastExpr)
-STMT(65, CXXZeroInitValueExpr , Expr)
-STMT(66, CXXConditionDeclExpr , DeclRefExpr)
+STMT(60, CXXNamedCastExpr       , ExplicitCastExpr)
+STMT(61, CXXStaticCastExpr      , CXXNamedCastExpr)
+STMT(62, CXXDynamicCastExpr     , CXXNamedCastExpr)
+STMT(63, CXXReinterpretCastExpr , CXXNamedCastExpr)
+STMT(64, CXXConstCastExpr       , CXXNamedCastExpr)
+STMT(65, CXXBoolLiteralExpr     , Expr)
+STMT(66, CXXThrowExpr           , Expr)
+STMT(67, CXXDefaultArgExpr      , Expr)
+STMT(68, CXXFunctionalCastExpr  , Expr)
+STMT(69, CXXZeroInitValueExpr   , Expr)
+STMT(70, CXXConditionDeclExpr   , DeclRefExpr)
 
 // Obj-C Expressions.
-STMT(70, ObjCStringLiteral    , Expr)
-STMT(71, ObjCEncodeExpr       , Expr)
-STMT(72, ObjCMessageExpr      , Expr)
-STMT(73, ObjCSelectorExpr     , Expr)
-STMT(74, ObjCProtocolExpr     , Expr)
-STMT(75, ObjCIvarRefExpr      , Expr)
-STMT(76, ObjCPropertyRefExpr  , Expr)
+STMT(80, ObjCStringLiteral    , Expr)
+STMT(81, ObjCEncodeExpr       , Expr)
+STMT(82, ObjCMessageExpr      , Expr)
+STMT(83, ObjCSelectorExpr     , Expr)
+STMT(84, ObjCProtocolExpr     , Expr)
+STMT(85, ObjCIvarRefExpr      , Expr)
+STMT(86, ObjCPropertyRefExpr  , Expr)
 
 // Clang Extensions.
-STMT(77, OverloadExpr         , Expr)
-STMT(78, ShuffleVectorExpr    , Expr)
-STMT(79, BlockExpr            , Expr)
-STMT(80, BlockDeclRefExpr     , Expr)
+STMT(90, OverloadExpr         , Expr)
+STMT(91, ShuffleVectorExpr    , Expr)
+STMT(92, BlockExpr            , Expr)
+STMT(93, BlockDeclRefExpr     , Expr)
 
-LAST_EXPR(80)
+LAST_EXPR(93)
 
 #undef STMT
 #undef FIRST_STMT

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Mon Oct 27 14:41:14 2008
@@ -593,12 +593,12 @@
   
   //===------------------------- C++ Expressions --------------------------===//
   
-  /// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
-  virtual ExprResult ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
-                                   SourceLocation LAngleBracketLoc, TypeTy *Ty,
-                                   SourceLocation RAngleBracketLoc,
-                                   SourceLocation LParenLoc, ExprTy *Op,
-                                   SourceLocation RParenLoc) {
+  /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
+  virtual ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
+                                       SourceLocation LAngleBracketLoc, TypeTy *Ty,
+                                       SourceLocation RAngleBracketLoc,
+                                       SourceLocation LParenLoc, ExprTy *Op,
+                                       SourceLocation RParenLoc) {
     return 0;
   }
 

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Mon Oct 27 14:41:14 2008
@@ -304,7 +304,7 @@
         return E->hasLocalSideEffect();
     return false;
   }
-  case ExplicitCastExprClass:
+  case ExplicitCCastExprClass:
   case CXXFunctionalCastExprClass:
     // If this is a cast to void, check the operand.  Otherwise, the result of
     // the cast is unused.
@@ -628,7 +628,7 @@
     return true;
   }
   case ImplicitCastExprClass:
-  case ExplicitCastExprClass:
+  case ExplicitCCastExprClass:
   case CXXFunctionalCastExprClass: {
     const Expr *SubExpr = cast<CastExpr>(this)->getSubExpr();
     SourceLocation CastLoc = getLocStart();
@@ -946,7 +946,7 @@
     break;
   }
   case ImplicitCastExprClass:
-  case ExplicitCastExprClass:
+  case ExplicitCCastExprClass:
   case CXXFunctionalCastExprClass: {
     const Expr *SubExpr = cast<CastExpr>(this)->getSubExpr();
     SourceLocation CastLoc = getLocStart();

Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Mon Oct 27 14:41:14 2008
@@ -25,10 +25,6 @@
 //===----------------------------------------------------------------------===//
 
 
-// CXXCastExpr
-Stmt::child_iterator CXXCastExpr::child_begin() { return &Op; }
-Stmt::child_iterator CXXCastExpr::child_end() { return &Op+1; }
-
 // CXXBoolLiteralExpr
 Stmt::child_iterator CXXBoolLiteralExpr::child_begin() { 
   return child_iterator();
@@ -67,3 +63,20 @@
 Stmt::child_iterator CXXConditionDeclExpr::child_end() {
   return child_iterator();
 }
+
+//===----------------------------------------------------------------------===//
+//  Named casts
+//===----------------------------------------------------------------------===//
+
+/// getCastName - Get the name of the C++ cast being used, e.g.,
+/// "static_cast", "dynamic_cast", "reinterpret_cast", or
+/// "const_cast". The returned pointer must not be freed.
+const char *CXXNamedCastExpr::getCastName() const {
+  switch (getStmtClass()) {
+  case CXXStaticCastExprClass:      return "static_cast";
+  case CXXDynamicCastExprClass:     return "dynamic_cast";
+  case CXXReinterpretCastExprClass: return "reinterpret_cast";
+  case CXXConstCastExprClass:       return "const_cast";
+  default:                          return "<invalid cast>";
+  }
+}

Modified: cfe/trunk/lib/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtDumper.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtDumper.cpp (original)
+++ cfe/trunk/lib/AST/StmtDumper.cpp Mon Oct 27 14:41:14 2008
@@ -128,8 +128,9 @@
     void VisitTypesCompatibleExpr(TypesCompatibleExpr *Node);
 
     // C++
-    void VisitCXXCastExpr(CXXCastExpr *Node);
+    void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
     void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node);
+    void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node);
 
     // ObjC
     void VisitObjCEncodeExpr(ObjCEncodeExpr *Node);
@@ -406,9 +407,10 @@
 // C++ Expressions
 //===----------------------------------------------------------------------===//
 
-void StmtDumper::VisitCXXCastExpr(CXXCastExpr *Node) {
+void StmtDumper::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
   DumpExpr(Node);
-  fprintf(F, " %s", CXXCastExpr::getOpcodeStr(Node->getOpcode()));
+  fprintf(F, " %s<%s>", Node->getCastName(),
+          Node->getTypeAsWritten().getAsString().c_str());
 }
 
 void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
@@ -416,6 +418,12 @@
   fprintf(F, " %s", Node->getValue() ? "true" : "false");
 }
 
+void StmtDumper::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
+  DumpExpr(Node);
+  fprintf(F, " functional cast to %s", 
+          Node->getTypeAsWritten().getAsString().c_str());
+}
+
 //===----------------------------------------------------------------------===//
 // Obj-C Expressions
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Mon Oct 27 14:41:14 2008
@@ -707,7 +707,10 @@
 void StmtPrinter::VisitCastExpr(CastExpr *) {
   assert(0 && "CastExpr is an abstract class");
 }
-void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *Node) {
+void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) {
+  assert(0 && "ExplicitCastExpr is an abstract class");
+}
+void StmtPrinter::VisitExplicitCCastExpr(ExplicitCCastExpr *Node) {
   OS << "(" << Node->getType().getAsString() << ")";
   PrintExpr(Node->getSubExpr());
 }
@@ -809,13 +812,29 @@
 
 // C++
 
-void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) {
-  OS << CXXCastExpr::getOpcodeStr(Node->getOpcode()) << '<';
-  OS << Node->getDestType().getAsString() << ">(";
+void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
+  OS << Node->getCastName() << '<';
+  OS << Node->getTypeAsWritten().getAsString() << ">(";
   PrintExpr(Node->getSubExpr());
   OS << ")";
 }
 
+void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
+  VisitCXXNamedCastExpr(Node);
+}
+
+void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
+  VisitCXXNamedCastExpr(Node);
+}
+
+void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
+  VisitCXXNamedCastExpr(Node);
+}
+
+void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
+  VisitCXXNamedCastExpr(Node);
+}
+
 void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
   OS << (Node->getValue() ? "true" : "false");
 }

Modified: cfe/trunk/lib/AST/StmtSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtSerialization.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtSerialization.cpp (original)
+++ cfe/trunk/lib/AST/StmtSerialization.cpp Mon Oct 27 14:41:14 2008
@@ -106,8 +106,8 @@
     case ImplicitCastExprClass:
       return ImplicitCastExpr::CreateImpl(D, C);
 
-    case ExplicitCastExprClass:
-      return ExplicitCastExpr::CreateImpl(D, C);
+    case ExplicitCCastExprClass:
+      return ExplicitCCastExpr::CreateImpl(D, C);
       
     case IndirectGotoStmtClass:
       return IndirectGotoStmt::CreateImpl(D, C);
@@ -201,6 +201,18 @@
     case CXXFunctionalCastExprClass:
       return CXXFunctionalCastExpr::CreateImpl(D, C);
 
+    case CXXStaticCastExprClass:
+      return CXXStaticCastExpr::CreateImpl(D, C, SC);
+
+    case CXXDynamicCastExprClass:
+      return CXXDynamicCastExpr::CreateImpl(D, C, SC);
+
+    case CXXReinterpretCastExprClass:
+      return CXXReinterpretCastExpr::CreateImpl(D, C, SC);
+
+    case CXXConstCastExprClass:
+      return CXXConstCastExpr::CreateImpl(D, C, SC);
+      
     case CXXZeroInitValueExprClass:
       return CXXZeroInitValueExpr::CreateImpl(D, C);
   }
@@ -364,19 +376,20 @@
   return stmt;
 }
 
-void ExplicitCastExpr::EmitImpl(Serializer& S) const {
+void ExplicitCCastExpr::EmitImpl(Serializer& S) const {
   S.Emit(getType());
+  S.Emit(getTypeAsWritten());
   S.Emit(Loc);
   S.EmitOwnedPtr(getSubExpr());
 }
 
-ExplicitCastExpr* ExplicitCastExpr::CreateImpl(Deserializer& D, ASTContext& C) {
+ExplicitCCastExpr* ExplicitCCastExpr::CreateImpl(Deserializer& D, ASTContext& C) {
   QualType t = QualType::ReadVal(D);
+  QualType writtenTy = QualType::ReadVal(D);
   SourceLocation Loc = SourceLocation::ReadVal(D);
   Expr* Op = D.ReadOwnedPtr<Expr>(C);
-  return new ExplicitCastExpr(t,Op,Loc);
+  return new ExplicitCCastExpr(t,Op,writtenTy,Loc);
 }
-  
 
 void CharacterLiteral::EmitImpl(Serializer& S) const {
   S.Emit(Value);
@@ -1270,6 +1283,7 @@
 
 void CXXFunctionalCastExpr::EmitImpl(Serializer& S) const {
   S.Emit(getType());
+  S.Emit(getTypeAsWritten());
   S.Emit(TyBeginLoc);
   S.Emit(RParenLoc);
   S.EmitOwnedPtr(getSubExpr());
@@ -1278,10 +1292,39 @@
 CXXFunctionalCastExpr *
 CXXFunctionalCastExpr::CreateImpl(Deserializer& D, ASTContext& C) {
   QualType Ty = QualType::ReadVal(D);
+  QualType WrittenTy = QualType::ReadVal(D);
   SourceLocation TyBeginLoc = SourceLocation::ReadVal(D);
   SourceLocation RParenLoc = SourceLocation::ReadVal(D);
   Expr* SubExpr = D.ReadOwnedPtr<Expr>(C);
-  return new CXXFunctionalCastExpr(Ty, TyBeginLoc, SubExpr, RParenLoc);
+  return new CXXFunctionalCastExpr(Ty, WrittenTy, TyBeginLoc, SubExpr, RParenLoc);
+}
+
+void CXXNamedCastExpr::EmitImpl(Serializer& S) const {
+  S.Emit(getType());
+  S.Emit(getTypeAsWritten());
+  S.Emit(Loc);
+  S.EmitOwnedPtr(getSubExpr());
+}
+
+CXXNamedCastExpr *
+CXXNamedCastExpr::CreateImpl(Deserializer& D, ASTContext& C, StmtClass SC) {
+  QualType Ty = QualType::ReadVal(D);
+  QualType WrittenTy = QualType::ReadVal(D);
+  SourceLocation Loc = SourceLocation::ReadVal(D);
+  Expr* SubExpr = D.ReadOwnedPtr<Expr>(C);
+  switch (SC) {
+  case CXXStaticCastExprClass: 
+    return new CXXStaticCastExpr(Ty, SubExpr, WrittenTy, Loc);
+  case CXXDynamicCastExprClass: 
+    return new CXXDynamicCastExpr(Ty, SubExpr, WrittenTy, Loc);
+  case CXXReinterpretCastExprClass: 
+    return new CXXReinterpretCastExpr(Ty, SubExpr, WrittenTy, Loc);
+  case CXXConstCastExprClass: 
+    return new CXXConstCastExpr(Ty, SubExpr, WrittenTy, Loc);
+  default:
+    assert(false && "Unknown cast type!");
+    return 0;
+  }
 }
 
 void CXXZeroInitValueExpr::EmitImpl(Serializer& S) const {

Modified: cfe/trunk/lib/Analysis/Environment.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Environment.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/Environment.cpp (original)
+++ cfe/trunk/lib/Analysis/Environment.cpp Mon Oct 27 14:41:14 2008
@@ -47,7 +47,7 @@
       // subexpression that has a value.
        
       case Stmt::ImplicitCastExprClass:
-      case Stmt::ExplicitCastExprClass: {
+      case Stmt::ExplicitCCastExprClass: {
         CastExpr* C = cast<CastExpr>(E);
         QualType CT = C->getType();
         QualType ST = C->getSubExpr()->getType();

Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Mon Oct 27 14:41:14 2008
@@ -345,7 +345,7 @@
       break;
       
     case Stmt::ImplicitCastExprClass:
-    case Stmt::ExplicitCastExprClass: {
+    case Stmt::ExplicitCCastExprClass: {
       CastExpr* C = cast<CastExpr>(S);
       VisitCast(C, C->getSubExpr(), Pred, Dst);
       break;
@@ -1445,6 +1445,9 @@
   QualType T = CastE->getType();
   QualType ExTy = Ex->getType();
 
+  if (const ExplicitCastExpr *ExCast = dyn_cast_or_null<ExplicitCastExpr>(CastE))
+    T = ExCast->getTypeAsWritten();
+
   if (ExTy->isArrayType() || ExTy->isFunctionType() || T->isReferenceType())
     VisitLValue(Ex, Pred, S1);
   else

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon Oct 27 14:41:14 2008
@@ -61,9 +61,9 @@
   ExprResult Result = ParseSimpleParenExpression(RParenLoc);
 
   if (!Result.isInvalid)
-    Result = Actions.ActOnCXXCasts(OpLoc, Kind,
-                                   LAngleBracketLoc, CastTy, RAngleBracketLoc,
-                                   LParenLoc, Result.Val, RParenLoc);
+    Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
+                                       LAngleBracketLoc, CastTy, RAngleBracketLoc,
+                                       LParenLoc, Result.Val, RParenLoc);
 
   return Result;
 }

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Oct 27 14:41:14 2008
@@ -695,12 +695,12 @@
                                              SourceLocation *CommaLocs,
                                              SourceLocation RParenLoc);
 
-  /// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
-  virtual ExprResult ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
-                                   SourceLocation LAngleBracketLoc, TypeTy *Ty,
-                                   SourceLocation RAngleBracketLoc,
-                                   SourceLocation LParenLoc, ExprTy *E,
-                                   SourceLocation RParenLoc);
+  /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
+  virtual ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
+                                       SourceLocation LAngleBracketLoc, TypeTy *Ty,
+                                       SourceLocation RAngleBracketLoc,
+                                       SourceLocation LParenLoc, ExprTy *E,
+                                       SourceLocation RParenLoc);
 
   // Helpers for ActOnCXXCasts
   bool CastsAwayConstness(QualType SrcType, QualType DestType);

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Oct 27 14:41:14 2008
@@ -736,12 +736,11 @@
   }
   // Perform checking for stack values returned by reference.
   else if (lhsType->isReferenceType()) {
-    // Check for an implicit cast to a reference.
-    if (ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(RetValExp))
-      if (DeclRefExpr *DR = EvalVal(I->getSubExpr()))
-        Diag(DR->getLocStart(), diag::warn_ret_stack_ref,
-             DR->getDecl()->getIdentifier()->getName(),
-             RetValExp->getSourceRange());
+    // Check for a reference to the stack
+    if (DeclRefExpr *DR = EvalVal(RetValExp))
+      Diag(DR->getLocStart(), diag::warn_ret_stack_ref,
+           DR->getDecl()->getIdentifier()->getName(),
+           RetValExp->getSourceRange());
   }
 }
 
@@ -826,9 +825,9 @@
     
   // For casts, we need to handle conversions from arrays to
   // pointer values, and pointer-to-pointer conversions.
-  case Stmt::ExplicitCastExprClass:
-  case Stmt::ImplicitCastExprClass: {
-    
+  case Stmt::ImplicitCastExprClass:
+  case Stmt::ExplicitCCastExprClass:
+  case Stmt::CXXFunctionalCastExprClass: {
     Expr* SubExpr = cast<CastExpr>(E)->getSubExpr();
     QualType T = SubExpr->getType();
     
@@ -844,21 +843,21 @@
     
   // C++ casts.  For dynamic casts, static casts, and const casts, we
   // are always converting from a pointer-to-pointer, so we just blow
-  // through the cast.  In the case the dynamic cast doesn't fail
-  // (and return NULL), we take the conservative route and report cases
+  // through the cast.  In the case the dynamic cast doesn't fail (and
+  // return NULL), we take the conservative route and report cases
   // where we return the address of a stack variable.  For Reinterpre
-  case Stmt::CXXCastExprClass: {
-    CXXCastExpr *C = cast<CXXCastExpr>(E);
-    
-    if (C->getOpcode() == CXXCastExpr::ReinterpretCast) {
-      Expr *S = C->getSubExpr();
+  // FIXME: The comment about is wrong; we're not always converting
+  // from pointer to pointer. I'm guessing that this code should also
+  // handle references to objects.  
+  case Stmt::CXXStaticCastExprClass: 
+  case Stmt::CXXDynamicCastExprClass: 
+  case Stmt::CXXConstCastExprClass:
+  case Stmt::CXXReinterpretCastExprClass: {
+      Expr *S = cast<CXXNamedCastExpr>(E)->getSubExpr();
       if (S->getType()->isPointerType() || S->getType()->isBlockPointerType())
         return EvalAddr(S);
       else
         return NULL;
-    }
-    else
-      return EvalAddr(C->getSubExpr());
   }
     
   // Everything else: we simply don't reason about them.

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Oct 27 14:41:14 2008
@@ -1060,7 +1060,7 @@
            CheckArithmeticConstantExpression(IExp);
   }
   case Expr::ImplicitCastExprClass:
-  case Expr::ExplicitCastExprClass: {
+  case Expr::ExplicitCCastExprClass: {
     const Expr* SubExpr = cast<CastExpr>(Init)->getSubExpr();
     if (Init->getStmtClass() == Expr::ImplicitCastExprClass) {
       // Check for implicit promotion
@@ -1190,7 +1190,7 @@
     // if we don't, we'll figure it out later
     return 0;
   }
-  case Expr::ExplicitCastExprClass: {
+  case Expr::ExplicitCCastExprClass: {
     const Expr* SubExpr = cast<CastExpr>(E)->getSubExpr();
 
     // Check for pointer->pointer cast
@@ -1310,7 +1310,7 @@
     return true;
   }
   case Expr::ImplicitCastExprClass:
-  case Expr::ExplicitCastExprClass: {
+  case Expr::ExplicitCCastExprClass: {
     const Expr *SubExpr = cast<CastExpr>(Init)->getSubExpr();
     if (SubExpr->getType()->isArithmeticType())
       return CheckArithmeticConstantExpression(SubExpr);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Oct 27 14:41:14 2008
@@ -1333,7 +1333,7 @@
 
   if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), castType, castExpr))
     return true;
-  return new ExplicitCastExpr(castType, castExpr, LParenLoc);
+  return new ExplicitCCastExpr(castType, castExpr, castType, LParenLoc);
 }
 
 /// Note that lex is not null here, even if this is the gnu "x ?: y" extension.

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Oct 27 14:41:14 2008
@@ -21,36 +21,39 @@
 #include "llvm/Support/Debug.h"
 using namespace clang;
 
-/// ActOnCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
+/// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
 Action::ExprResult
-Sema::ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
-                    SourceLocation LAngleBracketLoc, TypeTy *Ty,
-                    SourceLocation RAngleBracketLoc,
-                    SourceLocation LParenLoc, ExprTy *E,
-                    SourceLocation RParenLoc) {
-  CXXCastExpr::Opcode Op;
+Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
+                        SourceLocation LAngleBracketLoc, TypeTy *Ty,
+                        SourceLocation RAngleBracketLoc,
+                        SourceLocation LParenLoc, ExprTy *E,
+                        SourceLocation RParenLoc) {
   Expr *Ex = (Expr*)E;
   QualType DestType = QualType::getFromOpaquePtr(Ty);
 
   switch (Kind) {
   default: assert(0 && "Unknown C++ cast!");
+
   case tok::kw_const_cast:
-    Op = CXXCastExpr::ConstCast;
     CheckConstCast(OpLoc, Ex, DestType);
-    break;
+    return new CXXConstCastExpr(DestType.getNonReferenceType(), Ex, 
+                                DestType, OpLoc);
+
   case tok::kw_dynamic_cast:
-    Op = CXXCastExpr::DynamicCast;
-    break;
+    return new CXXDynamicCastExpr(DestType.getNonReferenceType(), Ex, 
+                                  DestType, OpLoc);
+
   case tok::kw_reinterpret_cast:
-    Op = CXXCastExpr::ReinterpretCast;
     CheckReinterpretCast(OpLoc, Ex, DestType);
-    break;
+    return new CXXReinterpretCastExpr(DestType.getNonReferenceType(), Ex, 
+                                      DestType, OpLoc);
+
   case tok::kw_static_cast:
-    Op = CXXCastExpr::StaticCast;
-    break;
+    return new CXXStaticCastExpr(DestType.getNonReferenceType(), Ex, 
+                                 DestType, OpLoc);
   }
   
-  return new CXXCastExpr(Op, DestType, Ex, OpLoc);
+  return true;
 }
 
 /// CheckConstCast - Check that a const_cast\<DestType\>(SrcExpr) is valid.
@@ -437,7 +440,8 @@
   if (NumExprs == 1) {
     if (CheckCastTypes(TypeRange, Ty, Exprs[0]))
       return true;
-    return new CXXFunctionalCastExpr(Ty, TyBeginLoc, Exprs[0], RParenLoc);
+    return new CXXFunctionalCastExpr(Ty.getNonReferenceType(), Ty, TyBeginLoc, 
+                                     Exprs[0], RParenLoc);
   }
 
   // C++ 5.2.3p1:

Modified: cfe/trunk/test/SemaCXX/return-stack-addr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/return-stack-addr.cpp?rev=58264&r1=58263&r2=58264&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/return-stack-addr.cpp (original)
+++ cfe/trunk/test/SemaCXX/return-stack-addr.cpp Mon Oct 27 14:41:14 2008
@@ -1,6 +1,5 @@
 // RUN: clang -fsyntax-only -verify %s
 
-
 int* ret_local() {
   int x = 1;
   return &x; // expected-warning {{address of stack memory}}





More information about the cfe-commits mailing list