[clang] Add size filter for stack auto init (PR #74777)

via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 7 15:04:23 PST 2023


https://github.com/haopliu updated https://github.com/llvm/llvm-project/pull/74777

>From bb5acad16c6a627d73a5af96e3dd4eba2ebe1a5d Mon Sep 17 00:00:00 2001
From: Haopeng Liu <haopliu at google.com>
Date: Thu, 7 Dec 2023 21:25:33 +0000
Subject: [PATCH 1/3] Add size filter for stack auto init

---
 .../include/clang/Basic/DiagnosticDriverKinds.td  |  7 +++++++
 clang/include/clang/Basic/LangOptions.def         |  2 ++
 clang/include/clang/Driver/Options.td             |  4 ++++
 clang/lib/CodeGen/CGDecl.cpp                      |  9 +++++++++
 clang/lib/Driver/ToolChains/Clang.cpp             | 15 +++++++++++++++
 clang/test/Driver/clang_f_opts.c                  | 13 +++++++++++++
 6 files changed, 50 insertions(+)

diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 676f1a62b49dd0..5fd097154d0fac 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -656,6 +656,13 @@ def err_drv_trivial_auto_var_init_stop_after_missing_dependency : Error<
 def err_drv_trivial_auto_var_init_stop_after_invalid_value : Error<
   "'-ftrivial-auto-var-init-stop-after=*' only accepts positive integers">;
 
+def err_drv_trivial_auto_var_init_size_bound_missing_dependency : Error<
+  "'-ftrivial-auto-var-init-size-bound=*' is used without "
+  "'-ftrivial-auto-var-init=zero' or '-ftrivial-auto-var-init=pattern'">;
+
+def err_drv_trivial_auto_var_init_size_bound_invalid_value : Error<
+  "'-ftrivial-auto-var-init-size-bound=*' only accepts positive integers (in bytes)">;
+
 def warn_drv_msp430_hwmult_unsupported : Warning<
   "the given MCU does not support hardware multiply, but '-mhwmult' is set to "
   "%0">, InGroup<InvalidCommandLineArgument>;
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index c3d5399905a3fd..8325561fc6d23f 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -376,6 +376,8 @@ ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKi
              "trivial automatic variable initialization")
 VALUE_LANGOPT(TrivialAutoVarInitStopAfter, 32, 0,
              "stop trivial automatic variable initialization after the specified number of instances. Must be greater than 0.")
+VALUE_LANGOPT(TrivialAutoVarInitSizeBound, 32, 0,
+             "stop trivial automatic variable initialization if var size exceeds the specified number of instances (in bytes). Must be greater than 0.")
 ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
              "signed integer overflow handling")
 ENUM_LANGOPT(ThreadModel  , ThreadModelKind, 2, ThreadModelKind::POSIX, "Thread Model")
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 0eec2b35263762..f92dbd07de20d2 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3627,6 +3627,10 @@ def ftrivial_auto_var_init_stop_after : Joined<["-"], "ftrivial-auto-var-init-st
   Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
   HelpText<"Stop initializing trivial automatic stack variables after the specified number of instances">,
   MarshallingInfoInt<LangOpts<"TrivialAutoVarInitStopAfter">>;
