diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 8a0b650..86ae462 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -418,7 +418,7 @@ public:
 
 
 struct BuiltinLocInfo {
-  SourceLocation BuiltinLoc;
+  SourceRange BuiltinRange;
 };
 
 /// \brief Wrapper for source info for builtin types.
@@ -430,12 +430,16 @@ public:
   enum { LocalDataSize = sizeof(BuiltinLocInfo) };
 
   SourceLocation getBuiltinLoc() const {
-    return getLocalData()->BuiltinLoc;
+    return getLocalData()->BuiltinRange.getBegin();
   }
   void setBuiltinLoc(SourceLocation Loc) {
-    getLocalData()->BuiltinLoc = Loc;
+    getLocalData()->BuiltinRange.setBegin(Loc);
+    getLocalData()->BuiltinRange.setEnd(Loc);
   }
-
+  void setBuiltinRange(SourceRange Range) {
+    getLocalData()->BuiltinRange = Range;
+  }
+  
   SourceLocation getNameLoc() const { return getBuiltinLoc(); }
 
   WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
@@ -458,7 +462,7 @@ public:
   }
 
   SourceRange getLocalSourceRange() const {
-    return SourceRange(getBuiltinLoc(), getBuiltinLoc());
+    return getLocalData()->BuiltinRange;
   }
 
   TypeSpecifierSign getWrittenSignSpec() const {
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 605c4bb..25070c6 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -188,7 +188,16 @@ public:
     return B != X.B || E != X.E;
   }
 };
-  
+
+// ExpandToFit - Returns a SourceRange that includes the input SourceRange
+// and SourceLocation. If the input location is less than the beginning of the
+// input range, the beginning of the returned range will be the input location.
+// Likewise, if the input location is greater than the end of the input range,
+// the end of the returned range will be the input location.
+// If the input location is already contained within the input range, or if it
+// is invalid, this function returns the input range unmodified.
+SourceRange ExpandToFit(const SourceRange& InRange, SourceLocation Loc);
+
 /// CharSourceRange - This class represents a character granular source range.
 /// The underlying SourceRange can either specify the starting/ending character
 /// of the range, or it can specify the start or the range and the start of the
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 30a188e..28477e8 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -328,7 +328,10 @@ private:
   SourceRange Range;
 
   SourceLocation StorageClassSpecLoc, SCS_threadLoc;
-  SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc;
+  SourceLocation TSCLoc, TSSLoc, TSTLoc, AltiVecLoc;
+  // The width specifier is a SourceRange instead of a SourceLocation
+  // in order to support 'long long'.
+  SourceRange TSWRange;
   SourceRange TypeofParensRange;
   SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc;
   SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc;
@@ -425,7 +428,7 @@ public:
   const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; }
 
   const SourceRange &getSourceRange() const { return Range; }
-  SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; }
+  SourceRange getTypeSpecWidthRange() const { return TSWRange; }
   SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; }
   SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
   SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; }
diff --git a/lib/Basic/SourceLocation.cpp b/lib/Basic/SourceLocation.cpp
index 5062d43..433575e 100644
--- a/lib/Basic/SourceLocation.cpp
+++ b/lib/Basic/SourceLocation.cpp
@@ -65,6 +65,23 @@ void SourceLocation::dump(const SourceManager &SM) const {
   print(llvm::errs(), SM);
 }
 
+namespace clang {
+
+SourceRange ExpandToFit(const SourceRange& Range, SourceLocation Loc) {
+  if (Loc.isValid()) {
+    if (Range.getBegin().isValid() && Loc < Range.getBegin()) {
+      return SourceRange(Loc, Range.getEnd());
+    } else if (Range.getEnd().isValid() && Range.getEnd() < Loc) {
+      return SourceRange(Range.getBegin(), Loc);
+    } else if (Range.getBegin().isInvalid() && Range.getEnd().isInvalid()) {
+      return SourceRange(Loc, Loc);
+    }
+  }
+  return Range;
+}
+
+}
+ 
 //===----------------------------------------------------------------------===//
 // FullSourceLoc
 //===----------------------------------------------------------------------===//
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index 388552d..a1a3932 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -380,14 +380,19 @@ bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
 bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
                                 const char *&PrevSpec,
                                 unsigned &DiagID) {
-  // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that
-  // for 'long long' we will keep the source location of the first 'long'.
-  if (TypeSpecWidth == TSW_unspecified)
-    TSWLoc = Loc;
+  // Overwrite TSWRange only if TypeSpecWidth was unspecified. If it was
+  // specified, this is probably a 'long long', in which case, the range
+  // for it is set below.
+  if (TypeSpecWidth == TSW_unspecified) {
+    TSWRange.setBegin(Loc);
+    TSWRange.setEnd(Loc);
+  }
   // Allow turning long -> long long.
   else if (W != TSW_longlong || TypeSpecWidth != TSW_long)
     return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
   TypeSpecWidth = W;
+  // Set the end of the range to the second 'long' of 'long long'.
+  TSWRange.setEnd(Loc);
   if (TypeAltiVecVector && !TypeAltiVecBool &&
       ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
@@ -659,7 +664,7 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) {
 
       // Only 'short' is valid with vector bool. (PIM 2.1)
       if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short))
