Index: test/Analysis/temp-obj-dtors-cfg-output.cpp
===================================================================
--- test/Analysis/temp-obj-dtors-cfg-output.cpp	(revision 151277)
+++ test/Analysis/temp-obj-dtors-cfg-output.cpp	(working copy)
@@ -114,37 +114,33 @@
 // CHECK:     2: [B1.1] (BindTemporary)
 // CHECK:     3: [B1.2].operator int
 // CHECK:     4: [B1.3]()
-// CHECK:     5: [B1.4] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK:     6: int([B1.5]) (CXXFunctionalCastExpr, NoOp, int)
-// CHECK:     7: B() (CXXConstructExpr, class B)
-// CHECK:     8: [B1.7] (BindTemporary)
-// CHECK:     9: [B1.8].operator int
-// CHECK:    10: [B1.9]()
-// CHECK:    11: [B1.10] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK:    12: int([B1.11]) (CXXFunctionalCastExpr, NoOp, int)
-// CHECK:    13: [B1.6] + [B1.12]
-// CHECK:    14: int a = int(A().operator int()) + int(B().operator int());
-// CHECK:    15: ~B() (Temporary object destructor)
-// CHECK:    16: ~A() (Temporary object destructor)
-// CHECK:    17: A() (CXXConstructExpr, class A)
-// CHECK:    18: [B1.17] (BindTemporary)
-// CHECK:    19: [B1.18].operator int
-// CHECK:    20: [B1.19]()
-// CHECK:    21: [B1.20] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK:    22: int([B1.21]) (CXXFunctionalCastExpr, NoOp, int)
-// CHECK:    23: B() (CXXConstructExpr, class B)
-// CHECK:    24: [B1.23] (BindTemporary)
-// CHECK:    25: [B1.24].operator int
-// CHECK:    26: [B1.25]()
-// CHECK:    27: [B1.26] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK:    28: int([B1.27]) (CXXFunctionalCastExpr, NoOp, int)
-// CHECK:    29: [B1.22] + [B1.28]
-// CHECK:    30: foo
-// CHECK:    31: [B1.30] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(int))
-// CHECK:    32: [B1.31]([B1.29])
-// CHECK:    33: ~B() (Temporary object destructor)
-// CHECK:    34: ~A() (Temporary object destructor)
-// CHECK:    35: int b;
+// CHECK:     5: int([B1.4]) (CXXFunctionalCastExpr, UserDefinedConversion, int)
+// CHECK:     6: B() (CXXConstructExpr, class B)
+// CHECK:     7: [B1.6] (BindTemporary)
+// CHECK:     8: [B1.7].operator int
+// CHECK:     9: [B1.8]()
+// CHECK:    10: int([B1.9]) (CXXFunctionalCastExpr, UserDefinedConversion, int)
+// CHECK:    11: [B1.5] + [B1.10]
+// CHECK:    12: int a = int(A().operator int()) + int(B().operator int());
+// CHECK:    13: ~B() (Temporary object destructor)
+// CHECK:    14: ~A() (Temporary object destructor)
+// CHECK:    15: A() (CXXConstructExpr, class A)
+// CHECK:    16: [B1.15] (BindTemporary)
+// CHECK:    17: [B1.16].operator int
+// CHECK:    18: [B1.17]()
+// CHECK:    19: int([B1.18]) (CXXFunctionalCastExpr, UserDefinedConversion, int)
+// CHECK:    20: B() (CXXConstructExpr, class B)
+// CHECK:    21: [B1.20] (BindTemporary)
+// CHECK:    22: [B1.21].operator int
+// CHECK:    23: [B1.22]()
+// CHECK:    24: int([B1.23]) (CXXFunctionalCastExpr, UserDefinedConversion, int)
+// CHECK:    25: [B1.19] + [B1.24]
+// CHECK:    26: foo
+// CHECK:    27: [B1.26] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(int))
+// CHECK:    28: [B1.27]([B1.25])
+// CHECK:    29: ~B() (Temporary object destructor)
+// CHECK:    30: ~A() (Temporary object destructor)
+// CHECK:    31: int b;
 // CHECK:     Preds (1): B2
 // CHECK:     Succs (1): B0
 // CHECK:   [B0 (EXIT)]
@@ -746,20 +742,18 @@
 // CHECK:     2: [B1.1] (BindTemporary)
 // CHECK:     3: [B1.2].operator int
 // CHECK:     4: [B1.3]()
-// CHECK:     5: [B1.4] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK:     6: int([B1.5]) (CXXFunctionalCastExpr, NoOp, int)
-// CHECK:     7: B() (CXXConstructExpr, class B)
-// CHECK:     8: [B1.7] (BindTemporary)
-// CHECK:     9: [B1.8].operator int
-// CHECK:    10: [B1.9]()
-// CHECK:    11: [B1.10] (ImplicitCastExpr, UserDefinedConversion, int)
-// CHECK:    12: int([B1.11]) (CXXFunctionalCastExpr, NoOp, int)
-// CHECK:    13: [B1.6] + [B1.12]
-// CHECK:    14: a([B1.13]) (Member initializer)
-// CHECK:    15: ~B() (Temporary object destructor)
-// CHECK:    16: ~A() (Temporary object destructor)
-// CHECK:    17: /*implicit*/int()
-// CHECK:    18: b([B1.17]) (Member initializer)
+// CHECK:     5: int([B1.4]) (CXXFunctionalCastExpr, UserDefinedConversion, int)
+// CHECK:     6: B() (CXXConstructExpr, class B)
+// CHECK:     7: [B1.6] (BindTemporary)
+// CHECK:     8: [B1.7].operator int
+// CHECK:     9: [B1.8]()
+// CHECK:    10: int([B1.9]) (CXXFunctionalCastExpr, UserDefinedConversion, int)
+// CHECK:    11: [B1.5] + [B1.10]
+// CHECK:    12: a([B1.11]) (Member initializer)
+// CHECK:    13: ~B() (Temporary object destructor)
+// CHECK:    14: ~A() (Temporary object destructor)
+// CHECK:    15: /*implicit*/int()
+// CHECK:    16: b([B1.15]) (Member initializer)
 // CHECK:     Preds (1): B2
 // CHECK:     Succs (1): B0
 // CHECK:   [B0 (EXIT)]
Index: test/Index/recursive-cxx-member-calls.cpp
===================================================================
--- test/Index/recursive-cxx-member-calls.cpp	(revision 151277)
+++ test/Index/recursive-cxx-member-calls.cpp	(working copy)
@@ -961,7 +961,7 @@
 // CHECK-tokens: Punctuation: ">" [105:51 - 105:52] CallExpr=StringSwitch:87:12
 // CHECK-tokens: Punctuation: "(" [105:53 - 105:54] CallExpr=StringSwitch:87:12
 // CHECK-tokens: Identifier: "AttrName" [105:54 - 105:62] DeclRefExpr=AttrName:101:19
-// CHECK-tokens: Punctuation: ")" [105:62 - 105:63] CXXFunctionalCastExpr=
+// CHECK-tokens: Punctuation: ")" [105:62 - 105:63] CallExpr=StringSwitch:87:12
 // CHECK-tokens: Punctuation: "." [106:5 - 106:6] MemberRefExpr=Case:88:42
 // CHECK-tokens: Identifier: "Case" [106:6 - 106:10] MemberRefExpr=Case:88:42
 // CHECK-tokens: Punctuation: "(" [106:10 - 106:11] CallExpr=Case:88:42