+def ftrivial_auto_var_init_size_bound : Joined<["-"], "ftrivial-auto-var-init-size-bound=">, Group<f_Group>,
+  Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
+  HelpText<"Stop initializing trivial automatic stack variables if var size exceeds the specified number of instances (in bytes)">,
+  MarshallingInfoInt<LangOpts<"TrivialAutoVarInitSizeBound">>;
 def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>,
   Visibility<[ClangOption, CLOption, DXCOption]>,
   HelpText<"Emit full debug info for all types used by the program">;
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index a5da0aa2965a00..1f9650e60d5e0a 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1759,20 +1759,29 @@ void CodeGenFunction::emitZeroOrPatternForAutoVarInit(QualType type,
                                                       const VarDecl &D,
                                                       Address Loc) {
   auto trivialAutoVarInit = getContext().getLangOpts().getTrivialAutoVarInit();
+  auto trivialAutoVarInitSizeBound = 
+      getContext().getLangOpts().TrivialAutoVarInitSizeBound;
   CharUnits Size = getContext().getTypeSizeInChars(type);
   bool isVolatile = type.isVolatileQualified();
   if (!Size.isZero()) {
+    auto allocSize = CGM.getDataLayout().getTypeAllocSize(Loc.getElementType());
     switch (trivialAutoVarInit) {
     case LangOptions::TrivialAutoVarInitKind::Uninitialized:
       llvm_unreachable("Uninitialized handled by caller");
     case LangOptions::TrivialAutoVarInitKind::Zero:
       if (CGM.stopAutoInit())
         return;
+      if (trivialAutoVarInitSizeBound > 0 &&
+          allocSize >= trivialAutoVarInitSizeBound)
+        return;
       emitStoresForZeroInit(CGM, D, Loc, isVolatile, Builder);
       break;
     case LangOptions::TrivialAutoVarInitKind::Pattern:
       if (CGM.stopAutoInit())
         return;
+      if (trivialAutoVarInitSizeBound > 0 &&
+          allocSize >= trivialAutoVarInitSizeBound)
+        return;
       emitStoresForPatternInit(CGM, D, Loc, isVolatile, Builder);
       break;
     }
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index f02f7c841b91f0..669c85c8c7722f 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3436,6 +3436,21 @@ static void RenderTrivialAutoVarInitOptions(const Driver &D,
     CmdArgs.push_back(
         Args.MakeArgString("-ftrivial-auto-var-init-stop-after=" + Val));
   }
+
+  if (Arg *A =
+          Args.getLastArg(options::OPT_ftrivial_auto_var_init_size_bound)) {
+    if (!Args.hasArg(options::OPT_ftrivial_auto_var_init) ||
+        StringRef(
+            Args.getLastArg(options::OPT_ftrivial_auto_var_init)->getValue()) ==
+            "uninitialized")
+      D.Diag(diag::err_drv_trivial_auto_var_init_size_bound_missing_dependency);
+    A->claim();
+    StringRef Val = A->getValue();
+    if (std::stoi(Val.str()) <= 0)
+      D.Diag(diag::err_drv_trivial_auto_var_init_size_bound_invalid_value);
+    CmdArgs.push_back(
+        Args.MakeArgString("-ftrivial-auto-var-init-size-bound=" + Val));
+  }
 }
 
 static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs,
diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c
index ebe8a0520bf0fc..7f947d2de5c6ea 100644
--- a/clang/test/Driver/clang_f_opts.c
+++ b/clang/test/Driver/clang_f_opts.c
@@ -585,6 +585,19 @@
 // CHECK-TRIVIAL-PATTERN-STOP-AFTER-INVALID-VALUE: only accepts positive integers
 // CHECK-TRIVIAL-ZERO-STOP-AFTER-INVALID-VALUE: only accepts positive integers
 
+// RUN: %clang -### -S -ftrivial-auto-var-init=pattern -ftrivial-auto-var-init-size-bound=1024 %s 2>&1 | FileCheck -check-prefix=CHECK-TRIVIAL-PATTERN-SIZE-BOUND %s
+// RUN: %clang -### -S -ftrivial-auto-var-init=zero -ftrivial-auto-var-init-size-bound=1024 %s 2>&1 | FileCheck -check-prefix=CHECK-TRIVIAL-ZERO-SIZE-BOUND %s
+// RUN: not %clang -### -S -ftrivial-auto-var-init-size-bound=1024 %s 2>&1 | FileCheck -check-prefix=CHECK-TRIVIAL-SIZE-BOUND-MISSING-DEPENDENCY %s
+// RUN: not %clang -### -S -ftrivial-auto-var-init=pattern -ftrivial-auto-var-init-size-bound=0 %s 2>&1 | FileCheck -check-prefix=CHECK-TRIVIAL-PATTERN-SIZE-BOUND-INVALID-VALUE %s
+// RUN: not %clang -### -S -ftrivial-auto-var-init=zero -ftrivial-auto-var-init-size-bound=0 %s 2>&1 | FileCheck -check-prefix=CHECK-TRIVIAL-ZERO-SIZE-BOUND-INVALID-VALUE %s
+// CHECK-TRIVIAL-PATTERN-SIZE-BOUND-NOT: is used without '-ftrivial-auto-var-init'
+// CHECK-TRIVIAL-PATTERN-SIZE-BOUND-NOT: only accepts positive integers (in bytes)
+// CHECK-TRIVIAL-ZERO-SIZE-BOUND-NOT: is used without '-ftrivial-auto-var-init'
+// CHECK-TRIVIAL-ZERO-SIZE-BOUND-NOT: only accepts positive integers (in bytes)
+// CHECK-TRIVIAL-SIZE-BOUND-MISSING-DEPENDENCY: used without '-ftrivial-auto-var-init=zero' or
+// CHECK-TRIVIAL-PATTERN-SIZE-BOUND-INVALID-VALUE: only accepts positive integers (in bytes)
+// CHECK-TRIVIAL-ZERO-SIZE-BOUND-INVALID-VALUE: only accepts positive integers (in bytes)
+
 // RUN: %clang -### -S -fno-temp-file %s 2>&1 | FileCheck -check-prefix=CHECK-NO-TEMP-FILE %s
 // CHECK-NO-TEMP-FILE: "-fno-temp-file"
 

>From 00af66353d938c6ce59dada49c8bededb06ac4fc Mon Sep 17 00:00:00 2001
From: Haopeng Liu <haopliu at google.com>
Date: Thu, 7 Dec 2023 21:30:07 +0000
Subject: [PATCH 2/3] Add size filter for stack auto init

---
 .../CodeGenCXX/auto-var-init-size-bound.cpp   | 82 +++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/auto-var-init-size-bound.cpp

diff --git a/clang/test/CodeGenCXX/auto-var-init-size-bound.cpp b/clang/test/CodeGenCXX/auto-var-init-size-bound.cpp
new file mode 100644
index 00000000000000..1f6c2b143d3978
--- /dev/null
+++ b/clang/test/CodeGenCXX/auto-var-init-size-bound.cpp
@@ -0,0 +1,82 @@
+// Pattern related size bound tests: 1, 8, 4096, 4097
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=pattern -ftrivial-auto-var-init-size-bound=1 %s -emit-llvm -o - | FileCheck -check-prefix=PATTERN-COMMON -check-prefix=PATTERN-BOUND-1 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=pattern -ftrivial-auto-var-init-size-bound=8 %s -emit-llvm -o - | FileCheck -check-prefix=PATTERN-COMMON -check-prefix=PATTERN-BOUND-8 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=pattern -ftrivial-auto-var-init-size-bound=4096 %s -emit-llvm -o - | FileCheck -check-prefix=PATTERN-COMMON -check-prefix=PATTERN-BOUND-4096 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=pattern -ftrivial-auto-var-init-size-bound=4097 %s -emit-llvm -o - | FileCheck -check-prefix=PATTERN-COMMON -check-prefix=PATTERN-BOUND-4097 %s
+//
+// Zero related size bound tests: 1, 8, 4096, 4097
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=zero -ftrivial-auto-var-init-size-bound=1 %s -emit-llvm -o - | FileCheck -check-prefix=ZERO-COMMON -check-prefix=ZERO-BOUND-1 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=zero -ftrivial-auto-var-init-size-bound=8 %s -emit-llvm -o - | FileCheck -check-prefix=ZERO-COMMON -check-prefix=ZERO-BOUND-8 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=zero -ftrivial-auto-var-init-size-bound=4096 %s -emit-llvm -o - | FileCheck -check-prefix=ZERO-COMMON -check-prefix=ZERO-BOUND-4096 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=zero -ftrivial-auto-var-init-size-bound=4097 %s -emit-llvm -o - | FileCheck -check-prefix=ZERO-COMMON -check-prefix=ZERO-BOUND-4097 %s
+
+#define ARRLEN 1024
+
+int foo(unsigned n) {
+  bool var_size_1;
+  long var_size_8 = 123;
+  void *var_size_8p;
+  int var_size_4096[ARRLEN];
+  // VLA, non-constant size
+  int var_vla[n];
+  // builtin, non-constant size
+  var_size_8p = __builtin_alloca(sizeof(unsigned long long) * n);
+  // There are 6 variables: var_size_1, var_size_8, var_size_8p, var_size_4096,
+  // var_vla, and a builtin anonymous var ("%5").
+  // "var_vla" and "%5" have a non-constant size, and they should be auto-inited
+  //  disregarding the size bound.
+  // - Size bound 1: "var_vla" and "%5"
+  // - Size bound 8: "var_size_1", "var_vla", and "%5"
+  // - Size bound 4096: "var_size_1", "var_size_8", "var_size_8p",
+  //                    "var_vla", and "%5"
+  // - Size bound 4097: "var_size_1", "var_size_8", "var_size_8p",
+  //                    "var_size_4096", "var_vla", and "%5"
+  //
+  // PATTERN-BOUND-1-NOT: store i8 -86, ptr %var_size_1, align 1, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-1-NOT: store i64 -6148914691236517206, ptr %var_size_8, align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-1-NOT: store ptr inttoptr (i64 -6148914691236517206 to ptr), ptr %var_size_8p, align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-1-NOT: call void @llvm.memset.p0.i64(ptr align 16 %var_size_4096, i8 -86, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // PATTERN-BOUND-8: store i8 -86, ptr %var_size_1, align 1, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-8-NOT: store i64 -6148914691236517206, ptr %var_size_8, align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-8-NOT: store ptr inttoptr (i64 -6148914691236517206 to ptr), ptr %var_size_8p, align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-8-NOT: call void @llvm.memset.p0.i64(ptr align 16 %var_size_4096, i8 -86, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // PATTERN-BOUND-4096: store i8 -86, ptr %var_size_1, align 1, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-4096: store i64 -6148914691236517206, ptr %var_size_8, align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-4096: store ptr inttoptr (i64 -6148914691236517206 to ptr), ptr %var_size_8p, align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-4096-NOT: call void @llvm.memset.p0.i64(ptr align 16 %var_size_4096, i8 -86, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // PATTERN-BOUND-4097: store i8 -86, ptr %var_size_1, align 1, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-4097: store i64 -6148914691236517206, ptr %var_size_8, align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-4097: store ptr inttoptr (i64 -6148914691236517206 to ptr), ptr %var_size_8p, align 8, !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-BOUND-4097: call void @llvm.memset.p0.i64(ptr align 16 %var_size_4096, i8 -86, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // PATTERN-COMMON: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %vla.cur, ptr align 4 @__const._Z3fooj.var_vla, i64 4, i1 false), !annotation [[AUTO_INIT:!.+]]
+  // PATTERN-COMMON: call void @llvm.memset.p0.i64(ptr align 16 %5, i8 -86, i64 %mul, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // ZERO-BOUND-1-NOT: store i8 0, ptr %var_size_1, align 1, !annotation [[AUTO_INIT:!.+]]
+  // ZERO-BOUND-1-NOT: store i64 0, ptr %var_size_8, align 8, !annotation [[AUTO_INIT:!.+]]
+  // ZERO-BOUND-1-NOT: store ptr null, ptr %var_size_8p, align 8, !annotation [[AUTO_INIT:!.+]]
+  // ZERO-BOUND-1-NOT: call void @llvm.memset.p0.i64(ptr align 16 %var_size_4096, i8 0, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // ZERO-BOUND-8: store i8 0, ptr %var_size_1, align 1, !annotation [[AUTO_INIT:!.+]]
+  // ZERO-BOUND-8-NOT: store i64 0, ptr %var_size_8, align 8, !annotation [[AUTO_INIT:!.+]]
+  // ZERO-BOUND-8-NOT: store ptr null, ptr %var_size_8p, align 8, !annotation [[AUTO_INIT:!.+]]
+  // ZERO-BOUND-8-NOT: call void @llvm.memset.p0.i64(ptr align 16 %var_size_4096, i8 0, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // ZERO-BOUND-4096: store i8 0, ptr %var_size_1, align 1, !annotation [[AUTO_INIT:!.+]]
+  // ZERO-BOUND-4096: store i64 0, ptr %var_size_8, align 8, !annotation [[AUTO_INIT:!.+]]
+  // ZERO-BOUND-4096: store ptr null, ptr %var_size_8p, align 8, !annotation [[AUTO_INIT:!.+]]
+  // ZERO-BOUND-4096-NOT: call void @llvm.memset.p0.i64(ptr align 16 %var_size_4096, i8 0, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // ZERO-BOUND-4097: store i8 0, ptr %var_size_1, align 1, !annotation [[AUTO_INIT:!.+]]
+  // ZERO-BOUND-4097: store i64 0, ptr %var_size_8, align 8, !annotation [[AUTO_INIT:!.+]]
+  // ZERO-BOUND-4097: store ptr null, ptr %var_size_8p, align 8, !annotation [[AUTO_INIT:!.+]]
+  // ZERO-BOUND-4097: call void @llvm.memset.p0.i64(ptr align 16 %var_size_4096, i8 0, i64 4096, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  // ZERO-COMMON: call void @llvm.memset.p0.i64(ptr align 16 %vla, i8 0, i64 %3, i1 false), !annotation [[AUTO_INIT:!.+]]
+  // ZERO-COMMON: call void @llvm.memset.p0.i64(ptr align 16 %5, i8 0, i64 %mul, i1 false), !annotation [[AUTO_INIT:!.+]]
+
+  return 0;
+}

>From 3443a97756ceeea8405c31899fded0d719f112b2 Mon Sep 17 00:00:00 2001
From: Haopeng Liu <haopliu at google.com>
Date: Thu, 7 Dec 2023 22:54:22 +0000
Subject: [PATCH 3/3] Fix the clang-format warning

---
 clang/lib/CodeGen/CGDecl.cpp | 552 +++++++++++++++++------------------
 1 file changed, 275 insertions(+), 277 deletions(-)

diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 1f9650e60d5e0a..d64ced5382b4b8 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -109,7 +109,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
       if (cast<RecordDecl>(D).getDefinition())
         DI->EmitAndRetainType(getContext().getRecordType(cast<RecordDecl>(&D)));
     return;
-  case Decl::Enum:      // enum X;
+  case Decl::Enum: // enum X;
     if (CGDebugInfo *DI = getDebugInfo())
       if (cast<EnumDecl>(D).getDefinition())
         DI->EmitAndRetainType(getContext().getEnumType(cast<EnumDecl>(&D)));
@@ -119,7 +119,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
   case Decl::StaticAssert: // static_assert(X, ""); [C++0x]
   case Decl::Label:        // __label__ x;
   case Decl::Import:
-  case Decl::MSGuid:    // __declspec(uuid("..."))
+  case Decl::MSGuid: // __declspec(uuid("..."))
   case Decl::UnnamedGlobalConstant:
   case Decl::TemplateParamObject:
   case Decl::OMPThreadPrivate:
@@ -136,11 +136,11 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
 
   case Decl::NamespaceAlias:
     if (CGDebugInfo *DI = getDebugInfo())
-        DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(D));
+      DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(D));
     return;