-        Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec)
+        Diag(D, TSWRange.getBegin(), diag::err_invalid_vector_bool_decl_spec)
           << getSpecifierName((TSW)TypeSpecWidth);
 
       // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
@@ -698,7 +703,7 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) {
     if (TypeSpecType == TST_unspecified)
       TypeSpecType = TST_int; // short -> short int, long long -> long long int.
     else if (TypeSpecType != TST_int) {
-      Diag(D, TSWLoc,
+      Diag(D, TSWRange.getBegin(),
            TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
                                       : diag::err_invalid_longlong_spec)
         <<  getSpecifierName((TST)TypeSpecType);
@@ -710,7 +715,7 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) {
     if (TypeSpecType == TST_unspecified)
       TypeSpecType = TST_int;  // long -> long int.
     else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
-      Diag(D, TSWLoc, diag::err_invalid_long_spec)
+      Diag(D, TSWRange.getBegin(), diag::err_invalid_long_spec)
         << getSpecifierName((TST)TypeSpecType);
       TypeSpecType = TST_int;
       TypeSpecOwned = false;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c967864..e2fa290 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -4510,7 +4510,14 @@ void Sema::CheckMain(FunctionDecl* FD) {
   const FunctionType* FT = T->getAs<FunctionType>();
 
   if (!Context.hasSameUnqualifiedType(FT->getResultType(), Context.IntTy)) {
-    Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint);
+    TypeSourceInfo *TSI = FD->getTypeSourceInfo();
+    TypeLoc TL = TSI->getTypeLoc();
+    const SemaDiagnosticBuilder& D = Diag(FD->getTypeSpecStartLoc(),
+                                          diag::err_main_returns_nonint);
+    if (FunctionTypeLoc* PTL = dyn_cast<FunctionTypeLoc>(&TL)) {
+      D << FixItHint::CreateReplacement(PTL->getResultLoc().getSourceRange(),
+                                        "int");
+    }
     FD->setInvalidDecl(true);
   }
 
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index f161f4e..692f686 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -675,7 +675,7 @@ static QualType ConvertDeclSpecToType(Sema &S, TypeProcessingState &state) {
         // long long is a C99 feature.
         if (!S.getLangOptions().C99 &&
             !S.getLangOptions().CPlusPlus0x)
-          S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_longlong);
+          S.Diag(DS.getTypeSpecWidthRange().getBegin(), diag::ext_longlong);
         break;
       }
     } else {
@@ -689,7 +689,7 @@ static QualType ConvertDeclSpecToType(Sema &S, TypeProcessingState &state) {
         // long long is a C99 feature.
         if (!S.getLangOptions().C99 &&
             !S.getLangOptions().CPlusPlus0x)
-          S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_longlong);
+          S.Diag(DS.getTypeSpecWidthRange().getBegin(), diag::ext_longlong);
         break;
       }
     }
@@ -2304,13 +2304,23 @@ namespace {
       if (TL.needsExtraLocalData()) {
         // Set info for the written builtin specifiers.
         TL.getWrittenBuiltinSpecs() = DS.getWrittenBuiltinSpecs();
-        // Try to have a meaningful source location.
-        if (TL.getWrittenSignSpec() != TSS_unspecified)
-          // Sign spec loc overrides the others (e.g., 'unsigned long').
-          TL.setBuiltinLoc(DS.getTypeSpecSignLoc());
-        else if (TL.getWrittenWidthSpec() != TSW_unspecified)
-          // Width spec loc overrides type spec loc (e.g., 'short int').
-          TL.setBuiltinLoc(DS.getTypeSpecWidthLoc());
+        // Have a meaningful source range. Since the specifiers can come in
+        // any order (e.g., 'unsigned long' or 'long unsigned' or even
+        // 'int signed long long'), expand the range in either direction
+        // as necessary.
+        SourceRange BuiltinRange(DS.getTypeSpecTypeLoc(),
+                                 DS.getTypeSpecTypeLoc());
+        
+        if (TL.getWrittenSignSpec() != TSS_unspecified) {         
+          BuiltinRange = ExpandToFit(BuiltinRange, DS.getTypeSpecSignLoc());
+        }
+        if (TL.getWrittenWidthSpec() != TSW_unspecified) {
+          BuiltinRange = ExpandToFit(BuiltinRange,
+                                     DS.getTypeSpecWidthRange().getBegin());
+          BuiltinRange = ExpandToFit(BuiltinRange,
+                                     DS.getTypeSpecWidthRange().getEnd());
+        }
+        TL.setBuiltinRange(BuiltinRange);
       }
     }
     void VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