@@ -1632,7 +1632,6 @@
 // CHECK: 41:30: UnaryOperator= Extent=[41:30 - 41:40]
 // CHECK: 41:31: CXXFunctionalCastExpr= Extent=[41:31 - 41:40]
 // CHECK: 41:31: TypeRef=size_t:2:25 Extent=[41:31 - 41:37]
-// CHECK: 41:38: UnexposedExpr= Extent=[41:38 - 41:39]
 // CHECK: 41:38: IntegerLiteral= Extent=[41:38 - 41:39]
 // CHECK: 42:1: CXXAccessSpecifier=:42:1 (Definition) Extent=[42:1 - 42:9]
 // CHECK: 43:15: FieldDecl=Data:43:15 (Definition) Extent=[43:3 - 43:19]
@@ -1804,7 +1803,6 @@
 // CHECK: 75:13: ParenExpr= Extent=[75:13 - 75:30]
 // CHECK: 75:14: CStyleCastExpr= Extent=[75:14 - 75:29]
 // CHECK: 75:25: UnexposedExpr= Extent=[75:25 - 75:29]
-// CHECK: 75:25: UnexposedExpr= Extent=[75:25 - 75:29]
 // CHECK: 75:25: ArraySubscriptExpr= Extent=[75:25 - 75:29]
 // CHECK: 75:25: DeclRefExpr=p:74:17 Extent=[75:25 - 75:26]
 // CHECK: 75:27: IntegerLiteral= Extent=[75:27 - 75:28]
@@ -1813,7 +1811,6 @@
 // CHECK: 75:34: ParenExpr= Extent=[75:34 - 75:51]
 // CHECK: 75:35: CStyleCastExpr= Extent=[75:35 - 75:50]
 // CHECK: 75:46: UnexposedExpr= Extent=[75:46 - 75:50]
-// CHECK: 75:46: UnexposedExpr= Extent=[75:46 - 75:50]
 // CHECK: 75:46: ArraySubscriptExpr= Extent=[75:46 - 75:50]
 // CHECK: 75:46: DeclRefExpr=p:74:17 Extent=[75:46 - 75:47]
 // CHECK: 75:48: IntegerLiteral= Extent=[75:48 - 75:49]
@@ -1885,7 +1882,6 @@
 // CHECK: 102:7: DeclRefExpr=AttrName:101:19 Extent=[102:7 - 102:15]
 // CHECK: 102:27: CallExpr= Extent=[102:27 - 102:31]
 // CHECK: 102:27: UnexposedExpr=StringRef:48:3 Extent=[102:27 - 102:31]
-// CHECK: 102:27: UnexposedExpr=StringRef:48:3 Extent=[102:27 - 102:31]
 // CHECK: 102:27: CallExpr=StringRef:48:3 Extent=[102:27 - 102:31]
 // CHECK: 102:27: UnexposedExpr= Extent=[102:27 - 102:31]
 // CHECK: 102:27: StringLiteral= Extent=[102:27 - 102:31]
@@ -1895,7 +1891,6 @@
 // CHECK: 102:36: DeclRefExpr=AttrName:101:19 Extent=[102:36 - 102:44]
 // CHECK: 102:54: CallExpr= Extent=[102:54 - 102:58]
 // CHECK: 102:54: UnexposedExpr=StringRef:48:3 Extent=[102:54 - 102:58]
-// CHECK: 102:54: UnexposedExpr=StringRef:48:3 Extent=[102:54 - 102:58]
 // CHECK: 102:54: CallExpr=StringRef:48:3 Extent=[102:54 - 102:58]
 // CHECK: 102:54: UnexposedExpr= Extent=[102:54 - 102:58]
 // CHECK: 102:54: StringLiteral= Extent=[102:54 - 102:58]
@@ -2081,7 +2076,7 @@
 // CHECK: 106:6: MemberRefExpr=Case:88:42 SingleRefName=[106:6 - 106:10] RefName=[106:6 - 106:10] Extent=[105:10 - 106:10]
 // CHECK: 105:10: CXXFunctionalCastExpr= Extent=[105:10 - 105:63]
 // CHECK: 105:16: TemplateRef=StringSwitch:83:47 Extent=[105:16 - 105:28]
-// CHECK: 105:10: CallExpr=StringSwitch:87:12 Extent=[105:10 - 105:62]
+// CHECK: 105:10: CallExpr=StringSwitch:87:12 Extent=[105:10 - 105:63]
 // CHECK: 105:54: CallExpr=StringRef:38:7 Extent=[105:54 - 105:62]
 // CHECK: 105:54: UnexposedExpr=AttrName:101:19 Extent=[105:54 - 105:62]
 // CHECK: 105:54: DeclRefExpr=AttrName:101:19 Extent=[105:54 - 105:62]
Index: test/Index/preamble_macro_template.cpp
===================================================================
--- test/Index/preamble_macro_template.cpp	(revision 151277)
+++ test/Index/preamble_macro_template.cpp	(working copy)
@@ -9,7 +9,6 @@
 // CHECK: preamble_macro_template.h:4:16: CompoundStmt= Extent=[4:16 - 6:2]
 // CHECK: preamble_macro_template.h:5:3: CStyleCastExpr= Extent=[5:3 - 5:27]
 // CHECK: preamble_macro_template.h:1:21: CXXStaticCastExpr= Extent=[1:21 - 5:27]
-// CHECK: preamble_macro_template.h:5:25: UnexposedExpr= Extent=[5:25 - 5:26]
 // CHECK: preamble_macro_template.h:5:25: IntegerLiteral= Extent=[5:25 - 5:26]
 // CHECK: preamble_macro_template.cpp:3:5: FunctionDecl=main:3:5 (Definition) Extent=[3:1 - 3:15]
 // CHECK: preamble_macro_template.cpp:3:12: CompoundStmt= Extent=[3:12 - 3:15]
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 151277)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -5837,18 +5837,44 @@
     CCK_CStyleCast,
     /// \brief A functional-style cast.
     CCK_FunctionalCast,
+    /// \breif A static cast
+    CCK_StaticCast,
     /// \brief A cast other than a C-style cast.
     CCK_OtherCast
   };
 
-  /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
-  /// cast.  If there is already an implicit cast, merge into the existing one.
-  /// If isLvalue, the result of the cast is an lvalue.
+  class CheckedConversionInfo {
+    CheckedConversionKind CCK;
+    SourceRange TypeRange;
+    TypeSourceInfo *TInfo;
+    
+  public:  
+    explicit CheckedConversionInfo(CheckedConversionKind CCK =
+                                                         CCK_ImplicitConversion,
+                                   SourceRange TypeRange = SourceRange(),
+                                   TypeSourceInfo *TInfo = 0)
+    : CCK(CCK), TypeRange(TypeRange), TInfo(TInfo) { }
+    
+    CheckedConversionKind getKind() const { return CCK; }
+    SourceRange getTypeRange() const { return TypeRange; }
+    
+    TypeSourceInfo *getTypeSourceInfo() const { return TInfo; }
+  };
+  
+  /// CastExprToType - If Expr is not of type 'Type', insert a cast of the
+  /// specified kind.
+  /// Redundant implicit casts are merged together.
+  ExprResult CastExprToType(Expr *E, QualType Ty,
+                            CastKind Kind, ExprValueKind VK,
+                            const CXXCastPath *BasePath,
+                            CheckedConversionInfo CCI);
+     
+  /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
+  /// If there is already an implicit cast, merge into the existing one.
+  /// The result is of the given category.
   ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK,
                                ExprValueKind VK = VK_RValue,