-  case Decl::Using:          // using X; [C++]
+  case Decl::Using: // using X; [C++]
     if (CGDebugInfo *DI = getDebugInfo())
-        DI->EmitUsingDecl(cast<UsingDecl>(D));
+      DI->EmitUsingDecl(cast<UsingDecl>(D));
     return;
   case Decl::UsingEnum: // using enum X; [C++]
     if (CGDebugInfo *DI = getDebugInfo())
@@ -173,8 +173,8 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
   case Decl::OMPDeclareMapper:
     return CGM.EmitOMPDeclareMapper(cast<OMPDeclareMapperDecl>(&D), this);
 
-  case Decl::Typedef:      // typedef int X;
-  case Decl::TypeAlias: {  // using X = int; [C++0x]
+  case Decl::Typedef:     // typedef int X;
+  case Decl::TypeAlias: { // using X = int; [C++0x]
     QualType Ty = cast<TypedefNameDecl>(D).getUnderlyingType();
     if (CGDebugInfo *DI = getDebugInfo())
       DI->EmitAndRetainType(Ty);
@@ -353,7 +353,7 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
       // be constant.
       GV->setConstant(false);
 
-      EmitCXXGuardedInit(D, GV, /*PerformInit*/true);
+      EmitCXXGuardedInit(D, GV, /*PerformInit*/ true);
     }
     return GV;
   }
@@ -405,14 +405,14 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
     // We have a constant initializer, but a nontrivial destructor. We still
     // need to perform a guarded "initialization" in order to register the
     // destructor.
-    EmitCXXGuardedInit(D, GV, /*PerformInit*/false);
+    EmitCXXGuardedInit(D, GV, /*PerformInit*/ false);
   }
 
   return GV;
 }
 
