Index: lib/Parse/ParseExprCXX.cpp
===================================================================
--- lib/Parse/ParseExprCXX.cpp	(revision 178237)
+++ lib/Parse/ParseExprCXX.cpp	(working copy)
@@ -989,7 +989,9 @@
   case tok::kw_static_cast:      CastName = "static_cast";      break;
   }
 
+  unsigned OpLength = Tok.getLength();
   SourceLocation OpLoc = ConsumeToken();
+  SourceRange OpRange(OpLoc, OpLoc.getLocWithOffset(OpLength - 1));
   SourceLocation LAngleBracketLoc = Tok.getLocation();
 
   // Check for "<::" which is parsed as "[:".  If found, fix token stream,
@@ -1028,7 +1030,7 @@
   T.consumeClose();
 
   if (!Result.isInvalid() && !DeclaratorInfo.isInvalidType())
-    Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
+    Result = Actions.ActOnCXXNamedCast(OpRange, Kind,
                                        LAngleBracketLoc, DeclaratorInfo,
                                        RAngleBracketLoc,
                                        T.getOpenLocation(), Result.take(), 
Index: lib/Sema/SemaCast.cpp
===================================================================
--- lib/Sema/SemaCast.cpp	(revision 178237)
+++ lib/Sema/SemaCast.cpp	(working copy)
@@ -72,6 +72,7 @@
 
     SourceRange OpRange;
     SourceRange DestRange;
+    SourceRange KeywordRange;
 
     // Top-level semantics-checking routines.
     void CheckConstCast();
@@ -211,7 +212,7 @@
 
 /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
 ExprResult
-Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
+Sema::ActOnCXXNamedCast(SourceRange OpRange, tok::TokenKind Kind,
                         SourceLocation LAngleBracketLoc, Declarator &D,
                         SourceLocation RAngleBracketLoc,
                         SourceLocation LParenLoc, Expr *E,
@@ -228,15 +229,16 @@
     CheckExtraCXXDefaultArguments(D);
   }
 
-  return BuildCXXNamedCast(OpLoc, Kind, TInfo, E,
+  return BuildCXXNamedCast(OpRange, Kind, TInfo, E,
                            SourceRange(LAngleBracketLoc, RAngleBracketLoc),
                            SourceRange(LParenLoc, RParenLoc));
 }
 
 ExprResult
-Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
+Sema::BuildCXXNamedCast(SourceRange OpRange, tok::TokenKind Kind,
                         TypeSourceInfo *DestTInfo, Expr *E,
                         SourceRange AngleBrackets, SourceRange Parens) {
+  SourceLocation OpLoc = OpRange.getBegin();
   ExprResult Ex = Owned(E);
   QualType DestType = DestTInfo->getType();
 
@@ -247,6 +249,7 @@
   CastOperation Op(*this, DestType, E);
   Op.OpRange = SourceRange(OpLoc, Parens.getEnd());
   Op.DestRange = AngleBrackets;
+  Op.KeywordRange = OpRange;
 
   switch (Kind) {
   default: llvm_unreachable("Unknown C++ cast!");
@@ -687,7 +690,8 @@
 /// or downcast between respective pointers or references.
 static void DiagnoseReinterpretUpDownCast(Sema &Self, const Expr *SrcExpr,
                                           QualType DestType,
-                                          SourceRange OpRange) {
+                                          SourceRange OpRange,
+                                          SourceRange KeywordRange) {
   QualType SrcType = SrcExpr->getType();
   // When casting from pointer or reference, get pointee type; use original
   // type otherwise.
@@ -767,11 +771,10 @@
       ReinterpretKind == ReinterpretUpcast? SrcType : DestType;
 
   Self.Diag(OpRange.getBegin(), diag::warn_reinterpret_different_from_static)
-    << DerivedType << BaseType << !VirtualBase << ReinterpretKind;
+    << DerivedType << BaseType << !VirtualBase << ReinterpretKind << OpRange;
   Self.Diag(OpRange.getBegin(), diag::note_reinterpret_updowncast_use_static)
-    << ReinterpretKind;
-
-  // TODO: emit fixits. This requires passing operator SourceRange from Parser.
+    << ReinterpretKind
+    << FixItHint::CreateReplacement(KeywordRange, "static_cast");
 }
 
 /// CheckReinterpretCast - Check that a reinterpret_cast\<DestType\>(SrcExpr) is
@@ -809,7 +812,8 @@
   } else if (tcr == TC_Success) {
     if (Self.getLangOpts().ObjCAutoRefCount)
       checkObjCARCConversion(Sema::CCK_OtherCast);
-    DiagnoseReinterpretUpDownCast(Self, SrcExpr.get(), DestType, OpRange);
+    DiagnoseReinterpretUpDownCast(Self, SrcExpr.get(), DestType, OpRange, 
+                                  KeywordRange);
   }
 }
 
Index: test/SemaCXX/warn-reinterpret-base-class.cpp
===================================================================
--- test/SemaCXX/warn-reinterpret-base-class.cpp	(revision 178237)
+++ test/SemaCXX/warn-reinterpret-base-class.cpp	(working copy)
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s
 
 // PR 13824
 class A {
@@ -117,12 +118,17 @@
   // expected-warning@+2 {{'reinterpret_cast' to class 'DVA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
   (void)*reinterpret_cast<DVA *>(a);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
   (void)*reinterpret_cast<DDVA *>(a);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' to class 'DMA *' from its virtual base 'A *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
   (void)*reinterpret_cast<DMA *>(a);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
 }
 
 void reinterpret_reference_downcast(A a, A &ra, const A &cra) {
@@ -145,12 +151,17 @@
   // expected-warning@+2 {{'reinterpret_cast' to class 'DVA &' from its virtual base 'A' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
   (void)reinterpret_cast<DVA &>(a);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' to class 'DDVA &' from its virtual base 'A' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
   (void)reinterpret_cast<DDVA &>(a);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' to class 'DMA &' from its virtual base 'A' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
   (void)reinterpret_cast<DMA &>(a);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
 }
 
 void reinterpret_pointer_upcast(DA *da, const DA *cda, DDA *dda, DAo *dao,
@@ -170,18 +181,27 @@
   // expected-warning@+2 {{'reinterpret_cast' from class 'DVA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)*reinterpret_cast<A *>(dva);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)*reinterpret_cast<A *>(ddva);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA *' to its virtual base 'DA *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)*reinterpret_cast<DA *>(ddva);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'A *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)*reinterpret_cast<A *>(dma);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' from class 'DMA *' to its virtual base 'DA *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)*reinterpret_cast<DA *>(dma);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:10-[[@LINE-1]]:26}:"static_cast"
 }
 
 void reinterpret_reference_upcast(DA &da, const DA &cda, DDA &dda, DAo &dao,
@@ -201,18 +221,27 @@
   // expected-warning@+2 {{'reinterpret_cast' from class 'DVA' to its virtual base 'A &' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)reinterpret_cast<A &>(dva);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'A &' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)reinterpret_cast<A &>(ddva);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' from class 'DDVA' to its virtual base 'DA &' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)reinterpret_cast<DA &>(ddva);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'A &' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)reinterpret_cast<A &>(dma);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' from class 'DMA' to its virtual base 'DA &' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)reinterpret_cast<DA &>(dma);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
 }
 
 struct E {
@@ -239,35 +268,45 @@
   // expected-warning@+2 {{'reinterpret_cast' to class 'F *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
   (void)reinterpret_cast<F *>(e);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' to class 'G *' from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
   (void)reinterpret_cast<G *>(e);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
   (void)reinterpret_cast<H *>(e);
   // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'E *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
   (void)reinterpret_cast<I *>(e);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
 
+
   (void)reinterpret_cast<G *>(f);
   // expected-warning@+2 {{'reinterpret_cast' to class 'I *' from its virtual base 'F *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
   (void)reinterpret_cast<I *>(f);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
 
   (void)reinterpret_cast<H *>(a);
 
   // expected-warning@+2 {{'reinterpret_cast' to class 'L' (aka 'const F *volatile') from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}}
   (void)reinterpret_cast<L>(e);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
 }
 
 void different_subobject_upcast(F *f, G *g, H *h, I *i) {
   // expected-warning@+2 {{'reinterpret_cast' from class 'F *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)reinterpret_cast<E *>(f);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
 
   (void)reinterpret_cast<F *>(g);
   // expected-warning@+2 {{'reinterpret_cast' from class 'G *' to its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)reinterpret_cast<E *>(g);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
 
   (void)reinterpret_cast<E *>(h);
   (void)reinterpret_cast<A *>(h);
@@ -275,7 +314,10 @@
   // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'F *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)reinterpret_cast<F *>(i);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+
   // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'E *' behaves differently from 'static_cast'}}
   // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while upcasting}}
   (void)reinterpret_cast<E *>(i);
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
 }
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 178237)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -3773,7 +3773,7 @@
                                       bool IsDereference, SourceRange Range);
 
   /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
-  ExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
+  ExprResult ActOnCXXNamedCast(SourceRange OpRange,
                                tok::TokenKind Kind,
                                SourceLocation LAngleBracketLoc,
                                Declarator &D,
@@ -3782,7 +3782,7 @@
                                Expr *E,
                                SourceLocation RParenLoc);
 
-  ExprResult BuildCXXNamedCast(SourceLocation OpLoc,
+  ExprResult BuildCXXNamedCast(SourceRange OpRange,
                                tok::TokenKind Kind,
                                TypeSourceInfo *Ty,
                                Expr *E,
