[clang] [clang-tools-extra] WIP: Extend SourceLocation to 64 bits. (PR #146314)

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 1 03:20:33 PDT 2025


https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/146314

>From 7346173c585b16d86d292989b5014ffb85a2f644 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Wed, 7 May 2025 21:47:32 +0200
Subject: [PATCH 01/20] 64-bit source location

fix

Reduce the Stmt size back to 8 bytes.

Reduce the CallExpr size

Fix the ObjCContainerDecl bit field

Change the SourceLocation::UIntTy to uint64_t

Update other SourceManager's getDecomposedSpellingLoc APIs, and fix many
failing tests.

Remaining failures:

  Clang :: Index/IBOutletCollection.m
  Clang :: Index/annotate-macro-args.m
  Clang :: Index/annotate-module.m
  Clang :: Index/annotate-tokens-pp.c
  Clang :: Index/annotate-tokens.c
  Clang :: Index/annotate-toplevel-in-objccontainer.m
  Clang :: Index/hidden-redecls.m
  Clang :: Index/index-module-with-vfs.m
  Clang :: Index/index-module.m
  Clang :: Index/index-pch-objc.m
  Clang :: Index/index-pch-with-module.m
  Clang :: Index/index-pch.cpp
  Clang :: Index/targeted-annotation.c
  Clang :: Lexer/SourceLocationsOverflow.c
  Clang-Unit :: ./AllClangUnitTests/PPMemoryAllocationsTest/PPMacroDefinesAllocations
  Clang-Unit :: ./AllClangUnitTests/SourceLocationEncoding/Individual
  Clang-Unit :: ./AllClangUnitTests/SourceLocationEncoding/Sequence
  Clang-Unit :: libclang/./libclangTests/14/53
  Clang-Unit :: libclang/./libclangTests/45/53
  Clang-Unit :: libclang/./libclangTests/47/53
  Clang-Unit :: libclang/./libclangTests/48/53
  Clang-Unit :: libclang/./libclangTests/49/53
  Clang-Unit :: libclang/./libclangTests/50/53
  Clang-Unit :: libclang/./libclangTests/52/53

Fix libclang failures

Fix Rewrite APIs

Fix PPMemoryAllocationsTest

Fix SourceLocationEncodingTest

More unsigned -> SourceLocation::UIntTy changes in the SourceManager APIs

Update the type of std::pair<FileID, unsigned> in CIndex.cpp

Fix SourceLocationEncodingTest

Tweak the SourceLocation Implementation.

The source location has a Bit which specify the number of bits used
for the offset. 40 by default;

Make MathExtra templates constexpr

Test Bits=64 perf

Try 48 bits

No bitfields

Fix CallExpr optimization.
---
 clang/include/clang/AST/DeclBase.h            |  10 +-
 clang/include/clang/AST/DeclObjC.h            |   5 +-
 clang/include/clang/AST/Expr.h                |  72 ++++---
 clang/include/clang/AST/ExprCXX.h             |  74 ++++---
 clang/include/clang/AST/ExprConcepts.h        |   6 +-
 clang/include/clang/AST/ExternalASTSource.h   |   2 +-
 clang/include/clang/AST/Stmt.h                | 189 +++++++++---------
 clang/include/clang/Basic/Diagnostic.h        |   8 +-
 clang/include/clang/Basic/SourceLocation.h    |  31 ++-
 clang/include/clang/Basic/SourceManager.h     |  11 +-
 clang/include/clang/Rewrite/Core/Rewriter.h   |   3 +-
 .../clang/Sema/MultiplexExternalSemaSource.h  |   2 +-
 .../include/clang/Serialization/ASTBitCodes.h |   2 +-
 clang/include/clang/Serialization/ASTReader.h |   2 +-
 .../Serialization/SourceLocationEncoding.h    |  12 +-
 clang/lib/AST/Expr.cpp                        |  33 +--
 clang/lib/AST/ExprCXX.cpp                     |   6 +-
 clang/lib/AST/ExprConcepts.cpp                |   2 +-
 clang/lib/AST/ExternalASTSource.cpp           |   2 +-
 clang/lib/AST/Stmt.cpp                        |   2 +-
 clang/lib/Basic/Diagnostic.cpp                |   2 +-
 clang/lib/Basic/SourceLocation.cpp            |  23 +++
 clang/lib/Basic/SourceManager.cpp             |   8 +-
 clang/lib/Format/FormatTokenLexer.cpp         |   3 +-
 clang/lib/Parse/ParseStmtAsm.cpp              |   3 +-
 clang/lib/Rewrite/Rewriter.cpp                |   2 +-
 .../lib/Sema/MultiplexExternalSemaSource.cpp  |   2 +-
 clang/lib/Serialization/ASTReader.cpp         |   2 +-
 clang/lib/Serialization/ASTReaderStmt.cpp     |  26 +--
 clang/lib/Serialization/ASTWriter.cpp         |   2 +-
 clang/lib/Serialization/ASTWriterDecl.cpp     |   2 +-
 clang/lib/Serialization/ASTWriterStmt.cpp     |   2 +-
 clang/test/Lexer/SourceLocationsOverflow.c    |  38 ----
 clang/tools/libclang/CIndex.cpp               |  92 +++++++--
 clang/tools/libclang/CXIndexDataConsumer.cpp  |  10 +-
 clang/tools/libclang/CXSourceLocation.cpp     |  69 ++++---
 clang/tools/libclang/CXSourceLocation.h       |  25 ++-
 clang/tools/libclang/Indexing.cpp             |  27 ++-
 .../unittests/Lex/PPMemoryAllocationsTest.cpp |   2 +-
 .../SourceLocationEncodingTest.cpp            |  11 +-
 40 files changed, 474 insertions(+), 351 deletions(-)
 delete mode 100644 clang/test/Lexer/SourceLocationsOverflow.c

diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index dd67ebc9873ff..b136329fce15a 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -1953,16 +1953,10 @@ class DeclContext {
     /// For the bits in DeclContextBitfields
     LLVM_PREFERRED_TYPE(DeclContextBitfields)
     uint32_t : NumDeclContextBits;
-
-    // Not a bitfield but this saves space.
-    // Note that ObjCContainerDeclBitfields is full.
-    SourceLocation AtStart;
   };
 
   /// Number of inherited and non-inherited bits in ObjCContainerDeclBitfields.
-  /// Note that here we rely on the fact that SourceLocation is 32 bits
-  /// wide. We check this with the static_assert in the ctor of DeclContext.
-  enum { NumObjCContainerDeclBits = 64 };
+  enum { NumObjCContainerDeclBits = NumDeclContextBits };
 
   /// Stores the bits used by LinkageSpecDecl.
   /// If modified NumLinkageSpecDeclBits and the accessor
@@ -2070,7 +2064,7 @@ class DeclContext {
                   "CXXConstructorDeclBitfields is larger than 8 bytes!");
     static_assert(sizeof(ObjCMethodDeclBitfields) <= 8,
                   "ObjCMethodDeclBitfields is larger than 8 bytes!");
-    static_assert(sizeof(ObjCContainerDeclBitfields) <= 8,
+    static_assert(sizeof(ObjCContainerDeclBitfields) <= 16,
                   "ObjCContainerDeclBitfields is larger than 8 bytes!");
     static_assert(sizeof(LinkageSpecDeclBitfields) <= 8,
                   "LinkageSpecDeclBitfields is larger than 8 bytes!");
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
index 9014d76f8433b..56fc4ba4177da 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -946,6 +946,7 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
   // This class stores some data in DeclContext::ObjCContainerDeclBits
   // to save some space. Use the provided accessors to access it.
 
+  SourceLocation AtStart;
   // These two locations in the range mark the end of the method container.
   // The first points to the '@' token, and the second to the 'end' token.
   SourceRange AtEnd;
@@ -1090,10 +1091,10 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
   /// Note, the superclass's properties are not included in the list.
   virtual void collectPropertiesToImplement(PropertyMap &PM) const {}
 
-  SourceLocation getAtStartLoc() const { return ObjCContainerDeclBits.AtStart; }
+  SourceLocation getAtStartLoc() const { return AtStart; }
 
   void setAtStartLoc(SourceLocation Loc) {
-    ObjCContainerDeclBits.AtStart = Loc;
+    AtStart = Loc;
   }
 
   // Marks the end of the container.
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index d95396fd59b95..0955b54163de3 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -1175,6 +1175,8 @@ class ConstantExpr final
 /// context.
 class OpaqueValueExpr : public Expr {
   friend class ASTStmtReader;
+
+  SourceLocation Loc;
   Expr *SourceExpr;
 
 public:
@@ -1182,7 +1184,7 @@ class OpaqueValueExpr : public Expr {
                   ExprObjectKind OK = OK_Ordinary, Expr *SourceExpr = nullptr)
       : Expr(OpaqueValueExprClass, T, VK, OK), SourceExpr(SourceExpr) {
     setIsUnique(false);
-    OpaqueValueExprBits.Loc = Loc;
+    this->Loc = Loc;
     setDependence(computeDependence(this));
   }
 
@@ -1195,7 +1197,7 @@ class OpaqueValueExpr : public Expr {
     : Expr(OpaqueValueExprClass, Empty) {}
 
   /// Retrieve the location of this expression.
-  SourceLocation getLocation() const { return OpaqueValueExprBits.Loc; }
+  SourceLocation getLocation() const { return Loc; }
 
   SourceLocation getBeginLoc() const LLVM_READONLY {
     return SourceExpr ? SourceExpr->getBeginLoc() : getLocation();
@@ -1269,6 +1271,9 @@ class DeclRefExpr final
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
   friend TrailingObjects;
+  
+      /// The location of the declaration name itself.
+      SourceLocation Loc;
 
   /// The declaration that we are referencing.
   ValueDecl *D;
@@ -1341,13 +1346,13 @@ class DeclRefExpr final
     return DeclarationNameInfo(getDecl()->getDeclName(), getLocation(), DNLoc);
   }
 
-  SourceLocation getLocation() const { return DeclRefExprBits.Loc; }
-  void setLocation(SourceLocation L) { DeclRefExprBits.Loc = L; }
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
 
   SourceLocation getBeginLoc() const {
     if (hasQualifier())
       return getQualifierLoc().getBeginLoc();
-    return DeclRefExprBits.Loc;
+    return Loc;
   }
 
   SourceLocation getEndLoc() const LLVM_READONLY;
@@ -2003,7 +2008,8 @@ class PredefinedExpr final
       private llvm::TrailingObjects<PredefinedExpr, Stmt *> {
   friend class ASTStmtReader;
   friend TrailingObjects;
-
+   /// The location of this PredefinedExpr.
+   SourceLocation Loc;
   // PredefinedExpr is optionally followed by a single trailing
   // "Stmt *" for the predefined identifier. It is present if and only if
   // hasFunctionName() is true and is always a "StringLiteral *".
@@ -2041,8 +2047,8 @@ class PredefinedExpr final
 
   bool isTransparent() const { return PredefinedExprBits.IsTransparent; }
 
-  SourceLocation getLocation() const { return PredefinedExprBits.Loc; }
-  void setLocation(SourceLocation L) { PredefinedExprBits.Loc = L; }
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
 
   StringLiteral *getFunctionName() {
     return hasFunctionName()
@@ -2240,6 +2246,7 @@ class ParenExpr : public Expr {
 class UnaryOperator final
     : public Expr,
       private llvm::TrailingObjects<UnaryOperator, FPOptionsOverride> {
+  SourceLocation Loc;
   Stmt *Val;
 
   FPOptionsOverride &getTrailingFPFeatures() {
@@ -2284,8 +2291,8 @@ class UnaryOperator final
   void setSubExpr(Expr *E) { Val = E; }
 
   /// getOperatorLoc - Return the location of the operator.
-  SourceLocation getOperatorLoc() const { return UnaryOperatorBits.Loc; }
-  void setOperatorLoc(SourceLocation L) { UnaryOperatorBits.Loc = L; }
+  SourceLocation getOperatorLoc() const { return Loc; }
+  void setOperatorLoc(SourceLocation L) { Loc = L; }
 
   /// Returns true if the unary operator can cause an overflow. For instance,
   ///   signed int i = INT_MAX; i++;
@@ -2718,6 +2725,7 @@ class UnaryExprOrTypeTraitExpr : public Expr {
 /// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
 class ArraySubscriptExpr : public Expr {
   enum { LHS, RHS, END_EXPR };
+  SourceLocation RBracketLoc;
   Stmt *SubExprs[END_EXPR];
 
   bool lhsIsBase() const { return getRHS()->getType()->isIntegerType(); }
@@ -2728,7 +2736,7 @@ class ArraySubscriptExpr : public Expr {
       : Expr(ArraySubscriptExprClass, t, VK, OK) {
     SubExprs[LHS] = lhs;
     SubExprs[RHS] = rhs;
-    ArrayOrMatrixSubscriptExprBits.RBracketLoc = rbracketloc;
+    this->RBracketLoc = rbracketloc;
     setDependence(computeDependence(this));
   }
 
@@ -2765,10 +2773,10 @@ class ArraySubscriptExpr : public Expr {
   SourceLocation getEndLoc() const { return getRBracketLoc(); }
 
   SourceLocation getRBracketLoc() const {
-    return ArrayOrMatrixSubscriptExprBits.RBracketLoc;
+    return RBracketLoc;
   }
   void setRBracketLoc(SourceLocation L) {
-    ArrayOrMatrixSubscriptExprBits.RBracketLoc = L;
+    RBracketLoc = L;
   }
 
   SourceLocation getExprLoc() const LLVM_READONLY {
@@ -2796,6 +2804,7 @@ class ArraySubscriptExpr : public Expr {
 /// exist during the initial construction of the AST.
 class MatrixSubscriptExpr : public Expr {
   enum { BASE, ROW_IDX, COLUMN_IDX, END_EXPR };
+  SourceLocation RBracketLoc;
   Stmt *SubExprs[END_EXPR];
 
 public:
@@ -2806,7 +2815,7 @@ class MatrixSubscriptExpr : public Expr {
     SubExprs[BASE] = Base;
     SubExprs[ROW_IDX] = RowIdx;
     SubExprs[COLUMN_IDX] = ColumnIdx;
-    ArrayOrMatrixSubscriptExprBits.RBracketLoc = RBracketLoc;
+    this->RBracketLoc = RBracketLoc;
     setDependence(computeDependence(this));
   }
 
@@ -2847,10 +2856,10 @@ class MatrixSubscriptExpr : public Expr {
   }
 
   SourceLocation getRBracketLoc() const {
-    return ArrayOrMatrixSubscriptExprBits.RBracketLoc;
+    return RBracketLoc;
   }
   void setRBracketLoc(SourceLocation L) {
-    ArrayOrMatrixSubscriptExprBits.RBracketLoc = L;
+    RBracketLoc = L;
   }
 
   static bool classof(const Stmt *T) {
@@ -2875,9 +2884,6 @@ class MatrixSubscriptExpr : public Expr {
 class CallExpr : public Expr {
   enum { FN = 0, PREARGS_START = 1 };
 
-  /// The number of arguments in the call expression.
-  unsigned NumArgs;
-
   /// The location of the right parentheses. This has a different meaning for
   /// the derived classes of CallExpr.
   SourceLocation RParenLoc;
@@ -2897,19 +2903,19 @@ class CallExpr : public Expr {
   //
   // * An optional of type FPOptionsOverride.
   //
-  // CallExpr subclasses are asssumed to be 32 bytes or less, and CallExpr
+  // CallExpr subclasses are asssumed to be 40 bytes or less, and CallExpr
   // itself is 24 bytes. To avoid having to recompute or store the offset of the
-  // trailing objects, we put it at 32 bytes (such that it is suitable for all
+  // trailing objects, we put it at 40 bytes (such that it is suitable for all
   // subclasses) We use the 8 bytes gap left for instances of CallExpr to store
   // the begin source location, which has a significant impact on perf as
   // getBeginLoc is assumed to be cheap.
   // The layourt is as follow:
-  // CallExpr | Begin | 4 bytes left | Trailing Objects
+  // CallExpr | Begin | 8 bytes left | Trailing Objects
   // CXXMemberCallExpr | Trailing Objects
   // A bit in CallExprBitfields indicates if source locations are present.
 
 protected:
-  static constexpr unsigned OffsetToTrailingObjects = 32;
+  static constexpr unsigned OffsetToTrailingObjects = 40;
   template <typename T>
   static constexpr unsigned
   sizeToAllocateForCallExprSubclass(unsigned SizeOfTrailingObjects) {
@@ -3063,7 +3069,7 @@ class CallExpr : public Expr {
   }
 
   /// getNumArgs - Return the number of actual arguments to this call.
-  unsigned getNumArgs() const { return NumArgs; }
+  unsigned getNumArgs() const { return CallExprBits.NumArgs; }
 
   /// Retrieve the call arguments.
   Expr **getArgs() {
@@ -3111,13 +3117,13 @@ class CallExpr : public Expr {
   void shrinkNumArgs(unsigned NewNumArgs) {
     assert((NewNumArgs <= getNumArgs()) &&
            "shrinkNumArgs cannot increase the number of arguments!");
-    NumArgs = NewNumArgs;
+    CallExprBits.NumArgs = NewNumArgs;
   }
 
   /// Bluntly set a new number of arguments without doing any checks whatsoever.
   /// Only used during construction of a CallExpr in a few places in Sema.
   /// FIXME: Find a way to remove it.
-  void setNumArgsUnsafe(unsigned NewNumArgs) { NumArgs = NewNumArgs; }
+  void setNumArgsUnsafe(unsigned NewNumArgs) { CallExprBits.NumArgs = NewNumArgs; }
 
   typedef ExprIterator arg_iterator;
   typedef ConstExprIterator const_arg_iterator;
@@ -3302,6 +3308,8 @@ class MemberExpr final
 
   /// MemberLoc - This is the location of the member name.
   SourceLocation MemberLoc;
+  
+  SourceLocation OperatorLoc;
 
   size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
     return hasQualifier();
@@ -3464,7 +3472,7 @@ class MemberExpr final
                                MemberLoc, MemberDNLoc);
   }
 
-  SourceLocation getOperatorLoc() const { return MemberExprBits.OperatorLoc; }
+  SourceLocation getOperatorLoc() const { return OperatorLoc; }
 
   bool isArrow() const { return MemberExprBits.IsArrow; }
   void setArrow(bool A) { MemberExprBits.IsArrow = A; }
@@ -3958,6 +3966,7 @@ class CStyleCastExpr final
 class BinaryOperator : public Expr {
   enum { LHS, RHS, END_EXPR };
   Stmt *SubExprs[END_EXPR];
+  SourceLocation OpLoc;
 
 public:
   typedef BinaryOperatorKind Opcode;
@@ -3997,8 +4006,8 @@ class BinaryOperator : public Expr {
                                 ExprObjectKind OK, SourceLocation opLoc,
                                 FPOptionsOverride FPFeatures);
   SourceLocation getExprLoc() const { return getOperatorLoc(); }
-  SourceLocation getOperatorLoc() const { return BinaryOperatorBits.OpLoc; }
-  void setOperatorLoc(SourceLocation L) { BinaryOperatorBits.OpLoc = L; }
+  SourceLocation getOperatorLoc() const { return OpLoc; }
+  void setOperatorLoc(SourceLocation L) { OpLoc = L; }
 
   Opcode getOpcode() const {
     return static_cast<Opcode>(BinaryOperatorBits.Opc);
@@ -6099,7 +6108,8 @@ class GenericSelectionExpr final
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
   friend TrailingObjects;
-
+  /// The location of the "_Generic".
+  SourceLocation GenericLoc;
   /// The number of association expressions and the index of the result
   /// expression in the case where the generic selection expression is not
   /// result-dependent. The result index is equal to ResultDependentIndex
@@ -6449,7 +6459,7 @@ class GenericSelectionExpr final
   }
 
   SourceLocation getGenericLoc() const {
-    return GenericSelectionExprBits.GenericLoc;
+    return GenericLoc;
   }
   SourceLocation getDefaultLoc() const { return DefaultLoc; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 477373f07f25d..2e2f4dd175d0c 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -720,11 +720,13 @@ class UserDefinedLiteral final : public CallExpr {
 
 /// A boolean literal, per ([C++ lex.bool] Boolean literals).
 class CXXBoolLiteralExpr : public Expr {
+  SourceLocation Loc;
+
 public:
   CXXBoolLiteralExpr(bool Val, QualType Ty, SourceLocation Loc)
       : Expr(CXXBoolLiteralExprClass, Ty, VK_PRValue, OK_Ordinary) {
     CXXBoolLiteralExprBits.Value = Val;
-    CXXBoolLiteralExprBits.Loc = Loc;
+    this->Loc = Loc;
     setDependence(ExprDependence::None);
   }
 
@@ -742,8 +744,8 @@ class CXXBoolLiteralExpr : public Expr {
   SourceLocation getBeginLoc() const { return getLocation(); }
   SourceLocation getEndLoc() const { return getLocation(); }
 
-  SourceLocation getLocation() const { return CXXBoolLiteralExprBits.Loc; }
-  void setLocation(SourceLocation L) { CXXBoolLiteralExprBits.Loc = L; }
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXBoolLiteralExprClass;
@@ -765,10 +767,11 @@ class CXXBoolLiteralExpr : public Expr {
 /// This also implements the null pointer literal in C23 (C23 6.4.1) which is
 /// intended to have the same semantics as the feature in C++.
 class CXXNullPtrLiteralExpr : public Expr {
+  SourceLocation Loc;
 public:
   CXXNullPtrLiteralExpr(QualType Ty, SourceLocation Loc)
       : Expr(CXXNullPtrLiteralExprClass, Ty, VK_PRValue, OK_Ordinary) {
-    CXXNullPtrLiteralExprBits.Loc = Loc;
+    this->Loc = Loc;
     setDependence(ExprDependence::None);
   }
 
@@ -778,8 +781,8 @@ class CXXNullPtrLiteralExpr : public Expr {
   SourceLocation getBeginLoc() const { return getLocation(); }
   SourceLocation getEndLoc() const { return getLocation(); }
 
-  SourceLocation getLocation() const { return CXXNullPtrLiteralExprBits.Loc; }
-  void setLocation(SourceLocation L) { CXXNullPtrLiteralExprBits.Loc = L; }
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXNullPtrLiteralExprClass;
@@ -1152,11 +1155,14 @@ class CXXUuidofExpr : public Expr {
 /// };
 /// \endcode
 class CXXThisExpr : public Expr {
+  /// The location of the "this".
+  SourceLocation Loc;
+
   CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit, ExprValueKind VK)
       : Expr(CXXThisExprClass, Ty, VK, OK_Ordinary) {
     CXXThisExprBits.IsImplicit = IsImplicit;
     CXXThisExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false;
-    CXXThisExprBits.Loc = L;
+    Loc = L;
     setDependence(computeDependence(this));
   }
 
@@ -1168,8 +1174,8 @@ class CXXThisExpr : public Expr {
 
   static CXXThisExpr *CreateEmpty(const ASTContext &Ctx);
 
-  SourceLocation getLocation() const { return CXXThisExprBits.Loc; }
-  void setLocation(SourceLocation L) { CXXThisExprBits.Loc = L; }
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
 
   SourceLocation getBeginLoc() const { return getLocation(); }
   SourceLocation getEndLoc() const { return getLocation(); }
@@ -1210,6 +1216,8 @@ class CXXThrowExpr : public Expr {
 
   /// The optional expression in the throw statement.
   Stmt *Operand;
+  /// The location of the "throw".
+  SourceLocation ThrowLoc;
 
 public:
   // \p Ty is the void type which is used as the result type of the
@@ -1219,7 +1227,7 @@ class CXXThrowExpr : public Expr {
   CXXThrowExpr(Expr *Operand, QualType Ty, SourceLocation Loc,
                bool IsThrownVariableInScope)
       : Expr(CXXThrowExprClass, Ty, VK_PRValue, OK_Ordinary), Operand(Operand) {
-    CXXThrowExprBits.ThrowLoc = Loc;
+    ThrowLoc = Loc;
     CXXThrowExprBits.IsThrownVariableInScope = IsThrownVariableInScope;
     setDependence(computeDependence(this));
   }
@@ -1228,7 +1236,7 @@ class CXXThrowExpr : public Expr {
   const Expr *getSubExpr() const { return cast_or_null<Expr>(Operand); }
   Expr *getSubExpr() { return cast_or_null<Expr>(Operand); }
 
-  SourceLocation getThrowLoc() const { return CXXThrowExprBits.ThrowLoc; }
+  SourceLocation getThrowLoc() const { return ThrowLoc; }
 
   /// Determines whether the variable thrown by this expression (if any!)
   /// is within the innermost try block.
@@ -1277,7 +1285,9 @@ class CXXDefaultArgExpr final
 
   /// The context where the default argument expression was used.
   DeclContext *UsedContext;
-
+  
+  /// The location where the default argument expression was used.
+  SourceLocation Loc;
   CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param,
                     Expr *RewrittenExpr, DeclContext *UsedContext)
       : Expr(SC,
@@ -1287,7 +1297,7 @@ class CXXDefaultArgExpr final
              Param->getDefaultArg()->getValueKind(),
              Param->getDefaultArg()->getObjectKind()),
         Param(Param), UsedContext(UsedContext) {
-    CXXDefaultArgExprBits.Loc = Loc;
+    this->Loc = Loc;
     CXXDefaultArgExprBits.HasRewrittenInit = RewrittenExpr != nullptr;
     if (RewrittenExpr)
       *getTrailingObjects() = RewrittenExpr;
@@ -1341,7 +1351,7 @@ class CXXDefaultArgExpr final
   DeclContext *getUsedContext() { return UsedContext; }
 
   /// Retrieve the location where this default argument was actually used.
-  SourceLocation getUsedLocation() const { return CXXDefaultArgExprBits.Loc; }
+  SourceLocation getUsedLocation() const { return Loc; }
 
   /// Default argument expressions have no representation in the
   /// source, so they have an empty source range.
@@ -1384,7 +1394,8 @@ class CXXDefaultInitExpr final
 
   /// The context where the default initializer expression was used.
   DeclContext *UsedContext;
-
+  /// The location where the default initializer expression was used.
+  SourceLocation Loc;
   CXXDefaultInitExpr(const ASTContext &Ctx, SourceLocation Loc,
                      FieldDecl *Field, QualType Ty, DeclContext *UsedContext,
                      Expr *RewrittenInitExpr);
@@ -1438,8 +1449,8 @@ class CXXDefaultInitExpr final
   /// actually used.
   SourceLocation getUsedLocation() const { return getBeginLoc(); }
 
-  SourceLocation getBeginLoc() const { return CXXDefaultInitExprBits.Loc; }
-  SourceLocation getEndLoc() const { return CXXDefaultInitExprBits.Loc; }
+  SourceLocation getBeginLoc() const { return Loc; }
+  SourceLocation getEndLoc() const { return Loc; }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXDefaultInitExprClass;
@@ -1555,7 +1566,7 @@ class CXXConstructExpr : public Expr {
 
   /// The number of arguments.
   unsigned NumArgs;
-
+  SourceLocation Loc;
   // We would like to stash the arguments of the constructor call after
   // CXXConstructExpr. However CXXConstructExpr is used as a base class of
   // CXXTemporaryObjectExpr which makes the use of llvm::TrailingObjects
@@ -1610,8 +1621,8 @@ class CXXConstructExpr : public Expr {
   /// Get the constructor that this expression will (ultimately) call.
   CXXConstructorDecl *getConstructor() const { return Constructor; }
 
-  SourceLocation getLocation() const { return CXXConstructExprBits.Loc; }
-  void setLocation(SourceLocation Loc) { CXXConstructExprBits.Loc = Loc; }
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation Loc) { this->Loc = Loc; }
 
   /// Whether this construction is elidable.
   bool isElidable() const { return CXXConstructExprBits.Elidable; }
@@ -2185,6 +2196,7 @@ class CXXScalarValueInitExpr : public Expr {
   friend class ASTStmtReader;
 
   TypeSourceInfo *TypeInfo;
+  SourceLocation RParenLoc;
 
 public:
   /// Create an explicitly-written scalar-value initialization
@@ -2193,7 +2205,7 @@ class CXXScalarValueInitExpr : public Expr {
                          SourceLocation RParenLoc)
       : Expr(CXXScalarValueInitExprClass, Type, VK_PRValue, OK_Ordinary),
         TypeInfo(TypeInfo) {
-    CXXScalarValueInitExprBits.RParenLoc = RParenLoc;
+    this->RParenLoc = RParenLoc;
     setDependence(computeDependence(this));
   }
 
@@ -2205,7 +2217,7 @@ class CXXScalarValueInitExpr : public Expr {
   }
 
   SourceLocation getRParenLoc() const {
-    return CXXScalarValueInitExprBits.RParenLoc;
+    return RParenLoc;
   }
 
   SourceLocation getBeginLoc() const LLVM_READONLY;
@@ -2611,7 +2623,8 @@ class CXXDeleteExpr : public Expr {
 
   /// The pointer expression to be deleted.
   Stmt *Argument = nullptr;
-
+    /// Location of the expression.
+    SourceLocation Loc;
 public:
   CXXDeleteExpr(QualType Ty, bool GlobalDelete, bool ArrayForm,
                 bool ArrayFormAsWritten, bool UsualArrayDeleteWantsSize,
@@ -2622,7 +2635,7 @@ class CXXDeleteExpr : public Expr {
     CXXDeleteExprBits.ArrayForm = ArrayForm;
     CXXDeleteExprBits.ArrayFormAsWritten = ArrayFormAsWritten;
     CXXDeleteExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize;
-    CXXDeleteExprBits.Loc = Loc;
+    this->Loc = Loc;
     setDependence(computeDependence(this));
   }
 
@@ -2653,7 +2666,7 @@ class CXXDeleteExpr : public Expr {
   /// be a pointer, return an invalid type.
   QualType getDestroyedType() const;
 
-  SourceLocation getBeginLoc() const { return CXXDeleteExprBits.Loc; }
+  SourceLocation getBeginLoc() const { return Loc; }
   SourceLocation getEndLoc() const LLVM_READONLY {
     return Argument->getEndLoc();
   }
@@ -3829,6 +3842,9 @@ class CXXDependentScopeMemberExpr final
   /// FIXME: could also be a template-id
   DeclarationNameInfo MemberNameInfo;
 
+      /// The location of the '->' or '.' operator.
+      SourceLocation OperatorLoc;
+
   // CXXDependentScopeMemberExpr is followed by several trailing objects,
   // some of which optional. They are in order:
   //
@@ -3908,7 +3924,7 @@ class CXXDependentScopeMemberExpr final
 
   /// Retrieve the location of the '->' or '.' operator.
   SourceLocation getOperatorLoc() const {
-    return CXXDependentScopeMemberExprBits.OperatorLoc;
+    return OperatorLoc;
   }
 
   /// Retrieve the nested-name-specifier that qualifies the member name.
@@ -4602,6 +4618,8 @@ class PackIndexingExpr final
 class SubstNonTypeTemplateParmExpr : public Expr {
   friend class ASTReader;
   friend class ASTStmtReader;
+      /// The location of the non-type template parameter reference.
+      SourceLocation NameLoc;
 
   /// The replacement expression.
   Stmt *Replacement;
@@ -4630,12 +4648,12 @@ class SubstNonTypeTemplateParmExpr : public Expr {
         AssociatedDeclAndRef(AssociatedDecl, RefParam), Index(Index),
         PackIndex(PackIndex.toInternalRepresentation()), Final(Final) {
     assert(AssociatedDecl != nullptr);
-    SubstNonTypeTemplateParmExprBits.NameLoc = Loc;
+    NameLoc = Loc;
     setDependence(computeDependence(this));
   }
 
   SourceLocation getNameLoc() const {
-    return SubstNonTypeTemplateParmExprBits.NameLoc;
+    return NameLoc;
   }
   SourceLocation getBeginLoc() const { return getNameLoc(); }
   SourceLocation getEndLoc() const { return getNameLoc(); }
diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h
index 8df5cdcaa9d75..9d1fc29a2753e 100644
--- a/clang/include/clang/AST/ExprConcepts.h
+++ b/clang/include/clang/AST/ExprConcepts.h
@@ -502,6 +502,8 @@ class RequiresExpr final : public Expr,
                           concepts::Requirement *> {
   friend TrailingObjects;
   friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+  SourceLocation RequiresKWLoc;
 
   unsigned NumLocalParameters;
   unsigned NumRequirements;
@@ -560,7 +562,7 @@ class RequiresExpr final : public Expr,
   }
 
   SourceLocation getRequiresKWLoc() const {
-    return RequiresExprBits.RequiresKWLoc;
+    return RequiresKWLoc;
   }
 
   SourceLocation getLParenLoc() const { return LParenLoc; }
@@ -572,7 +574,7 @@ class RequiresExpr final : public Expr,
   }
 
   SourceLocation getBeginLoc() const LLVM_READONLY {
-    return RequiresExprBits.RequiresKWLoc;
+    return RequiresKWLoc;
   }
   SourceLocation getEndLoc() const LLVM_READONLY {
     return RBraceLoc;
diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h
index e91d5132da10f..01dd56b576200 100644
--- a/clang/include/clang/AST/ExternalASTSource.h
+++ b/clang/include/clang/AST/ExternalASTSource.h
@@ -110,7 +110,7 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
   /// returns non-zero for GetNumKnownSelectors().
   ///
   /// The default implementation of this method is a no-op.
-  virtual Selector GetExternalSelector(uint32_t ID);
+  virtual Selector GetExternalSelector(uint64_t ID);
 
   /// Returns the number of selectors known to the external AST
   /// source.
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index a5b0d5053003f..83c1f646c6701 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -138,8 +138,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasLeadingEmptyMacro : 1;
 
-    /// The location of the semi-colon.
-    SourceLocation SemiLoc;
+ 
   };
 
   class CompoundStmtBitfields {
@@ -163,7 +162,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(StmtBitfields)
     unsigned : NumStmtBits;
 
-    SourceLocation IdentLoc;
+
   };
 
   class AttributedStmtBitfields {
@@ -176,8 +175,7 @@ class alignas(void *) Stmt {
     /// Number of attributes.
     unsigned NumAttrs : 32 - NumStmtBits;
 
-    /// The location of the attribute.
-    SourceLocation AttrLoc;
+
   };
 
   class IfStmtBitfields {
@@ -203,8 +201,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasInit : 1;
 
-    /// The location of the "if".
-    SourceLocation IfLoc;
+
   };
 
   class SwitchStmtBitfields {
@@ -227,8 +224,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned AllEnumCasesCovered : 1;
 
-    /// The location of the "switch".
-    SourceLocation SwitchLoc;
+
   };
 
   class WhileStmtBitfields {
@@ -242,8 +238,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasVar : 1;
 
-    /// The location of the "while".
-    SourceLocation WhileLoc;
+
   };
 
   class DoStmtBitfields {
@@ -252,8 +247,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(StmtBitfields)
     unsigned : NumStmtBits;
 
-    /// The location of the "do".
-    SourceLocation DoLoc;
+
   };
 
   class ForStmtBitfields {
@@ -262,8 +256,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(StmtBitfields)
     unsigned : NumStmtBits;
 
-    /// The location of the "for".
-    SourceLocation ForLoc;
+
   };
 
   class GotoStmtBitfields {
@@ -273,8 +266,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(StmtBitfields)
     unsigned : NumStmtBits;
 
-    /// The location of the "goto".
-    SourceLocation GotoLoc;
+
   };
 
   class ContinueStmtBitfields {
@@ -283,8 +275,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(StmtBitfields)
     unsigned : NumStmtBits;
 
-    /// The location of the "continue".
-    SourceLocation ContinueLoc;
+
   };
 
   class BreakStmtBitfields {
@@ -293,8 +284,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(StmtBitfields)
     unsigned : NumStmtBits;
 
-    /// The location of the "break".
-    SourceLocation BreakLoc;
+
   };
 
   class ReturnStmtBitfields {
@@ -307,8 +297,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasNRVOCandidate : 1;
 
-    /// The location of the "return".
-    SourceLocation RetLoc;
+
   };
 
   class SwitchCaseBitfields {
@@ -323,8 +312,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned CaseStmtIsGNURange : 1;
 
-    /// The location of the "case" or "default" keyword.
-    SourceLocation KeywordLoc;
+
   };
 
   //===--- Expression bitfields classes ---===//
@@ -422,8 +410,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned IsTransparent : 1;
 
-    /// The location of this PredefinedExpr.
-    SourceLocation Loc;
+   
   };
 
   class DeclRefExprBitfields {
@@ -450,8 +437,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned IsImmediateEscalating : 1;
 
-    /// The location of the declaration name itself.
-    SourceLocation Loc;
+
   };
 
 
@@ -522,7 +508,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasFPFeatures : 1;
 
-    SourceLocation Loc;
+
   };
 
   class UnaryExprOrTypeTraitExprBitfields {
@@ -544,7 +530,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(ExprBitfields)
     unsigned : NumExprBits;
 
-    SourceLocation RBracketLoc;
+
   };
 
   class CallExprBitfields {
@@ -576,9 +562,10 @@ class alignas(void *) Stmt {
     /// Trailing objects. See the definition of CallExpr.
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasTrailingSourceLoc : 1;
+    
+    unsigned NumArgs:20;
   };
-
-  enum { NumCallExprBits = 25 };
+  enum { NumCallExprBits = 52 };
 
   class MemberExprBitfields {
     friend class ASTStmtReader;
@@ -620,9 +607,10 @@ class alignas(void *) Stmt {
     unsigned NonOdrUseReason : 2;
 
     /// This is the location of the -> or . in the expression.
-    SourceLocation OperatorLoc;
+    // SourceLocation OperatorLoc;
   };
-
+  
+  // 8 bytes
   class CastExprBitfields {
     friend class CastExpr;
     friend class ImplicitCastExpr;
@@ -663,8 +651,6 @@ class alignas(void *) Stmt {
     /// overflow sanitization.
     LLVM_PREFERRED_TYPE(bool)
     unsigned ExcludedOverflowPattern : 1;
-
-    SourceLocation OpLoc;
   };
 
   class InitListExprBitfields {
@@ -697,8 +683,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(ExprBitfields)
     unsigned : NumExprBits;
 
-    /// The location of the "_Generic".
-    SourceLocation GenericLoc;
+
   };
 
   class PseudoObjectExprBitfields {
@@ -805,9 +790,6 @@ class alignas(void *) Stmt {
     /// The value of the boolean literal.
     LLVM_PREFERRED_TYPE(bool)
     unsigned Value : 1;
-
-    /// The location of the boolean literal.
-    SourceLocation Loc;
   };
 
   class CXXNullPtrLiteralExprBitfields {
@@ -817,7 +799,6 @@ class alignas(void *) Stmt {
     unsigned : NumExprBits;
 
     /// The location of the null pointer literal.
-    SourceLocation Loc;
   };
 
   class CXXThisExprBitfields {
@@ -835,8 +816,6 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned CapturedByCopyInLambdaWithExplicitObjectParameter : 1;
 
-    /// The location of the "this".
-    SourceLocation Loc;
   };
 
   class CXXThrowExprBitfields {
@@ -850,8 +829,6 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned IsThrownVariableInScope : 1;
 
-    /// The location of the "throw".
-    SourceLocation ThrowLoc;
   };
 
   class CXXDefaultArgExprBitfields {
@@ -865,8 +842,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasRewrittenInit : 1;
 
-    /// The location where the default argument expression was used.
-    SourceLocation Loc;
+
   };
 
   class CXXDefaultInitExprBitfields {
@@ -881,8 +857,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasRewrittenInit : 1;
 
-    /// The location where the default initializer expression was used.
-    SourceLocation Loc;
+
   };
 
   class CXXScalarValueInitExprBitfields {
@@ -892,7 +867,6 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(ExprBitfields)
     unsigned : NumExprBits;
 
-    SourceLocation RParenLoc;
   };
 
   class CXXNewExprBitfields {
@@ -967,8 +941,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned UsualArrayDeleteWantsSize : 1;
 
-    /// Location of the expression.
-    SourceLocation Loc;
+  
   };
 
   class TypeTraitExprBitfields {
@@ -1032,7 +1005,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned IsImmediateEscalating : 1;
 
-    SourceLocation Loc;
+
   };
 
   class ExprWithCleanupsBitfields {
@@ -1082,8 +1055,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasFirstQualifierFoundInScope : 1;
 
-    /// The location of the '->' or '.' operator.
-    SourceLocation OperatorLoc;
+
   };
 
   class OverloadExprBitfields {
@@ -1162,8 +1134,7 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(ExprBitfields)
     unsigned : NumExprBits;
 
-    /// The location of the non-type template parameter reference.
-    SourceLocation NameLoc;
+
   };
 
   class LambdaExprBitfields {
@@ -1202,7 +1173,6 @@ class alignas(void *) Stmt {
 
     LLVM_PREFERRED_TYPE(bool)
     unsigned IsSatisfied : 1;
-    SourceLocation RequiresKWLoc;
   };
 
   class ArrayTypeTraitExprBitfields {
@@ -1294,7 +1264,6 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned IsUnique : 1;
 
-    SourceLocation Loc;
   };
 
   class ConvertVectorExprBitfields {
@@ -1692,6 +1661,8 @@ class DeclStmt : public Stmt {
 /// NullStmt - This is the null statement ";": C99 6.8.3p3.
 ///
 class NullStmt : public Stmt {
+     /// The location of the semi-colon.
+     SourceLocation SemiLoc;
 public:
   NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false)
       : Stmt(NullStmtClass) {
@@ -1702,8 +1673,8 @@ class NullStmt : public Stmt {
   /// Build an empty null statement.
   explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) {}
 
-  SourceLocation getSemiLoc() const { return NullStmtBits.SemiLoc; }
-  void setSemiLoc(SourceLocation L) { NullStmtBits.SemiLoc = L; }
+  SourceLocation getSemiLoc() const { return SemiLoc; }
+  void setSemiLoc(SourceLocation L) { SemiLoc = L; }
 
   bool hasLeadingEmptyMacro() const {
     return NullStmtBits.HasLeadingEmptyMacro;
@@ -1883,6 +1854,8 @@ class CompoundStmt final
 // SwitchCase is the base class for CaseStmt and DefaultStmt,
 class SwitchCase : public Stmt {
 protected:
+    /// The location of the "case" or "default" keyword.
+    SourceLocation KeywordLoc;
   /// The location of the ":".
   SourceLocation ColonLoc;
 
@@ -1905,8 +1878,8 @@ class SwitchCase : public Stmt {
   SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
   void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
 
-  SourceLocation getKeywordLoc() const { return SwitchCaseBits.KeywordLoc; }
-  void setKeywordLoc(SourceLocation L) { SwitchCaseBits.KeywordLoc = L; }
+  SourceLocation getKeywordLoc() const { return KeywordLoc; }
+  void setKeywordLoc(SourceLocation L) { KeywordLoc = L; }
   SourceLocation getColonLoc() const { return ColonLoc; }
   void setColonLoc(SourceLocation L) { ColonLoc = L; }
 
@@ -1948,7 +1921,8 @@ class CaseStmt final
   //   with a range. Present if and only if caseStmtIsGNURange() is true.
   enum { LhsOffset = 0, SubStmtOffsetFromRhs = 1 };
   enum { NumMandatoryStmtPtr = 2 };
-
+      /// The location of the "case" or "default" keyword.
+      SourceLocation KeywordLoc;
   unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
     return NumMandatoryStmtPtr + caseStmtIsGNURange();
   }
@@ -2155,9 +2129,10 @@ class ValueStmt : public Stmt {
 /// LabelStmt - Represents a label, which has a substatement.  For example:
 ///    foo: return;
 class LabelStmt : public ValueStmt {
+  SourceLocation IdentLoc;
   LabelDecl *TheDecl;
   Stmt *SubStmt;
-  bool SideEntry = false;
+  bool SideEntry = false; // FIXME: could improve
 
 public:
   /// Build a label statement.
@@ -2169,8 +2144,8 @@ class LabelStmt : public ValueStmt {
   /// Build an empty label statement.
   explicit LabelStmt(EmptyShell Empty) : ValueStmt(LabelStmtClass, Empty) {}
 
-  SourceLocation getIdentLoc() const { return LabelStmtBits.IdentLoc; }
-  void setIdentLoc(SourceLocation L) { LabelStmtBits.IdentLoc = L; }
+  SourceLocation getIdentLoc() const { return IdentLoc; }
+  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
 
   LabelDecl *getDecl() const { return TheDecl; }
   void setDecl(LabelDecl *D) { TheDecl = D; }
@@ -2206,21 +2181,22 @@ class AttributedStmt final
       private llvm::TrailingObjects<AttributedStmt, const Attr *> {
   friend class ASTStmtReader;
   friend TrailingObjects;
-
+    /// The location of the attribute.
+    SourceLocation AttrLoc;
   Stmt *SubStmt;
 
   AttributedStmt(SourceLocation Loc, ArrayRef<const Attr *> Attrs,
                  Stmt *SubStmt)
       : ValueStmt(AttributedStmtClass), SubStmt(SubStmt) {
     AttributedStmtBits.NumAttrs = Attrs.size();
-    AttributedStmtBits.AttrLoc = Loc;
-    llvm::copy(Attrs, getAttrArrayPtr());
+    AttrLoc = Loc;
+    std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr());
   }
 
   explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
       : ValueStmt(AttributedStmtClass, Empty) {
     AttributedStmtBits.NumAttrs = NumAttrs;
-    AttributedStmtBits.AttrLoc = SourceLocation{};
+    AttrLoc = SourceLocation{};
     std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr);
   }
 
@@ -2234,7 +2210,7 @@ class AttributedStmt final
   // Build an empty attributed statement.
   static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs);
 
-  SourceLocation getAttrLoc() const { return AttributedStmtBits.AttrLoc; }
+  SourceLocation getAttrLoc() const { return AttrLoc; }
   ArrayRef<const Attr *> getAttrs() const {
     return {getAttrArrayPtr(), AttributedStmtBits.NumAttrs};
   }
@@ -2286,6 +2262,8 @@ class IfStmt final
   //    Present if and only if hasElseStorage().
   enum { InitOffset = 0, ThenOffsetFromCond = 1, ElseOffsetFromCond = 2 };
   enum { NumMandatoryStmtPtr = 2 };
+      /// The location of the "if".
+      SourceLocation IfLoc;
   SourceLocation LParenLoc;
   SourceLocation RParenLoc;
 
@@ -2425,8 +2403,8 @@ class IfStmt final
     getTrailingObjects<Stmt *>()[initOffset()] = Init;
   }
 
-  SourceLocation getIfLoc() const { return IfStmtBits.IfLoc; }
-  void setIfLoc(SourceLocation IfLoc) { IfStmtBits.IfLoc = IfLoc; }
+  SourceLocation getIfLoc() const { return IfLoc; }
+  void setIfLoc(SourceLocation IfLoc) { this->IfLoc = IfLoc; }
 
   SourceLocation getElseLoc() const {
     return hasElseStorage() ? *getTrailingObjects<SourceLocation>()
@@ -2511,7 +2489,8 @@ class IfStmt final
 class SwitchStmt final : public Stmt,
                          private llvm::TrailingObjects<SwitchStmt, Stmt *> {
   friend TrailingObjects;
-
+    /// The location of the "switch".
+    SourceLocation SwitchLoc;
   /// Points to a linked list of case and default statements.
   SwitchCase *FirstCase = nullptr;
 
@@ -2644,8 +2623,8 @@ class SwitchStmt final : public Stmt,
   const SwitchCase *getSwitchCaseList() const { return FirstCase; }
   void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
 
-  SourceLocation getSwitchLoc() const { return SwitchStmtBits.SwitchLoc; }
-  void setSwitchLoc(SourceLocation L) { SwitchStmtBits.SwitchLoc = L; }
+  SourceLocation getSwitchLoc() const { return SwitchLoc; }
+  void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
   SourceLocation getLParenLoc() const { return LParenLoc; }
   void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -2717,7 +2696,8 @@ class WhileStmt final : public Stmt,
   //
   enum { VarOffset = 0, BodyOffsetFromCond = 1 };
   enum { NumMandatoryStmtPtr = 2 };
-
+    /// The location of the "while".
+    SourceLocation WhileLoc;
   SourceLocation LParenLoc, RParenLoc;
 
   unsigned varOffset() const { return VarOffset; }
@@ -2802,8 +2782,8 @@ class WhileStmt final : public Stmt,
     getTrailingObjects()[varOffset()] = CondVar;
   }
 
-  SourceLocation getWhileLoc() const { return WhileStmtBits.WhileLoc; }
-  void setWhileLoc(SourceLocation L) { WhileStmtBits.WhileLoc = L; }
+  SourceLocation getWhileLoc() const { return WhileLoc; }
+  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
 
   SourceLocation getLParenLoc() const { return LParenLoc; }
   void setLParenLoc(SourceLocation L) { LParenLoc = L; }
@@ -2837,7 +2817,8 @@ class DoStmt : public Stmt {
   Stmt *SubExprs[END_EXPR];
   SourceLocation WhileLoc;
   SourceLocation RParenLoc; // Location of final ')' in do stmt condition.
-
+    /// The location of the "do".
+    SourceLocation DoLoc;
 public:
   DoStmt(Stmt *Body, Expr *Cond, SourceLocation DL, SourceLocation WL,
          SourceLocation RP)
@@ -2861,8 +2842,8 @@ class DoStmt : public Stmt {
   const Stmt *getBody() const { return SubExprs[BODY]; }
   void setBody(Stmt *Body) { SubExprs[BODY] = Body; }
 
-  SourceLocation getDoLoc() const { return DoStmtBits.DoLoc; }
-  void setDoLoc(SourceLocation L) { DoStmtBits.DoLoc = L; }
+  SourceLocation getDoLoc() const { return DoLoc; }
+  void setDoLoc(SourceLocation L) { DoLoc = L; }
   SourceLocation getWhileLoc() const { return WhileLoc; }
   void setWhileLoc(SourceLocation L) { WhileLoc = L; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -2892,6 +2873,8 @@ class ForStmt : public Stmt {
   friend class ASTStmtReader;
 
   enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
+      /// The location of the "for".
+      SourceLocation ForLoc;
   Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
   SourceLocation LParenLoc, RParenLoc;
 
@@ -2944,8 +2927,8 @@ class ForStmt : public Stmt {
   void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
   void setBody(Stmt *S) { SubExprs[BODY] = S; }
 
-  SourceLocation getForLoc() const { return ForStmtBits.ForLoc; }
-  void setForLoc(SourceLocation L) { ForStmtBits.ForLoc = L; }
+  SourceLocation getForLoc() const { return ForLoc; }
+  void setForLoc(SourceLocation L) { ForLoc = L; }
   SourceLocation getLParenLoc() const { return LParenLoc; }
   void setLParenLoc(SourceLocation L) { LParenLoc = L; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -2971,6 +2954,8 @@ class ForStmt : public Stmt {
 /// GotoStmt - This represents a direct goto.
 class GotoStmt : public Stmt {
   LabelDecl *Label;
+      /// The location of the "goto".
+      SourceLocation GotoLoc;
   SourceLocation LabelLoc;
 
 public:
@@ -2985,8 +2970,8 @@ class GotoStmt : public Stmt {
   LabelDecl *getLabel() const { return Label; }
   void setLabel(LabelDecl *D) { Label = D; }
 
-  SourceLocation getGotoLoc() const { return GotoStmtBits.GotoLoc; }
-  void setGotoLoc(SourceLocation L) { GotoStmtBits.GotoLoc = L; }
+  SourceLocation getGotoLoc() const { return GotoLoc; }
+  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
   SourceLocation getLabelLoc() const { return LabelLoc; }
   void setLabelLoc(SourceLocation L) { LabelLoc = L; }
 
@@ -3009,6 +2994,8 @@ class GotoStmt : public Stmt {
 
 /// IndirectGotoStmt - This represents an indirect goto.
 class IndirectGotoStmt : public Stmt {
+  /// The location of the "goto".
+  SourceLocation GotoLoc;
   SourceLocation StarLoc;
   Stmt *Target;
 
@@ -3023,8 +3010,8 @@ class IndirectGotoStmt : public Stmt {
   explicit IndirectGotoStmt(EmptyShell Empty)
       : Stmt(IndirectGotoStmtClass, Empty) {}
 
-  void setGotoLoc(SourceLocation L) { GotoStmtBits.GotoLoc = L; }
-  SourceLocation getGotoLoc() const { return GotoStmtBits.GotoLoc; }
+  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
+  SourceLocation getGotoLoc() const { return GotoLoc; }
   void setStarLoc(SourceLocation L) { StarLoc = L; }
   SourceLocation getStarLoc() const { return StarLoc; }
 
@@ -3058,7 +3045,10 @@ class IndirectGotoStmt : public Stmt {
 
 /// ContinueStmt - This represents a continue.
 class ContinueStmt : public Stmt {
+      /// The location of the "continue".
+      SourceLocation ContinueLoc;
 public:
+
   ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass) {
     setContinueLoc(CL);
   }
@@ -3066,8 +3056,8 @@ class ContinueStmt : public Stmt {
   /// Build an empty continue statement.
   explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) {}
 
-  SourceLocation getContinueLoc() const { return ContinueStmtBits.ContinueLoc; }
-  void setContinueLoc(SourceLocation L) { ContinueStmtBits.ContinueLoc = L; }
+  SourceLocation getContinueLoc() const { return ContinueLoc; }
+  void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
 
   SourceLocation getBeginLoc() const { return getContinueLoc(); }
   SourceLocation getEndLoc() const { return getContinueLoc(); }
@@ -3088,6 +3078,8 @@ class ContinueStmt : public Stmt {
 
 /// BreakStmt - This represents a break.
 class BreakStmt : public Stmt {
+      /// The location of the "break".
+      SourceLocation BreakLoc;
 public:
   BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass) {
     setBreakLoc(BL);
@@ -3096,8 +3088,8 @@ class BreakStmt : public Stmt {
   /// Build an empty break statement.
   explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) {}
 
-  SourceLocation getBreakLoc() const { return BreakStmtBits.BreakLoc; }
-  void setBreakLoc(SourceLocation L) { BreakStmtBits.BreakLoc = L; }
+  SourceLocation getBreakLoc() const { return BreakLoc; }
+  void setBreakLoc(SourceLocation L) { BreakLoc = L; }
 
   SourceLocation getBeginLoc() const { return getBreakLoc(); }
   SourceLocation getEndLoc() const { return getBreakLoc(); }
@@ -3128,7 +3120,8 @@ class ReturnStmt final
     : public Stmt,
       private llvm::TrailingObjects<ReturnStmt, const VarDecl *> {
   friend TrailingObjects;
-
+    /// The location of the "return".
+    SourceLocation RetLoc;
   /// The return expression.
   Stmt *RetExpr;
 
@@ -3175,8 +3168,8 @@ class ReturnStmt final
     *getTrailingObjects() = Var;
   }
 
-  SourceLocation getReturnLoc() const { return ReturnStmtBits.RetLoc; }
-  void setReturnLoc(SourceLocation L) { ReturnStmtBits.RetLoc = L; }
+  SourceLocation getReturnLoc() const { return RetLoc; }
+  void setReturnLoc(SourceLocation L) { RetLoc = L; }
 
   SourceLocation getBeginLoc() const { return getReturnLoc(); }
   SourceLocation getEndLoc() const LLVM_READONLY {
diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h
index 7ae4ef7df138c..8fdf1bc01bdd5 100644
--- a/clang/include/clang/Basic/Diagnostic.h
+++ b/clang/include/clang/Basic/Diagnostic.h
@@ -454,9 +454,9 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
     /// modifications done through the command-line.
     struct DiagStatePoint {
       DiagState *State;
-      unsigned Offset;
+      SourceLocation::UIntTy Offset;
 
-      DiagStatePoint(DiagState *State, unsigned Offset)
+      DiagStatePoint(DiagState *State, SourceLocation::UIntTy Offset)
           : State(State), Offset(Offset) {}
     };
 
@@ -469,7 +469,7 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
       File *Parent = nullptr;
 
       /// The offset of this file within its parent.
-      unsigned ParentOffset = 0;
+      SourceLocation::UIntTy ParentOffset = 0;
 
       /// Whether this file has any local (not imported from an AST file)
       /// diagnostic state transitions.
@@ -479,7 +479,7 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
       /// be at least one of these (the state on entry to the file).
       llvm::SmallVector<DiagStatePoint, 4> StateTransitions;
 
-      DiagState *lookup(unsigned Offset) const;
+      DiagState *lookup(SourceLocation::UIntTy Offset) const;
     };
 
     /// The diagnostic states for each file.
diff --git a/clang/include/clang/Basic/SourceLocation.h b/clang/include/clang/Basic/SourceLocation.h
index 14543cc41a38e..91352a4aa0ab6 100644
--- a/clang/include/clang/Basic/SourceLocation.h
+++ b/clang/include/clang/Basic/SourceLocation.h
@@ -17,6 +17,7 @@
 #include "clang/Basic/FileEntry.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/MathExtras.h"
 #include <cassert>
 #include <cstdint>
 #include <string>
@@ -70,8 +71,6 @@ class FileID {
   int getOpaqueValue() const { return ID; }
 };
 
-using FileIDAndOffset = std::pair<FileID, unsigned>;
-
 /// Encodes a location in the source. The SourceManager can decode this
 /// to get at the full include stack, line and column information.
 ///
@@ -95,13 +94,14 @@ class SourceLocation {
   friend class SourceLocationEncoding;
 
 public:
-  using UIntTy = uint32_t;
-  using IntTy = int32_t;
+  using UIntTy = uint64_t;
+  using IntTy = int64_t;
+  static constexpr unsigned Bits = 40;
 
 private:
-  UIntTy ID = 0;
+  uint64_t ID = 0;
 
-  enum : UIntTy { MacroIDBit = 1ULL << (8 * sizeof(UIntTy) - 1) };
+  enum : UIntTy { MacroIDBit = 1ULL << (Bits - 1) };
 
 public:
   bool isFileID() const  { return (ID & MacroIDBit) == 0; }
@@ -160,6 +160,24 @@ class SourceLocation {
     return X;
   }
 
+  static SourceLocation getFromRawEncoding32(const SourceManager &SM,
+                                             uint32_t Encoding32);
+
+  bool getRawEncoding32(uint32_t &Result) const {
+    // A mask that isolates this check to the required range higher of bits.
+    static constexpr uint64_t RangeMask = llvm::maskTrailingOnes<uint64_t>(Bits - 32) << 31;
+
+    // Check if the ID can be safely compressed to a 32-bit integer.
+    // The truncation is only possible if all higher bits of the ID are all identical:
+    //   all 0s for the local offset, or all 1s for loaded offset
+    if ((ID ^ (ID << 1)) & RangeMask)
+      return false; // won't fit
+    uint32_t Lower31Bits = ID & llvm::maskTrailingOnes<uint32_t>(31);
+    // Restore the top macro bit.
+    Result = Lower31Bits | ((ID & MacroIDBit) >> (Bits - 32));
+    return true;
+  }
+
   /// When a SourceLocation itself cannot be used, this returns
   /// an (opaque) pointer encoding for it.
   ///
@@ -210,6 +228,7 @@ inline bool operator<=(const SourceLocation &LHS, const SourceLocation &RHS) {
 inline bool operator>=(const SourceLocation &LHS, const SourceLocation &RHS) {
   return LHS.getRawEncoding() >= RHS.getRawEncoding();
 }
+using FileIDAndOffset = std::pair<FileID, SourceLocation::UIntTy>;
 
 /// A trivial tuple used to represent a source range.
 class SourceRange {
diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h
index eefd4885534c8..21a1eaaee1e3b 100644
--- a/clang/include/clang/Basic/SourceManager.h
+++ b/clang/include/clang/Basic/SourceManager.h
@@ -745,7 +745,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
   /// The highest possible offset is 2^31-1 (2^63-1 for 64-bit source
   /// locations), so CurrentLoadedOffset starts at 2^31 (2^63 resp.).
   static const SourceLocation::UIntTy MaxLoadedOffset =
-      1ULL << (8 * sizeof(SourceLocation::UIntTy) - 1);
+      1ULL << (SourceLocation::Bits - 1);
 
   /// A bitmap that indicates whether the entries of LoadedSLocEntryTable
   /// have already been loaded from the external source.
@@ -1255,7 +1255,8 @@ class SourceManager : public RefCountedBase<SourceManager> {
   SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const;
 
   /// Form a SourceLocation from a FileID and Offset pair.
-  SourceLocation getComposedLoc(FileID FID, unsigned Offset) const {
+  SourceLocation getComposedLoc(FileID FID,
+                                SourceLocation::UIntTy Offset) const {
     auto *Entry = getSLocEntryOrNull(FID);
     if (!Entry)
       return SourceLocation();
@@ -1287,7 +1288,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
     if (!E)
       return std::make_pair(FileID(), 0);
 
-    unsigned Offset = Loc.getOffset()-E->getOffset();
+    auto Offset = Loc.getOffset()-E->getOffset();
     if (Loc.isFileID())
       return std::make_pair(FID, Offset);
 
@@ -1304,7 +1305,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
     if (!E)
       return std::make_pair(FileID(), 0);
 
-    unsigned Offset = Loc.getOffset()-E->getOffset();
+    auto Offset = Loc.getOffset()-E->getOffset();
     if (Loc.isFileID())
       return std::make_pair(FID, Offset);
     return getDecomposedSpellingLocSlowCase(E, Offset);
@@ -1318,7 +1319,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
   /// specified SourceLocation represents.
   ///
   /// This is not very meaningful for a macro ID.
-  unsigned getFileOffset(SourceLocation SpellingLoc) const {
+  SourceLocation::UIntTy getFileOffset(SourceLocation SpellingLoc) const {
     return getDecomposedLoc(SpellingLoc).second;
   }
 
diff --git a/clang/include/clang/Rewrite/Core/Rewriter.h b/clang/include/clang/Rewrite/Core/Rewriter.h
index 4e96f6fcca919..02f9f2a60240b 100644
--- a/clang/include/clang/Rewrite/Core/Rewriter.h
+++ b/clang/include/clang/Rewrite/Core/Rewriter.h
@@ -216,7 +216,8 @@ class Rewriter {
   bool overwriteChangedFiles();
 
 private:
-  unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const;
+  SourceLocation::UIntTy getLocationOffsetAndFileID(SourceLocation Loc,
+                                                    FileID &FID) const;
 };
 
 } // namespace clang
diff --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h
index 7c66c26a17a13..449166881d207 100644
--- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -72,7 +72,7 @@ class MultiplexExternalSemaSource : public ExternalSemaSource {
   void CompleteRedeclChain(const Decl *D) override;
 
   /// Resolve a selector ID into a selector.
-  Selector GetExternalSelector(uint32_t ID) override;
+  Selector GetExternalSelector(uint64_t ID) override;
 
   /// Returns the number of selectors known to the external AST
   /// source.
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 9d265f27b8e31..ed92a9319742f 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -164,7 +164,7 @@ using LocalMacroID = uint32_t;
 const unsigned int NUM_PREDEF_MACRO_IDS = 1;
 
 /// An ID number that refers to an ObjC selector in an AST file.
-using SelectorID = uint32_t;
+using SelectorID = uint64_t;
 
 /// The number of predefined selector IDs.
 const unsigned int NUM_PREDEF_SELECTOR_IDS = 1;
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index 7d4b4467eb97d..43b4576093cf4 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -525,7 +525,7 @@ class ASTReader
   ContinuousRangeMap<unsigned, ModuleFile*, 64> GlobalSLocEntryMap;
 
   using GlobalSLocOffsetMapType =
-      ContinuousRangeMap<unsigned, ModuleFile *, 64>;
+      ContinuousRangeMap<SourceLocation::UIntTy, ModuleFile *, 64>;
 
   /// A map of reversed (SourceManager::MaxLoadedOffset - SLocOffset)
   /// SourceLocation offsets to the modules containing them.
diff --git a/clang/include/clang/Serialization/SourceLocationEncoding.h b/clang/include/clang/Serialization/SourceLocationEncoding.h
index 5b2485dbc719f..e18e1e2d042fd 100644
--- a/clang/include/clang/Serialization/SourceLocationEncoding.h
+++ b/clang/include/clang/Serialization/SourceLocationEncoding.h
@@ -46,10 +46,12 @@ class SourceLocationEncoding {
   constexpr static unsigned UIntBits = CHAR_BIT * sizeof(UIntTy);
 
   static UIntTy encodeRaw(UIntTy Raw) {
-    return (Raw << 1) | (Raw >> (UIntBits - 1));
+    return ((Raw & llvm::maskTrailingOnes<uint64_t>(SourceLocation::Bits - 1))
+            << 1) |
+           (Raw >> (SourceLocation::Bits - 1));
   }
   static UIntTy decodeRaw(UIntTy Raw) {
-    return (Raw >> 1) | (Raw << (UIntBits - 1));
+    return (Raw >> 1) | ((Raw & 1) << (SourceLocation::Bits - 1));
   }
 
 public:
@@ -79,18 +81,18 @@ SourceLocationEncoding::encode(SourceLocation Loc, UIntTy BaseOffset,
 
   // 16 bits should be sufficient to store the module file index.
   assert(BaseModuleFileIndex < (1 << 16));
-  Encoded |= (RawLocEncoding)BaseModuleFileIndex << 32;
+  Encoded |= (RawLocEncoding)BaseModuleFileIndex << (SourceLocation::Bits + 1);
   return Encoded;
 }
 inline std::pair<SourceLocation, unsigned>
 SourceLocationEncoding::decode(RawLocEncoding Encoded) {
-  unsigned ModuleFileIndex = Encoded >> 32;
+  unsigned ModuleFileIndex = Encoded >> (SourceLocation::Bits + 1);
 
   if (!ModuleFileIndex)
     return {SourceLocation::getFromRawEncoding(decodeRaw(Encoded)),
             ModuleFileIndex};
 
-  Encoded &= llvm::maskTrailingOnes<RawLocEncoding>(32);
+  Encoded &= llvm::maskTrailingOnes<RawLocEncoding>((SourceLocation::Bits + 1));
   SourceLocation Loc = SourceLocation::getFromRawEncoding(decodeRaw(Encoded));
 
   return {Loc, ModuleFileIndex};
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 149b274f36b63..3258ac2195aab 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -441,7 +441,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D,
   DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false;
   DeclRefExprBits.NonOdrUseReason = NOUR;
   DeclRefExprBits.IsImmediateEscalating = false;
-  DeclRefExprBits.Loc = L;
+  Loc = L;
   setDependence(computeDependence(this, Ctx));
 }
 
@@ -454,7 +454,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
                          QualType T, ExprValueKind VK, NonOdrUseReason NOUR)
     : Expr(DeclRefExprClass, T, VK, OK_Ordinary), D(D),
       DNLoc(NameInfo.getInfo()) {
-  DeclRefExprBits.Loc = NameInfo.getLoc();
+  Loc = NameInfo.getLoc();
   DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0;
   if (QualifierLoc)
     new (getTrailingObjects<NestedNameSpecifierLoc>())
@@ -618,7 +618,7 @@ PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy,
   bool HasFunctionName = SL != nullptr;
   PredefinedExprBits.HasFunctionName = HasFunctionName;
   PredefinedExprBits.IsTransparent = IsTransparent;
-  PredefinedExprBits.Loc = L;
+  Loc = L;
   if (HasFunctionName)
     setFunctionName(SL);
   setDependence(computeDependence(this));
@@ -1466,15 +1466,15 @@ static unsigned SizeOfCallExprInstance(Expr::StmtClass SC) {
 
 // changing the size of SourceLocation, CallExpr, and
 // subclasses requires careful considerations
-static_assert(sizeof(SourceLocation) == 4 && sizeof(CXXOperatorCallExpr) <= 32,
-              "we assume CXXOperatorCallExpr is at most 32 bytes");
+static_assert(sizeof(SourceLocation) == 8 && sizeof(CXXOperatorCallExpr) <= 40,
+              "we assume CXXOperatorCallExpr is at most 40 bytes");
 
 CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
                    ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
                    SourceLocation RParenLoc, FPOptionsOverride FPFeatures,
                    unsigned MinNumArgs, ADLCallKind UsesADL)
     : Expr(SC, Ty, VK, OK_Ordinary), RParenLoc(RParenLoc) {
-  NumArgs = std::max<unsigned>(Args.size(), MinNumArgs);
+  CallExprBits.NumArgs = std::max<unsigned>(Args.size(), MinNumArgs);
   unsigned NumPreArgs = PreArgs.size();
   CallExprBits.NumPreArgs = NumPreArgs;
   assert((NumPreArgs == getNumPreArgs()) && "NumPreArgs overflow!");
@@ -1488,7 +1488,7 @@ CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
     setPreArg(I, PreArgs[I]);
   for (unsigned I = 0; I != Args.size(); ++I)
     setArg(I, Args[I]);
-  for (unsigned I = Args.size(); I != NumArgs; ++I)
+  for (unsigned I = Args.size(); I != CallExprBits.NumArgs; ++I)
     setArg(I, nullptr);
 
   this->computeDependence();
@@ -1504,7 +1504,8 @@ CallExpr::CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
 
 CallExpr::CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs,
                    bool HasFPFeatures, EmptyShell Empty)
-    : Expr(SC, Empty), NumArgs(NumArgs) {
+    : Expr(SC, Empty) {
+  CallExprBits.NumArgs = NumArgs;
   CallExprBits.NumPreArgs = NumPreArgs;
   assert((NumPreArgs == getNumPreArgs()) && "NumPreArgs overflow!");
   CallExprBits.HasFPFeatures = HasFPFeatures;
@@ -1727,7 +1728,7 @@ MemberExpr::MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc,
       TemplateArgs || TemplateKWLoc.isValid();
   MemberExprBits.HadMultipleCandidates = false;
   MemberExprBits.NonOdrUseReason = NOUR;
-  MemberExprBits.OperatorLoc = OperatorLoc;
+  this->OperatorLoc = OperatorLoc;
 
   if (hasQualifier())
     new (getTrailingObjects<NestedNameSpecifierLoc>())
@@ -4420,7 +4421,7 @@ GenericSelectionExpr::GenericSelectionExpr(
          " and TypeSourceInfo!");
   assert(ResultIndex < NumAssocs && "ResultIndex is out-of-bounds!");
 
-  GenericSelectionExprBits.GenericLoc = GenericLoc;
+  this->GenericLoc = GenericLoc;
   getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()] =
       ControllingExpr;
   llvm::copy(AssocExprs,
@@ -4447,7 +4448,7 @@ GenericSelectionExpr::GenericSelectionExpr(
          " and TypeSourceInfo!");
   assert(ResultIndex < NumAssocs && "ResultIndex is out-of-bounds!");
 
-  GenericSelectionExprBits.GenericLoc = GenericLoc;
+  this->GenericLoc = GenericLoc;
   getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()] =
       ControllingType;
   llvm::copy(AssocExprs,
@@ -4471,7 +4472,7 @@ GenericSelectionExpr::GenericSelectionExpr(
          "Must have the same number of association expressions"
          " and TypeSourceInfo!");
 
-  GenericSelectionExprBits.GenericLoc = GenericLoc;
+  this->GenericLoc = GenericLoc;
   getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()] =
       ControllingExpr;
   llvm::copy(AssocExprs,
@@ -4495,7 +4496,7 @@ GenericSelectionExpr::GenericSelectionExpr(
          "Must have the same number of association expressions"
          " and TypeSourceInfo!");
 
-  GenericSelectionExprBits.GenericLoc = GenericLoc;
+  this->GenericLoc = GenericLoc;
   getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()] =
       ControllingType;
   llvm::copy(AssocExprs,
@@ -4850,7 +4851,7 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
   BinaryOperatorBits.Opc = opc;
   assert(!isCompoundAssignmentOp() &&
          "Use CompoundAssignOperator for compound assignments");
-  BinaryOperatorBits.OpLoc = opLoc;
+  this->OpLoc = opLoc;
   BinaryOperatorBits.ExcludedOverflowPattern = false;
   SubExprs[LHS] = lhs;
   SubExprs[RHS] = rhs;
@@ -4870,7 +4871,7 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
   BinaryOperatorBits.ExcludedOverflowPattern = false;
   assert(isCompoundAssignmentOp() &&
          "Use CompoundAssignOperator for compound assignments");
-  BinaryOperatorBits.OpLoc = opLoc;
+  this->OpLoc = opLoc;
   SubExprs[LHS] = lhs;
   SubExprs[RHS] = rhs;
   BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
@@ -4937,7 +4938,7 @@ UnaryOperator::UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc,
     : Expr(UnaryOperatorClass, type, VK, OK), Val(input) {
   UnaryOperatorBits.Opc = opc;
   UnaryOperatorBits.CanOverflow = CanOverflow;
-  UnaryOperatorBits.Loc = l;
+  this->Loc = l;
   UnaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
   if (hasStoredFPFeatures())
     setStoredFPFeatures(FPFeatures);
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 063eb1738a046..d65746c185c4f 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1060,7 +1060,7 @@ CXXDefaultInitExpr::CXXDefaultInitExpr(const ASTContext &Ctx,
                                          : VK_PRValue,
            /*FIXME*/ OK_Ordinary),
       Field(Field), UsedContext(UsedContext) {
-  CXXDefaultInitExprBits.Loc = Loc;
+  this->Loc = Loc;
   CXXDefaultInitExprBits.HasRewrittenInit = RewrittenInitExpr != nullptr;
 
   if (CXXDefaultInitExprBits.HasRewrittenInit)
@@ -1204,7 +1204,7 @@ CXXConstructExpr::CXXConstructExpr(
   CXXConstructExprBits.ZeroInitialization = ZeroInitialization;
   CXXConstructExprBits.ConstructionKind = llvm::to_underlying(ConstructKind);
   CXXConstructExprBits.IsImmediateEscalating = false;
-  CXXConstructExprBits.Loc = Loc;
+  this->Loc = Loc;
 
   Stmt **TrailingArgs = getTrailingArgs();
   llvm::copy(Args, TrailingArgs);
@@ -1508,7 +1508,7 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
       (TemplateArgs != nullptr) || TemplateKWLoc.isValid();
   CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope =
       FirstQualifierFoundInScope != nullptr;
-  CXXDependentScopeMemberExprBits.OperatorLoc = OperatorLoc;
+  this->OperatorLoc = OperatorLoc;
 
   if (TemplateArgs) {
     auto Deps = TemplateArgumentDependence::None;
diff --git a/clang/lib/AST/ExprConcepts.cpp b/clang/lib/AST/ExprConcepts.cpp
index a2cf431a312af..4dce391116729 100644
--- a/clang/lib/AST/ExprConcepts.cpp
+++ b/clang/lib/AST/ExprConcepts.cpp
@@ -123,7 +123,7 @@ RequiresExpr::RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
       NumRequirements(Requirements.size()), Body(Body), LParenLoc(LParenLoc),
       RParenLoc(RParenLoc), RBraceLoc(RBraceLoc) {
   RequiresExprBits.IsSatisfied = false;
-  RequiresExprBits.RequiresKWLoc = RequiresKWLoc;
+  this->RequiresKWLoc = RequiresKWLoc;
   bool Dependent = false;
   bool ContainsUnexpandedParameterPack = false;
   for (ParmVarDecl *P : LocalParameters) {
diff --git a/clang/lib/AST/ExternalASTSource.cpp b/clang/lib/AST/ExternalASTSource.cpp
index e8c1004089713..9f714f8a8d455 100644
--- a/clang/lib/AST/ExternalASTSource.cpp
+++ b/clang/lib/AST/ExternalASTSource.cpp
@@ -72,7 +72,7 @@ bool ExternalASTSource::layoutRecordType(
 
 Decl *ExternalASTSource::GetExternalDecl(GlobalDeclID ID) { return nullptr; }
 
-Selector ExternalASTSource::GetExternalSelector(uint32_t ID) {
+Selector ExternalASTSource::GetExternalSelector(uint64_t ID) {
   return Selector();
 }
 
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index 4fc4a99ad2405..e0bfcb93313cc 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -1072,7 +1072,7 @@ ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
   SubExprs[COND] = Cond;
   SubExprs[INC] = Inc;
   SubExprs[BODY] = Body;
-  ForStmtBits.ForLoc = FL;
+  ForLoc = FL;
 }
 
 VarDecl *ForStmt::getConditionVariable() const {
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
index ab0525e96f3ba..9e176c1bc7b1d 100644
--- a/clang/lib/Basic/Diagnostic.cpp
+++ b/clang/lib/Basic/Diagnostic.cpp
@@ -205,7 +205,7 @@ DiagnosticsEngine::DiagStateMap::lookup(SourceManager &SrcMgr,
 }
 
 DiagnosticsEngine::DiagState *
-DiagnosticsEngine::DiagStateMap::File::lookup(unsigned Offset) const {
+DiagnosticsEngine::DiagStateMap::File::lookup(SourceLocation::UIntTy Offset) const {
   auto OnePastIt =
       llvm::partition_point(StateTransitions, [=](const DiagStatePoint &P) {
         return P.Offset <= Offset;
diff --git a/clang/lib/Basic/SourceLocation.cpp b/clang/lib/Basic/SourceLocation.cpp
index 3e26f75d25b10..2a4e9f3e70681 100644
--- a/clang/lib/Basic/SourceLocation.cpp
+++ b/clang/lib/Basic/SourceLocation.cpp
@@ -17,6 +17,8 @@
 #include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cassert>
 #include <string>
@@ -48,6 +50,27 @@ static_assert(std::is_trivially_destructible_v<SourceRange>,
               "SourceRange must be trivially destructible because it is "
               "used in unions");
 
+SourceLocation SourceLocation::getFromRawEncoding32(const SourceManager &SM,
+                                                    uint32_t Encoding32) {
+  uint32_t Lower31Bits = Encoding32 & llvm::maskTrailingOnes<uint32_t>(31);
+  uint64_t MacroBit =
+      (static_cast<uint64_t>(Encoding32) & llvm::maskLeadingOnes<uint32_t>(1))
+      << (Bits - 32);
+
+  if (Lower31Bits < SM.getNextLocalOffset()) {
+    // This is local offset, 32-to-64 offset mapping is identical.
+    UIntTy Raw64 = Lower31Bits | MacroBit;
+    return getFromRawEncoding(Raw64);
+  }
+  // Offset of loaded source location.
+  //   2^63 -> 2^31
+  //   2^63 - 1 -> 2^31 - 1
+  static constexpr uint64_t RangeMask =
+      llvm::maskTrailingOnes<uint64_t>(Bits - 32) << 31;
+  UIntTy Raw64 = (RangeMask + Lower31Bits) | MacroBit;
+  return getFromRawEncoding(Raw64);
+}
+
 unsigned SourceLocation::getHashValue() const {
   return llvm::DenseMapInfo<UIntTy>::getHashValue(ID);
 }
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index a05d6c16caa32..defba0a351498 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -938,7 +938,7 @@ FileIDAndOffset SourceManager::getDecomposedExpansionLocSlowCase(
   // If this is an expansion record, walk through all the expansion points.
   FileID FID;
   SourceLocation Loc;
-  unsigned Offset;
+  SourceLocation::UIntTy Offset;
   do {
     Loc = E->getExpansion().getExpansionLocStart();
 
@@ -952,7 +952,7 @@ FileIDAndOffset SourceManager::getDecomposedExpansionLocSlowCase(
 
 FileIDAndOffset
 SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
-                                                unsigned Offset) const {
+                                                SourceLocation::UIntTy Offset) const {
   // If this is an expansion record, walk through all the expansion points.
   FileID FID;
   SourceLocation Loc;
@@ -1887,9 +1887,7 @@ SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const {
   if (Loc.isInvalid() || !Loc.isFileID())
     return Loc;
 
-  FileID FID;
-  unsigned Offset;
-  std::tie(FID, Offset) = getDecomposedLoc(Loc);
+  auto [FID, Offset] = getDecomposedLoc(Loc);
   if (FID.isInvalid())
     return Loc;
 
diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp
index 06f68ec8b0fc1..9b0dda81f02a8 100644
--- a/clang/lib/Format/FormatTokenLexer.cpp
+++ b/clang/lib/Format/FormatTokenLexer.cpp
@@ -1243,7 +1243,8 @@ FormatToken *FormatTokenLexer::getNextToken() {
   FormatTok = new (Allocator.Allocate()) FormatToken;
   readRawToken(*FormatTok);
   SourceLocation WhitespaceStart =
-      FormatTok->Tok.getLocation().getLocWithOffset(-TrailingWhitespace);
+      FormatTok->Tok.getLocation().getLocWithOffset(
+          -static_cast<SourceLocation::UIntTy>(TrailingWhitespace));
   FormatTok->IsFirst = IsFirstToken;
   IsFirstToken = false;
 
diff --git a/clang/lib/Parse/ParseStmtAsm.cpp b/clang/lib/Parse/ParseStmtAsm.cpp
index c679aa6fe7b27..9c1e497867a6e 100644
--- a/clang/lib/Parse/ParseStmtAsm.cpp
+++ b/clang/lib/Parse/ParseStmtAsm.cpp
@@ -183,7 +183,8 @@ ClangAsmParserCallback::translateLocation(const llvm::SourceMgr &LSM,
   if (TokIndex < AsmToks.size()) {
     const Token &Tok = AsmToks[TokIndex];
     Loc = Tok.getLocation();
-    Loc = Loc.getLocWithOffset(Offset - TokOffset);
+    Loc = Loc.getLocWithOffset(static_cast<SourceLocation::UIntTy>(Offset) -
+                               TokOffset);
   }
   return Loc;
 }
diff --git a/clang/lib/Rewrite/Rewriter.cpp b/clang/lib/Rewrite/Rewriter.cpp
index ae21a10f81c35..e4dca072bad70 100644
--- a/clang/lib/Rewrite/Rewriter.cpp
+++ b/clang/lib/Rewrite/Rewriter.cpp
@@ -130,7 +130,7 @@ std::string Rewriter::getRewrittenText(CharSourceRange Range) const {
   return std::string(Start, End);
 }
 
-unsigned Rewriter::getLocationOffsetAndFileID(SourceLocation Loc,
+SourceLocation::UIntTy Rewriter::getLocationOffsetAndFileID(SourceLocation Loc,
                                               FileID &FID) const {
   assert(Loc.isValid() && "Invalid location");
   FileIDAndOffset V = SourceMgr->getDecomposedLoc(Loc);
diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp
index 9f19f13592e86..fa7cb3ec07b76 100644
--- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp
+++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp
@@ -58,7 +58,7 @@ void MultiplexExternalSemaSource::CompleteRedeclChain(const Decl *D) {
     Sources[i]->CompleteRedeclChain(D);
 }
 
-Selector MultiplexExternalSemaSource::GetExternalSelector(uint32_t ID) {
+Selector MultiplexExternalSemaSource::GetExternalSelector(uint64_t ID) {
   Selector Sel;
   for(size_t i = 0; i < Sources.size(); ++i) {
     Sel = Sources[i]->GetExternalSelector(ID);
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 486971818f109..04c0a0e28fe7c 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -6967,7 +6967,7 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
       auto &F = Diag.DiagStatesByLoc.Files[FID];
       F.StateTransitions.reserve(F.StateTransitions.size() + Transitions);
       for (unsigned I = 0; I != Transitions; ++I) {
-        unsigned Offset = Record[Idx++];
+        SourceLocation::UIntTy Offset = Record[Idx++];
         auto *State = ReadDiagState(*FirstState, false);
         F.StateTransitions.push_back({State, Offset});
       }
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 8945407cf666e..089391eaeb9e2 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -209,7 +209,7 @@ void ASTStmtReader::VisitAttributedStmt(AttributedStmt *S) {
   assert(NumAttrs == Attrs.size());
   std::copy(Attrs.begin(), Attrs.end(), S->getAttrArrayPtr());
   S->SubStmt = Record.readSubStmt();
-  S->AttributedStmtBits.AttrLoc = readSourceLocation();
+  S->AttrLoc = readSourceLocation();
 }
 
 void ASTStmtReader::VisitIfStmt(IfStmt *S) {
@@ -843,7 +843,7 @@ void ASTStmtReader::VisitRequiresExpr(RequiresExpr *E) {
   VisitExpr(E);
   unsigned NumLocalParameters = Record.readInt();
   unsigned NumRequirements = Record.readInt();
-  E->RequiresExprBits.RequiresKWLoc = Record.readSourceLocation();
+  E->RequiresKWLoc = Record.readSourceLocation();
   E->RequiresExprBits.IsSatisfied = Record.readInt();
   E->Body = Record.readDeclAs<RequiresExprBodyDecl>();
   llvm::SmallVector<ParmVarDecl *, 4> LocalParameters;
@@ -1071,7 +1071,7 @@ void ASTStmtReader::VisitMemberExpr(MemberExpr *E) {
   E->MemberExprBits.HadMultipleCandidates = CurrentUnpackingBits->getNextBit();
   E->MemberExprBits.NonOdrUseReason =
       CurrentUnpackingBits->getNextBits(/*Width=*/2);
-  E->MemberExprBits.OperatorLoc = Record.readSourceLocation();
+  E->OperatorLoc = Record.readSourceLocation();
 
   if (HasQualifier)
     new (E->getTrailingObjects<NestedNameSpecifierLoc>())
@@ -1410,7 +1410,7 @@ void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
   assert(NumAssocs == E->getNumAssocs() && "Wrong NumAssocs!");
   E->IsExprPredicate = Record.readInt();
   E->ResultIndex = Record.readInt();
-  E->GenericSelectionExprBits.GenericLoc = readSourceLocation();
+  E->GenericLoc = readSourceLocation();
   E->DefaultLoc = readSourceLocation();
   E->RParenLoc = readSourceLocation();
 
@@ -1756,7 +1756,7 @@ void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
   E->CXXConstructExprBits.ZeroInitialization = Record.readInt();
   E->CXXConstructExprBits.ConstructionKind = Record.readInt();
   E->CXXConstructExprBits.IsImmediateEscalating = Record.readInt();
-  E->CXXConstructExprBits.Loc = readSourceLocation();
+  E->Loc = readSourceLocation();
   E->Constructor = readDeclAs<CXXConstructorDecl>();
   E->ParenOrBraceRange = readSourceRange();
 
@@ -1880,7 +1880,7 @@ void ASTStmtReader::VisitCXXThisExpr(CXXThisExpr *E) {
 
 void ASTStmtReader::VisitCXXThrowExpr(CXXThrowExpr *E) {
   VisitExpr(E);
-  E->CXXThrowExprBits.ThrowLoc = readSourceLocation();
+  E->ThrowLoc = readSourceLocation();
   E->Operand = Record.readSubExpr();
   E->CXXThrowExprBits.IsThrownVariableInScope = Record.readInt();
 }
@@ -1889,7 +1889,7 @@ void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   VisitExpr(E);
   E->Param = readDeclAs<ParmVarDecl>();
   E->UsedContext = readDeclAs<DeclContext>();
-  E->CXXDefaultArgExprBits.Loc = readSourceLocation();
+  E->Loc = readSourceLocation();
   E->CXXDefaultArgExprBits.HasRewrittenInit = Record.readInt();
   if (E->CXXDefaultArgExprBits.HasRewrittenInit)
     *E->getTrailingObjects() = Record.readSubExpr();
@@ -1900,7 +1900,7 @@ void ASTStmtReader::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
   E->CXXDefaultInitExprBits.HasRewrittenInit = Record.readInt();
   E->Field = readDeclAs<FieldDecl>();
   E->UsedContext = readDeclAs<DeclContext>();
-  E->CXXDefaultInitExprBits.Loc = readSourceLocation();
+  E->Loc = readSourceLocation();
   if (E->CXXDefaultInitExprBits.HasRewrittenInit)
     *E->getTrailingObjects() = Record.readSubExpr();
 }
@@ -1914,7 +1914,7 @@ void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
 void ASTStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
   VisitExpr(E);
   E->TypeInfo = readTypeSourceInfo();
-  E->CXXScalarValueInitExprBits.RParenLoc = readSourceLocation();
+  E->RParenLoc = readSourceLocation();
 }
 
 void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
@@ -1964,7 +1964,7 @@ void ASTStmtReader::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
   E->CXXDeleteExprBits.UsualArrayDeleteWantsSize = Record.readInt();
   E->OperatorDelete = readDeclAs<FunctionDecl>();
   E->Argument = Record.readSubExpr();
-  E->CXXDeleteExprBits.Loc = readSourceLocation();
+  E->Loc = readSourceLocation();
 }
 
 void ASTStmtReader::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
@@ -2040,7 +2040,7 @@ void ASTStmtReader::VisitCXXDependentScopeMemberExpr(
   else
     E->Base = nullptr;
 
-  E->CXXDependentScopeMemberExprBits.OperatorLoc = readSourceLocation();
+  E->OperatorLoc = readSourceLocation();
 
   if (HasFirstQualifierFoundInScope)
     *E->getTrailingObjects<NamedDecl *>() = readDeclAs<NamedDecl>();
@@ -2227,7 +2227,7 @@ void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
   E->Index = CurrentUnpackingBits->getNextBits(/*Width=*/12);
   E->PackIndex = Record.readUnsignedOrNone().toInternalRepresentation();
   E->Final = CurrentUnpackingBits->getNextBit();
-  E->SubstNonTypeTemplateParmExprBits.NameLoc = readSourceLocation();
+  E->NameLoc = readSourceLocation();
   E->Replacement = Record.readSubExpr();
 }
 
@@ -2305,7 +2305,7 @@ void ASTStmtReader::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
 void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
   VisitExpr(E);
   E->SourceExpr = Record.readSubExpr();
-  E->OpaqueValueExprBits.Loc = readSourceLocation();
+  E->Loc = readSourceLocation();
   E->setIsUnique(Record.readInt());
 }
 
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 06cd6c7305114..874b24b532b06 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -6652,7 +6652,7 @@ void ASTWriter::AddFileID(FileID FID, RecordDataImpl &Record) {
 
 SourceLocationEncoding::RawLocEncoding
 ASTWriter::getRawSourceLocationEncoding(SourceLocation Loc) {
-  unsigned BaseOffset = 0;
+  SourceLocation::UIntTy BaseOffset = 0;
   unsigned ModuleFileIndex = 0;
 
   // See SourceLocationEncoding.h for the encoding details.
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 2e390dbe79ec6..6d3af86230c5b 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1022,7 +1022,7 @@ void ASTDeclWriter::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
 }
 
 void ASTDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
-  static_assert(DeclContext::NumObjCContainerDeclBits == 64,
+  static_assert(DeclContext::NumObjCContainerDeclBits == 13,
                 "You need to update the serializer after you change the "
                 "ObjCContainerDeclBits");
 
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 87536be8c8d98..edbd4f6c7fc41 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -514,7 +514,7 @@ void ASTStmtWriter::VisitRequiresExpr(RequiresExpr *E) {
   VisitExpr(E);
   Record.push_back(E->getLocalParameters().size());
   Record.push_back(E->getRequirements().size());
-  Record.AddSourceLocation(E->RequiresExprBits.RequiresKWLoc);
+  Record.AddSourceLocation(E->RequiresKWLoc);
   Record.push_back(E->RequiresExprBits.IsSatisfied);
   Record.AddDeclRef(E->getBody());
   for (ParmVarDecl *P : E->getLocalParameters())
diff --git a/clang/test/Lexer/SourceLocationsOverflow.c b/clang/test/Lexer/SourceLocationsOverflow.c
deleted file mode 100644
index 26b0d204c49ff..0000000000000
--- a/clang/test/Lexer/SourceLocationsOverflow.c
+++ /dev/null
@@ -1,38 +0,0 @@
-// RUN: not %clang %s -S -o - 2>&1 | FileCheck %s
-// CHECK: In file included from {{.*}}SourceLocationsOverflow.c
-// CHECK-NEXT: inc1.h{{.*}}: fatal error: translation unit is too large for Clang to process: ran out of source locations
-// CHECK-NEXT: #include "inc2.h"
-// CHECK-NEXT:          ^
-// CHECK-NEXT: note: 214{{.......}}B (2.15GB) in local locations, 0B (0B) in locations loaded from AST files, for a total of 214{{.......}}B (2.15GB) (99% of available space)
-// CHECK-NEXT: {{.*}}inc2.h:1:1: note: file entered 214{{..}} times using 214{{.......}}B (2.15GB) of space
-// CHECK-NEXT: /*.................................................................................................
-// CHECK-NEXT: ^
-// CHECK-NEXT: {{.*}}inc1.h:1:1: note: file entered 15 times using 39{{....}}B (396.92kB) of space
-// CHECK-NEXT: #include "inc2.h"
-// CHECK-NEXT: ^
-// CHECK-NEXT: <built-in>:1:1: note: file entered {{.*}} times using {{.*}}B ({{.*}}B) of space
-// CHECK-NEXT: # {{.*}}
-// CHECK-NEXT: ^
-// CHECK-NEXT: {{.*}}SourceLocationsOverflow.c:1:1: note: file entered 1 time using {{.*}}B ({{.*}}B) of space
-// CHECK-NEXT: // RUN: not %clang %s -S -o - 2>&1 | FileCheck %s
-// CHECK-NEXT: ^
-// CHECK-NEXT: 1 error generated.
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
-#include "Inputs/inc1.h"
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 9089984fa4a54..01b5b8fb31ad6 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -166,16 +166,22 @@ CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
         Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc), SM, LangOpts);
     EndLoc = EndLoc.getLocWithOffset(Length);
   }
-
-  CXSourceRange Result = {
-      {&SM, &LangOpts}, R.getBegin().getRawEncoding(), EndLoc.getRawEncoding()};
+  unsigned BeginRaw, EndRaw;
+  if (!R.getBegin().getRawEncoding32(BeginRaw) ||
+      !EndLoc.getRawEncoding32(EndRaw))
+    return clang_getNullRange(); // location is too big for libclang ABI
+  CXSourceRange Result = {{&SM, &LangOpts}, BeginRaw, EndRaw};
   return Result;
 }
 
 CharSourceRange cxloc::translateCXRangeToCharRange(CXSourceRange R) {
+   if (!R.ptr_data[0])
+     return CharSourceRange();
+   const SourceManager &SM =
+      *static_cast<const SourceManager *>(R.ptr_data[0]);
   return CharSourceRange::getCharRange(
-      SourceLocation::getFromRawEncoding(R.begin_int_data),
-      SourceLocation::getFromRawEncoding(R.end_int_data));
+      SourceLocation::getFromRawEncoding32(SM, R.begin_int_data),
+      SourceLocation::getFromRawEncoding32(SM, R.end_int_data));
 }
 
 //===----------------------------------------------------------------------===//
@@ -270,10 +276,15 @@ bool CursorVisitor::visitFileRegion() {
   ASTUnit *Unit = cxtu::getASTUnit(TU);
   SourceManager &SM = Unit->getSourceManager();
 
+<<<<<<< HEAD
   FileIDAndOffset Begin = SM.getDecomposedLoc(
                       SM.getFileLoc(RegionOfInterest.getBegin())),
                   End = SM.getDecomposedLoc(
                       SM.getFileLoc(RegionOfInterest.getEnd()));
+=======
+  auto Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
+       End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
+>>>>>>> 795e9705ad62 (64-bit source location)
 
   if (End.first != Begin.first) {
     // If the end does not reside in the same file, try to recover by
@@ -2122,7 +2133,9 @@ class MemberRefVisit : public VisitorJob {
     return static_cast<const FieldDecl *>(data[0]);
   }
   SourceLocation getLoc() const {
-    return SourceLocation::getFromRawEncoding(
+    // this->get()->getASTContext().getSourceManager();
+    return SourceLocation::getFromRawEncoding32(
+        this->get()->getASTContext().getSourceManager(),
         (SourceLocation::UIntTy)(uintptr_t)data[1]);
   }
 };
@@ -7635,8 +7648,13 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
   if (!CXXUnit)
     return cxstring::createEmpty();
 
+<<<<<<< HEAD
   SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
   FileIDAndOffset LocInfo =
+=======
+  SourceLocation Loc = SourceLocation::getFromRawEncoding32(CXXUnit->getSourceManager(), CXTok.int_data[1]);
+  auto LocInfo =
+>>>>>>> 795e9705ad62 (64-bit source location)
       CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
   bool Invalid = false;
   StringRef Buffer =
@@ -7659,7 +7677,7 @@ CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
 
   return cxloc::translateSourceLocation(
       CXXUnit->getASTContext(),
-      SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
+      SourceLocation::getFromRawEncoding32(CXXUnit->getSourceManager(), CXTok.int_data[1]));
 }
 
 CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
@@ -7674,26 +7692,32 @@ CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
 
   return cxloc::translateSourceRange(
       CXXUnit->getASTContext(),
-      SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
+      SourceLocation::getFromRawEncoding32(CXXUnit->getSourceManager(), CXTok.int_data[1]));
 }
 
-static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
+static bool getTokens(ASTUnit *CXXUnit, SourceRange Range,
                       SmallVectorImpl<CXToken> &CXTokens) {
   SourceManager &SourceMgr = CXXUnit->getSourceManager();
+<<<<<<< HEAD
   FileIDAndOffset BeginLocInfo =
       SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
   FileIDAndOffset EndLocInfo =
+=======
+  auto BeginLocInfo =
+      SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
+  auto EndLocInfo =
+>>>>>>> 795e9705ad62 (64-bit source location)
       SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
 
   // Cannot tokenize across files.
   if (BeginLocInfo.first != EndLocInfo.first)
-    return;
+    return false;
 
   // Create a lexer
   bool Invalid = false;
   StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
   if (Invalid)
-    return;
+    return false;
 
   Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
             CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
@@ -7714,7 +7738,12 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
     CXToken CXTok;
 
     //   - Common fields
-    CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
+    // CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
+    uint32_t TokLocRaw;
+    if (!Tok.getLocation().getRawEncoding32(TokLocRaw))
+      return false; // location is too big for libclang ABI
+    CXTok.int_data[1] = TokLocRaw;
+    
     CXTok.int_data[2] = Tok.getLength();
     CXTok.int_data[3] = 0;
 
@@ -7743,6 +7772,8 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
     CXTokens.push_back(CXTok);
     previousWasAt = Tok.is(tok::at);
   } while (Lex.getBufferLocation() < EffectiveBufferEnd);
+
+  return true;
 }
 
 CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
@@ -7761,7 +7792,11 @@ CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
   if (Begin.isInvalid())
     return nullptr;
   SourceManager &SM = CXXUnit->getSourceManager();
+<<<<<<< HEAD
   FileIDAndOffset DecomposedEnd = SM.getDecomposedLoc(Begin);
+=======
+  auto DecomposedEnd = SM.getDecomposedLoc(Begin);
+>>>>>>> 795e9705ad62 (64-bit source location)
   DecomposedEnd.second +=
       Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
 
@@ -7769,7 +7804,8 @@ CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
       SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
 
   SmallVector<CXToken, 32> CXTokens;
-  getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
+  if (!getTokens(CXXUnit, SourceRange(Begin, End), CXTokens))
+    return nullptr;
 
   if (CXTokens.empty())
     return nullptr;
@@ -7806,7 +7842,8 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
     return;
 
   SmallVector<CXToken, 32> CXTokens;
-  getTokens(CXXUnit, R, CXTokens);
+  if (!getTokens(CXXUnit, R, CXTokens))
+    return;
 
   if (CXTokens.empty())
     return;
@@ -7870,13 +7907,15 @@ class AnnotateTokensWorker {
   unsigned NextToken() const { return TokIdx; }
   void AdvanceToken() { ++TokIdx; }
   SourceLocation GetTokenLoc(unsigned tokI) {
-    return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
+    return SourceLocation::getFromRawEncoding32(SrcMgr,
+                                                getTok(tokI).int_data[1]);
   }
   bool isFunctionMacroToken(unsigned tokI) const {
     return getTok(tokI).int_data[3] != 0;
   }
   SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
-    return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
+    return SourceLocation::getFromRawEncoding32(SrcMgr,
+                                                getTok(tokI).int_data[3]);
   }
 
   void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
@@ -8371,13 +8410,16 @@ class MarkMacroArgTokensVisitor {
   }
 
   SourceLocation getTokenLoc(unsigned tokI) {
-    return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
+    return SourceLocation::getFromRawEncoding32(SM, getTok(tokI).int_data[1]);
   }
 
   void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
     // The third field is reserved and currently not used. Use it here
     // to mark macro arg expanded tokens with their expanded locations.
-    getTok(tokI).int_data[3] = loc.getRawEncoding();
+    uint32_t Raw;
+    if (!loc.getRawEncoding32(Raw))
+      Raw = 0; // invalid source location
+    getTok(tokI).int_data[3] = Raw;
   }
 };
 
@@ -8410,9 +8452,15 @@ static void annotatePreprocessorTokens(CXTranslationUnit TU,
 
   Preprocessor &PP = CXXUnit->getPreprocessor();
   SourceManager &SourceMgr = CXXUnit->getSourceManager();
+<<<<<<< HEAD
   FileIDAndOffset BeginLocInfo =
       SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
   FileIDAndOffset EndLocInfo =
+=======
+  auto BeginLocInfo =
+      SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
+  auto EndLocInfo =
+>>>>>>> 795e9705ad62 (64-bit source location)
       SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
 
   if (BeginLocInfo.first != EndLocInfo.first)
@@ -8437,8 +8485,8 @@ static void annotatePreprocessorTokens(CXTranslationUnit TU,
     if (lexNext(Lex, Tok, NextIdx, NumTokens))
       break;
     unsigned TokIdx = NextIdx - 1;
-    assert(Tok.getLocation() ==
-           SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
+    assert(Tok.getLocation() == SourceLocation::getFromRawEncoding32(
+                                    SourceMgr, Tokens[TokIdx].int_data[1]));
 
   reprocess:
     if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
@@ -8488,8 +8536,8 @@ static void annotatePreprocessorTokens(CXTranslationUnit TU,
 
       unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
       assert(TokIdx <= LastIdx);
-      SourceLocation EndLoc =
-          SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
+      SourceLocation EndLoc = SourceLocation::getFromRawEncoding32(
+          SourceMgr, Tokens[LastIdx].int_data[1]);
       CXCursor Cursor =
           MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
 
diff --git a/clang/tools/libclang/CXIndexDataConsumer.cpp b/clang/tools/libclang/CXIndexDataConsumer.cpp
index f0d92e8c40124..938dd85737a35 100644
--- a/clang/tools/libclang/CXIndexDataConsumer.cpp
+++ b/clang/tools/libclang/CXIndexDataConsumer.cpp
@@ -988,8 +988,8 @@ bool CXIndexDataConsumer::handleCXXRecordDecl(const CXXRecordDecl *RD,
         const CXIdxBaseClassInfo *baseInfo = BaseList.getBases()[i];
         if (baseInfo->base) {
           const NamedDecl *BaseD = BaseList.BaseEntities[i].Dcl;
-          SourceLocation
-            Loc = SourceLocation::getFromRawEncoding(baseInfo->loc.int_data);
+          SourceLocation Loc = SourceLocation::getFromRawEncoding32(
+              Ctx->getSourceManager(), baseInfo->loc.int_data);
           markEntityOccurrenceInFile(BaseD, Loc);
         }
       }
@@ -1077,9 +1077,11 @@ CXIdxLoc CXIndexDataConsumer::getIndexLoc(SourceLocation Loc) const {
   CXIdxLoc idxLoc =  { {nullptr, nullptr}, 0 };
   if (Loc.isInvalid())
     return idxLoc;
-
+  uint32_t LocRaw;
+  if (!Loc.getRawEncoding32(LocRaw))
+    return idxLoc;
   idxLoc.ptr_data[0] = const_cast<CXIndexDataConsumer *>(this);
-  idxLoc.int_data = Loc.getRawEncoding();
+  idxLoc.int_data = LocRaw;
   return idxLoc;
 }
 
diff --git a/clang/tools/libclang/CXSourceLocation.cpp b/clang/tools/libclang/CXSourceLocation.cpp
index 4c16e5de4498a..6ea42f795310f 100644
--- a/clang/tools/libclang/CXSourceLocation.cpp
+++ b/clang/tools/libclang/CXSourceLocation.cpp
@@ -211,24 +211,27 @@ static void createNullLocation(CXString *filename, unsigned *line,
 }
 
 int clang_Location_isInSystemHeader(CXSourceLocation location) {
+  if (!location.ptr_data[0])
+    return 0;
+  const SourceManager &SM =
+      *static_cast<const SourceManager *>(location.ptr_data[0]);
   const SourceLocation Loc =
-    SourceLocation::getFromRawEncoding(location.int_data);
+    SourceLocation::getFromRawEncoding32(SM, location.int_data);
   if (Loc.isInvalid())
     return 0;
 
-  const SourceManager &SM =
-    *static_cast<const SourceManager*>(location.ptr_data[0]);
   return SM.isInSystemHeader(Loc);
 }
 
 int clang_Location_isFromMainFile(CXSourceLocation location) {
+  if (!location.ptr_data[0])
+    return 0;
+  const SourceManager &SM =
+      *static_cast<const SourceManager *>(location.ptr_data[0]);
   const SourceLocation Loc =
-    SourceLocation::getFromRawEncoding(location.int_data);
+      SourceLocation::getFromRawEncoding32(SM, location.int_data);
   if (Loc.isInvalid())
     return 0;
-
-  const SourceManager &SM =
-    *static_cast<const SourceManager*>(location.ptr_data[0]);
   return SM.isWrittenInMainFile(Loc);
 }
 
@@ -241,16 +244,21 @@ void clang_getExpansionLocation(CXSourceLocation location,
     CXLoadedDiagnostic::decodeLocation(location, file, line, column, offset);
     return;
   }
+  if (!location.ptr_data[0]) {
+    createNullLocation(file, line, column, offset);
+    return;
+  }
 
-  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
+  const SourceManager &SM =
+      *static_cast<const SourceManager *>(location.ptr_data[0]);
+  SourceLocation Loc =
+      SourceLocation::getFromRawEncoding32(SM, location.int_data);
 
-  if (!location.ptr_data[0] || Loc.isInvalid()) {
+  if (Loc.isInvalid()) {
     createNullLocation(file, line, column, offset);
     return;
   }
 
-  const SourceManager &SM =
-  *static_cast<const SourceManager*>(location.ptr_data[0]);
   SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
   
   // Check that the FileID is invalid on the expansion location.
@@ -283,16 +291,21 @@ void clang_getPresumedLocation(CXSourceLocation location,
     createNullLocation(filename, line, column);
     return;
   }
-
-  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
-
-  if (!location.ptr_data[0] || Loc.isInvalid()) {
+  if (!location.ptr_data[0]) {
     createNullLocation(filename, line, column);
     return;
   }
 
   const SourceManager &SM =
       *static_cast<const SourceManager *>(location.ptr_data[0]);
+  SourceLocation Loc =
+      SourceLocation::getFromRawEncoding32(SM, location.int_data);
+
+  if (Loc.isInvalid()) {
+    createNullLocation(filename, line, column);
+    return;
+  }
+
   PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
   if (PreLoc.isInvalid()) {
     createNullLocation(filename, line, column);
@@ -323,14 +336,16 @@ void clang_getSpellingLocation(CXSourceLocation location,
                                            column, offset);
     return;
   }
-  
-  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
-  
-  if (!location.ptr_data[0] || Loc.isInvalid())
+  if (!location.ptr_data[0])
     return createNullLocation(file, line, column, offset);
-  
   const SourceManager &SM =
-  *static_cast<const SourceManager*>(location.ptr_data[0]);
+      *static_cast<const SourceManager *>(location.ptr_data[0]);
+  SourceLocation Loc =
+      SourceLocation::getFromRawEncoding32(SM, location.int_data);
+
+  if (Loc.isInvalid())
+    return createNullLocation(file, line, column, offset);
+
   SourceLocation SpellLoc = SM.getSpellingLoc(Loc);
   FileIDAndOffset LocInfo = SM.getDecomposedLoc(SpellLoc);
   FileID FID = LocInfo.first;
@@ -360,13 +375,17 @@ void clang_getFileLocation(CXSourceLocation location,
     return;
   }
 
-  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
-
-  if (!location.ptr_data[0] || Loc.isInvalid())
+  if (!location.ptr_data[0])
     return createNullLocation(file, line, column, offset);
 
   const SourceManager &SM =
-  *static_cast<const SourceManager*>(location.ptr_data[0]);
+      *static_cast<const SourceManager *>(location.ptr_data[0]);
+  SourceLocation Loc =
+      SourceLocation::getFromRawEncoding32(SM, location.int_data);
+
+  if (Loc.isInvalid())
+    return createNullLocation(file, line, column, offset);
+
   SourceLocation FileLoc = SM.getFileLoc(Loc);
   FileIDAndOffset LocInfo = SM.getDecomposedLoc(FileLoc);
   FileID FID = LocInfo.first;
diff --git a/clang/tools/libclang/CXSourceLocation.h b/clang/tools/libclang/CXSourceLocation.h
index c86f6850375bb..bc36db3571b63 100644
--- a/clang/tools/libclang/CXSourceLocation.h
+++ b/clang/tools/libclang/CXSourceLocation.h
@@ -30,9 +30,15 @@ translateSourceLocation(const SourceManager &SM, const LangOptions &LangOpts,
                         SourceLocation Loc) {
   if (Loc.isInvalid())
     return clang_getNullLocation();
+  uint32_t LocRaw;
+  if (!Loc.getRawEncoding32(LocRaw))
+    return clang_getNullLocation(); // location is too big for libclang ABI
 
-  CXSourceLocation Result = { { &SM, &LangOpts, },
-                              Loc.getRawEncoding() };
+  CXSourceLocation Result = {{
+                                 &SM,
+                                 &LangOpts,
+                             },
+                             LocRaw};
   return Result;
 }
   
@@ -63,12 +69,21 @@ static inline CXSourceRange translateSourceRange(ASTContext &Context,
 }
 
 static inline SourceLocation translateSourceLocation(CXSourceLocation L) {
-  return SourceLocation::getFromRawEncoding(L.int_data);
+   if (!L.ptr_data[0]) {
+    return SourceLocation();
+  }
+  const SourceManager &SM =
+      *static_cast<const SourceManager *>(L.ptr_data[0]);
+  return SourceLocation::getFromRawEncoding32(SM, L.int_data);
 }
 
 static inline SourceRange translateCXSourceRange(CXSourceRange R) {
-  return SourceRange(SourceLocation::getFromRawEncoding(R.begin_int_data),
-                     SourceLocation::getFromRawEncoding(R.end_int_data));
+  if (!R.ptr_data[0]) {
+    return SourceRange();
+  }
+  const SourceManager &SM = *static_cast<const SourceManager *>(R.ptr_data[0]);
+  return SourceRange(SourceLocation::getFromRawEncoding32(SM, R.begin_int_data),
+                     SourceLocation::getFromRawEncoding32(SM, R.end_int_data));
 }
 
 /// Translates CXSourceRange to CharSourceRange.
diff --git a/clang/tools/libclang/Indexing.cpp b/clang/tools/libclang/Indexing.cpp
index 3cd49bf90235b..da3f3f973a675 100644
--- a/clang/tools/libclang/Indexing.cpp
+++ b/clang/tools/libclang/Indexing.cpp
@@ -979,23 +979,30 @@ void clang_indexLoc_getFileLocation(CXIdxLoc location,
   if (file)   *file = nullptr;
   if (line)   *line = 0;
   if (column) *column = 0;
-  if (offset) *offset = 0;
-
-  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
-  if (!location.ptr_data[0] || Loc.isInvalid())
+  if (offset)
+    *offset = 0;
+  if (!location.ptr_data[0])
     return;
-
   CXIndexDataConsumer &DataConsumer =
-      *static_cast<CXIndexDataConsumer*>(location.ptr_data[0]);
+      *static_cast<CXIndexDataConsumer *>(location.ptr_data[0]);
+  SourceLocation Loc = SourceLocation::getFromRawEncoding32(
+      DataConsumer.getASTContext().getSourceManager(), location.int_data);
+  if (Loc.isInvalid())
+    return;
+
   DataConsumer.translateLoc(Loc, indexFile, file, line, column, offset);
 }
 
 CXSourceLocation clang_indexLoc_getCXSourceLocation(CXIdxLoc location) {
-  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
-  if (!location.ptr_data[0] || Loc.isInvalid())
-    return clang_getNullLocation();
+  if (!location.ptr_data[0])
+  return clang_getNullLocation();
 
   CXIndexDataConsumer &DataConsumer =
-      *static_cast<CXIndexDataConsumer*>(location.ptr_data[0]);
+      *static_cast<CXIndexDataConsumer *>(location.ptr_data[0]);
+  const auto &SM = DataConsumer.getASTContext().getSourceManager();
+  SourceLocation Loc =
+      SourceLocation::getFromRawEncoding32(SM, location.int_data);
+  if (Loc.isInvalid())
+    return clang_getNullLocation();
   return cxloc::translateSourceLocation(DataConsumer.getASTContext(), Loc);
 }
diff --git a/clang/unittests/Lex/PPMemoryAllocationsTest.cpp b/clang/unittests/Lex/PPMemoryAllocationsTest.cpp
index 4d83003e28b36..7b36d5f3326e9 100644
--- a/clang/unittests/Lex/PPMemoryAllocationsTest.cpp
+++ b/clang/unittests/Lex/PPMemoryAllocationsTest.cpp
@@ -87,7 +87,7 @@ TEST_F(PPMemoryAllocationsTest, PPMacroDefinesAllocations) {
   // Assume a reasonable upper bound based on that number that we don't want
   // to exceed when storing information about a macro #define with 1 or 3
   // tokens.
-  EXPECT_LT(BytesPerDefine, 130.0f);
+  EXPECT_LT(BytesPerDefine, 150.0f);
 }
 
 } // anonymous namespace
diff --git a/clang/unittests/Serialization/SourceLocationEncodingTest.cpp b/clang/unittests/Serialization/SourceLocationEncodingTest.cpp
index 18fedd4de3973..63aec9a94981b 100644
--- a/clang/unittests/Serialization/SourceLocationEncodingTest.cpp
+++ b/clang/unittests/Serialization/SourceLocationEncodingTest.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Serialization/SourceLocationEncoding.h"
+#include "llvm/Support/MathExtras.h"
 
 #include "gtest/gtest.h"
 #include <climits>
@@ -31,11 +32,13 @@ void roundTrip(SourceLocation::UIntTy Loc,
   SourceLocation::UIntTy DecodedEncoded =
       SourceLocationEncoding::decode(ActualEncoded).first.getRawEncoding();
   ASSERT_EQ(DecodedEncoded, Loc) << "Decoding " << ActualEncoded;
-}
+} 
 
 constexpr SourceLocation::UIntTy MacroBit =
-    1 << (sizeof(SourceLocation::UIntTy) * CHAR_BIT - 1);
-constexpr SourceLocation::UIntTy Big = MacroBit >> 1;
+    1ull << (SourceLocation::Bits - 1);
+constexpr SourceLocation::UIntTy Big = 1ull << (SourceLocation::Bits - 2);
+constexpr SourceLocation::UIntTy Biggest =
+    llvm::maskTrailingOnes<uint64_t>(SourceLocation::Bits - 1);
 
 TEST(SourceLocationEncoding, Individual) {
   roundTrip(1, 2);
@@ -46,6 +49,8 @@ TEST(SourceLocationEncoding, Individual) {
   roundTrip(Big + 1);
   roundTrip(MacroBit | Big);
   roundTrip(MacroBit | (Big + 1));
+  roundTrip(Biggest);
+  roundTrip(MacroBit | Biggest);
 }
 
 } // namespace

>From 5a2700eb2902e4a8e19bc2a6bd39f6b71b34f5eb Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Wed, 25 Jun 2025 08:40:49 +0200
Subject: [PATCH 02/20] Test Bits=64 perf

---
 clang/include/clang/Basic/SourceLocation.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/SourceLocation.h b/clang/include/clang/Basic/SourceLocation.h
index 91352a4aa0ab6..5be7b2f261b1e 100644
--- a/clang/include/clang/Basic/SourceLocation.h
+++ b/clang/include/clang/Basic/SourceLocation.h
@@ -96,7 +96,7 @@ class SourceLocation {
 public:
   using UIntTy = uint64_t;
   using IntTy = int64_t;
-  static constexpr unsigned Bits = 40;
+  static constexpr unsigned Bits = 64;
 
 private:
   uint64_t ID = 0;

>From 755e67144d97faef5fe20b1d67a768ace6313ce5 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Wed, 25 Jun 2025 09:22:12 +0200
Subject: [PATCH 03/20] Switch Bits back to 40.

---
 clang/include/clang/Basic/SourceLocation.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/SourceLocation.h b/clang/include/clang/Basic/SourceLocation.h
index 5be7b2f261b1e..91352a4aa0ab6 100644
--- a/clang/include/clang/Basic/SourceLocation.h
+++ b/clang/include/clang/Basic/SourceLocation.h
@@ -96,7 +96,7 @@ class SourceLocation {
 public:
   using UIntTy = uint64_t;
   using IntTy = int64_t;
-  static constexpr unsigned Bits = 64;
+  static constexpr unsigned Bits = 40;
 
 private:
   uint64_t ID = 0;

>From 68ffab3a717aea3829dfae8110e78e1c897d8f49 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Wed, 25 Jun 2025 10:09:12 +0200
Subject: [PATCH 04/20] Reduce SubstNonTypeTemplateParmExpr size: 48 -> 40
 bytes

---
 clang/include/clang/AST/ExprCXX.h         | 6 ++----
 clang/include/clang/AST/Stmt.h            | 7 ++++---
 clang/lib/Serialization/ASTReaderStmt.cpp | 2 +-
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 2e2f4dd175d0c..5deccb8e47630 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -4618,8 +4618,6 @@ class PackIndexingExpr final
 class SubstNonTypeTemplateParmExpr : public Expr {
   friend class ASTReader;
   friend class ASTStmtReader;
-      /// The location of the non-type template parameter reference.
-      SourceLocation NameLoc;
 
   /// The replacement expression.
   Stmt *Replacement;
@@ -4648,12 +4646,12 @@ class SubstNonTypeTemplateParmExpr : public Expr {
         AssociatedDeclAndRef(AssociatedDecl, RefParam), Index(Index),
         PackIndex(PackIndex.toInternalRepresentation()), Final(Final) {
     assert(AssociatedDecl != nullptr);
-    NameLoc = Loc;
+    SubstNonTypeTemplateParmExprBits.NameLoc = Loc.getRawEncoding();
     setDependence(computeDependence(this));
   }
 
   SourceLocation getNameLoc() const {
-    return NameLoc;
+    return SourceLocation::getFromRawEncoding(SubstNonTypeTemplateParmExprBits.NameLoc);
   }
   SourceLocation getBeginLoc() const { return getNameLoc(); }
   SourceLocation getEndLoc() const { return getNameLoc(); }
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 83c1f646c6701..bdf92d57e0c25 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -1130,11 +1130,12 @@ class alignas(void *) Stmt {
   class SubstNonTypeTemplateParmExprBitfields {
     friend class ASTStmtReader;
     friend class SubstNonTypeTemplateParmExpr;
-
+    
     LLVM_PREFERRED_TYPE(ExprBitfields)
     unsigned : NumExprBits;
-
-
+    /// The location of the non-type template parameter reference.
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long NameLoc : SourceLocation::Bits;
   };
 
   class LambdaExprBitfields {
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 089391eaeb9e2..85b8165e9f9c3 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2227,7 +2227,7 @@ void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
   E->Index = CurrentUnpackingBits->getNextBits(/*Width=*/12);
   E->PackIndex = Record.readUnsignedOrNone().toInternalRepresentation();
   E->Final = CurrentUnpackingBits->getNextBit();
-  E->NameLoc = readSourceLocation();
+  E->SubstNonTypeTemplateParmExprBits.NameLoc = readSourceLocation().getRawEncoding();
   E->Replacement = Record.readSubExpr();
 }
 

>From b1f620593bb71878468b739de1547c0aea65acda Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Wed, 25 Jun 2025 10:34:08 +0200
Subject: [PATCH 05/20] Reduce OpaqueValueExpr: 32 -> 24 bytes

---
 clang/include/clang/AST/Expr.h            | 6 ++----
 clang/include/clang/AST/Stmt.h            | 5 ++++-
 clang/lib/Serialization/ASTReaderStmt.cpp | 2 +-
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 0955b54163de3..994274d9eea0b 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -1175,8 +1175,6 @@ class ConstantExpr final
 /// context.
 class OpaqueValueExpr : public Expr {
   friend class ASTStmtReader;
-
-  SourceLocation Loc;
   Expr *SourceExpr;
 
 public:
@@ -1184,7 +1182,7 @@ class OpaqueValueExpr : public Expr {
                   ExprObjectKind OK = OK_Ordinary, Expr *SourceExpr = nullptr)
       : Expr(OpaqueValueExprClass, T, VK, OK), SourceExpr(SourceExpr) {
     setIsUnique(false);
-    this->Loc = Loc;
+    OpaqueValueExprBits.Loc = Loc.getRawEncoding();
     setDependence(computeDependence(this));
   }
 
@@ -1197,7 +1195,7 @@ class OpaqueValueExpr : public Expr {
     : Expr(OpaqueValueExprClass, Empty) {}
 
   /// Retrieve the location of this expression.
-  SourceLocation getLocation() const { return Loc; }
+  SourceLocation getLocation() const { return SourceLocation::getFromRawEncoding(OpaqueValueExprBits.Loc); }
 
   SourceLocation getBeginLoc() const LLVM_READONLY {
     return SourceExpr ? SourceExpr->getBeginLoc() : getLocation();
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index bdf92d57e0c25..a935f7f64f931 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -1264,7 +1264,10 @@ class alignas(void *) Stmt {
     /// bit is set to true.
     LLVM_PREFERRED_TYPE(bool)
     unsigned IsUnique : 1;
-
+    
+     /// The location of the non-type template parameter reference.
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long Loc : SourceLocation::Bits;
   };
 
   class ConvertVectorExprBitfields {
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 85b8165e9f9c3..bfb798c1604d8 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2305,7 +2305,7 @@ void ASTStmtReader::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
 void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
   VisitExpr(E);
   E->SourceExpr = Record.readSubExpr();
-  E->Loc = readSourceLocation();
+  E->OpaqueValueExprBits.Loc = readSourceLocation().getRawEncoding();
   E->setIsUnique(Record.readInt());
 }
 

>From 86f0440fb3b463d6d2d4f9dfb07ce30b916c6432 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Wed, 25 Jun 2025 10:51:43 +0200
Subject: [PATCH 06/20] Reduce CXXDependentScopeMemberExpr size: 88 -> 80 bytes

---
 clang/include/clang/AST/ExprCXX.h         | 5 +----
 clang/include/clang/AST/Stmt.h            | 6 ++++--
 clang/lib/AST/ExprCXX.cpp                 | 2 +-
 clang/lib/Serialization/ASTReaderStmt.cpp | 2 +-
 4 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 5deccb8e47630..9da74234658c8 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -3842,9 +3842,6 @@ class CXXDependentScopeMemberExpr final
   /// FIXME: could also be a template-id
   DeclarationNameInfo MemberNameInfo;
 
-      /// The location of the '->' or '.' operator.
-      SourceLocation OperatorLoc;
-
   // CXXDependentScopeMemberExpr is followed by several trailing objects,
   // some of which optional. They are in order:
   //
@@ -3924,7 +3921,7 @@ class CXXDependentScopeMemberExpr final
 
   /// Retrieve the location of the '->' or '.' operator.
   SourceLocation getOperatorLoc() const {
-    return OperatorLoc;
+    return SourceLocation::getFromRawEncoding(CXXDependentScopeMemberExprBits.OperatorLoc);
   }
 
   /// Retrieve the nested-name-specifier that qualifies the member name.
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index a935f7f64f931..e3d5bac743848 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -1054,8 +1054,10 @@ class alignas(void *) Stmt {
     /// the trailing objects.
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasFirstQualifierFoundInScope : 1;
-
-
+    
+    /// The location of the '->' or '.' operator.
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long OperatorLoc : SourceLocation::Bits;
   };
 
   class OverloadExprBitfields {
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index d65746c185c4f..f503b33d84047 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1508,7 +1508,7 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
       (TemplateArgs != nullptr) || TemplateKWLoc.isValid();
   CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope =
       FirstQualifierFoundInScope != nullptr;
-  this->OperatorLoc = OperatorLoc;
+  CXXDependentScopeMemberExprBits.OperatorLoc = OperatorLoc.getRawEncoding();
 
   if (TemplateArgs) {
     auto Deps = TemplateArgumentDependence::None;
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index bfb798c1604d8..e85ec09fd95f5 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2040,7 +2040,7 @@ void ASTStmtReader::VisitCXXDependentScopeMemberExpr(
   else
     E->Base = nullptr;
 
-  E->OperatorLoc = readSourceLocation();
+  E->CXXDependentScopeMemberExprBits.OperatorLoc = readSourceLocation().getRawEncoding();
 
   if (HasFirstQualifierFoundInScope)
     *E->getTrailingObjects<NamedDecl *>() = readDeclAs<NamedDecl>();

>From 9dbf694a433ab09830e0fff8c4de69e7bdfce020 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Thu, 26 Jun 2025 13:30:33 +0200
Subject: [PATCH 07/20] Reduce DeclRefExpr size: 48 -> 40 bytes.

by moving out the two source locations for CXXOpName from DeclarationNameLoc
---
 clang/include/clang/AST/ASTContext.h      |  2 +
 clang/include/clang/AST/DeclarationName.h | 52 +++++++++++------------
 clang/lib/AST/ASTContext.cpp              | 12 +++++-
 clang/lib/AST/ASTImporter.cpp             |  3 +-
 clang/lib/AST/DeclarationName.cpp         |  2 +-
 clang/lib/Sema/SemaDecl.cpp               | 13 +++---
 clang/lib/Sema/SemaLambda.cpp             |  3 +-
 clang/lib/Sema/SemaOverload.cpp           | 13 ++++--
 clang/lib/Serialization/ASTReader.cpp     |  3 +-
 9 files changed, 63 insertions(+), 40 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 2b9cd035623cc..8ae212cc6cc94 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -3356,6 +3356,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
   getTrivialTypeSourceInfo(QualType T,
                            SourceLocation Loc = SourceLocation()) const;
 
+  CXXOperatorSourceInfo *getCXXOperatorSourceInfo(SourceRange R) const;
+
   /// Add a deallocation callback that will be invoked when the
   /// ASTContext is destroyed.
   ///
diff --git a/clang/include/clang/AST/DeclarationName.h b/clang/include/clang/AST/DeclarationName.h
index 9bf740b3bf7ce..10a0ce368b532 100644
--- a/clang/include/clang/AST/DeclarationName.h
+++ b/clang/include/clang/AST/DeclarationName.h
@@ -682,6 +682,11 @@ class DeclarationNameTable {
   DeclarationName getCXXLiteralOperatorName(const IdentifierInfo *II);
 };
 
+struct CXXOperatorSourceInfo {
+  SourceLocation::UIntTy BeginOpNameLoc;
+  SourceLocation::UIntTy EndOpNameLoc;
+};
+
 /// DeclarationNameLoc - Additional source/type location info
 /// for a declaration name. Needs a DeclarationName in order
 /// to be interpreted correctly.
@@ -698,8 +703,7 @@ class DeclarationNameLoc {
 
   // The location (if any) of the operator keyword is stored elsewhere.
   struct CXXOpName {
-    SourceLocation::UIntTy BeginOpNameLoc;
-    SourceLocation::UIntTy EndOpNameLoc;
+    CXXOperatorSourceInfo* OInfo;
   };
 
   // The location (if any) of the operator keyword is stored elsewhere.
@@ -719,11 +723,6 @@ class DeclarationNameLoc {
 
   void setNamedTypeLoc(TypeSourceInfo *TInfo) { NamedType.TInfo = TInfo; }
 
-  void setCXXOperatorNameRange(SourceRange Range) {
-    CXXOperatorName.BeginOpNameLoc = Range.getBegin().getRawEncoding();
-    CXXOperatorName.EndOpNameLoc = Range.getEnd().getRawEncoding();
-  }
-
   void setCXXLiteralOperatorNameLoc(SourceLocation Loc) {
     CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
   }
@@ -739,12 +738,18 @@ class DeclarationNameLoc {
 
   /// Return the beginning location of the getCXXOperatorNameRange() range.
   SourceLocation getCXXOperatorNameBeginLoc() const {
-    return SourceLocation::getFromRawEncoding(CXXOperatorName.BeginOpNameLoc);
+    if (!CXXOperatorName.OInfo)
+      return {};
+    return SourceLocation::getFromRawEncoding(
+        CXXOperatorName.OInfo->BeginOpNameLoc);
   }
 
   /// Return the end location of the getCXXOperatorNameRange() range.
   SourceLocation getCXXOperatorNameEndLoc() const {
-    return SourceLocation::getFromRawEncoding(CXXOperatorName.EndOpNameLoc);
+    if (!CXXOperatorName.OInfo)
+      return {};
+    return SourceLocation::getFromRawEncoding(
+        CXXOperatorName.OInfo->EndOpNameLoc);
   }
 
   /// Return the range of the operator name (without the operator keyword).
@@ -769,17 +774,12 @@ class DeclarationNameLoc {
     DNL.setNamedTypeLoc(TInfo);
     return DNL;
   }
-
-  /// Construct location information for a non-literal C++ operator.
-  static DeclarationNameLoc makeCXXOperatorNameLoc(SourceLocation BeginLoc,
-                                                   SourceLocation EndLoc) {
-    return makeCXXOperatorNameLoc(SourceRange(BeginLoc, EndLoc));
-  }
-
+  
   /// Construct location information for a non-literal C++ operator.
-  static DeclarationNameLoc makeCXXOperatorNameLoc(SourceRange Range) {
+  static DeclarationNameLoc
+  makeCXXOperatorNameLoc(CXXOperatorSourceInfo *OInfo) {
     DeclarationNameLoc DNL;
-    DNL.setCXXOperatorNameRange(Range);
+    DNL.CXXOperatorName.OInfo = OInfo;
     return DNL;
   }
 
@@ -839,7 +839,7 @@ struct DeclarationNameInfo {
       return nullptr;
     return LocInfo.getNamedTypeInfo();
   }
-
+  
   /// setNamedTypeInfo - Sets the source type info associated to
   /// the name. Assumes it is a constructor, destructor or conversion.
   void setNamedTypeInfo(TypeSourceInfo *TInfo) {
@@ -849,6 +849,13 @@ struct DeclarationNameInfo {
     LocInfo = DeclarationNameLoc::makeNamedTypeLoc(TInfo);
   }
 
+  /// Sets the range of the operator name (without the operator keyword).
+  /// Assumes it is a C++ operator.
+  void setCXXOperatorNameInfo(CXXOperatorSourceInfo *OInfo) {
+    assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
+    LocInfo = DeclarationNameLoc::makeCXXOperatorNameLoc(OInfo);
+  }
+
   /// getCXXOperatorNameRange - Gets the range of the operator name
   /// (without the operator keyword). Assumes it is a (non-literal) operator.
   SourceRange getCXXOperatorNameRange() const {
@@ -857,13 +864,6 @@ struct DeclarationNameInfo {
     return LocInfo.getCXXOperatorNameRange();
   }
 
-  /// setCXXOperatorNameRange - Sets the range of the operator name
-  /// (without the operator keyword). Assumes it is a C++ operator.
-  void setCXXOperatorNameRange(SourceRange R) {
-    assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
-    LocInfo = DeclarationNameLoc::makeCXXOperatorNameLoc(R);
-  }
-
   /// getCXXLiteralOperatorNameLoc - Returns the location of the literal
   /// operator name (not the operator keyword).
   /// Assumes it is a literal operator.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index b13bdd5642977..840469d7cace3 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3200,6 +3200,15 @@ TypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T,
   return DI;
 }
 
+CXXOperatorSourceInfo *
+ASTContext::getCXXOperatorSourceInfo(SourceRange R) const {
+  auto *TInfo = (CXXOperatorSourceInfo *)BumpAlloc.Allocate(
+      sizeof(CXXOperatorSourceInfo), 8);
+  TInfo->BeginOpNameLoc = R.getBegin().getRawEncoding();
+  TInfo->EndOpNameLoc = R.getEnd().getRawEncoding();
+  return TInfo;
+}
+
 const ASTRecordLayout &
 ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const {
   return getObjCLayout(D);
@@ -7095,8 +7104,7 @@ ASTContext::getNameForTemplate(TemplateName Name,
     } else {
       DName = DeclarationNames.getCXXOperatorName(TN.getOperator());
       // DNInfo work in progress: FIXME: source locations?
-      DeclarationNameLoc DNLoc =
-          DeclarationNameLoc::makeCXXOperatorNameLoc(SourceRange());
+      DeclarationNameLoc DNLoc = DeclarationNameLoc::makeCXXOperatorNameLoc(nullptr);
       return DeclarationNameInfo(DName, NameLoc, DNLoc);
     }
   }
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index c4d20554f09ef..a3ca9181aea07 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -2071,7 +2071,8 @@ ASTNodeImporter::ImportDeclarationNameLoc(
 
   case DeclarationName::CXXOperatorName: {
     if (auto ToRangeOrErr = import(From.getCXXOperatorNameRange()))
-      To.setCXXOperatorNameRange(*ToRangeOrErr);
+      To.setCXXOperatorNameInfo(
+          Importer.ToContext.getCXXOperatorSourceInfo(*ToRangeOrErr));
     else
       return ToRangeOrErr.takeError();
     return Error::success();
diff --git a/clang/lib/AST/DeclarationName.cpp b/clang/lib/AST/DeclarationName.cpp
index ae5fcf6e86adf..430fa9372b3cf 100644
--- a/clang/lib/AST/DeclarationName.cpp
+++ b/clang/lib/AST/DeclarationName.cpp
@@ -387,7 +387,7 @@ DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
     setNamedTypeLoc(nullptr);
     break;
   case DeclarationName::CXXOperatorName:
-    setCXXOperatorNameRange(SourceRange());
+    CXXOperatorName.OInfo = nullptr;
     break;
   case DeclarationName::CXXLiteralOperatorName:
     setCXXLiteralOperatorNameLoc(SourceLocation());
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a60a558155e69..cbb4f85f6e697 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5914,11 +5914,14 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
   }
 
   case UnqualifiedIdKind::IK_OperatorFunctionId:
-    NameInfo.setName(Context.DeclarationNames.getCXXOperatorName(
-                                           Name.OperatorFunctionId.Operator));
-    NameInfo.setCXXOperatorNameRange(SourceRange(
-        Name.OperatorFunctionId.SymbolLocations[0], Name.EndLocation));
-    return NameInfo;
+    return DeclarationNameInfo(
+        Context.DeclarationNames.getCXXOperatorName(
+            Name.OperatorFunctionId.Operator),
+        Name.StartLocation,
+        DeclarationNameLoc::makeCXXOperatorNameLoc(
+            Context.getCXXOperatorSourceInfo(
+                SourceRange(Name.OperatorFunctionId.SymbolLocations[0],
+                            Name.EndLocation))));
 
   case UnqualifiedIdKind::IK_LiteralOperatorId:
     NameInfo.setName(Context.DeclarationNames.getCXXLiteralOperatorName(
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 2c00616bc62d7..e172a099f5893 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1004,7 +1004,8 @@ CXXMethodDecl *Sema::CreateLambdaCallOperator(SourceRange IntroducerRange,
   DeclarationName MethodName =
       Context.DeclarationNames.getCXXOperatorName(OO_Call);
   DeclarationNameLoc MethodNameLoc =
-      DeclarationNameLoc::makeCXXOperatorNameLoc(IntroducerRange.getBegin());
+      DeclarationNameLoc::makeCXXOperatorNameLoc(
+        Context.getCXXOperatorSourceInfo(IntroducerRange.getBegin()));
   CXXMethodDecl *Method = CXXMethodDecl::Create(
       Context, Class, SourceLocation(),
       DeclarationNameInfo(MethodName, IntroducerRange.getBegin(),
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index f5bdd903bcf5c..6e98d2af591c8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -15829,8 +15829,13 @@ ExprResult Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
 
     CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators
     // CHECKME: no 'operator' keyword?
+    // DeclarationNameInfo OpNameInfo(
+    //     OpName, LLoc,
+    //     DeclarationNameLoc::makeCXXOperatorNameLoc(
+    //         Context.getCXXOperatorSourceInfo(SourceRange(LLoc, RLoc))));
     DeclarationNameInfo OpNameInfo(OpName, LLoc);
-    OpNameInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc));
+    OpNameInfo.setCXXOperatorNameInfo(
+        Context.getCXXOperatorSourceInfo(SourceRange(LLoc, RLoc)));
     ExprResult Fn = CreateUnresolvedLookupExpr(
         NamingClass, NestedNameSpecifierLoc(), OpNameInfo, UnresolvedSet<0>());
     if (Fn.isInvalid())
@@ -15902,7 +15907,8 @@ ExprResult Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
 
         // Build the actual expression node.
         DeclarationNameInfo OpLocInfo(OpName, LLoc);
-        OpLocInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc));
+        OpLocInfo.setCXXOperatorNameInfo(
+            Context.getCXXOperatorSourceInfo(SourceRange(LLoc, RLoc)));
         ExprResult FnExpr = CreateFunctionRefExpr(
             *this, FnDecl, Best->FoundDecl, Base, HadMultipleCandidates,
             OpLocInfo.getLoc(), OpLocInfo.getInfo());
@@ -16532,7 +16538,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
 
   DeclarationNameInfo OpLocInfo(
                Context.DeclarationNames.getCXXOperatorName(OO_Call), LParenLoc);
-  OpLocInfo.setCXXOperatorNameRange(SourceRange(LParenLoc, RParenLoc));
+  OpLocInfo.setCXXOperatorNameInfo(
+      Context.getCXXOperatorSourceInfo(SourceRange(LParenLoc, RParenLoc)));
   ExprResult NewFn = CreateFunctionRefExpr(*this, Method, Best->FoundDecl,
                                            Obj, HadMultipleCandidates,
                                            OpLocInfo.getLoc(),
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 04c0a0e28fe7c..f75e7df1a393b 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9792,7 +9792,8 @@ ASTRecordReader::readDeclarationNameLoc(DeclarationName Name) {
     return DeclarationNameLoc::makeNamedTypeLoc(readTypeSourceInfo());
 
   case DeclarationName::CXXOperatorName:
-    return DeclarationNameLoc::makeCXXOperatorNameLoc(readSourceRange());
+    return DeclarationNameLoc::makeCXXOperatorNameLoc(
+      getASTContext().getCXXOperatorSourceInfo(readSourceRange()));
 
   case DeclarationName::CXXLiteralOperatorName:
     return DeclarationNameLoc::makeCXXLiteralOperatorNameLoc(

>From da34ffe59f89bdbe74a9b8023c781f1e83af0275 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Thu, 26 Jun 2025 15:17:25 +0200
Subject: [PATCH 08/20] Fix some merge conflicts.

---
 clang/include/clang/Basic/SourceManager.h |  2 +-
 clang/tools/libclang/CIndex.cpp           | 26 -----------------------
 2 files changed, 1 insertion(+), 27 deletions(-)

diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h
index 21a1eaaee1e3b..68b1c7b469ecf 100644
--- a/clang/include/clang/Basic/SourceManager.h
+++ b/clang/include/clang/Basic/SourceManager.h
@@ -1980,7 +1980,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
   FileIDAndOffset
   getDecomposedExpansionLocSlowCase(const SrcMgr::SLocEntry *E) const;
   FileIDAndOffset getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
-                                                   unsigned Offset) const;
+                                                   SourceLocation::UIntTy Offset) const;
   void computeMacroArgsCache(MacroArgsMap &MacroArgsCache, FileID FID) const;
   void associateFileChunkWithMacroArgExp(MacroArgsMap &MacroArgsCache,
                                          FileID FID,
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 01b5b8fb31ad6..0554e155e9380 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -276,15 +276,10 @@ bool CursorVisitor::visitFileRegion() {
   ASTUnit *Unit = cxtu::getASTUnit(TU);
   SourceManager &SM = Unit->getSourceManager();
 
-<<<<<<< HEAD
   FileIDAndOffset Begin = SM.getDecomposedLoc(
                       SM.getFileLoc(RegionOfInterest.getBegin())),
                   End = SM.getDecomposedLoc(
                       SM.getFileLoc(RegionOfInterest.getEnd()));
-=======
-  auto Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
-       End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
->>>>>>> 795e9705ad62 (64-bit source location)
 
   if (End.first != Begin.first) {
     // If the end does not reside in the same file, try to recover by
@@ -7648,13 +7643,8 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
   if (!CXXUnit)
     return cxstring::createEmpty();
 
-<<<<<<< HEAD
-  SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
-  FileIDAndOffset LocInfo =
-=======
   SourceLocation Loc = SourceLocation::getFromRawEncoding32(CXXUnit->getSourceManager(), CXTok.int_data[1]);
   auto LocInfo =
->>>>>>> 795e9705ad62 (64-bit source location)
       CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
   bool Invalid = false;
   StringRef Buffer =
@@ -7698,15 +7688,9 @@ CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
 static bool getTokens(ASTUnit *CXXUnit, SourceRange Range,
                       SmallVectorImpl<CXToken> &CXTokens) {
   SourceManager &SourceMgr = CXXUnit->getSourceManager();
-<<<<<<< HEAD
   FileIDAndOffset BeginLocInfo =
       SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
   FileIDAndOffset EndLocInfo =
-=======
-  auto BeginLocInfo =
-      SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
-  auto EndLocInfo =
->>>>>>> 795e9705ad62 (64-bit source location)
       SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
 
   // Cannot tokenize across files.
@@ -7792,11 +7776,7 @@ CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
   if (Begin.isInvalid())
     return nullptr;
   SourceManager &SM = CXXUnit->getSourceManager();
-<<<<<<< HEAD
   FileIDAndOffset DecomposedEnd = SM.getDecomposedLoc(Begin);
-=======
-  auto DecomposedEnd = SM.getDecomposedLoc(Begin);
->>>>>>> 795e9705ad62 (64-bit source location)
   DecomposedEnd.second +=
       Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
 
@@ -8452,15 +8432,9 @@ static void annotatePreprocessorTokens(CXTranslationUnit TU,
 
   Preprocessor &PP = CXXUnit->getPreprocessor();
   SourceManager &SourceMgr = CXXUnit->getSourceManager();
-<<<<<<< HEAD
   FileIDAndOffset BeginLocInfo =
       SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
   FileIDAndOffset EndLocInfo =
-=======
-  auto BeginLocInfo =
-      SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
-  auto EndLocInfo =
->>>>>>> 795e9705ad62 (64-bit source location)
       SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
 
   if (BeginLocInfo.first != EndLocInfo.first)

>From 6be8784149b90abf25a7ed33c627d9e991c68aed Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Thu, 26 Jun 2025 16:18:48 +0200
Subject: [PATCH 09/20] Move the Loc back to the StmtBitFields if possible to
 save AST size.

---
 clang/include/clang/AST/Expr.h            |  21 +--
 clang/include/clang/AST/ExprCXX.h         |  76 ++++----
 clang/include/clang/AST/ExprConcepts.h    |   5 +-
 clang/include/clang/AST/Stmt.h            | 214 ++++++++++++++--------
 clang/lib/AST/Expr.cpp                    |   8 +-
 clang/lib/AST/ExprCXX.cpp                 |   2 +-
 clang/lib/AST/ExprConcepts.cpp            |   2 +-
 clang/lib/AST/Stmt.cpp                    |   2 +-
 clang/lib/Serialization/ASTReaderStmt.cpp |  17 +-
 clang/lib/Serialization/ASTWriterStmt.cpp |   2 +-
 10 files changed, 214 insertions(+), 135 deletions(-)

diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 994274d9eea0b..6d1c2df6bdc88 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -2723,7 +2723,6 @@ class UnaryExprOrTypeTraitExpr : public Expr {
 /// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
 class ArraySubscriptExpr : public Expr {
   enum { LHS, RHS, END_EXPR };
-  SourceLocation RBracketLoc;
   Stmt *SubExprs[END_EXPR];
 
   bool lhsIsBase() const { return getRHS()->getType()->isIntegerType(); }
@@ -2734,7 +2733,7 @@ class ArraySubscriptExpr : public Expr {
       : Expr(ArraySubscriptExprClass, t, VK, OK) {
     SubExprs[LHS] = lhs;
     SubExprs[RHS] = rhs;
-    this->RBracketLoc = rbracketloc;
+    ArrayOrMatrixSubscriptExprBits.RBracketLoc = rbracketloc.getRawEncoding();
     setDependence(computeDependence(this));
   }
 
@@ -2771,10 +2770,11 @@ class ArraySubscriptExpr : public Expr {
   SourceLocation getEndLoc() const { return getRBracketLoc(); }
 
   SourceLocation getRBracketLoc() const {
-    return RBracketLoc;
+    return SourceLocation::getFromRawEncoding(
+        ArrayOrMatrixSubscriptExprBits.RBracketLoc);
   }
   void setRBracketLoc(SourceLocation L) {
-    RBracketLoc = L;
+    ArrayOrMatrixSubscriptExprBits.RBracketLoc = L.getRawEncoding();
   }
 
   SourceLocation getExprLoc() const LLVM_READONLY {
@@ -2802,7 +2802,6 @@ class ArraySubscriptExpr : public Expr {
 /// exist during the initial construction of the AST.
 class MatrixSubscriptExpr : public Expr {
   enum { BASE, ROW_IDX, COLUMN_IDX, END_EXPR };
-  SourceLocation RBracketLoc;
   Stmt *SubExprs[END_EXPR];
 
 public:
@@ -2813,7 +2812,7 @@ class MatrixSubscriptExpr : public Expr {
     SubExprs[BASE] = Base;
     SubExprs[ROW_IDX] = RowIdx;
     SubExprs[COLUMN_IDX] = ColumnIdx;
-    this->RBracketLoc = RBracketLoc;
+    ArrayOrMatrixSubscriptExprBits.RBracketLoc = RBracketLoc.getRawEncoding();
     setDependence(computeDependence(this));
   }
 
@@ -2854,10 +2853,11 @@ class MatrixSubscriptExpr : public Expr {
   }
 
   SourceLocation getRBracketLoc() const {
-    return RBracketLoc;
+    return SourceLocation::getFromRawEncoding(
+        ArrayOrMatrixSubscriptExprBits.RBracketLoc);
   }
   void setRBracketLoc(SourceLocation L) {
-    RBracketLoc = L;
+    ArrayOrMatrixSubscriptExprBits.RBracketLoc = L.getRawEncoding();
   }
 
   static bool classof(const Stmt *T) {
@@ -6106,8 +6106,6 @@ class GenericSelectionExpr final
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
   friend TrailingObjects;
-  /// The location of the "_Generic".
-  SourceLocation GenericLoc;
   /// The number of association expressions and the index of the result
   /// expression in the case where the generic selection expression is not
   /// result-dependent. The result index is equal to ResultDependentIndex
@@ -6457,7 +6455,8 @@ class GenericSelectionExpr final
   }
 
   SourceLocation getGenericLoc() const {
-    return GenericLoc;
+    return SourceLocation::getFromRawEncoding(
+        GenericSelectionExprBits.GenericLoc);
   }
   SourceLocation getDefaultLoc() const { return DefaultLoc; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 9da74234658c8..98f40b8a89bf6 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -720,13 +720,11 @@ class UserDefinedLiteral final : public CallExpr {
 
 /// A boolean literal, per ([C++ lex.bool] Boolean literals).
 class CXXBoolLiteralExpr : public Expr {
-  SourceLocation Loc;
-
 public:
   CXXBoolLiteralExpr(bool Val, QualType Ty, SourceLocation Loc)
       : Expr(CXXBoolLiteralExprClass, Ty, VK_PRValue, OK_Ordinary) {
     CXXBoolLiteralExprBits.Value = Val;
-    this->Loc = Loc;
+    CXXBoolLiteralExprBits.Loc = Loc.getRawEncoding();
     setDependence(ExprDependence::None);
   }
 
@@ -744,8 +742,12 @@ class CXXBoolLiteralExpr : public Expr {
   SourceLocation getBeginLoc() const { return getLocation(); }
   SourceLocation getEndLoc() const { return getLocation(); }
 
-  SourceLocation getLocation() const { return Loc; }
-  void setLocation(SourceLocation L) { Loc = L; }
+  SourceLocation getLocation() const {
+    return SourceLocation::getFromRawEncoding(CXXBoolLiteralExprBits.Loc);
+  }
+  void setLocation(SourceLocation L) {
+    CXXBoolLiteralExprBits.Loc = L.getRawEncoding();
+  }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXBoolLiteralExprClass;
@@ -767,11 +769,10 @@ class CXXBoolLiteralExpr : public Expr {
 /// This also implements the null pointer literal in C23 (C23 6.4.1) which is
 /// intended to have the same semantics as the feature in C++.
 class CXXNullPtrLiteralExpr : public Expr {
-  SourceLocation Loc;
 public:
   CXXNullPtrLiteralExpr(QualType Ty, SourceLocation Loc)
       : Expr(CXXNullPtrLiteralExprClass, Ty, VK_PRValue, OK_Ordinary) {
-    this->Loc = Loc;
+    CXXNullPtrLiteralExprBits.Loc = Loc.getRawEncoding();
     setDependence(ExprDependence::None);
   }
 
@@ -781,8 +782,12 @@ class CXXNullPtrLiteralExpr : public Expr {
   SourceLocation getBeginLoc() const { return getLocation(); }
   SourceLocation getEndLoc() const { return getLocation(); }
 
-  SourceLocation getLocation() const { return Loc; }
-  void setLocation(SourceLocation L) { Loc = L; }
+  SourceLocation getLocation() const {
+    return SourceLocation::getFromRawEncoding(CXXNullPtrLiteralExprBits.Loc);
+  }
+  void setLocation(SourceLocation L) {
+    CXXNullPtrLiteralExprBits.Loc = L.getRawEncoding();
+  }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXNullPtrLiteralExprClass;
@@ -1155,14 +1160,12 @@ class CXXUuidofExpr : public Expr {
 /// };
 /// \endcode
 class CXXThisExpr : public Expr {
-  /// The location of the "this".
-  SourceLocation Loc;
 
   CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit, ExprValueKind VK)
       : Expr(CXXThisExprClass, Ty, VK, OK_Ordinary) {
     CXXThisExprBits.IsImplicit = IsImplicit;
     CXXThisExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false;
-    Loc = L;
+    CXXThisExprBits.Loc = L.getRawEncoding();
     setDependence(computeDependence(this));
   }
 
@@ -1174,8 +1177,12 @@ class CXXThisExpr : public Expr {
 
   static CXXThisExpr *CreateEmpty(const ASTContext &Ctx);
 
-  SourceLocation getLocation() const { return Loc; }
-  void setLocation(SourceLocation L) { Loc = L; }
+  SourceLocation getLocation() const {
+    return SourceLocation::getFromRawEncoding(CXXThisExprBits.Loc);
+  }
+  void setLocation(SourceLocation L) {
+    CXXThisExprBits.Loc = L.getRawEncoding();
+  }
 
   SourceLocation getBeginLoc() const { return getLocation(); }
   SourceLocation getEndLoc() const { return getLocation(); }
@@ -1216,8 +1223,6 @@ class CXXThrowExpr : public Expr {
 
   /// The optional expression in the throw statement.
   Stmt *Operand;
-  /// The location of the "throw".
-  SourceLocation ThrowLoc;
 
 public:
   // \p Ty is the void type which is used as the result type of the
@@ -1227,7 +1232,7 @@ class CXXThrowExpr : public Expr {
   CXXThrowExpr(Expr *Operand, QualType Ty, SourceLocation Loc,
                bool IsThrownVariableInScope)
       : Expr(CXXThrowExprClass, Ty, VK_PRValue, OK_Ordinary), Operand(Operand) {
-    ThrowLoc = Loc;
+    CXXThrowExprBits.ThrowLoc = Loc.getRawEncoding();
     CXXThrowExprBits.IsThrownVariableInScope = IsThrownVariableInScope;
     setDependence(computeDependence(this));
   }
@@ -1236,7 +1241,9 @@ class CXXThrowExpr : public Expr {
   const Expr *getSubExpr() const { return cast_or_null<Expr>(Operand); }
   Expr *getSubExpr() { return cast_or_null<Expr>(Operand); }
 
-  SourceLocation getThrowLoc() const { return ThrowLoc; }
+  SourceLocation getThrowLoc() const {
+    return SourceLocation::getFromRawEncoding(CXXThrowExprBits.ThrowLoc);
+  }
 
   /// Determines whether the variable thrown by this expression (if any!)
   /// is within the innermost try block.
@@ -1285,9 +1292,7 @@ class CXXDefaultArgExpr final
 
   /// The context where the default argument expression was used.
   DeclContext *UsedContext;
-  
-  /// The location where the default argument expression was used.
-  SourceLocation Loc;
+
   CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param,
                     Expr *RewrittenExpr, DeclContext *UsedContext)
       : Expr(SC,
@@ -1297,7 +1302,7 @@ class CXXDefaultArgExpr final
              Param->getDefaultArg()->getValueKind(),
              Param->getDefaultArg()->getObjectKind()),
         Param(Param), UsedContext(UsedContext) {
-    this->Loc = Loc;
+    CXXDefaultArgExprBits.Loc = Loc.getRawEncoding();
     CXXDefaultArgExprBits.HasRewrittenInit = RewrittenExpr != nullptr;
     if (RewrittenExpr)
       *getTrailingObjects() = RewrittenExpr;
@@ -1351,7 +1356,9 @@ class CXXDefaultArgExpr final
   DeclContext *getUsedContext() { return UsedContext; }
 
   /// Retrieve the location where this default argument was actually used.
-  SourceLocation getUsedLocation() const { return Loc; }
+  SourceLocation getUsedLocation() const {
+    return SourceLocation::getFromRawEncoding(CXXDefaultArgExprBits.Loc);
+  }
 
   /// Default argument expressions have no representation in the
   /// source, so they have an empty source range.
@@ -1394,8 +1401,6 @@ class CXXDefaultInitExpr final
 
   /// The context where the default initializer expression was used.
   DeclContext *UsedContext;
-  /// The location where the default initializer expression was used.
-  SourceLocation Loc;
   CXXDefaultInitExpr(const ASTContext &Ctx, SourceLocation Loc,
                      FieldDecl *Field, QualType Ty, DeclContext *UsedContext,
                      Expr *RewrittenInitExpr);
@@ -1449,8 +1454,10 @@ class CXXDefaultInitExpr final
   /// actually used.
   SourceLocation getUsedLocation() const { return getBeginLoc(); }
 
-  SourceLocation getBeginLoc() const { return Loc; }
-  SourceLocation getEndLoc() const { return Loc; }
+  SourceLocation getBeginLoc() const {
+    return SourceLocation::getFromRawEncoding(CXXDefaultInitExprBits.Loc);
+  }
+  SourceLocation getEndLoc() const { return getBeginLoc(); }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXDefaultInitExprClass;
@@ -2196,7 +2203,6 @@ class CXXScalarValueInitExpr : public Expr {
   friend class ASTStmtReader;
 
   TypeSourceInfo *TypeInfo;
-  SourceLocation RParenLoc;
 
 public:
   /// Create an explicitly-written scalar-value initialization
@@ -2205,7 +2211,7 @@ class CXXScalarValueInitExpr : public Expr {
                          SourceLocation RParenLoc)
       : Expr(CXXScalarValueInitExprClass, Type, VK_PRValue, OK_Ordinary),
         TypeInfo(TypeInfo) {
-    this->RParenLoc = RParenLoc;
+    CXXScalarValueInitExprBits.RParenLoc = RParenLoc.getRawEncoding();
     setDependence(computeDependence(this));
   }
 
@@ -2217,7 +2223,8 @@ class CXXScalarValueInitExpr : public Expr {
   }
 
   SourceLocation getRParenLoc() const {
-    return RParenLoc;
+    return SourceLocation::getFromRawEncoding(
+        CXXScalarValueInitExprBits.RParenLoc);
   }
 
   SourceLocation getBeginLoc() const LLVM_READONLY;
@@ -2623,8 +2630,7 @@ class CXXDeleteExpr : public Expr {
 
   /// The pointer expression to be deleted.
   Stmt *Argument = nullptr;
-    /// Location of the expression.
-    SourceLocation Loc;
+
 public:
   CXXDeleteExpr(QualType Ty, bool GlobalDelete, bool ArrayForm,
                 bool ArrayFormAsWritten, bool UsualArrayDeleteWantsSize,
@@ -2635,7 +2641,7 @@ class CXXDeleteExpr : public Expr {
     CXXDeleteExprBits.ArrayForm = ArrayForm;
     CXXDeleteExprBits.ArrayFormAsWritten = ArrayFormAsWritten;
     CXXDeleteExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize;
-    this->Loc = Loc;
+    CXXDeleteExprBits.Loc = Loc.getRawEncoding();
     setDependence(computeDependence(this));
   }
 
@@ -2666,7 +2672,9 @@ class CXXDeleteExpr : public Expr {
   /// be a pointer, return an invalid type.
   QualType getDestroyedType() const;
 
-  SourceLocation getBeginLoc() const { return Loc; }
+  SourceLocation getBeginLoc() const {
+    return SourceLocation::getFromRawEncoding(CXXDeleteExprBits.Loc);
+  }
   SourceLocation getEndLoc() const LLVM_READONLY {
     return Argument->getEndLoc();
   }
diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h
index 9d1fc29a2753e..c6724315194f9 100644
--- a/clang/include/clang/AST/ExprConcepts.h
+++ b/clang/include/clang/AST/ExprConcepts.h
@@ -503,7 +503,6 @@ class RequiresExpr final : public Expr,
   friend TrailingObjects;
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
-  SourceLocation RequiresKWLoc;
 
   unsigned NumLocalParameters;
   unsigned NumRequirements;
@@ -562,7 +561,7 @@ class RequiresExpr final : public Expr,
   }
 
   SourceLocation getRequiresKWLoc() const {
-    return RequiresKWLoc;
+    return SourceLocation::getFromRawEncoding(RequiresExprBits.RequiresKWLoc);
   }
 
   SourceLocation getLParenLoc() const { return LParenLoc; }
@@ -574,7 +573,7 @@ class RequiresExpr final : public Expr,
   }
 
   SourceLocation getBeginLoc() const LLVM_READONLY {
-    return RequiresKWLoc;
+    return getRequiresKWLoc();
   }
   SourceLocation getEndLoc() const LLVM_READONLY {
     return RBraceLoc;
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index e3d5bac743848..79991de6ed881 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -138,7 +138,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasLeadingEmptyMacro : 1;
 
- 
+    /// The location of the semi-colon.Add commentMore actions
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long SemiLoc : SourceLocation::Bits;
   };
 
   class CompoundStmtBitfields {
@@ -162,7 +164,8 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(StmtBitfields)
     unsigned : NumStmtBits;
 
-
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long IdentLoc : SourceLocation::Bits;
   };
 
   class AttributedStmtBitfields {
@@ -174,8 +177,6 @@ class alignas(void *) Stmt {
 
     /// Number of attributes.
     unsigned NumAttrs : 32 - NumStmtBits;
-
-
   };
 
   class IfStmtBitfields {
@@ -201,7 +202,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasInit : 1;
 
-
+    /// The location of the "if"
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long IfLoc : SourceLocation::Bits;
   };
 
   class SwitchStmtBitfields {
@@ -224,7 +227,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned AllEnumCasesCovered : 1;
 
-
+    /// The location of the "switch".
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long SwitchLoc : SourceLocation::Bits;
   };
 
   class WhileStmtBitfields {
@@ -238,7 +243,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasVar : 1;
 
-
+    /// The location of the "while"
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long WhileLoc : SourceLocation::Bits;
   };
 
   class DoStmtBitfields {
@@ -247,7 +254,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(StmtBitfields)
     unsigned : NumStmtBits;
 
-
+    /// The location of the "do"
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long DoLoc : SourceLocation::Bits;
   };
 
   class ForStmtBitfields {
@@ -256,7 +265,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(StmtBitfields)
     unsigned : NumStmtBits;
 
-
+    /// The location of the "for"
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long ForLoc : SourceLocation::Bits;
   };
 
   class GotoStmtBitfields {
@@ -266,7 +277,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(StmtBitfields)
     unsigned : NumStmtBits;
 
-
+    /// The location of the "goto"
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long GotoLoc : SourceLocation::Bits;
   };
 
   class ContinueStmtBitfields {
@@ -275,7 +288,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(StmtBitfields)
     unsigned : NumStmtBits;
 
-
+    /// The location of the "continue"
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long ContinueLoc : SourceLocation::Bits;
   };
 
   class BreakStmtBitfields {
@@ -284,7 +299,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(StmtBitfields)
     unsigned : NumStmtBits;
 
-
+    /// The location of the "break"
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long BreakLoc : SourceLocation::Bits;
   };
 
   class ReturnStmtBitfields {
@@ -297,7 +314,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasNRVOCandidate : 1;
 
-
+    /// The location of the "return"
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long RetLoc : SourceLocation::Bits;
   };
 
   class SwitchCaseBitfields {
@@ -312,7 +331,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned CaseStmtIsGNURange : 1;
 
-
+    /// The location of the "case" or "default" keyword.
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long KeywordLoc : SourceLocation::Bits;
   };
 
   //===--- Expression bitfields classes ---===//
@@ -409,8 +430,6 @@ class alignas(void *) Stmt {
     /// MSVC compatibility).
     LLVM_PREFERRED_TYPE(bool)
     unsigned IsTransparent : 1;
-
-   
   };
 
   class DeclRefExprBitfields {
@@ -530,7 +549,8 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(ExprBitfields)
     unsigned : NumExprBits;
 
-
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long RBracketLoc : SourceLocation::Bits;
   };
 
   class CallExprBitfields {
@@ -683,7 +703,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(ExprBitfields)
     unsigned : NumExprBits;
 
-
+    /// The location of the "_Generic"
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long GenericLoc : SourceLocation::Bits;
   };
 
   class PseudoObjectExprBitfields {
@@ -790,6 +812,10 @@ class alignas(void *) Stmt {
     /// The value of the boolean literal.
     LLVM_PREFERRED_TYPE(bool)
     unsigned Value : 1;
+
+    /// The location of the boolean ligeral
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long Loc : SourceLocation::Bits;
   };
 
   class CXXNullPtrLiteralExprBitfields {
@@ -799,6 +825,8 @@ class alignas(void *) Stmt {
     unsigned : NumExprBits;
 
     /// The location of the null pointer literal.
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long Loc : SourceLocation::Bits;
   };
 
   class CXXThisExprBitfields {
@@ -816,6 +844,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned CapturedByCopyInLambdaWithExplicitObjectParameter : 1;
 
+    /// The location of the "this"
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long Loc : SourceLocation::Bits;
   };
 
   class CXXThrowExprBitfields {
@@ -829,6 +860,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned IsThrownVariableInScope : 1;
 
+    /// The location of the "throw"
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long ThrowLoc : SourceLocation::Bits;
   };
 
   class CXXDefaultArgExprBitfields {
@@ -842,7 +876,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasRewrittenInit : 1;
 
-
+    /// The location where the default argument expression was used.
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long Loc : SourceLocation::Bits;
   };
 
   class CXXDefaultInitExprBitfields {
@@ -857,7 +893,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasRewrittenInit : 1;
 
-
+    /// The location where the default initializer expression was used.
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long Loc : SourceLocation::Bits;
   };
 
   class CXXScalarValueInitExprBitfields {
@@ -867,6 +905,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(ExprBitfields)
     unsigned : NumExprBits;
 
+    /// The location where the default initializer expression was used.
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long RParenLoc : SourceLocation::Bits;
   };
 
   class CXXNewExprBitfields {
@@ -941,7 +982,9 @@ class alignas(void *) Stmt {
     LLVM_PREFERRED_TYPE(bool)
     unsigned UsualArrayDeleteWantsSize : 1;
 
-  
+    /// Location of the expression
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long Loc : SourceLocation::Bits;
   };
 
   class TypeTraitExprBitfields {
@@ -1135,6 +1178,7 @@ class alignas(void *) Stmt {
     
     LLVM_PREFERRED_TYPE(ExprBitfields)
     unsigned : NumExprBits;
+
     /// The location of the non-type template parameter reference.
     LLVM_PREFERRED_TYPE(SourceLocation)
     unsigned long NameLoc : SourceLocation::Bits;
@@ -1176,6 +1220,9 @@ class alignas(void *) Stmt {
 
     LLVM_PREFERRED_TYPE(bool)
     unsigned IsSatisfied : 1;
+
+    LLVM_PREFERRED_TYPE(SourceLocation)
+    unsigned long RequiresKWLoc : SourceLocation::Bits;
   };
 
   class ArrayTypeTraitExprBitfields {
@@ -1667,8 +1714,6 @@ class DeclStmt : public Stmt {
 /// NullStmt - This is the null statement ";": C99 6.8.3p3.
 ///
 class NullStmt : public Stmt {
-     /// The location of the semi-colon.
-     SourceLocation SemiLoc;
 public:
   NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false)
       : Stmt(NullStmtClass) {
@@ -1679,8 +1724,12 @@ class NullStmt : public Stmt {
   /// Build an empty null statement.
   explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) {}
 
-  SourceLocation getSemiLoc() const { return SemiLoc; }
-  void setSemiLoc(SourceLocation L) { SemiLoc = L; }
+  SourceLocation getSemiLoc() const {
+    return SourceLocation::getFromRawEncoding(NullStmtBits.SemiLoc);
+  }
+  void setSemiLoc(SourceLocation L) {
+    NullStmtBits.SemiLoc = L.getRawEncoding();
+  }
 
   bool hasLeadingEmptyMacro() const {
     return NullStmtBits.HasLeadingEmptyMacro;
@@ -1860,8 +1909,6 @@ class CompoundStmt final
 // SwitchCase is the base class for CaseStmt and DefaultStmt,
 class SwitchCase : public Stmt {
 protected:
-    /// The location of the "case" or "default" keyword.
-    SourceLocation KeywordLoc;
   /// The location of the ":".
   SourceLocation ColonLoc;
 
@@ -1884,8 +1931,12 @@ class SwitchCase : public Stmt {
   SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
   void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
 
-  SourceLocation getKeywordLoc() const { return KeywordLoc; }
-  void setKeywordLoc(SourceLocation L) { KeywordLoc = L; }
+  SourceLocation getKeywordLoc() const {
+    return SourceLocation::getFromRawEncoding(SwitchCaseBits.KeywordLoc);
+  }
+  void setKeywordLoc(SourceLocation L) {
+    SwitchCaseBits.KeywordLoc = L.getRawEncoding();
+  }
   SourceLocation getColonLoc() const { return ColonLoc; }
   void setColonLoc(SourceLocation L) { ColonLoc = L; }
 
@@ -2135,7 +2186,6 @@ class ValueStmt : public Stmt {
 /// LabelStmt - Represents a label, which has a substatement.  For example:
 ///    foo: return;
 class LabelStmt : public ValueStmt {
-  SourceLocation IdentLoc;
   LabelDecl *TheDecl;
   Stmt *SubStmt;
   bool SideEntry = false; // FIXME: could improve
@@ -2150,8 +2200,12 @@ class LabelStmt : public ValueStmt {
   /// Build an empty label statement.
   explicit LabelStmt(EmptyShell Empty) : ValueStmt(LabelStmtClass, Empty) {}
 
-  SourceLocation getIdentLoc() const { return IdentLoc; }
-  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
+  SourceLocation getIdentLoc() const {
+    return SourceLocation::getFromRawEncoding(LabelStmtBits.IdentLoc);
+  }
+  void setIdentLoc(SourceLocation L) {
+    LabelStmtBits.IdentLoc = L.getRawEncoding();
+  }
 
   LabelDecl *getDecl() const { return TheDecl; }
   void setDecl(LabelDecl *D) { TheDecl = D; }
@@ -2268,8 +2322,6 @@ class IfStmt final
   //    Present if and only if hasElseStorage().
   enum { InitOffset = 0, ThenOffsetFromCond = 1, ElseOffsetFromCond = 2 };
   enum { NumMandatoryStmtPtr = 2 };
-      /// The location of the "if".
-      SourceLocation IfLoc;
   SourceLocation LParenLoc;
   SourceLocation RParenLoc;
 
@@ -2409,8 +2461,12 @@ class IfStmt final
     getTrailingObjects<Stmt *>()[initOffset()] = Init;
   }
 
-  SourceLocation getIfLoc() const { return IfLoc; }
-  void setIfLoc(SourceLocation IfLoc) { this->IfLoc = IfLoc; }
+  SourceLocation getIfLoc() const {
+    return SourceLocation::getFromRawEncoding(IfStmtBits.IfLoc);
+  }
+  void setIfLoc(SourceLocation IfLoc) {
+    IfStmtBits.IfLoc = IfLoc.getRawEncoding();
+  }
 
   SourceLocation getElseLoc() const {
     return hasElseStorage() ? *getTrailingObjects<SourceLocation>()
@@ -2495,8 +2551,6 @@ class IfStmt final
 class SwitchStmt final : public Stmt,
                          private llvm::TrailingObjects<SwitchStmt, Stmt *> {
   friend TrailingObjects;
-    /// The location of the "switch".
-    SourceLocation SwitchLoc;
   /// Points to a linked list of case and default statements.
   SwitchCase *FirstCase = nullptr;
 
@@ -2629,8 +2683,12 @@ class SwitchStmt final : public Stmt,
   const SwitchCase *getSwitchCaseList() const { return FirstCase; }
   void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
 
-  SourceLocation getSwitchLoc() const { return SwitchLoc; }
-  void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
+  SourceLocation getSwitchLoc() const {
+    return SourceLocation::getFromRawEncoding(SwitchStmtBits.SwitchLoc);
+  }
+  void setSwitchLoc(SourceLocation L) {
+    SwitchStmtBits.SwitchLoc = L.getRawEncoding();
+  }
   SourceLocation getLParenLoc() const { return LParenLoc; }
   void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -2702,8 +2760,6 @@ class WhileStmt final : public Stmt,
   //
   enum { VarOffset = 0, BodyOffsetFromCond = 1 };
   enum { NumMandatoryStmtPtr = 2 };
-    /// The location of the "while".
-    SourceLocation WhileLoc;
   SourceLocation LParenLoc, RParenLoc;
 
   unsigned varOffset() const { return VarOffset; }
@@ -2788,8 +2844,12 @@ class WhileStmt final : public Stmt,
     getTrailingObjects()[varOffset()] = CondVar;
   }
 
-  SourceLocation getWhileLoc() const { return WhileLoc; }
-  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
+  SourceLocation getWhileLoc() const {
+    return SourceLocation::getFromRawEncoding(WhileStmtBits.WhileLoc);
+  }
+  void setWhileLoc(SourceLocation L) {
+    WhileStmtBits.WhileLoc = L.getRawEncoding();
+  }
 
   SourceLocation getLParenLoc() const { return LParenLoc; }
   void setLParenLoc(SourceLocation L) { LParenLoc = L; }
@@ -2823,8 +2883,6 @@ class DoStmt : public Stmt {
   Stmt *SubExprs[END_EXPR];
   SourceLocation WhileLoc;
   SourceLocation RParenLoc; // Location of final ')' in do stmt condition.
-    /// The location of the "do".
-    SourceLocation DoLoc;
 public:
   DoStmt(Stmt *Body, Expr *Cond, SourceLocation DL, SourceLocation WL,
          SourceLocation RP)
@@ -2848,8 +2906,10 @@ class DoStmt : public Stmt {
   const Stmt *getBody() const { return SubExprs[BODY]; }
   void setBody(Stmt *Body) { SubExprs[BODY] = Body; }
 
-  SourceLocation getDoLoc() const { return DoLoc; }
-  void setDoLoc(SourceLocation L) { DoLoc = L; }
+  SourceLocation getDoLoc() const {
+    return SourceLocation::getFromRawEncoding(DoStmtBits.DoLoc);
+  }
+  void setDoLoc(SourceLocation L) { DoStmtBits.DoLoc = L.getRawEncoding(); }
   SourceLocation getWhileLoc() const { return WhileLoc; }
   void setWhileLoc(SourceLocation L) { WhileLoc = L; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -2879,8 +2939,6 @@ class ForStmt : public Stmt {
   friend class ASTStmtReader;
 
   enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
-      /// The location of the "for".
-      SourceLocation ForLoc;
   Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
   SourceLocation LParenLoc, RParenLoc;
 
@@ -2933,8 +2991,10 @@ class ForStmt : public Stmt {
   void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
   void setBody(Stmt *S) { SubExprs[BODY] = S; }
 
-  SourceLocation getForLoc() const { return ForLoc; }
-  void setForLoc(SourceLocation L) { ForLoc = L; }
+  SourceLocation getForLoc() const {
+    return SourceLocation::getFromRawEncoding(ForStmtBits.ForLoc);
+  }
+  void setForLoc(SourceLocation L) { ForStmtBits.ForLoc = L.getRawEncoding(); }
   SourceLocation getLParenLoc() const { return LParenLoc; }
   void setLParenLoc(SourceLocation L) { LParenLoc = L; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -2960,8 +3020,6 @@ class ForStmt : public Stmt {
 /// GotoStmt - This represents a direct goto.
 class GotoStmt : public Stmt {
   LabelDecl *Label;
-      /// The location of the "goto".
-      SourceLocation GotoLoc;
   SourceLocation LabelLoc;
 
 public:
@@ -2976,8 +3034,12 @@ class GotoStmt : public Stmt {
   LabelDecl *getLabel() const { return Label; }
   void setLabel(LabelDecl *D) { Label = D; }
 
-  SourceLocation getGotoLoc() const { return GotoLoc; }
-  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
+  SourceLocation getGotoLoc() const {
+    return SourceLocation::getFromRawEncoding(GotoStmtBits.GotoLoc);
+  }
+  void setGotoLoc(SourceLocation L) {
+    GotoStmtBits.GotoLoc = L.getRawEncoding();
+  }
   SourceLocation getLabelLoc() const { return LabelLoc; }
   void setLabelLoc(SourceLocation L) { LabelLoc = L; }
 
@@ -3000,8 +3062,6 @@ class GotoStmt : public Stmt {
 
 /// IndirectGotoStmt - This represents an indirect goto.
 class IndirectGotoStmt : public Stmt {
-  /// The location of the "goto".
-  SourceLocation GotoLoc;
   SourceLocation StarLoc;
   Stmt *Target;
 
@@ -3016,8 +3076,12 @@ class IndirectGotoStmt : public Stmt {
   explicit IndirectGotoStmt(EmptyShell Empty)
       : Stmt(IndirectGotoStmtClass, Empty) {}
 
-  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
-  SourceLocation getGotoLoc() const { return GotoLoc; }
+  void setGotoLoc(SourceLocation L) {
+    GotoStmtBits.GotoLoc = L.getRawEncoding();
+  }
+  SourceLocation getGotoLoc() const {
+    return SourceLocation::getFromRawEncoding(GotoStmtBits.GotoLoc);
+  }
   void setStarLoc(SourceLocation L) { StarLoc = L; }
   SourceLocation getStarLoc() const { return StarLoc; }
 
@@ -3051,8 +3115,6 @@ class IndirectGotoStmt : public Stmt {
 
 /// ContinueStmt - This represents a continue.
 class ContinueStmt : public Stmt {
-      /// The location of the "continue".
-      SourceLocation ContinueLoc;
 public:
 
   ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass) {
@@ -3062,8 +3124,12 @@ class ContinueStmt : public Stmt {
   /// Build an empty continue statement.
   explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) {}
 
-  SourceLocation getContinueLoc() const { return ContinueLoc; }
-  void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
+  SourceLocation getContinueLoc() const {
+    return SourceLocation::getFromRawEncoding(ContinueStmtBits.ContinueLoc);
+  }
+  void setContinueLoc(SourceLocation L) {
+    ContinueStmtBits.ContinueLoc = L.getRawEncoding();
+  }
 
   SourceLocation getBeginLoc() const { return getContinueLoc(); }
   SourceLocation getEndLoc() const { return getContinueLoc(); }
@@ -3084,8 +3150,6 @@ class ContinueStmt : public Stmt {
 
 /// BreakStmt - This represents a break.
 class BreakStmt : public Stmt {
-      /// The location of the "break".
-      SourceLocation BreakLoc;
 public:
   BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass) {
     setBreakLoc(BL);
@@ -3094,8 +3158,12 @@ class BreakStmt : public Stmt {
   /// Build an empty break statement.
   explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) {}
 
-  SourceLocation getBreakLoc() const { return BreakLoc; }
-  void setBreakLoc(SourceLocation L) { BreakLoc = L; }
+  SourceLocation getBreakLoc() const {
+    return SourceLocation::getFromRawEncoding(BreakStmtBits.BreakLoc);
+  }
+  void setBreakLoc(SourceLocation L) {
+    BreakStmtBits.BreakLoc = L.getRawEncoding();
+  }
 
   SourceLocation getBeginLoc() const { return getBreakLoc(); }
   SourceLocation getEndLoc() const { return getBreakLoc(); }
@@ -3126,8 +3194,6 @@ class ReturnStmt final
     : public Stmt,
       private llvm::TrailingObjects<ReturnStmt, const VarDecl *> {
   friend TrailingObjects;
-    /// The location of the "return".
-    SourceLocation RetLoc;
   /// The return expression.
   Stmt *RetExpr;
 
@@ -3174,8 +3240,12 @@ class ReturnStmt final
     *getTrailingObjects() = Var;
   }
 
-  SourceLocation getReturnLoc() const { return RetLoc; }
-  void setReturnLoc(SourceLocation L) { RetLoc = L; }
+  SourceLocation getReturnLoc() const {
+    return SourceLocation::getFromRawEncoding(ReturnStmtBits.RetLoc);
+  }
+  void setReturnLoc(SourceLocation L) {
+    ReturnStmtBits.RetLoc = L.getRawEncoding();
+  }
 
   SourceLocation getBeginLoc() const { return getReturnLoc(); }
   SourceLocation getEndLoc() const LLVM_READONLY {
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 3258ac2195aab..d2c72294e0289 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -4421,7 +4421,7 @@ GenericSelectionExpr::GenericSelectionExpr(
          " and TypeSourceInfo!");
   assert(ResultIndex < NumAssocs && "ResultIndex is out-of-bounds!");
 
-  this->GenericLoc = GenericLoc;
+  GenericSelectionExprBits.GenericLoc = GenericLoc.getRawEncoding();
   getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()] =
       ControllingExpr;
   llvm::copy(AssocExprs,
@@ -4448,7 +4448,7 @@ GenericSelectionExpr::GenericSelectionExpr(
          " and TypeSourceInfo!");
   assert(ResultIndex < NumAssocs && "ResultIndex is out-of-bounds!");
 
-  this->GenericLoc = GenericLoc;
+  GenericSelectionExprBits.GenericLoc = GenericLoc.getRawEncoding();
   getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()] =
       ControllingType;
   llvm::copy(AssocExprs,
@@ -4472,7 +4472,7 @@ GenericSelectionExpr::GenericSelectionExpr(
          "Must have the same number of association expressions"
          " and TypeSourceInfo!");
 
-  this->GenericLoc = GenericLoc;
+  GenericSelectionExprBits.GenericLoc = GenericLoc.getRawEncoding();
   getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()] =
       ControllingExpr;
   llvm::copy(AssocExprs,
@@ -4496,7 +4496,7 @@ GenericSelectionExpr::GenericSelectionExpr(
          "Must have the same number of association expressions"
          " and TypeSourceInfo!");
 
-  this->GenericLoc = GenericLoc;
+  GenericSelectionExprBits.GenericLoc = GenericLoc.getRawEncoding();
   getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()] =
       ControllingType;
   llvm::copy(AssocExprs,
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index f503b33d84047..07bef9e568ce9 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1060,7 +1060,7 @@ CXXDefaultInitExpr::CXXDefaultInitExpr(const ASTContext &Ctx,
                                          : VK_PRValue,
            /*FIXME*/ OK_Ordinary),
       Field(Field), UsedContext(UsedContext) {
-  this->Loc = Loc;
+  CXXDefaultInitExprBits.Loc = Loc.getRawEncoding();
   CXXDefaultInitExprBits.HasRewrittenInit = RewrittenInitExpr != nullptr;
 
   if (CXXDefaultInitExprBits.HasRewrittenInit)
diff --git a/clang/lib/AST/ExprConcepts.cpp b/clang/lib/AST/ExprConcepts.cpp
index 4dce391116729..df818922825cf 100644
--- a/clang/lib/AST/ExprConcepts.cpp
+++ b/clang/lib/AST/ExprConcepts.cpp
@@ -123,7 +123,7 @@ RequiresExpr::RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
       NumRequirements(Requirements.size()), Body(Body), LParenLoc(LParenLoc),
       RParenLoc(RParenLoc), RBraceLoc(RBraceLoc) {
   RequiresExprBits.IsSatisfied = false;
-  this->RequiresKWLoc = RequiresKWLoc;
+  RequiresExprBits.RequiresKWLoc = RequiresKWLoc.getRawEncoding();
   bool Dependent = false;
   bool ContainsUnexpandedParameterPack = false;
   for (ParmVarDecl *P : LocalParameters) {
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index e0bfcb93313cc..41c53f9be6027 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -1072,7 +1072,7 @@ ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
   SubExprs[COND] = Cond;
   SubExprs[INC] = Inc;
   SubExprs[BODY] = Body;
-  ForLoc = FL;
+  ForStmtBits.ForLoc = FL.getRawEncoding();
 }
 
 VarDecl *ForStmt::getConditionVariable() const {
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index e85ec09fd95f5..51115ac3796de 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -843,7 +843,8 @@ void ASTStmtReader::VisitRequiresExpr(RequiresExpr *E) {
   VisitExpr(E);
   unsigned NumLocalParameters = Record.readInt();
   unsigned NumRequirements = Record.readInt();
-  E->RequiresKWLoc = Record.readSourceLocation();
+  E->RequiresExprBits.RequiresKWLoc =
+      Record.readSourceLocation().getRawEncoding();
   E->RequiresExprBits.IsSatisfied = Record.readInt();
   E->Body = Record.readDeclAs<RequiresExprBodyDecl>();
   llvm::SmallVector<ParmVarDecl *, 4> LocalParameters;
@@ -1410,7 +1411,8 @@ void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
   assert(NumAssocs == E->getNumAssocs() && "Wrong NumAssocs!");
   E->IsExprPredicate = Record.readInt();
   E->ResultIndex = Record.readInt();
-  E->GenericLoc = readSourceLocation();
+  E->GenericSelectionExprBits.GenericLoc =
+      readSourceLocation().getRawEncoding();
   E->DefaultLoc = readSourceLocation();
   E->RParenLoc = readSourceLocation();
 
@@ -1880,7 +1882,7 @@ void ASTStmtReader::VisitCXXThisExpr(CXXThisExpr *E) {
 
 void ASTStmtReader::VisitCXXThrowExpr(CXXThrowExpr *E) {
   VisitExpr(E);
-  E->ThrowLoc = readSourceLocation();
+  E->CXXThrowExprBits.ThrowLoc = readSourceLocation().getRawEncoding();
   E->Operand = Record.readSubExpr();
   E->CXXThrowExprBits.IsThrownVariableInScope = Record.readInt();
 }
@@ -1889,7 +1891,7 @@ void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   VisitExpr(E);
   E->Param = readDeclAs<ParmVarDecl>();
   E->UsedContext = readDeclAs<DeclContext>();
-  E->Loc = readSourceLocation();
+  E->CXXDefaultArgExprBits.Loc = readSourceLocation().getRawEncoding();
   E->CXXDefaultArgExprBits.HasRewrittenInit = Record.readInt();
   if (E->CXXDefaultArgExprBits.HasRewrittenInit)
     *E->getTrailingObjects() = Record.readSubExpr();
@@ -1900,7 +1902,7 @@ void ASTStmtReader::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
   E->CXXDefaultInitExprBits.HasRewrittenInit = Record.readInt();
   E->Field = readDeclAs<FieldDecl>();
   E->UsedContext = readDeclAs<DeclContext>();
-  E->Loc = readSourceLocation();
+  E->CXXDefaultInitExprBits.Loc = readSourceLocation().getRawEncoding();
   if (E->CXXDefaultInitExprBits.HasRewrittenInit)
     *E->getTrailingObjects() = Record.readSubExpr();
 }
@@ -1914,7 +1916,8 @@ void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
 void ASTStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
   VisitExpr(E);
   E->TypeInfo = readTypeSourceInfo();
-  E->RParenLoc = readSourceLocation();
+  E->CXXScalarValueInitExprBits.RParenLoc =
+      readSourceLocation().getRawEncoding();
 }
 
 void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
@@ -1964,7 +1967,7 @@ void ASTStmtReader::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
   E->CXXDeleteExprBits.UsualArrayDeleteWantsSize = Record.readInt();
   E->OperatorDelete = readDeclAs<FunctionDecl>();
   E->Argument = Record.readSubExpr();
-  E->Loc = readSourceLocation();
+  E->CXXDeleteExprBits.Loc = readSourceLocation().getRawEncoding();
 }
 
 void ASTStmtReader::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index edbd4f6c7fc41..4fab00cc1c3e5 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -514,7 +514,7 @@ void ASTStmtWriter::VisitRequiresExpr(RequiresExpr *E) {
   VisitExpr(E);
   Record.push_back(E->getLocalParameters().size());
   Record.push_back(E->getRequirements().size());
-  Record.AddSourceLocation(E->RequiresKWLoc);
+  Record.AddSourceLocation(E->getRequiresKWLoc());
   Record.push_back(E->RequiresExprBits.IsSatisfied);
   Record.AddDeclRef(E->getBody());
   for (ParmVarDecl *P : E->getLocalParameters())

>From c5a21c5da18a04dfe9ded3625cba0a900187c5d1 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Thu, 26 Jun 2025 20:50:42 +0200
Subject: [PATCH 10/20] Improve getFildIDLocal binary search.

---
 clang/lib/Basic/SourceManager.cpp | 37 +++++++++++--------------------
 1 file changed, 13 insertions(+), 24 deletions(-)

diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index defba0a351498..76e9340d1c067 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -855,35 +855,24 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
       break;
   }
 
-  NumProbes = 0;
-  while (true) {
-    unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
+  while (LessIndex < GreaterIndex) {
+    ++NumBinaryProbes;
+
+    unsigned MiddleIndex = LessIndex + (GreaterIndex - LessIndex) / 2;
+
     SourceLocation::UIntTy MidOffset =
         getLocalSLocEntry(MiddleIndex).getOffset();
 
-    ++NumProbes;
-
-    // If the offset of the midpoint is too large, chop the high side of the
-    // range to the midpoint.
-    if (MidOffset > SLocOffset) {
+    if (MidOffset <= SLocOffset)
+      LessIndex = MiddleIndex + 1;
+    else
       GreaterIndex = MiddleIndex;
-      continue;
-    }
-
-    // If the middle index contains the value, succeed and return.
-    if (MiddleIndex + 1 == LocalSLocEntryTable.size() ||
-        SLocOffset < getLocalSLocEntry(MiddleIndex + 1).getOffset()) {
-      FileID Res = FileID::get(MiddleIndex);
-
-      // Remember it.  We have good locality across FileID lookups.
-      LastFileIDLookup = Res;
-      NumBinaryProbes += NumProbes;
-      return Res;
-    }
-
-    // Otherwise, move the low-side up to the middle index.
-    LessIndex = MiddleIndex;
   }
+
+  // The loop terminates when LessIndex == GreaterIndex. At this point,
+  // `LessIndex` is the index of the *first element greater than* SLocOffset.
+  // The element we are actually looking for is the one immediately before it.
+  return LastFileIDLookup = FileID::get(LessIndex - 1);
 }
 
 /// Return the FileID for a SourceLocation with a high offset.

>From 7f125a0c5f0fbcfbb920d223628dc1c48607d400 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Thu, 26 Jun 2025 21:03:11 +0200
Subject: [PATCH 11/20] Optimize binary search by using a dedicate offset table

improve the cache performance
---
 clang/include/clang/Basic/SourceManager.h |  2 ++
 clang/lib/Basic/SourceManager.cpp         | 15 ++++++++++-----
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h
index 68b1c7b469ecf..930e48d6c6d84 100644
--- a/clang/include/clang/Basic/SourceManager.h
+++ b/clang/include/clang/Basic/SourceManager.h
@@ -720,6 +720,8 @@ class SourceManager : public RefCountedBase<SourceManager> {
   /// expansion.
   SmallVector<SrcMgr::SLocEntry, 0> LocalSLocEntryTable;
 
+  SmallVector<SourceLocation::UIntTy, 0> LocalLocOffsetTable;
+  
   /// The table of SLocEntries that are loaded from other modules.
   ///
   /// Negative FileIDs are indexes into this table. To get from ID to an index,
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index 76e9340d1c067..b3aeebab16d27 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -330,6 +330,7 @@ void SourceManager::clearIDTables() {
   MainFileID = FileID();
   LocalSLocEntryTable.clear();
   LoadedSLocEntryTable.clear();
+  LocalLocOffsetTable.clear();
   SLocEntryLoaded.clear();
   SLocEntryOffsetLoaded.clear();
   LastLineNoFileIDQuery = FileID();
@@ -637,9 +638,11 @@ FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename,
     noteSLocAddressSpaceUsage(Diag);
     return FileID();
   }
+  assert(LocalSLocEntryTable.size() == LocalLocOffsetTable.size());
   LocalSLocEntryTable.push_back(
       SLocEntry::get(NextLocalOffset,
                      FileInfo::get(IncludePos, File, FileCharacter, Filename)));
+  LocalLocOffsetTable.push_back(NextLocalOffset);
   // We do a +1 here because we want a SourceLocation that means "the end of the
   // file", e.g. for the "no newline at the end of the file" diagnostic.
   NextLocalOffset += FileSize + 1;
@@ -691,7 +694,9 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo &Info,
     SLocEntryLoaded[Index] = SLocEntryOffsetLoaded[Index] = true;
     return SourceLocation::getMacroLoc(LoadedOffset);
   }
+  assert(LocalSLocEntryTable.size() == LocalLocOffsetTable.size());
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
+  LocalLocOffsetTable.push_back(NextLocalOffset);
   if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
       NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
     Diag.Report(diag::err_sloc_space_too_large);
@@ -830,10 +835,11 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
   // SLocOffset.
   unsigned LessIndex = 0;
   // upper bound of the search range.
-  unsigned GreaterIndex = LocalSLocEntryTable.size();
+  assert(LocalSLocEntryTable.size() == LocalLocOffsetTable.size());
+  unsigned GreaterIndex = LocalLocOffsetTable.size();
   if (LastFileIDLookup.ID >= 0) {
     // Use the LastFileIDLookup to prune the search space.
-    if (LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset)
+    if (LocalLocOffsetTable[LastFileIDLookup.ID] < SLocOffset)
       LessIndex = LastFileIDLookup.ID;
     else
       GreaterIndex = LastFileIDLookup.ID;
@@ -844,7 +850,7 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
   while (true) {
     --GreaterIndex;
     assert(GreaterIndex < LocalSLocEntryTable.size());
-    if (LocalSLocEntryTable[GreaterIndex].getOffset() <= SLocOffset) {
+    if (LocalLocOffsetTable[GreaterIndex] <= SLocOffset) {
       FileID Res = FileID::get(int(GreaterIndex));
       // Remember it.  We have good locality across FileID lookups.
       LastFileIDLookup = Res;
@@ -860,8 +866,7 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
 
     unsigned MiddleIndex = LessIndex + (GreaterIndex - LessIndex) / 2;
 
-    SourceLocation::UIntTy MidOffset =
-        getLocalSLocEntry(MiddleIndex).getOffset();
+    SourceLocation::UIntTy MidOffset = LocalLocOffsetTable[MiddleIndex];
 
     if (MidOffset <= SLocOffset)
       LessIndex = MiddleIndex + 1;

>From 98455475971a5f2d9ef6a2bc1945e05e7f12520c Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Mon, 30 Jun 2025 08:58:50 +0200
Subject: [PATCH 12/20] Revert the static_assert change for
 ObjCContainerDeclBitfields.

---
 clang/include/clang/AST/DeclBase.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index b136329fce15a..bdc92760ba092 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -2064,7 +2064,7 @@ class DeclContext {
                   "CXXConstructorDeclBitfields is larger than 8 bytes!");
     static_assert(sizeof(ObjCMethodDeclBitfields) <= 8,
                   "ObjCMethodDeclBitfields is larger than 8 bytes!");
-    static_assert(sizeof(ObjCContainerDeclBitfields) <= 16,
+    static_assert(sizeof(ObjCContainerDeclBitfields) <= 8,
                   "ObjCContainerDeclBitfields is larger than 8 bytes!");
     static_assert(sizeof(LinkageSpecDeclBitfields) <= 8,
                   "LinkageSpecDeclBitfields is larger than 8 bytes!");

>From 47940626b57b9d8e4c7f1677266d3729becc1d6d Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Mon, 30 Jun 2025 13:38:20 +0200
Subject: [PATCH 13/20] Fix the compile failures for include-cleaner.

---
 clang-tools-extra/include-cleaner/lib/HTMLReport.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/include-cleaner/lib/HTMLReport.cpp b/clang-tools-extra/include-cleaner/lib/HTMLReport.cpp
index b0a6c9565befd..1cc2db7031819 100644
--- a/clang-tools-extra/include-cleaner/lib/HTMLReport.cpp
+++ b/clang-tools-extra/include-cleaner/lib/HTMLReport.cpp
@@ -145,7 +145,7 @@ class Reporter {
   // Points within the main file that reference a Symbol.
   // Implicit refs will be marked with a symbol just before the token.
   struct Ref {
-    unsigned Offset;
+    uint64_t Offset;
     RefType Type;
     Symbol Sym;
     SmallVector<SymbolLocation> Locations = {};

>From 25aa128032a2ca725da1e5b55f66a0e5684e0882 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Mon, 30 Jun 2025 14:27:38 +0200
Subject: [PATCH 14/20] Fix clang-tidy build.

---
 .../readability/FunctionCognitiveComplexityCheck.cpp          | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp b/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp
index e1fb42b8210e2..ecde1f7c90080 100644
--- a/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp
@@ -127,12 +127,12 @@ struct CognitiveComplexity final {
   // https://sonarcloud.io/projects?languages=c%2Ccpp&size=5   we can estimate:
   // value ~20 would result in no allocs for 98% of functions, ~12 for 96%, ~10
   // for 91%, ~8 for 88%, ~6 for 84%, ~4 for 77%, ~2 for 64%, and ~1 for 37%.
-  static_assert(sizeof(Detail) <= 8,
+  static_assert(sizeof(Detail) <= 16,
                 "Since we use SmallVector to minimize the amount of "
                 "allocations, we also need to consider the price we pay for "
                 "that in terms of stack usage. "
                 "Thus, it is good to minimize the size of the Detail struct.");
-  SmallVector<Detail, DefaultLimit> Details; // 25 elements is 200 bytes.
+  SmallVector<Detail, DefaultLimit> Details; // 25 elements is 400 bytes.
   // Yes, 25 is a magic number. This is the seemingly-sane default for the
   // upper limit for function cognitive complexity. Thus it would make sense
   // to avoid allocations for any function that does not violate the limit.

>From 3527a02c2ba199acf17d4dd257e6a18696ffd941 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Mon, 30 Jun 2025 15:05:56 +0200
Subject: [PATCH 15/20] Fix clangd unittest

---
 clang-tools-extra/clangd/unittests/SourceCodeTests.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp b/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp
index 801d535c1b9d0..931241845c54a 100644
--- a/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp
@@ -829,7 +829,9 @@ TEST(SourceCodeTests, isSpelledInSource) {
   // FIXME: Should it return false on SourceLocation()? Does it matter?
   EXPECT_TRUE(isSpelledInSource(SourceLocation(), SM));
   EXPECT_FALSE(isSpelledInSource(
-      SourceLocation::getFromRawEncoding(SourceLocation::UIntTy(1 << 31)), SM));
+      SourceLocation::getFromRawEncoding(
+          SourceLocation::UIntTy(1ULL << (SourceLocation::Bits - 1))),
+      SM));
 }
 
 struct IncrementalTestStep {

>From 31c773f18b968fec89ed1bc1542d8dabbdfaa192 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Mon, 30 Jun 2025 23:07:29 +0200
Subject: [PATCH 16/20] Fix windows build failures.

unsigned long is 32 bits on MSVC
---
 clang/include/clang/AST/Stmt.h | 52 +++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 79991de6ed881..c99acde93f4a7 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -140,7 +140,7 @@ class alignas(void *) Stmt {
 
     /// The location of the semi-colon.Add commentMore actions
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long SemiLoc : SourceLocation::Bits;
+    uint64_t SemiLoc : SourceLocation::Bits;
   };
 
   class CompoundStmtBitfields {
@@ -165,7 +165,7 @@ class alignas(void *) Stmt {
     unsigned : NumStmtBits;
 
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long IdentLoc : SourceLocation::Bits;
+    uint64_t IdentLoc : SourceLocation::Bits;
   };
 
   class AttributedStmtBitfields {
@@ -204,7 +204,7 @@ class alignas(void *) Stmt {
 
     /// The location of the "if"
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long IfLoc : SourceLocation::Bits;
+    uint64_t IfLoc : SourceLocation::Bits;
   };
 
   class SwitchStmtBitfields {
@@ -229,7 +229,7 @@ class alignas(void *) Stmt {
 
     /// The location of the "switch".
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long SwitchLoc : SourceLocation::Bits;
+    uint64_t SwitchLoc : SourceLocation::Bits;
   };
 
   class WhileStmtBitfields {
@@ -245,7 +245,7 @@ class alignas(void *) Stmt {
 
     /// The location of the "while"
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long WhileLoc : SourceLocation::Bits;
+    uint64_t WhileLoc : SourceLocation::Bits;
   };
 
   class DoStmtBitfields {
@@ -256,7 +256,7 @@ class alignas(void *) Stmt {
 
     /// The location of the "do"
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long DoLoc : SourceLocation::Bits;
+    uint64_t DoLoc : SourceLocation::Bits;
   };
 
   class ForStmtBitfields {
@@ -267,7 +267,7 @@ class alignas(void *) Stmt {
 
     /// The location of the "for"
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long ForLoc : SourceLocation::Bits;
+    uint64_t ForLoc : SourceLocation::Bits;
   };
 
   class GotoStmtBitfields {
@@ -279,7 +279,7 @@ class alignas(void *) Stmt {
 
     /// The location of the "goto"
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long GotoLoc : SourceLocation::Bits;
+    uint64_t GotoLoc : SourceLocation::Bits;
   };
 
   class ContinueStmtBitfields {
@@ -290,7 +290,7 @@ class alignas(void *) Stmt {
 
     /// The location of the "continue"
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long ContinueLoc : SourceLocation::Bits;
+    uint64_t ContinueLoc : SourceLocation::Bits;
   };
 
   class BreakStmtBitfields {
@@ -301,7 +301,7 @@ class alignas(void *) Stmt {
 
     /// The location of the "break"
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long BreakLoc : SourceLocation::Bits;
+    uint64_t BreakLoc : SourceLocation::Bits;
   };
 
   class ReturnStmtBitfields {
@@ -316,7 +316,7 @@ class alignas(void *) Stmt {
 
     /// The location of the "return"
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long RetLoc : SourceLocation::Bits;
+    uint64_t RetLoc : SourceLocation::Bits;
   };
 
   class SwitchCaseBitfields {
@@ -333,7 +333,7 @@ class alignas(void *) Stmt {
 
     /// The location of the "case" or "default" keyword.
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long KeywordLoc : SourceLocation::Bits;
+    uint64_t KeywordLoc : SourceLocation::Bits;
   };
 
   //===--- Expression bitfields classes ---===//
@@ -550,7 +550,7 @@ class alignas(void *) Stmt {
     unsigned : NumExprBits;
 
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long RBracketLoc : SourceLocation::Bits;
+    uint64_t RBracketLoc : SourceLocation::Bits;
   };
 
   class CallExprBitfields {
@@ -705,7 +705,7 @@ class alignas(void *) Stmt {
 
     /// The location of the "_Generic"
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long GenericLoc : SourceLocation::Bits;
+    uint64_t GenericLoc : SourceLocation::Bits;
   };
 
   class PseudoObjectExprBitfields {
@@ -815,7 +815,7 @@ class alignas(void *) Stmt {
 
     /// The location of the boolean ligeral
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long Loc : SourceLocation::Bits;
+    uint64_t Loc : SourceLocation::Bits;
   };
 
   class CXXNullPtrLiteralExprBitfields {
@@ -826,7 +826,7 @@ class alignas(void *) Stmt {
 
     /// The location of the null pointer literal.
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long Loc : SourceLocation::Bits;
+    uint64_t Loc : SourceLocation::Bits;
   };
 
   class CXXThisExprBitfields {
@@ -846,7 +846,7 @@ class alignas(void *) Stmt {
 
     /// The location of the "this"
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long Loc : SourceLocation::Bits;
+    uint64_t Loc : SourceLocation::Bits;
   };
 
   class CXXThrowExprBitfields {
@@ -862,7 +862,7 @@ class alignas(void *) Stmt {
 
     /// The location of the "throw"
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long ThrowLoc : SourceLocation::Bits;
+    uint64_t ThrowLoc : SourceLocation::Bits;
   };
 
   class CXXDefaultArgExprBitfields {
@@ -878,7 +878,7 @@ class alignas(void *) Stmt {
 
     /// The location where the default argument expression was used.
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long Loc : SourceLocation::Bits;
+    uint64_t Loc : SourceLocation::Bits;
   };
 
   class CXXDefaultInitExprBitfields {
@@ -895,7 +895,7 @@ class alignas(void *) Stmt {
 
     /// The location where the default initializer expression was used.
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long Loc : SourceLocation::Bits;
+    uint64_t Loc : SourceLocation::Bits;
   };
 
   class CXXScalarValueInitExprBitfields {
@@ -907,7 +907,7 @@ class alignas(void *) Stmt {
 
     /// The location where the default initializer expression was used.
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long RParenLoc : SourceLocation::Bits;
+    uint64_t RParenLoc : SourceLocation::Bits;
   };
 
   class CXXNewExprBitfields {
@@ -984,7 +984,7 @@ class alignas(void *) Stmt {
 
     /// Location of the expression
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long Loc : SourceLocation::Bits;
+    uint64_t Loc : SourceLocation::Bits;
   };
 
   class TypeTraitExprBitfields {
@@ -1100,7 +1100,7 @@ class alignas(void *) Stmt {
     
     /// The location of the '->' or '.' operator.
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long OperatorLoc : SourceLocation::Bits;
+    uint64_t OperatorLoc : SourceLocation::Bits;
   };
 
   class OverloadExprBitfields {
@@ -1181,7 +1181,7 @@ class alignas(void *) Stmt {
 
     /// The location of the non-type template parameter reference.
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long NameLoc : SourceLocation::Bits;
+    uint64_t NameLoc : SourceLocation::Bits;
   };
 
   class LambdaExprBitfields {
@@ -1222,7 +1222,7 @@ class alignas(void *) Stmt {
     unsigned IsSatisfied : 1;
 
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long RequiresKWLoc : SourceLocation::Bits;
+    uint64_t RequiresKWLoc : SourceLocation::Bits;
   };
 
   class ArrayTypeTraitExprBitfields {
@@ -1316,7 +1316,7 @@ class alignas(void *) Stmt {
     
      /// The location of the non-type template parameter reference.
     LLVM_PREFERRED_TYPE(SourceLocation)
-    unsigned long Loc : SourceLocation::Bits;
+    uint64_t Loc : SourceLocation::Bits;
   };
 
   class ConvertVectorExprBitfields {

>From e63c9888ab1b803c0b8b97dc38f7e6d27be9bc8c Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Tue, 1 Jul 2025 08:17:50 +0200
Subject: [PATCH 17/20] More windows fix

---
 clang/include/clang/AST/Stmt.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index c99acde93f4a7..33430ce1a4a62 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -784,7 +784,7 @@ class alignas(void *) Stmt {
     friend class CXXOperatorCallExpr;
 
     LLVM_PREFERRED_TYPE(CallExprBitfields)
-    unsigned : NumCallExprBits;
+    uint64_t : NumCallExprBits;
 
     /// The kind of this overloaded operator. One of the enumerator
     /// value of OverloadedOperatorKind.
@@ -797,7 +797,7 @@ class alignas(void *) Stmt {
     friend class CXXRewrittenBinaryOperator;
 
     LLVM_PREFERRED_TYPE(CallExprBitfields)
-    unsigned : NumCallExprBits;
+    uint64_t : NumCallExprBits;
 
     LLVM_PREFERRED_TYPE(bool)
     unsigned IsReversed : 1;

>From 9dd6cdfe522ec4dfeadb784a25b67fa3860173c5 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Tue, 1 Jul 2025 09:23:32 +0200
Subject: [PATCH 18/20] Change the underlying StmtBitField type to uint64_t,
 fix windows failures.

So that the sizeof(Stmt) can stay with 8 bytes.
---
 clang/include/clang/AST/Stmt.h | 106 ++++++++++++++++-----------------
 1 file changed, 53 insertions(+), 53 deletions(-)

diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 33430ce1a4a62..513f2269f2fed 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -128,7 +128,7 @@ class alignas(void *) Stmt {
     friend class NullStmt;
 
     LLVM_PREFERRED_TYPE(StmtBitfields)
-    unsigned : NumStmtBits;
+    uint64_t : NumStmtBits;
 
     /// True if the null statement was preceded by an empty macro, e.g:
     /// @code
@@ -136,7 +136,7 @@ class alignas(void *) Stmt {
     ///   CALL(0);
     /// @endcode
     LLVM_PREFERRED_TYPE(bool)
-    unsigned HasLeadingEmptyMacro : 1;
+    uint64_t HasLeadingEmptyMacro : 1;
 
     /// The location of the semi-colon.Add commentMore actions
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -154,7 +154,7 @@ class alignas(void *) Stmt {
     /// floating-point features.
     LLVM_PREFERRED_TYPE(bool)
     unsigned HasFPFeatures : 1;
-
+  
     unsigned NumStmts;
   };
 
@@ -162,7 +162,7 @@ class alignas(void *) Stmt {
     friend class LabelStmt;
 
     LLVM_PREFERRED_TYPE(StmtBitfields)
-    unsigned : NumStmtBits;
+    uint64_t : NumStmtBits;
 
     LLVM_PREFERRED_TYPE(SourceLocation)
     uint64_t IdentLoc : SourceLocation::Bits;
@@ -184,23 +184,23 @@ class alignas(void *) Stmt {
     friend class IfStmt;
 
     LLVM_PREFERRED_TYPE(StmtBitfields)
-    unsigned : NumStmtBits;
+    uint64_t : NumStmtBits;
 
     /// Whether this is a constexpr if, or a consteval if, or neither.
     LLVM_PREFERRED_TYPE(IfStatementKind)
-    unsigned Kind : 3;
+    uint64_t Kind : 3;
 
     /// True if this if statement has storage for an else statement.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned HasElse : 1;
+    uint64_t HasElse : 1;
 
     /// True if this if statement has storage for a variable declaration.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned HasVar : 1;
+    uint64_t HasVar : 1;
 
     /// True if this if statement has storage for an init statement.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned HasInit : 1;
+    uint64_t HasInit : 1;
 
     /// The location of the "if"
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -211,21 +211,21 @@ class alignas(void *) Stmt {
     friend class SwitchStmt;
 
     LLVM_PREFERRED_TYPE(StmtBitfields)
-    unsigned : NumStmtBits;
+    uint64_t : NumStmtBits;
 
     /// True if the SwitchStmt has storage for an init statement.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned HasInit : 1;
+    uint64_t HasInit : 1;
 
     /// True if the SwitchStmt has storage for a condition variable.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned HasVar : 1;
+    uint64_t HasVar : 1;
 
     /// If the SwitchStmt is a switch on an enum value, records whether all
     /// the enum values were covered by CaseStmts.  The coverage information
     /// value is meant to be a hint for possible clients.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned AllEnumCasesCovered : 1;
+    uint64_t AllEnumCasesCovered : 1;
 
     /// The location of the "switch".
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -237,11 +237,11 @@ class alignas(void *) Stmt {
     friend class WhileStmt;
 
     LLVM_PREFERRED_TYPE(StmtBitfields)
-    unsigned : NumStmtBits;
+    uint64_t : NumStmtBits;
 
     /// True if the WhileStmt has storage for a condition variable.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned HasVar : 1;
+    uint64_t HasVar : 1;
 
     /// The location of the "while"
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -252,7 +252,7 @@ class alignas(void *) Stmt {
     friend class DoStmt;
 
     LLVM_PREFERRED_TYPE(StmtBitfields)
-    unsigned : NumStmtBits;
+    uint64_t : NumStmtBits;
 
     /// The location of the "do"
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -263,7 +263,7 @@ class alignas(void *) Stmt {
     friend class ForStmt;
 
     LLVM_PREFERRED_TYPE(StmtBitfields)
-    unsigned : NumStmtBits;
+    uint64_t : NumStmtBits;
 
     /// The location of the "for"
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -275,7 +275,7 @@ class alignas(void *) Stmt {
     friend class IndirectGotoStmt;
 
     LLVM_PREFERRED_TYPE(StmtBitfields)
-    unsigned : NumStmtBits;
+    uint64_t : NumStmtBits;
 
     /// The location of the "goto"
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -286,7 +286,7 @@ class alignas(void *) Stmt {
     friend class ContinueStmt;
 
     LLVM_PREFERRED_TYPE(StmtBitfields)
-    unsigned : NumStmtBits;
+    uint64_t : NumStmtBits;
 
     /// The location of the "continue"
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -297,7 +297,7 @@ class alignas(void *) Stmt {
     friend class BreakStmt;
 
     LLVM_PREFERRED_TYPE(StmtBitfields)
-    unsigned : NumStmtBits;
+    uint64_t : NumStmtBits;
 
     /// The location of the "break"
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -308,11 +308,11 @@ class alignas(void *) Stmt {
     friend class ReturnStmt;
 
     LLVM_PREFERRED_TYPE(StmtBitfields)
-    unsigned : NumStmtBits;
+    uint64_t : NumStmtBits;
 
     /// True if this ReturnStmt has storage for an NRVO candidate.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned HasNRVOCandidate : 1;
+    uint64_t HasNRVOCandidate : 1;
 
     /// The location of the "return"
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -324,12 +324,12 @@ class alignas(void *) Stmt {
     friend class CaseStmt;
 
     LLVM_PREFERRED_TYPE(StmtBitfields)
-    unsigned : NumStmtBits;
+    uint64_t : NumStmtBits;
 
     /// Used by CaseStmt to store whether it is a case statement
     /// of the form case LHS ... RHS (a GNU extension).
     LLVM_PREFERRED_TYPE(bool)
-    unsigned CaseStmtIsGNURange : 1;
+    uint64_t CaseStmtIsGNURange : 1;
 
     /// The location of the "case" or "default" keyword.
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -547,7 +547,7 @@ class alignas(void *) Stmt {
     friend class MatrixSubscriptExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     LLVM_PREFERRED_TYPE(SourceLocation)
     uint64_t RBracketLoc : SourceLocation::Bits;
@@ -701,7 +701,7 @@ class alignas(void *) Stmt {
     friend class GenericSelectionExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     /// The location of the "_Generic"
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -807,11 +807,11 @@ class alignas(void *) Stmt {
     friend class CXXBoolLiteralExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     /// The value of the boolean literal.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned Value : 1;
+    uint64_t Value : 1;
 
     /// The location of the boolean ligeral
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -822,7 +822,7 @@ class alignas(void *) Stmt {
     friend class CXXNullPtrLiteralExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     /// The location of the null pointer literal.
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -833,16 +833,16 @@ class alignas(void *) Stmt {
     friend class CXXThisExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     /// Whether this is an implicit "this".
     LLVM_PREFERRED_TYPE(bool)
-    unsigned IsImplicit : 1;
+    uint64_t IsImplicit : 1;
 
     /// Whether there is a lambda with an explicit object parameter that
     /// captures this "this" by copy.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned CapturedByCopyInLambdaWithExplicitObjectParameter : 1;
+    uint64_t CapturedByCopyInLambdaWithExplicitObjectParameter : 1;
 
     /// The location of the "this"
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -854,11 +854,11 @@ class alignas(void *) Stmt {
     friend class CXXThrowExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     /// Whether the thrown variable (if any) is in scope.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned IsThrownVariableInScope : 1;
+    uint64_t IsThrownVariableInScope : 1;
 
     /// The location of the "throw"
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -870,11 +870,11 @@ class alignas(void *) Stmt {
     friend class CXXDefaultArgExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     /// Whether this CXXDefaultArgExpr rewrote its argument and stores a copy.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned HasRewrittenInit : 1;
+    uint64_t HasRewrittenInit : 1;
 
     /// The location where the default argument expression was used.
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -886,12 +886,12 @@ class alignas(void *) Stmt {
     friend class CXXDefaultInitExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     /// Whether this CXXDefaultInitExprBitfields rewrote its argument and stores
     /// a copy.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned HasRewrittenInit : 1;
+    uint64_t HasRewrittenInit : 1;
 
     /// The location where the default initializer expression was used.
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -903,7 +903,7 @@ class alignas(void *) Stmt {
     friend class CXXScalarValueInitExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     /// The location where the default initializer expression was used.
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -961,26 +961,26 @@ class alignas(void *) Stmt {
     friend class CXXDeleteExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     /// Is this a forced global delete, i.e. "::delete"?
     LLVM_PREFERRED_TYPE(bool)
-    unsigned GlobalDelete : 1;
+    uint64_t GlobalDelete : 1;
 
     /// Is this the array form of delete, i.e. "delete[]"?
     LLVM_PREFERRED_TYPE(bool)
-    unsigned ArrayForm : 1;
+    uint64_t ArrayForm : 1;
 
     /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is
     /// applied to pointer-to-array type (ArrayFormAsWritten will be false
     /// while ArrayForm will be true).
     LLVM_PREFERRED_TYPE(bool)
-    unsigned ArrayFormAsWritten : 1;
+    uint64_t ArrayFormAsWritten : 1;
 
     /// Does the usual deallocation function for the element type require
     /// a size_t argument?
     LLVM_PREFERRED_TYPE(bool)
-    unsigned UsualArrayDeleteWantsSize : 1;
+    uint64_t UsualArrayDeleteWantsSize : 1;
 
     /// Location of the expression
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -1081,22 +1081,22 @@ class alignas(void *) Stmt {
     friend class CXXDependentScopeMemberExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     /// Whether this member expression used the '->' operator or
     /// the '.' operator.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned IsArrow : 1;
+    uint64_t IsArrow : 1;
 
     /// Whether this member expression has info for explicit template
     /// keyword and arguments.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned HasTemplateKWAndArgsInfo : 1;
+    uint64_t HasTemplateKWAndArgsInfo : 1;
 
     /// See getFirstQualifierFoundInScope() and the comment listing
     /// the trailing objects.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned HasFirstQualifierFoundInScope : 1;
+    uint64_t HasFirstQualifierFoundInScope : 1;
     
     /// The location of the '->' or '.' operator.
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -1177,7 +1177,7 @@ class alignas(void *) Stmt {
     friend class SubstNonTypeTemplateParmExpr;
     
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     /// The location of the non-type template parameter reference.
     LLVM_PREFERRED_TYPE(SourceLocation)
@@ -1216,10 +1216,10 @@ class alignas(void *) Stmt {
     friend class RequiresExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     LLVM_PREFERRED_TYPE(bool)
-    unsigned IsSatisfied : 1;
+    uint64_t IsSatisfied : 1;
 
     LLVM_PREFERRED_TYPE(SourceLocation)
     uint64_t RequiresKWLoc : SourceLocation::Bits;
@@ -1307,12 +1307,12 @@ class alignas(void *) Stmt {
     friend class OpaqueValueExpr;
 
     LLVM_PREFERRED_TYPE(ExprBitfields)
-    unsigned : NumExprBits;
+    uint64_t : NumExprBits;
 
     /// The OVE is a unique semantic reference to its source expression if this
     /// bit is set to true.
     LLVM_PREFERRED_TYPE(bool)
-    unsigned IsUnique : 1;
+    uint64_t IsUnique : 1;
     
      /// The location of the non-type template parameter reference.
     LLVM_PREFERRED_TYPE(SourceLocation)

>From 181420a8b0ce15c2d42def4a49f5f705276d45d0 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Tue, 1 Jul 2025 11:02:23 +0200
Subject: [PATCH 19/20] More window fix

---
 clang/include/clang/AST/Stmt.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 513f2269f2fed..9a363f25fc989 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -789,7 +789,7 @@ class alignas(void *) Stmt {
     /// The kind of this overloaded operator. One of the enumerator
     /// value of OverloadedOperatorKind.
     LLVM_PREFERRED_TYPE(OverloadedOperatorKind)
-    unsigned OperatorKind : 6;
+    uint64_t OperatorKind : 6;
   };
 
   class CXXRewrittenBinaryOperatorBitfields {
@@ -800,7 +800,7 @@ class alignas(void *) Stmt {
     uint64_t : NumCallExprBits;
 
     LLVM_PREFERRED_TYPE(bool)
-    unsigned IsReversed : 1;
+    uint64_t IsReversed : 1;
   };
 
   class CXXBoolLiteralExprBitfields {

>From 4379826b1ae28a775166b8481c87f04a8187ca60 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Tue, 1 Jul 2025 12:19:54 +0200
Subject: [PATCH 20/20] Fix merge failures

---
 clang/include/clang/AST/DeclarationName.h | 11 ++---------
 clang/lib/AST/ASTContext.cpp              |  4 ++--
 2 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/clang/include/clang/AST/DeclarationName.h b/clang/include/clang/AST/DeclarationName.h
index 20e504222c495..db7973bcc5bb7 100644
--- a/clang/include/clang/AST/DeclarationName.h
+++ b/clang/include/clang/AST/DeclarationName.h
@@ -703,8 +703,7 @@ class DeclarationNameLoc {
 
   // The location (if any) of the operator keyword is stored elsewhere.
   struct CXXOpName {
-    SourceLocation BeginOpNameLoc;
-    SourceLocation EndOpNameLoc;
+    CXXOperatorSourceInfo* OInfo;
   };
 
   // The location (if any) of the operator keyword is stored elsewhere.
@@ -724,12 +723,6 @@ class DeclarationNameLoc {
 
   void setNamedTypeLoc(TypeSourceInfo *TInfo) { NamedType.TInfo = TInfo; }
 
-  void setCXXOperatorNameRange(SourceRange Range) {
-    CXXOperatorName.BeginOpNameLoc = Range.getBegin();
-    CXXOperatorName.EndOpNameLoc = Range.getEnd();
-  }
-
-
   void setCXXLiteralOperatorNameLoc(SourceLocation Loc) {
     CXXLiteralOperatorName.OpNameLoc = Loc;
   }
@@ -755,7 +748,7 @@ class DeclarationNameLoc {
   SourceLocation getCXXOperatorNameEndLoc() const {
     if (!CXXOperatorName.OInfo)
       return {};
-    return CXXOperatorName.OInfo->EndOpNameLoc);
+    return CXXOperatorName.OInfo->EndOpNameLoc;
   }
 
   /// Return the range of the operator name (without the operator keyword).
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 840469d7cace3..689def9c6c38f 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3204,8 +3204,8 @@ CXXOperatorSourceInfo *
 ASTContext::getCXXOperatorSourceInfo(SourceRange R) const {
   auto *TInfo = (CXXOperatorSourceInfo *)BumpAlloc.Allocate(
       sizeof(CXXOperatorSourceInfo), 8);
-  TInfo->BeginOpNameLoc = R.getBegin().getRawEncoding();
-  TInfo->EndOpNameLoc = R.getEnd().getRawEncoding();
+  TInfo->BeginOpNameLoc = R.getBegin();
+  TInfo->EndOpNameLoc = R.getEnd();
   return TInfo;
 }
 



More information about the cfe-commits mailing list