-void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
-                                      llvm::GlobalValue::LinkageTypes Linkage) {
+void CodeGenFunction::EmitStaticVarDecl(
+    const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage) {
   // Check to see if we already have a global variable for this
   // declaration.  This can happen when double-emitting function
   // bodies, e.g. with complete and base constructors.
@@ -434,7 +434,7 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
   llvm::Type *expectedType = addr->getType();
 
   llvm::GlobalVariable *var =
-    cast<llvm::GlobalVariable>(addr->stripPointerCasts());
+      cast<llvm::GlobalVariable>(addr->stripPointerCasts());
 
   // CUDA's local and local static __shared__ variables should not
   // have any non-empty initializers. This is ensured by Sema.
@@ -477,7 +477,7 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
   // FIXME: It is really dangerous to store this in the map; if anyone
   // RAUW's the GV uses of this constant will be invalid.
   llvm::Constant *castedAddr =
-    llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(var, expectedType);
+      llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(var, expectedType);
   LocalDeclMap.find(&D)->second = Address(castedAddr, elemTy, alignment);
   CGM.setStaticLocalDeclAddress(&D, castedAddr);
 
@@ -492,153 +492,149 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
 }
 
 namespace {
-  struct DestroyObject final : EHScopeStack::Cleanup {
-    DestroyObject(Address addr, QualType type,
-                  CodeGenFunction::Destroyer *destroyer,
-                  bool useEHCleanupForArray)
+struct DestroyObject final : EHScopeStack::Cleanup {
+  DestroyObject(Address addr, QualType type,
+                CodeGenFunction::Destroyer *destroyer,
+                bool useEHCleanupForArray)
       : addr(addr), type(type), destroyer(destroyer),
         useEHCleanupForArray(useEHCleanupForArray) {}
 
-    Address addr;
-    QualType type;
-    CodeGenFunction::Destroyer *destroyer;
-    bool useEHCleanupForArray;
+  Address addr;
+  QualType type;
+  CodeGenFunction::Destroyer *destroyer;
+  bool useEHCleanupForArray;
 
-    void Emit(CodeGenFunction &CGF, Flags flags) override {
-      // Don't use an EH cleanup recursively from an EH cleanup.
-      bool useEHCleanupForArray =
+  void Emit(CodeGenFunction &CGF, Flags flags) override {
+    // Don't use an EH cleanup recursively from an EH cleanup.
+    bool useEHCleanupForArray =
         flags.isForNormalCleanup() && this->useEHCleanupForArray;
 
-      CGF.emitDestroy(addr, type, destroyer, useEHCleanupForArray);
-    }
-  };
+    CGF.emitDestroy(addr, type, destroyer, useEHCleanupForArray);
+  }
+};
 
-  template <class Derived>
-  struct DestroyNRVOVariable : EHScopeStack::Cleanup {
-    DestroyNRVOVariable(Address addr, QualType type, llvm::Value *NRVOFlag)
-        : NRVOFlag(NRVOFlag), Loc(addr), Ty(type) {}
-
-    llvm::Value *NRVOFlag;
-    Address Loc;
-    QualType Ty;
-
-    void Emit(CodeGenFunction &CGF, Flags flags) override {
-      // Along the exceptions path we always execute the dtor.
-      bool NRVO = flags.isForNormalCleanup() && NRVOFlag;
-
-      llvm::BasicBlock *SkipDtorBB = nullptr;
-      if (NRVO) {
-        // If we exited via NRVO, we skip the destructor call.
-        llvm::BasicBlock *RunDtorBB = CGF.createBasicBlock("nrvo.unused");
-        SkipDtorBB = CGF.createBasicBlock("nrvo.skipdtor");
-        llvm::Value *DidNRVO =
-          CGF.Builder.CreateFlagLoad(NRVOFlag, "nrvo.val");
-        CGF.Builder.CreateCondBr(DidNRVO, SkipDtorBB, RunDtorBB);
-        CGF.EmitBlock(RunDtorBB);
-      }
+template <class Derived> struct DestroyNRVOVariable : EHScopeStack::Cleanup {
+  DestroyNRVOVariable(Address addr, QualType type, llvm::Value *NRVOFlag)
+      : NRVOFlag(NRVOFlag), Loc(addr), Ty(type) {}
+
+  llvm::Value *NRVOFlag;
+  Address Loc;
+  QualType Ty;
 
-      static_cast<Derived *>(this)->emitDestructorCall(CGF);
+  void Emit(CodeGenFunction &CGF, Flags flags) override {
+    // Along the exceptions path we always execute the dtor.
+    bool NRVO = flags.isForNormalCleanup() && NRVOFlag;
 
-      if (NRVO) CGF.EmitBlock(SkipDtorBB);
+    llvm::BasicBlock *SkipDtorBB = nullptr;
+    if (NRVO) {
+      // If we exited via NRVO, we skip the destructor call.
+      llvm::BasicBlock *RunDtorBB = CGF.createBasicBlock("nrvo.unused");
+      SkipDtorBB = CGF.createBasicBlock("nrvo.skipdtor");
+      llvm::Value *DidNRVO = CGF.Builder.CreateFlagLoad(NRVOFlag, "nrvo.val");
+      CGF.Builder.CreateCondBr(DidNRVO, SkipDtorBB, RunDtorBB);
+      CGF.EmitBlock(RunDtorBB);
     }
 
-    virtual ~DestroyNRVOVariable() = default;
-  };
+    static_cast<Derived *>(this)->emitDestructorCall(CGF);
 
-  struct DestroyNRVOVariableCXX final
-      : DestroyNRVOVariable<DestroyNRVOVariableCXX> {
-    DestroyNRVOVariableCXX(Address addr, QualType type,
-                           const CXXDestructorDecl *Dtor, llvm::Value *NRVOFlag)
-        : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr, type, NRVOFlag),
-          Dtor(Dtor) {}
+    if (NRVO)
+      CGF.EmitBlock(SkipDtorBB);
+  }
 
-    const CXXDestructorDecl *Dtor;
+  virtual ~DestroyNRVOVariable() = default;
+};
 
-    void emitDestructorCall(CodeGenFunction &CGF) {
-      CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
-                                /*ForVirtualBase=*/false,
-                                /*Delegating=*/false, Loc, Ty);
-    }
-  };
+struct DestroyNRVOVariableCXX final
+    : DestroyNRVOVariable<DestroyNRVOVariableCXX> {
+  DestroyNRVOVariableCXX(Address addr, QualType type,
+                         const CXXDestructorDecl *Dtor, llvm::Value *NRVOFlag)
+      : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr, type, NRVOFlag),
+        Dtor(Dtor) {}
 
-  struct DestroyNRVOVariableC final
-      : DestroyNRVOVariable<DestroyNRVOVariableC> {
-    DestroyNRVOVariableC(Address addr, llvm::Value *NRVOFlag, QualType Ty)
-        : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, Ty, NRVOFlag) {}
+  const CXXDestructorDecl *Dtor;
 
-    void emitDestructorCall(CodeGenFunction &CGF) {
-      CGF.destroyNonTrivialCStruct(CGF, Loc, Ty);
-    }
-  };
+  void emitDestructorCall(CodeGenFunction &CGF) {
+    CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
+                              /*ForVirtualBase=*/false,
+                              /*Delegating=*/false, Loc, Ty);
+  }
+};
 
-  struct CallStackRestore final : EHScopeStack::Cleanup {
-    Address Stack;
-    CallStackRestore(Address Stack) : Stack(Stack) {}
-    bool isRedundantBeforeReturn() override { return true; }
-    void Emit(CodeGenFunction &CGF, Flags flags) override {
-      llvm::Value *V = CGF.Builder.CreateLoad(Stack);
-      CGF.Builder.CreateStackRestore(V);
-    }
-  };
+struct DestroyNRVOVariableC final : DestroyNRVOVariable<DestroyNRVOVariableC> {
+  DestroyNRVOVariableC(Address addr, llvm::Value *NRVOFlag, QualType Ty)
+      : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, Ty, NRVOFlag) {}
 
-  struct KmpcAllocFree final : EHScopeStack::Cleanup {
-    std::pair<llvm::Value *, llvm::Value *> AddrSizePair;
-    KmpcAllocFree(const std::pair<llvm::Value *, llvm::Value *> &AddrSizePair)
-        : AddrSizePair(AddrSizePair) {}
-    void Emit(CodeGenFunction &CGF, Flags EmissionFlags) override {
-      auto &RT = CGF.CGM.getOpenMPRuntime();
-      RT.getKmpcFreeShared(CGF, AddrSizePair);
-    }
-  };
+  void emitDestructorCall(CodeGenFunction &CGF) {
+    CGF.destroyNonTrivialCStruct(CGF, Loc, Ty);
+  }
+};
 
-  struct ExtendGCLifetime final : EHScopeStack::Cleanup {
-    const VarDecl &Var;
-    ExtendGCLifetime(const VarDecl *var) : Var(*var) {}
-
-    void Emit(CodeGenFunction &CGF, Flags flags) override {
-      // Compute the address of the local variable, in case it's a
-      // byref or something.
-      DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false,
-                      Var.getType(), VK_LValue, SourceLocation());
-      llvm::Value *value = CGF.EmitLoadOfScalar(CGF.EmitDeclRefLValue(&DRE),
-                                                SourceLocation());
-      CGF.EmitExtendGCLifetime(value);
-    }
-  };
+struct CallStackRestore final : EHScopeStack::Cleanup {
+  Address Stack;
+  CallStackRestore(Address Stack) : Stack(Stack) {}
+  bool isRedundantBeforeReturn() override { return true; }
+  void Emit(CodeGenFunction &CGF, Flags flags) override {
+    llvm::Value *V = CGF.Builder.CreateLoad(Stack);
+    CGF.Builder.CreateStackRestore(V);
+  }
+};
+
+struct KmpcAllocFree final : EHScopeStack::Cleanup {
+  std::pair<llvm::Value *, llvm::Value *> AddrSizePair;
+  KmpcAllocFree(const std::pair<llvm::Value *, llvm::Value *> &AddrSizePair)
+      : AddrSizePair(AddrSizePair) {}
+  void Emit(CodeGenFunction &CGF, Flags EmissionFlags) override {
+    auto &RT = CGF.CGM.getOpenMPRuntime();
+    RT.getKmpcFreeShared(CGF, AddrSizePair);
+  }
+};
 