-                               const CXXCastPath *BasePath = 0,
-                               CheckedConversionKind CCK
-                                  = CCK_ImplicitConversion);
+                               const CXXCastPath *BasePath = 0);
 
   /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
   /// to the conversion from scalar type ScalarTy to the Boolean type.
@@ -6035,12 +6061,12 @@
   ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
                                        const ImplicitConversionSequence& ICS,
                                        AssignmentAction Action,
-                                       CheckedConversionKind CCK
-                                          = CCK_ImplicitConversion);
-  ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
-                                       const StandardConversionSequence& SCS,
-                                       AssignmentAction Action,
-                                       CheckedConversionKind CCK);
+                                       CheckedConversionInfo CCI =
+                                         CheckedConversionInfo());
+  ExprResult PerformConversion(Expr *From, QualType ToType,
+                               const StandardConversionSequence& SCS,
+                               AssignmentAction Action,
+                               CheckedConversionInfo CCI);
 
   /// the following "Check" methods will return a valid/converted QualType
   /// or a null QualType (indicating an error diagnostic was issued).
Index: include/clang/Sema/Initialization.h
===================================================================
--- include/clang/Sema/Initialization.h	(revision 151277)
+++ include/clang/Sema/Initialization.h	(working copy)
@@ -13,6 +13,7 @@
 #ifndef LLVM_CLANG_SEMA_INITIALIZATION_H
 #define LLVM_CLANG_SEMA_INITIALIZATION_H
 
+#include "clang/Sema/Sema.h"
 #include "clang/Sema/Ownership.h"
 #include "clang/Sema/Overload.h"
 #include "clang/AST/Type.h"
@@ -30,7 +31,6 @@
 class FieldDecl;
 class FunctionDecl;
 class ParmVarDecl;
-class Sema;
 class TypeLoc;
 class VarDecl;
   
@@ -390,10 +390,16 @@
   
   /// \brief The source locations involved in the initialization.
   SourceLocation Locations[3];
+ 
+  /// \brief The source info of the initialization
+  TypeSourceInfo *TInfo;
   
-  InitializationKind(InitKind Kind, InitContext Context, SourceLocation Loc1, 
-                     SourceLocation Loc2, SourceLocation Loc3)
-    : Kind(Kind), Context(Context)
+  InitializationKind(InitKind Kind, InitContext Context,
+                     SourceLocation Loc1, 
+                     SourceLocation Loc2,
+                     SourceLocation Loc3,
+                     TypeSourceInfo *TInfo)
+    : Kind(Kind), Context(Context), TInfo(TInfo)
   {
     Locations[0] = Loc1;
     Locations[1] = Loc2;
@@ -406,49 +412,59 @@
                                          SourceLocation LParenLoc,
                                          SourceLocation RParenLoc) {
     return InitializationKind(IK_Direct, IC_Normal,
-                              InitLoc, LParenLoc, RParenLoc);
+                              InitLoc, LParenLoc, RParenLoc, /*TInfo=*/0);
   }
 
   static InitializationKind CreateDirectList(SourceLocation InitLoc) {
     return InitializationKind(IK_DirectList, IC_Normal,
-                              InitLoc, InitLoc, InitLoc);
+                              InitLoc, InitLoc, InitLoc, /*TInfo=*/0);
   }
 
   /// \brief Create a direct initialization due to a cast that isn't a C-style 
   /// or functional cast.
-  static InitializationKind CreateCast(SourceRange TypeRange) {
-    return InitializationKind(IK_Direct, IC_StaticCast, TypeRange.getBegin(),
-                              TypeRange.getBegin(), TypeRange.getEnd());
+  static InitializationKind CreateStaticCast(Sema::CheckedConversionInfo CCI) {
+    return InitializationKind(IK_Direct, IC_StaticCast,
+                              CCI.getTypeRange().getBegin(),
+                              CCI.getTypeRange().getBegin(),
+                              CCI.getTypeRange().getEnd(),
+                              CCI.getTypeSourceInfo());
   }
   
   /// \brief Create a direct initialization for a C-style cast.
-  static InitializationKind CreateCStyleCast(SourceLocation StartLoc,
-                                             SourceRange TypeRange,
+  static InitializationKind CreateCStyleCast(Sema::CheckedConversionInfo CCI,
                                              bool InitList) {
     // C++ cast syntax doesn't permit init lists, but C compound literals are
     // exactly that.
     return InitializationKind(InitList ? IK_DirectList : IK_Direct,
-                              IC_CStyleCast, StartLoc, TypeRange.getBegin(),
-                              TypeRange.getEnd());
+                              IC_CStyleCast,
+                              CCI.getTypeRange().getBegin(),
+                              CCI.getTypeRange().getBegin(),
+                              CCI.getTypeRange().getEnd(),
+                              CCI.getTypeSourceInfo());
   }
 
   /// \brief Create a direct initialization for a functional cast.
-  static InitializationKind CreateFunctionalCast(SourceRange TypeRange,
+  static InitializationKind CreateFunctionalCast(Sema::CheckedConversionInfo CCI,
                                                  bool InitList) {
     return InitializationKind(InitList ? IK_DirectList : IK_Direct,
-                              IC_FunctionalCast, TypeRange.getBegin(),
-                              TypeRange.getBegin(), TypeRange.getEnd());
+                              IC_FunctionalCast,
+                              CCI.getTypeRange().getBegin(),
+                              CCI.getTypeRange().getBegin(),
+                              CCI.getTypeRange().getEnd(),
+                              CCI.getTypeSourceInfo());
   }
 
   /// \brief Create a copy initialization.
   static InitializationKind CreateCopy(SourceLocation InitLoc,
                                        SourceLocation EqualLoc) {
-    return InitializationKind(IK_Copy, IC_Normal, InitLoc, EqualLoc, EqualLoc);
+    return InitializationKind(IK_Copy, IC_Normal, InitLoc,
+                              EqualLoc, EqualLoc, /*TInfo=*/0);
   }
   
   /// \brief Create a default initialization.
   static InitializationKind CreateDefault(SourceLocation InitLoc) {
-    return InitializationKind(IK_Default, IC_Normal, InitLoc, InitLoc, InitLoc);
+    return InitializationKind(IK_Default, IC_Normal, InitLoc,
+                              InitLoc, InitLoc, /*TInfo=*/0);
   }
   
   /// \brief Create a value initialization.
@@ -457,7 +473,7 @@
                                         SourceLocation RParenLoc,
                                         bool isImplicit = false) {
     return InitializationKind(IK_Value, isImplicit ? IC_Implicit : IC_Normal,
-                              InitLoc, LParenLoc, RParenLoc);
+                              InitLoc, LParenLoc, RParenLoc, /*TInfo=*/0);
   }
   
   /// \brief Determine the initialization kind.
@@ -475,6 +491,11 @@
     return Context >= IC_CStyleCast; 
   }
 
+  /// \brief Determine whether this initialization is a C++ static cast.
+  bool isStaticCast() const {
+    return Context == IC_StaticCast;
+  }
+  
   /// \brief Determine whether this is a C-style cast.
   bool isCStyleCast() const {
     return Context == IC_CStyleCast;
@@ -498,6 +519,11 @@
     return SourceRange(Locations[0], Locations[2]);
   }
   
