[clang] [Clang] support storage-class specifiers in C23 compound literals (PR #212559)

Oleksandr Tarasiuk via cfe-commits cfe-commits at lists.llvm.org
Sun Sep 13 12:19:16 PDT 2026


https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/212559

>From 0c41fd3fcbbdd487201d26a0fbadbebf24c4b669 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Tue, 28 Jul 2026 17:14:33 +0300
Subject: [PATCH 01/21] [Clang] support storage-class specifiers in C23
 compound literals

---
 clang/docs/ReleaseNotes.md                    |   2 +
 clang/include/clang/AST/Expr.h                |  66 +++-
 clang/include/clang/AST/Stmt.h                |  17 +
 .../clang/Basic/DiagnosticParseKinds.td       |   4 +
 .../clang/Basic/DiagnosticSemaKinds.td        |  18 +-
 clang/include/clang/Parse/Parser.h            |   6 +-
 clang/include/clang/Sema/DelayedDiagnostic.h  |  15 +-
 clang/include/clang/Sema/Initialization.h     |  24 +-
 clang/include/clang/Sema/Scope.h              |   6 +-
 clang/include/clang/Sema/Sema.h               |  24 +-
 clang/lib/AST/ASTImporter.cpp                 |   6 +-
 clang/lib/AST/Expr.cpp                        |   9 +-
 clang/lib/AST/ExprConstant.cpp                |  93 +++--
 clang/lib/AST/StmtPrinter.cpp                 |  24 +-
 clang/lib/AST/StmtProfile.cpp                 |   3 +
 clang/lib/CodeGen/CGExpr.cpp                  |  17 +-
 clang/lib/CodeGen/CGExprAgg.cpp               |   7 +-
 clang/lib/CodeGen/CGExprConstant.cpp          |  10 +-
 clang/lib/CodeGen/CodeGenFunction.cpp         |   4 +-
 clang/lib/Parse/ParseExpr.cpp                 |  98 ++++-
 clang/lib/Sema/CheckExprLifetime.cpp          |   3 +-
 clang/lib/Sema/DelayedDiagnostic.cpp          |   1 +
 clang/lib/Sema/Scope.cpp                      |  15 +-
 clang/lib/Sema/SemaDecl.cpp                   |  39 +-
 clang/lib/Sema/SemaDeclAttr.cpp               |   8 +
 clang/lib/Sema/SemaExpr.cpp                   | 370 ++++++++++++------
 clang/lib/Sema/SemaInit.cpp                   |  45 ++-
 clang/lib/Sema/TreeTransform.h                |  18 +-
 clang/lib/Serialization/ASTReaderStmt.cpp     |   3 +
 clang/lib/Serialization/ASTWriterStmt.cpp     |   3 +
 clang/test/AST/c23-compound-literal-print.c   |  33 ++
 clang/test/C/drs/dr3xx.c                      |   1 +
 clang/test/CodeGen/c23-compound-literal.c     | 275 +++++++++++++
 clang/test/CodeGenObjC/c23-compound-literal.m |  19 +
 clang/test/Parser/expressions.c               |  18 +-
 clang/test/Sema/c23-compound-literal.c        | 343 ++++++++++++++++
 clang/test/Sema/c23-compound-literal.m        |  11 +
 clang/test/Sema/constexpr.c                   |   2 +-
 38 files changed, 1418 insertions(+), 242 deletions(-)
 create mode 100644 clang/test/AST/c23-compound-literal-print.c
 create mode 100644 clang/test/CodeGen/c23-compound-literal.c
 create mode 100644 clang/test/CodeGenObjC/c23-compound-literal.m
 create mode 100644 clang/test/Sema/c23-compound-literal.c
 create mode 100644 clang/test/Sema/c23-compound-literal.m

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index c348ddaf23017..bd7689b2fc3c3 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -142,6 +142,8 @@ features cannot lower the translation-unit ABI level;
 
 #### C23 Feature Support
 
+- Clang now supports storage-class specifiers in compound literals. (#GH129365)
+
 ### Objective-C Language Changes
 
 ### Non-comprehensive list of changes in this release
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index f95f87cc4e8e0..6454a750b61c9 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -765,6 +765,8 @@ class Expr : public ValueStmt {
     /// evaluation is not part of the evaluation, but all other temporaries
     /// are destroyed.
     ImmediateInvocation,
+    /// The initializer of a compound literal constant.
+    CompoundLiteralInitializer,
   };
 
   /// Evaluate an expression that is required to be a constant expression. Does
@@ -3606,7 +3608,7 @@ class MemberExpr final
   }
 };
 
-/// CompoundLiteralExpr - [C99 6.5.2.5]
+/// CompoundLiteralExpr - [C99 6.5.2.5, C23 6.5.3.6]
 ///
 class CompoundLiteralExpr : public Expr {
   /// LParenLoc - If non-null, this is the location of the left paren in a
@@ -3624,11 +3626,20 @@ class CompoundLiteralExpr : public Expr {
   mutable APValue *StaticValue = nullptr;
 
 public:
-  CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo,
-                      QualType T, ExprValueKind VK, Expr *init, bool fileScope)
+  CompoundLiteralExpr(
+      SourceLocation LParenLoc, TypeSourceInfo *TInfo, QualType T,
+      ExprValueKind VK, Expr *Init, bool FileScope, StorageClass SC = SC_None,
+      ThreadStorageClassSpecifier TSC = TSCS_unspecified,
+      ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified)
       : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary),
-        LParenLoc(lparenloc), TInfoAndScope(tinfo, fileScope), Init(init) {
+        LParenLoc(LParenLoc), TInfoAndScope(TInfo, FileScope), Init(Init) {
     assert(Init && "Init is a nullptr");
+    assert((ConstexprKind == ConstexprSpecKind::Unspecified ||
+            ConstexprKind == ConstexprSpecKind::Constexpr) &&
+           "invalid compound literal constexpr specifier");
+    setStorageClass(SC);
+    setTSCSpec(TSC);
+    setConstexpr(ConstexprKind == ConstexprSpecKind::Constexpr);
     setDependence(computeDependence(this));
   }
 
@@ -3649,11 +3660,52 @@ class CompoundLiteralExpr : public Expr {
   TypeSourceInfo *getTypeSourceInfo() const {
     return TInfoAndScope.getPointer();
   }
-  void setTypeSourceInfo(TypeSourceInfo *tinfo) {
-    TInfoAndScope.setPointer(tinfo);
+
+  void setTypeSourceInfo(TypeSourceInfo *TInfo) {
+    TInfoAndScope.setPointer(TInfo);
+  }
+
+  bool hasStaticStorage() const {
+    return isGLValue() && !hasThreadStorage() &&
+           (isFileScope() || getStorageClass() == SC_Static);
+  }
+
+  bool hasThreadStorage() const { return getTSCSpec() != TSCS_unspecified; }
+
+  bool hasGlobalStorage() const {
+    return hasStaticStorage() || hasThreadStorage();
+  }
+
+  StorageClass getStorageClass() const {
+    return static_cast<StorageClass>(CompoundLiteralExprBits.SClass);
+  }
+
+  void setStorageClass(StorageClass SC) {
+    assert((SC == SC_None || SC == SC_Static || SC == SC_Register) &&
+           "invalid compound literal storage class");
+    CompoundLiteralExprBits.SClass = SC;
+    assert(getStorageClass() == SC && "truncation");
+  }
+
+  ThreadStorageClassSpecifier getTSCSpec() const {
+    return static_cast<ThreadStorageClassSpecifier>(
+        CompoundLiteralExprBits.TSCSpec);
+  }
+
+  void setTSCSpec(ThreadStorageClassSpecifier TSC) {
+    assert((TSC == TSCS_unspecified || TSC == TSCS_thread_local ||
+            TSC == TSCS__Thread_local) &&
+           "invalid compound literal thread storage class");
+    CompoundLiteralExprBits.TSCSpec = TSC;
+    assert(getTSCSpec() == TSC && "truncation");
+  }
+
+  bool isConstexpr() const { return CompoundLiteralExprBits.IsConstexpr; }
+
+  void setConstexpr(bool IsConstexpr) {
+    CompoundLiteralExprBits.IsConstexpr = IsConstexpr;
   }
 
-  bool hasStaticStorage() const { return isFileScope() && isGLValue(); }
   APValue &getOrCreateStaticValue(ASTContext &Ctx) const;
   APValue &getStaticValue() const;
 
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 69db8252f931e..791def70e72fd 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -668,6 +668,22 @@ class alignas(void *) Stmt {
     SourceLocation OpLoc;
   };
 
+  class CompoundLiteralExprBitfields {
+    friend class CompoundLiteralExpr;
+
+    LLVM_PREFERRED_TYPE(ExprBitfields)
+    unsigned : NumExprBits;
+
+    LLVM_PREFERRED_TYPE(StorageClass)
+    unsigned SClass : 3;
+
+    LLVM_PREFERRED_TYPE(ThreadStorageClassSpecifier)
+    unsigned TSCSpec : 2;
+
+    LLVM_PREFERRED_TYPE(bool)
+    unsigned IsConstexpr : 1;
+  };
+
   class InitListExprBitfields {
     friend class ASTStmtReader;
     friend class InitListExpr;
@@ -1363,6 +1379,7 @@ class alignas(void *) Stmt {
     MemberExprBitfields MemberExprBits;
     CastExprBitfields CastExprBits;
     BinaryOperatorBitfields BinaryOperatorBits;
+    CompoundLiteralExprBitfields CompoundLiteralExprBits;
     InitListExprBitfields InitListExprBits;
     ParenListExprBitfields ParenListExprBits;
     GenericSelectionExprBitfields GenericSelectionExprBits;
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 2672bfb2952c8..17ba28c5c094c 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -185,6 +185,10 @@ def warn_c11_compat_keyword : Warning<
 def warn_c23_compat_keyword : Warning<
  "'%0' is incompatible with C standards before C23">,
  InGroup<CPre23Compat>, DefaultIgnore;
+def warn_c23_compat_compound_literal_storage_class : Warning<
+  "compound literal storage-class specifiers are incompatible with C "
+  "standards before C23">,
+  InGroup<CPre23Compat>, DefaultIgnore;
 def warn_c2y_compat_keyword : Warning<
   "'%0' is incompatible with C standards before C2y">,
   InGroup<CPre2yCompat>, DefaultIgnore;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index cce6f70a58893..85528249c4be4 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2471,7 +2471,8 @@ def err_init_conversion_failed : Error<
   "base class|a constructor delegation|a vector element|a matrix element|a "
   "block element|a block element|a complex element|a lambda capture|a compound"
   " literal initializer|a related result|a parameter of CF audited function|a "
-  "structured binding|a member subobject}0 "
+  "structured binding|a member subobject|a constexpr compound literal "
+  "initializer}0 "
   "%diff{of type $ with an %select{rvalue|lvalue}2 of type $|"
   "with an %select{rvalue|lvalue}2 of incompatible type}1,3"
   "%select{|: different classes%diff{ ($ vs $)|}5,6"
@@ -3177,6 +3178,15 @@ def err_c23_constexpr_init_type_mismatch : Error<
   "constexpr initializer for type %0 is of type %1">;
 def err_c23_constexpr_pointer_not_null : Error<
   "constexpr pointer initializer is not null">;
+def err_register_compound_literal_file_scope : Error<
+  "file-scope compound literal specifies 'register'">;
+def err_thread_local_compound_literal_without_static : Error<
+  "compound literal with 'thread_local' storage duration at block scope must "
+  "also specify 'static'">;
+def err_constexpr_compound_literal_invalid_type : Error<
+  "constexpr compound literal cannot have type %0">;
+def err_compound_literal_initializer_not_constant : Error<
+  "initializer of compound literal must be a constant expression">;
 
 // C++ Concepts
 def err_concept_decls_may_only_appear_in_global_namespace_scope : Error<
@@ -3761,6 +3771,9 @@ def err_aix_attr_unsupported : Error<"%0 attribute is not yet supported on AIX">
 def err_tls_var_aligned_over_maximum : Error<
   "alignment (%0) of thread-local variable %1 is greater than the maximum supported "
   "alignment (%2) for a thread-local variable on this target">;
+def err_tls_compound_literal_aligned_over_maximum : Error<
+  "alignment (%0) of thread-local compound literal is greater than the maximum "
+  "supported alignment (%1) for thread-local storage on this target">;
 
 def err_only_annotate_after_access_spec : Error<
   "access specifier can only have annotation attributes">;
@@ -7950,7 +7963,8 @@ def err_typecheck_sclass_func : Error<"illegal storage class on function">;
 def err_static_block_func : Error<
   "function declared in block scope cannot have 'static' storage class">;
 def err_typecheck_address_of : Error<"address of %select{bit-field"
-  "|vector element|property expression|register variable|matrix element}0 requested">;
+  "|vector element|property expression|register variable|matrix element"
+  "|register compound literal}0 requested">;
 def ext_typecheck_addrof_void : Extension<
   "ISO C forbids taking the address of an expression of type 'void'">;
 def err_unqualified_pointer_member_function : Error<
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 163aa483a84e3..43c88344fbb2e 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -4294,7 +4294,8 @@ class Parser : public CodeCompletionHandler {
   /// \endverbatim
   ExprResult ParseCompoundLiteralExpression(ParsedType Ty,
                                             SourceLocation LParenLoc,
-                                            SourceLocation RParenLoc);
+                                            SourceLocation RParenLoc,
+                                            const DeclSpec *DS = nullptr);
 
   /// ParseGenericSelectionExpression - Parse a C11 generic-selection
   /// [C11 6.5.1.1].
@@ -5091,6 +5092,9 @@ class Parser : public CodeCompletionHandler {
     return isTypeIdInParens(isAmbiguous);
   }
 
+  bool isCompoundLiteralStorageClassSpecifier(const Token &Tok) const;
+  void ParseCompoundLiteralStorageClassSpecifiers(DeclSpec &DS);
+
   /// Finish parsing a C++ unqualified-id that is a template-id of
   /// some form.
   ///
diff --git a/clang/include/clang/Sema/DelayedDiagnostic.h b/clang/include/clang/Sema/DelayedDiagnostic.h
index 0105089a393f1..914fb2d6bc370 100644
--- a/clang/include/clang/Sema/DelayedDiagnostic.h
+++ b/clang/include/clang/Sema/DelayedDiagnostic.h
@@ -125,7 +125,12 @@ class AccessedEntity {
 /// the complete parsing of the current declaration.
 class DelayedDiagnostic {
 public:
-  enum DDKind : unsigned char { Availability, Access, ForbiddenType };
+  enum DDKind : unsigned char {
+    Availability,
+    Access,
+    ForbiddenType,
+    ForbiddenStatic
+  };
 
   DDKind Kind;
   bool Triggered;
@@ -167,6 +172,14 @@ class DelayedDiagnostic {
     return DD;
   }
 
+  static DelayedDiagnostic makeForbiddenStatic(SourceLocation Loc) {
+    DelayedDiagnostic DD;
+    DD.Kind = ForbiddenStatic;
+    DD.Triggered = false;
+    DD.Loc = Loc;
+    return DD;
+  }
+
   AccessedEntity &getAccessData() {
     assert(Kind == Access && "Not an access diagnostic.");
     return *reinterpret_cast<AccessedEntity*>(AccessData);
diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h
index 2c2df1f03747b..b338151cded83 100644
--- a/clang/include/clang/Sema/Initialization.h
+++ b/clang/include/clang/Sema/Initialization.h
@@ -131,6 +131,9 @@ class alignas(8) InitializedEntity {
     /// object initialized via parenthesized aggregate initialization.
     EK_ParenAggInitMember,
 
+    /// The entity initialized by a constexpr compound literal.
+    EK_ConstexprCompoundLiteralInit,
+
     // Note: err_init_conversion_failed in DiagnosticSemaKinds.td uses this
     // enum as an index for its first %select.  When modifying this list,
     // that diagnostic text needs to be updated as well.
@@ -216,8 +219,8 @@ class alignas(8) InitializedEntity {
     /// integer indicating whether the parameter is "consumed".
     llvm::PointerIntPair<ParmVarDecl *, 1> Parameter;
 
-    /// When Kind == EK_Temporary or EK_CompoundLiteralInit, the type
-    /// source information for the temporary.
+    /// When Kind is EK_Temporary, EK_CompoundLiteralInit, or
+    /// EK_ConstexprCompoundLiteralInit, the type source information.
     TypeSourceInfo *TypeInfo;
 
     struct LN LocAndNRVO;
@@ -465,13 +468,21 @@ class alignas(8) InitializedEntity {
   }
 
   /// Create the entity for a compound literal initializer.
-  static InitializedEntity InitializeCompoundLiteralInit(TypeSourceInfo *TSI) {
-    InitializedEntity Result(EK_CompoundLiteralInit, SourceLocation(),
-                             TSI->getType());
+  static InitializedEntity
+  InitializeCompoundLiteralInit(TypeSourceInfo *TSI, QualType Type,
+                                ConstexprSpecKind ConstexprKind) {
+    InitializedEntity Result(ConstexprKind == ConstexprSpecKind::Constexpr
+                                 ? EK_ConstexprCompoundLiteralInit
+                                 : EK_CompoundLiteralInit,
+                             SourceLocation(), Type);
     Result.TypeInfo = TSI;
     return Result;
   }
 
+  bool isConstexprCompoundLiteral() const {
+    return Kind == EK_ConstexprCompoundLiteralInit;
+  }
+
   /// Determine the kind of initialization.
   EntityKind getKind() const { return Kind; }
 
@@ -486,7 +497,8 @@ class alignas(8) InitializedEntity {
   /// Retrieve complete type-source information for the object being
   /// constructed, if known.
   TypeSourceInfo *getTypeSourceInfo() const {
-    if (Kind == EK_Temporary || Kind == EK_CompoundLiteralInit)
+    if (Kind == EK_Temporary || Kind == EK_CompoundLiteralInit ||
+        Kind == EK_ConstexprCompoundLiteralInit)
       return TypeInfo;
 
     return nullptr;
diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index 58ca2c0738f3c..4f69a18fb72a5 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -632,8 +632,10 @@ class Scope {
   /// loops where the condition follows the loop body.
   void LeaveLoopBody();
 
-  /// containedInPrototypeScope - Return true if this or a parent scope
-  /// is a FunctionPrototypeScope.
+  /// Return the innermost function prototype scope containing this scope.
+  const Scope *getEnclosingFunctionPrototypeScope() const;
+
+  /// Return true if this or a parent scope is a function prototype scope.
   bool containedInPrototypeScope() const;
 
   void PushUsingDirective(UsingDirectiveDecl *UDir) {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index d46edeb0d2872..45955c40756be 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4051,6 +4051,8 @@ class Sema final : public SemaBase {
   /// Returns true if the variable declaration is a redeclaration.
   bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
   void CheckVariableDeclarationType(VarDecl *NewVD);
+  bool CheckConstexprType(SourceLocation Loc, QualType T, unsigned DiagID);
+  void DiagnoseStaticInInline(SourceLocation Loc, const FunctionDecl *FD);
   void CheckCompleteVariableDeclaration(VarDecl *VD);
 
   NamedDecl *ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
@@ -7595,13 +7597,23 @@ class Sema final : public SemaBase {
   /// the ParenListExpr into a sequence of comma binary operators.
   ExprResult MaybeConvertParenListExprToParenExpr(Scope *S, Expr *ME);
 
-  ExprResult ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
-                                  SourceLocation RParenLoc, Expr *InitExpr);
+private:
+  ExprResult BuildCompoundLiteralExpr(
+      SourceLocation LParenLoc, TypeSourceInfo *TInfo, SourceLocation RParenLoc,
+      Expr *LiteralExpr, StorageClass SC, SourceLocation StorageClassLoc,
+      ThreadStorageClassSpecifier TSC, SourceLocation ThreadStorageClassLoc,
+      ConstexprSpecKind ConstexprKind, SourceLocation ConstexprLoc);
 
-  ExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc,
-                                      TypeSourceInfo *TInfo,
-                                      SourceLocation RParenLoc,
-                                      Expr *LiteralExpr);
+public:
+  ExprResult ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
+                                  SourceLocation RParenLoc, Expr *InitExpr,
+                                  const DeclSpec *DS = nullptr);
+
+  ExprResult BuildCompoundLiteralExpr(
+      SourceLocation LParenLoc, TypeSourceInfo *TInfo, SourceLocation RParenLoc,
+      Expr *LiteralExpr, StorageClass SC = SC_None,
+      ThreadStorageClassSpecifier TSC = TSCS_unspecified,
+      ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified);
 
   ExprResult ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,
                            SourceLocation RBraceLoc);
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 3ad71a223903c..97261a632390b 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -8100,8 +8100,10 @@ ExpectedStmt ASTNodeImporter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
     return std::move(Err);
 
   return new (Importer.getToContext()) CompoundLiteralExpr(
-        ToLParenLoc, ToTypeSourceInfo, ToType, E->getValueKind(),
-        ToInitializer, E->isFileScope());
+      ToLParenLoc, ToTypeSourceInfo, ToType, E->getValueKind(), ToInitializer,
+      E->isFileScope(), E->getStorageClass(), E->getTSCSpec(),
+      E->isConstexpr() ? ConstexprSpecKind::Constexpr
+                       : ConstexprSpecKind::Unspecified);
 }
 
 ExpectedStmt ASTNodeImporter::VisitAtomicExpr(AtomicExpr *E) {
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 9a9a76e265f6a..de6aaf503f767 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -3416,8 +3416,13 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
     // This handles gcc's extension that allows global initializers like
     // "struct x {int x;} x = (struct x) {};".
     // FIXME: This accepts other cases it shouldn't!
-    const Expr *Exp = cast<CompoundLiteralExpr>(this)->getInitializer();
-    return Exp->isConstantInitializer(Ctx, false, Culprit);
+    const auto *CLE = cast<CompoundLiteralExpr>(this);
+    if (CLE->hasThreadStorage()) {
+      if (Culprit)
+        *Culprit = this;
+      return false;
+    }
+    return CLE->getInitializer()->isConstantInitializer(Ctx, false, Culprit);
   }
   case DesignatedInitUpdateExprClass: {
     const DesignatedInitUpdateExpr *DIUE = cast<DesignatedInitUpdateExpr>(this);
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index a3385d3b7318f..c5d31c96c980f 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -157,6 +157,7 @@ namespace {
     case ConstantExprKind::Normal:
     case ConstantExprKind::ClassTemplateArgument:
     case ConstantExprKind::ImmediateInvocation:
+    case ConstantExprKind::CompoundLiteralInitializer:
       // Note that non-type template arguments of class type are emitted as
       // template parameter objects.
       return false;
@@ -171,6 +172,7 @@ namespace {
     switch (Kind) {
     case ConstantExprKind::Normal:
     case ConstantExprKind::ImmediateInvocation:
+    case ConstantExprKind::CompoundLiteralInitializer:
       return false;
 
     case ConstantExprKind::ClassTemplateArgument:
@@ -813,6 +815,8 @@ namespace {
     /// not supported by the interpreter, an error is triggered.
     bool EnableNewConstInterp;
 
+    ConstantExprKind ConstantKind;
+
     /// BottomFrame - The frame in which evaluation started. This must be
     /// initialized after CurrentCall and CallStackDepth.
     CallStackFrame BottomFrame;
@@ -913,11 +917,13 @@ namespace {
     /// initialization.
     uint64_t ArrayInitIndex = -1;
 
-    EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode)
+    EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode,
+             ConstantExprKind Kind = ConstantExprKind::Normal)
         : State(const_cast<ASTContext &>(C), S), CurrentCall(nullptr),
           CallStackDepth(0), NextCallIndex(1),
           StepsLeft(C.getLangOpts().ConstexprStepLimit),
           EnableNewConstInterp(C.getLangOpts().EnableNewConstInterp),
+          ConstantKind(Kind),
           BottomFrame(*this, SourceLocation(), /*Callee=*/nullptr,
                       /*This=*/nullptr,
                       /*CallExpr=*/nullptr, CallRef()),
@@ -1980,7 +1986,7 @@ static bool IsGlobalLValue(APValue::LValueBase B) {
     return false;
   case Expr::CompoundLiteralExprClass: {
     const CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
-    return CLE->isFileScope() && CLE->isLValue();
+    return CLE->hasStaticStorage() && CLE->isLValue();
   }
   case Expr::MaterializeTemporaryExprClass:
     // A materialized temporary might have been lifetime-extended to static
@@ -4653,6 +4659,11 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
   }
 
   bool IsAccess = isAnyAccess(AK);
+  bool IsConstexprInitializer =
+      Info.ConstantKind == ConstantExprKind::CompoundLiteralInitializer;
+  if (const auto *VD = dyn_cast_if_present<VarDecl>(
+          Info.EvaluatingDecl.dyn_cast<const ValueDecl *>()))
+    IsConstexprInitializer |= VD->isConstexpr();
 
   // C++11 DR1311: An lvalue-to-rvalue conversion on a volatile-qualified type
   // is not a constant expression (even if the object is non-volatile). We also
@@ -4731,11 +4742,6 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
     }
 
     bool IsConstant = BaseType.isConstant(Info.Ctx);
-    bool ConstexprVar = false;
-    if (const auto *VD = dyn_cast_if_present<VarDecl>(
-            Info.EvaluatingDecl.dyn_cast<const ValueDecl *>()))
-      ConstexprVar = VD->isConstexpr();
-
     // Unless we're looking at a local variable or argument in a constexpr call,
     // the variable we're reading must be const (unless we are binding to a
     // reference).
@@ -4755,7 +4761,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
         return CompleteObject();
       } else if (VD->isConstexpr()) {
         // OK, we can read this variable.
-      } else if (Info.getLangOpts().C23 && ConstexprVar) {
+      } else if (Info.getLangOpts().C23 && IsConstexprInitializer) {
         Info.FFDiag(E);
         return CompleteObject();
       } else if (BaseType->isIntegralOrEnumerationType()) {
@@ -4879,6 +4885,14 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
         assert(BaseVal && "got reference to unevaluated temporary");
       } else if (const CompoundLiteralExpr *CLE =
                      dyn_cast_or_null<CompoundLiteralExpr>(Base)) {
+        if (CLE->hasThreadStorage()) {
+          if (IsAccess) {
+            Info.FFDiag(E);
+            return CompleteObject();
+          }
+          return CompleteObject(LVal.getLValueBase(), nullptr, BaseType);
+        }
+
         // According to GCC info page:
         //
         // 6.28 Compound Literals
@@ -9754,6 +9768,11 @@ bool
 LValueExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
   assert((!Info.getLangOpts().CPlusPlus || E->isFileScope()) &&
          "lvalue compound literal in c++?");
+  if (E->hasThreadStorage()) {
+    Info.FFDiag(E);
+    return false;
+  }
+
   APValue *Lit;
   // If CompountLiteral has static storage, its value can be used outside
   // this expression. So evaluate it once and store it in ASTContext.
@@ -21977,13 +21996,14 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
   assert(!isValueDependent() &&
          "Expression evaluator can't be called on a dependent expression.");
   bool IsConst;
-  if (FastEvaluateAsRValue(this, Result.Val, Ctx, IsConst) &&
+  if (Kind != ConstantExprKind::CompoundLiteralInitializer &&
+      FastEvaluateAsRValue(this, Result.Val, Ctx, IsConst) &&
       Result.Val.hasValue())
     return true;
 
   ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateAsConstantExpr");
   EvaluationMode EM = EvaluationMode::ConstantExpression;
-  EvalInfo Info(Ctx, Result, EM);
+  EvalInfo Info(Ctx, Result, EM, Kind);
   Info.InConstantContext = true;
 
   if (Info.EnableNewConstInterp) {
@@ -22278,6 +22298,27 @@ static ICEDiag CheckEvalInICE(const Expr* E, const ASTContext &Ctx) {
   return NoDiag();
 }
 
+static const Expr *getMemberAccess(const Expr *E) {
+  E = E->IgnoreParenImpCasts();
+  while (const auto *ME = dyn_cast<MemberExpr>(E)) {
+    if (ME->isArrow())
+      return nullptr;
+    E = ME->getBase()->IgnoreParenImpCasts();
+  }
+  return E;
+}
+
+static bool isConstexprNamedConstant(const Expr *E) {
+  const auto *DRE = dyn_cast_or_null<DeclRefExpr>(getMemberAccess(E));
+  const auto *VD = DRE ? dyn_cast<VarDecl>(DRE->getDecl()) : nullptr;
+  return VD && VD->isConstexpr();
+}
+
+static bool isCompoundLiteralConstant(const Expr *E) {
+  const auto *CLE = dyn_cast_or_null<CompoundLiteralExpr>(getMemberAccess(E));
+  return CLE && CLE->isConstexpr();
+}
+
 static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
   assert(!E->isValueDependent() && "Should not see value dependent exprs!");
   if (!E->getType()->isIntegralOrEnumerationType())
@@ -22288,6 +22329,13 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
 #define STMT(Node, Base) case Expr::Node##Class:
 #define EXPR(Node, Base)
 #include "clang/AST/StmtNodes.inc"
+  case Expr::CompoundLiteralExprClass: {
+    const CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
+    if (CLE->isConstexpr())
+      return CheckEvalInICE(E, Ctx);
+    return ICEDiag(IK_NotICE, E->getBeginLoc());
+  }
+
   case Expr::PredefinedExprClass:
   case Expr::FloatingLiteralClass:
   case Expr::ImaginaryLiteralClass:
@@ -22299,7 +22347,6 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
   case Expr::OMPArrayShapingExprClass:
   case Expr::OMPIteratorExprClass:
   case Expr::CompoundAssignOperatorClass:
-  case Expr::CompoundLiteralExprClass:
   case Expr::ExtVectorElementExprClass:
   case Expr::MatrixElementExprClass:
   case Expr::DesignatedInitExprClass:
@@ -22377,20 +22424,9 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
     return ICEDiag(IK_NotICE, E->getBeginLoc());
 
   case Expr::MemberExprClass: {
-    if (Ctx.getLangOpts().C23) {
-      const Expr *ME = E->IgnoreParenImpCasts();
-      while (const auto *M = dyn_cast<MemberExpr>(ME)) {
-        if (M->isArrow())
-          return ICEDiag(IK_NotICE, E->getBeginLoc());
-        ME = M->getBase()->IgnoreParenImpCasts();
-      }
-      const auto *DRE = dyn_cast<DeclRefExpr>(ME);
-      if (DRE) {
-        if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
-            VD && VD->isConstexpr())
-          return CheckEvalInICE(E, Ctx);
-      }
-    }
+    if (Ctx.getLangOpts().C23 &&
+        (isConstexprNamedConstant(E) || isCompoundLiteralConstant(E)))
+      return CheckEvalInICE(E, Ctx);
     return ICEDiag(IK_NotICE, E->getBeginLoc());
   }
 
@@ -22629,8 +22665,8 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
   case Expr::ObjCBridgedCastExprClass: {
     const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr();
     if (isa<ExplicitCastExpr>(E)) {
-      if (const FloatingLiteral *FL
-            = dyn_cast<FloatingLiteral>(SubExpr->IgnoreParenImpCasts())) {
+      const Expr *Sub = SubExpr->IgnoreParenImpCasts();
+      if (const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(Sub)) {
         unsigned DestWidth = Ctx.getIntWidth(E->getType());
         bool DestSigned = E->getType()->isSignedIntegerOrEnumerationType();
         APSInt IgnoredVal(DestWidth, !DestSigned);
@@ -22644,6 +22680,9 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
           return ICEDiag(IK_NotICE, E->getBeginLoc());
         return NoDiag();
       }
+      if (Ctx.getLangOpts().C23 && Sub->getType()->isArithmeticType() &&
+          (isConstexprNamedConstant(Sub) || isCompoundLiteralConstant(Sub)))
+        return CheckEvalInICE(E, Ctx);
     }
     switch (cast<CastExpr>(E)->getCastKind()) {
     case CK_LValueToRValue:
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 877191d456b35..5bc65c6a76cf2 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1909,7 +1909,29 @@ void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
 
 void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
   OS << '(';
-  Node->getType().print(OS, Policy);
+  if (Node->getStorageClass() == SC_Static)
+    OS << "static ";
+  else if (Node->getStorageClass() == SC_Register)
+    OS << "register ";
+  switch (Node->getTSCSpec()) {
+  case TSCS_thread_local:
+    OS << "thread_local ";
+    break;
+  case TSCS__Thread_local:
+    OS << "_Thread_local ";
+    break;
+  case TSCS___thread:
+    OS << "__thread ";
+    break;
+  case TSCS_unspecified:
+    break;
+  }
+  QualType T = Node->getType();
+  if (Node->isConstexpr()) {
+    T = Node->getTypeSourceInfo()->getType();
+    OS << "constexpr ";
+  }
+  T.print(OS, Policy);
   OS << ')';
   PrintExpr(Node->getInitializer());
 }
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 00c132f1ed9e0..ef617ddfd49fb 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -1600,6 +1600,9 @@ void StmtProfiler::VisitMemberExpr(const MemberExpr *S) {
 void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *S) {
   VisitExpr(S);
   ID.AddBoolean(S->isFileScope());
+  ID.AddInteger(S->getStorageClass());
+  ID.AddInteger(S->getTSCSpec());
+  ID.AddBoolean(S->isConstexpr());
 }
 
 void StmtProfiler::VisitCastExpr(const CastExpr *S) {
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 9201e40bc13a1..fadf00a606f3e 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5993,8 +5993,17 @@ CodeGenFunction::EmitLValueForFieldInitialization(LValue Base,
 }
 
 LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
-  if (E->isFileScope()) {
+  if (E->isFileScope() || E->hasGlobalStorage()) {
+    if (E->getType()->isVariablyModifiedType())
+      EmitVariablyModifiedType(E->getType());
+
     ConstantAddress GlobalPtr = CGM.GetAddrOfConstantCompoundLiteral(E);
+    if (E->hasThreadStorage()) {
+      llvm::Value *V = Builder.CreateThreadLocalAddress(GlobalPtr.getPointer());
+      return MakeAddrLValue(
+          Address(V, ConvertTypeForMem(E->getType()), GlobalPtr.getAlignment()),
+          E->getType(), AlignmentSource::Decl);
+    }
     return MakeAddrLValue(GlobalPtr, E->getType(), AlignmentSource::Decl);
   }
   if (E->getType()->isVariablyModifiedType())
@@ -6005,8 +6014,10 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
   const Expr *InitExpr = E->getInitializer();
   LValue Result = MakeAddrLValue(DeclPtr, E->getType(), AlignmentSource::Decl);
 
-  EmitAnyExprToMem(InitExpr, DeclPtr, E->getType().getQualifiers(),
-                   /*Init*/ true);
+  if (E->getType()->isAtomicType())
+    EmitAtomicInit(const_cast<Expr *>(InitExpr), Result);
+  else
+    EmitInitializationToLValue(InitExpr, Result);
 
   // Block-scope compound literals are destroyed at the end of the enclosing
   // scope in C.
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index bc35ffdaad2bd..c1309c456d4e3 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -789,9 +789,10 @@ void AggExprEmitter::VisitOpaqueValueExpr(OpaqueValueExpr *e) {
 }
 
 void AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
-  if (Dest.isPotentiallyAliased()) {
-    // Just emit a load of the lvalue + a copy, because our compound literal
-    // might alias the destination.
+  if (E->hasGlobalStorage() || E->getType()->isAtomicType() ||
+      (E->getStorageClass() == SC_Register &&
+       E->getType().isVolatileQualified()) ||
+      Dest.isPotentiallyAliased()) {
     EmitAggLoadOfLValue(E);
     return;
   }
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 257de0145855b..2123eab890779 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -1089,8 +1089,8 @@ tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter,
   llvm::Constant *C = emitter.tryEmitForInitializer(E->getInitializer(),
                                                     addressSpace, E->getType());
   if (!C) {
-    assert(!E->isFileScope() &&
-           "file-scope compound literal did not have constant initializer!");
+    assert(!E->isFileScope() && !E->hasGlobalStorage() &&
+           "global compound literal did not have constant initializer!");
     return ConstantAddress::invalid();
   }
 
@@ -1098,7 +1098,8 @@ tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter,
       CGM.getModule(), C->getType(),
       E->getType().isConstantStorage(CGM.getContext(), true, false),
       llvm::GlobalValue::InternalLinkage, C, ".compoundliteral", nullptr,
-      llvm::GlobalVariable::NotThreadLocal,
+      E->hasThreadStorage() ? CGM.GetDefaultLLVMTLSModel()
+                            : llvm::GlobalVariable::NotThreadLocal,
       CGM.getContext().getTargetAddressSpace(addressSpace));
   emitter.finalize(GV);
   GV->setAlignment(Align.getAsAlign());
@@ -2770,7 +2771,8 @@ void CodeGenModule::setAddrOfConstantCompoundLiteral(
 
 ConstantAddress
 CodeGenModule::GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *E) {
-  assert(E->isFileScope() && "not a file-scope compound literal expr");
+  assert((E->isFileScope() || E->hasGlobalStorage()) &&
+         "not a global compound literal expression");
   ConstantEmitter emitter(*this);
   return tryEmitGlobalCompoundLiteral(emitter, E);
 }
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 119aebb673789..861dfa1f9f1c7 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1360,8 +1360,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
       else
         Ty = VD->getType();
 
-      if (Ty->isVariablyModifiedType())
+      if (Ty->isVariablyModifiedType()) {
+        RunCleanupsScope Scope(*this);
         EmitVariablyModifiedType(Ty);
+      }
     }
   }
   // Emit a location at the end of the prologue.
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 6ca036664094e..55e1d489efb39 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -2656,6 +2656,59 @@ bool Parser::tryParseOpenMPArrayShapingCastPart() {
   return !ErrorFound;
 }
 
+bool Parser::isCompoundLiteralStorageClassSpecifier(const Token &Tok) const {
+  if (!getLangOpts().C23)
+    return false;
+  switch (Tok.getKind()) {
+  case tok::kw_constexpr:
+  case tok::kw_register:
+  case tok::kw_static:
+  case tok::kw_thread_local:
+  case tok::kw__Thread_local:
+    return true;
+  default:
+    return false;
+  }
+}
+
+void Parser::ParseCompoundLiteralStorageClassSpecifiers(DeclSpec &DS) {
+  DS.SetRangeStart(Tok.getLocation());
+  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
+  while (isCompoundLiteralStorageClassSpecifier(Tok)) {
+    SourceLocation Loc = Tok.getLocation();
+    const char *PrevSpec = nullptr;
+    unsigned DiagID = 0;
+    bool IsInvalid = false;
+    switch (Tok.getKind()) {
+    case tok::kw_static:
+      IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
+                                         PrevSpec, DiagID, Policy);
+      break;
+    case tok::kw_register:
+      IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
+                                         PrevSpec, DiagID, Policy);
+      break;
+    case tok::kw_thread_local:
+    case tok::kw__Thread_local:
+      IsInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS__Thread_local,
+                                               Loc, PrevSpec, DiagID);
+      break;
+    case tok::kw_constexpr:
+      IsInvalid = DS.SetConstexprSpec(ConstexprSpecKind::Constexpr, Loc,
+                                      PrevSpec, DiagID);
+      break;
+    default:
+      llvm_unreachable("unexpected compound literal storage class specifier");
+    }
+
+    if (IsInvalid)
+      Diag(Loc, DiagID) << PrevSpec;
+
+    DS.SetRangeEnd(Loc);
+    ConsumeToken();
+  }
+}
+
 ExprResult
 Parser::ParseParenExpression(ParenParseOption &ExprType, bool StopIfCastExpr,
                              ParenExprKind ParenBehavior,
@@ -2671,7 +2724,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool StopIfCastExpr,
   PreferredType.enterParenExpr(Tok.getLocation(), OpenLoc);
 
   ExprResult Result(true);
-  bool isAmbiguousTypeId;
+  bool isAmbiguousTypeId = false;
   CastTy = nullptr;
 
   if (Tok.is(tok::code_completion)) {
@@ -2773,7 +2826,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool StopIfCastExpr,
                                                BridgeKeywordLoc, Ty.get(),
                                                RParenLoc, SubExpr.get());
   } else if (ExprType >= ParenParseOption::CompoundLiteral &&
-             isTypeIdInParens(isAmbiguousTypeId)) {
+             (isCompoundLiteralStorageClassSpecifier(Tok) ||
+              isTypeIdInParens(isAmbiguousTypeId))) {
 
     // Otherwise, this is a compound literal expression or cast expression.
 
@@ -2789,7 +2843,12 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool StopIfCastExpr,
       return res;
     }
 
-    // Parse the type declarator.
+    DeclSpec CompoundDS(AttrFactory);
+    if (isCompoundLiteralStorageClassSpecifier(Tok)) {
+      ParseCompoundLiteralStorageClassSpecifiers(CompoundDS);
+      CompoundDS.Finish(Actions, Actions.getASTContext().getPrintingPolicy());
+    }
+
     DeclSpec DS(AttrFactory);
     ParseSpecifierQualifierList(DS);
     Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
@@ -2817,12 +2876,32 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool StopIfCastExpr,
       RParenLoc = T.getCloseLocation();
       if (ParenBehavior == ParenExprKind::Unknown && Tok.is(tok::l_brace)) {
         ExprType = ParenParseOption::CompoundLiteral;
+
+        if (CompoundDS.getBeginLoc().isValid())
+          Diag(CompoundDS.getBeginLoc(),
+               diag::warn_c23_compat_compound_literal_storage_class);
+
         TypeResult Ty;
         {
           InMessageExpressionRAIIObject InMessage(*this, false);
           Ty = Actions.ActOnTypeName(DeclaratorInfo);
         }
-        return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc);
+        return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc,
+                                              &CompoundDS);
+      }
+
+      if (!DeclaratorInfo.isInvalidType()) {
+        if (CompoundDS.getParsedSpecifiers() &
+            DeclSpec::PQ_StorageClassSpecifier) {
+          SourceLocation Loc = CompoundDS.getStorageClassSpecLoc();
+          if (Loc.isInvalid())
+            Loc = CompoundDS.getThreadStorageClassSpecLoc();
+          Diag(Loc, diag::err_typename_invalid_storageclass);
+        }
+        if (CompoundDS.hasConstexprSpecifier())
+          Diag(CompoundDS.getConstexprSpecLoc(),
+               diag::err_typename_invalid_constexpr)
+              << static_cast<int>(CompoundDS.getConstexprSpecifier());
       }
 
       if (ParenBehavior == ParenExprKind::Unknown && Tok.is(tok::l_paren)) {
@@ -2996,17 +3075,18 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool StopIfCastExpr,
   return Result;
 }
 
-ExprResult
-Parser::ParseCompoundLiteralExpression(ParsedType Ty,
-                                       SourceLocation LParenLoc,
-                                       SourceLocation RParenLoc) {
+ExprResult Parser::ParseCompoundLiteralExpression(ParsedType Ty,
+                                                  SourceLocation LParenLoc,
+                                                  SourceLocation RParenLoc,
+                                                  const DeclSpec *DS) {
   assert(Tok.is(tok::l_brace) && "Not a compound literal!");
   if (!getLangOpts().C99)   // Compound literals don't exist in C90.
     Diag(LParenLoc, diag::ext_c99_compound_literal);
   PreferredType.enterTypeCast(Tok.getLocation(), Ty.get());
   ExprResult Result = ParseInitializer();
   if (!Result.isInvalid() && Ty)
-    return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get());
+    return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get(),
+                                        DS);
   return Result;
 }
 
diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp
index fafee76ec18c3..e5cfc3086fb58 100644
--- a/clang/lib/Sema/CheckExprLifetime.cpp
+++ b/clang/lib/Sema/CheckExprLifetime.cpp
@@ -131,6 +131,7 @@ getEntityLifetime(const InitializedEntity *Entity,
 
   case InitializedEntity::EK_Temporary:
   case InitializedEntity::EK_CompoundLiteralInit:
+  case InitializedEntity::EK_ConstexprCompoundLiteralInit:
   case InitializedEntity::EK_RelatedResult:
     // We don't yet know the storage duration of the surrounding temporary.
     // Assume it's got full-expression duration for now, it will patch up our
@@ -658,7 +659,7 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
 
   case Stmt::CompoundLiteralExprClass: {
     if (auto *CLE = dyn_cast<CompoundLiteralExpr>(Init)) {
-      if (!CLE->isFileScope())
+      if (!CLE->isFileScope() && !CLE->hasGlobalStorage())
         Visit(Path, Local(CLE), RK);
     }
     break;
diff --git a/clang/lib/Sema/DelayedDiagnostic.cpp b/clang/lib/Sema/DelayedDiagnostic.cpp
index cb2721b92090e..4f94da0e64fba 100644
--- a/clang/lib/Sema/DelayedDiagnostic.cpp
+++ b/clang/lib/Sema/DelayedDiagnostic.cpp
@@ -68,6 +68,7 @@ void DelayedDiagnostic::Destroy() {
     break;
 
   case ForbiddenType:
+  case ForbiddenStatic:
     break;
   }
 }
diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp
index fc79b1a056ed9..1cd7a21893ba4 100644
--- a/clang/lib/Sema/Scope.cpp
+++ b/clang/lib/Sema/Scope.cpp
@@ -103,14 +103,15 @@ void Scope::Init(Scope *parent, unsigned flags) {
   NRVO = std::nullopt;
 }
 
-bool Scope::containedInPrototypeScope() const {
-  const Scope *S = this;
-  while (S) {
+const Scope *Scope::getEnclosingFunctionPrototypeScope() const {
+  for (const Scope *S = this; S; S = S->getParent())
     if (S->isFunctionPrototypeScope())
-      return true;
-    S = S->getParent();
-  }
-  return false;
+      return S;
+  return nullptr;
+}
+
+bool Scope::containedInPrototypeScope() const {
+  return getEnclosingFunctionPrototypeScope() != nullptr;
 }
 
 void Scope::EnterLoopBody(LabelDecl *LD) {
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a553c6994f0ed..cf09bf2615b07 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7419,7 +7419,7 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
 /// Given that we are within the definition of the given function,
 /// will that definition behave like C99's 'inline', where the
 /// definition is discarded except for optimization purposes?
-static bool isFunctionDefinitionDiscarded(Sema &S, FunctionDecl *FD) {
+static bool isFunctionDefinitionDiscarded(Sema &S, const FunctionDecl *FD) {
   // Try to avoid calling GetGVALinkageForFunction.
 
   // All cases of this require the 'inline' keyword.
@@ -7433,6 +7433,14 @@ static bool isFunctionDefinitionDiscarded(Sema &S, FunctionDecl *FD) {
   return S.Context.GetGVALinkageForFunction(FD) == GVA_AvailableExternally;
 }
 
+void Sema::DiagnoseStaticInInline(SourceLocation Loc, const FunctionDecl *FD) {
+  if (!FD || !isFunctionDefinitionDiscarded(*this, FD))
+    return;
+
+  Diag(Loc, diag::warn_static_local_in_extern_inline);
+  MaybeSuggestAddingStaticToDecl(FD);
+}
+
 /// Determine whether a variable is extern "C" prior to attaching
 /// an initializer. We can't just call isExternC() here, because that
 /// will also compute and cache whether the declaration is externally
@@ -8190,14 +8198,9 @@ NamedDecl *Sema::ActOnVariableDeclarator(
   // be marked 'static'.  Also note that it's possible to get these
   // semantics in C++ using __attribute__((gnu_inline)).
   if (SC == SC_Static && S->getFnParent() != nullptr &&
-      !NewVD->getType().isConstQualified()) {
-    FunctionDecl *CurFD = getCurFunctionDecl();
-    if (CurFD && isFunctionDefinitionDiscarded(*this, CurFD)) {
-      Diag(D.getDeclSpec().getStorageClassSpecLoc(),
-           diag::warn_static_local_in_extern_inline);
-      MaybeSuggestAddingStaticToDecl(CurFD);
-    }
-  }
+      !NewVD->getType().isConstQualified())
+    DiagnoseStaticInInline(D.getDeclSpec().getStorageClassSpecLoc(),
+                           getCurFunctionDecl());
 
   if (D.getDeclSpec().isModulePrivateSpecified()) {
     if (IsVariableTemplateSpecialization)
@@ -8898,32 +8901,31 @@ static bool checkForConflictWithNonVisibleExternC(Sema &S, const T *ND,
   return false;
 }
 
-static bool CheckC23ConstexprVarType(Sema &SemaRef, SourceLocation VarLoc,
-                                     QualType T) {
-  QualType CanonT = SemaRef.Context.getCanonicalType(T);
+bool Sema::CheckConstexprType(SourceLocation Loc, QualType T, unsigned DiagID) {
+  QualType CanonT = Context.getCanonicalType(T);
   // C23 6.7.1p5: An object declared with storage-class specifier constexpr or
   // any of its members, even recursively, shall not have an atomic type, or a
   // variably modified type, or a type that is volatile or restrict qualified.
   if (CanonT->isVariablyModifiedType()) {
-    SemaRef.Diag(VarLoc, diag::err_c23_constexpr_invalid_type) << T;
+    Diag(Loc, DiagID) << T;
     return true;
   }
 
   // Arrays are qualified by their element type, so get the base type (this
   // works on non-arrays as well).
-  CanonT = SemaRef.Context.getBaseElementType(CanonT);
+  CanonT = Context.getBaseElementType(CanonT);
 
   if (CanonT->isAtomicType() || CanonT.isVolatileQualified() ||
       CanonT.isRestrictQualified()) {
-    SemaRef.Diag(VarLoc, diag::err_c23_constexpr_invalid_type) << T;
+    Diag(Loc, DiagID) << T;
     return true;
   }
 
   if (CanonT->isRecordType()) {
     const RecordDecl *RD = CanonT->getAsRecordDecl();
     if (!RD->isInvalidDecl() &&
-        llvm::any_of(RD->fields(), [&SemaRef, VarLoc](const FieldDecl *F) {
-          return CheckC23ConstexprVarType(SemaRef, VarLoc, F->getType());
+        llvm::any_of(RD->fields(), [this, Loc, DiagID](const FieldDecl *F) {
+          return CheckConstexprType(Loc, F->getType(), DiagID);
         }))
       return true;
   }
@@ -9199,7 +9201,8 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
   }
 
   if (getLangOpts().C23 && NewVD->isConstexpr() &&
-      CheckC23ConstexprVarType(*this, NewVD->getLocation(), T)) {
+      CheckConstexprType(NewVD->getLocation(), T,
+                         diag::err_c23_constexpr_invalid_type)) {
     NewVD->setInvalidDecl();
     return;
   }
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1b272b5416860..cf6ce9b5508be 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -9017,6 +9017,14 @@ void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
       case DelayedDiagnostic::ForbiddenType:
         handleDelayedForbiddenType(*this, diag, decl);
         break;
+
+      case DelayedDiagnostic::ForbiddenStatic:
+        if (const FunctionDecl *FD = decl->getAsFunction();
+            FD && FD->isThisDeclarationADefinition()) {
+          diag.Triggered = true;
+          DiagnoseStaticInInline(diag.Loc, FD);
+        }
+        break;
       }
     }
   } while ((pool = pool->getParent()));
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ed3d27b5adc27..b5f19964cbefd 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -63,6 +63,7 @@
 #include "clang/Sema/SemaOpenMP.h"
 #include "clang/Sema/SemaPseudoObject.h"
 #include "clang/Sema/Template.h"
+#include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/ConvertUTF.h"
@@ -123,6 +124,40 @@ static void DiagnoseUnusedOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc) {
   }
 }
 
+static bool checkThreadLocalCompoundLiteral(Sema &S, SourceLocation Loc,
+                                            QualType T) {
+  if (S.getLangOpts().ObjCAutoRefCount && T->isObjCLifetimeType()) {
+    Qualifiers::ObjCLifetime Lifetime = T.getObjCLifetime();
+    if (Lifetime == Qualifiers::OCL_None)
+      Lifetime = T->getObjCARCImplicitLifetime();
+
+    if (Lifetime && Lifetime != Qualifiers::OCL_ExplicitNone) {
+      S.Diag(Loc, diag::err_arc_thread_ownership)
+          << S.Context.getLifetimeQualifiedType(T, Lifetime);
+      return true;
+    }
+  }
+
+  if (T.isDestructedType()) {
+    S.Diag(Loc, diag::err_thread_nontrivial_dtor);
+    return true;
+  }
+
+  unsigned MaxAlign = S.Context.getTargetInfo().getMaxTLSAlign();
+  if (!MaxAlign || T->isDependentType())
+    return false;
+
+  CharUnits MaxAlignChars = S.Context.toCharUnitsFromBits(MaxAlign);
+  CharUnits TypeAlign = S.Context.getTypeAlignInChars(T);
+  if (TypeAlign <= MaxAlignChars)
+    return false;
+
+  S.Diag(Loc, diag::err_tls_compound_literal_aligned_over_maximum)
+      << (unsigned)TypeAlign.getQuantity()
+      << (unsigned)MaxAlignChars.getQuantity();
+  return true;
+}
+
 void Sema::NoteDeletedFunction(FunctionDecl *Decl) {
   assert(Decl && Decl->isDeleted());
 
@@ -519,6 +554,54 @@ SourceRange Sema::getExprRange(Expr *E) const {
 //  Standard Promotions and Conversions
 //===----------------------------------------------------------------------===//
 
+namespace {
+enum {
+  AO_Bit_Field = 0,
+  AO_Vector_Element = 1,
+  AO_Property_Expansion = 2,
+  AO_Register_Variable = 3,
+  AO_Matrix_Element = 4,
+  AO_Register_Compound_Literal = 5,
+  AO_No_Error = 6
+};
+}
+
+using PrimaryObject = llvm::PointerUnion<ValueDecl *, CompoundLiteralExpr *>;
+
+static PrimaryObject getPrimaryObject(Expr *E) {
+  E = E->IgnoreParens();
+  switch (E->getStmtClass()) {
+  case Stmt::DeclRefExprClass:
+    return cast<DeclRefExpr>(E)->getDecl();
+  case Stmt::CompoundLiteralExprClass:
+    return cast<CompoundLiteralExpr>(E);
+  case Stmt::MemberExprClass:
+    if (cast<MemberExpr>(E)->isArrow())
+      return {};
+    return getPrimaryObject(cast<MemberExpr>(E)->getBase());
+  case Stmt::ArraySubscriptExprClass: {
+    Expr *Base = cast<ArraySubscriptExpr>(E)->getBase()->IgnoreParens();
+    if (auto *ICE = dyn_cast<ImplicitCastExpr>(Base);
+        ICE && ICE->getSubExpr()->getType()->isArrayType())
+      return getPrimaryObject(ICE->getSubExpr());
+    return {};
+  }
+  case Stmt::UnaryOperatorClass: {
+    UnaryOperator *UO = cast<UnaryOperator>(E);
+    if (UO->getOpcode() == UO_Real || UO->getOpcode() == UO_Imag ||
+        UO->getOpcode() == UO_Extension)
+      return getPrimaryObject(UO->getSubExpr());
+    return {};
+  }
+  case Stmt::ImplicitCastExprClass:
+    return getPrimaryObject(cast<ImplicitCastExpr>(E)->getSubExpr());
+  case Stmt::CXXUuidofExprClass:
+    return cast<CXXUuidofExpr>(E)->getGuidDecl();
+  default:
+    return {};
+  }
+}
+
 /// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
 ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, bool Diagnose) {
   // Handle any placeholder expressions which made it here.
@@ -552,6 +635,13 @@ ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, bool Diagnose) {
     // T" can be converted to an rvalue of type "pointer to T".
     //
     if (getLangOpts().C99 || getLangOpts().CPlusPlus || E->isLValue()) {
+      if (!getLangOpts().CPlusPlus) {
+        auto *CLE = getPrimaryObject(E).dyn_cast<CompoundLiteralExpr *>();
+        if (CLE && CLE->getStorageClass() == SC_Register)
+          return Diag(E->getExprLoc(), diag::err_typecheck_address_of)
+                 << AO_Register_Compound_Literal << CLE->getSourceRange();
+      }
+
       ExprResult Res = ImpCastExprToType(E, Context.getArrayDecayedType(Ty),
                                          CK_ArrayToPointerDecay);
       if (Res.isInvalid())
@@ -7425,9 +7515,9 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
   return CheckForImmediateInvocation(MaybeBindToTemporary(TheCall), FDecl);
 }
 
-ExprResult
-Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
-                           SourceLocation RParenLoc, Expr *InitExpr) {
+ExprResult Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
+                                      SourceLocation RParenLoc, Expr *InitExpr,
+                                      const DeclSpec *DS) {
   assert(Ty && "ActOnCompoundLiteral(): missing type");
   assert(InitExpr && "ActOnCompoundLiteral(): missing expression");
 
@@ -7436,13 +7526,90 @@ Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
   if (!TInfo)
     TInfo = Context.getTrivialTypeSourceInfo(literalType);
 
-  return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, InitExpr);
-}
-
-ExprResult
-Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
-                               SourceLocation RParenLoc, Expr *LiteralExpr) {
+  StorageClass SC = SC_None;
+  ThreadStorageClassSpecifier TSC = TSCS_unspecified;
+  ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified;
+  SourceLocation StorageClassLoc;
+  SourceLocation ThreadStorageClassLoc;
+  SourceLocation ConstexprLoc;
+  if (DS) {
+    if (DS->getStorageClassSpec() == DeclSpec::SCS_static)
+      SC = SC_Static;
+    else if (DS->getStorageClassSpec() == DeclSpec::SCS_register)
+      SC = SC_Register;
+
+    TSC = DS->getThreadStorageClassSpec();
+    ConstexprKind = DS->getConstexprSpecifier();
+    StorageClassLoc = DS->getStorageClassSpecLoc();
+    ThreadStorageClassLoc = DS->getThreadStorageClassSpecLoc();
+    ConstexprLoc = DS->getConstexprSpecLoc();
+  }
+
+  return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, InitExpr, SC,
+                                  StorageClassLoc, TSC, ThreadStorageClassLoc,
+                                  ConstexprKind, ConstexprLoc);
+}
+
+ExprResult Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc,
+                                          TypeSourceInfo *TInfo,
+                                          SourceLocation RParenLoc,
+                                          Expr *LiteralExpr, StorageClass SC,
+                                          ThreadStorageClassSpecifier TSC,
+                                          ConstexprSpecKind ConstexprKind) {
+  return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, LiteralExpr, SC,
+                                  LParenLoc, TSC, LParenLoc, ConstexprKind,
+                                  LParenLoc);
+}
+
+ExprResult Sema::BuildCompoundLiteralExpr(
+    SourceLocation LParenLoc, TypeSourceInfo *TInfo, SourceLocation RParenLoc,
+    Expr *LiteralExpr, StorageClass SC, SourceLocation StorageClassLoc,
+    ThreadStorageClassSpecifier TSC, SourceLocation ThreadStorageClassLoc,
+    ConstexprSpecKind ConstexprKind, SourceLocation ConstexprLoc) {
   QualType literalType = TInfo->getType();
+  const Scope *S = getCurScope();
+  const Scope *PrototypeScope = S->getEnclosingFunctionPrototypeScope();
+
+  bool HasStatic = SC == SC_Static;
+  bool HasRegister = SC == SC_Register;
+  bool HasThreadStorage = TSC != TSCS_unspecified;
+  bool HasConstexpr = ConstexprKind == ConstexprSpecKind::Constexpr;
+
+  bool IsPrototypeScope = PrototypeScope;
+  bool IsFunctionDeclarationScope =
+      PrototypeScope && PrototypeScope->isFunctionDeclarationScope();
+  bool IsFileScope = !CurContext->isFunctionOrMethod() &&
+                     !S->isInCFunctionScope() && !PrototypeScope;
+
+  if (HasConstexpr && literalType->isObjectType())
+    literalType.addConst();
+
+  if (getLangOpts().C23 &&
+      (SC != SC_None || HasThreadStorage || HasConstexpr)) {
+    if (HasRegister && IsFileScope) {
+      Diag(StorageClassLoc, diag::err_register_compound_literal_file_scope);
+      return ExprError();
+    }
+    if (HasThreadStorage && !IsFileScope && !HasStatic) {
+      Diag(ThreadStorageClassLoc,
+           diag::err_thread_local_compound_literal_without_static);
+      return ExprError();
+    }
+    if (HasThreadStorage && !Context.getTargetInfo().isTLSSupported()) {
+      Diag(ThreadStorageClassLoc, diag::err_thread_unsupported);
+      return ExprError();
+    }
+    if (HasConstexpr &&
+        CheckConstexprType(ConstexprLoc, literalType,
+                           diag::err_constexpr_compound_literal_invalid_type))
+      return ExprError();
+  }
+
+  if (getLangOpts().C23 && IsFileScope &&
+      literalType->isVariablyModifiedType()) {
+    Diag(LParenLoc, diag::err_vm_decl_in_file_scope);
+    return ExprError();
+  }
 
   if (literalType->isArrayType()) {
     if (RequireCompleteSizedType(
@@ -7477,32 +7644,47 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
         return ExprError();
     }
   } else if (!literalType->isDependentType() &&
-             RequireCompleteType(LParenLoc, literalType,
-               diag::err_typecheck_decl_incomplete_type,
-               SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd())))
+             RequireCompleteType(
+                 LParenLoc, literalType,
+                 diag::err_typecheck_decl_incomplete_type,
+                 SourceRange(LParenLoc,
+                             LiteralExpr->getSourceRange().getEnd())))
     return ExprError();
 
-  InitializedEntity Entity
-    = InitializedEntity::InitializeCompoundLiteralInit(TInfo);
-  InitializationKind Kind
-    = InitializationKind::CreateCStyleCast(LParenLoc,
-                                           SourceRange(LParenLoc, RParenLoc),
-                                           /*InitList=*/true);
+  InitializedEntity Entity = InitializedEntity::InitializeCompoundLiteralInit(
+      TInfo, literalType, ConstexprKind);
+  InitializationKind Kind = InitializationKind::CreateCStyleCast(
+      LParenLoc, SourceRange(LParenLoc, RParenLoc),
+      /*InitList=*/true);
   InitializationSequence InitSeq(*this, Entity, Kind, LiteralExpr);
-  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, LiteralExpr,
-                                      &literalType);
+  ExprResult Result =
+      InitSeq.Perform(*this, Entity, Kind, LiteralExpr, &literalType);
   if (Result.isInvalid())
     return ExprError();
   LiteralExpr = Result.get();
 
-  // We treat the compound literal as being at file scope if it's not in a
-  // function or method body, or within the function's prototype scope. This
-  // means the following compound literal is not at file scope:
-  //   void func(char *para[(int [1]){ 0 }[0]);
-  const Scope *S = getCurScope();
-  bool IsFileScope = !CurContext->isFunctionOrMethod() &&
-                     !S->isInCFunctionScope() &&
-                     (!S || !S->isFunctionPrototypeScope());
+  if (HasConstexpr && !LiteralExpr->isTypeDependent() &&
+      !LiteralExpr->isValueDependent() && !literalType->isDependentType()) {
+    SmallVector<PartialDiagnosticAt, 4> Notes;
+    Expr::EvalResult Eval;
+    Eval.Diag = &Notes;
+    if (!LiteralExpr->EvaluateAsConstantExpr(
+            Eval, Context,
+            Expr::ConstantExprKind::CompoundLiteralInitializer) ||
+        Notes.size() > 0) {
+      SourceLocation DiagLoc = ConstexprLoc;
+      if (Notes.size() == 1 && Notes.front().second.getDiagID() ==
+                                   diag::note_invalid_subexpr_in_const_expr) {
+        DiagLoc = Notes.front().first;
+        Notes.clear();
+      }
+      Diag(DiagLoc, diag::err_compound_literal_initializer_not_constant)
+          << LiteralExpr->getSourceRange();
+      for (const PartialDiagnosticAt &Note : Notes)
+        Diag(Note.first, Note.second);
+      return ExprError();
+    }
+  }
 
   // In C, compound literals are l-values for some reason.
   // For GCC compatibility, in C++, file-scope array compound literals with
@@ -7527,33 +7709,52 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
           ? VK_PRValue
           : VK_LValue;
 
+  bool HasGlobalStorage =
+      IsFileScope || (getLangOpts().C23 && (HasStatic || HasThreadStorage));
+
+  if (HasThreadStorage && checkThreadLocalCompoundLiteral(
+                              *this, ThreadStorageClassLoc, literalType))
+    return ExprError();
+
   // C99 6.5.2.5
   //  "If the compound literal occurs outside the body of a function, the
   //  initializer list shall consist of constant expressions."
-  if (IsFileScope)
+  if (HasGlobalStorage || HasConstexpr)
     if (auto ILE = dyn_cast<InitListExpr>(LiteralExpr))
       for (unsigned i = 0, j = ILE->getNumInits(); i != j; i++) {
         Expr *Init = ILE->getInit(i);
-        if (!Init->isTypeDependent() && !Init->isValueDependent() &&
+        if (!HasConstexpr && !Init->isTypeDependent() &&
+            !Init->isValueDependent() &&
             !Init->isConstantInitializer(Context)) {
           Diag(Init->getExprLoc(), diag::err_init_element_not_constant)
               << Init->getSourceBitField();
           return ExprError();
         }
 
-        ILE->setInit(i, ConstantExpr::Create(Context, Init));
+        Expr::EvalResult Eval;
+        if (HasConstexpr &&
+            Init->EvaluateAsRValue(Eval, Context,
+                                   /*InConstantContext=*/true) &&
+            Eval.Val.hasValue())
+          ILE->setInit(i, ConstantExpr::Create(Context, Init, Eval.Val));
+        else
+          ILE->setInit(i, ConstantExpr::Create(Context, Init));
       }
 
-  auto *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, VK,
-                                              LiteralExpr, IsFileScope);
-  if (IsFileScope) {
-    if (!LiteralExpr->isTypeDependent() &&
-        !LiteralExpr->isValueDependent() &&
-        !literalType->isDependentType()) // C99 6.5.2.5p3
+  auto *E = new (Context)
+      CompoundLiteralExpr(LParenLoc, TInfo, literalType, VK, LiteralExpr,
+                          IsFileScope, SC, TSC, ConstexprKind);
+
+  if (HasGlobalStorage && !HasConstexpr) {
+    if (!LiteralExpr->isTypeDependent() && !LiteralExpr->isValueDependent() &&
+        !literalType->isDependentType()) { // C99 6.5.2.5p3
       if (CheckForConstantInitializer(LiteralExpr))
         return ExprError();
-  } else if (literalType.getAddressSpace() != LangAS::opencl_private &&
-             literalType.getAddressSpace() != LangAS::Default) {
+    }
+  }
+
+  if (!IsFileScope && literalType.getAddressSpace() != LangAS::opencl_private &&
+      literalType.getAddressSpace() != LangAS::Default) {
     // Embedded-C extensions to C99 6.5.2.5:
     //   "If the compound literal occurs inside the body of a function, the
     //   type name shall not be qualified by an address-space qualifier."
@@ -7562,7 +7763,17 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
     return ExprError();
   }
 
-  if (!IsFileScope && !getLangOpts().CPlusPlus) {
+  if (HasStatic && !literalType.isConstQualified()) {
+    if (!IsPrototypeScope) {
+      DiagnoseStaticInInline(StorageClassLoc, getCurFunctionDecl());
+    } else if (IsFunctionDeclarationScope &&
+               DelayedDiagnostics.shouldDelayDiagnostics()) {
+      DelayedDiagnostics.add(
+          sema::DelayedDiagnostic::makeForbiddenStatic(StorageClassLoc));
+    }
+  }
+
+  if (!HasGlobalStorage && !IsPrototypeScope && !getLangOpts().CPlusPlus) {
     // Compound literals that have automatic storage duration are destroyed at
     // the end of the scope in C; in C++, they're just temporaries.
 
@@ -14843,78 +15054,6 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,
   }
 }
 
-/// getPrimaryDecl - Helper function for CheckAddressOfOperand().
-/// This routine allows us to typecheck complex/recursive expressions
-/// where the declaration is needed for type checking. We only need to
-/// handle cases when the expression references a function designator
-/// or is an lvalue. Here are some examples:
-///  - &(x) => x
-///  - &*****f => f for f a function designator.
-///  - &s.xx => s
-///  - &s.zz[1].yy -> s, if zz is an array
-///  - *(x + 1) -> x, if x is an array
-///  - &"123"[2] -> 0
-///  - & __real__ x -> x
-///
-/// FIXME: We don't recurse to the RHS of a comma, nor handle pointers to
-/// members.
-static ValueDecl *getPrimaryDecl(Expr *E) {
-  switch (E->getStmtClass()) {
-  case Stmt::DeclRefExprClass:
-    return cast<DeclRefExpr>(E)->getDecl();
-  case Stmt::MemberExprClass:
-    // If this is an arrow operator, the address is an offset from
-    // the base's value, so the object the base refers to is
-    // irrelevant.
-    if (cast<MemberExpr>(E)->isArrow())
-      return nullptr;
-    // Otherwise, the expression refers to a part of the base
-    return getPrimaryDecl(cast<MemberExpr>(E)->getBase());
-  case Stmt::ArraySubscriptExprClass: {
-    // FIXME: This code shouldn't be necessary!  We should catch the implicit
-    // promotion of register arrays earlier.
-    Expr* Base = cast<ArraySubscriptExpr>(E)->getBase();
-    if (ImplicitCastExpr* ICE = dyn_cast<ImplicitCastExpr>(Base)) {
-      if (ICE->getSubExpr()->getType()->isArrayType())
-        return getPrimaryDecl(ICE->getSubExpr());
-    }
-    return nullptr;
-  }
-  case Stmt::UnaryOperatorClass: {
-    UnaryOperator *UO = cast<UnaryOperator>(E);
-
-    switch(UO->getOpcode()) {
-    case UO_Real:
-    case UO_Imag:
-    case UO_Extension:
-      return getPrimaryDecl(UO->getSubExpr());
-    default:
-      return nullptr;
-    }
-  }
-  case Stmt::ParenExprClass:
-    return getPrimaryDecl(cast<ParenExpr>(E)->getSubExpr());
-  case Stmt::ImplicitCastExprClass:
-    // If the result of an implicit cast is an l-value, we care about
-    // the sub-expression; otherwise, the result here doesn't matter.
-    return getPrimaryDecl(cast<ImplicitCastExpr>(E)->getSubExpr());
-  case Stmt::CXXUuidofExprClass:
-    return cast<CXXUuidofExpr>(E)->getGuidDecl();
-  default:
-    return nullptr;
-  }
-}
-
-namespace {
-enum {
-  AO_Bit_Field = 0,
-  AO_Vector_Element = 1,
-  AO_Property_Expansion = 2,
-  AO_Register_Variable = 3,
-  AO_Matrix_Element = 4,
-  AO_No_Error = 5
-};
-}
 /// Diagnose invalid operand for address of operations.
 ///
 /// \param Type The type of operand which cannot have its address taken.
@@ -15018,7 +15157,8 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
     // Technically, there should be a check for array subscript
     // expressions here, but the result of one is always an lvalue anyway.
   }
-  ValueDecl *dcl = getPrimaryDecl(op);
+  PrimaryObject Primary = getPrimaryObject(op);
+  ValueDecl *dcl = Primary.dyn_cast<ValueDecl *>();
 
   if (auto *FD = dyn_cast_or_null<FunctionDecl>(dcl))
     if (!checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true,
@@ -15169,6 +15309,10 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
                     NonTypeTemplateParmDecl, BindingDecl, MSGuidDecl,
                     UnnamedGlobalConstantDecl>(dcl))
       llvm_unreachable("Unknown/unexpected decl type");
+  } else if (!getLangOpts().CPlusPlus) {
+    if (auto *CLE = Primary.dyn_cast<CompoundLiteralExpr *>();
+        CLE && CLE->getStorageClass() == SC_Register)
+      AddressOfError = AO_Register_Compound_Literal;
   }
 
   if (AddressOfError != AO_No_Error) {
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 09d9f1eabd058..7f0a691a1cb28 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -194,18 +194,15 @@ static void updateGNUCompoundLiteralRValue(Expr *E) {
   }
 }
 
-static bool initializingConstexprVariable(const InitializedEntity &Entity) {
-  Decl *D = Entity.getDecl();
-  const InitializedEntity *Parent = &Entity;
-
-  while (Parent) {
-    D = Parent->getDecl();
-    Parent = Parent->getParent();
+static bool initializingConstexprObject(const InitializedEntity &Entity) {
+  for (const InitializedEntity *Parent = &Entity; Parent;
+       Parent = Parent->getParent()) {
+    if (Parent->isConstexprCompoundLiteral())
+      return true;
+    if (const auto *VD = dyn_cast_if_present<VarDecl>(Parent->getDecl());
+        VD && VD->isConstexpr())
+      return true;
   }
-
-  if (const auto *VD = dyn_cast_if_present<VarDecl>(D); VD && VD->isConstexpr())
-    return true;
-
   return false;
 }
 
@@ -1311,6 +1308,7 @@ static void warnBracedScalarInit(Sema &S, const InitializedEntity &Entity,
   case InitializedEntity::EK_New:
   case InitializedEntity::EK_Temporary:
   case InitializedEntity::EK_CompoundLiteralInit:
+  case InitializedEntity::EK_ConstexprCompoundLiteralInit:
     // No warning, braces are part of the syntax of the underlying construct.
     break;
 
@@ -1436,7 +1434,8 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity,
     // parts.
     CheckComplexType(Entity, IList, DeclType, Index,
                      StructuredList, StructuredIndex);
-  } else if (DeclType->isScalarType()) {
+  } else if (DeclType->isScalarType() ||
+             (!SemaRef.getLangOpts().CPlusPlus && DeclType->isAtomicType())) {
     CheckScalarType(Entity, IList, DeclType, Index,
                     StructuredList, StructuredIndex);
   } else if (DeclType->isVectorType()) {
@@ -1626,7 +1625,7 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
       if (!VerifyOnly)
         CheckStringInit(expr, ElemType, arrayType, SemaRef, Entity,
                         SemaRef.getLangOpts().C23 &&
-                            initializingConstexprVariable(Entity));
+                            initializingConstexprObject(Entity));
       if (StructuredList)
         UpdateStructuredListElement(StructuredList, StructuredIndex, expr);
       ++Index;
@@ -2177,7 +2176,7 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity,
       if (!VerifyOnly)
         CheckStringInit(
             IList->getInit(Index), DeclType, arrayType, SemaRef, Entity,
-            SemaRef.getLangOpts().C23 && initializingConstexprVariable(Entity));
+            SemaRef.getLangOpts().C23 && initializingConstexprObject(Entity));
       if (StructuredList) {
         UpdateStructuredListElement(StructuredList, StructuredIndex,
                                     IList->getInit(Index));
@@ -3809,6 +3808,7 @@ DeclarationName InitializedEntity::getName() const {
   case EK_BlockElement:
   case EK_LambdaToBlockConversionBlockElement:
   case EK_CompoundLiteralInit:
+  case EK_ConstexprCompoundLiteralInit:
   case EK_RelatedResult:
     return DeclarationName();
   }
@@ -3844,6 +3844,7 @@ ValueDecl *InitializedEntity::getDecl() const {
   case EK_LambdaToBlockConversionBlockElement:
   case EK_LambdaCapture:
   case EK_CompoundLiteralInit:
+  case EK_ConstexprCompoundLiteralInit:
   case EK_RelatedResult:
     return nullptr;
   }
@@ -3868,6 +3869,7 @@ bool InitializedEntity::allowsNRVO() const {
   case EK_New:
   case EK_Temporary:
   case EK_CompoundLiteralInit:
+  case EK_ConstexprCompoundLiteralInit:
   case EK_Base:
   case EK_Delegating:
   case EK_ArrayElement:
@@ -3907,6 +3909,9 @@ unsigned InitializedEntity::dumpImpl(raw_ostream &OS) const {
   case EK_New: OS << "New"; break;
   case EK_Temporary: OS << "Temporary"; break;
   case EK_CompoundLiteralInit: OS << "CompoundLiteral";break;
+  case EK_ConstexprCompoundLiteralInit:
+    OS << "ConstexprCompoundLiteral";
+    break;
   case EK_RelatedResult: OS << "RelatedResult"; break;
   case EK_Base: OS << "Base"; break;
   case EK_Delegating: OS << "Delegating"; break;
@@ -4930,7 +4935,8 @@ static void TryReferenceListInitialization(Sema &S,
     return;
   }
   // Can't reference initialize a compound literal.
-  if (Entity.getKind() == InitializedEntity::EK_CompoundLiteralInit) {
+  if (Entity.getKind() == InitializedEntity::EK_CompoundLiteralInit ||
+      Entity.getKind() == InitializedEntity::EK_ConstexprCompoundLiteralInit) {
     Sequence.SetFailed(InitializationSequence::FK_ReferenceBindingToInitList);
     return;
   }
@@ -7196,6 +7202,7 @@ static AssignmentAction getAssignmentAction(const InitializedEntity &Entity,
   case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
   case InitializedEntity::EK_LambdaCapture:
   case InitializedEntity::EK_CompoundLiteralInit:
+  case InitializedEntity::EK_ConstexprCompoundLiteralInit:
     return AssignmentAction::Initializing;
   }
 
@@ -7223,6 +7230,7 @@ static bool shouldBindAsTemporary(const InitializedEntity &Entity) {
   case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
   case InitializedEntity::EK_LambdaCapture:
   case InitializedEntity::EK_CompoundLiteralInit:
+  case InitializedEntity::EK_ConstexprCompoundLiteralInit:
   case InitializedEntity::EK_TemplateParameter:
     return false;
 
@@ -7265,6 +7273,7 @@ static bool shouldDestroyEntity(const InitializedEntity &Entity) {
     case InitializedEntity::EK_ArrayElement:
     case InitializedEntity::EK_Exception:
     case InitializedEntity::EK_CompoundLiteralInit:
+    case InitializedEntity::EK_ConstexprCompoundLiteralInit:
     case InitializedEntity::EK_RelatedResult:
       return true;
   }
@@ -7306,6 +7315,7 @@ static SourceLocation getInitializationLoc(const InitializedEntity &Entity,
   case InitializedEntity::EK_BlockElement:
   case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
   case InitializedEntity::EK_CompoundLiteralInit:
+  case InitializedEntity::EK_ConstexprCompoundLiteralInit:
   case InitializedEntity::EK_RelatedResult:
     return Initializer->getBeginLoc();
   }
@@ -7562,6 +7572,7 @@ static bool isExplicitTemporary(const InitializedEntity &Entity,
   switch (Entity.getKind()) {
   case InitializedEntity::EK_Temporary:
   case InitializedEntity::EK_CompoundLiteralInit:
+  case InitializedEntity::EK_ConstexprCompoundLiteralInit:
   case InitializedEntity::EK_RelatedResult:
     break;
   default:
@@ -8579,7 +8590,7 @@ ExprResult InitializationSequence::Perform(Sema &S,
         return ExprError();
       CurInit = CurInitExprRes;
 
-      if (S.getLangOpts().C23 && initializingConstexprVariable(Entity)) {
+      if (S.getLangOpts().C23 && initializingConstexprObject(Entity)) {
         CheckC23ConstexprInitConversion(S, SourceType, Entity.getType(),
                                         CurInit.get());
 
@@ -8623,7 +8634,7 @@ ExprResult InitializationSequence::Perform(Sema &S,
       CheckStringInit(CurInit.get(), UpdateType ? *ResultType : Ty,
                       S.Context.getAsArrayType(Ty), S, Entity,
                       S.getLangOpts().C23 &&
-                          initializingConstexprVariable(Entity));
+                          initializingConstexprObject(Entity));
       break;
     }
 
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 0725664a4e050..239700db3d0eb 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -3103,12 +3103,13 @@ class TreeTransform {
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
-                                              TypeSourceInfo *TInfo,
-                                              SourceLocation RParenLoc,
-                                              Expr *Init) {
-    return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
-                                              Init);
+  ExprResult RebuildCompoundLiteralExpr(
+      SourceLocation LParenLoc, TypeSourceInfo *TInfo, SourceLocation RParenLoc,
+      Expr *Init, StorageClass SC = SC_None,
+      ThreadStorageClassSpecifier TSC = TSCS_unspecified,
+      ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified) {
+    return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, Init,
+                                              SC, TSC, ConstexprKind);
   }
 
   /// Build a new extended vector or matrix element access expression.
@@ -14325,7 +14326,10 @@ TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
 
   return getDerived().RebuildCompoundLiteralExpr(
       E->getLParenLoc(), NewT,
-      /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
+      /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get(),
+      E->getStorageClass(), E->getTSCSpec(),
+      E->isConstexpr() ? ConstexprSpecKind::Constexpr
+                       : ConstexprSpecKind::Unspecified);
 }
 
 template<typename Derived>
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 97f1857e200ca..2e8c055a8ac6a 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1239,6 +1239,9 @@ void ASTStmtReader::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
   E->setTypeSourceInfo(readTypeSourceInfo());
   E->setInitializer(Record.readSubExpr());
   E->setFileScope(Record.readInt());
+  E->setStorageClass(static_cast<StorageClass>(Record.readInt()));
+  E->setTSCSpec(static_cast<ThreadStorageClassSpecifier>(Record.readInt()));
+  E->setConstexpr(Record.readInt());
 }
 
 void ASTStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 70477f4cf4001..f0ff9eb1ed80f 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1206,6 +1206,9 @@ void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
   Record.AddTypeSourceInfo(E->getTypeSourceInfo());
   Record.AddStmt(E->getInitializer());
   Record.push_back(E->isFileScope());
+  Record.push_back(E->getStorageClass());
+  Record.push_back(E->getTSCSpec());
+  Record.push_back(E->isConstexpr());
   Code = serialization::EXPR_COMPOUND_LITERAL;
 }
 
diff --git a/clang/test/AST/c23-compound-literal-print.c b/clang/test/AST/c23-compound-literal-print.c
new file mode 100644
index 0000000000000..c8e4fb7d1e8e3
--- /dev/null
+++ b/clang/test/AST/c23-compound-literal-print.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -std=c23 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -std=c23 -emit-pch -o %t %s
+// RUN: %clang_cc1 -std=c23 -include-pch %t -ast-print -x c /dev/null | FileCheck %s
+
+// CHECK-LABEL: int f1(void)
+// CHECK: return (constexpr int){1} + (static _Thread_local int){2} + (register int){3} + (constexpr const int){4};
+int f1(void) {
+  return (constexpr int){1} + (_Thread_local static int){2} + (register int){3} +
+         (constexpr const int){4};
+}
+
+// CHECK-LABEL: int f2(void)
+// CHECK: return (int[3]){1, 2, 3}[0] + (constexpr int[3]){1, 2, 3}[0];
+int f2(void) {
+  return (int[3]){1, 2, 3}[0] + (constexpr int[3]){1, 2, 3}[0];
+}
+
+typedef const int T;
+
+// CHECK-LABEL: int f3(void)
+// CHECK: return (constexpr T){1} + (constexpr int[]){1}[0] + (constexpr const int[]){1}[0] + (constexpr T[]){1}[0];
+int f3(void) {
+  return (constexpr T){1} + (constexpr int[]){1}[0] +
+         (constexpr const int[]){1}[0] + (constexpr T[]){1}[0];
+}
+
+// CHECK-LABEL: void f4(void)
+// CHECK: typedef typeof (*(int (*)[(static _Thread_local int){1}])0) T1;
+// CHECK: typedef typeof (*(int (*)[(register int){1}])0) T2;
+void f4(void) {
+  typedef typeof(*(int (*)[(static thread_local int){1}])0) T1;
+  typedef typeof(*(int (*)[(register int){1}])0) T2;
+}
diff --git a/clang/test/C/drs/dr3xx.c b/clang/test/C/drs/dr3xx.c
index 0f67470b013a5..e5d85dca78122 100644
--- a/clang/test/C/drs/dr3xx.c
+++ b/clang/test/C/drs/dr3xx.c
@@ -226,6 +226,7 @@ extern int dr339_v;
 void *dr339 = &(int (*)[dr339_v]){ 0 }; /* c89only-warning {{variable length arrays are a C99 feature}}
                                            c99andup-warning {{variable length array used}}
                                            c89only-warning {{compound literals are a C99-specific feature}}
+                                           c23andup-error {{variably modified type declaration not allowed at file scope}}
                                          */
 
 /* WG14 DR340: yes
diff --git a/clang/test/CodeGen/c23-compound-literal.c b/clang/test/CodeGen/c23-compound-literal.c
new file mode 100644
index 0000000000000..d255e72a23d1b
--- /dev/null
+++ b/clang/test/CodeGen/c23-compound-literal.c
@@ -0,0 +1,275 @@
+// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+struct S { int a; int b; };
+
+// CHECK-LABEL: define dso_local i32 @f1()
+// CHECK: %[[VALUE:.*]] = load i32, ptr @.compoundliteral, align 4
+// CHECK-NEXT: ret i32 %[[VALUE]]
+int f1(void) {
+  return (static int){42};
+}
+
+// CHECK-LABEL: define dso_local i32 @f2()
+// CHECK: %.compoundliteral = alloca i32
+// CHECK: store i32 7, ptr %.compoundliteral
+// CHECK-NEXT: %[[VALUE:.*]] = load i32, ptr %.compoundliteral, align 4
+// CHECK-NEXT: ret i32 %[[VALUE]]
+int f2(void) {
+  return (constexpr int){7};
+}
+
+// CHECK-LABEL: define dso_local ptr @f3()
+// CHECK: ret ptr @.compoundliteral.1
+const int *f3(void) {
+  return &(static constexpr int){15};
+}
+
+// CHECK-LABEL: define dso_local i32 @f4()
+// CHECK: [[ADDR:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @.compoundliteral.2)
+// CHECK-NEXT: %[[VALUE:.*]] = load i32, ptr [[ADDR]], align 4
+// CHECK-NEXT: ret i32 %[[VALUE]]
+int f4(void) {
+  return (thread_local static int){2};
+}
+
+// CHECK-LABEL: define dso_local ptr @f5()
+// CHECK: [[ADDR:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @.compoundliteral.3)
+// CHECK-NEXT: ret ptr [[ADDR]]
+int *f5(void) {
+  return &(thread_local static int){2};
+}
+
+// CHECK-LABEL: define dso_local i32 @f6()
+// CHECK: store ptr @.compoundliteral.4, ptr %a, align 8
+// CHECK-NEXT: %[[BASE:.*]] = load ptr, ptr %a, align 8
+// CHECK-NEXT: %[[MEMBER:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[BASE]], i32 0, i32 0
+// CHECK-NEXT: %[[VALUE:.*]] = load i32, ptr %[[MEMBER]], align 4
+// CHECK-NEXT: ret i32 %[[VALUE]]
+int f6(void) {
+  struct S *a = &(static struct S){1, 2};
+  return a->a;
+}
+
+// CHECK-LABEL: define dso_local i64 @f7()
+// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %retval, ptr align 4 @.compoundliteral.5, i64 8, i1 true)
+// CHECK-NEXT: %[[VALUE:.*]] = load i64, ptr %retval, align 4
+// CHECK-NEXT: ret i64 %[[VALUE]]
+struct S f7(void) {
+  return (static volatile struct S){9, 10};
+}
+
+// CHECK-LABEL: define dso_local i64 @f8()
+// CHECK: [[ADDR:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @.compoundliteral.6)
+// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %retval, ptr align 4 [[ADDR]], i64 8, i1 true)
+// CHECK-NEXT: %[[VALUE:.*]] = load i64, ptr %retval, align 4
+// CHECK-NEXT: ret i64 %[[VALUE]]
+struct S f8(void) {
+  return (thread_local static volatile struct S){11, 12};
+}
+
+// CHECK-LABEL: define dso_local i64 @f9()
+// CHECK: %.compoundliteral = alloca %struct.S
+// CHECK: store i32 13
+// CHECK: store i32 14
+// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %retval, ptr align 4 %.compoundliteral, i64 8, i1 true)
+// CHECK-NEXT: %[[VALUE:.*]] = load i64, ptr %retval, align 4
+// CHECK-NEXT: ret i64 %[[VALUE]]
+struct S f9(void) {
+  return (register volatile struct S){13, 14};
+}
+
+// CHECK-LABEL: define dso_local i32 @f10()
+// CHECK: %.compoundliteral = alloca %struct.S
+// CHECK: store i32 3
+// CHECK: store i32 4
+// CHECK: store ptr %.compoundliteral, ptr %a, align 8
+// CHECK-NEXT: %[[BASE:.*]] = load ptr, ptr %a, align 8
+// CHECK-NEXT: %[[MEMBER:.*]] = getelementptr inbounds nuw %struct.S, ptr %[[BASE]], i32 0, i32 0
+// CHECK-NEXT: %[[VALUE:.*]] = load i32, ptr %[[MEMBER]], align 4
+// CHECK-NEXT: ret i32 %[[VALUE]]
+int f10(void) {
+  const struct S *a = &(constexpr struct S){3, 4};
+  return a->a;
+}
+
+// CHECK-LABEL: define dso_local i32 @f11()
+// CHECK: %[[VALUE:.*]] = load i32, ptr @.compoundliteral.7, align 4
+// CHECK-NEXT: ret i32 %[[VALUE]]
+int f11(void) {
+  return (static int[]){5, 6, 7}[0];
+}
+
+// CHECK-LABEL: define dso_local i32 @f12()
+// CHECK: %.compoundliteral = alloca [3 x i32]
+// CHECK: store i32 8, ptr %.compoundliteral
+// CHECK: store i32 9
+// CHECK: store i32 10
+// CHECK: %[[ELEMENT:.*]] = getelementptr inbounds [3 x i32], ptr %.compoundliteral, i64 0, i64 0
+// CHECK-NEXT: %[[VALUE:.*]] = load i32, ptr %[[ELEMENT]], align 4
+// CHECK-NEXT: ret i32 %[[VALUE]]
+int f12(void) {
+  return (constexpr int[]){8, 9, 10}[0];
+}
+
+// CHECK-LABEL: define dso_local i32 @f13()
+// CHECK: %.compoundliteral = alloca i32
+// CHECK: store i32 99, ptr %.compoundliteral
+// CHECK-NEXT: %[[VALUE:.*]] = load i32, ptr %.compoundliteral, align 4
+// CHECK-NEXT: ret i32 %[[VALUE]]
+int f13(void) {
+  return (register constexpr int){99};
+}
+
+// CHECK-LABEL: define dso_local i32 @f14()
+// CHECK: %a = alloca i32
+// CHECK: store i32 16, ptr %a
+// CHECK-NEXT: %[[VALUE:.*]] = load atomic i32, ptr %a seq_cst, align 4
+// CHECK-NEXT: ret i32 %[[VALUE]]
+int f14(void) {
+  register _Atomic int a = 16;
+  return a;
+}
+
+// CHECK-LABEL: define dso_local i32 @f15()
+// CHECK: %.compoundliteral = alloca i32
+// CHECK: store i32 16, ptr %.compoundliteral
+// CHECK-NEXT: %[[VALUE:.*]] = load atomic i32, ptr %.compoundliteral seq_cst, align 4
+// CHECK-NEXT: ret i32 %[[VALUE]]
+int f15(void) {
+  return (register _Atomic int){16};
+}
+
+// CHECK-LABEL: define dso_local i64 @f16()
+// CHECK: %a = alloca %struct.S, align 8
+// CHECK: store i32 17
+// CHECK: store i32 18
+// CHECK: %[[VALUE:.*]] = load atomic i64, ptr %a seq_cst, align 8
+// CHECK-NEXT: store i64 %[[VALUE]], ptr %retval, align 4
+// CHECK-NEXT: %[[RESULT:.*]] = load i64, ptr %retval, align 4
+// CHECK-NEXT: ret i64 %[[RESULT]]
+struct S f16(void) {
+  register _Atomic(struct S) a = {(struct S){17, 18}};
+  return a;
+}
+
+// CHECK-LABEL: define dso_local i64 @f17()
+// CHECK: %.compoundliteral = alloca %struct.S, align 8
+// CHECK: store i32 17
+// CHECK: store i32 18
+// CHECK: %[[VALUE:.*]] = load atomic i64, ptr %.compoundliteral seq_cst, align 8
+// CHECK-NEXT: store i64 %[[VALUE]], ptr %retval, align 4
+// CHECK-NEXT: %[[RESULT:.*]] = load i64, ptr %retval, align 4
+// CHECK-NEXT: ret i64 %[[RESULT]]
+struct S f17(void) {
+  return (register _Atomic(struct S)){(struct S){17, 18}};
+}
+
+// CHECK-LABEL: define dso_local i32 @f18()
+// CHECK: %.compoundliteral = alloca i32
+// CHECK: store i32 5, ptr %.compoundliteral
+// CHECK-NEXT: %[[VALUE:.*]] = load i32, ptr %.compoundliteral, align 4
+// CHECK-NEXT: ret i32 %[[VALUE]]
+int f18(void) {
+  return (int){5};
+}
+
+// CHECK-LABEL: define dso_local i32 @f19(i32 noundef %a)
+// CHECK: %[[OLD:.*]] = load i32, ptr %a.addr, align 4
+// CHECK-NEXT: %[[INC:.*]] = add nsw i32 %[[OLD]], 1
+// CHECK-NEXT: store i32 %[[INC]], ptr %a.addr, align 4
+// CHECK: load ptr, ptr @.compoundliteral.8, align 8
+// CHECK: %[[RESULT:.*]] = load i32, ptr %a.addr, align 4
+// CHECK-NEXT: ret i32 %[[RESULT]]
+int f19(int a) {
+  (void)(static int (*)[a++]){0};
+  return a;
+}
+
+// CHECK-LABEL: define dso_local i32 @f20(i32 noundef %a)
+// CHECK: %[[OLD:.*]] = load i32, ptr %a.addr, align 4
+// CHECK-NEXT: %[[INC:.*]] = add nsw i32 %[[OLD]], 1
+// CHECK-NEXT: store i32 %[[INC]], ptr %a.addr, align 4
+// CHECK: %[[ADDR:.*]] = call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @.compoundliteral.9)
+// CHECK-NEXT: load ptr, ptr %[[ADDR]], align 8
+// CHECK: %[[RESULT:.*]] = load i32, ptr %a.addr, align 4
+// CHECK-NEXT: ret i32 %[[RESULT]]
+int f20(int a) {
+  (void)(thread_local static int (*)[a++]){0};
+  return a;
+}
+
+int f21(void);
+
+// CHECK-LABEL: define dso_local i32 @f22(
+// CHECK: %.compoundliteral = alloca i32
+// CHECK: [[CALL:%call]] = call i32 @f21()
+// CHECK-NEXT: store i32 [[CALL]], ptr %.compoundliteral
+// CHECK-NEXT: %[[BOUND:.*]] = load i32, ptr %.compoundliteral, align 4
+// CHECK-NEXT: zext i32 %[[BOUND]] to i64
+// CHECK: ret i32
+// CHECK-NEXT: }
+int f22(int a[(int){f21()}]) {
+  return a[0];
+}
+
+// CHECK-LABEL: define dso_local i32 @f23(
+// CHECK: %.compoundliteral = alloca i32
+// CHECK: [[CALL:%call]] = call i32 @f21()
+// CHECK-NEXT: store i32 [[CALL]], ptr %.compoundliteral
+// CHECK-NEXT: %[[BOUND:.*]] = load i32, ptr %.compoundliteral, align 4
+// CHECK-NEXT: zext i32 %[[BOUND]] to i64
+// CHECK: ret i32
+// CHECK-NEXT: }
+int f23(int a[(register int){f21()}]) {
+  return a[0];
+}
+
+// CHECK-LABEL: define dso_local i32 @f24(
+// CHECK: %[[BOUND:.*]] = load volatile i32, ptr @.compoundliteral.10, align 4
+// CHECK-NEXT: zext i32 %[[BOUND]] to i64
+// CHECK: ret i32
+// CHECK-NEXT: }
+int f24(int a[(static volatile int){13}]) {
+  return a[0];
+}
+
+// CHECK-LABEL: define dso_local i32 @f25(
+// CHECK: [[ADDR:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @.compoundliteral.11)
+// CHECK-NEXT: %[[BOUND:.*]] = load volatile i32, ptr [[ADDR]], align 4
+// CHECK-NEXT: zext i32 %[[BOUND]] to i64
+// CHECK: ret i32
+// CHECK-NEXT: }
+int f25(int a[(static thread_local volatile int){14}]) {
+  return a[0];
+}
+
+// CHECK-LABEL: define dso_local i32 @f26(
+// CHECK-NOT: call i32 @f21()
+// CHECK-NOT: load volatile i32
+// CHECK: ret i32 0
+int f26(int b(int a[((int){f21()} + (static volatile int){15})])) {
+  return 0;
+}
+
+// CHECK-LABEL: define dso_local i32 @f27(
+// CHECK: %.compoundliteral = alloca i32
+// CHECK: [[CALL:%call]] = call i32 @f21()
+// CHECK-NEXT: store i32 [[CALL]], ptr %.compoundliteral
+// CHECK-NEXT: load i32, ptr %.compoundliteral, align 4
+// CHECK-NEXT: ret i32 0
+int f27(int (*a(void))[((void)(int){f21()}, 1)]) {
+  return 0;
+}
+
+int f28(const int *);
+
+// CHECK-LABEL: define dso_local i32 @f29(
+// CHECK: %.compoundliteral = alloca i32
+// CHECK: store i32 3, ptr %.compoundliteral
+// CHECK-NEXT: %[[CALL:.*]] = call i32 @f28(ptr noundef %.compoundliteral)
+// CHECK-NEXT: zext i32 %[[CALL]] to i64
+// CHECK: ret i32
+// CHECK-NEXT: }
+int f29(int a[f28(&(constexpr int){3})]) {
+  return a[0];
+}
diff --git a/clang/test/CodeGenObjC/c23-compound-literal.m b/clang/test/CodeGenObjC/c23-compound-literal.m
new file mode 100644
index 0000000000000..245284cb23017
--- /dev/null
+++ b/clang/test/CodeGenObjC/c23-compound-literal.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c23 -triple x86_64-apple-macosx10.15 -emit-llvm -fobjc-arc -disable-llvm-passes -o - %s | FileCheck %s
+
+typedef struct {
+  id a;
+} S;
+int f1(const S *);
+
+// CHECK-LABEL: define i32 @f2(
+// CHECK: %.compoundliteral = alloca %struct.S, align 8
+// CHECK: store ptr null, ptr %{{.*}}, align 8
+// CHECK: %[[CALL:.*]] = call i32 @f1(ptr noundef %.compoundliteral)
+// CHECK-NEXT: zext i32 %[[CALL]] to i64
+// CHECK: %[[RESULT:.*]] = load i32, ptr %{{.*}}, align 4
+// CHECK-NEXT: call void @__destructor_8_s0(ptr %.compoundliteral)
+// CHECK-NEXT: ret i32 %[[RESULT]]
+// CHECK-NEXT: }
+int f2(int a[f1(&(constexpr S){.a = 0})]) {
+  return a[0];
+}
diff --git a/clang/test/Parser/expressions.c b/clang/test/Parser/expressions.c
index 82556c091206f..2921158dd5f35 100644
--- a/clang/test/Parser/expressions.c
+++ b/clang/test/Parser/expressions.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c17 -fsyntax-only -verify=expected,c17 %s
+// RUN: %clang_cc1 -std=c23 -Wpre-c23-compat -fsyntax-only -verify=expected,c23 %s
+// RUN: %clang_cc1 -std=c23 -triple x86_64-apple-darwin10 -fsyntax-only -verify=expected,notls %s
 
 void test1(void) {
   if (sizeof (int){ 1}) {}   // sizeof compound literal
@@ -73,3 +75,17 @@ void test8(void) {
   callee(foobar,   // expected-error {{use of undeclared identifier 'foobar'}}
          fizbin);  // expected-error {{use of undeclared identifier 'fizbin'}}
 }
+
+void test9(void) {
+  (void)(static int){1}; // c17-error {{expected expression}} \
+                         // c23-warning {{compound literal storage-class specifiers are incompatible with C standards before C23}}
+
+  (void)(register int){2}; // c17-error {{expected expression}} \
+                           // c23-warning {{compound literal storage-class specifiers are incompatible with C standards before C23}}
+
+  (void)(constexpr int){3}; // c17-error {{use of undeclared identifier 'constexpr'}} \
+                            // c23-warning {{compound literal storage-class specifiers are incompatible with C standards before C23}}
+
+  (void)(_Thread_local static int){4}; // c17-error {{expected expression}} notls-error {{thread-local storage is not supported for the current target}} \
+                                       // c23-warning {{compound literal storage-class specifiers are incompatible with C standards before C23}}
+}
diff --git a/clang/test/Sema/c23-compound-literal.c b/clang/test/Sema/c23-compound-literal.c
new file mode 100644
index 0000000000000..44759108bcd3a
--- /dev/null
+++ b/clang/test/Sema/c23-compound-literal.c
@@ -0,0 +1,343 @@
+// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -verify -fsyntax-only %s
+// RUN: %clang_cc1 -std=c23 -triple x86_64-scei-ps4 -verify=expected,ps4 -fsyntax-only %s
+
+#define M static
+struct S { int a; char b; };
+int f1(void);
+
+void test1(void) {
+  (void)(constexpr int){1};
+  (void)&(static int){42};
+  (void)(register int){0};
+  (void)(static thread_local int){1};
+  (void)(constexpr struct S){1, 'a'};
+  (void)(static struct S){2, 'b'};
+  (void)(register struct S){3, 'c'};
+}
+
+void test2(void) {
+  (void)(static constexpr int){1};
+  (void)(constexpr static int){2};
+  (void)(static thread_local int){3};
+  (void)(thread_local static int){4};
+  (void)(constexpr register int){5};
+  (void)(constexpr static thread_local int){6}; // expected-error {{cannot combine with previous '_Thread_local' declaration specifier}}
+}
+
+void test3(void) {
+  (void)(static static int){1};             // expected-warning {{duplicate 'static' declaration specifier}}
+  (void)(constexpr constexpr int){2};       // expected-warning {{duplicate 'constexpr' declaration specifier}}
+  (void)(register register int){3};         // expected-warning {{duplicate 'register' declaration specifier}}
+  (void)(thread_local thread_local int){4}; // expected-warning {{duplicate '_Thread_local' declaration specifier}} expected-error {{compound literal with 'thread_local' storage duration at block scope must also specify 'static'}}
+}
+
+void test4(void) {
+  (void)(register static int){1};       // expected-error {{cannot combine with previous 'register' declaration specifier}}
+  (void)(register thread_local int){2}; // expected-error {{cannot combine with previous 'register' declaration specifier}}
+  (void)(register constexpr int){3};
+  (void)(static register int){4};       // expected-error {{cannot combine with previous 'static' declaration specifier}}
+  (void)(register _Atomic int){5};
+}
+
+void test5(void) {
+  (void)&(thread_local int){1}; // expected-error {{compound literal with 'thread_local' storage duration at block scope must also specify 'static'}}
+}
+
+int *a1 = &(register int){42}; // expected-error {{file-scope compound literal specifies 'register'}}
+
+void test6(void) {
+  (void)(constexpr volatile int){1}; // expected-error {{constexpr compound literal cannot have type 'const volatile int'}}
+  (void)(constexpr _Atomic int){1};  // expected-error {{constexpr compound literal cannot have type 'const _Atomic(int)'}}
+
+  int c;
+  (void)(constexpr int[c]){0}; // expected-error {{constexpr compound literal cannot have type 'const int[c]'}}
+}
+
+void test7(void) {
+  (void)(constexpr int){f1()};          // expected-error {{initializer of compound literal must be a constant expression}}
+  (void)(static int){f1()};             // expected-error {{initializer element is not a compile-time constant}}
+  (void)(register constexpr int){f1()}; // expected-error {{initializer of compound literal must be a constant expression}}
+  (void)(constexpr int){1 / 0};
+  // expected-error at -1 {{initializer of compound literal must be a constant expression}}
+  // expected-note at -2 {{division by zero}}
+  // expected-warning at -3 {{division by zero is undefined}}
+}
+
+const int a2 = 1;
+const double a3 = 1.0;
+
+void test8(void) {
+  (void)(constexpr int){a2};    // expected-error {{initializer of compound literal must be a constant expression}}
+  (void)(constexpr double){a3}; // expected-error {{initializer of compound literal must be a constant expression}}
+
+  const int a = 2;
+  (void)(constexpr int){a}; // expected-error {{initializer of compound literal must be a constant expression}}
+
+  struct S1 {
+    int a;
+  };
+
+  (void)(constexpr int){(constexpr int){1}};
+  (void)(constexpr struct S1){.a = (constexpr int){1}};
+  (void)(constexpr int){(int){1}};
+  (void)(constexpr int){(static int){1}};
+}
+
+void test9(void) {
+  int *a = &(register int){1};   // expected-error {{address of register compound literal requested}}
+  int *b = (register int[1]){1}; // expected-error {{address of register compound literal requested}}
+  struct S2 { int a; };
+  int *c = &(register struct S2){1}.a;                   // expected-error {{address of register compound literal requested}}
+  double *d = &__real__ (register _Complex double){1};   // expected-error {{address of register compound literal requested}}
+  double *e = &__imag__ (register _Complex double){1};   // expected-error {{address of register compound literal requested}}
+  int *f = &_Generic(0, int: (register int){1});         // expected-error {{address of register compound literal requested}}
+  int *g = _Generic(0, int: (register int[1]){1});       // expected-error {{address of register compound literal requested}}
+  int *h = &_Generic(0, int: (register struct S2){1}).a; // expected-error {{address of register compound literal requested}}
+  int *i = &__extension__ (register int){1};             // expected-error {{address of register compound literal requested}}
+}
+
+int a5[1];
+struct S3 {
+  int *a;
+};
+struct S4 {
+  int a[1];
+};
+
+int *test10(void) {
+  return &((register struct S3){a5}.a[0]);
+}
+
+int *test11(void) {
+  return &(register struct S4){{1}}.a[0]; // expected-error {{address of register compound literal requested}}
+}
+
+enum { E1 = (constexpr int){42} };
+enum { E2 = (constexpr int){} };
+static int a6[(constexpr int){10}];
+static int a7[(constexpr int){} + 1];
+static const int *a8 = &(constexpr int){5};
+static int a9 = (constexpr int){7};
+static_assert(!(constexpr int){});
+
+struct S5 { int a; };
+enum { E3 = (constexpr struct S5){42}.a };
+enum { E4 = (int)(constexpr double){1.0} };
+
+union U1 {
+  int a;
+  long b;
+};
+enum { E5 = (constexpr union U1){.a = 9}.a };
+enum {
+  E6 = (constexpr union U1){.a = 9}.b
+  // expected-error at -1 {{expression is not an integer constant expression}}
+  // expected-note at -2 {{read of member 'b' of union with active member 'a' is not allowed in a constant expression}}
+};
+
+void test12(void) {
+  static int a = (constexpr int){8};
+  int b[(constexpr int){3}];
+  switch ((constexpr int){1}) {
+  case (constexpr int){1}:
+    break;
+  }
+}
+
+void test13(void) {
+  (constexpr int){1} = 2;             // expected-error {{read-only variable is not assignable}}
+  (constexpr int[1]){1}[0] = 2;       // expected-error {{read-only variable is not assignable}}
+  (constexpr struct S){1, 'a'}.a = 2; // expected-error {{read-only variable is not assignable}}
+}
+
+int *a10 = &(static int){100};
+int *a11 = &(thread_local int){200}; // expected-error {{initializer element is not a compile-time constant}}
+const int *a12 = &(constexpr int){300};
+
+void test14(void) {
+  const int *a = (constexpr int[]){1, 2, 3};
+  int *b = (static int[]){4, 5, 6};
+}
+
+int a13 = (thread_local int){1};              // expected-error {{initializer element is not a compile-time constant}}
+int a14 = (thread_local static int){1};       // expected-error {{initializer element is not a compile-time constant}}
+int a15 = 1 + (thread_local int){1};          // expected-error {{initializer element is not a compile-time constant}}
+int a16 = +(thread_local int){1};             // expected-error {{initializer element is not a compile-time constant}}
+int a17 = (thread_local struct S5){1}.a;      // expected-error {{initializer element is not a compile-time constant}}
+int a18 = *(thread_local int[1]){1};          // expected-error {{initializer element is not a compile-time constant}}
+
+struct S7 {
+  unsigned char a;
+};
+
+void test15(void) {
+  static int a;
+  (void)(constexpr int *){&a};     // expected-error {{constexpr pointer initializer is not null}}
+  (void)(constexpr struct S7){-1}; // expected-error {{constexpr initializer evaluates to -1 which is not exactly representable in type 'unsigned char'}}
+}
+
+int a19[3];
+static int *a20 = a19 + (constexpr int){1};
+static int *a21 = (constexpr int){0}; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
+static int *a22 = (constexpr int *){0};
+
+struct S8 {
+  int *restrict a;
+};
+void test16(void) {
+  (void)(constexpr struct S8){0}; // expected-error {{constexpr compound literal cannot have type 'int *restrict'}}
+}
+
+void test17(void) {
+  (void)(constexpr char[]){"\xFF"};
+  (void)(constexpr unsigned char[]){"\xFF"}; // expected-error {{constexpr initializer evaluates to -1 which is not exactly representable in type 'const unsigned char'}}
+}
+
+void test18(void) {
+  static const int *a = &(constexpr int){1}; // expected-error {{initializer element is not a compile-time constant}}
+  static const int *b = &(static constexpr int){1};
+}
+
+void f2(int a[sizeof((static int){1})]);
+void f3(int a[sizeof((register int){1})]);
+void f4(int a[sizeof((constexpr int){1})]);
+void f5(int a[sizeof((thread_local static int){1})]);
+int f6(void);
+
+void f7(int a[(constexpr int){f6()}]); // expected-error {{initializer of compound literal must be a constant expression}}
+void f8(int a[(static int){f6()}]);    // expected-error {{initializer element is not a compile-time constant}}
+
+typedef void F1(int a[(int){f6()}]);
+typedef void F2(int a[(thread_local int){1}]); // expected-error {{compound literal with 'thread_local' storage duration at block scope must also specify 'static'}}
+void (*a23)(int a[(register int){f6()}]);
+
+typedef int T __attribute__((address_space(1)));
+void f9(int a[sizeof((T){0})]);  // expected-error {{compound literal in function scope may not be qualified with an address space}}
+int f10(int a[sizeof((T){0})]) { // expected-error {{compound literal in function scope may not be qualified with an address space}}
+  return a[0];
+}
+
+void test19(void) {
+  (static T){0}; // expected-error {{compound literal in function scope may not be qualified with an address space}}
+}
+
+int f11(
+    typeof(sizeof((register T){0})) a(void)) { // expected-error {{compound literal in function scope may not be qualified with an address space}}
+  return a();
+}
+
+inline int f12(void) {    // expected-note {{use 'static' to give inline function 'f12' internal linkage}}
+  return (static int){1}; // expected-warning {{non-constant static local variable in inline function may be different in different files}}
+}
+
+inline int f13(int a[(static int){1}]) { // expected-warning {{non-constant static local variable in inline function may be different in different files}} \
+                                         // expected-note {{use 'static' to give inline function 'f13' internal linkage}}
+  return a[0];
+}
+
+inline int f14(int a[(static int){1}]);
+
+inline int f15(int a[(static const int){1}]) {
+  return a[0];
+}
+
+extern inline int f16(int a[(static int){1}]) {
+  return a[0];
+}
+
+static inline int f17(int a[(static int){1}]) {
+  return a[0];
+}
+
+inline int f18(int b(int a[sizeof((static int){1})])) {
+  return 0;
+}
+
+inline int f19(int (*a(void))[sizeof((static int){1})]) { // expected-warning {{non-constant static local variable in inline function may be different in different files}}
+                                                          // expected-note at -1 {{use 'static' to give inline function 'f19' internal linkage}}
+  return 0;
+}
+
+inline typeof((static int){1}) f20(void) {
+  return 0;
+}
+typeof((register int){1}) f21(void); // expected-error {{file-scope compound literal specifies 'register'}}
+
+inline int f22(int a) __attribute__((enable_if((static int){1}, "enabled"))) { // expected-warning {{non-constant static local variable in inline function may be different in different files}} \
+                                                                               // expected-note {{use 'static' to give inline function 'f22' internal linkage}}
+  return a;
+}
+
+int f23(int a) __attribute__((enable_if(sizeof((register T){0}), "enabled"))) { // expected-error {{compound literal in function scope may not be qualified with an address space}}
+  return a;
+}
+
+int f24(int a) __attribute__((enable_if( sizeof((register T){0}), "enabled"))); // expected-error {{compound literal in function scope may not be qualified with an address space}}
+int f24(int a) {
+  return a;
+}
+
+int a24;
+int a25 = sizeof((thread_local static int (*)[a24]){0}); // expected-error {{variably modified type declaration not allowed at file scope}}
+
+int *f25(void) {
+  return &(static int){1};
+}
+
+int *f26(void) {
+  return &(thread_local static int){1};
+}
+
+int *f27(void) {
+  return &(int){1}; // expected-warning {{address of stack memory associated with compound literal '{1}' returned}}
+}
+
+const int *f28(void) {
+  return &(constexpr int){1}; // expected-warning {{address of stack memory associated with compound literal '{1}' returned}}
+}
+
+inline int f29(void) {                 // expected-note {{use 'static' to give inline function 'f29' internal linkage}}
+  return (thread_local static int){1}; // expected-warning {{non-constant static local variable in inline function may be different in different files}}
+}
+
+void test20(void) {
+  (void)(M const int){1};
+  (void)(constexpr unsigned long){2};
+  (void)sizeof (static int){1};
+  (void)sizeof (static thread_local int){1};
+  (void)sizeof (constexpr int){1};
+}
+
+void test21(void) {
+  (void)(const static int){1};   // expected-error {{type name does not allow storage class to be specified}}
+  (void)(const int register){1}; // expected-error {{type name does not allow storage class to be specified}}
+}
+
+void test22(void) {
+  (void)(auto int){1};        // expected-error {{expected expression}}
+  (void)(extern int){2};      // expected-error {{expected expression}}
+  (void)(typedef int){3};     // expected-error {{expected expression}}
+  (void)(__auto_type int){4}; // expected-error {{expected expression}}
+  (void)(__thread int){5};    // expected-error {{expected expression}}
+}
+
+void test23(void) {
+  (void)(static int constexpr){1};     // expected-error {{type name does not allow constexpr specifier to be specified}}
+  (void)(static int thread_local){1};  // expected-error {{type name does not allow storage class to be specified}}
+  (void)(static int _Thread_local){1}; // expected-error {{type name does not allow storage class to be specified}}
+  (void)(static int __thread){1};      // expected-error {{type name does not allow storage class to be specified}}
+}
+
+void test24(void) {
+  (void)(static int)1;              // expected-error {{type name does not allow storage class to be specified}}
+  (void)sizeof(register int);       // expected-error {{type name does not allow storage class to be specified}}
+  (void)_Alignof(thread_local int); // expected-error {{type name does not allow storage class to be specified}}
+  (void)(constexpr int)1;           // expected-error {{type name does not allow constexpr specifier to be specified}}
+}
+
+int a26 = (static)3; // expected-error {{type name requires a specifier or qualifier}}
+
+typedef int A __attribute__((aligned(64)));
+A *f30(void) {
+  return &(thread_local static A){1}; // ps4-error {{alignment (64) of thread-local compound literal is greater than the maximum supported alignment (32) for thread-local storage on this target}}
+}
diff --git a/clang/test/Sema/c23-compound-literal.m b/clang/test/Sema/c23-compound-literal.m
new file mode 100644
index 0000000000000..142e5a49499eb
--- /dev/null
+++ b/clang/test/Sema/c23-compound-literal.m
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -std=c23 -fobjc-arc -verify %s
+
+typedef struct {
+  id a;
+} S;
+
+void test1(void) {
+  (void)(thread_local static __unsafe_unretained id){0};
+  (void)(thread_local static id){0}; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}}
+  (void)(thread_local static S){0};  // expected-error {{type of thread-local variable has non-trivial destruction}}
+}
diff --git a/clang/test/Sema/constexpr.c b/clang/test/Sema/constexpr.c
index 0a9b5724a8343..936e0a3a32e19 100644
--- a/clang/test/Sema/constexpr.c
+++ b/clang/test/Sema/constexpr.c
@@ -22,7 +22,7 @@ struct S3 {
 constexpr; // expected-error {{'constexpr' can only be used in variable declarations}}
 constexpr int V1 = 3;
 constexpr float V2 = 7.0;
-int V3 = (constexpr)3; // expected-error {{expected expression}}
+int V3 = (constexpr)3; // expected-error {{type name requires a specifier or qualifier}}
 
 void f2() {
   constexpr int a = 0;

>From f7af8028bf85cdc59b72cdeeb89fa17379910742 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Wed, 29 Jul 2026 10:04:08 +0300
Subject: [PATCH 02/21] use hasGlobalStorage for compound literal emission

---
 clang/lib/CodeGen/CGExpr.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index fadf00a606f3e..705d2dbb49a80 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5993,7 +5993,7 @@ CodeGenFunction::EmitLValueForFieldInitialization(LValue Base,
 }
 
 LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
-  if (E->isFileScope() || E->hasGlobalStorage()) {
+  if (E->hasGlobalStorage()) {
     if (E->getType()->isVariablyModifiedType())
       EmitVariablyModifiedType(E->getType());
 

>From 6ac710f83045b359a0ca12d448480edcd8e418df Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Wed, 29 Jul 2026 11:32:54 +0300
Subject: [PATCH 03/21] parse all storage-class specifiers in compound literals

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  2 ++
 clang/lib/Parse/ParseExpr.cpp                    | 15 +++++++++++++++
 clang/lib/Sema/SemaExpr.cpp                      | 11 +++++++++--
 clang/test/Sema/c23-compound-literal.c           |  6 +++---
 4 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 85528249c4be4..19d086abd8c0e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3183,6 +3183,8 @@ def err_register_compound_literal_file_scope : Error<
 def err_thread_local_compound_literal_without_static : Error<
   "compound literal with 'thread_local' storage duration at block scope must "
   "also specify 'static'">;
+def err_compound_literal_invalid_storage_class : Error<
+  "storage class specifier '%0' is not permitted in a compound literal">;
 def err_constexpr_compound_literal_invalid_type : Error<
   "constexpr compound literal cannot have type %0">;
 def err_compound_literal_initializer_not_constant : Error<
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 55e1d489efb39..9ae51290fa0ad 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -2660,11 +2660,14 @@ bool Parser::isCompoundLiteralStorageClassSpecifier(const Token &Tok) const {
   if (!getLangOpts().C23)
     return false;
   switch (Tok.getKind()) {
+  case tok::kw_auto:
   case tok::kw_constexpr:
+  case tok::kw_extern:
   case tok::kw_register:
   case tok::kw_static:
   case tok::kw_thread_local:
   case tok::kw__Thread_local:
+  case tok::kw_typedef:
     return true;
   default:
     return false;
@@ -2680,10 +2683,22 @@ void Parser::ParseCompoundLiteralStorageClassSpecifiers(DeclSpec &DS) {
     unsigned DiagID = 0;
     bool IsInvalid = false;
     switch (Tok.getKind()) {
+    case tok::kw_typedef:
+      IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
+                                         PrevSpec, DiagID, Policy);
+      break;
+    case tok::kw_extern:
+      IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
+                                         PrevSpec, DiagID, Policy);
+      break;
     case tok::kw_static:
       IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
                                          PrevSpec, DiagID, Policy);
       break;
+    case tok::kw_auto:
+      IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
+                                         PrevSpec, DiagID, Policy);
+      break;
     case tok::kw_register:
       IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
                                          PrevSpec, DiagID, Policy);
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index b5f19964cbefd..9d2c027e29fa5 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7533,10 +7533,17 @@ ExprResult Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
   SourceLocation ThreadStorageClassLoc;
   SourceLocation ConstexprLoc;
   if (DS) {
-    if (DS->getStorageClassSpec() == DeclSpec::SCS_static)
+    DeclSpec::SCS StorageClassSpec = DS->getStorageClassSpec();
+    if (StorageClassSpec == DeclSpec::SCS_static)
       SC = SC_Static;
-    else if (DS->getStorageClassSpec() == DeclSpec::SCS_register)
+    else if (StorageClassSpec == DeclSpec::SCS_register)
       SC = SC_Register;
+    else if (StorageClassSpec != DeclSpec::SCS_unspecified) {
+      Diag(DS->getStorageClassSpecLoc(),
+           diag::err_compound_literal_invalid_storage_class)
+          << DeclSpec::getSpecifierName(StorageClassSpec);
+      return ExprError();
+    }
 
     TSC = DS->getThreadStorageClassSpec();
     ConstexprKind = DS->getConstexprSpecifier();
diff --git a/clang/test/Sema/c23-compound-literal.c b/clang/test/Sema/c23-compound-literal.c
index 44759108bcd3a..187ea81608b55 100644
--- a/clang/test/Sema/c23-compound-literal.c
+++ b/clang/test/Sema/c23-compound-literal.c
@@ -314,9 +314,9 @@ void test21(void) {
 }
 
 void test22(void) {
-  (void)(auto int){1};        // expected-error {{expected expression}}
-  (void)(extern int){2};      // expected-error {{expected expression}}
-  (void)(typedef int){3};     // expected-error {{expected expression}}
+  (void)(auto int){1};        // expected-error {{storage class specifier 'auto' is not permitted in a compound literal}}
+  (void)(extern int){2};      // expected-error {{storage class specifier 'extern' is not permitted in a compound literal}}
+  (void)(typedef int){3};     // expected-error {{storage class specifier 'typedef' is not permitted in a compound literal}}
   (void)(__auto_type int){4}; // expected-error {{expected expression}}
   (void)(__thread int){5};    // expected-error {{expected expression}}
 }

>From 58a103790483ce9d7a688b84fd62d3c1564764cb Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Wed, 29 Jul 2026 13:25:41 +0300
Subject: [PATCH 04/21] fix compound literal aggrs emit

---
 clang/lib/CodeGen/CGExprAgg.cpp           | 13 ++++++-------
 clang/test/CodeGen/c23-compound-literal.c | 15 +++++++++++++--
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index c1309c456d4e3..a54ea7c599b1a 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -789,15 +789,14 @@ void AggExprEmitter::VisitOpaqueValueExpr(OpaqueValueExpr *e) {
 }
 
 void AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
-  if (E->hasGlobalStorage() || E->getType()->isAtomicType() ||
-      (E->getStorageClass() == SC_Register &&
-       E->getType().isVolatileQualified()) ||
-      Dest.isPotentiallyAliased()) {
+  QualType Ty = E->getType();
+  if (Dest.isPotentiallyAliased() || E->hasGlobalStorage() ||
+      Ty->isAtomicType() || Ty.isVolatileQualified()) {
     EmitAggLoadOfLValue(E);
     return;
   }
 
-  AggValueSlot Slot = EnsureSlot(E->getType());
+  AggValueSlot Slot = EnsureSlot(Ty);
 
   // Block-scope compound literals are destroyed at the end of the enclosing
   // scope in C.
@@ -809,9 +808,9 @@ void AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
   CGF.EmitAggExpr(E->getInitializer(), Slot);
 
   if (Destruct)
-    if (QualType::DestructionKind DtorKind = E->getType().isDestructedType())
+    if (QualType::DestructionKind DtorKind = Ty.isDestructedType())
       CGF.pushLifetimeExtendedDestroy(
-          CGF.getCleanupKind(DtorKind), Slot.getAddress(), E->getType(),
+          CGF.getCleanupKind(DtorKind), Slot.getAddress(), Ty,
           CGF.getDestroyer(DtorKind), DtorKind & EHCleanup);
 }
 
diff --git a/clang/test/CodeGen/c23-compound-literal.c b/clang/test/CodeGen/c23-compound-literal.c
index d255e72a23d1b..3f542021f5e21 100644
--- a/clang/test/CodeGen/c23-compound-literal.c
+++ b/clang/test/CodeGen/c23-compound-literal.c
@@ -51,11 +51,11 @@ int f6(void) {
 }
 
 // CHECK-LABEL: define dso_local i64 @f7()
-// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %retval, ptr align 4 @.compoundliteral.5, i64 8, i1 true)
+// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %retval, ptr align 4 @.compoundliteral.5, i64 8, i1 false)
 // CHECK-NEXT: %[[VALUE:.*]] = load i64, ptr %retval, align 4
 // CHECK-NEXT: ret i64 %[[VALUE]]
 struct S f7(void) {
-  return (static volatile struct S){9, 10};
+  return (static struct S){9, 10};
 }
 
 // CHECK-LABEL: define dso_local i64 @f8()
@@ -273,3 +273,14 @@ int f28(const int *);
 int f29(int a[f28(&(constexpr int){3})]) {
   return a[0];
 }
+
+// CHECK-LABEL: define dso_local i64 @f30()
+// CHECK: %.compoundliteral = alloca %struct.S
+// CHECK: store i32 19
+// CHECK: store i32 20
+// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %retval, ptr align 4 %.compoundliteral, i64 8, i1 true)
+// CHECK-NEXT: %[[VALUE:.*]] = load i64, ptr %retval, align 4
+// CHECK-NEXT: ret i64 %[[VALUE]]
+struct S f30(void) {
+  return (volatile struct S){19, 20};
+}

>From 203969c6027fa3a91ddbfaad36f091a7b2ce718f Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Wed, 29 Jul 2026 14:31:14 +0300
Subject: [PATCH 05/21] fix parsing of compound literal storage-class
 specifiers

---
 clang/include/clang/Parse/Parser.h     |  3 ++-
 clang/lib/Parse/ParseExpr.cpp          | 19 +++++++++++++++----
 clang/test/Sema/c23-compound-literal.c |  2 +-
 clang/test/Sema/constexpr.c            |  2 +-
 4 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 43c88344fbb2e..3fd2793eef992 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -5092,7 +5092,8 @@ class Parser : public CodeCompletionHandler {
     return isTypeIdInParens(isAmbiguous);
   }
 
-  bool isCompoundLiteralStorageClassSpecifier(const Token &Tok) const;
+  bool isCompoundLiteralStorageClassSpecifier() const;
+  bool isCompoundLiteralTypeName();
   void ParseCompoundLiteralStorageClassSpecifiers(DeclSpec &DS);
 
   /// Finish parsing a C++ unqualified-id that is a template-id of
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 9ae51290fa0ad..7fb21fdc5ba55 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -2656,7 +2656,7 @@ bool Parser::tryParseOpenMPArrayShapingCastPart() {
   return !ErrorFound;
 }
 
-bool Parser::isCompoundLiteralStorageClassSpecifier(const Token &Tok) const {
+bool Parser::isCompoundLiteralStorageClassSpecifier() const {
   if (!getLangOpts().C23)
     return false;
   switch (Tok.getKind()) {
@@ -2674,10 +2674,21 @@ bool Parser::isCompoundLiteralStorageClassSpecifier(const Token &Tok) const {
   }
 }
 
+bool Parser::isCompoundLiteralTypeName() {
+  if (!isCompoundLiteralStorageClassSpecifier())
+    return false;
+
+  RevertingTentativeParsingAction TPA(*this);
+  do
+    ConsumeToken();
+  while (isCompoundLiteralStorageClassSpecifier());
+  return isTypeIdInParens();
+}
+
 void Parser::ParseCompoundLiteralStorageClassSpecifiers(DeclSpec &DS) {
   DS.SetRangeStart(Tok.getLocation());
   const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
-  while (isCompoundLiteralStorageClassSpecifier(Tok)) {
+  while (isCompoundLiteralStorageClassSpecifier()) {
     SourceLocation Loc = Tok.getLocation();
     const char *PrevSpec = nullptr;
     unsigned DiagID = 0;
@@ -2841,7 +2852,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool StopIfCastExpr,
                                                BridgeKeywordLoc, Ty.get(),
                                                RParenLoc, SubExpr.get());
   } else if (ExprType >= ParenParseOption::CompoundLiteral &&
-             (isCompoundLiteralStorageClassSpecifier(Tok) ||
+             (isCompoundLiteralTypeName() ||
               isTypeIdInParens(isAmbiguousTypeId))) {
 
     // Otherwise, this is a compound literal expression or cast expression.
@@ -2859,7 +2870,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool StopIfCastExpr,
     }
 
     DeclSpec CompoundDS(AttrFactory);
-    if (isCompoundLiteralStorageClassSpecifier(Tok)) {
+    if (isCompoundLiteralStorageClassSpecifier()) {
       ParseCompoundLiteralStorageClassSpecifiers(CompoundDS);
       CompoundDS.Finish(Actions, Actions.getASTContext().getPrintingPolicy());
     }
diff --git a/clang/test/Sema/c23-compound-literal.c b/clang/test/Sema/c23-compound-literal.c
index 187ea81608b55..1310e5a847803 100644
--- a/clang/test/Sema/c23-compound-literal.c
+++ b/clang/test/Sema/c23-compound-literal.c
@@ -335,7 +335,7 @@ void test24(void) {
   (void)(constexpr int)1;           // expected-error {{type name does not allow constexpr specifier to be specified}}
 }
 
-int a26 = (static)3; // expected-error {{type name requires a specifier or qualifier}}
+int a26 = (static)3; // expected-error {{expected expression}}
 
 typedef int A __attribute__((aligned(64)));
 A *f30(void) {
diff --git a/clang/test/Sema/constexpr.c b/clang/test/Sema/constexpr.c
index 936e0a3a32e19..0a9b5724a8343 100644
--- a/clang/test/Sema/constexpr.c
+++ b/clang/test/Sema/constexpr.c
@@ -22,7 +22,7 @@ struct S3 {
 constexpr; // expected-error {{'constexpr' can only be used in variable declarations}}
 constexpr int V1 = 3;
 constexpr float V2 = 7.0;
-int V3 = (constexpr)3; // expected-error {{type name requires a specifier or qualifier}}
+int V3 = (constexpr)3; // expected-error {{expected expression}}
 
 void f2() {
   constexpr int a = 0;

>From bb65e74c8cd2d1a00897327dc6a623a63b00badf Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Fri, 31 Jul 2026 15:53:21 +0300
Subject: [PATCH 06/21] fix compound literal cleanup in params

---
 clang/include/clang/AST/Expr.h                 | 17 +++++++++++------
 clang/lib/AST/ASTImporter.cpp                  |  2 +-
 clang/lib/AST/StmtProfile.cpp                  |  2 +-
 clang/lib/CodeGen/CGExpr.cpp                   | 18 ++++++++++++------
 clang/lib/CodeGen/CodeGenFunction.cpp          |  4 +---
 .../lib/Frontend/Rewrite/RewriteModernObjC.cpp |  9 +++++----
 clang/lib/Frontend/Rewrite/RewriteObjC.cpp     |  9 +++++----
 clang/lib/Sema/SemaExpr.cpp                    | 13 +++++++++----
 clang/lib/Serialization/ASTReaderStmt.cpp      |  3 ++-
 clang/lib/Serialization/ASTWriterStmt.cpp      |  2 +-
 10 files changed, 48 insertions(+), 31 deletions(-)

diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 6454a750b61c9..0c247e32cb18e 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -3611,6 +3611,10 @@ class MemberExpr final
 /// CompoundLiteralExpr - [C99 6.5.2.5, C23 6.5.3.6]
 ///
 class CompoundLiteralExpr : public Expr {
+public:
+  enum class ScopeKind { Block, File, ParameterList };
+
+private:
   /// LParenLoc - If non-null, this is the location of the left paren in a
   /// compound literal like "(int){4}".  This can be null if this is a
   /// synthesized compound expression.
@@ -3618,8 +3622,7 @@ class CompoundLiteralExpr : public Expr {
 
   /// The type as written.  This can be an incomplete array type, in
   /// which case the actual expression type will be different.
-  /// The int part of the pair stores whether this expr is file scope.
-  llvm::PointerIntPair<TypeSourceInfo *, 1, bool> TInfoAndScope;
+  llvm::PointerIntPair<TypeSourceInfo *, 2, ScopeKind> TInfoAndScope;
   Stmt *Init;
 
   /// Value of constant literals with static storage duration.
@@ -3628,11 +3631,11 @@ class CompoundLiteralExpr : public Expr {
 public:
   CompoundLiteralExpr(
       SourceLocation LParenLoc, TypeSourceInfo *TInfo, QualType T,
-      ExprValueKind VK, Expr *Init, bool FileScope, StorageClass SC = SC_None,
+      ExprValueKind VK, Expr *Init, ScopeKind Scope, StorageClass SC = SC_None,
       ThreadStorageClassSpecifier TSC = TSCS_unspecified,
       ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified)
       : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary),
-        LParenLoc(LParenLoc), TInfoAndScope(TInfo, FileScope), Init(Init) {
+        LParenLoc(LParenLoc), TInfoAndScope(TInfo, Scope), Init(Init) {
     assert(Init && "Init is a nullptr");
     assert((ConstexprKind == ConstexprSpecKind::Unspecified ||
             ConstexprKind == ConstexprSpecKind::Constexpr) &&
@@ -3651,8 +3654,10 @@ class CompoundLiteralExpr : public Expr {
   Expr *getInitializer() { return cast<Expr>(Init); }
   void setInitializer(Expr *E) { Init = E; }
 
-  bool isFileScope() const { return TInfoAndScope.getInt(); }
-  void setFileScope(bool FS) { TInfoAndScope.setInt(FS); }
+  ScopeKind getScopeKind() const { return TInfoAndScope.getInt(); }
+  void setScopeKind(ScopeKind Scope) { TInfoAndScope.setInt(Scope); }
+
+  bool isFileScope() const { return getScopeKind() == ScopeKind::File; }
 
   SourceLocation getLParenLoc() const { return LParenLoc; }
   void setLParenLoc(SourceLocation L) { LParenLoc = L; }
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 97261a632390b..f0eddbba0ebff 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -8101,7 +8101,7 @@ ExpectedStmt ASTNodeImporter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
 
   return new (Importer.getToContext()) CompoundLiteralExpr(
       ToLParenLoc, ToTypeSourceInfo, ToType, E->getValueKind(), ToInitializer,
-      E->isFileScope(), E->getStorageClass(), E->getTSCSpec(),
+      E->getScopeKind(), E->getStorageClass(), E->getTSCSpec(),
       E->isConstexpr() ? ConstexprSpecKind::Constexpr
                        : ConstexprSpecKind::Unspecified);
 }
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index ef617ddfd49fb..83654ba9ca036 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -1599,7 +1599,7 @@ void StmtProfiler::VisitMemberExpr(const MemberExpr *S) {
 
 void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *S) {
   VisitExpr(S);
-  ID.AddBoolean(S->isFileScope());
+  ID.AddInteger(llvm::to_underlying(S->getScopeKind()));
   ID.AddInteger(S->getStorageClass());
   ID.AddInteger(S->getTSCSpec());
   ID.AddBoolean(S->isConstexpr());
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 705d2dbb49a80..bfd21925691f3 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5992,7 +5992,8 @@ CodeGenFunction::EmitLValueForFieldInitialization(LValue Base,
                         CGM.getTBAAInfoForSubobject(Base, FieldType));
 }
 
-LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
+LValue
+CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E) {
   if (E->hasGlobalStorage()) {
     if (E->getType()->isVariablyModifiedType())
       EmitVariablyModifiedType(E->getType());
@@ -6021,11 +6022,16 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
 
   // Block-scope compound literals are destroyed at the end of the enclosing
   // scope in C.
-  if (!getLangOpts().CPlusPlus)
-    if (QualType::DestructionKind DtorKind = E->getType().isDestructedType())
-      pushLifetimeExtendedDestroy(getCleanupKind(DtorKind), DeclPtr,
-                                  E->getType(), getDestroyer(DtorKind),
-                                  DtorKind & EHCleanup);
+  if (!getLangOpts().CPlusPlus) {
+    if (QualType::DestructionKind DtorKind = E->getType().isDestructedType()) {
+      if (E->getScopeKind() == CompoundLiteralExpr::ScopeKind::ParameterList)
+        pushDestroy(DtorKind, DeclPtr, E->getType());
+      else
+        pushLifetimeExtendedDestroy(getCleanupKind(DtorKind), DeclPtr,
+                                    E->getType(), getDestroyer(DtorKind),
+                                    DtorKind & EHCleanup);
+    }
+  }
 
   return Result;
 }
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 861dfa1f9f1c7..119aebb673789 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1360,10 +1360,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
       else
         Ty = VD->getType();
 
-      if (Ty->isVariablyModifiedType()) {
-        RunCleanupsScope Scope(*this);
+      if (Ty->isVariablyModifiedType())
         EmitVariablyModifiedType(Ty);
-      }
     }
   }
   // Emit a location at the end of the prologue.
diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index 12442040b13bb..3ebb54ac372aa 100644
--- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -3298,9 +3298,9 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
                                      SourceLocation(), /*isExplicit=*/true);
       TypeSourceInfo *superTInfo
         = Context->getTrivialTypeSourceInfo(superType);
-      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
-                                                   superType, VK_LValue,
-                                                   ILE, false);
+      SuperRep = new (Context) CompoundLiteralExpr(
+          SourceLocation(), superTInfo, superType, VK_LValue, ILE,
+          CompoundLiteralExpr::ScopeKind::Block);
       // struct __rw_objc_super *
       SuperRep = UnaryOperator::Create(
           const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf,
@@ -3391,7 +3391,8 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
       TypeSourceInfo *superTInfo
         = Context->getTrivialTypeSourceInfo(superType);
       SuperRep = new (Context) CompoundLiteralExpr(
-          SourceLocation(), superTInfo, superType, VK_PRValue, ILE, false);
+          SourceLocation(), superTInfo, superType, VK_PRValue, ILE,
+          CompoundLiteralExpr::ScopeKind::Block);
     }
     MsgExprs.push_back(SuperRep);
     break;
diff --git a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp
index 6b8753e29b8fe..d540a5830ee33 100644
--- a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp
+++ b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -2726,9 +2726,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
                                      SourceLocation(), /*isExplicit=*/true);
       TypeSourceInfo *superTInfo
         = Context->getTrivialTypeSourceInfo(superType);
-      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
-                                                   superType, VK_LValue,
-                                                   ILE, false);
+      SuperRep = new (Context) CompoundLiteralExpr(
+          SourceLocation(), superTInfo, superType, VK_LValue, ILE,
+          CompoundLiteralExpr::ScopeKind::Block);
       // struct objc_super *
       SuperRep = UnaryOperator::Create(
           const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf,
@@ -2819,7 +2819,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
       TypeSourceInfo *superTInfo
         = Context->getTrivialTypeSourceInfo(superType);
       SuperRep = new (Context) CompoundLiteralExpr(
-          SourceLocation(), superTInfo, superType, VK_PRValue, ILE, false);
+          SourceLocation(), superTInfo, superType, VK_PRValue, ILE,
+          CompoundLiteralExpr::ScopeKind::Block);
     }
     MsgExprs.push_back(SuperRep);
     break;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 9d2c027e29fa5..0f54f4b3db016 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7715,6 +7715,10 @@ ExprResult Sema::BuildCompoundLiteralExpr(
       (getLangOpts().CPlusPlus && !(IsFileScope && literalType->isArrayType()))
           ? VK_PRValue
           : VK_LValue;
+  CompoundLiteralExpr::ScopeKind Scope =
+      IsFileScope        ? CompoundLiteralExpr::ScopeKind::File
+      : IsPrototypeScope ? CompoundLiteralExpr::ScopeKind::ParameterList
+                         : CompoundLiteralExpr::ScopeKind::Block;
 
   bool HasGlobalStorage =
       IsFileScope || (getLangOpts().C23 && (HasStatic || HasThreadStorage));
@@ -7749,8 +7753,8 @@ ExprResult Sema::BuildCompoundLiteralExpr(
       }
 
   auto *E = new (Context)
-      CompoundLiteralExpr(LParenLoc, TInfo, literalType, VK, LiteralExpr,
-                          IsFileScope, SC, TSC, ConstexprKind);
+      CompoundLiteralExpr(LParenLoc, TInfo, literalType, VK, LiteralExpr, Scope,
+                          SC, TSC, ConstexprKind);
 
   if (HasGlobalStorage && !HasConstexpr) {
     if (!LiteralExpr->isTypeDependent() && !LiteralExpr->isValueDependent() &&
@@ -10332,8 +10336,9 @@ static void ConstructTransparentUnion(Sema &S, ASTContext &C,
   // Build a compound literal constructing a value of the transparent
   // union type from this initializer list.
   TypeSourceInfo *unionTInfo = C.getTrivialTypeSourceInfo(UnionType);
-  EResult = new (C) CompoundLiteralExpr(SourceLocation(), unionTInfo, UnionType,
-                                        VK_PRValue, Initializer, false);
+  EResult = new (C)
+      CompoundLiteralExpr(SourceLocation(), unionTInfo, UnionType, VK_PRValue,
+                          Initializer, CompoundLiteralExpr::ScopeKind::Block);
 }
 
 AssignConvertType
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 2e8c055a8ac6a..0f75089075056 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1238,7 +1238,8 @@ void ASTStmtReader::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
   E->setLParenLoc(readSourceLocation());
   E->setTypeSourceInfo(readTypeSourceInfo());
   E->setInitializer(Record.readSubExpr());
-  E->setFileScope(Record.readInt());
+  E->setScopeKind(
+      static_cast<CompoundLiteralExpr::ScopeKind>(Record.readInt()));
   E->setStorageClass(static_cast<StorageClass>(Record.readInt()));
   E->setTSCSpec(static_cast<ThreadStorageClassSpecifier>(Record.readInt()));
   E->setConstexpr(Record.readInt());
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index f0ff9eb1ed80f..49470190cfd34 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1205,7 +1205,7 @@ void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
   Record.AddSourceLocation(E->getLParenLoc());
   Record.AddTypeSourceInfo(E->getTypeSourceInfo());
   Record.AddStmt(E->getInitializer());
-  Record.push_back(E->isFileScope());
+  Record.push_back(llvm::to_underlying(E->getScopeKind()));
   Record.push_back(E->getStorageClass());
   Record.push_back(E->getTSCSpec());
   Record.push_back(E->isConstexpr());

>From 703ba4068fb2bf9d1cb91ceca19864d9dab38d10 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Sat, 1 Aug 2026 10:50:11 +0300
Subject: [PATCH 07/21] add additional tests

---
 clang/test/Sema/c23-compound-literal.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/test/Sema/c23-compound-literal.c b/clang/test/Sema/c23-compound-literal.c
index 1310e5a847803..d171f51cfc011 100644
--- a/clang/test/Sema/c23-compound-literal.c
+++ b/clang/test/Sema/c23-compound-literal.c
@@ -319,6 +319,7 @@ void test22(void) {
   (void)(typedef int){3};     // expected-error {{storage class specifier 'typedef' is not permitted in a compound literal}}
   (void)(__auto_type int){4}; // expected-error {{expected expression}}
   (void)(__thread int){5};    // expected-error {{expected expression}}
+  (void)(auto){1};            // expected-error {{expected expression}}
 }
 
 void test23(void) {
@@ -326,6 +327,7 @@ void test23(void) {
   (void)(static int thread_local){1};  // expected-error {{type name does not allow storage class to be specified}}
   (void)(static int _Thread_local){1}; // expected-error {{type name does not allow storage class to be specified}}
   (void)(static int __thread){1};      // expected-error {{type name does not allow storage class to be specified}}
+  (void)(int static){1};               // expected-error {{type name does not allow storage class to be specified}}
 }
 
 void test24(void) {

>From 3484d56d2150b409006b123438d75a4f2428f2de Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Sat, 1 Aug 2026 10:55:37 +0300
Subject: [PATCH 08/21] remove redundant file-scope checks

---
 clang/lib/CodeGen/CGExprConstant.cpp | 2 +-
 clang/lib/Sema/CheckExprLifetime.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 2123eab890779..e87f0b93f7d29 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -1089,7 +1089,7 @@ tryEmitGlobalCompoundLiteral(ConstantEmitter &emitter,
   llvm::Constant *C = emitter.tryEmitForInitializer(E->getInitializer(),
                                                     addressSpace, E->getType());
   if (!C) {
-    assert(!E->isFileScope() && !E->hasGlobalStorage() &&
+    assert(!E->hasGlobalStorage() &&
            "global compound literal did not have constant initializer!");
     return ConstantAddress::invalid();
   }
diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp
index e5cfc3086fb58..8007537075617 100644
--- a/clang/lib/Sema/CheckExprLifetime.cpp
+++ b/clang/lib/Sema/CheckExprLifetime.cpp
@@ -659,7 +659,7 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
 
   case Stmt::CompoundLiteralExprClass: {
     if (auto *CLE = dyn_cast<CompoundLiteralExpr>(Init)) {
-      if (!CLE->isFileScope() && !CLE->hasGlobalStorage())
+      if (!CLE->hasGlobalStorage())
         Visit(Path, Local(CLE), RK);
     }
     break;

>From d294ccf443945662a5f97169638e6cd891b54d5c Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Sat, 1 Aug 2026 11:02:19 +0300
Subject: [PATCH 09/21] use EvaluationMode for C23 const evaluation

---
 clang/include/clang/AST/Expr.h |  2 --
 clang/lib/AST/ExprConstant.cpp | 22 +++++-----------------
 clang/lib/Sema/SemaExpr.cpp    |  4 +---
 3 files changed, 6 insertions(+), 22 deletions(-)

diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 0c247e32cb18e..585f80fa35aed 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -765,8 +765,6 @@ class Expr : public ValueStmt {
     /// evaluation is not part of the evaluation, but all other temporaries
     /// are destroyed.
     ImmediateInvocation,
-    /// The initializer of a compound literal constant.
-    CompoundLiteralInitializer,
   };
 
   /// Evaluate an expression that is required to be a constant expression. Does
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 98e9bb69584f3..d13110bf1abb5 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -157,7 +157,6 @@ namespace {
     case ConstantExprKind::Normal:
     case ConstantExprKind::ClassTemplateArgument:
     case ConstantExprKind::ImmediateInvocation:
-    case ConstantExprKind::CompoundLiteralInitializer:
       // Note that non-type template arguments of class type are emitted as
       // template parameter objects.
       return false;
@@ -172,7 +171,6 @@ namespace {
     switch (Kind) {
     case ConstantExprKind::Normal:
     case ConstantExprKind::ImmediateInvocation:
-    case ConstantExprKind::CompoundLiteralInitializer:
       return false;
 
     case ConstantExprKind::ClassTemplateArgument:
@@ -815,8 +813,6 @@ namespace {
     /// not supported by the interpreter, an error is triggered.
     bool EnableNewConstInterp;
 
-    ConstantExprKind ConstantKind;
-
     /// BottomFrame - The frame in which evaluation started. This must be
     /// initialized after CurrentCall and CallStackDepth.
     CallStackFrame BottomFrame;
@@ -917,13 +913,11 @@ namespace {
     /// initialization.
     uint64_t ArrayInitIndex = -1;
 
-    EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode,
-             ConstantExprKind Kind = ConstantExprKind::Normal)
+    EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode)
         : State(const_cast<ASTContext &>(C), S), CurrentCall(nullptr),
           CallStackDepth(0), NextCallIndex(1),
           StepsLeft(C.getLangOpts().ConstexprStepLimit),
           EnableNewConstInterp(C.getLangOpts().EnableNewConstInterp),
-          ConstantKind(Kind),
           BottomFrame(*this, SourceLocation(), /*Callee=*/nullptr,
                       /*This=*/nullptr,
                       /*CallExpr=*/nullptr, CallRef()),
@@ -4663,12 +4657,6 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
   }
 
   bool IsAccess = isAnyAccess(AK);
-  bool IsConstexprInitializer =
-      Info.ConstantKind == ConstantExprKind::CompoundLiteralInitializer;
-  if (const auto *VD = dyn_cast_if_present<VarDecl>(
-          Info.EvaluatingDecl.dyn_cast<const ValueDecl *>()))
-    IsConstexprInitializer |= VD->isConstexpr();
-
   // C++11 DR1311: An lvalue-to-rvalue conversion on a volatile-qualified type
   // is not a constant expression (even if the object is non-volatile). We also
   // apply this rule to C++98, in order to conform to the expected 'volatile'
@@ -4765,7 +4753,8 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
         return CompleteObject();
       } else if (VD->isConstexpr()) {
         // OK, we can read this variable.
-      } else if (Info.getLangOpts().C23 && IsConstexprInitializer) {
+      } else if (Info.getLangOpts().C23 &&
+                 Info.EvalMode == EvaluationMode::ConstantExpression) {
         Info.FFDiag(E);
         return CompleteObject();
       } else if (BaseType->isIntegralOrEnumerationType()) {
@@ -22000,14 +21989,13 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
   assert(!isValueDependent() &&
          "Expression evaluator can't be called on a dependent expression.");
   bool IsConst;
-  if (Kind != ConstantExprKind::CompoundLiteralInitializer &&
-      FastEvaluateAsRValue(this, Result.Val, Ctx, IsConst) &&
+  if (FastEvaluateAsRValue(this, Result.Val, Ctx, IsConst) &&
       Result.Val.hasValue())
     return true;
 
   ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateAsConstantExpr");
   EvaluationMode EM = EvaluationMode::ConstantExpression;
-  EvalInfo Info(Ctx, Result, EM, Kind);
+  EvalInfo Info(Ctx, Result, EM);
   Info.InConstantContext = true;
 
   if (Info.EnableNewConstInterp) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 0f54f4b3db016..527907de8ab8e 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7675,9 +7675,7 @@ ExprResult Sema::BuildCompoundLiteralExpr(
     SmallVector<PartialDiagnosticAt, 4> Notes;
     Expr::EvalResult Eval;
     Eval.Diag = &Notes;
-    if (!LiteralExpr->EvaluateAsConstantExpr(
-            Eval, Context,
-            Expr::ConstantExprKind::CompoundLiteralInitializer) ||
+    if (!LiteralExpr->EvaluateAsConstantExpr(Eval, Context) ||
         Notes.size() > 0) {
       SourceLocation DiagLoc = ConstexprLoc;
       if (Notes.size() == 1 && Notes.front().second.getDiagID() ==

>From 2f98d2df32b609aea352738a20faf69c91b478ed Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Tue, 4 Aug 2026 16:52:40 +0300
Subject: [PATCH 10/21] handle compound literals in the constexpr interpreter

---
 clang/lib/AST/ByteCode/Compiler.cpp    |  5 ++++-
 clang/lib/AST/ByteCode/Interp.cpp      | 27 ++++++++++++++++++--------
 clang/test/Sema/c23-compound-literal.c |  1 +
 3 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index e72e7875f6937..156a77132c554 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -3613,6 +3613,9 @@ bool Compiler<Emitter>::VisitCXXBindTemporaryExpr(
 template <class Emitter>
 bool Compiler<Emitter>::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
   const Expr *Init = E->getInitializer();
+  if (E->hasThreadStorage())
+    return this->emitInvalid(E);
+
   if (DiscardResult)
     return this->discard(Init);
 
@@ -3622,7 +3625,7 @@ bool Compiler<Emitter>::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
   }
 
   OptPrimType T = classify(E->getType());
-  if (E->isFileScope()) {
+  if (E->hasGlobalStorage()) {
     // Avoid creating a variable if this is a primitive RValue anyway.
     if (T && !E->isLValue())
       return this->delegate(Init);
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 475d206356de8..2a21f28c485ee 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -460,10 +460,24 @@ bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
   return true;
 }
 
+static bool CheckConstexprVar(InterpState &S, CodePtr OpPC,
+                              const Descriptor *Desc) {
+  const auto *VD = Desc->asVarDecl();
+  if (!VD)
+    return true;
+  if (S.getLangOpts().C23 && S.EvalMode == EvaluationMode::ConstantExpression &&
+      VD != S.EvaluatingDecl && !VD->isConstexpr())
+    return Invalid(S, OpPC);
+  return true;
+}
+
 bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc,
                    AccessKinds AK) {
   assert(Desc);
 
+  if (!CheckConstexprVar(S, OpPC, Desc))
+    return false;
+
   const auto *D = Desc->asVarDecl();
   if (S.checkingConstantDestruction(D)) {
     // If we're checking for a constant destructor for this variable, we can
@@ -473,13 +487,6 @@ bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc,
   } else if (!D || D == S.EvaluatingDecl || D->isConstexpr())
     return true;
 
-  // If we're evaluating the initializer for a constexpr variable in C23, we may
-  // only read other contexpr variables. Abort here since this one isn't
-  // constexpr.
-  if (const auto *VD = S.EvaluatingDecl;
-      VD && VD->isConstexpr() && S.getLangOpts().C23)
-    return Invalid(S, OpPC);
-
   QualType T = D->getType();
   bool IsConstant = T.isConstant(S.getASTContext());
   if (T->isIntegralOrEnumerationType()) {
@@ -523,8 +530,10 @@ static bool CheckConstant(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
   if (S.checkingConstantDestruction(Ptr))
     return CheckConstant(S, OpPC, Ptr.getDeclDesc(), AK);
 
-  if (!Ptr.isStatic() || !Ptr.isBlockPointer())
+  if (!Ptr.isBlockPointer())
     return true;
+  if (!Ptr.isStatic())
+    return CheckConstexprVar(S, OpPC, Ptr.getDeclDesc());
   if (!Ptr.getDeclID())
     return true;
   return CheckConstant(S, OpPC, Ptr.getDeclDesc(), AK);
@@ -859,6 +868,8 @@ bool CheckLocalLoad(InterpState &S, CodePtr OpPC, const Block *B) {
   assert(!B->isExtern());
   const auto &Desc = *reinterpret_cast<const InlineDescriptor *>(B->rawData());
   const Descriptor *BlockDesc = B->getDescriptor();
+  if (!CheckConstexprVar(S, OpPC, BlockDesc))
+    return false;
   if (!Desc.IsInitialized)
     return diagnoseUninitialized(S, OpPC, /*Extern=*/false, B, Desc.LifeState);
   if (!CheckLifetime(S, OpPC, Desc.LifeState, B, AK_Read))
diff --git a/clang/test/Sema/c23-compound-literal.c b/clang/test/Sema/c23-compound-literal.c
index d171f51cfc011..1fe4210f036ba 100644
--- a/clang/test/Sema/c23-compound-literal.c
+++ b/clang/test/Sema/c23-compound-literal.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -verify -fsyntax-only %s
+// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -verify -fsyntax-only -fexperimental-new-constant-interpreter %s
 // RUN: %clang_cc1 -std=c23 -triple x86_64-scei-ps4 -verify=expected,ps4 -fsyntax-only %s
 
 #define M static

>From 94143f862a2bc07c01b24b24bac7033947793bb8 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Tue, 1 Sep 2026 09:38:07 +0300
Subject: [PATCH 11/21] reuse storage-class mapping

---
 clang/include/clang/Sema/Sema.h | 4 ++++
 clang/lib/Sema/SemaDecl.cpp     | 6 +-----
 clang/lib/Sema/SemaExpr.cpp     | 9 ++++-----
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b8e4ba6f3f474..b0a3899b560fb 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4038,6 +4038,10 @@ class Sema final : public SemaBase {
                                      ArrayRef<BindingDecl *> Bindings = {});
 
 private:
+  /// Maps a DeclSpec::SCS to a VarDecl::StorageClass. Any error reporting is up
+  /// to the caller; illegal input values are mapped to SC_None.
+  static StorageClass StorageClassSpecToVarDeclStorageClass(const DeclSpec &DS);
+
   // Perform a check on an AsmLabel to verify its consistency and emit
   // diagnostics in case of an error.
   void CheckAsmLabel(Scope *S, Expr *AsmLabelExpr, StorageClass SC,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 9264be70578ea..5118966186fd1 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5666,11 +5666,7 @@ InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S, DeclContext *Owner,
   return Invalid;
 }
 
-/// StorageClassSpecToVarDeclStorageClass - Maps a DeclSpec::SCS to
-/// a VarDecl::StorageClass. Any error reporting is up to the caller:
-/// illegal input values are mapped to SC_None.
-static StorageClass
-StorageClassSpecToVarDeclStorageClass(const DeclSpec &DS) {
+StorageClass Sema::StorageClassSpecToVarDeclStorageClass(const DeclSpec &DS) {
   DeclSpec::SCS StorageClassSpec = DS.getStorageClassSpec();
   assert(StorageClassSpec != DeclSpec::SCS_typedef &&
          "Parser allowed 'typedef' as storage class VarDecl.");
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index b1ed4c0977cc8..b3721f07a173e 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7534,16 +7534,15 @@ ExprResult Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
   SourceLocation ConstexprLoc;
   if (DS) {
     DeclSpec::SCS StorageClassSpec = DS->getStorageClassSpec();
-    if (StorageClassSpec == DeclSpec::SCS_static)
-      SC = SC_Static;
-    else if (StorageClassSpec == DeclSpec::SCS_register)
-      SC = SC_Register;
-    else if (StorageClassSpec != DeclSpec::SCS_unspecified) {
+    if (StorageClassSpec != DeclSpec::SCS_unspecified &&
+        StorageClassSpec != DeclSpec::SCS_static &&
+        StorageClassSpec != DeclSpec::SCS_register) {
       Diag(DS->getStorageClassSpecLoc(),
            diag::err_compound_literal_invalid_storage_class)
           << DeclSpec::getSpecifierName(StorageClassSpec);
       return ExprError();
     }
+    SC = StorageClassSpecToVarDeclStorageClass(*DS);
 
     TSC = DS->getThreadStorageClassSpec();
     ConstexprKind = DS->getConstexprSpecifier();

>From 8186617dc0cdaf71d218fe2d9a4550cca2be4d4e Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Tue, 1 Sep 2026 11:10:22 +0300
Subject: [PATCH 12/21] refactor SCS parsing

---
 clang/include/clang/AST/Expr.h              |   4 +-
 clang/include/clang/Parse/Parser.h          |   7 +-
 clang/lib/Parse/ParseDecl.cpp               | 242 ++++++++++++--------
 clang/lib/Parse/ParseExpr.cpp               |  63 +----
 clang/test/AST/c23-compound-literal-print.c |   4 +-
 clang/test/CodeGen/c23-compound-literal.c   |   8 +
 clang/test/Sema/c23-compound-literal.c      |   8 +-
 7 files changed, 173 insertions(+), 163 deletions(-)

diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 585f80fa35aed..133171c49ff63 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -3696,8 +3696,8 @@ class CompoundLiteralExpr : public Expr {
   }
 
   void setTSCSpec(ThreadStorageClassSpecifier TSC) {
-    assert((TSC == TSCS_unspecified || TSC == TSCS_thread_local ||
-            TSC == TSCS__Thread_local) &&
+    assert((TSC == TSCS_unspecified || TSC == TSCS___thread ||
+            TSC == TSCS_thread_local || TSC == TSCS__Thread_local) &&
            "invalid compound literal thread storage class");
     CompoundLiteralExprBits.TSCSpec = TSC;
     assert(getTSCSpec() == TSC && "truncation");
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index d2396fbf5cd20..47d7ca1c3a605 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -1884,6 +1884,11 @@ class Parser : public CodeCompletionHandler {
   /// DeclaratorContext enumerator values.
   DeclSpecContext
   getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context);
+
+  enum class StorageClassSpecifierContext { Declaration, CompoundLiteral };
+  void ParseStorageClassSpecifier(DeclSpec &DS,
+                                  StorageClassSpecifierContext Context);
+
   void
   ParseDeclarationSpecifiers(DeclSpec &DS, ParsedTemplateInfo &TemplateInfo,
                              AccessSpecifier AS = AS_none,
@@ -5095,7 +5100,7 @@ class Parser : public CodeCompletionHandler {
   }
 
   bool isCompoundLiteralStorageClassSpecifier() const;
-  bool isCompoundLiteralTypeName();
+  bool isTypeIdInParensWithStorageClassSpecifiers();
   void ParseCompoundLiteralStorageClassSpecifiers(DeclSpec &DS);
 
   /// Finish parsing a C++ unqualified-id that is a template-id of
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 9fa3b96527c08..8389aae8e0e23 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3379,6 +3379,138 @@ Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
   return false;
 }
 
+void Parser::ParseStorageClassSpecifier(DeclSpec &DS,
+                                        StorageClassSpecifierContext Context) {
+  SourceLocation Loc = Tok.getLocation();
+  const char *PrevSpec = nullptr;
+  unsigned DiagID = 0;
+  bool IsInvalid = false;
+  PrintingPolicy Policy = Actions.getPrintingPolicy();
+
+  switch (Tok.getKind()) {
+  case tok::kw_typedef:
+    IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
+                                       PrevSpec, DiagID, Policy);
+    break;
+  case tok::kw_extern:
+    if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
+      Diag(Tok, diag::ext_thread_before) << "extern";
+    IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
+                                       PrevSpec, DiagID, Policy);
+    break;
+  case tok::kw___private_extern__:
+    IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,
+                                       Loc, PrevSpec, DiagID, Policy);
+    break;
+  case tok::kw_static:
+    if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
+      Diag(Tok, diag::ext_thread_before) << "static";
+    IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
+                                       PrevSpec, DiagID, Policy);
+    break;
+  case tok::kw_auto:
+    if (getLangOpts().CPlusPlus11 || getLangOpts().C23) {
+      auto MayBeTypeSpecifier = [&]() {
+        // In pre-C23 C, auto can be used as a storage-class specifier.
+        // C23 removes auto from the storage-class specifiers and repurposes
+        // it for type inference (6.7.10).
+        if (getLangOpts().C23 && DS.hasTypeSpecifier() &&
+            DS.getTypeSpecType() != DeclSpec::TST_auto)
+          return true;
+
+        unsigned I = 1;
+        while (true) {
+          const Token &T = GetLookAheadToken(I);
+          if (isKnownToBeTypeSpecifier(T))
+            return true;
+
+          if (getLangOpts().C23 && isTypeSpecifierQualifier(T))
+            ++I;
+          else
+            return false;
+        }
+      };
+
+      if (!getLangOpts().CPlusPlus && MayBeTypeSpecifier()) {
+        IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
+                                           PrevSpec, DiagID, Policy);
+      } else {
+        if (getLangOpts().CPlusPlus11 &&
+            NextToken().isOneOf(tok::kw_class, tok::kw_struct,
+                                tok::kw___interface, tok::kw_union,
+                                tok::kw_enum))
+          Diag(Loc, diag::ext_auto_storage_class);
+        IsInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
+                                       DiagID, Policy);
+      }
+    } else {
+      IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
+                                         PrevSpec, DiagID, Policy);
+    }
+    break;
+  case tok::kw_register:
+    IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
+                                       PrevSpec, DiagID, Policy);
+    break;
+  case tok::kw_mutable:
+    IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,
+                                       PrevSpec, DiagID, Policy);
+    break;
+  case tok::kw___thread:
+    IsInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS___thread, Loc,
+                                             PrevSpec, DiagID);
+    break;
+  case tok::kw_thread_local:
+    if (Context == StorageClassSpecifierContext::Declaration &&
+        getLangOpts().C23)
+      Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
+    // We map thread_local to _Thread_local in C23 mode so it retains the C
+    // semantics rather than getting the C++ semantics.
+    // FIXME: diagnostics will show _Thread_local when the user wrote
+    // thread_local in source in C23 mode; we need some general way to
+    // identify which way the user spelled the keyword in source.
+    IsInvalid = DS.SetStorageClassSpecThread(getLangOpts().C23
+                                                 ? DeclSpec::TSCS__Thread_local
+                                                 : DeclSpec::TSCS_thread_local,
+                                             Loc, PrevSpec, DiagID);
+    break;
+  case tok::kw__Thread_local:
+    diagnoseUseOfC11Keyword(Tok);
+    IsInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS__Thread_local, Loc,
+                                             PrevSpec, DiagID);
+    break;
+  case tok::kw_constexpr:
+    if (Context == StorageClassSpecifierContext::Declaration &&
+        getLangOpts().C23)
+      Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
+    IsInvalid = DS.SetConstexprSpec(ConstexprSpecKind::Constexpr, Loc, PrevSpec,
+                                    DiagID);
+    break;
+  default:
+    llvm_unreachable("not a storage class specifier");
+  }
+
+  DS.SetRangeEnd(Loc);
+  if (IsInvalid && !DS.hasConflictingTypeSpecifier()) {
+    assert(PrevSpec && "Method did not return previous specifier!");
+    assert(DiagID);
+
+    if (DiagID == diag::ext_duplicate_declspec ||
+        DiagID == diag::ext_warn_duplicate_declspec ||
+        DiagID == diag::err_duplicate_declspec)
+      Diag(Loc, DiagID) << PrevSpec
+                        << FixItHint::CreateRemoval(
+                               SourceRange(Loc, DS.getEndLoc()));
+    else if (DiagID == diag::err_opencl_unknown_type_specifier)
+      Diag(Loc, DiagID) << getLangOpts().getOpenCLVersionString() << PrevSpec
+                        << /*IsStorageClass=*/true;
+    else
+      Diag(Loc, DiagID) << PrevSpec;
+  }
+
+  ConsumeToken();
+}
+
 void Parser::ParseDeclarationSpecifiers(
     DeclSpec &DS, ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS,
     DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
@@ -4122,108 +4254,24 @@ void Parser::ParseDeclarationSpecifiers(
 
     // storage-class-specifier
     case tok::kw_typedef:
-      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
-                                         PrevSpec, DiagID, Policy);
-      isStorageClass = true;
-      break;
     case tok::kw_extern:
-      if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
-        Diag(Tok, diag::ext_thread_before) << "extern";
-      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
-                                         PrevSpec, DiagID, Policy);
-      isStorageClass = true;
-      break;
     case tok::kw___private_extern__:
-      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,
-                                         Loc, PrevSpec, DiagID, Policy);
-      isStorageClass = true;
-      break;
     case tok::kw_static:
-      if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
-        Diag(Tok, diag::ext_thread_before) << "static";
-      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
-                                         PrevSpec, DiagID, Policy);
-      isStorageClass = true;
-      break;
     case tok::kw_auto:
-      if (getLangOpts().CPlusPlus11 || getLangOpts().C23) {
-        auto MayBeTypeSpecifier = [&]() {
-          // In pre-C23 C, auto can be used as a storage-class specifier.
-          // C23 removes auto from the storage-class specifiers and repurposes
-          // it for type inference (6.7.10).
-          if (getLangOpts().C23 && DS.hasTypeSpecifier() &&
-              DS.getTypeSpecType() != DeclSpec::TST_auto)
-            return true;
-
-          unsigned I = 1;
-          while (true) {
-            const Token &T = GetLookAheadToken(I);
-            if (isKnownToBeTypeSpecifier(T))
-              return true;
-
-            if (getLangOpts().C23 && isTypeSpecifierQualifier(T))
-              ++I;
-            else
-              return false;
-          }
-        };
-
-        if (!getLangOpts().CPlusPlus && MayBeTypeSpecifier()) {
-          isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
-                                             PrevSpec, DiagID, Policy);
-        } else {
-          if (getLangOpts().CPlusPlus11 &&
-              NextToken().isOneOf(tok::kw_class, tok::kw_struct,
-                                  tok::kw___interface, tok::kw_union,
-                                  tok::kw_enum))
-            Diag(Loc, diag::ext_auto_storage_class);
-          isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
-                                         DiagID, Policy);
-        }
-      } else
-        isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
-                                           PrevSpec, DiagID, Policy);
-      isStorageClass = true;
-      break;
-    case tok::kw___auto_type:
-      Diag(Tok, diag::ext_auto_type);
-      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto_type, Loc, PrevSpec,
-                                     DiagID, Policy);
-      break;
     case tok::kw_register:
-      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
-                                         PrevSpec, DiagID, Policy);
-      isStorageClass = true;
-      break;
     case tok::kw_mutable:
-      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,
-                                         PrevSpec, DiagID, Policy);
-      isStorageClass = true;
-      break;
     case tok::kw___thread:
-      isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS___thread, Loc,
-                                               PrevSpec, DiagID);
-      isStorageClass = true;
-      break;
     case tok::kw_thread_local:
-      if (getLangOpts().C23)
-        Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
-      // We map thread_local to _Thread_local in C23 mode so it retains the C
-      // semantics rather than getting the C++ semantics.
-      // FIXME: diagnostics will show _Thread_local when the user wrote
-      // thread_local in source in C23 mode; we need some general way to
-      // identify which way the user spelled the keyword in source.
-      isInvalid = DS.SetStorageClassSpecThread(
-          getLangOpts().C23 ? DeclSpec::TSCS__Thread_local
-                            : DeclSpec::TSCS_thread_local,
-          Loc, PrevSpec, DiagID);
-      isStorageClass = true;
-      break;
     case tok::kw__Thread_local:
-      diagnoseUseOfC11Keyword(Tok);
-      isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS__Thread_local,
-                                               Loc, PrevSpec, DiagID);
-      isStorageClass = true;
+    case tok::kw_constexpr:
+      ParseStorageClassSpecifier(DS, StorageClassSpecifierContext::Declaration);
+      AttrsLastTime = false;
+      continue;
+
+    case tok::kw___auto_type:
+      Diag(Tok, diag::ext_auto_type);
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto_type, Loc, PrevSpec,
+                                     DiagID, Policy);
       break;
 
     // function-specifier
@@ -4307,13 +4355,7 @@ void Parser::ParseDeclarationSpecifiers(
       isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID);
       break;
 
-    // constexpr, consteval, constinit specifiers
-    case tok::kw_constexpr:
-      if (getLangOpts().C23)
-        Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
-      isInvalid = DS.SetConstexprSpec(ConstexprSpecKind::Constexpr, Loc,
-                                      PrevSpec, DiagID);
-      break;
+    // consteval and constinit specifiers
     case tok::kw_consteval:
       isInvalid = DS.SetConstexprSpec(ConstexprSpecKind::Consteval, Loc,
                                       PrevSpec, DiagID);
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 7fb21fdc5ba55..d713ac2615b5b 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -2660,21 +2660,19 @@ bool Parser::isCompoundLiteralStorageClassSpecifier() const {
   if (!getLangOpts().C23)
     return false;
   switch (Tok.getKind()) {
-  case tok::kw_auto:
   case tok::kw_constexpr:
-  case tok::kw_extern:
   case tok::kw_register:
   case tok::kw_static:
+  case tok::kw___thread:
   case tok::kw_thread_local:
   case tok::kw__Thread_local:
-  case tok::kw_typedef:
     return true;
   default:
     return false;
   }
 }
 
-bool Parser::isCompoundLiteralTypeName() {
+bool Parser::isTypeIdInParensWithStorageClassSpecifiers() {
   if (!isCompoundLiteralStorageClassSpecifier())
     return false;
 
@@ -2686,52 +2684,11 @@ bool Parser::isCompoundLiteralTypeName() {
 }
 
 void Parser::ParseCompoundLiteralStorageClassSpecifiers(DeclSpec &DS) {
-  DS.SetRangeStart(Tok.getLocation());
-  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
   while (isCompoundLiteralStorageClassSpecifier()) {
-    SourceLocation Loc = Tok.getLocation();
-    const char *PrevSpec = nullptr;
-    unsigned DiagID = 0;
-    bool IsInvalid = false;
-    switch (Tok.getKind()) {
-    case tok::kw_typedef:
-      IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
-                                         PrevSpec, DiagID, Policy);
-      break;
-    case tok::kw_extern:
-      IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
-                                         PrevSpec, DiagID, Policy);
-      break;
-    case tok::kw_static:
-      IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
-                                         PrevSpec, DiagID, Policy);
-      break;
-    case tok::kw_auto:
-      IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
-                                         PrevSpec, DiagID, Policy);
-      break;
-    case tok::kw_register:
-      IsInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
-                                         PrevSpec, DiagID, Policy);
-      break;
-    case tok::kw_thread_local:
-    case tok::kw__Thread_local:
-      IsInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS__Thread_local,
-                                               Loc, PrevSpec, DiagID);
-      break;
-    case tok::kw_constexpr:
-      IsInvalid = DS.SetConstexprSpec(ConstexprSpecKind::Constexpr, Loc,
-                                      PrevSpec, DiagID);
-      break;
-    default:
-      llvm_unreachable("unexpected compound literal storage class specifier");
-    }
-
-    if (IsInvalid)
-      Diag(Loc, DiagID) << PrevSpec;
-
-    DS.SetRangeEnd(Loc);
-    ConsumeToken();
+    if (DS.getBeginLoc().isInvalid())
+      DS.SetRangeStart(Tok.getLocation());
+    ParseStorageClassSpecifier(DS,
+                               StorageClassSpecifierContext::CompoundLiteral);
   }
 }
 
@@ -2852,7 +2809,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool StopIfCastExpr,
                                                BridgeKeywordLoc, Ty.get(),
                                                RParenLoc, SubExpr.get());
   } else if (ExprType >= ParenParseOption::CompoundLiteral &&
-             (isCompoundLiteralTypeName() ||
+             (isTypeIdInParensWithStorageClassSpecifiers() ||
               isTypeIdInParens(isAmbiguousTypeId))) {
 
     // Otherwise, this is a compound literal expression or cast expression.
@@ -2870,10 +2827,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool StopIfCastExpr,
     }
 
     DeclSpec CompoundDS(AttrFactory);
-    if (isCompoundLiteralStorageClassSpecifier()) {
-      ParseCompoundLiteralStorageClassSpecifiers(CompoundDS);
-      CompoundDS.Finish(Actions, Actions.getASTContext().getPrintingPolicy());
-    }
+    ParseCompoundLiteralStorageClassSpecifiers(CompoundDS);
+    CompoundDS.Finish(Actions, Actions.getASTContext().getPrintingPolicy());
 
     DeclSpec DS(AttrFactory);
     ParseSpecifierQualifierList(DS);
diff --git a/clang/test/AST/c23-compound-literal-print.c b/clang/test/AST/c23-compound-literal-print.c
index c8e4fb7d1e8e3..460f17db6a364 100644
--- a/clang/test/AST/c23-compound-literal-print.c
+++ b/clang/test/AST/c23-compound-literal-print.c
@@ -3,10 +3,10 @@
 // RUN: %clang_cc1 -std=c23 -include-pch %t -ast-print -x c /dev/null | FileCheck %s
 
 // CHECK-LABEL: int f1(void)
-// CHECK: return (constexpr int){1} + (static _Thread_local int){2} + (register int){3} + (constexpr const int){4};
+// CHECK: return (constexpr int){1} + (static _Thread_local int){2} + (register int){3} + (constexpr const int){4} + (static __thread int){5};
 int f1(void) {
   return (constexpr int){1} + (_Thread_local static int){2} + (register int){3} +
-         (constexpr const int){4};
+         (constexpr const int){4} + (static __thread int){5};
 }
 
 // CHECK-LABEL: int f2(void)
diff --git a/clang/test/CodeGen/c23-compound-literal.c b/clang/test/CodeGen/c23-compound-literal.c
index 3f542021f5e21..875ffe55eece8 100644
--- a/clang/test/CodeGen/c23-compound-literal.c
+++ b/clang/test/CodeGen/c23-compound-literal.c
@@ -284,3 +284,11 @@ int f29(int a[f28(&(constexpr int){3})]) {
 struct S f30(void) {
   return (volatile struct S){19, 20};
 }
+
+// CHECK-LABEL: define dso_local i32 @f31()
+// CHECK: [[ADDR:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @.compoundliteral
+// CHECK-NEXT: %[[VALUE:.*]] = load i32, ptr [[ADDR]], align 4
+// CHECK-NEXT: ret i32 %[[VALUE]]
+int f31(void) {
+  return (static __thread int){21};
+}
diff --git a/clang/test/Sema/c23-compound-literal.c b/clang/test/Sema/c23-compound-literal.c
index 1fe4210f036ba..f940e0ee51c26 100644
--- a/clang/test/Sema/c23-compound-literal.c
+++ b/clang/test/Sema/c23-compound-literal.c
@@ -11,6 +11,7 @@ void test1(void) {
   (void)&(static int){42};
   (void)(register int){0};
   (void)(static thread_local int){1};
+  (void)(static __thread int){2};
   (void)(constexpr struct S){1, 'a'};
   (void)(static struct S){2, 'b'};
   (void)(register struct S){3, 'c'};
@@ -315,11 +316,10 @@ void test21(void) {
 }
 
 void test22(void) {
-  (void)(auto int){1};        // expected-error {{storage class specifier 'auto' is not permitted in a compound literal}}
-  (void)(extern int){2};      // expected-error {{storage class specifier 'extern' is not permitted in a compound literal}}
-  (void)(typedef int){3};     // expected-error {{storage class specifier 'typedef' is not permitted in a compound literal}}
+  (void)(auto int){1};        // expected-error {{expected expression}}
+  (void)(extern int){2};      // expected-error {{expected expression}}
+  (void)(typedef int){3};     // expected-error {{expected expression}}
   (void)(__auto_type int){4}; // expected-error {{expected expression}}
-  (void)(__thread int){5};    // expected-error {{expected expression}}
   (void)(auto){1};            // expected-error {{expected expression}}
 }
 

>From c4573785a61b7d7f7388a915e8f953ec7fdf6044 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Tue, 1 Sep 2026 11:36:15 +0300
Subject: [PATCH 13/21] fix typo

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +-
 clang/test/Sema/c23-compound-literal.c           | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0e5b33be551d9..fa4d124b4231b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3179,7 +3179,7 @@ def err_c23_constexpr_init_type_mismatch : Error<
 def err_c23_constexpr_pointer_not_null : Error<
   "constexpr pointer initializer is not null">;
 def err_register_compound_literal_file_scope : Error<
-  "file-scope compound literal specifies 'register'">;
+  "file scope compound literal specifies 'register'">;
 def err_thread_local_compound_literal_without_static : Error<
   "compound literal with 'thread_local' storage duration at block scope must "
   "also specify 'static'">;
diff --git a/clang/test/Sema/c23-compound-literal.c b/clang/test/Sema/c23-compound-literal.c
index f940e0ee51c26..424200b690956 100644
--- a/clang/test/Sema/c23-compound-literal.c
+++ b/clang/test/Sema/c23-compound-literal.c
@@ -45,7 +45,7 @@ void test5(void) {
   (void)&(thread_local int){1}; // expected-error {{compound literal with 'thread_local' storage duration at block scope must also specify 'static'}}
 }
 
-int *a1 = &(register int){42}; // expected-error {{file-scope compound literal specifies 'register'}}
+int *a1 = &(register int){42}; // expected-error {{file scope compound literal specifies 'register'}}
 
 void test6(void) {
   (void)(constexpr volatile int){1}; // expected-error {{constexpr compound literal cannot have type 'const volatile int'}}
@@ -263,7 +263,7 @@ inline int f19(int (*a(void))[sizeof((static int){1})]) { // expected-warning {{
 inline typeof((static int){1}) f20(void) {
   return 0;
 }
-typeof((register int){1}) f21(void); // expected-error {{file-scope compound literal specifies 'register'}}
+typeof((register int){1}) f21(void); // expected-error {{file scope compound literal specifies 'register'}}
 
 inline int f22(int a) __attribute__((enable_if((static int){1}, "enabled"))) { // expected-warning {{non-constant static local variable in inline function may be different in different files}} \
                                                                                // expected-note {{use 'static' to give inline function 'f22' internal linkage}}

>From f3d616db890ee4fb156de2b763e0c07d72b2f886 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Tue, 1 Sep 2026 11:46:26 +0300
Subject: [PATCH 14/21] combine tls alignment diagnostics

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 10 ++++------
 clang/lib/Sema/SemaDecl.cpp                      |  7 ++++---
 clang/lib/Sema/SemaDeclAttr.cpp                  |  5 +++--
 clang/lib/Sema/SemaExpr.cpp                      |  4 ++--
 4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index fa4d124b4231b..eda496873ab0b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3770,12 +3770,10 @@ def err_attr_codemodel_arg : Error<"code model '%0' is not supported on this tar
 
 def err_aix_attr_unsupported : Error<"%0 attribute is not yet supported on AIX">;
 
-def err_tls_var_aligned_over_maximum : Error<
-  "alignment (%0) of thread-local variable %1 is greater than the maximum supported "
-  "alignment (%2) for a thread-local variable on this target">;
-def err_tls_compound_literal_aligned_over_maximum : Error<
-  "alignment (%0) of thread-local compound literal is greater than the maximum "
-  "supported alignment (%1) for thread-local storage on this target">;
+def err_tls_aligned_over_maximum : Error<
+  "alignment (%0) of thread-local %select{variable %3|compound literal}1 is "
+  "greater than the maximum supported alignment (%2) for "
+  "%select{a thread-local variable|thread-local storage}1 on this target">;
 
 def err_only_annotate_after_access_spec : Error<
   "access specifier can only have annotation attributes">;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5118966186fd1..10b3bada13272 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15355,9 +15355,10 @@ void Sema::CheckThreadLocalForLargeAlignment(VarDecl *VD) {
     if (!VD->hasDependentAlignment()) {
       CharUnits MaxAlignChars = Context.toCharUnitsFromBits(MaxAlign);
       if (Context.getDeclAlign(VD) > MaxAlignChars) {
-        Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum)
-            << (unsigned)Context.getDeclAlign(VD).getQuantity() << VD
-            << (unsigned)MaxAlignChars.getQuantity();
+        Diag(VD->getLocation(), diag::err_tls_aligned_over_maximum)
+            << (unsigned)Context.getDeclAlign(VD).getQuantity()
+            << /*IsCompoundLiteral=*/false
+            << (unsigned)MaxAlignChars.getQuantity() << VD;
       }
     }
   }
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 6a67a8a124667..44dddcfdd768d 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -4894,8 +4894,9 @@ void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
             .getQuantity();
     if (MaxTLSAlign && AlignVal > MaxTLSAlign &&
         VD->getTLSKind() != VarDecl::TLS_None) {
-      Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum)
-          << (unsigned)AlignVal << VD << MaxTLSAlign;
+      Diag(VD->getLocation(), diag::err_tls_aligned_over_maximum)
+          << (unsigned)AlignVal << /*IsCompoundLiteral=*/false << MaxTLSAlign
+          << VD;
       return;
     }
   }
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index b3721f07a173e..4ba72b4acc34d 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -152,8 +152,8 @@ static bool checkThreadLocalCompoundLiteral(Sema &S, SourceLocation Loc,
   if (TypeAlign <= MaxAlignChars)
     return false;
 
-  S.Diag(Loc, diag::err_tls_compound_literal_aligned_over_maximum)
-      << (unsigned)TypeAlign.getQuantity()
+  S.Diag(Loc, diag::err_tls_aligned_over_maximum)
+      << (unsigned)TypeAlign.getQuantity() << /*IsCompoundLiteral=*/true
       << (unsigned)MaxAlignChars.getQuantity();
   return true;
 }

>From 516d7bb2e6ba134ae4e5e0c96381e0762f6b3c38 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Tue, 1 Sep 2026 12:03:08 +0300
Subject: [PATCH 15/21] cleanup diagnostics

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 --
 clang/lib/Sema/SemaExpr.cpp                      | 2 +-
 clang/test/Sema/c23-compound-literal.c           | 8 ++++----
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index eda496873ab0b..b99b640b370b3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3185,8 +3185,6 @@ def err_thread_local_compound_literal_without_static : Error<
   "also specify 'static'">;
 def err_compound_literal_invalid_storage_class : Error<
   "storage class specifier '%0' is not permitted in a compound literal">;
-def err_constexpr_compound_literal_invalid_type : Error<
-  "constexpr compound literal cannot have type %0">;
 def err_compound_literal_initializer_not_constant : Error<
   "initializer of compound literal must be a constant expression">;
 
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 4ba72b4acc34d..bb042abdcaeb8 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7607,7 +7607,7 @@ ExprResult Sema::BuildCompoundLiteralExpr(
     }
     if (HasConstexpr &&
         CheckConstexprType(ConstexprLoc, literalType,
-                           diag::err_constexpr_compound_literal_invalid_type))
+                           diag::err_c23_constexpr_invalid_type))
       return ExprError();
   }
 
diff --git a/clang/test/Sema/c23-compound-literal.c b/clang/test/Sema/c23-compound-literal.c
index 424200b690956..e75ccf7662423 100644
--- a/clang/test/Sema/c23-compound-literal.c
+++ b/clang/test/Sema/c23-compound-literal.c
@@ -48,11 +48,11 @@ void test5(void) {
 int *a1 = &(register int){42}; // expected-error {{file scope compound literal specifies 'register'}}
 
 void test6(void) {
-  (void)(constexpr volatile int){1}; // expected-error {{constexpr compound literal cannot have type 'const volatile int'}}
-  (void)(constexpr _Atomic int){1};  // expected-error {{constexpr compound literal cannot have type 'const _Atomic(int)'}}
+  (void)(constexpr volatile int){1}; // expected-error {{constexpr variable cannot have type 'const volatile int'}}
+  (void)(constexpr _Atomic int){1};  // expected-error {{constexpr variable cannot have type 'const _Atomic(int)'}}
 
   int c;
-  (void)(constexpr int[c]){0}; // expected-error {{constexpr compound literal cannot have type 'const int[c]'}}
+  (void)(constexpr int[c]){0}; // expected-error {{constexpr variable cannot have type 'const int[c]'}}
 }
 
 void test7(void) {
@@ -187,7 +187,7 @@ struct S8 {
   int *restrict a;
 };
 void test16(void) {
-  (void)(constexpr struct S8){0}; // expected-error {{constexpr compound literal cannot have type 'int *restrict'}}
+  (void)(constexpr struct S8){0}; // expected-error {{constexpr variable cannot have type 'int *restrict'}}
 }
 
 void test17(void) {

>From a97c037e1939d517f3c041b9744dc42b6fd83617 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Tue, 1 Sep 2026 12:11:43 +0300
Subject: [PATCH 16/21] add additional tests

---
 clang/test/Parser/c23-compound-literal.c | 32 ++++++++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 clang/test/Parser/c23-compound-literal.c

diff --git a/clang/test/Parser/c23-compound-literal.c b/clang/test/Parser/c23-compound-literal.c
new file mode 100644
index 0000000000000..3415bba7454e6
--- /dev/null
+++ b/clang/test/Parser/c23-compound-literal.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c17 -fsyntax-only -verify=c17 %s
+// RUN: %clang_cc1 -x c++ -std=c++23 -fsyntax-only -verify=cxx %s
+
+void t1(void) {
+  (void)(static int){1}; // c17-error {{expected expression}} \
+                         // cxx-error {{type name does not allow storage class to be specified}}
+}
+
+void t2(void) {
+  (void)(register int){1}; // c17-error {{expected expression}} \
+                           // cxx-error {{type name does not allow storage class to be specified}}
+}
+
+void t3(void) {
+  (void)(thread_local int){1}; // c17-error {{use of undeclared identifier 'thread_local'}} \
+                               // cxx-error {{type name does not allow storage class to be specified}}
+}
+
+void t4(void) {
+  (void)(_Thread_local int){1}; // c17-error {{expected expression}} \
+                                // cxx-error {{type name does not allow storage class to be specified}}
+}
+
+void t5(void) {
+  (void)(__thread int){1}; // c17-error {{expected expression}} \
+                           // cxx-error {{type name does not allow storage class to be specified}}
+}
+
+void t6(void) {
+  (void)(constexpr int){1}; // c17-error {{use of undeclared identifier 'constexpr'}} \
+                            // cxx-error {{type name does not allow constexpr specifier to be specified}}
+}

>From e176138a4ec97927e9c9c428c73556328455df4a Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Tue, 1 Sep 2026 13:32:32 +0300
Subject: [PATCH 17/21] clarify thread-local compound literal constant
 evaluation

---
 clang/lib/AST/Expr.cpp         | 1 +
 clang/lib/AST/ExprConstant.cpp | 9 +--------
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 577a101714efd..8dbc2816c4576 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -3417,6 +3417,7 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
     // "struct x {int x;} x = (struct x) {};".
     // FIXME: This accepts other cases it shouldn't!
     const auto *CLE = cast<CompoundLiteralExpr>(this);
+    // A constant initializer cannot access a thread-local lvalue.
     if (CLE->hasThreadStorage()) {
       if (Culprit)
         *Culprit = this;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index d13110bf1abb5..988f8818e7a70 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4878,14 +4878,6 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
         assert(BaseVal && "got reference to unevaluated temporary");
       } else if (const CompoundLiteralExpr *CLE =
                      dyn_cast_or_null<CompoundLiteralExpr>(Base)) {
-        if (CLE->hasThreadStorage()) {
-          if (IsAccess) {
-            Info.FFDiag(E);
-            return CompleteObject();
-          }
-          return CompleteObject(LVal.getLValueBase(), nullptr, BaseType);
-        }
-
         // According to GCC info page:
         //
         // 6.28 Compound Literals
@@ -9761,6 +9753,7 @@ bool
 LValueExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
   assert((!Info.getLangOpts().CPlusPlus || E->isFileScope()) &&
          "lvalue compound literal in c++?");
+  // A thread-local lvalue cannot be the result of constant evaluation.
   if (E->hasThreadStorage()) {
     Info.FFDiag(E);
     return false;

>From 94df8bdb826f1df4bfc6cc46c0ab68d4b07453e8 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Tue, 1 Sep 2026 17:23:38 +0300
Subject: [PATCH 18/21] remove ParameterList kind

---
 clang/include/clang/AST/Expr.h                |  4 +-
 clang/lib/CodeGen/CGExpr.cpp                  | 12 ++---
 clang/lib/Parse/ParseDecl.cpp                 |  2 +
 clang/lib/Sema/SemaExpr.cpp                   | 51 +++++++++++--------
 clang/test/CodeGenObjC/c23-compound-literal.m | 18 +++++++
 5 files changed, 55 insertions(+), 32 deletions(-)

diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 133171c49ff63..f6790652f2f59 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -3610,7 +3610,7 @@ class MemberExpr final
 ///
 class CompoundLiteralExpr : public Expr {
 public:
-  enum class ScopeKind { Block, File, ParameterList };
+  enum class ScopeKind { Block, File };
 
 private:
   /// LParenLoc - If non-null, this is the location of the left paren in a
@@ -3620,7 +3620,7 @@ class CompoundLiteralExpr : public Expr {
 
   /// The type as written.  This can be an incomplete array type, in
   /// which case the actual expression type will be different.
-  llvm::PointerIntPair<TypeSourceInfo *, 2, ScopeKind> TInfoAndScope;
+  llvm::PointerIntPair<TypeSourceInfo *, 1, ScopeKind> TInfoAndScope;
   Stmt *Init;
 
   /// Value of constant literals with static storage duration.
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index bfd21925691f3..1d062c1ce14e9 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -6023,14 +6023,10 @@ CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E) {
   // Block-scope compound literals are destroyed at the end of the enclosing
   // scope in C.
   if (!getLangOpts().CPlusPlus) {
-    if (QualType::DestructionKind DtorKind = E->getType().isDestructedType()) {
-      if (E->getScopeKind() == CompoundLiteralExpr::ScopeKind::ParameterList)
-        pushDestroy(DtorKind, DeclPtr, E->getType());
-      else
-        pushLifetimeExtendedDestroy(getCleanupKind(DtorKind), DeclPtr,
-                                    E->getType(), getDestroyer(DtorKind),
-                                    DtorKind & EHCleanup);
-    }
+    if (QualType::DestructionKind DtorKind = E->getType().isDestructedType())
+      pushLifetimeExtendedDestroy(getCleanupKind(DtorKind), DeclPtr,
+                                  E->getType(), getDestroyer(DtorKind),
+                                  DtorKind & EHCleanup);
   }
 
   return Result;
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 8389aae8e0e23..49ec3d206570c 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -8009,6 +8009,8 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
       EnterExpressionEvaluationContext Unevaluated(
           Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
       NumElements = ParseAssignmentExpression();
+      if (NumElements.isUsable())
+        NumElements = Actions.MaybeCreateExprWithCleanups(NumElements);
     }
   } else {
     if (StaticLoc.isValid()) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index bb042abdcaeb8..ec3bbacf377d0 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7581,7 +7581,6 @@ ExprResult Sema::BuildCompoundLiteralExpr(
   bool HasThreadStorage = TSC != TSCS_unspecified;
   bool HasConstexpr = ConstexprKind == ConstexprSpecKind::Constexpr;
 
-  bool IsPrototypeScope = PrototypeScope;
   bool IsFunctionDeclarationScope =
       PrototypeScope && PrototypeScope->isFunctionDeclarationScope();
   bool IsFileScope = !CurContext->isFunctionOrMethod() &&
@@ -7713,9 +7712,8 @@ ExprResult Sema::BuildCompoundLiteralExpr(
           ? VK_PRValue
           : VK_LValue;
   CompoundLiteralExpr::ScopeKind Scope =
-      IsFileScope        ? CompoundLiteralExpr::ScopeKind::File
-      : IsPrototypeScope ? CompoundLiteralExpr::ScopeKind::ParameterList
-                         : CompoundLiteralExpr::ScopeKind::Block;
+      IsFileScope ? CompoundLiteralExpr::ScopeKind::File
+                  : CompoundLiteralExpr::ScopeKind::Block;
 
   bool HasGlobalStorage =
       IsFileScope || (getLangOpts().C23 && (HasStatic || HasThreadStorage));
@@ -7772,31 +7770,40 @@ ExprResult Sema::BuildCompoundLiteralExpr(
   }
 
   if (HasStatic && !literalType.isConstQualified()) {
-    if (!IsPrototypeScope) {
+    if (PrototypeScope) {
+      if (IsFunctionDeclarationScope &&
+          DelayedDiagnostics.shouldDelayDiagnostics())
+        DelayedDiagnostics.add(
+            sema::DelayedDiagnostic::makeForbiddenStatic(StorageClassLoc));
+    } else {
       DiagnoseStaticInInline(StorageClassLoc, getCurFunctionDecl());
-    } else if (IsFunctionDeclarationScope &&
-               DelayedDiagnostics.shouldDelayDiagnostics()) {
-      DelayedDiagnostics.add(
-          sema::DelayedDiagnostic::makeForbiddenStatic(StorageClassLoc));
     }
   }
 
-  if (!HasGlobalStorage && !IsPrototypeScope && !getLangOpts().CPlusPlus) {
+  if (!HasGlobalStorage && !getLangOpts().CPlusPlus) {
     // Compound literals that have automatic storage duration are destroyed at
     // the end of the scope in C; in C++, they're just temporaries.
 
-    // Emit diagnostics if it is or contains a C union type that is non-trivial
-    // to destruct.
-    if (E->getType().hasNonTrivialToPrimitiveDestructCUnion())
-      checkNonTrivialCUnion(E->getType(), E->getExprLoc(),
-                            NonTrivialCUnionContext::CompoundLiteral,
-                            NTCUK_Destruct);
-
-    // Diagnose jumps that enter or exit the lifetime of the compound literal.
-    if (literalType.isDestructedType()) {
-      Cleanup.setExprNeedsCleanups(true);
-      ExprCleanupObjects.push_back(E);
-      getCurFunction()->setHasBranchProtectedScope();
+    if (PrototypeScope) {
+      if (literalType.isDestructedType()) {
+        Cleanup.setExprNeedsCleanups(true);
+        ExprCleanupObjects.push_back(E);
+      }
+    } else {
+      // Emit diagnostics if it is or contains a C union type that is
+      // non-trivial to destruct.
+      if (E->getType().hasNonTrivialToPrimitiveDestructCUnion())
+        checkNonTrivialCUnion(E->getType(), E->getExprLoc(),
+                              NonTrivialCUnionContext::CompoundLiteral,
+                              NTCUK_Destruct);
+
+      // Diagnose jumps that enter or exit the lifetime of the compound
+      // literal.
+      if (literalType.isDestructedType()) {
+        Cleanup.setExprNeedsCleanups(true);
+        ExprCleanupObjects.push_back(E);
+        getCurFunction()->setHasBranchProtectedScope();
+      }
     }
   }
 
diff --git a/clang/test/CodeGenObjC/c23-compound-literal.m b/clang/test/CodeGenObjC/c23-compound-literal.m
index 245284cb23017..c693071b0f213 100644
--- a/clang/test/CodeGenObjC/c23-compound-literal.m
+++ b/clang/test/CodeGenObjC/c23-compound-literal.m
@@ -10,6 +10,7 @@
 // CHECK: store ptr null, ptr %{{.*}}, align 8
 // CHECK: %[[CALL:.*]] = call i32 @f1(ptr noundef %.compoundliteral)
 // CHECK-NEXT: zext i32 %[[CALL]] to i64
+// CHECK-NOT: call void @__destructor_8_s0(ptr %.compoundliteral)
 // CHECK: %[[RESULT:.*]] = load i32, ptr %{{.*}}, align 4
 // CHECK-NEXT: call void @__destructor_8_s0(ptr %.compoundliteral)
 // CHECK-NEXT: ret i32 %[[RESULT]]
@@ -17,3 +18,20 @@
 int f2(int a[f1(&(constexpr S){.a = 0})]) {
   return a[0];
 }
+
+// CHECK-LABEL: define i32 @f3(
+// CHECK: %.compoundliteral = alloca %struct.S, align 8
+// CHECK: br i1 %{{.*}}, label %[[RETURN0:.*]], label %[[CONTINUE:.*]]
+// CHECK: [[RETURN0]]:
+// CHECK: br label %[[CLEANUP:.*]]
+// CHECK: [[CONTINUE]]:
+// CHECK: br label %[[CLEANUP]]
+// CHECK: [[CLEANUP]]:
+// CHECK-NEXT: call void @__destructor_8_s0(ptr %.compoundliteral)
+// CHECK-NEXT: %[[RESULT:.*]] = load i32, ptr %{{.*}}, align 4
+// CHECK-NEXT: ret i32 %[[RESULT]]
+int f3(int c, int a[f1(&(constexpr S){.a = 0})]) {
+  if (c)
+    return a[0];
+  return a[1];
+}

>From 3aed63a93ebed9a9584225f574a4bd0432f797be Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Tue, 1 Sep 2026 17:42:50 +0300
Subject: [PATCH 19/21] avoid diagnosing register compound literal array

---
 clang/lib/Sema/SemaExpr.cpp            | 103 ++++++++++++-------------
 clang/test/Sema/c23-compound-literal.c |   5 +-
 2 files changed, 51 insertions(+), 57 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ec3bbacf377d0..890cb1598e526 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -554,54 +554,6 @@ SourceRange Sema::getExprRange(Expr *E) const {
 //  Standard Promotions and Conversions
 //===----------------------------------------------------------------------===//
 
-namespace {
-enum {
-  AO_Bit_Field = 0,
-  AO_Vector_Element = 1,
-  AO_Property_Expansion = 2,
-  AO_Register_Variable = 3,
-  AO_Matrix_Element = 4,
-  AO_Register_Compound_Literal = 5,
-  AO_No_Error = 6
-};
-}
-
-using PrimaryObject = llvm::PointerUnion<ValueDecl *, CompoundLiteralExpr *>;
-
-static PrimaryObject getPrimaryObject(Expr *E) {
-  E = E->IgnoreParens();
-  switch (E->getStmtClass()) {
-  case Stmt::DeclRefExprClass:
-    return cast<DeclRefExpr>(E)->getDecl();
-  case Stmt::CompoundLiteralExprClass:
-    return cast<CompoundLiteralExpr>(E);
-  case Stmt::MemberExprClass:
-    if (cast<MemberExpr>(E)->isArrow())
-      return {};
-    return getPrimaryObject(cast<MemberExpr>(E)->getBase());
-  case Stmt::ArraySubscriptExprClass: {
-    Expr *Base = cast<ArraySubscriptExpr>(E)->getBase()->IgnoreParens();
-    if (auto *ICE = dyn_cast<ImplicitCastExpr>(Base);
-        ICE && ICE->getSubExpr()->getType()->isArrayType())
-      return getPrimaryObject(ICE->getSubExpr());
-    return {};
-  }
-  case Stmt::UnaryOperatorClass: {
-    UnaryOperator *UO = cast<UnaryOperator>(E);
-    if (UO->getOpcode() == UO_Real || UO->getOpcode() == UO_Imag ||
-        UO->getOpcode() == UO_Extension)
-      return getPrimaryObject(UO->getSubExpr());
-    return {};
-  }
-  case Stmt::ImplicitCastExprClass:
-    return getPrimaryObject(cast<ImplicitCastExpr>(E)->getSubExpr());
-  case Stmt::CXXUuidofExprClass:
-    return cast<CXXUuidofExpr>(E)->getGuidDecl();
-  default:
-    return {};
-  }
-}
-
 /// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
 ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, bool Diagnose) {
   // Handle any placeholder expressions which made it here.
@@ -635,13 +587,6 @@ ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, bool Diagnose) {
     // T" can be converted to an rvalue of type "pointer to T".
     //
     if (getLangOpts().C99 || getLangOpts().CPlusPlus || E->isLValue()) {
-      if (!getLangOpts().CPlusPlus) {
-        auto *CLE = getPrimaryObject(E).dyn_cast<CompoundLiteralExpr *>();
-        if (CLE && CLE->getStorageClass() == SC_Register)
-          return Diag(E->getExprLoc(), diag::err_typecheck_address_of)
-                 << AO_Register_Compound_Literal << CLE->getSourceRange();
-      }
-
       ExprResult Res = ImpCastExprToType(E, Context.getArrayDecayedType(Ty),
                                          CK_ArrayToPointerDecay);
       if (Res.isInvalid())
@@ -15070,6 +15015,54 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,
   }
 }
 
+namespace {
+enum {
+  AO_Bit_Field = 0,
+  AO_Vector_Element = 1,
+  AO_Property_Expansion = 2,
+  AO_Register_Variable = 3,
+  AO_Matrix_Element = 4,
+  AO_Register_Compound_Literal = 5,
+  AO_No_Error = 6
+};
+}
+
+using PrimaryObject = llvm::PointerUnion<ValueDecl *, CompoundLiteralExpr *>;
+
+static PrimaryObject getPrimaryObject(Expr *E) {
+  E = E->IgnoreParens();
+  switch (E->getStmtClass()) {
+  case Stmt::DeclRefExprClass:
+    return cast<DeclRefExpr>(E)->getDecl();
+  case Stmt::CompoundLiteralExprClass:
+    return cast<CompoundLiteralExpr>(E);
+  case Stmt::MemberExprClass:
+    if (cast<MemberExpr>(E)->isArrow())
+      return {};
+    return getPrimaryObject(cast<MemberExpr>(E)->getBase());
+  case Stmt::ArraySubscriptExprClass: {
+    Expr *Base = cast<ArraySubscriptExpr>(E)->getBase()->IgnoreParens();
+    if (auto *ICE = dyn_cast<ImplicitCastExpr>(Base);
+        ICE && ICE->getSubExpr()->getType()->isArrayType())
+      return getPrimaryObject(ICE->getSubExpr());
+    return {};
+  }
+  case Stmt::UnaryOperatorClass: {
+    UnaryOperator *UO = cast<UnaryOperator>(E);
+    if (UO->getOpcode() == UO_Real || UO->getOpcode() == UO_Imag ||
+        UO->getOpcode() == UO_Extension)
+      return getPrimaryObject(UO->getSubExpr());
+    return {};
+  }
+  case Stmt::ImplicitCastExprClass:
+    return getPrimaryObject(cast<ImplicitCastExpr>(E)->getSubExpr());
+  case Stmt::CXXUuidofExprClass:
+    return cast<CXXUuidofExpr>(E)->getGuidDecl();
+  default:
+    return {};
+  }
+}
+
 /// Diagnose invalid operand for address of operations.
 ///
 /// \param Type The type of operand which cannot have its address taken.
diff --git a/clang/test/Sema/c23-compound-literal.c b/clang/test/Sema/c23-compound-literal.c
index e75ccf7662423..2a7c49121af72 100644
--- a/clang/test/Sema/c23-compound-literal.c
+++ b/clang/test/Sema/c23-compound-literal.c
@@ -87,15 +87,16 @@ void test8(void) {
 
 void test9(void) {
   int *a = &(register int){1};   // expected-error {{address of register compound literal requested}}
-  int *b = (register int[1]){1}; // expected-error {{address of register compound literal requested}}
+  int *b = (register int[1]){1};
   struct S2 { int a; };
   int *c = &(register struct S2){1}.a;                   // expected-error {{address of register compound literal requested}}
   double *d = &__real__ (register _Complex double){1};   // expected-error {{address of register compound literal requested}}
   double *e = &__imag__ (register _Complex double){1};   // expected-error {{address of register compound literal requested}}
   int *f = &_Generic(0, int: (register int){1});         // expected-error {{address of register compound literal requested}}
-  int *g = _Generic(0, int: (register int[1]){1});       // expected-error {{address of register compound literal requested}}
+  int *g = _Generic(0, int: (register int[1]){1});
   int *h = &_Generic(0, int: (register struct S2){1}).a; // expected-error {{address of register compound literal requested}}
   int *i = &__extension__ (register int){1};             // expected-error {{address of register compound literal requested}}
+  int (*j)[1] = &(register int[1]){1};                   // expected-error {{address of register compound literal requested}}
 }
 
 int a5[1];

>From 0b29d9a7584f8dfbe4275159b7cf3f282dcf6b1b Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Fri, 4 Sep 2026 08:49:16 +0300
Subject: [PATCH 20/21] add additional obj-c test

---
 clang/test/Sema/c23-compound-literal.m | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/test/Sema/c23-compound-literal.m b/clang/test/Sema/c23-compound-literal.m
index 142e5a49499eb..1ddc5d6f583eb 100644
--- a/clang/test/Sema/c23-compound-literal.m
+++ b/clang/test/Sema/c23-compound-literal.m
@@ -6,6 +6,7 @@
 
 void test1(void) {
   (void)(thread_local static __unsafe_unretained id){0};
+  (void)(thread_local static Class){0};
   (void)(thread_local static id){0}; // expected-error {{thread-local variable has non-trivial ownership: type is '__strong id'}}
   (void)(thread_local static S){0};  // expected-error {{type of thread-local variable has non-trivial destruction}}
 }

>From c50c8b23dac63f6bfeb15baf169aff4ec0d651e1 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Sun, 13 Sep 2026 22:18:00 +0300
Subject: [PATCH 21/21] revert unrelated formatting changes

---
 clang/lib/CodeGen/CGExpr.cpp |  443 ++++---
 clang/lib/Sema/SemaExpr.cpp  | 2418 ++++++++++++++++------------------
 2 files changed, 1397 insertions(+), 1464 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 4aaeee4b7aeb0..961e8b20527fe 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -279,7 +279,8 @@ void CodeGenFunction::EmitIgnoredExpr(const Expr *E) {
 /// can have any type.  The result is returned as an RValue struct.
 /// If this is an aggregate expression, AggSlot indicates where the
 /// result should be returned.
-RValue CodeGenFunction::EmitAnyExpr(const Expr *E, AggValueSlot aggSlot,
+RValue CodeGenFunction::EmitAnyExpr(const Expr *E,
+                                    AggValueSlot aggSlot,
                                     bool ignoreResult) {
   switch (getEvaluationKind(E->getType())) {
   case TEK_Scalar:
@@ -307,8 +308,10 @@ RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E) {
 
 /// EmitAnyExprToMem - Evaluate an expression into a given memory
 /// location.
-void CodeGenFunction::EmitAnyExprToMem(const Expr *E, Address Location,
-                                       Qualifiers Quals, bool IsInit) {
+void CodeGenFunction::EmitAnyExprToMem(const Expr *E,
+                                       Address Location,
+                                       Qualifiers Quals,
+                                       bool IsInit) {
   // FIXME: This function should take an LValue as an argument.
   switch (getEvaluationKind(E->getType())) {
   case TEK_Complex:
@@ -358,9 +361,9 @@ void CodeGenFunction::EmitInitializationToLValue(
   llvm_unreachable("bad evaluation kind");
 }
 
-static void pushTemporaryCleanup(CodeGenFunction &CGF,
-                                 const MaterializeTemporaryExpr *M,
-                                 const Expr *E, Address ReferenceTemporary) {
+static void
+pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
+                     const Expr *E, Address ReferenceTemporary) {
   // Objective-C++ ARC:
   //   If we are binding a reference to a temporary that has ownership, we
   //   need to perform retain/release operations on the temporary.
@@ -407,12 +410,13 @@ static void pushTemporaryCleanup(CodeGenFunction &CGF,
           Destroy = &CodeGenFunction::destroyARCWeak;
         }
         if (Duration == SD_FullExpression)
-          CGF.pushDestroy(CleanupKind, ReferenceTemporary, M->getType(),
-                          *Destroy, CleanupKind & EHCleanup);
+          CGF.pushDestroy(CleanupKind, ReferenceTemporary,
+                          M->getType(), *Destroy,
+                          CleanupKind & EHCleanup);
         else
           CGF.pushLifetimeExtendedDestroy(CleanupKind, ReferenceTemporary,
-                                          M->getType(), *Destroy,
-                                          CleanupKind & EHCleanup);
+                                          M->getType(),
+                                          *Destroy, CleanupKind & EHCleanup);
         return;
 
       case SD_Dynamic:
@@ -511,8 +515,8 @@ static RawAddress createReferenceTemporary(CodeGenFunction &CGF,
   llvm_unreachable("unknown storage duration");
 }
 
-LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
-    const MaterializeTemporaryExpr *M) {
+LValue CodeGenFunction::
+EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {
   const Expr *E = M->getSubExpr();
 
   assert((!M->getExtendingDecl() || !isa<VarDecl>(M->getExtendingDecl()) ||
@@ -540,17 +544,17 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
 
       Var->setInitializer(CGM.EmitNullConstant(E->getType()));
     }
-    LValue RefTempDst =
-        MakeAddrLValue(Object, M->getType(), AlignmentSource::Decl);
+    LValue RefTempDst = MakeAddrLValue(Object, M->getType(),
+                                       AlignmentSource::Decl);
 
     switch (getEvaluationKind(E->getType())) {
-    default:
-      llvm_unreachable("expected scalar or aggregate expression");
+    default: llvm_unreachable("expected scalar or aggregate expression");
     case TEK_Scalar:
       EmitScalarInit(E, M->getExtendingDecl(), RefTempDst, false);
       break;
     case TEK_Aggregate: {
-      EmitAggExpr(E, AggValueSlot::forAddr(Object, E->getType().getQualifiers(),
+      EmitAggExpr(E, AggValueSlot::forAddr(Object,
+                                           E->getType().getQualifiers(),
                                            AggValueSlot::IsDestructed,
                                            AggValueSlot::DoesNotNeedGCBarriers,
                                            AggValueSlot::IsNotAliased,
@@ -650,7 +654,7 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
     default:
       break;
     }
-    EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/ true);
+    EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true);
   }
   pushTemporaryCleanup(*this, M, E, Object);
 
@@ -664,7 +668,7 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
           GetAddressOfBaseClass(Object, Adjustment.DerivedToBase.DerivedClass,
                                 Adjustment.DerivedToBase.BasePath->path_begin(),
                                 Adjustment.DerivedToBase.BasePath->path_end(),
-                                /*NullCheckValue=*/false, E->getExprLoc());
+                                /*NullCheckValue=*/ false, E->getExprLoc());
       break;
 
     case SubobjectAdjustment::FieldAdjustment: {
@@ -688,7 +692,8 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
   return MakeAddrLValue(Object, M->getType(), AlignmentSource::Decl);
 }
 
-RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E) {
+RValue
+CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E) {
   // Emit the expression as an lvalue.
   LValue LV = EmitLValue(E);
   assert(LV.isSimple());
@@ -707,6 +712,7 @@ RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E) {
   return RValue::get(Value);
 }
 
+
 /// getAccessedFieldNo - Given an encoded value and a result number, return the
 /// input field number being accessed.
 unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx,
@@ -915,9 +921,9 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
 
       llvm::Type *VPtrTy = llvm::PointerType::get(getLLVMContext(), 0);
       Address VPtrAddr(Ptr, IntPtrTy, getPointerAlign());
-      llvm::Value *VPtrVal =
-          GetVTablePtr(VPtrAddr, VPtrTy, Ty->getAsCXXRecordDecl(),
-                       VTableAuthMode::UnsafeUbsanStrip);
+      llvm::Value *VPtrVal = GetVTablePtr(VPtrAddr, VPtrTy,
+                                          Ty->getAsCXXRecordDecl(),
+                                          VTableAuthMode::UnsafeUbsanStrip);
       VPtrVal = Builder.CreateBitOrPointerCast(VPtrVal, IntPtrTy);
 
       llvm::Value *Hash =
@@ -927,11 +933,12 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
       // Look the hash up in our cache.
       const int CacheSize = 128;
       llvm::Type *HashTable = llvm::ArrayType::get(IntPtrTy, CacheSize);
-      llvm::Value *Cache =
-          CGM.CreateRuntimeVariable(HashTable, "__ubsan_vptr_type_cache");
-      llvm::Value *Slot = Builder.CreateAnd(
-          Hash, llvm::ConstantInt::get(IntPtrTy, CacheSize - 1));
-      llvm::Value *Indices[] = {Builder.getInt32(0), Slot};
+      llvm::Value *Cache = CGM.CreateRuntimeVariable(HashTable,
+                                                     "__ubsan_vptr_type_cache");
+      llvm::Value *Slot = Builder.CreateAnd(Hash,
+                                            llvm::ConstantInt::get(IntPtrTy,
+                                                                   CacheSize-1));
+      llvm::Value *Indices[] = { Builder.getInt32(0), Slot };
       llvm::Value *CacheVal = Builder.CreateAlignedLoad(
           IntPtrTy, Builder.CreateInBoundsGEP(HashTable, Cache, Indices),
           getPointerAlign());
@@ -942,10 +949,12 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
       // diagnostic.
       llvm::Value *EqualHash = Builder.CreateICmpEQ(CacheVal, Hash);
       llvm::Constant *StaticData[] = {
-          EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(Ty),
-          CGM.GetAddrOfRTTIDescriptor(Ty.getUnqualifiedType()),
-          llvm::ConstantInt::get(Int8Ty, TCK)};
-      llvm::Value *DynamicData[] = {Ptr, Hash};
+        EmitCheckSourceLocation(Loc),
+        EmitCheckTypeDescriptor(Ty),
+        CGM.GetAddrOfRTTIDescriptor(Ty.getUnqualifiedType()),
+        llvm::ConstantInt::get(Int8Ty, TCK)
+      };
+      llvm::Value *DynamicData[] = { Ptr, Hash };
       EmitCheck(std::make_pair(EqualHash, SanitizerKind::SO_Vptr),
                 SanitizerHandler::DynamicTypeCacheMiss, StaticData,
                 DynamicData);
@@ -1004,9 +1013,11 @@ llvm::Value *CodeGenFunction::LoadPassedObjectSize(const Expr *E,
 
 /// If Base is known to point to the start of an array, return the length of
 /// that array. Return 0 if the length cannot be determined.
-static llvm::Value *getArrayIndexingBound(
-    CodeGenFunction &CGF, const Expr *Base, QualType &IndexedType,
-    LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel) {
+static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
+                                          const Expr *Base,
+                                          QualType &IndexedType,
+                                          LangOptions::StrictFlexArraysLevelKind
+                                          StrictFlexArraysLevel) {
   // For the vector indexing extension, the bound is the number of elements.
   if (const VectorType *VT = Base->getType()->getAs<VectorType>()) {
     IndexedType = Base->getType();
@@ -1363,9 +1374,9 @@ void CodeGenFunction::EmitAllocToken(llvm::CallBase *CB, const CallExpr *E) {
     CB->setMetadata(llvm::LLVMContext::MD_alloc_token, MDN);
 }
 
-CodeGenFunction::ComplexPairTy
-CodeGenFunction::EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
-                                          bool isInc, bool isPre) {
+CodeGenFunction::ComplexPairTy CodeGenFunction::
+EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
+                         bool isInc, bool isPre) {
   ComplexPairTy InVal = EmitLoadOfComplex(LV, E->getExprLoc());
 
   llvm::Value *NextVal;
@@ -1491,10 +1502,8 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
         TBAAAccessInfo InnerTBAAInfo;
         Address Addr = CGF.EmitPointerWithAlignment(
             CE->getSubExpr(), &InnerBaseInfo, &InnerTBAAInfo, IsKnownNonNull);
-        if (BaseInfo)
-          *BaseInfo = InnerBaseInfo;
-        if (TBAAInfo)
-          *TBAAInfo = InnerTBAAInfo;
+        if (BaseInfo) *BaseInfo = InnerBaseInfo;
+        if (TBAAInfo) *TBAAInfo = InnerTBAAInfo;
 
         if (isa<ExplicitCastExpr>(CE)) {
           LValueBaseInfo TargetTypeBaseInfo;
@@ -1567,10 +1576,8 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
   if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
     if (UO->getOpcode() == UO_AddrOf) {
       LValue LV = CGF.EmitLValue(UO->getSubExpr(), IsKnownNonNull);
-      if (BaseInfo)
-        *BaseInfo = LV.getBaseInfo();
-      if (TBAAInfo)
-        *TBAAInfo = LV.getTBAAInfo();
+      if (BaseInfo) *BaseInfo = LV.getBaseInfo();
+      if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo();
       return LV.getAddress();
     }
   }
@@ -1584,10 +1591,8 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
     case Builtin::BI__addressof:
     case Builtin::BI__builtin_addressof: {
       LValue LV = CGF.EmitLValue(Call->getArg(0), IsKnownNonNull);
-      if (BaseInfo)
-        *BaseInfo = LV.getBaseInfo();
-      if (TBAAInfo)
-        *TBAAInfo = LV.getTBAAInfo();
+      if (BaseInfo) *BaseInfo = LV.getBaseInfo();
+      if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo();
       return LV.getAddress();
     }
     }
@@ -1633,7 +1638,7 @@ RValue CodeGenFunction::GetUndefRValue(QualType Ty) {
   switch (getEvaluationKind(Ty)) {
   case TEK_Complex: {
     llvm::Type *EltTy =
-        ConvertType(Ty->castAs<ComplexType>()->getElementType());
+      ConvertType(Ty->castAs<ComplexType>()->getElementType());
     llvm::Value *U = llvm::UndefValue::get(EltTy);
     return RValue::getComplex(std::make_pair(U, U));
   }
@@ -1652,12 +1657,14 @@ RValue CodeGenFunction::GetUndefRValue(QualType Ty) {
   llvm_unreachable("bad evaluation kind");
 }
 
-RValue CodeGenFunction::EmitUnsupportedRValue(const Expr *E, const char *Name) {
+RValue CodeGenFunction::EmitUnsupportedRValue(const Expr *E,
+                                              const char *Name) {
   ErrorUnsupported(E, Name);
   return GetUndefRValue(E->getType());
 }
 
-LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E, const char *Name) {
+LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,
+                                              const char *Name) {
   ErrorUnsupported(E, Name);
   llvm::Type *ElTy = ConvertType(E->getType());
   llvm::Type *Ty = DefaultPtrTy;
@@ -1691,7 +1698,7 @@ bool CodeGenFunction::IsWrappedCXXThis(const Expr *Obj) {
 LValue CodeGenFunction::EmitCheckedLValue(const Expr *E, TypeCheckKind TCK) {
   LValue LV;
   if (SanOpts.has(SanitizerKind::ArrayBounds) && isa<ArraySubscriptExpr>(E))
-    LV = EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E), /*Accessed*/ true);
+    LV = EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E), /*Accessed*/true);
   else
     LV = EmitLValue(E);
   if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple()) {
@@ -1740,8 +1747,7 @@ LValue CodeGenFunction::EmitLValueHelper(const Expr *E,
                                          KnownNonNull_t IsKnownNonNull) {
   ApplyDebugLocation DL(*this, E);
   switch (E->getStmtClass()) {
-  default:
-    return EmitUnsupportedLValue(E, "l-value expression");
+  default: return EmitUnsupportedLValue(E, "l-value expression");
 
   case Expr::ObjCPropertyRefExprClass:
     llvm_unreachable("cannot emit a property reference directly");
@@ -1905,8 +1911,7 @@ static bool isConstantEmittableObjectType(QualType type) {
 
   // Must be const-qualified but non-volatile.
   Qualifiers qs = type.getLocalQualifiers();
-  if (!qs.hasConst() || qs.hasVolatile())
-    return false;
+  if (!qs.hasConst() || qs.hasVolatile()) return false;
 
   // Otherwise, all object types satisfy this except C++ classes with
   // mutable subobjects or non-trivial copy/destroy behavior.
@@ -1966,8 +1971,7 @@ CodeGenFunction::tryEmitAsConstant(const DeclRefExpr *RefExpr) {
   } else {
     CEK = CEK_None;
   }
-  if (CEK == CEK_None)
-    return ConstantEmission();
+  if (CEK == CEK_None) return ConstantEmission();
 
   Expr::EvalResult result;
   bool resultIsReference;
@@ -1979,13 +1983,13 @@ CodeGenFunction::tryEmitAsConstant(const DeclRefExpr *RefExpr) {
     resultIsReference = false;
     resultType = RefExpr->getType().getUnqualifiedType();
 
-    // Otherwise, try to evaluate as an l-value.
+  // Otherwise, try to evaluate as an l-value.
   } else if (CEK != CEK_AsValueOnly &&
              RefExpr->EvaluateAsLValue(result, getContext())) {
     resultIsReference = true;
     resultType = Value->getType();
 
-    // Failure.
+  // Failure.
   } else {
     return ConstantEmission();
   }
@@ -2145,7 +2149,8 @@ bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
   // Single-bit booleans don't need to be checked. Special-case this to avoid
   // a bit width mismatch when handling bitfield values. This is handled by
   // EmitFromMemory for the non-bitfield case.
-  if (IsBool && cast<llvm::IntegerType>(Value->getType())->getBitWidth() == 1)
+  if (IsBool &&
+      cast<llvm::IntegerType>(Value->getType())->getBitWidth() == 1)
     return false;
 
   if (NeedsEnumCheck &&
@@ -2181,7 +2186,8 @@ bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
 }
 
 llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
-                                               QualType Ty, SourceLocation Loc,
+                                               QualType Ty,
+                                               SourceLocation Loc,
                                                LValueBaseInfo BaseInfo,
                                                TBAAAccessInfo TBAAInfo,
                                                bool isNontemporal) {
@@ -2428,8 +2434,8 @@ static void EmitStoreOfMatrixScalar(llvm::Value *value, LValue lvalue,
 void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
                                         bool Volatile, QualType Ty,
                                         LValueBaseInfo BaseInfo,
-                                        TBAAAccessInfo TBAAInfo, bool isInit,
-                                        bool isNontemporal) {
+                                        TBAAAccessInfo TBAAInfo,
+                                        bool isInit, bool isNontemporal) {
   if (auto *GV = dyn_cast<llvm::GlobalValue>(Addr.getBasePointer()))
     if (GV->isThreadLocal())
       Addr = Addr.withPointer(Builder.CreateThreadLocalAddress(GV),
@@ -2542,8 +2548,8 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
   if (LV.isObjCWeak()) {
     // load of a __weak object.
     Address AddrWeakObj = LV.getAddress();
-    return RValue::get(
-        CGM.getObjCRuntime().EmitObjCWeakRead(*this, AddrWeakObj));
+    return RValue::get(CGM.getObjCRuntime().EmitObjCWeakRead(*this,
+                                                             AddrWeakObj));
   }
   if (LV.getQuals().getObjCLifetime() == Qualifiers::OCL_Weak) {
     // In MRC mode, we do a load+autorelease.
@@ -2568,8 +2574,8 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
   }
 
   if (LV.isVectorElt()) {
-    llvm::LoadInst *Load =
-        Builder.CreateLoad(LV.getVectorAddress(), LV.isVolatileQualified());
+    llvm::LoadInst *Load = Builder.CreateLoad(LV.getVectorAddress(),
+                                              LV.isVolatileQualified());
     llvm::Value *Elt =
         Builder.CreateExtractElement(Load, LV.getVectorIdx(), "vecext");
     return RValue::get(EmitFromMemory(Elt, LV.getType()));
@@ -2682,8 +2688,8 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
 // If this is a reference to a subset of the elements of a vector, create an
 // appropriate shufflevector.
 RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV) {
-  llvm::Value *Vec =
-      Builder.CreateLoad(LV.getExtVectorAddress(), LV.isVolatileQualified());
+  llvm::Value *Vec = Builder.CreateLoad(LV.getExtVectorAddress(),
+                                        LV.isVolatileQualified());
 
   // HLSL allows treating scalars as one-element vectors. Converting the scalar
   // IR value to a vector here allows the rest of codegen to behave as normal.
@@ -2750,7 +2756,8 @@ Address CodeGenFunction::EmitExtVectorElementLValue(LValue LV) {
   unsigned ix = getAccessedFieldNo(0, Elts);
 
   Address VectorBasePtrPlusIx =
-      Builder.CreateConstInBoundsGEP(CastToPointerElement, ix, "vector.elt");
+    Builder.CreateConstInBoundsGEP(CastToPointerElement, ix,
+                                   "vector.elt");
 
   return VectorBasePtrPlusIx;
 }
@@ -2767,7 +2774,7 @@ RValue CodeGenFunction::EmitLoadOfGlobalRegLValue(LValue LV) {
   llvm::Type *Ty = OrigTy;
   if (OrigTy->isPointerTy())
     Ty = CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
-  llvm::Type *Types[] = {Ty};
+  llvm::Type *Types[] = { Ty };
 
   llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
   llvm::Value *Call = Builder.CreateCall(
@@ -2811,8 +2818,8 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
       }
 
       // Read/modify/write the vector, inserting the new element.
-      llvm::Value *Vec =
-          Builder.CreateLoad(Dst.getVectorAddress(), Dst.isVolatileQualified());
+      llvm::Value *Vec = Builder.CreateLoad(Dst.getVectorAddress(),
+                                            Dst.isVolatileQualified());
       llvm::Type *VecTy = Vec->getType();
       llvm::Value *SrcVal = Src.getScalarVal();
 
@@ -2999,8 +3006,8 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
       return;
 
     case Qualifiers::OCL_Autoreleasing:
-      Src = RValue::get(
-          EmitObjCExtendObjectLifetime(Dst.getType(), Src.getScalarVal()));
+      Src = RValue::get(EmitObjCExtendObjectLifetime(Dst.getType(),
+                                                     Src.getScalarVal()));
       // fall into the normal path
       break;
     }
@@ -3010,7 +3017,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
     // load of a __weak object.
     Address LvalueDst = Dst.getAddress();
     llvm::Value *src = Src.getScalarVal();
-    CGM.getObjCRuntime().EmitObjCWeakAssign(*this, src, LvalueDst);
+     CGM.getObjCRuntime().EmitObjCWeakAssign(*this, src, LvalueDst);
     return;
   }
 
@@ -3031,7 +3038,8 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
     } else if (Dst.isGlobalObjCRef()) {
       CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst,
                                                 Dst.isThreadLocalRef());
-    } else
+    }
+    else
       CGM.getObjCRuntime().EmitObjCStrongCastAssign(*this, src, LvalueDst);
     return;
   }
@@ -3241,7 +3249,7 @@ void CodeGenFunction::EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst) {
   llvm::Type *Ty = OrigTy;
   if (OrigTy->isPointerTy())
     Ty = CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
-  llvm::Type *Types[] = {Ty};
+  llvm::Type *Types[] = { Ty };
 
   llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
   llvm::Value *Value = Src.getScalarVal();
@@ -3255,7 +3263,8 @@ void CodeGenFunction::EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst) {
 // generating write-barries API. It is currently a global, ivar,
 // or neither.
 static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,
-                                 LValue &LV, bool IsMemberAccess = false) {
+                                 LValue &LV,
+                                 bool IsMemberAccess=false) {
   if (Ctx.getLangOpts().getGC() == LangOptions::NonGC)
     return;
 
@@ -3350,11 +3359,9 @@ static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,
   }
 }
 
-static LValue EmitThreadPrivateVarDeclLValue(CodeGenFunction &CGF,
-                                             const VarDecl *VD, QualType T,
-                                             Address Addr,
-                                             llvm::Type *RealVarTy,
-                                             SourceLocation Loc) {
+static LValue EmitThreadPrivateVarDeclLValue(
+    CodeGenFunction &CGF, const VarDecl *VD, QualType T, Address Addr,
+    llvm::Type *RealVarTy, SourceLocation Loc) {
   if (CGF.CGM.getLangOpts().OpenMPIRBuilder)
     Addr = CodeGenFunction::OMPBuilderCBHelpers::getAddrOfThreadPrivate(
         CGF, VD, Addr, Loc);
@@ -3389,9 +3396,10 @@ static Address emitDeclTargetVarDeclLValue(CodeGenFunction &CGF,
   return CGF.EmitLoadOfPointer(Addr, PtrTy->castAs<PointerType>());
 }
 
-Address CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
-                                             LValueBaseInfo *PointeeBaseInfo,
-                                             TBAAAccessInfo *PointeeTBAAInfo) {
+Address
+CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
+                                     LValueBaseInfo *PointeeBaseInfo,
+                                     TBAAAccessInfo *PointeeTBAAInfo) {
   llvm::LoadInst *Load =
       Builder.CreateLoad(RefLVal.getAddress(), RefLVal.isVolatile());
   CGM.DecorateInstructionWithTBAA(Load, RefLVal.getTBAAInfo());
@@ -3425,8 +3433,8 @@ Address CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
 LValue CodeGenFunction::EmitLoadOfReferenceLValue(LValue RefLVal) {
   LValueBaseInfo PointeeBaseInfo;
   TBAAAccessInfo PointeeTBAAInfo;
-  Address PointeeAddr =
-      EmitLoadOfReference(RefLVal, &PointeeBaseInfo, &PointeeTBAAInfo);
+  Address PointeeAddr = EmitLoadOfReference(RefLVal, &PointeeBaseInfo,
+                                            &PointeeTBAAInfo);
   return MakeAddrLValue(PointeeAddr, RefLVal.getType()->getPointeeType(),
                         PointeeBaseInfo, PointeeTBAAInfo);
 }
@@ -3449,8 +3457,8 @@ LValue CodeGenFunction::EmitLoadOfPointerLValue(Address PtrAddr,
   return MakeAddrLValue(Addr, PtrTy->getPointeeType(), BaseInfo, TBAAInfo);
 }
 
-static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, const Expr *E,
-                                      const VarDecl *VD) {
+static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
+                                      const Expr *E, const VarDecl *VD) {
   QualType T = E->getType();
 
   // If it's thread_local, emit a call to its wrapper function instead.
@@ -3489,10 +3497,10 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, const Expr *E,
     return EmitThreadPrivateVarDeclLValue(CGF, VD, T, Addr, RealVarTy,
                                           E->getExprLoc());
   }
-  LValue LV = VD->getType()->isReferenceType()
-                  ? CGF.EmitLoadOfReferenceLValue(Addr, VD->getType(),
-                                                  AlignmentSource::Decl)
-                  : CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
+  LValue LV = VD->getType()->isReferenceType() ?
+      CGF.EmitLoadOfReferenceLValue(Addr, VD->getType(),
+                                    AlignmentSource::Decl) :
+      CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
   setObjCGCLValueClass(CGF.getContext(), E, LV);
   return LV;
 }
@@ -3537,12 +3545,14 @@ static LValue EmitCapturedFieldLValue(CodeGenFunction &CGF, const FieldDecl *FD,
 static LValue EmitGlobalNamedRegister(const VarDecl *VD, CodeGenModule &CGM) {
   SmallString<64> Name("llvm.named.register.");
   AsmLabelAttr *Asm = VD->getAttr<AsmLabelAttr>();
-  assert(Asm->getLabel().size() < 64 - Name.size() && "Register name too big");
+  assert(Asm->getLabel().size() < 64-Name.size() &&
+      "Register name too big");
   Name.append(Asm->getLabel());
-  llvm::NamedMDNode *M = CGM.getModule().getOrInsertNamedMetadata(Name);
+  llvm::NamedMDNode *M =
+    CGM.getModule().getOrInsertNamedMetadata(Name);
   if (M->getNumOperands() == 0) {
-    llvm::MDString *Str =
-        llvm::MDString::get(CGM.getLLVMContext(), Asm->getLabel());
+    llvm::MDString *Str = llvm::MDString::get(CGM.getLLVMContext(),
+                                              Asm->getLabel());
     llvm::Metadata *Ops[] = {Str};
     M->addOperand(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
   }
@@ -3550,7 +3560,7 @@ static LValue EmitGlobalNamedRegister(const VarDecl *VD, CodeGenModule &CGM) {
   CharUnits Alignment = CGM.getContext().getDeclAlign(VD);
 
   llvm::Value *Ptr =
-      llvm::MetadataAsValue::get(CGM.getLLVMContext(), M->getOperand(0));
+    llvm::MetadataAsValue::get(CGM.getLLVMContext(), M->getOperand(0));
   return LValue::MakeGlobalReg(Ptr, Alignment, VD->getType());
 }
 
@@ -3613,8 +3623,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
 
   if (const auto *VD = dyn_cast<VarDecl>(ND)) {
     // Global Named registers access via intrinsics only
-    if (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
-        !VD->isLocalVarDecl())
+    if (VD->getStorageClass() == SC_Register &&
+        VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
       return EmitGlobalNamedRegister(VD, CGM);
 
     // If this DeclRefExpr does not constitute an odr-use of the variable,
@@ -3722,15 +3732,15 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
     if (iter != LocalDeclMap.end()) {
       addr = iter->second;
 
-      // Otherwise, it might be static local we haven't emitted yet for
-      // some reason; most likely, because it's in an outer function.
+    // Otherwise, it might be static local we haven't emitted yet for
+    // some reason; most likely, because it's in an outer function.
     } else if (VD->isStaticLocal()) {
       llvm::Constant *var = CGM.getOrCreateStaticVarDecl(
           *VD, CGM.getLLVMLinkageVarDefinition(VD));
-      addr = Address(var, ConvertTypeForMem(VD->getType()),
-                     getContext().getDeclAlign(VD));
+      addr = Address(
+          var, ConvertTypeForMem(VD->getType()), getContext().getDeclAlign(VD));
 
-      // No other cases for now.
+    // No other cases for now.
     } else {
       llvm_unreachable("DeclRefExpr for Decl not entered in LocalDeclMap?");
     }
@@ -3756,22 +3766,22 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
     }
 
     // Drill into reference types.
-    LValue LV = VD->getType()->isReferenceType()
-                    ? EmitLoadOfReferenceLValue(addr, VD->getType(),
-                                                AlignmentSource::Decl)
-                    : MakeAddrLValue(addr, T, AlignmentSource::Decl);
+    LValue LV = VD->getType()->isReferenceType() ?
+        EmitLoadOfReferenceLValue(addr, VD->getType(), AlignmentSource::Decl) :
+        MakeAddrLValue(addr, T, AlignmentSource::Decl);
 
     bool isLocalStorage = VD->hasLocalStorage();
 
-    bool NonGCable =
-        isLocalStorage && !VD->getType()->isReferenceType() && !isBlockByref;
+    bool NonGCable = isLocalStorage &&
+                     !VD->getType()->isReferenceType() &&
+                     !isBlockByref;
     if (NonGCable) {
       LV.getQuals().removeObjCGCAttr();
       LV.setNonGC(true);
     }
 
     bool isImpreciseLifetime =
-        (isLocalStorage && !VD->hasAttr<ObjCPreciseLifetimeAttr>());
+      (isLocalStorage && !VD->hasAttr<ObjCPreciseLifetimeAttr>());
     if (isImpreciseLifetime)
       LV.setARCPreciseLifetime(ARCImpreciseLifetime);
     setObjCGCLValueClass(getContext(), E, LV);
@@ -3830,16 +3840,15 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
 
   QualType ExprTy = getContext().getCanonicalType(E->getSubExpr()->getType());
   switch (E->getOpcode()) {
-  default:
-    llvm_unreachable("Unknown unary operator lvalue!");
+  default: llvm_unreachable("Unknown unary operator lvalue!");
   case UO_Deref: {
     QualType T = E->getSubExpr()->getType()->getPointeeType();
     assert(!T.isNull() && "CodeGenFunction::EmitUnaryOpLValue: Illegal type");
 
     LValueBaseInfo BaseInfo;
     TBAAAccessInfo TBAAInfo;
-    Address Addr =
-        EmitPointerWithAlignment(E->getSubExpr(), &BaseInfo, &TBAAInfo);
+    Address Addr = EmitPointerWithAlignment(E->getSubExpr(), &BaseInfo,
+                                            &TBAAInfo);
     LValue LV = MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo);
     LV.getQuals().setAddressSpace(ExprTy.getAddressSpace());
 
@@ -3847,7 +3856,8 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
     // of a pointer to object; as in void foo (__weak id *param); *param = 0;
     // But, we continue to generate __strong write barrier on indirect write
     // into a pointer to object.
-    if (getLangOpts().ObjC && getLangOpts().getGC() != LangOptions::NonGC &&
+    if (getLangOpts().ObjC &&
+        getLangOpts().getGC() != LangOptions::NonGC &&
         LV.isObjCWeak())
       LV.setNonGC(!E->isOBJCGCCandidate(getContext()));
     return LV;
@@ -3882,17 +3892,17 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
     bool isInc = E->getOpcode() == UO_PreInc;
 
     if (E->getType()->isAnyComplexType())
-      EmitComplexPrePostIncDec(E, LV, isInc, true /*isPre*/);
+      EmitComplexPrePostIncDec(E, LV, isInc, true/*isPre*/);
     else
-      EmitScalarPrePostIncDec(E, LV, isInc, true /*isPre*/);
+      EmitScalarPrePostIncDec(E, LV, isInc, true/*isPre*/);
     return LV;
   }
   }
 }
 
 LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
-  return MakeAddrLValue(CGM.GetAddrOfConstantStringFromLiteral(E), E->getType(),
-                        AlignmentSource::Decl);
+  return MakeAddrLValue(CGM.GetAddrOfConstantStringFromLiteral(E),
+                        E->getType(), AlignmentSource::Decl);
 }
 
 LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) {
@@ -3905,8 +3915,8 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
   assert(SL != nullptr && "No StringLiteral name in PredefinedExpr");
   StringRef FnName = CurFn->getName();
   FnName.consume_front("\01");
-  StringRef NameItems[] = {PredefinedExpr::getIdentKindName(E->getIdentKind()),
-                           FnName};
+  StringRef NameItems[] = {
+      PredefinedExpr::getIdentKindName(E->getIdentKind()), FnName};
   std::string GVName = llvm::join(NameItems, NameItems + 2, ".");
   if (auto *BD = dyn_cast_or_null<BlockDecl>(CurCodeDecl)) {
     std::string Name = std::string(SL->getString());
@@ -3992,8 +4002,9 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
   }
 
   llvm::Constant *Components[] = {
-      Builder.getInt16(TypeKind), Builder.getInt16(TypeInfo),
-      llvm::ConstantDataArray::getString(getLLVMContext(), Buffer)};
+    Builder.getInt16(TypeKind), Builder.getInt16(TypeInfo),
+    llvm::ConstantDataArray::getString(getLLVMContext(), Buffer)
+  };
   llvm::Constant *Descriptor = llvm::ConstantStruct::getAnon(Components);
 
   auto *GV = new llvm::GlobalVariable(
@@ -4019,8 +4030,8 @@ llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) {
   if (V->getType()->isFloatingPointTy()) {
     unsigned Bits = V->getType()->getPrimitiveSizeInBits().getFixedValue();
     if (Bits <= TargetTy->getIntegerBitWidth())
-      V = Builder.CreateBitCast(V,
-                                llvm::Type::getIntNTy(getLLVMContext(), Bits));
+      V = Builder.CreateBitCast(V, llvm::Type::getIntNTy(getLLVMContext(),
+                                                         Bits));
   }
 
   // Integers which fit in intptr_t are zero-extended and passed directly.
@@ -4108,7 +4119,7 @@ enum class CheckRecoverableKind {
   /// Runtime conditionally aborts, always need to support recovery.
   AlwaysRecoverable
 };
-} // namespace
+}
 
 static CheckRecoverableKind
 getRecoverableKind(SanitizerKind::SanitizerOrdinal Ordinal) {
@@ -4126,7 +4137,7 @@ struct SanitizerHandlerInfo {
   char const *const Name;
   unsigned Version;
 };
-} // namespace
+}
 
 const SanitizerHandlerInfo SanitizerHandlers[] = {
 #define SANITIZER_CHECK(Enum, Name, Version, Msg) {#Name, Version},
@@ -4303,7 +4314,7 @@ void CodeGenFunction::EmitCheck(
   }
 
   llvm::FunctionType *FnType =
-      llvm::FunctionType::get(CGM.VoidTy, ArgTypes, false);
+    llvm::FunctionType::get(CGM.VoidTy, ArgTypes, false);
 
   if (!FatalCond || !RecoverableCond) {
     // Simple case: we need to generate a single handler call, either
@@ -4402,7 +4413,7 @@ void CodeGenFunction::EmitCfiCheckStub() {
   llvm::LLVMContext &Ctx = M->getContext();
   llvm::BasicBlock *BB = llvm::BasicBlock::Create(Ctx, "entry", F);
   // CrossDSOCFI pass is not executed if there is no executable code.
-  SmallVector<llvm::Value *> Args{F->getArg(2), F->getArg(1)};
+  SmallVector<llvm::Value*> Args{F->getArg(2), F->getArg(1)};
   llvm::CallInst::Create(M->getFunction("__cfi_check_fail"), Args, "", BB);
   llvm::ReturnInst::Create(Ctx, nullptr, BB);
 }
@@ -4432,8 +4443,8 @@ void CodeGenFunction::EmitCfiCheckFail() {
       getContext(), getContext().VoidPtrTy, ImplicitParamKind::Other);
 
   FunctionArgList Args{ArgData, ArgAddr};
-  const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
-      getContext().VoidTy, Args);
+  const CGFunctionInfo &FI =
+    CGM.getTypes().arrangeBuiltinFunctionDeclaration(getContext().VoidTy, Args);
 
   llvm::Function *F = llvm::Function::Create(
       llvm::FunctionType::get(VoidTy, {VoidPtrTy, VoidPtrTy}, false),
@@ -4686,10 +4697,8 @@ Address CodeGenFunction::EmitArrayToPointerDecay(const Expr *E,
   // to the pointee object as if it had no any base lvalue specified.
   // TODO: Support TBAA for member arrays.
   QualType EltType = E->getType()->castAsArrayTypeUnsafe()->getElementType();
-  if (BaseInfo)
-    *BaseInfo = LV.getBaseInfo();
-  if (TBAAInfo)
-    *TBAAInfo = CGM.getTBAAAccessInfo(EltType);
+  if (BaseInfo) *BaseInfo = LV.getBaseInfo();
+  if (TBAAInfo) *TBAAInfo = CGM.getTBAAAccessInfo(EltType);
 
   return Addr.withElementType(ConvertTypeForMem(EltType));
 }
@@ -4710,11 +4719,14 @@ static const Expr *isSimpleArrayDecayOperand(const Expr *E) {
   return SubExpr;
 }
 
-static llvm::Value *
-emitArraySubscriptGEP(CodeGenFunction &CGF, llvm::Type *elemType,
-                      llvm::Value *ptr, ArrayRef<llvm::Value *> indices,
-                      bool inbounds, bool signedIndices, SourceLocation loc,
-                      const llvm::Twine &name = "arrayidx") {
+static llvm::Value *emitArraySubscriptGEP(CodeGenFunction &CGF,
+                                          llvm::Type *elemType,
+                                          llvm::Value *ptr,
+                                          ArrayRef<llvm::Value*> indices,
+                                          bool inbounds,
+                                          bool signedIndices,
+                                          SourceLocation loc,
+                                    const llvm::Twine &name = "arrayidx") {
   if (inbounds && CGF.getLangOpts().EmitLogicalPointer)
     return CGF.Builder.CreateStructuredGEP(elemType, ptr, indices);
 
@@ -4811,8 +4823,8 @@ static bool IsPreserveAIArrayBase(CodeGenFunction &CGF, const Expr *ArrayBase) {
     if (!PtrT)
       return false;
 
-    const auto *PointeeT =
-        PtrT->getPointeeType()->getUnqualifiedDesugaredType();
+    const auto *PointeeT = PtrT->getPointeeType()
+                             ->getUnqualifiedDesugaredType();
     if (const auto *RecT = dyn_cast<RecordType>(PointeeT))
       return RecT->getDecl()
           ->getMostRecentDecl()
@@ -5040,7 +5052,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
       !isa<ExtVectorElementExpr>(E->getBase())) {
     // Emit the vector as an lvalue to get its address.
     LValue LHS = EmitLValue(E->getBase());
-    auto *Idx = EmitIdxAfterBase(/*Promote*/ false);
+    auto *Idx = EmitIdxAfterBase(/*Promote*/false);
     assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
     return LValue::MakeVectorElt(LHS.getAddress(), Idx, E->getBase()->getType(),
                                  LHS.getBaseInfo(), TBAAAccessInfo());
@@ -5066,7 +5078,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
   // Handle the extvector case we ignored above.
   if (isa<ExtVectorElementExpr>(E->getBase())) {
     LValue LV = EmitLValue(E->getBase());
-    auto *Idx = EmitIdxAfterBase(/*Promote*/ true);
+    auto *Idx = EmitIdxAfterBase(/*Promote*/true);
     Address Addr = EmitExtVectorElementLValue(LV);
 
     QualType EltType = LV.getType()->castAs<VectorType>()->getElementType();
@@ -5080,12 +5092,12 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
   TBAAAccessInfo EltTBAAInfo;
   Address Addr = Address::invalid();
   if (const VariableArrayType *vla =
-          getContext().getAsVariableArrayType(E->getType())) {
+           getContext().getAsVariableArrayType(E->getType())) {
     // The base must be a pointer, which is not an aggregate.  Emit
     // it.  It needs to be emitted first in case it's what captures
     // the VLA bounds.
     Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
-    auto *Idx = EmitIdxAfterBase(/*Promote*/ true);
+    auto *Idx = EmitIdxAfterBase(/*Promote*/true);
 
     // The element count here is the total number of non-VLA elements.
     llvm::Value *numElements = getVLASize(vla).NumElts;
@@ -5104,13 +5116,12 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
                                  !getLangOpts().PointerOverflowDefined,
                                  SignedIndices, E->getExprLoc());
 
-  } else if (const ObjCObjectType *OIT =
-                 E->getType()->getAs<ObjCObjectType>()) {
+  } else if (const ObjCObjectType *OIT = E->getType()->getAs<ObjCObjectType>()){
     // Indexing over an interface, as in "NSString *P; P[4];"
 
     // Emit the base pointer.
     Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
-    auto *Idx = EmitIdxAfterBase(/*Promote*/ true);
+    auto *Idx = EmitIdxAfterBase(/*Promote*/true);
 
     CharUnits InterfaceSize = getContext().getTypeSizeInChars(OIT);
     llvm::Value *InterfaceSizeVal =
@@ -5126,7 +5137,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
 
     // Do the GEP.
     CharUnits EltAlign =
-        getArrayElementAlign(Addr.getAlignment(), Idx, InterfaceSize);
+      getArrayElementAlign(Addr.getAlignment(), Idx, InterfaceSize);
     llvm::Value *EltPtr =
         emitArraySubscriptGEP(*this, Int8Ty, Addr.emitRawPointer(*this),
                               ScaledIdx, false, SignedIndices, E->getExprLoc());
@@ -5145,7 +5156,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
       ArrayLV = EmitArraySubscriptExpr(ASE, /*Accessed*/ true);
     else
       ArrayLV = EmitLValue(Array);
-    auto *Idx = EmitIdxAfterBase(/*Promote*/ true);
+    auto *Idx = EmitIdxAfterBase(/*Promote*/true);
 
     if (SanOpts.has(SanitizerKind::ArrayBounds))
       EmitCountedByBoundsChecking(Array, Array->getType(), ArrayLV.getAddress(),
@@ -5189,7 +5200,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
     // The base must be a pointer; emit it with an estimate of its alignment.
     Address BaseAddr =
         EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
-    auto *Idx = EmitIdxAfterBase(/*Promote*/ true);
+    auto *Idx = EmitIdxAfterBase(/*Promote*/true);
     QualType ptrType = E->getBase()->getType();
     Addr = emitArraySubscriptGEP(*this, BaseAddr, Idx, E->getType(),
                                  !getLangOpts().PointerOverflowDefined,
@@ -5210,7 +5221,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
 
   LValue LV = MakeAddrLValue(Addr, E->getType(), EltBaseInfo, EltTBAAInfo);
 
-  if (getLangOpts().ObjC && getLangOpts().getGC() != LangOptions::NonGC) {
+  if (getLangOpts().ObjC &&
+      getLangOpts().getGC() != LangOptions::NonGC) {
     LV.setNonGC(!E->isOBJCGCCandidate(getContext()));
     setObjCGCLValueClass(getContext(), E, LV);
   }
@@ -5360,10 +5372,11 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
                       LowerBound->getType()->hasSignedIntegerRepresentation())
                 : llvm::ConstantInt::get(IntPtrTy, ConstLowerBound);
         auto *LengthVal =
-            Length ? Builder.CreateIntCast(
-                         EmitScalarExpr(Length), IntPtrTy,
-                         Length->getType()->hasSignedIntegerRepresentation())
-                   : llvm::ConstantInt::get(IntPtrTy, ConstLength);
+            Length
+                ? Builder.CreateIntCast(
+                      EmitScalarExpr(Length), IntPtrTy,
+                      Length->getType()->hasSignedIntegerRepresentation())
+                : llvm::ConstantInt::get(IntPtrTy, ConstLength);
         Idx = Builder.CreateAdd(LowerBoundVal, LengthVal, "lb_add_len",
                                 /*HasNUW=*/false,
                                 !getLangOpts().PointerOverflowDefined);
@@ -5414,8 +5427,8 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
     // it.  It needs to be emitted first in case it's what captures
     // the VLA bounds.
     Address Base =
-        emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo, BaseTy,
-                                VLA->getElementType(), IsLowerBound);
+        emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo,
+                                BaseTy, VLA->getElementType(), IsLowerBound);
     // The element count here is the total number of non-VLA elements.
     llvm::Value *NumElements = getVLASize(VLA).NumElts;
 
@@ -5464,8 +5477,8 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
   return MakeAddrLValue(EltPtr, ResultExprTy, BaseInfo, TBAAInfo);
 }
 
-LValue
-CodeGenFunction::EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
+LValue CodeGenFunction::
+EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
   // Emit the base vector as an l-value.
   LValue Base;
 
@@ -5502,7 +5515,7 @@ CodeGenFunction::EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
   }
 
   QualType type =
-      E->getType().withCVRQualifiers(Base.getQuals().getCVRQualifiers());
+    E->getType().withCVRQualifiers(Base.getQuals().getCVRQualifiers());
 
   // Encode the element access list into a vector of unsigned indices.
   SmallVector<uint32_t, 4> Indices;
@@ -5729,7 +5742,7 @@ static Address emitRawAddrOfFieldStorage(CodeGenFunction &CGF, Address base,
   const RecordDecl *rec = field->getParent();
 
   unsigned idx =
-      CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
+    CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
   llvm::Type *StructType =
       CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMType();
 
@@ -5856,8 +5869,8 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field,
   AlignmentSource BaseAlignSource = BaseInfo.getAlignmentSource();
   LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource));
   TBAAAccessInfo FieldTBAAInfo;
-  if (base.getTBAAInfo().isMayAlias() || rec->hasAttr<MayAliasAttr>() ||
-      FieldType->isVectorType()) {
+  if (base.getTBAAInfo().isMayAlias() ||
+          rec->hasAttr<MayAliasAttr>() || FieldType->isVectorType()) {
     FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
   } else if (rec->isUnion()) {
     // TODO: Support TBAA for unions.
@@ -5867,9 +5880,9 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field,
     // one for this base lvalue.
     FieldTBAAInfo = base.getTBAAInfo();
     if (!FieldTBAAInfo.BaseType) {
-      FieldTBAAInfo.BaseType = CGM.getTBAABaseTypeInfo(base.getType());
-      assert(!FieldTBAAInfo.Offset &&
-             "Nonzero offset for an access with no base type!");
+        FieldTBAAInfo.BaseType = CGM.getTBAABaseTypeInfo(base.getType());
+        assert(!FieldTBAAInfo.Offset &&
+               "Nonzero offset for an access with no base type!");
     }
 
     // Adjust offset to be relative to the base type.
@@ -5914,8 +5927,8 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field,
     if (IsInPreservedAIRegion ||
         (getDebugInfo() && rec->hasAttr<BPFPreserveAccessIndexAttr>())) {
       // Remember the original union field index
-      llvm::DIType *DbgInfo = getDebugInfo()->getOrCreateStandaloneType(
-          base.getType(), rec->getLocation());
+      llvm::DIType *DbgInfo = getDebugInfo()->getOrCreateStandaloneType(base.getType(),
+          rec->getLocation());
       addr =
           Address(Builder.CreatePreserveUnionAccessIndex(
                       addr.emitRawPointer(*this),
@@ -6054,7 +6067,7 @@ LValue CodeGenFunction::EmitInitListLValue(const InitListExpr *E) {
 static std::optional<LValue> EmitLValueOrThrowExpression(CodeGenFunction &CGF,
                                                          const Expr *Operand) {
   if (auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Operand->IgnoreParens())) {
-    CGF.EmitCXXThrowExpr(ThrowExpr, /*KeepInsertionPoint*/ false);
+    CGF.EmitCXXThrowExpr(ThrowExpr, /*KeepInsertionPoint*/false);
     return std::nullopt;
   }
 
@@ -6101,7 +6114,7 @@ struct ConditionalInfo {
 
 // Create and generate the 3 blocks for a conditional operator.
 // Leaves the 'current block' in the continuation basic block.
-template <typename FuncTy>
+template<typename FuncTy>
 ConditionalInfo EmitConditionalBlocks(CodeGenFunction &CGF,
                                       const AbstractConditionalOperator *E,
                                       const FuncTy &BranchGenFunc) {
@@ -6440,8 +6453,8 @@ LValue
 CodeGenFunction::getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e) {
   assert(OpaqueValueMapping::shouldBindAsLValue(e));
 
-  llvm::DenseMap<const OpaqueValueExpr *, LValue>::iterator it =
-      OpaqueLValues.find(e);
+  llvm::DenseMap<const OpaqueValueExpr*,LValue>::iterator
+      it = OpaqueLValues.find(e);
 
   if (it != OpaqueLValues.end())
     return it->second;
@@ -6454,8 +6467,8 @@ RValue
 CodeGenFunction::getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e) {
   assert(!OpaqueValueMapping::shouldBindAsLValue(e));
 
-  llvm::DenseMap<const OpaqueValueExpr *, RValue>::iterator it =
-      OpaqueRValues.find(e);
+  llvm::DenseMap<const OpaqueValueExpr*,RValue>::iterator
+      it = OpaqueRValues.find(e);
 
   if (it != OpaqueRValues.end())
     return it->second;
@@ -6470,7 +6483,8 @@ bool CodeGenFunction::isOpaqueValueEmitted(const OpaqueValueExpr *E) {
   return OpaqueRValues.contains(E);
 }
 
-RValue CodeGenFunction::EmitRValueForField(LValue LV, const FieldDecl *FD,
+RValue CodeGenFunction::EmitRValueForField(LValue LV,
+                                           const FieldDecl *FD,
                                            SourceLocation Loc) {
   QualType FT = FD->getType();
   LValue FieldLV = EmitLValueForField(LV, FD);
@@ -6534,8 +6548,8 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,
   CGCallee callee = EmitCallee(E->getCallee());
 
   if (callee.isBuiltin()) {
-    return EmitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(), E,
-                           ReturnValue);
+    return EmitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(),
+                           E, ReturnValue);
   }
 
   if (callee.isPseudoDestructor()) {
@@ -6672,7 +6686,7 @@ CGCallee CodeGenFunction::EmitCallee(const Expr *E) {
       }
     }
 
-    // Resolve direct calls.
+  // Resolve direct calls.
   } else if (auto DRE = dyn_cast<DeclRefExpr>(E)) {
     if (auto FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
       return EmitDirectCallee(*this, getGlobalDeclForDirectCall(FD));
@@ -6683,11 +6697,11 @@ CGCallee CodeGenFunction::EmitCallee(const Expr *E) {
       return EmitDirectCallee(*this, FD);
     }
 
-    // Look through template substitutions.
+  // Look through template substitutions.
   } else if (auto NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
     return EmitCallee(NTTP->getReplacement());
 
-    // Treat pseudo-destructor calls differently.
+  // Treat pseudo-destructor calls differently.
   } else if (auto PDE = dyn_cast<CXXPseudoDestructorExpr>(E)) {
     return CGCallee::forPseudoDestructor(PDE);
   }
@@ -6723,7 +6737,8 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
     return EmitLValue(E->getRHS());
   }
 
-  if (E->getOpcode() == BO_PtrMemD || E->getOpcode() == BO_PtrMemI)
+  if (E->getOpcode() == BO_PtrMemD ||
+      E->getOpcode() == BO_PtrMemI)
     return EmitPointerToDataMemberBinaryExpr(E);
 
   assert(E->getOpcode() == BO_Assign && "unexpected binary l-value");
@@ -6872,14 +6887,15 @@ LValue CodeGenFunction::EmitVAArgExprLValue(const VAArgExpr *E) {
 }
 
 LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) {
-  assert(E->getType()->getAsCXXRecordDecl()->hasTrivialDestructor() &&
-         "binding l-value to type which needs a temporary");
+  assert(E->getType()->getAsCXXRecordDecl()->hasTrivialDestructor()
+         && "binding l-value to type which needs a temporary");
   AggValueSlot Slot = CreateAggTemp(E->getType());
   EmitCXXConstructExpr(E, Slot);
   return MakeAddrLValue(Slot.getAddress(), E->getType(), AlignmentSource::Decl);
 }
 
-LValue CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) {
+LValue
+CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) {
   return MakeNaturalAlignRawAddrLValue(EmitCXXTypeidExpr(E), E->getType());
 }
 
@@ -6917,7 +6933,8 @@ LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {
 }
 
 LValue CodeGenFunction::EmitObjCSelectorLValue(const ObjCSelectorExpr *E) {
-  Address V = CGM.getObjCRuntime().GetAddrOfSelector(*this, E->getSelector());
+  Address V =
+    CGM.getObjCRuntime().GetAddrOfSelector(*this, E->getSelector());
   return MakeAddrLValue(V, E->getType(), AlignmentSource::Decl);
 }
 
@@ -6960,8 +6977,9 @@ LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) {
     BaseQuals = ObjectTy.getQualifiers();
   }
 
-  LValue LV = EmitLValueForIvar(ObjectTy, BaseValue, E->getDecl(),
-                                BaseQuals.getCVRQualifiers());
+  LValue LV =
+    EmitLValueForIvar(ObjectTy, BaseValue, E->getDecl(),
+                      BaseQuals.getCVRQualifiers());
   setObjCGCLValueClass(getContext(), E, LV);
   return LV;
 }
@@ -7230,8 +7248,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
   return Call;
 }
 
-LValue
-CodeGenFunction::EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {
+LValue CodeGenFunction::
+EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {
   Address BaseAddr = Address::invalid();
   if (E->getOpcode() == BO_PtrMemI) {
     BaseAddr = EmitPointerWithAlignment(E->getLHS());
@@ -7254,7 +7272,8 @@ CodeGenFunction::EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {
 
 /// Given the address of a temporary variable, produce an r-value of
 /// its type.
-RValue CodeGenFunction::convertTempToRValue(Address addr, QualType type,
+RValue CodeGenFunction::convertTempToRValue(Address addr,
+                                            QualType type,
                                             SourceLocation loc) {
   LValue lvalue = MakeAddrLValue(addr, type, AlignmentSource::Decl);
   switch (getEvaluationKind(type)) {
@@ -7324,24 +7343,24 @@ void CodeGenFunction::SetDivFPAccuracy(llvm::Value *Val) {
 }
 
 namespace {
-struct LValueOrRValue {
-  LValue LV;
-  RValue RV;
-};
-} // namespace
+  struct LValueOrRValue {
+    LValue LV;
+    RValue RV;
+  };
+}
 
 static LValueOrRValue emitPseudoObjectExpr(CodeGenFunction &CGF,
                                            const PseudoObjectExpr *E,
-                                           bool forLValue, AggValueSlot slot) {
+                                           bool forLValue,
+                                           AggValueSlot slot) {
   SmallVector<CodeGenFunction::OpaqueValueMappingData, 4> opaques;
 
   // Find the result expression, if any.
   const Expr *resultExpr = E->getResultExpr();
   LValueOrRValue result;
 
-  for (PseudoObjectExpr::const_semantics_iterator i = E->semantics_begin(),
-                                                  e = E->semantics_end();
-       i != e; ++i) {
+  for (PseudoObjectExpr::const_semantics_iterator
+         i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
     const Expr *semantic = *i;
 
     // If this semantic expression is an opaque value, bind it
@@ -7366,7 +7385,7 @@ static LValueOrRValue emitPseudoObjectExpr(CodeGenFunction &CGF,
         opaqueData = OVMA::bind(CGF, ov, LV);
         result.RV = slot.asRValue();
 
-        // Otherwise, emit as normal.
+      // Otherwise, emit as normal.
       } else {
         opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
 
@@ -7381,15 +7400,15 @@ static LValueOrRValue emitPseudoObjectExpr(CodeGenFunction &CGF,
 
       opaques.push_back(opaqueData);
 
-      // Otherwise, if the expression is the result, evaluate it
-      // and remember the result.
+    // Otherwise, if the expression is the result, evaluate it
+    // and remember the result.
     } else if (semantic == resultExpr) {
       if (forLValue)
         result.LV = CGF.EmitLValue(semantic);
       else
         result.RV = CGF.EmitAnyExpr(semantic, slot);
 
-      // Otherwise, evaluate the expression in an ignored context.
+    // Otherwise, evaluate the expression in an ignored context.
     } else {
       CGF.EmitIgnoredExpr(semantic);
     }
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 1a90d53a88e34..062cacc98244e 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -178,7 +178,7 @@ void Sema::NoteDeletedFunction(FunctionDecl *Decl) {
     return NoteDeletedInheritingConstructor(Ctor);
 
   Diag(Decl->getLocation(), diag::note_availability_specified_here)
-      << Decl << 1;
+    << Decl << 1;
 }
 
 /// Determine whether a FunctionDecl was ever declared with an
@@ -256,7 +256,7 @@ void Sema::MaybeSuggestAddingStaticToDecl(const FunctionDecl *Cur) {
   if (!hasAnyExplicitStorageClass(First)) {
     SourceLocation DeclBegin = First->getSourceRange().getBegin();
     Diag(DeclBegin, diag::note_convert_inline_to_static)
-        << Cur << FixItHint::CreateInsertion(DeclBegin, "static ");
+      << Cur << FixItHint::CreateInsertion(DeclBegin, "static ");
   }
 }
 
@@ -295,7 +295,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
   if (ParsingInitForAutoVars.count(D)) {
     if (isa<BindingDecl>(D)) {
       Diag(Loc, diag::err_binding_cannot_appear_in_own_initializer)
-          << D->getDeclName();
+        << D->getDeclName();
     } else {
       Diag(Loc, diag::err_auto_variable_cannot_appear_in_own_initializer)
           << diag::ParsingInitFor::Var << D->getDeclName()
@@ -337,7 +337,8 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
         // constraint expression, for example)
         return true;
       if (!Satisfaction.IsSatisfied) {
-        Diag(Loc, diag::err_reference_to_function_with_unsatisfied_constraints)
+        Diag(Loc,
+             diag::err_reference_to_function_with_unsatisfied_constraints)
             << D;
         DiagnoseUnsatisfiedConstraint(Satisfaction);
         return true;
@@ -352,6 +353,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
 
     if (getLangOpts().CUDA && !CUDA().CheckCall(Loc, FD))
       return true;
+
   }
 
   if (auto *Concept = dyn_cast<ConceptDecl>(D);
@@ -365,12 +367,12 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
           cast<CXXConstructorDecl>(MD)->isDefaultConstructor()) ||
          MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator())) {
       Diag(Loc, diag::warn_cxx17_compat_lambda_def_ctor_assign)
-          << !isa<CXXConstructorDecl>(MD);
+        << !isa<CXXConstructorDecl>(MD);
     }
   }
 
-  auto getReferencedObjCProp =
-      [](const NamedDecl *D) -> const ObjCPropertyDecl * {
+  auto getReferencedObjCProp = [](const NamedDecl *D) ->
+                                      const ObjCPropertyDecl * {
     if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
       return MD->findPropertyDecl();
     return nullptr;
@@ -379,7 +381,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
     if (diagnoseArgIndependentDiagnoseIfAttrs(ObjCPDecl, Loc))
       return true;
   } else if (diagnoseArgIndependentDiagnoseIfAttrs(D, Loc)) {
-    return true;
+      return true;
   }
 
   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
@@ -558,8 +560,7 @@ ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, bool Diagnose) {
   // Handle any placeholder expressions which made it here.
   if (E->hasPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(E);
-    if (result.isInvalid())
-      return ExprError();
+    if (result.isInvalid()) return ExprError();
     E = result.get();
   }
 
@@ -573,8 +574,7 @@ ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, bool Diagnose) {
           return ExprError();
 
     E = ImpCastExprToType(E, Context.getPointerType(Ty),
-                          CK_FunctionToPointerDecay)
-            .get();
+                          CK_FunctionToPointerDecay).get();
   } else if (Ty->isArrayType()) {
     // In C90 mode, arrays only promote to pointers if the array expression is
     // an lvalue.  The relevant legalese is C90 6.2.2.1p3: "an lvalue that has
@@ -624,7 +624,8 @@ static void CheckForNullPointerDereference(Sema &S, Expr *E) {
 }
 
 static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE,
-                                    SourceLocation AssignLoc, const Expr *RHS) {
+                                    SourceLocation AssignLoc,
+                                    const Expr* RHS) {
   const ObjCIvarDecl *IV = OIRE->getDecl();
   if (!IV)
     return;
@@ -642,12 +643,13 @@ static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE,
     if (ObjCInterfaceDecl *IDecl = OTy->getInterface()) {
       ObjCInterfaceDecl *ClassDeclared = nullptr;
       ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
-      if (!ClassDeclared->getSuperClass() &&
-          (*ClassDeclared->ivar_begin()) == IV) {
+      if (!ClassDeclared->getSuperClass()
+          && (*ClassDeclared->ivar_begin()) == IV) {
         if (RHS) {
-          NamedDecl *ObjectSetClass = S.LookupSingleName(
-              S.TUScope, &S.Context.Idents.get("object_setClass"),
-              SourceLocation(), S.LookupOrdinaryName);
+          NamedDecl *ObjectSetClass =
+            S.LookupSingleName(S.TUScope,
+                               &S.Context.Idents.get("object_setClass"),
+                               SourceLocation(), S.LookupOrdinaryName);
           if (ObjectSetClass) {
             SourceLocation RHSLocEnd = S.getLocForEndOfToken(RHS->getEndLoc());
             S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_assign)
@@ -656,12 +658,14 @@ static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE,
                 << FixItHint::CreateReplacement(
                        SourceRange(OIRE->getOpLoc(), AssignLoc), ",")
                 << FixItHint::CreateInsertion(RHSLocEnd, ")");
-          } else
+          }
+          else
             S.Diag(OIRE->getLocation(), diag::warn_objc_isa_assign);
         } else {
-          NamedDecl *ObjectGetClass = S.LookupSingleName(
-              S.TUScope, &S.Context.Idents.get("object_getClass"),
-              SourceLocation(), S.LookupOrdinaryName);
+          NamedDecl *ObjectGetClass =
+            S.LookupSingleName(S.TUScope,
+                               &S.Context.Idents.get("object_getClass"),
+                               SourceLocation(), S.LookupOrdinaryName);
           if (ObjectGetClass)
             S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_use)
                 << FixItHint::CreateInsertion(OIRE->getBeginLoc(),
@@ -680,16 +684,14 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
   // Handle any placeholder expressions which made it here.
   if (E->hasPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(E);
-    if (result.isInvalid())
-      return ExprError();
+    if (result.isInvalid()) return ExprError();
     E = result.get();
   }
 
   // C++ [conv.lval]p1:
   //   A glvalue of a non-function, non-array type T can be
   //   converted to a prvalue.
-  if (!E->isGLValue())
-    return E;
+  if (!E->isGLValue()) return E;
 
   QualType T = E->getType();
   assert(!T.isNull() && "r-value conversion on typeless expression?");
@@ -721,15 +723,16 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
   if (getLangOpts().OpenCL &&
       !getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts()) &&
       T->isHalfType()) {
-    Diag(E->getExprLoc(), diag::err_opencl_half_load_store) << 0 << T;
+    Diag(E->getExprLoc(), diag::err_opencl_half_load_store)
+      << 0 << T;
     return ExprError();
   }
 
   CheckForNullPointerDereference(*this, E);
   if (const ObjCIsaExpr *OISA = dyn_cast<ObjCIsaExpr>(E->IgnoreParenCasts())) {
-    NamedDecl *ObjectGetClass =
-        LookupSingleName(TUScope, &Context.Idents.get("object_getClass"),
-                         SourceLocation(), LookupOrdinaryName);
+    NamedDecl *ObjectGetClass = LookupSingleName(TUScope,
+                                     &Context.Idents.get("object_getClass"),
+                                     SourceLocation(), LookupOrdinaryName);
     if (ObjectGetClass)
       Diag(E->getExprLoc(), diag::warn_objc_isa_use)
           << FixItHint::CreateInsertion(OISA->getBeginLoc(), "object_getClass(")
@@ -737,9 +740,10 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
                  SourceRange(OISA->getOpLoc(), OISA->getIsaMemberLoc()), ")");
     else
       Diag(E->getExprLoc(), diag::warn_objc_isa_use);
-  } else if (const ObjCIvarRefExpr *OIRE =
-                 dyn_cast<ObjCIvarRefExpr>(E->IgnoreParenCasts()))
-    DiagnoseDirectIsaAccess(*this, OIRE, SourceLocation(), /* Expr*/ nullptr);
+  }
+  else if (const ObjCIvarRefExpr *OIRE =
+            dyn_cast<ObjCIvarRefExpr>(E->IgnoreParenCasts()))
+    DiagnoseDirectIsaAccess(*this, OIRE, SourceLocation(), /* Expr*/nullptr);
 
   // C++ [conv.lval]p1:
   //   [...] If T is a non-class type, the type of the prvalue is the
@@ -763,8 +767,8 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
     return Res;
   E = Res.get();
 
-  // Loading a __weak object implicitly retains the value, so we need a cleanup
-  // to balance that.
+  // Loading a __weak object implicitly retains the value, so we need a cleanup to
+  // balance that.
   if (E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
     Cleanup.setExprNeedsCleanups(true);
 
@@ -973,8 +977,8 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) {
   // potentially potentially evaluated contexts.
   if (getLangOpts().CPlusPlus && E->isGLValue() && !isUnevaluatedContext()) {
     ExprResult Temp = PerformCopyInitialization(
-        InitializedEntity::InitializeTemporary(E->getType()), E->getExprLoc(),
-        E);
+                       InitializedEntity::InitializeTemporary(E->getType()),
+                                                E->getExprLoc(), E);
     if (Temp.isInvalid())
       return ExprError();
     E = Temp.get();
@@ -1170,10 +1174,8 @@ static bool handleComplexIntegerToFloatConversion(Sema &S, ExprResult &IntExpr,
                                                   QualType IntTy,
                                                   QualType ComplexTy,
                                                   bool SkipCast) {
-  if (IntTy->isComplexType() || IntTy->isRealFloatingType())
-    return true;
-  if (SkipCast)
-    return false;
+  if (IntTy->isComplexType() || IntTy->isRealFloatingType()) return true;
+  if (SkipCast) return false;
   if (IntTy->isIntegerType()) {
     QualType fpTy = ComplexTy->castAs<ComplexType>()->getElementType();
     IntExpr = S.ImpCastExprToType(IntExpr.get(), fpTy, CK_IntegralToFloating);
@@ -1249,8 +1251,8 @@ static QualType handleIntToFloatConversion(Sema &S, ExprResult &FloatExpr,
   if (IntTy->isIntegerType()) {
     if (ConvertInt)
       // Convert intExpr to the lhs floating point type.
-      IntExpr =
-          S.ImpCastExprToType(IntExpr.get(), FloatTy, CK_IntegralToFloating);
+      IntExpr = S.ImpCastExprToType(IntExpr.get(), FloatTy,
+                                    CK_IntegralToFloating);
     return FloatTy;
   }
 
@@ -1265,17 +1267,17 @@ static QualType handleIntToFloatConversion(Sema &S, ExprResult &FloatExpr,
 
   // float -> _Complex float
   if (ConvertFloat)
-    FloatExpr =
-        S.ImpCastExprToType(FloatExpr.get(), result, CK_FloatingRealToComplex);
+    FloatExpr = S.ImpCastExprToType(FloatExpr.get(), result,
+                                    CK_FloatingRealToComplex);
 
   return result;
 }
 
 /// Handle arithmethic conversion with floating point types.  Helper
 /// function of UsualArithmeticConversions()
-static QualType handleFloatConversion(Sema &S, ExprResult &LHS, ExprResult &RHS,
-                                      QualType LHSType, QualType RHSType,
-                                      bool IsCompAssign) {
+static QualType handleFloatConversion(Sema &S, ExprResult &LHS,
+                                      ExprResult &RHS, QualType LHSType,
+                                      QualType RHSType, bool IsCompAssign) {
   bool LHSFloat = LHSType->isRealFloatingType();
   bool RHSFloat = RHSType->isRealFloatingType();
 
@@ -1312,11 +1314,11 @@ static QualType handleFloatConversion(Sema &S, ExprResult &LHS, ExprResult &RHS,
 
     return handleIntToFloatConversion(S, LHS, RHS, LHSType, RHSType,
                                       /*ConvertFloat=*/!IsCompAssign,
-                                      /*ConvertInt=*/true);
+                                      /*ConvertInt=*/ true);
   }
   assert(RHSFloat);
   return handleIntToFloatConversion(S, RHS, LHS, RHSType, LHSType,
-                                    /*ConvertFloat=*/true,
+                                    /*ConvertFloat=*/ true,
                                     /*ConvertInt=*/!IsCompAssign);
 }
 
@@ -1361,7 +1363,7 @@ ExprResult doComplexIntegralCast(Sema &S, Expr *op, QualType toType) {
   return S.ImpCastExprToType(op, S.Context.getComplexType(toType),
                              CK_IntegralComplexCast);
 }
-} // namespace
+}
 
 /// Handle integer arithmetic conversions.  Helper function of
 /// UsualArithmeticConversions()
@@ -1406,7 +1408,7 @@ static QualType handleIntegerConversion(Sema &S, ExprResult &LHS,
     // on most 32-bit systems).  Use the unsigned type corresponding
     // to the signed type.
     QualType result =
-        S.Context.getCorrespondingUnsignedType(LHSSigned ? LHSType : RHSType);
+      S.Context.getCorrespondingUnsignedType(LHSSigned ? LHSType : RHSType);
     RHS = (*doRHSCast)(S, RHS.get(), result);
     if (!IsCompAssign)
       LHS = (*doLHSCast)(S, LHS.get(), result);
@@ -1427,8 +1429,8 @@ static QualType handleComplexIntConversion(Sema &S, ExprResult &LHS,
     QualType LHSEltType = LHSComplexInt->getElementType();
     QualType RHSEltType = RHSComplexInt->getElementType();
     QualType ScalarType =
-        handleIntegerConversion<doComplexIntegralCast, doComplexIntegralCast>(
-            S, LHS, RHS, LHSEltType, RHSEltType, IsCompAssign);
+      handleIntegerConversion<doComplexIntegralCast, doComplexIntegralCast>
+        (S, LHS, RHS, LHSEltType, RHSEltType, IsCompAssign);
 
     return S.Context.getComplexType(ScalarType);
   }
@@ -1436,10 +1438,11 @@ static QualType handleComplexIntConversion(Sema &S, ExprResult &LHS,
   if (LHSComplexInt) {
     QualType LHSEltType = LHSComplexInt->getElementType();
     QualType ScalarType =
-        handleIntegerConversion<doComplexIntegralCast, doIntegralCast>(
-            S, LHS, RHS, LHSEltType, RHSType, IsCompAssign);
+      handleIntegerConversion<doComplexIntegralCast, doIntegralCast>
+        (S, LHS, RHS, LHSEltType, RHSType, IsCompAssign);
     QualType ComplexType = S.Context.getComplexType(ScalarType);
-    RHS = S.ImpCastExprToType(RHS.get(), ComplexType, CK_IntegralRealToComplex);
+    RHS = S.ImpCastExprToType(RHS.get(), ComplexType,
+                              CK_IntegralRealToComplex);
 
     return ComplexType;
   }
@@ -1448,12 +1451,13 @@ static QualType handleComplexIntConversion(Sema &S, ExprResult &LHS,
 
   QualType RHSEltType = RHSComplexInt->getElementType();
   QualType ScalarType =
-      handleIntegerConversion<doIntegralCast, doComplexIntegralCast>(
-          S, LHS, RHS, LHSType, RHSEltType, IsCompAssign);
+    handleIntegerConversion<doIntegralCast, doComplexIntegralCast>
+      (S, LHS, RHS, LHSType, RHSEltType, IsCompAssign);
   QualType ComplexType = S.Context.getComplexType(ScalarType);
 
   if (!IsCompAssign)
-    LHS = S.ImpCastExprToType(LHS.get(), ComplexType, CK_IntegralRealToComplex);
+    LHS = S.ImpCastExprToType(LHS.get(), ComplexType,
+                              CK_IntegralRealToComplex);
   return ComplexType;
 }
 
@@ -1828,6 +1832,7 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
 //  Semantic Analysis for various Expression Types
 //===----------------------------------------------------------------------===//
 
+
 ExprResult Sema::ActOnGenericSelectionExpr(
     SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc,
     bool PredicateIsExpr, void *ControllingExprOrType,
@@ -1835,10 +1840,10 @@ ExprResult Sema::ActOnGenericSelectionExpr(
   unsigned NumAssocs = ArgTypes.size();
   assert(NumAssocs == ArgExprs.size());
 
-  TypeSourceInfo **Types = new TypeSourceInfo *[NumAssocs];
+  TypeSourceInfo **Types = new TypeSourceInfo*[NumAssocs];
   for (unsigned i = 0; i < NumAssocs; ++i) {
     if (ArgTypes[i])
-      (void)GetTypeFromParser(ArgTypes[i], &Types[i]);
+      (void) GetTypeFromParser(ArgTypes[i], &Types[i]);
     else
       Types[i] = nullptr;
   }
@@ -1856,7 +1861,7 @@ ExprResult Sema::ActOnGenericSelectionExpr(
   ExprResult ER = CreateGenericSelectionExpr(
       KeyLoc, DefaultLoc, RParenLoc, PredicateIsExpr, ControllingExprOrType,
       llvm::ArrayRef(Types, NumAssocs), ArgExprs);
-  delete[] Types;
+  delete [] Types;
   return ER;
 }
 
@@ -2005,17 +2010,19 @@ ExprResult Sema::CreateGenericSelectionExpr(
 
         // C11 6.5.1.1p2 "No two generic associations in the same generic
         // selection shall specify compatible types."
-        for (unsigned j = i + 1; j < NumAssocs; ++j)
+        for (unsigned j = i+1; j < NumAssocs; ++j)
           if (Types[j] && !Types[j]->getType()->isDependentType() &&
               areTypesCompatibleForGeneric(Context, Types[i]->getType(),
                                            Types[j]->getType())) {
             Diag(Types[j]->getTypeLoc().getBeginLoc(),
                  diag::err_assoc_compatible_types)
-                << Types[j]->getTypeLoc().getSourceRange()
-                << Types[j]->getType() << Types[i]->getType();
-            Diag(Types[i]->getTypeLoc().getBeginLoc(), diag::note_compat_assoc)
-                << Types[i]->getTypeLoc().getSourceRange()
-                << Types[i]->getType();
+              << Types[j]->getTypeLoc().getSourceRange()
+              << Types[j]->getType()
+              << Types[i]->getType();
+            Diag(Types[i]->getTypeLoc().getBeginLoc(),
+                 diag::note_compat_assoc)
+              << Types[i]->getTypeLoc().getSourceRange()
+              << Types[i]->getType();
             TypeErrorFound = true;
           }
       }
@@ -2084,8 +2091,10 @@ ExprResult Sema::CreateGenericSelectionExpr(
     Diag(SR.getBegin(), diag::err_generic_sel_multi_match)
         << SR << P.second << (unsigned)CompatIndices.size();
     for (unsigned I : CompatIndices) {
-      Diag(Types[I]->getTypeLoc().getBeginLoc(), diag::note_compat_assoc)
-          << Types[I]->getTypeLoc().getSourceRange() << Types[I]->getType();
+      Diag(Types[I]->getTypeLoc().getBeginLoc(),
+           diag::note_compat_assoc)
+        << Types[I]->getTypeLoc().getSourceRange()
+        << Types[I]->getType();
     }
     return ExprError();
   }
@@ -2106,7 +2115,8 @@ ExprResult Sema::CreateGenericSelectionExpr(
   // then the result expression of the generic selection is the expression
   // in that generic association. Otherwise, the result expression of the
   // generic selection is the expression in the default generic association."
-  unsigned ResultIndex = CompatIndices.size() ? CompatIndices[0] : DefaultIndex;
+  unsigned ResultIndex =
+    CompatIndices.size() ? CompatIndices[0] : DefaultIndex;
 
   if (ControllingExpr) {
     return GenericSelectionExpr::Create(
@@ -2180,7 +2190,7 @@ static SourceLocation getUDSuffixLoc(Sema &S, SourceLocation TokLoc,
 static ExprResult BuildCookedLiteralOperatorCall(Sema &S, Scope *Scope,
                                                  IdentifierInfo *UDSuffix,
                                                  SourceLocation UDSuffixLoc,
-                                                 ArrayRef<Expr *> Args,
+                                                 ArrayRef<Expr*> Args,
                                                  SourceLocation LitEndLoc) {
   assert(Args.size() <= 2 && "too many arguments for literal operator");
 
@@ -2192,7 +2202,7 @@ static ExprResult BuildCookedLiteralOperatorCall(Sema &S, Scope *Scope,
   }
 
   DeclarationName OpName =
-      S.Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix);
+    S.Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix);
   DeclarationNameInfo OpNameInfo(OpName, UDSuffixLoc);
   OpNameInfo.setCXXLiteralOperatorNameLoc(UDSuffixLoc);
 
@@ -2284,8 +2294,8 @@ Sema::ExpandFunctionLocalPredefinedMacros(ArrayRef<Token> Toks) {
   return ExpandedToks;
 }
 
-ExprResult Sema::ActOnStringLiteral(ArrayRef<Token> StringToks,
-                                    Scope *UDLScope) {
+ExprResult
+Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) {
   assert(!StringToks.empty() && "Must have at least one string!");
 
   // StringToks needs backing storage as it doesn't hold array elements itself
@@ -2366,8 +2376,8 @@ ExprResult Sema::ActOnStringLiteral(ArrayRef<Token> StringToks,
   // We're building a user-defined literal.
   IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix());
   SourceLocation UDSuffixLoc =
-      getUDSuffixLoc(*this, StringTokLocs[Literal.getUDSuffixToken()],
-                     Literal.getUDSuffixOffset());
+    getUDSuffixLoc(*this, StringTokLocs[Literal.getUDSuffixToken()],
+                   Literal.getUDSuffixOffset());
 
   // Make sure we're allowed user-defined literals here.
   if (!UDLScope)
@@ -2378,11 +2388,13 @@ ExprResult Sema::ActOnStringLiteral(ArrayRef<Token> StringToks,
   QualType SizeType = Context.getSizeType();
 
   DeclarationName OpName =
-      Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix);
+    Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix);
   DeclarationNameInfo OpNameInfo(OpName, UDSuffixLoc);
   OpNameInfo.setCXXLiteralOperatorNameLoc(UDSuffixLoc);
 
-  QualType ArgTy[] = {Context.getArrayDecayedType(StrTy), SizeType};
+  QualType ArgTy[] = {
+    Context.getArrayDecayedType(StrTy), SizeType
+  };
 
   LookupResult R(*this, OpName, UDSuffixLoc, LookupOrdinaryName);
   switch (LookupLiteralOperator(UDLScope, R, ArgTy,
@@ -2392,9 +2404,9 @@ ExprResult Sema::ActOnStringLiteral(ArrayRef<Token> StringToks,
 
   case LOLR_Cooked: {
     llvm::APInt Len(Context.getIntWidth(SizeType), Literal.GetNumStringChars());
-    IntegerLiteral *LenArg =
-        IntegerLiteral::Create(Context, Len, SizeType, StringTokLocs[0]);
-    Expr *Args[] = {Lit, LenArg};
+    IntegerLiteral *LenArg = IntegerLiteral::Create(Context, Len, SizeType,
+                                                    StringTokLocs[0]);
+    Expr *Args[] = { Lit, LenArg };
 
     return BuildLiteralOperatorCall(R, OpNameInfo, Args, StringTokLocs.back());
   }
@@ -2416,8 +2428,7 @@ ExprResult Sema::ActOnStringLiteral(ArrayRef<Token> StringToks,
     llvm::APSInt Value(CharBits, CharIsUnsigned);
 
     TemplateArgument TypeArg(CharTy);
-    TemplateArgumentLocInfo TypeArgInfo(
-        Context.getTrivialTypeSourceInfo(CharTy));
+    TemplateArgumentLocInfo TypeArgInfo(Context.getTrivialTypeSourceInfo(CharTy));
     ExplicitArgs.addArgument(TemplateArgumentLoc(TypeArg, TypeArgInfo));
 
     SourceLocation Loc = StringTokLocs.back();
@@ -2438,9 +2449,10 @@ ExprResult Sema::ActOnStringLiteral(ArrayRef<Token> StringToks,
   llvm_unreachable("unexpected literal operator lookup result");
 }
 
-DeclRefExpr *Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
-                                    SourceLocation Loc,
-                                    const CXXScopeSpec *SS) {
+DeclRefExpr *
+Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
+                       SourceLocation Loc,
+                       const CXXScopeSpec *SS) {
   DeclarationNameInfo NameInfo(D->getDeclName(), Loc);
   return BuildDeclRefExpr(D, Ty, VK, NameInfo, SS);
 }
@@ -2604,10 +2616,11 @@ static bool diagnoseFunctionLikeMacro(Sema &SemaRef, DeclarationName Name,
   return false;
 }
 
-void Sema::DecomposeUnqualifiedId(
-    const UnqualifiedId &Id, TemplateArgumentListInfo &Buffer,
-    DeclarationNameInfo &NameInfo,
-    const TemplateArgumentListInfo *&TemplateArgs) {
+void
+Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id,
+                             TemplateArgumentListInfo &Buffer,
+                             DeclarationNameInfo &NameInfo,
+                             const TemplateArgumentListInfo *&TemplateArgs) {
   if (Id.getKind() == UnqualifiedIdKind::IK_TemplateId) {
     Buffer.setLAngleLoc(Id.TemplateId->LAngleLoc);
     Buffer.setRAngleLoc(Id.TemplateId->RAngleLoc);
@@ -2764,14 +2777,15 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
                                  OverloadCandidateSet::CSK_Normal);
         OverloadCandidateSet::iterator Best;
         for (NamedDecl *CD : Corrected) {
-          if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(CD))
-            AddTemplateOverloadCandidate(FTD,
-                                         DeclAccessPair::make(FTD, AS_none),
-                                         ExplicitTemplateArgs, Args, OCS);
+          if (FunctionTemplateDecl *FTD =
+                   dyn_cast<FunctionTemplateDecl>(CD))
+            AddTemplateOverloadCandidate(
+                FTD, DeclAccessPair::make(FTD, AS_none), ExplicitTemplateArgs,
+                Args, OCS);
           else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(CD))
             if (!ExplicitTemplateArgs || ExplicitTemplateArgs->size() == 0)
-              AddOverloadCandidate(FD, DeclAccessPair::make(FD, AS_none), Args,
-                                   OCS);
+              AddOverloadCandidate(FD, DeclAccessPair::make(FD, AS_none),
+                                   Args, OCS);
         }
         switch (OCS.BestViableFunction(*this, R.getNameLoc(), Best)) {
         case OR_Success:
@@ -2789,8 +2803,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
         CXXRecordDecl *Record =
             Corrected.getCorrectionSpecifier().getAsRecordDecl();
         if (!Record)
-          Record =
-              cast<CXXRecordDecl>(ND->getDeclContext()->getRedeclContext());
+          Record = cast<CXXRecordDecl>(
+              ND->getDeclContext()->getRedeclContext());
         R.setNamingClass(Record);
       }
 
@@ -3002,8 +3016,7 @@ ExprResult Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
   if (R.empty() && HasTrailingLParen && II &&
       getLangOpts().implicitFunctionsAllowed()) {
     NamedDecl *D = ImplicitlyDefineFunction(NameLoc, *II, S);
-    if (D)
-      R.addDecl(D);
+    if (D) R.addDecl(D);
   }
 
   // Determine whether this name might be a candidate for
@@ -3129,7 +3142,7 @@ ExprResult Sema::BuildQualifiedDeclarationNameExpr(
       if (CD->isInvalidDecl() || CD->isBeingDefined())
         return ExprError();
     Diag(NameInfo.getLoc(), diag::err_no_member)
-        << NameInfo.getName() << DC << SS.getRange();
+      << NameInfo.getName() << DC << SS.getRange();
     return ExprError();
   }
 
@@ -3294,15 +3307,14 @@ ExprResult Sema::PerformObjectMemberConversion(Expr *From,
     // Otherwise build the appropriate casts.
     if (IsDerivedFrom(FromLoc, FromRecordType, QRecordType)) {
       CXXCastPath BasePath;
-      if (CheckDerivedToBaseConversion(FromRecordType, QRecordType, FromLoc,
-                                       FromRange, &BasePath))
+      if (CheckDerivedToBaseConversion(FromRecordType, QRecordType,
+                                       FromLoc, FromRange, &BasePath))
         return ExprError();
 
       if (PointerConversions)
         QType = Context.getPointerType(QType);
-      From = ImpCastExprToType(From, QType, CK_UncheckedDerivedToBase, VK,
-                               &BasePath)
-                 .get();
+      From = ImpCastExprToType(From, QType, CK_UncheckedDerivedToBase,
+                               VK, &BasePath).get();
 
       FromType = QType;
       FromRecordType = QRecordType;
@@ -3315,8 +3327,8 @@ ExprResult Sema::PerformObjectMemberConversion(Expr *From,
   }
 
   CXXCastPath BasePath;
-  if (CheckDerivedToBaseConversion(FromRecordType, DestRecordType, FromLoc,
-                                   FromRange, &BasePath,
+  if (CheckDerivedToBaseConversion(FromRecordType, DestRecordType,
+                                   FromLoc, FromRange, &BasePath,
                                    /*IgnoreAccess=*/true))
     return ExprError();
 
@@ -3382,6 +3394,7 @@ bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS,
   return true;
 }
 
+
 /// Diagnoses obvious problems with the use of the given declaration
 /// as an expression.  This is only actually called for lookups that
 /// were not overloaded, and it doesn't promise that the declaration
@@ -3787,7 +3800,7 @@ ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) {
   else if (Literal.isUTF32())
     Ty = Context.Char32Ty; // U'x' -> char32_t in C11 and C++11.
   else if (!getLangOpts().CPlusPlus || Literal.isMultiChar())
-    Ty = Context.IntTy; // 'x' -> int in C, 'wxyz' -> int in C++.
+    Ty = Context.IntTy;   // 'x' -> int in C, 'wxyz' -> int in C++.
   else
     Ty = Context.CharTy; // 'x' -> char in C++;
                          // u8'x' -> char in C11-C17 and in C++ without char8_t.
@@ -3802,8 +3815,8 @@ ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) {
   else if (Literal.isUTF8())
     Kind = CharacterLiteralKind::UTF8;
 
-  Expr *Lit = new (Context)
-      CharacterLiteral(Literal.getValue(), Kind, Ty, Tok.getLocation());
+  Expr *Lit = new (Context) CharacterLiteral(Literal.getValue(), Kind, Ty,
+                                             Tok.getLocation());
 
   if (Literal.getUDSuffix().empty())
     return Lit;
@@ -3811,7 +3824,7 @@ ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) {
   // We're building a user-defined literal.
   IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix());
   SourceLocation UDSuffixLoc =
-      getUDSuffixLoc(*this, Tok.getLocation(), Literal.getUDSuffixOffset());
+    getUDSuffixLoc(*this, Tok.getLocation(), Literal.getUDSuffixOffset());
 
   // Make sure we're allowed user-defined literals here.
   if (!UDLScope)
@@ -3942,7 +3955,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
     // We're building a user-defined literal.
     const IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix());
     SourceLocation UDSuffixLoc =
-        getUDSuffixLoc(*this, Tok.getLocation(), Literal.getUDSuffixOffset());
+      getUDSuffixLoc(*this, Tok.getLocation(), Literal.getUDSuffixOffset());
 
     // Make sure we're allowed user-defined literals here.
     if (!UDLScope)
@@ -3962,7 +3975,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
     }
 
     DeclarationName OpName =
-        Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix);
+      Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix);
     DeclarationNameInfo OpNameInfo(OpName, UDSuffixLoc);
     OpNameInfo.setCXXLiteralOperatorNameLoc(UDSuffixLoc);
 
@@ -4056,8 +4069,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
       }
     }
 
-    if (Literal.isUnsigned)
-      Ty = Context.getCorrespondingUnsignedType(Ty);
+    if (Literal.isUnsigned) Ty = Context.getCorrespondingUnsignedType(Ty);
 
     bool isSigned = !Literal.isUnsigned;
     unsigned scale = Context.getFixedPointScale(Ty);
@@ -4081,7 +4093,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
                                               Tok.getLocation(), scale);
   } else if (Literal.isFloatingLiteral()) {
     QualType Ty;
-    if (Literal.isHalf) {
+    if (Literal.isHalf){
       if (getLangOpts().HLSL ||
           getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts()))
         Ty = Context.HalfTy;
@@ -4256,7 +4268,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
         // Does it fit in a unsigned int?
         if (ResultVal.isIntN(IntSize)) {
           // Does it fit in a signed int?
-          if (!Literal.isUnsigned && ResultVal[IntSize - 1] == 0)
+          if (!Literal.isUnsigned && ResultVal[IntSize-1] == 0)
             Ty = Context.IntTy;
           else if (AllowUnsigned)
             Ty = Context.UnsignedIntTy;
@@ -4271,7 +4283,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
         // Does it fit in a unsigned long?
         if (ResultVal.isIntN(LongSize)) {
           // Does it fit in a signed long?
-          if (!Literal.isUnsigned && ResultVal[LongSize - 1] == 0)
+          if (!Literal.isUnsigned && ResultVal[LongSize-1] == 0)
             Ty = Context.LongTy;
           else if (AllowUnsigned)
             Ty = Context.UnsignedLongTy;
@@ -4304,9 +4316,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
           // Does it fit in a signed long long?
           // To be compatible with MSVC, hex integer literals ending with the
           // LL or i64 suffix are always signed in Microsoft mode.
-          if (!Literal.isUnsigned &&
-              (ResultVal[LongLongSize - 1] == 0 ||
-               (getLangOpts().MSVCCompat && Literal.isLongLong)))
+          if (!Literal.isUnsigned && (ResultVal[LongLongSize-1] == 0 ||
+              (getLangOpts().MSVCCompat && Literal.isLongLong)))
             Ty = Context.LongLongTy;
           else if (AllowUnsigned)
             Ty = Context.UnsignedLongLongTy;
@@ -4345,8 +4356,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
 
   // If this is an imaginary literal, create the ImaginaryLiteral wrapper.
   if (Literal.isImaginary) {
-    Res = new (Context)
-        ImaginaryLiteral(Res, Context.getComplexType(Res->getType()));
+    Res = new (Context) ImaginaryLiteral(Res,
+                                        Context.getComplexType(Res->getType()));
 
     // In C++, this is a GNU extension. In C, it's a C2y extension.
     if (getLangOpts().CPlusPlus)
@@ -4374,7 +4385,8 @@ static bool CheckVecStepTraitOperandType(Sema &S, QualType T,
   // Every built-in scalar type (OpenCL 1.1 6.1.1) is either an arithmetic
   // type (C99 6.2.5p18) or void.
   if (!(T->isArithmeticType() || T->isVoidType() || T->isVectorType())) {
-    S.Diag(Loc, diag::err_vecstep_non_scalar_vector_type) << T << ArgRange;
+    S.Diag(Loc, diag::err_vecstep_non_scalar_vector_type)
+      << T << ArgRange;
     return true;
   }
 
@@ -4457,7 +4469,8 @@ static bool CheckObjCTraitOperandConstraints(Sema &S, QualType T,
   // runtime doesn't allow it.
   if (!S.LangOpts.ObjCRuntime.allowsSizeofAlignof() && T->isObjCObjectType()) {
     S.Diag(Loc, diag::err_sizeof_nonfragile_interface)
-        << T << (TraitKind == UETT_SizeOf) << ArgRange;
+      << T << (TraitKind == UETT_SizeOf)
+      << ArgRange;
     return true;
   }
 
@@ -4477,9 +4490,9 @@ static void warnOnSizeofOnArrayDecay(Sema &S, SourceLocation Loc, QualType T,
   if (!ICE || ICE->getCastKind() != CK_ArrayToPointerDecay)
     return;
 
-  S.Diag(Loc, diag::warn_sizeof_array_decay)
-      << ICE->getSourceRange() << ICE->getType()
-      << ICE->getSubExpr()->getType();
+  S.Diag(Loc, diag::warn_sizeof_array_decay) << ICE->getSourceRange()
+                                             << ICE->getType()
+                                             << ICE->getSubExpr()->getType();
 }
 
 bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,
@@ -4504,7 +4517,8 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,
   // used to build SFINAE gadgets.
   // FIXME: Should we consider instantiation-dependent operands to 'alignof'?
   if (IsUnevaluatedOperand && !inTemplateInstantiation() &&
-      !E->isInstantiationDependent() && !E->getType()->isVariableArrayType() &&
+      !E->isInstantiationDependent() &&
+      !E->getType()->isVariableArrayType() &&
       E->HasSideEffects(Context, false))
     Diag(E->getExprLoc(), diag::warn_side_effects_unevaluated_context);
 
@@ -4582,7 +4596,8 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,
         QualType OType = PVD->getOriginalType();
         QualType Type = PVD->getType();
         if (Type->isPointerType() && OType->isArrayType()) {
-          Diag(E->getExprLoc(), diag::warn_sizeof_array_param) << Type << OType;
+          Diag(E->getExprLoc(), diag::warn_sizeof_array_param)
+            << Type << OType;
           Diag(PVD->getLocation(), diag::note_declared_at);
         }
       }
@@ -4609,7 +4624,7 @@ static bool CheckAlignOfExpr(Sema &S, Expr *E, UnaryExprOrTypeTrait ExprKind) {
 
   if (E->getObjectKind() == OK_BitField) {
     S.Diag(E->getExprLoc(), diag::err_sizeof_alignof_typeof_bitfield)
-        << 1 << E->getSourceRange();
+       << 1 << E->getSourceRange();
     return true;
   }
 
@@ -4643,7 +4658,7 @@ static bool CheckAlignOfExpr(Sema &S, Expr *E, UnaryExprOrTypeTrait ExprKind) {
     // definition if we can find a member of it.
     if (!FD->getParent()->isCompleteDefinition()) {
       S.Diag(E->getExprLoc(), diag::err_alignof_member_of_incomplete_type)
-          << E->getSourceRange();
+        << E->getSourceRange();
       return true;
     }
 
@@ -4926,8 +4941,9 @@ ExprResult Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
       ExprKind, TInfo, Context.getSizeType(), OpLoc, R.getEnd());
 }
 
-ExprResult Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
-                                                UnaryExprOrTypeTrait ExprKind) {
+ExprResult
+Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
+                                     UnaryExprOrTypeTrait ExprKind) {
   ExprResult PE = CheckPlaceholderExpr(E);
   if (PE.isInvalid())
     return ExprError();
@@ -4943,9 +4959,9 @@ ExprResult Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
   } else if (ExprKind == UETT_VecStep) {
     isInvalid = CheckVecStepExpr(E);
   } else if (ExprKind == UETT_OpenMPRequiredSimdAlign) {
-    Diag(E->getExprLoc(), diag::err_openmp_default_simd_align_expr);
-    isInvalid = true;
-  } else if (E->refersToBitField()) { // C99 6.5.3.4p1.
+      Diag(E->getExprLoc(), diag::err_openmp_default_simd_align_expr);
+      isInvalid = true;
+  } else if (E->refersToBitField()) {  // C99 6.5.3.4p1.
     Diag(E->getExprLoc(), diag::err_sizeof_alignof_typeof_bitfield) << 0;
     isInvalid = true;
   } else if (ExprKind == UETT_VectorElements || ExprKind == UETT_SizeOf ||
@@ -4959,8 +4975,7 @@ ExprResult Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
   if ((ExprKind == UETT_SizeOf || ExprKind == UETT_CountOf) &&
       E->getType()->isVariableArrayType()) {
     PE = TransformToPotentiallyEvaluated(E);
-    if (PE.isInvalid())
-      return ExprError();
+    if (PE.isInvalid()) return ExprError();
     E = PE.get();
   }
 
@@ -4969,17 +4984,16 @@ ExprResult Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
       ExprKind, E, Context.getSizeType(), OpLoc, E->getSourceRange().getEnd());
 }
 
-ExprResult Sema::ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc,
-                                               UnaryExprOrTypeTrait ExprKind,
-                                               bool IsType, void *TyOrEx,
-                                               SourceRange ArgRange) {
+ExprResult
+Sema::ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc,
+                                    UnaryExprOrTypeTrait ExprKind, bool IsType,
+                                    void *TyOrEx, SourceRange ArgRange) {
   // If error parsing type, ignore.
-  if (!TyOrEx)
-    return ExprError();
+  if (!TyOrEx) return ExprError();
 
   if (IsType) {
     TypeSourceInfo *TInfo;
-    (void)GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrEx), &TInfo);
+    (void) GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrEx), &TInfo);
     return CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, ArgRange);
   }
 
@@ -5026,37 +5040,33 @@ static QualType CheckRealImagOperand(Sema &S, ExprResult &V, SourceLocation Loc,
 
   // Test for placeholders.
   ExprResult PR = S.CheckPlaceholderExpr(V.get());
-  if (PR.isInvalid())
-    return QualType();
+  if (PR.isInvalid()) return QualType();
   if (PR.get() != V.get()) {
     V = PR;
     return CheckRealImagOperand(S, V, Loc, IsReal);
   }
 
   // Reject anything else.
-  S.Diag(Loc, diag::err_realimag_invalid_type)
-      << V.get()->getType() << (IsReal ? "__real" : "__imag");
+  S.Diag(Loc, diag::err_realimag_invalid_type) << V.get()->getType()
+    << (IsReal ? "__real" : "__imag");
   return QualType();
 }
 
-ExprResult Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
-                                     tok::TokenKind Kind, Expr *Input) {
+
+
+ExprResult
+Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
+                          tok::TokenKind Kind, Expr *Input) {
   UnaryOperatorKind Opc;
   switch (Kind) {
-  default:
-    llvm_unreachable("Unknown unary op!");
-  case tok::plusplus:
-    Opc = UO_PostInc;
-    break;
-  case tok::minusminus:
-    Opc = UO_PostDec;
-    break;
+  default: llvm_unreachable("Unknown unary op!");
+  case tok::plusplus:   Opc = UO_PostInc; break;
+  case tok::minusminus: Opc = UO_PostDec; break;
   }
 
   // Since this might is a postfix expression, get rid of ParenListExprs.
   ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Input);
-  if (Result.isInvalid())
-    return ExprError();
+  if (Result.isInvalid()) return ExprError();
   Input = Result.get();
 
   return BuildUnaryOp(S, OpLoc, Opc, Input);
@@ -5065,7 +5075,8 @@ ExprResult Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
 /// Diagnose if arithmetic on the given ObjC pointer is illegal.
 ///
 /// \return true on error
-static bool checkArithmeticOnObjCPointer(Sema &S, SourceLocation opLoc,
+static bool checkArithmeticOnObjCPointer(Sema &S,
+                                         SourceLocation opLoc,
                                          Expr *op) {
   assert(op->getType()->isObjCObjectPointerType());
   if (S.LangOpts.ObjCRuntime.allowsPointerArithmetic() &&
@@ -5073,8 +5084,8 @@ static bool checkArithmeticOnObjCPointer(Sema &S, SourceLocation opLoc,
     return false;
 
   S.Diag(opLoc, diag::err_arithmetic_nonfragile_interface)
-      << op->getType()->castAs<ObjCObjectPointerType>()->getPointeeType()
-      << op->getSourceRange();
+    << op->getType()->castAs<ObjCObjectPointerType>()->getPointeeType()
+    << op->getSourceRange();
   return true;
 }
 
@@ -5480,9 +5491,9 @@ void Sema::CheckSubscriptAccessOfNoDeref(const ArraySubscriptExpr *E) {
   }
 }
 
-ExprResult Sema::CreateBuiltinArraySubscriptExpr(Expr *Base,
-                                                 SourceLocation LLoc, Expr *Idx,
-                                                 SourceLocation RLoc) {
+ExprResult
+Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
+                                      Expr *Idx, SourceLocation RLoc) {
   Expr *LHSExp = Base;
   Expr *RHSExp = Idx;
 
@@ -5529,7 +5540,7 @@ ExprResult Sema::CreateBuiltinArraySubscriptExpr(Expr *Base,
     IndexExpr = RHSExp;
     ResultType = PTy->getPointeeType();
   } else if (const ObjCObjectPointerType *PTy =
-                 LHSTy->getAs<ObjCObjectPointerType>()) {
+               LHSTy->getAs<ObjCObjectPointerType>()) {
     BaseExpr = LHSExp;
     IndexExpr = RHSExp;
 
@@ -5541,19 +5552,19 @@ ExprResult Sema::CreateBuiltinArraySubscriptExpr(Expr *Base,
 
     ResultType = PTy->getPointeeType();
   } else if (const PointerType *PTy = RHSTy->getAs<PointerType>()) {
-    // Handle the uncommon case of "123[Ptr]".
+     // Handle the uncommon case of "123[Ptr]".
     BaseExpr = RHSExp;
     IndexExpr = LHSExp;
     ResultType = PTy->getPointeeType();
   } else if (const ObjCObjectPointerType *PTy =
-                 RHSTy->getAs<ObjCObjectPointerType>()) {
-    // Handle the uncommon case of "123[Ptr]".
+               RHSTy->getAs<ObjCObjectPointerType>()) {
+     // Handle the uncommon case of "123[Ptr]".
     BaseExpr = RHSExp;
     IndexExpr = LHSExp;
     ResultType = PTy->getPointeeType();
     if (!LangOpts.isSubscriptPointerArithmetic()) {
       Diag(LLoc, diag::err_subscript_nonfragile_interface)
-          << ResultType << BaseExpr->getSourceRange();
+        << ResultType << BaseExpr->getSourceRange();
       return ExprError();
     }
   } else if (LHSTy->isSubscriptableVectorType()) {
@@ -5597,8 +5608,7 @@ ExprResult Sema::CreateBuiltinArraySubscriptExpr(Expr *Base,
     Diag(LHSExp->getBeginLoc(), diag::ext_subscript_non_lvalue)
         << LHSExp->getSourceRange();
     LHSExp = ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy),
-                               CK_ArrayToPointerDecay)
-                 .get();
+                               CK_ArrayToPointerDecay).get();
     LHSTy = LHSExp->getType();
 
     BaseExpr = LHSExp;
@@ -5609,8 +5619,7 @@ ExprResult Sema::CreateBuiltinArraySubscriptExpr(Expr *Base,
     Diag(RHSExp->getBeginLoc(), diag::ext_subscript_non_lvalue)
         << RHSExp->getSourceRange();
     RHSExp = ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy),
-                               CK_ArrayToPointerDecay)
-                 .get();
+                               CK_ArrayToPointerDecay).get();
     RHSTy = RHSExp->getType();
 
     BaseExpr = RHSExp;
@@ -5618,7 +5627,7 @@ ExprResult Sema::CreateBuiltinArraySubscriptExpr(Expr *Base,
     ResultType = RHSTy->castAs<PointerType>()->getPointeeType();
   } else {
     return ExprError(Diag(LLoc, diag::err_typecheck_subscript_value)
-                     << LHSExp->getSourceRange() << RHSExp->getSourceRange());
+       << LHSExp->getSourceRange() << RHSExp->getSourceRange());
   }
   // C99 6.5.2.1p1
   if (!IndexExpr->getType()->isIntegerType() && !IndexExpr->isTypeDependent())
@@ -5647,7 +5656,8 @@ ExprResult Sema::CreateBuiltinArraySubscriptExpr(Expr *Base,
 
   if (ResultType->isVoidType() && !getLangOpts().CPlusPlus) {
     // GNU extension: subscripting on pointer to void
-    Diag(LLoc, diag::ext_gnu_subscript_void_type) << BaseExpr->getSourceRange();
+    Diag(LLoc, diag::ext_gnu_subscript_void_type)
+      << BaseExpr->getSourceRange();
 
     // C forbids expressions of unqualified void type from being l-values.
     // See IsCForbiddenLValueType.
@@ -6113,7 +6123,7 @@ class FunctionCallCCC final : public FunctionCallFilterCCC {
 private:
   const IdentifierInfo *const FunctionName;
 };
-} // namespace
+}
 
 static TypoCorrection TryTypoCorrectionForCall(Sema &S, Expr *Fn,
                                                FunctionDecl *FDecl,
@@ -6173,12 +6183,13 @@ static bool isParenthetizedAndQualifiedAddressOfExpr(Expr *Fn) {
   return false;
 }
 
-bool Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
-                                   FunctionDecl *FDecl,
-                                   const FunctionProtoType *Proto,
-                                   ArrayRef<Expr *> Args,
-                                   SourceLocation RParenLoc,
-                                   bool IsExecConfig) {
+bool
+Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
+                              FunctionDecl *FDecl,
+                              const FunctionProtoType *Proto,
+                              ArrayRef<Expr *> Args,
+                              SourceLocation RParenLoc,
+                              bool IsExecConfig) {
   // Bail out early if calling a builtin with custom typechecking.
   // For HLSL builtin aliases, argument conversion is still needed because
   // overload resolution may have selected a conversion sequence (e.g.,
@@ -6201,9 +6212,9 @@ bool Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
   bool Invalid = false;
   unsigned MinArgs = FDecl ? FDecl->getMinRequiredArguments() : NumParams;
   unsigned FnKind = Fn->getType()->isBlockPointerType()
-                        ? 1                 /* block */
-                        : (IsExecConfig ? 3 /* kernel function (exec config) */
-                                        : 0 /* function */);
+                       ? 1 /* block */
+                       : (IsExecConfig ? 3 /* kernel function (exec config) */
+                                       : 0 /* function */);
 
   // If too few arguments are available (and we don't have default
   // arguments for the remaining parameters), don't make the call.
@@ -6342,12 +6353,12 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl,
 
       // Strip the unbridged-cast placeholder expression off, if applicable.
       bool CFAudited = false;
-      if (Arg->getType() == Context.ARCUnbridgedCastTy && FDecl &&
-          FDecl->hasAttr<CFAuditedTransferAttr>() &&
+      if (Arg->getType() == Context.ARCUnbridgedCastTy &&
+          FDecl && FDecl->hasAttr<CFAuditedTransferAttr>() &&
           (!Param || !Param->hasAttr<CFConsumedAttr>()))
         Arg = ObjC().stripARCUnbridgedCast(Arg);
-      else if (getLangOpts().ObjCAutoRefCount && FDecl &&
-               FDecl->hasAttr<CFAuditedTransferAttr>() &&
+      else if (getLangOpts().ObjCAutoRefCount &&
+               FDecl && FDecl->hasAttr<CFAuditedTransferAttr>() &&
                (!Param || !Param->hasAttr<CFConsumedAttr>()))
         CFAudited = true;
 
@@ -6425,7 +6436,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl,
         AllArgs.push_back(arg.get());
       }
 
-      // Otherwise do argument promotion, (C99 6.5.2.2p7).
+    // Otherwise do argument promotion, (C99 6.5.2.2p7).
     } else {
       for (Expr *A : Args.slice(ArgIx)) {
         ExprResult Arg = DefaultVariadicArgumentPromotion(A, CallType, FDecl);
@@ -6447,11 +6458,13 @@ static void DiagnoseCalleeStaticArrayParam(Sema &S, ParmVarDecl *PVD) {
     TL = DTL.getOriginalLoc();
   if (ArrayTypeLoc ATL = TL.getAs<ArrayTypeLoc>())
     S.Diag(PVD->getLocation(), diag::note_callee_static_array)
-        << ATL.getLocalSourceRange();
+      << ATL.getLocalSourceRange();
 }
 
-void Sema::CheckStaticArrayArgument(SourceLocation CallLoc, ParmVarDecl *Param,
-                                    const Expr *ArgExpr) {
+void
+Sema::CheckStaticArrayArgument(SourceLocation CallLoc,
+                               ParmVarDecl *Param,
+                               const Expr *ArgExpr) {
   // Static array parameters are not supported in C++.
   if (!Param || getLangOpts().CPlusPlus)
     return;
@@ -6462,7 +6475,8 @@ void Sema::CheckStaticArrayArgument(SourceLocation CallLoc, ParmVarDecl *Param,
   if (!AT || AT->getSizeModifier() != ArraySizeModifier::Static)
     return;
 
-  if (ArgExpr->isNullPointerConstant(Context, Expr::NPC_NeverValueDependent)) {
+  if (ArgExpr->isNullPointerConstant(Context,
+                                     Expr::NPC_NeverValueDependent)) {
     Diag(CallLoc, diag::warn_null_arg) << ArgExpr->getSourceRange();
     DiagnoseCalleeStaticArrayParam(*this, Param);
     return;
@@ -6473,7 +6487,7 @@ void Sema::CheckStaticArrayArgument(SourceLocation CallLoc, ParmVarDecl *Param,
     return;
 
   const ConstantArrayType *ArgCAT =
-      Context.getAsConstantArrayType(ArgExpr->IgnoreParenCasts()->getType());
+    Context.getAsConstantArrayType(ArgExpr->IgnoreParenCasts()->getType());
   if (!ArgCAT)
     return;
 
@@ -6509,21 +6523,23 @@ static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *fn);
 static bool isPlaceholderToRemoveAsArg(QualType type) {
   // Placeholders are never sugared.
   const BuiltinType *placeholder = dyn_cast<BuiltinType>(type);
-  if (!placeholder)
-    return false;
+  if (!placeholder) return false;
 
   switch (placeholder->getKind()) {
-    // Ignore all the non-placeholder types.
-#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix)                   \
+  // Ignore all the non-placeholder types.
+#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
   case BuiltinType::Id:
 #include "clang/Basic/OpenCLImageTypes.def"
-#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+  case BuiltinType::Id:
 #include "clang/Basic/OpenCLExtensionTypes.def"
-    // In practice we'll never use this, since all SVE types are sugared
-    // via TypedefTypes rather than exposed directly as BuiltinTypes.
-#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+  // In practice we'll never use this, since all SVE types are sugared
+  // via TypedefTypes rather than exposed directly as BuiltinTypes.
+#define SVE_TYPE(Name, Id, SingletonId) \
+  case BuiltinType::Id:
 #include "clang/Basic/AArch64ACLETypes.def"
-#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
+#define PPC_VECTOR_TYPE(Name, Id, Size) \
+  case BuiltinType::Id:
 #include "clang/Basic/PPCTypes.def"
 #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/RISCVVTypes.def"
@@ -6568,6 +6584,7 @@ static bool isPlaceholderToRemoveAsArg(QualType type) {
   case BuiltinType::OMPArrayShaping:
   case BuiltinType::OMPIterator:
     return true;
+
   }
   llvm_unreachable("bad builtin type kind");
 }
@@ -6579,10 +6596,8 @@ bool Sema::CheckArgsForPlaceholders(MultiExprArg args) {
   for (size_t i = 0, e = args.size(); i != e; i++) {
     if (isPlaceholderToRemoveAsArg(args[i]->getType())) {
       ExprResult result = CheckPlaceholderExpr(args[i]);
-      if (result.isInvalid())
-        hasInvalid = true;
-      else
-        args[i] = result.get();
+      if (result.isInvalid()) hasInvalid = true;
+      else args[i] = result.get();
     }
   }
   return hasInvalid;
@@ -6653,8 +6668,8 @@ static FunctionDecl *rewriteBuiltinFunctionDecl(Sema *Sema, ASTContext &Context,
 
   FunctionProtoType::ExtProtoInfo EPI;
   EPI.Variadic = FT->isVariadic();
-  QualType OverloadTy =
-      Context.getFunctionType(FT->getReturnType(), OverloadParams, EPI);
+  QualType OverloadTy = Context.getFunctionType(FT->getReturnType(),
+                                                OverloadParams, EPI);
   DeclContext *Parent = FDecl->getParent();
   FunctionDecl *OverloadDecl = FunctionDecl::Create(
       Context, Parent, FDecl->getLocation(), FDecl->getLocation(),
@@ -6662,14 +6677,14 @@ static FunctionDecl *rewriteBuiltinFunctionDecl(Sema *Sema, ASTContext &Context,
       /*TInfo=*/nullptr, SC_Extern, Sema->getCurFPFeatures().isFPConstrained(),
       false,
       /*hasPrototype=*/true);
-  SmallVector<ParmVarDecl *, 16> Params;
+  SmallVector<ParmVarDecl*, 16> Params;
   FT = cast<FunctionProtoType>(OverloadTy);
   for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
     QualType ParamType = FT->getParamType(i);
     ParmVarDecl *Parm =
         ParmVarDecl::Create(Context, OverloadDecl, SourceLocation(),
-                            SourceLocation(), nullptr, ParamType,
-                            /*TInfo=*/nullptr, SC_None, nullptr);
+                                SourceLocation(), nullptr, ParamType,
+                                /*TInfo=*/nullptr, SC_None, nullptr);
     Parm->setScopeInfo(0, i);
     Params.push_back(Parm);
   }
@@ -6775,6 +6790,7 @@ tryImplicitlyCaptureThisIfImplicitMemberFunctionAccessWithDependentArgs(
   if (!enclosingClassIsRelatedToClassInWhichMembersWereFound(UME, S))
     return;
 
+
   DeclContext *EnclosingFunctionCtx = S.CurContext->getParent()->getParent();
   // If the enclosing function is not dependent, then this lambda is
   // capture ready, so if we can capture this, do so.
@@ -6883,8 +6899,7 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
                                bool AllowRecovery) {
   // Since this might be a postfix expression, get rid of ParenListExprs.
   ExprResult Result = MaybeConvertParenListExprToParenExpr(Scope, Fn);
-  if (Result.isInvalid())
-    return ExprError();
+  if (Result.isInvalid()) return ExprError();
   Fn = Result.get();
 
   // The __builtin_amdgcn_is_invocable builtin is special, and will be resolved
@@ -6929,8 +6944,7 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
     }
     if (Fn->getType() == Context.PseudoObjectTy) {
       ExprResult result = CheckPlaceholderExpr(Fn);
-      if (result.isInvalid())
-        return ExprError();
+      if (result.isInvalid()) return ExprError();
       Fn = result.get();
     }
 
@@ -6968,8 +6982,7 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
 
     if (Fn->getType() == Context.UnknownAnyTy) {
       ExprResult result = rebuildUnknownAnyFunction(*this, Fn);
-      if (result.isInvalid())
-        return ExprError();
+      if (result.isInvalid()) return ExprError();
       Fn = result.get();
     }
 
@@ -7003,8 +7016,7 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
   // If we're directly calling a function, get the appropriate declaration.
   if (Fn->getType() == Context.UnknownAnyTy) {
     ExprResult result = rebuildUnknownAnyFunction(*this, Fn);
-    if (result.isInvalid())
-      return ExprError();
+    if (result.isInvalid()) return ExprError();
     Fn = result.get();
   }
 
@@ -7063,7 +7075,7 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
     // type.
     if (getLangOpts().HIP && FD && FD->getBuiltinID()) {
       for (unsigned Idx = 0; Idx < ArgExprs.size() && Idx < FD->param_size();
-           ++Idx) {
+          ++Idx) {
         ParmVarDecl *Param = FD->getParamDecl(Idx);
         if (!ArgExprs[Idx] || !Param || !Param->getType()->isPointerType() ||
             !ArgExprs[Idx]->getType()->isPointerType())
@@ -7076,14 +7088,10 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
 
         // Add address space cast if target address spaces are different
         bool NeedImplicitASC =
-            ParamAS != LangAS::Default && // Pointer params in generic AS don't
-                                          // need special handling.
-            (ArgAS ==
-                 LangAS::Default || // We do allow implicit conversion from
-                                    // generic AS or from specific AS which has
-                                    // target AS matching that of Param.
-             getASTContext().getTargetAddressSpace(ArgAS) ==
-                 getASTContext().getTargetAddressSpace(ParamAS));
+          ParamAS != LangAS::Default &&       // Pointer params in generic AS don't need special handling.
+          ( ArgAS == LangAS::Default  ||      // We do allow implicit conversion from generic AS
+                                              // or from specific AS which has target AS matching that of Param.
+          getASTContext().getTargetAddressSpace(ArgAS) == getASTContext().getTargetAddressSpace(ParamAS));
         if (!NeedImplicitASC)
           continue;
 
@@ -7100,8 +7108,9 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
         ArgPtQuals.setAddressSpace(ParamAS);
         auto NewArgPtTy =
             Context.getQualifiedType(ArgPtTy.getUnqualifiedType(), ArgPtQuals);
-        auto NewArgTy = Context.getQualifiedType(
-            Context.getPointerType(NewArgPtTy), ArgTy.getQualifiers());
+        auto NewArgTy =
+            Context.getQualifiedType(Context.getPointerType(NewArgPtTy),
+                                     ArgTy.getQualifiers());
 
         // Finally perform an implicit address space cast
         ArgExprs[Idx] = ImpCastExprToType(ArgExprs[Idx], NewArgTy,
@@ -7340,8 +7349,7 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
     if (Config) {
       // CUDA: Kernel calls must be to global functions
       if (FDecl && !FDecl->hasAttr<CUDAGlobalAttr>())
-        return ExprError(
-            Diag(LParenLoc, diag::err_kern_call_not_global_function)
+        return ExprError(Diag(LParenLoc,diag::err_kern_call_not_global_function)
             << FDecl << Fn->getSourceRange());
 
       // CUDA: Kernel function must have 'void' return type
@@ -7349,12 +7357,12 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
           !FuncT->getReturnType()->getAs<AutoType>() &&
           !FuncT->getReturnType()->isInstantiationDependentType())
         return ExprError(Diag(LParenLoc, diag::err_kern_type_not_void_return)
-                         << Fn->getType() << Fn->getSourceRange());
+            << Fn->getType() << Fn->getSourceRange());
     } else {
       // CUDA: Calls to global functions must be configured
       if (FDecl && FDecl->hasAttr<CUDAGlobalAttr>())
         return ExprError(Diag(LParenLoc, diag::err_global_call_not_config)
-                         << FDecl << Fn->getSourceRange());
+            << FDecl << Fn->getSourceRange());
     }
   }
 
@@ -7396,11 +7404,9 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
       const FunctionDecl *Def = nullptr;
       if (FDecl->hasBody(Def) && Args.size() != Def->param_size()) {
         Proto = Def->getType()->getAs<FunctionProtoType>();
-        if (!Proto ||
-            !(Proto->isVariadic() && Args.size() >= Def->param_size()))
+       if (!Proto || !(Proto->isVariadic() && Args.size() >= Def->param_size()))
           Diag(RParenLoc, diag::warn_call_wrong_number_of_arguments)
-              << (Args.size() > Def->param_size()) << FDecl
-              << Fn->getSourceRange();
+          << (Args.size() > Def->param_size()) << FDecl << Fn->getSourceRange();
       }
 
       // If the function we're calling isn't a function prototype, but we have
@@ -7750,7 +7756,7 @@ ExprResult Sema::BuildCompoundLiteralExpr(
     //   "If the compound literal occurs inside the body of a function, the
     //   type name shall not be qualified by an address-space qualifier."
     Diag(LParenLoc, diag::err_compound_literal_with_address_space)
-        << SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd());
+      << SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd());
     return ExprError();
   }
 
@@ -7800,9 +7806,9 @@ ExprResult Sema::BuildCompoundLiteralExpr(
   return MaybeBindToTemporary(E);
 }
 
-ExprResult Sema::ActOnInitList(SourceLocation LBraceLoc,
-                               MultiExprArg InitArgList,
-                               SourceLocation RBraceLoc) {
+ExprResult
+Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,
+                    SourceLocation RBraceLoc) {
   // Only produce each kind of designated initialization diagnostic once.
   SourceLocation FirstDesignator;
   bool DiagnosedArrayDesignator = false;
@@ -7822,14 +7828,14 @@ ExprResult Sema::ActOnInitList(SourceLocation LBraceLoc,
       if (!DiagnosedNestedDesignator && DIE->size() > 1) {
         DiagnosedNestedDesignator = true;
         Diag(DIE->getBeginLoc(), diag::ext_designated_init_nested)
-            << DIE->getDesignatorsSourceRange();
+          << DIE->getDesignatorsSourceRange();
       }
 
       for (auto &Desig : DIE->designators()) {
         if (!Desig.isFieldDesignator() && !DiagnosedArrayDesignator) {
           DiagnosedArrayDesignator = true;
           Diag(Desig.getBeginLoc(), diag::ext_designated_init_array)
-              << Desig.getSourceRange();
+            << Desig.getSourceRange();
         }
       }
 
@@ -7837,18 +7843,18 @@ ExprResult Sema::ActOnInitList(SourceLocation LBraceLoc,
           !isa<DesignatedInitExpr>(InitArgList[0])) {
         DiagnosedMixedDesignator = true;
         Diag(DIE->getBeginLoc(), diag::ext_designated_init_mixed)
-            << DIE->getSourceRange();
+          << DIE->getSourceRange();
         Diag(InitArgList[0]->getBeginLoc(), diag::note_designated_init_mixed)
-            << InitArgList[0]->getSourceRange();
+          << InitArgList[0]->getSourceRange();
       }
     } else if (getLangOpts().CPlusPlus && !DiagnosedMixedDesignator &&
                isa<DesignatedInitExpr>(InitArgList[0])) {
       DiagnosedMixedDesignator = true;
       auto *DIE = cast<DesignatedInitExpr>(InitArgList[0]);
       Diag(DIE->getBeginLoc(), diag::ext_designated_init_mixed)
-          << DIE->getSourceRange();
+        << DIE->getSourceRange();
       Diag(InitArgList[I]->getBeginLoc(), diag::note_designated_init_mixed)
-          << InitArgList[I]->getSourceRange();
+        << InitArgList[I]->getSourceRange();
     }
   }
 
@@ -7882,8 +7888,7 @@ ExprResult Sema::BuildInitList(SourceLocation LBraceLoc,
 
       // Ignore failures; dropping the entire initializer list because
       // of one failure would be terrible for indexing/etc.
-      if (result.isInvalid())
-        continue;
+      if (result.isInvalid()) continue;
 
       InitArgList[I] = result.get();
     }
@@ -7900,8 +7905,7 @@ void Sema::maybeExtendBlockObject(ExprResult &E) {
   assert(E.get()->isPRValue());
 
   // Only do this in an r-value context.
-  if (!getLangOpts().ObjCAutoRefCount)
-    return;
+  if (!getLangOpts().ObjCAutoRefCount) return;
 
   E = ImplicitCastExpr::Create(
       Context, E.get()->getType(), CK_ARCExtendBlockObject, E.get(),
@@ -7937,8 +7941,7 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) {
     }
     case Type::STK_BlockPointer:
       return (SrcKind == Type::STK_BlockPointer
-                  ? CK_BitCast
-                  : CK_AnyPointerToBlockPointerCast);
+                ? CK_BitCast : CK_AnyPointerToBlockPointerCast);
     case Type::STK_ObjCObjectPointer:
       if (SrcKind == Type::STK_ObjCObjectPointer)
         return CK_BitCast;
@@ -8001,13 +8004,13 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) {
       return CK_IntegralToFloating;
     case Type::STK_IntegralComplex:
       Src = ImpCastExprToType(Src.get(),
-                              DestTy->castAs<ComplexType>()->getElementType(),
-                              CK_IntegralCast);
+                      DestTy->castAs<ComplexType>()->getElementType(),
+                      CK_IntegralCast);
       return CK_IntegralRealToComplex;
     case Type::STK_FloatingComplex:
       Src = ImpCastExprToType(Src.get(),
-                              DestTy->castAs<ComplexType>()->getElementType(),
-                              CK_IntegralToFloating);
+                      DestTy->castAs<ComplexType>()->getElementType(),
+                      CK_IntegralToFloating);
       return CK_FloatingRealToComplex;
     case Type::STK_MemberPointer:
       llvm_unreachable("member pointer type in C");
@@ -8129,8 +8132,7 @@ static bool breakDownVectorType(QualType type, uint64_t &len,
 
   // We allow lax conversion to and from non-vector types, but only if
   // they're real types (i.e. non-complex, non-pointer scalar types).
-  if (!type->isRealType())
-    return false;
+  if (!type->isRealType()) return false;
 
   len = 1;
   eltType = type;
@@ -8213,10 +8215,8 @@ bool Sema::areLaxCompatibleVectorTypes(QualType srcTy, QualType destTy) {
   // depend on them).  Most scalar OP ExtVector cases are handled by the
   // splat path anyway, which does what we want (convert, not bitcast).
   // What this rules out for ExtVectors is crazy things like char4*float.
-  if (srcTy->isScalarType() && destTy->isExtVectorType())
-    return false;
-  if (destTy->isScalarType() && srcTy->isExtVectorType())
-    return false;
+  if (srcTy->isScalarType() && destTy->isExtVectorType()) return false;
+  if (destTy->isScalarType() && srcTy->isExtVectorType()) return false;
 
   return areVectorTypesSameSize(srcTy, destTy);
 }
@@ -8242,7 +8242,7 @@ bool Sema::isLaxVectorConversion(QualType srcTy, QualType destTy) {
     // OK, integer (vector) -> integer (vector) bitcast.
     break;
 
-  case LangOptions::LaxVectorConversionKind::All:
+    case LangOptions::LaxVectorConversionKind::All:
     break;
   }
 
@@ -8277,14 +8277,14 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
   if (Ty->isVectorType() || Ty->isIntegralType(Context)) {
     if (!areLaxCompatibleVectorTypes(Ty, VectorTy))
       return Diag(R.getBegin(),
-                  Ty->isVectorType()
-                      ? diag::err_invalid_conversion_between_vectors
-                      : diag::err_invalid_conversion_between_vector_and_integer)
-             << VectorTy << Ty << R;
+                  Ty->isVectorType() ?
+                  diag::err_invalid_conversion_between_vectors :
+                  diag::err_invalid_conversion_between_vector_and_integer)
+        << VectorTy << Ty << R;
   } else
     return Diag(R.getBegin(),
                 diag::err_invalid_conversion_between_vector_and_scalar)
-           << VectorTy << Ty << R;
+      << VectorTy << Ty << R;
 
   Kind = CK_BitCast;
   return false;
@@ -8356,8 +8356,8 @@ ExprResult Sema::CheckExtVectorCast(SourceRange R, QualType DestTy,
         (getLangOpts().OpenCL &&
          !Context.hasSameUnqualifiedType(DestTy, SrcTy) &&
          !Context.areCompatibleVectorTypes(DestTy, SrcTy))) {
-      Diag(R.getBegin(), diag::err_invalid_conversion_between_ext_vectors)
-          << DestTy << SrcTy << R;
+      Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
+        << DestTy << SrcTy << R;
       return ExprError();
     }
     Kind = CK_BitCast;
@@ -8370,7 +8370,7 @@ ExprResult Sema::CheckExtVectorCast(SourceRange R, QualType DestTy,
   if (SrcTy->isPointerType())
     return Diag(R.getBegin(),
                 diag::err_invalid_conversion_between_vector_and_scalar)
-           << DestTy << SrcTy << R;
+      << DestTy << SrcTy << R;
 
   Kind = CK_VectorSplat;
   return prepareVectorSplat(DestTy, CastExpr);
@@ -8411,9 +8411,10 @@ static void CheckSufficientAllocSize(Sema &S, QualType DestType,
         << Size.getQuantity() << TargetType << LhsSize->getQuantity();
 }
 
-ExprResult Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
-                               Declarator &D, ParsedType &Ty,
-                               SourceLocation RParenLoc, Expr *CastExpr) {
+ExprResult
+Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
+                    Declarator &D, ParsedType &Ty,
+                    SourceLocation RParenLoc, Expr *CastExpr) {
   assert(!D.isInvalidType() && (CastExpr != nullptr) &&
          "ActOnCastExpr(): missing type or expr");
 
@@ -8437,9 +8438,8 @@ ExprResult Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
   // i.e. all the elements are integer constants.
   ParenExpr *PE = dyn_cast<ParenExpr>(CastExpr);
   ParenListExpr *PLE = dyn_cast<ParenListExpr>(CastExpr);
-  if ((getLangOpts().AltiVec || getLangOpts().ZVector ||
-       getLangOpts().OpenCL) &&
-      castType->isVectorType() && (PE || PLE)) {
+  if ((getLangOpts().AltiVec || getLangOpts().ZVector || getLangOpts().OpenCL)
+       && castType->isVectorType() && (PE || PLE)) {
     if (PLE && PLE->getNumExprs() == 0) {
       Diag(PLE->getExprLoc(), diag::err_altivec_empty_initializer);
       return ExprError();
@@ -8448,7 +8448,8 @@ ExprResult Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
       Expr *E = (PE ? PE->getSubExpr() : PLE->getExpr(0));
       if (!E->isTypeDependent() && !E->getType()->isVectorType())
         isVectorLiteral = true;
-    } else
+    }
+    else
       isVectorLiteral = true;
   }
 
@@ -8462,8 +8463,7 @@ ExprResult Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
   // sequence of BinOp comma operators.
   if (isa<ParenListExpr>(CastExpr)) {
     ExprResult Result = MaybeConvertParenListExprToParenExpr(S, CastExpr);
-    if (Result.isInvalid())
-      return ExprError();
+    if (Result.isInvalid()) return ExprError();
     CastExpr = Result.get();
   }
 
@@ -8530,12 +8530,16 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc,
       Literal = ImpCastExprToType(Literal.get(), ElemTy,
                                   PrepareScalarCast(Literal, ElemTy));
       return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.get());
-    } else if (numExprs < numElems) {
-      Diag(E->getExprLoc(), diag::err_incorrect_number_of_vector_initializers);
+    }
+    else if (numExprs < numElems) {
+      Diag(E->getExprLoc(),
+           diag::err_incorrect_number_of_vector_initializers);
       return ExprError();
-    } else
+    }
+    else
       initExprs.append(exprs, exprs + numExprs);
-  } else {
+  }
+  else {
     // For OpenCL, when the number of initializers is a single value,
     // it will be replicated to all components of the vector.
     if (getLangOpts().OpenCL && VTy->getVectorKind() == VectorKind::Generic &&
@@ -8567,8 +8571,8 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc,
   return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, initE);
 }
 
-ExprResult Sema::MaybeConvertParenListExprToParenExpr(Scope *S,
-                                                      Expr *OrigExpr) {
+ExprResult
+Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) {
   ParenListExpr *E = dyn_cast<ParenListExpr>(OrigExpr);
   if (!E)
     return OrigExpr;
@@ -8576,16 +8580,16 @@ ExprResult Sema::MaybeConvertParenListExprToParenExpr(Scope *S,
   ExprResult Result(E->getExpr(0));
 
   for (unsigned i = 1, e = E->getNumExprs(); i != e && !Result.isInvalid(); ++i)
-    Result =
-        ActOnBinOp(S, E->getExprLoc(), tok::comma, Result.get(), E->getExpr(i));
+    Result = ActOnBinOp(S, E->getExprLoc(), tok::comma, Result.get(),
+                        E->getExpr(i));
 
-  if (Result.isInvalid())
-    return ExprError();
+  if (Result.isInvalid()) return ExprError();
 
   return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), Result.get());
 }
 
-ExprResult Sema::ActOnParenListExpr(SourceLocation L, SourceLocation R,
+ExprResult Sema::ActOnParenListExpr(SourceLocation L,
+                                    SourceLocation R,
                                     MultiExprArg Val) {
   return ParenListExpr::Create(Context, L, Val, R);
 }
@@ -8603,14 +8607,16 @@ bool Sema::DiagnoseConditionalForNull(const Expr *LHSExpr, const Expr *RHSExpr,
                                       SourceLocation QuestionLoc) {
   const Expr *NullExpr = LHSExpr;
   const Expr *NonPointerExpr = RHSExpr;
-  Expr::NullPointerConstantKind NullKind = NullExpr->isNullPointerConstant(
-      Context, Expr::NPC_ValueDependentIsNotNull);
+  Expr::NullPointerConstantKind NullKind =
+      NullExpr->isNullPointerConstant(Context,
+                                      Expr::NPC_ValueDependentIsNotNull);
 
   if (NullKind == Expr::NPCK_NotNull) {
     NullExpr = RHSExpr;
     NonPointerExpr = LHSExpr;
-    NullKind = NullExpr->isNullPointerConstant(
-        Context, Expr::NPC_ValueDependentIsNotNull);
+    NullKind =
+        NullExpr->isNullPointerConstant(Context,
+                                        Expr::NPC_ValueDependentIsNotNull);
   }
 
   if (NullKind == Expr::NPCK_NotNull)
@@ -8643,16 +8649,15 @@ static bool checkCondition(Sema &S, const Expr *Cond,
   // OpenCL v1.1 s6.3.i says the condition cannot be a floating point type.
   if (S.getLangOpts().OpenCL && CondTy->isFloatingType()) {
     S.Diag(QuestionLoc, diag::err_typecheck_cond_expect_nonfloat)
-        << CondTy << Cond->getSourceRange();
+      << CondTy << Cond->getSourceRange();
     return true;
   }
 
   // C99 6.5.15p2
-  if (CondTy->isScalarType())
-    return false;
+  if (CondTy->isScalarType()) return false;
 
   S.Diag(QuestionLoc, diag::err_typecheck_cond_expect_scalar)
-      << CondTy << Cond->getSourceRange();
+    << CondTy << Cond->getSourceRange();
   return true;
 }
 
@@ -8662,7 +8667,7 @@ static bool checkConditionalNullPointer(Sema &S, ExprResult &NullExpr,
                                         QualType PointerTy) {
   if ((!PointerTy->isAnyPointerType() && !PointerTy->isBlockPointerType()) ||
       !NullExpr.get()->isNullPointerConstant(S.Context,
-                                             Expr::NPC_ValueDependentIsNull))
+                                            Expr::NPC_ValueDependentIsNull))
     return true;
 
   NullExpr = S.ImpCastExprToType(NullExpr.get(), PointerTy, CK_NullToPointer);
@@ -8724,8 +8729,7 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
     return QualType();
   }
 
-  unsigned MergedCVRQual =
-      lhQual.getCVRQualifiers() | rhQual.getCVRQualifiers();
+  unsigned MergedCVRQual = lhQual.getCVRQualifiers() | rhQual.getCVRQualifiers();
   auto LHSCastKind = CK_BitCast, RHSCastKind = CK_BitCast;
   lhQual.removeCVRQualifiers();
   rhQual.removeCVRQualifiers();
@@ -8825,8 +8829,8 @@ static QualType checkConditionalBlockPointerCompatibility(Sema &S,
       return destType;
     }
     S.Diag(Loc, diag::err_typecheck_cond_incompatible_operands)
-        << LHSTy << RHSTy << LHS.get()->getSourceRange()
-        << RHS.get()->getSourceRange();
+      << LHSTy << RHSTy << LHS.get()->getSourceRange()
+      << RHS.get()->getSourceRange();
     return QualType();
   }
 
@@ -8835,8 +8839,10 @@ static QualType checkConditionalBlockPointerCompatibility(Sema &S,
 }
 
 /// Return the resulting type when the operands are both pointers.
-static QualType checkConditionalObjectPointersCompatibility(
-    Sema &S, ExprResult &LHS, ExprResult &RHS, SourceLocation Loc) {
+static QualType
+checkConditionalObjectPointersCompatibility(Sema &S, ExprResult &LHS,
+                                            ExprResult &RHS,
+                                            SourceLocation Loc) {
   // get the pointer types
   QualType LHSTy = LHS.get()->getType();
   QualType RHSTy = RHS.get()->getType();
@@ -8848,8 +8854,8 @@ static QualType checkConditionalObjectPointersCompatibility(
   // ignore qualifiers on void (C99 6.5.15p3, clause 6)
   if (lhptee->isVoidType() && rhptee->isIncompleteOrObjectType()) {
     // Figure out necessary qualifiers (C99 6.5.15p6)
-    QualType destPointee =
-        S.Context.getQualifiedType(lhptee, rhptee.getQualifiers());
+    QualType destPointee
+      = S.Context.getQualifiedType(lhptee, rhptee.getQualifiers());
     QualType destType = S.Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
     LHS = S.ImpCastExprToType(LHS.get(), destType, CK_NoOp);
@@ -8858,8 +8864,8 @@ static QualType checkConditionalObjectPointersCompatibility(
     return destType;
   }
   if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
-    QualType destPointee =
-        S.Context.getQualifiedType(rhptee, lhptee.getQualifiers());
+    QualType destPointee
+      = S.Context.getQualifiedType(rhptee, lhptee.getQualifiers());
     QualType destType = S.Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
     RHS = S.ImpCastExprToType(RHS.get(), destType, CK_NoOp);
@@ -8874,7 +8880,7 @@ static QualType checkConditionalObjectPointersCompatibility(
 /// Return false if the first expression is not an integer and the second
 /// expression is not a pointer, true otherwise.
 static bool checkPointerIntegerMismatch(Sema &S, ExprResult &Int,
-                                        Expr *PointerExpr, SourceLocation Loc,
+                                        Expr* PointerExpr, SourceLocation Loc,
                                         bool IsIntFirstExpr) {
   if (!PointerExpr->getType()->isPointerType() ||
       !Int.get()->getType()->isIntegerType())
@@ -8884,8 +8890,8 @@ static bool checkPointerIntegerMismatch(Sema &S, ExprResult &Int,
   Expr *Expr2 = IsIntFirstExpr ? PointerExpr : Int.get();
 
   S.Diag(Loc, diag::ext_typecheck_cond_pointer_integer_mismatch)
-      << Expr1->getType() << Expr2->getType() << Expr1->getSourceRange()
-      << Expr2->getSourceRange();
+    << Expr1->getType() << Expr2->getType()
+    << Expr1->getSourceRange() << Expr2->getSourceRange();
   Int = S.ImpCastExprToType(Int.get(), PointerExpr->getType(),
                             CK_IntegralToPointer);
   return true;
@@ -8916,19 +8922,19 @@ static QualType OpenCLArithmeticConversions(Sema &S, ExprResult &LHS,
   // For conversion purposes, we ignore any qualifiers.
   // For example, "const float" and "float" are equivalent.
   QualType LHSType =
-      S.Context.getCanonicalType(LHS.get()->getType()).getUnqualifiedType();
+    S.Context.getCanonicalType(LHS.get()->getType()).getUnqualifiedType();
   QualType RHSType =
-      S.Context.getCanonicalType(RHS.get()->getType()).getUnqualifiedType();
+    S.Context.getCanonicalType(RHS.get()->getType()).getUnqualifiedType();
 
   if (!LHSType->isIntegerType() && !LHSType->isRealFloatingType()) {
     S.Diag(QuestionLoc, diag::err_typecheck_cond_expect_int_float)
-        << LHSType << LHS.get()->getSourceRange();
+      << LHSType << LHS.get()->getSourceRange();
     return QualType();
   }
 
   if (!RHSType->isIntegerType() && !RHSType->isRealFloatingType()) {
     S.Diag(QuestionLoc, diag::err_typecheck_cond_expect_int_float)
-        << RHSType << RHS.get()->getSourceRange();
+      << RHSType << RHS.get()->getSourceRange();
     return QualType();
   }
 
@@ -8942,8 +8948,8 @@ static QualType OpenCLArithmeticConversions(Sema &S, ExprResult &LHS,
                                  /*IsCompAssign = */ false);
 
   // Finally, we have two differing integer types.
-  return handleIntegerConversion<doIntegralCast, doIntegralCast>(
-      S, LHS, RHS, LHSType, RHSType, /*IsCompAssign = */ false);
+  return handleIntegerConversion<doIntegralCast, doIntegralCast>
+  (S, LHS, RHS, LHSType, RHSType, /*IsCompAssign = */ false);
 }
 
 /// Convert scalar operands to a vector that matches the
@@ -8957,12 +8963,11 @@ static QualType OpenCLArithmeticConversions(Sema &S, ExprResult &LHS,
 /// into a vector of that type where the length matches the condition
 /// vector type. s6.11.6 requires that the element types of the result
 /// and the condition must have the same number of bits.
-static QualType OpenCLConvertScalarsToVectors(Sema &S, ExprResult &LHS,
-                                              ExprResult &RHS, QualType CondTy,
-                                              SourceLocation QuestionLoc) {
+static QualType
+OpenCLConvertScalarsToVectors(Sema &S, ExprResult &LHS, ExprResult &RHS,
+                              QualType CondTy, SourceLocation QuestionLoc) {
   QualType ResTy = OpenCLArithmeticConversions(S, LHS, RHS, QuestionLoc);
-  if (ResTy.isNull())
-    return QualType();
+  if (ResTy.isNull()) return QualType();
 
   const VectorType *CV = CondTy->getAs<VectorType>();
   assert(CV);
@@ -8972,8 +8977,8 @@ static QualType OpenCLConvertScalarsToVectors(Sema &S, ExprResult &LHS,
   QualType VectorTy = S.Context.getExtVectorType(ResTy, NumElements);
 
   // Ensure that all types have the same number of bits
-  if (S.Context.getTypeSize(CV->getElementType()) !=
-      S.Context.getTypeSize(ResTy)) {
+  if (S.Context.getTypeSize(CV->getElementType())
+      != S.Context.getTypeSize(ResTy)) {
     // Since VectorTy is created internally, it does not pretty print
     // with an OpenCL name. Instead, we just print a description.
     std::string EleTyName = ResTy.getUnqualifiedType().getAsString();
@@ -8981,7 +8986,7 @@ static QualType OpenCLConvertScalarsToVectors(Sema &S, ExprResult &LHS,
     llvm::raw_svector_ostream OS(Str);
     OS << "(vector of " << NumElements << " '" << EleTyName << "' values)";
     S.Diag(QuestionLoc, diag::err_conditional_vector_element_size)
-        << CondTy << OS.str();
+      << CondTy << OS.str();
     return QualType();
   }
 
@@ -9000,11 +9005,10 @@ static bool checkOpenCLConditionVector(Sema &S, Expr *Cond,
   const VectorType *CondTy = Cond->getType()->getAs<VectorType>();
   assert(CondTy);
   QualType EleTy = CondTy->getElementType();
-  if (EleTy->isIntegerType())
-    return false;
+  if (EleTy->isIntegerType()) return false;
 
   S.Diag(QuestionLoc, diag::err_typecheck_cond_expect_nonfloat)
-      << Cond->getType() << Cond->getSourceRange();
+    << Cond->getType() << Cond->getSourceRange();
   return true;
 }
 
@@ -9022,7 +9026,7 @@ static bool checkVectorResult(Sema &S, QualType CondTy, QualType VecResTy,
 
   if (CV->getNumElements() != RV->getNumElements()) {
     S.Diag(QuestionLoc, diag::err_conditional_vector_size)
-        << CondTy << VecResTy;
+      << CondTy << VecResTy;
     return true;
   }
 
@@ -9043,9 +9047,10 @@ static bool checkVectorResult(Sema &S, QualType CondTy, QualType VecResTy,
 /// Return the resulting type for the conditional operator in
 ///        OpenCL (aka "ternary selection operator", OpenCL v1.1
 ///        s6.3.i) when the condition is a vector type.
-static QualType OpenCLCheckVectorConditional(Sema &S, ExprResult &Cond,
-                                             ExprResult &LHS, ExprResult &RHS,
-                                             SourceLocation QuestionLoc) {
+static QualType
+OpenCLCheckVectorConditional(Sema &S, ExprResult &Cond,
+                             ExprResult &LHS, ExprResult &RHS,
+                             SourceLocation QuestionLoc) {
   Cond = S.DefaultFunctionArrayLvalueConversion(Cond.get());
   if (Cond.isInvalid())
     return QualType();
@@ -9106,13 +9111,11 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
                                         SourceLocation QuestionLoc) {
 
   ExprResult LHSResult = CheckPlaceholderExpr(LHS.get());
-  if (!LHSResult.isUsable())
-    return QualType();
+  if (!LHSResult.isUsable()) return QualType();
   LHS = LHSResult;
 
   ExprResult RHSResult = CheckPlaceholderExpr(RHS.get());
-  if (!RHSResult.isUsable())
-    return QualType();
+  if (!RHSResult.isUsable()) return QualType();
   RHS = RHSResult;
 
   // C++ is sufficiently different to merit its own checker.
@@ -9171,16 +9174,16 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
   // Diagnose attempts to convert between __ibm128, __float128 and long double
   // where such conversions currently can't be handled.
   if (unsupportedTypeConversion(*this, LHSTy, RHSTy)) {
-    Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
-        << LHSTy << RHSTy << LHS.get()->getSourceRange()
-        << RHS.get()->getSourceRange();
+    Diag(QuestionLoc,
+         diag::err_typecheck_cond_incompatible_operands) << LHSTy << RHSTy
+      << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
     return QualType();
   }
 
   // OpenCL v2.0 s6.12.5 - Blocks cannot be used as expressions of the ternary
   // selection operator (?:).
-  if (getLangOpts().OpenCL && ((int)checkBlockType(*this, LHS.get()) |
-                               (int)checkBlockType(*this, RHS.get()))) {
+  if (getLangOpts().OpenCL &&
+      ((int)checkBlockType(*this, LHS.get()) | (int)checkBlockType(*this, RHS.get()))) {
     return QualType();
   }
 
@@ -9239,10 +9242,8 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
 
   // C99 6.5.15p6 - "if one operand is a null pointer constant, the result has
   // the type of the other operand."
-  if (!checkConditionalNullPointer(*this, RHS, LHSTy))
-    return LHSTy;
-  if (!checkConditionalNullPointer(*this, LHS, RHSTy))
-    return RHSTy;
+  if (!checkConditionalNullPointer(*this, RHS, LHSTy)) return LHSTy;
+  if (!checkConditionalNullPointer(*this, LHS, RHSTy)) return RHSTy;
 
   // All objective-c pointer type analysis is done here.
   QualType compositeType =
@@ -9252,6 +9253,7 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
   if (!compositeType.isNull())
     return compositeType;
 
+
   // Handle block pointer types.
   if (LHSTy->isBlockPointerType() || RHSTy->isBlockPointerType())
     return checkConditionalBlockPointerCompatibility(*this, LHS, RHS,
@@ -9265,10 +9267,10 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
   // GCC compatibility: soften pointer/integer mismatch.  Note that
   // null pointers have been filtered out by this point.
   if (checkPointerIntegerMismatch(*this, LHS, RHS.get(), QuestionLoc,
-                                  /*IsIntFirstExpr=*/true))
+      /*IsIntFirstExpr=*/true))
     return RHSTy;
   if (checkPointerIntegerMismatch(*this, RHS, LHS.get(), QuestionLoc,
-                                  /*IsIntFirstExpr=*/false))
+      /*IsIntFirstExpr=*/false))
     return LHSTy;
 
   // Emit a better diagnostic if one of the expressions is a null pointer
@@ -9284,8 +9286,8 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
 
   // Otherwise, the operands are not compatible.
   Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
-      << LHSTy << RHSTy << LHS.get()->getSourceRange()
-      << RHS.get()->getSourceRange();
+    << LHSTy << RHSTy << LHS.get()->getSourceRange()
+    << RHS.get()->getSourceRange();
   return QualType();
 }
 
@@ -9297,9 +9299,9 @@ static void SuggestParentheses(Sema &Self, SourceLocation Loc,
   SourceLocation EndLoc = Self.getLocForEndOfToken(ParenRange.getEnd());
   if (ParenRange.getBegin().isFileID() && ParenRange.getEnd().isFileID() &&
       EndLoc.isValid()) {
-    Self.Diag(Loc, Note) << FixItHint::CreateInsertion(ParenRange.getBegin(),
-                                                       "(")
-                         << FixItHint::CreateInsertion(EndLoc, ")");
+    Self.Diag(Loc, Note)
+      << FixItHint::CreateInsertion(ParenRange.getBegin(), "(")
+      << FixItHint::CreateInsertion(EndLoc, ")");
   } else {
     // We can't display the parentheses, so just show the bare note.
     Self.Diag(Loc, Note) << ParenRange;
@@ -9348,8 +9350,8 @@ static bool IsArithmeticBinaryExpr(const Expr *E, BinaryOperatorKind *Opcode,
     // Make sure this is really a binary operator that is safe to pass into
     // BinaryOperator::getOverloadedOpcode(), e.g. it's not a subscript op.
     OverloadedOperatorKind OO = Call->getOperator();
-    if (OO < OO_Plus || OO > OO_Arrow || OO == OO_PlusPlus ||
-        OO == OO_MinusMinus)
+    if (OO < OO_Plus || OO > OO_Arrow ||
+        OO == OO_PlusPlus || OO == OO_MinusMinus)
       return false;
 
     BinaryOperatorKind OpKind = BinaryOperator::getOverloadedOpcode(OO);
@@ -9405,8 +9407,9 @@ static void DiagnoseConditionalPrecedence(Sema &Self, SourceLocation OpLoc,
                         ? diag::warn_precedence_bitwise_conditional
                         : diag::warn_precedence_conditional;
 
-  Self.Diag(OpLoc, DiagID) << Condition->getSourceRange()
-                           << BinaryOperator::getOpcodeStr(CondOpcode);
+  Self.Diag(OpLoc, DiagID)
+      << Condition->getSourceRange()
+      << BinaryOperator::getOpcodeStr(CondOpcode);
 
   SuggestParentheses(
       Self, OpLoc,
@@ -9446,7 +9449,7 @@ static QualType computeConditionalNullability(QualType ResTy, bool IsBin,
       MergedKind = NullabilityKind::NonNull;
     else
       MergedKind = RHSKind;
-    // Compute nullability of a normal conditional expression.
+  // Compute nullability of a normal conditional expression.
   } else {
     if (LHSKind == NullabilityKind::Nullable ||
         RHSKind == NullabilityKind::Nullable)
@@ -9472,8 +9475,9 @@ static QualType computeConditionalNullability(QualType ResTy, bool IsBin,
 }
 
 ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
-                                    SourceLocation ColonLoc, Expr *CondExpr,
-                                    Expr *LHSExpr, Expr *RHSExpr) {
+                                    SourceLocation ColonLoc,
+                                    Expr *CondExpr, Expr *LHSExpr,
+                                    Expr *RHSExpr) {
   // If this is the gnu "x ?: y" extension, analyze the types as though the LHS
   // was the condition.
   OpaqueValueExpr *opaqueValue = nullptr;
@@ -9485,17 +9489,18 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
     // as Objective-C++'s dictionary subscripting syntax.
     if (commonExpr->hasPlaceholderType()) {
       ExprResult result = CheckPlaceholderExpr(commonExpr);
-      if (!result.isUsable())
-        return ExprError();
+      if (!result.isUsable()) return ExprError();
       commonExpr = result.get();
     }
     // We usually want to apply unary conversions *before* saving, except
     // in the special case of a C++ l-value conditional.
-    if (!(getLangOpts().CPlusPlus && !commonExpr->isTypeDependent() &&
-          commonExpr->getValueKind() == RHSExpr->getValueKind() &&
-          commonExpr->isGLValue() && commonExpr->isOrdinaryOrBitFieldObject() &&
-          RHSExpr->isOrdinaryOrBitFieldObject() &&
-          Context.hasSameType(commonExpr->getType(), RHSExpr->getType()))) {
+    if (!(getLangOpts().CPlusPlus
+          && !commonExpr->isTypeDependent()
+          && commonExpr->getValueKind() == RHSExpr->getValueKind()
+          && commonExpr->isGLValue()
+          && commonExpr->isOrdinaryOrBitFieldObject()
+          && RHSExpr->isOrdinaryOrBitFieldObject()
+          && Context.hasSameType(commonExpr->getType(), RHSExpr->getType()))) {
       ExprResult commonRes = UsualUnaryConversions(commonExpr);
       if (commonRes.isInvalid())
         return ExprError();
@@ -9512,9 +9517,11 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
       commonExpr = MatExpr.get();
     }
 
-    opaqueValue = new (Context) OpaqueValueExpr(
-        commonExpr->getExprLoc(), commonExpr->getType(),
-        commonExpr->getValueKind(), commonExpr->getObjectKind(), commonExpr);
+    opaqueValue = new (Context) OpaqueValueExpr(commonExpr->getExprLoc(),
+                                                commonExpr->getType(),
+                                                commonExpr->getValueKind(),
+                                                commonExpr->getObjectKind(),
+                                                commonExpr);
     LHSExpr = CondExpr = opaqueValue;
   }
 
@@ -9522,9 +9529,10 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
   ExprValueKind VK = VK_PRValue;
   ExprObjectKind OK = OK_Ordinary;
   ExprResult Cond = CondExpr, LHS = LHSExpr, RHS = RHSExpr;
-  QualType result =
-      CheckConditionalOperands(Cond, LHS, RHS, VK, OK, QuestionLoc);
-  if (result.isNull() || Cond.isInvalid() || LHS.isInvalid() || RHS.isInvalid())
+  QualType result = CheckConditionalOperands(Cond, LHS, RHS,
+                                             VK, OK, QuestionLoc);
+  if (result.isNull() || Cond.isInvalid() || LHS.isInvalid() ||
+      RHS.isInvalid())
     return ExprError();
 
   DiagnoseConditionalPrecedence(*this, QuestionLoc, Cond.get(), LHS.get(),
@@ -9532,8 +9540,8 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
 
   CheckBoolLikeConversion(Cond.get(), QuestionLoc);
 
-  result =
-      computeConditionalNullability(result, commonExpr, LHSTy, RHSTy, Context);
+  result = computeConditionalNullability(result, commonExpr, LHSTy, RHSTy,
+                                         Context);
 
   if (!commonExpr)
     return new (Context)
@@ -9707,9 +9715,9 @@ static AssignConvertType checkPointerTypesForAssignment(Sema &S,
     if (isa<PointerType>(lhptee) && isa<PointerType>(rhptee)) {
       do {
         std::tie(lhptee, lhq) =
-            cast<PointerType>(lhptee)->getPointeeType().split().asPair();
+          cast<PointerType>(lhptee)->getPointeeType().split().asPair();
         std::tie(rhptee, rhq) =
-            cast<PointerType>(rhptee)->getPointeeType().split().asPair();
+          cast<PointerType>(rhptee)->getPointeeType().split().asPair();
 
         // Inconsistent address spaces at this point is invalid, even if the
         // address spaces would be compatible.
@@ -10360,7 +10368,8 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType,
 
       if (RHS.get()->isNullPointerConstant(Context,
                                            Expr::NPC_ValueDependentIsNull)) {
-        RHS = ImpCastExprToType(RHS.get(), it->getType(), CK_NullToPointer);
+        RHS = ImpCastExprToType(RHS.get(), it->getType(),
+                                CK_NullToPointer);
         InitField = it;
         break;
       }
@@ -10418,12 +10427,13 @@ AssignConvertType Sema::CheckSingleAssignmentConstraints(QualType LHSType,
         RHS = PerformImplicitConversion(RHS.get(), LHSType.getUnqualifiedType(),
                                         AssignmentAction::Assigning);
       } else {
-        ImplicitConversionSequence ICS = TryImplicitConversion(
-            RHS.get(), LHSType.getUnqualifiedType(),
-            /*SuppressUserConversions=*/false, AllowedExplicit::None,
-            /*InOverloadResolution=*/false,
-            /*CStyle=*/false,
-            /*AllowObjCWritebackConversion=*/false);
+        ImplicitConversionSequence ICS =
+            TryImplicitConversion(RHS.get(), LHSType.getUnqualifiedType(),
+                                  /*SuppressUserConversions=*/false,
+                                  AllowedExplicit::None,
+                                  /*InOverloadResolution=*/false,
+                                  /*CStyle=*/false,
+                                  /*AllowObjCWritebackConversion=*/false);
         if (ICS.isFailure())
           return AssignConvertType::Incompatible;
         RHS = PerformImplicitConversion(RHS.get(), LHSType.getUnqualifiedType(),
@@ -10639,27 +10649,27 @@ struct OriginalOperand {
   Expr *Orig;
   NamedDecl *Conversion;
 };
-} // namespace
+}
 
 QualType Sema::InvalidOperands(SourceLocation Loc, ExprResult &LHS,
                                ExprResult &RHS) {
   OriginalOperand OrigLHS(LHS.get()), OrigRHS(RHS.get());
 
   Diag(Loc, diag::err_typecheck_invalid_operands)
-      << OrigLHS.getType() << OrigRHS.getType() << LHS.get()->getSourceRange()
-      << RHS.get()->getSourceRange();
+    << OrigLHS.getType() << OrigRHS.getType()
+    << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
 
   // If a user-defined conversion was applied to either of the operands prior
   // to applying the built-in operator rules, tell the user about it.
   if (OrigLHS.Conversion) {
     Diag(OrigLHS.Conversion->getLocation(),
          diag::note_typecheck_invalid_operands_converted)
-        << 0 << LHS.get()->getType();
+      << 0 << LHS.get()->getType();
   }
   if (OrigRHS.Conversion) {
     Diag(OrigRHS.Conversion->getLocation(),
          diag::note_typecheck_invalid_operands_converted)
-        << 1 << RHS.get()->getType();
+      << 1 << RHS.get()->getType();
   }
 
   return QualType();
@@ -10702,8 +10712,10 @@ QualType Sema::InvalidLogicalVectorOperands(SourceLocation Loc, ExprResult &LHS,
 /// \param scalar - if non-null, actually perform the conversions
 /// \return true if the operation fails (but without diagnosing the failure)
 static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar,
-                                     QualType scalarTy, QualType vectorEltTy,
-                                     QualType vectorTy, unsigned &DiagID) {
+                                     QualType scalarTy,
+                                     QualType vectorEltTy,
+                                     QualType vectorTy,
+                                     unsigned &DiagID) {
   // The conversion to apply to the scalar before splatting it,
   // if necessary.
   CastKind scalarCast = CK_NoOp;
@@ -10711,10 +10723,9 @@ static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar,
   if (vectorEltTy->isBooleanType() && scalarTy->isIntegralType(S.Context)) {
     scalarCast = CK_IntegralToBoolean;
   } else if (vectorEltTy->isIntegralType(S.Context)) {
-    if (S.getLangOpts().OpenCL &&
-        (scalarTy->isRealFloatingType() ||
-         (scalarTy->isIntegerType() &&
-          S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy) < 0))) {
+    if (S.getLangOpts().OpenCL && (scalarTy->isRealFloatingType() ||
+        (scalarTy->isIntegerType() &&
+         S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy) < 0))) {
       DiagID = diag::err_opencl_scalar_type_rank_greater_than_vector_type;
       return true;
     }
@@ -10729,7 +10740,8 @@ static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar,
         return true;
       }
       scalarCast = CK_FloatingCast;
-    } else if (scalarTy->isIntegralType(S.Context))
+    }
+    else if (scalarTy->isIntegralType(S.Context))
       scalarCast = CK_IntegralToFloating;
     else
       return true;
@@ -11159,11 +11171,11 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
     if (!IsCompAssign) {
       *OtherExpr = ImpCastExprToType(OtherExpr->get(), VecType, CK_BitCast);
       return VecType;
-      // In a compound assignment, lhs += rhs, 'lhs' is a lvalue src, forbidding
-      // any implicit cast. Here, the 'rhs' should be implicit casted to 'lhs'
-      // type. Note that this is already done by non-compound assignments in
-      // CheckAssignmentConstraints. If it's a scalar type, only bitcast for
-      // <1 x T> -> T. The result is also a vector type.
+    // In a compound assignment, lhs += rhs, 'lhs' is a lvalue src, forbidding
+    // any implicit cast. Here, the 'rhs' should be implicit casted to 'lhs'
+    // type. Note that this is already done by non-compound assignments in
+    // CheckAssignmentConstraints. If it's a scalar type, only bitcast for
+    // <1 x T> -> T. The result is also a vector type.
     } else if (OtherType->isExtVectorType() || OtherType->isVectorType() ||
                (OtherType->isScalarType() && VT->getNumElements() == 1)) {
       ExprResult *RHSExpr = &RHS;
@@ -11178,8 +11190,8 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
   if ((!RHSVecType && !RHSType->isRealType()) ||
       (!LHSVecType && !LHSType->isRealType())) {
     Diag(Loc, diag::err_typecheck_vector_not_convertable_non_scalar)
-        << LHSType << RHSType << LHS.get()->getSourceRange()
-        << RHS.get()->getSourceRange();
+      << LHSType << RHSType
+      << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
     return QualType();
   }
 
@@ -11187,13 +11199,15 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
   // If the operands are of more than one vector type, then an error shall
   // occur. Implicit conversions between vector types are not permitted, per
   // section 6.2.1.
-  if (getLangOpts().OpenCL && RHSVecType && isa<ExtVectorType>(RHSVecType) &&
+  if (getLangOpts().OpenCL &&
+      RHSVecType && isa<ExtVectorType>(RHSVecType) &&
       LHSVecType && isa<ExtVectorType>(LHSVecType)) {
-    Diag(Loc, diag::err_opencl_implicit_vector_conversion)
-        << LHSType << RHSType;
+    Diag(Loc, diag::err_opencl_implicit_vector_conversion) << LHSType
+                                                           << RHSType;
     return QualType();
   }
 
+
   // If there is a vector type that is not a ExtVector and a scalar, we reach
   // this point if scalar could not be converted to the vector's element type
   // without truncation.
@@ -11202,15 +11216,17 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
     QualType Scalar = LHSVecType ? RHSType : LHSType;
     QualType Vector = LHSVecType ? LHSType : RHSType;
     unsigned ScalarOrVector = LHSVecType && RHSVecType ? 1 : 0;
-    Diag(Loc, diag::err_typecheck_vector_not_convertable_implict_truncation)
+    Diag(Loc,
+         diag::err_typecheck_vector_not_convertable_implict_truncation)
         << ScalarOrVector << Scalar << Vector;
 
     return QualType();
   }
 
   // Otherwise, use the generic diagnostic.
-  Diag(Loc, DiagID) << LHSType << RHSType << LHS.get()->getSourceRange()
-                    << RHS.get()->getSourceRange();
+  Diag(Loc, DiagID)
+    << LHSType << RHSType
+    << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
   return QualType();
 }
 
@@ -11324,8 +11340,8 @@ static void checkArithmeticNull(Sema &S, ExprResult &LHS, ExprResult &RHS,
     return;
 
   S.Diag(Loc, diag::warn_null_in_comparison_operation)
-      << LHSNull /* LHS is NULL */ << NonNullType << LHS.get()->getSourceRange()
-      << RHS.get()->getSourceRange();
+      << LHSNull /* LHS is NULL */ << NonNullType
+      << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
 }
 
 static void DetectPrecisionLossInComplexDivision(Sema &S, QualType DivisorTy,
@@ -11368,7 +11384,7 @@ static void DetectPrecisionLossInComplexDivision(Sema &S, QualType DivisorTy,
 }
 
 static void DiagnoseDivisionSizeofPointerOrArray(Sema &S, Expr *LHS, Expr *RHS,
-                                                 SourceLocation Loc) {
+                                          SourceLocation Loc) {
   const auto *LUE = dyn_cast<UnaryExprOrTypeTraitExpr>(LHS);
   const auto *RUE = dyn_cast<UnaryExprOrTypeTraitExpr>(RHS);
   if (!LUE || !RUE)
@@ -11415,7 +11431,7 @@ static void DiagnoseDivisionSizeofPointerOrArray(Sema &S, Expr *LHS, Expr *RHS,
   }
 }
 
-static void DiagnoseBadDivideOrRemainderValues(Sema &S, ExprResult &LHS,
+static void DiagnoseBadDivideOrRemainderValues(Sema& S, ExprResult &LHS,
                                                ExprResult &RHS,
                                                SourceLocation Loc, bool IsDiv) {
   // Check for division/remainder by zero.
@@ -11425,7 +11441,7 @@ static void DiagnoseBadDivideOrRemainderValues(Sema &S, ExprResult &LHS,
       RHSValue.Val.getInt() == 0)
     S.DiagRuntimeBehavior(Loc, RHS.get(),
                           S.PDiag(diag::warn_remainder_division_by_zero)
-                              << IsDiv << RHS.get()->getSourceRange());
+                            << IsDiv << RHS.get()->getSourceRange());
 }
 
 static void diagnoseScopedEnums(Sema &S, const SourceLocation Loc,
@@ -11512,8 +11528,8 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS,
   return compType;
 }
 
-QualType Sema::CheckRemainderOperands(ExprResult &LHS, ExprResult &RHS,
-                                      SourceLocation Loc, bool IsCompAssign) {
+QualType Sema::CheckRemainderOperands(
+  ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign) {
   checkArithmeticNull(*this, LHS, RHS, Loc, /*IsCompare=*/false);
 
   // Note: This check is here to simplify the double exclusions of
@@ -11580,19 +11596,19 @@ QualType Sema::CheckRemainderOperands(ExprResult &LHS, ExprResult &RHS,
 static void diagnoseArithmeticOnTwoVoidPointers(Sema &S, SourceLocation Loc,
                                                 Expr *LHSExpr, Expr *RHSExpr) {
   S.Diag(Loc, S.getLangOpts().CPlusPlus
-                  ? diag::err_typecheck_pointer_arith_void_type
-                  : diag::ext_gnu_void_ptr)
-      << 1 /* two pointers */ << LHSExpr->getSourceRange()
-      << RHSExpr->getSourceRange();
+                ? diag::err_typecheck_pointer_arith_void_type
+                : diag::ext_gnu_void_ptr)
+    << 1 /* two pointers */ << LHSExpr->getSourceRange()
+                            << RHSExpr->getSourceRange();
 }
 
 /// Diagnose invalid arithmetic on a void pointer.
 static void diagnoseArithmeticOnVoidPointer(Sema &S, SourceLocation Loc,
                                             Expr *Pointer) {
   S.Diag(Loc, S.getLangOpts().CPlusPlus
-                  ? diag::err_typecheck_pointer_arith_void_type
-                  : diag::ext_gnu_void_ptr)
-      << 0 /* one pointer */ << Pointer->getSourceRange();
+                ? diag::err_typecheck_pointer_arith_void_type
+                : diag::ext_gnu_void_ptr)
+    << 0 /* one pointer */ << Pointer->getSourceRange();
 }
 
 /// Diagnose invalid arithmetic on a null pointer.
@@ -11603,10 +11619,11 @@ static void diagnoseArithmeticOnVoidPointer(Sema &S, SourceLocation Loc,
 static void diagnoseArithmeticOnNullPointer(Sema &S, SourceLocation Loc,
                                             Expr *Pointer, bool IsGNUIdiom) {
   if (IsGNUIdiom)
-    S.Diag(Loc, diag::warn_gnu_null_ptr_arith) << Pointer->getSourceRange();
+    S.Diag(Loc, diag::warn_gnu_null_ptr_arith)
+      << Pointer->getSourceRange();
   else
     S.Diag(Loc, diag::warn_pointer_arith_null_ptr)
-        << S.getLangOpts().CPlusPlus << Pointer->getSourceRange();
+      << S.getLangOpts().CPlusPlus << Pointer->getSourceRange();
 }
 
 /// Diagnose invalid subraction on a null pointer.
@@ -11633,15 +11650,14 @@ static void diagnoseArithmeticOnTwoFunctionPointers(Sema &S, SourceLocation Loc,
   assert(LHS->getType()->isAnyPointerType());
   assert(RHS->getType()->isAnyPointerType());
   S.Diag(Loc, S.getLangOpts().CPlusPlus
-                  ? diag::err_typecheck_pointer_arith_function_type
-                  : diag::ext_gnu_ptr_func_arith)
-      << 1 /* two pointers */
-      << LHS->getType()->getPointeeType()
-      // We only show the second type if it differs from the first.
-      << (unsigned)!S.Context.hasSameUnqualifiedType(LHS->getType(),
-                                                     RHS->getType())
-      << RHS->getType()->getPointeeType() << LHS->getSourceRange()
-      << RHS->getSourceRange();
+                ? diag::err_typecheck_pointer_arith_function_type
+                : diag::ext_gnu_ptr_func_arith)
+    << 1 /* two pointers */ << LHS->getType()->getPointeeType()
+    // We only show the second type if it differs from the first.
+    << (unsigned)!S.Context.hasSameUnqualifiedType(LHS->getType(),
+                                                   RHS->getType())
+    << RHS->getType()->getPointeeType()
+    << LHS->getSourceRange() << RHS->getSourceRange();
 }
 
 /// Diagnose invalid arithmetic on a function pointer.
@@ -11649,11 +11665,11 @@ static void diagnoseArithmeticOnFunctionPointer(Sema &S, SourceLocation Loc,
                                                 Expr *Pointer) {
   assert(Pointer->getType()->isAnyPointerType());
   S.Diag(Loc, S.getLangOpts().CPlusPlus
-                  ? diag::err_typecheck_pointer_arith_function_type
-                  : diag::ext_gnu_ptr_func_arith)
-      << 0 /* one pointer */ << Pointer->getType()->getPointeeType()
-      << 0 /* one pointer, so only one type */
-      << Pointer->getSourceRange();
+                ? diag::err_typecheck_pointer_arith_function_type
+                : diag::ext_gnu_ptr_func_arith)
+    << 0 /* one pointer */ << Pointer->getType()->getPointeeType()
+    << 0 /* one pointer, so only one type */
+    << Pointer->getSourceRange();
 }
 
 /// Emit error if Operand is incomplete pointer type
@@ -11687,8 +11703,7 @@ static bool checkArithmeticOpPointerOperand(Sema &S, SourceLocation Loc,
   if (const AtomicType *ResAtomicType = ResType->getAs<AtomicType>())
     ResType = ResAtomicType->getValueType();
 
-  if (!ResType->isAnyPointerType())
-    return true;
+  if (!ResType->isAnyPointerType()) return true;
 
   QualType PointeeTy = ResType->getPointeeType();
   if (PointeeTy->isVoidType()) {
@@ -11700,8 +11715,7 @@ static bool checkArithmeticOpPointerOperand(Sema &S, SourceLocation Loc,
     return !S.getLangOpts().CPlusPlus;
   }
 
-  if (checkArithmeticIncompletePointerType(S, Loc, Operand))
-    return false;
+  if (checkArithmeticIncompletePointerType(S, Loc, Operand)) return false;
 
   return true;
 }
@@ -11719,14 +11733,11 @@ static bool checkArithmeticBinOpPointerOperands(Sema &S, SourceLocation Loc,
                                                 Expr *LHSExpr, Expr *RHSExpr) {
   bool isLHSPointer = LHSExpr->getType()->isAnyPointerType();
   bool isRHSPointer = RHSExpr->getType()->isAnyPointerType();
-  if (!isLHSPointer && !isRHSPointer)
-    return true;
+  if (!isLHSPointer && !isRHSPointer) return true;
 
   QualType LHSPointeeTy, RHSPointeeTy;
-  if (isLHSPointer)
-    LHSPointeeTy = LHSExpr->getType()->getPointeeType();
-  if (isRHSPointer)
-    RHSPointeeTy = RHSExpr->getType()->getPointeeType();
+  if (isLHSPointer) LHSPointeeTy = LHSExpr->getType()->getPointeeType();
+  if (isRHSPointer) RHSPointeeTy = RHSExpr->getType()->getPointeeType();
 
   // if both are pointers check if operation is valid wrt address spaces
   if (isLHSPointer && isRHSPointer) {
@@ -11744,12 +11755,9 @@ static bool checkArithmeticBinOpPointerOperands(Sema &S, SourceLocation Loc,
   bool isLHSVoidPtr = isLHSPointer && LHSPointeeTy->isVoidType();
   bool isRHSVoidPtr = isRHSPointer && RHSPointeeTy->isVoidType();
   if (isLHSVoidPtr || isRHSVoidPtr) {
-    if (!isRHSVoidPtr)
-      diagnoseArithmeticOnVoidPointer(S, Loc, LHSExpr);
-    else if (!isLHSVoidPtr)
-      diagnoseArithmeticOnVoidPointer(S, Loc, RHSExpr);
-    else
-      diagnoseArithmeticOnTwoVoidPointers(S, Loc, LHSExpr, RHSExpr);
+    if (!isRHSVoidPtr) diagnoseArithmeticOnVoidPointer(S, Loc, LHSExpr);
+    else if (!isLHSVoidPtr) diagnoseArithmeticOnVoidPointer(S, Loc, RHSExpr);
+    else diagnoseArithmeticOnTwoVoidPointers(S, Loc, LHSExpr, RHSExpr);
 
     return !S.getLangOpts().CPlusPlus;
   }
@@ -11757,12 +11765,10 @@ static bool checkArithmeticBinOpPointerOperands(Sema &S, SourceLocation Loc,
   bool isLHSFuncPtr = isLHSPointer && LHSPointeeTy->isFunctionType();
   bool isRHSFuncPtr = isRHSPointer && RHSPointeeTy->isFunctionType();
   if (isLHSFuncPtr || isRHSFuncPtr) {
-    if (!isRHSFuncPtr)
-      diagnoseArithmeticOnFunctionPointer(S, Loc, LHSExpr);
-    else if (!isLHSFuncPtr)
-      diagnoseArithmeticOnFunctionPointer(S, Loc, RHSExpr);
-    else
-      diagnoseArithmeticOnTwoFunctionPointers(S, Loc, LHSExpr, RHSExpr);
+    if (!isRHSFuncPtr) diagnoseArithmeticOnFunctionPointer(S, Loc, LHSExpr);
+    else if (!isLHSFuncPtr) diagnoseArithmeticOnFunctionPointer(S, Loc,
+                                                                RHSExpr);
+    else diagnoseArithmeticOnTwoFunctionPointers(S, Loc, LHSExpr, RHSExpr);
 
     return !S.getLangOpts().CPlusPlus;
   }
@@ -11779,15 +11785,15 @@ static bool checkArithmeticBinOpPointerOperands(Sema &S, SourceLocation Loc,
 /// literal.
 static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc,
                                   Expr *LHSExpr, Expr *RHSExpr) {
-  StringLiteral *StrExpr = dyn_cast<StringLiteral>(LHSExpr->IgnoreImpCasts());
-  Expr *IndexExpr = RHSExpr;
+  StringLiteral* StrExpr = dyn_cast<StringLiteral>(LHSExpr->IgnoreImpCasts());
+  Expr* IndexExpr = RHSExpr;
   if (!StrExpr) {
     StrExpr = dyn_cast<StringLiteral>(RHSExpr->IgnoreImpCasts());
     IndexExpr = LHSExpr;
   }
 
-  bool IsStringPlusInt =
-      StrExpr && IndexExpr->getType()->isIntegralOrUnscopedEnumerationType();
+  bool IsStringPlusInt = StrExpr &&
+      IndexExpr->getType()->isIntegralOrUnscopedEnumerationType();
   if (!IsStringPlusInt || IndexExpr->isValueDependent())
     return;
 
@@ -11835,9 +11841,11 @@ static void diagnoseStringPlusChar(Sema &Self, SourceLocation OpLoc,
   SourceRange DiagRange(LHSExpr->getBeginLoc(), RHSExpr->getEndLoc());
 
   const QualType CharType = CharExpr->getType();
-  if (!CharType->isAnyCharacterType() && CharType->isIntegerType() &&
+  if (!CharType->isAnyCharacterType() &&
+      CharType->isIntegerType() &&
       llvm::isUIntN(Ctx.getCharWidth(), CharExpr->getValue())) {
-    Self.Diag(OpLoc, diag::warn_string_plus_char) << DiagRange << Ctx.CharTy;
+    Self.Diag(OpLoc, diag::warn_string_plus_char)
+        << DiagRange << Ctx.CharTy;
   } else {
     Self.Diag(OpLoc, diag::warn_string_plus_char)
         << DiagRange << CharExpr->getType();
@@ -11861,14 +11869,14 @@ static void diagnosePointerIncompatibility(Sema &S, SourceLocation Loc,
   assert(LHSExpr->getType()->isAnyPointerType());
   assert(RHSExpr->getType()->isAnyPointerType());
   S.Diag(Loc, diag::err_typecheck_sub_ptr_compatible)
-      << LHSExpr->getType() << RHSExpr->getType() << LHSExpr->getSourceRange()
-      << RHSExpr->getSourceRange();
+    << LHSExpr->getType() << RHSExpr->getType() << LHSExpr->getSourceRange()
+    << RHSExpr->getSourceRange();
 }
 
 // C99 6.5.6
 QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS,
                                      SourceLocation Loc, BinaryOperatorKind Opc,
-                                     QualType *CompLHSTy) {
+                                     QualType* CompLHSTy) {
   checkArithmeticNull(*this, LHS, RHS, Loc, /*IsCompare=*/false);
 
   if (LHS.get()->getType()->isVectorType() ||
@@ -11879,8 +11887,7 @@ QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS,
                             /*AllowBoolConversions*/ getLangOpts().ZVector,
                             /*AllowBooleanOperation*/ false,
                             /*ReportInvalid*/ true);
-    if (CompLHSTy)
-      *CompLHSTy = compType;
+    if (CompLHSTy) *CompLHSTy = compType;
     return compType;
   }
 
@@ -11916,8 +11923,7 @@ QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS,
 
   // handle the common case first (both operands are arithmetic).
   if (!compType.isNull() && compType->isArithmeticType()) {
-    if (CompLHSTy)
-      *CompLHSTy = compType;
+    if (CompLHSTy) *CompLHSTy = compType;
     return compType;
   }
 
@@ -11952,9 +11958,10 @@ QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS,
           Context, Expr::NPC_ValueDependentIsNotNull)) {
     // In C++ adding zero to a null pointer is defined.
     Expr::EvalResult KnownVal;
-    if (!getLangOpts().CPlusPlus || (!IExp->isValueDependent() &&
-                                     (!IExp->EvaluateAsInt(KnownVal, Context) ||
-                                      KnownVal.Val.getInt() != 0))) {
+    if (!getLangOpts().CPlusPlus ||
+        (!IExp->isValueDependent() &&
+         (!IExp->EvaluateAsInt(KnownVal, Context) ||
+          KnownVal.Val.getInt() != 0))) {
       // Check the conditions to see if this is the 'p = nullptr + n' idiom.
       bool IsGNUIdiom = BinaryOperator::isNullPointerArithmeticExtension(
           Context, BO_Add, PExp, IExp);
@@ -12027,8 +12034,7 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
                             /*AllowBoolConversions*/ getLangOpts().ZVector,
                             /*AllowBooleanOperation*/ false,
                             /*ReportInvalid*/ true);
-    if (CompLHSTy)
-      *CompLHSTy = compType;
+    if (CompLHSTy) *CompLHSTy = compType;
     return compType;
   }
 
@@ -12060,8 +12066,7 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
 
   // Handle the common case first (both operands are arithmetic).
   if (!compType.isNull() && compType->isArithmeticType()) {
-    if (CompLHSTy)
-      *CompLHSTy = compType;
+    if (CompLHSTy) *CompLHSTy = compType;
     return compType;
   }
 
@@ -12088,8 +12093,8 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
       // Subtracting from a null pointer should produce a warning.
       // The last argument to the diagnose call says this doesn't match the
       // GNU int-to-pointer idiom.
-      if (LHS.get()->IgnoreParenCasts()->isNullPointerConstant(
-              Context, Expr::NPC_ValueDependentIsNotNull)) {
+      if (LHS.get()->IgnoreParenCasts()->isNullPointerConstant(Context,
+                                           Expr::NPC_ValueDependentIsNotNull)) {
         // In C++ adding zero to a null pointer is defined.
         Expr::EvalResult KnownVal;
         if (!getLangOpts().CPlusPlus ||
@@ -12104,17 +12109,16 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
         return QualType();
 
       // Check array bounds for pointer arithemtic
-      CheckArrayAccess(LHS.get(), RHS.get(), /*ArraySubscriptExpr*/ nullptr,
-                       /*AllowOnePastEnd*/ true, /*IndexNegated*/ true);
+      CheckArrayAccess(LHS.get(), RHS.get(), /*ArraySubscriptExpr*/nullptr,
+                       /*AllowOnePastEnd*/true, /*IndexNegated*/true);
 
-      if (CompLHSTy)
-        *CompLHSTy = LHS.get()->getType();
+      if (CompLHSTy) *CompLHSTy = LHS.get()->getType();
       return LHS.get()->getType();
     }
 
     // Handle pointer-pointer subtractions.
-    if (const PointerType *RHSPTy =
-            RHS.get()->getType()->getAs<PointerType>()) {
+    if (const PointerType *RHSPTy
+          = RHS.get()->getType()->getAs<PointerType>()) {
       QualType rpointee = RHSPTy->getPointeeType();
 
       if (getLangOpts().CPlusPlus) {
@@ -12132,8 +12136,8 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
         }
       }
 
-      if (!checkArithmeticBinOpPointerOperands(*this, Loc, LHS.get(),
-                                               RHS.get()))
+      if (!checkArithmeticBinOpPointerOperands(*this, Loc,
+                                               LHS.get(), RHS.get()))
         return QualType();
 
       // For pointer subtraction, if the address spaces differ but overlap,
@@ -12186,8 +12190,7 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
             << rpointee.getUnqualifiedType() << LHS.get()->getSourceRange()
             << RHS.get()->getSourceRange();
 
-      if (CompLHSTy)
-        *CompLHSTy = LHS.get()->getType();
+      if (CompLHSTy) *CompLHSTy = LHS.get()->getType();
       return Context.getPointerDiffType();
     }
   }
@@ -12203,12 +12206,11 @@ static bool isScopedEnumerationType(QualType T) {
   return false;
 }
 
-static void DiagnoseBadShiftValues(Sema &S, ExprResult &LHS, ExprResult &RHS,
+static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
                                    SourceLocation Loc, BinaryOperatorKind Opc,
                                    QualType LHSType) {
-  // OpenCL 6.3j: shift values are effectively % word size of LHS (more
-  // defined), so skip remaining warnings as we don't want to modify values
-  // within Sema.
+  // OpenCL 6.3j: shift values are effectively % word size of LHS (more defined),
+  // so skip remaining warnings as we don't want to modify values within Sema.
   if (S.getLangOpts().OpenCL)
     return;
 
@@ -12296,8 +12298,8 @@ static void DiagnoseBadShiftValues(Sema &S, ExprResult &LHS, ExprResult &RHS,
   // turned off separately if needed.
   if (ResultBits - 1 == LeftSize) {
     S.Diag(Loc, diag::warn_shift_result_sets_sign_bit)
-        << HexResult << LHSType << LHS.get()->getSourceRange()
-        << RHS.get()->getSourceRange();
+        << HexResult << LHSType
+        << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
     return;
   }
 
@@ -12315,20 +12317,18 @@ static QualType checkVectorShift(Sema &S, ExprResult &LHS, ExprResult &RHS,
   if ((S.LangOpts.OpenCL || S.LangOpts.ZVector) &&
       !LHS.get()->getType()->isVectorType()) {
     S.Diag(Loc, diag::err_shift_rhs_only_vector)
-        << RHS.get()->getType() << LHS.get()->getType()
-        << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
+      << RHS.get()->getType() << LHS.get()->getType()
+      << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
     return QualType();
   }
 
   if (!IsCompAssign) {
     LHS = S.UsualUnaryConversions(LHS.get());
-    if (LHS.isInvalid())
-      return QualType();
+    if (LHS.isInvalid()) return QualType();
   }
 
   RHS = S.UsualUnaryConversions(RHS.get());
-  if (RHS.isInvalid())
-    return QualType();
+  if (RHS.isInvalid()) return QualType();
 
   QualType LHSType = LHS.get()->getType();
   // Note that LHS might be a scalar because the routine calls not only in
@@ -12353,13 +12353,13 @@ static QualType checkVectorShift(Sema &S, ExprResult &LHS, ExprResult &RHS,
   // The operands need to be integers.
   if (!LHSEleType->isIntegerType()) {
     S.Diag(Loc, diag::err_typecheck_expect_int)
-        << LHS.get()->getType() << LHS.get()->getSourceRange();
+      << LHS.get()->getType() << LHS.get()->getSourceRange();
     return QualType();
   }
 
   if (!RHSEleType->isIntegerType()) {
     S.Diag(Loc, diag::err_typecheck_expect_int)
-        << RHS.get()->getType() << RHS.get()->getSourceRange();
+      << RHS.get()->getType() << RHS.get()->getSourceRange();
     return QualType();
   }
 
@@ -12368,7 +12368,7 @@ static QualType checkVectorShift(Sema &S, ExprResult &LHS, ExprResult &RHS,
     if (IsCompAssign)
       return RHSType;
     if (LHSEleType != RHSEleType) {
-      LHS = S.ImpCastExprToType(LHS.get(), RHSEleType, CK_IntegralCast);
+      LHS = S.ImpCastExprToType(LHS.get(),RHSEleType, CK_IntegralCast);
       LHSEleType = RHSEleType;
     }
     QualType VecTy =
@@ -12381,8 +12381,8 @@ static QualType checkVectorShift(Sema &S, ExprResult &LHS, ExprResult &RHS,
     // that the number of elements is the same as LHS...
     if (RHSVecTy->getNumElements() != LHSVecTy->getNumElements()) {
       S.Diag(Loc, diag::err_typecheck_vector_lengths_not_equal)
-          << LHS.get()->getType() << RHS.get()->getType()
-          << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
+        << LHS.get()->getType() << RHS.get()->getType()
+        << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
       return QualType();
     }
     if (!S.LangOpts.OpenCL && !S.LangOpts.ZVector) {
@@ -12398,7 +12398,7 @@ static QualType checkVectorShift(Sema &S, ExprResult &LHS, ExprResult &RHS,
   } else {
     // ...else expand RHS to match the number of elements in LHS.
     QualType VecTy =
-        S.Context.getExtVectorType(RHSEleType, LHSVecTy->getNumElements());
+      S.Context.getExtVectorType(RHSEleType, LHSVecTy->getNumElements());
     RHS = S.ImpCastExprToType(RHS.get(), VecTy, CK_VectorSplat);
   }
 
@@ -12533,8 +12533,7 @@ QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS,
   if (LHS.isInvalid())
     return QualType();
   QualType LHSType = LHS.get()->getType();
-  if (IsCompAssign)
-    LHS = OldLHS;
+  if (IsCompAssign) LHS = OldLHS;
 
   // The RHS is simpler.
   RHS = UsualUnaryConversions(RHS.get());
@@ -12564,8 +12563,8 @@ static void diagnoseDistinctPointerComparison(Sema &S, SourceLocation Loc,
                                               bool IsError) {
   S.Diag(Loc, IsError ? diag::err_typecheck_comparison_of_distinct_pointers
                       : diag::ext_typecheck_comparison_of_distinct_pointers)
-      << LHS.get()->getType() << RHS.get()->getType()
-      << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
+    << LHS.get()->getType() << RHS.get()->getType()
+    << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
 }
 
 /// Returns false if the pointers are converted to a composite type,
@@ -12590,7 +12589,7 @@ static bool convertPointersToCompositeType(Sema &S, SourceLocation Loc,
   if (T.isNull()) {
     if ((LHSType->isAnyPointerType() || LHSType->isMemberPointerType()) &&
         (RHSType->isAnyPointerType() || RHSType->isMemberPointerType()))
-      diagnoseDistinctPointerComparison(S, Loc, LHS, RHS, /*isError*/ true);
+      diagnoseDistinctPointerComparison(S, Loc, LHS, RHS, /*isError*/true);
     else
       S.InvalidOperands(Loc, LHS, RHS);
     return true;
@@ -12605,8 +12604,8 @@ static void diagnoseFunctionPointerToVoidComparison(Sema &S, SourceLocation Loc,
                                                     bool IsError) {
   S.Diag(Loc, IsError ? diag::err_typecheck_comparison_of_fptr_to_void
                       : diag::ext_typecheck_comparison_of_fptr_to_void)
-      << LHS.get()->getType() << RHS.get()->getType()
-      << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
+    << LHS.get()->getType() << RHS.get()->getType()
+    << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
 }
 
 static bool isObjCObjectLiteral(ExprResult &E) {
@@ -12624,7 +12623,7 @@ static bool isObjCObjectLiteral(ExprResult &E) {
 
 static bool hasIsEqualMethod(Sema &S, const Expr *LHS, const Expr *RHS) {
   const ObjCObjectPointerType *Type =
-      LHS->getType()->getAs<ObjCObjectPointerType>();
+    LHS->getType()->getAs<ObjCObjectPointerType>();
 
   // If this is not actually an Objective-C object, bail out.
   if (!Type)
@@ -12671,7 +12670,7 @@ static bool hasIsEqualMethod(Sema &S, const Expr *LHS, const Expr *RHS) {
 
 static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc,
                                           ExprResult &LHS, ExprResult &RHS,
-                                          BinaryOperator::Opcode Opc) {
+                                          BinaryOperator::Opcode Opc){
   Expr *Literal;
   Expr *Other;
   if (isObjCObjectLiteral(LHS)) {
@@ -12699,22 +12698,22 @@ static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc,
 
   if (LiteralKind == SemaObjC::LK_String)
     S.Diag(Loc, diag::warn_objc_string_literal_comparison)
-        << Literal->getSourceRange();
+      << Literal->getSourceRange();
   else
     S.Diag(Loc, diag::warn_objc_literal_comparison)
-        << LiteralKind << Literal->getSourceRange();
+      << LiteralKind << Literal->getSourceRange();
 
   if (BinaryOperator::isEqualityOp(Opc) &&
       hasIsEqualMethod(S, LHS.get(), RHS.get())) {
     SourceLocation Start = LHS.get()->getBeginLoc();
     SourceLocation End = S.getLocForEndOfToken(RHS.get()->getEndLoc());
     CharSourceRange OpRange =
-        CharSourceRange::getCharRange(Loc, S.getLocForEndOfToken(Loc));
+      CharSourceRange::getCharRange(Loc, S.getLocForEndOfToken(Loc));
 
     S.Diag(Loc, diag::note_objc_literal_comparison_isequal)
-        << FixItHint::CreateInsertion(Start, Opc == BO_EQ ? "[" : "![")
-        << FixItHint::CreateReplacement(OpRange, " isEqual:")
-        << FixItHint::CreateInsertion(End, "]");
+      << FixItHint::CreateInsertion(Start, Opc == BO_EQ ? "[" : "![")
+      << FixItHint::CreateReplacement(OpRange, " isEqual:")
+      << FixItHint::CreateInsertion(End, "]");
   }
 }
 
@@ -12724,17 +12723,14 @@ static void diagnoseLogicalNotOnLHSofCheck(Sema &S, ExprResult &LHS,
                                            BinaryOperatorKind Opc) {
   // Check that left hand side is !something.
   UnaryOperator *UO = dyn_cast<UnaryOperator>(LHS.get()->IgnoreImpCasts());
-  if (!UO || UO->getOpcode() != UO_LNot)
-    return;
+  if (!UO || UO->getOpcode() != UO_LNot) return;
 
   // Only check if the right hand side is non-bool arithmetic type.
-  if (RHS.get()->isKnownToHaveBooleanValue())
-    return;
+  if (RHS.get()->isKnownToHaveBooleanValue()) return;
 
   // Make sure that the something in !something is not bool.
   Expr *SubExpr = UO->getSubExpr()->IgnoreImpCasts();
-  if (SubExpr->isKnownToHaveBooleanValue())
-    return;
+  if (SubExpr->isKnownToHaveBooleanValue()) return;
 
   // Emit warning.
   bool IsBitwiseOp = Opc == BO_And || Opc == BO_Or || Opc == BO_Xor;
@@ -12748,7 +12744,8 @@ static void diagnoseLogicalNotOnLHSofCheck(Sema &S, ExprResult &LHS,
   if (FirstClose.isInvalid())
     FirstOpen = SourceLocation();
   S.Diag(UO->getOperatorLoc(), diag::note_logical_not_fix)
-      << IsBitwiseOp << FixItHint::CreateInsertion(FirstOpen, "(")
+      << IsBitwiseOp
+      << FixItHint::CreateInsertion(FirstOpen, "(")
       << FixItHint::CreateInsertion(FirstClose, ")");
 
   // Second note suggests (!x) < y
@@ -12955,8 +12952,8 @@ static void diagnoseTautologicalComparison(Sema &S, SourceLocation Loc,
     LiteralStringStripped = LHSStripped;
   } else if ((isa<StringLiteral>(RHSStripped) ||
               isa<ObjCEncodeExpr>(RHSStripped)) &&
-             !LHSStripped->isNullPointerConstant(
-                 S.Context, Expr::NPC_ValueDependentIsNull)) {
+             !LHSStripped->isNullPointerConstant(S.Context,
+                                          Expr::NPC_ValueDependentIsNull)) {
     LiteralString = RHS;
     LiteralStringStripped = RHSStripped;
   }
@@ -13172,7 +13169,7 @@ void Sema::CheckPtrComparisonWithNullChar(ExprResult &E, ExprResult &NullE) {
   if (!E.get()->getType()->isAnyPointerType() &&
       E.get()->isNullPointerConstant(Context,
                                      Expr::NPC_ValueDependentIsNotNull) ==
-          Expr::NPCK_ZeroExpression) {
+        Expr::NPCK_ZeroExpression) {
     if (const auto *CL = dyn_cast<CharacterLiteral>(E.get())) {
       if (CL->getValue() == 0)
         Diag(E.get()->getExprLoc(), diag::warn_pointer_compare)
@@ -13180,14 +13177,14 @@ void Sema::CheckPtrComparisonWithNullChar(ExprResult &E, ExprResult &NullE) {
             << FixItHint::CreateReplacement(E.get()->getExprLoc(),
                                             NullValue ? "NULL" : "(void *)0");
     } else if (const auto *CE = dyn_cast<CStyleCastExpr>(E.get())) {
-      TypeSourceInfo *TI = CE->getTypeInfoAsWritten();
-      QualType T = Context.getCanonicalType(TI->getType()).getUnqualifiedType();
-      if (T == Context.CharTy)
-        Diag(E.get()->getExprLoc(), diag::warn_pointer_compare)
-            << NullValue
-            << FixItHint::CreateReplacement(E.get()->getExprLoc(),
-                                            NullValue ? "NULL" : "(void *)0");
-    }
+        TypeSourceInfo *TI = CE->getTypeInfoAsWritten();
+        QualType T = Context.getCanonicalType(TI->getType()).getUnqualifiedType();
+        if (T == Context.CharTy)
+          Diag(E.get()->getExprLoc(), diag::warn_pointer_compare)
+              << NullValue
+              << FixItHint::CreateReplacement(E.get()->getExprLoc(),
+                                              NullValue ? "NULL" : "(void *)0");
+      }
   }
 }
 
@@ -13368,9 +13365,9 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
     // All of the following pointer-related warnings are GCC extensions, except
     // when handling null pointer constants.
     QualType LCanPointeeTy =
-        LHSType->castAs<PointerType>()->getPointeeType().getCanonicalType();
+      LHSType->castAs<PointerType>()->getPointeeType().getCanonicalType();
     QualType RCanPointeeTy =
-        RHSType->castAs<PointerType>()->getPointeeType().getCanonicalType();
+      RHSType->castAs<PointerType>()->getPointeeType().getCanonicalType();
 
     // C99 6.5.9p2 and C99 6.5.8p2
     if (Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),
@@ -13389,15 +13386,13 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
     } else if (!IsRelational &&
                (LCanPointeeTy->isVoidType() || RCanPointeeTy->isVoidType())) {
       // Valid unless comparison between non-null pointer and function pointer
-      if ((LCanPointeeTy->isFunctionType() ||
-           RCanPointeeTy->isFunctionType()) &&
-          !LHSIsNull && !RHSIsNull)
+      if ((LCanPointeeTy->isFunctionType() || RCanPointeeTy->isFunctionType())
+          && !LHSIsNull && !RHSIsNull)
         diagnoseFunctionPointerToVoidComparison(*this, Loc, LHS, RHS,
-                                                /*isError*/ false);
+                                                /*isError*/false);
     } else {
       // Invalid
-      diagnoseDistinctPointerComparison(*this, Loc, LHS, RHS,
-                                        /*isError*/ false);
+      diagnoseDistinctPointerComparison(*this, Loc, LHS, RHS, /*isError*/false);
     }
     if (LCanPointeeTy != RCanPointeeTy) {
       // Treat NULL constant as a special case in OpenCL.
@@ -13412,8 +13407,8 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
       }
       LangAS AddrSpaceL = LCanPointeeTy.getAddressSpace();
       LangAS AddrSpaceR = RCanPointeeTy.getAddressSpace();
-      CastKind Kind =
-          AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast;
+      CastKind Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion
+                                               : CK_BitCast;
 
       const FunctionType *LFn = LCanPointeeTy->getAs<FunctionType>();
       const FunctionType *RFn = RCanPointeeTy->getAs<FunctionType>();
@@ -13430,6 +13425,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
     return computeResultTy();
   }
 
+
   // C++ [expr.eq]p4:
   //   Two operands of type std::nullptr_t or one operand of type
   //   std::nullptr_t and the other a null pointer constant compare
@@ -13524,36 +13520,34 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
     if (!LHSIsNull && !RHSIsNull &&
         !Context.typesAreCompatible(lpointee, rpointee)) {
       Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
-          << LHSType << RHSType << LHS.get()->getSourceRange()
-          << RHS.get()->getSourceRange();
+        << LHSType << RHSType << LHS.get()->getSourceRange()
+        << RHS.get()->getSourceRange();
     }
     RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
     return computeResultTy();
   }
 
   // Allow block pointers to be compared with null pointer constants.
-  if (!IsOrdered &&
-      ((LHSType->isBlockPointerType() && RHSType->isPointerType()) ||
-       (LHSType->isPointerType() && RHSType->isBlockPointerType()))) {
+  if (!IsOrdered
+      && ((LHSType->isBlockPointerType() && RHSType->isPointerType())
+          || (LHSType->isPointerType() && RHSType->isBlockPointerType()))) {
     if (!LHSIsNull && !RHSIsNull) {
-      if (!((RHSType->isPointerType() &&
-             RHSType->castAs<PointerType>()->getPointeeType()->isVoidType()) ||
-            (LHSType->isPointerType() &&
-             LHSType->castAs<PointerType>()->getPointeeType()->isVoidType())))
+      if (!((RHSType->isPointerType() && RHSType->castAs<PointerType>()
+             ->getPointeeType()->isVoidType())
+            || (LHSType->isPointerType() && LHSType->castAs<PointerType>()
+                ->getPointeeType()->isVoidType())))
         Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
-            << LHSType << RHSType << LHS.get()->getSourceRange()
-            << RHS.get()->getSourceRange();
+          << LHSType << RHSType << LHS.get()->getSourceRange()
+          << RHS.get()->getSourceRange();
     }
     if (LHSIsNull && !RHSIsNull)
       LHS = ImpCastExprToType(LHS.get(), RHSType,
-                              RHSType->isPointerType()
-                                  ? CK_BitCast
-                                  : CK_AnyPointerToBlockPointerCast);
+                              RHSType->isPointerType() ? CK_BitCast
+                                : CK_AnyPointerToBlockPointerCast);
     else
       RHS = ImpCastExprToType(RHS.get(), LHSType,
-                              LHSType->isPointerType()
-                                  ? CK_BitCast
-                                  : CK_AnyPointerToBlockPointerCast);
+                              LHSType->isPointerType() ? CK_BitCast
+                                : CK_AnyPointerToBlockPointerCast);
     return computeResultTy();
   }
 
@@ -13568,7 +13562,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
       if (!LPtrToVoid && !RPtrToVoid &&
           !Context.typesAreCompatible(LHSType, RHSType)) {
         diagnoseDistinctPointerComparison(*this, Loc, LHS, RHS,
-                                          /*isError*/ false);
+                                          /*isError*/false);
       }
       // FIXME: If LPtrToVoid, we should presumably convert the LHS rather than
       // the RHS, but we have test coverage for this behavior.
@@ -13578,17 +13572,18 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
         if (getLangOpts().ObjCAutoRefCount)
           ObjC().CheckObjCConversion(SourceRange(), RHSType, E,
                                      CheckedConversionKind::Implicit);
-        LHS = ImpCastExprToType(
-            E, RHSType, RPT ? CK_BitCast : CK_CPointerToObjCPointerCast);
-      } else {
+        LHS = ImpCastExprToType(E, RHSType,
+                                RPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
+      }
+      else {
         Expr *E = RHS.get();
         if (getLangOpts().ObjCAutoRefCount)
           ObjC().CheckObjCConversion(SourceRange(), LHSType, E,
                                      CheckedConversionKind::Implicit,
                                      /*Diagnose=*/true,
                                      /*DiagnoseCFAudited=*/false, Opc);
-        RHS = ImpCastExprToType(
-            E, LHSType, LPT ? CK_BitCast : CK_CPointerToObjCPointerCast);
+        RHS = ImpCastExprToType(E, LHSType,
+                                LPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
       }
       return computeResultTy();
     }
@@ -13596,7 +13591,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
         RHSType->isObjCObjectPointerType()) {
       if (!Context.areComparableObjCPointerTypes(LHSType, RHSType))
         diagnoseDistinctPointerComparison(*this, Loc, LHS, RHS,
-                                          /*isError*/ false);
+                                          /*isError*/false);
       if (isObjCObjectLiteral(LHS) || isObjCObjectLiteral(RHS))
         diagnoseObjCLiteralComparison(*this, Loc, LHS, RHS, Opc);
 
@@ -13632,9 +13627,8 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
       if (IsOrdered) {
         isError = getLangOpts().CPlusPlus;
         DiagID =
-            isError
-                ? diag::err_typecheck_ordered_comparison_of_pointer_and_zero
-                : diag::ext_typecheck_ordered_comparison_of_pointer_and_zero;
+          isError ? diag::err_typecheck_ordered_comparison_of_pointer_and_zero
+                  : diag::ext_typecheck_ordered_comparison_of_pointer_and_zero;
       }
     } else if (getLangOpts().CPlusPlus) {
       DiagID = diag::err_typecheck_comparison_of_pointer_integer;
@@ -13645,31 +13639,30 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
       DiagID = diag::ext_typecheck_comparison_of_pointer_integer;
 
     if (DiagID) {
-      Diag(Loc, DiagID) << LHSType << RHSType << LHS.get()->getSourceRange()
-                        << RHS.get()->getSourceRange();
+      Diag(Loc, DiagID)
+        << LHSType << RHSType << LHS.get()->getSourceRange()
+        << RHS.get()->getSourceRange();
       if (isError)
         return QualType();
     }
 
     if (LHSType->isIntegerType())
       LHS = ImpCastExprToType(LHS.get(), RHSType,
-                              LHSIsNull ? CK_NullToPointer
-                                        : CK_IntegralToPointer);
+                        LHSIsNull ? CK_NullToPointer : CK_IntegralToPointer);
     else
       RHS = ImpCastExprToType(RHS.get(), LHSType,
-                              RHSIsNull ? CK_NullToPointer
-                                        : CK_IntegralToPointer);
+                        RHSIsNull ? CK_NullToPointer : CK_IntegralToPointer);
     return computeResultTy();
   }
 
   // Handle block pointers.
-  if (!IsOrdered && RHSIsNull && LHSType->isBlockPointerType() &&
-      RHSType->isIntegerType()) {
+  if (!IsOrdered && RHSIsNull
+      && LHSType->isBlockPointerType() && RHSType->isIntegerType()) {
     RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer);
     return computeResultTy();
   }
-  if (!IsOrdered && LHSIsNull && LHSType->isIntegerType() &&
-      RHSType->isBlockPointerType()) {
+  if (!IsOrdered && LHSIsNull
+      && LHSType->isIntegerType() && RHSType->isBlockPointerType()) {
     LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer);
     return computeResultTy();
   }
@@ -14353,14 +14346,11 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
 
 static bool IsReadonlyMessage(Expr *E, Sema &S) {
   const MemberExpr *ME = dyn_cast<MemberExpr>(E);
-  if (!ME)
-    return false;
-  if (!isa<FieldDecl>(ME->getMemberDecl()))
-    return false;
+  if (!ME) return false;
+  if (!isa<FieldDecl>(ME->getMemberDecl())) return false;
   ObjCMessageExpr *Base = dyn_cast<ObjCMessageExpr>(
       ME->getBase()->IgnoreImplicit()->IgnoreParenImpCasts());
-  if (!Base)
-    return false;
+  if (!Base) return false;
   return Base->getMethodDecl() != nullptr;
 }
 
@@ -14374,10 +14364,8 @@ static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) {
 
   // Must be a reference to a declaration from an enclosing scope.
   DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
-  if (!DRE)
-    return NCCK_None;
-  if (!DRE->refersToEnclosingVariableOrCapture())
-    return NCCK_None;
+  if (!DRE) return NCCK_None;
+  if (!DRE->refersToEnclosingVariableOrCapture()) return NCCK_None;
 
   ValueDecl *Value = DRE->getDecl();
 
@@ -14516,8 +14504,8 @@ static void DiagnoseConstAssignment(Sema &S, const Expr *E,
     const FunctionDecl *FD = CE->getDirectCallee();
     if (FD && !IsTypeModifiable(FD->getReturnType(), IsDereference)) {
       if (!DiagnosticEmitted) {
-        S.Diag(Loc, diag::err_typecheck_assign_const)
-            << ExprRange << ConstFunction << FD;
+        S.Diag(Loc, diag::err_typecheck_assign_const) << ExprRange
+                                                      << ConstFunction << FD;
         DiagnosticEmitted = true;
       }
       S.Diag(FD->getReturnTypeSourceRange().getBegin(),
@@ -14561,7 +14549,11 @@ static void DiagnoseConstAssignment(Sema &S, const Expr *E,
   S.Diag(Loc, diag::err_typecheck_assign_const) << ExprRange << ConstUnknown;
 }
 
-enum OriginalExprKind { OEK_Variable, OEK_Member, OEK_LValue };
+enum OriginalExprKind {
+  OEK_Variable,
+  OEK_Member,
+  OEK_LValue
+};
 
 static void DiagnoseRecursiveConstFields(Sema &S, const ValueDecl *VD,
                                          const RecordType *Ty,
@@ -14584,12 +14576,13 @@ static void DiagnoseRecursiveConstFields(Sema &S, const ValueDecl *VD,
       if (FieldTy.isConstQualified()) {
         if (!DiagnosticEmitted) {
           S.Diag(Loc, diag::err_typecheck_assign_const)
-              << Range << NestedConstMember << OEK << VD << IsNested << Field;
+              << Range << NestedConstMember << OEK << VD
+              << IsNested << Field;
           DiagnosticEmitted = true;
         }
         S.Diag(Field->getLocation(), diag::note_typecheck_assign_const)
-            << NestedConstMember << IsNested << Field << FieldTy
-            << Field->getSourceRange();
+            << NestedConstMember << IsNested << Field
+            << FieldTy << Field->getSourceRange();
       }
 
       // Then we append it to the list to check next in order.
@@ -14614,14 +14607,14 @@ static void DiagnoseRecursiveConstFields(Sema &S, const Expr *E,
   bool DiagEmitted = false;
 
   if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
-    DiagnoseRecursiveConstFields(S, ME->getMemberDecl(), RTy, Loc, Range,
-                                 OEK_Member, DiagEmitted);
+    DiagnoseRecursiveConstFields(S, ME->getMemberDecl(), RTy, Loc,
+            Range, OEK_Member, DiagEmitted);
   else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
-    DiagnoseRecursiveConstFields(S, DRE->getDecl(), RTy, Loc, Range,
-                                 OEK_Variable, DiagEmitted);
+    DiagnoseRecursiveConstFields(S, DRE->getDecl(), RTy, Loc,
+            Range, OEK_Variable, DiagEmitted);
   else
-    DiagnoseRecursiveConstFields(S, nullptr, RTy, Loc, Range, OEK_LValue,
-                                 DiagEmitted);
+    DiagnoseRecursiveConstFields(S, nullptr, RTy, Loc,
+            Range, OEK_LValue, DiagEmitted);
   if (!DiagEmitted)
     DiagnoseConstAssignment(S, E, Loc);
 }
@@ -14634,7 +14627,8 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {
   S.CheckShadowingDeclModification(E, Loc);
 
   SourceLocation OrigLoc = Loc;
-  Expr::isModifiableLvalueResult IsLV = E->isModifiableLvalue(S.Context, &Loc);
+  Expr::isModifiableLvalueResult IsLV = E->isModifiableLvalue(S.Context,
+                                                              &Loc);
   if (IsLV == Expr::MLV_ClassTemporary && IsReadonlyMessage(E, S))
     IsLV = Expr::MLV_InvalidMessageExpression;
   if (IsLV == Expr::MLV_Valid)
@@ -14671,15 +14665,15 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {
           ObjCMethodDecl *method = S.getCurMethodDecl();
           if (method && var == method->getSelfDecl()) {
             DiagID = method->isClassMethod()
-                         ? diag::err_typecheck_arc_assign_self_class_method
-                         : diag::err_typecheck_arc_assign_self;
+              ? diag::err_typecheck_arc_assign_self_class_method
+              : diag::err_typecheck_arc_assign_self;
 
-            //  - Objective-C externally_retained attribute.
+          //  - Objective-C externally_retained attribute.
           } else if (var->hasAttr<ObjCExternallyRetainedAttr>() ||
                      isa<ParmVarDecl>(var)) {
             DiagID = diag::err_typecheck_arc_assign_externally_retained;
 
-            //  - fast enumeration variables
+          //  - fast enumeration variables
           } else {
             DiagID = diag::err_typecheck_arr_assign_enumeration;
           }
@@ -14730,9 +14724,8 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {
     break;
   case Expr::MLV_IncompleteType:
   case Expr::MLV_IncompleteVoidType:
-    return S.RequireCompleteType(
-        Loc, E->getType(),
-        diag::err_typecheck_incomplete_type_not_modifiable_lvalue, E);
+    return S.RequireCompleteType(Loc, E->getType(),
+             diag::err_typecheck_incomplete_type_not_modifiable_lvalue, E);
   case Expr::MLV_DuplicateVectorComponents:
     DiagID = diag::err_typecheck_duplicate_vector_components_not_mlvalue;
     break;
@@ -14760,7 +14753,8 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {
 }
 
 static void CheckIdentityFieldAssignment(Expr *LHSExpr, Expr *RHSExpr,
-                                         SourceLocation Loc, Sema &Sema) {
+                                         SourceLocation Loc,
+                                         Sema &Sema) {
   if (Sema.inTemplateInstantiation())
     return;
   if (Sema.isUnevaluatedContext())
@@ -14814,8 +14808,8 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
     return QualType();
 
   QualType LHSType = LHSExpr->getType();
-  QualType RHSType =
-      CompoundType.isNull() ? RHS.get()->getType() : CompoundType;
+  QualType RHSType = CompoundType.isNull() ? RHS.get()->getType() :
+                                             CompoundType;
 
   if (RHS.isUsable()) {
     // Even if this check fails don't return early to allow the best
@@ -14842,8 +14836,8 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
   if (getLangOpts().OpenCL &&
       !getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts()) &&
       LHSType->isHalfType()) {
-    Diag(Loc, diag::err_opencl_half_load_store)
-        << 1 << LHSType.getUnqualifiedType();
+    Diag(Loc, diag::err_opencl_half_load_store) << 1
+        << LHSType.getUnqualifiedType();
     return QualType();
   }
 
@@ -14889,8 +14883,8 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
           Loc.getLocWithOffset(2) != UO->getSubExpr()->getBeginLoc() &&
           UO->getSubExpr()->getBeginLoc().isFileID()) {
         Diag(Loc, diag::warn_not_compound_assign)
-            << (UO->getOpcode() == UO_Plus ? "+" : "-")
-            << SourceRange(UO->getOperatorLoc(), UO->getOperatorLoc());
+          << (UO->getOpcode() == UO_Plus ? "+" : "-")
+          << SourceRange(UO->getOperatorLoc(), UO->getOperatorLoc());
       }
     }
 
@@ -15082,7 +15076,7 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,
     // Increment of bool sets it to true, but is deprecated.
     S.Diag(OpLoc, S.getLangOpts().CPlusPlus17 ? diag::ext_increment_bool
                                               : diag::warn_increment_bool)
-        << Op->getSourceRange();
+      << Op->getSourceRange();
   } else if (S.getLangOpts().CPlusPlus && ResType->isEnumeralType()) {
     // Error on enum increments and decrements in C++ mode
     S.Diag(OpLoc, diag::err_increment_decrement_enum) << IsInc << ResType;
@@ -15107,10 +15101,9 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,
         << IsInc << Op->getSourceRange();
   } else if (ResType->isPlaceholderType()) {
     ExprResult PR = S.CheckPlaceholderExpr(Op);
-    if (PR.isInvalid())
-      return QualType();
-    return CheckIncrementDecrementOperand(S, PR.get(), VK, OK, OpLoc, IsInc,
-                                          IsPrefix);
+    if (PR.isInvalid()) return QualType();
+    return CheckIncrementDecrementOperand(S, PR.get(), VK, OK, OpLoc,
+                                          IsInc, IsPrefix);
   } else if (S.getLangOpts().AltiVec && ResType->isVectorType()) {
     // OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 )
   } else if (S.getLangOpts().ZVector && ResType->isVectorType() &&
@@ -15122,7 +15115,7 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,
     // OpenCL V1.2 6.3 says dec/inc ops operate on integer vector types.
   } else {
     S.Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement)
-        << ResType << int(IsInc) << Op->getSourceRange();
+      << ResType << int(IsInc) << Op->getSourceRange();
     return QualType();
   }
   // At this point, we know we have a real, complex or pointer type.
@@ -15199,8 +15192,8 @@ static PrimaryObject getPrimaryObject(Expr *E) {
 /// Diagnose invalid operand for address of operations.
 ///
 /// \param Type The type of operand which cannot have its address taken.
-static void diagnoseAddressOfInvalidType(Sema &S, SourceLocation Loc, Expr *E,
-                                         unsigned Type) {
+static void diagnoseAddressOfInvalidType(Sema &S, SourceLocation Loc,
+                                         Expr *E, unsigned Type) {
   S.Diag(Loc, diag::err_typecheck_address_of) << Type << E->getSourceRange();
 }
 
@@ -15233,14 +15226,13 @@ bool Sema::CheckUseOfCXXMethodAsAddressOfOperand(SourceLocation OpLoc,
 }
 
 QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
-  if (const BuiltinType *PTy =
-          OrigOp.get()->getType()->getAsPlaceholderType()) {
+  if (const BuiltinType *PTy = OrigOp.get()->getType()->getAsPlaceholderType()){
     if (PTy->getKind() == BuiltinType::Overload) {
       Expr *E = OrigOp.get()->IgnoreParens();
       if (!isa<OverloadExpr>(E)) {
         assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf);
         Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof_addrof_function)
-            << OrigOp.get()->getSourceRange();
+          << OrigOp.get()->getSourceRange();
         return QualType();
       }
 
@@ -15248,7 +15240,7 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
       if (isa<UnresolvedMemberExpr>(Ovl))
         if (!ResolveSingleFunctionTemplateSpecialization(Ovl)) {
           Diag(OpLoc, diag::err_invalid_form_pointer_member_function)
-              << OrigOp.get()->getSourceRange();
+            << OrigOp.get()->getSourceRange();
           return QualType();
         }
 
@@ -15260,13 +15252,12 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
 
     if (PTy->getKind() == BuiltinType::BoundMember) {
       Diag(OpLoc, diag::err_invalid_form_pointer_member_function)
-          << OrigOp.get()->getSourceRange();
+        << OrigOp.get()->getSourceRange();
       return QualType();
     }
 
     OrigOp = CheckPlaceholderExpr(OrigOp.get());
-    if (OrigOp.isInvalid())
-      return QualType();
+    if (OrigOp.isInvalid()) return QualType();
   }
 
   if (OrigOp.get()->isTypeDependent())
@@ -15283,7 +15274,7 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
   // depending on a vendor implementation. Thus preventing
   // taking an address of the capture to avoid invalid AS casts.
   if (LangOpts.OpenCL) {
-    auto *VarRef = dyn_cast<DeclRefExpr>(op);
+    auto* VarRef = dyn_cast<DeclRefExpr>(op);
     if (VarRef && VarRef->refersToEnclosingVariableOrCapture()) {
       Diag(op->getExprLoc(), diag::err_opencl_taking_address_capture);
       return QualType();
@@ -15292,7 +15283,7 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
 
   if (getLangOpts().C99) {
     // Implement C99-only parts of addressof rules.
-    if (UnaryOperator *uOp = dyn_cast<UnaryOperator>(op)) {
+    if (UnaryOperator* uOp = dyn_cast<UnaryOperator>(op)) {
       if (uOp->getOpcode() == UO_Deref)
         // Per C99 6.5.3.2, the address of a deref always returns a valid result
         // (assuming the deref expression is valid).
@@ -15331,7 +15322,7 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
     // If the underlying expression isn't a decl ref, give up.
     if (!isa<DeclRefExpr>(op)) {
       Diag(OpLoc, diag::err_invalid_form_pointer_member_function)
-          << OrigOp.get()->getSourceRange();
+        << OrigOp.get()->getSourceRange();
       return QualType();
     }
     DeclRefExpr *DRE = cast<DeclRefExpr>(op);
@@ -15386,7 +15377,7 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
         AddressOfError = AO_Property_Expansion;
       } else {
         Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof)
-            << op->getType() << op->getSourceRange();
+          << op->getType() << op->getSourceRange();
         return QualType();
       }
     } else if (const auto *DRE = dyn_cast<DeclRefExpr>(op)) {
@@ -15409,7 +15400,8 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
     if (const VarDecl *vd = dyn_cast<VarDecl>(dcl)) {
       // in C++ it is not error to take address of a register
       // variable (c++03 7.1.1P3)
-      if (vd->getStorageClass() == SC_Register && !getLangOpts().CPlusPlus) {
+      if (vd->getStorageClass() == SC_Register &&
+          !getLangOpts().CPlusPlus) {
         AddressOfError = AO_Register_Variable;
       }
     } else if (isa<MSPropertyDecl>(dcl)) {
@@ -15433,7 +15425,7 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
           if (dcl->getType()->isReferenceType()) {
             Diag(OpLoc,
                  diag::err_cannot_form_pointer_to_member_of_reference_type)
-                << dcl->getDeclName() << dcl->getType();
+              << dcl->getDeclName() << dcl->getType();
             return QualType();
           }
 
@@ -15504,7 +15496,7 @@ static void RecordModifiableNonNullParam(Sema &S, const Expr *Exp) {
   const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D);
   if (!Param)
     return;
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Param->getDeclContext()))
+  if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(Param->getDeclContext()))
     if (!FD->hasAttr<NonNullAttr>() && !Param->hasAttr<NonNullAttr>())
       return;
   if (FunctionScopeInfo *FD = S.getCurFunction())
@@ -15524,26 +15516,27 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK,
 
   if (isa<CXXReinterpretCastExpr>(Op->IgnoreParens())) {
     QualType OpOrigType = Op->IgnoreParenCasts()->getType();
-    S.CheckCompatibleReinterpretCast(OpOrigType, OpTy, /*IsDereference*/ true,
+    S.CheckCompatibleReinterpretCast(OpOrigType, OpTy, /*IsDereference*/true,
                                      Op->getSourceRange());
   }
 
-  if (const PointerType *PT = OpTy->getAs<PointerType>()) {
+  if (const PointerType *PT = OpTy->getAs<PointerType>())
+  {
     Result = PT->getPointeeType();
-  } else if (const ObjCObjectPointerType *OPT =
-                 OpTy->getAs<ObjCObjectPointerType>())
+  }
+  else if (const ObjCObjectPointerType *OPT =
+             OpTy->getAs<ObjCObjectPointerType>())
     Result = OPT->getPointeeType();
   else {
     ExprResult PR = S.CheckPlaceholderExpr(Op);
-    if (PR.isInvalid())
-      return QualType();
+    if (PR.isInvalid()) return QualType();
     if (PR.get() != Op)
       return CheckIndirectionOperand(S, PR.get(), VK, OpLoc);
   }
 
   if (Result.isNull()) {
     S.Diag(OpLoc, diag::err_typecheck_indirection_requires_pointer)
-        << OpTy << Op->getSourceRange();
+      << OpTy << Op->getSourceRange();
     return QualType();
   }
 
@@ -15573,150 +15566,60 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK,
 BinaryOperatorKind Sema::ConvertTokenKindToBinaryOpcode(tok::TokenKind Kind) {
   BinaryOperatorKind Opc;
   switch (Kind) {
-  default:
-    llvm_unreachable("Unknown binop!");
-  case tok::periodstar:
-    Opc = BO_PtrMemD;
-    break;
-  case tok::arrowstar:
-    Opc = BO_PtrMemI;
-    break;
-  case tok::star:
-    Opc = BO_Mul;
-    break;
-  case tok::slash:
-    Opc = BO_Div;
-    break;
-  case tok::percent:
-    Opc = BO_Rem;
-    break;
-  case tok::plus:
-    Opc = BO_Add;
-    break;
-  case tok::minus:
-    Opc = BO_Sub;
-    break;
-  case tok::lessless:
-    Opc = BO_Shl;
-    break;
-  case tok::greatergreater:
-    Opc = BO_Shr;
-    break;
-  case tok::lessequal:
-    Opc = BO_LE;
-    break;
-  case tok::less:
-    Opc = BO_LT;
-    break;
-  case tok::greaterequal:
-    Opc = BO_GE;
-    break;
-  case tok::greater:
-    Opc = BO_GT;
-    break;
-  case tok::exclaimequal:
-    Opc = BO_NE;
-    break;
-  case tok::equalequal:
-    Opc = BO_EQ;
-    break;
-  case tok::spaceship:
-    Opc = BO_Cmp;
-    break;
-  case tok::amp:
-    Opc = BO_And;
-    break;
-  case tok::caret:
-    Opc = BO_Xor;
-    break;
-  case tok::pipe:
-    Opc = BO_Or;
-    break;
-  case tok::ampamp:
-    Opc = BO_LAnd;
-    break;
-  case tok::pipepipe:
-    Opc = BO_LOr;
-    break;
-  case tok::equal:
-    Opc = BO_Assign;
-    break;
-  case tok::starequal:
-    Opc = BO_MulAssign;
-    break;
-  case tok::slashequal:
-    Opc = BO_DivAssign;
-    break;
-  case tok::percentequal:
-    Opc = BO_RemAssign;
-    break;
-  case tok::plusequal:
-    Opc = BO_AddAssign;
-    break;
-  case tok::minusequal:
-    Opc = BO_SubAssign;
-    break;
-  case tok::lesslessequal:
-    Opc = BO_ShlAssign;
-    break;
-  case tok::greatergreaterequal:
-    Opc = BO_ShrAssign;
-    break;
-  case tok::ampequal:
-    Opc = BO_AndAssign;
-    break;
-  case tok::caretequal:
-    Opc = BO_XorAssign;
-    break;
-  case tok::pipeequal:
-    Opc = BO_OrAssign;
-    break;
-  case tok::comma:
-    Opc = BO_Comma;
-    break;
+  default: llvm_unreachable("Unknown binop!");
+  case tok::periodstar:           Opc = BO_PtrMemD; break;
+  case tok::arrowstar:            Opc = BO_PtrMemI; break;
+  case tok::star:                 Opc = BO_Mul; break;
+  case tok::slash:                Opc = BO_Div; break;
+  case tok::percent:              Opc = BO_Rem; break;
+  case tok::plus:                 Opc = BO_Add; break;
+  case tok::minus:                Opc = BO_Sub; break;
+  case tok::lessless:             Opc = BO_Shl; break;
+  case tok::greatergreater:       Opc = BO_Shr; break;
+  case tok::lessequal:            Opc = BO_LE; break;
+  case tok::less:                 Opc = BO_LT; break;
+  case tok::greaterequal:         Opc = BO_GE; break;
+  case tok::greater:              Opc = BO_GT; break;
+  case tok::exclaimequal:         Opc = BO_NE; break;
+  case tok::equalequal:           Opc = BO_EQ; break;
+  case tok::spaceship:            Opc = BO_Cmp; break;
+  case tok::amp:                  Opc = BO_And; break;
+  case tok::caret:                Opc = BO_Xor; break;
+  case tok::pipe:                 Opc = BO_Or; break;
+  case tok::ampamp:               Opc = BO_LAnd; break;
+  case tok::pipepipe:             Opc = BO_LOr; break;
+  case tok::equal:                Opc = BO_Assign; break;
+  case tok::starequal:            Opc = BO_MulAssign; break;
+  case tok::slashequal:           Opc = BO_DivAssign; break;
+  case tok::percentequal:         Opc = BO_RemAssign; break;
+  case tok::plusequal:            Opc = BO_AddAssign; break;
+  case tok::minusequal:           Opc = BO_SubAssign; break;
+  case tok::lesslessequal:        Opc = BO_ShlAssign; break;
+  case tok::greatergreaterequal:  Opc = BO_ShrAssign; break;
+  case tok::ampequal:             Opc = BO_AndAssign; break;
+  case tok::caretequal:           Opc = BO_XorAssign; break;
+  case tok::pipeequal:            Opc = BO_OrAssign; break;
+  case tok::comma:                Opc = BO_Comma; break;
   }
   return Opc;
 }
 
-static inline UnaryOperatorKind
-ConvertTokenKindToUnaryOpcode(tok::TokenKind Kind) {
+static inline UnaryOperatorKind ConvertTokenKindToUnaryOpcode(
+  tok::TokenKind Kind) {
   UnaryOperatorKind Opc;
   switch (Kind) {
-  default:
-    llvm_unreachable("Unknown unary op!");
-  case tok::plusplus:
-    Opc = UO_PreInc;
-    break;
-  case tok::minusminus:
-    Opc = UO_PreDec;
-    break;
-  case tok::amp:
-    Opc = UO_AddrOf;
-    break;
-  case tok::star:
-    Opc = UO_Deref;
-    break;
-  case tok::plus:
-    Opc = UO_Plus;
-    break;
-  case tok::minus:
-    Opc = UO_Minus;
-    break;
-  case tok::tilde:
-    Opc = UO_Not;
-    break;
-  case tok::exclaim:
-    Opc = UO_LNot;
-    break;
-  case tok::kw___real:
-    Opc = UO_Real;
-    break;
-  case tok::kw___imag:
-    Opc = UO_Imag;
-    break;
-  case tok::kw___extension__:
-    Opc = UO_Extension;
-    break;
+  default: llvm_unreachable("Unknown unary op!");
+  case tok::plusplus:     Opc = UO_PreInc; break;
+  case tok::minusminus:   Opc = UO_PreDec; break;
+  case tok::amp:          Opc = UO_AddrOf; break;
+  case tok::star:         Opc = UO_Deref; break;
+  case tok::plus:         Opc = UO_Plus; break;
+  case tok::minus:        Opc = UO_Minus; break;
+  case tok::tilde:        Opc = UO_Not; break;
+  case tok::exclaim:      Opc = UO_LNot; break;
+  case tok::kw___real:    Opc = UO_Real; break;
+  case tok::kw___imag:    Opc = UO_Imag; break;
+  case tok::kw___extension__: Opc = UO_Extension; break;
   }
   return Opc;
 }
@@ -15769,13 +15672,14 @@ static void DiagnoseSelfAssignment(Sema &S, Expr *LHSExpr, Expr *RHSExpr,
   RHSExpr = RHSExpr->IgnoreParenImpCasts();
   const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
   const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
-  if (!LHSDeclRef || !RHSDeclRef || LHSDeclRef->getLocation().isMacroID() ||
+  if (!LHSDeclRef || !RHSDeclRef ||
+      LHSDeclRef->getLocation().isMacroID() ||
       RHSDeclRef->getLocation().isMacroID())
     return;
   const ValueDecl *LHSDecl =
-      cast<ValueDecl>(LHSDeclRef->getDecl()->getCanonicalDecl());
+    cast<ValueDecl>(LHSDeclRef->getDecl()->getCanonicalDecl());
   const ValueDecl *RHSDecl =
-      cast<ValueDecl>(RHSDeclRef->getDecl()->getCanonicalDecl());
+    cast<ValueDecl>(RHSDeclRef->getDecl()->getCanonicalDecl());
   if (LHSDecl != RHSDecl)
     return;
   if (LHSDecl->getType().isVolatileQualified())
@@ -15810,7 +15714,8 @@ static void checkObjCPointerIntrospection(Sema &S, ExprResult &L, ExprResult &R,
   if (LHS->IgnoreParenCasts()->getType()->isObjCObjectPointerType()) {
     ObjCPointerExpr = LHS;
     OtherExpr = RHS;
-  } else if (RHS->IgnoreParenCasts()->getType()->isObjCObjectPointerType()) {
+  }
+  else if (RHS->IgnoreParenCasts()->getType()->isObjCObjectPointerType()) {
     ObjCPointerExpr = RHS;
     OtherExpr = LHS;
   }
@@ -15833,7 +15738,8 @@ static void checkObjCPointerIntrospection(Sema &S, ExprResult &L, ExprResult &R,
         Diag = diag::warn_objc_pointer_masking_performSelector;
     }
 
-    S.Diag(OpLoc, Diag) << ObjCPointerExpr->getSourceRange();
+    S.Diag(OpLoc, Diag)
+      << ObjCPointerExpr->getSourceRange();
   }
 }
 
@@ -15926,7 +15832,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
   }
 
   ExprResult LHS = LHSExpr, RHS = RHSExpr;
-  QualType ResultTy; // Result type of the binary operator.
+  QualType ResultTy;     // Result type of the binary operator.
   // The following two variables are used for compound assignment operators
   QualType CompLHSTy;    // Type of LHS after promotions for computation
   QualType CompResultTy; // Type of computation result
@@ -15953,8 +15859,9 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
 
     // OpenCL special types - image, sampler, pipe, and blocks are to be used
     // only with a builtin functions and therefore should be disallowed here.
-    if (LHSTy->isImageType() || RHSTy->isImageType() || LHSTy->isSamplerT() ||
-        RHSTy->isSamplerT() || LHSTy->isPipeType() || RHSTy->isPipeType() ||
+    if (LHSTy->isImageType() || RHSTy->isImageType() ||
+        LHSTy->isSamplerT() || RHSTy->isSamplerT() ||
+        LHSTy->isPipeType() || RHSTy->isPipeType() ||
         LHSTy->isBlockPointerType() || RHSTy->isBlockPointerType()) {
       ResultTy = InvalidOperands(OpLoc, LHS, RHS);
       return ExprError();
@@ -16003,8 +15910,8 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
     break;
   case BO_PtrMemD:
   case BO_PtrMemI:
-    ResultTy =
-        CheckPointerToMemberOperands(LHS, RHS, VK, OpLoc, Opc == BO_PtrMemI);
+    ResultTy = CheckPointerToMemberOperands(LHS, RHS, VK, OpLoc,
+                                            Opc == BO_PtrMemI);
     break;
   case BO_Mul:
   case BO_Div:
@@ -16136,11 +16043,10 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
   CheckArrayAccess(LHS.get());
   CheckArrayAccess(RHS.get());
 
-  if (const ObjCIsaExpr *OISA =
-          dyn_cast<ObjCIsaExpr>(LHS.get()->IgnoreParenCasts())) {
-    NamedDecl *ObjectSetClass =
-        LookupSingleName(TUScope, &Context.Idents.get("object_setClass"),
-                         SourceLocation(), LookupOrdinaryName);
+  if (const ObjCIsaExpr *OISA = dyn_cast<ObjCIsaExpr>(LHS.get()->IgnoreParenCasts())) {
+    NamedDecl *ObjectSetClass = LookupSingleName(TUScope,
+                                                 &Context.Idents.get("object_setClass"),
+                                                 SourceLocation(), LookupOrdinaryName);
     if (ObjectSetClass && isa<ObjCIsaExpr>(LHS.get())) {
       SourceLocation RHSLocEnd = getLocForEndOfToken(RHS.get()->getEndLoc());
       Diag(LHS.get()->getExprLoc(), diag::warn_objc_isa_assign)
@@ -16149,10 +16055,12 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
           << FixItHint::CreateReplacement(SourceRange(OISA->getOpLoc(), OpLoc),
                                           ",")
           << FixItHint::CreateInsertion(RHSLocEnd, ")");
-    } else
+    }
+    else
       Diag(LHS.get()->getExprLoc(), diag::warn_objc_isa_assign);
-  } else if (const ObjCIvarRefExpr *OIRE =
-                 dyn_cast<ObjCIvarRefExpr>(LHS.get()->IgnoreParenCasts()))
+  }
+  else if (const ObjCIvarRefExpr *OIRE =
+           dyn_cast<ObjCIvarRefExpr>(LHS.get()->IgnoreParenCasts()))
     DiagnoseDirectIsaAccess(*this, OIRE, OpLoc, RHS.get());
 
   // Opc is not a compound assignment if CompResultTy is null.
@@ -16165,8 +16073,8 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
   }
 
   // Handle compound assignments.
-  if (getLangOpts().CPlusPlus &&
-      LHS.get()->getObjectKind() != OK_ObjCProperty) {
+  if (getLangOpts().CPlusPlus && LHS.get()->getObjectKind() !=
+      OK_ObjCProperty) {
     VK = VK_LValue;
     OK = LHS.get()->getObjectKind();
   }
@@ -16219,29 +16127,29 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc,
           : SourceRange(LHSExpr->getBeginLoc(), RHSBO->getLHS()->getEndLoc());
 
   Self.Diag(OpLoc, diag::warn_precedence_bitwise_rel)
-      << DiagRange << BinaryOperator::getOpcodeStr(Opc) << OpStr;
+    << DiagRange << BinaryOperator::getOpcodeStr(Opc) << OpStr;
   SuggestParentheses(Self, OpLoc,
-                     Self.PDiag(diag::note_precedence_silence) << OpStr,
-                     (isLeftComp ? LHSExpr : RHSExpr)->getSourceRange());
+    Self.PDiag(diag::note_precedence_silence) << OpStr,
+    (isLeftComp ? LHSExpr : RHSExpr)->getSourceRange());
   SuggestParentheses(Self, OpLoc,
-                     Self.PDiag(diag::note_precedence_bitwise_first)
-                         << BinaryOperator::getOpcodeStr(Opc),
-                     ParensRange);
+    Self.PDiag(diag::note_precedence_bitwise_first)
+      << BinaryOperator::getOpcodeStr(Opc),
+    ParensRange);
 }
 
 /// It accepts a '&&' expr that is inside a '||' one.
 /// Emit a diagnostic together with a fixit hint that wraps the '&&' expression
 /// in parentheses.
-static void EmitDiagnosticForLogicalAndInLogicalOr(Sema &Self,
-                                                   SourceLocation OpLoc,
-                                                   BinaryOperator *Bop) {
+static void
+EmitDiagnosticForLogicalAndInLogicalOr(Sema &Self, SourceLocation OpLoc,
+                                       BinaryOperator *Bop) {
   assert(Bop->getOpcode() == BO_LAnd);
   Self.Diag(Bop->getOperatorLoc(), diag::warn_logical_and_in_logical_or)
       << Bop->getSourceRange() << OpLoc;
   SuggestParentheses(Self, Bop->getOperatorLoc(),
-                     Self.PDiag(diag::note_precedence_silence)
-                         << Bop->getOpcodeStr(),
-                     Bop->getSourceRange());
+    Self.PDiag(diag::note_precedence_silence)
+      << Bop->getOpcodeStr(),
+    Bop->getSourceRange());
 }
 
 /// Look for '&&' in the left hand of a '||' expr.
@@ -16286,12 +16194,12 @@ static void DiagnoseBitwiseOpInBitwiseOp(Sema &S, BinaryOperatorKind Opc,
   if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(SubExpr)) {
     if (Bop->isBitwiseOp() && Bop->getOpcode() < Opc) {
       S.Diag(Bop->getOperatorLoc(), diag::warn_bitwise_op_in_bitwise_op)
-          << Bop->getOpcodeStr() << BinaryOperator::getOpcodeStr(Opc)
-          << Bop->getSourceRange() << OpLoc;
+        << Bop->getOpcodeStr() << BinaryOperator::getOpcodeStr(Opc)
+        << Bop->getSourceRange() << OpLoc;
       SuggestParentheses(S, Bop->getOperatorLoc(),
-                         S.PDiag(diag::note_precedence_silence)
-                             << Bop->getOpcodeStr(),
-                         Bop->getSourceRange());
+        S.PDiag(diag::note_precedence_silence)
+          << Bop->getOpcodeStr(),
+        Bop->getSourceRange());
     }
   }
 }
@@ -16304,14 +16212,14 @@ static void DiagnoseAdditionInShift(Sema &S, SourceLocation OpLoc,
       S.Diag(Bop->getOperatorLoc(), diag::warn_addition_in_bitshift)
           << Bop->getSourceRange() << OpLoc << Shift << Op;
       SuggestParentheses(S, Bop->getOperatorLoc(),
-                         S.PDiag(diag::note_precedence_silence) << Op,
-                         Bop->getSourceRange());
+          S.PDiag(diag::note_precedence_silence) << Op,
+          Bop->getSourceRange());
     }
   }
 }
 
-static void DiagnoseShiftCompare(Sema &S, SourceLocation OpLoc, Expr *LHSExpr,
-                                 Expr *RHSExpr) {
+static void DiagnoseShiftCompare(Sema &S, SourceLocation OpLoc,
+                                 Expr *LHSExpr, Expr *RHSExpr) {
   CXXOperatorCallExpr *OCE = dyn_cast<CXXOperatorCallExpr>(LHSExpr);
   if (!OCE)
     return;
@@ -16340,28 +16248,27 @@ static void DiagnoseShiftCompare(Sema &S, SourceLocation OpLoc, Expr *LHSExpr,
 /// precedence.
 static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc,
                                     SourceLocation OpLoc, Expr *LHSExpr,
-                                    Expr *RHSExpr) {
+                                    Expr *RHSExpr){
   // Diagnose "arg1 'bitwise' arg2 'eq' arg3".
   if (BinaryOperator::isBitwiseOp(Opc))
     DiagnoseBitwisePrecedence(Self, Opc, OpLoc, LHSExpr, RHSExpr);
 
   // Diagnose "arg1 & arg2 | arg3"
   if ((Opc == BO_Or || Opc == BO_Xor) &&
-      !OpLoc.isMacroID() /* Don't warn in macros. */) {
+      !OpLoc.isMacroID()/* Don't warn in macros. */) {
     DiagnoseBitwiseOpInBitwiseOp(Self, Opc, OpLoc, LHSExpr);
     DiagnoseBitwiseOpInBitwiseOp(Self, Opc, OpLoc, RHSExpr);
   }
 
   // Warn about arg1 || arg2 && arg3, as GCC 4.3+ does.
   // We don't warn for 'assert(a || b && "bad")' since this is safe.
-  if (Opc == BO_LOr && !OpLoc.isMacroID() /* Don't warn in macros. */) {
+  if (Opc == BO_LOr && !OpLoc.isMacroID()/* Don't warn in macros. */) {
     DiagnoseLogicalAndInLogicalOrLHS(Self, OpLoc, LHSExpr, RHSExpr);
     DiagnoseLogicalAndInLogicalOrRHS(Self, OpLoc, LHSExpr, RHSExpr);
   }
 
-  if ((Opc == BO_Shl &&
-       LHSExpr->getType()->isIntegralType(Self.getASTContext())) ||
-      Opc == BO_Shr) {
+  if ((Opc == BO_Shl && LHSExpr->getType()->isIntegralType(Self.getASTContext()))
+      || Opc == BO_Shr) {
     StringRef Shift = BinaryOperator::getOpcodeStr(Opc);
     DiagnoseAdditionInShift(Self, OpLoc, LHSExpr, Shift);
     DiagnoseAdditionInShift(Self, OpLoc, RHSExpr, Shift);
@@ -16374,7 +16281,8 @@ static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc,
 }
 
 ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
-                            tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr) {
+                            tok::TokenKind Kind,
+                            Expr *LHSExpr, Expr *RHSExpr) {
   BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Kind);
   assert(LHSExpr && "ActOnBinOp(): missing left expression");
   assert(RHSExpr && "ActOnBinOp(): missing right expression");
@@ -16407,8 +16315,8 @@ void Sema::LookupBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc,
 
 /// Build an overloaded binary operator expression in the given scope.
 static ExprResult BuildOverloadedBinOp(Sema &S, Scope *Sc, SourceLocation OpLoc,
-                                       BinaryOperatorKind Opc, Expr *LHS,
-                                       Expr *RHS) {
+                                       BinaryOperatorKind Opc,
+                                       Expr *LHS, Expr *RHS) {
   switch (Opc) {
   case BO_Assign:
     // In the non-overloaded case, we warn about self-assignment (x = x) for
@@ -16469,8 +16377,7 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
       // that an overload set can be dependently-typed, but it never
       // instantiates to having an overloadable type.
       ExprResult resolvedRHS = CheckPlaceholderExpr(RHSExpr);
-      if (resolvedRHS.isInvalid())
-        return ExprError();
+      if (resolvedRHS.isInvalid()) return ExprError();
       RHSExpr = resolvedRHS.get();
 
       if (RHSExpr->isTypeDependent() ||
@@ -16501,8 +16408,7 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
     }
 
     ExprResult LHS = CheckPlaceholderExpr(LHSExpr);
-    if (LHS.isInvalid())
-      return ExprError();
+    if (LHS.isInvalid()) return ExprError();
     LHSExpr = LHS.get();
   }
 
@@ -16526,8 +16432,7 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
       return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
 
     ExprResult resolvedRHS = CheckPlaceholderExpr(RHSExpr);
-    if (!resolvedRHS.isUsable())
-      return ExprError();
+    if (!resolvedRHS.isUsable()) return ExprError();
     RHSExpr = resolvedRHS.get();
   }
 
@@ -16629,11 +16534,10 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
     QualType Ty = InputExpr->getType();
     // The only legal unary operation for atomics is '&'.
     if ((Opc != UO_AddrOf && Ty->isAtomicType()) ||
-        // OpenCL special types - image, sampler, pipe, and blocks are to be
-        // used only with a builtin functions and therefore should be disallowed
-        // here.
-        (Ty->isImageType() || Ty->isSamplerT() || Ty->isPipeType() ||
-         Ty->isBlockPointerType())) {
+    // OpenCL special types - image, sampler, pipe, and blocks are to be used
+    // only with a builtin functions and therefore should be disallowed here.
+        (Ty->isImageType() || Ty->isSamplerT() || Ty->isPipeType()
+        || Ty->isBlockPointerType())) {
       return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
                        << InputExpr->getType()
                        << Input.get()->getSourceRange());
@@ -16931,15 +16835,15 @@ ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
 
     // & gets special logic for several kinds of placeholder.
     // The builtin code knows what to do.
-    if (Opc == UO_AddrOf && (pty->getKind() == BuiltinType::Overload ||
-                             pty->getKind() == BuiltinType::UnknownAny ||
-                             pty->getKind() == BuiltinType::BoundMember))
+    if (Opc == UO_AddrOf &&
+        (pty->getKind() == BuiltinType::Overload ||
+         pty->getKind() == BuiltinType::UnknownAny ||
+         pty->getKind() == BuiltinType::BoundMember))
       return CreateBuiltinUnaryOp(OpLoc, Opc, Input);
 
     // Anything else needs to be handled now.
     ExprResult Result = CheckPlaceholderExpr(Input);
-    if (Result.isInvalid())
-      return ExprError();
+    if (Result.isInvalid()) return ExprError();
     Input = Result.get();
   }
 
@@ -17077,13 +16981,13 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
   // a struct/union/class.
   if (!Dependent && !ArgTy->isRecordType())
     return ExprError(Diag(BuiltinLoc, diag::err_offsetof_record_type)
-                     << ArgTy << TypeRange);
+                       << ArgTy << TypeRange);
 
   // Type must be complete per C99 7.17p3 because a declaring a variable
   // with an incomplete type would be ill-formed.
-  if (!Dependent &&
-      RequireCompleteType(BuiltinLoc, ArgTy, diag::err_offsetof_incomplete_type,
-                          TypeRange))
+  if (!Dependent
+      && RequireCompleteType(BuiltinLoc, ArgTy,
+                             diag::err_offsetof_incomplete_type, TypeRange))
     return ExprError();
 
   bool DidWarnAboutNonPOD = false;
@@ -17097,7 +17001,7 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
       // Offset of an array sub-field.  TODO: Should we allow vector elements?
       if (!CurrentType->isDependentType()) {
         const ArrayType *AT = Context.getAsArrayType(CurrentType);
-        if (!AT)
+        if(!AT)
           return ExprError(Diag(D.getEndLoc(), diag::err_offsetof_array_type)
                            << CurrentType);
         CurrentType = AT->getElementType();
@@ -17155,10 +17059,9 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
     //   If type is not a standard-layout class (Clause 9), the results are
     //   undefined.
     if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
-      bool IsSafe =
-          LangOpts.CPlusPlus11 ? CRD->isStandardLayout() : CRD->isPOD();
-      unsigned DiagID = LangOpts.CPlusPlus11
-                            ? diag::ext_offsetof_non_standardlayout_type
+      bool IsSafe = LangOpts.CPlusPlus11? CRD->isStandardLayout() : CRD->isPOD();
+      unsigned DiagID =
+        LangOpts.CPlusPlus11? diag::ext_offsetof_non_standardlayout_type
                             : diag::ext_offsetof_non_pod_type;
 
       if (!IsSafe && !DidWarnAboutNonPOD && !isUnevaluatedContext()) {
@@ -17253,7 +17156,8 @@ ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S, SourceLocation BuiltinLoc,
   return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, Desig, RParenLoc);
 }
 
-ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, Expr *CondExpr,
+ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
+                                 Expr *CondExpr,
                                  Expr *LHSExpr, Expr *RHSExpr,
                                  SourceLocation RPLoc) {
   assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)");
@@ -17339,8 +17243,8 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
   // Look for an explicit signature in that function type.
   FunctionProtoTypeLoc ExplicitSignature;
 
-  if ((ExplicitSignature =
-           Sig->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>())) {
+  if ((ExplicitSignature = Sig->getTypeLoc()
+                               .getAsAdjusted<FunctionProtoTypeLoc>())) {
 
     // Check whether that explicit signature was synthesized by
     // GetTypeForDeclarator.  If so, don't save that as part of the
@@ -17379,7 +17283,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
   }
 
   // Push block parameters from the declarator if we had them.
-  SmallVector<ParmVarDecl *, 8> Params;
+  SmallVector<ParmVarDecl*, 8> Params;
   if (ExplicitSignature) {
     for (unsigned I = 0, E = ExplicitSignature.getNumParams(); I != E; ++I) {
       ParmVarDecl *Param = ExplicitSignature.getParam(I);
@@ -17392,8 +17296,8 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
       Params.push_back(Param);
     }
 
-    // Fake up parameter variables if we have a typedef, like
-    //   ^ fntype { ... }
+  // Fake up parameter variables if we have a typedef, like
+  //   ^ fntype { ... }
   } else if (const FunctionProtoType *Fn = T->getAs<FunctionProtoType>()) {
     for (const auto &I : Fn->param_types()) {
       ParmVarDecl *Param = BuildParmVarDeclForTypedef(
@@ -17438,8 +17342,8 @@ void Sema::ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) {
   PopFunctionScopeInfo();
 }
 
-ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body,
-                                    Scope *CurScope) {
+ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
+                                    Stmt *Body, Scope *CurScope) {
   // If blocks are disabled, emit an error.
   if (!LangOpts.Blocks)
     Diag(CaretLoc, diag::err_blocks_disable) << LangOpts.OpenCL;
@@ -17471,8 +17375,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body,
     const FunctionType *FTy = BSI->FunctionType->castAs<FunctionType>();
 
     FunctionType::ExtInfo Ext = FTy->getExtInfo();
-    if (NoReturn && !Ext.getNoReturn())
-      Ext = Ext.withNoReturn(true);
+    if (NoReturn && !Ext.getNoReturn()) Ext = Ext.withNoReturn(true);
 
     // Turn protoless block types into nullary block types.
     if (isa<FunctionNoProtoType>(FTy)) {
@@ -17486,7 +17389,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body,
                (!NoReturn || FTy->getNoReturnAttr())) {
       BlockTy = BSI->FunctionType;
 
-      // Otherwise, make the minimal modifications to the function type.
+    // Otherwise, make the minimal modifications to the function type.
     } else {
       const FunctionProtoType *FPT = cast<FunctionProtoType>(FTy);
       FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
@@ -17495,7 +17398,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body,
       BlockTy = Context.getFunctionType(RetTy, FPT->getParamTypes(), EPI);
     }
 
-    // If we don't have a function type, just build one from nothing.
+  // If we don't have a function type, just build one from nothing.
   } else {
     FunctionProtoType::ExtProtoInfo EPI;
     EPI.ExtInfo = FunctionType::ExtInfo().withNoReturn(NoReturn);
@@ -17506,7 +17409,8 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body,
   BlockTy = Context.getBlockPointerType(BlockTy);
 
   // If needed, diagnose invalid gotos and switches in the block.
-  if (getCurFunction()->NeedsScopeChecking() && !PP.isCodeCompletionEnabled())
+  if (getCurFunction()->NeedsScopeChecking() &&
+      !PP.isCodeCompletionEnabled())
     DiagnoseInvalidJumps(cast<CompoundStmt>(Body));
 
   BD->setBody(cast<CompoundStmt>(Body));
@@ -17581,9 +17485,9 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body,
         // Build a full-expression copy expression if initialization
         // succeeded and used a non-trivial constructor.  Recover from
         // errors by pretending that the copy isn't necessary.
-        if (!Result.isInvalid() && !cast<CXXConstructExpr>(Result.get())
-                                        ->getConstructor()
-                                        ->isTrivial()) {
+        if (!Result.isInvalid() &&
+            !cast<CXXConstructExpr>(Result.get())->getConstructor()
+                ->isTrivial()) {
           Result = MaybeCreateExprWithCleanups(Result);
           CopyExpr = Result.get();
         }
@@ -17640,8 +17544,9 @@ ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc, Expr *E, ParsedType Ty,
   return BuildVAArgExpr(BuiltinLoc, E, TInfo, RPLoc);
 }
 
-ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E,
-                                TypeSourceInfo *TInfo, SourceLocation RPLoc) {
+ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
+                                Expr *E, TypeSourceInfo *TInfo,
+                                SourceLocation RPLoc) {
   Expr *OrigExpr = E;
   VAArgExpr::VarArgKind VAKind = VAArgExpr::VA_Std;
 
@@ -17663,8 +17568,7 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E,
   // as Microsoft ABI on an actual Microsoft platform, where
   // __builtin_ms_va_list and __builtin_va_list are the same.)
   if (!E->isTypeDependent() && Context.getTargetInfo().hasBuiltinMSVaList() &&
-      Context.getTargetInfo().getBuiltinVaListKind() !=
-          TargetInfo::CharPtrBuiltinVaList) {
+      Context.getTargetInfo().getBuiltinVaListKind() != TargetInfo::CharPtrBuiltinVaList) {
     QualType MSVaListType = Context.getBuiltinMSVaListType();
     if (Context.hasSameType(MSVaListType, E->getType())) {
       if (CheckForModifiableLvalue(E, BuiltinLoc, *this))
@@ -17735,17 +17639,19 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E,
                             TInfo->getTypeLoc()))
       return ExprError();
 
-    if (RequireNonAbstractType(
-            TInfo->getTypeLoc().getBeginLoc(), TInfo->getType(),
-            diag::err_second_parameter_to_va_arg_abstract, TInfo->getTypeLoc()))
+    if (RequireNonAbstractType(TInfo->getTypeLoc().getBeginLoc(),
+                               TInfo->getType(),
+                               diag::err_second_parameter_to_va_arg_abstract,
+                               TInfo->getTypeLoc()))
       return ExprError();
 
     if (!TInfo->getType().isPODType(Context)) {
       Diag(TInfo->getTypeLoc().getBeginLoc(),
            TInfo->getType()->isObjCLifetimeType()
-               ? diag::warn_second_parameter_to_va_arg_ownership_qualified
-               : diag::warn_second_parameter_to_va_arg_not_pod)
-          << TInfo->getType() << TInfo->getTypeLoc().getSourceRange();
+             ? diag::warn_second_parameter_to_va_arg_ownership_qualified
+             : diag::warn_second_parameter_to_va_arg_not_pod)
+        << TInfo->getType()
+        << TInfo->getTypeLoc().getSourceRange();
     }
 
     if (TInfo->getType()->isArrayType()) {
@@ -17807,11 +17713,11 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E,
     if (TInfo->getType()->isSpecificBuiltinType(BuiltinType::Float))
       PromoteType = Context.DoubleTy;
     if (!PromoteType.isNull())
-      DiagRuntimeBehavior(
-          TInfo->getTypeLoc().getBeginLoc(), E,
-          PDiag(diag::warn_second_parameter_to_va_arg_never_compatible)
-              << TInfo->getType() << PromoteType
-              << TInfo->getTypeLoc().getSourceRange());
+      DiagRuntimeBehavior(TInfo->getTypeLoc().getBeginLoc(), E,
+                  PDiag(diag::warn_second_parameter_to_va_arg_never_compatible)
+                          << TInfo->getType()
+                          << PromoteType
+                          << TInfo->getTypeLoc().getSourceRange());
   }
 
   QualType T = TInfo->getType().getNonLValueExprType(Context);
@@ -17974,9 +17880,10 @@ static bool maybeDiagnoseAssignmentToFunction(Sema &S, QualType DstType,
 }
 
 bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
-                                    SourceLocation Loc, QualType DstType,
-                                    QualType SrcType, Expr *SrcExpr,
-                                    AssignmentAction Action, bool *Complained) {
+                                    SourceLocation Loc,
+                                    QualType DstType, QualType SrcType,
+                                    Expr *SrcExpr, AssignmentAction Action,
+                                    bool *Complained) {
   if (Complained)
     *Complained = false;
 
@@ -18045,7 +17952,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
       DiagKind = diag::ext_typecheck_convert_incompatible_pointer;
     }
     CheckInferredResultType = DstType->isObjCObjectPointerType() &&
-                              SrcType->isObjCObjectPointerType();
+      SrcType->isObjCObjectPointerType();
     if (CheckInferredResultType) {
       SrcType = SrcType.getUnqualifiedType();
       DstType = DstType.getUnqualifiedType();
@@ -18113,10 +18020,10 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
         IsStringLiteralToNonConstPointerConversion(SrcExpr, DstType))
       return false;
     if (getLangOpts().CPlusPlus) {
-      DiagKind = diag::err_typecheck_convert_discards_qualifiers;
+      DiagKind =  diag::err_typecheck_convert_discards_qualifiers;
       isInvalid = true;
     } else {
-      DiagKind = diag::ext_typecheck_convert_discards_qualifiers;
+      DiagKind =  diag::ext_typecheck_convert_discards_qualifiers;
     }
 
     break;
@@ -18143,23 +18050,24 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
   case AssignConvertType::IncompatibleObjCQualifiedId: {
     if (SrcType->isObjCQualifiedIdType()) {
       const ObjCObjectPointerType *srcOPT =
-          SrcType->castAs<ObjCObjectPointerType>();
+                SrcType->castAs<ObjCObjectPointerType>();
       for (auto *srcProto : srcOPT->quals()) {
         PDecl = srcProto;
         break;
       }
       if (const ObjCInterfaceType *IFaceT =
-              DstType->castAs<ObjCObjectPointerType>()->getInterfaceType())
+            DstType->castAs<ObjCObjectPointerType>()->getInterfaceType())
         IFace = IFaceT->getDecl();
-    } else if (DstType->isObjCQualifiedIdType()) {
+    }
+    else if (DstType->isObjCQualifiedIdType()) {
       const ObjCObjectPointerType *dstOPT =
-          DstType->castAs<ObjCObjectPointerType>();
+        DstType->castAs<ObjCObjectPointerType>();
       for (auto *dstProto : dstOPT->quals()) {
         PDecl = dstProto;
         break;
       }
       if (const ObjCInterfaceType *IFaceT =
-              SrcType->castAs<ObjCObjectPointerType>()->getInterfaceType())
+            SrcType->castAs<ObjCObjectPointerType>()->getInterfaceType())
         IFace = IFaceT->getDecl();
     }
     if (getLangOpts().CPlusPlus) {
@@ -18268,9 +18176,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
       FDiag << H;
   }
 
-  if (MayHaveConvFixit) {
-    FDiag << (unsigned)(ConvHints.Kind);
-  }
+  if (MayHaveConvFixit) { FDiag << (unsigned) (ConvHints.Kind); }
 
   if (MayHaveFunctionDiff)
     HandleFunctionTypeMismatch(FDiag, SecondType, FirstType);
@@ -18283,8 +18189,8 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
         << IFace << PDecl;
 
   if (SecondType == Context.OverloadTy)
-    NoteAllOverloadCandidates(OverloadExpr::find(SrcExpr).Expression, FirstType,
-                              /*TakingAddress=*/true);
+    NoteAllOverloadCandidates(OverloadExpr::find(SrcExpr).Expression,
+                              FirstType, /*TakingAddress=*/true);
 
   if (CheckInferredResultType)
     ObjC().EmitRelatedResultTypeNote(SrcExpr);
@@ -18298,7 +18204,8 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
   return isInvalid;
 }
 
-ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
+ExprResult Sema::VerifyIntegerConstantExpression(Expr *E,
+                                                 llvm::APSInt *Result,
                                                  AllowFoldKind CanFold) {
   class SimpleICEDiagnoser : public VerifyICEDiagnoser {
   public:
@@ -18315,7 +18222,8 @@ ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
   return VerifyIntegerConstantExpression(E, Result, Diagnoser, CanFold);
 }
 
-ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
+ExprResult Sema::VerifyIntegerConstantExpression(Expr *E,
+                                                 llvm::APSInt *Result,
                                                  unsigned DiagID,
                                                  AllowFoldKind CanFold) {
   class IDDiagnoser : public VerifyICEDiagnoser {
@@ -18323,7 +18231,7 @@ ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
 
   public:
     IDDiagnoser(unsigned DiagID)
-        : VerifyICEDiagnoser(DiagID == 0), DiagID(DiagID) {}
+      : VerifyICEDiagnoser(DiagID == 0), DiagID(DiagID) { }
 
     SemaDiagnosticBuilder diagnoseNotICE(Sema &S, SourceLocation Loc) override {
       return S.Diag(Loc, DiagID);
@@ -18344,9 +18252,10 @@ Sema::VerifyICEDiagnoser::diagnoseFold(Sema &S, SourceLocation Loc) {
   return S.Diag(Loc, diag::ext_expr_not_ice) << S.LangOpts.CPlusPlus;
 }
 
-ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
-                                                 VerifyICEDiagnoser &Diagnoser,
-                                                 AllowFoldKind CanFold) {
+ExprResult
+Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
+                                      VerifyICEDiagnoser &Diagnoser,
+                                      AllowFoldKind CanFold) {
   SourceLocation DiagLoc = E->getBeginLoc();
 
   if (getLangOpts().CPlusPlus11) {
@@ -18358,7 +18267,6 @@ ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
     ExprResult Converted;
     class CXX11ConvertDiagnoser : public ICEConvertDiagnoser {
       VerifyICEDiagnoser &BaseDiagnoser;
-
     public:
       CXX11ConvertDiagnoser(VerifyICEDiagnoser &BaseDiagnoser)
           : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false,
@@ -18370,43 +18278,41 @@ ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
         return BaseDiagnoser.diagnoseNotICEType(S, Loc, T);
       }
 
-      SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
-                                               QualType T) override {
+      SemaDiagnosticBuilder diagnoseIncomplete(
+          Sema &S, SourceLocation Loc, QualType T) override {
         return S.Diag(Loc, diag::err_ice_incomplete_type) << T;
       }
 
-      SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
-                                                 QualType T,
-                                                 QualType ConvTy) override {
+      SemaDiagnosticBuilder diagnoseExplicitConv(
+          Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
         return S.Diag(Loc, diag::err_ice_explicit_conversion) << T << ConvTy;
       }
 
-      SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
-                                             QualType ConvTy) override {
+      SemaDiagnosticBuilder noteExplicitConv(
+          Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
         return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here)
-               << ConvTy->isEnumeralType() << ConvTy;
+                 << ConvTy->isEnumeralType() << ConvTy;
       }
 
-      SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
-                                              QualType T) override {
+      SemaDiagnosticBuilder diagnoseAmbiguous(
+          Sema &S, SourceLocation Loc, QualType T) override {
         return S.Diag(Loc, diag::err_ice_ambiguous_conversion) << T;
       }
 
-      SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
-                                          QualType ConvTy) override {
+      SemaDiagnosticBuilder noteAmbiguous(
+          Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
         return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here)
-               << ConvTy->isEnumeralType() << ConvTy;
+                 << ConvTy->isEnumeralType() << ConvTy;
       }
 
-      SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc,
-                                               QualType T,
-                                               QualType ConvTy) override {
+      SemaDiagnosticBuilder diagnoseConversion(
+          Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
         llvm_unreachable("conversion functions are permitted");
       }
     } ConvertDiagnoser(Diagnoser);
 
-    Converted =
-        PerformContextualImplicitConversion(DiagLoc, E, ConvertDiagnoser);
+    Converted = PerformContextualImplicitConversion(DiagLoc, E,
+                                                    ConvertDiagnoser);
     if (Converted.isInvalid())
       return Converted;
     E = Converted.get();
@@ -18449,7 +18355,7 @@ ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
     // the caret at its location rather than producing an essentially
     // redundant note.
     if (Notes.size() == 1 && Notes[0].second.getDiagID() ==
-                                 diag::note_invalid_subexpr_in_const_expr) {
+          diag::note_invalid_subexpr_in_const_expr) {
       DiagLoc = Notes[0].first;
       Notes.clear();
     }
@@ -18509,8 +18415,8 @@ ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
   // If our only note is the usual "invalid subexpression" note, just point
   // the caret at its location rather than producing an essentially
   // redundant note.
-  if (Notes.size() == 1 &&
-      Notes[0].second.getDiagID() == diag::note_invalid_subexpr_in_const_expr) {
+  if (Notes.size() == 1 && Notes[0].second.getDiagID() ==
+        diag::note_invalid_subexpr_in_const_expr) {
     DiagLoc = Notes[0].first;
     Notes.clear();
   }
@@ -18535,57 +18441,58 @@ ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
 }
 
 namespace {
-// Handle the case where we conclude a expression which we speculatively
-// considered to be unevaluated is actually evaluated.
-class TransformToPE : public TreeTransform<TransformToPE> {
-  typedef TreeTransform<TransformToPE> BaseTransform;
+  // Handle the case where we conclude a expression which we speculatively
+  // considered to be unevaluated is actually evaluated.
+  class TransformToPE : public TreeTransform<TransformToPE> {
+    typedef TreeTransform<TransformToPE> BaseTransform;
 
-public:
-  TransformToPE(Sema &SemaRef) : BaseTransform(SemaRef) {}
+  public:
+    TransformToPE(Sema &SemaRef) : BaseTransform(SemaRef) { }
 
-  // Make sure we redo semantic analysis
-  bool AlwaysRebuild() { return true; }
-  bool ReplacingOriginal() { return true; }
+    // Make sure we redo semantic analysis
+    bool AlwaysRebuild() { return true; }
+    bool ReplacingOriginal() { return true; }
 
-  // We need to special-case DeclRefExprs referring to FieldDecls which
-  // are not part of a member pointer formation; normal TreeTransforming
-  // doesn't catch this case because of the way we represent them in the AST.
-  // FIXME: This is a bit ugly; is it really the best way to handle this
-  // case?
-  //
-  // Error on DeclRefExprs referring to FieldDecls.
-  ExprResult TransformDeclRefExpr(DeclRefExpr *E) {
-    if (isa<FieldDecl>(E->getDecl()) && !SemaRef.isUnevaluatedContext())
-      return SemaRef.Diag(E->getLocation(),
-                          diag::err_invalid_non_static_member_use)
-             << E->getDecl() << E->getSourceRange();
+    // We need to special-case DeclRefExprs referring to FieldDecls which
+    // are not part of a member pointer formation; normal TreeTransforming
+    // doesn't catch this case because of the way we represent them in the AST.
+    // FIXME: This is a bit ugly; is it really the best way to handle this
+    // case?
+    //
+    // Error on DeclRefExprs referring to FieldDecls.
+    ExprResult TransformDeclRefExpr(DeclRefExpr *E) {
+      if (isa<FieldDecl>(E->getDecl()) &&
+          !SemaRef.isUnevaluatedContext())
+        return SemaRef.Diag(E->getLocation(),
+                            diag::err_invalid_non_static_member_use)
+            << E->getDecl() << E->getSourceRange();
 
-    return BaseTransform::TransformDeclRefExpr(E);
-  }
+      return BaseTransform::TransformDeclRefExpr(E);
+    }
 
-  // Exception: filter out member pointer formation
-  ExprResult TransformUnaryOperator(UnaryOperator *E) {
-    if (E->getOpcode() == UO_AddrOf && E->getType()->isMemberPointerType())
-      return E;
+    // Exception: filter out member pointer formation
+    ExprResult TransformUnaryOperator(UnaryOperator *E) {
+      if (E->getOpcode() == UO_AddrOf && E->getType()->isMemberPointerType())
+        return E;
 
-    return BaseTransform::TransformUnaryOperator(E);
-  }
+      return BaseTransform::TransformUnaryOperator(E);
+    }
 
-  // The body of a lambda-expression is in a separate expression evaluation
-  // context so never needs to be transformed.
-  // FIXME: Ideally we wouldn't transform the closure type either, and would
-  // just recreate the capture expressions and lambda expression.
-  StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body) {
-    return SkipLambdaBody(E, Body);
-  }
-};
-} // namespace
+    // The body of a lambda-expression is in a separate expression evaluation
+    // context so never needs to be transformed.
+    // FIXME: Ideally we wouldn't transform the closure type either, and would
+    // just recreate the capture expressions and lambda expression.
+    StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body) {
+      return SkipLambdaBody(E, Body);
+    }
+  };
+}
 
 ExprResult Sema::TransformToPotentiallyEvaluated(Expr *E) {
   assert(isUnevaluatedContext() &&
          "Should only transform unevaluated expressions");
   ExprEvalContexts.back().Context =
-      ExprEvalContexts[ExprEvalContexts.size() - 2].Context;
+      ExprEvalContexts[ExprEvalContexts.size()-2].Context;
   if (isUnevaluatedContext())
     return E;
   return TransformToPE(*this).TransformExpr(E);
@@ -18600,7 +18507,8 @@ TypeSourceInfo *Sema::TransformToPotentiallyEvaluated(TypeSourceInfo *TInfo) {
   return TransformToPE(*this).TransformType(TInfo);
 }
 
-void Sema::PushExpressionEvaluationContext(
+void
+Sema::PushExpressionEvaluationContext(
     ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl,
     ExpressionEvaluationContextRecord::ExpressionKind ExprContext) {
   ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(), Cleanup,
@@ -18628,7 +18536,8 @@ void Sema::PushExpressionEvaluationContext(
     std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs);
 }
 
-void Sema::PushExpressionEvaluationContext(
+void
+Sema::PushExpressionEvaluationContext(
     ExpressionEvaluationContext NewContext, ReuseLambdaContextDecl_t,
     ExpressionEvaluationContextRecord::ExpressionKind ExprContext) {
   Decl *ClosureContextDecl = ExprEvalContexts.back().ManglingContextDecl;
@@ -18895,7 +18804,7 @@ static void RemoveNestedImmediateInvocation(
                   SmallVector<Sema::ImmediateInvocationCandidate,
                               4>::reverse_iterator Current)
         : Base(SemaRef), DRSet(DR), IISet(II), CurrentII(Current) {}
-    void RemoveImmediateInvocation(ConstantExpr *E) {
+    void RemoveImmediateInvocation(ConstantExpr* E) {
       auto It = std::find_if(CurrentII, IISet.rend(),
                              [E](Sema::ImmediateInvocationCandidate Elem) {
                                return Elem.getPointer() == E;
@@ -19104,7 +19013,7 @@ HandleImmediateInvocations(Sema &SemaRef,
 }
 
 void Sema::PopExpressionEvaluationContext() {
-  ExpressionEvaluationContextRecord &Rec = ExprEvalContexts.back();
+  ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back();
   if (!Rec.Lambdas.empty()) {
     using ExpressionKind = ExpressionEvaluationContextRecord::ExpressionKind;
     if (!getLangOpts().CPlusPlus20 &&
@@ -19164,7 +19073,7 @@ void Sema::PopExpressionEvaluationContext() {
     Cleanup = Rec.ParentCleanup;
     CleanupVarDeclMarking();
     std::swap(MaybeODRUseExprs, Rec.SavedMaybeODRUseExprs);
-    // Otherwise, merge the contexts together.
+  // Otherwise, merge the contexts together.
   } else {
     Cleanup.mergeFrom(Rec.ParentCleanup);
     MaybeODRUseExprs.insert_range(Rec.SavedMaybeODRUseExprs);
@@ -19177,9 +19086,9 @@ void Sema::PopExpressionEvaluationContext() {
 }
 
 void Sema::DiscardCleanupsInEvaluationContext() {
-  ExprCleanupObjects.erase(ExprCleanupObjects.begin() +
-                               ExprEvalContexts.back().NumCleanupObjects,
-                           ExprCleanupObjects.end());
+  ExprCleanupObjects.erase(
+         ExprCleanupObjects.begin() + ExprEvalContexts.back().NumCleanupObjects,
+         ExprCleanupObjects.end());
   Cleanup.reset();
   MaybeODRUseExprs.clear();
 }
@@ -19200,27 +19109,27 @@ static bool isPotentiallyConstantEvaluatedContext(Sema &SemaRef) {
   /// C++2a [expr.const]p12:
   //   An expression or conversion is potentially constant evaluated if it is
   switch (SemaRef.ExprEvalContexts.back().Context) {
-  case Sema::ExpressionEvaluationContext::ConstantEvaluated:
-  case Sema::ExpressionEvaluationContext::ImmediateFunctionContext:
-
-    // -- a manifestly constant-evaluated expression,
-  case Sema::ExpressionEvaluationContext::PotentiallyEvaluated:
-  case Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed:
-  case Sema::ExpressionEvaluationContext::DiscardedStatement:
-    // -- a potentially-evaluated expression,
-  case Sema::ExpressionEvaluationContext::UnevaluatedList:
-    // -- an immediate subexpression of a braced-init-list,
-
-    // -- [FIXME] an expression of the form & cast-expression that occurs
-    //    within a templated entity
-    // -- a subexpression of one of the above that is not a subexpression of
-    // a nested unevaluated operand.
-    return true;
+    case Sema::ExpressionEvaluationContext::ConstantEvaluated:
+    case Sema::ExpressionEvaluationContext::ImmediateFunctionContext:
+
+      // -- a manifestly constant-evaluated expression,
+    case Sema::ExpressionEvaluationContext::PotentiallyEvaluated:
+    case Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed:
+    case Sema::ExpressionEvaluationContext::DiscardedStatement:
+      // -- a potentially-evaluated expression,
+    case Sema::ExpressionEvaluationContext::UnevaluatedList:
+      // -- an immediate subexpression of a braced-init-list,
+
+      // -- [FIXME] an expression of the form & cast-expression that occurs
+      //    within a templated entity
+      // -- a subexpression of one of the above that is not a subexpression of
+      // a nested unevaluated operand.
+      return true;
 
-  case Sema::ExpressionEvaluationContext::Unevaluated:
-  case Sema::ExpressionEvaluationContext::UnevaluatedAbstract:
-    // Expressions in this context are never evaluated.
-    return false;
+    case Sema::ExpressionEvaluationContext::Unevaluated:
+    case Sema::ExpressionEvaluationContext::UnevaluatedAbstract:
+      // Expressions in this context are never evaluated.
+      return false;
   }
   llvm_unreachable("Invalid context");
 }
@@ -19498,7 +19407,7 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
           PointOfInstantiation = Loc;
           if (auto *MSI = Func->getMemberSpecializationInfo())
             MSI->setPointOfInstantiation(Loc);
-          // FIXME: Notify listener.
+            // FIXME: Notify listener.
           else
             Func->setTemplateSpecializationKind(TSK, PointOfInstantiation);
         } else if (TSK != TSK_ImplicitInstantiation) {
@@ -19591,7 +19500,8 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
     if (!Func->isDefined() && !Func->isInAnotherModuleUnit()) {
       if (mightHaveNonExternalLinkage(Func))
         UndefinedButUsed.insert(std::make_pair(Func->getCanonicalDecl(), Loc));
-      else if (Func->getMostRecentDecl()->isInlined() && !LangOpts.GNUInline &&
+      else if (Func->getMostRecentDecl()->isInlined() &&
+               !LangOpts.GNUInline &&
                !Func->getMostRecentDecl()->hasAttr<GNUInlineAttr>())
         UndefinedButUsed.insert(std::make_pair(Func->getCanonicalDecl(), Loc));
       else if (isExternalWithNoLinkageType(Func))
@@ -19721,7 +19631,8 @@ static void diagnoseUncapturableValueReferenceOrBinding(Sema &S,
   //  If the parameter still belongs to the translation unit, then
   //  we're actually just using one parameter in the declaration of
   //  the next.
-  if (isa<ParmVarDecl>(var) && isa<TranslationUnitDecl>(VarDC))
+  if (isa<ParmVarDecl>(var) &&
+      isa<TranslationUnitDecl>(VarDC))
     return;
 
   // For C code, don't diagnose about capture if we're not actually in code
@@ -19746,8 +19657,9 @@ static void diagnoseUncapturableValueReferenceOrBinding(Sema &S,
   }
 
   S.Diag(loc, diag::err_reference_to_local_in_enclosing_context)
-      << var << ValueKind << ContextKind << VarDC;
-  S.Diag(var->getLocation(), diag::note_entity_declared_at) << var;
+    << var << ValueKind << ContextKind << VarDC;
+  S.Diag(var->getLocation(), diag::note_entity_declared_at)
+      << var;
 
   // FIXME: Add additional diagnostic info about class etc. which prevents
   // capture.
@@ -19908,7 +19820,8 @@ static bool captureInBlock(BlockScopeInfo *BSI, ValueDecl *Var,
   if (!Invalid &&
       CaptureType.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) {
     if (BuildAndDiagnose) {
-      S.Diag(Loc, diag::err_arc_autoreleasing_capture) << /*block*/ 0;
+      S.Diag(Loc, diag::err_arc_autoreleasing_capture)
+        << /*block*/ 0;
       S.Diag(Var->getLocation(), diag::note_previous_decl) << Var;
       Invalid = true;
     } else {
@@ -20039,7 +19952,7 @@ static bool captureInLambda(LambdaScopeInfo *LSI, ValueDecl *Var,
     //   captured entity is a reference to a function, the
     //   corresponding data member is also a reference to a
     //   function. - end note ]
-    if (const ReferenceType *RefType = CaptureType->getAs<ReferenceType>()) {
+    if (const ReferenceType *RefType = CaptureType->getAs<ReferenceType>()){
       if (!RefType->getPointeeType()->isFunctionType())
         CaptureType = RefType->getPointeeType();
     }
@@ -20050,7 +19963,7 @@ static bool captureInLambda(LambdaScopeInfo *LSI, ValueDecl *Var,
       if (BuildAndDiagnose) {
         S.Diag(Loc, diag::err_arc_autoreleasing_capture) << /*lambda*/ 1;
         S.Diag(Var->getLocation(), diag::note_previous_decl)
-            << Var->getDeclName();
+          << Var->getDeclName();
         Invalid = true;
       } else {
         return false;
@@ -20238,8 +20151,7 @@ bool Sema::tryCaptureVariable(
   assert(VD && "Cannot capture a null variable");
 
   const unsigned MaxFunctionScopesIndex = FunctionScopeIndexToStopAt
-                                              ? *FunctionScopeIndexToStopAt
-                                              : FunctionScopes.size() - 1;
+      ? *FunctionScopeIndexToStopAt : FunctionScopes.size() - 1;
   // We need to sync up the Declaration Context with the
   // FunctionScopeIndexToStopAt
   if (FunctionScopeIndexToStopAt) {
@@ -20324,7 +20236,7 @@ bool Sema::tryCaptureVariable(
       return true;
     }
 
-    FunctionScopeInfo *FSI = FunctionScopes[FunctionScopesIndex];
+    FunctionScopeInfo  *FSI = FunctionScopes[FunctionScopesIndex];
     CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FSI);
 
     // Check whether we've already captured it.
@@ -20472,13 +20384,13 @@ bool Sema::tryCaptureVariable(
   // If the variable had already been captured previously, we start capturing
   // at the lambda nested within that one.
   bool Invalid = false;
-  for (unsigned I = ++FunctionScopesIndex, N = MaxFunctionScopesIndex + 1;
-       I != N; ++I) {
+  for (unsigned I = ++FunctionScopesIndex, N = MaxFunctionScopesIndex + 1; I != N;
+       ++I) {
     CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[I]);
 
-    // Certain capturing entities (lambdas, blocks etc.) are not allowed to
-    // capture certain types of variables (unnamed, variably modified types
-    // etc.) so check for eligibility.
+    // Certain capturing entities (lambdas, blocks etc.) are not allowed to capture
+    // certain types of variables (unnamed, variably modified types etc.)
+    // so check for eligibility.
     if (!Invalid)
       Invalid =
           !isVariableCapturable(CSI, Var, ExprLoc, BuildAndDiagnose, *this);
@@ -20489,12 +20401,10 @@ bool Sema::tryCaptureVariable(
       return true;
 
     if (BlockScopeInfo *BSI = dyn_cast<BlockScopeInfo>(CSI)) {
-      Invalid =
-          !captureInBlock(BSI, Var, ExprLoc, BuildAndDiagnose, CaptureType,
-                          DeclRefType, Nested, *this, Invalid);
+      Invalid = !captureInBlock(BSI, Var, ExprLoc, BuildAndDiagnose, CaptureType,
+                               DeclRefType, Nested, *this, Invalid);
       Nested = true;
-    } else if (CapturedRegionScopeInfo *RSI =
-                   dyn_cast<CapturedRegionScopeInfo>(CSI)) {
+    } else if (CapturedRegionScopeInfo *RSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) {
       Invalid = !captureInCapturedRegion(
           RSI, Var, ExprLoc, BuildAndDiagnose, CaptureType, DeclRefType, Nested,
           Kind, /*IsTopScope*/ I == N - 1, *this, Invalid);
@@ -20519,8 +20429,8 @@ bool Sema::tryCaptureVariable(ValueDecl *Var, SourceLocation Loc,
   QualType CaptureType;
   QualType DeclRefType;
   return tryCaptureVariable(Var, Loc, Kind, EllipsisLoc,
-                            /*BuildAndDiagnose=*/true, CaptureType, DeclRefType,
-                            nullptr);
+                            /*BuildAndDiagnose=*/true, CaptureType,
+                            DeclRefType, nullptr);
 }
 
 bool Sema::NeedToCaptureVariable(ValueDecl *Var, SourceLocation Loc) {
@@ -20554,24 +20464,23 @@ namespace {
 class CopiedTemplateArgs {
   bool HasArgs;
   TemplateArgumentListInfo TemplateArgStorage;
-
 public:
-  template <typename RefExpr>
+  template<typename RefExpr>
   CopiedTemplateArgs(RefExpr *E) : HasArgs(E->hasExplicitTemplateArgs()) {
     if (HasArgs)
       E->copyTemplateArgumentsInto(TemplateArgStorage);
   }
-  operator TemplateArgumentListInfo *()
+  operator TemplateArgumentListInfo*()
 #ifdef __has_cpp_attribute
 #if __has_cpp_attribute(clang::lifetimebound)
-      [[clang::lifetimebound]]
+  [[clang::lifetimebound]]
 #endif
 #endif
   {
     return HasArgs ? &TemplateArgStorage : nullptr;
   }
 };
-} // namespace
+}
 
 /// Walk the set of potential results of an expression and mark them all as
 /// non-odr-uses if they satisfy the side-conditions of the NonOdrUseReason.
@@ -20763,7 +20672,7 @@ static ExprResult rebuildPotentialResultsAsNonOdrUsed(Sema &S, Expr *E,
       if (!Sub.isUsable())
         return Sub;
       BO->setLHS(Sub.get());
-      //   -- If e is a comma expression, ...
+    //   -- If e is a comma expression, ...
     } else if (BO->getOpcode() == BO_Comma) {
       ExprResult Sub = Rebuild(RHS);
       if (!Sub.isUsable())
@@ -20960,8 +20869,8 @@ void Sema::CleanupVarDeclMarking() {
 
   for (Expr *E : LocalMaybeODRUseExprs) {
     if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
-      MarkVarDeclODRUsed(cast<VarDecl>(DRE->getDecl()), DRE->getLocation(),
-                         *this);
+      MarkVarDeclODRUsed(cast<VarDecl>(DRE->getDecl()),
+                         DRE->getLocation(), *this);
     } else if (auto *ME = dyn_cast<MemberExpr>(E)) {
       MarkVarDeclODRUsed(cast<VarDecl>(ME->getMemberDecl()), ME->getMemberLoc(),
                          *this);
@@ -21082,7 +20991,7 @@ static void DoMarkVarDeclReferenced(
         PointOfInstantiation = Loc;
         if (MSI)
           MSI->setPointOfInstantiation(PointOfInstantiation);
-        // FIXME: Notify listener.
+          // FIXME: Notify listener.
         else
           Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
       }
@@ -21108,8 +21017,8 @@ static void DoMarkVarDeclReferenced(
         else if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
           ME->setMemberDecl(ME->getMemberDecl());
       } else if (FirstInstantiation) {
-        SemaRef.PendingInstantiations.push_back(
-            std::make_pair(Var, PointOfInstantiation));
+        SemaRef.PendingInstantiations
+            .push_back(std::make_pair(Var, PointOfInstantiation));
       } else {
         bool Inserted = false;
         for (auto &I : SemaRef.SavedPendingInstantiations) {
@@ -21131,8 +21040,8 @@ static void DoMarkVarDeclReferenced(
         // no direct way to avoid enqueueing the pending instantiation
         // multiple times.
         if (isa<VarTemplateSpecializationDecl>(Var) && !Inserted)
-          SemaRef.PendingInstantiations.push_back(
-              std::make_pair(Var, PointOfInstantiation));
+          SemaRef.PendingInstantiations
+            .push_back(std::make_pair(Var, PointOfInstantiation));
       }
     }
   }
@@ -21306,8 +21215,8 @@ MarkExprReferenced(Sema &SemaRef, SourceLocation Loc, Decl *D, Expr *E,
   if (!MD)
     return;
   // Only attempt to devirtualize if this is truly a virtual call.
-  bool IsVirtualCall =
-      MD->isVirtual() && ME->performsVirtualDispatch(SemaRef.getLangOpts());
+  bool IsVirtualCall = MD->isVirtual() &&
+                          ME->performsVirtualDispatch(SemaRef.getLangOpts());
   if (!IsVirtualCall)
     return;
 
@@ -21388,13 +21297,13 @@ void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D,
 }
 
 namespace {
-// Mark all of the declarations used by a type as referenced.
-// FIXME: Not fully implemented yet! We need to have a better understanding
-// of when we're entering a context we should not recurse into.
-// FIXME: This is and EvaluatedExprMarker are more-or-less equivalent to
-// TreeTransforms rebuilding the type in a new context. Rather than
-// duplicating the TreeTransform logic, we should consider reusing it here.
-// Currently that causes problems when rebuilding LambdaExprs.
+  // Mark all of the declarations used by a type as referenced.
+  // FIXME: Not fully implemented yet! We need to have a better understanding
+  // of when we're entering a context we should not recurse into.
+  // FIXME: This is and EvaluatedExprMarker are more-or-less equivalent to
+  // TreeTransforms rebuilding the type in a new context. Rather than
+  // duplicating the TreeTransform logic, we should consider reusing it here.
+  // Currently that causes problems when rebuilding LambdaExprs.
 class MarkReferencedDecls : public DynamicRecursiveASTVisitor {
   Sema &S;
   SourceLocation Loc;
@@ -21404,7 +21313,7 @@ class MarkReferencedDecls : public DynamicRecursiveASTVisitor {
 
   bool TraverseTemplateArgument(const TemplateArgument &Arg) override;
 };
-} // namespace
+}
 
 bool MarkReferencedDecls::TraverseTemplateArgument(
     const TemplateArgument &Arg) {
@@ -21477,8 +21386,9 @@ class EvaluatedExprMarker : public UsedDeclVisitor<EvaluatedExprMarker> {
 };
 } // namespace
 
-void Sema::MarkDeclarationsReferencedInExpr(Expr *E, bool SkipLocalVariables,
-                                            ArrayRef<const Expr *> StopAt) {
+void Sema::MarkDeclarationsReferencedInExpr(Expr *E,
+                                            bool SkipLocalVariables,
+                                            ArrayRef<const Expr*> StopAt) {
   EvaluatedExprMarker(*this, SkipLocalVariables, StopAt).Visit(E);
 }
 
@@ -21543,7 +21453,7 @@ bool Sema::DiagIfReachable(SourceLocation Loc, ArrayRef<const Stmt *> Stmts,
 /// behavior of a program, such as passing a non-POD value through an ellipsis.
 /// Failure to do so will likely result in spurious diagnostics or failures
 /// during overload resolution or within sizeof/alignof/typeof/typeid.
-bool Sema::DiagRuntimeBehavior(SourceLocation Loc, ArrayRef<const Stmt *> Stmts,
+bool Sema::DiagRuntimeBehavior(SourceLocation Loc, ArrayRef<const Stmt*> Stmts,
                                const PartialDiagnostic &PD) {
 
   if (ExprEvalContexts.back().isDiscardedStatementContext())
@@ -21596,12 +21506,12 @@ bool Sema::CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
 
   public:
     CallReturnIncompleteDiagnoser(FunctionDecl *FD, CallExpr *CE)
-        : FD(FD), CE(CE) {}
+      : FD(FD), CE(CE) { }
 
     void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
       if (!FD) {
         S.Diag(Loc, diag::err_call_incomplete_return)
-            << T << CE->getSourceRange();
+          << T << CE->getSourceRange();
         return;
       }
 
@@ -21633,8 +21543,8 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
     IsOrAssign = Op->getOpcode() == BO_OrAssign;
 
     // Greylist some idioms by putting them into a warning subcategory.
-    if (ObjCMessageExpr *ME =
-            dyn_cast<ObjCMessageExpr>(Op->getRHS()->IgnoreParenCasts())) {
+    if (ObjCMessageExpr *ME
+          = dyn_cast<ObjCMessageExpr>(Op->getRHS()->IgnoreParenCasts())) {
       Selector Sel = ME->getSelector();
 
       // self = [<foo> init...]
@@ -21665,15 +21575,15 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
   SourceLocation Open = E->getBeginLoc();
   SourceLocation Close = getLocForEndOfToken(E->getSourceRange().getEnd());
   Diag(Loc, diag::note_condition_assign_silence)
-      << FixItHint::CreateInsertion(Open, "(")
-      << FixItHint::CreateInsertion(Close, ")");
+        << FixItHint::CreateInsertion(Open, "(")
+        << FixItHint::CreateInsertion(Close, ")");
 
   if (IsOrAssign)
     Diag(Loc, diag::note_condition_or_assign_to_comparison)
-        << FixItHint::CreateReplacement(Loc, "!=");
+      << FixItHint::CreateReplacement(Loc, "!=");
   else
     Diag(Loc, diag::note_condition_assign_to_comparison)
-        << FixItHint::CreateReplacement(Loc, "==");
+      << FixItHint::CreateReplacement(Loc, "==");
 }
 
 void Sema::DiagnoseEqualityWithExtraParens(ParenExpr *ParenE) {
@@ -21691,17 +21601,17 @@ void Sema::DiagnoseEqualityWithExtraParens(ParenExpr *ParenE) {
 
   if (BinaryOperator *opE = dyn_cast<BinaryOperator>(E))
     if (opE->getOpcode() == BO_EQ &&
-        opE->getLHS()->IgnoreParenImpCasts()->isModifiableLvalue(Context) ==
-            Expr::MLV_Valid) {
+        opE->getLHS()->IgnoreParenImpCasts()->isModifiableLvalue(Context)
+                                                           == Expr::MLV_Valid) {
       SourceLocation Loc = opE->getOperatorLoc();
 
       Diag(Loc, diag::warn_equality_with_extra_parens) << E->getSourceRange();
       SourceRange ParenERange = ParenE->getSourceRange();
       Diag(Loc, diag::note_equality_comparison_silence)
-          << FixItHint::CreateRemoval(ParenERange.getBegin())
-          << FixItHint::CreateRemoval(ParenERange.getEnd());
+        << FixItHint::CreateRemoval(ParenERange.getBegin())
+        << FixItHint::CreateRemoval(ParenERange.getEnd());
       Diag(Loc, diag::note_equality_comparison_to_assign)
-          << FixItHint::CreateReplacement(Loc, "=");
+        << FixItHint::CreateReplacement(Loc, "=");
     }
 }
 
@@ -21712,8 +21622,7 @@ ExprResult Sema::CheckBooleanCondition(SourceLocation Loc, Expr *E,
     DiagnoseEqualityWithExtraParens(parenE);
 
   ExprResult result = CheckPlaceholderExpr(E);
-  if (result.isInvalid())
-    return ExprError();
+  if (result.isInvalid()) return ExprError();
   E = result.get();
 
   if (!E->isTypeDependent()) {
@@ -21731,7 +21640,7 @@ ExprResult Sema::CheckBooleanCondition(SourceLocation Loc, Expr *E,
     QualType T = E->getType();
     if (!T->isScalarType()) { // C99 6.8.4.1p1
       Diag(Loc, diag::err_typecheck_statement_requires_scalar)
-          << T << E->getSourceRange();
+        << T << E->getSourceRange();
       return ExprError();
     }
     CheckBoolLikeConversion(E, Loc);
@@ -21779,182 +21688,190 @@ Sema::ConditionResult Sema::ActOnCondition(Scope *S, SourceLocation Loc,
 }
 
 namespace {
-/// A visitor for rebuilding a call to an __unknown_any expression
-/// to have an appropriate type.
-struct RebuildUnknownAnyFunction
+  /// A visitor for rebuilding a call to an __unknown_any expression
+  /// to have an appropriate type.
+  struct RebuildUnknownAnyFunction
     : StmtVisitor<RebuildUnknownAnyFunction, ExprResult> {
 
-  Sema &S;
+    Sema &S;
 
-  RebuildUnknownAnyFunction(Sema &S) : S(S) {}
+    RebuildUnknownAnyFunction(Sema &S) : S(S) {}
 
-  ExprResult VisitStmt(Stmt *S) { llvm_unreachable("unexpected statement!"); }
+    ExprResult VisitStmt(Stmt *S) {
+      llvm_unreachable("unexpected statement!");
+    }
 
-  ExprResult VisitExpr(Expr *E) {
-    S.Diag(E->getExprLoc(), diag::err_unsupported_unknown_any_call)
+    ExprResult VisitExpr(Expr *E) {
+      S.Diag(E->getExprLoc(), diag::err_unsupported_unknown_any_call)
         << E->getSourceRange();
-    return ExprError();
-  }
-
-  /// Rebuild an expression which simply semantically wraps another
-  /// expression which it shares the type and value kind of.
-  template <class T> ExprResult rebuildSugarExpr(T *E) {
-    ExprResult SubResult = Visit(E->getSubExpr());
-    if (SubResult.isInvalid())
       return ExprError();
+    }
 
-    Expr *SubExpr = SubResult.get();
-    E->setSubExpr(SubExpr);
-    E->setType(SubExpr->getType());
-    E->setValueKind(SubExpr->getValueKind());
-    assert(E->getObjectKind() == OK_Ordinary);
-    return E;
-  }
+    /// Rebuild an expression which simply semantically wraps another
+    /// expression which it shares the type and value kind of.
+    template <class T> ExprResult rebuildSugarExpr(T *E) {
+      ExprResult SubResult = Visit(E->getSubExpr());
+      if (SubResult.isInvalid()) return ExprError();
 
-  ExprResult VisitParenExpr(ParenExpr *E) { return rebuildSugarExpr(E); }
+      Expr *SubExpr = SubResult.get();
+      E->setSubExpr(SubExpr);
+      E->setType(SubExpr->getType());
+      E->setValueKind(SubExpr->getValueKind());
+      assert(E->getObjectKind() == OK_Ordinary);
+      return E;
+    }
 
-  ExprResult VisitUnaryExtension(UnaryOperator *E) {
-    return rebuildSugarExpr(E);
-  }
+    ExprResult VisitParenExpr(ParenExpr *E) {
+      return rebuildSugarExpr(E);
+    }
 
-  ExprResult VisitUnaryAddrOf(UnaryOperator *E) {
-    ExprResult SubResult = Visit(E->getSubExpr());
-    if (SubResult.isInvalid())
-      return ExprError();
+    ExprResult VisitUnaryExtension(UnaryOperator *E) {
+      return rebuildSugarExpr(E);
+    }
 
-    Expr *SubExpr = SubResult.get();
-    E->setSubExpr(SubExpr);
-    E->setType(S.Context.getPointerType(SubExpr->getType()));
-    assert(E->isPRValue());
-    assert(E->getObjectKind() == OK_Ordinary);
-    return E;
-  }
+    ExprResult VisitUnaryAddrOf(UnaryOperator *E) {
+      ExprResult SubResult = Visit(E->getSubExpr());
+      if (SubResult.isInvalid()) return ExprError();
 
-  ExprResult resolveDecl(Expr *E, ValueDecl *VD) {
-    if (!isa<FunctionDecl>(VD))
-      return VisitExpr(E);
+      Expr *SubExpr = SubResult.get();
+      E->setSubExpr(SubExpr);
+      E->setType(S.Context.getPointerType(SubExpr->getType()));
+      assert(E->isPRValue());
+      assert(E->getObjectKind() == OK_Ordinary);
+      return E;
+    }
 
-    E->setType(VD->getType());
+    ExprResult resolveDecl(Expr *E, ValueDecl *VD) {
+      if (!isa<FunctionDecl>(VD)) return VisitExpr(E);
 
-    assert(E->isPRValue());
-    if (S.getLangOpts().CPlusPlus &&
-        !(isa<CXXMethodDecl>(VD) && cast<CXXMethodDecl>(VD)->isInstance()))
-      E->setValueKind(VK_LValue);
+      E->setType(VD->getType());
 
-    return E;
-  }
+      assert(E->isPRValue());
+      if (S.getLangOpts().CPlusPlus &&
+          !(isa<CXXMethodDecl>(VD) &&
+            cast<CXXMethodDecl>(VD)->isInstance()))
+        E->setValueKind(VK_LValue);
 
-  ExprResult VisitMemberExpr(MemberExpr *E) {
-    return resolveDecl(E, E->getMemberDecl());
-  }
+      return E;
+    }
 
-  ExprResult VisitDeclRefExpr(DeclRefExpr *E) {
-    return resolveDecl(E, E->getDecl());
-  }
-};
-} // namespace
+    ExprResult VisitMemberExpr(MemberExpr *E) {
+      return resolveDecl(E, E->getMemberDecl());
+    }
+
+    ExprResult VisitDeclRefExpr(DeclRefExpr *E) {
+      return resolveDecl(E, E->getDecl());
+    }
+  };
+}
 
 /// Given a function expression of unknown-any type, try to rebuild it
 /// to have a function type.
 static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *FunctionExpr) {
   ExprResult Result = RebuildUnknownAnyFunction(S).Visit(FunctionExpr);
-  if (Result.isInvalid())
-    return ExprError();
+  if (Result.isInvalid()) return ExprError();
   return S.DefaultFunctionArrayConversion(Result.get());
 }
 
 namespace {
-/// A visitor for rebuilding an expression of type __unknown_anytype
-/// into one which resolves the type directly on the referring
-/// expression.  Strict preservation of the original source
-/// structure is not a goal.
-struct RebuildUnknownAnyExpr : StmtVisitor<RebuildUnknownAnyExpr, ExprResult> {
+  /// A visitor for rebuilding an expression of type __unknown_anytype
+  /// into one which resolves the type directly on the referring
+  /// expression.  Strict preservation of the original source
+  /// structure is not a goal.
+  struct RebuildUnknownAnyExpr
+    : StmtVisitor<RebuildUnknownAnyExpr, ExprResult> {
 
-  Sema &S;
+    Sema &S;
 
-  /// The current destination type.
-  QualType DestType;
+    /// The current destination type.
+    QualType DestType;
 
-  RebuildUnknownAnyExpr(Sema &S, QualType CastType)
+    RebuildUnknownAnyExpr(Sema &S, QualType CastType)
       : S(S), DestType(CastType) {}
 
-  ExprResult VisitStmt(Stmt *S) { llvm_unreachable("unexpected statement!"); }
+    ExprResult VisitStmt(Stmt *S) {
+      llvm_unreachable("unexpected statement!");
+    }
 
-  ExprResult VisitExpr(Expr *E) {
-    S.Diag(E->getExprLoc(), diag::err_unsupported_unknown_any_expr)
+    ExprResult VisitExpr(Expr *E) {
+      S.Diag(E->getExprLoc(), diag::err_unsupported_unknown_any_expr)
         << E->getSourceRange();
-    return ExprError();
-  }
+      return ExprError();
+    }
 
-  ExprResult VisitCallExpr(CallExpr *E);
-  ExprResult VisitObjCMessageExpr(ObjCMessageExpr *E);
+    ExprResult VisitCallExpr(CallExpr *E);
+    ExprResult VisitObjCMessageExpr(ObjCMessageExpr *E);
 
-  /// Rebuild an expression which simply semantically wraps another
-  /// expression which it shares the type and value kind of.
-  template <class T> ExprResult rebuildSugarExpr(T *E) {
-    ExprResult SubResult = Visit(E->getSubExpr());
-    if (SubResult.isInvalid())
-      return ExprError();
-    Expr *SubExpr = SubResult.get();
-    E->setSubExpr(SubExpr);
-    E->setType(SubExpr->getType());
-    E->setValueKind(SubExpr->getValueKind());
-    assert(E->getObjectKind() == OK_Ordinary);
-    return E;
-  }
+    /// Rebuild an expression which simply semantically wraps another
+    /// expression which it shares the type and value kind of.
+    template <class T> ExprResult rebuildSugarExpr(T *E) {
+      ExprResult SubResult = Visit(E->getSubExpr());
+      if (SubResult.isInvalid()) return ExprError();
+      Expr *SubExpr = SubResult.get();
+      E->setSubExpr(SubExpr);
+      E->setType(SubExpr->getType());
+      E->setValueKind(SubExpr->getValueKind());
+      assert(E->getObjectKind() == OK_Ordinary);
+      return E;
+    }
 
-  ExprResult VisitParenExpr(ParenExpr *E) { return rebuildSugarExpr(E); }
+    ExprResult VisitParenExpr(ParenExpr *E) {
+      return rebuildSugarExpr(E);
+    }
 
-  ExprResult VisitUnaryExtension(UnaryOperator *E) {
-    return rebuildSugarExpr(E);
-  }
+    ExprResult VisitUnaryExtension(UnaryOperator *E) {
+      return rebuildSugarExpr(E);
+    }
 
-  ExprResult VisitUnaryAddrOf(UnaryOperator *E) {
-    const PointerType *Ptr = DestType->getAs<PointerType>();
-    if (!Ptr) {
-      S.Diag(E->getOperatorLoc(), diag::err_unknown_any_addrof)
+    ExprResult VisitUnaryAddrOf(UnaryOperator *E) {
+      const PointerType *Ptr = DestType->getAs<PointerType>();
+      if (!Ptr) {
+        S.Diag(E->getOperatorLoc(), diag::err_unknown_any_addrof)
           << E->getSourceRange();
-      return ExprError();
-    }
+        return ExprError();
+      }
 
-    if (isa<CallExpr>(E->getSubExpr())) {
-      S.Diag(E->getOperatorLoc(), diag::err_unknown_any_addrof_call)
+      if (isa<CallExpr>(E->getSubExpr())) {
+        S.Diag(E->getOperatorLoc(), diag::err_unknown_any_addrof_call)
           << E->getSourceRange();
-      return ExprError();
-    }
+        return ExprError();
+      }
 
-    assert(E->isPRValue());
-    assert(E->getObjectKind() == OK_Ordinary);
-    E->setType(DestType);
+      assert(E->isPRValue());
+      assert(E->getObjectKind() == OK_Ordinary);
+      E->setType(DestType);
 
-    // Build the sub-expression as if it were an object of the pointee type.
-    DestType = Ptr->getPointeeType();
-    ExprResult SubResult = Visit(E->getSubExpr());
-    if (SubResult.isInvalid())
-      return ExprError();
-    E->setSubExpr(SubResult.get());
-    return E;
-  }
+      // Build the sub-expression as if it were an object of the pointee type.
+      DestType = Ptr->getPointeeType();
+      ExprResult SubResult = Visit(E->getSubExpr());
+      if (SubResult.isInvalid()) return ExprError();
+      E->setSubExpr(SubResult.get());
+      return E;
+    }
 
-  ExprResult VisitImplicitCastExpr(ImplicitCastExpr *E);
+    ExprResult VisitImplicitCastExpr(ImplicitCastExpr *E);
 
-  ExprResult resolveDecl(Expr *E, ValueDecl *VD);
+    ExprResult resolveDecl(Expr *E, ValueDecl *VD);
 
-  ExprResult VisitMemberExpr(MemberExpr *E) {
-    return resolveDecl(E, E->getMemberDecl());
-  }
+    ExprResult VisitMemberExpr(MemberExpr *E) {
+      return resolveDecl(E, E->getMemberDecl());
+    }
 
-  ExprResult VisitDeclRefExpr(DeclRefExpr *E) {
-    return resolveDecl(E, E->getDecl());
-  }
-};
-} // namespace
+    ExprResult VisitDeclRefExpr(DeclRefExpr *E) {
+      return resolveDecl(E, E->getDecl());
+    }
+  };
+}
 
 /// Rebuilds a call expression which yielded __unknown_anytype.
 ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *E) {
   Expr *CalleeExpr = E->getCallee();
 
-  enum FnKind { FK_MemberFunction, FK_FunctionPointer, FK_BlockPointer };
+  enum FnKind {
+    FK_MemberFunction,
+    FK_FunctionPointer,
+    FK_BlockPointer
+  };
 
   FnKind Kind;
   QualType CalleeType = CalleeExpr->getType();
@@ -21978,7 +21895,8 @@ ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *E) {
     if (Kind == FK_BlockPointer)
       diagID = diag::err_block_returning_array_function;
 
-    S.Diag(E->getExprLoc(), diagID) << DestType->isFunctionType() << DestType;
+    S.Diag(E->getExprLoc(), diagID)
+      << DestType->isFunctionType() << DestType;
     return ExprError();
   }
 
@@ -22021,7 +21939,8 @@ ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *E) {
     DestType = S.Context.getFunctionType(DestType, ParamTypes,
                                          Proto->getExtProtoInfo());
   } else {
-    DestType = S.Context.getFunctionNoProtoType(DestType, FnType->getExtInfo());
+    DestType = S.Context.getFunctionNoProtoType(DestType,
+                                                FnType->getExtInfo());
   }
 
   // Rebuild the appropriate pointer-to-function type.
@@ -22041,8 +21960,7 @@ ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *E) {
 
   // Finally, we can recurse.
   ExprResult CalleeResult = Visit(CalleeExpr);
-  if (!CalleeResult.isUsable())
-    return ExprError();
+  if (!CalleeResult.isUsable()) return ExprError();
   E->setCallee(CalleeResult.get());
 
   // Bind a temporary if necessary.
@@ -22053,7 +21971,7 @@ ExprResult RebuildUnknownAnyExpr::VisitObjCMessageExpr(ObjCMessageExpr *E) {
   // Verify that this is a legal result type of a call.
   if (DestType->isArrayType() || DestType->isFunctionType()) {
     S.Diag(E->getExprLoc(), diag::err_func_returning_array_function)
-        << DestType->isFunctionType() << DestType;
+      << DestType->isFunctionType() << DestType;
     return ExprError();
   }
 
@@ -22082,8 +22000,7 @@ ExprResult RebuildUnknownAnyExpr::VisitImplicitCastExpr(ImplicitCastExpr *E) {
     DestType = DestType->castAs<PointerType>()->getPointeeType();
 
     ExprResult Result = Visit(E->getSubExpr());
-    if (!Result.isUsable())
-      return ExprError();
+    if (!Result.isUsable()) return ExprError();
 
     E->setSubExpr(Result.get());
     return E;
@@ -22099,8 +22016,7 @@ ExprResult RebuildUnknownAnyExpr::VisitImplicitCastExpr(ImplicitCastExpr *E) {
     DestType = S.Context.getLValueReferenceType(DestType);
 
     ExprResult Result = Visit(E->getSubExpr());
-    if (!Result.isUsable())
-      return ExprError();
+    if (!Result.isUsable()) return ExprError();
 
     E->setSubExpr(Result.get());
     return E;
@@ -22120,15 +22036,14 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) {
     if (const PointerType *Ptr = Type->getAs<PointerType>()) {
       DestType = Ptr->getPointeeType();
       ExprResult Result = resolveDecl(E, VD);
-      if (Result.isInvalid())
-        return ExprError();
+      if (Result.isInvalid()) return ExprError();
       return S.ImpCastExprToType(Result.get(), Type, CK_FunctionToPointerDecay,
                                  VK_PRValue);
     }
 
     if (!Type->isFunctionType()) {
       S.Diag(E->getExprLoc(), diag::err_unknown_any_function)
-          << VD << E->getSourceRange();
+        << VD << E->getSourceRange();
       return ExprError();
     }
     if (const FunctionProtoType *FT = Type->getAs<FunctionProtoType>()) {
@@ -22137,11 +22052,9 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) {
       // type. See the lengthy commentary in that routine.
       QualType FDT = FD->getType();
       const FunctionType *FnType = FDT->castAs<FunctionType>();
-      const FunctionProtoType *Proto =
-          dyn_cast_or_null<FunctionProtoType>(FnType);
+      const FunctionProtoType *Proto = dyn_cast_or_null<FunctionProtoType>(FnType);
       DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
-      if (DRE && Proto && Proto->getParamTypes().empty() &&
-          Proto->isVariadic()) {
+      if (DRE && Proto && Proto->getParamTypes().empty() && Proto->isVariadic()) {
         SourceLocation Loc = FD->getLocation();
         FunctionDecl *NewFD = FunctionDecl::Create(
             S.Context, FD->getDeclContext(), Loc, Loc,
@@ -22153,9 +22066,10 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) {
         if (FD->getQualifier())
           NewFD->setQualifierInfo(FD->getQualifierLoc());
 
-        SmallVector<ParmVarDecl *, 16> Params;
+        SmallVector<ParmVarDecl*, 16> Params;
         for (const auto &AI : FT->param_types()) {
-          ParmVarDecl *Param = S.BuildParmVarDeclForTypedef(FD, Loc, AI);
+          ParmVarDecl *Param =
+            S.BuildParmVarDeclForTypedef(FD, Loc, AI);
           Param->setScopeInfo(0, Params.size());
           Params.push_back(Param);
         }
@@ -22175,20 +22089,20 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) {
     if (!S.getLangOpts().CPlusPlus)
       ValueKind = VK_PRValue;
 
-    //  - variables
+  //  - variables
   } else if (isa<VarDecl>(VD)) {
     if (const ReferenceType *RefTy = Type->getAs<ReferenceType>()) {
       Type = RefTy->getPointeeType();
     } else if (Type->isFunctionType()) {
       S.Diag(E->getExprLoc(), diag::err_unknown_any_var_function_type)
-          << VD << E->getSourceRange();
+        << VD << E->getSourceRange();
       return ExprError();
     }
 
-    //  - nothing else
+  //  - nothing else
   } else {
     S.Diag(E->getExprLoc(), diag::err_unsupported_unknown_any_decl)
-        << VD << E->getSourceRange();
+      << VD << E->getSourceRange();
     return ExprError();
   }
 
@@ -22211,8 +22125,7 @@ ExprResult Sema::checkUnknownAnyCast(SourceRange TypeRange, QualType CastType,
 
   // Rewrite the casted expression from scratch.
   ExprResult result = RebuildUnknownAnyExpr(*this, CastType).Visit(CastExpr);
-  if (!result.isUsable())
-    return ExprError();
+  if (!result.isUsable()) return ExprError();
 
   CastExpr = result.get();
   VK = CastExpr->getValueKind();
@@ -22225,15 +22138,14 @@ ExprResult Sema::forceUnknownAnyToType(Expr *E, QualType ToType) {
   return RebuildUnknownAnyExpr(*this, ToType).Visit(E);
 }
 
-ExprResult Sema::checkUnknownAnyArg(SourceLocation callLoc, Expr *arg,
-                                    QualType &paramType) {
+ExprResult Sema::checkUnknownAnyArg(SourceLocation callLoc,
+                                    Expr *arg, QualType &paramType) {
   // If the syntactic form of the argument is not an explicit cast of
   // any sort, just do default argument promotion.
   ExplicitCastExpr *castArg = dyn_cast<ExplicitCastExpr>(arg->IgnoreParens());
   if (!castArg) {
     ExprResult result = DefaultArgumentPromotion(arg);
-    if (result.isInvalid())
-      return ExprError();
+    if (result.isInvalid()) return ExprError();
     paramType = result.get()->getType();
     return result;
   }
@@ -22244,8 +22156,8 @@ ExprResult Sema::checkUnknownAnyArg(SourceLocation callLoc, Expr *arg,
 
   // Copy-initialize a parameter of that type.
   InitializedEntity entity =
-      InitializedEntity::InitializeParameter(Context, paramType,
-                                             /*consumed*/ false);
+    InitializedEntity::InitializeParameter(Context, paramType,
+                                           /*consumed*/ false);
   return PerformCopyInitialization(entity, callLoc, arg);
 }
 
@@ -22276,13 +22188,13 @@ static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) {
     d = msg->getMethodDecl();
     if (!d) {
       S.Diag(loc, diag::err_uncasted_send_to_unknown_any_method)
-          << static_cast<unsigned>(msg->isClassMessage()) << msg->getSelector()
-          << orig->getSourceRange();
+        << static_cast<unsigned>(msg->isClassMessage()) << msg->getSelector()
+        << orig->getSourceRange();
       return ExprError();
     }
   } else {
     S.Diag(E->getExprLoc(), diag::err_unsupported_unknown_any_expr)
-        << E->getSourceRange();
+      << E->getSourceRange();
     return ExprError();
   }
 
@@ -22294,8 +22206,7 @@ static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) {
 
 ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
   const BuiltinType *placeholderType = E->getType()->getAsPlaceholderType();
-  if (!placeholderType)
-    return E;
+  if (!placeholderType) return E;
 
   switch (placeholderType->getKind()) {
   case BuiltinType::UnresolvedTemplate: {
@@ -22476,15 +22387,18 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
   case BuiltinType::OMPIterator:
     return ExprError(Diag(E->getBeginLoc(), diag::err_omp_iterator_use));
 
-    // Everything else should be impossible.
-#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix)                   \
+  // Everything else should be impossible.
+#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
   case BuiltinType::Id:
 #include "clang/Basic/OpenCLImageTypes.def"
-#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+  case BuiltinType::Id:
 #include "clang/Basic/OpenCLExtensionTypes.def"
-#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#define SVE_TYPE(Name, Id, SingletonId) \
+  case BuiltinType::Id:
 #include "clang/Basic/AArch64ACLETypes.def"
-#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
+#define PPC_VECTOR_TYPE(Name, Id, Size) \
+  case BuiltinType::Id:
 #include "clang/Basic/PPCTypes.def"
 #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
 #include "clang/Basic/RISCVVTypes.def"



More information about the cfe-commits mailing list