-  struct CallCleanupFunction final : EHScopeStack::Cleanup {
-    llvm::Constant *CleanupFn;
-    const CGFunctionInfo &FnInfo;
-    const VarDecl &Var;
+struct ExtendGCLifetime final : EHScopeStack::Cleanup {
+  const VarDecl &Var;
+  ExtendGCLifetime(const VarDecl *var) : Var(*var) {}
 
-    CallCleanupFunction(llvm::Constant *CleanupFn, const CGFunctionInfo *Info,
-                        const VarDecl *Var)
+  void Emit(CodeGenFunction &CGF, Flags flags) override {
+    // Compute the address of the local variable, in case it's a
+    // byref or something.
+    DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false,
+                    Var.getType(), VK_LValue, SourceLocation());
+    llvm::Value *value =
+        CGF.EmitLoadOfScalar(CGF.EmitDeclRefLValue(&DRE), SourceLocation());
+    CGF.EmitExtendGCLifetime(value);
+  }
+};
+
+struct CallCleanupFunction final : EHScopeStack::Cleanup {
+  llvm::Constant *CleanupFn;
+  const CGFunctionInfo &FnInfo;
+  const VarDecl &Var;
+
+  CallCleanupFunction(llvm::Constant *CleanupFn, const CGFunctionInfo *Info,
+                      const VarDecl *Var)
       : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) override {
-      DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false,
-                      Var.getType(), VK_LValue, SourceLocation());
-      // Compute the address of the local variable, in case it's a byref
-      // or something.
-      llvm::Value *Addr = CGF.EmitDeclRefLValue(&DRE).getPointer(CGF);
-
-      // In some cases, the type of the function argument will be different from
-      // the type of the pointer. An example of this is
-      // void f(void* arg);
-      // __attribute__((cleanup(f))) void *g;
-      //
-      // To fix this we insert a bitcast here.
-      QualType ArgTy = FnInfo.arg_begin()->type;
-      llvm::Value *Arg =
-        CGF.Builder.CreateBitCast(Addr, CGF.ConvertType(ArgTy));
-
-      CallArgList Args;
-      Args.add(RValue::get(Arg),
-               CGF.getContext().getPointerType(Var.getType()));
-      auto Callee = CGCallee::forDirect(CleanupFn);
-      CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
-    }
-  };
+  void Emit(CodeGenFunction &CGF, Flags flags) override {
+    DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false,
+                    Var.getType(), VK_LValue, SourceLocation());
+    // Compute the address of the local variable, in case it's a byref
+    // or something.
+    llvm::Value *Addr = CGF.EmitDeclRefLValue(&DRE).getPointer(CGF);
+
+    // In some cases, the type of the function argument will be different from
+    // the type of the pointer. An example of this is
+    // void f(void* arg);
+    // __attribute__((cleanup(f))) void *g;
+    //
+    // To fix this we insert a bitcast here.
+    QualType ArgTy = FnInfo.arg_begin()->type;
+    llvm::Value *Arg = CGF.Builder.CreateBitCast(Addr, CGF.ConvertType(ArgTy));
+
+    CallArgList Args;
+    Args.add(RValue::get(Arg), CGF.getContext().getPointerType(Var.getType()));
+    auto Callee = CGCallee::forDirect(CleanupFn);
+    CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
+  }
+};
 } // end anonymous namespace
 
 /// EmitAutoVarWithLifetime - Does the setup required for an automatic