+  /// \brief Retrieve the source info of the initialization.
+  TypeSourceInfo *getTypeSourceInfo() const {
+    return TInfo;
+  }
+  
   /// \brief Retrieve the location of the equal sign for copy initialization
   /// (if present).
   SourceLocation getEqualLoc() const {
Index: include/clang/AST/ExprCXX.h
===================================================================
--- include/clang/AST/ExprCXX.h	(revision 151277)
+++ include/clang/AST/ExprCXX.h	(working copy)
@@ -179,9 +179,11 @@
   /// \brief Retrieve the location of the cast operator keyword, e.g.,
   /// "static_cast".
   SourceLocation getOperatorLoc() const { return Loc; }
+  void setOperatorLoc(SourceLocation const & OpLoc) { Loc = OpLoc; }
 
   /// \brief Retrieve the location of the closing parenthesis.
   SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation const & Loc) { RParenLoc = Loc; }
 
   SourceRange getSourceRange() const {
     return SourceRange(Loc, RParenLoc);
Index: lib/Sema/SemaCast.cpp
===================================================================
--- lib/Sema/SemaCast.cpp	(revision 151277)
+++ lib/Sema/SemaCast.cpp	(working copy)
@@ -75,9 +75,12 @@
     // Top-level semantics-checking routines.
     void CheckConstCast();
     void CheckReinterpretCast();
-    void CheckStaticCast();
+    void CheckStaticCast(bool &CastNodesCreated,
+                         Sema::CheckedConversionInfo CCI);
     void CheckDynamicCast();
-    void CheckCXXCStyleCast(bool FunctionalCast, bool ListInitialization);
+    void CheckCXXCStyleCast(bool &CastNodesCreated,
+                            Sema::CheckedConversionInfo CCI,
+                            bool ListInitialization);
     void CheckCStyleCast();
 
     /// Complete an apparently-successful cast operation that yields
@@ -188,13 +191,13 @@
 
 static TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr,
                                            QualType DestType, 
-                                           Sema::CheckedConversionKind CCK,
+                                           Sema::CheckedConversionInfo CCI,
                                            const SourceRange &OpRange,
                                            unsigned &msg, CastKind &Kind,
                                            bool ListInitialization);
 static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
                                    QualType DestType, 
-                                   Sema::CheckedConversionKind CCK,
+                                   Sema::CheckedConversionInfo CCI,
                                    const SourceRange &OpRange,
                                    unsigned &msg, CastKind &Kind,
                                    CXXCastPath &BasePath,
@@ -283,12 +286,23 @@
                                                       Parens.getEnd()));
   }
   case tok::kw_static_cast: {
+    bool CastNodesCreated = false;
+    CheckedConversionInfo CCI(Sema::CCK_StaticCast,
+                              SourceRange(OpLoc, Parens.getEnd()), DestTInfo);
     if (!TypeDependent) {
-      Op.CheckStaticCast();
+      Op.CheckStaticCast(CastNodesCreated, CCI);
       if (Op.SrcExpr.isInvalid())
         return ExprError();
     }
     
+    // CheckStaticCast _may_ have already created the cast node. Let's check
+    if (CastNodesCreated) {
+      if (CXXStaticCastExpr *Cast =
+          dyn_cast<CXXStaticCastExpr>(Op.SrcExpr.get())) {
+        return Op.complete(Cast);
+      }
+    }
+    
     return Op.complete(CXXStaticCastExpr::Create(Context, Op.ResultType,
                                    Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
                                                  &Op.BasePath, DestTInfo,
@@ -300,7 +314,8 @@
 /// Try to diagnose a failed overloaded cast.  Returns true if
 /// diagnostics were emitted.
 static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT,
-                                      SourceRange range, Expr *src,
+                                      Sema::CheckedConversionInfo CCI,
+                                      Expr *src,
                                       QualType destType,
                                       bool listInitialization) {
   switch (CT) {
@@ -323,11 +338,11 @@
 
   InitializedEntity entity = InitializedEntity::InitializeTemporary(destType);
   InitializationKind initKind
-    = (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(range.getBegin(),
-                                                      range, listInitialization)
-    : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range,
+    = (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(CCI,
                                                              listInitialization)
-    : InitializationKind::CreateCast(/*type range?*/ range);
+    : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(CCI,
+                                                             listInitialization)
+    : InitializationKind::CreateStaticCast(CCI);
   InitializationSequence sequence(S, entity, initKind, &src, 1);
 
   assert(sequence.Failed() && "initialization succeeded on second try?");
@@ -365,9 +380,9 @@
     break;
   }
 
-  S.Diag(range.getBegin(), msg)
+  S.Diag(CCI.getTypeRange().getBegin(), msg)
     << CT << srcType << destType
-    << range << src->getSourceRange();
+    << CCI.getTypeRange() << src->getSourceRange();
 
   candidates.NoteCandidates(S, howManyCandidates, &src, 1);
 
@@ -376,7 +391,8 @@
 
 /// Diagnose a failed cast.
 static void diagnoseBadCast(Sema &S, unsigned msg, CastType castType,
-                            SourceRange opRange, Expr *src, QualType destType,
+                            Sema::CheckedConversionInfo CCI,
+                            Expr *src, QualType destType,
                             bool listInitialization) {
   if (src->getType() == S.Context.BoundMemberTy) {
     (void) S.CheckPlaceholderExpr(src); // will always fail
@@ -384,12 +400,13 @@
   }
 
   if (msg == diag::err_bad_cxx_cast_generic &&
-      tryDiagnoseOverloadedCast(S, castType, opRange, src, destType,
+      tryDiagnoseOverloadedCast(S, castType, CCI, src, destType,
                                 listInitialization))
     return;
 
-  S.Diag(opRange.getBegin(), msg) << castType
-    << src->getType() << destType << opRange << src->getSourceRange();
+  S.Diag(CCI.getTypeRange().getBegin(), msg) << castType
+    << src->getType() << destType << CCI.getTypeRange()
+    << src->getSourceRange();
 }
 
 /// UnwrapDissimilarPointerTypes - Like Sema::UnwrapSimilarPointerTypes,
@@ -707,7 +724,10 @@
       Self.NoteAllOverloadCandidates(SrcExpr.get());
 
     } else {
-      diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(),
+      Sema::CheckedConversionInfo CCI(Sema::CCK_OtherCast,
+                                      SourceRange(OpRange.getBegin(),
+                                                  OpRange.getEnd()), 0);
+      diagnoseBadCast(Self, msg, CT_Reinterpret, CCI, SrcExpr.get(),
                       DestType, /*listInitialization=*/false);
     }
   } else if (tcr == TC_Success && Self.getLangOptions().ObjCAutoRefCount) {
@@ -719,7 +739,8 @@
 /// CheckStaticCast - Check that a static_cast\<DestType\>(SrcExpr) is valid.
 /// Refer to C++ 5.2.9 for details. Static casts are mostly used for making
 /// implicit conversions explicit and getting rid of data loss warnings.
-void CastOperation::CheckStaticCast() {
+void CastOperation::CheckStaticCast(bool &CastNodesCreated,
+                                    Sema::CheckedConversionInfo CCI) {
   if (isPlaceholder()) {
     checkNonOverloadPlaceholders();
     if (SrcExpr.isInvalid())
@@ -752,9 +773,10 @@
       return;
   }
 
+  Expr *SrcExprOrig = SrcExpr.get();
   unsigned msg = diag::err_bad_cxx_cast_generic;
   TryCastResult tcr
-    = TryStaticCast(Self, SrcExpr, DestType, Sema::CCK_OtherCast, OpRange, msg,
+    = TryStaticCast(Self, SrcExpr, DestType, CCI, OpRange, msg,
                     Kind, BasePath, /*ListInitialization=*/false);
   if (tcr != TC_Success && msg != 0) {
     if (SrcExpr.isInvalid())
@@ -766,17 +788,20 @@
         << oe->getQualifierLoc().getSourceRange();
       Self.NoteAllOverloadCandidates(SrcExpr.get());
     } else {
-      diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr.get(), DestType,
+      diagnoseBadCast(Self, msg, CT_Static, CCI, SrcExpr.get(), DestType,
                       /*listInitialization=*/false);
     }
   } else if (tcr == TC_Success) {
     if (Kind == CK_BitCast)
       checkCastAlign();
     if (Self.getLangOptions().ObjCAutoRefCount)
-      checkObjCARCConversion(Sema::CCK_OtherCast);
+      checkObjCARCConversion(Sema::CCK_StaticCast);
   } else if (Kind == CK_BitCast) {
     checkCastAlign();
   }
+  
+  CastNodesCreated = (SrcExpr.get() != SrcExprOrig &&
+                      Kind != CK_ConstructorConversion);
 }
 
 /// TryStaticCast - Check if a static cast can be performed, and do so if
@@ -784,13 +809,14 @@
 /// and casting away constness.
 static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
                                    QualType DestType, 
-                                   Sema::CheckedConversionKind CCK,
+                                   Sema::CheckedConversionInfo CCI,
                                    const SourceRange &OpRange, unsigned &msg,
                                    CastKind &Kind, CXXCastPath &BasePath,
                                    bool ListInitialization) {
   // Determine whether we have the semantics of a C-style cast.
   bool CStyle 
-    = (CCK == Sema::CCK_CStyleCast || CCK == Sema::CCK_FunctionalCast);
+    = (CCI.getKind() == Sema::CCK_CStyleCast ||
+       CCI.getKind() == Sema::CCK_FunctionalCast);
   
   // The order the tests is not entirely arbitrary. There is one conversion
   // that can be handled in two different ways. Given:
@@ -827,7 +853,7 @@
 
   // C++ 5.2.9p2: An expression e can be explicitly converted to a type T
   //   [...] if the declaration "T t(e);" is well-formed, [...].
-  tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CCK, OpRange, msg,
+  tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CCI, OpRange, msg,
                               Kind, ListInitialization);
   if (SrcExpr.isInvalid())
     return TC_Failed;
@@ -1297,7 +1323,7 @@
 ///   @c static_cast if the declaration "T t(e);" is well-formed [...].
 TryCastResult
 TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
-                      Sema::CheckedConversionKind CCK, 
+                      Sema::CheckedConversionInfo CCI, 
                       const SourceRange &OpRange, unsigned &msg,
                       CastKind &Kind, bool ListInitialization) {
   if (DestType->isRecordType()) {
@@ -1310,12 +1336,11 @@
 
   InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
   InitializationKind InitKind
-    = (CCK == Sema::CCK_CStyleCast)
-        ? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange,
-                                               ListInitialization)
-    : (CCK == Sema::CCK_FunctionalCast)
-        ? InitializationKind::CreateFunctionalCast(OpRange, ListInitialization)
-    : InitializationKind::CreateCast(OpRange);
+    = (CCI.getKind() == Sema::CCK_CStyleCast)
+        ? InitializationKind::CreateCStyleCast(CCI, ListInitialization)
+    : (CCI.getKind() == Sema::CCK_FunctionalCast)
+        ? InitializationKind::CreateFunctionalCast(CCI, ListInitialization)
+    : InitializationKind::CreateStaticCast(CCI);
   Expr *SrcExprRaw = SrcExpr.get();
   InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExprRaw, 1);
 
@@ -1325,7 +1350,8 @@
   // On the other hand, if we're checking a C-style cast, we've still got
   // the reinterpret_cast way.
   bool CStyle 
-    = (CCK == Sema::CCK_CStyleCast || CCK == Sema::CCK_FunctionalCast);
+    = (CCI.getKind() == Sema::CCK_CStyleCast ||
+       CCI.getKind() == Sema::CCK_FunctionalCast);
   if (InitSeq.Failed() && (CStyle || !DestType->isReferenceType()))
     return TC_NotApplicable;
     
@@ -1759,8 +1785,15 @@
   return TC_Success;
 }                                     
 
-void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
+void CastOperation::CheckCXXCStyleCast(bool &CastNodesCreated,
+                                       Sema::CheckedConversionInfo CCI,
                                        bool ListInitialization) {
+  assert(CCI.getKind() == Sema::CCK_FunctionalCast ||
+         CCI.getKind() == Sema::CCK_CStyleCast);
+
+  CastNodesCreated = false;
+  
+  
   // Handle placeholders.
   if (isPlaceholder()) {
     // C-style casts can resolve __unknown_any types.
@@ -1837,17 +1870,18 @@
   if (tcr == TC_Success)
     Kind = CK_NoOp;
 
-  Sema::CheckedConversionKind CCK
-    = FunctionalStyle? Sema::CCK_FunctionalCast
-                     : Sema::CCK_CStyleCast;
   if (tcr == TC_NotApplicable) {
+    Expr *SrcExprOrig = SrcExpr.get();
     // ... or if that is not possible, a static_cast, ignoring const, ...
-    tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange,
+    tcr = TryStaticCast(Self, SrcExpr, DestType, CCI, OpRange,
                         msg, Kind, BasePath, ListInitialization);
     if (SrcExpr.isInvalid())
       return;
 
-    if (tcr == TC_NotApplicable) {
+    if (tcr == TC_Success) {
+      CastNodesCreated = (SrcExpr.get() != SrcExprOrig &&
+                          Kind != CK_ConstructorConversion);
+    } else if (tcr == TC_NotApplicable) {
       // ... and finally a reinterpret_cast, ignoring const.
       tcr = TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/true,
                                OpRange, msg, Kind);
@@ -1857,7 +1891,7 @@
   }
 
   if (Self.getLangOptions().ObjCAutoRefCount && tcr == TC_Success)
-    checkObjCARCConversion(CCK);
+    checkObjCARCConversion(CCI.getKind());
 
   if (tcr != TC_Success && msg != 0) {
     if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
@@ -1871,8 +1905,11 @@
       (void)Fn;
 
     } else {
-      diagnoseBadCast(Self, msg, (FunctionalStyle ? CT_Functional : CT_CStyle),
-                      OpRange, SrcExpr.get(), DestType, ListInitialization);
+      CastType CT = CCI.getKind() == Sema::CCK_FunctionalCast ?
+                                                CT_Functional : CT_CStyle;
+      
+      diagnoseBadCast(Self, msg, CT, CCI, SrcExpr.get(), DestType,
+                      ListInitialization);
     }
   } else if (Kind == CK_BitCast) {
     checkCastAlign();
@@ -2076,9 +2113,12 @@
   Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
   Op.OpRange = SourceRange(LPLoc, CastExpr->getLocEnd());
 
+  bool CastNodesCreated = false;
   if (getLangOptions().CPlusPlus) {
-    Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ false,
-                          isa<InitListExpr>(CastExpr));
+    CheckedConversionInfo CCI(Sema::CCK_CStyleCast,
+                              Op.OpRange,
+                              CastTypeInfo);
+    Op.CheckCXXCStyleCast(CastNodesCreated, CCI, isa<InitListExpr>(CastExpr));
   } else {
     Op.CheckCStyleCast();
   }
@@ -2086,6 +2126,14 @@
   if (Op.SrcExpr.isInvalid())
     return ExprError();
 
+  // CheckCXXCStyleCast _may_ have already created the CStyleCastExpr
+  // node. Let's check.
+  if (CastNodesCreated) {
+    if (CStyleCastExpr *Cast = dyn_cast<CStyleCastExpr>(Op.SrcExpr.get())) {
+      return Op.complete(Cast);
+    }
+  }
+  
   return Op.complete(CStyleCastExpr::Create(Context, Op.ResultType,
                               Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
                               &Op.BasePath, CastTypeInfo, LPLoc, RPLoc));
@@ -2100,11 +2148,24 @@
   Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
   Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getLocEnd());
 
-  Op.CheckCXXCStyleCast(/*FunctionalStyle=*/true, /*ListInit=*/false);
+  bool CastNodesCreated = false;
+  CheckedConversionInfo CCI(Sema::CCK_FunctionalCast,
+                            SourceRange(Op.DestRange.getBegin(), RPLoc),
+                            CastTypeInfo);
+  Op.CheckCXXCStyleCast(CastNodesCreated, CCI, /*ListInitialization=*/false);
   if (Op.SrcExpr.isInvalid())
     return ExprError();
+  
+  // CheckCXXCStyleCast _may_ have already created the CXXFunctionalCastExpr
+  // node. Let's check.
+  if (CastNodesCreated) {
+    if (CXXFunctionalCastExpr *Cast =
+          dyn_cast<CXXFunctionalCastExpr>(Op.SrcExpr.get())) {
+      return Op.complete(Cast);
+    }
+  }
 
   return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType,
-                         Op.ValueKind, CastTypeInfo, Op.DestRange.getBegin(),
-                         Op.Kind, Op.SrcExpr.take(), &Op.BasePath, RPLoc));
+                     Op.ValueKind, CastTypeInfo, Op.DestRange.getBegin(),
+                     Op.Kind, Op.SrcExpr.take(), &Op.BasePath, RPLoc));
 }
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp	(revision 151277)
+++ lib/Sema/SemaExprCXX.cpp	(working copy)
@@ -2300,11 +2300,11 @@
 Sema::PerformImplicitConversion(Expr *From, QualType ToType,
                                 const ImplicitConversionSequence &ICS,
                                 AssignmentAction Action, 
-                                CheckedConversionKind CCK) {
+                                CheckedConversionInfo CCI) {
   switch (ICS.getKind()) {
   case ImplicitConversionSequence::StandardConversion: {
-    ExprResult Res = PerformImplicitConversion(From, ToType, ICS.Standard,
-                                               Action, CCK);
+    ExprResult Res = PerformConversion(From, ToType, ICS.Standard,
+                                       Action, CCI);
     if (Res.isInvalid())
       return ExprError();
     From = Res.take();
@@ -2338,9 +2338,8 @@
       // Watch out for elipsis conversion.
       if (!ICS.UserDefined.EllipsisConversion) {
         ExprResult Res =
-          PerformImplicitConversion(From, BeforeToType,
-                                    ICS.UserDefined.Before, AA_Converting,
-                                    CCK);
+          PerformConversion(From, BeforeToType,
+                            ICS.UserDefined.Before, AA_Converting, CCI);
         if (Res.isInvalid())
           return ExprError();
         From = Res.take();
@@ -2360,8 +2359,8 @@
 
       From = CastArg.take();
 
-      return PerformImplicitConversion(From, ToType, ICS.UserDefined.After,
-                                       AA_Converting, CCK);
+      return PerformConversion(From, ToType, ICS.UserDefined.After,
+                               AA_Converting, CCI);
   }
 
   case ImplicitConversionSequence::AmbiguousConversion:
@@ -2381,17 +2380,18 @@
   return Owned(From);
 }
 
-/// PerformImplicitConversion - Perform an implicit conversion of the
+/// PerformConversion - Perform a conversion of the
 /// expression From to the type ToType by following the standard
 /// conversion sequence SCS. Returns the converted
 /// expression. Flavor is the context in which we're performing this
 /// conversion, for use in error messages.
 ExprResult
-Sema::PerformImplicitConversion(Expr *From, QualType ToType,
-                                const StandardConversionSequence& SCS,
-                                AssignmentAction Action, 
-                                CheckedConversionKind CCK) {
-  bool CStyle = (CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast);
+Sema::PerformConversion(Expr *From, QualType ToType,
+                        const StandardConversionSequence& SCS,
+                        AssignmentAction Action, 
+                        CheckedConversionInfo CCI) {
+  bool CStyle = (CCI.getKind() == CCK_CStyleCast ||
+                 CCI.getKind() == CCK_FunctionalCast);
   
   // Overall FIXME: we are recomputing too many types here and doing far too
   // much extra work. What this means is that we need to keep track of more
@@ -2441,7 +2441,7 @@
     FromType = From->getType();
   }
 
-  // Perform the first implicit conversion.
+  // Perform the first conversion step.
   switch (SCS.First) {
   case ICK_Identity:
     // Nothing to do.
@@ -2458,21 +2458,21 @@
 
   case ICK_Array_To_Pointer:
     FromType = Context.getArrayDecayedType(FromType);
-    From = ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+    From = CastExprToType(From, FromType, CK_ArrayToPointerDecay, 
+                          VK_RValue, /*BasePath=*/0, CCI).take();
     break;
 
   case ICK_Function_To_Pointer:
     FromType = Context.getPointerType(FromType);
-    From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+    From = CastExprToType(From, FromType, CK_FunctionToPointerDecay, 
+                          VK_RValue, /*BasePath=*/0, CCI).take();
     break;
 
   default:
     llvm_unreachable("Improper first standard conversion");
   }
 
-  // Perform the second implicit conversion
+  // Perform the second conversion step
   switch (SCS.Second) {
   case ICK_Identity:
     // If both sides are functions (or pointers/references to them), there could
@@ -2488,20 +2488,20 @@
     if (CheckExceptionSpecCompatibility(From, ToType))
       return ExprError();
 
-    From = ImpCastExprToType(From, ToType, CK_NoOp, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+    From = CastExprToType(From, ToType, CK_NoOp, 
+                          VK_RValue, /*BasePath=*/0, CCI).take();
     break;
 
   case ICK_Integral_Promotion:
   case ICK_Integral_Conversion:
-    From = ImpCastExprToType(From, ToType, CK_IntegralCast, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+    From = CastExprToType(From, ToType, CK_IntegralCast, 
+                          VK_RValue, /*BasePath=*/0, CCI).take();
     break;
 
   case ICK_Floating_Promotion:
   case ICK_Floating_Conversion:
-    From = ImpCastExprToType(From, ToType, CK_FloatingCast, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+    From = CastExprToType(From, ToType, CK_FloatingCast, 
+                          VK_RValue, /*BasePath=*/0, CCI).take();
     break;
 
   case ICK_Complex_Promotion:
@@ -2519,23 +2519,23 @@
     } else {
       CK = CK_IntegralComplexCast;
     }
-    From = ImpCastExprToType(From, ToType, CK, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+    From = CastExprToType(From, ToType, CK, 
+                          VK_RValue, /*BasePath=*/0, CCI).take();
     break;
   }
 
   case ICK_Floating_Integral:
     if (ToType->isRealFloatingType())
-      From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, 
-                               VK_RValue, /*BasePath=*/0, CCK).take();
+      From = CastExprToType(From, ToType, CK_IntegralToFloating, 
+                            VK_RValue, /*BasePath=*/0, CCI).take();
     else
-      From = ImpCastExprToType(From, ToType, CK_FloatingToIntegral, 
-                               VK_RValue, /*BasePath=*/0, CCK).take();
+      From = CastExprToType(From, ToType, CK_FloatingToIntegral, 
+                            VK_RValue, /*BasePath=*/0, CCI).take();
     break;
 
   case ICK_Compatible_Conversion:
-      From = ImpCastExprToType(From, ToType, CK_NoOp, 
-                               VK_RValue, /*BasePath=*/0, CCK).take();
+      From = CastExprToType(From, ToType, CK_NoOp, 
+                            VK_RValue, /*BasePath=*/0, CCI).take();
     break;
 
   case ICK_Writeback_Conversion:
@@ -2583,8 +2583,7 @@
       From = E.take();
     }
 
-    From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK)
-             .take();
+    From = CastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCI).take();
     break;
   }
 
@@ -2595,8 +2594,7 @@
       return ExprError();
     if (CheckExceptionSpecCompatibility(From, ToType))
       return ExprError();
-    From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK)
-             .take();
+    From = CastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCI).take();
     break;
   }
 