@@ -656,9 +652,9 @@ static void EmitAutoVarWithLifetime(CodeGenFunction &CGF, const VarDecl &var,
 
   case Qualifiers::OCL_Strong: {
     CodeGenFunction::Destroyer *destroyer =
-      (var.hasAttr<ObjCPreciseLifetimeAttr>()
-       ? CodeGenFunction::destroyARCStrongPrecise
-       : CodeGenFunction::destroyARCStrongImprecise);
+        (var.hasAttr<ObjCPreciseLifetimeAttr>()
+             ? CodeGenFunction::destroyARCStrongPrecise
+             : CodeGenFunction::destroyARCStrongImprecise);
 
     CleanupKind cleanupKind = CGF.getARCCleanupKind();
     CGF.pushDestroy(cleanupKind, addr, var.getType(), destroyer,
@@ -705,14 +701,16 @@ static bool isAccessedBy(const VarDecl &var, const Stmt *s) {
 }
 
 static bool isAccessedBy(const ValueDecl *decl, const Expr *e) {
-  if (!decl) return false;
-  if (!isa<VarDecl>(decl)) return false;
+  if (!decl)
+    return false;
+  if (!isa<VarDecl>(decl))
+    return false;
   const VarDecl *var = cast<VarDecl>(decl);
   return isAccessedBy(*var, e);
 }
 
-static bool tryEmitARCCopyWeakInit(CodeGenFunction &CGF,
-                                   const LValue &destLV, const Expr *init) {
+static bool tryEmitARCCopyWeakInit(CodeGenFunction &CGF, const LValue &destLV,
+                                   const Expr *init) {
   bool needsCast = false;
 
   while (auto castExpr = dyn_cast<CastExpr>(init->IgnoreParens())) {
@@ -761,8 +759,7 @@ static bool tryEmitARCCopyWeakInit(CodeGenFunction &CGF,
   return false;
 }
 
-static void drillIntoBlockVariable(CodeGenFunction &CGF,
-                                   LValue &lvalue,
+static void drillIntoBlockVariable(CodeGenFunction &CGF, LValue &lvalue,
                                    const VarDecl *var) {
   lvalue.setAddress(CGF.emitBlockByrefAddress(lvalue.getAddress(CGF), var));
 }
@@ -875,7 +872,8 @@ void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
     // disappear in the common case.
     value = EmitScalarExpr(init);
 
-    if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
+    if (capturedByInit)
+      drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
     if (accessedByInit)
       EmitARCStoreWeak(lvalue.getAddress(*this), value, /*ignored*/ true);
     else
@@ -888,7 +886,8 @@ void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
     break;
   }
 
-  if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
+  if (capturedByInit)
+    drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
 
   EmitNullabilityCheck(lvalue, value, init->getExprLoc());
 
@@ -911,8 +910,7 @@ static bool canEmitInitWithFewStoresAfterBZero(llvm::Constant *Init,
                                                unsigned &NumStores) {
   // Zero and Undef never requires any extra stores.
   if (isa<llvm::ConstantAggregateZero>(Init) ||
-      isa<llvm::ConstantPointerNull>(Init) ||
-      isa<llvm::UndefValue>(Init))
+      isa<llvm::ConstantPointerNull>(Init) || isa<llvm::UndefValue>(Init))
     return true;
   if (isa<llvm::ConstantInt>(Init) || isa<llvm::ConstantFP>(Init) ||
       isa<llvm::ConstantVector>(Init) || isa<llvm::BlockAddress>(Init) ||
@@ -930,7 +928,7 @@ static bool canEmitInitWithFewStoresAfterBZero(llvm::Constant *Init,
   }
 
   if (llvm::ConstantDataSequential *CDS =
-        dyn_cast<llvm::ConstantDataSequential>(Init)) {
+          dyn_cast<llvm::ConstantDataSequential>(Init)) {
     for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
       llvm::Constant *Elt = CDS->getElementAsConstant(i);
       if (!canEmitInitWithFewStoresAfterBZero(Elt, NumStores))
@@ -995,7 +993,8 @@ static void emitStoresForInitAfterBZero(CodeGenModule &CGM,
 static bool shouldUseBZeroPlusStoresToInitialize(llvm::Constant *Init,
                                                  uint64_t GlobalSize) {
   // If a global is all zeros, always use a bzero.
-  if (isa<llvm::ConstantAggregateZero>(Init)) return true;
+  if (isa<llvm::ConstantAggregateZero>(Init))
+    return true;
 
   // If a non-zero global is <= 32 bytes, always use a memcpy.  If it is large,
   // do it if it will require 6 or fewer scalar stores.
@@ -1714,20 +1713,19 @@ static bool isCapturedBy(const VarDecl &Var, const Expr *E) {
       if (const auto *BIE = dyn_cast<Expr>(BI)) {
         if (isCapturedBy(Var, BIE))
           return true;
-      }
-      else if (const auto *DS = dyn_cast<DeclStmt>(BI)) {
-          // special case declarations
-          for (const auto *I : DS->decls()) {
-              if (const auto *VD = dyn_cast<VarDecl>((I))) {
-                const Expr *Init = VD->getInit();
-                if (Init && isCapturedBy(Var, Init))
-                  return true;
-              }
+      } else if (const auto *DS = dyn_cast<DeclStmt>(BI)) {
+        // special case declarations
+        for (const auto *I : DS->decls()) {
+          if (const auto *VD = dyn_cast<VarDecl>((I))) {
+            const Expr *Init = VD->getInit();
+            if (Init && isCapturedBy(Var, Init))
+              return true;
           }
-      }
-      else
-        // FIXME. Make safe assumption assuming arbitrary statements cause capturing.
-        // Later, provide code to poke into statements for capture analysis.
+        }
+      } else
+        // FIXME. Make safe assumption assuming arbitrary statements cause
+        // capturing. Later, provide code to poke into statements for capture
+        // analysis.
         return true;
     return false;
   }
@@ -1747,8 +1745,7 @@ bool CodeGenFunction::isTrivialInitializer(const Expr *Init) {
 
   if (const CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init))
     if (CXXConstructorDecl *Constructor = Construct->getConstructor())
-      if (Constructor->isTrivial() &&
-          Constructor->isDefaultConstructor() &&
+      if (Constructor->isTrivial() && Constructor->isDefaultConstructor() &&
           !Construct->requiresZeroInitialization())
         return true;
 
@@ -1759,7 +1756,7 @@ void CodeGenFunction::emitZeroOrPatternForAutoVarInit(QualType type,
                                                       const VarDecl &D,
                                                       Address Loc) {
   auto trivialAutoVarInit = getContext().getLangOpts().getTrivialAutoVarInit();
-  auto trivialAutoVarInitSizeBound = 
+  auto trivialAutoVarInitSizeBound =
       getContext().getLangOpts().TrivialAutoVarInitSizeBound;
   CharUnits Size = getContext().getTypeSizeInChars(type);
   bool isVolatile = type.isVolatileQualified();
@@ -1861,7 +1858,8 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
   assert(emission.Variable && "emission was not valid!");
 
   // If this was emitted as a global constant, we're done.
-  if (emission.wasEmittedAsGlobal()) return;
+  if (emission.wasEmittedAsGlobal())
+    return;
 
   const VarDecl &D = *emission.Variable;
   auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, D.getLocation());
@@ -1873,7 +1871,8 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
   // If we are at an unreachable point, we don't need to emit the initializer
   // unless it contains a label.
   if (!HaveInsertPoint()) {
-    if (!Init || !ContainsLabel(Init)) return;
+    if (!Init || !ContainsLabel(Init))
+      return;
     EnsureInsertPoint();
   }
 
@@ -1884,9 +1883,8 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
   // Initialize the variable here if it doesn't have a initializer and it is a
   // C struct that is non-trivial to initialize or an array containing such a
   // struct.
-  if (!Init &&
-      type.isNonTrivialToPrimitiveDefaultInitialize() ==
-          QualType::PDIK_Struct) {
+  if (!Init && type.isNonTrivialToPrimitiveDefaultInitialize() ==
+                   QualType::PDIK_Struct) {
     LValue Dst = MakeAddrLValue(emission.getAllocatedAddress(), type);
     if (emission.IsEscapingByRef)
       drillIntoBlockVariable(*this, Dst, &D);
@@ -2003,7 +2001,7 @@ void CodeGenFunction::EmitExprAsInit(const Expr *init, const ValueDecl *D,
   }
   case TEK_Aggregate:
     if (type->isAtomicType()) {
-      EmitAtomicInit(const_cast<Expr*>(init), lvalue);
+      EmitAtomicInit(const_cast<Expr *>(init), lvalue);
     } else {
       AggValueSlot::Overlap_t Overlap = AggValueSlot::MayOverlap;
       if (isa<VarDecl>(D))
@@ -2023,8 +2021,8 @@ void CodeGenFunction::EmitExprAsInit(const Expr *init, const ValueDecl *D,
 
 /// Enter a destroy cleanup for the given local variable.
 void CodeGenFunction::emitAutoVarTypeCleanup(
-                            const CodeGenFunction::AutoVarEmission &emission,
-                            QualType::DestructionKind dtorKind) {
+    const CodeGenFunction::AutoVarEmission &emission,
+    QualType::DestructionKind dtorKind) {
   assert(dtorKind != QualType::DK_none);
 
   // Note that for __block variables, we want to destroy the
@@ -2055,7 +2053,8 @@ void CodeGenFunction::emitAutoVarTypeCleanup(
 
   case QualType::DK_objc_strong_lifetime:
     // Suppress cleanups for pseudo-strong variables.
-    if (var->isARCPseudoStrong()) return;
+    if (var->isARCPseudoStrong())
+      return;
 
     // Otherwise, consider whether to use an EH cleanup or not.
     cleanupKind = getARCCleanupKind();
@@ -2080,7 +2079,8 @@ void CodeGenFunction::emitAutoVarTypeCleanup(
   }
 
   // If we haven't chosen a more specific destroyer, use the default.
-  if (!destroyer) destroyer = getDestroyer(dtorKind);
+  if (!destroyer)
+    destroyer = getDestroyer(dtorKind);
 
   // Use an EH cleanup in array destructors iff the destructor itself
   // is being pushed as an EH cleanup.
@@ -2093,11 +2093,13 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) {
   assert(emission.Variable && "emission was not valid!");
 
   // If this was emitted as a global constant, we're done.
-  if (emission.wasEmittedAsGlobal()) return;
+  if (emission.wasEmittedAsGlobal())
+    return;
 
   // If we don't have an insertion point, we're done.  Sema prevents
   // us from jumping into any of these scopes anyway.
-  if (!HaveInsertPoint()) return;
+  if (!HaveInsertPoint())
+    return;
 
   const VarDecl &D = *emission.Variable;
 
@@ -2139,7 +2141,8 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) {
 CodeGenFunction::Destroyer *
 CodeGenFunction::getDestroyer(QualType::DestructionKind kind) {
   switch (kind) {
-  case QualType::DK_none: llvm_unreachable("no destroyer for trivial dtor");
+  case QualType::DK_none:
+    llvm_unreachable("no destroyer for trivial dtor");
   case QualType::DK_cxx_destructor:
     return destroyCXXObject;
   case QualType::DK_objc_strong_lifetime:
@@ -2176,8 +2179,8 @@ void CodeGenFunction::pushDestroy(QualType::DestructionKind dtorKind,
 void CodeGenFunction::pushDestroy(CleanupKind cleanupKind, Address addr,
                                   QualType type, Destroyer *destroyer,
                                   bool useEHCleanupForArray) {
-  pushFullExprCleanup<DestroyObject>(cleanupKind, addr, type,
-                                     destroyer, useEHCleanupForArray);
+  pushFullExprCleanup<DestroyObject>(cleanupKind, addr, type, destroyer,
+                                     useEHCleanupForArray);
 }
 
 void CodeGenFunction::pushStackRestore(CleanupKind Kind, Address SPMem) {
@@ -2205,7 +2208,8 @@ void CodeGenFunction::pushLifetimeExtendedDestroy(CleanupKind cleanupKind,
           destroyer, useEHCleanupForArray);
 
     return pushCleanupAfterFullExprWithActiveFlag<DestroyObject>(
-        cleanupKind, Address::invalid(), addr, type, destroyer, useEHCleanupForArray);
+        cleanupKind, Address::invalid(), addr, type, destroyer,
+        useEHCleanupForArray);
   }
 
   // Otherwise, we should only destroy the object if it's been initialized.
@@ -2252,9 +2256,8 @@ void CodeGenFunction::emitDestroy(Address addr, QualType type,
 
   llvm::Value *length = emitArrayLength(arrayType, type, addr);
 
-  CharUnits elementAlign =
-    addr.getAlignment()
-        .alignmentOfArrayElement(getContext().getTypeSizeInChars(type));
+  CharUnits elementAlign = addr.getAlignment().alignmentOfArrayElement(
+      getContext().getTypeSizeInChars(type));
 
   // Normally we have to check whether the array is zero-length.
   bool checkZeroLength = true;
@@ -2262,15 +2265,16 @@ void CodeGenFunction::emitDestroy(Address addr, QualType type,
   // But if the array length is constant, we can suppress that.
   if (llvm::ConstantInt *constLength = dyn_cast<llvm::ConstantInt>(length)) {
     // ...and if it's constant zero, we can just skip the entire thing.
-    if (constLength->isZero()) return;
+    if (constLength->isZero())
+      return;
     checkZeroLength = false;
   }
 
   llvm::Value *begin = addr.getPointer();
   llvm::Value *end =
       Builder.CreateInBoundsGEP(addr.getElementType(), begin, length);
-  emitArrayDestroy(begin, end, type, elementAlign, destroyer,
-                   checkZeroLength, useEHCleanupForArray);
+  emitArrayDestroy(begin, end, type, elementAlign, destroyer, checkZeroLength,
+                   useEHCleanupForArray);
 }
 
 /// emitArrayDestroy - Destroys all the elements of the given array,
@@ -2283,8 +2287,7 @@ void CodeGenFunction::emitDestroy(Address addr, QualType type,
 /// \param useEHCleanup - whether to push an EH cleanup to destroy
 ///   the remaining elements in case the destruction of a single
 ///   element throws
-void CodeGenFunction::emitArrayDestroy(llvm::Value *begin,
-                                       llvm::Value *end,
+void CodeGenFunction::emitArrayDestroy(llvm::Value *begin, llvm::Value *end,
                                        QualType elementType,
                                        CharUnits elementAlign,
                                        Destroyer *destroyer,
@@ -2298,8 +2301,8 @@ void CodeGenFunction::emitArrayDestroy(llvm::Value *begin,
   llvm::BasicBlock *doneBB = createBasicBlock("arraydestroy.done");
 
   if (checkZeroLength) {
-    llvm::Value *isEmpty = Builder.CreateICmpEQ(begin, end,
-                                                "arraydestroy.isempty");
+    llvm::Value *isEmpty =
+        Builder.CreateICmpEQ(begin, end, "arraydestroy.isempty");
     Builder.CreateCondBr(isEmpty, doneBB, bodyBB);
   }
 
@@ -2307,7 +2310,7 @@ void CodeGenFunction::emitArrayDestroy(llvm::Value *begin,
   llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
   EmitBlock(bodyBB);
   llvm::PHINode *elementPast =
-    Builder.CreatePHI(begin->getType(), 2, "arraydestroy.elementPast");
+      Builder.CreatePHI(begin->getType(), 2, "arraydestroy.elementPast");
   elementPast->addIncoming(end, entryBB);
 
   // Shift the address back by one element.
@@ -2338,9 +2341,9 @@ void CodeGenFunction::emitArrayDestroy(llvm::Value *begin,
 
 /// Perform partial array destruction as if in an EH cleanup.  Unlike
 /// emitArrayDestroy, the element type here may still be an array type.
-static void emitPartialArrayDestroy(CodeGenFunction &CGF,
-                                    llvm::Value *begin, llvm::Value *end,
-                                    QualType type, CharUnits elementAlign,
+static void emitPartialArrayDestroy(CodeGenFunction &CGF, llvm::Value *begin,
+                                    llvm::Value *end, QualType type,
+                                    CharUnits elementAlign,
                                     CodeGenFunction::Destroyer *destroyer) {
   llvm::Type *elemTy = CGF.ConvertTypeForMem(type);
 
@@ -2356,11 +2359,11 @@ static void emitPartialArrayDestroy(CodeGenFunction &CGF,
   if (arrayDepth) {
     llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
 
-    SmallVector<llvm::Value*,4> gepIndices(arrayDepth+1, zero);
-    begin = CGF.Builder.CreateInBoundsGEP(
-        elemTy, begin, gepIndices, "pad.arraybegin");
-    end = CGF.Builder.CreateInBoundsGEP(
-        elemTy, end, gepIndices, "pad.arrayend");
+    SmallVector<llvm::Value *, 4> gepIndices(arrayDepth + 1, zero);
+    begin = CGF.Builder.CreateInBoundsGEP(elemTy, begin, gepIndices,
+                                          "pad.arraybegin");
+    end =
+        CGF.Builder.CreateInBoundsGEP(elemTy, end, gepIndices, "pad.arrayend");
   }
 
   // Destroy the array.  We don't ever need an EH cleanup because we
@@ -2371,54 +2374,53 @@ static void emitPartialArrayDestroy(CodeGenFunction &CGF,
 }
 
 namespace {
-  /// RegularPartialArrayDestroy - a cleanup which performs a partial
-  /// array destroy where the end pointer is regularly determined and
-  /// does not need to be loaded from a local.
-  class RegularPartialArrayDestroy final : public EHScopeStack::Cleanup {
-    llvm::Value *ArrayBegin;
-    llvm::Value *ArrayEnd;
-    QualType ElementType;
-    CodeGenFunction::Destroyer *Destroyer;
-    CharUnits ElementAlign;
-  public:
-    RegularPartialArrayDestroy(llvm::Value *arrayBegin, llvm::Value *arrayEnd,
+/// RegularPartialArrayDestroy - a cleanup which performs a partial
+/// array destroy where the end pointer is regularly determined and
+/// does not need to be loaded from a local.
+class RegularPartialArrayDestroy final : public EHScopeStack::Cleanup {
+  llvm::Value *ArrayBegin;
+  llvm::Value *ArrayEnd;
+  QualType ElementType;
+  CodeGenFunction::Destroyer *Destroyer;
+  CharUnits ElementAlign;
+
+public:
+  RegularPartialArrayDestroy(llvm::Value *arrayBegin, llvm::Value *arrayEnd,
+                             QualType elementType, CharUnits elementAlign,
+                             CodeGenFunction::Destroyer *destroyer)
+      : ArrayBegin(arrayBegin), ArrayEnd(arrayEnd), ElementType(elementType),
+        Destroyer(destroyer), ElementAlign(elementAlign) {}
+
+  void Emit(CodeGenFunction &CGF, Flags flags) override {
+    emitPartialArrayDestroy(CGF, ArrayBegin, ArrayEnd, ElementType,
+                            ElementAlign, Destroyer);
+  }
+};
+
+/// IrregularPartialArrayDestroy - a cleanup which performs a
+/// partial array destroy where the end pointer is irregularly
+/// determined and must be loaded from a local.
+class IrregularPartialArrayDestroy final : public EHScopeStack::Cleanup {
+  llvm::Value *ArrayBegin;
+  Address ArrayEndPointer;
+  QualType ElementType;
+  CodeGenFunction::Destroyer *Destroyer;
+  CharUnits ElementAlign;
+
+public:
+  IrregularPartialArrayDestroy(llvm::Value *arrayBegin, Address arrayEndPointer,
                                QualType elementType, CharUnits elementAlign,
                                CodeGenFunction::Destroyer *destroyer)
-      : ArrayBegin(arrayBegin), ArrayEnd(arrayEnd),
-        ElementType(elementType), Destroyer(destroyer),
-        ElementAlign(elementAlign) {}
-
-    void Emit(CodeGenFunction &CGF, Flags flags) override {
-      emitPartialArrayDestroy(CGF, ArrayBegin, ArrayEnd,
-                              ElementType, ElementAlign, Destroyer);
-    }
-  };
-
-  /// IrregularPartialArrayDestroy - a cleanup which performs a
-  /// partial array destroy where the end pointer is irregularly
-  /// determined and must be loaded from a local.
-  class IrregularPartialArrayDestroy final : public EHScopeStack::Cleanup {
-    llvm::Value *ArrayBegin;
-    Address ArrayEndPointer;
-    QualType ElementType;
-    CodeGenFunction::Destroyer *Destroyer;
-    CharUnits ElementAlign;
-  public:
-    IrregularPartialArrayDestroy(llvm::Value *arrayBegin,
-                                 Address arrayEndPointer,
-                                 QualType elementType,
-                                 CharUnits elementAlign,
-                                 CodeGenFunction::Destroyer *destroyer)
       : ArrayBegin(arrayBegin), ArrayEndPointer(arrayEndPointer),
         ElementType(elementType), Destroyer(destroyer),
         ElementAlign(elementAlign) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) override {
-      llvm::Value *arrayEnd = CGF.Builder.CreateLoad(ArrayEndPointer);
-      emitPartialArrayDestroy(CGF, ArrayBegin, arrayEnd,
-                              ElementType, ElementAlign, Destroyer);
-    }
-  };
+  void Emit(CodeGenFunction &CGF, Flags flags) override {
+    llvm::Value *arrayEnd = CGF.Builder.CreateLoad(ArrayEndPointer);
+    emitPartialArrayDestroy(CGF, ArrayBegin, arrayEnd, ElementType,
+                            ElementAlign, Destroyer);
+  }
+};
 } // end anonymous namespace
 
 /// pushIrregularPartialArrayCleanup - Push an EH cleanup to destroy
@@ -2432,10 +2434,9 @@ void CodeGenFunction::pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin,
                                                        QualType elementType,
                                                        CharUnits elementAlign,
                                                        Destroyer *destroyer) {
-  pushFullExprCleanup<IrregularPartialArrayDestroy>(EHCleanup,
-                                                    arrayBegin, arrayEndPointer,
-                                                    elementType, elementAlign,
-                                                    destroyer);
+  pushFullExprCleanup<IrregularPartialArrayDestroy>(
+      EHCleanup, arrayBegin, arrayEndPointer, elementType, elementAlign,
+      destroyer);
 }
 
 /// pushRegularPartialArrayCleanup - Push an EH cleanup to destroy
@@ -2449,18 +2450,16 @@ void CodeGenFunction::pushRegularPartialArrayCleanup(llvm::Value *arrayBegin,
                                                      QualType elementType,
                                                      CharUnits elementAlign,
                                                      Destroyer *destroyer) {
-  pushFullExprCleanup<RegularPartialArrayDestroy>(EHCleanup,
-                                                  arrayBegin, arrayEnd,
-                                                  elementType, elementAlign,
-                                                  destroyer);
+  pushFullExprCleanup<RegularPartialArrayDestroy>(
+      EHCleanup, arrayBegin, arrayEnd, elementType, elementAlign, destroyer);
 }
 
 /// Lazily declare the @llvm.lifetime.start intrinsic.
 llvm::Function *CodeGenModule::getLLVMLifetimeStartFn() {
   if (LifetimeStartFn)
     return LifetimeStartFn;
-  LifetimeStartFn = llvm::Intrinsic::getDeclaration(&getModule(),
-    llvm::Intrinsic::lifetime_start, AllocaInt8PtrTy);
+  LifetimeStartFn = llvm::Intrinsic::getDeclaration(
+      &getModule(), llvm::Intrinsic::lifetime_start, AllocaInt8PtrTy);
   return LifetimeStartFn;
 }
 
@@ -2468,28 +2467,27 @@ llvm::Function *CodeGenModule::getLLVMLifetimeStartFn() {
 llvm::Function *CodeGenModule::getLLVMLifetimeEndFn() {
   if (LifetimeEndFn)
     return LifetimeEndFn;
-  LifetimeEndFn = llvm::Intrinsic::getDeclaration(&getModule(),
-    llvm::Intrinsic::lifetime_end, AllocaInt8PtrTy);
+  LifetimeEndFn = llvm::Intrinsic::getDeclaration(
+      &getModule(), llvm::Intrinsic::lifetime_end, AllocaInt8PtrTy);
   return LifetimeEndFn;
 }
 
 namespace {
-  /// A cleanup to perform a release of an object at the end of a
-  /// function.  This is used to balance out the incoming +1 of a
-  /// ns_consumed argument when we can't reasonably do that just by
-  /// not doing the initial retain for a __block argument.
-  struct ConsumeARCParameter final : EHScopeStack::Cleanup {
-    ConsumeARCParameter(llvm::Value *param,
-                        ARCPreciseLifetime_t precise)
+/// A cleanup to perform a release of an object at the end of a
+/// function.  This is used to balance out the incoming +1 of a
+/// ns_consumed argument when we can't reasonably do that just by
+/// not doing the initial retain for a __block argument.
+struct ConsumeARCParameter final : EHScopeStack::Cleanup {
+  ConsumeARCParameter(llvm::Value *param, ARCPreciseLifetime_t precise)
       : Param(param), Precise(precise) {}
 
-    llvm::Value *Param;
-    ARCPreciseLifetime_t Precise;
+  llvm::Value *Param;
+  ARCPreciseLifetime_t Precise;
 
-    void Emit(CodeGenFunction &CGF, Flags flags) override {
-      CGF.EmitARCRelease(Param, Precise);
-    }
-  };
+  void Emit(CodeGenFunction &CGF, Flags flags) override {
+    CGF.EmitARCRelease(Param, Precise);
+  }
+};
 } // end anonymous namespace
 
 /// Emit an alloca (or GlobalValue depending on target)
@@ -2633,18 +2631,18 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
             EmitStoreOfScalar(Null, lv, /* isInitialization */ true);
             EmitARCStoreStrongCall(lv.getAddress(*this), ArgVal, true);
             DoStore = false;
-          }
-          else
-          // Don't use objc_retainBlock for block pointers, because we
-          // don't want to Block_copy something just because we got it
-          // as a parameter.
+          } else
+            // Don't use objc_retainBlock for block pointers, because we
+            // don't want to Block_copy something just because we got it
+            // as a parameter.
             ArgVal = EmitARCRetainNonBlock(ArgVal);
         }
       } else {
         // Push the cleanup for a consumed parameter.
         if (isConsumed) {
-          ARCPreciseLifetime_t precise = (D.hasAttr<ObjCPreciseLifetimeAttr>()
-                                ? ARCPreciseLifetime : ARCImpreciseLifetime);
+          ARCPreciseLifetime_t precise =
+              (D.hasAttr<ObjCPreciseLifetimeAttr>() ? ARCPreciseLifetime
+                                                    : ARCImpreciseLifetime);
           EHStack.pushCleanup<ConsumeARCParameter>(getARCCleanupKind(), ArgVal,
                                                    precise);
         }



More information about the cfe-commits mailing list