@@ -2607,9 +2605,9 @@
       FromType = Context.FloatTy;
     }
 
-    From = ImpCastExprToType(From, Context.BoolTy,
-                             ScalarTypeToBooleanCastKind(FromType), 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+    From = CastExprToType(From, Context.BoolTy,
+                          ScalarTypeToBooleanCastKind(FromType), 
+                          VK_RValue, /*BasePath=*/0, CCI).take();
     break;
 
   case ICK_Derived_To_Base: {
@@ -2622,20 +2620,20 @@
                                      CStyle))
       return ExprError();
 
-    From = ImpCastExprToType(From, ToType.getNonReferenceType(),
-                      CK_DerivedToBase, From->getValueKind(),
-                      &BasePath, CCK).take();
+    From = CastExprToType(From, ToType.getNonReferenceType(),
+                          CK_DerivedToBase, From->getValueKind(),
+                          &BasePath, CCI).take();
     break;
   }
 
   case ICK_Vector_Conversion:
-    From = ImpCastExprToType(From, ToType, CK_BitCast, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+    From = CastExprToType(From, ToType, CK_BitCast, 
+                          VK_RValue, /*BasePath=*/0, CCI).take();
     break;
 
   case ICK_Vector_Splat:
-    From = ImpCastExprToType(From, ToType, CK_VectorSplat, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+    From = CastExprToType(From, ToType, CK_VectorSplat, 
+                          VK_RValue, /*BasePath=*/0, CCI).take();
     break;
 
   case ICK_Complex_Real:
@@ -2649,16 +2647,19 @@
         // do nothing
       } else if (From->getType()->isRealFloatingType()) {
         From = ImpCastExprToType(From, ElType,
-                isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).take();
+                              isFloatingComplex ? CK_FloatingCast
+                                                : CK_FloatingToIntegral).take();
       } else {
         assert(From->getType()->isIntegerType());
         From = ImpCastExprToType(From, ElType,
-                isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).take();
+                                 isFloatingComplex ? CK_IntegralToFloating
+                                                   : CK_IntegralCast).take();
       }
       // y -> _Complex y
-      From = ImpCastExprToType(From, ToType,
-                   isFloatingComplex ? CK_FloatingRealToComplex
-                                     : CK_IntegralRealToComplex).take();
+      From = CastExprToType(From, ToType,
+                            isFloatingComplex ? CK_FloatingRealToComplex
+                                              : CK_IntegralRealToComplex,
+                            VK_RValue, /*BasePath=*/ 0, CCI).take();
 
     // Case 2.  _Complex x -> y
     } else {
@@ -2670,29 +2671,30 @@
 
       // _Complex x -> x
       From = ImpCastExprToType(From, ElType,
-                   isFloatingComplex ? CK_FloatingComplexToReal
-                                     : CK_IntegralComplexToReal, 
-                               VK_RValue, /*BasePath=*/0, CCK).take();
+                           isFloatingComplex ? CK_FloatingComplexToReal
+                                             : CK_IntegralComplexToReal).take();
 
       // x -> y
       if (Context.hasSameUnqualifiedType(ElType, ToType)) {
         // do nothing
       } else if (ToType->isRealFloatingType()) {
-        From = ImpCastExprToType(From, ToType,
-                   isFloatingComplex ? CK_FloatingCast : CK_IntegralToFloating, 
-                                 VK_RValue, /*BasePath=*/0, CCK).take();
+        From = CastExprToType(From, ToType,
+                              isFloatingComplex ? CK_FloatingCast 
+                                                : CK_IntegralToFloating, 
+                              VK_RValue, /*BasePath=*/0, CCI).take();
       } else {
         assert(ToType->isIntegerType());
-        From = ImpCastExprToType(From, ToType,
-                   isFloatingComplex ? CK_FloatingToIntegral : CK_IntegralCast, 
-                                 VK_RValue, /*BasePath=*/0, CCK).take();
+        From = CastExprToType(From, ToType,
+                              isFloatingComplex ? CK_FloatingToIntegral
+                                                : CK_IntegralCast, 
+                              VK_RValue, /*BasePath=*/0, CCI).take();
       }
     }
     break;
   
   case ICK_Block_Pointer_Conversion: {
-    From = ImpCastExprToType(From, ToType.getUnqualifiedType(), CK_BitCast,
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+    From = CastExprToType(From, ToType.getUnqualifiedType(), CK_BitCast,
+                          VK_RValue, /*BasePath=*/0, CCI).take();
     break;
   }
       
@@ -2727,8 +2729,8 @@
     // target type isn't a reference.
     ExprValueKind VK = ToType->isReferenceType() ?
                                   From->getValueKind() : VK_RValue;
-    From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context),
-                             CK_NoOp, VK, /*BasePath=*/0, CCK).take();
+    From = CastExprToType(From, ToType.getNonLValueExprType(Context),
+                          CK_NoOp, VK, /*BasePath=*/0, CCI).take();
 
     if (SCS.DeprecatedStringLiteralToCharPtr &&
         !getLangOptions().WritableStrings)
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp	(revision 151277)
+++ lib/Sema/SemaInit.cpp	(working copy)
@@ -4794,6 +4794,17 @@
 
   ExprResult CurInit = S.Owned((Expr *)0);
 
+  Sema::CheckedConversionKind CCK
+        = Kind.isCStyleCast()     ? Sema::CCK_CStyleCast
+        : Kind.isFunctionalCast() ? Sema::CCK_FunctionalCast
+        : Kind.isStaticCast()     ? Sema::CCK_StaticCast
+                                  : Sema::CCK_ImplicitConversion;
+  
+  Sema::CheckedConversionInfo CCI(CCK,
+                                  SourceRange(Kind.getRange().getBegin(),
+                                              Kind.getRange().getEnd()),
+                                  Kind.getTypeSourceInfo());
+  
   // For initialization steps that start with a single initializer,
   // grab the only argument out the Args and place it into the "current"
   // initializer.
@@ -4844,6 +4855,20 @@
 
     QualType SourceType = CurInit.get() ? CurInit.get()->getType() : QualType();
 
+    Sema::CheckedConversionKind CCK = Sema::CCK_ImplicitConversion;
+    
+    // Only the last step is implemented as an explicit cast, if any
+    if(Step == StepEnd - 1)
+      CCK = Kind.isCStyleCast()     ? Sema::CCK_CStyleCast
+          : Kind.isFunctionalCast() ? Sema::CCK_FunctionalCast
+          : Kind.isStaticCast()     ? Sema::CCK_StaticCast
+                                    : Sema::CCK_ImplicitConversion;
+    
+    Sema::CheckedConversionInfo CCI(CCK,
+                                    SourceRange(Kind.getRange().getBegin(),
+                                                Kind.getRange().getEnd()),
+                                    Kind.getTypeSourceInfo());
+    
     switch (Step->Kind) {
     case SK_ResolveAddressOfOverloadedFunction:
       // Overload resolution determined which function invoke; update the
@@ -4886,11 +4911,9 @@
               (Step->Kind == SK_CastDerivedToBaseXValue ?
                    VK_XValue :
                    VK_RValue);
-      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
-                                                 Step->Type,
-                                                 CK_DerivedToBase,
-                                                 CurInit.get(),
-                                                 &BasePath, VK));
+      
+      CurInit = S.CastExprToType(CurInit.get(), Step->Type, CK_DerivedToBase,
+                                 VK, &BasePath, CCI);
       break;
     }
 
@@ -5033,10 +5056,9 @@
         }
       }
 
-      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
-                                                 CurInit.get()->getType(),
-                                                 CastKind, CurInit.get(), 0,
-                                                CurInit.get()->getValueKind()));
+      CurInit = S.CastExprToType(CurInit.get(), CurInit.get()->getType(),
+                                 CastKind, CurInit.get()->getValueKind(),
+                                 /*BasePath=*/0, CCI);
       if (MaybeBindToTemp)
         CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
       if (RequiresCopy)
@@ -5060,14 +5082,9 @@
     }
 
     case SK_ConversionSequence: {
-      Sema::CheckedConversionKind CCK 
-        = Kind.isCStyleCast()? Sema::CCK_CStyleCast
-        : Kind.isFunctionalCast()? Sema::CCK_FunctionalCast
-        : Kind.isExplicitCast()? Sema::CCK_OtherCast
-        : Sema::CCK_ImplicitConversion;
       ExprResult CurInitExprRes =
         S.PerformImplicitConversion(CurInit.get(), Step->Type, *Step->ICS,
-                                    getAssignmentAction(Entity), CCK);
+                                    getAssignmentAction(Entity), CCI);
       if (CurInitExprRes.isInvalid())
         return ExprError();
       CurInit = move(CurInitExprRes);
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 151277)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -3778,11 +3778,16 @@
                                        LiteralExpr->getSourceRange().getEnd())))
     return ExprError();
 
+  
+  
   InitializedEntity Entity
     = InitializedEntity::InitializeTemporary(literalType);
+
+  CheckedConversionInfo CCI(CCK_CStyleCast,
+                            SourceRange(LParenLoc, RParenLoc),
+                            TInfo);
   InitializationKind Kind
-    = InitializationKind::CreateCStyleCast(LParenLoc, 
-                                           SourceRange(LParenLoc, RParenLoc),
+    = InitializationKind::CreateCStyleCast(CCI,
                                            /*InitList=*/true);
   InitializationSequence InitSeq(*this, Entity, Kind, &LiteralExpr, 1);
   ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
Index: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp	(revision 151277)
+++ lib/Sema/Sema.cpp	(working copy)
@@ -230,13 +230,13 @@
   AnalysisWarnings.PrintStats();
 }
 
-/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
-/// If there is already an implicit cast, merge into the existing one.
-/// The result is of the given category.
-ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
-                                   CastKind Kind, ExprValueKind VK,
-                                   const CXXCastPath *BasePath,
-                                   CheckedConversionKind CCK) {
+/// CastExprToType - If Expr is not of type 'Type', insert a cast of the
+/// specified kind.
+/// Redundant implicit casts are merged together.
+ExprResult Sema::CastExprToType(Expr *E, QualType Ty,
+                                CastKind Kind, ExprValueKind VK,
+                                const CXXCastPath *BasePath,
+                                CheckedConversionInfo CCI) {
 #ifndef NDEBUG
   if (VK == VK_RValue && !E->isRValue()) {
     switch (Kind) {
@@ -255,11 +255,11 @@
   QualType ExprTy = Context.getCanonicalType(E->getType());
   QualType TypeTy = Context.getCanonicalType(Ty);
 
-  if (ExprTy == TypeTy)
+  if (Kind != CK_UserDefinedConversion && ExprTy == TypeTy)
     return Owned(E);
 
   if (getLangOptions().ObjCAutoRefCount)
-    CheckObjCARCConversion(SourceRange(), Ty, E, CCK);
+    CheckObjCARCConversion(SourceRange(), Ty, E, CCI.getKind());
 
   // If this is a derived-to-base cast to a through a virtual base, we
   // need a vtable.
@@ -272,16 +272,49 @@
       MarkVTableUsed(E->getLocStart(), 
                      cast<CXXRecordDecl>(RecordTy->getDecl()));
   }
-
-  if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(E)) {
-    if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
-      ImpCast->setType(Ty);
-      ImpCast->setValueKind(VK);
-      return Owned(E);
-    }
+  
+  switch(CCI.getKind()) {
+    default:
+      llvm_unreachable("Unexpected CheckedConversionKind");
+    case CCK_ImplicitConversion:
+      if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(E)) {
+        if (ImpCast->getCastKind() == Kind &&
+            (!BasePath || BasePath->empty())) {
+          ImpCast->setType(Ty);
+          ImpCast->setValueKind(VK);
+          return Owned(E);
+        }
+      }
+      return Owned(ImplicitCastExpr::Create(Context, Ty, Kind,
+                                            E, BasePath, VK));
+    case CCK_CStyleCast:
+      return Owned(CStyleCastExpr::Create(Context, Ty, VK, Kind, E, BasePath,
+                                          CCI.getTypeSourceInfo(),
+                                          CCI.getTypeRange().getBegin(),
+                                          CCI.getTypeRange().getEnd()));
+    case CCK_FunctionalCast:
+      return Owned(CXXFunctionalCastExpr::Create(Context, Ty, VK,
+                                                 CCI.getTypeSourceInfo(),
+                                                 CCI.getTypeRange().getBegin(),
+                                                 Kind, E,
+                                                 BasePath,
+                                                 CCI.getTypeRange().getEnd()));
+    case CCK_StaticCast:
+      return Owned(CXXStaticCastExpr::Create(Context, Ty, VK, Kind, E, BasePath,
+                                             CCI.getTypeSourceInfo(),
+                                             CCI.getTypeRange().getBegin(),
+                                             CCI.getTypeRange().getEnd()));
   }
+  
+}
 
-  return Owned(ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK));
+/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
+/// If there is already an implicit cast, merge into the existing one.
+/// The result is of the given category.
+ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
+                                   CastKind Kind, ExprValueKind VK,
+                                   const CXXCastPath *BasePath) {
+  return CastExprToType(E, Ty, Kind, VK, BasePath, CheckedConversionInfo());
 }
 
 /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
