[llvm-branch-commits] [clang] [docs] Finish MyST migration for selected Clang docs (PR #214617)

Reid Kleckner via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Aug 12 14:03:15 PDT 2026


https://github.com/rnk updated https://github.com/llvm/llvm-project/pull/214617

>From 13fbbe338fc20332921de6016f3cb18d29d0cc4d Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rkleckner at nvidia.com>
Date: Fri, 7 Aug 2026 02:17:12 +0000
Subject: [PATCH 1/3] [docs] Convert selected rst docs with rst2myst

---
 clang/docs/AutomaticReferenceCounting.md      | 3199 ++++++++---------
 clang/docs/Block-ABI-Apple.md                 | 1403 ++++----
 clang/docs/BlockLanguageSpec.md               |  278 +-
 clang/docs/CIR/ABILowering.md                 |  736 ++--
 clang/docs/CIR/CleanupAndEHDesign.md          | 2233 ++++++------
 clang/docs/CIR/CodeDuplication.md             |   50 +-
 clang/docs/CommandGuide/clang.md              | 1486 ++++----
 clang/docs/CommandGuide/diagtool.md           |   55 +-
 clang/docs/ConstantInterpreter.md             |  308 +-
 clang/docs/ControlFlowIntegrityDesign.md      |  696 ++--
 clang/docs/DataFlowSanitizerDesign.md         |  335 +-
 clang/docs/HLSL/AvailabilityDiagnostics.md    |  156 +-
 clang/docs/HLSL/EntryFunctions.md             |   65 +-
 clang/docs/HLSL/ExpectedDifferences.md        |  275 +-
 clang/docs/HLSL/FunctionCalls.md              |  416 ++-
 clang/docs/HLSL/HLSLIRReference.md            |   23 +-
 clang/docs/HLSL/HLSLSupport.md                |  177 +-
 clang/docs/HLSL/ResourceTypes.md              |   56 +-
 .../HardwareAssistedAddressSanitizerDesign.md |  334 +-
 clang/docs/ItaniumMangleAbiTags.md            |   86 +-
 20 files changed, 6028 insertions(+), 6339 deletions(-)

diff --git a/clang/docs/AutomaticReferenceCounting.md b/clang/docs/AutomaticReferenceCounting.md
index 4a97cac7b2615..1f8dd7f15cb02 100644
--- a/clang/docs/AutomaticReferenceCounting.md
+++ b/clang/docs/AutomaticReferenceCounting.md
@@ -1,185 +1,188 @@
-.. FIXME: move to the stylesheet or Sphinx plugin
-
-.. raw:: html
-
-  <style>
-    .arc-term { font-style: italic; font-weight: bold; }
-    .revision { font-style: italic; }
-    .when-revised { font-weight: bold; font-style: normal; }
-
-    /*
-     * Automatic numbering is described in this article:
-     * https://dev.opera.com/articles/view/automatic-numbering-with-css-counters/
-     */
-    /*
-     * Automatic numbering for the TOC.
-     * This is wrong from the semantics point of view, since it is an ordered
-     * list, but uses "ul" tag.
-     */
-    div#contents.contents.local ul {
-      counter-reset: toc-section;
-      list-style-type: none;
-    }
-    div#contents.contents.local ul li {
-      counter-increment: toc-section;
-      background: none; // Remove bullets
-    }
-    div#contents.contents.local ul li a.reference:before {
-      content: counters(toc-section, ".") " ";
-    }
-
-    /* Automatic numbering for the body. */
-    body {
-      counter-reset: section subsection subsubsection;
-    }
-    .section h2 {
-      counter-reset: subsection subsubsection;
-      counter-increment: section;
-    }
-    .section h2 a.toc-backref:before {
-      content: counter(section) " ";
-    }
-    .section h3 {
-      counter-reset: subsubsection;
-      counter-increment: subsection;
-    }
-    .section h3 a.toc-backref:before {
-      content: counter(section) "." counter(subsection) " ";
-    }
-    .section h4 {
-      counter-increment: subsubsection;
-    }
-    .section h4 a.toc-backref:before {
-      content: counter(section) "." counter(subsection) "." counter(subsubsection) " ";
-    }
-  </style>
+% FIXME: move to the stylesheet or Sphinx plugin
+
+```{raw} html
+<style>
+  .arc-term { font-style: italic; font-weight: bold; }
+  .revision { font-style: italic; }
+  .when-revised { font-weight: bold; font-style: normal; }
+
+  /*
+   * Automatic numbering is described in this article:
+   * https://dev.opera.com/articles/view/automatic-numbering-with-css-counters/
+   */
+  /*
+   * Automatic numbering for the TOC.
+   * This is wrong from the semantics point of view, since it is an ordered
+   * list, but uses "ul" tag.
+   */
+  div#contents.contents.local ul {
+    counter-reset: toc-section;
+    list-style-type: none;
+  }
+  div#contents.contents.local ul li {
+    counter-increment: toc-section;
+    background: none; // Remove bullets
+  }
+  div#contents.contents.local ul li a.reference:before {
+    content: counters(toc-section, ".") " ";
+  }
 
+  /* Automatic numbering for the body. */
+  body {
+    counter-reset: section subsection subsubsection;
+  }
+  .section h2 {
+    counter-reset: subsection subsubsection;
+    counter-increment: section;
+  }
+  .section h2 a.toc-backref:before {
+    content: counter(section) " ";
+  }
+  .section h3 {
+    counter-reset: subsubsection;
+    counter-increment: subsection;
+  }
+  .section h3 a.toc-backref:before {
+    content: counter(section) "." counter(subsection) " ";
+  }
+  .section h4 {
+    counter-increment: subsubsection;
+  }
+  .section h4 a.toc-backref:before {
+    content: counter(section) "." counter(subsection) "." counter(subsubsection) " ";
+  }
+</style>
+```
+
+```{eval-rst}
 .. role:: arc-term
+```
+
+```{eval-rst}
 .. role:: revision
+```
+
+```{eval-rst}
 .. role:: when-revised
+```
 
-==============================================
-Objective-C Automatic Reference Counting (ARC)
-==============================================
+# Objective-C Automatic Reference Counting (ARC)
 
-.. contents::
-   :local:
+```{contents}
+:local: true
+```
 
-.. _arc.meta:
+(arc-meta)=
 
-About this document
-===================
+## About this document
 
-.. _arc.meta.purpose:
+(arc-meta-purpose)=
 
-Purpose
--------
+### Purpose
 
 The first and primary purpose of this document is to serve as a complete
-technical specification of Automatic Reference Counting.  Given a core
+technical specification of Automatic Reference Counting. Given a core
 Objective-C compiler and runtime, it should be possible to write a compiler and
 runtime which implements these new semantics.
 
 The secondary purpose is to act as a rationale for why ARC was designed in this
-way.  This should remain tightly focused on the technical design and should not
+way. This should remain tightly focused on the technical design and should not
 stray into marketing speculation.
 
-.. _arc.meta.background:
+(arc-meta-background)=
 
-Background
-----------
+### Background
 
 This document assumes a basic familiarity with C.
 
-:arc-term:`Blocks` are a C language extension for creating anonymous functions.
-Users interact with and transfer block objects using :arc-term:`block
-pointers`, which are represented like a normal pointer.  A block may capture
+{arc-term}`Blocks` are a C language extension for creating anonymous functions.
+Users interact with and transfer block objects using {arc-term}`block
+pointers`, which are represented like a normal pointer. A block may capture
 values from local variables; when this occurs, memory must be dynamically
-allocated.  The initial allocation is done on the stack, but the runtime
-provides a ``Block_copy`` function which, given a block pointer, either copies
+allocated. The initial allocation is done on the stack, but the runtime
+provides a `Block_copy` function which, given a block pointer, either copies
 the underlying block object to the heap, setting its reference count to 1 and
 returning the new block pointer, or (if the block object is already on the
-heap) increases its reference count by 1.  The paired function is
-``Block_release``, which decreases the reference count by 1 and destroys the
+heap) increases its reference count by 1. The paired function is
+`Block_release`, which decreases the reference count by 1 and destroys the
 object if the count reaches zero and is on the heap.
 
 Objective-C is a set of language extensions, significant enough to be
-considered a different language.  It is a strict superset of C.  The extensions
-can also be imposed on C++, producing a language called Objective-C++.  The
+considered a different language. It is a strict superset of C. The extensions
+can also be imposed on C++, producing a language called Objective-C++. The
 primary feature is a single-inheritance object system; we briefly describe the
 modern dialect.
 
-Objective-C defines a new type kind, collectively called the :arc-term:`object
-pointer types`.  This kind has two notable builtin members, ``id`` and
-``Class``; ``id`` is the final supertype of all object pointers.  The validity
-of conversions between object pointer types is not checked at runtime.  Users
-may define :arc-term:`classes`; each class is a type, and the pointer to that
-type is an object pointer type.  A class may have a superclass; its pointer
-type is a subtype of its superclass's pointer type.  A class has a set of
-:arc-term:`ivars`, fields which appear on all instances of that class.  For
+Objective-C defines a new type kind, collectively called the {arc-term}`object
+pointer types`. This kind has two notable builtin members, `id` and
+`Class`; `id` is the final supertype of all object pointers. The validity
+of conversions between object pointer types is not checked at runtime. Users
+may define {arc-term}`classes`; each class is a type, and the pointer to that
+type is an object pointer type. A class may have a superclass; its pointer
+type is a subtype of its superclass's pointer type. A class has a set of
+{arc-term}`ivars`, fields which appear on all instances of that class. For
 every class *T* there's an associated metaclass; it has no fields, its
 superclass is the metaclass of *T*'s superclass, and its metaclass is a global
-class.  Every class has a global object whose class is the class's metaclass;
+class. Every class has a global object whose class is the class's metaclass;
 metaclasses have no associated type, so pointers to this object have type
-``Class``.
+`Class`.
 
-A class declaration (``@interface``) declares a set of :arc-term:`methods`.  A
-method has a return type, a list of argument types, and a :arc-term:`selector`:
-a name like ``foo:bar:baz:``, where the number of colons corresponds to the
-number of formal arguments.  A method may be an instance method, in which case
+A class declaration (`@interface`) declares a set of {arc-term}`methods`. A
+method has a return type, a list of argument types, and a {arc-term}`selector`:
+a name like `foo:bar:baz:`, where the number of colons corresponds to the
+number of formal arguments. A method may be an instance method, in which case
 it can be invoked on objects of the class, or a class method, in which case it
-can be invoked on objects of the metaclass.  A method may be invoked by
-providing an object (called the :arc-term:`receiver`) and a list of formal
+can be invoked on objects of the metaclass. A method may be invoked by
+providing an object (called the {arc-term}`receiver`) and a list of formal
 arguments interspersed with the selector, like so:
 
-.. code-block:: objc
-
-  [receiver foo: fooArg bar: barArg baz: bazArg]
+```objc
+[receiver foo: fooArg bar: barArg baz: bazArg]
+```
 
 This looks in the dynamic class of the receiver for a method with this name,
 then in that class's superclass, etc., until it finds something it can execute.
 The receiver "expression" may also be the name of a class, in which case the
 actual receiver is the class object for that class, or (within method
-definitions) it may be ``super``, in which case the lookup algorithm starts
-with the static superclass instead of the dynamic class.  The actual methods
-dynamically found in a class are not those declared in the ``@interface``, but
-those defined in a separate ``@implementation`` declaration; however, when
+definitions) it may be `super`, in which case the lookup algorithm starts
+with the static superclass instead of the dynamic class. The actual methods
+dynamically found in a class are not those declared in the `@interface`, but
+those defined in a separate `@implementation` declaration; however, when
 compiling a call, typechecking is done based on the methods declared in the
-``@interface``.
+`@interface`.
 
-Method declarations may also be grouped into :arc-term:`protocols`, which are not
+Method declarations may also be grouped into {arc-term}`protocols`, which are not
 inherently associated with any class, but which classes may claim to follow.
 Object pointer types may be qualified with additional protocols that the object
 is known to support.
 
-:arc-term:`Class extensions` are collections of ivars and methods, designed to
-allow a class's ``@interface`` to be split across multiple files; however,
+{arc-term}`Class extensions` are collections of ivars and methods, designed to
+allow a class's `@interface` to be split across multiple files; however,
 there is still a primary implementation file which must see the
-``@interface``\ s of all class extensions.  :arc-term:`Categories` allow
+`@interface`s of all class extensions. {arc-term}`Categories` allow
 methods (but not ivars) to be declared *post hoc* on an arbitrary class; the
-methods in the category's ``@implementation`` will be dynamically added to that
+methods in the category's `@implementation` will be dynamically added to that
 class's method tables which the category is loaded at runtime, replacing those
 methods in case of a collision.
 
 In the standard environment, objects are allocated on the heap, and their
-lifetime is manually managed using a reference count.  This is done using two
-instance methods which all classes are expected to implement: ``retain``
-increases the object's reference count by 1, whereas ``release`` decreases it
-by 1 and calls the instance method ``dealloc`` if the count reaches 0.  To
-simplify certain operations, there is also an :arc-term:`autorelease pool`, a
-thread-local list of objects to call ``release`` on later; an object can be
-added to this pool by calling ``autorelease`` on it.
-
-Block pointers may be converted to type ``id``; block objects are laid out in a
-way that makes them compatible with Objective-C objects.  There is a builtin
+lifetime is manually managed using a reference count. This is done using two
+instance methods which all classes are expected to implement: `retain`
+increases the object's reference count by 1, whereas `release` decreases it
+by 1 and calls the instance method `dealloc` if the count reaches 0. To
+simplify certain operations, there is also an {arc-term}`autorelease pool`, a
+thread-local list of objects to call `release` on later; an object can be
+added to this pool by calling `autorelease` on it.
+
+Block pointers may be converted to type `id`; block objects are laid out in a
+way that makes them compatible with Objective-C objects. There is a builtin
 class that all block objects are considered to be objects of; this class
-implements ``retain`` by adjusting the reference count, not by calling
-``Block_copy``.
+implements `retain` by adjusting the reference count, not by calling
+`Block_copy`.
 
-.. _arc.meta.evolution:
+(arc-meta-evolution)=
 
-Evolution
----------
+### Evolution
 
 ARC is under continual evolution, and this document must be updated as the
 language progresses.
@@ -188,199 +191,192 @@ If a change increases the expressiveness of the language, for example by
 lifting a restriction or by adding new syntax, the change will be annotated
 with a revision marker, like so:
 
-  ARC applies to Objective-C pointer types, block pointer types, and
-  :when-revised:`[beginning Apple 8.0, LLVM 3.8]` :revision:`BPTRs declared
-  within` ``extern "BCPL"`` blocks.
+> ARC applies to Objective-C pointer types, block pointer types, and
+> {when-revised}`[beginning Apple 8.0, LLVM 3.8]` {revision}`BPTRs declared
+> within` `extern "BCPL"` blocks.
 
 For now, it is sensible to version this document by the releases of its sole
-implementation (and its host project), clang.  "LLVM X.Y" refers to an
-open-source release of clang from the LLVM project.  "Apple X.Y" refers to an
-Apple-provided release of the Apple LLVM Compiler.  Other organizations that
+implementation (and its host project), clang. "LLVM X.Y" refers to an
+open-source release of clang from the LLVM project. "Apple X.Y" refers to an
+Apple-provided release of the Apple LLVM Compiler. Other organizations that
 prepare their own, separately-versioned clang releases and wish to maintain
 similar information in this document should send requests to cfe-dev.
 
 If a change decreases the expressiveness of the language, for example by
 imposing a new restriction, this should be taken as an oversight in the
-original specification and something to be avoided in all versions.  Such
+original specification and something to be avoided in all versions. Such
 changes are generally to be avoided.
 
-.. _arc.general:
+(arc-general)=
 
-General
-=======
+## General
 
 Automatic Reference Counting implements automatic memory management for
 Objective-C objects and blocks, freeing the programmer from the need to
-explicitly insert retains and releases.  It does not provide a cycle collector;
+explicitly insert retains and releases. It does not provide a cycle collector;
 users must explicitly manage the lifetime of their objects, breaking cycles
 manually or with weak or unsafe references.
 
-ARC may be explicitly enabled with the compiler flag ``-fobjc-arc``.  It may
-also be explicitly disabled with the compiler flag ``-fno-objc-arc``.  The last
+ARC may be explicitly enabled with the compiler flag `-fobjc-arc`. It may
+also be explicitly disabled with the compiler flag `-fno-objc-arc`. The last
 of these two flags appearing on the compile line "wins".
 
-If ARC is enabled, ``__has_feature(objc_arc)`` will expand to 1 in the
-preprocessor.  For more information about ``__has_feature``, see the
-:ref:`language extensions <langext-__has_feature-__has_extension>` document.
+If ARC is enabled, `__has_feature(objc_arc)` will expand to 1 in the
+preprocessor. For more information about `__has_feature`, see the
+{ref}`language extensions <langext-__has_feature-__has_extension>` document.
 
-.. _arc.objects:
+(arc-objects)=
 
-Retainable object pointers
-==========================
+## Retainable object pointers
 
 This section describes retainable object pointers, their basic operations, and
-the restrictions imposed on their use under ARC.  Note in particular that it
+the restrictions imposed on their use under ARC. Note in particular that it
 covers the rules for pointer *values* (patterns of bits indicating the location
 of a pointed-to object), not pointer *objects* (locations in memory which store
-pointer values).  The rules for objects are covered in the next section.
+pointer values). The rules for objects are covered in the next section.
 
-A :arc-term:`retainable object pointer` (or "retainable pointer") is a value of
-a :arc-term:`retainable object pointer type` ("retainable type").  There are
+A {arc-term}`retainable object pointer` (or "retainable pointer") is a value of
+a {arc-term}`retainable object pointer type` ("retainable type"). There are
 three kinds of retainable object pointer types:
 
-* block pointers (formed by applying the caret (``^``) declarator sigil to a
+- block pointers (formed by applying the caret (`^`) declarator sigil to a
   function type)
-* Objective-C object pointers (``id``, ``Class``, ``NSFoo*``, etc.)
-* typedefs marked with ``__attribute__((NSObject))``
+- Objective-C object pointers (`id`, `Class`, `NSFoo*`, etc.)
+- typedefs marked with `__attribute__((NSObject))`
 
-Other pointer types, such as ``int*`` and ``CFStringRef``, are not subject to
+Other pointer types, such as `int*` and `CFStringRef`, are not subject to
 ARC's semantics and restrictions.
 
-.. admonition:: Rationale
-
-  We are not at liberty to require all code to be recompiled with ARC;
-  therefore, ARC must interoperate with Objective-C code which manages retains
-  and releases manually.  In general, there are three requirements in order for
-  a compiler-supported reference-count system to provide reliable
-  interoperation:
-
-  * The type system must reliably identify which objects are to be managed.  An
-    ``int*`` might be a pointer to a ``malloc``'ed array, or it might be an
-    interior pointer to such an array, or it might point to some field or local
-    variable.  In contrast, values of the retainable object pointer types are
-    never interior.
-
-  * The type system must reliably indicate how to manage objects of a type.
-    This usually means that the type must imply a procedure for incrementing
-    and decrementing retain counts.  Supporting single-ownership objects
-    requires a lot more explicit mediation in the language.
-
-  * There must be reliable conventions for whether and when "ownership" is
-    passed between caller and callee, for both arguments and return values.
-    Objective-C methods follow such a convention very reliably, at least for
-    system libraries on macOS, and functions always pass objects at +0.  The
-    C-based APIs for Core Foundation objects, on the other hand, have much more
-    varied transfer semantics.
-
-The use of ``__attribute__((NSObject))`` typedefs is not recommended.  If it's
+:::{admonition} Rationale
+We are not at liberty to require all code to be recompiled with ARC;
+therefore, ARC must interoperate with Objective-C code which manages retains
+and releases manually. In general, there are three requirements in order for
+a compiler-supported reference-count system to provide reliable
+interoperation:
+
+- The type system must reliably identify which objects are to be managed. An
+  `int*` might be a pointer to a `malloc`'ed array, or it might be an
+  interior pointer to such an array, or it might point to some field or local
+  variable. In contrast, values of the retainable object pointer types are
+  never interior.
+- The type system must reliably indicate how to manage objects of a type.
+  This usually means that the type must imply a procedure for incrementing
+  and decrementing retain counts. Supporting single-ownership objects
+  requires a lot more explicit mediation in the language.
+- There must be reliable conventions for whether and when "ownership" is
+  passed between caller and callee, for both arguments and return values.
+  Objective-C methods follow such a convention very reliably, at least for
+  system libraries on macOS, and functions always pass objects at +0. The
+  C-based APIs for Core Foundation objects, on the other hand, have much more
+  varied transfer semantics.
+:::
+
+The use of `__attribute__((NSObject))` typedefs is not recommended. If it's
 absolutely necessary to use this attribute, be very explicit about using the
 typedef, and do not assume that it will be preserved by language features like
-``__typeof`` and C++ template argument substitution.
-
-.. admonition:: Rationale
+`__typeof` and C++ template argument substitution.
 
-  Any compiler operation which incidentally strips type "sugar" from a type
-  will yield a type without the attribute, which may result in unexpected
-  behavior.
+:::{admonition} Rationale
+Any compiler operation which incidentally strips type "sugar" from a type
+will yield a type without the attribute, which may result in unexpected
+behavior.
+:::
 
-.. _arc.objects.retains:
+(arc-objects-retains)=
 
-Retain count semantics
-----------------------
+### Retain count semantics
 
-A retainable object pointer is either a :arc-term:`null pointer` or a pointer
-to a valid object.  Furthermore, if it has block pointer type and is not
-``null`` then it must actually be a pointer to a block object, and if it has
-``Class`` type (possibly protocol-qualified) then it must actually be a pointer
-to a class object.  Otherwise ARC does not enforce the Objective-C type system
+A retainable object pointer is either a {arc-term}`null pointer` or a pointer
+to a valid object. Furthermore, if it has block pointer type and is not
+`null` then it must actually be a pointer to a block object, and if it has
+`Class` type (possibly protocol-qualified) then it must actually be a pointer
+to a class object. Otherwise ARC does not enforce the Objective-C type system
 as long as the implementing methods follow the signature of the static type.
 It is undefined behavior if ARC is exposed to an invalid pointer.
 
 For ARC's purposes, a valid object is one with "well-behaved" retaining
-operations.  Specifically, the object must be laid out such that the
+operations. Specifically, the object must be laid out such that the
 Objective-C message send machinery can successfully send it the following
 messages:
 
-* ``retain``, taking no arguments and returning a pointer to the object.
-* ``release``, taking no arguments and returning ``void``.
-* ``autorelease``, taking no arguments and returning a pointer to the object.
+- `retain`, taking no arguments and returning a pointer to the object.
+- `release`, taking no arguments and returning `void`.
+- `autorelease`, taking no arguments and returning a pointer to the object.
 
-The behavior of these methods is constrained in the following ways.  The term
-:arc-term:`high-level semantics` is an intentionally vague term; the intent is
+The behavior of these methods is constrained in the following ways. The term
+{arc-term}`high-level semantics` is an intentionally vague term; the intent is
 that programmers must implement these methods in a way such that the compiler,
 modifying code in ways it deems safe according to these constraints, will not
-violate their requirements.  For example, if the user puts logging statements
-in ``retain``, they should not be surprised if those statements are executed
-more or less often depending on optimization settings.  These constraints are
+violate their requirements. For example, if the user puts logging statements
+in `retain`, they should not be surprised if those statements are executed
+more or less often depending on optimization settings. These constraints are
 not exhaustive of the optimization opportunities: values held in local
 variables are subject to additional restrictions, described later in this
 document.
 
 It is undefined behavior if a computation history featuring a send of
-``retain`` followed by a send of ``release`` to the same object, with no
-intervening ``release`` on that object, is not equivalent under the high-level
-semantics to a computation history in which these sends are removed.  Note that
+`retain` followed by a send of `release` to the same object, with no
+intervening `release` on that object, is not equivalent under the high-level
+semantics to a computation history in which these sends are removed. Note that
 this implies that these methods may not raise exceptions.
 
 It is undefined behavior if a computation history features any use whatsoever
-of an object following the completion of a send of ``release`` that is not
-preceded by a send of ``retain`` to the same object.
+of an object following the completion of a send of `release` that is not
+preceded by a send of `retain` to the same object.
 
-The behavior of ``autorelease`` must be equivalent to sending ``release`` when
-one of the autorelease pools currently in scope is popped.  It may not throw an
+The behavior of `autorelease` must be equivalent to sending `release` when
+one of the autorelease pools currently in scope is popped. It may not throw an
 exception.
 
 When the semantics call for performing one of these operations on a retainable
-object pointer, if that pointer is ``null`` then the effect is a no-op.
+object pointer, if that pointer is `null` then the effect is a no-op.
 
 All of the semantics described in this document are subject to additional
-:ref:`optimization rules <arc.optimization>` which permit the removal or
-optimization of operations based on local knowledge of data flow.  The
+{ref}`optimization rules <arc.optimization>` which permit the removal or
+optimization of operations based on local knowledge of data flow. The
 semantics describe the high-level behaviors that the compiler implements, not
 an exact sequence of operations that a program will be compiled into.
 
-.. _arc.objects.operands:
+(arc-objects-operands)=
 
-Retainable object pointers as operands and arguments
-----------------------------------------------------
+### Retainable object pointers as operands and arguments
 
 In general, ARC does not perform retain or release operations when simply using
-a retainable object pointer as an operand within an expression.  This includes:
+a retainable object pointer as an operand within an expression. This includes:
 
-* loading a retainable pointer from an object with non-weak :ref:`ownership
+- loading a retainable pointer from an object with non-weak {ref}`ownership
   <arc.ownership>`,
-* passing a retainable pointer as an argument to a function or method, and
-* receiving a retainable pointer as the result of a function or method call.
-
-.. admonition:: Rationale
-
-  While this might seem uncontroversial, it is actually unsafe when multiple
-  expressions are evaluated in "parallel", as with binary operators and calls,
-  because (for example) one expression might load from an object while another
-  writes to it.  However, C and C++ already call this undefined behavior
-  because the evaluations are unsequenced, and ARC simply exploits that here to
-  avoid needing to retain arguments across a large number of calls.
+- passing a retainable pointer as an argument to a function or method, and
+- receiving a retainable pointer as the result of a function or method call.
+
+:::{admonition} Rationale
+While this might seem uncontroversial, it is actually unsafe when multiple
+expressions are evaluated in "parallel", as with binary operators and calls,
+because (for example) one expression might load from an object while another
+writes to it. However, C and C++ already call this undefined behavior
+because the evaluations are unsequenced, and ARC simply exploits that here to
+avoid needing to retain arguments across a large number of calls.
+:::
 
 The remainder of this section describes exceptions to these rules, how those
 exceptions are detected, and what those exceptions imply semantically.
 
-.. _arc.objects.operands.consumed:
+(arc-objects-operands-consumed)=
 
-Consumed parameters
-^^^^^^^^^^^^^^^^^^^
+#### Consumed parameters
 
 A function or method parameter of retainable object pointer type may be marked
-as :arc-term:`consumed`, signifying that the callee expects to take ownership
-of a +1 retain count.  This is done by adding the ``ns_consumed`` attribute to
+as {arc-term}`consumed`, signifying that the callee expects to take ownership
+of a +1 retain count. This is done by adding the `ns_consumed` attribute to
 the parameter declaration, like so:
 
-.. code-block:: objc
-
-  void foo(__attribute((ns_consumed)) id x);
-  - (void) foo: (id) __attribute((ns_consumed)) x;
+```objc
+void foo(__attribute((ns_consumed)) id x);
+- (void) foo: (id) __attribute((ns_consumed)) x;
+```
 
 This attribute is part of the type of the function or method, not the type of
-the parameter.  It controls only how the argument is passed and received.
+the parameter. It controls only how the argument is passed and received.
 
 When passing such an argument, ARC retains the argument prior to making the
 call.
@@ -388,52 +384,51 @@ call.
 When receiving such an argument, ARC releases the argument at the end of the
 function, subject to the usual optimizations for local values.
 
-.. admonition:: Rationale
-
-  This formalizes direct transfers of ownership from a caller to a callee.  The
-  most common scenario here is passing the ``self`` parameter to ``init``, but
-  it is useful to generalize.  Typically, local optimization will remove any
-  extra retains and releases: on the caller side the retain will be merged with
-  a +1 source, and on the callee side the release will be rolled into the
-  initialization of the parameter.
-
-The implicit ``self`` parameter of a method may be marked as consumed by adding
-``__attribute__((ns_consumes_self))`` to the method declaration.  Methods in
-the ``init`` :ref:`family <arc.method-families>` are treated as if they were
+:::{admonition} Rationale
+This formalizes direct transfers of ownership from a caller to a callee. The
+most common scenario here is passing the `self` parameter to `init`, but
+it is useful to generalize. Typically, local optimization will remove any
+extra retains and releases: on the caller side the retain will be merged with
+a +1 source, and on the callee side the release will be rolled into the
+initialization of the parameter.
+:::
+
+The implicit `self` parameter of a method may be marked as consumed by adding
+`__attribute__((ns_consumes_self))` to the method declaration. Methods in
+the `init` {ref}`family <arc.method-families>` are treated as if they were
 implicitly marked with this attribute.
 
 It is undefined behavior if an Objective-C message send to a method with
-``ns_consumed`` parameters (other than self) is made with a null receiver.  It
+`ns_consumed` parameters (other than self) is made with a null receiver. It
 is undefined behavior if the method to which an Objective-C message send
-statically resolves to has a different set of ``ns_consumed`` parameters than
-the method it dynamically resolves to.  It is undefined behavior if a block or
+statically resolves to has a different set of `ns_consumed` parameters than
+the method it dynamically resolves to. It is undefined behavior if a block or
 function call is made through a static type with a different set of
-``ns_consumed`` parameters than the implementation of the called block or
+`ns_consumed` parameters than the implementation of the called block or
 function.
 
-.. admonition:: Rationale
+:::{admonition} Rationale
+Consumed parameters with null receiver are a guaranteed leak. Mismatches
+with consumed parameters will cause over-retains or over-releases, depending
+on the direction. The rule about function calls is really just an
+application of the existing C/C++ rule about calling functions through an
+incompatible function type, but it's useful to state it explicitly.
+:::
 
-  Consumed parameters with null receiver are a guaranteed leak.  Mismatches
-  with consumed parameters will cause over-retains or over-releases, depending
-  on the direction.  The rule about function calls is really just an
-  application of the existing C/C++ rule about calling functions through an
-  incompatible function type, but it's useful to state it explicitly.
+(arc-object-operands-retained-return-values)=
 
-.. _arc.object.operands.retained-return-values:
-
-Retained return values
-^^^^^^^^^^^^^^^^^^^^^^
+#### Retained return values
 
 A function or method which returns a retainable object pointer type may be
 marked as returning a retained value, signifying that the caller expects to take
-ownership of a +1 retain count.  This is done by adding the
-``ns_returns_retained`` attribute to the function or method declaration, like
+ownership of a +1 retain count. This is done by adding the
+`ns_returns_retained` attribute to the function or method declaration, like
 so:
 
-.. code-block:: objc
-
-  id foo(void) __attribute((ns_returns_retained));
-  - (id) foo __attribute((ns_returns_retained));
+```objc
+id foo(void) __attribute((ns_returns_retained));
+- (id) foo __attribute((ns_returns_retained));
+```
 
 This attribute is part of the type of the function or method.
 
@@ -444,36 +439,35 @@ When receiving a return result from such a function or method, ARC releases the
 value at the end of the full-expression it is contained within, subject to the
 usual optimizations for local values.
 
-.. admonition:: Rationale
+:::{admonition} Rationale
+This formalizes direct transfers of ownership from a callee to a caller. The
+most common scenario this models is the retained return from `init`,
+`alloc`, `new`, and `copy` methods, but there are other cases in the
+frameworks. After optimization there are typically no extra retains and
+releases required.
+:::
 
-  This formalizes direct transfers of ownership from a callee to a caller.  The
-  most common scenario this models is the retained return from ``init``,
-  ``alloc``, ``new``, and ``copy`` methods, but there are other cases in the
-  frameworks.  After optimization there are typically no extra retains and
-  releases required.
-
-Methods in the ``alloc``, ``copy``, ``init``, ``mutableCopy``, and ``new``
-:ref:`families <arc.method-families>` are implicitly marked
-``__attribute__((ns_returns_retained))``.  This may be suppressed by explicitly
-marking the method ``__attribute__((ns_returns_not_retained))``.
+Methods in the `alloc`, `copy`, `init`, `mutableCopy`, and `new`
+{ref}`families <arc.method-families>` are implicitly marked
+`__attribute__((ns_returns_retained))`. This may be suppressed by explicitly
+marking the method `__attribute__((ns_returns_not_retained))`.
 
 It is undefined behavior if the method to which an Objective-C message send
 statically resolves has different retain semantics on its result from the
-method it dynamically resolves to.  It is undefined behavior if a block or
+method it dynamically resolves to. It is undefined behavior if a block or
 function call is made through a static type with different retain semantics on
 its result from the implementation of the called block or function.
 
-.. admonition:: Rationale
-
-  Mismatches with returned results will cause over-retains or over-releases,
-  depending on the direction.  Again, the rule about function calls is really
-  just an application of the existing C/C++ rule about calling functions
-  through an incompatible function type.
+:::{admonition} Rationale
+Mismatches with returned results will cause over-retains or over-releases,
+depending on the direction. Again, the rule about function calls is really
+just an application of the existing C/C++ rule about calling functions
+through an incompatible function type.
+:::
 
-.. _arc.objects.operands.unretained-returns:
+(arc-objects-operands-unretained-returns)=
 
-Unretained return values
-^^^^^^^^^^^^^^^^^^^^^^^^
+#### Unretained return values
 
 A method or function which returns a retainable object type but does not return
 a retained value must ensure that the object is still valid across the return
@@ -482,91 +476,87 @@ boundary.
 When returning from such a function or method, ARC retains the value at the
 point of evaluation of the return statement, then leaves all local scopes, and
 then balances out the retain while ensuring that the value lives across the
-call boundary.  In the worst case, this may involve an ``autorelease``, but
+call boundary. In the worst case, this may involve an `autorelease`, but
 callers must not assume that the value is actually in the autorelease pool.
 
 ARC performs no extra mandatory work on the caller side, although it may elect
 to do something to shorten the lifetime of the returned value.
 
-.. admonition:: Rationale
-
-  It is common in non-ARC code to not return an autoreleased value; therefore
-  the convention does not force either path.  It is convenient to not be
-  required to do unnecessary retains and autoreleases; this permits
-  optimizations such as eliding retain/autoreleases when it can be shown that
-  the original pointer will still be valid at the point of return.
+:::{admonition} Rationale
+It is common in non-ARC code to not return an autoreleased value; therefore
+the convention does not force either path. It is convenient to not be
+required to do unnecessary retains and autoreleases; this permits
+optimizations such as eliding retain/autoreleases when it can be shown that
+the original pointer will still be valid at the point of return.
+:::
 
 A method or function may be marked with
-``__attribute__((ns_returns_autoreleased))`` to indicate that it returns a
+`__attribute__((ns_returns_autoreleased))` to indicate that it returns a
 pointer which is guaranteed to be valid at least as long as the innermost
-autorelease pool.  There are no additional semantics enforced in the definition
+autorelease pool. There are no additional semantics enforced in the definition
 of such a method; it merely enables optimizations in callers.
 
-.. _arc.objects.operands.casts:
+(arc-objects-operands-casts)=
 
-Bridged casts
-^^^^^^^^^^^^^
+#### Bridged casts
 
-A :arc-term:`bridged cast` is a C-style cast annotated with one of three
+A {arc-term}`bridged cast` is a C-style cast annotated with one of three
 keywords:
 
-* ``(__bridge T) op`` casts the operand to the destination type ``T``.  If
-  ``T`` is a retainable object pointer type, then ``op`` must have a
-  non-retainable pointer type.  If ``T`` is a non-retainable pointer type,
-  then ``op`` must have a retainable object pointer type.  Otherwise the cast
-  is ill-formed.  There is no transfer of ownership, and ARC inserts no retain
+- `(__bridge T) op` casts the operand to the destination type `T`. If
+  `T` is a retainable object pointer type, then `op` must have a
+  non-retainable pointer type. If `T` is a non-retainable pointer type,
+  then `op` must have a retainable object pointer type. Otherwise the cast
+  is ill-formed. There is no transfer of ownership, and ARC inserts no retain
   operations.
-* ``(__bridge_retained T) op`` casts the operand, which must have retainable
+- `(__bridge_retained T) op` casts the operand, which must have retainable
   object pointer type, to the destination type, which must be a non-retainable
-  pointer type.  ARC retains the value, subject to the usual optimizations on
+  pointer type. ARC retains the value, subject to the usual optimizations on
   local values, and the recipient is responsible for balancing that +1.
-* ``(__bridge_transfer T) op`` casts the operand, which must have
+- `(__bridge_transfer T) op` casts the operand, which must have
   non-retainable pointer type, to the destination type, which must be a
-  retainable object pointer type.  ARC will release the value at the end of
+  retainable object pointer type. ARC will release the value at the end of
   the enclosing full-expression, subject to the usual optimizations on local
   values.
 
 These casts are required in order to transfer objects in and out of ARC
-control; see the rationale in the section on :ref:`conversion of retainable
+control; see the rationale in the section on {ref}`conversion of retainable
 object pointers <arc.objects.restrictions.conversion>`.
 
-Using a ``__bridge_retained`` or ``__bridge_transfer`` cast purely to convince
+Using a `__bridge_retained` or `__bridge_transfer` cast purely to convince
 ARC to emit an unbalanced retain or release, respectively, is poor form.
 
-.. _arc.objects.restrictions:
+(arc-objects-restrictions)=
 
-Restrictions
-------------
+### Restrictions
 
-.. _arc.objects.restrictions.conversion:
+(arc-objects-restrictions-conversion)=
 
-Conversion of retainable object pointers
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Conversion of retainable object pointers
 
 In general, a program which attempts to implicitly or explicitly convert a
 value of retainable object pointer type to any non-retainable type, or
-vice-versa, is ill-formed.  For example, an Objective-C object pointer shall
-not be converted to ``void*``.  As an exception, cast to ``intptr_t`` is
-allowed because such casts are not transferring ownership.  The :ref:`bridged
+vice-versa, is ill-formed. For example, an Objective-C object pointer shall
+not be converted to `void*`. As an exception, cast to `intptr_t` is
+allowed because such casts are not transferring ownership. The {ref}`bridged
 casts <arc.objects.operands.casts>` may be used to perform these conversions
 where necessary.
 
-.. admonition:: Rationale
-
-  We cannot ensure the correct management of the lifetime of objects if they
-  may be freely passed around as unmanaged types.  The bridged casts are
-  provided so that the programmer may explicitly describe whether the cast
-  transfers control into or out of ARC.
+:::{admonition} Rationale
+We cannot ensure the correct management of the lifetime of objects if they
+may be freely passed around as unmanaged types. The bridged casts are
+provided so that the programmer may explicitly describe whether the cast
+transfers control into or out of ARC.
+:::
 
 However, the following exceptions apply.
 
-.. _arc.objects.restrictions.conversion.with.known.semantics:
+(arc-objects-restrictions-conversion-with-known-semantics)=
 
-Conversion to retainable object pointer type of expressions with known semantics
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Conversion to retainable object pointer type of expressions with known semantics
 
-:when-revised:`[beginning Apple 4.0, LLVM 3.1]`
-:revision:`These exceptions have been greatly expanded; they previously applied
+{when-revised}`[beginning Apple 4.0, LLVM 3.1]`
+{revision}`These exceptions have been greatly expanded; they previously applied
 only to a much-reduced subset which is difficult to categorize but which
 included null pointers, message sends (under the given rules), and the various
 global constants.`
@@ -576,108 +566,106 @@ than a retainable object pointer type is ill-formed, as discussed above, unless
 the operand of the cast has a syntactic form which is known retained, known
 unretained, or known retain-agnostic.
 
-An expression is :arc-term:`known retain-agnostic` if it is:
+An expression is {arc-term}`known retain-agnostic` if it is:
 
-* an Objective-C string literal,
-* a load from a ``const`` system global variable of :ref:`C retainable pointer
+- an Objective-C string literal,
+- a load from a `const` system global variable of {ref}`C retainable pointer
   type <arc.misc.c-retainable>`, or
-* a null pointer constant.
+- a null pointer constant.
 
-An expression is :arc-term:`known unretained` if it is an rvalue of :ref:`C
+An expression is {arc-term}`known unretained` if it is an rvalue of {ref}`C
 retainable pointer type <arc.misc.c-retainable>` and it is:
 
-* a direct call to a function, and either that function has the
-  ``cf_returns_not_retained`` attribute or it is an :ref:`audited
+- a direct call to a function, and either that function has the
+  `cf_returns_not_retained` attribute or it is an {ref}`audited
   <arc.misc.c-retainable.audit>` function that does not have the
-  ``cf_returns_retained`` attribute and does not follow the create/copy naming
+  `cf_returns_retained` attribute and does not follow the create/copy naming
   convention,
-* a message send, and the declared method either has the
-  ``cf_returns_not_retained`` attribute or it has neither the
-  ``cf_returns_retained`` attribute nor a :ref:`selector family
+- a message send, and the declared method either has the
+  `cf_returns_not_retained` attribute or it has neither the
+  `cf_returns_retained` attribute nor a {ref}`selector family
   <arc.method-families>` that implies a retained result, or
-* :when-revised:`[beginning LLVM 3.6]` :revision:`a load from a` ``const``
-  :revision:`non-system global variable.`
+- {when-revised}`[beginning LLVM 3.6]` {revision}`a load from a` `const`
+  {revision}`non-system global variable.`
 
-An expression is :arc-term:`known retained` if it is an rvalue of :ref:`C
+An expression is {arc-term}`known retained` if it is an rvalue of {ref}`C
 retainable pointer type <arc.misc.c-retainable>` and it is:
 
-* a message send, and the declared method either has the
-  ``cf_returns_retained`` attribute, or it does not have the
-  ``cf_returns_not_retained`` attribute but it does have a :ref:`selector
+- a message send, and the declared method either has the
+  `cf_returns_retained` attribute, or it does not have the
+  `cf_returns_not_retained` attribute but it does have a {ref}`selector
   family <arc.method-families>` that implies a retained result.
 
 Furthermore:
 
-* a comma expression is classified according to its right-hand side,
-* a statement expression is classified according to its result expression, if
+- a comma expression is classified according to its right-hand side,
+- a statement expression is classified according to its result expression, if
   it has one,
-* an lvalue-to-rvalue conversion applied to an Objective-C property lvalue is
+- an lvalue-to-rvalue conversion applied to an Objective-C property lvalue is
   classified according to the underlying message send, and
-* a conditional operator is classified according to its second and third
+- a conditional operator is classified according to its second and third
   operands, if they agree in classification, or else the other if one is known
   retain-agnostic.
 
 If the cast operand is known retained, the conversion is treated as a
-``__bridge_transfer`` cast.  If the cast operand is known unretained or known
-retain-agnostic, the conversion is treated as a ``__bridge`` cast.
+`__bridge_transfer` cast. If the cast operand is known unretained or known
+retain-agnostic, the conversion is treated as a `__bridge` cast.
 
-.. admonition:: Rationale
+:::{admonition} Rationale
+Bridging casts are annoying. Absent the ability to completely automate the
+management of CF objects, however, we are left with relatively poor attempts
+to reduce the need for a glut of explicit bridges. Hence these rules.
 
-  Bridging casts are annoying.  Absent the ability to completely automate the
-  management of CF objects, however, we are left with relatively poor attempts
-  to reduce the need for a glut of explicit bridges.  Hence these rules.
+We've so far consciously refrained from implicitly turning retained CF
+results from function calls into `__bridge_transfer` casts. The worry is
+that some code patterns --- for example, creating a CF value, assigning it
+to an ObjC-typed local, and then calling `CFRelease` when done --- are a
+bit too likely to be accidentally accepted, leading to mysterious behavior.
 
-  We've so far consciously refrained from implicitly turning retained CF
-  results from function calls into ``__bridge_transfer`` casts.  The worry is
-  that some code patterns  ---  for example, creating a CF value, assigning it
-  to an ObjC-typed local, and then calling ``CFRelease`` when done  ---  are a
-  bit too likely to be accidentally accepted, leading to mysterious behavior.
+For loads from `const` global variables of {ref}`C retainable pointer type
+<arc.misc.c-retainable>`, it is reasonable to assume that global system
+constants were initialized with true constants (e.g. string literals), but
+user constants might have been initialized with something dynamically
+allocated, using a global initializer.
+:::
 
-  For loads from ``const`` global variables of :ref:`C retainable pointer type
-  <arc.misc.c-retainable>`, it is reasonable to assume that global system
-  constants were initialized with true constants (e.g. string literals), but
-  user constants might have been initialized with something dynamically
-  allocated, using a global initializer.
+(arc-objects-restrictions-conversion-exception-contextual)=
 
-.. _arc.objects.restrictions.conversion-exception-contextual:
+#### Conversion from retainable object pointer type in certain contexts
 
-Conversion from retainable object pointer type in certain contexts
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-:when-revised:`[beginning Apple 4.0, LLVM 3.1]`
+{when-revised}`[beginning Apple 4.0, LLVM 3.1]`
 
 If an expression of retainable object pointer type is explicitly cast to a
-:ref:`C retainable pointer type <arc.misc.c-retainable>`, the program is
+{ref}`C retainable pointer type <arc.misc.c-retainable>`, the program is
 ill-formed as discussed above unless the result is immediately used:
 
-* to initialize a parameter in an Objective-C message send where the parameter
-  is not marked with the ``cf_consumed`` attribute, or
-* to initialize a parameter in a direct call to an
-  :ref:`audited <arc.misc.c-retainable.audit>` function where the parameter is
-  not marked with the ``cf_consumed`` attribute.
-
-.. admonition:: Rationale
+- to initialize a parameter in an Objective-C message send where the parameter
+  is not marked with the `cf_consumed` attribute, or
+- to initialize a parameter in a direct call to an
+  {ref}`audited <arc.misc.c-retainable.audit>` function where the parameter is
+  not marked with the `cf_consumed` attribute.
 
-  Consumed parameters are left out because ARC would naturally balance them
-  with a retain, which was judged too treacherous.  This is in part because
-  several of the most common consuming functions are in the ``Release`` family,
-  and it would be quite unfortunate for explicit releases to be silently
-  balanced out in this way.
+:::{admonition} Rationale
+Consumed parameters are left out because ARC would naturally balance them
+with a retain, which was judged too treacherous. This is in part because
+several of the most common consuming functions are in the `Release` family,
+and it would be quite unfortunate for explicit releases to be silently
+balanced out in this way.
+:::
 
-.. _arc.ownership:
+(arc-ownership)=
 
-Ownership qualification
-=======================
+## Ownership qualification
 
 This section describes the behavior of *objects* of retainable object pointer
 type; that is, locations in memory which store retainable object pointers.
 
-A type is a :arc-term:`retainable object owner type` if it is a retainable
+A type is a {arc-term}`retainable object owner type` if it is a retainable
 object pointer type or an array type whose element type is a retainable object
 owner type.
 
-An :arc-term:`ownership qualifier` is a type qualifier which applies only to
-retainable object owner types.  An array type is ownership-qualified according
+An {arc-term}`ownership qualifier` is a type qualifier which applies only to
+retainable object owner types. An array type is ownership-qualified according
 to its element type, and adding an ownership qualifier to an array type so
 qualifies its element type.
 
@@ -690,36 +678,35 @@ qualifier provided by the template argument.
 When forming a function type, the result type is adjusted so that any
 top-level ownership qualifier is deleted.
 
-Except as described under the :ref:`inference rules <arc.ownership.inference>`,
+Except as described under the {ref}`inference rules <arc.ownership.inference>`,
 a program is ill-formed if it attempts to form a pointer or reference type to a
 retainable object owner type which lacks an ownership qualifier.
 
-.. admonition:: Rationale
-
-  These rules, together with the inference rules, ensure that all objects and
-  lvalues of retainable object pointer type have an ownership qualifier.  The
-  ability to override an ownership qualifier during template substitution is
-  required to counteract the :ref:`inference of __strong for template type
-  arguments <arc.ownership.inference.template.arguments>`.  Ownership qualifiers
-  on return types are dropped because they serve no purpose there except to
-  cause spurious problems with overloading and templates.
+:::{admonition} Rationale
+These rules, together with the inference rules, ensure that all objects and
+lvalues of retainable object pointer type have an ownership qualifier. The
+ability to override an ownership qualifier during template substitution is
+required to counteract the {ref}`inference of __strong for template type
+arguments <arc.ownership.inference.template.arguments>`. Ownership qualifiers
+on return types are dropped because they serve no purpose there except to
+cause spurious problems with overloading and templates.
+:::
 
 There are four ownership qualifiers:
 
-* ``__autoreleasing``
-* ``__strong``
-* ``__unsafe_unretained``
-* ``__weak``
+- `__autoreleasing`
+- `__strong`
+- `__unsafe_unretained`
+- `__weak`
 
-A type is :arc-term:`nontrivially ownership-qualified` if it is qualified with
-``__autoreleasing``, ``__strong``, or ``__weak``.
+A type is {arc-term}`nontrivially ownership-qualified` if it is qualified with
+`__autoreleasing`, `__strong`, or `__weak`.
 
-.. _arc.ownership.spelling:
+(arc-ownership-spelling)=
 
-Spelling
---------
+### Spelling
 
-The names of the ownership qualifiers are reserved for the implementation.  A
+The names of the ownership qualifiers are reserved for the implementation. A
 program may not assume that they are or are not implemented with macros, or
 what those macros expand to.
 
@@ -729,16 +716,13 @@ may be written.
 If an ownership qualifier appears in the *declaration-specifiers*, the
 following rules apply:
 
-* if the type specifier is a retainable object owner type, the qualifier
+- if the type specifier is a retainable object owner type, the qualifier
   initially applies to that type;
-
-* otherwise, if the outermost non-array declarator is a pointer
+- otherwise, if the outermost non-array declarator is a pointer
   or block pointer declarator, the qualifier initially applies to
   that type;
-
-* otherwise the program is ill-formed.
-
-* If the qualifier is so applied at a position in the declaration
+- otherwise the program is ill-formed.
+- If the qualifier is so applied at a position in the declaration
   where the next-innermost declarator is a function declarator, and
   there is a block declarator within that function declarator, then
   the qualifier applies instead to that block declarator and this rule
@@ -750,315 +734,309 @@ object, it is applied to the innermost pointer or block-pointer type.
 If an ownership qualifier appears anywhere else in a declarator, it applies to
 the type there.
 
-.. admonition:: Rationale
+:::{admonition} Rationale
+Ownership qualifiers are like `const` and `volatile` in the sense
+that they may sensibly apply at multiple distinct positions within a
+declarator. However, unlike those qualifiers, there are many
+situations where they are not meaningful, and so we make an effort
+to "move" the qualifier to a place where it will be meaningful. The
+general goal is to allow the programmer to write, say, `__strong`
+before the entire declaration and have it apply in the leftmost
+sensible place.
+:::
 
-  Ownership qualifiers are like ``const`` and ``volatile`` in the sense
-  that they may sensibly apply at multiple distinct positions within a
-  declarator.  However, unlike those qualifiers, there are many
-  situations where they are not meaningful, and so we make an effort
-  to "move" the qualifier to a place where it will be meaningful.  The
-  general goal is to allow the programmer to write, say, ``__strong``
-  before the entire declaration and have it apply in the leftmost
-  sensible place.
+(arc-ownership-spelling-property)=
 
-.. _arc.ownership.spelling.property:
+#### Property declarations
 
-Property declarations
-^^^^^^^^^^^^^^^^^^^^^
-
-A property of retainable object pointer type may have ownership.  If the
+A property of retainable object pointer type may have ownership. If the
 property's type is ownership-qualified, then the property has that ownership.
 If the property has one of the following modifiers, then the property has the
-corresponding ownership.  A property is ill-formed if it has conflicting
+corresponding ownership. A property is ill-formed if it has conflicting
 sources of ownership, or if it has redundant ownership modifiers, or if it has
-``__autoreleasing`` ownership.
+`__autoreleasing` ownership.
 
-* ``assign`` implies ``__unsafe_unretained`` ownership.
-* ``copy`` implies ``__strong`` ownership, as well as the usual behavior of
+- `assign` implies `__unsafe_unretained` ownership.
+- `copy` implies `__strong` ownership, as well as the usual behavior of
   copy semantics on the setter.
-* ``retain`` implies ``__strong`` ownership.
-* ``strong`` implies ``__strong`` ownership.
-* ``unsafe_unretained`` implies ``__unsafe_unretained`` ownership.
-* ``weak`` implies ``__weak`` ownership.
+- `retain` implies `__strong` ownership.
+- `strong` implies `__strong` ownership.
+- `unsafe_unretained` implies `__unsafe_unretained` ownership.
+- `weak` implies `__weak` ownership.
 
-With the exception of ``weak``, these modifiers are available in non-ARC
+With the exception of `weak`, these modifiers are available in non-ARC
 modes.
 
 A property's specified ownership is preserved in its metadata, but otherwise
-the meaning is purely conventional unless the property is synthesized.  If a
-property is synthesized, then the :arc-term:`associated instance variable` is
+the meaning is purely conventional unless the property is synthesized. If a
+property is synthesized, then the {arc-term}`associated instance variable` is
 the instance variable which is named, possibly implicitly, by the
-``@synthesize`` declaration.  If the associated instance variable already
+`@synthesize` declaration. If the associated instance variable already
 exists, then its ownership qualification must equal the ownership of the
 property; otherwise, the instance variable is created with that ownership
 qualification.
 
 A property of retainable object pointer type which is synthesized without a
 source of ownership has the ownership of its associated instance variable, if it
-already exists; otherwise, :when-revised:`[beginning Apple 3.1, LLVM 3.1]`
-:revision:`its ownership is implicitly` ``strong``.  Prior to this revision, it
+already exists; otherwise, {when-revised}`[beginning Apple 3.1, LLVM 3.1]`
+{revision}`its ownership is implicitly` `strong`. Prior to this revision, it
 was ill-formed to synthesize such a property.
 
-.. admonition:: Rationale
-
-  Using ``strong`` by default is safe and consistent with the generic ARC rule
-  about :ref:`inferring ownership <arc.ownership.inference.variables>`.  It is,
-  unfortunately, inconsistent with the non-ARC rule which states that such
-  properties are implicitly ``assign``.  However, that rule is clearly
-  untenable in ARC, since it leads to default-unsafe code.  The main merit to
-  banning the properties is to avoid confusion with non-ARC practice, which did
-  not ultimately strike us as sufficient to justify requiring extra syntax and
-  (more importantly) forcing novices to understand ownership rules just to
-  declare a property when the default is so reasonable.  Changing the rule away
-  from non-ARC practice was acceptable because we had conservatively banned the
-  synthesis in order to give ourselves exactly this leeway.
-
-Applying ``__attribute__((NSObject))`` to a property not of retainable object
+:::{admonition} Rationale
+Using `strong` by default is safe and consistent with the generic ARC rule
+about {ref}`inferring ownership <arc.ownership.inference.variables>`. It is,
+unfortunately, inconsistent with the non-ARC rule which states that such
+properties are implicitly `assign`. However, that rule is clearly
+untenable in ARC, since it leads to default-unsafe code. The main merit to
+banning the properties is to avoid confusion with non-ARC practice, which did
+not ultimately strike us as sufficient to justify requiring extra syntax and
+(more importantly) forcing novices to understand ownership rules just to
+declare a property when the default is so reasonable. Changing the rule away
+from non-ARC practice was acceptable because we had conservatively banned the
+synthesis in order to give ourselves exactly this leeway.
+:::
+
+Applying `__attribute__((NSObject))` to a property not of retainable object
 pointer type has the same behavior it does outside of ARC: it requires the
 property type to be some sort of pointer and permits the use of modifiers other
-than ``assign``.  These modifiers only affect the synthesized getter and
+than `assign`. These modifiers only affect the synthesized getter and
 setter; direct accesses to the ivar (even if synthesized) still have primitive
 semantics, and the value in the ivar will not be automatically released during
 deallocation.
 
-.. _arc.ownership.semantics:
+(arc-ownership-semantics)=
 
-Semantics
----------
+### Semantics
 
-There are five :arc-term:`managed operations` which may be performed on an
-object of retainable object pointer type.  Each qualifier specifies different
-semantics for each of these operations.  It is still undefined behavior to
+There are five {arc-term}`managed operations` which may be performed on an
+object of retainable object pointer type. Each qualifier specifies different
+semantics for each of these operations. It is still undefined behavior to
 access an object outside of its lifetime.
 
 A load or store with "primitive semantics" has the same semantics as the
-respective operation would have on an ``void*`` lvalue with the same alignment
+respective operation would have on an `void*` lvalue with the same alignment
 and non-ownership qualification.
 
-:arc-term:`Reading` occurs when performing a lvalue-to-rvalue conversion on an
+{arc-term}`Reading` occurs when performing a lvalue-to-rvalue conversion on an
 object lvalue.
 
-* For ``__weak`` objects, the current pointee is retained and then released at
-  the end of the current full-expression. In particular, messaging a ``__weak``
+- For `__weak` objects, the current pointee is retained and then released at
+  the end of the current full-expression. In particular, messaging a `__weak`
   object keeps the object retained until the end of the full expression.
 
-  .. code-block:: objc
-
-    __weak MyObject *weakObj;
+  ```objc
+  __weak MyObject *weakObj;
 
-    void foo() {
-      // weakObj is retained before the message send and released at the end of
-      // the full expression.
-      [weakObj m];
-    }
+  void foo() {
+    // weakObj is retained before the message send and released at the end of
+    // the full expression.
+    [weakObj m];
+  }
+  ```
 
   This must execute atomically with respect to assignments and to the final
   release of the pointee.
-* For all other objects, the lvalue is loaded with primitive semantics.
 
-:arc-term:`Assignment` occurs when evaluating an assignment operator.  The
+- For all other objects, the lvalue is loaded with primitive semantics.
+
+{arc-term}`Assignment` occurs when evaluating an assignment operator. The
 semantics vary based on the qualification:
 
-* For ``__strong`` objects, the new pointee is first retained; second, the
+- For `__strong` objects, the new pointee is first retained; second, the
   lvalue is loaded with primitive semantics; third, the new pointee is stored
   into the lvalue with primitive semantics; and finally, the old pointee is
-  released.  This is not performed atomically; external synchronization must be
+  released. This is not performed atomically; external synchronization must be
   used to make this safe in the face of concurrent loads and stores.
-* For ``__weak`` objects, the lvalue is updated to point to the new pointee,
+- For `__weak` objects, the lvalue is updated to point to the new pointee,
   unless the new pointee is an object currently undergoing deallocation, in
-  which case the lvalue is updated to a null pointer.  This must execute
+  which case the lvalue is updated to a null pointer. This must execute
   atomically with respect to other assignments to the object, to reads from the
   object, and to the final release of the new pointee.
-* For ``__unsafe_unretained`` objects, the new pointee is stored into the
+- For `__unsafe_unretained` objects, the new pointee is stored into the
   lvalue using primitive semantics.
-* For ``__autoreleasing`` objects, the new pointee is retained, autoreleased,
+- For `__autoreleasing` objects, the new pointee is retained, autoreleased,
   and stored into the lvalue using primitive semantics.
 
-:arc-term:`Initialization` occurs when an object's lifetime begins, which
-depends on its storage duration.  Initialization proceeds in two stages:
+{arc-term}`Initialization` occurs when an object's lifetime begins, which
+depends on its storage duration. Initialization proceeds in two stages:
 
-#. First, a null pointer is stored into the lvalue using primitive semantics.
-   This step is skipped if the object is ``__unsafe_unretained``.
-#. Second, if the object has an initializer, that expression is evaluated and
+1. First, a null pointer is stored into the lvalue using primitive semantics.
+   This step is skipped if the object is `__unsafe_unretained`.
+2. Second, if the object has an initializer, that expression is evaluated and
    then assigned into the object using the usual assignment semantics.
 
-:arc-term:`Destruction` occurs when an object's lifetime ends.  In all cases it
+{arc-term}`Destruction` occurs when an object's lifetime ends. In all cases it
 is semantically equivalent to assigning a null pointer to the object, with the
 proviso that of course the object cannot be legally read after the object's
 lifetime ends.
 
-:arc-term:`Moving` occurs in specific situations where an lvalue is "moved
+{arc-term}`Moving` occurs in specific situations where an lvalue is "moved
 from", meaning that its current pointee will be used but the object may be left
-in a different (but still valid) state.  This arises with ``__block`` variables
-and rvalue references in C++.  For ``__strong`` lvalues, moving is equivalent
+in a different (but still valid) state. This arises with `__block` variables
+and rvalue references in C++. For `__strong` lvalues, moving is equivalent
 to loading the lvalue with primitive semantics, writing a null pointer to it
 with primitive semantics, and then releasing the result of the load at the end
-of the current full-expression.  For all other lvalues, moving is equivalent to
+of the current full-expression. For all other lvalues, moving is equivalent to
 reading the object.
 
-.. _arc.ownership.restrictions:
+(arc-ownership-restrictions)=
 
-Restrictions
-------------
+### Restrictions
 
-.. _arc.ownership.restrictions.weak:
+(arc-ownership-restrictions-weak)=
 
-Weak-unavailable types
-^^^^^^^^^^^^^^^^^^^^^^
+#### Weak-unavailable types
 
-It is explicitly permitted for Objective-C classes to not support ``__weak``
-references.  It is undefined behavior to perform an operation with weak
+It is explicitly permitted for Objective-C classes to not support `__weak`
+references. It is undefined behavior to perform an operation with weak
 assignment semantics with a pointer to an Objective-C object whose class does
-not support ``__weak`` references.
-
-.. admonition:: Rationale
-
-  Historically, it has been possible for a class to provide its own
-  reference-count implementation by overriding ``retain``, ``release``, etc.
-  However, weak references to an object require coordination with its class's
-  reference-count implementation because, among other things, weak loads and
-  stores must be atomic with respect to the final release.  Therefore, existing
-  custom reference-count implementations will generally not support weak
-  references without additional effort.  This is unavoidable without breaking
-  binary compatibility.
+not support `__weak` references.
+
+:::{admonition} Rationale
+Historically, it has been possible for a class to provide its own
+reference-count implementation by overriding `retain`, `release`, etc.
+However, weak references to an object require coordination with its class's
+reference-count implementation because, among other things, weak loads and
+stores must be atomic with respect to the final release. Therefore, existing
+custom reference-count implementations will generally not support weak
+references without additional effort. This is unavoidable without breaking
+binary compatibility.
+:::
 
 A class may indicate that it does not support weak references by providing the
-``objc_arc_weak_reference_unavailable`` attribute on the class's interface declaration.  A
+`objc_arc_weak_reference_unavailable` attribute on the class's interface declaration. A
 retainable object pointer type is **weak-unavailable** if it
-is a pointer to an (optionally protocol-qualified) Objective-C class ``T`` where
-``T`` or one of its superclasses has the ``objc_arc_weak_reference_unavailable``
-attribute.  A program is ill-formed if it applies the ``__weak`` ownership
+is a pointer to an (optionally protocol-qualified) Objective-C class `T` where
+`T` or one of its superclasses has the `objc_arc_weak_reference_unavailable`
+attribute. A program is ill-formed if it applies the `__weak` ownership
 qualifier to a weak-unavailable type or if the value operand of a weak
 assignment operation has a weak-unavailable type.
 
-.. _arc.ownership.restrictions.autoreleasing:
+(arc-ownership-restrictions-autoreleasing)=
 
-Storage duration of ``__autoreleasing`` objects
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Storage duration of `__autoreleasing` objects
 
-A program is ill-formed if it declares an ``__autoreleasing`` object of
-non-automatic storage duration.  A program is ill-formed if it captures an
-``__autoreleasing`` object in a block or, unless by reference, in a C++11
+A program is ill-formed if it declares an `__autoreleasing` object of
+non-automatic storage duration. A program is ill-formed if it captures an
+`__autoreleasing` object in a block or, unless by reference, in a C++11
 lambda.
 
-.. admonition:: Rationale
-
-  Autorelease pools are tied to the current thread and scope by their nature.
-  While it is possible to have temporary objects whose instance variables are
-  filled with autoreleased objects, there is no way that ARC can provide any
-  sort of safety guarantee there.
+:::{admonition} Rationale
+Autorelease pools are tied to the current thread and scope by their nature.
+While it is possible to have temporary objects whose instance variables are
+filled with autoreleased objects, there is no way that ARC can provide any
+sort of safety guarantee there.
+:::
 
 It is undefined behavior if a non-null pointer is assigned to an
-``__autoreleasing`` object while an autorelease pool is in scope and then that
+`__autoreleasing` object while an autorelease pool is in scope and then that
 object is read after the autorelease pool's scope is left.
 
-.. _arc.ownership.restrictions.conversion.indirect:
+(arc-ownership-restrictions-conversion-indirect)=
 
-Conversion of pointers to ownership-qualified types
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Conversion of pointers to ownership-qualified types
 
-A program is ill-formed if an expression of type ``T*`` is converted,
-explicitly or implicitly, to the type ``U*``, where ``T`` and ``U`` have
+A program is ill-formed if an expression of type `T*` is converted,
+explicitly or implicitly, to the type `U*`, where `T` and `U` have
 different ownership qualification, unless:
 
-* ``T`` is qualified with ``__strong``, ``__autoreleasing``, or
-  ``__unsafe_unretained``, and ``U`` is qualified with both ``const`` and
-  ``__unsafe_unretained``; or
-* either ``T`` or ``U`` is ``cv void``, where ``cv`` is an optional sequence
+- `T` is qualified with `__strong`, `__autoreleasing`, or
+  `__unsafe_unretained`, and `U` is qualified with both `const` and
+  `__unsafe_unretained`; or
+- either `T` or `U` is `cv void`, where `cv` is an optional sequence
   of non-ownership qualifiers; or
-* the conversion is requested with a ``reinterpret_cast`` in Objective-C++; or
-* the conversion is a well-formed :ref:`pass-by-writeback
+- the conversion is requested with a `reinterpret_cast` in Objective-C++; or
+- the conversion is a well-formed {ref}`pass-by-writeback
   <arc.ownership.restrictions.pass_by_writeback>`.
 
-The analogous rule applies to ``T&`` and ``U&`` in Objective-C++.
+The analogous rule applies to `T&` and `U&` in Objective-C++.
 
-.. admonition:: Rationale
-
-  These rules provide a reasonable level of type-safety for indirect pointers,
-  as long as the underlying memory is not deallocated.  The conversion to
-  ``const __unsafe_unretained`` is permitted because the semantics of reads are
-  equivalent across all these ownership semantics, and that's a very useful and
-  common pattern.  The interconversion with ``void*`` is useful for allocating
-  memory or otherwise escaping the type system, but use it carefully.
-  ``reinterpret_cast`` is considered to be an obvious enough sign of taking
-  responsibility for any problems.
+:::{admonition} Rationale
+These rules provide a reasonable level of type-safety for indirect pointers,
+as long as the underlying memory is not deallocated. The conversion to
+`const __unsafe_unretained` is permitted because the semantics of reads are
+equivalent across all these ownership semantics, and that's a very useful and
+common pattern. The interconversion with `void*` is useful for allocating
+memory or otherwise escaping the type system, but use it carefully.
+`reinterpret_cast` is considered to be an obvious enough sign of taking
+responsibility for any problems.
+:::
 
 It is undefined behavior to access an ownership-qualified object through an
-lvalue of a differently-qualified type, except that any non-``__weak`` object
-may be read through an ``__unsafe_unretained`` lvalue.
+lvalue of a differently-qualified type, except that any non-`__weak` object
+may be read through an `__unsafe_unretained` lvalue.
 
-It is undefined behavior if the storage of a ``__strong`` or ``__weak``
+It is undefined behavior if the storage of a `__strong` or `__weak`
 object is not properly initialized before the first managed operation
 is performed on the object, or if the storage of such an object is freed
-or reused before the object has been properly deinitialized.  Storage for
-a ``__strong`` or ``__weak`` object may be properly initialized by filling
+or reused before the object has been properly deinitialized. Storage for
+a `__strong` or `__weak` object may be properly initialized by filling
 it with the representation of a null pointer, e.g. by acquiring the memory
-with ``calloc`` or using ``bzero`` to zero it out.  A ``__strong`` or
-``__weak`` object may be properly deinitialized by assigning a null pointer
-into it.  A ``__strong`` object may also be properly initialized
-by copying into it (e.g. with ``memcpy``) the representation of a
-different ``__strong`` object whose storage has been properly initialized;
+with `calloc` or using `bzero` to zero it out. A `__strong` or
+`__weak` object may be properly deinitialized by assigning a null pointer
+into it. A `__strong` object may also be properly initialized
+by copying into it (e.g. with `memcpy`) the representation of a
+different `__strong` object whose storage has been properly initialized;
 doing this properly deinitializes the source object and causes its storage
-to no longer be properly initialized.  A ``__weak`` object may not be
+to no longer be properly initialized. A `__weak` object may not be
 representation-copied in this way.
 
 These requirements are followed automatically for objects whose
 initialization and deinitialization are under the control of ARC:
 
-* objects of static, automatic, and temporary storage duration
-* instance variables of Objective-C objects
-* elements of arrays where the array object's initialization and
+- objects of static, automatic, and temporary storage duration
+- instance variables of Objective-C objects
+- elements of arrays where the array object's initialization and
   deinitialization are under the control of ARC
-* fields of Objective-C struct types where the struct object's
+- fields of Objective-C struct types where the struct object's
   initialization and deinitialization are under the control of ARC
-* non-static data members of Objective-C++ non-union class types
-* Objective-C++ objects and arrays of dynamic storage duration created
-  with the ``new`` or ``new[]`` operators and destroyed with the
-  corresponding ``delete`` or ``delete[]`` operator
+- non-static data members of Objective-C++ non-union class types
+- Objective-C++ objects and arrays of dynamic storage duration created
+  with the `new` or `new[]` operators and destroyed with the
+  corresponding `delete` or `delete[]` operator
 
 They are not followed automatically for these objects:
 
-* objects of dynamic storage duration created in other memory, such as
-  that returned by ``malloc``
-* union members
-
-.. admonition:: Rationale
-
-  ARC must perform special operations when initializing an object and
-  when destroying it.  In many common situations, ARC knows when an
-  object is created and when it is destroyed and can ensure that these
-  operations are performed correctly.  Otherwise, however, ARC requires
-  programmer cooperation to establish its initialization invariants
-  because it is infeasible for ARC to dynamically infer whether they
-  are intact.  For example, there is no syntactic difference in C between
-  an assignment that is intended by the programmer to initialize a variable
-  and one that is intended to replace the existing value stored there,
-  but ARC must perform one operation or the other.  ARC chooses to always
-  assume that objects are initialized (except when it is in charge of
-  initializing them) because the only workable alternative would be to
-  ban all code patterns that could potentially be used to access
-  uninitialized memory, and that would be too limiting.  In practice,
-  this is rarely a problem because programmers do not generally need to
-  work with objects for which the requirements are not handled
-  automatically.
+- objects of dynamic storage duration created in other memory, such as
+  that returned by `malloc`
+- union members
+
+:::{admonition} Rationale
+ARC must perform special operations when initializing an object and
+when destroying it. In many common situations, ARC knows when an
+object is created and when it is destroyed and can ensure that these
+operations are performed correctly. Otherwise, however, ARC requires
+programmer cooperation to establish its initialization invariants
+because it is infeasible for ARC to dynamically infer whether they
+are intact. For example, there is no syntactic difference in C between
+an assignment that is intended by the programmer to initialize a variable
+and one that is intended to replace the existing value stored there,
+but ARC must perform one operation or the other. ARC chooses to always
+assume that objects are initialized (except when it is in charge of
+initializing them) because the only workable alternative would be to
+ban all code patterns that could potentially be used to access
+uninitialized memory, and that would be too limiting. In practice,
+this is rarely a problem because programmers do not generally need to
+work with objects for which the requirements are not handled
+automatically.
+:::
 
 Note that dynamically-allocated Objective-C++ arrays of
 nontrivially-ownership-qualified type are not ABI-compatible with non-ARC
 code because the non-ARC code will consider the element type to be POD.
-Such arrays that are ``new[]``'d in ARC translation units cannot be
-``delete[]``'d in non-ARC translation units and vice-versa.
+Such arrays that are `new[]`'d in ARC translation units cannot be
+`delete[]`'d in non-ARC translation units and vice-versa.
 
-.. _arc.ownership.restrictions.pass_by_writeback:
+(arc-ownership-restrictions-pass-by-writeback)=
 
-Passing to an out parameter by writeback
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Passing to an out parameter by writeback
 
-If the argument passed to a parameter of type ``T __autoreleasing *`` has type
-``U oq *``, where ``oq`` is an ownership qualifier, then the argument is a
-candidate for :arc-term:`pass-by-writeback`` if:
+If the argument passed to a parameter of type `T __autoreleasing *` has type
+`U oq *`, where `oq` is an ownership qualifier, then the argument is a
+candidate for {arc-term}`pass-by-writeback`` if:
 
-* ``oq`` is ``__strong`` or ``__weak``, and
-* it would be legal to initialize a ``T __strong *`` with a ``U __strong *``.
+- `oq` is `__strong` or `__weak`, and
+- it would be legal to initialize a `T __strong *` with a `U __strong *`.
 
 For purposes of overload resolution, an implicit conversion sequence requiring
 a pass-by-writeback is always worse than an implicit conversion sequence not
@@ -1067,95 +1045,93 @@ requiring a pass-by-writeback.
 The pass-by-writeback is ill-formed if the argument expression does not have a
 legal form:
 
-* ``&var``, where ``var`` is a scalar variable of automatic storage duration
+- `&var`, where `var` is a scalar variable of automatic storage duration
   with retainable object pointer type
-* a conditional expression where the second and third operands are both legal
+- a conditional expression where the second and third operands are both legal
   forms
-* a cast whose operand is a legal form
-* a null pointer constant
-
-.. admonition:: Rationale
-
-  The restriction in the form of the argument serves two purposes.  First, it
-  makes it impossible to pass the address of an array to the argument, which
-  serves to protect against an otherwise serious risk of mis-inferring an
-  "array" argument as an out-parameter.  Second, it makes it much less likely
-  that the user will see confusing aliasing problems due to the implementation,
-  below, where their store to the writeback temporary is not immediately seen
-  in the original argument variable.
+- a cast whose operand is a legal form
+- a null pointer constant
+
+:::{admonition} Rationale
+The restriction in the form of the argument serves two purposes. First, it
+makes it impossible to pass the address of an array to the argument, which
+serves to protect against an otherwise serious risk of mis-inferring an
+"array" argument as an out-parameter. Second, it makes it much less likely
+that the user will see confusing aliasing problems due to the implementation,
+below, where their store to the writeback temporary is not immediately seen
+in the original argument variable.
+:::
 
 A pass-by-writeback is evaluated as follows:
 
-#. The argument is evaluated to yield a pointer ``p`` of type ``U oq *``.
-#. If ``p`` is a null pointer, then a null pointer is passed as the argument,
+1. The argument is evaluated to yield a pointer `p` of type `U oq *`.
+2. If `p` is a null pointer, then a null pointer is passed as the argument,
    and no further work is required for the pass-by-writeback.
-#. Otherwise, a temporary of type ``T __autoreleasing`` is created and
+3. Otherwise, a temporary of type `T __autoreleasing` is created and
    initialized to a null pointer.
-#. If the parameter is not an Objective-C method parameter marked ``out``,
-   then ``*p`` is read, and the result is written into the temporary with
+4. If the parameter is not an Objective-C method parameter marked `out`,
+   then `*p` is read, and the result is written into the temporary with
    primitive semantics.
-#. The address of the temporary is passed as the argument to the actual call.
-#. After the call completes, the temporary is loaded with primitive
-   semantics, and that value is assigned into ``*p``.
-
-.. admonition:: Rationale
+5. The address of the temporary is passed as the argument to the actual call.
+6. After the call completes, the temporary is loaded with primitive
+   semantics, and that value is assigned into `*p`.
 
-  This is all admittedly convoluted.  In an ideal world, we would see that a
-  local variable is being passed to an out-parameter and retroactively modify
-  its type to be ``__autoreleasing`` rather than ``__strong``.  This would be
-  remarkably difficult and not always well-founded under the C type system.
-  However, it was judged unacceptably invasive to require programmers to write
-  ``__autoreleasing`` on all the variables they intend to use for
-  out-parameters.  This was the least bad solution.
+:::{admonition} Rationale
+This is all admittedly convoluted. In an ideal world, we would see that a
+local variable is being passed to an out-parameter and retroactively modify
+its type to be `__autoreleasing` rather than `__strong`. This would be
+remarkably difficult and not always well-founded under the C type system.
+However, it was judged unacceptably invasive to require programmers to write
+`__autoreleasing` on all the variables they intend to use for
+out-parameters. This was the least bad solution.
+:::
 
-.. _arc.ownership.restrictions.records:
+(arc-ownership-restrictions-records)=
 
-Ownership-qualified fields of structs and unions
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Ownership-qualified fields of structs and unions
 
 A member of a struct or union may be declared to have ownership-qualified
-type.  If the type is qualified with ``__unsafe_unretained``, the semantics
-of the containing aggregate are unchanged from the semantics of an unqualified type in a non-ARC mode.  If the type is qualified with ``__autoreleasing``, the program is ill-formed.  Otherwise, if the type is nontrivially ownership-qualified, additional rules apply.
+type. If the type is qualified with `__unsafe_unretained`, the semantics
+of the containing aggregate are unchanged from the semantics of an unqualified type in a non-ARC mode. If the type is qualified with `__autoreleasing`, the program is ill-formed. Otherwise, if the type is nontrivially ownership-qualified, additional rules apply.
 
 Both Objective-C and Objective-C++ support nontrivially ownership-qualified
-fields.  Due to formal differences between the standards, the formal
+fields. Due to formal differences between the standards, the formal
 treatment is different; however, the basic language model is intended to
 be the same for identical code.
 
-.. admonition:: Rationale
-
-  Permitting ``__strong`` and ``__weak`` references in aggregate types
-  allows programmers to take advantage of the normal language tools of
-  C and C++ while still automatically managing memory.  While it is
-  usually simpler and more idiomatic to use Objective-C objects for
-  secondary data structures, doing so can introduce extra allocation
-  and message-send overhead, which can cause unacceptable
-  performance.  Using structs can resolve some of this tension.
-
-  ``__autoreleasing`` is forbidden because it is treacherous to rely
-  on autoreleases as an ownership tool outside of a function-local
-  contexts.
-
-  Earlier releases of Clang permitted ``__strong`` and ``__weak`` only
-  references in Objective-C++ classes, not in Objective-C.  This
-  restriction was an undesirable short-term constraint arising from the
-  complexity of adding support for non-trivial struct types to C.
+:::{admonition} Rationale
+Permitting `__strong` and `__weak` references in aggregate types
+allows programmers to take advantage of the normal language tools of
+C and C++ while still automatically managing memory. While it is
+usually simpler and more idiomatic to use Objective-C objects for
+secondary data structures, doing so can introduce extra allocation
+and message-send overhead, which can cause unacceptable
+performance. Using structs can resolve some of this tension.
+
+`__autoreleasing` is forbidden because it is treacherous to rely
+on autoreleases as an ownership tool outside of a function-local
+contexts.
+
+Earlier releases of Clang permitted `__strong` and `__weak` only
+references in Objective-C++ classes, not in Objective-C. This
+restriction was an undesirable short-term constraint arising from the
+complexity of adding support for non-trivial struct types to C.
+:::
 
 In Objective-C++, nontrivially ownership-qualified types are treated
 for nearly all purposes as if they were class types with non-trivial
 default constructors, copy constructors, move constructors, copy assignment
-operators, move assignment operators, and destructors.  This includes the
+operators, move assignment operators, and destructors. This includes the
 determination of the triviality of special members of classes with a
 non-static data member of such a type.
 
 In Objective-C, the definition cannot be so succinct: because the C
 standard lacks rules for non-trivial types, those rules must first be
-developed.  They are given in the next section.  The intent is that these
+developed. They are given in the next section. The intent is that these
 rules are largely consistent with the rules of C++ for code expressible
 in both languages.
 
-Formal rules for non-trivial types in C
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+##### Formal rules for non-trivial types in C
 
 The following are base rules which can be added to C to support
 implementation-defined non-trivial types.
@@ -1165,11 +1141,9 @@ or *non-trivial to default-initialize* if:
 
 - it is a struct or union containing a member whose type is non-trivial
   to (respectively) copy, destroy, or default-initialize;
-
 - it is a qualified type whose unqualified type is non-trivial to
   (respectively) copy, destroy, or default-initialize (for at least
   the standard C qualifiers); or
-
 - it is an array type whose element type is non-trivial to (respectively)
   copy, destroy, or default-initialize.
 
@@ -1178,11 +1152,9 @@ A type in C is said to be *illegal to copy*, *illegal to destroy*, or
 
 - it is a union which contains a member whose type is either illegal
   or non-trivial to (respectively) copy, destroy, or initialize;
-
 - it is a qualified type whose unqualified type is illegal to
   (respectively) copy, destroy, or default-initialize (for at least
   the standard C qualifiers); or
-
 - it is an array type whose element type is illegal to (respectively)
   copy, destroy, or default-initialize.
 
@@ -1218,42 +1190,40 @@ destroyed, or default-initialized and that type is illegal to
 
 A program is ill-formed if it contains a function type specifier
 with a parameter or return type that is illegal to copy or
-destroy.  If a function type specifier would be ill-formed for this
+destroy. If a function type specifier would be ill-formed for this
 reason except that the parameter or return type was incomplete at
 that point in the translation unit, the program is ill-formed but
 no diagnostic is required.
 
-A ``goto`` or ``switch`` is ill-formed if it jumps into the scope of
+A `goto` or `switch` is ill-formed if it jumps into the scope of
 an object of automatic storage duration whose type is non-trivial to
 destroy.
 
 C specifies that it is generally undefined behavior to access an l-value
-if there is no object of that type at that location.  Implementations
+if there is no object of that type at that location. Implementations
 are often lenient about this, but non-trivial types generally require
-it to be enforced more strictly.  The following rules apply:
-
-The *static subobjects* of a type ``T`` at a location ``L`` are:
+it to be enforced more strictly. The following rules apply:
 
-  - an object of type ``T`` spanning from ``L`` to ``L + sizeof(T)``;
+The *static subobjects* of a type `T` at a location `L` are:
 
-  - if ``T`` is a struct type, then for each field ``f`` of that struct,
-    the static subobjects of ``T`` at location ``L + offsetof(T, .f)``; and
-
-  - if ``T`` is the array type ``E[N]``, then for each ``i`` satisfying
-    ``0 <= i < N``, the static subobjects of ``E`` at location
-    ``L + i * sizeof(E)``.
+> - an object of type `T` spanning from `L` to `L + sizeof(T)`;
+> - if `T` is a struct type, then for each field `f` of that struct,
+>   the static subobjects of `T` at location `L + offsetof(T, .f)`; and
+> - if `T` is the array type `E[N]`, then for each `i` satisfying
+>   `0 <= i < N`, the static subobjects of `E` at location
+>   `L + i * sizeof(E)`.
 
 If an l-value is converted to an r-value, then all static subobjects
-whose types are non-trivial to copy are accessed.  If an l-value is
+whose types are non-trivial to copy are accessed. If an l-value is
 assigned to, or if an object of automatic storage duration goes out of
 scope, then all static subobjects of types that are non-trivial to destroy
 are accessed.
 
 A dynamic object is created at a location if an initialization initializes
-an object of that type there.  A dynamic object ceases to exist at a
-location if the memory is repurposed.  Memory is repurposed if it is
+an object of that type there. A dynamic object ceases to exist at a
+location if the memory is repurposed. Memory is repurposed if it is
 freed or if a different dynamic object is created there, for example by
-assigning into a different union member.  An implementation may provide
+assigning into a different union member. An implementation may provide
 additional rules for what constitutes creating or destroying a dynamic
 object.
 
@@ -1263,55 +1233,53 @@ If memory for a location is repurposed while a dynamic object that is
 non-trivial to destroy exists at that location, the program has
 undefined behavior.
 
-.. admonition:: Rationale
-
-  While these rules are far less fine-grained than C++, they are
-  nonetheless sufficient to express a wide spectrum of types.
-  Types that express some sort of ownership will generally be non-trivial
-  to both copy and destroy and either non-trivial or illegal to
-  default-initialize.  Types that don't express ownership may still
-  be non-trivial to copy because of some sort of address sensitivity;
-  for example, a relative reference.  Distinguishing default
-  initialization allows types to impose policies about how they are
-  created.
-
-  These rules assume that assignment into an l-value is always a
-  modification of an existing object rather than an initialization.
-  Assignment is then a compound operation where the old value is
-  read and destroyed, if necessary, and the new value is put into
-  place.  These are the natural semantics of value propagation, where
-  all basic operations on the type come down to copies and destroys,
-  and everything else is just an optimization on top of those.
-
-  The most glaring weakness of programming with non-trivial types in C
-  is that there are no language mechanisms (akin to C++'s placement
-  ``new`` and explicit destructor calls) for explicitly creating and
-  destroying objects.  Clang should consider adding builtins for this
-  purpose, as well as for common optimizations like destructive
-  relocation.
-
-Application of the formal C rules to nontrivial ownership qualifiers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+:::{admonition} Rationale
+While these rules are far less fine-grained than C++, they are
+nonetheless sufficient to express a wide spectrum of types.
+Types that express some sort of ownership will generally be non-trivial
+to both copy and destroy and either non-trivial or illegal to
+default-initialize. Types that don't express ownership may still
+be non-trivial to copy because of some sort of address sensitivity;
+for example, a relative reference. Distinguishing default
+initialization allows types to impose policies about how they are
+created.
+
+These rules assume that assignment into an l-value is always a
+modification of an existing object rather than an initialization.
+Assignment is then a compound operation where the old value is
+read and destroyed, if necessary, and the new value is put into
+place. These are the natural semantics of value propagation, where
+all basic operations on the type come down to copies and destroys,
+and everything else is just an optimization on top of those.
+
+The most glaring weakness of programming with non-trivial types in C
+is that there are no language mechanisms (akin to C++'s placement
+`new` and explicit destructor calls) for explicitly creating and
+destroying objects. Clang should consider adding builtins for this
+purpose, as well as for common optimizations like destructive
+relocation.
+:::
+
+##### Application of the formal C rules to nontrivial ownership qualifiers
 
 Nontrivially ownership-qualified types are considered non-trivial
 to copy, destroy, and default-initialize.
 
 A dynamic object of nontrivially ownership-qualified type contingently
 exists at a location if the memory is filled with a zero pattern, e.g.
-by ``calloc`` or ``bzero``.  Such an object can be safely accessed in
+by `calloc` or `bzero`. Such an object can be safely accessed in
 all of the cases above, but its memory can also be safely repurposed.
-Assigning a null pointer into an l-value of ``__weak`` or
-``__strong``-qualified type accesses the dynamic object there (and thus
+Assigning a null pointer into an l-value of `__weak` or
+`__strong`-qualified type accesses the dynamic object there (and thus
 may have undefined behavior if no such object exists), but afterwards
 the object's memory is guaranteed to be filled with a zero pattern
 and thus may be either further accessed or repurposed as needed.
 The upshot is that programs may safely initialize dynamically-allocated
 memory for nontrivially ownership-qualified types by ensuring it is zero-initialized, and they may safely deinitialize memory before
-freeing it by storing ``nil`` into any ``__strong`` or ``__weak``
+freeing it by storing `nil` into any `__strong` or `__weak`
 references previously created in that memory.
 
-C/C++ compatibility for structs and unions with non-trivial members
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+##### C/C++ compatibility for structs and unions with non-trivial members
 
 Structs and unions with non-trivial members are compatible in
 different language modes (e.g. between Objective-C and Objective-C++,
@@ -1319,7 +1287,7 @@ or between ARC and non-ARC modes) under the following conditions:
 
 - The types must be compatible ignoring ownership qualifiers according
   to the baseline, non-ARC rules (e.g. C struct compatibility or C++'s
-  ODR).  This condition implies a pairwise correspondence between
+  ODR). This condition implies a pairwise correspondence between
   fields.
 
   Note that an Objective-C++ class with base classes, a user-provided
@@ -1329,358 +1297,349 @@ or between ARC and non-ARC modes) under the following conditions:
 - If two fields correspond as above, and at least one of the fields is
   ownership-qualified, then:
 
-    - the fields must be identically qualified, or else
-
-    - one type must be unqualified (and thus declared in a non-ARC mode),
-      and the other type must be qualified with ``__unsafe_unretained``
-      or ``__strong``.
+  > - the fields must be identically qualified, or else
+  > - one type must be unqualified (and thus declared in a non-ARC mode),
+  >   and the other type must be qualified with `__unsafe_unretained`
+  >   or `__strong`.
 
-  Note that ``__weak`` fields must always be declared ``__weak``  because
+  Note that `__weak` fields must always be declared `__weak` because
   of the need to pin those fields in memory and keep them properly
-  registered with the Objective-C runtime.  Non-ARC modes may still
-  declare fields ``__weak`` by enabling ``-fobjc-weak``.
+  registered with the Objective-C runtime. Non-ARC modes may still
+  declare fields `__weak` by enabling `-fobjc-weak`.
 
 These compatibility rules permit a function that takes a parameter
 of non-trivial struct type to be written in ARC and called from
-non-ARC or vice-versa.  The convention for this always transfers
-ownership of objects stored in ``__strong`` fields from the caller
-to the callee, just as for an ``ns_consumed`` argument.  Therefore,
+non-ARC or vice-versa. The convention for this always transfers
+ownership of objects stored in `__strong` fields from the caller
+to the callee, just as for an `ns_consumed` argument. Therefore,
 non-ARC callers must ensure that such fields are initialized to a +1
 reference, and non-ARC callees must balance that +1 by releasing the
 reference or transferring it as appropriate.
 
 Likewise, a function returning a non-trivial struct may be written in
-ARC and called from non-ARC or vice-versa.  The convention for this
-always transfers ownership of objects stored in ``__strong`` fields
+ARC and called from non-ARC or vice-versa. The convention for this
+always transfers ownership of objects stored in `__strong` fields
 from the callee to the caller, and so callees must initialize such
 fields with +1 references, and callers must balance that +1 by releasing
 or transferring them.
 
-Similar transfers of responsibility occur for ``__weak`` fields, but
-since both sides must use native ``__weak`` support to ensure
+Similar transfers of responsibility occur for `__weak` fields, but
+since both sides must use native `__weak` support to ensure
 calling convention compatibility, this transfer is always handled
 automatically by the compiler.
 
-.. admonition:: Rationale
-
-  In earlier releases, when non-trivial ownership was only permitted
-  on fields in Objective-C++, the ABI used for such classes was the
-  ordinary ABI for non-trivial C++ classes, which passes arguments and
-  returns indirectly and does not transfer responsibility for arguments.
-  When support for Objective-C structs was added, it was decided to
-  change to the current ABI for three reasons:
-
-  - It permits ARC / non-ARC compatibility for structs containing only
-    ``__strong`` references, as long as the non-ARC side is careful about
-    transferring ownership.
-
-  - It avoids unnecessary indirection for sufficiently small types that
-    the C ABI would prefer to pass in registers.
-
-  - Given that struct arguments must be produced at +1 to satisfy C's
-    semantics of initializing the local parameter variable, transferring
-    ownership of that copy to the callee is generally better for ARC
-    optimization, since otherwise there will be releases in the caller
-    that are much harder to pair with transfers in the callee.
-
-  Breaking compatibility with existing Objective-C++ structures was
-  considered an acceptable cost, as most Objective-C++ code does not have
-  binary-compatibility requirements.  Any existing code which cannot accept
-  this compatibility break, which is necessarily Objective-C++, should
-  force the use of the standard C++ ABI by declaring an empty (but
-  non-defaulted) destructor.
-
-.. _arc.ownership.inference:
-
-Ownership inference
--------------------
-
-.. _arc.ownership.inference.variables:
-
-Objects
-^^^^^^^
+:::{admonition} Rationale
+In earlier releases, when non-trivial ownership was only permitted
+on fields in Objective-C++, the ABI used for such classes was the
+ordinary ABI for non-trivial C++ classes, which passes arguments and
+returns indirectly and does not transfer responsibility for arguments.
+When support for Objective-C structs was added, it was decided to
+change to the current ABI for three reasons:
+
+- It permits ARC / non-ARC compatibility for structs containing only
+  `__strong` references, as long as the non-ARC side is careful about
+  transferring ownership.
+- It avoids unnecessary indirection for sufficiently small types that
+  the C ABI would prefer to pass in registers.
+- Given that struct arguments must be produced at +1 to satisfy C's
+  semantics of initializing the local parameter variable, transferring
+  ownership of that copy to the callee is generally better for ARC
+  optimization, since otherwise there will be releases in the caller
+  that are much harder to pair with transfers in the callee.
+
+Breaking compatibility with existing Objective-C++ structures was
+considered an acceptable cost, as most Objective-C++ code does not have
+binary-compatibility requirements. Any existing code which cannot accept
+this compatibility break, which is necessarily Objective-C++, should
+force the use of the standard C++ ABI by declaring an empty (but
+non-defaulted) destructor.
+:::
+
+(arc-ownership-inference)=
+
+### Ownership inference
+
+(arc-ownership-inference-variables)=
+
+#### Objects
 
 If an object is declared with retainable object owner type, but without an
 explicit ownership qualifier, its type is implicitly adjusted to have
-``__strong`` qualification.
+`__strong` qualification.
 
-As a special case, if the object's base type is ``Class`` (possibly
-protocol-qualified), the type is adjusted to have ``__unsafe_unretained``
+As a special case, if the object's base type is `Class` (possibly
+protocol-qualified), the type is adjusted to have `__unsafe_unretained`
 qualification instead.
 
-.. _arc.ownership.inference.indirect_parameters:
+(arc-ownership-inference-indirect-parameters)=
 
-Indirect parameters
-^^^^^^^^^^^^^^^^^^^
+#### Indirect parameters
 
-If a function or method parameter has type ``T*``, where ``T`` is an
+If a function or method parameter has type `T*`, where `T` is an
 ownership-unqualified retainable object pointer type, then:
 
-* if ``T`` is ``const``-qualified or ``Class``, then it is implicitly
-  qualified with ``__unsafe_unretained``;
-* otherwise, it is implicitly qualified with ``__autoreleasing``.
-
-.. admonition:: Rationale
+- if `T` is `const`-qualified or `Class`, then it is implicitly
+  qualified with `__unsafe_unretained`;
+- otherwise, it is implicitly qualified with `__autoreleasing`.
 
-  ``__autoreleasing`` exists mostly for this case, the Cocoa convention for
-  out-parameters.  Since a pointer to ``const`` is obviously not an
-  out-parameter, we instead use a type more useful for passing arrays.  If the
-  user instead intends to pass in a *mutable* array, inferring
-  ``__autoreleasing`` is the wrong thing to do; this directs some of the
-  caution in the following rules about writeback.
+:::{admonition} Rationale
+`__autoreleasing` exists mostly for this case, the Cocoa convention for
+out-parameters. Since a pointer to `const` is obviously not an
+out-parameter, we instead use a type more useful for passing arrays. If the
+user instead intends to pass in a *mutable* array, inferring
+`__autoreleasing` is the wrong thing to do; this directs some of the
+caution in the following rules about writeback.
+:::
 
 Such a type written anywhere else would be ill-formed by the general rule
 requiring ownership qualifiers.
 
 This rule does not apply in Objective-C++ if a parameter's type is dependent in
 a template pattern and is only *instantiated* to a type which would be a
-pointer to an unqualified retainable object pointer type.  Such code is still
+pointer to an unqualified retainable object pointer type. Such code is still
 ill-formed.
 
-.. admonition:: Rationale
+:::{admonition} Rationale
+The convention is very unlikely to be intentional in template code.
+:::
 
-  The convention is very unlikely to be intentional in template code.
+(arc-ownership-inference-template-arguments)=
 
-.. _arc.ownership.inference.template.arguments:
-
-Template arguments
-^^^^^^^^^^^^^^^^^^
+#### Template arguments
 
 If a template argument for a template type parameter is a retainable object
 owner type that does not have an explicit ownership qualifier, it is adjusted
-to have ``__strong`` qualification.  This adjustment occurs regardless of
+to have `__strong` qualification. This adjustment occurs regardless of
 whether the template argument was deduced or explicitly specified.
 
-.. admonition:: Rationale
-
-  ``__strong`` is a useful default for containers (e.g., ``std::vector<id>``),
-  which would otherwise require explicit qualification.  Moreover, unqualified
-  retainable object pointer types are unlikely to be useful within templates,
-  since they generally need to have a qualifier applied to the before being
-  used.
+:::{admonition} Rationale
+`__strong` is a useful default for containers (e.g., `std::vector<id>`),
+which would otherwise require explicit qualification. Moreover, unqualified
+retainable object pointer types are unlikely to be useful within templates,
+since they generally need to have a qualifier applied to the before being
+used.
+:::
 
-.. _arc.method-families:
+(arc-method-families)=
 
-Method families
-===============
+## Method families
 
-An Objective-C method may fall into a :arc-term:`method family`, which is a
+An Objective-C method may fall into a {arc-term}`method family`, which is a
 conventional set of behaviors ascribed to it by the Cocoa conventions.
 
 A method is in a certain method family if:
 
-* it has a ``objc_method_family`` attribute placing it in that family; or if
+- it has a `objc_method_family` attribute placing it in that family; or if
   not that,
-* it does not have an ``objc_method_family`` attribute placing it in a
+- it does not have an `objc_method_family` attribute placing it in a
   different or no family, and
-* its selector falls into the corresponding selector family, and
-* its signature obeys the added restrictions of the method family.
+- its selector falls into the corresponding selector family, and
+- its signature obeys the added restrictions of the method family.
 
 A selector is in a certain selector family if, ignoring any leading
 underscores, the first component of the selector either consists entirely of
 the name of the method family or it begins with that name followed by a
-character other than a lowercase letter.  For example, ``_perform:with:`` and
-``performWith:`` would fall into the ``perform`` family (if we recognized one),
-but ``performing:with`` would not.
+character other than a lowercase letter. For example, `_perform:with:` and
+`performWith:` would fall into the `perform` family (if we recognized one),
+but `performing:with` would not.
 
 The families and their added restrictions are:
 
-* ``alloc`` methods must return a retainable object pointer type.
-* ``copy`` methods must return a retainable object pointer type.
-* ``mutableCopy`` methods must return a retainable object pointer type.
-* ``new`` methods must return a retainable object pointer type.
-* ``init`` methods must be instance methods and must return an Objective-C
-  pointer type.  Additionally, a program is ill-formed if it declares or
-  contains a call to an ``init`` method whose return type is neither ``id`` nor
+- `alloc` methods must return a retainable object pointer type.
+
+- `copy` methods must return a retainable object pointer type.
+
+- `mutableCopy` methods must return a retainable object pointer type.
+
+- `new` methods must return a retainable object pointer type.
+
+- `init` methods must be instance methods and must return an Objective-C
+  pointer type. Additionally, a program is ill-formed if it declares or
+  contains a call to an `init` method whose return type is neither `id` nor
   a pointer to a super-class or sub-class of the declaring class (if the method
   was declared on a class) or the static receiver type of the call (if it was
   declared on a protocol).
 
-  .. admonition:: Rationale
-
-    There are a fair number of existing methods with ``init``-like selectors
-    which nonetheless don't follow the ``init`` conventions.  Typically these
-    are either accidental naming collisions or helper methods called during
-    initialization.  Because of the peculiar retain/release behavior of
-    ``init`` methods, it's very important not to treat these methods as
-    ``init`` methods if they aren't meant to be.  It was felt that implicitly
-    defining these methods out of the family based on the exact relationship
-    between the return type and the declaring class would be much too subtle
-    and fragile.  Therefore we identify a small number of legitimate-seeming
-    return types and call everything else an error.  This serves the secondary
-    purpose of encouraging programmers not to accidentally give methods names
-    in the ``init`` family.
-
-    Note that a method with an ``init``-family selector which returns a
-    non-Objective-C type (e.g. ``void``) is perfectly well-formed; it simply
-    isn't in the ``init`` family.
+  :::{admonition} Rationale
+  There are a fair number of existing methods with `init`-like selectors
+  which nonetheless don't follow the `init` conventions. Typically these
+  are either accidental naming collisions or helper methods called during
+  initialization. Because of the peculiar retain/release behavior of
+  `init` methods, it's very important not to treat these methods as
+  `init` methods if they aren't meant to be. It was felt that implicitly
+  defining these methods out of the family based on the exact relationship
+  between the return type and the declaring class would be much too subtle
+  and fragile. Therefore we identify a small number of legitimate-seeming
+  return types and call everything else an error. This serves the secondary
+  purpose of encouraging programmers not to accidentally give methods names
+  in the `init` family.
+
+  Note that a method with an `init`-family selector which returns a
+  non-Objective-C type (e.g. `void`) is perfectly well-formed; it simply
+  isn't in the `init` family.
+  :::
 
 A program is ill-formed if a method's declarations, implementations, and
 overrides do not all have the same method family.
 
-.. _arc.family.attribute:
+(arc-family-attribute)=
 
-Explicit method family control
-------------------------------
+### Explicit method family control
 
-A method may be annotated with the ``objc_method_family`` attribute to
-precisely control which method family it belongs to.  If a method in an
-``@implementation`` does not have this attribute, but there is a method
-declared in the corresponding ``@interface`` that does, then the attribute is
-copied to the declaration in the ``@implementation``.  The attribute is
+A method may be annotated with the `objc_method_family` attribute to
+precisely control which method family it belongs to. If a method in an
+`@implementation` does not have this attribute, but there is a method
+declared in the corresponding `@interface` that does, then the attribute is
+copied to the declaration in the `@implementation`. The attribute is
 available outside of ARC, and may be tested for with the preprocessor query
-``__has_attribute(objc_method_family)``.
+`__has_attribute(objc_method_family)`.
 
 The attribute is spelled
-``__attribute__((objc_method_family(`` *family* ``)))``.  If *family* is
-``none``, the method has no family, even if it would otherwise be considered to
-have one based on its selector and type.  Otherwise, *family* must be one of
-``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``, in which case the
+`__attribute__((objc_method_family(` *family* `)))`. If *family* is
+`none`, the method has no family, even if it would otherwise be considered to
+have one based on its selector and type. Otherwise, *family* must be one of
+`alloc`, `copy`, `init`, `mutableCopy`, or `new`, in which case the
 method is considered to belong to the corresponding family regardless of its
-selector.  It is an error if a method that is explicitly added to a family in
+selector. It is an error if a method that is explicitly added to a family in
 this way does not meet the requirements of the family other than the selector
 naming convention.
 
-.. admonition:: Rationale
-
-  The rules codified in this document describe the standard conventions of
-  Objective-C.  However, as these conventions have not heretofore been enforced
-  by an unforgiving mechanical system, they are only imperfectly kept,
-  especially as they haven't always even been precisely defined.  While it is
-  possible to define low-level ownership semantics with attributes like
-  ``ns_returns_retained``, this attribute allows the user to communicate
-  semantic intent, which is of use both to ARC (which, e.g., treats calls to
-  ``init`` specially) and the static analyzer.
+:::{admonition} Rationale
+The rules codified in this document describe the standard conventions of
+Objective-C. However, as these conventions have not heretofore been enforced
+by an unforgiving mechanical system, they are only imperfectly kept,
+especially as they haven't always even been precisely defined. While it is
+possible to define low-level ownership semantics with attributes like
+`ns_returns_retained`, this attribute allows the user to communicate
+semantic intent, which is of use both to ARC (which, e.g., treats calls to
+`init` specially) and the static analyzer.
+:::
 
-.. _arc.family.semantics:
+(arc-family-semantics)=
 
-Semantics of method families
-----------------------------
+### Semantics of method families
 
 A method's membership in a method family may imply non-standard semantics for
 its parameters and return type.
 
-Methods in the ``alloc``, ``copy``, ``mutableCopy``, and ``new`` families ---
-that is, methods in all the currently-defined families except ``init`` ---
-implicitly :ref:`return a retained object
+Methods in the `alloc`, `copy`, `mutableCopy`, and `new` families ---
+that is, methods in all the currently-defined families except `init` ---
+implicitly {ref}`return a retained object
 <arc.object.operands.retained-return-values>` as if they were annotated with
-the ``ns_returns_retained`` attribute.  This can be overridden by annotating
-the method with either of the ``ns_returns_autoreleased`` or
-``ns_returns_not_retained`` attributes.
-
-Properties also follow same naming rules as methods.  This means that those in
-the ``alloc``, ``copy``, ``mutableCopy``, and ``new`` families provide access
-to :ref:`retained objects <arc.object.operands.retained-return-values>`.  This
-can be overridden by annotating the property with ``ns_returns_not_retained``
+the `ns_returns_retained` attribute. This can be overridden by annotating
+the method with either of the `ns_returns_autoreleased` or
+`ns_returns_not_retained` attributes.
+
+Properties also follow same naming rules as methods. This means that those in
+the `alloc`, `copy`, `mutableCopy`, and `new` families provide access
+to {ref}`retained objects <arc.object.operands.retained-return-values>`. This
+can be overridden by annotating the property with `ns_returns_not_retained`
 attribute.
 
-.. _arc.family.semantics.init:
+(arc-family-semantics-init)=
 
-Semantics of ``init``
-^^^^^^^^^^^^^^^^^^^^^
+#### Semantics of `init`
 
-Methods in the ``init`` family implicitly :ref:`consume
-<arc.objects.operands.consumed>` their ``self`` parameter and :ref:`return a
-retained object <arc.object.operands.retained-return-values>`.  Neither of
+Methods in the `init` family implicitly {ref}`consume
+<arc.objects.operands.consumed>` their `self` parameter and {ref}`return a
+retained object <arc.object.operands.retained-return-values>`. Neither of
 these properties can be altered through attributes.
 
-A call to an ``init`` method with a receiver that is either ``self`` (possibly
-parenthesized or casted) or ``super`` is called a :arc-term:`delegate init
-call`.  It is an error for a delegate init call to be made except from an
-``init`` method, and excluding blocks within such methods.
+A call to an `init` method with a receiver that is either `self` (possibly
+parenthesized or casted) or `super` is called a {arc-term}`delegate init
+call`. It is an error for a delegate init call to be made except from an
+`init` method, and excluding blocks within such methods.
 
-As an exception to the :ref:`usual rule <arc.misc.self>`, the variable ``self``
-is mutable in an ``init`` method and has the usual semantics for a ``__strong``
-variable.  However, it is undefined behavior and the program is ill-formed, no
-diagnostic required, if an ``init`` method attempts to use the previous value
-of ``self`` after the completion of a delegate init call.  It is conventional,
-but not required, for an ``init`` method to return ``self``.
+As an exception to the {ref}`usual rule <arc.misc.self>`, the variable `self`
+is mutable in an `init` method and has the usual semantics for a `__strong`
+variable. However, it is undefined behavior and the program is ill-formed, no
+diagnostic required, if an `init` method attempts to use the previous value
+of `self` after the completion of a delegate init call. It is conventional,
+but not required, for an `init` method to return `self`.
 
-It is undefined behavior for a program to cause two or more calls to ``init``
-methods on the same object, except that each ``init`` method invocation may
+It is undefined behavior for a program to cause two or more calls to `init`
+methods on the same object, except that each `init` method invocation may
 perform at most one delegate init call.
 
-.. _arc.family.semantics.result_type:
+(arc-family-semantics-result-type)=
 
-Related result types
-^^^^^^^^^^^^^^^^^^^^
+#### Related result types
 
-Certain methods are candidates to have :arc-term:`related result types`:
+Certain methods are candidates to have {arc-term}`related result types`:
 
-* class methods in the ``alloc`` and ``new`` method families
-* instance methods in the ``init`` family
-* the instance method ``self``
-* outside of ARC, the instance methods ``retain`` and ``autorelease``
+- class methods in the `alloc` and `new` method families
+- instance methods in the `init` family
+- the instance method `self`
+- outside of ARC, the instance methods `retain` and `autorelease`
 
-If the formal result type of such a method is ``id`` or protocol-qualified
-``id``, or a type equal to the declaring class or a superclass, then it is said
-to have a related result type.  In this case, when invoked in an explicit
+If the formal result type of such a method is `id` or protocol-qualified
+`id`, or a type equal to the declaring class or a superclass, then it is said
+to have a related result type. In this case, when invoked in an explicit
 message send, it is assumed to return a type related to the type of the
 receiver:
 
-* if it is a class method, and the receiver is a class name ``T``, the message
-  send expression has type ``T*``; otherwise
-* if it is an instance method, and the receiver has type ``T``, the message
-  send expression has type ``T``; otherwise
-* the message send expression has the normal result type of the method.
+- if it is a class method, and the receiver is a class name `T`, the message
+  send expression has type `T*`; otherwise
+- if it is an instance method, and the receiver has type `T`, the message
+  send expression has type `T`; otherwise
+- the message send expression has the normal result type of the method.
 
 This is a new rule of the Objective-C language and applies outside of ARC.
 
-.. admonition:: Rationale
+:::{admonition} Rationale
+ARC's automatic code emission is more prone than most code to signature
+errors, i.e. errors where a call was emitted against one method signature,
+but the implementing method has an incompatible signature. Having more
+precise type information helps drastically lower this risk, as well as
+catching a number of latent bugs.
+:::
 
-  ARC's automatic code emission is more prone than most code to signature
-  errors, i.e. errors where a call was emitted against one method signature,
-  but the implementing method has an incompatible signature.  Having more
-  precise type information helps drastically lower this risk, as well as
-  catching a number of latent bugs.
+(arc-optimization)=
 
-.. _arc.optimization:
+## Optimization
 
-Optimization
-============
-
-Within this section, the word :arc-term:`function` will be used to
+Within this section, the word {arc-term}`function` will be used to
 refer to any structured unit of code, be it a C function, an
 Objective-C method, or a block.
 
-This specification describes ARC as performing specific ``retain`` and
-``release`` operations on retainable object pointers at specific
-points during the execution of a program.  These operations make up a
+This specification describes ARC as performing specific `retain` and
+`release` operations on retainable object pointers at specific
+points during the execution of a program. These operations make up a
 non-contiguous subsequence of the computation history of the program.
 The portion of this sequence for a particular retainable object
 pointer for which a specific function execution is directly
-responsible is the :arc-term:`formal local retain history` of the
-object pointer.  The corresponding actual sequence executed is the
+responsible is the {arc-term}`formal local retain history` of the
+object pointer. The corresponding actual sequence executed is the
 `dynamic local retain history`.
 
 However, under certain circumstances, ARC is permitted to re-order and
 eliminate operations in a manner which may alter the overall
 computation history beyond what is permitted by the general "as if"
-rule of C/C++ and the :ref:`restrictions <arc.objects.retains>` on
-the implementation of ``retain`` and ``release``.
-
-.. admonition:: Rationale
-
-  Specifically, ARC is sometimes permitted to optimize ``release``
-  operations in ways which might cause an object to be deallocated
-  before it would otherwise be.  Without this, it would be almost
-  impossible to eliminate any ``retain``/``release`` pairs.  For
-  example, consider the following code:
-
-  .. code-block:: objc
-
-    id x = _ivar;
-    [x foo];
-
-  If we were not permitted in any event to shorten the lifetime of the
-  object in ``x``, then we would not be able to eliminate this retain
-  and release unless we could prove that the message send could not
-  modify ``_ivar`` (or deallocate ``self``).  Since message sends are
-  opaque to the optimizer, this is not possible, and so ARC's hands
-  would be almost completely tied.
+rule of C/C++ and the {ref}`restrictions <arc.objects.retains>` on
+the implementation of `retain` and `release`.
+
+:::{admonition} Rationale
+Specifically, ARC is sometimes permitted to optimize `release`
+operations in ways which might cause an object to be deallocated
+before it would otherwise be. Without this, it would be almost
+impossible to eliminate any `retain`/`release` pairs. For
+example, consider the following code:
+
+```objc
+id x = _ivar;
+[x foo];
+```
+
+If we were not permitted in any event to shorten the lifetime of the
+object in `x`, then we would not be able to eliminate this retain
+and release unless we could prove that the message send could not
+modify `_ivar` (or deallocate `self`). Since message sends are
+opaque to the optimizer, this is not possible, and so ARC's hands
+would be almost completely tied.
+:::
 
 ARC makes no guarantees about the execution of a computation history
-which contains undefined behavior.  In particular, ARC makes no
+which contains undefined behavior. In particular, ARC makes no
 guarantees in the presence of race conditions.
 
 ARC may assume that any retainable object pointers it receives or
@@ -1690,985 +1649,947 @@ the generation of the pointer and happens-before a release of that
 object (possibly via an aliasing pointer or indirectly due to
 destruction of a different object).
 
-.. admonition:: Rationale
-
-  There is very little point in trying to guarantee correctness in the
-  presence of race conditions.  ARC does not have a stack-scanning
-  garbage collector, and guaranteeing the atomicity of every load and
-  store operation would be prohibitive and preclude a vast amount of
-  optimization.
+:::{admonition} Rationale
+There is very little point in trying to guarantee correctness in the
+presence of race conditions. ARC does not have a stack-scanning
+garbage collector, and guaranteeing the atomicity of every load and
+store operation would be prohibitive and preclude a vast amount of
+optimization.
+:::
 
 ARC may assume that non-ARC code engages in sensible balancing
 behavior and does not rely on exact or minimum retain count values
-except as guaranteed by ``__strong`` object invariants or +1 transfer
-conventions.  For example, if an object is provably double-retained
+except as guaranteed by `__strong` object invariants or +1 transfer
+conventions. For example, if an object is provably double-retained
 and double-released, ARC may eliminate the inner retain and release;
 it does not need to guard against code which performs an unbalanced
 release followed by a "balancing" retain.
 
-.. _arc.optimization.liveness:
-
-Object liveness
----------------
+(arc-optimization-liveness)=
 
-ARC may not allow a retainable object ``X`` to be deallocated at a
-time ``T`` in a computation history if:
+### Object liveness
 
-* ``X`` is the value stored in a ``__strong`` object ``S`` with
-  :ref:`precise lifetime semantics <arc.optimization.precise>`, or
+ARC may not allow a retainable object `X` to be deallocated at a
+time `T` in a computation history if:
 
-* ``X`` is the value stored in a ``__strong`` object ``S`` with
-  imprecise lifetime semantics and, at some point after ``T`` but
-  before the next store to ``S``, the computation history features a
-  load from ``S`` and in some way depends on the value loaded, or
-
-* ``X`` is a value described as being released at the end of the
-  current full-expression and, at some point after ``T`` but before
+- `X` is the value stored in a `__strong` object `S` with
+  {ref}`precise lifetime semantics <arc.optimization.precise>`, or
+- `X` is the value stored in a `__strong` object `S` with
+  imprecise lifetime semantics and, at some point after `T` but
+  before the next store to `S`, the computation history features a
+  load from `S` and in some way depends on the value loaded, or
+- `X` is a value described as being released at the end of the
+  current full-expression and, at some point after `T` but before
   the end of the full-expression, the computation history depends
   on that value.
 
-.. admonition:: Rationale
-
-  The intent of the second rule is to say that objects held in normal
-  ``__strong`` local variables may be released as soon as the value in
-  the variable is no longer being used: either the variable stops
-  being used completely or a new value is stored in the variable.
+:::{admonition} Rationale
+The intent of the second rule is to say that objects held in normal
+`__strong` local variables may be released as soon as the value in
+the variable is no longer being used: either the variable stops
+being used completely or a new value is stored in the variable.
 
-  The intent of the third rule is to say that return values may be
-  released after they've been used.
+The intent of the third rule is to say that return values may be
+released after they've been used.
+:::
 
-A computation history depends on a pointer value ``P`` if it:
+A computation history depends on a pointer value `P` if it:
 
-* performs a pointer comparison with ``P``,
-* loads from ``P``,
-* stores to ``P``,
-* depends on a pointer value ``Q`` derived via pointer arithmetic
-  from ``P`` (including an instance-variable or field access), or
-* depends on a pointer value ``Q`` loaded from ``P``.
+- performs a pointer comparison with `P`,
+- loads from `P`,
+- stores to `P`,
+- depends on a pointer value `Q` derived via pointer arithmetic
+  from `P` (including an instance-variable or field access), or
+- depends on a pointer value `Q` loaded from `P`.
 
 Dependency applies only to values derived directly or indirectly from
 a particular expression result and does not occur merely because a
-separate pointer value dynamically aliases ``P``.  Furthermore, this
+separate pointer value dynamically aliases `P`. Furthermore, this
 dependency is not carried by values that are stored to objects.
 
-.. admonition:: Rationale
-
-  The restrictions on dependency are intended to make this analysis
-  feasible by an optimizer with only incomplete information about a
-  program.  Essentially, dependence is carried to "obvious" uses of a
-  pointer.  Merely passing a pointer argument to a function does not
-  itself cause dependence, but since generally the optimizer will not
-  be able to prove that the function doesn't depend on that parameter,
-  it will be forced to conservatively assume it does.
-
-  Dependency propagates to values loaded from a pointer because those
-  values might be invalidated by deallocating the object.  For
-  example, given the code ``__strong id x = p->ivar;``, ARC must not
-  move the release of ``p`` to between the load of ``p->ivar`` and the
-  retain of that value for storing into ``x``.
-
-  Dependency does not propagate through stores of dependent pointer
-  values because doing so would allow dependency to outlive the
-  full-expression which produced the original value.  For example, the
-  address of an instance variable could be written to some global
-  location and then freely accessed during the lifetime of the local,
-  or a function could return an inner pointer of an object and store
-  it to a local.  These cases would be potentially impossible to
-  reason about and so would basically prevent any optimizations based
-  on imprecise lifetime.  There are also uncommon enough to make it
-  reasonable to require the precise-lifetime annotation if someone
-  really wants to rely on them.
-
-  Dependency does propagate through return values of pointer type.
-  The compelling source of need for this rule is a property accessor
-  which returns an un-autoreleased result; the calling function must
-  have the chance to operate on the value, e.g. to retain it, before
-  ARC releases the original pointer.  Note again, however, that
-  dependence does not survive a store, so ARC does not guarantee the
-  continued validity of the return value past the end of the
-  full-expression.
-
-.. _arc.optimization.object_lifetime:
-
-No object lifetime extension
-----------------------------
-
-If, in the formal computation history of the program, an object ``X``
+:::{admonition} Rationale
+The restrictions on dependency are intended to make this analysis
+feasible by an optimizer with only incomplete information about a
+program. Essentially, dependence is carried to "obvious" uses of a
+pointer. Merely passing a pointer argument to a function does not
+itself cause dependence, but since generally the optimizer will not
+be able to prove that the function doesn't depend on that parameter,
+it will be forced to conservatively assume it does.
+
+Dependency propagates to values loaded from a pointer because those
+values might be invalidated by deallocating the object. For
+example, given the code `__strong id x = p->ivar;`, ARC must not
+move the release of `p` to between the load of `p->ivar` and the
+retain of that value for storing into `x`.
+
+Dependency does not propagate through stores of dependent pointer
+values because doing so would allow dependency to outlive the
+full-expression which produced the original value. For example, the
+address of an instance variable could be written to some global
+location and then freely accessed during the lifetime of the local,
+or a function could return an inner pointer of an object and store
+it to a local. These cases would be potentially impossible to
+reason about and so would basically prevent any optimizations based
+on imprecise lifetime. There are also uncommon enough to make it
+reasonable to require the precise-lifetime annotation if someone
+really wants to rely on them.
+
+Dependency does propagate through return values of pointer type.
+The compelling source of need for this rule is a property accessor
+which returns an un-autoreleased result; the calling function must
+have the chance to operate on the value, e.g. to retain it, before
+ARC releases the original pointer. Note again, however, that
+dependence does not survive a store, so ARC does not guarantee the
+continued validity of the return value past the end of the
+full-expression.
+:::
+
+(arc-optimization-object-lifetime)=
+
+### No object lifetime extension
+
+If, in the formal computation history of the program, an object `X`
 has been deallocated by the time of an observable side-effect, then
-ARC must cause ``X`` to be deallocated by no later than the occurrence
+ARC must cause `X` to be deallocated by no later than the occurrence
 of that side-effect, except as influenced by the re-ordering of the
 destruction of objects.
 
-.. admonition:: Rationale
+:::{admonition} Rationale
+This rule is intended to prohibit ARC from observably extending the
+lifetime of a retainable object, other than as specified in this
+document. Together with the rule limiting the transformation of
+releases, this rule requires ARC to eliminate retains and release
+only in pairs.
 
-  This rule is intended to prohibit ARC from observably extending the
-  lifetime of a retainable object, other than as specified in this
-  document.  Together with the rule limiting the transformation of
-  releases, this rule requires ARC to eliminate retains and release
-  only in pairs.
+ARC's power to reorder the destruction of objects is critical to its
+ability to do any optimization, for essentially the same reason that
+it must retain the power to decrease the lifetime of an object.
+Unfortunately, while it's generally poor style for the destruction
+of objects to have arbitrary side-effects, it's certainly possible.
+Hence the caveat.
+:::
 
-  ARC's power to reorder the destruction of objects is critical to its
-  ability to do any optimization, for essentially the same reason that
-  it must retain the power to decrease the lifetime of an object.
-  Unfortunately, while it's generally poor style for the destruction
-  of objects to have arbitrary side-effects, it's certainly possible.
-  Hence the caveat.
+(arc-optimization-precise)=
 
-.. _arc.optimization.precise:
-
-Precise lifetime semantics
---------------------------
+### Precise lifetime semantics
 
 In general, ARC maintains an invariant that a retainable object pointer held in
-a ``__strong`` object will be retained for the full formal lifetime of the
-object.  Objects subject to this invariant have :arc-term:`precise lifetime
+a `__strong` object will be retained for the full formal lifetime of the
+object. Objects subject to this invariant have {arc-term}`precise lifetime
 semantics`.
 
 By default, local variables of automatic storage duration do not have precise
-lifetime semantics.  Such objects are simply strong references which hold
+lifetime semantics. Such objects are simply strong references which hold
 values of retainable object pointer type, and these values are still fully
 subject to the optimizations on values under local control.
 
-.. admonition:: Rationale
-
-  Applying these precise-lifetime semantics strictly would be prohibitive.
-  Many useful optimizations that might theoretically decrease the lifetime of
-  an object would be rendered impossible.  Essentially, it promises too much.
+:::{admonition} Rationale
+Applying these precise-lifetime semantics strictly would be prohibitive.
+Many useful optimizations that might theoretically decrease the lifetime of
+an object would be rendered impossible. Essentially, it promises too much.
+:::
 
 A local variable of retainable object owner type and automatic storage duration
-may be annotated with the ``objc_precise_lifetime`` attribute to indicate that
+may be annotated with the `objc_precise_lifetime` attribute to indicate that
 it should be considered to be an object with precise lifetime semantics.
 
-.. admonition:: Rationale
+:::{admonition} Rationale
+Nonetheless, it is sometimes useful to be able to force an object to be
+released at a precise time, even if that object does not appear to be used.
+This is likely to be uncommon enough that the syntactic weight of explicitly
+requesting these semantics will not be burdensome, and may even make the code
+clearer.
+:::
 
-  Nonetheless, it is sometimes useful to be able to force an object to be
-  released at a precise time, even if that object does not appear to be used.
-  This is likely to be uncommon enough that the syntactic weight of explicitly
-  requesting these semantics will not be burdensome, and may even make the code
-  clearer.
+(arc-misc)=
 
-.. _arc.misc:
+## Miscellaneous
 
-Miscellaneous
-=============
+(arc-misc-special-methods)=
 
-.. _arc.misc.special_methods:
+### Special methods
 
-Special methods
----------------
+(arc-misc-special-methods-retain)=
 
-.. _arc.misc.special_methods.retain:
-
-Memory management methods
-^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Memory management methods
 
 A program is ill-formed if it contains a method definition, message send, or
-``@selector`` expression for any of the following selectors:
-
-* ``autorelease``
-* ``release``
-* ``retain``
-* ``retainCount``
-
-.. admonition:: Rationale
-
-  ``retainCount`` is banned because ARC robs it of consistent semantics.  The
-  others were banned after weighing three options for how to deal with message
-  sends:
-
-  **Honoring** them would work out very poorly if a programmer naively or
-  accidentally tried to incorporate code written for manual retain/release code
-  into an ARC program.  At best, such code would do twice as much work as
-  necessary; quite frequently, however, ARC and the explicit code would both
-  try to balance the same retain, leading to crashes.  The cost is losing the
-  ability to perform "unrooted" retains, i.e. retains not logically
-  corresponding to a strong reference in the object graph.
-
-  **Ignoring** them would badly violate user expectations about their code.
-  While it *would* make it easier to develop code simultaneously for ARC and
-  non-ARC, there is very little reason to do so except for certain library
-  developers.  ARC and non-ARC translation units share an execution model and
-  can seamlessly interoperate.  Within a translation unit, a developer who
-  faithfully maintains their code in non-ARC mode is suffering all the
-  restrictions of ARC for zero benefit, while a developer who isn't testing the
-  non-ARC mode is likely to be unpleasantly surprised if they try to go back to
-  it.
-
-  **Banning** them has the disadvantage of making it very awkward to migrate
-  existing code to ARC.  The best answer to that, given a number of other
-  changes and restrictions in ARC, is to provide a specialized tool to assist
-  users in that migration.
-
-  Implementing these methods was banned because they are too integral to the
-  semantics of ARC; many tricks which worked tolerably under manual reference
-  counting will misbehave if ARC performs an ephemeral extra retain or two.  If
-  absolutely required, it is still possible to implement them in non-ARC code,
-  for example in a category; the implementations must obey the :ref:`semantics
-  <arc.objects.retains>` laid out elsewhere in this document.
-
-.. _arc.misc.special_methods.dealloc:
-
-``dealloc``
-^^^^^^^^^^^
-
-A program is ill-formed if it contains a message send or ``@selector``
-expression for the selector ``dealloc``.
-
-.. admonition:: Rationale
-
-  There are no legitimate reasons to call ``dealloc`` directly.
+`@selector` expression for any of the following selectors:
+
+- `autorelease`
+- `release`
+- `retain`
+- `retainCount`
+
+:::{admonition} Rationale
+`retainCount` is banned because ARC robs it of consistent semantics. The
+others were banned after weighing three options for how to deal with message
+sends:
+
+**Honoring** them would work out very poorly if a programmer naively or
+accidentally tried to incorporate code written for manual retain/release code
+into an ARC program. At best, such code would do twice as much work as
+necessary; quite frequently, however, ARC and the explicit code would both
+try to balance the same retain, leading to crashes. The cost is losing the
+ability to perform "unrooted" retains, i.e. retains not logically
+corresponding to a strong reference in the object graph.
+
+**Ignoring** them would badly violate user expectations about their code.
+While it *would* make it easier to develop code simultaneously for ARC and
+non-ARC, there is very little reason to do so except for certain library
+developers. ARC and non-ARC translation units share an execution model and
+can seamlessly interoperate. Within a translation unit, a developer who
+faithfully maintains their code in non-ARC mode is suffering all the
+restrictions of ARC for zero benefit, while a developer who isn't testing the
+non-ARC mode is likely to be unpleasantly surprised if they try to go back to
+it.
+
+**Banning** them has the disadvantage of making it very awkward to migrate
+existing code to ARC. The best answer to that, given a number of other
+changes and restrictions in ARC, is to provide a specialized tool to assist
+users in that migration.
+
+Implementing these methods was banned because they are too integral to the
+semantics of ARC; many tricks which worked tolerably under manual reference
+counting will misbehave if ARC performs an ephemeral extra retain or two. If
+absolutely required, it is still possible to implement them in non-ARC code,
+for example in a category; the implementations must obey the {ref}`semantics
+<arc.objects.retains>` laid out elsewhere in this document.
+:::
+
+(arc-misc-special-methods-dealloc)=
+
+#### `dealloc`
+
+A program is ill-formed if it contains a message send or `@selector`
+expression for the selector `dealloc`.
+
+:::{admonition} Rationale
+There are no legitimate reasons to call `dealloc` directly.
+:::
 
 A class may provide a method definition for an instance method named
-``dealloc``.  This method will be called after the final ``release`` of the
+`dealloc`. This method will be called after the final `release` of the
 object but before it is deallocated or any of its instance variables are
-destroyed.  The superclass's implementation of ``dealloc`` will be called
+destroyed. The superclass's implementation of `dealloc` will be called
 automatically when the method returns.
 
-.. admonition:: Rationale
-
-  Even though ARC destroys instance variables automatically, there are still
-  legitimate reasons to write a ``dealloc`` method, such as freeing
-  non-retainable resources.  Failing to call ``[super dealloc]`` in such a
-  method is nearly always a bug.  Sometimes, the object is simply trying to
-  prevent itself from being destroyed, but ``dealloc`` is really far too late
-  for the object to be raising such objections.  Somewhat more legitimately, an
-  object may have been pool-allocated and should not be deallocated with
-  ``free``; for now, this can only be supported with a ``dealloc``
-  implementation outside of ARC.  Such an implementation must be very careful
-  to do all the other work that ``NSObject``'s ``dealloc`` would, which is
-  outside the scope of this document to describe.
+:::{admonition} Rationale
+Even though ARC destroys instance variables automatically, there are still
+legitimate reasons to write a `dealloc` method, such as freeing
+non-retainable resources. Failing to call `[super dealloc]` in such a
+method is nearly always a bug. Sometimes, the object is simply trying to
+prevent itself from being destroyed, but `dealloc` is really far too late
+for the object to be raising such objections. Somewhat more legitimately, an
+object may have been pool-allocated and should not be deallocated with
+`free`; for now, this can only be supported with a `dealloc`
+implementation outside of ARC. Such an implementation must be very careful
+to do all the other work that `NSObject`'s `dealloc` would, which is
+outside the scope of this document to describe.
+:::
 
 The instance variables for an ARC-compiled class will be destroyed at some
-point after control enters the ``dealloc`` method for the root class of the
-class.  The ordering of the destruction of instance variables is unspecified,
+point after control enters the `dealloc` method for the root class of the
+class. The ordering of the destruction of instance variables is unspecified,
 both within a single class and between subclasses and superclasses.
 
-.. admonition:: Rationale
-
-  The traditional, non-ARC pattern for destroying instance variables is to
-  destroy them immediately before calling ``[super dealloc]``.  Unfortunately,
-  message sends from the superclass are quite capable of reaching methods in
-  the subclass, and those methods may well read or write to those instance
-  variables.  Making such message sends from dealloc is generally discouraged,
-  since the subclass may well rely on other invariants that were broken during
-  ``dealloc``, but it's not so inescapably dangerous that we felt comfortable
-  calling it undefined behavior.  Therefore we chose to delay destroying the
-  instance variables to a point at which message sends are clearly disallowed:
-  the point at which the root class's deallocation routines take over.
-
-  In most code, the difference is not observable.  It can, however, be observed
-  if an instance variable holds a strong reference to an object whose
-  deallocation will trigger a side-effect which must be carefully ordered with
-  respect to the destruction of the super class.  Such code violates the design
-  principle that semantically important behavior should be explicit.  A simple
-  fix is to clear the instance variable manually during ``dealloc``; a more
-  holistic solution is to move semantically important side-effects out of
-  ``dealloc`` and into a separate teardown phase which can rely on working with
-  well-formed objects.
-
-.. _arc.misc.autoreleasepool:
-
-``@autoreleasepool``
---------------------
+:::{admonition} Rationale
+The traditional, non-ARC pattern for destroying instance variables is to
+destroy them immediately before calling `[super dealloc]`. Unfortunately,
+message sends from the superclass are quite capable of reaching methods in
+the subclass, and those methods may well read or write to those instance
+variables. Making such message sends from dealloc is generally discouraged,
+since the subclass may well rely on other invariants that were broken during
+`dealloc`, but it's not so inescapably dangerous that we felt comfortable
+calling it undefined behavior. Therefore we chose to delay destroying the
+instance variables to a point at which message sends are clearly disallowed:
+the point at which the root class's deallocation routines take over.
+
+In most code, the difference is not observable. It can, however, be observed
+if an instance variable holds a strong reference to an object whose
+deallocation will trigger a side-effect which must be carefully ordered with
+respect to the destruction of the super class. Such code violates the design
+principle that semantically important behavior should be explicit. A simple
+fix is to clear the instance variable manually during `dealloc`; a more
+holistic solution is to move semantically important side-effects out of
+`dealloc` and into a separate teardown phase which can rely on working with
+well-formed objects.
+:::
+
+(arc-misc-autoreleasepool)=
+
+### `@autoreleasepool`
 
 To simplify the use of autorelease pools, and to bring them under the control
-of the compiler, a new kind of statement is available in Objective-C.  It is
-written ``@autoreleasepool`` followed by a *compound-statement*, i.e.  by a new
-scope delimited by curly braces.  Upon entry to this block, the current state
-of the autorelease pool is captured.  When the block is exited normally,
-whether by fallthrough or directed control flow (such as ``return`` or
-``break``), the autorelease pool is restored to the saved state, releasing all
-the objects in it.  When the block is exited with an exception, the pool is not
+of the compiler, a new kind of statement is available in Objective-C. It is
+written `@autoreleasepool` followed by a *compound-statement*, i.e. by a new
+scope delimited by curly braces. Upon entry to this block, the current state
+of the autorelease pool is captured. When the block is exited normally,
+whether by fallthrough or directed control flow (such as `return` or
+`break`), the autorelease pool is restored to the saved state, releasing all
+the objects in it. When the block is exited with an exception, the pool is not
 drained.
 
-``@autoreleasepool`` may be used in non-ARC translation units, with equivalent
+`@autoreleasepool` may be used in non-ARC translation units, with equivalent
 semantics.
 
-A program is ill-formed if it refers to the ``NSAutoreleasePool`` class.
-
-.. admonition:: Rationale
+A program is ill-formed if it refers to the `NSAutoreleasePool` class.
 
-  Autorelease pools are clearly important for the compiler to reason about, but
-  it is far too much to expect the compiler to accurately reason about control
-  dependencies between two calls.  It is also very easy to accidentally forget
-  to drain an autorelease pool when using the manual API, and this can
-  significantly inflate the process's high-water-mark.  The introduction of a
-  new scope is unfortunate but basically required for sane interaction with the
-  rest of the language.  Not draining the pool during an unwind is apparently
-  required by the Objective-C exceptions implementation.
+:::{admonition} Rationale
+Autorelease pools are clearly important for the compiler to reason about, but
+it is far too much to expect the compiler to accurately reason about control
+dependencies between two calls. It is also very easy to accidentally forget
+to drain an autorelease pool when using the manual API, and this can
+significantly inflate the process's high-water-mark. The introduction of a
+new scope is unfortunate but basically required for sane interaction with the
+rest of the language. Not draining the pool during an unwind is apparently
+required by the Objective-C exceptions implementation.
+:::
 
-.. _arc.misc.externally_retained:
+(arc-misc-externally-retained)=
 
-Externally-Retained Variables
------------------------------
+### Externally-Retained Variables
 
 In some situations, variables with strong ownership are considered
 externally-retained by the implementation. This means that the variable is
 retained elsewhere, and therefore the implementation can elide retaining and
-releasing its value. Such a variable is implicitly ``const`` for safety. In
-contrast with ``__unsafe_unretained``, an externally-retained variable still
+releasing its value. Such a variable is implicitly `const` for safety. In
+contrast with `__unsafe_unretained`, an externally-retained variable still
 behaves as a strong variable outside of initialization and destruction. For
 instance, when an externally-retained variable is captured in a block the value
 of the variable is retained and released on block capture and destruction. It
-also affects C++ features such as lambda capture, ``decltype``, and template
+also affects C++ features such as lambda capture, `decltype`, and template
 argument deduction.
 
-Implicitly, the implementation assumes that the :ref:`self parameter in a
-non-init method <arc.misc.self>` and the :ref:`variable in a for-in loop
+Implicitly, the implementation assumes that the {ref}`self parameter in a
+non-init method <arc.misc.self>` and the {ref}`variable in a for-in loop
 <arc.misc.enumeration>` are externally-retained.
 
 Externally-retained semantics can also be opted into with the
-``objc_externally_retained`` attribute. This attribute can apply to strong local
+`objc_externally_retained` attribute. This attribute can apply to strong local
 variables, functions, methods, or blocks:
 
-.. code-block:: objc
+```objc
+ at class WobbleAmount;
 
-  @class WobbleAmount;
+ at interface Widget : NSObject
+-(void)wobble:(WobbleAmount *)amount;
+ at end
 
-  @interface Widget : NSObject
-  -(void)wobble:(WobbleAmount *)amount;
-  @end
+ at implementation Widget
 
-  @implementation Widget
-
-  -(void)wobble:(WobbleAmount *)amount
-           __attribute__((objc_externally_retained)) {
-    // 'amount' and 'alias' aren't retained on entry, nor released on exit.
-    __attribute__((objc_externally_retained)) WobbleAmount *alias = amount;
-  }
-  @end
+-(void)wobble:(WobbleAmount *)amount
+         __attribute__((objc_externally_retained)) {
+  // 'amount' and 'alias' aren't retained on entry, nor released on exit.
+  __attribute__((objc_externally_retained)) WobbleAmount *alias = amount;
+}
+ at end
+```
 
 Annotating a function with this attribute makes every parameter with strong
 retainable object pointer type externally-retained, unless the variable was
-explicitly qualified with ``__strong``. For instance, ``first_param`` is
-externally-retained (and therefore ``const``) below, but not ``second_param``:
+explicitly qualified with `__strong`. For instance, `first_param` is
+externally-retained (and therefore `const`) below, but not `second_param`:
 
-.. code-block:: objc
-
-  __attribute__((objc_externally_retained))
-  void f(NSArray *first_param, __strong NSArray *second_param) {
-    // ...
-  }
+```objc
+__attribute__((objc_externally_retained))
+void f(NSArray *first_param, __strong NSArray *second_param) {
+  // ...
+}
+```
 
-You can test if your compiler has support for ``objc_externally_retained`` with
-``__has_attribute``:
+You can test if your compiler has support for `objc_externally_retained` with
+`__has_attribute`:
 
-.. code-block:: objc
+```objc
+#if __has_attribute(objc_externally_retained)
+// Use externally retained...
+#endif
+```
 
-  #if __has_attribute(objc_externally_retained)
-  // Use externally retained...
-  #endif
+(arc-misc-self)=
 
-.. _arc.misc.self:
+### `self`
 
-``self``
---------
-
-The ``self`` parameter variable of a non-init Objective-C method is considered
-:ref:`externally-retained <arc.misc.externally_retained>` by the implementation.
+The `self` parameter variable of a non-init Objective-C method is considered
+{ref}`externally-retained <arc.misc.externally_retained>` by the implementation.
 It is undefined behavior, or at least dangerous, to cause an object to be
-deallocated during a message send to that object.  In an init method, ``self``
-follows the :ref:``init family rules <arc.family.semantics.init>``.
-
-.. admonition:: Rationale
-
-  The cost of retaining ``self`` in all methods was found to be prohibitive, as
-  it tends to be live across calls, preventing the optimizer from proving that
-  the retain and release are unnecessary --- for good reason, as it's quite
-  possible in theory to cause an object to be deallocated during its execution
-  without this retain and release.  Since it's extremely uncommon to actually
-  do so, even unintentionally, and since there's no natural way for the
-  programmer to remove this retain/release pair otherwise (as there is for
-  other parameters by, say, making the variable ``objc_externally_retained`` or
-  qualifying it with ``__unsafe_unretained``), we chose to make this optimizing
-  assumption and shift some amount of risk to the user.
-
-.. _arc.misc.enumeration:
-
-Fast enumeration iteration variables
-------------------------------------
+deallocated during a message send to that object. In an init method, `self`
+follows the :ref:`init family rules <arc.family.semantics.init>`.
+
+:::{admonition} Rationale
+The cost of retaining `self` in all methods was found to be prohibitive, as
+it tends to be live across calls, preventing the optimizer from proving that
+the retain and release are unnecessary --- for good reason, as it's quite
+possible in theory to cause an object to be deallocated during its execution
+without this retain and release. Since it's extremely uncommon to actually
+do so, even unintentionally, and since there's no natural way for the
+programmer to remove this retain/release pair otherwise (as there is for
+other parameters by, say, making the variable `objc_externally_retained` or
+qualifying it with `__unsafe_unretained`), we chose to make this optimizing
+assumption and shift some amount of risk to the user.
+:::
+
+(arc-misc-enumeration)=
+
+### Fast enumeration iteration variables
 
 If a variable is declared in the condition of an Objective-C fast enumeration
 loop, and the variable has no explicit ownership qualifier, then it is
-implicitly :ref:`externally-retained <arc.misc.externally_retained>` so that
+implicitly {ref}`externally-retained <arc.misc.externally_retained>` so that
 objects encountered during the enumeration are not actually retained and
 released.
 
-.. admonition:: Rationale
+:::{admonition} Rationale
+This is an optimization made possible because fast enumeration loops promise
+to keep the objects retained during enumeration, and the collection itself
+cannot be synchronously modified. It can be overridden by explicitly
+qualifying the variable with `__strong`, which will make the variable
+mutable again and cause the loop to retain the objects it encounters.
+:::
 
-  This is an optimization made possible because fast enumeration loops promise
-  to keep the objects retained during enumeration, and the collection itself
-  cannot be synchronously modified.  It can be overridden by explicitly
-  qualifying the variable with ``__strong``, which will make the variable
-  mutable again and cause the loop to retain the objects it encounters.
+(arc-misc-blocks)=
 
-.. _arc.misc.blocks:
+### Blocks
 
-Blocks
-------
-
-The implicit ``const`` capture variables created when evaluating a block
+The implicit `const` capture variables created when evaluating a block
 literal expression have the same ownership semantics as the local variables
-they capture.  The capture is performed by reading from the captured variable
+they capture. The capture is performed by reading from the captured variable
 and initializing the capture variable with that value; the capture variable is
 destroyed when the block literal is, i.e. at the end of the enclosing scope.
 
-The :ref:`inference <arc.ownership.inference>` rules apply equally to
-``__block`` variables, which is a shift in semantics from non-ARC, where
-``__block`` variables did not implicitly retain during capture.
+The {ref}`inference <arc.ownership.inference>` rules apply equally to
+`__block` variables, which is a shift in semantics from non-ARC, where
+`__block` variables did not implicitly retain during capture.
 
-``__block`` variables of retainable object owner type are moved off the stack
+`__block` variables of retainable object owner type are moved off the stack
 by initializing the heap copy with the result of moving from the stack copy.
 
-With the exception of retains done as part of initializing a ``__strong``
-parameter variable or reading a ``__weak`` variable, whenever these semantics
+With the exception of retains done as part of initializing a `__strong`
+parameter variable or reading a `__weak` variable, whenever these semantics
 call for retaining a value of block-pointer type, it has the effect of a
-``Block_copy``.  The optimizer may remove such copies when it sees that the
+`Block_copy`. The optimizer may remove such copies when it sees that the
 result is used only as an argument to a call.
 
 When a block pointer type is converted to a non-block pointer type (such as
-``id``), ``Block_copy`` is called. This is necessary because a block allocated
+`id`), `Block_copy` is called. This is necessary because a block allocated
 on the stack won't get copied to the heap when the non-block pointer escapes.
-A block pointer is implicitly converted to ``id`` when it is passed to a
+A block pointer is implicitly converted to `id` when it is passed to a
 function as a variadic argument.
 
-.. _arc.misc.exceptions:
+(arc-misc-exceptions)=
 
-Exceptions
-----------
+### Exceptions
 
 By default in Objective C, ARC is not exception-safe for normal releases:
 
-* It does not end the lifetime of ``__strong`` variables when their scopes are
+- It does not end the lifetime of `__strong` variables when their scopes are
   abnormally terminated by an exception.
-* It does not perform releases which would occur at the end of a
+- It does not perform releases which would occur at the end of a
   full-expression if that full-expression throws an exception.
 
-A program may be compiled with the option ``-fobjc-arc-exceptions`` in order to
-enable these, or with the option ``-fno-objc-arc-exceptions`` to explicitly
+A program may be compiled with the option `-fobjc-arc-exceptions` in order to
+enable these, or with the option `-fno-objc-arc-exceptions` to explicitly
 disable them, with the last such argument "winning".
 
-.. admonition:: Rationale
-
-  The standard Cocoa convention is that exceptions signal programmer error and
-  are not intended to be recovered from.  Making code exceptions-safe by
-  default would impose severe runtime and code size penalties on code that
-  typically does not actually care about exceptions safety.  Therefore,
-  ARC-generated code leaks by default on exceptions, which is just fine if the
-  process is going to be immediately terminated anyway.  Programs which do care
-  about recovering from exceptions should enable the option.
-
-In Objective-C++, ``-fobjc-arc-exceptions`` is enabled by default.
-
-.. admonition:: Rationale
-
-  C++ already introduces pervasive exceptions-cleanup code of the sort that ARC
-  introduces.  C++ programmers who have not already disabled exceptions are
-  much more likely to actual require exception-safety.
-
-ARC does end the lifetimes of ``__weak`` objects when an exception terminates
+:::{admonition} Rationale
+The standard Cocoa convention is that exceptions signal programmer error and
+are not intended to be recovered from. Making code exceptions-safe by
+default would impose severe runtime and code size penalties on code that
+typically does not actually care about exceptions safety. Therefore,
+ARC-generated code leaks by default on exceptions, which is just fine if the
+process is going to be immediately terminated anyway. Programs which do care
+about recovering from exceptions should enable the option.
+:::
+
+In Objective-C++, `-fobjc-arc-exceptions` is enabled by default.
+
+:::{admonition} Rationale
+C++ already introduces pervasive exceptions-cleanup code of the sort that ARC
+introduces. C++ programmers who have not already disabled exceptions are
+much more likely to actual require exception-safety.
+:::
+
+ARC does end the lifetimes of `__weak` objects when an exception terminates
 their scope unless exceptions are disabled in the compiler.
 
-.. admonition:: Rationale
+:::{admonition} Rationale
+The consequence of a local `__weak` object not being destroyed is very
+likely to be corruption of the Objective-C runtime, so we want to be safer
+here. Of course, potentially massive leaks are about as likely to take down
+the process as this corruption is if the program does try to recover from
+exceptions.
+:::
 
-  The consequence of a local ``__weak`` object not being destroyed is very
-  likely to be corruption of the Objective-C runtime, so we want to be safer
-  here.  Of course, potentially massive leaks are about as likely to take down
-  the process as this corruption is if the program does try to recover from
-  exceptions.
+(arc-misc-interior)=
 
-.. _arc.misc.interior:
-
-Interior pointers
------------------
+### Interior pointers
 
 An Objective-C method returning a non-retainable pointer may be annotated with
-the ``objc_returns_inner_pointer`` attribute to indicate that it returns a
+the `objc_returns_inner_pointer` attribute to indicate that it returns a
 handle to the internal data of an object, and that this reference will be
-invalidated if the object is destroyed.  When such a message is sent to an
+invalidated if the object is destroyed. When such a message is sent to an
 object, the object's lifetime will be extended until at least the earliest of:
 
-* the last use of the returned pointer, or any pointer derived from it, in the
+- the last use of the returned pointer, or any pointer derived from it, in the
   calling function or
-* the autorelease pool is restored to a previous state.
-
-.. admonition:: Rationale
-
-  Rationale: not all memory and resources are managed with reference counts; it
-  is common for objects to manage private resources in their own, private way.
-  Typically these resources are completely encapsulated within the object, but
-  some classes offer their users direct access for efficiency.  If ARC is not
-  aware of methods that return such "interior" pointers, its optimizations can
-  cause the owning object to be reclaimed too soon.  This attribute informs ARC
-  that it must tread lightly.
-
-  The extension rules are somewhat intentionally vague.  The autorelease pool
-  limit is there to permit a simple implementation to simply retain and
-  autorelease the receiver.  The other limit permits some amount of
-  optimization.  The phrase "derived from" is intended to encompass the results
-  both of pointer transformations, such as casts and arithmetic, and of loading
-  from such derived pointers; furthermore, it applies whether or not such
-  derivations are applied directly in the calling code or by other utility code
-  (for example, the C library routine ``strchr``).  However, the implementation
-  never need account for uses after a return from the code which calls the
-  method returning an interior pointer.
+- the autorelease pool is restored to a previous state.
+
+:::{admonition} Rationale
+Rationale: not all memory and resources are managed with reference counts; it
+is common for objects to manage private resources in their own, private way.
+Typically these resources are completely encapsulated within the object, but
+some classes offer their users direct access for efficiency. If ARC is not
+aware of methods that return such "interior" pointers, its optimizations can
+cause the owning object to be reclaimed too soon. This attribute informs ARC
+that it must tread lightly.
+
+The extension rules are somewhat intentionally vague. The autorelease pool
+limit is there to permit a simple implementation to simply retain and
+autorelease the receiver. The other limit permits some amount of
+optimization. The phrase "derived from" is intended to encompass the results
+both of pointer transformations, such as casts and arithmetic, and of loading
+from such derived pointers; furthermore, it applies whether or not such
+derivations are applied directly in the calling code or by other utility code
+(for example, the C library routine `strchr`). However, the implementation
+never need account for uses after a return from the code which calls the
+method returning an interior pointer.
+:::
 
 As an exception, no extension is required if the receiver is loaded directly
-from a ``__strong`` object with :ref:`precise lifetime semantics
+from a `__strong` object with {ref}`precise lifetime semantics
 <arc.optimization.precise>`.
 
-.. admonition:: Rationale
-
-  Implicit autoreleases carry the risk of significantly inflating memory use,
-  so it's important to provide users a way of avoiding these autoreleases.
-  Tying this to precise lifetime semantics is ideal, as for local variables
-  this requires a very explicit annotation, which allows ARC to trust the user
-  with good cheer.
+:::{admonition} Rationale
+Implicit autoreleases carry the risk of significantly inflating memory use,
+so it's important to provide users a way of avoiding these autoreleases.
+Tying this to precise lifetime semantics is ideal, as for local variables
+this requires a very explicit annotation, which allows ARC to trust the user
+with good cheer.
+:::
 
-.. _arc.misc.c-retainable:
+(arc-misc-c-retainable)=
 
-C retainable pointer types
---------------------------
+### C retainable pointer types
 
-A type is a :arc-term:`C retainable pointer type` if it is a pointer to
-(possibly qualified) ``void`` or a pointer to a (possibly qualifier) ``struct``
-or ``class`` type.
+A type is a {arc-term}`C retainable pointer type` if it is a pointer to
+(possibly qualified) `void` or a pointer to a (possibly qualifier) `struct`
+or `class` type.
 
-.. admonition:: Rationale
+:::{admonition} Rationale
+ARC does not manage pointers of CoreFoundation type (or any of the related
+families of retainable C pointers which interoperate with Objective-C for
+retain/release operation). In fact, ARC does not even know how to
+distinguish these types from arbitrary C pointer types. The intent of this
+concept is to filter out some obviously non-object types while leaving a hook
+for later tightening if a means of exhaustively marking CF types is made
+available.
+:::
 
-  ARC does not manage pointers of CoreFoundation type (or any of the related
-  families of retainable C pointers which interoperate with Objective-C for
-  retain/release operation).  In fact, ARC does not even know how to
-  distinguish these types from arbitrary C pointer types.  The intent of this
-  concept is to filter out some obviously non-object types while leaving a hook
-  for later tightening if a means of exhaustively marking CF types is made
-  available.
+(arc-misc-c-retainable-audit)=
 
-.. _arc.misc.c-retainable.audit:
+#### Auditing of C retainable pointer interfaces
 
-Auditing of C retainable pointer interfaces
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+{when-revised}`[beginning Apple 4.0, LLVM 3.1]`
 
-:when-revised:`[beginning Apple 4.0, LLVM 3.1]`
-
-A C function may be marked with the ``cf_audited_transfer`` attribute to
+A C function may be marked with the `cf_audited_transfer` attribute to
 express that, except as otherwise marked with attributes, it obeys the
 parameter (consuming vs. non-consuming) and return (retained vs. non-retained)
 conventions for a C function of its name, namely:
 
-* A parameter of C retainable pointer type is assumed to not be consumed
-  unless it is marked with the ``cf_consumed`` attribute, and
-* A result of C retainable pointer type is assumed to not be returned retained
-  unless the function is either marked ``cf_returns_retained`` or it follows
+- A parameter of C retainable pointer type is assumed to not be consumed
+  unless it is marked with the `cf_consumed` attribute, and
+- A result of C retainable pointer type is assumed to not be returned retained
+  unless the function is either marked `cf_returns_retained` or it follows
   the create/copy naming convention and is not marked
-  ``cf_returns_not_retained``.
+  `cf_returns_not_retained`.
 
-A function obeys the :arc-term:`create/copy` naming convention if its name
+A function obeys the {arc-term}`create/copy` naming convention if its name
 contains as a substring:
 
-* either "Create" or "Copy" not followed by a lowercase letter, or
-* either "create" or "copy" not followed by a lowercase letter and
+- either "Create" or "Copy" not followed by a lowercase letter, or
+- either "create" or "copy" not followed by a lowercase letter and
   not preceded by any letter, whether uppercase or lowercase.
 
-A second attribute, ``cf_unknown_transfer``, signifies that a function's
+A second attribute, `cf_unknown_transfer`, signifies that a function's
 transfer semantics cannot be accurately captured using any of these
-annotations.  A program is ill-formed if it annotates the same function with
-both ``cf_audited_transfer`` and ``cf_unknown_transfer``.
+annotations. A program is ill-formed if it annotates the same function with
+both `cf_audited_transfer` and `cf_unknown_transfer`.
 
 A pragma is provided to facilitate the mass annotation of interfaces:
 
-.. code-block:: objc
-
-  #pragma clang arc_cf_code_audited begin
-  ...
-  #pragma clang arc_cf_code_audited end
+```objc
+#pragma clang arc_cf_code_audited begin
+...
+#pragma clang arc_cf_code_audited end
+```
 
 All C functions declared within the extent of this pragma are treated as if
-annotated with the ``cf_audited_transfer`` attribute unless they otherwise have
-the ``cf_unknown_transfer`` attribute.  The pragma is accepted in all language
-modes.  A program is ill-formed if it attempts to change files, whether by
+annotated with the `cf_audited_transfer` attribute unless they otherwise have
+the `cf_unknown_transfer` attribute. The pragma is accepted in all language
+modes. A program is ill-formed if it attempts to change files, whether by
 including a file or ending the current file, within the extent of this pragma.
 
 It is possible to test for all the features in this section with
-``__has_feature(arc_cf_code_audited)``.
+`__has_feature(arc_cf_code_audited)`.
 
-.. admonition:: Rationale
+:::{admonition} Rationale
+A significant inconvenience in ARC programming is the necessity of
+interacting with APIs based around C retainable pointers. These features are
+designed to make it relatively easy for API authors to quickly review and
+annotate their interfaces, in turn improving the fidelity of tools such as
+the static analyzer and ARC. The single-file restriction on the pragma is
+designed to eliminate the risk of accidentally annotating some other header's
+interfaces.
+:::
 
-  A significant inconvenience in ARC programming is the necessity of
-  interacting with APIs based around C retainable pointers.  These features are
-  designed to make it relatively easy for API authors to quickly review and
-  annotate their interfaces, in turn improving the fidelity of tools such as
-  the static analyzer and ARC.  The single-file restriction on the pragma is
-  designed to eliminate the risk of accidentally annotating some other header's
-  interfaces.
+(arc-runtime)=
 
-.. _arc.runtime:
-
-Runtime support
-===============
+## Runtime support
 
 This section describes the interaction between the ARC runtime and the code
-generated by the ARC compiler.  This is not part of the ARC language
+generated by the ARC compiler. This is not part of the ARC language
 specification; instead, it is effectively a language-specific ABI supplement,
 akin to the "Itanium" generic ABI for C++.
 
 Ownership qualification does not alter the storage requirements for objects,
-except that it is undefined behavior if a ``__weak`` object is inadequately
-aligned for an object of type ``id``.  The other qualifiers may be used on
+except that it is undefined behavior if a `__weak` object is inadequately
+aligned for an object of type `id`. The other qualifiers may be used on
 explicitly under-aligned memory.
 
-The runtime tracks ``__weak`` objects which holds non-null values.  It is
-undefined behavior to directly modify a ``__weak`` object which is being tracked
+The runtime tracks `__weak` objects which holds non-null values. It is
+undefined behavior to directly modify a `__weak` object which is being tracked
 by the runtime except through an
-:ref:`objc_storeWeak <arc.runtime.objc_storeWeak>`,
-:ref:`objc_destroyWeak <arc.runtime.objc_destroyWeak>`, or
-:ref:`objc_moveWeak <arc.runtime.objc_moveWeak>` call.
+{ref}`objc_storeWeak <arc.runtime.objc_storeWeak>`,
+{ref}`objc_destroyWeak <arc.runtime.objc_destroyWeak>`, or
+{ref}`objc_moveWeak <arc.runtime.objc_moveWeak>` call.
 
 The runtime must provide a number of new entrypoints which the compiler may
 emit, which are described in the remainder of this section.
 
-.. admonition:: Rationale
-
-  Several of these functions are semantically equivalent to a message send; we
-  emit calls to C functions instead because:
+:::{admonition} Rationale
+Several of these functions are semantically equivalent to a message send; we
+emit calls to C functions instead because:
 
-  * the machine code to do so is significantly smaller,
-  * it is much easier to recognize the C functions in the ARC optimizer, and
-  * a sufficiently sophisticated runtime may be able to avoid the message send in
-    common cases.
+- the machine code to do so is significantly smaller,
+- it is much easier to recognize the C functions in the ARC optimizer, and
+- a sufficiently sophisticated runtime may be able to avoid the message send in
+  common cases.
 
-  Several other of these functions are "fused" operations which can be
-  described entirely in terms of other operations.  We use the fused operations
-  primarily as a code-size optimization, although in some cases there is also a
-  real potential for avoiding redundant operations in the runtime.
+Several other of these functions are "fused" operations which can be
+described entirely in terms of other operations. We use the fused operations
+primarily as a code-size optimization, although in some cases there is also a
+real potential for avoiding redundant operations in the runtime.
+:::
 
-.. _arc.runtime.objc_autorelease:
+(arc-runtime-objc-autorelease)=
 
-``id objc_autorelease(id value);``
-----------------------------------
+### `id objc_autorelease(id value);`
 
-*Precondition:* ``value`` is null or a pointer to a valid object.
+*Precondition:* `value` is null or a pointer to a valid object.
 
-If ``value`` is null, this call has no effect.  Otherwise, it adds the object
+If `value` is null, this call has no effect. Otherwise, it adds the object
 to the innermost autorelease pool exactly as if the object had been sent the
-``autorelease`` message.
+`autorelease` message.
 
-Always returns ``value``.
+Always returns `value`.
 
-.. _arc.runtime.objc_autoreleasePoolPop:
+(arc-runtime-objc-autoreleasepoolpop)=
 
-``void objc_autoreleasePoolPop(void *pool);``
----------------------------------------------
+### `void objc_autoreleasePoolPop(void *pool);`
 
-*Precondition:* ``pool`` is the result of a previous call to
-:ref:`objc_autoreleasePoolPush <arc.runtime.objc_autoreleasePoolPush>` on the
-current thread, where neither ``pool`` nor any enclosing pool have previously
+*Precondition:* `pool` is the result of a previous call to
+{ref}`objc_autoreleasePoolPush <arc.runtime.objc_autoreleasePoolPush>` on the
+current thread, where neither `pool` nor any enclosing pool have previously
 been popped.
 
 Releases all the objects added to the given autorelease pool and any
 autorelease pools it encloses, then sets the current autorelease pool to the
-pool directly enclosing ``pool``.
+pool directly enclosing `pool`.
 
-.. _arc.runtime.objc_autoreleasePoolPush:
+(arc-runtime-objc-autoreleasepoolpush)=
 
-``void *objc_autoreleasePoolPush(void);``
------------------------------------------
+### `void *objc_autoreleasePoolPush(void);`
 
 Creates a new autorelease pool that is enclosed by the current pool, makes that
 the current pool, and returns an opaque "handle" to it.
 
-.. admonition:: Rationale
+:::{admonition} Rationale
+While the interface is described as an explicit hierarchy of pools, the rules
+allow the implementation to just keep a stack of objects, using the stack
+depth as the opaque pool handle.
+:::
 
-  While the interface is described as an explicit hierarchy of pools, the rules
-  allow the implementation to just keep a stack of objects, using the stack
-  depth as the opaque pool handle.
+(arc-runtime-objc-autoreleasereturnvalue)=
 
-.. _arc.runtime.objc_autoreleaseReturnValue:
+### `id objc_autoreleaseReturnValue(id value);`
 
-``id objc_autoreleaseReturnValue(id value);``
----------------------------------------------
+*Precondition:* `value` is null or a pointer to a valid object.
 
-*Precondition:* ``value`` is null or a pointer to a valid object.
-
-If ``value`` is null, this call has no effect.  Otherwise, it makes a best
+If `value` is null, this call has no effect. Otherwise, it makes a best
 effort to hand off ownership of a retain count on the object to a call to
-:ref:`objc_retainAutoreleasedReturnValue
+{ref}`objc_retainAutoreleasedReturnValue
 <arc.runtime.objc_retainAutoreleasedReturnValue>` (or
-:ref:`objc_unsafeClaimAutoreleasedReturnValue
+{ref}`objc_unsafeClaimAutoreleasedReturnValue
 <arc.runtime.objc_unsafeClaimAutoreleasedReturnValue>`) for the same object in
-an enclosing call frame.  If this is not possible, the object is autoreleased as
+an enclosing call frame. If this is not possible, the object is autoreleased as
 above.
 
-Always returns ``value``.
-
-.. _arc.runtime.objc_copyWeak:
+Always returns `value`.
 
-``void objc_copyWeak(id *dest, id *src);``
-------------------------------------------
+(arc-runtime-objc-copyweak)=
 
-*Precondition:* ``src`` is a valid pointer which either contains a null pointer
-or has been registered as a ``__weak`` object.  ``dest`` is a valid pointer
-which has not been registered as a ``__weak`` object.
+### `void objc_copyWeak(id *dest, id *src);`
 
-``dest`` is initialized to be equivalent to ``src``, potentially registering it
-with the runtime.  Equivalent to the following code:
+*Precondition:* `src` is a valid pointer which either contains a null pointer
+or has been registered as a `__weak` object. `dest` is a valid pointer
+which has not been registered as a `__weak` object.
 
-.. code-block:: objc
-
-  void objc_copyWeak(id *dest, id *src) {
-    objc_release(objc_initWeak(dest, objc_loadWeakRetained(src)));
-  }
+`dest` is initialized to be equivalent to `src`, potentially registering it
+with the runtime. Equivalent to the following code:
 
-Must be atomic with respect to calls to ``objc_storeWeak`` on ``src``.
+```objc
+void objc_copyWeak(id *dest, id *src) {
+  objc_release(objc_initWeak(dest, objc_loadWeakRetained(src)));
+}
+```
 
-.. _arc.runtime.objc_destroyWeak:
+Must be atomic with respect to calls to `objc_storeWeak` on `src`.
 
-``void objc_destroyWeak(id *object);``
---------------------------------------
+(arc-runtime-objc-destroyweak)=
 
-*Precondition:* ``object`` is a valid pointer which either contains a null
-pointer or has been registered as a ``__weak`` object.
+### `void objc_destroyWeak(id *object);`
 
-``object`` is unregistered as a weak object, if it ever was.  The current value
-of ``object`` is left unspecified; otherwise, equivalent to the following code:
+*Precondition:* `object` is a valid pointer which either contains a null
+pointer or has been registered as a `__weak` object.
 
-.. code-block:: objc
+`object` is unregistered as a weak object, if it ever was. The current value
+of `object` is left unspecified; otherwise, equivalent to the following code:
 
-  void objc_destroyWeak(id *object) {
-    objc_storeWeak(object, nil);
-  }
+```objc
+void objc_destroyWeak(id *object) {
+  objc_storeWeak(object, nil);
+}
+```
 
-Does not need to be atomic with respect to calls to ``objc_storeWeak`` on
-``object``.
+Does not need to be atomic with respect to calls to `objc_storeWeak` on
+`object`.
 
-.. _arc.runtime.objc_initWeak:
+(arc-runtime-objc-initweak)=
 
-``id objc_initWeak(id *object, id value);``
--------------------------------------------
+### `id objc_initWeak(id *object, id value);`
 
-*Precondition:* ``object`` is a valid pointer which has not been registered as
-a ``__weak`` object.  ``value`` is null or a pointer to a valid object.
+*Precondition:* `object` is a valid pointer which has not been registered as
+a `__weak` object. `value` is null or a pointer to a valid object.
 
-If ``value`` is a null pointer or the object to which it points has begun
-deallocation, ``object`` is zero-initialized.  Otherwise, ``object`` is
-registered as a ``__weak`` object pointing to ``value``.  Equivalent to the
+If `value` is a null pointer or the object to which it points has begun
+deallocation, `object` is zero-initialized. Otherwise, `object` is
+registered as a `__weak` object pointing to `value`. Equivalent to the
 following code:
 
-.. code-block:: objc
-
-  id objc_initWeak(id *object, id value) {
-    *object = nil;
-    return objc_storeWeak(object, value);
-  }
+```objc
+id objc_initWeak(id *object, id value) {
+  *object = nil;
+  return objc_storeWeak(object, value);
+}
+```
 
-Returns the value of ``object`` after the call.
+Returns the value of `object` after the call.
 
-Does not need to be atomic with respect to calls to ``objc_storeWeak`` on
-``object``.
+Does not need to be atomic with respect to calls to `objc_storeWeak` on
+`object`.
 
-.. _arc.runtime.objc_loadWeak:
+(arc-runtime-objc-loadweak)=
 
-``id objc_loadWeak(id *object);``
----------------------------------
+### `id objc_loadWeak(id *object);`
 
-*Precondition:* ``object`` is a valid pointer which either contains a null
-pointer or has been registered as a ``__weak`` object.
+*Precondition:* `object` is a valid pointer which either contains a null
+pointer or has been registered as a `__weak` object.
 
-If ``object`` is registered as a ``__weak`` object, and the last value stored
-into ``object`` has not yet been deallocated or begun deallocation, retains and
-autoreleases that value and returns it.  Otherwise returns null.  Equivalent to
+If `object` is registered as a `__weak` object, and the last value stored
+into `object` has not yet been deallocated or begun deallocation, retains and
+autoreleases that value and returns it. Otherwise returns null. Equivalent to
 the following code:
 
-.. code-block:: objc
-
-  id objc_loadWeak(id *object) {
-    return objc_autorelease(objc_loadWeakRetained(object));
-  }
-
-Must be atomic with respect to calls to ``objc_storeWeak`` on ``object``.
+```objc
+id objc_loadWeak(id *object) {
+  return objc_autorelease(objc_loadWeakRetained(object));
+}
+```
 
-.. admonition:: Rationale
+Must be atomic with respect to calls to `objc_storeWeak` on `object`.
 
-  Loading weak references would be inherently prone to race conditions without
-  the retain.
+:::{admonition} Rationale
+Loading weak references would be inherently prone to race conditions without
+the retain.
+:::
 
-.. _arc.runtime.objc_loadWeakRetained:
+(arc-runtime-objc-loadweakretained)=
 
-``id objc_loadWeakRetained(id *object);``
------------------------------------------
+### `id objc_loadWeakRetained(id *object);`
 
-*Precondition:* ``object`` is a valid pointer which either contains a null
-pointer or has been registered as a ``__weak`` object.
+*Precondition:* `object` is a valid pointer which either contains a null
+pointer or has been registered as a `__weak` object.
 
-If ``object`` is registered as a ``__weak`` object, and the last value stored
-into ``object`` has not yet been deallocated or begun deallocation, retains
-that value and returns it.  Otherwise returns null.
+If `object` is registered as a `__weak` object, and the last value stored
+into `object` has not yet been deallocated or begun deallocation, retains
+that value and returns it. Otherwise returns null.
 
-Must be atomic with respect to calls to ``objc_storeWeak`` on ``object``.
+Must be atomic with respect to calls to `objc_storeWeak` on `object`.
 
-.. _arc.runtime.objc_moveWeak:
+(arc-runtime-objc-moveweak)=
 
-``void objc_moveWeak(id *dest, id *src);``
-------------------------------------------
+### `void objc_moveWeak(id *dest, id *src);`
 
-*Precondition:* ``src`` is a valid pointer which either contains a null pointer
-or has been registered as a ``__weak`` object.  ``dest`` is a valid pointer
-which has not been registered as a ``__weak`` object.
+*Precondition:* `src` is a valid pointer which either contains a null pointer
+or has been registered as a `__weak` object. `dest` is a valid pointer
+which has not been registered as a `__weak` object.
 
-``dest`` is initialized to be equivalent to ``src``, potentially registering it
-with the runtime.  ``src`` may then be left in its original state, in which
-case this call is equivalent to :ref:`objc_copyWeak
+`dest` is initialized to be equivalent to `src`, potentially registering it
+with the runtime. `src` may then be left in its original state, in which
+case this call is equivalent to {ref}`objc_copyWeak
 <arc.runtime.objc_copyWeak>`, or it may be left as null.
 
-Must be atomic with respect to calls to ``objc_storeWeak`` on ``src``.
+Must be atomic with respect to calls to `objc_storeWeak` on `src`.
 
-.. _arc.runtime.objc_release:
+(arc-runtime-objc-release)=
 
-``void objc_release(id value);``
---------------------------------
+### `void objc_release(id value);`
 
-*Precondition:* ``value`` is null or a pointer to a valid object.
+*Precondition:* `value` is null or a pointer to a valid object.
 
-If ``value`` is null, this call has no effect.  Otherwise, it performs a
-release operation exactly as if the object had been sent the ``release``
+If `value` is null, this call has no effect. Otherwise, it performs a
+release operation exactly as if the object had been sent the `release`
 message.
 
-.. _arc.runtime.objc_retain:
+(arc-runtime-objc-retain)=
 
-``id objc_retain(id value);``
------------------------------
+### `id objc_retain(id value);`
 
-*Precondition:* ``value`` is null or a pointer to a valid object.
+*Precondition:* `value` is null or a pointer to a valid object.
 
-If ``value`` is null, this call has no effect.  Otherwise, it performs a retain
-operation exactly as if the object had been sent the ``retain`` message.
+If `value` is null, this call has no effect. Otherwise, it performs a retain
+operation exactly as if the object had been sent the `retain` message.
 
-Always returns ``value``.
+Always returns `value`.
 
-.. _arc.runtime.objc_retainAutorelease:
+(arc-runtime-objc-retainautorelease)=
 
-``id objc_retainAutorelease(id value);``
-----------------------------------------
+### `id objc_retainAutorelease(id value);`
 
-*Precondition:* ``value`` is null or a pointer to a valid object.
+*Precondition:* `value` is null or a pointer to a valid object.
 
-If ``value`` is null, this call has no effect.  Otherwise, it performs a retain
-operation followed by an autorelease operation.  Equivalent to the following
+If `value` is null, this call has no effect. Otherwise, it performs a retain
+operation followed by an autorelease operation. Equivalent to the following
 code:
 
-.. code-block:: objc
-
-  id objc_retainAutorelease(id value) {
-    return objc_autorelease(objc_retain(value));
-  }
+```objc
+id objc_retainAutorelease(id value) {
+  return objc_autorelease(objc_retain(value));
+}
+```
 
-Always returns ``value``.
+Always returns `value`.
 
-.. _arc.runtime.objc_retainAutoreleaseReturnValue:
+(arc-runtime-objc-retainautoreleasereturnvalue)=
 
-``id objc_retainAutoreleaseReturnValue(id value);``
----------------------------------------------------
+### `id objc_retainAutoreleaseReturnValue(id value);`
 
-*Precondition:* ``value`` is null or a pointer to a valid object.
+*Precondition:* `value` is null or a pointer to a valid object.
 
-If ``value`` is null, this call has no effect.  Otherwise, it performs a retain
+If `value` is null, this call has no effect. Otherwise, it performs a retain
 operation followed by the operation described in
-:ref:`objc_autoreleaseReturnValue <arc.runtime.objc_autoreleaseReturnValue>`.
+{ref}`objc_autoreleaseReturnValue <arc.runtime.objc_autoreleaseReturnValue>`.
 Equivalent to the following code:
 
-.. code-block:: objc
+```objc
+id objc_retainAutoreleaseReturnValue(id value) {
+  return objc_autoreleaseReturnValue(objc_retain(value));
+}
+```
 
-  id objc_retainAutoreleaseReturnValue(id value) {
-    return objc_autoreleaseReturnValue(objc_retain(value));
-  }
-
-Always returns ``value``.
+Always returns `value`.
 
-.. _arc.runtime.objc_retainAutoreleasedReturnValue:
+(arc-runtime-objc-retainautoreleasedreturnvalue)=
 
-``id objc_retainAutoreleasedReturnValue(id value);``
-----------------------------------------------------
+### `id objc_retainAutoreleasedReturnValue(id value);`
 
-*Precondition:* ``value`` is null or a pointer to a valid object.
+*Precondition:* `value` is null or a pointer to a valid object.
 
-If ``value`` is null, this call has no effect.  Otherwise, it attempts to
+If `value` is null, this call has no effect. Otherwise, it attempts to
 accept a hand off of a retain count from a call to
-:ref:`objc_autoreleaseReturnValue <arc.runtime.objc_autoreleaseReturnValue>` on
-``value`` in a recently-called function or something it tail-calls.  If that
-fails, it performs a retain operation exactly like :ref:`objc_retain
+{ref}`objc_autoreleaseReturnValue <arc.runtime.objc_autoreleaseReturnValue>` on
+`value` in a recently-called function or something it tail-calls. If that
+fails, it performs a retain operation exactly like {ref}`objc_retain
 <arc.runtime.objc_retain>`.
 
-Always returns ``value``.
+Always returns `value`.
 
-.. _arc.runtime.objc_retainBlock:
+(arc-runtime-objc-retainblock)=
 
-``id objc_retainBlock(id value);``
-----------------------------------
+### `id objc_retainBlock(id value);`
 
-*Precondition:* ``value`` is null or a pointer to a valid block object.
+*Precondition:* `value` is null or a pointer to a valid block object.
 
-If ``value`` is null, this call has no effect.  Otherwise, if the block pointed
-to by ``value`` is still on the stack, it is copied to the heap and the address
-of the copy is returned.  Otherwise a retain operation is performed on the
-block exactly as if it had been sent the ``retain`` message.
+If `value` is null, this call has no effect. Otherwise, if the block pointed
+to by `value` is still on the stack, it is copied to the heap and the address
+of the copy is returned. Otherwise a retain operation is performed on the
+block exactly as if it had been sent the `retain` message.
 
-.. _arc.runtime.objc_storeStrong:
+(arc-runtime-objc-storestrong)=
 
-``void objc_storeStrong(id *object, id value);``
-------------------------------------------------
+### `void objc_storeStrong(id *object, id value);`
 
-*Precondition:* ``object`` is a valid pointer to a ``__strong`` object which is
-adequately aligned for a pointer.  ``value`` is null or a pointer to a valid
+*Precondition:* `object` is a valid pointer to a `__strong` object which is
+adequately aligned for a pointer. `value` is null or a pointer to a valid
 object.
 
-Performs the complete sequence for assigning to a ``__strong`` object of
-non-block type [*]_.  Equivalent to the following code:
+Performs the complete sequence for assigning to a `__strong` object of
+non-block type [^footnote-1]. Equivalent to the following code:
 
-.. code-block:: objc
-
-  void objc_storeStrong(id *object, id value) {
-    id oldValue = *object;
-    value = [value retain];
-    *object = value;
-    [oldValue release];
-  }
+```objc
+void objc_storeStrong(id *object, id value) {
+  id oldValue = *object;
+  value = [value retain];
+  *object = value;
+  [oldValue release];
+}
+```
 
-.. [*] This does not imply that a ``__strong`` object of block type is an
-   invalid argument to this function. Rather it implies that an ``objc_retain``
-   and not an ``objc_retainBlock`` operation will be emitted if the argument is
-   a block.
+[^footnote-1]: This does not imply that a `__strong` object of block type is an
+    invalid argument to this function. Rather it implies that an `objc_retain`
+    and not an `objc_retainBlock` operation will be emitted if the argument is
+    a block.
 
-.. _arc.runtime.objc_storeWeak:
+(arc-runtime-objc-storeweak)=
 
-``id objc_storeWeak(id *object, id value);``
---------------------------------------------
+### `id objc_storeWeak(id *object, id value);`
 
-*Precondition:* ``object`` is a valid pointer which either contains a null
-pointer or has been registered as a ``__weak`` object.  ``value`` is null or a
+*Precondition:* `object` is a valid pointer which either contains a null
+pointer or has been registered as a `__weak` object. `value` is null or a
 pointer to a valid object.
 
-If ``value`` is a null pointer or the object to which it points has begun
-deallocation, ``object`` is assigned null and unregistered as a ``__weak``
-object.  Otherwise, ``object`` is registered as a ``__weak`` object or has its
-registration updated to point to ``value``.
+If `value` is a null pointer or the object to which it points has begun
+deallocation, `object` is assigned null and unregistered as a `__weak`
+object. Otherwise, `object` is registered as a `__weak` object or has its
+registration updated to point to `value`.
 
-Returns the value of ``object`` after the call.
+Returns the value of `object` after the call.
 
-.. _arc.runtime.objc_unsafeClaimAutoreleasedReturnValue:
+(arc-runtime-objc-unsafeclaimautoreleasedreturnvalue)=
 
-``id objc_unsafeClaimAutoreleasedReturnValue(id value);``
----------------------------------------------------------
+### `id objc_unsafeClaimAutoreleasedReturnValue(id value);`
 
-*Precondition:* ``value`` is null or a pointer to a valid object.
+*Precondition:* `value` is null or a pointer to a valid object.
 
-If ``value`` is null, this call has no effect.  Otherwise, it attempts to
+If `value` is null, this call has no effect. Otherwise, it attempts to
 accept a hand off of a retain count from a call to
-:ref:`objc_autoreleaseReturnValue <arc.runtime.objc_autoreleaseReturnValue>` on
-``value`` in a recently-called function or something it tail-calls (in a manner
-similar to :ref:`objc_retainAutoreleasedReturnValue
-<arc.runtime.objc_retainAutoreleasedReturnValue>`).  If that succeeds,
-it performs a release operation exactly like :ref:`objc_release
-<arc.runtime.objc_release>`.  If the handoff fails, this call has no effect.
-
-Always returns ``value``.
+{ref}`objc_autoreleaseReturnValue <arc.runtime.objc_autoreleaseReturnValue>` on
+`value` in a recently-called function or something it tail-calls (in a manner
+similar to {ref}`objc_retainAutoreleasedReturnValue
+<arc.runtime.objc_retainAutoreleasedReturnValue>`). If that succeeds,
+it performs a release operation exactly like {ref}`objc_release
+<arc.runtime.objc_release>`. If the handoff fails, this call has no effect.
+
+Always returns `value`.
 
diff --git a/clang/docs/Block-ABI-Apple.md b/clang/docs/Block-ABI-Apple.md
index c577e43b171b5..b46ea99f34ab9 100644
--- a/clang/docs/Block-ABI-Apple.md
+++ b/clang/docs/Block-ABI-Apple.md
@@ -1,25 +1,23 @@
-==================================
-Block Implementation Specification
-==================================
-
-.. contents::
-   :local:
-
-History
-=======
-
-* 2008/7/14 - created.
-* 2008/8/21 - revised, C++.
-* 2008/9/24 - add ``NULL`` ``isa`` field to ``__block`` storage.
-* 2008/10/1 - revise block layout to use a ``static`` descriptor structure.
-* 2008/10/6 - revise block layout to use an unsigned long int flags.
-* 2008/10/28 - specify use of ``_Block_object_assign`` and
-  ``_Block_object_dispose`` for all "Object" types in helper functions.
-* 2008/10/30 - revise new layout to have invoke function in same place.
-* 2008/10/30 - add ``__weak`` support.
-* 2010/3/16 - rev for stret return, signature field.
-* 2010/4/6 - improved wording.
-* 2013/1/6 - improved wording and converted to rst.
+# Block Implementation Specification
+
+```{contents}
+:local: true
+```
+
+## History
+
+- 2008/7/14 - created.
+- 2008/8/21 - revised, C++.
+- 2008/9/24 - add `NULL` `isa` field to `__block` storage.
+- 2008/10/1 - revise block layout to use a `static` descriptor structure.
+- 2008/10/6 - revise block layout to use an unsigned long int flags.
+- 2008/10/28 - specify use of `_Block_object_assign` and
+  `_Block_object_dispose` for all "Object" types in helper functions.
+- 2008/10/30 - revise new layout to have invoke function in same place.
+- 2008/10/30 - add `__weak` support.
+- 2010/3/16 - rev for stret return, signature field.
+- 2010/4/6 - improved wording.
+- 2013/1/6 - improved wording and converted to rst.
 
 This document describes the Apple ABI implementation specification of Blocks.
 
@@ -31,898 +29,876 @@ to as ABI.2010.3.16.
 Since the Apple ABI references symbols from other elements of the system, any
 attempt to use this ABI on systems prior to SnowLeopard is undefined.
 
-High Level
-==========
+## High Level
 
-The ABI of ``Blocks`` consists of their layout and the runtime functions required
-by the compiler.  A ``Block`` of type ``R (^)(P...)`` consists of a structure of
+The ABI of `Blocks` consists of their layout and the runtime functions required
+by the compiler. A `Block` of type `R (^)(P...)` consists of a structure of
 the following form:
 
-.. code-block:: c
-
-    struct Block_literal_1 {
-        void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
-        int flags;
-        int reserved;
-        R (*invoke)(struct Block_literal_1 *, P...);
-        struct Block_descriptor_1 {
-            unsigned long int reserved;     // NULL
-            unsigned long int size;         // sizeof(struct Block_literal_1)
-            // optional helper functions
-            void (*copy_helper)(void *dst, void *src);     // IFF (1<<25)
-            void (*dispose_helper)(void *src);             // IFF (1<<25)
-            // required ABI.2010.3.16
-            const char *signature;                         // IFF (1<<30)
-        } *descriptor;
-        // imported variables
-    };
+```c
+struct Block_literal_1 {
+    void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
+    int flags;
+    int reserved;
+    R (*invoke)(struct Block_literal_1 *, P...);
+    struct Block_descriptor_1 {
+        unsigned long int reserved;     // NULL
+        unsigned long int size;         // sizeof(struct Block_literal_1)
+        // optional helper functions
+        void (*copy_helper)(void *dst, void *src);     // IFF (1<<25)
+        void (*dispose_helper)(void *src);             // IFF (1<<25)
+        // required ABI.2010.3.16
+        const char *signature;                         // IFF (1<<30)
+    } *descriptor;
+    // imported variables
+};
+```
 
 The following flags bits are in use thusly for a possible ABI.2010.3.16:
 
-.. code-block:: c
-
-    enum {
-        // Set to true on blocks that have captures (and thus are not true
-        // global blocks) but are known not to escape for various other
-        // reasons. For backward compatibility with old runtimes, whenever
-        // BLOCK_IS_NOESCAPE is set, BLOCK_IS_GLOBAL is set too. Copying a
-        // non-escaping block returns the original block and releasing such a
-        // block is a no-op, which is exactly how global blocks are handled.
-        BLOCK_IS_NOESCAPE      =  (1 << 23),
-
-        BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
-        BLOCK_HAS_CTOR =          (1 << 26), // helpers have C++ code
-        BLOCK_IS_GLOBAL =         (1 << 28),
-        BLOCK_HAS_STRET =         (1 << 29), // IFF BLOCK_HAS_SIGNATURE
-        BLOCK_HAS_SIGNATURE =     (1 << 30),
-    };
-
-In 10.6.ABI the (1<<29) was usually set and was always ignored by the runtime -
+```c
+enum {
+    // Set to true on blocks that have captures (and thus are not true
+    // global blocks) but are known not to escape for various other
+    // reasons. For backward compatibility with old runtimes, whenever
+    // BLOCK_IS_NOESCAPE is set, BLOCK_IS_GLOBAL is set too. Copying a
+    // non-escaping block returns the original block and releasing such a
+    // block is a no-op, which is exactly how global blocks are handled.
+    BLOCK_IS_NOESCAPE      =  (1 << 23),
+
+    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+    BLOCK_HAS_CTOR =          (1 << 26), // helpers have C++ code
+    BLOCK_IS_GLOBAL =         (1 << 28),
+    BLOCK_HAS_STRET =         (1 << 29), // IFF BLOCK_HAS_SIGNATURE
+    BLOCK_HAS_SIGNATURE =     (1 << 30),
+};
+```
+
+In 10.6.ABI the (1\<<29) was usually set and was always ignored by the runtime -
 it had been a transitional marker that did not get deleted after the
-transition. This bit is now paired with (1<<30), and represented as the pair
-(3<<29), for the following combinations of valid bit settings, and their
+transition. This bit is now paired with (1\<<30), and represented as the pair
+(3\<<29), for the following combinations of valid bit settings, and their
 meanings:
 
-.. code-block:: c
-
-    switch (flags & (3<<29)) {
-      case (0<<29):      10.6.ABI, no signature field available
-      case (1<<29):      10.6.ABI, no signature field available
-      case (2<<29): ABI.2010.3.16, regular calling convention, presence of signature field
-      case (3<<29): ABI.2010.3.16, stret calling convention, presence of signature field,
-    }
+```c
+switch (flags & (3<<29)) {
+  case (0<<29):      10.6.ABI, no signature field available
+  case (1<<29):      10.6.ABI, no signature field available
+  case (2<<29): ABI.2010.3.16, regular calling convention, presence of signature field
+  case (3<<29): ABI.2010.3.16, stret calling convention, presence of signature field,
+}
+```
 
 The signature field is not always populated.
 
 The following discussions are presented as 10.6.ABI otherwise.
 
-``Block`` literals may occur within functions where the structure is created in
-stack local memory.  They may also appear as initialization expressions for
-``Block`` variables of global or ``static`` local variables.
+`Block` literals may occur within functions where the structure is created in
+stack local memory. They may also appear as initialization expressions for
+`Block` variables of global or `static` local variables.
 
-When a ``Block`` literal expression is evaluated the stack based structure is
+When a `Block` literal expression is evaluated the stack based structure is
 initialized as follows:
 
-1. A ``static`` descriptor structure is declared and initialized as follows:
-
-  a. The ``invoke`` function pointer is set to a function that takes the
-  ``Block`` structure as its first argument and the rest of the arguments (if
-  any) to the ``Block`` and executes the ``Block`` compound statement.
-
-  b. The ``size`` field is set to the size of the following ``Block`` literal
-  structure.
+1. A `static` descriptor structure is declared and initialized as follows:
 
-  c. The ``copy_helper`` and ``dispose_helper`` function pointers are set to
-  respective helper functions if they are required by the ``Block`` literal.
+> a. The `invoke` function pointer is set to a function that takes the
+> `Block` structure as its first argument and the rest of the arguments (if
+> any) to the `Block` and executes the `Block` compound statement.
+>
+> b. The `size` field is set to the size of the following `Block` literal
+> structure.
+>
+> c. The `copy_helper` and `dispose_helper` function pointers are set to
+> respective helper functions if they are required by the `Block` literal.
 
-2. A stack (or global) ``Block`` literal data structure is created and
+2. A stack (or global) `Block` literal data structure is created and
    initialized as follows:
 
-   a. The ``isa`` field is set to the address of the external
-   ``_NSConcreteStackBlock``, which is a block of uninitialized memory supplied
-   in ``libSystem``, or ``_NSConcreteGlobalBlock`` if this is a static or file
-   level ``Block`` literal.
+   a. The `isa` field is set to the address of the external
+   `_NSConcreteStackBlock`, which is a block of uninitialized memory supplied
+   in `libSystem`, or `_NSConcreteGlobalBlock` if this is a static or file
+   level `Block` literal.
 
-   b. The ``flags`` field is set to zero unless there are variables imported
-   into the ``Block`` that need helper functions for program level
-   ``Block_copy()`` and ``Block_release()`` operations, in which case the
-   (1<<25) flags bit is set.
+   b. The `flags` field is set to zero unless there are variables imported
+   into the `Block` that need helper functions for program level
+   `Block_copy()` and `Block_release()` operations, in which case the
+   (1\<<25) flags bit is set.
 
-As an example, the ``Block`` literal expression:
+As an example, the `Block` literal expression:
 
-.. code-block:: c
-
-    ^ { printf("hello world\n"); }
+```c
+^ { printf("hello world\n"); }
+```
 
 would cause the following to be created on a 32-bit system:
 
-.. code-block:: c
-
-    struct __block_literal_1 {
-        void *isa;
-        int flags;
-        int reserved;
-        void (*invoke)(struct __block_literal_1 *);
-        struct __block_descriptor_1 *descriptor;
-    };
-
-    void __block_invoke_1(struct __block_literal_1 *_block) {
-        printf("hello world\n");
-    }
-
-    static struct __block_descriptor_1 {
-        unsigned long int reserved;
-        unsigned long int Block_size;
-    } __block_descriptor_1 = { 0, sizeof(struct __block_literal_1) };
-
-and where the ``Block`` literal itself appears:
-
-.. code-block:: c
-
-    struct __block_literal_1 _block_literal = {
-         &_NSConcreteStackBlock,
-         (1<<29), <uninitialized>,
-         __block_invoke_1,
-         &__block_descriptor_1
-    };
-
-A ``Block`` imports other ``Block`` references, ``const`` copies of other
-variables, and variables marked ``__block``.  In Objective-C, variables may
+```c
+struct __block_literal_1 {
+    void *isa;
+    int flags;
+    int reserved;
+    void (*invoke)(struct __block_literal_1 *);
+    struct __block_descriptor_1 *descriptor;
+};
+
+void __block_invoke_1(struct __block_literal_1 *_block) {
+    printf("hello world\n");
+}
+
+static struct __block_descriptor_1 {
+    unsigned long int reserved;
+    unsigned long int Block_size;
+} __block_descriptor_1 = { 0, sizeof(struct __block_literal_1) };
+```
+
+and where the `Block` literal itself appears:
+
+```c
+struct __block_literal_1 _block_literal = {
+     &_NSConcreteStackBlock,
+     (1<<29), <uninitialized>,
+     __block_invoke_1,
+     &__block_descriptor_1
+};
+```
+
+A `Block` imports other `Block` references, `const` copies of other
+variables, and variables marked `__block`. In Objective-C, variables may
 additionally be objects.
 
-When a ``Block`` literal expression is used as the initial value of a global
-or ``static`` local variable, it is initialized as follows:
+When a `Block` literal expression is used as the initial value of a global
+or `static` local variable, it is initialized as follows:
 
-.. code-block:: c
-
-    struct __block_literal_1 __block_literal_1 = {
-          &_NSConcreteGlobalBlock,
-          (1<<28)|(1<<29), <uninitialized>,
-          __block_invoke_1,
-          &__block_descriptor_1
-    };
+```c
+struct __block_literal_1 __block_literal_1 = {
+      &_NSConcreteGlobalBlock,
+      (1<<28)|(1<<29), <uninitialized>,
+      __block_invoke_1,
+      &__block_descriptor_1
+};
+```
 
 that is, a different address is provided as the first value and a particular
-(1<<28) bit is set in the ``flags`` field, and otherwise it is the same as for
-stack based ``Block`` literals.  This is an optimization that can be used for
-any ``Block`` literal that imports no ``const`` or ``__block`` storage
+(1\<<28) bit is set in the `flags` field, and otherwise it is the same as for
+stack based `Block` literals. This is an optimization that can be used for
+any `Block` literal that imports no `const` or `__block` storage
 variables.
 
-Imported Variables
-==================
+## Imported Variables
 
-Variables of ``auto`` storage class are imported as ``const`` copies.  Variables
-of ``__block`` storage class are imported as a pointer to an enclosing data
-structure.  Global variables are simply referenced and not considered as
+Variables of `auto` storage class are imported as `const` copies. Variables
+of `__block` storage class are imported as a pointer to an enclosing data
+structure. Global variables are simply referenced and not considered as
 imported.
 
-Imported ``const`` copy variables
----------------------------------
-
-Automatic storage variables not marked with ``__block`` are imported as
-``const`` copies.
+### Imported `const` copy variables
 
-The simplest example is that of importing a variable of type ``int``:
+Automatic storage variables not marked with `__block` are imported as
+`const` copies.
 
-.. code-block:: c
+The simplest example is that of importing a variable of type `int`:
 
-    int x = 10;
-    void (^vv)(void) = ^{ printf("x is %d\n", x); }
-    x = 11;
-    vv();
+```c
+int x = 10;
+void (^vv)(void) = ^{ printf("x is %d\n", x); }
+x = 11;
+vv();
+```
 
 which would be compiled to:
 
-.. code-block:: c
-
-    struct __block_literal_2 {
-        void *isa;
-        int flags;
-        int reserved;
-        void (*invoke)(struct __block_literal_2 *);
-        struct __block_descriptor_2 *descriptor;
-        const int x;
-    };
-
-    void __block_invoke_2(struct __block_literal_2 *_block) {
-        printf("x is %d\n", _block->x);
-    }
-
-    static struct __block_descriptor_2 {
-        unsigned long int reserved;
-        unsigned long int Block_size;
-    } __block_descriptor_2 = { 0, sizeof(struct __block_literal_2) };
+```c
+struct __block_literal_2 {
+    void *isa;
+    int flags;
+    int reserved;
+    void (*invoke)(struct __block_literal_2 *);
+    struct __block_descriptor_2 *descriptor;
+    const int x;
+};
+
+void __block_invoke_2(struct __block_literal_2 *_block) {
+    printf("x is %d\n", _block->x);
+}
+
+static struct __block_descriptor_2 {
+    unsigned long int reserved;
+    unsigned long int Block_size;
+} __block_descriptor_2 = { 0, sizeof(struct __block_literal_2) };
+```
 
 and:
 
-.. code-block:: c
-
-    struct __block_literal_2 __block_literal_2 = {
-          &_NSConcreteStackBlock,
-          (1<<29), <uninitialized>,
-          __block_invoke_2,
-          &__block_descriptor_2,
-          x
-     };
+```c
+struct __block_literal_2 __block_literal_2 = {
+      &_NSConcreteStackBlock,
+      (1<<29), <uninitialized>,
+      __block_invoke_2,
+      &__block_descriptor_2,
+      x
+ };
+```
 
 In summary, scalars, structures, unions, and function pointers are generally
-imported as ``const`` copies with no need for helper functions.
+imported as `const` copies with no need for helper functions.
 
-Imported ``const`` copy of ``Block`` reference
-----------------------------------------------
+### Imported `const` copy of `Block` reference
 
 The first case where copy and dispose helper functions are required is for the
-case of when a ``Block`` itself is imported.  In this case both a
-``copy_helper`` function and a ``dispose_helper`` function are needed.  The
-``copy_helper`` function is passed both the existing stack based pointer and the
+case of when a `Block` itself is imported. In this case both a
+`copy_helper` function and a `dispose_helper` function are needed. The
+`copy_helper` function is passed both the existing stack based pointer and the
 pointer to the new heap version and should call back into the runtime to
-actually do the copy operation on the imported fields within the ``Block``. The
-runtime functions are all described in :ref:`RuntimeHelperFunctions`.
+actually do the copy operation on the imported fields within the `Block`. The
+runtime functions are all described in {ref}`RuntimeHelperFunctions`.
 
 A quick example:
 
-.. code-block:: c
-
-    void (^existingBlock)(void) = ...;
-    void (^vv)(void) = ^{ existingBlock(); }
-    vv();
-
-    struct __block_literal_3 {
-       ...; // existing block
-    };
-
-    struct __block_literal_4 {
-        void *isa;
-        int flags;
-        int reserved;
-        void (*invoke)(struct __block_literal_4 *);
-        struct __block_literal_3 *const existingBlock;
-    };
-
-    void __block_invoke_4(struct __block_literal_2 *_block) {
-       __block->existingBlock->invoke(__block->existingBlock);
-    }
-
-    void __block_copy_4(struct __block_literal_4 *dst, struct __block_literal_4 *src) {
-         //_Block_copy_assign(&dst->existingBlock, src->existingBlock, 0);
-         _Block_object_assign(&dst->existingBlock, src->existingBlock, BLOCK_FIELD_IS_BLOCK);
-    }
-
-    void __block_dispose_4(struct __block_literal_4 *src) {
-         // was _Block_destroy
-         _Block_object_dispose(src->existingBlock, BLOCK_FIELD_IS_BLOCK);
-    }
-
-    static struct __block_descriptor_4 {
-        unsigned long int reserved;
-        unsigned long int Block_size;
-        void (*copy_helper)(struct __block_literal_4 *dst, struct __block_literal_4 *src);
-        void (*dispose_helper)(struct __block_literal_4 *);
-    } __block_descriptor_4 = {
-        0,
-        sizeof(struct __block_literal_4),
-        __block_copy_4,
-        __block_dispose_4,
-    };
-
-and where said ``Block`` is used:
-
-.. code-block:: c
-
-    struct __block_literal_4 _block_literal = {
-          &_NSConcreteStackBlock,
-          (1<<25)|(1<<29), <uninitialized>
-          __block_invoke_4,
-          & __block_descriptor_4
-          existingBlock,
-    };
-
-Importing ``__attribute__((NSObject))`` variables
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-GCC introduces ``__attribute__((NSObject))`` on structure pointers to mean "this
-is an object".  This is useful because many low level data structures are
-declared as opaque structure pointers, e.g. ``CFStringRef``, ``CFArrayRef``,
-etc.  When used from C, however, these are still really objects and are the
+```c
+void (^existingBlock)(void) = ...;
+void (^vv)(void) = ^{ existingBlock(); }
+vv();
+
+struct __block_literal_3 {
+   ...; // existing block
+};
+
+struct __block_literal_4 {
+    void *isa;
+    int flags;
+    int reserved;
+    void (*invoke)(struct __block_literal_4 *);
+    struct __block_literal_3 *const existingBlock;
+};
+
+void __block_invoke_4(struct __block_literal_2 *_block) {
+   __block->existingBlock->invoke(__block->existingBlock);
+}
+
+void __block_copy_4(struct __block_literal_4 *dst, struct __block_literal_4 *src) {
+     //_Block_copy_assign(&dst->existingBlock, src->existingBlock, 0);
+     _Block_object_assign(&dst->existingBlock, src->existingBlock, BLOCK_FIELD_IS_BLOCK);
+}
+
+void __block_dispose_4(struct __block_literal_4 *src) {
+     // was _Block_destroy
+     _Block_object_dispose(src->existingBlock, BLOCK_FIELD_IS_BLOCK);
+}
+
+static struct __block_descriptor_4 {
+    unsigned long int reserved;
+    unsigned long int Block_size;
+    void (*copy_helper)(struct __block_literal_4 *dst, struct __block_literal_4 *src);
+    void (*dispose_helper)(struct __block_literal_4 *);
+} __block_descriptor_4 = {
+    0,
+    sizeof(struct __block_literal_4),
+    __block_copy_4,
+    __block_dispose_4,
+};
+```
+
+and where said `Block` is used:
+
+```c
+struct __block_literal_4 _block_literal = {
+      &_NSConcreteStackBlock,
+      (1<<25)|(1<<29), <uninitialized>
+      __block_invoke_4,
+      & __block_descriptor_4
+      existingBlock,
+};
+```
+
+#### Importing `__attribute__((NSObject))` variables
+
+GCC introduces `__attribute__((NSObject))` on structure pointers to mean "this
+is an object". This is useful because many low level data structures are
+declared as opaque structure pointers, e.g. `CFStringRef`, `CFArrayRef`,
+etc. When used from C, however, these are still really objects and are the
 second case where that requires copy and dispose helper functions to be
-generated.  The copy helper functions generated by the compiler should use the
-``_Block_object_assign`` runtime helper function and in the dispose helper the
-``_Block_object_dispose`` runtime helper function should be called.
+generated. The copy helper functions generated by the compiler should use the
+`_Block_object_assign` runtime helper function and in the dispose helper the
+`_Block_object_dispose` runtime helper function should be called.
 
-For example, ``Block`` foo in the following:
+For example, `Block` foo in the following:
 
-.. code-block:: c
-
-    struct Opaque *__attribute__((NSObject)) objectPointer = ...;
-    ...
-    void (^foo)(void) = ^{  CFPrint(objectPointer); };
+```c
+struct Opaque *__attribute__((NSObject)) objectPointer = ...;
+...
+void (^foo)(void) = ^{  CFPrint(objectPointer); };
+```
 
 would have the following helper functions generated:
 
-.. code-block:: c
-
-    void __block_copy_foo(struct __block_literal_5 *dst, struct __block_literal_5 *src) {
-         _Block_object_assign(&dst->objectPointer, src-> objectPointer, BLOCK_FIELD_IS_OBJECT);
-    }
+```c
+void __block_copy_foo(struct __block_literal_5 *dst, struct __block_literal_5 *src) {
+     _Block_object_assign(&dst->objectPointer, src-> objectPointer, BLOCK_FIELD_IS_OBJECT);
+}
 
-    void __block_dispose_foo(struct __block_literal_5 *src) {
-         _Block_object_dispose(src->objectPointer, BLOCK_FIELD_IS_OBJECT);
-    }
+void __block_dispose_foo(struct __block_literal_5 *src) {
+     _Block_object_dispose(src->objectPointer, BLOCK_FIELD_IS_OBJECT);
+}
+```
 
-Imported ``__block`` marked variables
--------------------------------------
+### Imported `__block` marked variables
 
-Layout of ``__block`` marked variables
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Layout of `__block` marked variables
 
-The compiler must embed variables that are marked ``__block`` in a specialized
+The compiler must embed variables that are marked `__block` in a specialized
 structure of the form:
 
-.. code-block:: c
-
-    struct _block_byref_foo {
-        void *isa;
-        struct Block_byref *forwarding;
-        int flags;   //refcount;
-        int size;
-        typeof(marked_variable) marked_variable;
-    };
-
-Variables of certain types require helper functions for when ``Block_copy()``
-and ``Block_release()`` are performed upon a referencing ``Block``.  At the "C"
-level only variables that are of type ``Block`` or ones that have
-``__attribute__((NSObject))`` marked require helper functions.  In Objective-C
+```c
+struct _block_byref_foo {
+    void *isa;
+    struct Block_byref *forwarding;
+    int flags;   //refcount;
+    int size;
+    typeof(marked_variable) marked_variable;
+};
+```
+
+Variables of certain types require helper functions for when `Block_copy()`
+and `Block_release()` are performed upon a referencing `Block`. At the "C"
+level only variables that are of type `Block` or ones that have
+`__attribute__((NSObject))` marked require helper functions. In Objective-C
 objects require helper functions and in C++ stack based objects require helper
 functions. Variables that require helper functions use the form:
 
-.. code-block:: c
-
-    struct _block_byref_foo {
-        void *isa;
-        struct _block_byref_foo *forwarding;
-        int flags;   //refcount;
-        int size;
-        // helper functions called via Block_copy() and Block_release()
-        void (*byref_keep)(void  *dst, void *src);
-        void (*byref_dispose)(void *);
-        typeof(marked_variable) marked_variable;
-    };
+```c
+struct _block_byref_foo {
+    void *isa;
+    struct _block_byref_foo *forwarding;
+    int flags;   //refcount;
+    int size;
+    // helper functions called via Block_copy() and Block_release()
+    void (*byref_keep)(void  *dst, void *src);
+    void (*byref_dispose)(void *);
+    typeof(marked_variable) marked_variable;
+};
+```
 
 The structure is initialized such that:
 
-    a. The ``forwarding`` pointer is set to the beginning of its enclosing
-    structure.
-
-    b. The ``size`` field is initialized to the total size of the enclosing
-    structure.
-
-    c. The ``flags`` field is set to either 0 if no helper functions are needed
-    or (1<<25) if they are.
-
-    d. The helper functions are initialized (if present).
-
-    e. The variable itself is set to its initial value.
-
-    f. The ``isa`` field is set to ``NULL``.
-
-Access to ``__block`` variables from within its lexical scope
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-In order to "move" the variable to the heap upon a ``copy_helper`` operation the
+> a. The `forwarding` pointer is set to the beginning of its enclosing
+> structure.
+>
+> b. The `size` field is initialized to the total size of the enclosing
+> structure.
+>
+> c. The `flags` field is set to either 0 if no helper functions are needed
+> or (1\<<25) if they are.
+>
+> 4. The helper functions are initialized (if present).
+> 5. The variable itself is set to its initial value.
+> 6. The `isa` field is set to `NULL`.
+
+#### Access to `__block` variables from within its lexical scope
+
+In order to "move" the variable to the heap upon a `copy_helper` operation the
 compiler must rewrite access to such a variable to be indirect through the
-structures ``forwarding`` pointer.  For example:
+structures `forwarding` pointer. For example:
 
-.. code-block:: c
-
-    int __block i = 10;
-    i = 11;
+```c
+int __block i = 10;
+i = 11;
+```
 
 would be rewritten to be:
 
-.. code-block:: c
-
-    struct _block_byref_i {
-      void *isa;
-      struct _block_byref_i *forwarding;
-      int flags;   //refcount;
-      int size;
-      int captured_i;
-    } i = { NULL, &i, 0, sizeof(struct _block_byref_i), 10 };
-
-    i.forwarding->captured_i = 11;
-
-In the case of a ``Block`` reference variable being marked ``__block`` the
-helper code generated must use the ``_Block_object_assign`` and
-``_Block_object_dispose`` routines supplied by the runtime to make the
+```c
+struct _block_byref_i {
+  void *isa;
+  struct _block_byref_i *forwarding;
+  int flags;   //refcount;
+  int size;
+  int captured_i;
+} i = { NULL, &i, 0, sizeof(struct _block_byref_i), 10 };
+
+i.forwarding->captured_i = 11;
+```
+
+In the case of a `Block` reference variable being marked `__block` the
+helper code generated must use the `_Block_object_assign` and
+`_Block_object_dispose` routines supplied by the runtime to make the
 copies. For example:
 
-.. code-block:: c
-
-    __block void (voidBlock)(void) = blockA;
-    voidBlock = blockB;
+```c
+__block void (voidBlock)(void) = blockA;
+voidBlock = blockB;
+```
 
 would translate into:
 
-.. code-block:: c
-
-    struct _block_byref_voidBlock {
-        void *isa;
-        struct _block_byref_voidBlock *forwarding;
-        int flags;   //refcount;
-        int size;
-        void (*byref_keep)(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src);
-        void (*byref_dispose)(struct _block_byref_voidBlock *);
-        void (^captured_voidBlock)(void);
-    };
-
-    void _block_byref_keep_helper(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src) {
-        //_Block_copy_assign(&dst->captured_voidBlock, src->captured_voidBlock, 0);
-        _Block_object_assign(&dst->captured_voidBlock, src->captured_voidBlock, BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER);
-    }
-
-    void _block_byref_dispose_helper(struct _block_byref_voidBlock *param) {
-        //_Block_destroy(param->captured_voidBlock, 0);
-        _Block_object_dispose(param->captured_voidBlock, BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER)}
+```c
+struct _block_byref_voidBlock {
+    void *isa;
+    struct _block_byref_voidBlock *forwarding;
+    int flags;   //refcount;
+    int size;
+    void (*byref_keep)(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src);
+    void (*byref_dispose)(struct _block_byref_voidBlock *);
+    void (^captured_voidBlock)(void);
+};
+
+void _block_byref_keep_helper(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src) {
+    //_Block_copy_assign(&dst->captured_voidBlock, src->captured_voidBlock, 0);
+    _Block_object_assign(&dst->captured_voidBlock, src->captured_voidBlock, BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER);
+}
+
+void _block_byref_dispose_helper(struct _block_byref_voidBlock *param) {
+    //_Block_destroy(param->captured_voidBlock, 0);
+    _Block_object_dispose(param->captured_voidBlock, BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER)}
+```
 
 and:
 
-.. code-block:: c
+```c
+struct _block_byref_voidBlock voidBlock = {( .forwarding=&voidBlock, .flags=(1<<25), .size=sizeof(struct _block_byref_voidBlock *),
+    .byref_keep=_block_byref_keep_helper, .byref_dispose=_block_byref_dispose_helper,
+    .captured_voidBlock=blockA )};
 
-    struct _block_byref_voidBlock voidBlock = {( .forwarding=&voidBlock, .flags=(1<<25), .size=sizeof(struct _block_byref_voidBlock *),
-        .byref_keep=_block_byref_keep_helper, .byref_dispose=_block_byref_dispose_helper,
-        .captured_voidBlock=blockA )};
+voidBlock.forwarding->captured_voidBlock = blockB;
+```
 
-    voidBlock.forwarding->captured_voidBlock = blockB;
+#### Importing `__block` variables into `Blocks`
 
-Importing ``__block`` variables into ``Blocks``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-A ``Block`` that uses a ``__block`` variable in its compound statement body must
-import the variable and emit ``copy_helper`` and ``dispose_helper`` helper
+A `Block` that uses a `__block` variable in its compound statement body must
+import the variable and emit `copy_helper` and `dispose_helper` helper
 functions that, in turn, call back into the runtime to actually copy or release
-the ``byref`` data block using the functions ``_Block_object_assign`` and
-``_Block_object_dispose``.
+the `byref` data block using the functions `_Block_object_assign` and
+`_Block_object_dispose`.
 
 For example:
 
-.. code-block:: c
-
-    int __block i = 2;
-    functioncall(^{ i = 10; });
+```c
+int __block i = 2;
+functioncall(^{ i = 10; });
+```
 
 would translate to:
 
-.. code-block:: c
-
-    struct _block_byref_i {
-        void *isa;  // set to NULL
-        struct _block_byref_voidBlock *forwarding;
-        int flags;   //refcount;
-        int size;
-        void (*byref_keep)(struct _block_byref_i *dst, struct _block_byref_i *src);
-        void (*byref_dispose)(struct _block_byref_i *);
-        int captured_i;
-    };
-
-
-    struct __block_literal_5 {
-        void *isa;
-        int flags;
-        int reserved;
-        void (*invoke)(struct __block_literal_5 *);
-        struct __block_descriptor_5 *descriptor;
-        struct _block_byref_i *i_holder;
-    };
-
-    void __block_invoke_5(struct __block_literal_5 *_block) {
-       _block->forwarding->captured_i = 10;
-    }
-
-    void __block_copy_5(struct __block_literal_5 *dst, struct __block_literal_5 *src) {
-         //_Block_byref_assign_copy(&dst->captured_i, src->captured_i);
-         _Block_object_assign(&dst->captured_i, src->captured_i, BLOCK_FIELD_IS_BYREF | BLOCK_BYREF_CALLER);
-    }
-
-    void __block_dispose_5(struct __block_literal_5 *src) {
-         //_Block_byref_release(src->captured_i);
-         _Block_object_dispose(src->captured_i, BLOCK_FIELD_IS_BYREF | BLOCK_BYREF_CALLER);
-    }
-
-    static struct __block_descriptor_5 {
-        unsigned long int reserved;
-        unsigned long int Block_size;
-        void (*copy_helper)(struct __block_literal_5 *dst, struct __block_literal_5 *src);
-        void (*dispose_helper)(struct __block_literal_5 *);
-    } __block_descriptor_5 = { 0, sizeof(struct __block_literal_5) __block_copy_5, __block_dispose_5 };
+```c
+struct _block_byref_i {
+    void *isa;  // set to NULL
+    struct _block_byref_voidBlock *forwarding;
+    int flags;   //refcount;
+    int size;
+    void (*byref_keep)(struct _block_byref_i *dst, struct _block_byref_i *src);
+    void (*byref_dispose)(struct _block_byref_i *);
+    int captured_i;
+};
+
+
+struct __block_literal_5 {
+    void *isa;
+    int flags;
+    int reserved;
+    void (*invoke)(struct __block_literal_5 *);
+    struct __block_descriptor_5 *descriptor;
+    struct _block_byref_i *i_holder;
+};
+
+void __block_invoke_5(struct __block_literal_5 *_block) {
+   _block->forwarding->captured_i = 10;
+}
+
+void __block_copy_5(struct __block_literal_5 *dst, struct __block_literal_5 *src) {
+     //_Block_byref_assign_copy(&dst->captured_i, src->captured_i);
+     _Block_object_assign(&dst->captured_i, src->captured_i, BLOCK_FIELD_IS_BYREF | BLOCK_BYREF_CALLER);
+}
+
+void __block_dispose_5(struct __block_literal_5 *src) {
+     //_Block_byref_release(src->captured_i);
+     _Block_object_dispose(src->captured_i, BLOCK_FIELD_IS_BYREF | BLOCK_BYREF_CALLER);
+}
+
+static struct __block_descriptor_5 {
+    unsigned long int reserved;
+    unsigned long int Block_size;
+    void (*copy_helper)(struct __block_literal_5 *dst, struct __block_literal_5 *src);
+    void (*dispose_helper)(struct __block_literal_5 *);
+} __block_descriptor_5 = { 0, sizeof(struct __block_literal_5) __block_copy_5, __block_dispose_5 };
+```
 
 and:
 
-.. code-block:: c
+```c
+struct _block_byref_i i = {( .isa=NULL, .forwarding=&i, .flags=0, .size=sizeof(struct _block_byref_i), .captured_i=2 )};
+struct __block_literal_5 _block_literal = {
+      &_NSConcreteStackBlock,
+      (1<<25)|(1<<29), <uninitialized>,
+      __block_invoke_5,
+      &__block_descriptor_5,
+      &i,
+};
+```
 
-    struct _block_byref_i i = {( .isa=NULL, .forwarding=&i, .flags=0, .size=sizeof(struct _block_byref_i), .captured_i=2 )};
-    struct __block_literal_5 _block_literal = {
-          &_NSConcreteStackBlock,
-          (1<<25)|(1<<29), <uninitialized>,
-          __block_invoke_5,
-          &__block_descriptor_5,
-          &i,
-    };
+#### Importing `__attribute__((NSObject))` `__block` variables
 
-Importing ``__attribute__((NSObject))`` ``__block`` variables
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+A `__block` variable that is also marked `__attribute__((NSObject))` should
+have `byref_keep` and `byref_dispose` helper functions that use
+`_Block_object_assign` and `_Block_object_dispose`.
 
-A ``__block`` variable that is also marked ``__attribute__((NSObject))`` should
-have ``byref_keep`` and ``byref_dispose`` helper functions that use
-``_Block_object_assign`` and ``_Block_object_dispose``.
+#### `__block` escapes
 
-``__block`` escapes
-^^^^^^^^^^^^^^^^^^^
-
-Because ``Blocks`` referencing ``__block`` variables may have ``Block_copy()``
+Because `Blocks` referencing `__block` variables may have `Block_copy()`
 performed upon them the underlying storage for the variables may move to the
-heap.  In Objective-C Garbage Collection Only compilation environments the heap
-used is the garbage collected one and no further action is required.  Otherwise
+heap. In Objective-C Garbage Collection Only compilation environments the heap
+used is the garbage collected one and no further action is required. Otherwise
 the compiler must issue a call to potentially release any heap storage for
-``__block`` variables at all escapes or terminations of their scope.  The call
+`__block` variables at all escapes or terminations of their scope. The call
 should be:
 
-.. code-block:: c
-
-    _Block_object_dispose(&_block_byref_foo, BLOCK_FIELD_IS_BYREF);
+```c
+_Block_object_dispose(&_block_byref_foo, BLOCK_FIELD_IS_BYREF);
+```
 
-Nesting
-^^^^^^^
+#### Nesting
 
-``Blocks`` may contain ``Block`` literal expressions.  Any variables used within
-inner blocks are imported into all enclosing ``Block`` scopes even if the
-variables are not used. This includes ``const`` imports as well as ``__block``
+`Blocks` may contain `Block` literal expressions. Any variables used within
+inner blocks are imported into all enclosing `Block` scopes even if the
+variables are not used. This includes `const` imports as well as `__block`
 variables.
 
-Objective C Extensions to ``Blocks``
-====================================
+## Objective C Extensions to `Blocks`
 
-Importing Objects
------------------
+### Importing Objects
 
-Objects should be treated as ``__attribute__((NSObject))`` variables; all
-``copy_helper``, ``dispose_helper``, ``byref_keep``, and ``byref_dispose``
-helper functions should use ``_Block_object_assign`` and
-``_Block_object_dispose``.  There should be no code generated that uses
-``*-retain`` or ``*-release`` methods.
+Objects should be treated as `__attribute__((NSObject))` variables; all
+`copy_helper`, `dispose_helper`, `byref_keep`, and `byref_dispose`
+helper functions should use `_Block_object_assign` and
+`_Block_object_dispose`. There should be no code generated that uses
+`*-retain` or `*-release` methods.
 
-``Blocks`` as Objects
----------------------
+### `Blocks` as Objects
 
-The compiler will treat ``Blocks`` as objects when synthesizing property setters
+The compiler will treat `Blocks` as objects when synthesizing property setters
 and getters, will characterize them as objects when generating garbage
 collection strong and weak layout information in the same manner as objects, and
 will issue strong and weak write-barrier assignments in the same manner as
 objects.
 
-``__weak __block`` Support
---------------------------
+### `__weak __block` Support
 
-Objective-C (and Objective-C++) support the ``__weak`` attribute on ``__block``
-variables.  Under normal circumstances the compiler uses the Objective-C runtime
-helper support functions ``objc_assign_weak`` and ``objc_read_weak``.  Both
-should continue to be used for all reads and writes of ``__weak __block``
+Objective-C (and Objective-C++) support the `__weak` attribute on `__block`
+variables. Under normal circumstances the compiler uses the Objective-C runtime
+helper support functions `objc_assign_weak` and `objc_read_weak`. Both
+should continue to be used for all reads and writes of `__weak __block`
 variables:
 
-.. code-block:: c
+```c
+objc_read_weak(&block->byref_i->forwarding->i)
+```
 
-    objc_read_weak(&block->byref_i->forwarding->i)
+The `__weak` variable is stored in a `_block_byref_foo` structure and the
+`Block` has copy and dispose helpers for this structure that call:
 
-The ``__weak`` variable is stored in a ``_block_byref_foo`` structure and the
-``Block`` has copy and dispose helpers for this structure that call:
-
-.. code-block:: c
-
-    _Block_object_assign(&dest->_block_byref_i, src-> _block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BYREF);
+```c
+_Block_object_assign(&dest->_block_byref_i, src-> _block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BYREF);
+```
 
 and:
 
-.. code-block:: c
-
-    _Block_object_dispose(src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BYREF);
-
-In turn, the ``block_byref`` copy support helpers distinguish between whether
-the ``__block`` variable is a ``Block`` or not and should either call:
+```c
+_Block_object_dispose(src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BYREF);
+```
 
-.. code-block:: c
+In turn, the `block_byref` copy support helpers distinguish between whether
+the `__block` variable is a `Block` or not and should either call:
 
-    _Block_object_assign(&dest->_block_byref_i, src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_OBJECT | BLOCK_BYREF_CALLER);
+```c
+_Block_object_assign(&dest->_block_byref_i, src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_OBJECT | BLOCK_BYREF_CALLER);
+```
 
 for something declared as an object or:
 
-.. code-block:: c
+```c
+_Block_object_assign(&dest->_block_byref_i, src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER);
+```
 
-    _Block_object_assign(&dest->_block_byref_i, src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER);
-
-for something declared as a ``Block``.
+for something declared as a `Block`.
 
 A full example follows:
 
-.. code-block:: c
-
-    __block __weak id obj = <initialization expression>;
-    functioncall(^{ [obj somemessage]; });
+```c
+__block __weak id obj = <initialization expression>;
+functioncall(^{ [obj somemessage]; });
+```
 
 would translate to:
 
-.. code-block:: c
-
-    struct _block_byref_obj {
-        void *isa;  // uninitialized
-        struct _block_byref_obj *forwarding;
-        int flags;   //refcount;
-        int size;
-        void (*byref_keep)(struct _block_byref_i *dst, struct _block_byref_i *src);
-        void (*byref_dispose)(struct _block_byref_i *);
-        id captured_obj;
-    };
-
-    void _block_byref_obj_keep(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src) {
-        //_Block_copy_assign(&dst->captured_obj, src->captured_obj, 0);
-        _Block_object_assign(&dst->captured_obj, src->captured_obj, BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER);
-    }
-
-    void _block_byref_obj_dispose(struct _block_byref_voidBlock *param) {
-        //_Block_destroy(param->captured_obj, 0);
-        _Block_object_dispose(param->captured_obj, BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER);
-    };
-
-for the block ``byref`` part and:
-
-.. code-block:: c
-
-    struct __block_literal_5 {
-        void *isa;
-        int flags;
-        int reserved;
-        void (*invoke)(struct __block_literal_5 *);
-        struct __block_descriptor_5 *descriptor;
-        struct _block_byref_obj *byref_obj;
-    };
-
-    void __block_invoke_5(struct __block_literal_5 *_block) {
-       [objc_read_weak(&_block->byref_obj->forwarding->captured_obj) somemessage];
-    }
-
-    void __block_copy_5(struct __block_literal_5 *dst, struct __block_literal_5 *src) {
-         //_Block_byref_assign_copy(&dst->byref_obj, src->byref_obj);
-         _Block_object_assign(&dst->byref_obj, src->byref_obj, BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK);
-    }
-
-    void __block_dispose_5(struct __block_literal_5 *src) {
-         //_Block_byref_release(src->byref_obj);
-         _Block_object_dispose(src->byref_obj, BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK);
-    }
-
-    static struct __block_descriptor_5 {
-        unsigned long int reserved;
-        unsigned long int Block_size;
-        void (*copy_helper)(struct __block_literal_5 *dst, struct __block_literal_5 *src);
-        void (*dispose_helper)(struct __block_literal_5 *);
-    } __block_descriptor_5 = { 0, sizeof(struct __block_literal_5), __block_copy_5, __block_dispose_5 };
+```c
+struct _block_byref_obj {
+    void *isa;  // uninitialized
+    struct _block_byref_obj *forwarding;
+    int flags;   //refcount;
+    int size;
+    void (*byref_keep)(struct _block_byref_i *dst, struct _block_byref_i *src);
+    void (*byref_dispose)(struct _block_byref_i *);
+    id captured_obj;
+};
+
+void _block_byref_obj_keep(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src) {
+    //_Block_copy_assign(&dst->captured_obj, src->captured_obj, 0);
+    _Block_object_assign(&dst->captured_obj, src->captured_obj, BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER);
+}
+
+void _block_byref_obj_dispose(struct _block_byref_voidBlock *param) {
+    //_Block_destroy(param->captured_obj, 0);
+    _Block_object_dispose(param->captured_obj, BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER);
+};
+```
+
+for the block `byref` part and:
+
+```c
+struct __block_literal_5 {
+    void *isa;
+    int flags;
+    int reserved;
+    void (*invoke)(struct __block_literal_5 *);
+    struct __block_descriptor_5 *descriptor;
+    struct _block_byref_obj *byref_obj;
+};
+
+void __block_invoke_5(struct __block_literal_5 *_block) {
+   [objc_read_weak(&_block->byref_obj->forwarding->captured_obj) somemessage];
+}
+
+void __block_copy_5(struct __block_literal_5 *dst, struct __block_literal_5 *src) {
+     //_Block_byref_assign_copy(&dst->byref_obj, src->byref_obj);
+     _Block_object_assign(&dst->byref_obj, src->byref_obj, BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK);
+}
+
+void __block_dispose_5(struct __block_literal_5 *src) {
+     //_Block_byref_release(src->byref_obj);
+     _Block_object_dispose(src->byref_obj, BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK);
+}
+
+static struct __block_descriptor_5 {
+    unsigned long int reserved;
+    unsigned long int Block_size;
+    void (*copy_helper)(struct __block_literal_5 *dst, struct __block_literal_5 *src);
+    void (*dispose_helper)(struct __block_literal_5 *);
+} __block_descriptor_5 = { 0, sizeof(struct __block_literal_5), __block_copy_5, __block_dispose_5 };
+```
 
 and within the compound statement:
 
-.. code-block:: c
+```c
+truct _block_byref_obj obj = {( .forwarding=&obj, .flags=(1<<25), .size=sizeof(struct _block_byref_obj),
+                 .byref_keep=_block_byref_obj_keep, .byref_dispose=_block_byref_obj_dispose,
+                 .captured_obj = <initialization expression> )};
 
-    truct _block_byref_obj obj = {( .forwarding=&obj, .flags=(1<<25), .size=sizeof(struct _block_byref_obj),
-                     .byref_keep=_block_byref_obj_keep, .byref_dispose=_block_byref_obj_dispose,
-                     .captured_obj = <initialization expression> )};
+truct __block_literal_5 _block_literal = {
+     &_NSConcreteStackBlock,
+     (1<<25)|(1<<29), <uninitialized>,
+     __block_invoke_5,
+     &__block_descriptor_5,
+     &obj,        // a reference to the on-stack structure containing "captured_obj"
+};
 
-    truct __block_literal_5 _block_literal = {
-         &_NSConcreteStackBlock,
-         (1<<25)|(1<<29), <uninitialized>,
-         __block_invoke_5,
-         &__block_descriptor_5,
-         &obj,        // a reference to the on-stack structure containing "captured_obj"
-    };
 
+functioncall(_block_literal->invoke(&_block_literal));
+```
 
-    functioncall(_block_literal->invoke(&_block_literal));
+## C++ Support
 
-C++ Support
-===========
-
-Within a block stack based C++ objects are copied into ``const`` copies using
-the copy constructor.  It is an error if a stack based C++ object is used within
-a block if it does not have a copy constructor.  In addition both copy and
+Within a block stack based C++ objects are copied into `const` copies using
+the copy constructor. It is an error if a stack based C++ object is used within
+a block if it does not have a copy constructor. In addition both copy and
 destroy helper routines must be synthesized for the block to support the
-``Block_copy()`` operation, and the flags work marked with the (1<<26) bit in
-addition to the (1<<25) bit.  The copy helper should call the constructor using
+`Block_copy()` operation, and the flags work marked with the (1\<<26) bit in
+addition to the (1\<<25) bit. The copy helper should call the constructor using
 appropriate offsets of the variable within the supplied stack based block source
-and heap based destination for all ``const`` constructed copies, and similarly
+and heap based destination for all `const` constructed copies, and similarly
 should call the destructor in the destroy routine.
 
-As an example, suppose a C++ class ``FOO`` existed with a copy constructor.
-Within a code block a stack version of a ``FOO`` object is declared and used
-within a ``Block`` literal expression:
-
-.. code-block:: c++
+As an example, suppose a C++ class `FOO` existed with a copy constructor.
+Within a code block a stack version of a `FOO` object is declared and used
+within a `Block` literal expression:
 
-    {
-        FOO foo;
-        void (^block)(void) = ^{ printf("%d\n", foo.value()); };
-    }
+```c++
+{
+    FOO foo;
+    void (^block)(void) = ^{ printf("%d\n", foo.value()); };
+}
+```
 
 The compiler would synthesize:
 
-.. code-block:: c++
-
-    struct __block_literal_10 {
-        void *isa;
-        int flags;
-        int reserved;
-        void (*invoke)(struct __block_literal_10 *);
-        struct __block_descriptor_10 *descriptor;
-        const FOO foo;
-    };
-
-    void __block_invoke_10(struct __block_literal_10 *_block) {
-       printf("%d\n", _block->foo.value());
-    }
-
-    void __block_copy_10(struct __block_literal_10 *dst, struct __block_literal_10 *src) {
-         FOO_ctor(&dst->foo, &src->foo);
-    }
-
-    void __block_dispose_10(struct __block_literal_10 *src) {
-         FOO_dtor(&src->foo);
-    }
-
-    static struct __block_descriptor_10 {
-        unsigned long int reserved;
-        unsigned long int Block_size;
-        void (*copy_helper)(struct __block_literal_10 *dst, struct __block_literal_10 *src);
-        void (*dispose_helper)(struct __block_literal_10 *);
-    } __block_descriptor_10 = { 0, sizeof(struct __block_literal_10), __block_copy_10, __block_dispose_10 };
+```c++
+struct __block_literal_10 {
+    void *isa;
+    int flags;
+    int reserved;
+    void (*invoke)(struct __block_literal_10 *);
+    struct __block_descriptor_10 *descriptor;
+    const FOO foo;
+};
+
+void __block_invoke_10(struct __block_literal_10 *_block) {
+   printf("%d\n", _block->foo.value());
+}
+
+void __block_copy_10(struct __block_literal_10 *dst, struct __block_literal_10 *src) {
+     FOO_ctor(&dst->foo, &src->foo);
+}
+
+void __block_dispose_10(struct __block_literal_10 *src) {
+     FOO_dtor(&src->foo);
+}
+
+static struct __block_descriptor_10 {
+    unsigned long int reserved;
+    unsigned long int Block_size;
+    void (*copy_helper)(struct __block_literal_10 *dst, struct __block_literal_10 *src);
+    void (*dispose_helper)(struct __block_literal_10 *);
+} __block_descriptor_10 = { 0, sizeof(struct __block_literal_10), __block_copy_10, __block_dispose_10 };
+```
 
 and the code would be:
 
-.. code-block:: c++
-
-    {
-      FOO foo;
-      comp_ctor(&foo); // default constructor
-      struct __block_literal_10 _block_literal = {
-        &_NSConcreteStackBlock,
-        (1<<25)|(1<<26)|(1<<29), <uninitialized>,
-        __block_invoke_10,
-        &__block_descriptor_10,
-       };
-       comp_ctor(&_block_literal->foo, &foo);  // const copy into stack version
-       struct __block_literal_10 &block = &_block_literal;  // assign literal to block variable
-       block->invoke(block);    // invoke block
-       comp_dtor(&_block_literal->foo); // destroy stack version of const block copy
-       comp_dtor(&foo); // destroy original version
-    }
-
-
-C++ objects stored in ``__block`` storage start out on the stack in a
-``block_byref`` data structure as do other variables.  Such objects (if not
-``const`` objects) must support a regular copy constructor.  The ``block_byref``
+```c++
+{
+  FOO foo;
+  comp_ctor(&foo); // default constructor
+  struct __block_literal_10 _block_literal = {
+    &_NSConcreteStackBlock,
+    (1<<25)|(1<<26)|(1<<29), <uninitialized>,
+    __block_invoke_10,
+    &__block_descriptor_10,
+   };
+   comp_ctor(&_block_literal->foo, &foo);  // const copy into stack version
+   struct __block_literal_10 &block = &_block_literal;  // assign literal to block variable
+   block->invoke(block);    // invoke block
+   comp_dtor(&_block_literal->foo); // destroy stack version of const block copy
+   comp_dtor(&foo); // destroy original version
+}
+```
+
+C++ objects stored in `__block` storage start out on the stack in a
+`block_byref` data structure as do other variables. Such objects (if not
+`const` objects) must support a regular copy constructor. The `block_byref`
 data structure will have copy and destroy helper routines synthesized by the
-compiler.  The copy helper will have code created to perform the copy
-constructor based on the initial stack ``block_byref`` data structure, and will
-also set the (1<<26) bit in addition to the (1<<25) bit.  The destroy helper
+compiler. The copy helper will have code created to perform the copy
+constructor based on the initial stack `block_byref` data structure, and will
+also set the (1\<<26) bit in addition to the (1\<<25) bit. The destroy helper
 will have code to do the destructor on the object stored within the supplied
-``block_byref`` heap data structure.  For example,
-
-.. code-block:: c++
+`block_byref` heap data structure. For example,
 
-    __block FOO blockStorageFoo;
+```c++
+__block FOO blockStorageFoo;
+```
 
-requires the normal constructor for the embedded ``blockStorageFoo`` object:
+requires the normal constructor for the embedded `blockStorageFoo` object:
 
-.. code-block:: c++
-
-    FOO_ctor(& _block_byref_blockStorageFoo->blockStorageFoo);
+```c++
+FOO_ctor(& _block_byref_blockStorageFoo->blockStorageFoo);
+```
 
 and at scope termination the destructor:
 
-.. code-block:: c++
-
-    FOO_dtor(& _block_byref_blockStorageFoo->blockStorageFoo);
+```c++
+FOO_dtor(& _block_byref_blockStorageFoo->blockStorageFoo);
+```
 
 Note that the forwarding indirection is *NOT* used.
 
 The compiler would need to generate (if used from a block literal) the following
 copy/dispose helpers:
 
-.. code-block:: c++
+```c++
+void _block_byref_obj_keep(struct _block_byref_blockStorageFoo *dst, struct _block_byref_blockStorageFoo *src) {
+     FOO_ctor(&dst->blockStorageFoo, &src->blockStorageFoo);
+}
 
-    void _block_byref_obj_keep(struct _block_byref_blockStorageFoo *dst, struct _block_byref_blockStorageFoo *src) {
-         FOO_ctor(&dst->blockStorageFoo, &src->blockStorageFoo);
-    }
-
-    void _block_byref_obj_dispose(struct _block_byref_blockStorageFoo *src) {
-         FOO_dtor(&src->blockStorageFoo);
-    }
+void _block_byref_obj_dispose(struct _block_byref_blockStorageFoo *src) {
+     FOO_dtor(&src->blockStorageFoo);
+}
+```
 
 for the appropriately named constructor and destructor for the class/struct
-``FOO``.
+`FOO`.
 
 To support member variable and function access the compiler will synthesize a
-``const`` pointer to a block version of the ``this`` pointer.
+`const` pointer to a block version of the `this` pointer.
 
-.. _RuntimeHelperFunctions:
+(runtimehelperfunctions)=
 
-Runtime Helper Functions
-========================
+## Runtime Helper Functions
 
 The runtime helper functions are described in
-``/usr/local/include/Block_private.h``.  To summarize their use, a ``Block``
-requires copy/dispose helpers if it imports any block variables, ``__block``
-storage variables, ``__attribute__((NSObject))`` variables, or C++ ``const``
-copied objects with constructor/destructors.  The (1<<26) bit is set and
+`/usr/local/include/Block_private.h`. To summarize their use, a `Block`
+requires copy/dispose helpers if it imports any block variables, `__block`
+storage variables, `__attribute__((NSObject))` variables, or C++ `const`
+copied objects with constructor/destructors. The (1\<<26) bit is set and
 functions are generated.
 
 The block copy helper function should, for each of the variables of the type
 mentioned above, call:
 
-.. code-block:: c
-
-     _Block_object_assign(&dst->target, src->target, BLOCK_FIELD_<apropos>);
+```c
+_Block_object_assign(&dst->target, src->target, BLOCK_FIELD_<apropos>);
+```
 
 in the copy helper and:
 
-.. code-block:: c
-
-    _Block_object_dispose(->target, BLOCK_FIELD_<apropos>);
-
-in the dispose helper where ``<apropos>`` is:
+```c
+_Block_object_dispose(->target, BLOCK_FIELD_<apropos>);
+```
 
-.. code-block:: c
+in the dispose helper where `<apropos>` is:
 
-    enum {
-        BLOCK_FIELD_IS_OBJECT   =  3,  // id, NSObject, __attribute__((NSObject)), block, ...
-        BLOCK_FIELD_IS_BLOCK    =  7,  // a block variable
-        BLOCK_FIELD_IS_BYREF    =  8,  // the on stack structure holding the __block variable
+```c
+enum {
+    BLOCK_FIELD_IS_OBJECT   =  3,  // id, NSObject, __attribute__((NSObject)), block, ...
+    BLOCK_FIELD_IS_BLOCK    =  7,  // a block variable
+    BLOCK_FIELD_IS_BYREF    =  8,  // the on stack structure holding the __block variable
 
-        BLOCK_FIELD_IS_WEAK     = 16,  // declared __weak
+    BLOCK_FIELD_IS_WEAK     = 16,  // declared __weak
 
-        BLOCK_BYREF_CALLER      = 128, // called from byref copy/dispose helpers
-    };
+    BLOCK_BYREF_CALLER      = 128, // called from byref copy/dispose helpers
+};
+```
 
-and of course the constructors/destructors for ``const`` copied C++ objects.
+and of course the constructors/destructors for `const` copied C++ objects.
 
-The ``block_byref`` data structure similarly requires copy/dispose helpers for
-block variables, ``__attribute__((NSObject))`` variables, or C++ ``const``
-copied objects with constructor/destructors, and again the (1<<26) bit is set
+The `block_byref` data structure similarly requires copy/dispose helpers for
+block variables, `__attribute__((NSObject))` variables, or C++ `const`
+copied objects with constructor/destructors, and again the (1\<<26) bit is set
 and functions are generated in the same manner.
 
-Under ObjC we allow ``__weak`` as an attribute on ``__block`` variables, and
-this causes the addition of ``BLOCK_FIELD_IS_WEAK`` orred onto the
-``BLOCK_FIELD_IS_BYREF`` flag when copying the ``block_byref`` structure in the
-``Block`` copy helper, and onto the ``BLOCK_FIELD_<apropos>`` field within the
-``block_byref`` copy/dispose helper calls.
+Under ObjC we allow `__weak` as an attribute on `__block` variables, and
+this causes the addition of `BLOCK_FIELD_IS_WEAK` orred onto the
+`BLOCK_FIELD_IS_BYREF` flag when copying the `block_byref` structure in the
+`Block` copy helper, and onto the `BLOCK_FIELD_<apropos>` field within the
+`block_byref` copy/dispose helper calls.
 
 The prototypes, and summary, of the helper functions are:
 
-.. code-block:: c
-
-    /* Certain field types require runtime assistance when being copied to the
-       heap.  The following function is used to copy fields of types: blocks,
-       pointers to byref structures, and objects (including
-       __attribute__((NSObject)) pointers.  BLOCK_FIELD_IS_WEAK is orthogonal to
-       the other choices which are mutually exclusive.  Only in a Block copy
-       helper will one see BLOCK_FIELD_IS_BYREF.
-    */
-    void _Block_object_assign(void *destAddr, const void *object, const int flags);
-
-    /* Similarly a compiler generated dispose helper needs to call back for each
-       field of the byref data structure.  (Currently the implementation only
-       packs one field into the byref structure but in principle there could be
-       more).  The same flags used in the copy helper should be used for each
-       call generated to this function:
-    */
-    void _Block_object_dispose(const void *object, const int flags);
-
-Copyright
-=========
+```c
+/* Certain field types require runtime assistance when being copied to the
+   heap.  The following function is used to copy fields of types: blocks,
+   pointers to byref structures, and objects (including
+   __attribute__((NSObject)) pointers.  BLOCK_FIELD_IS_WEAK is orthogonal to
+   the other choices which are mutually exclusive.  Only in a Block copy
+   helper will one see BLOCK_FIELD_IS_BYREF.
+*/
+void _Block_object_assign(void *destAddr, const void *object, const int flags);
+
+/* Similarly a compiler generated dispose helper needs to call back for each
+   field of the byref data structure.  (Currently the implementation only
+   packs one field into the byref structure but in principle there could be
+   more).  The same flags used in the copy helper should be used for each
+   call generated to this function:
+*/
+void _Block_object_dispose(const void *object, const int flags);
+```
+
+## Copyright
 
 Copyright 2008-2010 Apple, Inc.
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -942,3 +918,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
+
diff --git a/clang/docs/BlockLanguageSpec.md b/clang/docs/BlockLanguageSpec.md
index 0c3a000be5c88..76dafe4e4244a 100644
--- a/clang/docs/BlockLanguageSpec.md
+++ b/clang/docs/BlockLanguageSpec.md
@@ -1,34 +1,31 @@
-
+```{eval-rst}
 .. role:: block-term
+```
 
-=================================
-Language Specification for Blocks
-=================================
+# Language Specification for Blocks
 
-.. contents::
-   :local:
+```{contents}
+:local: true
+```
 
-Revisions
-=========
+## Revisions
 
 - 2008/2/25 --- created
-- 2008/7/28 --- revised, ``__block`` syntax
+- 2008/7/28 --- revised, `__block` syntax
 - 2008/8/13 --- revised, Block globals
 - 2008/8/21 --- revised, C++ elaboration
-- 2008/11/1 --- revised, ``__weak`` support
+- 2008/11/1 --- revised, `__weak` support
 - 2009/1/12 --- revised, explicit return types
-- 2009/2/10 --- revised, ``__block`` objects need retain
+- 2009/2/10 --- revised, `__block` objects need retain
 
-Overview
-========
+## Overview
 
 A new derived type is introduced to C and, by extension, Objective-C,
 C++, and Objective-C++
 
-The Block Type
-==============
+## The Block Type
 
-Like function types, the :block-term:`Block type` is a pair consisting
+Like function types, the {block-term}`Block type` is a pair consisting
 of a result value type and a list of parameter types very similar to a
 function type. Blocks are intended to be used much like functions with
 the key distinction being that in addition to executable code they
@@ -37,62 +34,60 @@ also contain various variable bindings to automatic (stack) or managed
 
 The abstract declarator,
 
-.. code-block:: c
-
-   int (^)(char, float)
+```c
+int (^)(char, float)
+```
 
 describes a reference to a Block that, when invoked, takes two
 parameters, the first of type char and the second of type float, and
-returns a value of type int.  The Block referenced is of opaque data
+returns a value of type int. The Block referenced is of opaque data
 that may reside in automatic (stack) memory, global memory, or heap
 memory.
 
-Block Variable Declarations
-===========================
+## Block Variable Declarations
 
-A :block-term:`variable with Block type` is declared using function
-pointer style notation substituting ``^`` for ``*``. The following are
+A {block-term}`variable with Block type` is declared using function
+pointer style notation substituting `^` for `*`. The following are
 valid Block variable declarations:
 
-.. code-block:: c
-
-    void (^blockReturningVoidWithVoidArgument)(void);
-    int (^blockReturningIntWithIntAndCharArguments)(int, char);
-    void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);
+```c
+void (^blockReturningVoidWithVoidArgument)(void);
+int (^blockReturningIntWithIntAndCharArguments)(int, char);
+void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);
+```
 
-Variadic ``...`` arguments are supported. [variadic.c] A Block that
+Variadic `...` arguments are supported. [variadic.c] A Block that
 takes no arguments must specify void in the argument list [voidarg.c].
 An empty parameter list does not represent, as K&R provide, an
-unspecified argument list.  Note: both gcc and clang support K&R style
+unspecified argument list. Note: both gcc and clang support K&R style
 as a convenience.
 
 A Block reference may be cast to a pointer of arbitrary type and vice
 versa. [cast.c] A Block reference may not be dereferenced via the
-pointer dereference operator ``*``, and thus a Block's size may not be
+pointer dereference operator `*`, and thus a Block's size may not be
 computed at compile time. [sizeof.c]
 
-Block Literal Expressions
-=========================
+## Block Literal Expressions
 
-A :block-term:`Block literal expression` produces a reference to a
-Block. It is introduced by the use of the ``^`` token as a unary
+A {block-term}`Block literal expression` produces a reference to a
+Block. It is introduced by the use of the `^` token as a unary
 operator.
 
-.. code-block:: c
+```c
+Block_literal_expression ::=   ^ block_decl compound_statement_body
+block_decl ::=
+block_decl ::= parameter_list
+block_decl ::= type_expression
+```
 
-    Block_literal_expression ::=   ^ block_decl compound_statement_body
-    block_decl ::=
-    block_decl ::= parameter_list
-    block_decl ::= type_expression
-
-where type expression is extended to allow ``^`` as a Block reference
-(pointer) where ``*`` is allowed as a function reference (pointer).
+where type expression is extended to allow `^` as a Block reference
+(pointer) where `*` is allowed as a function reference (pointer).
 
 The following Block literal:
 
-.. code-block:: c
-
-    ^ void (void) { printf("hello world\n"); }
+```c
+^ void (void) { printf("hello world\n"); }
+```
 
 produces a reference to a Block with no arguments with no return value.
 
@@ -102,20 +97,20 @@ return a value of the same type. If there is no value returned the
 inferred type of the Block is void; otherwise it is the type of the
 return statement value.
 
-If the return type is omitted and the argument list is ``( void )``,
-the ``( void )`` argument list may also be omitted.
+If the return type is omitted and the argument list is `( void )`,
+the `( void )` argument list may also be omitted.
 
 So:
 
-.. code-block:: c
-
-    ^ ( void ) { printf("hello world\n"); }
+```c
+^ ( void ) { printf("hello world\n"); }
+```
 
 and:
 
-.. code-block:: c
-
-    ^ { printf("hello world\n"); }
+```c
+^ { printf("hello world\n"); }
+```
 
 are exactly equivalent constructs for the same expression.
 
@@ -125,23 +120,23 @@ declarations.
 
 Given:
 
-.. code-block:: c
-
-    typedef int (*pointerToFunctionThatReturnsIntWithCharArg)(char);
-    pointerToFunctionThatReturnsIntWithCharArg functionPointer;
-    ^ pointerToFunctionThatReturnsIntWithCharArg (float x) { return functionPointer; }
+```c
+typedef int (*pointerToFunctionThatReturnsIntWithCharArg)(char);
+pointerToFunctionThatReturnsIntWithCharArg functionPointer;
+^ pointerToFunctionThatReturnsIntWithCharArg (float x) { return functionPointer; }
+```
 
 and:
 
-.. code-block:: c
-
-    ^ int ((*)(float x))(char) { return functionPointer; }
+```c
+^ int ((*)(float x))(char) { return functionPointer; }
+```
 
 are equivalent expressions, as is:
 
-.. code-block:: c
-
-    ^(float x) { return functionPointer; }
+```c
+^(float x) { return functionPointer; }
+```
 
 [returnfunctionptr.c]
 
@@ -162,9 +157,9 @@ that no references to the variable will actually be evaluated.
 Programmers can force a variable to be captured by referencing it in a
 statement at the beginning of the Block, like so:
 
-.. code-block:: c
-
-  (void) foo;
+```c
+(void) foo;
+```
 
 This matters when capturing the variable has side-effects, as it can
 in Objective-C or C++.
@@ -182,84 +177,76 @@ also captured in the scopes of their enclosing Blocks.
 A Block literal expression may be used as the initialization value for
 Block variables at global or local static scope.
 
-The Invoke Operator
-===================
+## The Invoke Operator
 
-Blocks are :block-term:`invoked` using function call syntax with a
+Blocks are {block-term}`invoked` using function call syntax with a
 list of expression parameters of types corresponding to the
 declaration and returning a result type also according to the
 declaration. Given:
 
-.. code-block:: c
-
-    int (^x)(char);
-    void (^z)(void);
-    int (^(*y))(char) = &x;
+```c
+int (^x)(char);
+void (^z)(void);
+int (^(*y))(char) = &x;
+```
 
 the following are all legal Block invocations:
 
-.. code-block:: c
-
-    x('a');
-    (*y)('a');
-    (true ? x : *y)('a')
+```c
+x('a');
+(*y)('a');
+(true ? x : *y)('a')
+```
 
-The Copy and Release Operations
-===============================
+## The Copy and Release Operations
 
-The compiler and runtime provide :block-term:`copy` and
-:block-term:`release` operations for Block references that create and,
+The compiler and runtime provide {block-term}`copy` and
+{block-term}`release` operations for Block references that create and,
 in matched use, release allocated storage for referenced Blocks.
 
-The copy operation ``Block_copy()`` is styled as a function that takes
+The copy operation `Block_copy()` is styled as a function that takes
 an arbitrary Block reference and returns a Block reference of the same
-type. The release operation, ``Block_release()``, is styled as a
+type. The release operation, `Block_release()`, is styled as a
 function that takes an arbitrary Block reference and, if dynamically
 matched to a Block copy operation, allows recovery of the referenced
 allocated memory.
 
-
-The ``__block`` Storage Qualifier
-=================================
+## The `__block` Storage Qualifier
 
 In addition to the new Block type we also introduce a new storage
-qualifier, :block-term:`__block`, for local variables. [testme: a
-__block declaration within a block literal] The ``__block`` storage
+qualifier, {block-term}`__block`, for local variables. [testme: a
+\_\_block declaration within a block literal] The `__block` storage
 qualifier is mutually exclusive to the existing local storage
 qualifiers auto, register, and static. [testme] Variables qualified by
-``__block`` act as if they were in allocated storage and this storage
-is automatically recovered after last use of said variable.  An
+`__block` act as if they were in allocated storage and this storage
+is automatically recovered after last use of said variable. An
 implementation may choose an optimization where the storage is
 initially automatic and only "moved" to allocated (heap) storage upon
-a Block_copy of a referencing Block.  Such variables may be mutated as
+a Block_copy of a referencing Block. Such variables may be mutated as
 normal variables are.
 
-In the case where a ``__block`` variable is a Block one must assume
-that the ``__block`` variable resides in allocated storage and as such
+In the case where a `__block` variable is a Block one must assume
+that the `__block` variable resides in allocated storage and as such
 is assumed to reference a Block that is also in allocated storage
-(that it is the result of a ``Block_copy`` operation).  Despite this
-there is no provision to do a ``Block_copy`` or a ``Block_release`` if
-an implementation provides initial automatic storage for Blocks.  This
+(that it is the result of a `Block_copy` operation). Despite this
+there is no provision to do a `Block_copy` or a `Block_release` if
+an implementation provides initial automatic storage for Blocks. This
 is due to the inherent race condition of potentially several threads
 trying to update the shared variable and the need for synchronization
-around disposing of older values and copying new ones.  Such
+around disposing of older values and copying new ones. Such
 synchronization is beyond the scope of this language specification.
 
-
-Control Flow
-============
+## Control Flow
 
 The compound statement of a Block is treated much like a function body
 with respect to control flow in that goto, break, and continue do not
-escape the Block.  Exceptions are treated *normally* in that when
+escape the Block. Exceptions are treated *normally* in that when
 thrown they pop stack frames until a catch clause is found.
 
-
-Objective-C Extensions
-======================
+## Objective-C Extensions
 
 Objective-C extends the definition of a Block reference type to be
-that also of id.  A variable or expression of Block type may be
+that also of id. A variable or expression of Block type may be
 messaged or used as a parameter wherever an id may be. The converse is
 also true. Block references may thus appear as properties and are
 subject to the assign, retain, and copy attribute logic that is
@@ -268,7 +255,7 @@ reserved for objects.
 All Blocks are constructed to be Objective-C objects regardless of
 whether the Objective-C runtime is operational in the program or
 not. Blocks using automatic (stack) memory are objects and may be
-messaged, although they may not be assigned into ``__weak`` locations
+messaged, although they may not be assigned into `__weak` locations
 if garbage collection is enabled.
 
 Within a Block literal expression within a method definition
@@ -277,85 +264,84 @@ scope of the compound statement. These variables are implicitly
 qualified as references from self, and so self is imported as a const
 copy. The net effect is that instance variables can be mutated.
 
-The :block-term:`Block_copy` operator retains all objects held in
+The {block-term}`Block_copy` operator retains all objects held in
 variables of automatic storage referenced within the Block expression
 (or forms strong references if running under garbage collection).
-Object variables of ``__block`` storage type are assumed to hold
+Object variables of `__block` storage type are assumed to hold
 normal pointers with no provision for retain and release messages.
 
-Foundation defines (and supplies) ``-copy`` and ``-release`` methods for
+Foundation defines (and supplies) `-copy` and `-release` methods for
 Blocks.
 
 In the Objective-C and Objective-C++ languages, we allow the
-``__weak`` specifier for ``__block`` variables of object type.  If
+`__weak` specifier for `__block` variables of object type. If
 garbage collection is not enabled, this qualifier causes these
 variables to be kept without retain messages being sent. This
 knowingly leads to dangling pointers if the Block (or a copy) outlives
 the lifetime of this object.
 
-In garbage collected environments, the ``__weak`` variable is set to
+In garbage collected environments, the `__weak` variable is set to
 nil when the object it references is collected, as long as the
-``__block`` variable resides in the heap (either by default or via
-``Block_copy()``).  The initial Apple implementation does in fact
-start ``__block`` variables on the stack and migrate them to the heap
-only as a result of a ``Block_copy()`` operation.
+`__block` variable resides in the heap (either by default or via
+`Block_copy()`). The initial Apple implementation does in fact
+start `__block` variables on the stack and migrate them to the heap
+only as a result of a `Block_copy()` operation.
 
 It is a runtime error to attempt to assign a reference to a
-stack-based Block into any storage marked ``__weak``, including
-``__weak`` ``__block`` variables.
-
+stack-based Block into any storage marked `__weak`, including
+`__weak` `__block` variables.
 
-C++ Extensions
-==============
+## C++ Extensions
 
 Block literal expressions within functions are extended to allow const
 use of C++ objects, pointers, or references held in automatic storage.
 
 As usual, within the block, references to captured variables become
 const-qualified, as if they were references to members of a const
-object.  Note that this does not change the type of a variable of
+object. Note that this does not change the type of a variable of
 reference type.
 
 For example, given a class Foo:
 
-.. code-block:: c
-
-      Foo foo;
-      Foo &fooRef = foo;
-      Foo *fooPtr = &foo;
+```c
+Foo foo;
+Foo &fooRef = foo;
+Foo *fooPtr = &foo;
+```
 
 A Block that referenced these variables would import the variables as
 const variations:
 
-.. code-block:: c
-
-      const Foo block_foo = foo;
-      Foo &block_fooRef = fooRef;
-      Foo *const block_fooPtr = fooPtr;
+```c
+const Foo block_foo = foo;
+Foo &block_fooRef = fooRef;
+Foo *const block_fooPtr = fooPtr;
+```
 
 Captured variables are copied into the Block at the instant of
-evaluating the Block literal expression.  They are also copied when
-calling ``Block_copy()`` on a Block allocated on the stack.  In both
+evaluating the Block literal expression. They are also copied when
+calling `Block_copy()` on a Block allocated on the stack. In both
 cases, they are copied as if the variable were const-qualified, and
 it's an error if there's no such constructor.
 
 Captured variables in Blocks on the stack are destroyed when control
 leaves the compound statement that contains the Block literal
-expression.  Captured variables in Blocks on the heap are destroyed
+expression. Captured variables in Blocks on the heap are destroyed
 when the reference count of the Block drops to zero.
 
-Variables declared as residing in ``__block`` storage may be initially
+Variables declared as residing in `__block` storage may be initially
 allocated in the heap or may first appear on the stack and be copied
-to the heap as a result of a ``Block_copy()`` operation. When copied
-from the stack, ``__block`` variables are copied using their normal
-qualification (i.e. without adding const).  In C++11, ``__block``
+to the heap as a result of a `Block_copy()` operation. When copied
+from the stack, `__block` variables are copied using their normal
+qualification (i.e. without adding const). In C++11, `__block`
 variables are copied as x-values if that is possible, then as l-values
-if not; if both fail, it's an error.  The destructor for any initial
+if not; if both fail, it's an error. The destructor for any initial
 stack-based version is called at the variable's normal end of scope.
 
-References to ``this``, as well as references to non-static members of
-any enclosing class, are evaluated by capturing ``this`` just like a
+References to `this`, as well as references to non-static members of
+any enclosing class, are evaluated by capturing `this` just like a
 normal variable of C pointer type.
 
 Member variables that are Blocks may not be overloaded by the types of
 their arguments.
+
diff --git a/clang/docs/CIR/ABILowering.md b/clang/docs/CIR/ABILowering.md
index 3b5256a2c810c..59cd9bb6573f4 100644
--- a/clang/docs/CIR/ABILowering.md
+++ b/clang/docs/CIR/ABILowering.md
@@ -1,142 +1,133 @@
-====================================
-ClangIR ABI Lowering Design Document
-====================================
+# ClangIR ABI Lowering Design Document
 
-.. contents::
-   :local:
+```{contents}
+:local: true
+```
 
-Introduction
-============
+## Introduction
 
 This design describes calling convention lowering that builds on the LLVM ABI
-Lowering Library in ``llvm/lib/ABI/``: we use its ``abi::Type*`` and target ABI
+Lowering Library in `llvm/lib/ABI/`: we use its `abi::Type*` and target ABI
 logic and add an MLIR integration layer (ABITypeMapper, ABI lowering pass, and
-dialect rewriters).  The framework relies on the LLVM ABI library as the single
-source of truth for ABI classification.  MLIR dialects use it via an adapter
-layer.  The design provides a way to perform ABI-compliant calling convention
+dialect rewriters). The framework relies on the LLVM ABI library as the single
+source of truth for ABI classification. MLIR dialects use it via an adapter
+layer. The design provides a way to perform ABI-compliant calling convention
 lowering that can be used by any MLIR dialect that implements the necessary
-interfaces.  Inputs are high-level function signatures in CIR, FIR, or other
-MLIR dialect.  Outputs are ABI-lowered signatures and call sites.  Lowering
+interfaces. Inputs are high-level function signatures in CIR, FIR, or other
+MLIR dialect. Outputs are ABI-lowered signatures and call sites. Lowering
 runs as an MLIR pass in the compilation pipeline.
 
-Design Goals
-------------
+### Design Goals
 
 Building on the LLVM ABI library and adding an MLIR integration layer avoids
 duplicating complex ABI logic across MLIR dialects, reduces maintenance, and
-keeps a single source of ABI compliance in ``llvm/lib/ABI/``.  The separation
+keeps a single source of ABI compliance in `llvm/lib/ABI/`. The separation
 between the ABI library (classification) and dialect-specific ABIRewriteContext
 (rewriting) enables clearer testing and a straightforward migration path from
 the CIR incubator by porting useful algorithms into the ABI library where
 appropriate.
 
 A central goal is that generated code be call-compatible with Classic Clang
-CodeGen and other compilers.  Parity is with Classic Clang CodeGen output,
-not only with the incubator.  Success means CIR correctly lowers x86_64 and
+CodeGen and other compilers. Parity is with Classic Clang CodeGen output,
+not only with the incubator. Success means CIR correctly lowers x86_64 and
 AArch64 calling conventions with full ABI compliance using the LLVM ABI library
 and MLIR integration layer; FIR can adopt the same infrastructure with minimal
-dialect-specific adaptation (e.g.  cdecl when calling C from Fortran).  ABI
+dialect-specific adaptation (e.g. cdecl when calling C from Fortran). ABI
 compliance will be validated through differential testing against Classic Clang
 CodeGen, and performance overhead should remain under 5% compared to a direct,
-dialect-specific implementation.  Variadic calls are lowered on x86_64 by
+dialect-specific implementation. Variadic calls are lowered on x86_64 by
 classifying each call site from its own operand types, since an argument
 passed through an ellipsis competes for registers with the declared ones.
 An indirect variadic call whose operands already carry their wire form is left
-as written.  One that needs an ABI rewrite is deferred, as is variadic
+as written. One that needs an ABI rewrite is deferred, as is variadic
 lowering for other targets.
 
-Background and Context
-======================
+## Background and Context
 
-What is Calling Convention Lowering?
-------------------------------------
+### What is Calling Convention Lowering?
 
 Calling convention lowering transforms high-level function signatures to match
-target ABI (Application Binary Interface) requirements.  When a function is
+target ABI (Application Binary Interface) requirements. When a function is
 declared at the source level with convenient, language-level types, these types
 must be translated into the specific register assignments, memory layouts, and
-calling sequences that the target architecture expects.  For example, on x86_64
+calling sequences that the target architecture expects. For example, on x86_64
 System V ABI, a struct containing two 64-bit integers might be "expanded" into
 two separate arguments passed in registers, rather than being passed as a single
 aggregate:
 
-.. code-block::
-    
-    // High-level CIR
-    func @foo(i32, struct<i64, i64>) -> i32
+```
+// High-level CIR
+func @foo(i32, struct<i64, i64>) -> i32
 
-    // After ABI lowering
-    func @foo(i32 %arg0, i64 %arg1, i64 %arg2) -> i32
-    //        ^       ^            ^        ^
-    //        |       |            +--------+ struct expanded into fields
-    //        |       +---- first field passed in register
-    //        +---- small integer passed in register
+// After ABI lowering
+func @foo(i32 %arg0, i64 %arg1, i64 %arg2) -> i32
+//        ^       ^            ^        ^
+//        |       |            +--------+ struct expanded into fields
+//        |       +---- first field passed in register
+//        +---- small integer passed in register
+```
 
 Calling convention lowering is complex for several reasons: it is highly
 target-specific (each architecture has different rules for registers vs.
 memory), type-dependent (rules differ for integers, floats, structs, unions,
 arrays), and context-sensitive (varargs, virtual calls, conventions like
-vectorcall or preserve_most).  The same target may have multiple ABI variants
-(e.g.  x86_64 System V vs.  Windows x64), adding further complexity.
+vectorcall or preserve_most). The same target may have multiple ABI variants
+(e.g. x86_64 System V vs. Windows x64), adding further complexity.
 
-Existing Implementations
-------------------------
+### Existing Implementations
 
-Classic Clang CodeGen
-^^^^^^^^^^^^^^^^^^^^^
+#### Classic Clang CodeGen
 
-Classic Clang CodeGen (located in ``clang/lib/CodeGen/``) transforms calling
-conventions during the AST-to-LLVM-IR lowering process.  This implementation is
+Classic Clang CodeGen (located in `clang/lib/CodeGen/`) transforms calling
+conventions during the AST-to-LLVM-IR lowering process. This implementation is
 mature and well-tested, handling all supported targets with comprehensive ABI
-coverage.  However, it's tightly coupled to both Clang's AST representation and
+coverage. However, it's tightly coupled to both Clang's AST representation and
 LLVM IR, making it difficult to reuse for MLIR-based frontends.
 
-CIR Incubator
-^^^^^^^^^^^^^
+#### CIR Incubator
 
 The CIR incubator includes a calling convention lowering pass in
-``clang/lib/CIR/Dialect/Transforms/TargetLowering/`` that transforms CIR
-operations into ABI-lowered CIR operations as an MLIR pass.  This implementation
+`clang/lib/CIR/Dialect/Transforms/TargetLowering/` that transforms CIR
+operations into ABI-lowered CIR operations as an MLIR pass. This implementation
 successfully adapted logic from Classic Clang CodeGen to work within the MLIR
-framework.  However, it relies on CIR-specific types and operations, preventing
+framework. However, it relies on CIR-specific types and operations, preventing
 reuse by other MLIR dialects.
 
-LLVM ABI Lowering Library
-^^^^^^^^^^^^^^^^^^^^^^^^^
+#### LLVM ABI Lowering Library
 
-A 2025 Google Summer of Code project produced `PR
-#140112 <https://github.com/llvm/llvm-project/pull/140112>`__, which proposes
-extracting Clang's ABI logic into a reusable library in ``llvm/lib/ABI/``.  The
-design centers on a shadow type system (``abi::Type*``) separate from both
+A 2025 Google Summer of Code project produced [PR
+#140112](https://github.com/llvm/llvm-project/pull/140112), which proposes
+extracting Clang's ABI logic into a reusable library in `llvm/lib/ABI/`. The
+design centers on a shadow type system (`abi::Type*`) separate from both
 Clang's AST types and LLVM IR types, enabling the ABI classification algorithms
-to work independently of any specific frontend representation.  The library
-includes abstract ``ABIInfo`` base classes and target-specific implementations
-(e.g. x86_64, BPF) and provides QualTypeMapper for Clang to map ``QualType`` to
-``abi::Type*``.
+to work independently of any specific frontend representation. The library
+includes abstract `ABIInfo` base classes and target-specific implementations
+(e.g. x86_64, BPF) and provides QualTypeMapper for Clang to map `QualType` to
+`abi::Type*`.
 
 Our approach is to complete and extend this library and use it as the single
-source of truth for ABI classification.  One implementation in one place reduces
+source of truth for ABI classification. One implementation in one place reduces
 duplication, simplifies bug fixes, and creates a path for Classic Clang CodeGen
-to use the same logic in the future.  MLIR dialects (CIR, FIR, and others) will
+to use the same logic in the future. MLIR dialects (CIR, FIR, and others) will
 use the library via an adapter layer rather than reimplementing ABI logic.
 
 **Current state.** The x86_64 implementation is largely complete and under
-review.  AArch64 and some other targets are not yet implemented; there is no
-MLIR integration today.  The work is being upstreamed in smaller parts (e.g.
-`PR 158329 <https://github.com/llvm/llvm-project/pull/158329>`__); progress is
-limited by reviewer bandwidth.  The overhead of the shadow type system
-(converting to and from ``abi::Type*``) has been measured at under 0.1% for clang
--O0, so it is negligible for CIR.  Our approach therefore depends on the ABI
+review. AArch64 and some other targets are not yet implemented; there is no
+MLIR integration today. The work is being upstreamed in smaller parts (e.g.
+[PR 158329](https://github.com/llvm/llvm-project/pull/158329)); progress is
+limited by reviewer bandwidth. The overhead of the shadow type system
+(converting to and from `abi::Type*`) has been measured at under 0.1% for clang
+-O0, so it is negligible for CIR. Our approach therefore depends on the ABI
 library being merged upstream or our contributions to it being accepted.
 
 **Our approach.** The approach is to complete and extend the ABI library (e.g.
 AArch64, review feedback, tests) and add an **MLIR integration layer** so that
 MLIR dialects can use it:
 
-* **ABITypeMapper**: maps ``mlir::Type`` to ``abi::Type*``, analogous to
+- **ABITypeMapper**: maps `mlir::Type` to `abi::Type*`, analogous to
   QualTypeMapper for Clang.
-* **MLIR ABI lowering pass**: uses the library's ``ABIInfo`` for classification,
-  then performs dialect-specific rewriting via ``ABIRewriteContext`` for CIR,
+- **MLIR ABI lowering pass**: uses the library's `ABIInfo` for classification,
+  then performs dialect-specific rewriting via `ABIRewriteContext` for CIR,
   FIR, and other dialects.
 
 The CIR incubator serves as a **reference only** (e.g. for AArch64 algorithms).
@@ -144,497 +135,474 @@ We do not upstream the incubator's CIR-specific ABI implementation as the
 long-term solution; we port useful algorithms into the ABI library where
 appropriate.
 
-Requirements for MLIR Dialects
-------------------------------
+### Requirements for MLIR Dialects
 
 CIR needs to lower C/C++ calling conventions correctly, with initial support for
-x86_64 and AArch64 targets.  It must handle structs, unions, and complex types,
-as well as support instance methods and virtual calls.  FIR's initial need is
+x86_64 and AArch64 targets. It must handle structs, unions, and complex types,
+as well as support instance methods and virtual calls. FIR's initial need is
 **cdecl for calling C from Fortran** (C interop); that is in scope.
-Fortran-specific ABI semantics (e.g.  CHARACTER hidden length parameters, array
+Fortran-specific ABI semantics (e.g. CHARACTER hidden length parameters, array
 descriptors) are out of initial scope; full Fortran ABI lowering is a broader
-goal.  Both dialects share common requirements: strict target ABI compliance,
+goal. Both dialects share common requirements: strict target ABI compliance,
 efficient lowering with minimal overhead, extensibility for adding new target
 architectures, and comprehensive testability and validation capabilities.
 
-Proposed Solution
-=================
+## Proposed Solution
 
-**Core.** The LLVM ABI library in ``llvm/lib/ABI/`` performs ABI classification
-on ``abi::Type*``.  It provides ``ABIInfo`` and target-specific implementations
-(x86_64, BPF, and eventually AArch64 and others).  This is the single place
+**Core.** The LLVM ABI library in `llvm/lib/ABI/` performs ABI classification
+on `abi::Type*`. It provides `ABIInfo` and target-specific implementations
+(x86_64, BPF, and eventually AArch64 and others). This is the single place
 where ABI rules are implemented.
 
 **MLIR side.** To use this library from MLIR dialects we add an integration
-layer: (1) **ABITypeMapper** maps ``mlir::Type`` to ``abi::Type*`` (analogous to
-QualTypeMapper for Clang).  (2) A **generic ABI lowering pass** invokes the
-library's ``ABIInfo`` for classification, then (3) performs **dialect-specific
-rewriting** via the ``ABIRewriteContext`` interface—each dialect (CIR, FIR,
-etc.) implements only the glue to create its own operations (e.g. ``cir.call``,
-``fir.call``).  Classification logic is shared; operation creation is
+layer: (1) **ABITypeMapper** maps `mlir::Type` to `abi::Type*` (analogous to
+QualTypeMapper for Clang). (2) A **generic ABI lowering pass** invokes the
+library's `ABIInfo` for classification, then (3) performs **dialect-specific
+rewriting** via the `ABIRewriteContext` interface—each dialect (CIR, FIR,
+etc.) implements only the glue to create its own operations (e.g. `cir.call`,
+`fir.call`). Classification logic is shared; operation creation is
 dialect-specific.
 
-The following diagram shows the layering.  At the top, the ABI library holds
-the ABI logic.  In the middle, adapters connect frontends to it: Classic Clang
+The following diagram shows the layering. At the top, the ABI library holds
+the ABI logic. In the middle, adapters connect frontends to it: Classic Clang
 CodeGen uses QualTypeMapper; MLIR uses ABITypeMapper and the ABI lowering pass.
-At the bottom, each dialect implements ``ABIRewriteContext`` only; FIR is shown
+At the bottom, each dialect implements `ABIRewriteContext` only; FIR is shown
 as a consumer for cdecl/C interop (e.g. calling C from Fortran).
 
-.. code-block::
-
-    ┌─────────────────────────────────────────────────────────────────┐
-    │  LLVM ABI Library (llvm/lib/ABI/)                               │
-    │  ABIInfo, abi::Type*, target implementations (X86, AArch64,…)   │
-    └─────────────────────────────────────────────────────────────────┘
-                                  │
-                ┌─────────────────┴─────────────────┐
-                │                                   │
-                ▼                                   ▼
-    ┌───────────────────────┐         ┌───────────────────────────────┐
-    │  Classic CodeGen      │         │  MLIR adapter                 │
-    │  QualTypeMapper       │         │  ABITypeMapper + ABI pass     │
-    └───────────────────────┘         └───────────────────────────────┘
-                                                    │
-                                   ┌────────────────┼────────────────┐
-                                   │                │                │
-                                   ▼                ▼                ▼
-                             ┌────────────┐   ┌────────────┐   ┌────────────┐
-                             │ CIR        │   │ FIR        │   │ Future     │
-                             │ ABIRewrite │   │ (cdecl/C   │   │ Dialects   │
-                             │ Context    │   │  interop)  │   │            │
-                             └────────────┘   └────────────┘   └────────────┘
-
-Design Overview
-===============
-
-Architecture Diagram
---------------------
+```
+┌─────────────────────────────────────────────────────────────────┐
+│  LLVM ABI Library (llvm/lib/ABI/)                               │
+│  ABIInfo, abi::Type*, target implementations (X86, AArch64,…)   │
+└─────────────────────────────────────────────────────────────────┘
+                              │
+            ┌─────────────────┴─────────────────┐
+            │                                   │
+            ▼                                   ▼
+┌───────────────────────┐         ┌───────────────────────────────┐
+│  Classic CodeGen      │         │  MLIR adapter                 │
+│  QualTypeMapper       │         │  ABITypeMapper + ABI pass     │
+└───────────────────────┘         └───────────────────────────────┘
+                                                │
+                               ┌────────────────┼────────────────┐
+                               │                │                │
+                               ▼                ▼                ▼
+                         ┌────────────┐   ┌────────────┐   ┌────────────┐
+                         │ CIR        │   │ FIR        │   │ Future     │
+                         │ ABIRewrite │   │ (cdecl/C   │   │ Dialects   │
+                         │ Context    │   │  interop)  │   │            │
+                         └────────────┘   └────────────┘   └────────────┘
+```
+
+## Design Overview
+
+### Architecture Diagram
 
 The following diagram shows how the design builds on the ABI library (Section
-3).  At the top, the ABI library holds the classification logic.  The middle
-layer adapts MLIR to the ABI library: ABITypeMapper converts ``mlir::Type`` to
-``abi::Type*``, and the MLIR ABI lowering pass invokes the library's ``ABIInfo``
-and uses the classification to drive rewriting.  At the bottom, each dialect
-implements only ``ABIRewriteContext`` for operation creation; there is no
+3). At the top, the ABI library holds the classification logic. The middle
+layer adapts MLIR to the ABI library: ABITypeMapper converts `mlir::Type` to
+`abi::Type*`, and the MLIR ABI lowering pass invokes the library's `ABIInfo`
+and uses the classification to drive rewriting. At the bottom, each dialect
+implements only `ABIRewriteContext` for operation creation; there is no
 separate type abstraction layer in MLIR for classification—that lives in the ABI
 library.
 
-.. code-block::
-
-    ┌─────────────────────────────────────────────────────────────────────────┐
-    │  LLVM ABI Library (llvm/lib/ABI/) — single source of truth              │
-    │  abi::Type*, ABIInfo, target implementations (X86_64, AArch64, …)       │
-    │  Input: abi::Type*  →  Output: classification (ABIArgInfo, etc.)        │
-    └─────────────────────────────────────────────────────────────────────────┘
-                                          │
-                                          ▼
-    ┌─────────────────────────────────────────────────────────────────────────┐
-    │  MLIR adapter                                                           │
-    │  ABITypeMapper (mlir::Type → abi::Type*)  +  MLIR ABI lowering pass     │
-    │  (1) Map types  (2) Call ABIInfo  (3) Drive rewriting from              │
-    │  classification result                                                  │
-    └─────────────────────────────────────────────────────────────────────────┘
-                                          │
-                        ┌─────────────────┼─────────────────┐
-                        ▼                 ▼                 ▼
-                  ┌────────────┐    ┌────────────┐    ┌────────────┐
-                  │ CIR        │    │ FIR        │    │ Future     │
-                  │ ABIRewrite │    │ ABIRewrite │    │ Dialects   │
-                  │ Context    │    │ Context    │    │            │
-                  └────────────┘    └────────────┘    └────────────┘
-                  Dialect-specific operation creation only (no type
-                  abstraction for classification in MLIR)
-
-ABI Library, Adapter, and Dialect Layers
-----------------------------------------
-
-The architecture has three parts.  **The ABI library** (``llvm/lib/ABI/``) is
-the single source of truth for ABI classification: it operates on ``abi::Type*``
-and produces classification results (e.g.  ABIArgInfo, ABIFunctionInfo).
-Target-specific ``ABIInfo`` implementations (X86_64, AArch64, etc.) live there.
-The **adapter layer** is MLIR-specific: ABITypeMapper maps ``mlir::Type`` to
-``abi::Type*``, and the MLIR ABI lowering pass (1) maps types, (2) calls the
-library's ABIInfo, and (3) uses the classification to drive rewriting.  The
+```
+┌─────────────────────────────────────────────────────────────────────────┐
+│  LLVM ABI Library (llvm/lib/ABI/) — single source of truth              │
+│  abi::Type*, ABIInfo, target implementations (X86_64, AArch64, …)       │
+│  Input: abi::Type*  →  Output: classification (ABIArgInfo, etc.)        │
+└─────────────────────────────────────────────────────────────────────────┘
+                                      │
+                                      ▼
+┌─────────────────────────────────────────────────────────────────────────┐
+│  MLIR adapter                                                           │
+│  ABITypeMapper (mlir::Type → abi::Type*)  +  MLIR ABI lowering pass     │
+│  (1) Map types  (2) Call ABIInfo  (3) Drive rewriting from              │
+│  classification result                                                  │
+└─────────────────────────────────────────────────────────────────────────┘
+                                      │
+                    ┌─────────────────┼─────────────────┐
+                    ▼                 ▼                 ▼
+              ┌────────────┐    ┌────────────┐    ┌────────────┐
+              │ CIR        │    │ FIR        │    │ Future     │
+              │ ABIRewrite │    │ ABIRewrite │    │ Dialects   │
+              │ Context    │    │ Context    │    │            │
+              └────────────┘    └────────────┘    └────────────┘
+              Dialect-specific operation creation only (no type
+              abstraction for classification in MLIR)
+```
+
+### ABI Library, Adapter, and Dialect Layers
+
+The architecture has three parts. **The ABI library** (`llvm/lib/ABI/`) is
+the single source of truth for ABI classification: it operates on `abi::Type*`
+and produces classification results (e.g. ABIArgInfo, ABIFunctionInfo).
+Target-specific `ABIInfo` implementations (X86_64, AArch64, etc.) live there.
+The **adapter layer** is MLIR-specific: ABITypeMapper maps `mlir::Type` to
+`abi::Type*`, and the MLIR ABI lowering pass (1) maps types, (2) calls the
+library's ABIInfo, and (3) uses the classification to drive rewriting. The
 **dialect layer** is only ABIRewriteContext: each dialect (CIR, FIR) implements
 operation creation (createFunction, createCall, createExtractValue, etc.).
 There is no type abstraction layer in MLIR for classification; type queries for
-ABI are performed on ``abi::Type*`` inside the ABI library.
+ABI are performed on `abi::Type*` inside the ABI library.
 
-Key Components
---------------
+### Key Components
 
-The framework is built from the following components.  **The ABI library**
-(``llvm/lib/ABI/``) provides the single source of truth for ABI classification:
-the ``abi::Type*`` type system, the ``ABIInfo`` base and target-specific
-implementations (e.g.  X86_64, AArch64), and the classification result types
-(e.g.  ABIArgInfo, ABIFunctionInfo).  **ABITypeMapper** maps ``mlir::Type`` to
-``abi::Type*`` so that MLIR dialect types can be classified by the ABI library.
+The framework is built from the following components. **The ABI library**
+(`llvm/lib/ABI/`) provides the single source of truth for ABI classification:
+the `abi::Type*` type system, the `ABIInfo` base and target-specific
+implementations (e.g. X86_64, AArch64), and the classification result types
+(e.g. ABIArgInfo, ABIFunctionInfo). **ABITypeMapper** maps `mlir::Type` to
+`abi::Type*` so that MLIR dialect types can be classified by the ABI library.
 The generic mapper relies on existing MLIR type interfaces (e.g.
-``DataLayoutTypeInterface``) for size and alignment, and pattern-matches on
+`DataLayoutTypeInterface`) for size and alignment, and pattern-matches on
 standard type categories (integers, floats, pointers, structs, arrays,
-vectors) to build ``abi::Type*``.  Dialects whose types do not conform to
-standard MLIR type categories (e.g.  CIR's ``cir::IntType`` is not
-``mlir::IntegerType``) may need dialect-aware mapping alongside the generic
+vectors) to build `abi::Type*`. Dialects whose types do not conform to
+standard MLIR type categories (e.g. CIR's `cir::IntType` is not
+`mlir::IntegerType`) may need dialect-aware mapping alongside the generic
 mapper to preserve semantics such as signedness, pointer identity, and
 record field structure.
 
 The **MLIR ABI lowering pass** orchestrates the flow: it uses ABITypeMapper,
 calls the library's ABIInfo, and drives rewriting from the classification
-result.  **ABIRewriteContext** is the dialect-specific interface for operation
-creation (each dialect implements it to produce e.g.  cir.call, fir.call).  A
+result. **ABIRewriteContext** is the dialect-specific interface for operation
+creation (each dialect implements it to produce e.g. cir.call, fir.call). A
 **target registry** (or equivalent) is used to select the appropriate ABIInfo
-for the compilation target.  There is no ABITypeInterface or separate "ABIInfo
+for the compilation target. There is no ABITypeInterface or separate "ABIInfo
 in MLIR"; classification lives entirely in the ABI library.
 
-ABI Lowering Flow: How the Pieces Fit Together
-----------------------------------------------
+### ABI Lowering Flow: How the Pieces Fit Together
 
 This section describes the end-to-end flow of ABI lowering, showing how all
 interfaces and components work together.
 
-Step 1: Function Signature Analysis
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Step 1: Function Signature Analysis
 
-The ABI lowering pass begins by analyzing the function signature.  Function
-operations are identified via MLIR's ``FunctionOpInterface``, which provides
-access to the function type, argument types, and return types.  The pass
+The ABI lowering pass begins by analyzing the function signature. Function
+operations are identified via MLIR's `FunctionOpInterface`, which provides
+access to the function type, argument types, and return types. The pass
 extracts the parameter types and return type to prepare them for classification.
 At this stage, the types are still in their high-level, dialect-specific form
-(e.g., ``!cir.struct`` for CIR, or ``!fir.type`` for FIR).  The pass collect
+(e.g., `!cir.struct` for CIR, or `!fir.type` for FIR). The pass collect
 these types into a list that will be fed to the classification logic in the next
 step.
 
-.. code-block::
+```
+Input: func @foo(%arg0: !cir.int<u, 32>,
+       %arg1: !cir.struct<{!cir.int<u, 64>,
+                            !cir.int<u, 64>}>) -> !cir.int<u, 32>
+```
 
-    Input: func @foo(%arg0: !cir.int<u, 32>,
-           %arg1: !cir.struct<{!cir.int<u, 64>,
-                                !cir.int<u, 64>}>) -> !cir.int<u, 32>
+#### Step 2: Type Mapping via ABITypeMapper
 
-Step 2: Type Mapping via ABITypeMapper
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-For each argument and the return type, the pass maps ``mlir::Type`` to
-``abi::Type*`` using ABITypeMapper.  The mapper produces the representation that
+For each argument and the return type, the pass maps `mlir::Type` to
+`abi::Type*` using ABITypeMapper. The mapper produces the representation that
 the library's ABIInfo expects; optionally, it can map back to MLIR types for
 coercion types when needed.
 
-.. code-block:: c++
-
-  // Map dialect types to the library's type system
-  ABITypeMapper abiTypeMapper(module.getDataLayout());
-  abi::Type *arg0Abi = abiTypeMapper.map(arg0Type);   // i32 -> IntegerType
-  abi::Type *arg1Abi = abiTypeMapper.map(arg1Type);   // struct -> RecordType
-  abi::Type *retAbi = abiTypeMapper.map(returnType);
+```c++
+// Map dialect types to the library's type system
+ABITypeMapper abiTypeMapper(module.getDataLayout());
+abi::Type *arg0Abi = abiTypeMapper.map(arg0Type);   // i32 -> IntegerType
+abi::Type *arg1Abi = abiTypeMapper.map(arg1Type);   // struct -> RecordType
+abi::Type *retAbi = abiTypeMapper.map(returnType);
+```
 
-**Key Point**: Classification runs in the ABI library on ``abi::Type*``;
+**Key Point**: Classification runs in the ABI library on `abi::Type*`;
 ABITypeMapper is the only bridge from dialect types to that representation.
 
-Step 3: ABI Classification
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The library's target-specific ``ABIInfo`` (e.g.  X86_64) performs classification
-on ``abi::Type*`` and produces the library's classification result
-(e.g.  ABIFunctionInfo and ABIArgInfo as defined in ``llvm/lib/ABI/``):
-
-.. code-block:: c++
+#### Step 3: ABI Classification
 
-    // The MLIR ABI lowering pass obtains the ABIInfo from the target
-    // registry based on the module's target triple (see Section 5.2).
-    llvm::abi::ABIInfo *abiInfo = getABIInfo();  // e.g. X86_64
-    llvm::abi::ABIFunctionInfo abiFI;
-    abiInfo->computeInfo(abiFI, arg0Abi, arg1Abi, retAbi);
-    // For struct<i64,i64> on x86_64: produces Expand (two i64 args)
+The library's target-specific `ABIInfo` (e.g. X86_64) performs classification
+on `abi::Type*` and produces the library's classification result
+(e.g. ABIFunctionInfo and ABIArgInfo as defined in `llvm/lib/ABI/`):
 
+```c++
+// The MLIR ABI lowering pass obtains the ABIInfo from the target
+// registry based on the module's target triple (see Section 5.2).
+llvm::abi::ABIInfo *abiInfo = getABIInfo();  // e.g. X86_64
+llvm::abi::ABIFunctionInfo abiFI;
+abiInfo->computeInfo(abiFI, arg0Abi, arg1Abi, retAbi);
+// For struct<i64,i64> on x86_64: produces Expand (two i64 args)
+```
 
-Output: the library's classification (e.g.  ABIFunctionInfo) for all arguments
+Output: the library's classification (e.g. ABIFunctionInfo) for all arguments
 and return:
-* ``%arg0 (i32)`` → Direct (pass as-is)
-* ``%arg1 (struct)`` → Expand (split into two i64 fields)
-* Return type → Direct
+\* `%arg0 (i32)` → Direct (pass as-is)
+\* `%arg1 (struct)` → Expand (split into two i64 fields)
+\* Return type → Direct
 
-Step 4: Function Signature Rewriting
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Step 4: Function Signature Rewriting
 
 After the library's classification is complete, the pass rewrites the function
-to match the ABI requirements using the dialect's `ABIRewriteContext`.  The
+to match the ABI requirements using the dialect's `ABIRewriteContext`. The
 classification result (from the ABI library) describes the lowered signature;
-the rewrite context creates the actual dialect operations.  For example, if a
+the rewrite context creates the actual dialect operations. For example, if a
 struct is classified as "Expand", the new function signature will have multiple
 scalar parameters instead of the single struct parameter.
 
-.. code-block:: c++
+```c++
+ABIRewriteContext &ctx = getDialectRewriteContext();
 
-    ABIRewriteContext &ctx = getDialectRewriteContext();
+// Create new function with lowered signature
+FunctionType newType = ...; // (i32, i64, i64) -> i32
+Operation *newFunc = ctx.createFunction(loc, "foo", newType);
+```
 
-    // Create new function with lowered signature
-    FunctionType newType = ...; // (i32, i64, i64) -> i32
-    Operation *newFunc = ctx.createFunction(loc, "foo", newType);
-
-**Key Point**: The original function had signature ``(i32, struct) -> i32``, but
-the ABI-lowered function has signature ``(i32, i64, i64) -> i32`` with the
+**Key Point**: The original function had signature `(i32, struct) -> i32`, but
+the ABI-lowered function has signature `(i32, i64, i64) -> i32` with the
 struct expanded into its constituent fields.
 
-Step 5: Argument Expansion
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Step 5: Argument Expansion
 
 With the function signature rewritten, the pass updates all call sites to match
 the new signature, using the classification from the ABI library to drive
-rewriting via ``ABIRewriteContext``.  For arguments classified as "Expand", the
-pass breaks down the aggregate into its constituent parts (e.g.  struct into two
+rewriting via `ABIRewriteContext`. For arguments classified as "Expand", the
+pass breaks down the aggregate into its constituent parts (e.g. struct into two
 i64 values). The rewrite context provides operations to extract fields and
 construct the new call with the expanded argument list.
 
-.. code-block:: c++
-
-    // Original call: call @foo(%val0, %structVal)
-    // Need to extract struct fields:
+```c++
+// Original call: call @foo(%val0, %structVal)
+// Need to extract struct fields:
 
-    Value field0 = ctx.createExtractValue(loc, structVal, {0}); // extract 1st i64
-    Value field1 = ctx.createExtractValue(loc, structVal, {1}); // extract 2nd i64
+Value field0 = ctx.createExtractValue(loc, structVal, {0}); // extract 1st i64
+Value field1 = ctx.createExtractValue(loc, structVal, {1}); // extract 2nd i64
 
-    // New call with expanded arguments
-    ctx.createCall(loc, newFunc, {resultType}, {val0, field0, field1});
+// New call with expanded arguments
+ctx.createCall(loc, newFunc, {resultType}, {val0, field0, field1});
+```
 
-**Key Point**: ``ABIRewriteContext`` abstracts the dialect-specific operation
+**Key Point**: `ABIRewriteContext` abstracts the dialect-specific operation
 creation, so the lowering logic doesn't need to know about CIR operations.
 
-Step 6: Return Value Handling
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Step 6: Return Value Handling
 
 For functions returning large structs (indirect return):
 
-.. code-block:: c++
+```c++
+// If return type is classified as Indirect:
+Value sretPtr = ctx.createAlloca(loc, retType, alignment);
+ctx.createCall(loc, func, {}, {sretPtr, ...otherArgs});
+Value result = ctx.createLoad(loc, sretPtr);
+```
 
-    // If return type is classified as Indirect:
-    Value sretPtr = ctx.createAlloca(loc, retType, alignment);
-    ctx.createCall(loc, func, {}, {sretPtr, ...otherArgs});
-    Value result = ctx.createLoad(loc, sretPtr);
-
-Complete Flow Diagram
-^^^^^^^^^^^^^^^^^^^^^
+#### Complete Flow Diagram
 
 The diagram below combines the three-layer architecture (Section 4.1) with the
 step-by-step flow, showing which layer owns each step.
 
-.. code-block::
-
-     ┌─────────────────────────────────────────────────────────┐
-     │ Input: High-Level Function (CIR/FIR/other dialect)      │
-     │   func @foo(%arg0: i32, %arg1: struct<i64,i64>) -> i32  │
-     └──────────────────────────┬──────────────────────────────┘
-                                │
-    ╔═══════════════════════════╪═══════════════════════════════╗
-    ║  MLIR Adapter Layer       │                               ║
-    ║                           ▼                               ║
-    ║  Step 1: Extract types from FunctionOpInterface           ║
-    ║            arg0: mlir::Type, arg1: mlir::Type, ret: …     ║
-    ║                           │                               ║
-    ║                           ▼                               ║
-    ║  Step 2: ABITypeMapper    │                               ║
-    ║            mlir::Type ──> abi::Type*                      ║
-    ║            (uses DataLayoutTypeInterface for size/align)  ║
-    ╚═══════════════════════════╪═══════════════════════════════╝
-                                │
-    ╔═══════════════════════════╪═══════════════════════════════╗
-    ║  LLVM ABI Library         │  (llvm/lib/ABI/)              ║
-    ║                           ▼                               ║
-    ║  Step 3: ABIInfo::computeInfo() on abi::Type*             ║
-    ║            Applies target rules (e.g. x86_64 System V)    ║
-    ║            Produces: ABIArgInfo per arg/return            ║
-    ║              arg0 (i32)   → Direct                        ║
-    ║              arg1 (struct)→ Expand (two i64 fields)       ║
-    ║              return (i32) → Direct                        ║
-    ╚═══════════════════════════╪═══════════════════════════════╝
-                                │
-    ╔═══════════════════════════╪═══════════════════════════════╗
-    ║  Dialect-Specific Layer   │  (ABIRewriteContext)          ║
-    ║                           ▼                               ║
-    ║  Step 4: Rewrite function signature                       ║
-    ║            (i32, struct) -> i32                           ║
-    ║            becomes (i32, i64, i64) -> i32                 ║
-    ║                           │                               ║
-    ║                           ▼                               ║
-    ║  Step 5: Rewrite call sites                               ║
-    ║            createExtractValue() to expand struct args     ║
-    ║            createCall() with lowered arg list             ║
-    ║                           │                               ║
-    ║                           ▼                               ║
-    ║  Step 6: Handle return values                             ║
-    ║            Indirect: createAlloca + sret pointer          ║
-    ║            Coerced: memory-based reinterpretation         ║
-    ╚═══════════════════════════╪═══════════════════════════════╝
-                                │
-                                ▼
-     ┌─────────────────────────────────────────────────────────┐
-     │ Output: ABI-Lowered Function                            │
-     │   func @foo(%arg0: i32, %arg1: i64, %arg2: i64) -> i32  │
-     └─────────────────────────────────────────────────────────┘
-
-Key Interactions Between Components
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Classification lives in the ABI library: ``ABIInfo`` operates on ``abi::Type*``
-and produces classification results (e.g.  ABIArgInfo, ABIFunctionInfo).  MLIR
+```
+ ┌─────────────────────────────────────────────────────────┐
+ │ Input: High-Level Function (CIR/FIR/other dialect)      │
+ │   func @foo(%arg0: i32, %arg1: struct<i64,i64>) -> i32  │
+ └──────────────────────────┬──────────────────────────────┘
+                            │
+╔═══════════════════════════╪═══════════════════════════════╗
+║  MLIR Adapter Layer       │                               ║
+║                           ▼                               ║
+║  Step 1: Extract types from FunctionOpInterface           ║
+║            arg0: mlir::Type, arg1: mlir::Type, ret: …     ║
+║                           │                               ║
+║                           ▼                               ║
+║  Step 2: ABITypeMapper    │                               ║
+║            mlir::Type ──> abi::Type*                      ║
+║            (uses DataLayoutTypeInterface for size/align)  ║
+╚═══════════════════════════╪═══════════════════════════════╝
+                            │
+╔═══════════════════════════╪═══════════════════════════════╗
+║  LLVM ABI Library         │  (llvm/lib/ABI/)              ║
+║                           ▼                               ║
+║  Step 3: ABIInfo::computeInfo() on abi::Type*             ║
+║            Applies target rules (e.g. x86_64 System V)    ║
+║            Produces: ABIArgInfo per arg/return            ║
+║              arg0 (i32)   → Direct                        ║
+║              arg1 (struct)→ Expand (two i64 fields)       ║
+║              return (i32) → Direct                        ║
+╚═══════════════════════════╪═══════════════════════════════╝
+                            │
+╔═══════════════════════════╪═══════════════════════════════╗
+║  Dialect-Specific Layer   │  (ABIRewriteContext)          ║
+║                           ▼                               ║
+║  Step 4: Rewrite function signature                       ║
+║            (i32, struct) -> i32                           ║
+║            becomes (i32, i64, i64) -> i32                 ║
+║                           │                               ║
+║                           ▼                               ║
+║  Step 5: Rewrite call sites                               ║
+║            createExtractValue() to expand struct args     ║
+║            createCall() with lowered arg list             ║
+║                           │                               ║
+║                           ▼                               ║
+║  Step 6: Handle return values                             ║
+║            Indirect: createAlloca + sret pointer          ║
+║            Coerced: memory-based reinterpretation         ║
+╚═══════════════════════════╪═══════════════════════════════╝
+                            │
+                            ▼
+ ┌─────────────────────────────────────────────────────────┐
+ │ Output: ABI-Lowered Function                            │
+ │   func @foo(%arg0: i32, %arg1: i64, %arg2: i64) -> i32  │
+ └─────────────────────────────────────────────────────────┘
+```
+
+#### Key Interactions Between Components
+
+Classification lives in the ABI library: `ABIInfo` operates on `abi::Type*`
+and produces classification results (e.g. ABIArgInfo, ABIFunctionInfo). MLIR
 types reach the ABI library only via ABITypeMapper, which converts
-``mlir::Type`` to ``abi::Type*``.  The lowering pass (1) maps types with
+`mlir::Type` to `abi::Type*`. The lowering pass (1) maps types with
 ABITypeMapper, (2) calls the library's ABIInfo to get classification, and (3)
 uses that result to drive rewriting through the dialect's ABIRewriteContext.
 
-ABIRewriteContext consumes the classification (e.g.  "Expand" for a struct) and
+ABIRewriteContext consumes the classification (e.g. "Expand" for a struct) and
 performs the actual IR changes: createFunction with the lowered signature,
-createExtractValue and createCall at call sites.  Each dialect implements
-ABIRewriteContext to produce its own operations (e.g.  cir.call, fir.call).
+createExtractValue and createCall at call sites. Each dialect implements
+ABIRewriteContext to produce its own operations (e.g. cir.call, fir.call).
 This keeps classification in one place (the ABI library) and limits dialect code
 to operation creation.
 
-ABIRewriteContext and Target Registry
-=====================================
+## ABIRewriteContext and Target Registry
 
-ABIRewriteContext Interface
----------------------------
+### ABIRewriteContext Interface
 
 ABIRewriteContext is the only dialect-specific layer: CIR and FIR each
-implement it to create their own dialect operations (e.g.  cir.call, fir.call).
+implement it to create their own dialect operations (e.g. cir.call, fir.call).
 In a module with mixed dialect content, the pass selects the appropriate
 ABIRewriteContext for each function based on the dialect of its operations.
 Classification is performed by the library's ABIInfo and produces the library's
-result (e.g.  ABIFunctionInfo, ABIArgInfo); ABIRewriteContext consumes that
-classification to perform the actual IR rewriting.  ABIRewriteContext is also
-responsible for updating ABI-related attributes (e.g.  sret, byval, signext,
+result (e.g. ABIFunctionInfo, ABIArgInfo); ABIRewriteContext consumes that
+classification to perform the actual IR rewriting. ABIRewriteContext is also
+responsible for updating ABI-related attributes (e.g. sret, byval, signext,
 zeroext, inreg) on the rewritten function signatures and call sites as indicated
 by the classification result.
 
 The interface defines two high-level methods:
-``rewriteFunctionDefinition(funcOp, classification, builder)`` rewrites a
+`rewriteFunctionDefinition(funcOp, classification, builder)` rewrites a
 function's signature and body (coercing return values, adapting arguments,
-handling sret), and ``rewriteCallSite(callOp, classification, builder)``
+handling sret), and `rewriteCallSite(callOp, classification, builder)`
 rewrites a call to match the lowered callee (coercing arguments, handling
-coerced returns).  Each method encapsulates the full rewriting logic for its
+coerced returns). Each method encapsulates the full rewriting logic for its
 scope, using the dialect's own builder operations internally
-(e.g.  ``cir::CastOp``, ``cir::AllocaOp``, ``cir::StoreOp``).  Each dialect
+(e.g. `cir::CastOp`, `cir::AllocaOp`, `cir::StoreOp`). Each dialect
 handles operation creation using its own builder internally.
 
 Each dialect implementing ABI lowering must provide a concrete
-``ABIRewriteContext`` subclass.  This is a significant but one-time cost:
-CIR implements ``CIRABIRewriteContext``, FIR implements ``FIRABIRewriteContext``,
+`ABIRewriteContext` subclass. This is a significant but one-time cost:
+CIR implements `CIRABIRewriteContext`, FIR implements `FIRABIRewriteContext`,
 and any future dialect reuses the shared classification infrastructure by
-providing its own context implementation.  The alternative—reimplementing the
+providing its own context implementation. The alternative—reimplementing the
 entire ABI classification logic per dialect—would require 8,000-15,000 lines per
 dialect (the combined size of x86_64 and AArch64 classification code plus all
 supporting infrastructure), introduce divergent behavior across dialects, and
 create a maintenance burden where ABI bug fixes must be propagated to every
 dialect independently.
 
-Target Registry
----------------
+### Target Registry
 
 We use the library's target selection or registry to obtain the appropriate
-ABIInfo for the compilation target (e.g.  X86_64, AArch64).  We do not introduce
+ABIInfo for the compilation target (e.g. X86_64, AArch64). We do not introduce
 a separate MLIR TargetRegistry unless the MLIR ABI pass needs it for pass
-options or configuration.  The dependency direction is: the MLIR ABI pass
-depends on ``llvm/lib/ABI``; there is no reverse dependency from the ABI library
+options or configuration. The dependency direction is: the MLIR ABI pass
+depends on `llvm/lib/ABI`; there is no reverse dependency from the ABI library
 to MLIR dialects.
 
-CIR Pass Pipeline Position
---------------------------
+### CIR Pass Pipeline Position
 
 For the CIR dialect, the calling-convention lowering pass is named
-``cir-call-conv-lowering`` and runs late in the CIR-to-LLVM pipeline:
+`cir-call-conv-lowering` and runs late in the CIR-to-LLVM pipeline:
 
-1. ``cir-target-lowering`` legalizes target-specific operations (e.g.
+1. `cir-target-lowering` legalizes target-specific operations (e.g.
    atomic synchronization scopes).
-2. ``cir-cxxabi-lowering`` lowers C++-specific high-level types (member
+2. `cir-cxxabi-lowering` lowers C++-specific high-level types (member
    pointers, vtable lookups, etc.) to ABI-specific representations.
-3. ``cir-call-conv-lowering`` rewrites function signatures and call sites
+3. `cir-call-conv-lowering` rewrites function signatures and call sites
    to match the target ABI's calling convention rules.
 
-``cir-call-conv-lowering`` requires a ``dlti.dl_spec`` attribute on the
+`cir-call-conv-lowering` requires a `dlti.dl_spec` attribute on the
 module so it can query type sizes and alignments through MLIR's
-``DataLayout``.  When the attribute is missing, the pass emits a
+`DataLayout`. When the attribute is missing, the pass emits a
 diagnostic and fails rather than silently using a default layout.
 
 The pass takes one of two driver modes via pass options:
 
-- ``target=<name>`` selects a real ABI target.  The first supported value
-  is ``test`` (the MLIR test target in ``mlir/lib/ABI/Targets/Test/``,
+- `target=<name>` selects a real ABI target. The first supported value
+  is `test` (the MLIR test target in `mlir/lib/ABI/Targets/Test/`,
   used for testing the rewriter without depending on the in-progress
-  LLVM ABI library targets).  Real targets (``x86_64``, ``aarch64``,
+  LLVM ABI library targets). Real targets (`x86_64`, `aarch64`,
   ...) will be added as the LLVM ABI library ships them.
-- ``classification-attr=<name>`` reads a pre-built ``FunctionClassifica
-  tion`` from a ``DictionaryAttr`` named ``<name>`` on each ``cir.func``
-  and rewrites accordingly.  This driver is for tests that need to
+- `classification-attr=<name>` reads a pre-built `FunctionClassifica
+  tion` from a `DictionaryAttr` named `<name>` on each `cir.func`
+  and rewrites accordingly. This driver is for tests that need to
   exercise rewriter behavior against arbitrary classifications without
   routing through any real classifier.
 
 Exactly one of the two options must be set.
 
-Enabling the Pass
------------------
+### Enabling the Pass
 
-``cir-call-conv-lowering`` runs by default whenever ClangIR code generation is
-enabled on an x86_64 target.  On every other triple the pipeline omits the
+`cir-call-conv-lowering` runs by default whenever ClangIR code generation is
+enabled on an x86_64 target. On every other triple the pipeline omits the
 pass, because x86_64 System V is the only classifier implemented so far, and
 signatures reach the LLVM dialect in their high-level form.
 
-``-fno-clangir-call-conv-lowering`` turns the pass off and
-``-fclangir-call-conv-lowering`` turns it back on.  The last one on the
+`-fno-clangir-call-conv-lowering` turns the pass off and
+`-fclangir-call-conv-lowering` turns it back on. The last one on the
 command line wins, so a build can disable the pass globally and re-enable it
-for a single translation unit.  Both are ``-cc1`` options, so reach them from
-the driver through ``-Xclang``.
+for a single translation unit. Both are `-cc1` options, so reach them from
+the driver through `-Xclang`.
 
-Open Questions
-==============
+## Open Questions
 
-The following items are open for discussion.  This section may be revised,
+The following items are open for discussion. This section may be revised,
 shortened, or removed before final merge.
 
-How to Handle clang::TargetInfo Dependency in MLIR?
----------------------------------------------------
+### How to Handle clang::TargetInfo Dependency in MLIR?
 
-The CIR incubator currently uses ``clang::TargetInfo`` to query target-specific
+The CIR incubator currently uses `clang::TargetInfo` to query target-specific
 properties needed for ABI decisions, such as pointer width, alignment,
-endianness, and calling convention availability.  Moving this functionality to
+endianness, and calling convention availability. Moving this functionality to
 MLIR dialect-agnostic infrastructure raises an architectural question: should
 MLIR code depend on a Clang library, or should it use MLIR-based mechanisms?
 
 Three approaches are under consideration.
 
-1. Continue using ``clang::TargetInfo`` directly, accepting an MLIR→Clang
-   dependency for this target-specific infrastructure.  This approach requires
+1. Continue using `clang::TargetInfo` directly, accepting an MLIR→Clang
+   dependency for this target-specific infrastructure. This approach requires
    no additional implementation since it already works in the CIR incubator,
-   and ``clang::TargetInfo`` provides comprehensive, battle-tested coverage of
-   all target properties.  However, it creates a dependency relationship that
+   and `clang::TargetInfo` provides comprehensive, battle-tested coverage of
+   all target properties. However, it creates a dependency relationship that
    may violate MLIR's architectural principle of being a peer to Clang rather
    than dependent on it.
-2. Combine ``llvm::Triple`` with MLIR's ``DataLayoutInterface``, supplemented by
+2. Combine `llvm::Triple` with MLIR's `DataLayoutInterface`, supplemented by
    module-level attributes for ABI-specific properties not covered by the data
-   layout.  This approach maintains clean layering with no Clang dependency and
+   layout. This approach maintains clean layering with no Clang dependency and
    follows MLIR patterns, but requires defining approximately 10-15 additional
    attributes and some upfront design work.
-3. Create a new ``mlir::target::TargetInfo`` abstraction with minimal methods
-   tailored specifically for ABI needs (approximately 15-20 methods).  This
+3. Create a new `mlir::target::TargetInfo` abstraction with minimal methods
+   tailored specifically for ABI needs (approximately 15-20 methods). This
    provides clean layering without Clang dependency but requires implementing
    and maintaining target-specific code that duplicates some knowledge from
-   ``clang::TargetInfo``.
+   `clang::TargetInfo`.
 
-Option 2 is recommended as the preferred approach.  It maintains MLIR's
+Option 2 is recommended as the preferred approach. It maintains MLIR's
 independence from Clang, which is important for MLIR's mission to be reusable by
-non-Clang frontends like Rust, Julia, and Swift.  Target information is input
+non-Clang frontends like Rust, Julia, and Swift. Target information is input
 metadata rather than an output format, so it should be expressible through
-MLIR's existing mechanisms rather than requiring external dependencies.  Option
+MLIR's existing mechanisms rather than requiring external dependencies. Option
 3 serves as an acceptable fallback if Option 2 proves insufficient during
 prototyping, while Option 1 is not recommended due to the architectural concerns
 around MLIR depending on Clang.
 
-Scope: C Calling Convention vs.  Arbitrary Calling Conventions
---------------------------------------------------------------
+### Scope: C Calling Convention vs. Arbitrary Calling Conventions
 
 This design focuses on the **C calling convention layer** (e.g. cdecl, System V,
-AAPCS).  C++ ABI concerns such as non-trivial copy constructors or destructors
+AAPCS). C++ ABI concerns such as non-trivial copy constructors or destructors
 are largely handled elsewhere in the compilation pipeline; the ABI library and
 MLIR integration layer address how arguments and return values are passed at the
-C ABI boundary.  An open question is whether the design should remain explicitly
+C ABI boundary. An open question is whether the design should remain explicitly
 scoped to C calling conventions only, or be general enough to support arbitrary
 calling conventions (e.g. vectorcall, preserve_most) via extensible interfaces.
 Clarifying this scope will guide the design of the LLVM ABI library integration
 and the MLIR pass.
+
diff --git a/clang/docs/CIR/CleanupAndEHDesign.md b/clang/docs/CIR/CleanupAndEHDesign.md
index c8e3dbf7d87cb..5ce8a0624cb70 100644
--- a/clang/docs/CIR/CleanupAndEHDesign.md
+++ b/clang/docs/CIR/CleanupAndEHDesign.md
@@ -1,19 +1,17 @@
-=============================================
-ClangIR Cleanup and Exception Handling Design
-=============================================
+# ClangIR Cleanup and Exception Handling Design
 
-.. contents::
-   :local:
+```{contents}
+:local: true
+```
 
-Overview
-========
+## Overview
 
 This document describes the design for C++ cleanups and exception
 handling representation and lowering in the CIR dialect. The initial CIR
 generation will follow the general structure of the cleanup and
 exception handling code in Clang's LLVM IR generation. In particular,
-we will continue to use the ``EHScopeStack`` with pushing and popping of
-``EHScopeStack::Cleanup`` objects to drive the creation of cleanup scopes
+we will continue to use the `EHScopeStack` with pushing and popping of
+`EHScopeStack::Cleanup` objects to drive the creation of cleanup scopes
 within CIR.
 
 However, the LLVM IR generated by Clang is fundamentally unstructured
@@ -21,7 +19,7 @@ and therefore isn't well suited to the goals of CIR. Therefore, we are
 proposing a high-level representation that follows MLIR's structured
 control flow model.
 
-The ``cir::LowerCFG`` pass will lower this high-level representation to a
+The `cir::LowerCFG` pass will lower this high-level representation to a
 different form where control flow is block-based and explicit. This form
 will more closely resemble the LLVM IR used when Clang is generating
 LLVM IR directly. However, this form will still be ABI-agnostic.
@@ -31,47 +29,45 @@ ABI-specific representation. This ABI-specific form will have a direct
 correspondence to the LLVM IR exception handling representation for a
 given target.
 
-High-level CIR representation
-=============================
+## High-level CIR representation
 
-Normal and EH cleanups
-----------------------
+### Normal and EH cleanups
 
 Scopes that require normal or EH cleanup will be represented using a new
-operation, ``cir.cleanup.scope``.
+operation, `cir.cleanup.scope`.
 
-.. code-block::
-
-    cir.cleanup.scope {
-      // body region
-    } cleanup [normal|eh|all] {
-      // cleanup instructions
-    }
+```
+cir.cleanup.scope {
+  // body region
+} cleanup [normal|eh|all] {
+  // cleanup instructions
+}
+```
 
 Execution begins with the first operation in the body region and
 continues according to normal control flow semantics until a terminating
-operation (``cir.yield``, ``cir.break``, ``cir.return``, ``cir.continue``) is
+operation (`cir.yield`, `cir.break`, `cir.return`, `cir.continue`) is
 encountered or an exception is thrown.
 
-If the cleanup region is marked as ``eh_only``, normal control flow exits
+If the cleanup region is marked as `eh_only`, normal control flow exits
 from the body region skip the cleanup region and continue to their
 normal destination according to the semantics of the operation. If the
-cleanup region is not marked as ``eh_only``, normal control flow exits
+cleanup region is not marked as `eh_only`, normal control flow exits
 from the body region must execute the cleanup region before control is
 transferred to the destination implied by the operation.
 
-If a ``cir.goto`` operation occurs within a cleanup scope, the behavior
+If a `cir.goto` operation occurs within a cleanup scope, the behavior
 depends on the target of the operation. If the target is within the
 same cleanup scope, control is transferred to the target block directly.
 If the target is not within the cleanup scope, control is transferred to
 the cleanup region according to the rules described above for normal
 exits before branching to the destination of the goto operation.
 
-While we do not expect to encounter ``cir.br`` or ``cir.brcond`` operations
+While we do not expect to encounter `cir.br` or `cir.brcond` operations
 that exit a cleanup scope, if such a thing did happen, it would follow
-the rules described above for ``cir.goto`` operations.
+the rules described above for `cir.goto` operations.
 
-The ``cir.indirect_br`` operation is not permitted within a cleanup scope.
+The `cir.indirect_br` operation is not permitted within a cleanup scope.
 
 When an exception is thrown from within a cleanup scope and not caught
 within the scope, the cleanup region must be executed before handling of
@@ -83,117 +79,114 @@ within a try operation, the cleanup region is executed before control is
 transferred to the catch handlers. If an exception is thrown from within
 a cleanup region that is not nested within either another cleanup region
 or a try operation, the cleanup region is executed and then exception
-unwinding continues as if a ``cir.resume`` operation had been executed.
+unwinding continues as if a `cir.resume` operation had been executed.
 
-If a ``cir.resume`` operation occurs within a cleanup scope, for example,
+If a `cir.resume` operation occurs within a cleanup scope, for example,
 if the scope contains a try operation with uncaught exception types, the
-``cir.resume`` operation will unwind to the cleanup region of the enclosing
+`cir.resume` operation will unwind to the cleanup region of the enclosing
 cleanup scope.
 
 Note that this design eliminates the need for synthetic try operations,
 such as were used to represent calls within a cleanup scope in the
 ClangIR incubator project.
 
-Implementation notes
-^^^^^^^^^^^^^^^^^^^^
+#### Implementation notes
 
-The ``cir.cleanup.scope`` must be created when we call ``pushCleanup``. We
+The `cir.cleanup.scope` must be created when we call `pushCleanup`. We
 will need to set the insertion point at that time. When each cleanup
 block is popped, we will need to set the insertion point to immediately
-following the cleanup scope operation. If ``forceCleanups()`` is called,
+following the cleanup scope operation. If `forceCleanups()` is called,
 it will pop cleanup blocks, which is good.
 
-Example: Automatic storage object cleanup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Example: Automatic storage object cleanup
 
 **C++**
 
-.. code-block:: c++
-
-    void someFunc() {
-      SomeClass c;
-      c.doSomething();
-    }
+```c++
+void someFunc() {
+  SomeClass c;
+  c.doSomething();
+}
+```
 
 **CIR**
 
-.. code-block::
-
-    cir.func @someFunc() {
-      %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-      cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.cleanup.scope {
-        cir.call @_ZN9SomeClass11doSomethingEv(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-        cir.yield
-      } cleanup normal {
-        cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-        cir.yield
-      }
-      cir.return
-    }
+```
+cir.func @someFunc() {
+  %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+  cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.cleanup.scope {
+    cir.call @_ZN9SomeClass11doSomethingEv(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+    cir.yield
+  } cleanup normal {
+    cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+    cir.yield
+  }
+  cir.return
+}
+```
 
-In this example, we create an instance of ``SomeClass`` which has a
+In this example, we create an instance of `SomeClass` which has a
 constructor and a destructor. If an exception occurs within the
 constructor call, it unwinds without any handling in this function. The
 cleanup scope is not entered in that case. Once the object has been
 constructed, we enter a cleanup scope which continues until the object
 goes out of scope, in this case for the remainder of the function.
 
-If an exception is thrown from within the ``doSomething()`` function, we
-execute the cleanup region, calling the ``SomeClass`` destructor before
-continuing to unwind the exception. If the call to ``doSomething()``
+If an exception is thrown from within the `doSomething()` function, we
+execute the cleanup region, calling the `SomeClass` destructor before
+continuing to unwind the exception. If the call to `doSomething()`
 completes successfully, the object goes out of scope and we execute the
 cleanup region, calling the destructor, before continuing to the return
 operation.
 
-Example: Multiple automatic objects
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Example: Multiple automatic objects
 
 **C++**
 
-.. code-block:: c++
-
-  void someFunc() {
-    SomeClass c;
-    SomeClass c2;
-    c.doSomething();
-    SomeClass c3;
-    c3.doSomething();
-  }
+```c++
+void someFunc() {
+  SomeClass c;
+  SomeClass c2;
+  c.doSomething();
+  SomeClass c3;
+  c3.doSomething();
+}
+```
 
 **CIR**
 
-.. code-block::
-
-    cir.func @someFunc() {
-      %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-      %1 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c2", init]
-      %2 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c3", init]
-      cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+```
+cir.func @someFunc() {
+  %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+  %1 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c2", init]
+  %2 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c3", init]
+  cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.cleanup.scope {
+    cir.call @_ZN9SomeClassC1Ev(%1) : (!cir.ptr<!rec_SomeClass>) -> ()
+    cir.cleanup.scope {
+      cir.call @_ZN9SomeClass11doSomethingEv(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+      cir.call @_ZN9SomeClassC1Ev(%2) : (!cir.ptr<!rec_SomeClass>) -> ()
       cir.cleanup.scope {
-        cir.call @_ZN9SomeClassC1Ev(%1) : (!cir.ptr<!rec_SomeClass>) -> ()
-        cir.cleanup.scope {
-          cir.call @_ZN9SomeClass11doSomethingEv(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-          cir.call @_ZN9SomeClassC1Ev(%2) : (!cir.ptr<!rec_SomeClass>) -> ()
-          cir.cleanup.scope {
-            cir.call @_ZN9SomeClass11doSomethingEv(%2) : (!cir.ptr<!rec_SomeClass>) -> ()
-            cir.yield
-          } cleanup normal {
-            cir.call @_ZN9SomeClassD1Ev(%2) : (!cir.ptr<!rec_SomeClass>) -> ()
-            cir.yield
-          }
-          cir.yield
-        } cleanup normal {
-          cir.call @_ZN9SomeClassD1Ev(%1) : (!cir.ptr<!rec_SomeClass>) -> ()
-          cir.yield
-        }
+        cir.call @_ZN9SomeClass11doSomethingEv(%2) : (!cir.ptr<!rec_SomeClass>) -> ()
         cir.yield
       } cleanup normal {
-        cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+        cir.call @_ZN9SomeClassD1Ev(%2) : (!cir.ptr<!rec_SomeClass>) -> ()
         cir.yield
       }
-      cir.return
+      cir.yield
+    } cleanup normal {
+      cir.call @_ZN9SomeClassD1Ev(%1) : (!cir.ptr<!rec_SomeClass>) -> ()
+      cir.yield
     }
+    cir.yield
+  } cleanup normal {
+    cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+    cir.yield
+  }
+  cir.return
+}
+```
 
 In this example, we have three objects with automatic storage duration.
 The destructor must be called for each object that has been constructed,
@@ -206,191 +199,230 @@ nested cleanup scopes until the body of the innermost scope. Next, the
 cleanup scopes are visited, calling the destructor once in each cleanup
 scope, in reverse order of the object construction.
 
-Implementation notes
-^^^^^^^^^^^^^^^^^^^^
+#### Implementation notes
 
 Branch through cleanups will be handled during flattening. In the
-structured CIR representation, an operation like ``cir.break``,
-``cir.return``, or ``cir.continue`` has well-defined behavior. We will need
+structured CIR representation, an operation like `cir.break`,
+`cir.return`, or `cir.continue` has well-defined behavior. We will need
 to define the semantics such that they include visiting the cleanup
 region before continuing to their currently defined destination.
 
-Example: Branch through cleanup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Example: Branch through cleanup
 
 **C++**
 
-.. code-block:: c++
-
-    int someFunc() {
-      int i = 0;
-      while (true) {
-        SomeClass c;
-        if (i == 3)
-          continue;
-        if (i == 7)
-          break;
-        i = c.get();
-      }
-      return i;
-    }
+```c++
+int someFunc() {
+  int i = 0;
+  while (true) {
+    SomeClass c;
+    if (i == 3)
+      continue;
+    if (i == 7)
+      break;
+    i = c.get();
+  }
+  return i;
+}
+```
 
 **CIR**
 
-.. code-block::
-
-    cir.func @someFunc() -> !s32i {
-      %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
-      %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init]
-      %2 = cir.const #cir.int<0> : !s32i
-      cir.store align(4) %2, %1 : !s32i, !cir.ptr<!s32i>
+```
+cir.func @someFunc() -> !s32i {
+  %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
+  %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init]
+  %2 = cir.const #cir.int<0> : !s32i
+  cir.store align(4) %2, %1 : !s32i, !cir.ptr<!s32i>
+  cir.scope {
+    cir.while {
+      %5 = cir.const #true
+      cir.condition(%5)
+    } do {
       cir.scope {
-        cir.while {
-          %5 = cir.const #true
-          cir.condition(%5)
-        } do {
-          cir.scope {
-            %5 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-            cir.call @_ZN9SomeClassC1Ev(%5) : (!cir.ptr<!rec_SomeClass>) -> ()
-            cir.cleanup.scope {
-              cir.scope { // This is a scope for the `if`, unrelated to cleanups
-                %7 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
-                %8 = cir.const #cir.int<3> : !s32i
-                %9 = cir.cmp(eq, %7, %8) : !s32i, !cir.bool
-                cir.if %9 {
-                  cir.continue // This implicitly branches through the cleanup region
-                }
-              }
-              cir.scope { // This is a scope for the `if`, unrelated to cleanups
-                %7 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
-                %8 = cir.const #cir.int<7> : !s32i
-                %9 = cir.cmp(eq, %7, %8) : !s32i, !cir.bool
-                cir.if %9 {
-                  cir.break // This implicitly branches through the cleanup region
-                }
-              }
-              %6 = cir.call @_ZN9SomeClass3getEv(%5) : (!cir.ptr<!rec_SomeClass>) -> !s32i
-              cir.store align(4) %6, %1 : !s32i, !cir.ptr<!s32i>
-              cir.yield
-            } cleanup normal {
-              cir.call @_ZN9SomeClassD1Ev(%5) : (!cir.ptr<!rec_SomeClass>) -> ()
-              cir.yield
+        %5 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+        cir.call @_ZN9SomeClassC1Ev(%5) : (!cir.ptr<!rec_SomeClass>) -> ()
+        cir.cleanup.scope {
+          cir.scope { // This is a scope for the `if`, unrelated to cleanups
+            %7 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
+            %8 = cir.const #cir.int<3> : !s32i
+            %9 = cir.cmp(eq, %7, %8) : !s32i, !cir.bool
+            cir.if %9 {
+              cir.continue // This implicitly branches through the cleanup region
             }
           }
+          cir.scope { // This is a scope for the `if`, unrelated to cleanups
+            %7 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
+            %8 = cir.const #cir.int<7> : !s32i
+            %9 = cir.cmp(eq, %7, %8) : !s32i, !cir.bool
+            cir.if %9 {
+              cir.break // This implicitly branches through the cleanup region
+            }
+          }
+          %6 = cir.call @_ZN9SomeClass3getEv(%5) : (!cir.ptr<!rec_SomeClass>) -> !s32i
+          cir.store align(4) %6, %1 : !s32i, !cir.ptr<!s32i>
+          cir.yield
+        } cleanup normal {
+          cir.call @_ZN9SomeClassD1Ev(%5) : (!cir.ptr<!rec_SomeClass>) -> ()
           cir.yield
         }
       }
-      %3 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
-      cir.store %3, %0 : !s32i, !cir.ptr<!s32i>
-      %4 = cir.load %0 : !cir.ptr<!s32i>, !s32i
-      cir.return %4 : !s32i
+      cir.yield
     }
+  }
+  %3 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
+  cir.store %3, %0 : !s32i, !cir.ptr<!s32i>
+  %4 = cir.load %0 : !cir.ptr<!s32i>, !s32i
+  cir.return %4 : !s32i
+}
+```
 
 In this example we have a cleanup scope inside the body of a
-``while-loop``, and multiple instructions that may exit the loop body with
-different destinations. When the ``cir.continue`` operation is executed,
+`while-loop`, and multiple instructions that may exit the loop body with
+different destinations. When the `cir.continue` operation is executed,
 it will transfer control to the cleanup region, which calls the object
 destructor before transferring control to the while condition region
-according to the semantics of the ``cir.continue`` operation.
+according to the semantics of the `cir.continue` operation.
 
-When the ``cir.break`` operation is executed, it will transfer control to
+When the `cir.break` operation is executed, it will transfer control to
 the cleanup region, which calls the object destructor before
 transferring control to the operation following the while loop according
-to the semantics of the ``cir.break`` operation.
+to the semantics of the `cir.break` operation.
 
-If neither the ``cir.continue`` or ``cir.break`` operations are executed
+If neither the `cir.continue` or `cir.break` operations are executed
 during an iteration of the loop, when the end of the cleanup scope's
 body region is reached, control will be transferred to the cleanup
 region, which calls the object destructor before transferring control to
 the next operation following the cleanup scope, in this case falling
-through to the ``cir.yield`` operation to complete the loop iteration.
+through to the `cir.yield` operation to complete the loop iteration.
 
 This control flow is implicit in the semantics of the CIR operations at
 this point. When this CIR is flattened, explicit branches and a switch
 on destination slots will be created, matching the LLVM IR control flow
 for cleanup block sharing.
 
-Example: EH-only cleanup
-^^^^^^^^^^^^^^^^^^^^^^^^
+#### Example: EH-only cleanup
 
 **C++**
 
-.. code-block:: c++
-
-    class Base {
-    public:
-      Base();
-      ~Base();
-    };
+```c++
+class Base {
+public:
+  Base();
+  ~Base();
+};
 
-    class Derived : public Base {
-    public:
-      Derived() : Base() { f(); }
-      ~Derived();
-    };
+class Derived : public Base {
+public:
+  Derived() : Base() { f(); }
+  ~Derived();
+};
+```
 
 **CIR**
 
-.. code-block::
-
-    cir.func @_ZN7DerivedC2Ev(%arg0: !cir.ptr<!rec_Derived>) {
-      %0 = cir.alloca !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>, ["this", init]
-      cir.store %arg0, %0 : !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>
-      %1 = cir.load %0 : !cir.ptr<!cir.ptr<!rec_Derived>>, !cir.ptr<!rec_Derived>
-      %2 = cir.base_class_addr %1 : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
-      cir.call @_ZN4BaseC2Ev(%2) : (!cir.ptr<!rec_Base>) -> ()
-      cir.cleanup.scope {
-        cir.call exception @_Z1fv() : () -> ()
-        cir.yield
-      } cleanup eh {
-        %3 = cir.base_class_addr %1 : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
-        cir.call @_ZN4BaseD2Ev(%3) : (!cir.ptr<!rec_Base>) -> ()
-        cir.yield
-      }
-      cir.return
-    }
+```
+cir.func @_ZN7DerivedC2Ev(%arg0: !cir.ptr<!rec_Derived>) {
+  %0 = cir.alloca !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>, ["this", init]
+  cir.store %arg0, %0 : !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>
+  %1 = cir.load %0 : !cir.ptr<!cir.ptr<!rec_Derived>>, !cir.ptr<!rec_Derived>
+  %2 = cir.base_class_addr %1 : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+  cir.call @_ZN4BaseC2Ev(%2) : (!cir.ptr<!rec_Base>) -> ()
+  cir.cleanup.scope {
+    cir.call exception @_Z1fv() : () -> ()
+    cir.yield
+  } cleanup eh {
+    %3 = cir.base_class_addr %1 : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+    cir.call @_ZN4BaseD2Ev(%3) : (!cir.ptr<!rec_Base>) -> ()
+    cir.yield
+  }
+  cir.return
+}
+```
 
-In this example, the ``Derived`` constructor calls the ``Base`` constructor
+In this example, the `Derived` constructor calls the `Base` constructor
 and then calls a function which may throw an exception. If an exception
-is thrown, we must call the ``Base`` destructor before continuing to
+is thrown, we must call the `Base` destructor before continuing to
 unwind the exception. However, if no exception is thrown, we do not call
 the destructor. Therefore, this cleanup handler is marked as eh_only.
 
-Try Operations and Exception Handling
--------------------------------------
+### Try Operations and Exception Handling
 
 Try-catch blocks will be represented, as they are in the ClangIR
-incubator project, using a ``cir.try`` operation.
+incubator project, using a `cir.try` operation.
 
-Each catch handler region and unwind region in a ``cir.try`` operation
-receives a ``!cir.eh_token`` argument representing the inflight exception.
+Each catch handler region and unwind region in a `cir.try` operation
+receives a `!cir.eh_token` argument representing the inflight exception.
 
-The ``cir.begin_catch`` operation takes a ``!cir.eh_token`` as an argument
-and returns two values: a ``!cir.catch_token`` that uniquely identifies
+The `cir.begin_catch` operation takes a `!cir.eh_token` as an argument
+and returns two values: a `!cir.catch_token` that uniquely identifies
 this catch handler, and a pointer to the exception object. When the
 catch handler includes a source variable representing the exception
-object, the pointer returned by ``cir.begin_catch`` will be stored to an
+object, the pointer returned by `cir.begin_catch` will be stored to an
 alloca object for the source variable. If the handler is a catch-all,
-the ``cir.begin_catch`` operation will return a pointer to void, but this
+the `cir.begin_catch` operation will return a pointer to void, but this
 cannot be captured by a source variable.
 
-The ``cir.end_catch`` operation takes a ``!cir.catch_token`` as an argument,
+The `cir.end_catch` operation takes a `!cir.catch_token` as an argument,
 marking the end of the catch handler. All paths through the catch
-handler must converge on a single ``cir.end_catch`` operation.
+handler must converge on a single `cir.end_catch` operation.
+
+The first operation in a catch handler region must be a `cir.begin_catch`
+operation. This must be followed by a `cir.cleanup.scope` operation,
+with the `cir.end_catch` operation in its cleanup region.
+
+```
+cir.try {
+  cir.call exception @function() : () -> ()
+  cir.yield
+} catch [type #cir.global_view<@_ZTIPf> : !cir.ptr<!u8i>] (%eh_token : !cir.eh_token) {
+  %catch_token, %exn_ptr = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!cir.float>)
+  cir.cleanup.scope {
+    ...
+    cir.yield
+  } cleanup eh {
+    cir.end_catch %catch_token
+    cir.yield
+  }
+  cir.yield
+} unwind (%eh_token : !cir.eh_token) {
+  cir.resume %eh_token : !cir.eh_token
+}
+```
 
-The first operation in a catch handler region must be a ``cir.begin_catch``
-operation. This must be followed by a ``cir.cleanup.scope`` operation,
-with the ``cir.end_catch`` operation in its cleanup region.
+The operation consists of a try region, which contains the operations to
+be executed during normal execution, and one or more handler regions,
+which represent catch handlers or the fallback unwind for uncaught
+exceptions.
 
-.. code-block::
+#### Example: Simple try-catch
+
+**C++**
 
+```c++
+void someFunc() {
+  try {
+    f();
+  } catch (std::exception &e) {
+    // Do nothing
+  }
+}
+```
+
+**CIR**
+
+```
+cir.func @someFunc(){
+  %0 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"]
+  cir.scope {
     cir.try {
-      cir.call exception @function() : () -> ()
+      cir.call exception @_Z1fv() : () -> ()
       cir.yield
-    } catch [type #cir.global_view<@_ZTIPf> : !cir.ptr<!u8i>] (%eh_token : !cir.eh_token) {
-      %catch_token, %exn_ptr = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!cir.float>)
+    } catch [type #cir.global_view<@_ZTISt9exception> : !cir.ptr<!u8i>] (%eh_token : !cir.eh_token) {
+      %catch_token, %1 = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>)
       cir.cleanup.scope {
-        ...
+        %2 = cir.load align(8) %1 : !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, !cir.ptr<!rec_std3A3Aexception>
+        cir.store align(8) %2, %0 : !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>
         cir.yield
       } cleanup eh {
         cir.end_catch %catch_token
@@ -400,248 +432,200 @@ with the ``cir.end_catch`` operation in its cleanup region.
     } unwind (%eh_token : !cir.eh_token) {
       cir.resume %eh_token : !cir.eh_token
     }
+  }
+  cir.return
+}
+```
 
-The operation consists of a try region, which contains the operations to
-be executed during normal execution, and one or more handler regions,
-which represent catch handlers or the fallback unwind for uncaught
-exceptions.
-
-Example: Simple try-catch
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-**C++**
-
-.. code-block:: c++
-
-    void someFunc() {
-      try {
-        f();
-      } catch (std::exception &e) {
-        // Do nothing
-      }
-    }
-
-**CIR**
-
-.. code-block::
-
-    cir.func @someFunc(){
-      %0 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"]
-      cir.scope {
-        cir.try {
-          cir.call exception @_Z1fv() : () -> ()
-          cir.yield
-        } catch [type #cir.global_view<@_ZTISt9exception> : !cir.ptr<!u8i>] (%eh_token : !cir.eh_token) {
-          %catch_token, %1 = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>)
-          cir.cleanup.scope {
-            %2 = cir.load align(8) %1 : !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, !cir.ptr<!rec_std3A3Aexception>
-            cir.store align(8) %2, %0 : !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>
-            cir.yield
-          } cleanup eh {
-            cir.end_catch %catch_token
-            cir.yield
-          }
-          cir.yield
-        } unwind (%eh_token : !cir.eh_token) {
-          cir.resume %eh_token : !cir.eh_token
-        }
-      }
-      cir.return
-    }
-
-If the call to ``f()`` throws an exception that matches the handled type
-(``std::exception&``), control will be transferred to the catch handler
+If the call to `f()` throws an exception that matches the handled type
+(`std::exception&`), control will be transferred to the catch handler
 for that type, which simply yields, continuing execution immediately
 after the try operation.
 
-If the call to ``f()`` throws any other type of exception, control will be
+If the call to `f()` throws any other type of exception, control will be
 transferred to the unwind region, which simply continues unwinding the
 exception at the next level, in this case, the handlers (if any) for the
-function that called ``someFunc()``.
+function that called `someFunc()`.
 
-Example: Try-catch with catch all
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Example: Try-catch with catch all
 
 **C++**
 
-.. code-block:: c++
-
-    void someFunc() {
-      try {
-        f();
-      } catch (std::exception &e) {
-        // Do nothing
-      } catch (...) {
-        // Do nothing
-      }
-    }
+```c++
+void someFunc() {
+  try {
+    f();
+  } catch (std::exception &e) {
+    // Do nothing
+  } catch (...) {
+    // Do nothing
+  }
+}
+```
 
 **CIR**
 
-.. code-block::
-
-    cir.func @someFunc(){
-      %0 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"]
-      cir.scope {
-        cir.try {
-          cir.call exception @_Z1fv() : () -> ()
-          cir.yield
-        } catch [type #cir.global_view<@_ZTISt9exception> : !cir.ptr<!u8i>] (%eh_token : !cir.eh_token) {
-          %catch_token, %1 = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>)
-          cir.cleanup.scope {
-            %2 = cir.load align(8) %1 : !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, !cir.ptr<!rec_std3A3Aexception>
-            cir.store align(8) %2, %0 : !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>
-            cir.yield
-          } cleanup eh {
-            cir.end_catch %catch_token
-            cir.yield
-          }
-          cir.yield
-        } catch all (%eh_token : !cir.eh_token) {
-          %catch_token.1, %3 = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!void>)
-          cir.cleanup.scope {
-            cir.yield
-          } cleanup eh {
-            cir.end_catch %catch_token.1
-            cir.yield
-          }
-          cir.yield
-        }
+```
+cir.func @someFunc(){
+  %0 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"]
+  cir.scope {
+    cir.try {
+      cir.call exception @_Z1fv() : () -> ()
+      cir.yield
+    } catch [type #cir.global_view<@_ZTISt9exception> : !cir.ptr<!u8i>] (%eh_token : !cir.eh_token) {
+      %catch_token, %1 = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>)
+      cir.cleanup.scope {
+        %2 = cir.load align(8) %1 : !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, !cir.ptr<!rec_std3A3Aexception>
+        cir.store align(8) %2, %0 : !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>
+        cir.yield
+      } cleanup eh {
+        cir.end_catch %catch_token
+        cir.yield
+      }
+      cir.yield
+    } catch all (%eh_token : !cir.eh_token) {
+      %catch_token.1, %3 = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!void>)
+      cir.cleanup.scope {
+        cir.yield
+      } cleanup eh {
+        cir.end_catch %catch_token.1
+        cir.yield
       }
-      cir.return
+      cir.yield
     }
+  }
+  cir.return
+}
+```
 
-In this case, if the call to ``f()`` throws an exception that matches the
-handled type (``std::exception&``), everything works exactly as in the
+In this case, if the call to `f()` throws an exception that matches the
+handled type (`std::exception&`), everything works exactly as in the
 previous example. Control will be transferred to the catch handler for
 that type, which simply yields, continuing execution immediately after
 the try operation.
 
-If the call to ``f()`` throws any other type of exception, control will be
+If the call to `f()` throws any other type of exception, control will be
 transferred to the catch all region, which also yields, continuing
 execution immediately after the try operation.
 
-Example: Try-catch with cleanup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Example: Try-catch with cleanup
 
 **C++**
 
-.. code-block:: c++
-
-    void someFunc() {
-      try {
-        SomeClass c;
-        c.doSomething();
-      } catch (...) {
-        // Do nothing
-      }
-    }
+```c++
+void someFunc() {
+  try {
+    SomeClass c;
+    c.doSomething();
+  } catch (...) {
+    // Do nothing
+  }
+}
+```
 
 **CIR**
 
-.. code-block::
-
-    cir.func @someFunc(){
-      cir.scope {
-        %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-        cir.try {
-          cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-          cir.cleanup.scope {
-            cir.call @_ZN9SomeClass11doSomethingEv(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-            cir.yield
-          } cleanup all {
-            cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-            cir.yield
-          }
-        } catch all (%eh_token : !cir.eh_token) {
-          %catch_token, %1 = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!void>)
-          cir.cleanup.scope {
-            cir.yield
-          } cleanup eh {
-            cir.end_catch %catch_token
-            cir.yield
-          }
-          cir.yield
-        }
+```
+cir.func @someFunc(){
+  cir.scope {
+    %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+    cir.try {
+      cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+      cir.cleanup.scope {
+        cir.call @_ZN9SomeClass11doSomethingEv(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+        cir.yield
+      } cleanup all {
+        cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+        cir.yield
       }
-      cir.return
+    } catch all (%eh_token : !cir.eh_token) {
+      %catch_token, %1 = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!void>)
+      cir.cleanup.scope {
+        cir.yield
+      } cleanup eh {
+        cir.end_catch %catch_token
+        cir.yield
+      }
+      cir.yield
     }
+  }
+  cir.return
+}
+```
 
 In this case, an object that requires cleanup is instantiated inside the
-try block scope. If the call to ``doSomething()`` throws an exception, the
+try block scope. If the call to `doSomething()` throws an exception, the
 cleanup region will be executed before control is transferred to the
 catch handler.
 
-Example: Try-catch within a cleanup region
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Example: Try-catch within a cleanup region
 
 **C++**
 
-.. code-block:: c++
-
-    void someFunc() {
-      SomeClass c;
-      try {
-        c.doSomething();
-      } catch (std::exception& e) {
-        // Do nothing
-      }
-    }
+```c++
+void someFunc() {
+  SomeClass c;
+  try {
+    c.doSomething();
+  } catch (std::exception& e) {
+    // Do nothing
+  }
+}
+```
 
 **CIR**
 
-.. code-block::
-
-    cir.func @someFunc(){
-      %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-      %1 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"]
-      cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.cleanup.scope {
-        cir.scope {
-          cir.try {
-            cir.call @_ZN9SomeClass11doSomethingEv(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-            cir.yield
-          } catch [type #cir.global_view<@_ZTISt9exception> : !cir.ptr<!u8i>] (%eh_token : !cir.eh_token) {
-            %catch_token, %2 = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>)
-            cir.cleanup.scope {
-              %3 = cir.load align(8) %2 : !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, !cir.ptr<!rec_std3A3Aexception>
-              cir.store align(8) %3, %1 : !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>
-              cir.yield
-            } cleanup eh {
-              cir.end_catch %catch_token
-              cir.yield
-            }
-            cir.yield
-          } unwind (%eh_token : !cir.eh_token) {
-            cir.resume %eh_token : !cir.eh_token
-          }
-        }
+```
+cir.func @someFunc(){
+  %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+  %1 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"]
+  cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.cleanup.scope {
+    cir.scope {
+      cir.try {
+        cir.call @_ZN9SomeClass11doSomethingEv(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
         cir.yield
-      } cleanup all {
-        cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+      } catch [type #cir.global_view<@_ZTISt9exception> : !cir.ptr<!u8i>] (%eh_token : !cir.eh_token) {
+        %catch_token, %2 = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>)
+        cir.cleanup.scope {
+          %3 = cir.load align(8) %2 : !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, !cir.ptr<!rec_std3A3Aexception>
+          cir.store align(8) %3, %1 : !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>
+          cir.yield
+        } cleanup eh {
+          cir.end_catch %catch_token
+          cir.yield
+        }
         cir.yield
+      } unwind (%eh_token : !cir.eh_token) {
+        cir.resume %eh_token : !cir.eh_token
       }
-      cir.return
     }
+    cir.yield
+  } cleanup all {
+    cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+    cir.yield
+  }
+  cir.return
+}
+```
 
 In this case, the object that requires cleanup is instantiated outside
 the try block scope, and not all exception types have catch handlers.
 
-If the call to ``doSomething()`` throws an exception of type
-``std::exception&``, control will be transferred to the catch handler,
+If the call to `doSomething()` throws an exception of type
+`std::exception&`, control will be transferred to the catch handler,
 which will simply continue execution at the point immediately following
 the try operation, and the cleanup handler will be executed when the
 cleanup scope is exited normally.
 
-If the call to ``doSomething()`` throws any other exception of type,
+If the call to `doSomething()` throws any other exception of type,
 control will be transferred to the unwind region, which executes
-``cir.resume`` to continue unwinding the exception. However, the cleanup
+`cir.resume` to continue unwinding the exception. However, the cleanup
 region of the cleanup scope will be executed before exception unwinding
-continues because we are exiting the scope via the ``cir.resume``
+continues because we are exiting the scope via the `cir.resume`
 operation.
 
-Partial Array Cleanup
----------------------
+### Partial Array Cleanup
 
 Partial array cleanup is a special case because the details of array
 construction and deletion are already encapsulated within high-level CIR
@@ -650,86 +634,85 @@ each object is called sequentially. If one of the constructors throws an
 exception, we must call the destructor for each object that was
 previously constructed in reverse order of their construction. In the
 high-level CIR representation, we have a single operation,
-``cir.array.ctor`` to represent the array construction. Because the
+`cir.array.ctor` to represent the array construction. Because the
 cleanup needed is entirely within the scope of this operation, we can
 represent the cleanup by adding a cleanup region to this operation.
 
-.. code-block::
-
-    cir.array.ctor(%0 : !cir.ptr<!cir.array<!rec_SomeClass x 16>>) {
-    ^bb0(%arg0: !cir.ptr<!rec_SomeClass>):
-      cir.call @_ZN9SomeClassC1Ev(%arg0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.yield
-    } cleanup {
-    ^bb0(%arg0: !cir.ptr<!rec_SomeClass>):
-      cir.call @_ZN9SomeClassD1Ev(%arg0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.yield
-    }
+```
+cir.array.ctor(%0 : !cir.ptr<!cir.array<!rec_SomeClass x 16>>) {
+^bb0(%arg0: !cir.ptr<!rec_SomeClass>):
+  cir.call @_ZN9SomeClassC1Ev(%arg0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.yield
+} cleanup {
+^bb0(%arg0: !cir.ptr<!rec_SomeClass>):
+  cir.call @_ZN9SomeClassD1Ev(%arg0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.yield
+}
+```
 
 This representation shows how a single instance of the object is
 initialized and cleaned up. When the operation is transformed to a
-low-level form (during ``cir::LoweringPrepare``), these two regions will
-be expanded to a loop within a ``cir.cleanup.scope`` for the
+low-level form (during `cir::LoweringPrepare`), these two regions will
+be expanded to a loop within a `cir.cleanup.scope` for the
 initialization, and a loop within the cleanup scope's cleanup region to
 perform the partial array cleanup, as follows
 
-.. code-block::
-
-    cir.scope {
-      %1 = cir.const #cir.int<16> : !u64i
-      %2 = cir.cast array_to_ptrdecay %0 : !cir.ptr<!cir.array<!rec_SomeClass x 16>> -> !cir.ptr<!rec_SomeClass>
-      %3 = cir.ptr_stride %2, %1 : (!cir.ptr<!rec_SomeClass>, !u64i) -> !cir.ptr<!rec_SomeClass>
-      %4 = cir.alloca !cir.ptr<!rec_SomeClass>, !cir.ptr<!cir.ptr<!rec_SomeClass>>, ["__array_idx"]
-      cir.store %2, %4 : !cir.ptr<!rec_SomeClass>, !cir.ptr<!cir.ptr<!rec_SomeClass>>
-      cir.cleanup.scope {
-        cir.do {
-          %5 = cir.load %4 : !cir.ptr<!cir.ptr<!rec_SomeClass>>, !cir.ptr<!rec_SomeClass>
-          cir.call @_ZN9SomeClassC1Ev(%5) : (!cir.ptr<!rec_SomeClass>) -> ()
-          %6 = cir.const #cir.int<1> : !u64i
-          %7 = cir.ptr_stride %5, %6 : (!cir.ptr<!rec_SomeClass>, !u64i) -> !cir.ptr<!rec_SomeClass>
-          cir.store %7, %4 : !cir.ptr<!rec_SomeClass>, !cir.ptr<!cir.ptr<!rec_SomeClass>>
-          cir.yield
-        } while {
-          %5 = cir.load %4 : !cir.ptr<!cir.ptr<!rec_SomeClass>>, !cir.ptr<!rec_SomeClass>
-          %6 = cir.cmp(ne, %5, %3) : !cir.ptr<!rec_SomeClass>, !cir.bool
-          cir.condition(%6)
-        }
-      } cleanup eh {
-        cir.while {
-          %5 = cir.load %4 : !cir.ptr<!cir.ptr<!rec_SomeClass>>, !cir.ptr<!rec_SomeClass>
-          %6 = cir.cmp(ne, %5, %2) : !cir.ptr<!rec_SomeClass>, !cir.bool
-          cir.condition(%6)
-        } cir.do {
-          %5 = cir.load %4 : !cir.ptr<!cir.ptr<!rec_SomeClass>>, !cir.ptr<!rec_SomeClass>
-          %6 = cir.const #cir.int<-1> : !s64i
-          %7 = cir.ptr_stride %5, %6 : (!cir.ptr<!rec_SomeClass>, !s64i) -> !cir.ptr<!rec_SomeClass>
-          cir.call @_ZN9SomeClassD1Ev(%7) : (!cir.ptr<!rec_SomeClass>) -> ()
-          cir.store %7, %4 : !cir.ptr<!rec_SomeClass>, !cir.ptr<!cir.ptr<!rec_SomeClass>>
-          cir.yield
-        }
-      }
+```
+cir.scope {
+  %1 = cir.const #cir.int<16> : !u64i
+  %2 = cir.cast array_to_ptrdecay %0 : !cir.ptr<!cir.array<!rec_SomeClass x 16>> -> !cir.ptr<!rec_SomeClass>
+  %3 = cir.ptr_stride %2, %1 : (!cir.ptr<!rec_SomeClass>, !u64i) -> !cir.ptr<!rec_SomeClass>
+  %4 = cir.alloca !cir.ptr<!rec_SomeClass>, !cir.ptr<!cir.ptr<!rec_SomeClass>>, ["__array_idx"]
+  cir.store %2, %4 : !cir.ptr<!rec_SomeClass>, !cir.ptr<!cir.ptr<!rec_SomeClass>>
+  cir.cleanup.scope {
+    cir.do {
+      %5 = cir.load %4 : !cir.ptr<!cir.ptr<!rec_SomeClass>>, !cir.ptr<!rec_SomeClass>
+      cir.call @_ZN9SomeClassC1Ev(%5) : (!cir.ptr<!rec_SomeClass>) -> ()
+      %6 = cir.const #cir.int<1> : !u64i
+      %7 = cir.ptr_stride %5, %6 : (!cir.ptr<!rec_SomeClass>, !u64i) -> !cir.ptr<!rec_SomeClass>
+      cir.store %7, %4 : !cir.ptr<!rec_SomeClass>, !cir.ptr<!cir.ptr<!rec_SomeClass>>
+      cir.yield
+    } while {
+      %5 = cir.load %4 : !cir.ptr<!cir.ptr<!rec_SomeClass>>, !cir.ptr<!rec_SomeClass>
+      %6 = cir.cmp(ne, %5, %3) : !cir.ptr<!rec_SomeClass>, !cir.bool
+      cir.condition(%6)
     }
+  } cleanup eh {
+    cir.while {
+      %5 = cir.load %4 : !cir.ptr<!cir.ptr<!rec_SomeClass>>, !cir.ptr<!rec_SomeClass>
+      %6 = cir.cmp(ne, %5, %2) : !cir.ptr<!rec_SomeClass>, !cir.bool
+      cir.condition(%6)
+    } cir.do {
+      %5 = cir.load %4 : !cir.ptr<!cir.ptr<!rec_SomeClass>>, !cir.ptr<!rec_SomeClass>
+      %6 = cir.const #cir.int<-1> : !s64i
+      %7 = cir.ptr_stride %5, %6 : (!cir.ptr<!rec_SomeClass>, !s64i) -> !cir.ptr<!rec_SomeClass>
+      cir.call @_ZN9SomeClassD1Ev(%7) : (!cir.ptr<!rec_SomeClass>) -> ()
+      cir.store %7, %4 : !cir.ptr<!rec_SomeClass>, !cir.ptr<!cir.ptr<!rec_SomeClass>>
+      cir.yield
+    }
+  }
+}
+```
 
 Here, both the construction and cleanup loops use the same temporary
 pointer variable to track their location. If an exception is thrown by
-one of the constructor, the ``__array_idx`` variable will point to the
+one of the constructor, the `__array_idx` variable will point to the
 object that was being constructed when the exception was thrown. If the
 exception was thrown during construction of the first object,
-``__array_idx`` will point to the start of the array, and so no destructor
+`__array_idx` will point to the start of the array, and so no destructor
 will be called. If an exception is thrown during the constructor call
-for any other object, ``__array_idx`` will not point to the start of the
+for any other object, `__array_idx` will not point to the start of the
 array, and so the cleanup region will decrement the pointer, call the
 destructor for the previous object, and so on until we reach the
 beginning of the array. This corresponds to the way that partial array
 destruction is handled in Clang's LLVM IR codegen.
 
-CFG Flattening
-==============
+## CFG Flattening
 
 Before CIR can be lowered to the LLVM dialect, the CFG must be
 flattened. That is, functions must not contain nested regions, and all
 blocks in the function must belong to the parent region. This state is
-formed by the ``cir::FlattenCFG`` pass. This pass will need to transform
+formed by the `cir::FlattenCFG` pass. This pass will need to transform
 the high-level CIR representation described above to a flat form where
 cleanups and exception handling are explicitly routed through blocks,
 which are shared as needed.
@@ -739,54 +722,53 @@ pass. The flattening pass will implement the semantics for branching
 through cleanup regions using the same slot and dispatch mechanism used
 in Clang's LLVM IR codegen.
 
-Exception Handling
-------------------
+### Exception Handling
 
 Flattening the CIR for exception handling, including any cleanups that
 must be performed during exception unwinding, requires some specialized
 CIR operations. The operations that were used in the ClangIR incubator
 project were closely matched to the Itanium exception handling ABI. In
 order to achieve a representation that also works well for other ABIs,
-the following new operations are being proposed: ``cir.eh.initiate``,
-``cir.eh.dispatch``, ``cir.eh.terminate``, ``cir.begin_cleanup``, and
-``cir.end_cleanup``. The ``cir.begin_catch`` and ``cir.end_catch`` operations,
+the following new operations are being proposed: `cir.eh.initiate`,
+`cir.eh.dispatch`, `cir.eh.terminate`, `cir.begin_cleanup`, and
+`cir.end_cleanup`. The `cir.begin_catch` and `cir.end_catch` operations,
 described above, are also used in the flattened form.
 
 Any time a cir.call operation that may throw and exception appears
-within the try region of a ``cir.try`` operation or within the body region
-of a ``cir.cleanup.scope`` with a cleanup region marked as an exception
-cleanup, the call will be converted to a ``cir.try_call`` operation, with
+within the try region of a `cir.try` operation or within the body region
+of a `cir.cleanup.scope` with a cleanup region marked as an exception
+cleanup, the call will be converted to a `cir.try_call` operation, with
 normal and unwind destinations. The first operation in the unwind
-destination block must be a ``cir.eh.initiate`` operation.
+destination block must be a `cir.eh.initiate` operation.
 
-.. code-block::
-
-    %eh_token = cir.eh.initiate [cleanup]
+```
+%eh_token = cir.eh.initiate [cleanup]
+```
 
 If this destination includes cleanup code, the cleanup keyword will be
 present, and the cleanup code will be executed before the exception is
-dispatched to any handlers. The ``cir.eh.initiate`` operation returns a
-value of type ``!cir.eh_token``. This is an opaque value that will be used
+dispatched to any handlers. The `cir.eh.initiate` operation returns a
+value of type `!cir.eh_token`. This is an opaque value that will be used
 during ABI-lowering. At this phase, it conceptually represents the
 exception that was thrown and is passed as the argument to the
-``cir.begin_cleanup``, ``cir.begin_catch``, and ``cir.eh.dispatch``
+`cir.begin_cleanup`, `cir.begin_catch`, and `cir.eh.dispatch`
 operations.
 
-.. code-block::
-
-    cir.eh.dispatch %eh_token : !cir.eh_token [
-      catch (#cir.global_view<@_ZTIi> : !u32i) : ^bb6
-      catch_all : ^bb7
-    ]
+```
+cir.eh.dispatch %eh_token : !cir.eh_token [
+  catch (#cir.global_view<@_ZTIi> : !u32i) : ^bb6
+  catch_all : ^bb7
+]
 
-    cir.eh.dispatch %eh_token : !cir.eh_token [
-      catch (#cir.global_view<@_ZTIi> : !u32i) : ^bb6
-      unwind : ^bb7
-    ]
+cir.eh.dispatch %eh_token : !cir.eh_token [
+  catch (#cir.global_view<@_ZTIi> : !u32i) : ^bb6
+  unwind : ^bb7
+]
+```
 
-The ``cir.eh.dispatch`` operation behaves similarly to the LLVM IR switch
+The `cir.eh.dispatch` operation behaves similarly to the LLVM IR switch
 instruction. It takes as an argument a token that was returned by a
-previous ``cir.eh.initiate`` operation. It then has a list of key-value
+previous `cir.eh.initiate` operation. It then has a list of key-value
 pairs, where the key is either a type identifier, the keyword catch_all,
 or the keyword unwind and the value is a block to which execution should
 be transferred if the key is matched. Although the example above shows
@@ -794,411 +776,406 @@ both the catch_all and unwind keyword, in practice only one or the other
 will be present, but the operation is required to have one of these
 values.
 
-When we are unwinding an exception with cleanups, the ``cir.eh.initiate``
+When we are unwinding an exception with cleanups, the `cir.eh.initiate`
 operation will be marked with the cleanup attribute and will be followed
 by a branch to the cleanup block, passing the EH token as an operand to
 the block. The cleanup block will begin with a call to
-``cir.begin_cleanup`` which returns a cleanup token.
+`cir.begin_cleanup` which returns a cleanup token.
 
-.. code-block::
-
-    ^bb4 (%eh_token : !cir.eh_token): 
-      %cleanup_token = cir.begin_cleanup %eh_token : !cir.eh_token -> !cir.cleanup_token
+```
+^bb4 (%eh_token : !cir.eh_token):
+  %cleanup_token = cir.begin_cleanup %eh_token : !cir.eh_token -> !cir.cleanup_token
+```
 
 This is followed by the operations to perform the cleanup and then a
 cir.end_cleanup operation.
 
-.. code-block::
-
-    cir.end_cleanup(%cleanup_token : !cir.cleanup_token)
+```
+cir.end_cleanup(%cleanup_token : !cir.cleanup_token)
+```
 
 Finally, the cleanup block either branches to a catch dispatch block or
-executes a ``cir.resume`` operation to continue unwinding the exception.
+executes a `cir.resume` operation to continue unwinding the exception.
 
 When an exception is caught, the catch block will receive the eh token
-for the exception being caught as an argument. The ``cir.begin_catch``
-and ``cir.end_catch`` operations, described above in the high-level
+for the exception being caught as an argument. The `cir.begin_catch`
+and `cir.end_catch` operations, described above in the high-level
 representation, continue to be used in the flattened form. In the
-flattened form, the ``eh_token`` argument to ``cir.begin_catch`` comes
+flattened form, the `eh_token` argument to `cir.begin_catch` comes
 from the block argument rather than a region argument, and the
-``cir.end_catch`` operation appears directly in the catch block rather
-than within a ``cir.cleanup.scope`` cleanup region.
+`cir.end_catch` operation appears directly in the catch block rather
+than within a `cir.cleanup.scope` cleanup region.
 
-Example: Try-catch with cleanup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Example: Try-catch with cleanup
 
 **C++**
 
-.. code-block:: c++
-
-    void someFunc() {
-      try {
-        SomeClass c;
-        c.doSomething();
-      } catch (...) {
-        // Do nothing
-      }
-    }
+```c++
+void someFunc() {
+  try {
+    SomeClass c;
+    c.doSomething();
+  } catch (...) {
+    // Do nothing
+  }
+}
+```
 
 **High-level CIR**
 
-.. code-block::
-
-    cir.func @someFunc(){
-      cir.scope {
-        %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-        cir.try {
-          cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-          cir.cleanup.scope {
-            cir.call @_ZN9SomeClass11doSomethingEv(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-            cir.yield
-          } cleanup all {
-            cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-            cir.yield
-          }
-        } catch all (%eh_token : !cir.eh_token) {
-          %catch_token, %1 = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!void>)
-          cir.cleanup.scope {
-            cir.yield
-          } cleanup eh {
-            cir.end_catch %catch_token
-            cir.yield
-          }
-          cir.yield
-        }
+```
+cir.func @someFunc(){
+  cir.scope {
+    %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+    cir.try {
+      cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+      cir.cleanup.scope {
+        cir.call @_ZN9SomeClass11doSomethingEv(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+        cir.yield
+      } cleanup all {
+        cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+        cir.yield
+      }
+    } catch all (%eh_token : !cir.eh_token) {
+      %catch_token, %1 = cir.begin_catch %eh_token -> (!cir.catch_token, !cir.ptr<!void>)
+      cir.cleanup.scope {
+        cir.yield
+      } cleanup eh {
+        cir.end_catch %catch_token
+        cir.yield
       }
-      cir.return
+      cir.yield
     }
+  }
+  cir.return
+}
+```
 
 **Flattened CIR**
 
-.. code-block::
-
-    cir.func @someFunc(){
-      %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-      cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
-    ^bb1
-      cir.try_call @_ZN9SomeClass11doSomethingEv(%0) ^bb2, ^bb4 : (!cir.ptr<!rec_SomeClass>) -> ()
-    ^bb2 // Normal cleanup
-      cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.br ^bb8
-    ^bb3 // EH catch (from entry block)
-      %1 = cir.eh.initiate : !cir.eh_token
-      cir.br ^bb6(%1 : !cir.eh_token)
-    ^bb4 // EH cleanup (from ^bb1)
-      %2 = cir.eh.initiate cleanup : !cir.eh_token
-      cir.br ^bb5(%2 : !cir.eh_token)
-    ^bb5(%eh_token : !cir.eh_token)
-      %3 = cir.begin_cleanup(%eh_token : !cir.eh_token) : !cir.cleanup_token
-      cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.end_cleanup(%3 : !cir.cleanup_token)
-      cir.br ^bb6(%eh_token : !cir.eh_token)
-    ^bb6(%eh_token.1 : !cir.eh_token) // Catch dispatch (from ^bb3 or ^bb4)
-      cir.eh.dispatch %eh_token.1 : !cir.eh_token [
-        catch_all : ^bb7
-      ]
-    ^bb7(%eh_token.2 : !cir.eh_token)
-      %catch.token = cir.begin_catch(%eh_token.2 : !cir.eh_token) : !cir.catch_token
-      cir.end_catch(%catch.token : !cir.catch_token)
-      cir.br ^bb8
-    ^bb8 // Normal continue (from ^bb2 or ^bb6)
-      cir.return
-    }
+```
+cir.func @someFunc(){
+  %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+  cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
+^bb1
+  cir.try_call @_ZN9SomeClass11doSomethingEv(%0) ^bb2, ^bb4 : (!cir.ptr<!rec_SomeClass>) -> ()
+^bb2 // Normal cleanup
+  cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.br ^bb8
+^bb3 // EH catch (from entry block)
+  %1 = cir.eh.initiate : !cir.eh_token
+  cir.br ^bb6(%1 : !cir.eh_token)
+^bb4 // EH cleanup (from ^bb1)
+  %2 = cir.eh.initiate cleanup : !cir.eh_token
+  cir.br ^bb5(%2 : !cir.eh_token)
+^bb5(%eh_token : !cir.eh_token)
+  %3 = cir.begin_cleanup(%eh_token : !cir.eh_token) : !cir.cleanup_token
+  cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.end_cleanup(%3 : !cir.cleanup_token)
+  cir.br ^bb6(%eh_token : !cir.eh_token)
+^bb6(%eh_token.1 : !cir.eh_token) // Catch dispatch (from ^bb3 or ^bb4)
+  cir.eh.dispatch %eh_token.1 : !cir.eh_token [
+    catch_all : ^bb7
+  ]
+^bb7(%eh_token.2 : !cir.eh_token)
+  %catch.token = cir.begin_catch(%eh_token.2 : !cir.eh_token) : !cir.catch_token
+  cir.end_catch(%catch.token : !cir.catch_token)
+  cir.br ^bb8
+^bb8 // Normal continue (from ^bb2 or ^bb6)
+  cir.return
+}
+```
 
 In this example, the normal cleanup is performed in a different block
 than the EH cleanup. This follows the pattern established by Clang's
-LLVM IR codegen. Only the EH cleanup requires ``cir.begin_cleanup`` and
-``cir.end_cleanup`` operations.
+LLVM IR codegen. Only the EH cleanup requires `cir.begin_cleanup` and
+`cir.end_cleanup` operations.
 
-If the ``SomeClass`` constructor throws an exception, it unwinds to an EH
-catch block (``^bb3``), which has excecutes a ``cir.eh.initiate`` operation
-before branching to a shared catch dispatch block (``^bb6``).
+If the `SomeClass` constructor throws an exception, it unwinds to an EH
+catch block (`^bb3`), which has excecutes a `cir.eh.initiate` operation
+before branching to a shared catch dispatch block (`^bb6`).
 
-If the ``doSomething()`` function throws an exception, it unwinds to an EH
-block ``^bb4`` that performs cleanup before branching to the shared catch
-dispatch block (``^bb5``).
+If the `doSomething()` function throws an exception, it unwinds to an EH
+block `^bb4` that performs cleanup before branching to the shared catch
+dispatch block (`^bb5`).
 
-Example: Cleanup with unhandled exception
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Example: Cleanup with unhandled exception
 
 **C++**
 
-.. code-block:: c++
-
-    void someFunc() {
-      SomeClass c;
-      c.doSomething();
-    }
+```c++
+void someFunc() {
+  SomeClass c;
+  c.doSomething();
+}
+```
 
 **High-level CIR**
 
-.. code-block::
-
-    cir.func @someFunc(){
-      %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-      cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.cleanup.scope {
-        cir.call @_ZN9SomeClass11doSomethingEv(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-        cir.yield
-      } cleanup all {
-        cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-        cir.yield
-      }
-      cir.return
-    }
+```
+cir.func @someFunc(){
+  %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+  cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.cleanup.scope {
+    cir.call @_ZN9SomeClass11doSomethingEv(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+    cir.yield
+  } cleanup all {
+    cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+    cir.yield
+  }
+  cir.return
+}
+```
 
 **Flattened CIR**
 
-.. code-block::
-
-    cir.func @someFunc(){
-      %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-      cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.try_call @_ZN9SomeClass11doSomethingEv(%0) ^bb1, ^bb2 : (!cir.ptr<!rec_SomeClass>) -> ()
-    ^bb1 // Normal cleanup
-      cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.br ^bb4
-    ^bb2 // EH cleanup (from entry block)
-      %1 = cir.eh.initiate cleanup : !cir.eh_token
-      cir.br ^bb3(%1 : !cir.eh_token)
-    ^bb3(%eh_token : !cir.eh_token) // Perform cleanup
-      %2 = cir.begin_cleanup(%eh_token : !cir.eh_token) : !cir.cleanup_token
-      cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.end_cleanup(%2 : !cir.cleanup_token)
-      cir.resume %eh_token : !cir.eh_token // Unwind to caller
-    ^bb4 // Normal continue (from ^bb1)
-      cir.return
-    }
-
-In this example, if ``doSomething()`` throws an exception, it unwinds to
-the EH cleanup block (``^bb2``), which branches to ``^bb3`` to perform the
-cleanup, but because we have no catch handler, we execute ``cir.resume``
-after the cleanup to unwind to the function that called ``someFunc()``.
-
-Throwing Calls in Cleanup Regions
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+```
+cir.func @someFunc(){
+  %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+  cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.try_call @_ZN9SomeClass11doSomethingEv(%0) ^bb1, ^bb2 : (!cir.ptr<!rec_SomeClass>) -> ()
+^bb1 // Normal cleanup
+  cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.br ^bb4
+^bb2 // EH cleanup (from entry block)
+  %1 = cir.eh.initiate cleanup : !cir.eh_token
+  cir.br ^bb3(%1 : !cir.eh_token)
+^bb3(%eh_token : !cir.eh_token) // Perform cleanup
+  %2 = cir.begin_cleanup(%eh_token : !cir.eh_token) : !cir.cleanup_token
+  cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.end_cleanup(%2 : !cir.cleanup_token)
+  cir.resume %eh_token : !cir.eh_token // Unwind to caller
+^bb4 // Normal continue (from ^bb1)
+  cir.return
+}
+```
+
+In this example, if `doSomething()` throws an exception, it unwinds to
+the EH cleanup block (`^bb2`), which branches to `^bb3` to perform the
+cleanup, but because we have no catch handler, we execute `cir.resume`
+after the cleanup to unwind to the function that called `someFunc()`.
+
+#### Throwing Calls in Cleanup Regions
 
 When a call in an EH cleanup region may throw an exception, it requires
 special handling. The C++ standard requires that if an exception is
 thrown during exception cleanup (i.e., while unwinding a previous
-exception), the program must call ``std::terminate()``. In the flattened
-CIR, such calls are replaced with ``cir.try_call`` operations whose
-unwind destination contains a ``cir.eh.initiate`` followed by a
-``cir.eh.terminate`` operation.
+exception), the program must call `std::terminate()`. In the flattened
+CIR, such calls are replaced with `cir.try_call` operations whose
+unwind destination contains a `cir.eh.initiate` followed by a
+`cir.eh.terminate` operation.
 
-The ``cir.eh.terminate`` operation is a terminator that signals the need
+The `cir.eh.terminate` operation is a terminator that signals the need
 for program termination due to an exception thrown during cleanup. It
-takes the ``!cir.eh_token`` returned by ``cir.eh.initiate`` and is further
+takes the `!cir.eh_token` returned by `cir.eh.initiate` and is further
 processed during EH ABI lowering, where it is replaced with target-specific
 termination code.
 
-Example: Cleanup with throwing destructor
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Example: Cleanup with throwing destructor
 
 **C++**
 
-.. code-block:: c++
+```c++
+struct ThrowingDtor {
+  ~ThrowingDtor() noexcept(false);
+};
 
-    struct ThrowingDtor {
-      ~ThrowingDtor() noexcept(false);
-    };
-
-    void someFunc() {
-      ThrowingDtor c;
-      c.doSomething();
-    }
+void someFunc() {
+  ThrowingDtor c;
+  c.doSomething();
+}
+```
 
 **CIR**
 
-.. code-block::
-
-    cir.func @someFunc(){
-      %0 = cir.alloca !rec_ThrowingDtor, !cir.ptr<!rec_ThrowingDtor>, ["c", init]
-      cir.call @_ZN12ThrowingDtorC1Ev(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
-      cir.cleanup.scope {
-        cir.call @_ZN12ThrowingDtor11doSomethingEv(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
-        cir.yield
-      } cleanup all {
-        cir.call @_ZN12ThrowingDtorD1Ev(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
-        cir.yield
-      }
-      cir.return
-    }
+```
+cir.func @someFunc(){
+  %0 = cir.alloca !rec_ThrowingDtor, !cir.ptr<!rec_ThrowingDtor>, ["c", init]
+  cir.call @_ZN12ThrowingDtorC1Ev(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
+  cir.cleanup.scope {
+    cir.call @_ZN12ThrowingDtor11doSomethingEv(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
+    cir.yield
+  } cleanup all {
+    cir.call @_ZN12ThrowingDtorD1Ev(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
+    cir.yield
+  }
+  cir.return
+}
+```
 
 **Flattened CIR**
 
-.. code-block::
-
-    cir.func @someFunc(){
-      %0 = cir.alloca !rec_ThrowingDtor, !cir.ptr<!rec_ThrowingDtor>, ["c", init]
-      cir.call @_ZN12ThrowingDtorC1Ev(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
-      cir.try_call @_ZN12ThrowingDtor11doSomethingEv(%0) ^bb1, ^bb2 : (!cir.ptr<!rec_ThrowingDtor>) -> ()
-    ^bb1 // Normal cleanup
-      cir.call @_ZN12ThrowingDtorD1Ev(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
-      cir.br ^bb6
-    ^bb2 // EH cleanup (from entry block)
-      %1 = cir.eh.initiate cleanup : !cir.eh_token
-      cir.br ^bb3(%1 : !cir.eh_token)
-    ^bb3(%eh_token : !cir.eh_token) // Perform cleanup
-      %2 = cir.begin_cleanup(%eh_token : !cir.eh_token) : !cir.cleanup_token
-      cir.try_call @_ZN12ThrowingDtorD1Ev(%0) ^bb4, ^bb5 : (!cir.ptr<!rec_ThrowingDtor>) -> ()
-    ^bb4 // Destructor completed: continue unwinding
-      cir.end_cleanup(%2 : !cir.cleanup_token)
-      cir.resume %eh_token : !cir.eh_token
-    ^bb5 // Destructor threw: terminate
-      %3 = cir.eh.initiate : !cir.eh_token
-      cir.eh.terminate %3 : !cir.eh_token
-    ^bb6 // Normal continue (from ^bb1)
-      cir.return
-    }
-
-In this example, the destructor for ``ThrowingDtor`` may throw. In the
-normal cleanup path (``^bb1``), the destructor is a regular ``cir.call``
+```
+cir.func @someFunc(){
+  %0 = cir.alloca !rec_ThrowingDtor, !cir.ptr<!rec_ThrowingDtor>, ["c", init]
+  cir.call @_ZN12ThrowingDtorC1Ev(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
+  cir.try_call @_ZN12ThrowingDtor11doSomethingEv(%0) ^bb1, ^bb2 : (!cir.ptr<!rec_ThrowingDtor>) -> ()
+^bb1 // Normal cleanup
+  cir.call @_ZN12ThrowingDtorD1Ev(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
+  cir.br ^bb6
+^bb2 // EH cleanup (from entry block)
+  %1 = cir.eh.initiate cleanup : !cir.eh_token
+  cir.br ^bb3(%1 : !cir.eh_token)
+^bb3(%eh_token : !cir.eh_token) // Perform cleanup
+  %2 = cir.begin_cleanup(%eh_token : !cir.eh_token) : !cir.cleanup_token
+  cir.try_call @_ZN12ThrowingDtorD1Ev(%0) ^bb4, ^bb5 : (!cir.ptr<!rec_ThrowingDtor>) -> ()
+^bb4 // Destructor completed: continue unwinding
+  cir.end_cleanup(%2 : !cir.cleanup_token)
+  cir.resume %eh_token : !cir.eh_token
+^bb5 // Destructor threw: terminate
+  %3 = cir.eh.initiate : !cir.eh_token
+  cir.eh.terminate %3 : !cir.eh_token
+^bb6 // Normal continue (from ^bb1)
+  cir.return
+}
+```
+
+In this example, the destructor for `ThrowingDtor` may throw. In the
+normal cleanup path (`^bb1`), the destructor is a regular `cir.call`
 since the exception would propagate normally. In the EH cleanup path
-(``^bb3``), the destructor call is a ``cir.try_call`` because if the
+(`^bb3`), the destructor call is a `cir.try_call` because if the
 destructor throws during exception unwinding, the program must
 terminate. If the destructor completes normally, the exception
-continues unwinding via ``cir.resume``. If the destructor throws, control
-transfers to ``^bb5``, which initiates exception handling and immediately
+continues unwinding via `cir.resume`. If the destructor throws, control
+transfers to `^bb5`, which initiates exception handling and immediately
 terminates.
 
-Example: Shared cleanups
-^^^^^^^^^^^^^^^^^^^^^^^^
+#### Example: Shared cleanups
 
 **C++**
 
-.. code-block:: c++
-
-    int someFunc() {
-      int i = 0;
-      while (true) {
-        SomeClass c;
-        if (i == 3)
-          continue;
-        if (i == 7)
-          break;
-        i = c.get();
-      }
-      return i;
-    }
+```c++
+int someFunc() {
+  int i = 0;
+  while (true) {
+    SomeClass c;
+    if (i == 3)
+      continue;
+    if (i == 7)
+      break;
+    i = c.get();
+  }
+  return i;
+}
+```
 
 **CIR**
 
-.. code-block::
-
-    cir.func @someFunc() -> !s32i {
-      %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
-      %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init]
-      %2 = cir.const #cir.int<0> : !s32i
-      cir.store align(4) %2, %1 : !s32i, !cir.ptr<!s32i>
+```
+cir.func @someFunc() -> !s32i {
+  %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
+  %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init]
+  %2 = cir.const #cir.int<0> : !s32i
+  cir.store align(4) %2, %1 : !s32i, !cir.ptr<!s32i>
+  cir.scope {
+    cir.while {
+      %5 = cir.const #true
+      cir.condition(%5)
+    } do {
       cir.scope {
-        cir.while {
-          %5 = cir.const #true
-          cir.condition(%5)
-        } do {
+        %5 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+        cir.call @_ZN9SomeClassC1Ev(%5) : (!cir.ptr<!rec_SomeClass>) -> ()
+        cir.cleanup.scope {
+          cir.scope {
+            %7 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
+            %8 = cir.const #cir.int<3> : !s32i
+            %9 = cir.cmp(eq, %7, %8) : !s32i, !cir.bool
+            cir.if %9 {
+              cir.continue
+            }
+          }
           cir.scope {
-            %5 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-            cir.call @_ZN9SomeClassC1Ev(%5) : (!cir.ptr<!rec_SomeClass>) -> ()
-            cir.cleanup.scope {
-              cir.scope {
-                %7 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
-                %8 = cir.const #cir.int<3> : !s32i
-                %9 = cir.cmp(eq, %7, %8) : !s32i, !cir.bool
-                cir.if %9 {
-                  cir.continue
-                }
-              }
-              cir.scope {
-                %7 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
-                %8 = cir.const #cir.int<7> : !s32i
-                %9 = cir.cmp(eq, %7, %8) : !s32i, !cir.bool
-                cir.if %9 {
-                  cir.break
-                }
-              }
-              %6 = cir.call @_ZN9SomeClass3getEv(%5) : (!cir.ptr<!rec_SomeClass>) -> !s32i
-              cir.store align(4) %6, %1 : !s32i, !cir.ptr<!s32i>
-              cir.yield
-            } cleanup all {
-              cir.call @_ZN9SomeClassD1Ev(%5) : (!cir.ptr<!rec_SomeClass>) -> ()
-              cir.yield
+            %7 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
+            %8 = cir.const #cir.int<7> : !s32i
+            %9 = cir.cmp(eq, %7, %8) : !s32i, !cir.bool
+            cir.if %9 {
+              cir.break
             }
           }
+          %6 = cir.call @_ZN9SomeClass3getEv(%5) : (!cir.ptr<!rec_SomeClass>) -> !s32i
+          cir.store align(4) %6, %1 : !s32i, !cir.ptr<!s32i>
+          cir.yield
+        } cleanup all {
+          cir.call @_ZN9SomeClassD1Ev(%5) : (!cir.ptr<!rec_SomeClass>) -> ()
           cir.yield
         }
       }
-      %3 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
-      cir.store %3, %0 : !s32i, !cir.ptr<!s32i>
-      %4 = cir.load %0 : !cir.ptr<!s32i>, !s32i
-      cir.return %4 : !s32i
+      cir.yield
     }
+  }
+  %3 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
+  cir.store %3, %0 : !s32i, !cir.ptr<!s32i>
+  %4 = cir.load %0 : !cir.ptr<!s32i>, !s32i
+  cir.return %4 : !s32i
+}
+```
 
 **Flattened CIR**
 
-.. code-block::
-
-    cir.func @someFunc() -> !s32i {
-      %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-      %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__cleanup_dest_slot "]
-      %2 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
-      %3 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init]
-      %4 = cir.const #cir.int<0> : !s32i
-      cir.store align(4) %4, %3 : !s32i, !cir.ptr<!s32i>
-      cir.br ^bb1
-    ^bb1:  // 3 preds: ^bb0, ^bb9, ^bb11
-      %5 = cir.const #true
-      cir.brcond %5 ^bb2, ^bb12
-    ^bb2:  // pred: ^bb1
-      cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.br ^bb3
-    ^bb3:  // pred: ^bb2
-      %6 = cir.load align(4) %3 : !cir.ptr<!s32i>, !s32i
-      %7 = cir.const #cir.int<3> : !s32i
-      %8 = cir.cmp(eq, %6, %7) : !s32i, !cir.bool
-      cir.brcond %8 ^bb4, ^bb5
-    ^bb4:  // pred: ^bb3
-      // Set the destination slot and branch through cleanup
-      %9 = cir.const #cir.int<0> : !s32i
-      cir.store %9, %1 : !s32i, !cir.ptr<!s32i>
-      cir.br ^bb9
-    ^bb5:  // pred: ^bb3
-      %10 = cir.load align(4) %3 : !cir.ptr<!s32i>, !s32i
-      %11 = cir.const #cir.int<7> : !s32i
-      %12 = cir.cmp(eq, %10, %11) : !s32i, !cir.bool
-      cir.brcond %12 ^bb6, ^bb7
-    ^bb6:  // pred: ^bb5
-      // Set the destination slot and branch through cleanup
-      %13 = cir.const #cir.int<1> : !s32i
-      cir.store %13, %1 : !s32i, !cir.ptr<!s32i>
-      cir.br ^bb9
-    ^bb7:  // pred: ^bb5
-      %14 = cir.call @_ZN9SomeClass3getEv(%0) : (!cir.ptr<!rec_SomeClass>) -> !s32i
-      cir.store align(4) %14, %3 : !s32i, !cir.ptr<!s32i>
-      cir.br ^bb8
-    ^bb8: // pred: ^bb7
-      // Set the destination slot and branch through cleanup
-      %15 = cir.const #cir.int<2> : !s32i
-      cir.store %15, %1 : !s32i, !cir.ptr<!s32i>
-      cir.br ^bb9
-    ^bb9: // pred
-      // Shared cleanup
-      cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      %16 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
-      cir.switch.flat %16 : !s32i, ^bb10 [
-        0: ^bb1  // continue
-        1: ^bb12 // break
-        2: ^bb11 // end of loop
-      ]
-    ^bb10:  // preds: ^bb9
-      cir.unreachable
-    ^bb11:  // pred: ^bb9
-      cir.br ^bb1
-    ^bb12:  // pred: ^bb1
-      %17 = cir.load align(4) %3 : !cir.ptr<!s32i>, !s32i
-      cir.store align(4) %17, %2 : !s32i, !cir.ptr<!s32i>
-      %18 = cir.load align(4) %2 : !cir.ptr<!s32i>, !s32i
-      cir.return %18 : !s32i
-    }
+```
+cir.func @someFunc() -> !s32i {
+  %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+  %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__cleanup_dest_slot "]
+  %2 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
+  %3 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init]
+  %4 = cir.const #cir.int<0> : !s32i
+  cir.store align(4) %4, %3 : !s32i, !cir.ptr<!s32i>
+  cir.br ^bb1
+^bb1:  // 3 preds: ^bb0, ^bb9, ^bb11
+  %5 = cir.const #true
+  cir.brcond %5 ^bb2, ^bb12
+^bb2:  // pred: ^bb1
+  cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.br ^bb3
+^bb3:  // pred: ^bb2
+  %6 = cir.load align(4) %3 : !cir.ptr<!s32i>, !s32i
+  %7 = cir.const #cir.int<3> : !s32i
+  %8 = cir.cmp(eq, %6, %7) : !s32i, !cir.bool
+  cir.brcond %8 ^bb4, ^bb5
+^bb4:  // pred: ^bb3
+  // Set the destination slot and branch through cleanup
+  %9 = cir.const #cir.int<0> : !s32i
+  cir.store %9, %1 : !s32i, !cir.ptr<!s32i>
+  cir.br ^bb9
+^bb5:  // pred: ^bb3
+  %10 = cir.load align(4) %3 : !cir.ptr<!s32i>, !s32i
+  %11 = cir.const #cir.int<7> : !s32i
+  %12 = cir.cmp(eq, %10, %11) : !s32i, !cir.bool
+  cir.brcond %12 ^bb6, ^bb7
+^bb6:  // pred: ^bb5
+  // Set the destination slot and branch through cleanup
+  %13 = cir.const #cir.int<1> : !s32i
+  cir.store %13, %1 : !s32i, !cir.ptr<!s32i>
+  cir.br ^bb9
+^bb7:  // pred: ^bb5
+  %14 = cir.call @_ZN9SomeClass3getEv(%0) : (!cir.ptr<!rec_SomeClass>) -> !s32i
+  cir.store align(4) %14, %3 : !s32i, !cir.ptr<!s32i>
+  cir.br ^bb8
+^bb8: // pred: ^bb7
+  // Set the destination slot and branch through cleanup
+  %15 = cir.const #cir.int<2> : !s32i
+  cir.store %15, %1 : !s32i, !cir.ptr<!s32i>
+  cir.br ^bb9
+^bb9: // pred
+  // Shared cleanup
+  cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  %16 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
+  cir.switch.flat %16 : !s32i, ^bb10 [
+    0: ^bb1  // continue
+    1: ^bb12 // break
+    2: ^bb11 // end of loop
+  ]
+^bb10:  // preds: ^bb9
+  cir.unreachable
+^bb11:  // pred: ^bb9
+  cir.br ^bb1
+^bb12:  // pred: ^bb1
+  %17 = cir.load align(4) %3 : !cir.ptr<!s32i>, !s32i
+  cir.store align(4) %17, %2 : !s32i, !cir.ptr<!s32i>
+  %18 = cir.load align(4) %2 : !cir.ptr<!s32i>, !s32i
+  cir.return %18 : !s32i
+}
+```
 
 In this example we have a cleanup scope inside the body of a while loop,
 and multiple instructions that may exit the loop body with different
@@ -1213,17 +1190,16 @@ slot value to the set of expected constants and branches to the
 corresponding destination.
 
 For example, when the continue instruction is reached, we set the
-cleanup destination slot (``%1``) to zero, branch to the shared cleanup
-block (``^bb9``), which calls the ``SomeClass`` destructor, then uses
-``cir.switch.flat`` to switch on the cleanup destination slot value and,
-finding it to be zero, branches to the loop condition block (``^bb1``).
+cleanup destination slot (`%1`) to zero, branch to the shared cleanup
+block (`^bb9`), which calls the `SomeClass` destructor, then uses
+`cir.switch.flat` to switch on the cleanup destination slot value and,
+finding it to be zero, branches to the loop condition block (`^bb1`).
 
-If none of the expected values is matched, the ``cir.switch.flat``
-branches to a block with a ``cir.unreachable`` operation. This corresponds
+If none of the expected values is matched, the `cir.switch.flat`
+branches to a block with a `cir.unreachable` operation. This corresponds
 to the behavior of Clang's LLVM IR codegen.
 
-ABI Lowering
-============
+## ABI Lowering
 
 A new pass will be introduced to lower the flattened representation to
 lower the ABI-agnostic flattened CIR representation to an ABI-specific
@@ -1231,401 +1207,396 @@ form. This will be a separate pass from the main CXXABI lowering pass,
 which runs before CFG flattening. The ABI lowering pass will introduce
 personality functions and ABI-specific exception handling operations.
 
-This new pass will make use of the ``cir::CXXABI`` interface class and
+This new pass will make use of the `cir::CXXABI` interface class and
 ABI-specific subclasses, but it will introduce a new set of interface
 methods for use with the exception handling ABI.
 
 For each supported exception handling ABI, the operations and function
 calls used will have a direct correspondence to the LLVM IR instructions
 and runtime library functions used for that ABI. The LLVM IR exception
-handling model is described in detail here: `LLVM Exception
-Handling <https://llvm.org/docs/ExceptionHandling.html>`__.
+handling model is described in detail here: [LLVM Exception
+Handling](https://llvm.org/docs/ExceptionHandling.html).
 
 A personality function attribute will be added to functions that require
 it during the ABI lowering phase.
 
-Itanium ABI Lowering
---------------------
+### Itanium ABI Lowering
 
 The Itanium exception handling ABI representation replaces the
-``cir.eh.initiate`` and ``cir.eh.dispatch`` operations with a
-``cir.eh.landingpad`` operation and a series of ``cir.compare`` and
-``cir.brcond`` operations to model the correct handling based on type IDs
-for the catch handlers. The ``cir.begin_cleanup`` and ``cir.end_cleanup``
-operations are simply dropped. The ``cir.begin_catch`` operation becomes a
-call to ``__cxa_begin_catch``. The ``cir.end_catch`` operation becomes a
-call to ``__cxa_end_catch``. The ``cir.eh.terminate`` operation becomes a
-call to ``__clang_call_terminate`` (which calls ``__cxa_begin_catch``
-followed by ``std::terminate()``) and then an unreachable operation.
+`cir.eh.initiate` and `cir.eh.dispatch` operations with a
+`cir.eh.landingpad` operation and a series of `cir.compare` and
+`cir.brcond` operations to model the correct handling based on type IDs
+for the catch handlers. The `cir.begin_cleanup` and `cir.end_cleanup`
+operations are simply dropped. The `cir.begin_catch` operation becomes a
+call to `__cxa_begin_catch`. The `cir.end_catch` operation becomes a
+call to `__cxa_end_catch`. The `cir.eh.terminate` operation becomes a
+call to `__clang_call_terminate` (which calls `__cxa_begin_catch`
+followed by `std::terminate()`) and then an unreachable operation.
 
 The only operation that is specific to Itanium exception handling is
-``cir.eh.landingpad``.
-
-.. code-block::
+`cir.eh.landingpad`.
 
-    %exn_ptr_0, %type_id = cir.eh.landingpad [@_ZTISt9exception] : !cir.ptr<!void>, !u32i
+```
+%exn_ptr_0, %type_id = cir.eh.landingpad [@_ZTISt9exception] : !cir.ptr<!void>, !u32i
+```
 
 This operation corresponds directly to the LLVM IR landingpad
 instruction. It may have a list of type IDs that the handler can catch
 (or null for "catch all") or it may have the cleanup attribute if the
 handler performs cleanup but does not catch any exceptions.
 
-Example: Try-catch with cleanup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Example: Try-catch with cleanup
 
 **Flattened CIR**
 
-.. code-block::
-
-    cir.func @someFunc(){
-      %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-      cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
-    ^bb1
-      cir.try_call @_ZN9SomeClass11doSomethingEv(%0) ^bb2, ^bb4 : (!cir.ptr<!rec_SomeClass>) -> ()
-    ^bb2 // Normal cleanup
-      cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.br ^bb8
-    ^bb3 // EH catch (from entry block)
-      %1 = cir.eh.initiate : !cir.eh_token
-      cir.br ^bb6(%1 : !cir.eh_token)
-    ^bb4 // EH cleanup (from ^bb1)
-      %2 = cir.eh.initiate cleanup : !cir.eh_token
-      cir.br ^bb5(%2 : !cir.eh_token)
-    ^bb5(%eh_token : !cir.eh_token)
-      %3 = cir.begin_cleanup(%eh_token : !cir.eh_token) : !cir.cleanup_token
-      cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.end_cleanup(%3 : !cir.cleanup_token)
-      cir.br ^bb6(%eh_token : !cir.eh_token)
-    ^bb6(%eh_token.1 : !cir.eh_token) // Catch dispatch (from ^bb3 or ^bb4)
-      cir.eh.dispatch %eh_token.1 : !cir.eh_token [
-        catch_all : ^bb7
-      ]
-    ^bb7(%eh_token.2 : !cir.eh_token)
-      %catch.token = cir.begin_catch(%eh_token.2 : !cir.eh_token) : !cir.catch_token
-      cir.end_catch(%catch.token : !cir.catch_token)
-      cir.br ^bb8
-    ^bb8 // Normal continue (from ^bb2 or ^bb6)
-      cir.return
-    }
+```
+cir.func @someFunc(){
+  %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+  cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
+^bb1
+  cir.try_call @_ZN9SomeClass11doSomethingEv(%0) ^bb2, ^bb4 : (!cir.ptr<!rec_SomeClass>) -> ()
+^bb2 // Normal cleanup
+  cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.br ^bb8
+^bb3 // EH catch (from entry block)
+  %1 = cir.eh.initiate : !cir.eh_token
+  cir.br ^bb6(%1 : !cir.eh_token)
+^bb4 // EH cleanup (from ^bb1)
+  %2 = cir.eh.initiate cleanup : !cir.eh_token
+  cir.br ^bb5(%2 : !cir.eh_token)
+^bb5(%eh_token : !cir.eh_token)
+  %3 = cir.begin_cleanup(%eh_token : !cir.eh_token) : !cir.cleanup_token
+  cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.end_cleanup(%3 : !cir.cleanup_token)
+  cir.br ^bb6(%eh_token : !cir.eh_token)
+^bb6(%eh_token.1 : !cir.eh_token) // Catch dispatch (from ^bb3 or ^bb4)
+  cir.eh.dispatch %eh_token.1 : !cir.eh_token [
+    catch_all : ^bb7
+  ]
+^bb7(%eh_token.2 : !cir.eh_token)
+  %catch.token = cir.begin_catch(%eh_token.2 : !cir.eh_token) : !cir.catch_token
+  cir.end_catch(%catch.token : !cir.catch_token)
+  cir.br ^bb8
+^bb8 // Normal continue (from ^bb2 or ^bb6)
+  cir.return
+}
+```
 
 **ABI-lowered CIR**
 
-.. code-block::
-
-    cir.func @someFunc() #personality_fn = @__gxx_personality_v0 {
-      %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-      cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
-    ^bb1
-      cir.try_call @_ZN9SomeClass11doSomethingEv(%0) ^bb2, ^bb4 : (!cir.ptr<!rec_SomeClass>) -> ()
-    ^bb2 // Normal cleanup
-      cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.br ^bb8
-    ^bb3 // EH catch (from entry block)
-      %exn, %type_id = cir.eh.landingpad [null] : (!cir.ptr<!void>, !u32i)
-      cir.br ^bb6(%exn, &type_id : !cir.ptr<!void>, !u32i)
-    ^bb4 // EH cleanup (from ^bb1)
-      %exn.1, %type_id.1 = cir.eh.landingpad cleanup [null] : (!cir.ptr<!void>, !u32i)
-      cir.br ^bb5(%exn, %type_id : !cir.ptr<!void>, !u32i)
-    ^bb5(%1: !cir.ptr<!void>, %2: !u32i)
-      cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.br ^bb6(%1, %2 : !cir.ptr<!void>, !u32i)
-    ^bb6(%3: !cir.ptr<!void>, %4: !u32i) // Catch dispatch (from ^bb3 or ^bb4)
-      cir.br ^bb7(%3, %4 : !cir.ptr<!void>, !u32i)
-    ^bb7(%5: !cir.ptr<!void>, %6: !u32i) // Catch all handler
-      %7 = cir.call @__cxa_begin_catch(%5 : !cir.ptr<!void>)
-      cir.call @__cxa_end_catch()
-      cir.br ^bb8
-    ^bb8 // Normal continue (from ^bb2 or ^bb6)
-      cir.return
-    }
-
-In this example, if an exception is thrown by the ``SomeClass``
-constructor, it unwinds to a landing pad block (``^bb3``), which branches
-to the shared catch dispatch block (``^bb6``), which branches to the catch
-all handler block (``^bb7``). The catch all handler calls
-``__cxa_begin_catch`` and ``__cxa_end_catch`` and then continues to the
-normal continuation block (``^bb8``).
-
-Example: Try-catch with multiple catch handlers
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+```
+cir.func @someFunc() #personality_fn = @__gxx_personality_v0 {
+  %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+  cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
+^bb1
+  cir.try_call @_ZN9SomeClass11doSomethingEv(%0) ^bb2, ^bb4 : (!cir.ptr<!rec_SomeClass>) -> ()
+^bb2 // Normal cleanup
+  cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.br ^bb8
+^bb3 // EH catch (from entry block)
+  %exn, %type_id = cir.eh.landingpad [null] : (!cir.ptr<!void>, !u32i)
+  cir.br ^bb6(%exn, &type_id : !cir.ptr<!void>, !u32i)
+^bb4 // EH cleanup (from ^bb1)
+  %exn.1, %type_id.1 = cir.eh.landingpad cleanup [null] : (!cir.ptr<!void>, !u32i)
+  cir.br ^bb5(%exn, %type_id : !cir.ptr<!void>, !u32i)
+^bb5(%1: !cir.ptr<!void>, %2: !u32i)
+  cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.br ^bb6(%1, %2 : !cir.ptr<!void>, !u32i)
+^bb6(%3: !cir.ptr<!void>, %4: !u32i) // Catch dispatch (from ^bb3 or ^bb4)
+  cir.br ^bb7(%3, %4 : !cir.ptr<!void>, !u32i)
+^bb7(%5: !cir.ptr<!void>, %6: !u32i) // Catch all handler
+  %7 = cir.call @__cxa_begin_catch(%5 : !cir.ptr<!void>)
+  cir.call @__cxa_end_catch()
+  cir.br ^bb8
+^bb8 // Normal continue (from ^bb2 or ^bb6)
+  cir.return
+}
+```
+
+In this example, if an exception is thrown by the `SomeClass`
+constructor, it unwinds to a landing pad block (`^bb3`), which branches
+to the shared catch dispatch block (`^bb6`), which branches to the catch
+all handler block (`^bb7`). The catch all handler calls
+`__cxa_begin_catch` and `__cxa_end_catch` and then continues to the
+normal continuation block (`^bb8`).
+
+#### Example: Try-catch with multiple catch handlers
 
 **Flattened CIR**
 
-.. code-block::
-
-    cir.func @someFunc(){
-      cir.try_call @f() ^bb1, ^bb2
-    ^bb1
-      cir.br ^bb7
-    ^bb2 // EH catch (from entry block)
-      %1 = cir.eh.initiate : !cir.eh_token
-      cir.br ^bb3(%1 : !cir.eh_token)
-    ^bb3(%eh_token : !cir.eh_token) // Catch dispatch (from ^bb2)
-      cir.eh.dispatch %eh_token : !cir.eh_token [
-        catch (#cir.global_view<@_ZTIi> : !u32i) : ^bb4
-        catch (#cir.global_view<@_ZTIf> : !u32i) : ^bb5
-        catch_all : ^bb6
-      ]
-    ^bb4(%eh_token.1 : !cir.eh_token) // Catch handler for int exception
-      %catch.token = cir.begin_catch(%eh_token.1 : !cir.eh_token) : !cir.catch_token
-      cir.end_catch(%catch.token : !cir.catch_token)
-      cir.br ^bb7
-    ^bb5(%eh_token.2 : !cir.eh_token) // Catch handler for float exception
-      %catch.token = cir.begin_catch(%eh_token.2 : !cir.eh_token) : !cir.catch_token
-      cir.end_catch(%catch.token : !cir.catch_token)
-      cir.br ^bb7
-    ^bb6(%eh_token.3 : !cir.eh_token) // Catch all handler
-      %catch.token = cir.begin_catch(%eh_token.3 : !cir.eh_token) : !cir.catch_token
-      cir.end_catch(%catch.token : !cir.catch_token)
-      cir.br ^bb7
-    ^bb7 // Normal continue (from ^bb1, ^bb4, ^bb5, or ^bb6)
-      cir.return
-    }
+```
+cir.func @someFunc(){
+  cir.try_call @f() ^bb1, ^bb2
+^bb1
+  cir.br ^bb7
+^bb2 // EH catch (from entry block)
+  %1 = cir.eh.initiate : !cir.eh_token
+  cir.br ^bb3(%1 : !cir.eh_token)
+^bb3(%eh_token : !cir.eh_token) // Catch dispatch (from ^bb2)
+  cir.eh.dispatch %eh_token : !cir.eh_token [
+    catch (#cir.global_view<@_ZTIi> : !u32i) : ^bb4
+    catch (#cir.global_view<@_ZTIf> : !u32i) : ^bb5
+    catch_all : ^bb6
+  ]
+^bb4(%eh_token.1 : !cir.eh_token) // Catch handler for int exception
+  %catch.token = cir.begin_catch(%eh_token.1 : !cir.eh_token) : !cir.catch_token
+  cir.end_catch(%catch.token : !cir.catch_token)
+  cir.br ^bb7
+^bb5(%eh_token.2 : !cir.eh_token) // Catch handler for float exception
+  %catch.token = cir.begin_catch(%eh_token.2 : !cir.eh_token) : !cir.catch_token
+  cir.end_catch(%catch.token : !cir.catch_token)
+  cir.br ^bb7
+^bb6(%eh_token.3 : !cir.eh_token) // Catch all handler
+  %catch.token = cir.begin_catch(%eh_token.3 : !cir.eh_token) : !cir.catch_token
+  cir.end_catch(%catch.token : !cir.catch_token)
+  cir.br ^bb7
+^bb7 // Normal continue (from ^bb1, ^bb4, ^bb5, or ^bb6)
+  cir.return
+}
+```
 
 **ABI-lowered CIR**
 
-.. code-block::
-
-    cir.func @someFunc() #personality_fn = @__gxx_personality_v0 {
-      cir.try_call @f() ^bb1, ^bb2
-    ^bb1
-      cir.br ^bb8
-    ^bb2 // EH catch (from entry block)
-      %exn, %type_id = cir.eh.landingpad [null] : (!cir.ptr<!void>, !u32i)
-      cir.br ^bb3(%exn, &type_id : !cir.ptr<!void>, !u32i)
-    ^bb3(%0: !cir.ptr<!void>, %1: !u32i) // Catch compare for int exception
-      %2 = cir.eh.typeid @_ZTIi : !u32i
-      %3 = cir.cmp(eq, %1, %2) : !u32i, !cir.bool
-      cir.brcond %3 ^bb4(%0 : !cir.ptr<!void>), ^bb5(%0, %1 : !cir.ptr<!void>, !u32i)
-    ^bb4(%4: !cir.ptr<!void>, %5: !u32i) // Catch all handler for int exception
-      %6 = cir.call @__cxa_begin_catch(%4 : !cir.ptr<!void>)
-      cir.call @__cxa_end_catch()
-      cir.br ^bb8
-    ^bb5(%7: !cir.ptr<!void>, %8: !u32i) // Catch compare for float exception
-      %9 = cir.eh.typeid @_ZTIf : !u32i
-      %10 = cir.cmp(eq, %8, %9) : !u32i, !cir.bool
-      cir.brcond %10 ^bb7(%7 : !cir.ptr<!void>), ^bb8(%7 : !cir.ptr<!void>)
-    ^bb6(%11: !cir.ptr<!void>, %12: !u32i) // Catch all handler for float exception
-      %13 = cir.call @__cxa_begin_catch(%11 : !cir.ptr<!void>)
-      cir.call @__cxa_end_catch()
-      cir.br ^bb8
-    ^bb7(%14: !cir.ptr<!void>) // Catch all handler
-      %15 = cir.call @__cxa_begin_catch(%14 : !cir.ptr<!void>)
-      cir.call @__cxa_end_catch()
-      cir.br ^bb8
-    ^bb8 // Normal continue (from ^bb1, ^bb4, ^bb6, or ^bb7)
-      cir.return
-    }
-
-In this example, if an exception is thrown by the ``f()`` call, it unwinds
-to a landing pad block (``^bb2``), which uses the ``cir.eh.landingpad``
+```
+cir.func @someFunc() #personality_fn = @__gxx_personality_v0 {
+  cir.try_call @f() ^bb1, ^bb2
+^bb1
+  cir.br ^bb8
+^bb2 // EH catch (from entry block)
+  %exn, %type_id = cir.eh.landingpad [null] : (!cir.ptr<!void>, !u32i)
+  cir.br ^bb3(%exn, &type_id : !cir.ptr<!void>, !u32i)
+^bb3(%0: !cir.ptr<!void>, %1: !u32i) // Catch compare for int exception
+  %2 = cir.eh.typeid @_ZTIi : !u32i
+  %3 = cir.cmp(eq, %1, %2) : !u32i, !cir.bool
+  cir.brcond %3 ^bb4(%0 : !cir.ptr<!void>), ^bb5(%0, %1 : !cir.ptr<!void>, !u32i)
+^bb4(%4: !cir.ptr<!void>, %5: !u32i) // Catch all handler for int exception
+  %6 = cir.call @__cxa_begin_catch(%4 : !cir.ptr<!void>)
+  cir.call @__cxa_end_catch()
+  cir.br ^bb8
+^bb5(%7: !cir.ptr<!void>, %8: !u32i) // Catch compare for float exception
+  %9 = cir.eh.typeid @_ZTIf : !u32i
+  %10 = cir.cmp(eq, %8, %9) : !u32i, !cir.bool
+  cir.brcond %10 ^bb7(%7 : !cir.ptr<!void>), ^bb8(%7 : !cir.ptr<!void>)
+^bb6(%11: !cir.ptr<!void>, %12: !u32i) // Catch all handler for float exception
+  %13 = cir.call @__cxa_begin_catch(%11 : !cir.ptr<!void>)
+  cir.call @__cxa_end_catch()
+  cir.br ^bb8
+^bb7(%14: !cir.ptr<!void>) // Catch all handler
+  %15 = cir.call @__cxa_begin_catch(%14 : !cir.ptr<!void>)
+  cir.call @__cxa_end_catch()
+  cir.br ^bb8
+^bb8 // Normal continue (from ^bb1, ^bb4, ^bb6, or ^bb7)
+  cir.return
+}
+```
+
+In this example, if an exception is thrown by the `f()` call, it unwinds
+to a landing pad block (`^bb2`), which uses the `cir.eh.landingpad`
 operation to capture the exception pointer and its type id, then branches
-to ``^bb3`` to begin searching for a catch handler that handles the type id
+to `^bb3` to begin searching for a catch handler that handles the type id
 of the exception. Each catch handler simply consumes the exception by
-calling ``__cxa_begin_catch`` and ``__cxa_end_catch`` and then continues to
-the normal continuation block (``^bb8``).
+calling `__cxa_begin_catch` and `__cxa_end_catch` and then continues to
+the normal continuation block (`^bb8`).
 
-Microsoft C++ ABI Lowering
---------------------------
+### Microsoft C++ ABI Lowering
 
 The Microsoft C++ exception handling ABI representation drops the
-``cir.eh.initiate`` operation and replaces the ``cir.eh.dispatch`` operation
-with ``cir.eh.catchswitch`` operation. The ``cir.begin_cleanup`` and
-``cir.end_cleanup`` operations are replaced with ``cir.cleanuppad`` and
-``cir.cleanupret`` respectively, and the ``cir.begin_catch`` and
-``cir.end_catch`` operations are replaced with ``cir.catchpad`` and
-``cir.catchret``.
+`cir.eh.initiate` operation and replaces the `cir.eh.dispatch` operation
+with `cir.eh.catchswitch` operation. The `cir.begin_cleanup` and
+`cir.end_cleanup` operations are replaced with `cir.cleanuppad` and
+`cir.cleanupret` respectively, and the `cir.begin_catch` and
+`cir.end_catch` operations are replaced with `cir.catchpad` and
+`cir.catchret`.
 
 Each of these operations corresponds directly to a similarly named
 instruction in LLVM IR and have the same semantics. The first operation
-in the unwind destination of a ``cir.try_call`` must be either
-``cir.eh.catchswitch`` or ``cir.cleanuppad``.
+in the unwind destination of a `cir.try_call` must be either
+`cir.eh.catchswitch` or `cir.cleanuppad`.
 
-.. code-block::
+```
+%4 = cir.eh.catchswitch within none [^bb2, ^bb3] unwind to caller
+```
 
-    %4 = cir.eh.catchswitch within none [^bb2, ^bb3] unwind to caller
-
-The ``cir.eh.catchswitch`` operation takes an operand which specifies the
+The `cir.eh.catchswitch` operation takes an operand which specifies the
 parent token, which may either be none or the token returned by a
-previous ``cir.catchpad`` operation. This is followed by a list of blocks
+previous `cir.catchpad` operation. This is followed by a list of blocks
 which contain catch handlers. Each block in this list must begin with a
-``cir.catchpad`` operation. Finally, the unwind destination is provided to
+`cir.catchpad` operation. Finally, the unwind destination is provided to
 specify where excution continues if the exception is not caught by any
 of the handlers, with unwind to caller indicating that the unwind is not
 handled further in the current function. This operation returns a token
-that is used as the operand for ``cir.catchpad`` operations associated
+that is used as the operand for `cir.catchpad` operations associated
 with this switch.
 
-.. code-block::
-
-    %5 = cir.cleanuppad within none []
+```
+%5 = cir.cleanuppad within none []
+```
 
-The ``cir.cleanuppad`` operation takes an operand which specifies the
+The `cir.cleanuppad` operation takes an operand which specifies the
 parent token, which may either be none or the token returned by a
-previous ``cir.catchpad`` operation. This is followed by a arguments
+previous `cir.catchpad` operation. This is followed by a arguments
 required by the personality function. In the case of C++ exception
-handlers, the personality function will be ``__CxxFrameHandler3`` and the
+handlers, the personality function will be `__CxxFrameHandler3` and the
 argument list will be empty. This operation returns a token that is used
-as the operand for the associated ``cir.cleanupret`` operation.
+as the operand for the associated `cir.cleanupret` operation.
 
-.. code-block::
+```
+cir.cleanupret from %5 unwind to ^bb7
+```
 
-    cir.cleanupret from %5 unwind to ^bb7
-
-The ``cir.cleanupret`` operation takes an operand which specifies the
-``cir.cleanuppad`` operation which is completed by this operation and a
+The `cir.cleanupret` operation takes an operand which specifies the
+`cir.cleanuppad` operation which is completed by this operation and a
 block at which unwinding of the current exception continues (or unwind
 to caller if there is no catch handling in the current function).
 
-.. code-block::
-
-    %8 = cir.catchpad within %4 [ptr @"??_R0H at 8", i32 0, ptr %e]
+```
+%8 = cir.catchpad within %4 [ptr @"??_R0H at 8", i32 0, ptr %e]
+```
 
-The ``cir.catchpad`` operation takes an operand which specifies the parent
-token, which must have been return by a previous ``cir.catchswitch``
+The `cir.catchpad` operation takes an operand which specifies the parent
+token, which must have been return by a previous `cir.catchswitch`
 operation. This is followed by a list of arguments, beginning with the
 typeid for the type of exception being caught (or null for catch all),
 followed by a type info flag value, followed by a pointer to the
 in-flight exception. This operation returns a token that is used as the
-operand for the associated ``cir.catchret`` operation or as the parent for
-any ``cir.catchswitch`` or ``cir.cleanuppad`` operations that are nested
+operand for the associated `cir.catchret` operation or as the parent for
+any `cir.catchswitch` or `cir.cleanuppad` operations that are nested
 within this catch handler.
 
-.. code-block::
+```
+cir.catchret from %8 to ^bb8
+```
 
-    cir.catchret from %8 to ^bb8
-
-The ``cir.catchret`` operation takes an operand which specifies the
-``cir.catchpad`` operation which is completed by this operation and a
+The `cir.catchret` operation takes an operand which specifies the
+`cir.catchpad` operation which is completed by this operation and a
 block at which excution should be resumed.
 
-Example: Try-catch with cleanup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#### Example: Try-catch with cleanup
 
 **Flattened CIR**
 
-.. code-block::
-
-    cir.func @someFunc() {
-      %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-      cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
-    ^bb1
-      cir.try_call @_ZN9SomeClass11doSomethingEv(%0) ^bb2, ^bb4 : (!cir.ptr<!rec_SomeClass>) -> ()
-    ^bb2 // Normal cleanup
-      cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.br ^bb8
-    ^bb3 // EH catch (from entry block)
-      %1 = cir.eh.initiate : !cir.eh_token
-      cir.br ^bb6(%1 : !cir.eh_token)
-    ^bb4 // EH cleanup (from ^bb1)
-      %2 = cir.eh.initiate cleanup : !cir.eh_token
-      cir.br ^bb5(%2 : !cir.eh_token)
-    ^bb5(%eh_token : !cir.eh_token)
-      %3 = cir.begin_cleanup(%eh_token : !cir.eh_token) : !cir.cleanup_token
-      cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.end_cleanup(%3 : !cir.cleanup_token)
-      cir.br ^bb6(%eh_token : !cir.eh_token)
-    ^bb6(%eh_token.1 : !cir.eh_token) // Catch dispatch (from ^bb3 or ^bb4)
-      cir.eh.dispatch %eh_token.1 : !cir.eh_token [
-        catch_all : ^bb7
-      ]
-    ^bb7(%eh_token.2 : !cir.eh_token)
-      %catch.token = cir.begin_catch(%eh_token.2 : !cir.eh_token) : !cir.catch_token
-      cir.end_catch(%catch.token : !cir.catch_token)
-      cir.br ^bb8
-    ^bb8 // Normal continue (from ^bb2 or ^bb6)
-      cir.return
-    }
+```
+cir.func @someFunc() {
+  %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+  cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
+^bb1
+  cir.try_call @_ZN9SomeClass11doSomethingEv(%0) ^bb2, ^bb4 : (!cir.ptr<!rec_SomeClass>) -> ()
+^bb2 // Normal cleanup
+  cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.br ^bb8
+^bb3 // EH catch (from entry block)
+  %1 = cir.eh.initiate : !cir.eh_token
+  cir.br ^bb6(%1 : !cir.eh_token)
+^bb4 // EH cleanup (from ^bb1)
+  %2 = cir.eh.initiate cleanup : !cir.eh_token
+  cir.br ^bb5(%2 : !cir.eh_token)
+^bb5(%eh_token : !cir.eh_token)
+  %3 = cir.begin_cleanup(%eh_token : !cir.eh_token) : !cir.cleanup_token
+  cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.end_cleanup(%3 : !cir.cleanup_token)
+  cir.br ^bb6(%eh_token : !cir.eh_token)
+^bb6(%eh_token.1 : !cir.eh_token) // Catch dispatch (from ^bb3 or ^bb4)
+  cir.eh.dispatch %eh_token.1 : !cir.eh_token [
+    catch_all : ^bb7
+  ]
+^bb7(%eh_token.2 : !cir.eh_token)
+  %catch.token = cir.begin_catch(%eh_token.2 : !cir.eh_token) : !cir.catch_token
+  cir.end_catch(%catch.token : !cir.catch_token)
+  cir.br ^bb8
+^bb8 // Normal continue (from ^bb2 or ^bb6)
+  cir.return
+}
+```
 
 **ABI-lowered CIR**
 
-.. code-block::
-
-    cir.func @someFunc() #personality_fn = @ __CxxFrameHandler3 {
-      %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
-      cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb4 : (!cir.ptr<!rec_SomeClass>) -> ()
-    ^bb1
-      cir.try_call @_ZN9SomeClass11doSomethingEv(%0) ^bb2, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
-    ^bb2 // Normal cleanup
-      cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.br ^bb6
-    ^bb3 // EH cleanup (from ^bb1)
-      %1 = cir.cleanuppad within none : !cir.cleanup_token
-      cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
-      cir.cleanupret from %1 unwind to ^bb4
-    ^bb4 // Catch dispatch (from ^bb3 or ^bb4)
-      %2 = cir.catchswitch within none [^bb5] unwind to caller
-    ^bb5
-      %catch.token = cir.catchpad within %2 [null : !cir.ptr<!void>] : !cir.catch_token
-      cir.catchret within %catch.token to ^bb6
-    ^bb6 // Normal continue (from ^bb2 or ^bb6)
-      cir.return
-    }
-
-Example: Try-catch with multiple catch handlers
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+```
+cir.func @someFunc() #personality_fn = @ __CxxFrameHandler3 {
+  %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
+  cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb4 : (!cir.ptr<!rec_SomeClass>) -> ()
+^bb1
+  cir.try_call @_ZN9SomeClass11doSomethingEv(%0) ^bb2, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
+^bb2 // Normal cleanup
+  cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.br ^bb6
+^bb3 // EH cleanup (from ^bb1)
+  %1 = cir.cleanuppad within none : !cir.cleanup_token
+  cir.call @_ZN9SomeClassD1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
+  cir.cleanupret from %1 unwind to ^bb4
+^bb4 // Catch dispatch (from ^bb3 or ^bb4)
+  %2 = cir.catchswitch within none [^bb5] unwind to caller
+^bb5
+  %catch.token = cir.catchpad within %2 [null : !cir.ptr<!void>] : !cir.catch_token
+  cir.catchret within %catch.token to ^bb6
+^bb6 // Normal continue (from ^bb2 or ^bb6)
+  cir.return
+}
+```
+
+#### Example: Try-catch with multiple catch handlers
 
 **Flattened CIR**
 
-.. code-block::
-
-    cir.func @someFunc(){
-      cir.try_call @f() ^bb1, ^bb2
-    ^bb1
-      cir.br ^bb7
-    ^bb2 // EH catch (from entry block)
-      %1 = cir.eh.initiate : !cir.eh_token
-      cir.br ^bb3(%1 : !cir.eh_token)
-    ^bb3(%eh_token : !cir.eh_token) // Catch dispatch (from ^bb2)
-      cir.eh.dispatch %eh_token : !cir.eh_token [
-        catch (#cir.global_view<@_ZTIi> : !u32i) : ^bb4
-        catch (#cir.global_view<@_ZTIf> : !u32i) : ^bb5
-        catch_all : ^bb6
-      ]
-    ^bb4(%eh_token.1 : !cir.eh_token) // Catch handler for int exception
-      %catch.token = cir.begin_catch(%eh_token.1 : !cir.eh_token) : !cir.catch_token
-      cir.end_catch(%catch.token : !cir.catch_token)
-      cir.br ^bb7
-    ^bb5(%eh_token.2 : !cir.eh_token) // Catch handler for float exception
-      %catch.token = cir.begin_catch(%eh_token.2 : !cir.eh_token) : !cir.catch_token
-      cir.end_catch(%catch.token : !cir.catch_token)
-      cir.br ^bb7
-    ^bb6(%eh_token.3 : !cir.eh_token) // Catch all handler
-      %catch.token = cir.begin_catch(%eh_token.3 : !cir.eh_token) : !cir.catch_token
-      cir.end_catch(%catch.token : !cir.catch_token)
-      cir.br ^bb7
-    ^bb7 // Normal continue (from ^bb1, ^bb4, ^bb5, or ^bb6)
-      cir.return
-    }
+```
+cir.func @someFunc(){
+  cir.try_call @f() ^bb1, ^bb2
+^bb1
+  cir.br ^bb7
+^bb2 // EH catch (from entry block)
+  %1 = cir.eh.initiate : !cir.eh_token
+  cir.br ^bb3(%1 : !cir.eh_token)
+^bb3(%eh_token : !cir.eh_token) // Catch dispatch (from ^bb2)
+  cir.eh.dispatch %eh_token : !cir.eh_token [
+    catch (#cir.global_view<@_ZTIi> : !u32i) : ^bb4
+    catch (#cir.global_view<@_ZTIf> : !u32i) : ^bb5
+    catch_all : ^bb6
+  ]
+^bb4(%eh_token.1 : !cir.eh_token) // Catch handler for int exception
+  %catch.token = cir.begin_catch(%eh_token.1 : !cir.eh_token) : !cir.catch_token
+  cir.end_catch(%catch.token : !cir.catch_token)
+  cir.br ^bb7
+^bb5(%eh_token.2 : !cir.eh_token) // Catch handler for float exception
+  %catch.token = cir.begin_catch(%eh_token.2 : !cir.eh_token) : !cir.catch_token
+  cir.end_catch(%catch.token : !cir.catch_token)
+  cir.br ^bb7
+^bb6(%eh_token.3 : !cir.eh_token) // Catch all handler
+  %catch.token = cir.begin_catch(%eh_token.3 : !cir.eh_token) : !cir.catch_token
+  cir.end_catch(%catch.token : !cir.catch_token)
+  cir.br ^bb7
+^bb7 // Normal continue (from ^bb1, ^bb4, ^bb5, or ^bb6)
+  cir.return
+}
+```
 
 **ABI-lowered CIR**
 
-.. code-block::
-
-    cir.func @someFunc() #personality_fn = @__CxxFrameHandler3 {
-      cir.try_call @f() ^bb1, ^bb2
-    ^bb1
-      cir.br ^bb6
-    ^bb2 // EH catch (from entry block)
-      %0 = cir.catchswitch within none [^bb3, ^bb4, ^bb5] unwind to caller
-    ^bb3(%0: !cir.ptr<!void>) // Catch handler for int exception
-      %1 = cir.catchpad within %0 [eh.typeid @"??_R0H at 8", 0, %0 : (!cir.ptr<!void>, !u32i, !cir.ptr<!void>)] : !cir.catch_token
-      cir.catchret from %1 to ^bb6
-    ^bb4(%2: !cir.ptr<!void>) // Catch compare for float exception
-      %2 = cir.catchpad within %0 [eh.typeid @"??_R0M at 8", 0, %0 : (!cir.ptr<!void>, !u32i, !cir.ptr<!void>)] : !cir.catch_token
-      cir.catchret from %2 to ^bb6
-    ^bb5(%3: !cir.ptr<!void>) // Catch all handler
-      %4 = cir.catchpad within %0 [null, 64, null : (!cir.ptr<!void>, !u32i, !cir.ptr<!void>)] : !cir.catch_token
-      cir.catchret from %4 to ^bb6
-    ^bb6 // Normal continue (from ^bb1, ^bb3, ^bb4, or ^bb5)
-      cir.return
-    }
-
-In this example, if an exception is thrown by the ``f()`` call, it unwinds
-to a catch dispatch block (``^bb2``), which uses the ``cir.catchswitch``
-operation to dispatch to a catch handler (``^bb3``, ``^bb4``, or ``^bb5``)
+```
+cir.func @someFunc() #personality_fn = @__CxxFrameHandler3 {
+  cir.try_call @f() ^bb1, ^bb2
+^bb1
+  cir.br ^bb6
+^bb2 // EH catch (from entry block)
+  %0 = cir.catchswitch within none [^bb3, ^bb4, ^bb5] unwind to caller
+^bb3(%0: !cir.ptr<!void>) // Catch handler for int exception
+  %1 = cir.catchpad within %0 [eh.typeid @"??_R0H at 8", 0, %0 : (!cir.ptr<!void>, !u32i, !cir.ptr<!void>)] : !cir.catch_token
+  cir.catchret from %1 to ^bb6
+^bb4(%2: !cir.ptr<!void>) // Catch compare for float exception
+  %2 = cir.catchpad within %0 [eh.typeid @"??_R0M at 8", 0, %0 : (!cir.ptr<!void>, !u32i, !cir.ptr<!void>)] : !cir.catch_token
+  cir.catchret from %2 to ^bb6
+^bb5(%3: !cir.ptr<!void>) // Catch all handler
+  %4 = cir.catchpad within %0 [null, 64, null : (!cir.ptr<!void>, !u32i, !cir.ptr<!void>)] : !cir.catch_token
+  cir.catchret from %4 to ^bb6
+^bb6 // Normal continue (from ^bb1, ^bb3, ^bb4, or ^bb5)
+  cir.return
+}
+```
+
+In this example, if an exception is thrown by the `f()` call, it unwinds
+to a catch dispatch block (`^bb2`), which uses the `cir.catchswitch`
+operation to dispatch to a catch handler (`^bb3`, `^bb4`, or `^bb5`)
 based on the type id of the exception. The actual comparisons in this
 case will be handled by the personality function, using tables that are
-generated from the ``cir.catchpad`` operations. Each catch handler simply
-continues to the normal continuation block (``^bb6``) using the
-``cir.catchret`` operation.
+generated from the `cir.catchpad` operations. Each catch handler simply
+continues to the normal continuation block (`^bb6`) using the
+`cir.catchret` operation.
+
diff --git a/clang/docs/CIR/CodeDuplication.md b/clang/docs/CIR/CodeDuplication.md
index 9135441fdd1d9..aa22a790cd6da 100644
--- a/clang/docs/CIR/CodeDuplication.md
+++ b/clang/docs/CIR/CodeDuplication.md
@@ -1,12 +1,10 @@
-================================
-ClangIR Code Duplication Roadmap
-================================
+# ClangIR Code Duplication Roadmap
 
-.. contents::
-   :local:
+```{contents}
+:local: true
+```
 
-Introduction
-============
+## Introduction
 
 This document describes the general approach to code duplication in the ClangIR
 code generation implementation. It acknowledges specific problems with the
@@ -14,8 +12,7 @@ current implementation, discusses strategies for mitigating the risk inherent in
 the current approach, and describes a general long-term plan for addressing the
 issue.
 
-Background
-==========
+## Background
 
 The ClangIR code generation is very closely modeled after Clang's LLVM IR code
 generation, and we intend for the CIR produced to eventually be semantically
@@ -38,8 +35,7 @@ keeping the analogous CIR code up to date will be a purely manual process.
 
 Long term, we need a more sustainable approach.
 
-Current Strategy
-================
+## Current Strategy
 
 Practical considerations require that we make steady progress towards a working
 implementation of ClangIR. This necessity is directly opposed to the goal of
@@ -71,8 +67,7 @@ without degrading the quality of the other. Therefore, we have decided that it
 is better to accept significant amounts of code duplication now, and defer
 this type of refactoring until it is clear what the permanent solution will be.
 
-Mitigation Through Testing
-==========================
+## Mitigation Through Testing
 
 The most important tactic that we are using to mitigate the risk of CIR diverging
 from classic codegen is to incorporate two sets of LLVM IR checks in the CIR
@@ -102,8 +97,7 @@ of the generated LLVM IR, perhaps using a combination of tools such as `opt
 Eventually, we would like to be able to run all existing classic codegen tests
 using the CIR path as well.
 
-Other Considerations
-====================
+## Other Considerations
 
 The close modeling of CIR after classic codegen has also meant that the CIR
 dialect often represents language details at a much lower level than it ideally
@@ -117,12 +111,11 @@ and immediate benefit to doing so.
 
 Over time, we expect to progressively raise the CIR representation to a higher
 level and remove low level details, including ABI-specific handling from the
-dialect. (See the "Long Term Vision" section below for more  details.) Having
+dialect. (See the "Long Term Vision" section below for more details.) Having
 a working implementation in place makes it easier to verify that the
 high-level representation and subsequent lowering are correct.
 
-Mixing With Other Dialects
-==========================
+## Mixing With Other Dialects
 
 Mixing of dialects is a central design feature of MLIR. The CIR dialect is
 currently more self-contained than most dialects, but even now we generate
@@ -137,8 +130,7 @@ Therefore, any plan for generating LLVM IR from CIR must be integrated with the
 general MLIR lowering design, which typically involves lowering to the LLVM
 dialect, which is then transformed to LLVM IR.
 
-Other Consumers of CIR and MLIR
-===============================
+## Other Consumers of CIR and MLIR
 
 We must also consider that we will not always be lowering CIR to LLVM IR. CIR,
 usually mixed with other dialects, will also be directed to offload targets
@@ -146,8 +138,7 @@ and other code generators through interfaces that are opaque to Clang, such as
 SPIR-V and MLIR core dialects. We must still produce semantically correct CIR
 for these consumers.
 
-Long Term Vision
-================
+## Long Term Vision
 
 As the CIR implementation matures, we will eliminate target-specific handling
 from the high-level CIR generated by Clang. The high-level CIR will then be
@@ -177,8 +168,7 @@ to overlay reuse onto the existing implementations, we will replace relevant
 parts of the existing implementation, piece by piece, as appropriate, with new
 implementations that perform the same function but with a more general design.
 
-Example: C Calling Convention Handling
-======================================
+## Example: C Calling Convention Handling
 
 C calling convention handling is an example of a general purpose redesign that
 is already underway. This was started independently of CIR, but it will be
@@ -206,8 +196,7 @@ calling convention library that is being created, but it should create an MLIR
 transform pass on top of that library that is general enough to be used by other
 dialects, such as FIR, that also need the same calling convention handling.
 
-Significant Areas For Improvement
-=================================
+## Significant Areas For Improvement
 
 The following list enumerates some of the areas where significant restructuring
 of the code is needed to enable better code sharing between CIR and classic
@@ -215,10 +204,15 @@ codegen. Each of these areas is relatively self-contained in the codegen
 implementation, making the path to a shared implementation relatively clear.
 
 - Constant expression evaluation
+
 - Complex multiplication and division expansion
+
 - Builtin function handling
+
 - Exception Handling and C++ Cleanups
+
 - Inline assembly handling
+
 - C++ ABI Handling
 
   - VTable generation
@@ -229,8 +223,7 @@ implementation, making the path to a shared implementation relatively clear.
   - Type descriptors
   - Array new and delete
 
-Pervasive Low-Level Issues
-==========================
+## Pervasive Low-Level Issues
 
 This section lists some of the features where a non-trivial amount of code
 is shared between CIR and classic codegen, but the handling of the feature
@@ -243,3 +236,4 @@ to design an abstraction that can easily be shared.
 - TBAA handling
 - Sanitizer integration
 - Lifetime markers
+
diff --git a/clang/docs/CommandGuide/clang.md b/clang/docs/CommandGuide/clang.md
index c4dcca3d093fd..cf4dd98a29fb2 100644
--- a/clang/docs/CommandGuide/clang.md
+++ b/clang/docs/CommandGuide/clang.md
@@ -1,770 +1,774 @@
-clang - the Clang C, C++, and Objective-C compiler
-==================================================
+# clang - the Clang C, C++, and Objective-C compiler
 
-SYNOPSIS
---------
+## SYNOPSIS
 
-:program:`clang` [*options*] *filename ...*
+{program}`clang` \[*options*\] *filename ...*
 
-DESCRIPTION
------------
+## DESCRIPTION
 
-:program:`clang` is a C, C++, and Objective-C compiler which encompasses
+{program}`clang` is a C, C++, and Objective-C compiler which encompasses
 preprocessing, parsing, optimization, code generation, assembly, and linking.
 Depending on which high-level mode setting is passed, Clang will stop before
-doing a full link.  While Clang is highly integrated, it is important to
-understand the stages of compilation, to understand how to invoke it.  These
+doing a full link. While Clang is highly integrated, it is important to
+understand the stages of compilation, to understand how to invoke it. These
 stages are:
 
 Driver
-    The clang executable is actually a small driver which controls the overall
-    execution of other tools such as the compiler, assembler and linker.
-    Typically you do not need to interact with the driver, but you
-    transparently use it to run the other tools.
+
+: The clang executable is actually a small driver which controls the overall
+  execution of other tools such as the compiler, assembler and linker.
+  Typically you do not need to interact with the driver, but you
+  transparently use it to run the other tools.
 
 Preprocessing
-    This stage handles tokenization of the input source file, macro expansion,
-    #include expansion and handling of other preprocessor directives.  The
-    output of this stage is typically called a ".i" (for C), ".ii" (for C++),
-    ".mi" (for Objective-C), or ".mii" (for Objective-C++) file.
+
+: This stage handles tokenization of the input source file, macro expansion,
+  #include expansion and handling of other preprocessor directives. The
+  output of this stage is typically called a ".i" (for C), ".ii" (for C++),
+  ".mi" (for Objective-C), or ".mii" (for Objective-C++) file.
 
 Parsing and Semantic Analysis
-    This stage parses the input file, translating preprocessor tokens into a
-    parse tree.  Once in the form of a parse tree, it applies semantic
-    analysis to compute types for expressions as well and determine whether
-    the code is well formed. This stage is responsible for generating most of
-    the compiler warnings as well as parse errors. The output of this stage is
-    an "Abstract Syntax Tree" (AST).
+
+: This stage parses the input file, translating preprocessor tokens into a
+  parse tree. Once in the form of a parse tree, it applies semantic
+  analysis to compute types for expressions as well and determine whether
+  the code is well formed. This stage is responsible for generating most of
+  the compiler warnings as well as parse errors. The output of this stage is
+  an "Abstract Syntax Tree" (AST).
 
 Code Generation and Optimization
-    This stage translates an AST into low-level intermediate code (known as
-    "LLVM IR") and ultimately to machine code.  This phase is responsible for
-    optimizing the generated code and handling target-specific code generation.
-    The output of this stage is typically called a ".s" file or "assembly" file.
 
-    Clang also supports the use of an integrated assembler, in which the code
-    generator produces object files directly. This avoids the overhead of
-    generating the ".s" file and of calling the target assembler.
+: This stage translates an AST into low-level intermediate code (known as
+  "LLVM IR") and ultimately to machine code. This phase is responsible for
+  optimizing the generated code and handling target-specific code generation.
+  The output of this stage is typically called a ".s" file or "assembly" file.
+
+  Clang also supports the use of an integrated assembler, in which the code
+  generator produces object files directly. This avoids the overhead of
+  generating the ".s" file and of calling the target assembler.
 
 Assembler
-    This stage runs the target assembler to translate the output of the
-    compiler into a target object file. The output of this stage is typically
-    called a ".o" file or "object" file.
+
+: This stage runs the target assembler to translate the output of the
+  compiler into a target object file. The output of this stage is typically
+  called a ".o" file or "object" file.
 
 Linker
-    This stage runs the target linker to merge multiple object files into an
-    executable or dynamic library. The output of this stage is typically called
-    an "a.out", ".dylib" or ".so" file.
 
-:program:`Clang Static Analyzer`
+: This stage runs the target linker to merge multiple object files into an
+  executable or dynamic library. The output of this stage is typically called
+  an "a.out", ".dylib" or ".so" file.
+
+{program}`Clang Static Analyzer`
 
 The Clang Static Analyzer is a tool that scans source code to try to find bugs
-through code analysis.  This tool uses many parts of Clang and is built into
-the same driver.  Please see <https://clang-analyzer.llvm.org> for more details
+through code analysis. This tool uses many parts of Clang and is built into
+the same driver. Please see \<<https://clang-analyzer.llvm.org>> for more details
 on how to use the static analyzer.
 
-OPTIONS
--------
-
-Stage Selection Options
-~~~~~~~~~~~~~~~~~~~~~~~
-
-.. option:: -E
-
- Run the preprocessor stage.
-
-.. option:: -fsyntax-only
-
- Run the preprocessor, parser and semantic analysis stages.
-
-.. option:: -S
-
- Run the previous stages as well as LLVM generation and optimization stages
- and target-specific code generation, producing an assembly file.
-
-.. option:: -c
-
- Run all of the above, plus the assembler, generating a target ".o" object file.
-
-.. option:: no stage selection option
-
- If no stage selection option is specified, all stages above are run, and the
- linker is run to combine the results into an executable or shared library.
-
-Language Selection and Mode Options
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. option:: -x <language>
-
- Treat subsequent input files as having type language.
-
-.. option:: -std=<standard>
-
- Specify the language standard to compile for.
-
- Supported values for the C language are:
-
-  | ``c89``
-  | ``c90``
-  | ``iso9899:1990``
-
-   ISO C 1990
-
-  | ``iso9899:199409``
-
-   ISO C 1990 with amendment 1
-
-  | ``gnu89``
-  | ``gnu90``
-
-   ISO C 1990 with GNU extensions
-
-  | ``c99``
-  | ``iso9899:1999``
-
-   ISO C 1999
-
-  | ``gnu99``
-
-   ISO C 1999 with GNU extensions
-
-  | ``c11``
-  | ``iso9899:2011``
-
-   ISO C 2011
-
-  | ``gnu11``
-
-   ISO C 2011 with GNU extensions
-
-  | ``c17``
-  | ``iso9899:2017``
-
-   ISO C 2017
-
-  | ``gnu17``
-
-   ISO C 2017 with GNU extensions
-
-  | ``c23``
-  | ``iso9899:2024``
-
-   ISO C 2023
-
-  | ``gnu23``
-
-   ISO C 2023 with GNU extensions
-
-  | ``c2y``
-
-   ISO C 202y
-
-  | ``gnu2y``
-
-   ISO C 202y with GNU extensions
-
- The default C language standard is ``gnu17``, except on PS4, where it is
- ``gnu99``.
-
- Supported values for the C++ language are:
-
-  | ``c++98``
-  | ``c++03``
-
-   ISO C++ 1998 with amendments
-
-  | ``gnu++98``
-  | ``gnu++03``
-
-   ISO C++ 1998 with amendments and GNU extensions
-
-  | ``c++11``
-
-   ISO C++ 2011 with amendments
-
-  | ``gnu++11``
-
-    ISO C++ 2011 with amendments and GNU extensions
-
-  | ``c++14``
-
-   ISO C++ 2014 with amendments
-
-  | ``gnu++14``
-
-   ISO C++ 2014 with amendments and GNU extensions
-
-  | ``c++17``
-
-   ISO C++ 2017 with amendments
-
-  | ``gnu++17``
-
-   ISO C++ 2017 with amendments and GNU extensions
-
-  | ``c++20``
-
-   ISO C++ 2020 with amendments
-
-  | ``gnu++20``
-
-   ISO C++ 2020 with amendments and GNU extensions
-
-  | ``c++23``
-
-   ISO C++ 2023 with amendments
-
-  | ``gnu++23``
-
-   ISO C++ 2023 with amendments and GNU extensions
-
-  | ``c++2c``
-
-   Working draft for C++2c
-
-  | ``gnu++2c``
-
-   Working draft for C++2c with GNU extensions
-
-  | ``c++2d``
-
-   Working draft for C++2d
-
-  | ``gnu++2d``
-
-   Working draft for C++2d with GNU extensions
-
- The default C++ language standard is ``gnu++17``.
-
- Supported values for the OpenCL language are:
-
-  | ``cl1.0``
-
-   OpenCL 1.0
-
-  | ``cl1.1``
-
-   OpenCL 1.1
-
-  | ``cl1.2``
-
-   OpenCL 1.2
-
-  | ``cl2.0``
-
-   OpenCL 2.0
-
- The default OpenCL language standard is ``cl1.0``.
-
- Supported values for the CUDA language are:
-
-  | ``cuda``
-
-   NVIDIA CUDA(tm)
-
-.. option:: -stdlib=<library>
-
- Specify the C++ standard library to use; supported options are libstdc++ and
- libc++. If not specified, platform default will be used.
-
-.. option:: -rtlib=<library>
-
- Specify the compiler runtime library to use; supported options are libgcc and
- compiler-rt. If not specified, platform default will be used.
-
-.. option:: -ansi
-
- Same as -std=c89.
-
-.. option:: -ObjC, -ObjC++
-
- Treat source input files as Objective-C and Object-C++ inputs respectively.
-
-.. option:: -trigraphs
-
- Enable trigraphs.
-
-.. option:: -ffreestanding
-
- Indicate that the file should be compiled for a freestanding, not a hosted,
- environment. Note that a freestanding build still requires linking against a C
- Standard Library which supports the freestanding interfaces for the specified
- language mode and target environment. This includes functions like `memcpy`,
- `memmove`, and `memset`.
-
-.. option:: -fno-builtin
-
- Disable special handling and optimizations of well-known library functions,
- like :c:func:`strlen` and :c:func:`malloc`.
-
-.. option:: -fno-builtin-<function>
-
- Disable special handling and optimizations for the specific library function.
- For example, ``-fno-builtin-strlen`` removes any special handling for the
- :c:func:`strlen` library function.
-
-.. option:: -fno-builtin-std-<function>
-
- Disable special handling and optimizations for the specific C++ standard
- library function in namespace ``std``. For example,
- ``-fno-builtin-std-move_if_noexcept`` removes any special handling for the
- :cpp:func:`std::move_if_noexcept` library function.
-
- For C standard library functions that the C++ standard library also provides
- in namespace ``std``, use :option:`-fno-builtin-\<function\>` instead.
-
-.. option:: -fmath-errno
-
- Indicate that math functions should be treated as updating :c:data:`errno`.
-
-.. option:: -fpascal-strings
-
- Enable support for Pascal-style strings with "\\pfoo".
-
-.. option:: -fms-extensions
-
- Enable support for Microsoft extensions.
-
-.. option:: -fmsc-version=
-
- Set ``_MSC_VER``. When on Windows, this defaults to either the same value as
- the currently installed version of cl.exe, or ``1933``. Not set otherwise.
-
-.. option:: -fborland-extensions
-
- Enable support for Borland extensions.
-
-.. option:: -fwritable-strings
-
- Make all string literals default to writable.  This disables uniquing of
- strings and other optimizations.
-
-.. option:: -flax-vector-conversions, -flax-vector-conversions=<kind>, -fno-lax-vector-conversions
-
- Allow loose type checking rules for implicit vector conversions.
- Possible values of <kind>:
-
- - ``none``: allow no implicit conversions between vectors
- - ``integer``: allow implicit bitcasts between integer vectors of the same
-   overall bit-width
- - ``all``: allow implicit bitcasts between any vectors of the same
-   overall bit-width
-
- <kind> defaults to ``integer`` if unspecified.
-
-.. option:: -fblocks
-
- Enable the "Blocks" language feature.
-
-.. option:: -fobjc-abi-version=version
-
- Select the Objective-C ABI version to use. Available versions are 1 (legacy
- "fragile" ABI), 2 (non-fragile ABI 1), and 3 (non-fragile ABI 2).
-
-.. option:: -fobjc-nonfragile-abi-version=<version>
-
- Select the Objective-C non-fragile ABI version to use by default. This will
- only be used as the Objective-C ABI when the non-fragile ABI is enabled
- (either via :option:`-fobjc-nonfragile-abi`, or because it is the platform
- default).
-
-.. option:: -fobjc-nonfragile-abi, -fno-objc-nonfragile-abi
-
- Enable use of the Objective-C non-fragile ABI. On platforms for which this is
- the default ABI, it can be disabled with :option:`-fno-objc-nonfragile-abi`.
-
-Target Selection Options
-~~~~~~~~~~~~~~~~~~~~~~~~
+## OPTIONS
+
+### Stage Selection Options
+
+:::{option} -E
+Run the preprocessor stage.
+:::
+
+:::{option} -fsyntax-only
+Run the preprocessor, parser and semantic analysis stages.
+:::
+
+:::{option} -S
+Run the previous stages as well as LLVM generation and optimization stages
+and target-specific code generation, producing an assembly file.
+:::
+
+:::{option} -c
+Run all of the above, plus the assembler, generating a target ".o" object file.
+:::
+
+:::{option} no stage selection option
+If no stage selection option is specified, all stages above are run, and the
+linker is run to combine the results into an executable or shared library.
+:::
+
+### Language Selection and Mode Options
+
+:::{option} -x <language>
+Treat subsequent input files as having type language.
+:::
+
+:::{option} -std=<standard>
+Specify the language standard to compile for.
+
+Supported values for the C language are:
+
+> `c89`
+>
+> `c90`
+>
+> `iso9899:1990`
+>
+> > ISO C 1990
+>
+> `iso9899:199409`
+>
+> > ISO C 1990 with amendment 1
+>
+> `gnu89`
+>
+> `gnu90`
+>
+> > ISO C 1990 with GNU extensions
+>
+> `c99`
+>
+> `iso9899:1999`
+>
+> > ISO C 1999
+>
+> `gnu99`
+>
+> > ISO C 1999 with GNU extensions
+>
+> `c11`
+>
+> `iso9899:2011`
+>
+> > ISO C 2011
+>
+> `gnu11`
+>
+> > ISO C 2011 with GNU extensions
+>
+> `c17`
+>
+> `iso9899:2017`
+>
+> > ISO C 2017
+>
+> `gnu17`
+>
+> > ISO C 2017 with GNU extensions
+>
+> `c23`
+>
+> `iso9899:2024`
+>
+> > ISO C 2023
+>
+> `gnu23`
+>
+> > ISO C 2023 with GNU extensions
+>
+> `c2y`
+>
+> > ISO C 202y
+>
+> `gnu2y`
+>
+> > ISO C 202y with GNU extensions
+
+The default C language standard is `gnu17`, except on PS4, where it is
+`gnu99`.
+
+Supported values for the C++ language are:
+
+> `c++98`
+>
+> `c++03`
+>
+> > ISO C++ 1998 with amendments
+>
+> `gnu++98`
+>
+> `gnu++03`
+>
+> > ISO C++ 1998 with amendments and GNU extensions
+>
+> `c++11`
+>
+> > ISO C++ 2011 with amendments
+>
+> `gnu++11`
+>
+> > ISO C++ 2011 with amendments and GNU extensions
+>
+> `c++14`
+>
+> > ISO C++ 2014 with amendments
+>
+> `gnu++14`
+>
+> > ISO C++ 2014 with amendments and GNU extensions
+>
+> `c++17`
+>
+> > ISO C++ 2017 with amendments
+>
+> `gnu++17`
+>
+> > ISO C++ 2017 with amendments and GNU extensions
+>
+> `c++20`
+>
+> > ISO C++ 2020 with amendments
+>
+> `gnu++20`
+>
+> > ISO C++ 2020 with amendments and GNU extensions
+>
+> `c++23`
+>
+> > ISO C++ 2023 with amendments
+>
+> `gnu++23`
+>
+> > ISO C++ 2023 with amendments and GNU extensions
+>
+> `c++2c`
+>
+> > Working draft for C++2c
+>
+> `gnu++2c`
+>
+> > Working draft for C++2c with GNU extensions
+>
+> `c++2d`
+>
+> > Working draft for C++2d
+>
+> `gnu++2d`
+>
+> > Working draft for C++2d with GNU extensions
+
+The default C++ language standard is `gnu++17`.
+
+Supported values for the OpenCL language are:
+
+> `cl1.0`
+>
+> > OpenCL 1.0
+>
+> `cl1.1`
+>
+> > OpenCL 1.1
+>
+> `cl1.2`
+>
+> > OpenCL 1.2
+>
+> `cl2.0`
+>
+> > OpenCL 2.0
+
+The default OpenCL language standard is `cl1.0`.
+
+Supported values for the CUDA language are:
+
+> `cuda`
+>
+> > NVIDIA CUDA(tm)
+:::
+
+:::{option} -stdlib=<library>
+Specify the C++ standard library to use; supported options are libstdc++ and
+libc++. If not specified, platform default will be used.
+:::
+
+:::{option} -rtlib=<library>
+Specify the compiler runtime library to use; supported options are libgcc and
+compiler-rt. If not specified, platform default will be used.
+:::
+
+:::{option} -ansi
+Same as -std=c89.
+:::
+
+:::{option} -ObjC, -ObjC++
+Treat source input files as Objective-C and Object-C++ inputs respectively.
+:::
+
+:::{option} -trigraphs
+Enable trigraphs.
+:::
+
+:::{option} -ffreestanding
+Indicate that the file should be compiled for a freestanding, not a hosted,
+environment. Note that a freestanding build still requires linking against a C
+Standard Library which supports the freestanding interfaces for the specified
+language mode and target environment. This includes functions like `memcpy`,
+`memmove`, and `memset`.
+:::
+
+:::{option} -fno-builtin
+Disable special handling and optimizations of well-known library functions,
+like {c:func}`strlen` and {c:func}`malloc`.
+:::
+
+:::{option} -fno-builtin-<function>
+Disable special handling and optimizations for the specific library function.
+For example, `-fno-builtin-strlen` removes any special handling for the
+{c:func}`strlen` library function.
+:::
+
+:::{option} -fno-builtin-std-<function>
+Disable special handling and optimizations for the specific C++ standard
+library function in namespace `std`. For example,
+`-fno-builtin-std-move_if_noexcept` removes any special handling for the
+{cpp:func}`std::move_if_noexcept` library function.
+
+For C standard library functions that the C++ standard library also provides
+in namespace `std`, use {option}`-fno-builtin-\<function\>` instead.
+:::
+
+:::{option} -fmath-errno
+Indicate that math functions should be treated as updating {c:data}`errno`.
+:::
+
+:::{option} -fpascal-strings
+Enable support for Pascal-style strings with "\\pfoo".
+:::
+
+:::{option} -fms-extensions
+Enable support for Microsoft extensions.
+:::
+
+:::{option} -fmsc-version=
+Set `_MSC_VER`. When on Windows, this defaults to either the same value as
+the currently installed version of cl.exe, or `1933`. Not set otherwise.
+:::
+
+:::{option} -fborland-extensions
+Enable support for Borland extensions.
+:::
+
+:::{option} -fwritable-strings
+Make all string literals default to writable. This disables uniquing of
+strings and other optimizations.
+:::
+
+:::{option} -flax-vector-conversions, -flax-vector-conversions=<kind>, -fno-lax-vector-conversions
+Allow loose type checking rules for implicit vector conversions.
+Possible values of \<kind>:
+
+- `none`: allow no implicit conversions between vectors
+- `integer`: allow implicit bitcasts between integer vectors of the same
+  overall bit-width
+- `all`: allow implicit bitcasts between any vectors of the same
+  overall bit-width
+
+\<kind> defaults to `integer` if unspecified.
+:::
+
+:::{option} -fblocks
+Enable the "Blocks" language feature.
+:::
+
+:::{option} -fobjc-abi-version=version
+Select the Objective-C ABI version to use. Available versions are 1 (legacy
+"fragile" ABI), 2 (non-fragile ABI 1), and 3 (non-fragile ABI 2).
+:::
+
+:::{option} -fobjc-nonfragile-abi-version=<version>
+Select the Objective-C non-fragile ABI version to use by default. This will
+only be used as the Objective-C ABI when the non-fragile ABI is enabled
+(either via {option}`-fobjc-nonfragile-abi`, or because it is the platform
+default).
+:::
+
+:::{option} -fobjc-nonfragile-abi, -fno-objc-nonfragile-abi
+Enable use of the Objective-C non-fragile ABI. On platforms for which this is
+the default ABI, it can be disabled with {option}`-fno-objc-nonfragile-abi`.
+:::
+
+### Target Selection Options
 
 Clang fully supports cross compilation as an inherent part of its design.
 Depending on how your version of Clang is configured, it may have support for a
 number of cross compilers, or may only support a native target.
 
-.. option:: -arch <architecture>
-
-  Specify the architecture to build for (Mac OS X specific).
-
-.. option:: -target <architecture>
-
-  Specify the architecture to build for (all platforms).
-
-.. option:: -mmacos-version-min=<version>
-
-  When building for macOS, specify the minimum version supported by your
-  application.
-
-.. option:: -miphoneos-version-min
-
-  When building for iPhone OS, specify the minimum version supported by your
-  application.
-
-.. option:: --print-supported-cpus
-
-  Print out a list of supported processors for the given target (specified
-  through ``--target=<architecture>`` or :option:`-arch` ``<architecture>``). If no
-  target is specified, the system default target will be used.
-
-.. option:: -mcpu=?, -mtune=?
-
-  Acts as an alias for :option:`--print-supported-cpus`.
-
-.. option:: -mcpu=help, -mtune=help
-
-  Acts as an alias for :option:`--print-supported-cpus`.
-
-.. option:: -march=<cpu>
-
-  Specify that Clang should generate code for a specific processor family
-  member and later.  For example, if you specify -march=i486, the compiler is
-  allowed to generate instructions that are valid on i486 and later processors,
-  but which may not exist on earlier ones.
-
-.. option:: --print-enabled-extensions
-
-  Prints the list of extensions that are enabled for the target specified by the
-  combination of `--target`, `-march`, and `-mcpu` values. Currently, this
-  option is only supported on AArch64 and RISC-V. On RISC-V, this option also
-  prints out the ISA string of enabled extensions.
-
-.. option:: --print-supported-extensions
-
-  Prints the list of all extensions that are supported for every CPU target
-  for an architecture (specified through ``--target=<architecture>`` or
-  :option:`-arch` ``<architecture>``). If no target is specified, the system
-  default target will be used. Currently, this option is only supported on
-  AArch64 and RISC-V.
-
-Code Generation Options
-~~~~~~~~~~~~~~~~~~~~~~~
-
-.. option:: -O0, -O1, -O2, -O3, -Ofast, -Os, -Oz, -Og, -O, -O4
-
-  Specify which optimization level to use:
-
-    :option:`-O0` Means "no optimization": this level compiles the fastest and
-    generates the most debuggable code.
-
-    :option:`-O1` Somewhere between :option:`-O0` and :option:`-O2`.
-
-    :option:`-O2` Moderate level of optimization which enables most
-    optimizations.
-
-    :option:`-O3` Like :option:`-O2`, except that it enables optimizations that
-    take longer to perform or that may generate larger code (in an attempt to
-    make the program run faster).
-
-    :option:`-Ofast` Enables all the optimizations from :option:`-O3` along with
-    other aggressive optimizations that may violate strict compliance with
-    language standards. This has been deprecated since Clang 19. There is no
-    timeline yet for removal; the aim is to discourage use of :option:`-Ofast`
-    due to the surprising behavior of an optimization flag changing the
-    observable behavior of correct code.
-
-    If :option:`-Ofast` has been specified and is the effective optimization
-    level (i.e. there is no later `-O` option specified), then the option can be
-    replaced in the option string with `-O3 -ffast-math -fstrict-aliasing`.
-    (:option:`-fstrict-aliasing` is the default on non-Windows, non-UEFI
-    platforms). If :option:`-Ofast` has been specified but is not the effective
-    optimization level, then it can be removed or replaced with :option:`-O3`.
-
-    :option:`-Os` Like :option:`-O2` with extra optimizations to reduce code
-    size.
-
-    :option:`-Oz` Like :option:`-Os` (and thus :option:`-O2`), but reduces code
-    size further.
-
-    :option:`-Og` Similar to :option:`-O1`, but with slightly reduced
-    optimization and better variable visibility. The same optimizations are run
-    as at :option:`-O1`, but the ``-fextend-variable-liveness`` flag is
-    also set, which tries to prevent optimizations from reducing the liveness of
-    user variables, improving their availability when debugging.
-
-    :option:`-O` Equivalent to :option:`-O1`.
-
-    :option:`-O4` and higher
-
-      Currently equivalent to :option:`-O3`
-
-.. option:: -g, -gline-tables-only, -gmodules
-
-  Control debug information output.  Note that Clang debug information works
-  best at :option:`-O0`.  When more than one option starting with `-g` is
-  specified, the last one wins:
-
-    :option:`-g` Generate debug information.
-
-    :option:`-gline-tables-only` Generate only line table debug information. This
-    allows for symbolicated backtraces with inlining information, but does not
-    include any information about variables, their locations or types.
-
-    :option:`-gmodules` Generate debug information that contains external
-    references to types defined in Clang modules or precompiled headers instead
-    of emitting redundant debug type information into every object file.  This
-    option transparently switches the Clang module format to object file
-    containers that hold the Clang module together with the debug information.
-    When compiling a program that uses Clang modules or precompiled headers,
-    this option produces complete debug information with faster compile
-    times and much smaller object files.
-
-    This option should not be used when building static libraries for
-    distribution to other machines because the debug info will contain
-    references to the module cache on the machine the object files in the
-    library were built on.
-
-.. option:: -fstandalone-debug -fno-standalone-debug
-
-  Clang supports a number of optimizations to reduce the size of debug
-  information in the binary. They work based on the assumption that the
-  debug type information can be spread out over multiple compilation units.
-  For instance, Clang will not emit type definitions for types that are not
-  needed by a module and could be replaced with a forward declaration.
-  Further, Clang will only emit type info for a dynamic C++ class in the
-  module that contains the vtable for the class.
-
-  The :option:`-fstandalone-debug` option turns off these optimizations.
-  This is useful when working with 3rd-party libraries that don't come with
-  debug information.  This is the default on Darwin.  Note that Clang will
-  never emit type information for types that are not referenced at all by the
-  program.
-
-.. option:: -feliminate-unused-debug-types
-
-  By default, Clang does not emit type information for types that are defined
-  but not used in a program. To retain the debug info for these unused types,
-  the negation **-fno-eliminate-unused-debug-types** can be used.
-
-.. option:: -fexceptions
-
-  Allow exceptions to be thrown through Clang compiled stack frames (on many
-  targets, this will enable unwind information for functions that might have
-  an exception thrown through them). For most targets, this is enabled by
-  default for C++.
-
-.. option:: -ftrapv
-
-  Generate code to catch integer overflow errors.  Signed integer overflow is
-  undefined in C. With this flag, extra code is generated to detect this and
-  abort when it happens.
-
-.. option:: -fvisibility
-
-  This flag sets the default visibility level.
-
-.. option:: -fcommon, -fno-common
-
-  This flag specifies that variables without initializers get common linkage.
-  It can be disabled with :option:`-fno-common`.
-
-.. option:: -ftls-model=<model>
-
-  Set the default thread-local storage (TLS) model to use for thread-local
-  variables. Valid values are: "global-dynamic", "local-dynamic",
-  "initial-exec" and "local-exec". The default is "global-dynamic". The default
-  model can be overridden with the tls_model attribute. The compiler will try
-  to choose a more efficient model if possible.
-
-.. option:: -flto, -flto=full, -flto=thin, -emit-llvm
-
-  Generate output files in LLVM formats, suitable for link time optimization.
-  When used with :option:`-S` this generates LLVM intermediate language
-  assembly files, otherwise this generates LLVM bitcode format object files
-  (which may be passed to the linker depending on the stage selection options).
-
-  The default for :option:`-flto` is "full", in which the
-  LLVM bitcode is suitable for monolithic Link Time Optimization (LTO), where
-  the linker merges all such modules into a single combined module for
-  optimization. With "thin", :doc:`ThinLTO <../ThinLTO>`
-  compilation is invoked instead.
-
-  .. note::
-
-     On Darwin, when using :option:`-flto` along with :option:`-g` and
-     compiling and linking in separate steps, you also need to pass
-     ``-Wl,-object_path_lto,<lto-filename>.o`` at the linking step to instruct the
-     ld64 linker not to delete the temporary object file generated during Link
-     Time Optimization (this flag is automatically passed to the linker by Clang
-     if compilation and linking are done in a single step). This allows debugging
-     the executable as well as generating the ``.dSYM`` bundle using :manpage:`dsymutil(1)`.
-
-Driver Options
-~~~~~~~~~~~~~~
-
-.. option:: -###
-
-  Print (but do not run) the commands to run for this compilation.
-
-.. option:: --help
-
-  Display available options.
-
-.. option:: -Qunused-arguments
-
-  Do not emit any warnings for unused driver arguments.
-
-.. option:: -Wa,<args>
-
-  Pass the comma separated arguments in args to the assembler.
-
-.. option:: -Wl,<args>
-
-  Pass the comma separated arguments in args to the linker.
-
-.. option:: -Wp,<args>
-
-  Pass the comma separated arguments in args to the preprocessor.
-
-.. option:: -Xanalyzer <arg>
-
-  Pass arg to the static analyzer.
-
-.. option:: -Xassembler <arg>
-
-  Pass arg to the assembler.
-
-.. option:: -Xlinker <arg>
-
-  Pass arg to the linker.
-
-.. option:: -Xpreprocessor <arg>
-
-  Pass arg to the preprocessor.
-
-.. option:: -o <file>
-
-  Write output to file.
-
-.. option:: -print-file-name=<file>
-
-  Print the full library path of file.
-
-.. option:: -print-libgcc-file-name
-
-  Print the library path for the currently used compiler runtime library
-  ("libgcc.a" or "libclang_rt.builtins.*.a").
-
-.. option:: -print-prog-name=<name>
-
-  Print the full program path of name.
-
-.. option:: -print-search-dirs
-
-  Print the paths used for finding libraries and programs.
-
-.. option:: -save-temps
-
-  Save intermediate compilation results.
-
-.. option:: -save-stats, -save-stats=cwd, -save-stats=obj
-
-  Save internal code generation (LLVM) statistics to a file in the current
-  directory (:option:`-save-stats`/"-save-stats=cwd") or the directory
-  of the output file ("-save-stats=obj").
-
-  You can also use environment variables to control the statistics reporting.
-  Setting ``CC_PRINT_INTERNAL_STAT`` to ``1`` enables the feature, the report
-  goes to stdout in JSON format.
-
-  Setting ``CC_PRINT_INTERNAL_STAT_FILE`` to a file path makes it report
-  statistics to the given file in the JSON format.
-
-  Note that ``-save-stats`` take precedence over ``CC_PRINT_INTERNAL_STAT``
-  and ``CC_PRINT_INTERNAL_STAT_FILE``.
-
-.. option:: -integrated-as, -no-integrated-as
-
-  Used to enable and disable, respectively, the use of the integrated
-  assembler. Whether the integrated assembler is on by default is target
-  dependent.
-
-.. option:: -time
-
-  Time individual commands.
-
-.. option:: -ftime-report
-
-  Print timing summary of each stage of compilation.
-
-.. option:: -v
-
-  Show commands to run and use verbose output.
-
-
-Diagnostics Options
-~~~~~~~~~~~~~~~~~~~
-
-.. option:: -fshow-column, -fshow-source-location, -fcaret-diagnostics, -fdiagnostics-fixit-info, -fdiagnostics-parseable-fixits, -fdiagnostics-print-source-range-info, -fprint-source-range-info, -fdiagnostics-show-option, -fmessage-length
-
-  These options control how Clang prints out information about diagnostics
-  (errors and warnings). Please see the Clang User's Manual for more information.
-
-Preprocessor Options
-~~~~~~~~~~~~~~~~~~~~
-
-.. option:: -D<macroname>=<value>
-
-  Adds an implicit #define into the predefines buffer which is read before the
-  source file is preprocessed.
-
-.. option:: -U<macroname>
-
-  Adds an implicit #undef into the predefines buffer which is read before the
-  source file is preprocessed.
-
-.. option:: -include <filename>
-
-  Adds an implicit #include into the predefines buffer which is read before the
-  source file is preprocessed.
-
-.. option:: -I<directory>
-
-  Add the specified directory to the search path for include files.
-
-.. option:: -F<directory>
-
-  Add the specified directory to the search path for framework include files.
-
-.. option:: -nostdinc
-
-  Do not search the standard system directories or compiler builtin directories
-  for include files.
-
-.. option:: -nostdlibinc
-
-  Do not search the standard system directories for include files, but do
-  search compiler builtin include directories.
-
-.. option:: -nobuiltininc
-
-  Do not search clang's builtin directory for include files.
-
-.. option:: -nostdinc++
-
-  Do not search the system C++ standard library directory for include files.
-
-.. option:: -fkeep-system-includes
-
-  Usable only with :option:`-E`. Do not copy the preprocessed content of
-  "system" headers to the output; instead, preserve the #include directive.
-  This can greatly reduce the volume of text produced by :option:`-E` which
-  can be helpful when trying to produce a "small" reproduceable test case.
-
-  This option does not guarantee reproduceability, however. If the including
-  source defines preprocessor symbols that influence the behavior of system
-  headers (for example, ``_XOPEN_SOURCE``) the operation of :option:`-E` will
-  remove that definition and thus can change the semantics of the included
-  header. Also, using a different version of the system headers (especially a
-  different version of the STL) may result in different behavior. Always verify
-  the preprocessed file by compiling it separately.
-
-
-ENVIRONMENT
------------
-
+:::{option} -arch <architecture>
+Specify the architecture to build for (Mac OS X specific).
+:::
+
+:::{option} -target <architecture>
+Specify the architecture to build for (all platforms).
+:::
+
+:::{option} -mmacos-version-min=<version>
+When building for macOS, specify the minimum version supported by your
+application.
+:::
+
+:::{option} -miphoneos-version-min
+When building for iPhone OS, specify the minimum version supported by your
+application.
+:::
+
+:::{option} --print-supported-cpus
+Print out a list of supported processors for the given target (specified
+through `--target=<architecture>` or {option}`-arch` `<architecture>`). If no
+target is specified, the system default target will be used.
+:::
+
+:::{option} -mcpu=?, -mtune=?
+Acts as an alias for {option}`--print-supported-cpus`.
+:::
+
+:::{option} -mcpu=help, -mtune=help
+Acts as an alias for {option}`--print-supported-cpus`.
+:::
+
+:::{option} -march=<cpu>
+Specify that Clang should generate code for a specific processor family
+member and later. For example, if you specify -march=i486, the compiler is
+allowed to generate instructions that are valid on i486 and later processors,
+but which may not exist on earlier ones.
+:::
+
+:::{option} --print-enabled-extensions
+Prints the list of extensions that are enabled for the target specified by the
+combination of `--target`, `-march`, and `-mcpu` values. Currently, this
+option is only supported on AArch64 and RISC-V. On RISC-V, this option also
+prints out the ISA string of enabled extensions.
+:::
+
+:::{option} --print-supported-extensions
+Prints the list of all extensions that are supported for every CPU target
+for an architecture (specified through `--target=<architecture>` or
+{option}`-arch` `<architecture>`). If no target is specified, the system
+default target will be used. Currently, this option is only supported on
+AArch64 and RISC-V.
+:::
+
+### Code Generation Options
+
+:::{option} -O0, -O1, -O2, -O3, -Ofast, -Os, -Oz, -Og, -O, -O4
+Specify which optimization level to use:
+
+> {option}`-O0` Means "no optimization": this level compiles the fastest and
+> generates the most debuggable code.
+>
+> {option}`-O1` Somewhere between {option}`-O0` and {option}`-O2`.
+>
+> {option}`-O2` Moderate level of optimization which enables most
+> optimizations.
+>
+> {option}`-O3` Like {option}`-O2`, except that it enables optimizations that
+> take longer to perform or that may generate larger code (in an attempt to
+> make the program run faster).
+>
+> {option}`-Ofast` Enables all the optimizations from {option}`-O3` along with
+> other aggressive optimizations that may violate strict compliance with
+> language standards. This has been deprecated since Clang 19. There is no
+> timeline yet for removal; the aim is to discourage use of {option}`-Ofast`
+> due to the surprising behavior of an optimization flag changing the
+> observable behavior of correct code.
+>
+> If {option}`-Ofast` has been specified and is the effective optimization
+> level (i.e. there is no later `-O` option specified), then the option can be
+> replaced in the option string with `-O3 -ffast-math -fstrict-aliasing`.
+> ({option}`-fstrict-aliasing` is the default on non-Windows, non-UEFI
+> platforms). If {option}`-Ofast` has been specified but is not the effective
+> optimization level, then it can be removed or replaced with {option}`-O3`.
+>
+> {option}`-Os` Like {option}`-O2` with extra optimizations to reduce code
+> size.
+>
+> {option}`-Oz` Like {option}`-Os` (and thus {option}`-O2`), but reduces code
+> size further.
+>
+> {option}`-Og` Similar to {option}`-O1`, but with slightly reduced
+> optimization and better variable visibility. The same optimizations are run
+> as at {option}`-O1`, but the `-fextend-variable-liveness` flag is
+> also set, which tries to prevent optimizations from reducing the liveness of
+> user variables, improving their availability when debugging.
+>
+> {option}`-O` Equivalent to {option}`-O1`.
+>
+> {option}`-O4` and higher
+>
+> > Currently equivalent to {option}`-O3`
+:::
+
+:::{option} -g, -gline-tables-only, -gmodules
+Control debug information output. Note that Clang debug information works
+best at {option}`-O0`. When more than one option starting with `-g` is
+specified, the last one wins:
+
+> {option}`-g` Generate debug information.
+>
+> {option}`-gline-tables-only` Generate only line table debug information. This
+> allows for symbolicated backtraces with inlining information, but does not
+> include any information about variables, their locations or types.
+>
+> {option}`-gmodules` Generate debug information that contains external
+> references to types defined in Clang modules or precompiled headers instead
+> of emitting redundant debug type information into every object file. This
+> option transparently switches the Clang module format to object file
+> containers that hold the Clang module together with the debug information.
+> When compiling a program that uses Clang modules or precompiled headers,
+> this option produces complete debug information with faster compile
+> times and much smaller object files.
+>
+> This option should not be used when building static libraries for
+> distribution to other machines because the debug info will contain
+> references to the module cache on the machine the object files in the
+> library were built on.
+:::
+
+:::{option} -fstandalone-debug -fno-standalone-debug
+Clang supports a number of optimizations to reduce the size of debug
+information in the binary. They work based on the assumption that the
+debug type information can be spread out over multiple compilation units.
+For instance, Clang will not emit type definitions for types that are not
+needed by a module and could be replaced with a forward declaration.
+Further, Clang will only emit type info for a dynamic C++ class in the
+module that contains the vtable for the class.
+
+The {option}`-fstandalone-debug` option turns off these optimizations.
+This is useful when working with 3rd-party libraries that don't come with
+debug information. This is the default on Darwin. Note that Clang will
+never emit type information for types that are not referenced at all by the
+program.
+:::
+
+:::{option} -feliminate-unused-debug-types
+By default, Clang does not emit type information for types that are defined
+but not used in a program. To retain the debug info for these unused types,
+the negation **-fno-eliminate-unused-debug-types** can be used.
+:::
+
+:::{option} -fexceptions
+Allow exceptions to be thrown through Clang compiled stack frames (on many
+targets, this will enable unwind information for functions that might have
+an exception thrown through them). For most targets, this is enabled by
+default for C++.
+:::
+
+:::{option} -ftrapv
+Generate code to catch integer overflow errors. Signed integer overflow is
+undefined in C. With this flag, extra code is generated to detect this and
+abort when it happens.
+:::
+
+:::{option} -fvisibility
+This flag sets the default visibility level.
+:::
+
+:::{option} -fcommon, -fno-common
+This flag specifies that variables without initializers get common linkage.
+It can be disabled with {option}`-fno-common`.
+:::
+
+:::{option} -ftls-model=<model>
+Set the default thread-local storage (TLS) model to use for thread-local
+variables. Valid values are: "global-dynamic", "local-dynamic",
+"initial-exec" and "local-exec". The default is "global-dynamic". The default
+model can be overridden with the tls_model attribute. The compiler will try
+to choose a more efficient model if possible.
+:::
+
+::::{option} -flto, -flto=full, -flto=thin, -emit-llvm
+Generate output files in LLVM formats, suitable for link time optimization.
+When used with {option}`-S` this generates LLVM intermediate language
+assembly files, otherwise this generates LLVM bitcode format object files
+(which may be passed to the linker depending on the stage selection options).
+
+The default for {option}`-flto` is "full", in which the
+LLVM bitcode is suitable for monolithic Link Time Optimization (LTO), where
+the linker merges all such modules into a single combined module for
+optimization. With "thin", {doc}`ThinLTO <../ThinLTO>`
+compilation is invoked instead.
+
+:::{note}
+On Darwin, when using {option}`-flto` along with {option}`-g` and
+compiling and linking in separate steps, you also need to pass
+`-Wl,-object_path_lto,<lto-filename>.o` at the linking step to instruct the
+ld64 linker not to delete the temporary object file generated during Link
+Time Optimization (this flag is automatically passed to the linker by Clang
+if compilation and linking are done in a single step). This allows debugging
+the executable as well as generating the `.dSYM` bundle using {manpage}`dsymutil(1)`.
+:::
+::::
+
+### Driver Options
+
+:::{option} -###
+Print (but do not run) the commands to run for this compilation.
+:::
+
+:::{option} --help
+Display available options.
+:::
+
+:::{option} -Qunused-arguments
+Do not emit any warnings for unused driver arguments.
+:::
+
+:::{option} -Wa,<args>
+Pass the comma separated arguments in args to the assembler.
+:::
+
+:::{option} -Wl,<args>
+Pass the comma separated arguments in args to the linker.
+:::
+
+:::{option} -Wp,<args>
+Pass the comma separated arguments in args to the preprocessor.
+:::
+
+:::{option} -Xanalyzer <arg>
+Pass arg to the static analyzer.
+:::
+
+:::{option} -Xassembler <arg>
+Pass arg to the assembler.
+:::
+
+:::{option} -Xlinker <arg>
+Pass arg to the linker.
+:::
+
+:::{option} -Xpreprocessor <arg>
+Pass arg to the preprocessor.
+:::
+
+:::{option} -o <file>
+Write output to file.
+:::
+
+:::{option} -print-file-name=<file>
+Print the full library path of file.
+:::
+
+:::{option} -print-libgcc-file-name
+Print the library path for the currently used compiler runtime library
+("libgcc.a" or "libclang_rt.builtins.\*.a").
+:::
+
+:::{option} -print-prog-name=<name>
+Print the full program path of name.
+:::
+
+:::{option} -print-search-dirs
+Print the paths used for finding libraries and programs.
+:::
+
+:::{option} -save-temps
+Save intermediate compilation results.
+:::
+
+:::{option} -save-stats, -save-stats=cwd, -save-stats=obj
+Save internal code generation (LLVM) statistics to a file in the current
+directory ({option}`-save-stats`/"-save-stats=cwd") or the directory
+of the output file ("-save-stats=obj").
+
+You can also use environment variables to control the statistics reporting.
+Setting `CC_PRINT_INTERNAL_STAT` to `1` enables the feature, the report
+goes to stdout in JSON format.
+
+Setting `CC_PRINT_INTERNAL_STAT_FILE` to a file path makes it report
+statistics to the given file in the JSON format.
+
+Note that `-save-stats` take precedence over `CC_PRINT_INTERNAL_STAT`
+and `CC_PRINT_INTERNAL_STAT_FILE`.
+:::
+
+:::{option} -integrated-as, -no-integrated-as
+Used to enable and disable, respectively, the use of the integrated
+assembler. Whether the integrated assembler is on by default is target
+dependent.
+:::
+
+:::{option} -time
+Time individual commands.
+:::
+
+:::{option} -ftime-report
+Print timing summary of each stage of compilation.
+:::
+
+:::{option} -v
+Show commands to run and use verbose output.
+:::
+
+### Diagnostics Options
+
+:::{option} -fshow-column, -fshow-source-location, -fcaret-diagnostics, -fdiagnostics-fixit-info, -fdiagnostics-parseable-fixits, -fdiagnostics-print-source-range-info, -fprint-source-range-info, -fdiagnostics-show-option, -fmessage-length
+These options control how Clang prints out information about diagnostics
+(errors and warnings). Please see the Clang User's Manual for more information.
+:::
+
+### Preprocessor Options
+
+:::{option} -D<macroname>=<value>
+Adds an implicit #define into the predefines buffer which is read before the
+source file is preprocessed.
+:::
+
+:::{option} -U<macroname>
+Adds an implicit #undef into the predefines buffer which is read before the
+source file is preprocessed.
+:::
+
+:::{option} -include <filename>
+Adds an implicit #include into the predefines buffer which is read before the
+source file is preprocessed.
+:::
+
+:::{option} -I<directory>
+Add the specified directory to the search path for include files.
+:::
+
+:::{option} -F<directory>
+Add the specified directory to the search path for framework include files.
+:::
+
+:::{option} -nostdinc
+Do not search the standard system directories or compiler builtin directories
+for include files.
+:::
+
+:::{option} -nostdlibinc
+Do not search the standard system directories for include files, but do
+search compiler builtin include directories.
+:::
+
+:::{option} -nobuiltininc
+Do not search clang's builtin directory for include files.
+:::
+
+:::{option} -nostdinc++
+Do not search the system C++ standard library directory for include files.
+:::
+
+:::{option} -fkeep-system-includes
+Usable only with {option}`-E`. Do not copy the preprocessed content of
+"system" headers to the output; instead, preserve the #include directive.
+This can greatly reduce the volume of text produced by {option}`-E` which
+can be helpful when trying to produce a "small" reproduceable test case.
+
+This option does not guarantee reproduceability, however. If the including
+source defines preprocessor symbols that influence the behavior of system
+headers (for example, `_XOPEN_SOURCE`) the operation of {option}`-E` will
+remove that definition and thus can change the semantics of the included
+header. Also, using a different version of the system headers (especially a
+different version of the STL) may result in different behavior. Always verify
+the preprocessed file by compiling it separately.
+:::
+
+## ENVIRONMENT
+
+```{eval-rst}
 .. envvar:: TMPDIR, TEMP, TMP
 
   These environment variables are checked, in order, for the location to write
   temporary files used during the compilation process.
+```
 
+```{eval-rst}
 .. envvar:: CPATH
 
   This environment variable specifies additional (non-system) header search
@@ -774,27 +778,31 @@ ENVIRONMENT
   delimiter as used in the ``PATH`` environment variable. Empty entries in the
   delimited path list, including those at the beginning or end of the list, are
   treated as specifying the compiler's current working directory.
+```
 
+```{eval-rst}
 .. envvar:: C_INCLUDE_PATH, OBJC_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJCPLUS_INCLUDE_PATH
 
   These environment variables specify additional system header file search
   paths to be used when processing the corresponding language. Search paths are
   delimited as for the :envvar:`CPATH` environment variable.
+```
 
+```{eval-rst}
 .. envvar:: MACOSX_DEPLOYMENT_TARGET
 
   If :option:`-mmacos-version-min` is unspecified, the default deployment
   target is read from this environment variable. This option only affects
   Darwin targets.
+```
 
-BUGS
-----
+## BUGS
 
-To report bugs, please visit <https://github.com/llvm/llvm-project/issues/>.  Most bug reports should
-include preprocessed source files (use the :option:`-E` option) and the full
+To report bugs, please visit \<<https://github.com/llvm/llvm-project/issues/>>. Most bug reports should
+include preprocessed source files (use the {option}`-E` option) and the full
 output of the compiler, along with information to reproduce.
 
-SEE ALSO
---------
+## SEE ALSO
+
+{manpage}`as(1)`, {manpage}`ld(1)`
 
-:manpage:`as(1)`, :manpage:`ld(1)`
diff --git a/clang/docs/CommandGuide/diagtool.md b/clang/docs/CommandGuide/diagtool.md
index 656ce10b23319..7c3790509fe4d 100644
--- a/clang/docs/CommandGuide/diagtool.md
+++ b/clang/docs/CommandGuide/diagtool.md
@@ -1,52 +1,45 @@
-diagtool - clang diagnostics tool
-=================================
+# diagtool - clang diagnostics tool
 
-SYNOPSIS
---------
+## SYNOPSIS
 
-:program:`diagtool` *command* [*args*]
+{program}`diagtool` *command* \[*args*\]
 
-DESCRIPTION
------------
+## DESCRIPTION
 
-:program:`diagtool` is a combination of four tools for dealing with diagnostics in :program:`clang`.
+{program}`diagtool` is a combination of four tools for dealing with diagnostics in {program}`clang`.
 
-SUBCOMMANDS
------------
+## SUBCOMMANDS
 
-:program:`diagtool` is separated into several subcommands each tailored to a
+{program}`diagtool` is separated into several subcommands each tailored to a
 different purpose. A brief summary of each command follows, with more detail in
 the sections that follow.
 
-  * :ref:`find_diagnostic_id` - Print the id of the given diagnostic.
-  * :ref:`list_warnings` - List warnings and their corresponding flags.
-  * :ref:`show_enabled` - Show which warnings are enabled for a given command line.
-  * :ref:`tree` - Show warning flags in a tree view.
+> - {ref}`find_diagnostic_id` - Print the id of the given diagnostic.
+> - {ref}`list_warnings` - List warnings and their corresponding flags.
+> - {ref}`show_enabled` - Show which warnings are enabled for a given command line.
+> - {ref}`tree` - Show warning flags in a tree view.
 
-.. _find_diagnostic_id:
+(find-diagnostic-id)=
 
-find-diagnostic-id
-~~~~~~~~~~~~~~~~~~
+### find-diagnostic-id
 
-:program:`diagtool` find-diagnostic-id *diagnostic-name*
+{program}`diagtool` find-diagnostic-id *diagnostic-name*
 
-.. _list_warnings:
+(list-warnings)=
 
-list-warnings
-~~~~~~~~~~~~~
+### list-warnings
 
-:program:`diagtool` list-warnings
+{program}`diagtool` list-warnings
 
-.. _show_enabled:
+(show-enabled)=
 
-show-enabled
-~~~~~~~~~~~~
+### show-enabled
 
-:program:`diagtool` show-enabled [*options*] *filename ...*
+{program}`diagtool` show-enabled \[*options*\] *filename ...*
 
-.. _tree:
+(tree)=
 
-tree
-~~~~
+### tree
+
+{program}`diagtool` tree \[*diagnostic-group*\]
 
-:program:`diagtool` tree [*diagnostic-group*]
diff --git a/clang/docs/ConstantInterpreter.md b/clang/docs/ConstantInterpreter.md
index c92e9387bad20..7a86c266a7a74 100644
--- a/clang/docs/ConstantInterpreter.md
+++ b/clang/docs/ConstantInterpreter.md
@@ -1,33 +1,28 @@
-====================
-Constant Interpreter
-====================
+# Constant Interpreter
 
-.. contents::
-   :local:
+```{contents}
+:local: true
+```
 
-Introduction
-============
+## Introduction
 
 The bytecode interpreter aims to replace the existing AST traversal-based
 evaluator in Clang, improving performance on constructs which are executed
 inefficiently by the evaluator. The interpreter is activated by passing
-``-fexperimental-new-constant-interpreter`` to clang.
+`-fexperimental-new-constant-interpreter` to clang.
 
 Since Clang 23, the bytecode interpreter can also be enabled by default
-by passing ``-DCLANG_USE_EXPERIMENTAL_CONST_INTERP=ON`` to cmake. In
+by passing `-DCLANG_USE_EXPERIMENTAL_CONST_INTERP=ON` to cmake. In
 that case, it can be deactivated again via
-``-fno-experimental-new-constant-interpreter``.
+`-fno-experimental-new-constant-interpreter`.
 
+## Bytecode Compilation
 
-
-Bytecode Compilation
-====================
-
-Bytecode compilation is handled in ``Compiler.h`` for statements
+Bytecode compilation is handled in `Compiler.h` for statements
 and for expressions. The compiler has two different
-backends: one to generate bytecode for functions (``ByteCodeEmitter``) and
+backends: one to generate bytecode for functions (`ByteCodeEmitter`) and
 one to directly evaluate expressions as they are compiled, without
-generating bytecode (``EvalEmitter``). All functions are compiled to
+generating bytecode (`EvalEmitter`). All functions are compiled to
 bytecode, while toplevel expressions used in constant contexts are directly
 evaluated since the bytecode would never be reused. This mechanism aims to
 pave the way towards replacing the evaluator, improving its performance on
@@ -36,85 +31,78 @@ expressions.
 
 The interpreter relies on stack-based, strongly-typed opcodes. The glue
 logic between the code generator, along with the enumeration and
-description of opcodes, can be found in ``Opcodes.td``. The opcodes are
-implemented as generic template methods in ``Interp.h`` and instantiated
+description of opcodes, can be found in `Opcodes.td`. The opcodes are
+implemented as generic template methods in `Interp.h` and instantiated
 with the relevant primitive types by the interpreter loop or by the
 evaluating emitter.
 
-Primitive Types
----------------
+### Primitive Types
 
-* ``PT_{U|S}int{8|16|32|64}``
+- `PT_{U|S}int{8|16|32|64}`
 
   Signed or unsigned integers of a specific bit width.
   1-byte types are also 1 byte in size. Sizes >= 16 bits are implemented
-  using the ``Integral`` class. They take up 24 bytes each since they
+  using the `Integral` class. They take up 24 bytes each since they
   need to be able to represent a pointer that has been casted to an integer.
 
-
-* ``PT_IntAP{S}``
+- `PT_IntAP{S}`
 
   Signed or unsigned integers of an arbitrary, but fixed width used to
   implement integral types which are required by the target, but are not
-  supported by the host. Under the hood, they rely on ``APInt``. The
-  ``Integral`` specialisation for these types is required by opcodes to
+  supported by the host. Under the hood, they rely on `APInt`. The
+  `Integral` specialisation for these types is required by opcodes to
   share an implementation with fixed integrals.
 
-* ``PT_Bool``
+- `PT_Bool`
 
   Representation for boolean types, essentially a 1-bit unsigned
-  ``Integral``.
+  `Integral`.
 
-* ``PT_Float``
+- `PT_Float`
 
   Arbitrary, but fixed precision floating point numbers. Could be
   specialised in the future similarly to integers in order to improve
   floating point performance.
 
-* ``PT_Ptr``
+- `PT_Ptr`
 
-  Pointer type, defined in ``"Pointer.h"``. The most common type of
-  pointer is a "BlockPointer", which points to an ``interp::Block``.
+  Pointer type, defined in `"Pointer.h"`. The most common type of
+  pointer is a "BlockPointer", which points to an `interp::Block`.
   But other pointer types exist, such as typeid pointers or
   integral pointers.
 
-* ``PT_MemberPtr``
+- `PT_MemberPtr`
 
   Member pointer type, can also be a null member pointer. Defined
-  in ``"MemberPointer.h"``
+  in `"MemberPointer.h"`
 
-Composite types
----------------
+### Composite types
 
 The interpreter distinguishes two kinds of composite types: arrays and
 records (structs and classes). Unions are represented as records, except
 at most a single field can be marked as active. The contents of inactive
 fields are kept until they are reactivated and overwritten.
-Complex numbers (``_Complex``) and vectors
-(``__attribute((vector_size(16)))``) are treated as arrays.
+Complex numbers (`_Complex`) and vectors
+(`__attribute((vector_size(16)))`) are treated as arrays.
 
-
-Bytecode Execution
-==================
+## Bytecode Execution
 
 Bytecode is executed using a stack-based interpreter. The execution
-context consists of an ``InterpStack``, along with a chain of
-``InterpFrame`` objects storing the call frames. Frames are built by
+context consists of an `InterpStack`, along with a chain of
+`InterpFrame` objects storing the call frames. Frames are built by
 call instructions and destroyed by return instructions. They perform
 one allocation to reserve space for all locals in a single block.
 These objects store all the required information to emit stack traces
 whenever evaluation fails.
 
-Memory Organisation
-===================
+## Memory Organisation
 
-Memory management in the interpreter relies on 3 data structures: ``Block``
-objects which store the data and associated inline metadata, ``Pointer``
-objects which refer to or into blocks, and ``Descriptor`` structures which
+Memory management in the interpreter relies on 3 data structures: `Block`
+objects which store the data and associated inline metadata, `Pointer`
+objects which refer to or into blocks, and `Descriptor` structures which
 describe blocks and subobjects nested inside blocks.
 
-Blocks
-------
+### Blocks
 
 Blocks contain data interleaved with metadata. They are allocated either
 statically in the code generator (globals, static members, dummy parameter
@@ -123,10 +111,9 @@ containing the local variables of a function. Blocks are associated with a
 descriptor that characterises the entire allocation, along with a few
 additional attributes:
 
-* ``IsStatic`` indicates whether the block has static duration in the
+- `IsStatic` indicates whether the block has static duration in the
   interpreter, i.e. it is not a local in a frame.
-
-* ``DeclID`` identifies each global declaration (it is set to an invalid
+- `DeclID` identifies each global declaration (it is set to an invalid
   and irrelevant value for locals) in order to prevent illegal writes and
   reads involving globals and temporaries with static storage duration.
 
@@ -135,7 +122,7 @@ even when there are live pointers to them. Pointers are only valid as
 long as the blocks they point to are valid, so a block with pointers to
 it whose lifetime ends is kept alive until all pointers to it go out of
 scope. Since the frame is destroyed on function exit, such blocks are
-turned into a ``DeadBlock`` and copied to storage managed by the
+turned into a `DeadBlock` and copied to storage managed by the
 interpreter itself, not the frame. Reads and writes to these blocks are
 illegal and cause an appropriate diagnostic to be emitted. When the last
 pointer goes out of scope, dead blocks are also deallocated.
@@ -143,11 +130,10 @@ pointer goes out of scope, dead blocks are also deallocated.
 The lifetime of blocks is managed through 2 methods stored in the
 descriptor of the block:
 
-* **CtorFn**: initializes the metadata which is stored in the block,
+- **CtorFn**: initializes the metadata which is stored in the block,
   alongside actual data. Invokes the default constructors of objects
-  which are not trivial (``Pointer``, ``Floating``, etc.)
-
-* **DtorFn**: invokes the destructors of non-trivial objects.
+  which are not trivial (`Pointer`, `Floating`, etc.)
+- **DtorFn**: invokes the destructors of non-trivial objects.
 
 Blocks track all the pointers into them through an intrusive
 doubly-linked list, required to adjust and invalidate all pointers when
@@ -155,31 +141,29 @@ transforming a block into a dead block. If the lifetime of an object ends,
 all pointers to it are invalidated, emitting the appropriate diagnostics when
 dereferenced.
 
-
 Records are laid out identically to arrays of composites: each field and base
-class is preceded by an inline descriptor. The ``InlineDescriptor`` saves
+class is preceded by an inline descriptor. The `InlineDescriptor` saves
 information about the initialization state, constness, mutability, lifetime,
 etc. of a field.
 
 Consider this struct:
 
-.. code-block:: c++
+```c++
+struct S {
+    char c;
+};
+constexpr S s{12};
+```
 
-    struct S {
-        char c;
-    };
-    constexpr S s{12};
-
-When allocating space for ``s``, we allocate 24 bytes (not counting the ``Descriptor``
-instances we created for the ``Record`` and the field). The field ``c`` needs 8 bytes,
+When allocating space for `s`, we allocate 24 bytes (not counting the `Descriptor`
+instances we created for the `Record` and the field). The field `c` needs 8 bytes,
 since we align to pointer size (this example uses a 64 bit system). The
-``InlineDescriptor`` preceding the field data uses up the remaining 16 bytes.
+`InlineDescriptor` preceding the field data uses up the remaining 16 bytes.
 
-Inline descriptors are filled in by the ``CtorFn`` of blocks, which leaves storage
+Inline descriptors are filled in by the `CtorFn` of blocks, which leaves storage
 in an uninitialised, but valid state.
 
-Descriptors
------------
+### Descriptors
 
 Descriptors are generated at bytecode compilation time and contain information
 required to determine if a particular memory access is allowed in constexpr.
@@ -188,31 +172,29 @@ a memory access, such as the declaration which originates the block.
 Currently there is a single kind of descriptor encoding information for all
 block types.
 
-Pointers
---------
+### Pointers
 
-Pointers, implemented in ``Pointer.h`` are represented as a tagged union.
+Pointers, implemented in `Pointer.h` are represented as a tagged union.
 
- * **BlockPointer**: used to reference memory allocated and managed by the
-   interpreter, being the only pointer kind which allows dereferencing in the
-   interpreter
- * **TypeIDPointer**: tracks information for the opaque type returned by
-   ``typeid``
- * **IntegralPointer**: a pointer formed from an integer,
-   think ``(int*)123``.
- * **FunctionPointer**: a pointer to a function.
+> - **BlockPointer**: used to reference memory allocated and managed by the
+>   interpreter, being the only pointer kind which allows dereferencing in the
+>   interpreter
+> - **TypeIDPointer**: tracks information for the opaque type returned by
+>   `typeid`
+> - **IntegralPointer**: a pointer formed from an integer,
+>   think `(int*)123`.
+> - **FunctionPointer**: a pointer to a function.
 
 Besides the previously mentioned union, a number of other pointer-like types
 have their own type:
 
- * **FunctionPointer** tracks functions.
- * **MemberPointer** tracks C++ object members
+> - **FunctionPointer** tracks functions.
+> - **MemberPointer** tracks C++ object members
 
-BlockPointer
-~~~~~~~~~~~~
+#### BlockPointer
 
-Block pointers track a ``Pointee``, the block to which they point, along
-with a ``Base`` and an ``Offset``. The base identifies the innermost field,
+Block pointers track a `Pointee`, the block to which they point, along
+with a `Base` and an `Offset`. The base identifies the innermost field,
 while the offset points to an array element relative to the base (including
 one-past-end pointers). The offset identifies the array element or field
 which is referenced, while the base points to the outer object or array which
@@ -221,23 +203,23 @@ identified, disambiguated and characterised.
 
 As an example, consider the following structure:
 
-.. code-block:: c
-
-    struct A {
-        struct B {
-            int x;
-            int y;
-        } b;
-        struct C {
-            int a;
-            int b;
-        } c[2];
-        int z;
-    };
-    constexpr A a;
-
-On the target, ``&a`` and ``&a.b.x`` are equal. So are ``&a.c[0]`` and
-``&a.c[0].a``. In the interpreter, all these pointers must be
+```c
+struct A {
+    struct B {
+        int x;
+        int y;
+    } b;
+    struct C {
+        int a;
+        int b;
+    } c[2];
+    int z;
+};
+constexpr A a;
+```
+
+On the target, `&a` and `&a.b.x` are equal. So are `&a.c[0]` and
+`&a.c[0].a`. In the interpreter, all these pointers must be
 distinguished since they are all allowed to address a distinct range of
 memory.
 
@@ -245,84 +227,80 @@ In the interpreter, the object would require 240 bytes of storage and
 would have its fields interleaved with metadata. The pointers which can
 be derived to the object are illustrated in the following diagram:
 
-::
-
-      0   16  32  40  56  64  80  96  112 120 136 144 160 176 184 200 208 224 240
-  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
-  + B | D | D | x | D | y | D | D | D | a | D | b | D | D | a | D | b | D | z |
-  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
-      ^   ^   ^       ^       ^   ^   ^       ^       ^   ^       ^       ^
-      |   |   |       |       |   |   |   &a.c[0].b   |   |   &a.c[1].b   |
-      a   |&a.b.x  &a.b.y   &a.c  |&a.c[0].a          |&a.c[1].a          |
-        &a.b                   &a.c[0]            &a.c[1]               &a.z
-
-The ``Base`` offset of all pointers points to the start of a field or
-an array and is preceded by an inline descriptor (unless ``Base`` is
+```
+    0   16  32  40  56  64  80  96  112 120 136 144 160 176 184 200 208 224 240
++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
++ B | D | D | x | D | y | D | D | D | a | D | b | D | D | a | D | b | D | z |
++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+    ^   ^   ^       ^       ^   ^   ^       ^       ^   ^       ^       ^
+    |   |   |       |       |   |   |   &a.c[0].b   |   |   &a.c[1].b   |
+    a   |&a.b.x  &a.b.y   &a.c  |&a.c[0].a          |&a.c[1].a          |
+      &a.b                   &a.c[0]            &a.c[1]               &a.z
+```
+
+The `Base` offset of all pointers points to the start of a field or
+an array and is preceded by an inline descriptor (unless `Base` is
 zero, pointing to the root). All the relevant attributes can be read
 from either the inline descriptor or the descriptor of the block.
 
-
-Array elements are identified by the ``Offset`` field of pointers,
+Array elements are identified by the `Offset` field of pointers,
 pointing to past the inline descriptors for composites and before
-the actual data in the case of primitive arrays. The ``Offset``
+the actual data in the case of primitive arrays. The `Offset`
 points to the offset where primitives can be read from. As an example,
-``a.c + 1`` would have the same base as ``a.c`` since it is an element
-of ``a.c``, but its offset would point to ``&a.c[1]``. The
+`a.c + 1` would have the same base as `a.c` since it is an element
+of `a.c`, but its offset would point to `&a.c[1]`. The
 array-to-pointer decay operation adjusts a pointer to an array (where
 the offset is equal to the base) to a pointer to the first element.
 
-TypeInfoPointer
-~~~~~~~~~~~~~~~
+#### TypeInfoPointer
 
-``TypeInfoPointer`` tracks two types: the type assigned to
-``std::type_info`` and the type which was passed to ``typeinfo``.
-It is part of the tagged union in ``Pointer``.
+`TypeInfoPointer` tracks two types: the type assigned to
+`std::type_info` and the type which was passed to `typeinfo`.
+It is part of the tagged union in `Pointer`.
 
+### Interpretation
 
-
-Interpretation
---------------
 After bytecode has been generated (or not, for expressions), the bytecode
-is then interpreted. The bytecode is stack-based and uses ``InterpStack``
+is then interpreted. The bytecode is stack-based and uses `InterpStack`
 to allocate memory for the produced values.
 
 Here is an example function:
 
-.. code-block:: c++
-
-    constexpr int add(int a, int b) {
-      return a + b;
-    }
-    static_assert(add(1, 2) == 3);
-
-Which generates the following bytecode (this can be produced via ``interp::Function::dump()``):
-
-::
-
-  add 0x7cb97f7e2000
-  [...]
-  0     GetParamSint32    0
-  16    GetParamSint32    1
-  32    AddSint32
-  40    RetSint32
-  48    NoRet
+```c++
+constexpr int add(int a, int b) {
+  return a + b;
+}
+static_assert(add(1, 2) == 3);
+```
+
+Which generates the following bytecode (this can be produced via `interp::Function::dump()`):
+
+```
+add 0x7cb97f7e2000
+[...]
+0     GetParamSint32    0
+16    GetParamSint32    1
+32    AddSint32
+40    RetSint32
+48    NoRet
+```
 
 As you can see, all instructions here are type-aware. We're first pushing both parameter values
-to the stack. Then the ``Add`` opcode will add them up and push the result to the stack, which
-will be returned via the ``Ret`` opcode.
+to the stack. Then the `Add` opcode will add them up and push the result to the stack, which
+will be returned via the `Ret` opcode.
 
+### Debugging
 
-Debugging
----------
 Here are a few hints when working on the bytecode interpreter:
 
-* Setting a breakpoint on ``CCEDiag`` and ``FFDiag`` will stop the debugger when a diagnostic
+- Setting a breakpoint on `CCEDiag` and `FFDiag` will stop the debugger when a diagnostic
   is emitted.
-* If you want to see the bytecode of a function call ``dump()`` on the ``interp::Function``.
-* Additionally to the last point, ``interp::Function::dump(CodePtr)`` exists, which you can
-  pass the current ``OpPC`` and it will then show you where in the bytecode that opcode is.
-* ``interp::Pointer`` has an ``operator<<`` that prints useful information. Try it e.g.
-  via ``llvm::errs() << Ptr << '\n';``.
-* Printing ``APValue`` instances also works via ``APValue::dump()``.
-* If you want to see *everything* that's being evaluated, add debugging output to
-  the ``evaluate*`` functions in ``Context.cpp``.
+- If you want to see the bytecode of a function call `dump()` on the `interp::Function`.
+- Additionally to the last point, `interp::Function::dump(CodePtr)` exists, which you can
+  pass the current `OpPC` and it will then show you where in the bytecode that opcode is.
+- `interp::Pointer` has an `operator<<` that prints useful information. Try it e.g.
+  via `llvm::errs() << Ptr << '\n';`.
+- Printing `APValue` instances also works via `APValue::dump()`.
+- If you want to see *everything* that's being evaluated, add debugging output to
+  the `evaluate*` functions in `Context.cpp`.
+
diff --git a/clang/docs/ControlFlowIntegrityDesign.md b/clang/docs/ControlFlowIntegrityDesign.md
index d66bd16155a9f..a4acd20cae4cd 100644
--- a/clang/docs/ControlFlowIntegrityDesign.md
+++ b/clang/docs/ControlFlowIntegrityDesign.md
@@ -1,70 +1,71 @@
-===========================================
-Control Flow Integrity Design Documentation
-===========================================
+# Control Flow Integrity Design Documentation
 
-This page documents the design of the :doc:`ControlFlowIntegrity` schemes
+This page documents the design of the {doc}`ControlFlowIntegrity` schemes
 supported by Clang.
 
-Forward-Edge CFI for Virtual Calls
-==================================
+## Forward-Edge CFI for Virtual Calls
 
 This scheme works by allocating, for each static type used to make a virtual
 call, a region of read-only storage in the object file holding a bit vector
 that maps onto to the region of storage used for those virtual tables. Each
-set bit in the bit vector corresponds to the `address point`_ for a virtual
+set bit in the bit vector corresponds to the [address point][address point] for a virtual
 table compatible with the static type for which the bit vector is being built.
 
 For example, consider the following three C++ classes:
 
-.. code-block:: c++
-
-  struct A {
-    virtual void f1();
-    virtual void f2();
-    virtual void f3();
-  };
-
-  struct B : A {
-    virtual void f1();
-    virtual void f2();
-    virtual void f3();
-  };
-
-  struct C : A {
-    virtual void f1();
-    virtual void f2();
-    virtual void f3();
-  };
+```c++
+struct A {
+  virtual void f1();
+  virtual void f2();
+  virtual void f3();
+};
+
+struct B : A {
+  virtual void f1();
+  virtual void f2();
+  virtual void f3();
+};
+
+struct C : A {
+  virtual void f1();
+  virtual void f2();
+  virtual void f3();
+};
+```
 
 The scheme will cause the virtual tables for A, B and C to be laid out
 consecutively:
 
+```{eval-rst}
 .. csv-table:: Virtual Table Layout for A, B, C
   :header: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
 
   A::offset-to-top, &A::rtti, &A::f1, &A::f2, &A::f3, B::offset-to-top, &B::rtti, &B::f1, &B::f2, &B::f3, C::offset-to-top, &C::rtti, &C::f1, &C::f2, &C::f3
+```
 
 The bit vector for static types A, B and C will look like this:
 
+```{eval-rst}
 .. csv-table:: Bit Vectors for A, B, C
   :header: Class, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
 
   A, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0
   B, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0
   C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0
+```
 
 Bit vectors are represented in the object file as byte arrays. By loading
 from indexed offsets into the byte array and applying a mask, a program can
 test bits from the bit set with a relatively short instruction sequence. Bit
 vectors may overlap so long as they use different bits. For the full details,
-see the `ByteArrayBuilder`_ class.
+see the [ByteArrayBuilder][bytearraybuilder] class.
 
 In this case, assuming A is laid out at offset 0 in bit 0, B at offset 0 in
 bit 1 and C at offset 0 in bit 2, the byte array would look like this:
 
-.. code-block:: c++
-
-  char bits[] = { 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 5, 0, 0 };
+```c++
+char bits[] = { 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 5, 0, 0 };
+```
 
 To emit a virtual call, the compiler will assemble code that checks that
 the object's virtual table pointer is in-bounds and aligned and that the
@@ -72,32 +73,27 @@ relevant bit is set in the bit vector.
 
 For example on x86 a typical virtual call may look like this:
 
-.. code-block:: none
-
-  ca7fbb:       48 8b 0f                mov    (%rdi),%rcx
-  ca7fbe:       48 8d 15 c3 42 fb 07    lea    0x7fb42c3(%rip),%rdx
-  ca7fc5:       48 89 c8                mov    %rcx,%rax
-  ca7fc8:       48 29 d0                sub    %rdx,%rax
-  ca7fcb:       48 c1 c0 3d             rol    $0x3d,%rax
-  ca7fcf:       48 3d 7f 01 00 00       cmp    $0x17f,%rax
-  ca7fd5:       0f 87 36 05 00 00       ja     ca8511
-  ca7fdb:       48 8d 15 c0 0b f7 06    lea    0x6f70bc0(%rip),%rdx
-  ca7fe2:       f6 04 10 10             testb  $0x10,(%rax,%rdx,1)
-  ca7fe6:       0f 84 25 05 00 00       je     ca8511
-  ca7fec:       ff 91 98 00 00 00       callq  *0x98(%rcx)
-    [...]
-  ca8511:       0f 0b                   ud2
+```none
+ca7fbb:       48 8b 0f                mov    (%rdi),%rcx
+ca7fbe:       48 8d 15 c3 42 fb 07    lea    0x7fb42c3(%rip),%rdx
+ca7fc5:       48 89 c8                mov    %rcx,%rax
+ca7fc8:       48 29 d0                sub    %rdx,%rax
+ca7fcb:       48 c1 c0 3d             rol    $0x3d,%rax
+ca7fcf:       48 3d 7f 01 00 00       cmp    $0x17f,%rax
+ca7fd5:       0f 87 36 05 00 00       ja     ca8511
+ca7fdb:       48 8d 15 c0 0b f7 06    lea    0x6f70bc0(%rip),%rdx
+ca7fe2:       f6 04 10 10             testb  $0x10,(%rax,%rdx,1)
+ca7fe6:       0f 84 25 05 00 00       je     ca8511
+ca7fec:       ff 91 98 00 00 00       callq  *0x98(%rcx)
+  [...]
+ca8511:       0f 0b                   ud2
+```
 
 The compiler relies on co-operation from the linker in order to assemble
 the bit vectors for the whole program. It currently does this using LLVM's
-`type metadata`_ mechanism together with link-time optimization.
+[type metadata][type metadata] mechanism together with link-time optimization.
 
-.. _address point: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general
-.. _type metadata: https://llvm.org/docs/TypeMetadata.html
-.. _ByteArrayBuilder: https://llvm.org/docs/doxygen/html/structllvm_1_1ByteArrayBuilder.html
-
-Optimizations
--------------
+### Optimizations
 
 The scheme as described above is the fully general variant of the scheme.
 Most of the time we are able to apply one or more of the following
@@ -109,8 +105,7 @@ table layout or machine instructions. Some of the optimizations we are about
 to introduce cause the compiler to use a different layout or a different
 sequence of machine instructions.
 
-Stripping Leading/Trailing Zeros in Bit Vectors
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#### Stripping Leading/Trailing Zeros in Bit Vectors
 
 If a bit vector contains leading or trailing zeros, we can strip them from
 the vector. The compiler will emit code to check if the pointer is in range
@@ -118,15 +113,16 @@ of the region covered by ones, and perform the bit vector check using a
 truncated version of the bit vector. For example, the bit vectors for our
 example class hierarchy will be emitted like this:
 
+```{eval-rst}
 .. csv-table:: Bit Vectors for A, B, C
   :header: Class, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
 
   A,  ,  , 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,  ,
   B,  ,  ,  ,  ,  ,  ,  , 1,  ,  ,  ,  ,  ,  ,
   C,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  , 1,  ,
+```
 
-Short Inline Bit Vectors
-~~~~~~~~~~~~~~~~~~~~~~~~
+#### Short Inline Bit Vectors
 
 If the vector is sufficiently short, we can represent it as an inline constant
 on x86. This saves us a few instructions when reading the correct element
@@ -134,125 +130,124 @@ of the bit vector.
 
 If the bit vector fits in 32 bits, the code looks like this:
 
-.. code-block:: none
-
-     dc2:       48 8b 03                mov    (%rbx),%rax
-     dc5:       48 8d 15 14 1e 00 00    lea    0x1e14(%rip),%rdx
-     dcc:       48 89 c1                mov    %rax,%rcx
-     dcf:       48 29 d1                sub    %rdx,%rcx
-     dd2:       48 c1 c1 3d             rol    $0x3d,%rcx
-     dd6:       48 83 f9 03             cmp    $0x3,%rcx
-     dda:       77 2f                   ja     e0b <main+0x9b>
-     ddc:       ba 09 00 00 00          mov    $0x9,%edx
-     de1:       0f a3 ca                bt     %ecx,%edx
-     de4:       73 25                   jae    e0b <main+0x9b>
-     de6:       48 89 df                mov    %rbx,%rdi
-     de9:       ff 10                   callq  *(%rax)
-    [...]
-     e0b:       0f 0b                   ud2
+```none
+ dc2:       48 8b 03                mov    (%rbx),%rax
+ dc5:       48 8d 15 14 1e 00 00    lea    0x1e14(%rip),%rdx
+ dcc:       48 89 c1                mov    %rax,%rcx
+ dcf:       48 29 d1                sub    %rdx,%rcx
+ dd2:       48 c1 c1 3d             rol    $0x3d,%rcx
+ dd6:       48 83 f9 03             cmp    $0x3,%rcx
+ dda:       77 2f                   ja     e0b <main+0x9b>
+ ddc:       ba 09 00 00 00          mov    $0x9,%edx
+ de1:       0f a3 ca                bt     %ecx,%edx
+ de4:       73 25                   jae    e0b <main+0x9b>
+ de6:       48 89 df                mov    %rbx,%rdi
+ de9:       ff 10                   callq  *(%rax)
+[...]
+ e0b:       0f 0b                   ud2
+```
 
 Or if the bit vector fits in 64 bits:
 
-.. code-block:: none
-
-    11a6:       48 8b 03                mov    (%rbx),%rax
-    11a9:       48 8d 15 d0 28 00 00    lea    0x28d0(%rip),%rdx
-    11b0:       48 89 c1                mov    %rax,%rcx
-    11b3:       48 29 d1                sub    %rdx,%rcx
-    11b6:       48 c1 c1 3d             rol    $0x3d,%rcx
-    11ba:       48 83 f9 2a             cmp    $0x2a,%rcx
-    11be:       77 35                   ja     11f5 <main+0xb5>
-    11c0:       48 ba 09 00 00 00 00    movabs $0x40000000009,%rdx
-    11c7:       04 00 00
-    11ca:       48 0f a3 ca             bt     %rcx,%rdx
-    11ce:       73 25                   jae    11f5 <main+0xb5>
-    11d0:       48 89 df                mov    %rbx,%rdi
-    11d3:       ff 10                   callq  *(%rax)
-    [...]
-    11f5:       0f 0b                   ud2
+```none
+11a6:       48 8b 03                mov    (%rbx),%rax
+11a9:       48 8d 15 d0 28 00 00    lea    0x28d0(%rip),%rdx
+11b0:       48 89 c1                mov    %rax,%rcx
+11b3:       48 29 d1                sub    %rdx,%rcx
+11b6:       48 c1 c1 3d             rol    $0x3d,%rcx
+11ba:       48 83 f9 2a             cmp    $0x2a,%rcx
+11be:       77 35                   ja     11f5 <main+0xb5>
+11c0:       48 ba 09 00 00 00 00    movabs $0x40000000009,%rdx
+11c7:       04 00 00
+11ca:       48 0f a3 ca             bt     %rcx,%rdx
+11ce:       73 25                   jae    11f5 <main+0xb5>
+11d0:       48 89 df                mov    %rbx,%rdi
+11d3:       ff 10                   callq  *(%rax)
+[...]
+11f5:       0f 0b                   ud2
+```
 
 If the bit vector consists of a single bit, there is only one possible
 virtual table, and the check can consist of a single equality comparison:
 
-.. code-block:: none
-
-     9a2:   48 8b 03                mov    (%rbx),%rax
-     9a5:   48 8d 0d a4 13 00 00    lea    0x13a4(%rip),%rcx
-     9ac:   48 39 c8                cmp    %rcx,%rax
-     9af:   75 25                   jne    9d6 <main+0x86>
-     9b1:   48 89 df                mov    %rbx,%rdi
-     9b4:   ff 10                   callq  *(%rax)
-     [...]
-     9d6:   0f 0b                   ud2
+```none
+9a2:   48 8b 03                mov    (%rbx),%rax
+9a5:   48 8d 0d a4 13 00 00    lea    0x13a4(%rip),%rcx
+9ac:   48 39 c8                cmp    %rcx,%rax
+9af:   75 25                   jne    9d6 <main+0x86>
+9b1:   48 89 df                mov    %rbx,%rdi
+9b4:   ff 10                   callq  *(%rax)
+[...]
+9d6:   0f 0b                   ud2
+```
 
-Virtual Table Layout
-~~~~~~~~~~~~~~~~~~~~
+#### Virtual Table Layout
 
 The compiler lays out classes of disjoint hierarchies in separate regions
 of the object file. At worst, bit vectors in disjoint hierarchies only
 need to cover their disjoint hierarchy. But the closer that classes in
 sub-hierarchies are laid out to each other, the smaller the bit vectors for
 those sub-hierarchies need to be (see "Stripping Leading/Trailing Zeros in Bit
-Vectors" above). The `GlobalLayoutBuilder`_ class is responsible for laying
+Vectors" above). The [GlobalLayoutBuilder][globallayoutbuilder] class is responsible for laying
 out the globals efficiently to minimize the sizes of the underlying bitsets.
 
-.. _GlobalLayoutBuilder: https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h
-
-Alignment
-~~~~~~~~~
+#### Alignment
 
 If all gaps between address points in a particular bit vector are multiples
 of powers of 2, the compiler can compress the bit vector by strengthening
 the alignment requirements of the virtual table pointer. For example, given
 this class hierarchy:
 
-.. code-block:: c++
-
-  struct A {
-    virtual void f1();
-    virtual void f2();
-  };
-
-  struct B : A {
-    virtual void f1();
-    virtual void f2();
-    virtual void f3();
-    virtual void f4();
-    virtual void f5();
-    virtual void f6();
-  };
-
-  struct C : A {
-    virtual void f1();
-    virtual void f2();
-  };
+```c++
+struct A {
+  virtual void f1();
+  virtual void f2();
+};
+
+struct B : A {
+  virtual void f1();
+  virtual void f2();
+  virtual void f3();
+  virtual void f4();
+  virtual void f5();
+  virtual void f6();
+};
+
+struct C : A {
+  virtual void f1();
+  virtual void f2();
+};
+```
 
 The virtual tables will be laid out like this:
 
+```{eval-rst}
 .. csv-table:: Virtual Table Layout for A, B, C
   :header: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
 
   A::offset-to-top, &A::rtti, &A::f1, &A::f2, B::offset-to-top, &B::rtti, &B::f1, &B::f2, &B::f3, &B::f4, &B::f5, &B::f6, C::offset-to-top, &C::rtti, &C::f1, &C::f2
+```
 
 Notice that each address point for A is separated by 4 words. This lets us
 emit a compressed bit vector for A that looks like this:
 
+```{eval-rst}
 .. csv-table::
   :header: 2, 6, 10, 14
 
   1, 1, 0, 1
+```
 
 At call sites, the compiler will strengthen the alignment requirements by
 using a different rotate count. For example, on a 64-bit machine where the
-address points are 4-word aligned (as in A from our example), the ``rol``
+address points are 4-word aligned (as in A from our example), the `rol`
 instruction may look like this:
 
-.. code-block:: none
+```none
+dd2:       48 c1 c1 3b             rol    $0x3b,%rcx
+```
 
-     dd2:       48 c1 c1 3b             rol    $0x3b,%rcx
-
-Padding to Powers of 2
-~~~~~~~~~~~~~~~~~~~~~~
+#### Padding to Powers of 2
 
 Of course, this alignment scheme works best if the address points are
 in fact aligned correctly. To make this more likely to happen, we insert
@@ -267,17 +262,15 @@ instructions and bit vectors and increased overhead in the form of padding. We
 therefore limit the amount of padding so that we align to no more than 128
 bytes. This number was found experimentally to provide a good tradeoff.
 
-Eliminating Bit Vector Checks for All-Ones Bit Vectors
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#### Eliminating Bit Vector Checks for All-Ones Bit Vectors
 
 If the bit vector is all ones, the bit vector check is redundant; we simply
 need to check that the address is in range and well aligned. This is more
 likely to occur if the virtual tables are padded.
 
-Forward-Edge CFI for Virtual Calls by Interleaving Virtual Tables
------------------------------------------------------------------
+### Forward-Edge CFI for Virtual Calls by Interleaving Virtual Tables
 
-Dimitar et. al. proposed a novel approach that interleaves virtual tables in [1]_.
+Dimitar et. al. proposed a novel approach that interleaves virtual tables in [^footnote-1].
 This approach is more efficient in terms of space because padding and bit vectors are no longer needed.
 At the same time, it is also more efficient in terms of performance because in the interleaved layout
 address points of the virtual tables are consecutive, thus the validity check of a virtual
@@ -287,23 +280,19 @@ At a high level, the interleaving scheme consists of three steps: 1) split virtu
 separate virtual tables, 2) order virtual tables by a pre-order traversal of the class hierarchy
 and 3) interleave virtual tables.
 
-The interleaving scheme implemented in LLVM is inspired by [1]_ but has its own
-enhancements (more in `Interleave virtual tables`_).
+The interleaving scheme implemented in LLVM is inspired by [^footnote-1] but has its own
+enhancements (more in [Interleave virtual tables]).
 
-.. [1] `Protecting C++ Dynamic Dispatch Through VTable Interleaving <https://cseweb.ucsd.edu/~lerner/papers/ivtbl-ndss16.pdf>`_. Dimitar Bounov, Rami Gökhan Kıcı, Sorin Lerner.
+[^footnote-1]: [Protecting C++ Dynamic Dispatch Through VTable Interleaving](https://cseweb.ucsd.edu/~lerner/papers/ivtbl-ndss16.pdf). Dimitar Bounov, Rami Gökhan Kıcı, Sorin Lerner.
 
-Split virtual table groups into separate virtual tables
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#### Split virtual table groups into separate virtual tables
 
 The Itanium C++ ABI glues multiple individual virtual tables for a class into a combined virtual table (virtual table group).
 The interleaving scheme, however, can only work with individual virtual tables so it must split the combined virtual tables first.
 In comparison, the old scheme does not require the splitting but it is more efficient when the combined virtual tables have been split.
-The `GlobalSplit`_ pass is responsible for splitting combined virtual tables into individual ones.
-
-.. _GlobalSplit: https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/IPO/GlobalSplit.cpp
+The [GlobalSplit][globalsplit] pass is responsible for splitting combined virtual tables into individual ones.
 
-Order virtual tables by a pre-order traversal of the class hierarchy
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#### Order virtual tables by a pre-order traversal of the class hierarchy
 
 This step is common to both the old scheme described above and the interleaving scheme.
 For the interleaving scheme, since the combined virtual tables have been split in the previous step,
@@ -312,85 +301,94 @@ For the old scheme, the same property may not hold since it may work on combined
 
 For example, consider the following four C++ classes:
 
-.. code-block:: c++
-
-  struct A {
-    virtual void f1();
-  };
+```c++
+struct A {
+  virtual void f1();
+};
 
-  struct B : A {
-    virtual void f1();
-    virtual void f2();
-  };
+struct B : A {
+  virtual void f1();
+  virtual void f2();
+};
 
-  struct C : A {
-    virtual void f1();
-    virtual void f3();
-  };
+struct C : A {
+  virtual void f1();
+  virtual void f3();
+};
 
-  struct D : B {
-    virtual void f1();
-    virtual void f2();
-  };
+struct D : B {
+  virtual void f1();
+  virtual void f2();
+};
+```
 
 This step will arrange the virtual tables for A, B, C, and D in the order of *vtable-of-A, vtable-of-B, vtable-of-D, vtable-of-C*.
 
-Interleave virtual tables
-~~~~~~~~~~~~~~~~~~~~~~~~~
+#### Interleave virtual tables
 
 This step is where the interleaving scheme deviates from the old scheme. Instead of laying out
 whole virtual tables in the previously computed order, the interleaving scheme lays out table
 entries of the virtual tables strategically to ensure the following properties:
 
-(1) offset-to-top and RTTI fields layout property
+1. offset-to-top and RTTI fields layout property
 
 The Itanium C++ ABI specifies that offset-to-top and RTTI fields appear at the offsets behind the
 address point. Note that libraries like libcxxabi do assume this property.
 
-(2) virtual function entry layout property
+2. virtual function entry layout property
 
 For each virtual function the distance between a virtual table entry for this function and the corresponding
 address point is always the same. This property ensures that dynamic dispatch still works with the interleaving layout.
 
 Note that the interleaving scheme in the CFI implementation guarantees both properties above whereas the original scheme proposed
-in [1]_ only guarantees the second property.
+in [^footnote-1] only guarantees the second property.
 
 To illustrate how the interleaving algorithm works, let us continue with the running example.
 The algorithm first separates all the virtual table entries into two work lists. To do so,
 it starts by allocating two work lists, one initialized with all the offset-to-top entries of virtual tables in the order
 computed in the last step, one initialized with all the RTTI entries in the same order.
 
+```{eval-rst}
 .. csv-table:: Work list 1 Layout
   :header: 0, 1, 2, 3
 
   A::offset-to-top, B::offset-to-top, D::offset-to-top, C::offset-to-top
 
+```
 
+```{eval-rst}
 .. csv-table:: Work list 2 layout
   :header: 0, 1, 2, 3,
 
   &A::rtti, &B::rtti, &D::rtti, &C::rtti
+```
 
 Then for each virtual function the algorithm goes through all the virtual tables in the previously computed order
 to collect all the related entries into a virtual function list.
 After this step, there are the following virtual function lists:
 
+```{eval-rst}
 .. csv-table:: f1 list
   :header: 0, 1, 2, 3
 
   &A::f1, &B::f1, &D::f1, &C::f1
 
+```
 
+```{eval-rst}
 .. csv-table:: f2 list
   :header: 0, 1
 
   &B::f2, &D::f2
 
+```
 
+```{eval-rst}
 .. csv-table:: f3 list
   :header: 0
 
   &C::f3
+```
 
 Next, the algorithm picks the longest remaining virtual function list and appends the whole list to the shortest work list
 until no function lists are left, and pads the shorter work list so that they are of the same length.
@@ -398,32 +396,37 @@ In the example, f1 list will be first added to work list 1, then f2 list will be
 to work list 2, and finally f3 list will be added to the work list 2. Since work list 1 now has one more entry than
 work list 2, a padding entry is added to the latter. After this step, the two work lists look like:
 
+```{eval-rst}
 .. csv-table:: Work list 1 Layout
   :header: 0, 1, 2, 3, 4, 5, 6, 7
 
   A::offset-to-top, B::offset-to-top, D::offset-to-top, C::offset-to-top, &A::f1, &B::f1, &D::f1, &C::f1
 
+```
 
+```{eval-rst}
 .. csv-table:: Work list 2 layout
   :header: 0, 1, 2, 3, 4, 5, 6, 7
 
   &A::rtti, &B::rtti, &D::rtti, &C::rtti, &B::f2, &D::f2, &C::f3, padding
+```
 
 Finally, the algorithm merges the two work lists into the interleaved layout by alternatingly
 moving the head of each list to the final layout. After this step, the final interleaved layout looks like:
 
+```{eval-rst}
 .. csv-table:: Interleaved layout
   :header: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
 
   A::offset-to-top, &A::rtti, B::offset-to-top, &B::rtti, D::offset-to-top, &D::rtti, C::offset-to-top, &C::rtti, &A::f1, &B::f2, &B::f1, &D::f2, &D::f1, &C::f3, &C::f1, padding
+```
 
 In the above interleaved layout, each virtual table's offset-to-top and RTTI are always adjacent, which shows that the layout has the first property.
 For the second property, let us look at f2 as an example. In the interleaved layout,
 there are two entries for f2: B::f2 and D::f2. The distance between &B::f2
 and its address point D::offset-to-top (the entry immediately after &B::rtti) is 5 entry-length, so is the distance between &D::f2 and C::offset-to-top (the entry immediately after &D::rtti).
 
-Forward-Edge CFI for Indirect Function Calls
-============================================
+## Forward-Edge CFI for Indirect Function Calls
 
 Under forward-edge CFI for indirect function calls, each unique function
 type has its own bit vector, and at each call site we need to check that the
@@ -445,78 +448,77 @@ file's symbol table, the symbols for the target functions also refer to the
 jump table entries, so that addresses taken outside the module will pass
 any verification done inside the module.
 
-In more concrete terms, suppose we have three functions ``f``, ``g``,
-``h`` which are all of the same type, and a function foo that returns their
+In more concrete terms, suppose we have three functions `f`, `g`,
+`h` which are all of the same type, and a function foo that returns their
 addresses:
 
-.. code-block:: none
+```none
+f:
+mov 0, %eax
+ret
 
-  f:
-  mov 0, %eax
-  ret
+g:
+mov 1, %eax
+ret
 
-  g:
-  mov 1, %eax
-  ret
+h:
+mov 2, %eax
+ret
 
-  h:
-  mov 2, %eax
-  ret
-
-  foo:
-  mov f, %eax
-  mov g, %edx
-  mov h, %ecx
-  ret
+foo:
+mov f, %eax
+mov g, %edx
+mov h, %ecx
+ret
+```
 
 Our jump table will (conceptually) look like this:
 
-.. code-block:: none
-
-  f:
-  jmp .Ltmp0 ; 5 bytes
-  int3       ; 1 byte
-  int3       ; 1 byte
-  int3       ; 1 byte
-
-  g:
-  jmp .Ltmp1 ; 5 bytes
-  int3       ; 1 byte
-  int3       ; 1 byte
-  int3       ; 1 byte
-
-  h:
-  jmp .Ltmp2 ; 5 bytes
-  int3       ; 1 byte
-  int3       ; 1 byte
-  int3       ; 1 byte
-
-  .Ltmp0:
-  mov 0, %eax
-  ret
-
-  .Ltmp1:
-  mov 1, %eax
-  ret
-
-  .Ltmp2:
-  mov 2, %eax
-  ret
-
-  foo:
-  mov f, %eax
-  mov g, %edx
-  mov h, %ecx
-  ret
-
-Because the addresses of ``f``, ``g``, ``h`` are evenly spaced at a power of
+```none
+f:
+jmp .Ltmp0 ; 5 bytes
+int3       ; 1 byte
+int3       ; 1 byte
+int3       ; 1 byte
+
+g:
+jmp .Ltmp1 ; 5 bytes
+int3       ; 1 byte
+int3       ; 1 byte
+int3       ; 1 byte
+
+h:
+jmp .Ltmp2 ; 5 bytes
+int3       ; 1 byte
+int3       ; 1 byte
+int3       ; 1 byte
+
+.Ltmp0:
+mov 0, %eax
+ret
+
+.Ltmp1:
+mov 1, %eax
+ret
+
+.Ltmp2:
+mov 2, %eax
+ret
+
+foo:
+mov f, %eax
+mov g, %edx
+mov h, %ecx
+ret
+```
+
+Because the addresses of `f`, `g`, `h` are evenly spaced at a power of
 2, and function types do not overlap (unlike class types with base classes),
-we can normally apply the `Alignment`_ and `Eliminating Bit Vector Checks
-for All-Ones Bit Vectors`_ optimizations thus simplifying the check at each
+we can normally apply the [Alignment] and [Eliminating Bit Vector Checks
+for All-Ones Bit Vectors][eliminating bit vector checks for all-ones bit vectors] optimizations thus simplifying the check at each
 call site to a range and alignment check.
 
-Shared library support
-======================
+## Shared library support
 
 **EXPERIMENTAL**
 
@@ -531,120 +533,116 @@ Assuming the following setup: the binary consists of several
 instrumented and several uninstrumented DSOs. Some of them may be
 dlopen-ed/dlclose-d periodically, even frequently.
 
-  - Calls made from uninstrumented DSOs are not checked and just work.
-  - Calls inside any instrumented DSO are fully protected.
-  - Calls between different instrumented DSOs are also protected, with
-     a performance penalty (in addition to the monolithic CFI
-     overhead).
-  - Calls from an instrumented DSO to an uninstrumented one are
-     unchecked and just work, with performance penalty.
-  - Calls from an instrumented DSO outside of any known DSO are
-     detected as CFI violations.
+> - Calls made from uninstrumented DSOs are not checked and just work.
+> - Calls inside any instrumented DSO are fully protected.
+> - Calls between different instrumented DSOs are also protected, with
+>   : a performance penalty (in addition to the monolithic CFI
+>     overhead).
+> - Calls from an instrumented DSO to an uninstrumented one are
+>   : unchecked and just work, with performance penalty.
+> - Calls from an instrumented DSO outside of any known DSO are
+>   : detected as CFI violations.
 
 In the monolithic scheme a call site is instrumented as
 
-.. code-block:: none
-
-   if (!InlinedFastCheck(f))
-     abort();
-   call *f
+```none
+if (!InlinedFastCheck(f))
+  abort();
+call *f
+```
 
 In the cross-DSO scheme it becomes
 
-.. code-block:: none
+```none
+if (!InlinedFastCheck(f))
+  __cfi_slowpath(CallSiteTypeId, f);
+call *f
+```
 
-   if (!InlinedFastCheck(f))
-     __cfi_slowpath(CallSiteTypeId, f);
-   call *f
+### CallSiteTypeId
 
-CallSiteTypeId
---------------
-
-``CallSiteTypeId`` is a stable process-wide identifier of the
+`CallSiteTypeId` is a stable process-wide identifier of the
 call-site type. For a virtual call site, the type in question is the class
 type; for an indirect function call it is the function signature. The
 mapping from a type to an identifier is an ABI detail. In the current,
 experimental, implementation the identifier of type T is calculated as
 follows:
 
-  -  Obtain the mangled name for "typeinfo name for T".
-  -  Calculate MD5 hash of the name as a string.
-  -  Reinterpret the first 8 bytes of the hash as a little-endian
-     64-bit integer.
+> - Obtain the mangled name for "typeinfo name for T".
+> - Calculate MD5 hash of the name as a string.
+> - Reinterpret the first 8 bytes of the hash as a little-endian
+>   64-bit integer.
 
 It is possible, but unlikely, that collisions in the
-``CallSiteTypeId`` hashing will result in weaker CFI checks that would
+`CallSiteTypeId` hashing will result in weaker CFI checks that would
 still be conservatively correct.
 
-CFI_Check
----------
+### CFI_Check
 
 In the general case, only the target DSO knows whether the call to
-function ``f`` with type ``CallSiteTypeId`` is valid or not.  To
+function `f` with type `CallSiteTypeId` is valid or not. To
 export this information, every DSO implements
 
-.. code-block:: none
-
-   void __cfi_check(uint64 CallSiteTypeId, void *TargetAddr, void *DiagData)
+```none
+void __cfi_check(uint64 CallSiteTypeId, void *TargetAddr, void *DiagData)
+```
 
 This function provides external modules with access to CFI checks for
-the targets inside this DSO.  For each known ``CallSiteTypeId``, this
-function performs an ``llvm.type.test`` with the corresponding type
+the targets inside this DSO. For each known `CallSiteTypeId`, this
+function performs an `llvm.type.test` with the corresponding type
 identifier. It reports an error if the type is unknown, or if the
 check fails. Depending on the values of compiler flags
-``-fsanitize-trap`` and ``-fsanitize-recover``, this function may
-print an error, abort and/or return to the caller. ``DiagData`` is an
+`-fsanitize-trap` and `-fsanitize-recover`, this function may
+print an error, abort and/or return to the caller. `DiagData` is an
 opaque pointer to the diagnostic information about the error, or
-``null`` if the caller does not provide this information.
+`null` if the caller does not provide this information.
 
 The basic implementation is a large switch statement over all values
 of CallSiteTypeId supported by this DSO, and each case is similar to
 the InlinedFastCheck() in the basic CFI mode.
 
-CFI Shadow
-----------
+### CFI Shadow
 
-To route CFI checks to the target DSO's __cfi_check function, a
+To route CFI checks to the target DSO's \_\_cfi_check function, a
 mapping from possible virtual / indirect call targets to the
-corresponding __cfi_check functions is maintained. This mapping is
+corresponding \_\_cfi_check functions is maintained. This mapping is
 implemented as a sparse array of 2 bytes for every possible page (4096
 bytes) of memory. The table is kept readonly most of the time.
 
 There are 3 types of shadow values:
 
-  -  Address in a CFI-instrumented DSO.
-  -  Unchecked address (a “trusted” non-instrumented DSO). Encoded as
-     value 0xFFFF.
-  -  Invalid address (everything else). Encoded as value 0.
+> - Address in a CFI-instrumented DSO.
+> - Unchecked address (a “trusted” non-instrumented DSO). Encoded as
+>   value 0xFFFF.
+> - Invalid address (everything else). Encoded as value 0.
 
 For a CFI-instrumented DSO, a shadow value encodes the address of the
-__cfi_check function for all call targets in the corresponding memory
+\_\_cfi_check function for all call targets in the corresponding memory
 page. If Addr is the target address, and V is the shadow value, then
-the address of __cfi_check is calculated as
+the address of \_\_cfi_check is calculated as
 
-.. code-block:: none
+```none
+__cfi_check = AlignUpTo(Addr, 4096) - (V + 1) * 4096
+```
 
-  __cfi_check = AlignUpTo(Addr, 4096) - (V + 1) * 4096
-
-This works as long as __cfi_check is aligned by 4096 bytes and located
+This works as long as \_\_cfi_check is aligned by 4096 bytes and located
 below any call targets in its DSO, but not more than 256MB apart from
 them.
 
-CFI_SlowPath
-------------
+### CFI_SlowPath
 
 The slow path check is implemented in a runtime support library as
 
-.. code-block:: none
-
-  void __cfi_slowpath(uint64 CallSiteTypeId, void *TargetAddr)
-  void __cfi_slowpath_diag(uint64 CallSiteTypeId, void *TargetAddr, void *DiagData)
+```none
+void __cfi_slowpath(uint64 CallSiteTypeId, void *TargetAddr)
+void __cfi_slowpath_diag(uint64 CallSiteTypeId, void *TargetAddr, void *DiagData)
+```
 
-These functions loads a shadow value for ``TargetAddr``, finds the
-address of ``__cfi_check`` as described above and calls
-that. ``DiagData`` is an opaque pointer to diagnostic data which is
-passed verbatim to ``__cfi_check``, and ``__cfi_slowpath`` passes
-``nullptr`` instead.
+These functions loads a shadow value for `TargetAddr`, finds the
+address of `__cfi_check` as described above and calls
+that. `DiagData` is an opaque pointer to diagnostic data which is
+passed verbatim to `__cfi_check`, and `__cfi_slowpath` passes
+`nullptr` instead.
 
 Compiler-RT library contains reference implementations of slowpath
 functions, but they have unresolvable issues with correctness and
@@ -652,29 +650,27 @@ performance in the handling of dlopen(). It is recommended that
 platforms provide their own implementations, usually as part of libc
 or libdl.
 
-Position-independent executable requirement
--------------------------------------------
+### Position-independent executable requirement
 
 Cross-DSO CFI mode requires that the main executable is built as PIE.
 In non-PIE executables the address of an external function (taken from
 the main executable) is the address of that function’s PLT record in
 the main executable. This would break the CFI checks.
 
-Backward-edge CFI for return statements (RCFI)
-==============================================
+## Backward-edge CFI for return statements (RCFI)
 
 This section is a proposal. As of March 2017 it is not implemented.
 
 Backward-edge control flow (`RET` instructions) can be hijacked
 via overwriting the return address (`RA`) on stack.
-Various mitigation techniques (e.g. `SafeStack`_, `RFG`_, `Intel CET`_)
+Various mitigation techniques (e.g. [SafeStack][safestack], [RFG][rfg], [Intel CET][intel cet])
 try to detect or prevent `RA` corruption on stack.
 
 RCFI enforces the expected control flow in several different ways described below.
 RCFI heavily relies on LTO.
 
-Leaf Functions
---------------
+### Leaf Functions
+
 If `f()` is a leaf function (i.e. it has no calls
 except maybe no-return calls) it can be called using a special calling convention
 that stores `RA` in a dedicated register `R` before the `CALL` instruction.
@@ -690,9 +686,8 @@ then `JMP` to `R`.
 This approach is simpler to implement (does not require changing the caller)
 but weaker (there is a small window when `RA` is actually stored on stack).
 
+### Functions called once
 
-Functions called once
----------------------
 Suppose `f()` is called in just one place in the program
 (assuming we can verify this in LTO mode).
 In this case we can replace the `RET` instruction with a `JMP` instruction
@@ -702,8 +697,8 @@ This will *precisely* enforce the return control flow no matter what is stored o
 Another variant is to compare `RA` on stack with the known constant and abort
 if they don't match; then `JMP` to the known constant address.
 
-Functions called in a small number of call sites
-------------------------------------------------
+### Functions called in a small number of call sites
+
 We may extend the above approach to cases where `f()`
 is called more than once (but still a small number of times).
 With LTO we know all possible values of `RA` and we check them
@@ -714,8 +709,8 @@ This protection is *near-precise*, i.e. it guarantees that the control flow will
 be transferred to one of the valid return addresses for this function,
 but not necessary to the point of the most recent `CALL`.
 
-General case
-------------
+### General case
+
 For functions called multiple times a *return jump table* is constructed
 in the same manner as jump tables for indirect function calls (see above).
 The correct jump table entry (or its index) is passed by `CALL` to `f()`
@@ -725,32 +720,25 @@ jump table range check, and `JMP` to the jump table entry.
 
 This protection is also *near-precise*.
 
-Returns from functions called indirectly
-----------------------------------------
+### Returns from functions called indirectly
 
 If a function is called indirectly, the return jump table is constructed for the
 equivalence class of functions instead of a single function.
 
-Cross-DSO calls
----------------
+### Cross-DSO calls
+
 Consider two instrumented DSOs, `A` and `B`. `A` defines `f()` and `B` calls it.
 
 This case will be handled similarly to the cross-DSO scheme using the slow path callback.
 
-Non-goals
----------
+### Non-goals
 
 RCFI does not protect `RET` instructions:
-  * in non-instrumented DSOs,
-  * in instrumented DSOs for functions that are called from non-instrumented DSOs,
-  * embedded into other instructions (e.g. `0f4fc3 cmovg %ebx,%eax`).
+: - in non-instrumented DSOs,
+  - in instrumented DSOs for functions that are called from non-instrumented DSOs,
+  - embedded into other instructions (e.g. `0f4fc3 cmovg %ebx,%eax`).
 
-.. _SafeStack: https://clang.llvm.org/docs/SafeStack.html
-.. _RFG: https://xlab.tencent.com/en/2016/11/02/return-flow-guard
-.. _Intel CET: https://software.intel.com/en-us/blogs/2016/06/09/intel-release-new-technology-specifications-protect-rop-attacks
-
-Hardware support
-================
+## Hardware support
 
 We believe that the above design can be efficiently implemented in hardware.
 A single new instruction added to an ISA would allow to perform the forward-edge CFI check
@@ -763,32 +751,32 @@ and is properly aligned, and if the checks fail it will either trap (in monolith
 or call the slow path function (cross-DSO scheme).
 The bit vector lookup is probably too complex for a hardware implementation.
 
-.. code-block:: none
-
-  //  This instruction checks that 'Ptr'
-  //   * is aligned by (1 << kAlignment) and
-  //   * is inside [kRangeBeg, kRangeBeg+(kRangeSize<<kAlignment))
-  //  and if the check fails it jumps to the given target (slow path).
-  //
-  // 'Ptr' is a register, pointing to the virtual function table
-  //    or to the function which we need to check. We may require an explicit
-  //    fixed register to be used.
-  // 'kAlignment' is a 4-bit constant.
-  // 'kRangeSize' is a ~20-bit constant.
-  // 'kRangeBeg' is a PC-relative constant (~28 bits)
-  //    pointing to the beginning of the allowed range for 'Ptr'.
-  // 'kFailedCheckTarget': is a PC-relative constant (~28 bits)
-  //    representing the target to branch to when the check fails.
-  //    If kFailedCheckTarget==0, the process will trap
-  //    (monolithic binary scheme).
-  //    Otherwise it will jump to a handler that implements `CFI_SlowPath`
-  //    (cross-DSO scheme).
-  CFI_Check(Ptr, kAlignment, kRangeSize, kRangeBeg, kFailedCheckTarget) {
-     if (Ptr < kRangeBeg ||
-         Ptr >= kRangeBeg + (kRangeSize << kAlignment) ||
-         Ptr & ((1 << kAlignment) - 1))
-           Jump(kFailedCheckTarget);
-  }
+```none
+//  This instruction checks that 'Ptr'
+//   * is aligned by (1 << kAlignment) and
+//   * is inside [kRangeBeg, kRangeBeg+(kRangeSize<<kAlignment))
+//  and if the check fails it jumps to the given target (slow path).
+//
+// 'Ptr' is a register, pointing to the virtual function table
+//    or to the function which we need to check. We may require an explicit
+//    fixed register to be used.
+// 'kAlignment' is a 4-bit constant.
+// 'kRangeSize' is a ~20-bit constant.
+// 'kRangeBeg' is a PC-relative constant (~28 bits)
+//    pointing to the beginning of the allowed range for 'Ptr'.
+// 'kFailedCheckTarget': is a PC-relative constant (~28 bits)
+//    representing the target to branch to when the check fails.
+//    If kFailedCheckTarget==0, the process will trap
+//    (monolithic binary scheme).
+//    Otherwise it will jump to a handler that implements `CFI_SlowPath`
+//    (cross-DSO scheme).
+CFI_Check(Ptr, kAlignment, kRangeSize, kRangeBeg, kFailedCheckTarget) {
+   if (Ptr < kRangeBeg ||
+       Ptr >= kRangeBeg + (kRangeSize << kAlignment) ||
+       Ptr & ((1 << kAlignment) - 1))
+         Jump(kFailedCheckTarget);
+}
+```
 
 An alternative and more compact encoding would not use `kFailedCheckTarget`,
 and will trap on check failure instead.
@@ -801,3 +789,13 @@ Note that such hardware extension would be complementary to checks
 at the callee side, such as e.g. **Intel ENDBRANCH**.
 Moreover, CFI would have two benefits over ENDBRANCH: a) precision and b)
 ability to protect against invalid casts between polymorphic types.
+
+[address point]: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general
+[bytearraybuilder]: https://llvm.org/docs/doxygen/html/structllvm_1_1ByteArrayBuilder.html
+[globallayoutbuilder]: https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h
+[globalsplit]: https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/IPO/GlobalSplit.cpp
+[intel cet]: https://software.intel.com/en-us/blogs/2016/06/09/intel-release-new-technology-specifications-protect-rop-attacks
+[rfg]: https://xlab.tencent.com/en/2016/11/02/return-flow-guard
+[safestack]: https://clang.llvm.org/docs/SafeStack.html
+[type metadata]: https://llvm.org/docs/TypeMetadata.html
+
diff --git a/clang/docs/DataFlowSanitizerDesign.md b/clang/docs/DataFlowSanitizerDesign.md
index ef6e6d5821df6..764fbdbceaf7a 100644
--- a/clang/docs/DataFlowSanitizerDesign.md
+++ b/clang/docs/DataFlowSanitizerDesign.md
@@ -1,8 +1,7 @@
-DataFlowSanitizer Design Document
-=================================
+# DataFlowSanitizer Design Document
 
 This document sets out the design for DataFlowSanitizer, a general
-dynamic data flow analysis.  Unlike other Sanitizer tools, this tool is
+dynamic data flow analysis. Unlike other Sanitizer tools, this tool is
 not designed to detect a specific class of bugs on its own. Instead,
 it provides a generic dynamic data flow analysis framework to be used
 by clients to help detect application-specific issues within their
@@ -14,8 +13,7 @@ accessible by the program. The analysis is dynamic, which means that
 it operates on a running program, and tracks how the labels propagate
 through that program.
 
-Use Cases
----------
+## Use Cases
 
 This instrumentation can be used as a tool to help monitor how data
 flows from a program's inputs (sources) to its outputs (sinks).
@@ -23,106 +21,104 @@ This has applications from a privacy/security perspective in that
 one can audit how a sensitive data item is used within a program and
 ensure it isn't exiting the program anywhere it shouldn't be.
 
-Interface
----------
+## Interface
 
 A number of functions are provided which will attach taint labels to
 memory regions and extract the set of labels associated with a
 specific memory region. These functions are declared in the header
-file ``sanitizer/dfsan_interface.h``.
-
-.. code-block:: c
-
-  /// Sets the label for each address in [addr,addr+size) to \c label.
-  void dfsan_set_label(dfsan_label label, void *addr, size_t size);
-
-  /// Sets the label for each address in [addr,addr+size) to the union of the
-  /// current label for that address and \c label.
-  void dfsan_add_label(dfsan_label label, void *addr, size_t size);
-
-  /// Retrieves the label associated with the given data.
-  ///
-  /// The type of 'data' is arbitrary.  The function accepts a value of any type,
-  /// which can be truncated or extended (implicitly or explicitly) as necessary.
-  /// The truncation/extension operations will preserve the label of the original
-  /// value.
-  dfsan_label dfsan_get_label(long data);
-
-  /// Retrieves the label associated with the data at the given address.
-  dfsan_label dfsan_read_label(const void *addr, size_t size);
-
-  /// Returns whether the given label contains the label elem.
-  int dfsan_has_label(dfsan_label label, dfsan_label elem);
-
-  /// Computes the union of \c l1 and \c l2, resulting in a union label.
-  dfsan_label dfsan_union(dfsan_label l1, dfsan_label l2);
-
-  /// Flushes the DFSan shadow, i.e. forgets about all labels currently associated
-  /// with the application memory.  Use this call to start over the taint tracking
-  /// within the same process.
-  ///
-  /// Note: If another thread is working with tainted data during the flush, that
-  /// taint could still be written to shadow after the flush.
-  void dfsan_flush(void);
+file `sanitizer/dfsan_interface.h`.
+
+```c
+/// Sets the label for each address in [addr,addr+size) to \c label.
+void dfsan_set_label(dfsan_label label, void *addr, size_t size);
+
+/// Sets the label for each address in [addr,addr+size) to the union of the
+/// current label for that address and \c label.
+void dfsan_add_label(dfsan_label label, void *addr, size_t size);
+
+/// Retrieves the label associated with the given data.
+///
+/// The type of 'data' is arbitrary.  The function accepts a value of any type,
+/// which can be truncated or extended (implicitly or explicitly) as necessary.
+/// The truncation/extension operations will preserve the label of the original
+/// value.
+dfsan_label dfsan_get_label(long data);
+
+/// Retrieves the label associated with the data at the given address.
+dfsan_label dfsan_read_label(const void *addr, size_t size);
+
+/// Returns whether the given label contains the label elem.
+int dfsan_has_label(dfsan_label label, dfsan_label elem);
+
+/// Computes the union of \c l1 and \c l2, resulting in a union label.
+dfsan_label dfsan_union(dfsan_label l1, dfsan_label l2);
+
+/// Flushes the DFSan shadow, i.e. forgets about all labels currently associated
+/// with the application memory.  Use this call to start over the taint tracking
+/// within the same process.
+///
+/// Note: If another thread is working with tainted data during the flush, that
+/// taint could still be written to shadow after the flush.
+void dfsan_flush(void);
+```
 
 The following functions are provided to check origin tracking status and results.
 
-.. code-block:: c
-
-  /// Retrieves the immediate origin associated with the given data. The returned
-  /// origin may point to another origin.
-  ///
-  /// The type of 'data' is arbitrary. The function accepts a value of any type,
-  /// which can be truncated or extended (implicitly or explicitly) as necessary.
-  /// The truncation/extension operations will preserve the label of the original
-  /// value.
-  dfsan_origin dfsan_get_origin(long data);
-
-  /// Retrieves the very first origin associated with the data at the given
-  /// address.
-  dfsan_origin dfsan_get_init_origin(const void *addr);
-
-  /// Prints the origin trace of the label at the address `addr` to stderr. It also
-  /// prints description at the beginning of the trace. If origin tracking is not
-  /// on, or the address is not labeled, it prints nothing.
-  void dfsan_print_origin_trace(const void *addr, const char *description);
-
-  /// Prints the origin trace of the label at the address `addr` to a pre-allocated
-  /// output buffer. If origin tracking is not on, or the address is`
-  /// not labeled, it prints nothing.
-  ///
-  /// `addr` is the tainted memory address whose origin we are printing.
-  /// `description` is a description printed at the beginning of the trace.
-  /// `out_buf` is the output buffer to write the results to. `out_buf_size` is
-  /// the size of `out_buf`. The function returns the number of symbols that
-  /// should have been written to `out_buf` (not including trailing null byte '\0').
-  /// Thus, the string is truncated iff return value is not less than `out_buf_size`.
-  size_t dfsan_sprint_origin_trace(const void *addr, const char *description,
-                                   char *out_buf, size_t out_buf_size);
-
-  /// Returns the value of `-dfsan-track-origins`.
-  int dfsan_get_track_origins(void);
+```c
+/// Retrieves the immediate origin associated with the given data. The returned
+/// origin may point to another origin.
+///
+/// The type of 'data' is arbitrary. The function accepts a value of any type,
+/// which can be truncated or extended (implicitly or explicitly) as necessary.
+/// The truncation/extension operations will preserve the label of the original
+/// value.
+dfsan_origin dfsan_get_origin(long data);
+
+/// Retrieves the very first origin associated with the data at the given
+/// address.
+dfsan_origin dfsan_get_init_origin(const void *addr);
+
+/// Prints the origin trace of the label at the address `addr` to stderr. It also
+/// prints description at the beginning of the trace. If origin tracking is not
+/// on, or the address is not labeled, it prints nothing.
+void dfsan_print_origin_trace(const void *addr, const char *description);
+
+/// Prints the origin trace of the label at the address `addr` to a pre-allocated
+/// output buffer. If origin tracking is not on, or the address is`
+/// not labeled, it prints nothing.
+///
+/// `addr` is the tainted memory address whose origin we are printing.
+/// `description` is a description printed at the beginning of the trace.
+/// `out_buf` is the output buffer to write the results to. `out_buf_size` is
+/// the size of `out_buf`. The function returns the number of symbols that
+/// should have been written to `out_buf` (not including trailing null byte '\0').
+/// Thus, the string is truncated iff return value is not less than `out_buf_size`.
+size_t dfsan_sprint_origin_trace(const void *addr, const char *description,
+                                 char *out_buf, size_t out_buf_size);
+
+/// Returns the value of `-dfsan-track-origins`.
+int dfsan_get_track_origins(void);
+```
 
 The following functions are provided to register hooks called by custom wrappers.
 
-.. code-block:: c
-
-  /// Sets a callback to be invoked on calls to `write`.  The callback is invoked
-  /// before the write is done. The write is not guaranteed to succeed when the
-  /// callback executes. Pass in NULL to remove any callback.
-  typedef void (*dfsan_write_callback_t)(int fd, const void *buf, size_t count);
-  void dfsan_set_write_callback(dfsan_write_callback_t labeled_write_callback);
+```c
+/// Sets a callback to be invoked on calls to `write`.  The callback is invoked
+/// before the write is done. The write is not guaranteed to succeed when the
+/// callback executes. Pass in NULL to remove any callback.
+typedef void (*dfsan_write_callback_t)(int fd, const void *buf, size_t count);
+void dfsan_set_write_callback(dfsan_write_callback_t labeled_write_callback);
 
-  /// Callbacks to be invoked on calls to `memcmp` or `strncmp`.
-  void dfsan_weak_hook_memcmp(void *caller_pc, const void *s1, const void *s2,
-                              size_t n, dfsan_label s1_label,
-                              dfsan_label s2_label, dfsan_label n_label);
-  void dfsan_weak_hook_strncmp(void *caller_pc, const char *s1, const char *s2,
-                              size_t n, dfsan_label s1_label,
-                              dfsan_label s2_label, dfsan_label n_label);
+/// Callbacks to be invoked on calls to `memcmp` or `strncmp`.
+void dfsan_weak_hook_memcmp(void *caller_pc, const void *s1, const void *s2,
+                            size_t n, dfsan_label s1_label,
+                            dfsan_label s2_label, dfsan_label n_label);
+void dfsan_weak_hook_strncmp(void *caller_pc, const char *s1, const char *s2,
+                            size_t n, dfsan_label s1_label,
+                            dfsan_label s2_label, dfsan_label n_label);
+```
 
-Taint label representation
---------------------------
+## Taint label representation
 
 We use an 8-bit unsigned integer for the representation of a
 label. The label identifier 0 is special, and means that the data item
@@ -135,8 +131,7 @@ Users are responsible for managing the 8 integer labels (i.e., keeping
 track of what labels they have used so far, picking one that is yet
 unused, etc).
 
-Origin tracking trace representation
-------------------------------------
+## Origin tracking trace representation
 
 An origin tracking trace is a list of chains. Each chain has a stack trace
 where the DFSan runtime records a label propagation, and a pointer to its
@@ -148,15 +143,15 @@ Every four 4-bytes aligned application bytes share a 4-byte origin trace ID. A
 A chain ID is calculated as a hash from a chain structure. A chain structure
 contains a stack ID and the previous chain ID. The chain head has a zero
 previous chain ID. A stack ID is a hash from a stack trace. The 4-bit depth
-limits the maximal length of a path. The environment variable ``origin_history_size``
+limits the maximal length of a path. The environment variable `origin_history_size`
 can set the depth limit. Non-positive values mean unlimited. Its default value
 is 16. When reaching the limit, origin tracking ignores following propagation
 chains.
 
 The first chain of a trace starts by `dfsan_set_label` with non-zero labels. A
 new chain is appended at the end of a trace at stores or memory transfers when
-``-dfsan-track-origins`` is 1. Memory transfers include LLVM memory transfer
-instructions, glibc memcpy and memmove. When ``-dfsan-track-origins`` is 2, a
+`-dfsan-track-origins` is 1. Memory transfers include LLVM memory transfer
+instructions, glibc memcpy and memmove. When `-dfsan-track-origins` is 2, a
 new chain is also appended at loads.
 
 Other instructions do not create new chains, but simply propagate origin trace
@@ -164,128 +159,110 @@ IDs. If an instruction has more than one operand with non-zero labels, the origi
 trace ID of the last operand with non-zero label is propagated to the result of
 the instruction.
 
-Memory layout and label management
-----------------------------------
-
-The following is the memory layout for Linux/x86\_64:
-
-+---------------+---------------+--------------------+
-|    Start      |    End        |        Use         |
-+===============+===============+====================+
-| 0x700000000000|0x800000000000 |    application 3   |
-+---------------+---------------+--------------------+
-| 0x610000000000|0x700000000000 |       unused       |
-+---------------+---------------+--------------------+
-| 0x600000000000|0x610000000000 |      origin 1      |
-+---------------+---------------+--------------------+
-| 0x510000000000|0x600000000000 |    application 2   |
-+---------------+---------------+--------------------+
-| 0x500000000000|0x510000000000 |      shadow 1      |
-+---------------+---------------+--------------------+
-| 0x400000000000|0x500000000000 |       unused       |
-+---------------+---------------+--------------------+
-| 0x300000000000|0x400000000000 |      origin 3      |
-+---------------+---------------+--------------------+
-| 0x200000000000|0x300000000000 |      shadow 3      |
-+---------------+---------------+--------------------+
-| 0x110000000000|0x200000000000 |      origin 2      |
-+---------------+---------------+--------------------+
-| 0x100000000000|0x110000000000 |       unused       |
-+---------------+---------------+--------------------+
-| 0x010000000000|0x100000000000 |      shadow 2      |
-+---------------+---------------+--------------------+
-| 0x000000000000|0x010000000000 |    application 1   |
-+---------------+---------------+--------------------+
+## Memory layout and label management
+
+The following is the memory layout for Linux/x86_64:
+
+| Start          | End            | Use           |
+| -------------- | -------------- | ------------- |
+| 0x700000000000 | 0x800000000000 | application 3 |
+| 0x610000000000 | 0x700000000000 | unused        |
+| 0x600000000000 | 0x610000000000 | origin 1      |
+| 0x510000000000 | 0x600000000000 | application 2 |
+| 0x500000000000 | 0x510000000000 | shadow 1      |
+| 0x400000000000 | 0x500000000000 | unused        |
+| 0x300000000000 | 0x400000000000 | origin 3      |
+| 0x200000000000 | 0x300000000000 | shadow 3      |
+| 0x110000000000 | 0x200000000000 | origin 2      |
+| 0x100000000000 | 0x110000000000 | unused        |
+| 0x010000000000 | 0x100000000000 | shadow 2      |
+| 0x000000000000 | 0x010000000000 | application 1 |
 
 Each byte of application memory corresponds to a single byte of shadow
 memory, which is used to store its taint label. We map memory, shadow, and
 origin regions to each other with these masks and offsets:
 
-* shadow_addr = memory_addr ^ 0x500000000000
-
-* origin_addr = shadow_addr + 0x100000000000
+- shadow_addr = memory_addr ^ 0x500000000000
+- origin_addr = shadow_addr + 0x100000000000
 
 As for LLVM SSA registers, we have not found it necessary to associate a label
 with each byte or bit of data, as some other tools do. Instead, labels are
-associated directly with registers.  Loads will result in a union of
+associated directly with registers. Loads will result in a union of
 all shadow labels corresponding to bytes loaded, and stores will
 result in a copy of the label of the stored value to the shadow of all
 bytes stored to.
 
-Propagating labels through arguments
-------------------------------------
+## Propagating labels through arguments
 
 In order to propagate labels through function arguments and return values,
 DataFlowSanitizer changes the ABI of each function in the translation unit.
 There are currently two supported ABIs:
 
-* Args -- Argument and return value labels are passed through additional
+- Args -- Argument and return value labels are passed through additional
   arguments and by modifying the return type.
-
-* TLS -- Argument and return value labels are passed through TLS variables
-  ``__dfsan_arg_tls`` and ``__dfsan_retval_tls``.
+- TLS -- Argument and return value labels are passed through TLS variables
+  `__dfsan_arg_tls` and `__dfsan_retval_tls`.
 
 The main advantage of the TLS ABI is that it is more tolerant of ABI mismatches
 (TLS storage is not shared with any other form of storage, whereas extra
 arguments may be stored in registers which under the native ABI are not used
-for parameter passing and thus could contain arbitrary values).  On the other
+for parameter passing and thus could contain arbitrary values). On the other
 hand the args ABI is more efficient and allows ABI mismatches to be more easily
 identified by checking for nonzero labels in nominally unlabelled programs.
 
-Implementing the ABI list
--------------------------
+## Implementing the ABI list
 
-The `ABI list <DataFlowSanitizer.html#abi-list>`_ provides a list of functions
+The [ABI list](DataFlowSanitizer.html#abi-list) provides a list of functions
 which conform to the native ABI, each of which is callable from an instrumented
-program.  This is implemented by replacing each reference to a native ABI
+program. This is implemented by replacing each reference to a native ABI
 function with a reference to a function which uses the instrumented ABI.
 Such functions are automatically-generated wrappers for the native functions.
 For example, given the ABI list example provided in the user manual, the
 following wrappers will be generated under the args ABI:
 
-.. code-block:: llvm
-
-    define linkonce_odr { i8*, i16 } @"dfsw$malloc"(i64 %0, i16 %1) {
-    entry:
-      %2 = call i8* @malloc(i64 %0)
-      %3 = insertvalue { i8*, i16 } undef, i8* %2, 0
-      %4 = insertvalue { i8*, i16 } %3, i16 0, 1
-      ret { i8*, i16 } %4
-    }
-
-    define linkonce_odr { i32, i16 } @"dfsw$tolower"(i32 %0, i16 %1) {
-    entry:
-      %2 = call i32 @tolower(i32 %0)
-      %3 = insertvalue { i32, i16 } undef, i32 %2, 0
-      %4 = insertvalue { i32, i16 } %3, i16 %1, 1
-      ret { i32, i16 } %4
-    }
-
-    define linkonce_odr { i8*, i16 } @"dfsw$memcpy"(i8* %0, i8* %1, i64 %2, i16 %3, i16 %4, i16 %5) {
-    entry:
-      %labelreturn = alloca i16
-      %6 = call i8* @__dfsw_memcpy(i8* %0, i8* %1, i64 %2, i16 %3, i16 %4, i16 %5, i16* %labelreturn)
-      %7 = load i16* %labelreturn
-      %8 = insertvalue { i8*, i16 } undef, i8* %6, 0
-      %9 = insertvalue { i8*, i16 } %8, i16 %7, 1
-      ret { i8*, i16 } %9
-    }
+```llvm
+define linkonce_odr { i8*, i16 } @"dfsw$malloc"(i64 %0, i16 %1) {
+entry:
+  %2 = call i8* @malloc(i64 %0)
+  %3 = insertvalue { i8*, i16 } undef, i8* %2, 0
+  %4 = insertvalue { i8*, i16 } %3, i16 0, 1
+  ret { i8*, i16 } %4
+}
+
+define linkonce_odr { i32, i16 } @"dfsw$tolower"(i32 %0, i16 %1) {
+entry:
+  %2 = call i32 @tolower(i32 %0)
+  %3 = insertvalue { i32, i16 } undef, i32 %2, 0
+  %4 = insertvalue { i32, i16 } %3, i16 %1, 1
+  ret { i32, i16 } %4
+}
+
+define linkonce_odr { i8*, i16 } @"dfsw$memcpy"(i8* %0, i8* %1, i64 %2, i16 %3, i16 %4, i16 %5) {
+entry:
+  %labelreturn = alloca i16
+  %6 = call i8* @__dfsw_memcpy(i8* %0, i8* %1, i64 %2, i16 %3, i16 %4, i16 %5, i16* %labelreturn)
+  %7 = load i16* %labelreturn
+  %8 = insertvalue { i8*, i16 } undef, i8* %6, 0
+  %9 = insertvalue { i8*, i16 } %8, i16 %7, 1
+  ret { i8*, i16 } %9
+}
+```
 
 As an optimization, direct calls to native ABI functions will call the
 native ABI function directly and the pass will compute the appropriate label
-internally.  This has the advantage of reducing the number of union operations
-required when the return value label is known to be zero (i.e. ``discard``
-functions, or ``functional`` functions with known unlabelled arguments).
+internally. This has the advantage of reducing the number of union operations
+required when the return value label is known to be zero (i.e. `discard`
+functions, or `functional` functions with known unlabelled arguments).
 
-Checking ABI Consistency
-------------------------
+## Checking ABI Consistency
 
-DFSan changes the ABI of each function in the module.  This makes it possible
+DFSan changes the ABI of each function in the module. This makes it possible
 for a function with the native ABI to be called with the instrumented ABI,
-or vice versa, thus possibly invoking undefined behavior.  A simple way
+or vice versa, thus possibly invoking undefined behavior. A simple way
 of statically detecting instances of this problem is to append the suffix
 ".dfsan" to the name of each instrumented-ABI function.
 
 This will not catch every such problem; in particular function pointers passed
 across the instrumented-native barrier cannot be used on the other side.
 These problems could potentially be caught dynamically.
+
diff --git a/clang/docs/HLSL/AvailabilityDiagnostics.md b/clang/docs/HLSL/AvailabilityDiagnostics.md
index 0db94f4b15a86..ba947699e3bec 100644
--- a/clang/docs/HLSL/AvailabilityDiagnostics.md
+++ b/clang/docs/HLSL/AvailabilityDiagnostics.md
@@ -1,136 +1,126 @@
-=============================
-HLSL Availability Diagnostics
-=============================
+# HLSL Availability Diagnostics
 
-.. contents::
-   :local:
+```{contents}
+:local: true
+```
 
-Introduction
-============
+## Introduction
 
 HLSL availability diagnostics emits errors or warning when unavailable shader APIs are used. Unavailable shader APIs are APIs that are exposed in HLSL code but are not available in the target shader stage or shader model version.
 
 There are three modes of HLSL availability diagnostic:
 
-#. **Default mode** - compiler emits an error when an unavailable API is found in a code that is reachable from the shader entry point function or from an exported library function (when compiling a shader library)
+1. **Default mode** - compiler emits an error when an unavailable API is found in a code that is reachable from the shader entry point function or from an exported library function (when compiling a shader library)
+2. **Relaxed mode** - same as default mode except the compiler emits a warning. This mode is enabled by `-Wno-error=hlsl-availability`.
+3. **Strict mode** - compiler emits an error when an unavailable API is found in parsed code regardless of whether it can be reached from the shader entry point or exported functions, or not. This mode is enabled by `-fhlsl-strict-availability`.
 
-#. **Relaxed mode** - same as default mode except the compiler emits a warning. This mode is enabled by ``-Wno-error=hlsl-availability``.
+## Implementation Details
 
-#. **Strict mode** - compiler emits an error when an unavailable API is found in parsed code regardless of whether it can be reached from the shader entry point or exported functions, or not. This mode is enabled by ``-fhlsl-strict-availability``.
+### Environment Parameter
 
-Implementation Details
-======================
+In order to encode API availability based on the shader model version and shader model stage a new `environment` parameter was added to the existing Clang `availability` attribute.
 
-Environment Parameter
----------------------
+The values allowed for this parameter are a subset of values allowed as the `llvm::Triple` environment component. If the environment parameters is present, the declared availability attribute applies only to targets with the same platform and environment.
 
-In order to encode API availability based on the shader model version and shader model stage a new ``environment`` parameter was added to the existing Clang ``availability`` attribute.
+### Default and Relaxed Diagnostic Modes
 
-The values allowed for this parameter are a subset of values allowed as the ``llvm::Triple`` environment component. If the environment parameters is present, the declared availability attribute applies only to targets with the same platform and environment.
+This mode is implemented in `DiagnoseHLSLAvailability` class in `SemaHLSL.cpp` and it is invoked after the whole translation unit is parsed (from `Sema::ActOnEndOfTranslationUnit`). The implementation iterates over all shader entry points and exported library functions in the translation unit and performs an AST traversal of each function body.
 
-Default and Relaxed Diagnostic Modes
-------------------------------------
-
-This mode is implemented in ``DiagnoseHLSLAvailability`` class in ``SemaHLSL.cpp`` and it is invoked after the whole translation unit is parsed (from ``Sema::ActOnEndOfTranslationUnit``). The implementation iterates over all shader entry points and exported library functions in the translation unit and performs an AST traversal of each function body.
-
-When a reference to another function or member method is found (``DeclRefExpr`` or ``MemberExpr``) and it has a body, the AST of the referenced function is also scanned. This chain of AST traversals will reach all of the code that is reachable from the initial shader entry point or exported library function and avoids the need to generate a call graph.
+When a reference to another function or member method is found (`DeclRefExpr` or `MemberExpr`) and it has a body, the AST of the referenced function is also scanned. This chain of AST traversals will reach all of the code that is reachable from the initial shader entry point or exported library function and avoids the need to generate a call graph.
 
 All shader APIs have an availability attribute that specifies the shader model version (and environment, if applicable) when this API was first introduced.When a reference to a function without a definition is found and it has an availability attribute, the version of the attribute is checked against the target shader model version and shader stage (if shader stage context is known), and an appropriate diagnostic is generated as needed.
 
-All shader entry functions have ``HLSLShaderAttr`` attribute that specifies what type of shader this function represents. However, for exported library functions the target shader stage is unknown, so in this case the HLSL API availability will be only checked against the shader model version. It means that for exported library functions the diagnostic of APIs with availability specific to shader stage will be deferred until DXIL linking time.
+All shader entry functions have `HLSLShaderAttr` attribute that specifies what type of shader this function represents. However, for exported library functions the target shader stage is unknown, so in this case the HLSL API availability will be only checked against the shader model version. It means that for exported library functions the diagnostic of APIs with availability specific to shader stage will be deferred until DXIL linking time.
 
-A list of functions that were already scanned is kept in order to avoid duplicate scans and diagnostics (see ``DiagnoseHLSLAvailability::ScannedDecls``). It might happen that a shader library has multiple shader entry points for different shader stages that all call into the same shared function. It is therefore important to record not just that a function has been scanned, but also in which shader stage context. This is done by using ``llvm::DenseMap`` that maps ``FunctionDecl *`` to a ``unsigned`` bitmap that represents a set of shader stages (or environments) the function has been scanned for. The ``N``'th bit in the set is set if the function has been scanned in shader environment whose ``HLSLShaderAttr::ShaderType`` integer value equals ``N``.
+A list of functions that were already scanned is kept in order to avoid duplicate scans and diagnostics (see `DiagnoseHLSLAvailability::ScannedDecls`). It might happen that a shader library has multiple shader entry points for different shader stages that all call into the same shared function. It is therefore important to record not just that a function has been scanned, but also in which shader stage context. This is done by using `llvm::DenseMap` that maps `FunctionDecl *` to a `unsigned` bitmap that represents a set of shader stages (or environments) the function has been scanned for. The `N`'th bit in the set is set if the function has been scanned in shader environment whose `HLSLShaderAttr::ShaderType` integer value equals `N`.
 
-The emitted diagnostic messages belong to ``hlsl-availability`` diagnostic group and are reported as errors by default. With ``-Wno-error=hlsl-availability`` flag they become warning, making it relaxed HLSL diagnostics mode.
+The emitted diagnostic messages belong to `hlsl-availability` diagnostic group and are reported as errors by default. With `-Wno-error=hlsl-availability` flag they become warning, making it relaxed HLSL diagnostics mode.
 
-Strict Diagnostic Mode
-----------------------
+### Strict Diagnostic Mode
 
-When strict HLSL availability diagnostic mode is enabled the compiler must report all HLSL API availability issues regardless of code reachability. The implementation of this mode takes advantage of an existing diagnostic scan in ``DiagnoseUnguardedAvailability`` class which is already traversing AST of each function as soon as the function body has been parsed. For HLSL, this pass was only slightly modified, such as making sure diagnostic messages are in the ``hlsl-availability`` group and that availability checks based on shader stage are not included if the shader stage context is unknown.
+When strict HLSL availability diagnostic mode is enabled the compiler must report all HLSL API availability issues regardless of code reachability. The implementation of this mode takes advantage of an existing diagnostic scan in `DiagnoseUnguardedAvailability` class which is already traversing AST of each function as soon as the function body has been parsed. For HLSL, this pass was only slightly modified, such as making sure diagnostic messages are in the `hlsl-availability` group and that availability checks based on shader stage are not included if the shader stage context is unknown.
 
-If the compilation target is a shader library, only availability based on shader model version can be diagnosed during this scan. To diagnose availability based on shader stage, the compiler needs to run the AST traversals implemented in ``DiagnoseHLSLAvailability`` at the end of the translation unit as described above.
+If the compilation target is a shader library, only availability based on shader model version can be diagnosed during this scan. To diagnose availability based on shader stage, the compiler needs to run the AST traversals implemented in `DiagnoseHLSLAvailability` at the end of the translation unit as described above.
 
 As a result, availability based on specific shader stage will only be diagnosed in code that is reachable from a shader entry point or library export function. It also means that function bodies might be scanned multiple time. When that happens, care should be taken not to produce duplicated diagnostics.
 
-Examples
-========
+## Examples
 
 **Note**
-For the example below, the ``WaveActiveCountBits`` API function became available in shader model 6.0 and ``WaveMultiPrefixSum`` in shader model 6.5.
+For the example below, the `WaveActiveCountBits` API function became available in shader model 6.0 and `WaveMultiPrefixSum` in shader model 6.5.
 
-The availability of ``ddx`` function depends on a shader stage. It is available for pixel shaders in shader model 2.1 and higher, for compute, mesh and amplification shaders in shader model 6.6 and higher. For any other shader stages it is not available.
+The availability of `ddx` function depends on a shader stage. It is available for pixel shaders in shader model 2.1 and higher, for compute, mesh and amplification shaders in shader model 6.6 and higher. For any other shader stages it is not available.
 
-Compute shader example
-----------------------
+### Compute shader example
 
-.. code-block:: c++
+```c++
+float unusedFunction(float f) {
+  return ddx(f);
+}
 
-   float unusedFunction(float f) {
-     return ddx(f);
-   }
-
-   [numthreads(4, 4, 1)]
-   void main(uint3 threadId : SV_DispatchThreadId) {
-     float f1 = ddx(threadId.x);
-     float f2 = WaveActiveCountBits(threadId.y == 1.0);
-   }
+[numthreads(4, 4, 1)]
+void main(uint3 threadId : SV_DispatchThreadId) {
+  float f1 = ddx(threadId.x);
+  float f2 = WaveActiveCountBits(threadId.y == 1.0);
+}
+```
 
 When compiled as compute shader for shader model version 5.0, Clang will emit the following error by default:
 
-.. code-block:: console
-
-   <>:7:13: error: 'ddx' is only available in compute shader environment on Shader Model 6.6 or newer
-   <>:8:13: error: 'WaveActiveCountBits' is only available on Shader Model 6.5 or newer
+```console
+<>:7:13: error: 'ddx' is only available in compute shader environment on Shader Model 6.6 or newer
+<>:8:13: error: 'WaveActiveCountBits' is only available on Shader Model 6.5 or newer
+```
 
 With relaxed diagnostic mode this errors will become warnings.
 
-With strict diagnostic mode, in addition to the 2 errors above Clang will also emit error for the ``ddx`` call in ``unusedFunction``.:
+With strict diagnostic mode, in addition to the 2 errors above Clang will also emit error for the `ddx` call in `unusedFunction`.:
 
-.. code-block:: console
+```console
+<>:2:9: error: 'ddx' is only available in compute shader environment on Shader Model 6.5 or newer
+<>:7:13: error: 'ddx' is only available in compute shader environment on Shader Model 6.5 or newer
+<>:7:13: error: 'WaveActiveCountBits' is only available on Shader Model 6.5 or newer
+```
 
-   <>:2:9: error: 'ddx' is only available in compute shader environment on Shader Model 6.5 or newer
-   <>:7:13: error: 'ddx' is only available in compute shader environment on Shader Model 6.5 or newer
-   <>:7:13: error: 'WaveActiveCountBits' is only available on Shader Model 6.5 or newer
+### Shader library example
 
-Shader library example
-----------------------
+```c++
+float myFunction(float f) {
+  return ddx(f);
+}
 
-.. code-block:: c++
+float unusedFunction(float f) {
+  return WaveMultiPrefixSum(f, 1.0);
+}
 
-   float myFunction(float f) {
-     return ddx(f);
-   }
+[shader("compute")]
+[numthreads(4, 4, 1)]
+void main(uint3 threadId : SV_DispatchThreadId) {
+   float f = 3;
+   float e = myFunction(f);
+}
 
-   float unusedFunction(float f) {
-     return WaveMultiPrefixSum(f, 1.0);
-   }
-
-   [shader("compute")]
-   [numthreads(4, 4, 1)]
-   void main(uint3 threadId : SV_DispatchThreadId) {
-      float f = 3;
-      float e = myFunction(f);
-   }
-
-   [shader("pixel")]
-   void main() {
-      float f = 3;
-      float e = myFunction(f);
-   }
+[shader("pixel")]
+void main() {
+   float f = 3;
+   float e = myFunction(f);
+}
+```
 
 When compiled as shader library vshader model version 6.4, Clang will emit the following error by default:
 
-.. code-block:: console
-
-   <>:2:9: error: 'ddx' is only available in compute shader environment on Shader Model 6.5 or newer
+```console
+<>:2:9: error: 'ddx' is only available in compute shader environment on Shader Model 6.5 or newer
+```
 
 With relaxed diagnostic mode this errors will become warnings.
 
 With strict diagnostic mode Clang will also emit errors for availability issues in code that is not used by any of the entry points:
 
-.. code-block:: console
+```console
+<>2:9: error: 'ddx' is only available in compute shader environment on Shader Model 6.6 or newer
+<>:6:9: error: 'WaveActiveCountBits' is only available on Shader Model 6.5 or newer
+```
 
-   <>2:9: error: 'ddx' is only available in compute shader environment on Shader Model 6.6 or newer
-   <>:6:9: error: 'WaveActiveCountBits' is only available on Shader Model 6.5 or newer
+Note that `myFunction` is reachable from both pixel and compute shader entry points is therefore scanned twice - once for each context. The diagnostic is emitted only for the compute shader context.
 
-Note that ``myFunction`` is reachable from both pixel and compute shader entry points is therefore scanned twice - once for each context. The diagnostic is emitted only for the compute shader context.
diff --git a/clang/docs/HLSL/EntryFunctions.md b/clang/docs/HLSL/EntryFunctions.md
index 518698b9b1f7a..e82d3513151f8 100644
--- a/clang/docs/HLSL/EntryFunctions.md
+++ b/clang/docs/HLSL/EntryFunctions.md
@@ -1,18 +1,16 @@
-====================
-HLSL Entry Functions
-====================
+# HLSL Entry Functions
 
-.. contents::
-   :local:
+```{contents}
+:local: true
+```
 
-Usage
-=====
+## Usage
 
 In HLSL, entry functions denote the starting point for shader execution. They
 must be known at compile time. For all non-library shaders, the compiler assumes
-the default entry function name ``main``, unless the DXC ``/E`` option is
+the default entry function name `main`, unless the DXC `/E` option is
 provided to specify an alternate entry point. For library shaders entry points
-are denoted using the ``[shader(...)]`` attribute.
+are denoted using the `[shader(...)]` attribute.
 
 All scalar parameters to entry functions must have semantic annotations, and all
 struct parameters must have semantic annotations on every field in the struct
@@ -22,13 +20,12 @@ annotation must be provided for the return type as well.
 HLSL entry functions can be called from other parts of the shader, which has
 implications on code generation.
 
-Implementation Details
-======================
+## Implementation Details
 
-In Clang, the DXC ``/E`` option is translated to the cc1 flag ``-hlsl-entry``,
-which in turn applies the ``HLSLShader`` attribute to the function with the
+In Clang, the DXC `/E` option is translated to the cc1 flag `-hlsl-entry`,
+which in turn applies the `HLSLShader` attribute to the function with the
 specified name. This allows code generation for entry functions to always key
-off the presence of the ``HLSLShader`` attribute, regardless of what shader
+off the presence of the `HLSLShader` attribute, regardless of what shader
 profile you are compiling.
 
 In code generation, two functions are generated. One is the user defined
@@ -36,9 +33,9 @@ function, which is code generated as a mangled C++ function with internal
 linkage following normal function code generation.
 
 The actual exported entry function which can be called by the GPU driver is a
-``void(void)`` function that isn't name mangled. In code generation we generate
+`void(void)` function that isn't name mangled. In code generation we generate
 the unmangled entry function to serve as the actual shader entry. The shader
-entry function is annotated with the ``hlsl.shader`` function attribute
+entry function is annotated with the `hlsl.shader` function attribute
 identifying the entry's pipeline stage.
 
 The body of the unmangled entry function contains first a call to execute global
@@ -46,28 +43,28 @@ constructors, then instantiations of the user-defined entry parameters with
 their semantic values populated, and a call to the user-defined function.
 After the call instruction the return value (if any) is saved using a
 target-appropriate intrinsic for storing outputs (for DirectX, the
-``llvm.dx.store.output``). Lastly, any present global destructors will be called
-immediately before the return. HLSL does not support C++ ``atexit``
+`llvm.dx.store.output`). Lastly, any present global destructors will be called
+immediately before the return. HLSL does not support C++ `atexit`
 registrations, instead calls to global destructors are compile-time generated.
 
-.. note::
-
-   HLSL support in Clang is currently focused on compute shaders, which do not
-   support output semantics. Support for output semantics will not be
-   implemented until other shader profiles are supported.
+:::{note}
+HLSL support in Clang is currently focused on compute shaders, which do not
+support output semantics. Support for output semantics will not be
+implemented until other shader profiles are supported.
+:::
 
 Below is example IR that represents the planned implementation, subject to
-change as the ``llvm.dx.store.output`` and ``llvm.dx.load.input`` intrinsics are
+change as the `llvm.dx.store.output` and `llvm.dx.load.input` intrinsics are
 not yet implemented.
 
-.. code-block:: none
-
-   ; Function Attrs: norecurse
-   define void @main() #1 {
-      entry:
-      %0 = call i32 @llvm.dx.load.input.i32(...)
-      %1 = call i32 @"?main@@YAXII at Z"(i32 %0)
-      call @llvm.dx.store.output.i32(%1, ...)
-      ret void
-   }
+```none
+; Function Attrs: norecurse
+define void @main() #1 {
+   entry:
+   %0 = call i32 @llvm.dx.load.input.i32(...)
+   %1 = call i32 @"?main@@YAXII at Z"(i32 %0)
+   call @llvm.dx.store.output.i32(%1, ...)
+   ret void
+}
+```
 
diff --git a/clang/docs/HLSL/ExpectedDifferences.md b/clang/docs/HLSL/ExpectedDifferences.md
index e143c5b71575a..c5f0e8508e602 100644
--- a/clang/docs/HLSL/ExpectedDifferences.md
+++ b/clang/docs/HLSL/ExpectedDifferences.md
@@ -1,31 +1,26 @@
-===================================
-Expected Differences vs DXC and FXC
-===================================
+# Expected Differences vs DXC and FXC
 
-.. contents::
-   :local:
+```{contents}
+:local: true
+```
 
-Introduction
-============
+## Introduction
 
-HLSL currently has two reference compilers, the `DirectX Shader Compiler (DXC)
-<https://github.com/microsoft/DirectXShaderCompiler/>`_ and the
-`Effect-Compiler (FXC) <https://learn.microsoft.com/en-us/windows/win32/direct3dtools/fxc>`_.
+HLSL currently has two reference compilers, the [DirectX Shader Compiler (DXC)](https://github.com/microsoft/DirectXShaderCompiler/) and the
+[Effect-Compiler (FXC)](https://learn.microsoft.com/en-us/windows/win32/direct3dtools/fxc).
 The two reference compilers do not fully agree. Some known disagreements in the
 references are tracked on
-`DXC's GitHub
-<https://github.com/microsoft/DirectXShaderCompiler/issues?q=is%3Aopen+is%3Aissue+label%3Afxc-disagrees>`_,
+[DXC's GitHub](https://github.com/microsoft/DirectXShaderCompiler/issues?q=is%3Aopen+is%3Aissue+label%3Afxc-disagrees),
 but many more are known to exist.
 
 HLSL as implemented by Clang will also not fully match either of the reference
-implementations, it is instead being written to match the `draft language
-specification <https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf>`_.
+implementations, it is instead being written to match the [draft language
+specification](https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf).
 
 This document is a non-exhaustive collection the known differences between
 Clang's implementation of HLSL and the existing reference compilers.
 
-General Principles
-------------------
+### General Principles
 
 Most of the intended differences between Clang and the earlier reference
 compilers are focused on increased consistency and correctness. Both reference
@@ -38,32 +33,30 @@ compatibility with conforming HLSL code, Clang may produce earlier and more
 robust diagnostics for incorrect code or reject code that a reference compiler
 incorrectly accepted.
 
-Language Version
-================
+## Language Version
 
 Clang targets language compatibility for HLSL 2021 as implemented by DXC.
 Language features that were removed in earlier versions of HLSL may be added on
 a case-by-case basis, but are not planned for the initial implementation.
 
-Overload Resolution
-===================
+## Overload Resolution
 
 Clang's HLSL implementation adopts C++ overload resolution rules as proposed for
 HLSL 202x based on proposal
-`0007 <https://github.com/microsoft/hlsl-specs/blob/main/proposals/0007-const-instance-methods.md>`_
+[0007](https://github.com/microsoft/hlsl-specs/blob/main/proposals/0007-const-instance-methods.md)
 and
-`0008 <https://github.com/microsoft/hlsl-specs/blob/main/proposals/0008-non-member-operator-overloading.md>`_.
+[0008](https://github.com/microsoft/hlsl-specs/blob/main/proposals/0008-non-member-operator-overloading.md).
 
 The largest difference between Clang and DXC's overload resolution is the
 algorithm used for identifying best-match overloads. There are more details
-about the algorithmic differences in the :ref:`multi_argument_overloads` section
+about the algorithmic differences in the {ref}`multi_argument_overloads` section
 below. There are three high level differences that should be highlighted:
 
-* **There should be no cases** where DXC and Clang both successfully
+- **There should be no cases** where DXC and Clang both successfully
   resolve an overload where the resolved overload is different between the two.
-* There are cases where Clang will successfully resolve an overload that DXC
+- There are cases where Clang will successfully resolve an overload that DXC
   wouldn't because we've trimmed the overload set in Clang to remove ambiguity.
-* There are cases where DXC will successfully resolve an overload that Clang
+- There are cases where DXC will successfully resolve an overload that Clang
   will not for two reasons: (1) DXC only generates partial overload sets for
   builtin functions and (2) DXC resolves cases that probably should be ambiguous.
 
@@ -71,144 +64,143 @@ Clang's implementation extends standard overload resolution rules to HLSL
 library functionality. This causes subtle changes in overload resolution
 behavior between Clang and DXC. Some examples include:
 
-.. code-block:: c++
-
-  void halfOrInt16(half H);
-  void halfOrInt16(uint16_t U);
-  void halfOrInt16(int16_t I);
-
-  void takesDoubles(double, double, double);
-
-  cbuffer CB {
-    bool B;
-    uint U;
-    int I;
-    float X, Y, Z;
-    double3 R, G;
-  }
-
-  void takesSingleDouble(double);
-  void takesSingleDouble(vector<double, 1>);
-
-  void scalarOrVector(double);
-  void scalarOrVector(vector<double, 2>);
-
-  export void call() {
-    half H;
-    halfOrInt16(I); // All: Resolves to halfOrInt16(int16_t).
-
-  #ifndef IGNORE_ERRORS
-    halfOrInt16(U); // All: Fails with call ambiguous between int16_t and uint16_t
-                    // overloads
-
-    // asfloat16 is a builtin with overloads for half, int16_t, and uint16_t.
-    H = asfloat16(I); // DXC: Fails to resolve overload for int.
-                      // Clang: Resolves to asfloat16(int16_t).
-    H = asfloat16(U); // DXC: Fails to resolve overload for int.
-                      // Clang: Resolves to asfloat16(uint16_t).
-  #endif
-    H = asfloat16(0x01); // DXC: Resolves to asfloat16(half).
-                         // Clang: Resolves to asfloat16(uint16_t).
-
-    takesDoubles(X, Y, Z); // Works on all compilers
-  #ifndef IGNORE_ERRORS
-    fma(X, Y, Z); // DXC: Fails to resolve no known conversion from float to
-                  //   double.
-                  // Clang: Resolves to fma(double,double,double).
-
-    double D = dot(R, G); // DXC: Resolves to dot(double3, double3), fails DXIL Validation.
-                          // FXC: Expands to compute double dot product with fmul/fadd
-                          // Clang: Fails to resolve as ambiguous against
-                          //   dot(half, half) or dot(float, float)
-  #endif
-
-  #ifndef IGNORE_ERRORS
-    tan(B); // DXC: resolves to tan(float).
-            // Clang: Fails to resolve, ambiguous between integer types.
-
-  #endif
-
-    double D;
-    takesSingleDouble(D); // All: Fails to resolve ambiguous conversions.
-    takesSingleDouble(R); // All: Fails to resolve ambiguous conversions.
-
-    scalarOrVector(D); // All: Resolves to scalarOrVector(double).
-    scalarOrVector(R); // All: Fails to resolve ambiguous conversions.
-  }
-
-.. note::
-
-  In Clang, a conscious decision was made to exclude the ``dot(vector<double,N>, vector<double,N>)``
-  overload and allow overload resolution to resolve the
-  ``vector<float,N>`` overload. This approach provides ``-Wconversion``
-  diagnostic notifying the user of the conversion rather than silently altering
-  precision relative to the other overloads (as FXC does) or generating code
-  that will fail validation (as DXC does).
-
-.. _multi_argument_overloads:
-
-Multi-Argument Overloads
-------------------------
+```c++
+void halfOrInt16(half H);
+void halfOrInt16(uint16_t U);
+void halfOrInt16(int16_t I);
+
+void takesDoubles(double, double, double);
+
+cbuffer CB {
+  bool B;
+  uint U;
+  int I;
+  float X, Y, Z;
+  double3 R, G;
+}
+
+void takesSingleDouble(double);
+void takesSingleDouble(vector<double, 1>);
+
+void scalarOrVector(double);
+void scalarOrVector(vector<double, 2>);
+
+export void call() {
+  half H;
+  halfOrInt16(I); // All: Resolves to halfOrInt16(int16_t).
+
+#ifndef IGNORE_ERRORS
+  halfOrInt16(U); // All: Fails with call ambiguous between int16_t and uint16_t
+                  // overloads
+
+  // asfloat16 is a builtin with overloads for half, int16_t, and uint16_t.
+  H = asfloat16(I); // DXC: Fails to resolve overload for int.
+                    // Clang: Resolves to asfloat16(int16_t).
+  H = asfloat16(U); // DXC: Fails to resolve overload for int.
+                    // Clang: Resolves to asfloat16(uint16_t).
+#endif
+  H = asfloat16(0x01); // DXC: Resolves to asfloat16(half).
+                       // Clang: Resolves to asfloat16(uint16_t).
+
+  takesDoubles(X, Y, Z); // Works on all compilers
+#ifndef IGNORE_ERRORS
+  fma(X, Y, Z); // DXC: Fails to resolve no known conversion from float to
+                //   double.
+                // Clang: Resolves to fma(double,double,double).
+
+  double D = dot(R, G); // DXC: Resolves to dot(double3, double3), fails DXIL Validation.
+                        // FXC: Expands to compute double dot product with fmul/fadd
+                        // Clang: Fails to resolve as ambiguous against
+                        //   dot(half, half) or dot(float, float)
+#endif
+
+#ifndef IGNORE_ERRORS
+  tan(B); // DXC: resolves to tan(float).
+          // Clang: Fails to resolve, ambiguous between integer types.
+
+#endif
+
+  double D;
+  takesSingleDouble(D); // All: Fails to resolve ambiguous conversions.
+  takesSingleDouble(R); // All: Fails to resolve ambiguous conversions.
+
+  scalarOrVector(D); // All: Resolves to scalarOrVector(double).
+  scalarOrVector(R); // All: Fails to resolve ambiguous conversions.
+}
+```
+
+:::{note}
+In Clang, a conscious decision was made to exclude the `dot(vector<double,N>, vector<double,N>)`
+overload and allow overload resolution to resolve the
+`vector<float,N>` overload. This approach provides `-Wconversion`
+diagnostic notifying the user of the conversion rather than silently altering
+precision relative to the other overloads (as FXC does) or generating code
+that will fail validation (as DXC does).
+:::
+
+(multi-argument-overloads)=
+
+### Multi-Argument Overloads
 
 In addition to the differences in single-element conversions, Clang and DXC
 differ dramatically in multi-argument overload resolution. C++ multi-argument
 overload resolution behavior (or something very similar) is required to
 implement
-`non-member operator overloading <https://github.com/microsoft/hlsl-specs/blob/main/proposals/0008-non-member-operator-overloading.md>`_.
+[non-member operator overloading](https://github.com/microsoft/hlsl-specs/blob/main/proposals/0008-non-member-operator-overloading.md).
 
 Clang adopts the C++ inspired language from the
-`draft HLSL specification <https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf>`_,
-where an overload ``f1`` is a better candidate than ``f2`` if for all arguments the
+[draft HLSL specification](https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf),
+where an overload `f1` is a better candidate than `f2` if for all arguments the
 conversion sequences is not worse than the corresponding conversion sequence and
 for at least one argument it is better.
 
-.. code-block:: c++
-
-  cbuffer CB {
-    int I;
-    float X;
-    float4 V;
-  }
-
-  void twoParams(int, int);
-  void twoParams(float, float);
-  void threeParams(float, float, float);
-  void threeParams(float4, float4, float4);
-
-  export void call() {
-    twoParams(I, X); // DXC: resolves twoParams(int, int).
-                     // Clang: Fails to resolve ambiguous conversions.
-
-    threeParams(X, V, V); // DXC: resolves threeParams(float4, float4, float4).
-                          // Clang: Fails to resolve ambiguous conversions.
-  }
-
-For the examples above since ``twoParams`` called with mixed parameters produces
-implicit conversion sequences that are { ExactMatch, FloatingIntegral }  and {
+```c++
+cbuffer CB {
+  int I;
+  float X;
+  float4 V;
+}
+
+void twoParams(int, int);
+void twoParams(float, float);
+void threeParams(float, float, float);
+void threeParams(float4, float4, float4);
+
+export void call() {
+  twoParams(I, X); // DXC: resolves twoParams(int, int).
+                   // Clang: Fails to resolve ambiguous conversions.
+
+  threeParams(X, V, V); // DXC: resolves threeParams(float4, float4, float4).
+                        // Clang: Fails to resolve ambiguous conversions.
+}
+```
+
+For the examples above since `twoParams` called with mixed parameters produces
+implicit conversion sequences that are { ExactMatch, FloatingIntegral } and {
 FloatingIntegral, ExactMatch }. In both cases an argument has a worse conversion
 in the other sequence, so the overload is ambiguous.
 
-In the ``threeParams`` example the sequences are { ExactMatch, VectorTruncation,
+In the `threeParams` example the sequences are { ExactMatch, VectorTruncation,
 VectorTruncation } or { VectorSplat, ExactMatch, ExactMatch }, again in both
 cases at least one parameter has a worse conversion in the other sequence, so
 the overload is ambiguous.
 
-.. note::
-
-  The behavior of DXC documented below is undocumented so this is gleaned from
-  observation and a bit of reading the source.
+:::{note}
+The behavior of DXC documented below is undocumented so this is gleaned from
+observation and a bit of reading the source.
+:::
 
 DXC's approach for determining the best overload produces an integer score value
 for each implicit conversion sequence for each argument expression. Scores for
 casts are based on a bitmask construction that is complicated to reverse
 engineer. It seems that:
 
-* Exact match is 0
-* Dimension increase is 1
-* Promotion is 2
-* Integral -> Float conversion is 4
-* Float -> Integral conversion is 8
-* Cast is 16
+- Exact match is 0
+- Dimension increase is 1
+- Promotion is 2
+- Integral -> Float conversion is 4
+- Float -> Integral conversion is 8
+- Cast is 16
 
 The masks are or'd against each other to produce a score for the cast.
 
@@ -216,3 +208,4 @@ The scores of each conversion sequence are then summed to generate a score for
 the overload candidate. The overload candidate with the lowest score is the best
 candidate. If more than one overload are matched for the lowest score the call
 is ambiguous.
+
diff --git a/clang/docs/HLSL/FunctionCalls.md b/clang/docs/HLSL/FunctionCalls.md
index ea6dc2ad8a4df..045a305ed9cc8 100644
--- a/clang/docs/HLSL/FunctionCalls.md
+++ b/clang/docs/HLSL/FunctionCalls.md
@@ -1,12 +1,10 @@
-===================
-HLSL Function Calls
-===================
+# HLSL Function Calls
 
-.. contents::
-   :local:
+```{contents}
+:local: true
+```
 
-Introduction
-============
+## Introduction
 
 This document describes the design and implementation of HLSL's function call
 semantics in Clang. This includes details related to argument conversion and
@@ -14,23 +12,22 @@ parameter lifetimes.
 
 This document does not seek to serve as official documentation for HLSL's
 call semantics, but does provide an overview to assist a reader. The
-authoritative documentation for HLSL's language semantics is the `draft language
-specification <https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf>`_.
+authoritative documentation for HLSL's language semantics is the [draft language
+specification](https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf).
 
-Argument Semantics
-==================
+## Argument Semantics
 
 In HLSL, all function arguments are passed by value in and out of functions.
-HLSL has 3 keywords which denote the parameter semantics (``in``, ``out`` and
-``inout``). In a function declaration a parameter may be annotated any of the
+HLSL has 3 keywords which denote the parameter semantics (`in`, `out` and
+`inout`). In a function declaration a parameter may be annotated any of the
 following ways:
 
-#. <no parameter annotation> - denotes input
-#. ``in`` - denotes input
-#. ``out`` - denotes output
-#. ``in out`` - denotes input and output
-#. ``out in`` - denotes input and output
-#. ``inout`` - denotes input and output
+1. \<no parameter annotation> - denotes input
+2. `in` - denotes input
+3. `out` - denotes output
+4. `in out` - denotes input and output
+5. `out in` - denotes input and output
+6. `inout` - denotes input and output
 
 Parameters that are exclusively input behave like C/C++ parameters that are
 passed by value.
@@ -41,12 +38,12 @@ output-only parameters, the temporary is uninitialized when passed (if the
 parameter is not explicitly initialized inside the function an undefined value
 is stored back to the argument expression). For parameters that are both input
 and output, the temporary is initialized from the lvalue argument expression
-through implicit  or explicit casting from the lvalue argument type to the
+through implicit or explicit casting from the lvalue argument type to the
 parameter type.
 
 On return of the function, the values of any parameter temporaries are written
 back to the argument expression through an inverted conversion sequence (if an
-``out`` parameter was not initialized in the function, the uninitialized value
+`out` parameter was not initialized in the function, the uninitialized value
 may be written back).
 
 Parameters of constant-sized array type are also passed with value semantics.
@@ -56,106 +53,102 @@ temporaries go through array-to-pointer decay when initializing parameters.
 Implementations are allowed to avoid unnecessary temporaries, and HLSL's strict
 no-alias rules can enable some trivial optimizations.
 
-Array Temporaries
------------------
+### Array Temporaries
 
 Given the following example:
 
-.. code-block:: c++
+```c++
+void fn(float a[4]) {
+  a[0] = a[1] + a[2] + a[3];
+}
 
-  void fn(float a[4]) {
-    a[0] = a[1] + a[2] + a[3];
-  }
-
-  float4 main() : SV_Target {
-    float arr[4] = {1, 1, 1, 1};
-    fn(arr);
-    return float4(arr[0], arr[1], arr[2], arr[3]);
-  }
+float4 main() : SV_Target {
+  float arr[4] = {1, 1, 1, 1};
+  fn(arr);
+  return float4(arr[0], arr[1], arr[2], arr[3]);
+}
+```
 
 In C or C++, the array parameter decays to a pointer, so after the call to
-``fn``, the value of ``arr[0]`` is ``3``. In HLSL, the array is passed by value,
-so modifications inside ``fn`` do not propagate out.
-
-.. note::
-
-  DXC may pass unsized arrays directly as decayed pointers, which is an
-  unfortunate behavior divergence.
+`fn`, the value of `arr[0]` is `3`. In HLSL, the array is passed by value,
+so modifications inside `fn` do not propagate out.
 
-Out Parameter Temporaries
--------------------------
+:::{note}
+DXC may pass unsized arrays directly as decayed pointers, which is an
+unfortunate behavior divergence.
+:::
 
-.. code-block:: c++
+### Out Parameter Temporaries
 
-  void Init(inout int X, inout int Y) {
-    Y = 2;
-    X = 1;
-  }
+```c++
+void Init(inout int X, inout int Y) {
+  Y = 2;
+  X = 1;
+}
 
-  void main() {
-    int V;
-    Init(V, V); // MSVC (or clang-cl) V == 2, Clang V == 1
-  }
+void main() {
+  int V;
+  Init(V, V); // MSVC (or clang-cl) V == 2, Clang V == 1
+}
+```
 
-In the above example the ``Init`` function's behavior depends on the C++
+In the above example the `Init` function's behavior depends on the C++
 implementation. C++ does not define the order in which parameters are
 initialized or destroyed. In MSVC and Clang's MSVC compatibility mode, arguments
-are emitted right-to-left and destroyed left-to-right. This means that  the
-parameter initialization and destruction occurs in the order: {``Y``, ``X``,
-``~X``, ``~Y``}. This causes the write-back of the value of ``Y`` to occur last,
-so the resulting value of ``V`` is ``2``. In the Itanium C++ ABI, the  parameter
+are emitted right-to-left and destroyed left-to-right. This means that the
+parameter initialization and destruction occurs in the order: {`Y`, `X`,
+`~X`, `~Y`}. This causes the write-back of the value of `Y` to occur last,
+so the resulting value of `V` is `2`. In the Itanium C++ ABI, the parameter
 ordering is reversed, so the initialization and destruction occurs in the order:
-{``X``, ``Y``, ``~Y``, ``X``}. This causes the write-back of the value ``X`` to
-occur last, resulting in the value of ``V`` being set to ``1``.
+{`X`, `Y`, `~Y`, `X`}. This causes the write-back of the value `X` to
+occur last, resulting in the value of `V` being set to `1`.
 
-.. code-block:: c++
+```c++
+void Trunc(inout int3 V) { }
 
-  void Trunc(inout int3 V) { }
 
+void main() {
+  float3 F = {1.5, 2.6, 3.3};
+  Trunc(F); // F == {1.0, 2.0, 3.0}
+}
+```
 
-  void main() {
-    float3 F = {1.5, 2.6, 3.3};
-    Trunc(F); // F == {1.0, 2.0, 3.0}
-  }
-
-In the above example, the argument expression ``F`` undergoes element-wise
+In the above example, the argument expression `F` undergoes element-wise
 conversion from a float vector to an integer vector to create a temporary
-``int3``. On expiration the temporary undergoes elementwise conversion back to
-the floating point vector type ``float3``. This results in an implicit
+`int3`. On expiration the temporary undergoes elementwise conversion back to
+the floating point vector type `float3`. This results in an implicit
 element-wise conversion of the vector even if the value is unused in the
 function (effectively truncating the floating point values).
 
+```c++
+void UB(out int X) {}
 
-.. code-block:: c++
-
-  void UB(out int X) {}
+void main() {
+  int X = 7;
+  UB(X); // X is undefined!
+}
+```
 
-  void main() {
-    int X = 7;
-    UB(X); // X is undefined!
-  }
-
-In this example an initialized value is passed to an ``out`` parameter.
-Parameters marked ``out`` are not initialized by the argument expression or
+In this example an initialized value is passed to an `out` parameter.
+Parameters marked `out` are not initialized by the argument expression or
 implicitly by the function. They must be explicitly initialized. In this case
 the argument is not initialized in the function so the temporary is still
 uninitialized when it is copied back to the argument expression. This is
 undefined behavior in HLSL, and any use of the argument after the call is a use
 of an undefined value which may be illegal in the target (DXIL programs with
-used or potentially used ``undef`` or ``poison`` values fail validation).
-
-Clang Implementation
-====================
+used or potentially used `undef` or `poison` values fail validation).
 
-.. note::
+## Clang Implementation
 
-  The implementation described here is a proposal. It has not yet been fully
-  implemented, so the current state of Clang's sources may not reflect this
-  design. A prototype implementation was built on DXC which is Clang-3.7 based.
-  The prototype can be found
-  `here <https://github.com/microsoft/DirectXShaderCompiler/pull/5249>`_. A lot
-  of the changes in the prototype implementation are restoring Clang-3.7 code
-  that was previously modified to its original state.
+:::{note}
+The implementation described here is a proposal. It has not yet been fully
+implemented, so the current state of Clang's sources may not reflect this
+design. A prototype implementation was built on DXC which is Clang-3.7 based.
+The prototype can be found
+[here](https://github.com/microsoft/DirectXShaderCompiler/pull/5249). A lot
+of the changes in the prototype implementation are restoring Clang-3.7 code
+that was previously modified to its original state.
+:::
 
 The implementation in clang adds a new non-decaying array type, a new AST node
 to represent output parameters, and minor extensions to Clang's existing support
@@ -163,185 +156,184 @@ for Objective-C write-back arguments. The goal of this design is to capture the
 semantic details of HLSL function calls in the AST, and minimize the amount of
 magic that needs to occur during IR generation.
 
-Array Temporaries
------------------
+### Array Temporaries
 
-The new ``ArrayParameterType`` is a sub-class of ``ConstantArrayType``
+The new `ArrayParameterType` is a sub-class of `ConstantArrayType`
 inheriting all the behaviors and methods of the parent except that it does not
 decay to a pointer during overload resolution or template type deduction.
 
-An argument of ``ConstantArrayType`` can be implicitly converted to an
-equivalent non-decayed ``ArrayParameterType`` if the underlying canonical
-``ConstantArrayType`` is the same. This occurs during overload resolution
+An argument of `ConstantArrayType` can be implicitly converted to an
+equivalent non-decayed `ArrayParameterType` if the underlying canonical
+`ConstantArrayType` is the same. This occurs during overload resolution
 instead of array to pointer decay.
 
-.. code-block:: c++
+```c++
+void SizedArray(float a[4]);
+void UnsizedArray(float a[]);
 
-  void SizedArray(float a[4]);
-  void UnsizedArray(float a[]);
-
-  void main() {
-    float arr[4] = {1, 1, 1, 1};
-    SizedArray(arr);
-    UnsizedArray(arr);
-  }
+void main() {
+  float arr[4] = {1, 1, 1, 1};
+  SizedArray(arr);
+  UnsizedArray(arr);
+}
+```
 
 In the example above, the following AST is generated for the call to
-``SizedArray``:
-
-.. code-block:: text
+`SizedArray`:
 
-  CallExpr 'void'
-  |-ImplicitCastExpr 'void (*)(float [4])' <FunctionToPointerDecay>
-  | `-DeclRefExpr 'void (float [4])' lvalue Function 'SizedArray' 'void (float [4])'
-  `-ImplicitCastExpr 'float [4]' <HLSLArrayRValue>
-    `-DeclRefExpr 'float [4]' lvalue Var 'arr' 'float [4]'
+```text
+CallExpr 'void'
+|-ImplicitCastExpr 'void (*)(float [4])' <FunctionToPointerDecay>
+| `-DeclRefExpr 'void (float [4])' lvalue Function 'SizedArray' 'void (float [4])'
+`-ImplicitCastExpr 'float [4]' <HLSLArrayRValue>
+  `-DeclRefExpr 'float [4]' lvalue Var 'arr' 'float [4]'
+```
 
 In the example above, the following AST is generated for the call to
-``UnsizedArray``:
+`UnsizedArray`:
 
-.. code-block:: text
-
-  CallExpr 'void'
-  |-ImplicitCastExpr 'void (*)(float [])' <FunctionToPointerDecay>
-  | `-DeclRefExpr 'void (float [])' lvalue Function 'UnsizedArray' 'void (float [])'
-  `-ImplicitCastExpr 'float [4]' <HLSLArrayRValue>
-    `-DeclRefExpr 'float [4]' lvalue Var 'arr' 'float [4]'
+```text
+CallExpr 'void'
+|-ImplicitCastExpr 'void (*)(float [])' <FunctionToPointerDecay>
+| `-DeclRefExpr 'void (float [])' lvalue Function 'UnsizedArray' 'void (float [])'
+`-ImplicitCastExpr 'float [4]' <HLSLArrayRValue>
+  `-DeclRefExpr 'float [4]' lvalue Var 'arr' 'float [4]'
+```
 
 In both of these cases the argument expression is of known array size so we can
 initialize an appropriately sized temporary.
 
 It is illegal in HLSL to convert an unsized array to a sized array:
 
-.. code-block:: c++
-
-  void SizedArray(float a[4]);
-  void UnsizedArray(float a[]) {
-    SizedArray(a); // Cannot convert float[] to float[4]
-  }
+```c++
+void SizedArray(float a[4]);
+void UnsizedArray(float a[]) {
+  SizedArray(a); // Cannot convert float[] to float[4]
+}
+```
 
 When converting a sized array to an unsized array, an array temporary can also
 be inserted. Given the following code:
 
-.. code-block:: c++
-
-  void UnsizedArray(float a[]);
-  void SizedArray(float a[4]) {
-    UnsizedArray(a);
-  }
+```c++
+void UnsizedArray(float a[]);
+void SizedArray(float a[4]) {
+  UnsizedArray(a);
+}
+```
 
 An expected AST should be something like:
 
-.. code-block:: text
+```text
+CallExpr 'void'
+|-ImplicitCastExpr 'void (*)(float [])' <FunctionToPointerDecay>
+| `-DeclRefExpr 'void (float [])' lvalue Function 'UnsizedArray' 'void (float [])'
+`-ImplicitCastExpr 'float [4]' <HLSLArrayRValue>
+  `-DeclRefExpr 'float [4]' lvalue Var 'arr' 'float [4]'
+```
 
-  CallExpr 'void'
-  |-ImplicitCastExpr 'void (*)(float [])' <FunctionToPointerDecay>
-  | `-DeclRefExpr 'void (float [])' lvalue Function 'UnsizedArray' 'void (float [])'
-  `-ImplicitCastExpr 'float [4]' <HLSLArrayRValue>
-    `-DeclRefExpr 'float [4]' lvalue Var 'arr' 'float [4]'
-
-Out Parameter Temporaries
--------------------------
+### Out Parameter Temporaries
 
 Output parameters are defined in HLSL as *casting expiring values* (cx-values),
 which is a term made up for HLSL. A cx-value is a temporary value which may be
 the result of a cast, and stores its value back to an lvalue when the value
 expires.
 
-To represent this concept in Clang we introduce a new ``HLSLOutArgExpr``. An
-``HLSLOutArgExpr`` has three sub-expressions:
+To represent this concept in Clang we introduce a new `HLSLOutArgExpr`. An
+`HLSLOutArgExpr` has three sub-expressions:
 
-* An OpaqueValueExpr of the argument lvalue expression.
-* An OpaqueValueExpr of the copy-initialized parameter temporary.
-* A BinaryOpExpr assigning the first with the value of the second.
+- An OpaqueValueExpr of the argument lvalue expression.
+- An OpaqueValueExpr of the copy-initialized parameter temporary.
+- A BinaryOpExpr assigning the first with the value of the second.
 
 Given this example:
 
-.. code-block:: c++
-
-  void Init(inout int X) {
-    X = 1;
-  }
+```c++
+void Init(inout int X) {
+  X = 1;
+}
 
-  void main() {
-    int V;
-    Init(V);
-  }
+void main() {
+  int V;
+  Init(V);
+}
+```
 
 The expected AST formulation for this code would be something like the example
 below. Due to the nature of OpaqueValueExpr nodes, the nodes repeat in the AST
-dump. The fake addresses ``0xSOURCE`` and ``0xTEMPORARY`` denote the source
+dump. The fake addresses `0xSOURCE` and `0xTEMPORARY` denote the source
 lvalue and argument temporary lvalue expressions.
 
-.. code-block:: text
-
-  CallExpr 'void'
-  |-ImplicitCastExpr 'void (*)(int &)' <FunctionToPointerDecay>
-  | `-DeclRefExpr 'void (int &)' lvalue Function  'Init' 'void (int &)'
-  `-HLSLOutArgExpr <col:10> 'int' lvalue inout
+```text
+CallExpr 'void'
+|-ImplicitCastExpr 'void (*)(int &)' <FunctionToPointerDecay>
+| `-DeclRefExpr 'void (int &)' lvalue Function  'Init' 'void (int &)'
+`-HLSLOutArgExpr <col:10> 'int' lvalue inout
+  |-OpaqueValueExpr 0xSOURCE <col:10> 'int' lvalue
+  | `-DeclRefExpr <col:10> 'int' lvalue Var 'V' 'int'
+  |-OpaqueValueExpr 0xTEMPORARY <col:10> 'int' lvalue
+  | `-ImplicitCastExpr <col:10> 'int' <LValueToRValue>
+  |   `-OpaqueValueExpr 0xSOURCE <col:10> 'int' lvalue
+  |     `-DeclRefExpr <col:10> 'int' lvalue Var 'V' 'int'
+  `-BinaryOperator <col:10> 'int' lvalue '='
     |-OpaqueValueExpr 0xSOURCE <col:10> 'int' lvalue
     | `-DeclRefExpr <col:10> 'int' lvalue Var 'V' 'int'
-    |-OpaqueValueExpr 0xTEMPORARY <col:10> 'int' lvalue
-    | `-ImplicitCastExpr <col:10> 'int' <LValueToRValue>
-    |   `-OpaqueValueExpr 0xSOURCE <col:10> 'int' lvalue
-    |     `-DeclRefExpr <col:10> 'int' lvalue Var 'V' 'int'
-    `-BinaryOperator <col:10> 'int' lvalue '='
-      |-OpaqueValueExpr 0xSOURCE <col:10> 'int' lvalue
-      | `-DeclRefExpr <col:10> 'int' lvalue Var 'V' 'int'
-      `-ImplicitCastExpr <col:10> 'int' <LValueToRValue>
-        `-OpaqueValueExpr 0xTEMPORARY <col:10> 'int' lvalue
-          `-ImplicitCastExpr <col:10> 'int' <LValueToRValue>
-            `-OpaqueValueExpr 0xSOURCE <col:10> 'int' lvalue
-              `-DeclRefExpr <col:10> 'int' lvalue Var 'V' 'int'
-
-The ``HLSLOutArgExpr`` captures that the value is ``inout`` vs ``out`` to
+    `-ImplicitCastExpr <col:10> 'int' <LValueToRValue>
+      `-OpaqueValueExpr 0xTEMPORARY <col:10> 'int' lvalue
+        `-ImplicitCastExpr <col:10> 'int' <LValueToRValue>
+          `-OpaqueValueExpr 0xSOURCE <col:10> 'int' lvalue
+            `-DeclRefExpr <col:10> 'int' lvalue Var 'V' 'int'
+```
+
+The `HLSLOutArgExpr` captures that the value is `inout` vs `out` to
 denote whether or not the temporary is initialized from the sub-expression.
 
 The example below demonstrates argument casting:
 
-.. code-block:: c++
-
-  void Trunc(inout int3 V) { }
+```c++
+void Trunc(inout int3 V) { }
 
 
-  void main() {
-    float3 F = {1.5, 2.6, 3.3};
-    Trunc(F);
-  }
+void main() {
+  float3 F = {1.5, 2.6, 3.3};
+  Trunc(F);
+}
+```
 
-For this case the ``HLSLOutArgExpr`` will have sub-expressions to record both
+For this case the `HLSLOutArgExpr` will have sub-expressions to record both
 casting expression sequences for the initialization and write back:
 
-.. code-block:: text
-
-  -CallExpr 'void'
-    |-ImplicitCastExpr 'void (*)(int3 &)' <FunctionToPointerDecay>
-    | `-DeclRefExpr 'void (int3 &)' lvalue Function 'inc_i32' 'void (int3 &)'
-    `-HLSLOutArgExpr <col:11> 'int3':'vector<int, 3>' lvalue inout
+```text
+-CallExpr 'void'
+  |-ImplicitCastExpr 'void (*)(int3 &)' <FunctionToPointerDecay>
+  | `-DeclRefExpr 'void (int3 &)' lvalue Function 'inc_i32' 'void (int3 &)'
+  `-HLSLOutArgExpr <col:11> 'int3':'vector<int, 3>' lvalue inout
+    |-OpaqueValueExpr 0xSOURCE <col:11> 'float3':'vector<float, 3>' lvalue
+    | `-DeclRefExpr <col:11> 'float3':'vector<float, 3>' lvalue Var 'F' 'float3':'vector<float, 3>'
+    |-OpaqueValueExpr 0xTEMPORARY <col:11> 'int3':'vector<int, 3>' lvalue
+    | `-ImplicitCastExpr <col:11> 'vector<int, 3>' <FloatingToIntegral>
+    |   `-ImplicitCastExpr <col:11> 'float3':'vector<float, 3>' <LValueToRValue>
+    |     `-OpaqueValueExpr 0xSOURCE <col:11> 'float3':'vector<float, 3>' lvalue
+    |       `-DeclRefExpr <col:11> 'float3':'vector<float, 3>' lvalue Var 'F' 'float3':'vector<float, 3>'
+    `-BinaryOperator <col:11> 'float3':'vector<float, 3>' lvalue '='
       |-OpaqueValueExpr 0xSOURCE <col:11> 'float3':'vector<float, 3>' lvalue
       | `-DeclRefExpr <col:11> 'float3':'vector<float, 3>' lvalue Var 'F' 'float3':'vector<float, 3>'
-      |-OpaqueValueExpr 0xTEMPORARY <col:11> 'int3':'vector<int, 3>' lvalue
-      | `-ImplicitCastExpr <col:11> 'vector<int, 3>' <FloatingToIntegral>
-      |   `-ImplicitCastExpr <col:11> 'float3':'vector<float, 3>' <LValueToRValue>
-      |     `-OpaqueValueExpr 0xSOURCE <col:11> 'float3':'vector<float, 3>' lvalue
-      |       `-DeclRefExpr <col:11> 'float3':'vector<float, 3>' lvalue Var 'F' 'float3':'vector<float, 3>'
-      `-BinaryOperator <col:11> 'float3':'vector<float, 3>' lvalue '='
-        |-OpaqueValueExpr 0xSOURCE <col:11> 'float3':'vector<float, 3>' lvalue
-        | `-DeclRefExpr <col:11> 'float3':'vector<float, 3>' lvalue Var 'F' 'float3':'vector<float, 3>'
-        `-ImplicitCastExpr <col:11> 'vector<float, 3>' <IntegralToFloating>
-          `-ImplicitCastExpr <col:11> 'int3':'vector<int, 3>' <LValueToRValue>
-            `-OpaqueValueExpr 0xTEMPORARY <col:11> 'int3':'vector<int, 3>' lvalue
-              `-ImplicitCastExpr <col:11> 'vector<int, 3>' <FloatingToIntegral>
-                `-ImplicitCastExpr <col:11> 'float3':'vector<float, 3>' <LValueToRValue>
-                  `-OpaqueValueExpr 0xSOURCE <col:11> 'float3':'vector<float, 3>' lvalue
-                    `-DeclRefExpr <col:11> 'float3':'vector<float, 3>' lvalue Var 'F' 'float3':'vector<float, 3>'
+      `-ImplicitCastExpr <col:11> 'vector<float, 3>' <IntegralToFloating>
+        `-ImplicitCastExpr <col:11> 'int3':'vector<int, 3>' <LValueToRValue>
+          `-OpaqueValueExpr 0xTEMPORARY <col:11> 'int3':'vector<int, 3>' lvalue
+            `-ImplicitCastExpr <col:11> 'vector<int, 3>' <FloatingToIntegral>
+              `-ImplicitCastExpr <col:11> 'float3':'vector<float, 3>' <LValueToRValue>
+                `-OpaqueValueExpr 0xSOURCE <col:11> 'float3':'vector<float, 3>' lvalue
+                  `-DeclRefExpr <col:11> 'float3':'vector<float, 3>' lvalue Var 'F' 'float3':'vector<float, 3>'
+```
 
 The AST representation is the same whether casting is required or not, which
 simplifies the code generation. IR generation does the following:
 
-* Emit the argument lvalue expression.
-* Initialize the argument:
-  * For ``inout`` arguments, emit the copy-initialization expression.
-  * For ``out`` arguments, emit an uninitialized temporary.
-* Emit the call
-* Emit the write-back BinaryOperator expression.
+- Emit the argument lvalue expression.
+- Initialize the argument:
+  \* For `inout` arguments, emit the copy-initialization expression.
+  \* For `out` arguments, emit an uninitialized temporary.
+- Emit the call
+- Emit the write-back BinaryOperator expression.
+
diff --git a/clang/docs/HLSL/HLSLIRReference.md b/clang/docs/HLSL/HLSLIRReference.md
index c0033946a6ec8..1e8c8c1013819 100644
--- a/clang/docs/HLSL/HLSLIRReference.md
+++ b/clang/docs/HLSL/HLSLIRReference.md
@@ -1,22 +1,19 @@
-=================
-HLSL IR Reference
-=================
+# HLSL IR Reference
 
-.. contents::
-   :local:
+```{contents}
+:local: true
+```
 
-Introduction
-============
+## Introduction
 
 The goal of this document is to provide a reference for all the special purpose
 IR metadata and attributes used by the HLSL code generation path.
 
-Function Attributes
-===================
+## Function Attributes
 
-``hlsl.shader``
----------------
+### `hlsl.shader`
 
-The ``hlsl.shader`` function attribute is a string attribute applied to entry
+The `hlsl.shader` function attribute is a string attribute applied to entry
 functions. The value is the string representation of the shader stage (i.e.
-``compute``, ``pixel``, etc).
+`compute`, `pixel`, etc).
+
diff --git a/clang/docs/HLSL/HLSLSupport.md b/clang/docs/HLSL/HLSLSupport.md
index 2d309ddff2f36..d9f3cdab458c9 100644
--- a/clang/docs/HLSL/HLSLSupport.md
+++ b/clang/docs/HLSL/HLSLSupport.md
@@ -1,37 +1,31 @@
-============
-HLSL Support
-============
+# HLSL Support
 
-.. contents::
-   :local:
+```{contents}
+:local: true
+```
 
-Introduction
-============
+## Introduction
 
 HLSL Support is under active development in the Clang codebase. This document
 describes the high level goals of the project, the guiding principles, as well
 as some idiosyncrasies of the HLSL language and how we intend to support them in
 Clang.
 
-Project Goals
-=============
+## Project Goals
 
 The long term goal of this project is to enable Clang to function as a
-replacement for the `DirectXShaderCompiler (DXC)
-<https://github.com/microsoft/DirectXShaderCompiler/>`_ in all its supported
+replacement for the [DirectXShaderCompiler (DXC)](https://github.com/microsoft/DirectXShaderCompiler/) in all its supported
 use cases. Accomplishing that goal will require Clang to be able to process most
 existing HLSL programs with a high degree of source compatibility.
 
-Non-Goals
----------
+### Non-Goals
 
 HLSL ASTs do not need to be compatible between DXC and Clang. We do not expect
 identical code generation or that features will resemble DXC's implementation or
 architecture. In fact, we explicitly expect to deviate from DXC's implementation
 in key ways.
 
-Guiding Principles
-==================
+## Guiding Principles
 
 This document lacks details for architectural decisions that are not yet
 finalized. Our top priorities are quality, maintainability, and flexibility. In
@@ -40,8 +34,7 @@ coverage, and we will engineer our solutions with long term maintenance in mind.
 We are also working to limit modifications to the Clang C++ code paths and
 share as much functionality as possible.
 
-Architectural Direction
-=======================
+## Architectural Direction
 
 HLSL support in Clang is expressed as C++ minus unsupported C and C++ features.
 This is different from how other Clang languages are implemented. Most languages
@@ -55,7 +48,7 @@ the reference implementation.
 The HLSL effort prioritizes following similar patterns for other languages,
 drivers, runtimes and targets. Specifically, We will maintain separation between
 HSLS-specific code and the rest of Clang as much as possible following patterns
-in use in Clang code today (i.e. ParseHLSL.cpp, SemaHLSL.cpp, CGHLSL*.cpp...).
+in use in Clang code today (i.e. ParseHLSL.cpp, SemaHLSL.cpp, CGHLSL\*.cpp...).
 We will use inline checks on language options where the code is simple and
 isolated, and prefer HLSL-specific implementation files for any code of
 reasonable complexity.
@@ -64,42 +57,38 @@ In places where the HLSL language is in conflict with C and C++, we will seek to
 make minimally invasive changes guarded under the HLSL language options. We will
 seek to make HLSL language support as minimal a maintenance burden as possible.
 
-DXC Driver
-----------
+### DXC Driver
 
 A DXC driver mode will provide command-line compatibility with DXC, supporting
 DXC's options and flags. The DXC driver is HLSL-specific and will create an
 HLSLToolchain which will provide the basis to support targeting both DirectX and
 Vulkan.
 
-Parser
-------
+### Parser
 
 Following the examples of other parser extensions HLSL will add a ParseHLSL.cpp
 file to contain the implementations of HLSL-specific extensions to the Clang
 parser. The HLSL grammar shares most of its structure with C and C++, so we will
 use the existing C/C++ parsing code paths.
 
-Sema
-----
+### Sema
 
-HLSL's Sema implementation will also provide an ``ExternalSemaSource``. In DXC,
-an ``ExternalSemaSource`` is used to provide definitions for HLSL built-in data
+HLSL's Sema implementation will also provide an `ExternalSemaSource`. In DXC,
+an `ExternalSemaSource` is used to provide definitions for HLSL built-in data
 types and built-in templates. Clang is already designed to allow an attached
-``ExternalSemaSource`` to lazily complete data types, which is a **huge**
+`ExternalSemaSource` to lazily complete data types, which is a **huge**
 performance win for HLSL.
 
-If precompiled headers are used when compiling HLSL, the ``ExternalSemaSource``
-will be a ``MultiplexExternalSemaSource`` which includes both the ``ASTReader``
+If precompiled headers are used when compiling HLSL, the `ExternalSemaSource`
+will be a `MultiplexExternalSemaSource` which includes both the `ASTReader`
 and -. For Built-in declarations that are already
-completed in the serialized AST, the ``HLSLExternalSemaSource`` will reuse the
+completed in the serialized AST, the `HLSLExternalSemaSource` will reuse the
 existing declarations and not introduce new declarations. If the built-in types
-are not completed in the serialized AST, the ``HLSLExternalSemaSource`` will
+are not completed in the serialized AST, the `HLSLExternalSemaSource` will
 create new declarations and connect the de-serialized decls as the previous
 declaration.
 
-CodeGen
--------
+### CodeGen
 
 Like OpenCL, HLSL relies on capturing a lot of information into IR metadata.
 *hand wave* *hand wave* *hand wave* As a design principle here we want our IR to
@@ -114,33 +103,32 @@ not re-targetable, we want to share the Clang CodeGen implementation for HLSL
 with other GPU graphics targets like SPIR-V and possibly other GPU and even CPU
 targets.
 
-hlsl.h
-------
+### hlsl.h
 
 HLSL has a library of standalone functions. This is similar to OpenCL and CUDA,
 and is analogous to C's standard library. The implementation approach for the
 HLSL library functionality draws from patterns in use by OpenCL and other Clang
 resource headers. All of the clang resource headers are part of the
-``ClangHeaders`` component found in the source tree under
-`clang/lib/Headers <https://github.com/llvm/llvm-project/tree/main/clang/lib/Headers>`_.
+`ClangHeaders` component found in the source tree under
+[clang/lib/Headers](https://github.com/llvm/llvm-project/tree/main/clang/lib/Headers).
 
-.. note::
-
-   HLSL's complex data types are not defined in HLSL's header because many of
-   the semantics of those data types cannot be expressed in HLSL due to missing
-   language features. Data types that can't be expressed in HLSL are defined in
-   code in the ``HLSLExternalSemaSource``.
+:::{note}
+HLSL's complex data types are not defined in HLSL's header because many of
+the semantics of those data types cannot be expressed in HLSL due to missing
+language features. Data types that can't be expressed in HLSL are defined in
+code in the `HLSLExternalSemaSource`.
+:::
 
 Similar to OpenCL, the HLSL library functionality is implicitly declared in
 translation units without needing to include a header to provide declarations.
-In Clang this is handled by making ``hlsl.h`` an implicitly included header
+In Clang this is handled by making `hlsl.h` an implicitly included header
 distributed as part of the Clang resource directory.
 
 Similar to OpenCL, HLSL's implicit header will explicitly declare all overloads,
-and each overload will map to a corresponding ``__builtin*`` compiler intrinsic
+and each overload will map to a corresponding `__builtin*` compiler intrinsic
 that is handled in ClangCodeGen. CUDA uses a similar pattern although many CUDA
 functions have full definitions in the included headers which in turn call
-corresponding ``__builtin*`` compiler intrinsics. By not having bodies HLSL
+corresponding `__builtin*` compiler intrinsics. By not having bodies HLSL
 avoids the need for the inliner to clean up and inline large numbers of small
 library functions.
 
@@ -149,11 +137,11 @@ with how the AVX vector header is implemented.
 
 Concerns have been expressed that this approach may result in slower compile
 times than the approach DXC uses where library functions are treated more like
-Clang ``__builtin*`` intrinsics. No real world use cases have been identified
+Clang `__builtin*` intrinsics. No real world use cases have been identified
 where parsing is a significant compile-time overhead, but the HLSL implicit
 headers can be compiled into a module for performance if needed.
 
-Further, by treating these as functions rather than ``__builtin*`` compiler
+Further, by treating these as functions rather than `__builtin*` compiler
 intrinsics, the language behaviors are more consistent and aligned with user
 expectation because normal overload resolution rules and implicit conversions
 apply as expected.
@@ -162,12 +150,10 @@ It is a feature of this design that clangd-powered "go to declaration" for
 library functions will jump to a valid header declaration and all overloads will
 be user readable.
 
-HLSL Language
-=============
+## HLSL Language
 
 The HLSL language is insufficiently documented, and not formally specified.
-Documentation is available on `Microsoft's website
-<https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl>`_.
+Documentation is available on [Microsoft's website](https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl).
 The language syntax is similar enough to C and C++ that carefully written C and
 C++ code is valid HLSL. HLSL has some key differences from C & C++ which we will
 need to handle in Clang.
@@ -176,8 +162,7 @@ HLSL is not a conforming or valid extension or superset of C or C++. The
 language has key incompatibilities with C and C++, both syntactically and
 semantically.
 
-An Aside on GPU Languages
--------------------------
+### An Aside on GPU Languages
 
 Due to HLSL being a GPU targeted language HLSL is a Single Program Multiple Data
 (SPMD) language relying on the implicit parallelism provided by GPU hardware.
@@ -190,26 +175,23 @@ example, register spilling is often excessively expensive on GPUs, so HLSL
 requires all functions to be inlined during code generation, and does not
 support a runtime calling convention.
 
-Pointers & References
----------------------
+### Pointers & References
 
 HLSL does not support referring to values by address. Semantically all variables
 are value-types and behave as such. HLSL disallows the pointer dereference
-operators (unary ``*``, and ``->``), as well as the address of operator (unary
+operators (unary `*`, and `->`), as well as the address of operator (unary
 &). While HLSL disallows pointers and references in the syntax, HLSL does use
 reference types in the AST, and we intend to use pointer decay in the AST in
 the Clang implementation.
 
-HLSL ``this`` Keyword
----------------------
+### HLSL `this` Keyword
 
 HLSL does support member functions, and (in HLSL 2021) limited operator
-overloading. With member function support, HLSL also has a ``this`` keyword. The
-``this`` keyword is an example of one of the places where HLSL relies on
-references in the AST, because ``this`` is a reference.
+overloading. With member function support, HLSL also has a `this` keyword. The
+`this` keyword is an example of one of the places where HLSL relies on
+references in the AST, because `this` is a reference.
 
-Bitshifts
----------
+### Bitshifts
 
 In deviation from C, HLSL bitshifts are defined to mask the shift count by the
 size of the type. In DXC, the semantics of LLVM IR were altered to accommodate
@@ -217,33 +199,30 @@ this, in Clang we intend to generate the mask explicitly in the IR. In cases
 where the shift value is constant, this will be constant folded appropriately,
 in other cases we can clean it up in the DXIL target.
 
-Non-short Circuiting Logical Operators
---------------------------------------
+### Non-short Circuiting Logical Operators
 
 In HLSL 2018 and earlier, HLSL supported logical operators (and the ternary
 operator) on vector types. This behavior required that operators not short
 circuit. The non-short circuiting behavior applies to all data types until HLSL
-2021. In HLSL 2021, logical and ternary operators do not support vector types
-instead builtin functions ``and``, ``or`` and ``select`` are available, and
+2021\. In HLSL 2021, logical and ternary operators do not support vector types
+instead builtin functions `and`, `or` and `select` are available, and
 operators short circuit matching C behavior.
 
-Precise Qualifier
------------------
+### Precise Qualifier
 
-HLSL has a ``precise`` qualifier that behaves unlike anything else in the C
+HLSL has a `precise` qualifier that behaves unlike anything else in the C
 language. The support for this qualifier in DXC is buggy, so our bar for
 compatibility is low.
 
-The ``precise`` qualifier applies in the inverse direction from normal
-qualifiers. Rather than signifying that the declaration containing ``precise``
+The `precise` qualifier applies in the inverse direction from normal
+qualifiers. Rather than signifying that the declaration containing `precise`
 qualifier be precise, it signifies that the operations contributing to the
-declaration's value be ``precise``. Additionally, ``precise`` is a misnomer:
-values attributed as ``precise`` comply with IEEE-754 floating point semantics,
+declaration's value be `precise`. Additionally, `precise` is a misnomer:
+values attributed as `precise` comply with IEEE-754 floating point semantics,
 and are prevented from optimizations which could decrease *or increase*
 precision.
 
-Differences in Templates
-------------------------
+### Differences in Templates
 
 HLSL uses templates to define builtin types and methods, but disallowed
 user-defined templates until HLSL 2021. HLSL also allows omitting empty template
@@ -251,20 +230,17 @@ parameter lists when all template parameters are defaulted. This is an ambiguous
 syntax in C++, but Clang detects the case and issues a diagnostic. This makes
 supporting the case in Clang minimally invasive.
 
-Vector Extensions
------------------
+### Vector Extensions
 
 HLSL uses the OpenCL vector extensions, and also provides C++-style constructors
 for vectors that are not supported by Clang.
 
-Standard Library
-----------------
+### Standard Library
 
 HLSL does not support the C or C++ standard libraries. Like OpenCL, HLSL
 describes its own library of built in types, complex data types, and functions.
 
-Unsupported C & C++ Features
-----------------------------
+### Unsupported C & C++ Features
 
 HLSL does not support all features of C and C++. In implementing HLSL in Clang
 use of some C and C++ features will produce diagnostics under HLSL, and others
@@ -275,23 +251,24 @@ must be diagnosed as errors.
 
 HLSL does not support the following C features:
 
-* Pointers
-* References
-* ``goto`` or labels
-* Variable Length Arrays
-* ``_Complex`` and ``_Imaginary``
-* C Threads or Atomics (or Obj-C blocks)
-* ``union`` types `(in progress for HLSL 202x) <https://github.com/microsoft/DirectXShaderCompiler/pull/4132>`_
-* Most features C11 and later
+- Pointers
+- References
+- `goto` or labels
+- Variable Length Arrays
+- `_Complex` and `_Imaginary`
+- C Threads or Atomics (or Obj-C blocks)
+- `union` types [(in progress for HLSL 202x)](https://github.com/microsoft/DirectXShaderCompiler/pull/4132)
+- Most features C11 and later
 
 HLSL does not support the following C++ features:
 
-* RTTI
-* Exceptions
-* Multiple inheritance
-* Access specifiers
-* Anonymous or inline namespaces
-* ``new`` & ``delete`` operators in all of their forms (array, placement, etc)
-* Constructors and destructors
-* Any use of the ``virtual`` keyword
-* Most features C++11 and later
+- RTTI
+- Exceptions
+- Multiple inheritance
+- Access specifiers
+- Anonymous or inline namespaces
+- `new` & `delete` operators in all of their forms (array, placement, etc)
+- Constructors and destructors
+- Any use of the `virtual` keyword
+- Most features C++11 and later
+
diff --git a/clang/docs/HLSL/ResourceTypes.md b/clang/docs/HLSL/ResourceTypes.md
index e2a2d86f1346a..a7c7e68f2a84f 100644
--- a/clang/docs/HLSL/ResourceTypes.md
+++ b/clang/docs/HLSL/ResourceTypes.md
@@ -1,54 +1,46 @@
-===================
-HLSL Resource Types
-===================
+# HLSL Resource Types
 
-.. contents::
-   :local:
+```{contents}
+:local: true
+```
 
-Introduction
-============
+## Introduction
 
 HLSL Resources are runtime-bound data that is provided as input, output or both
 to shader programs written in HLSL. These appear in HLSL source as instances of
-special classes like `RWByteAddressBuffer`_, `ConstantBuffer`_, `Texture3D`_,
-and `RasterizerOrderedTexture2D`_. They provide key user abstractions for
+special classes like [RWByteAddressBuffer][rwbyteaddressbuffer], [ConstantBuffer][constantbuffer], [Texture3D][texture3d],
+and [RasterizerOrderedTexture2D][rasterizerorderedtexture2d]. They provide key user abstractions for
 reading and writing resource data.
 
-.. _RWByteAddressBuffer: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-object-rwbyteaddressbuffer
-.. _ConstantBuffer: https://learn.microsoft.com/en-us/windows/win32/direct3d12/resource-binding-in-hlsl#constant-buffers
-.. _Texture3D: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-object-texture3d
-.. _RasterizerOrderedTexture2D: https://learn.microsoft.com/en-us/windows/win32/direct3d11/rasterizer-order-views
-
-Implementation Details
-======================
+## Implementation Details
 
 Clang's implementation of the HLSL resource types is designed to allow for a
 future version where the individual classes are implemented directly as HLSL in
 a library. However, this isn't possible today as they rely on some features,
 such as constructors, that are explicitly disallowed in HLSL user code. Because
-of this, these types are forward declared by the ``HLSLExternalSemaSource`` on
-initialization. They are then lazily completed when ``requiresCompleteType`` is
+of this, these types are forward declared by the `HLSLExternalSemaSource` on
+initialization. They are then lazily completed when `requiresCompleteType` is
 called later in Sema.
 
-A class is a resource if it contains a member of the ``__hlsl_resource_t``
+A class is a resource if it contains a member of the `__hlsl_resource_t`
 type, which represents a "intangible resource handle". This resource handle
 type is annotated with various attributes to describe what type of resource it
 is and what can be done with it.
 
-- ``hlsl::resource_class(C)``: Given ``C`` in ``"SRV"``, ``"UAV"``,
-  ``"CBuffer"``, or ``"Sampler"``, mark the resource as a shader resource view,
+- `hlsl::resource_class(C)`: Given `C` in `"SRV"`, `"UAV"`,
+  `"CBuffer"`, or `"Sampler"`, mark the resource as a shader resource view,
   unordered access view, constant buffer, or sampler, respectively.
-- ``hlsl::contained_type(T)``: Given a type ``T``, specify the type of objects
+- `hlsl::contained_type(T)`: Given a type `T`, specify the type of objects
   contained in the resource.
-- ``hlsl::dimension(K)``: Given ``K`` in ``"Unknown"``, ``"1D"``, ``"2D"``,
-  ``"3D"``, or ``"Cube"``, mark the resource as having the given dimensions.
-- ``hlsl::is_array``: Specify that the resource is an array of objects of the
+- `hlsl::dimension(K)`: Given `K` in `"Unknown"`, `"1D"`, `"2D"`,
+  `"3D"`, or `"Cube"`, mark the resource as having the given dimensions.
+- `hlsl::is_array`: Specify that the resource is an array of objects of the
   given dimensions.
-- ``hlsl::raw_buffer``: Specify that the resource is accessed as a raw buffer,
+- `hlsl::raw_buffer`: Specify that the resource is accessed as a raw buffer,
   rather than following the typed buffer alignment and offset rules.
-- ``hlsl::is_ms``: Specify that the resource is multisampled.
-- ``hlsl::is_rov``: Specify that the resource is a rasterizer ordered view.
-- ``hlsl::is_counter``: Specify that this is a counter associated with another
+- `hlsl::is_ms`: Specify that the resource is multisampled.
+- `hlsl::is_rov`: Specify that the resource is a rasterizer ordered view.
+- `hlsl::is_counter`: Specify that this is a counter associated with another
   resource.
 
 Member functions of a resource class are generally fairly simple wrappers
@@ -58,3 +50,9 @@ During code generation resource types are lowered to target extension types in
 IR. These types are target specific and differ between DXIL and SPIR-V
 generation, providing the necessary information for the targets to generate
 binding metadata for their respective target runtimes.
+
+[constantbuffer]: https://learn.microsoft.com/en-us/windows/win32/direct3d12/resource-binding-in-hlsl#constant-buffers
+[rasterizerorderedtexture2d]: https://learn.microsoft.com/en-us/windows/win32/direct3d11/rasterizer-order-views
+[rwbyteaddressbuffer]: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-object-rwbyteaddressbuffer
+[texture3d]: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-object-texture3d
+
diff --git a/clang/docs/HardwareAssistedAddressSanitizerDesign.md b/clang/docs/HardwareAssistedAddressSanitizerDesign.md
index f2e76d6faa400..2cc2b831006af 100644
--- a/clang/docs/HardwareAssistedAddressSanitizerDesign.md
+++ b/clang/docs/HardwareAssistedAddressSanitizerDesign.md
@@ -1,49 +1,44 @@
-=======================================================
-Hardware-assisted AddressSanitizer Design Documentation
-=======================================================
+# Hardware-assisted AddressSanitizer Design Documentation
 
 This page is a design document for
 **hardware-assisted AddressSanitizer** (or **HWASAN**)
-a tool similar to :doc:`AddressSanitizer`,
+a tool similar to {doc}`AddressSanitizer`,
 but based on partial hardware assistance.
 
+## Introduction
 
-Introduction
-============
-
-:doc:`AddressSanitizer`
+{doc}`AddressSanitizer`
 tags every 8 bytes of the application memory with a 1 byte tag (using *shadow memory*),
 uses *redzones* to find buffer-overflows and
 *quarantine* to find use-after-free.
 The redzones, the quarantine, and, to a lesser extent, the shadow, are the
 sources of AddressSanitizer's memory overhead.
-See the `AddressSanitizer paper`_ for details.
+See the [AddressSanitizer paper][addresssanitizer paper] for details.
 
-AArch64 has `Address Tagging`_ (or top-byte-ignore, TBI), a hardware feature that allows
+AArch64 has [Address Tagging][address tagging] (or top-byte-ignore, TBI), a hardware feature that allows
 software to use the 8 most significant bits of a 64-bit pointer as
-a tag. HWASAN uses `Address Tagging`_
-to implement a memory safety tool, similar to :doc:`AddressSanitizer`,
+a tag. HWASAN uses [Address Tagging][address tagging]
+to implement a memory safety tool, similar to {doc}`AddressSanitizer`,
 but with smaller memory overhead and slightly different (mostly better)
 accuracy guarantees.
 
-Intel's `Linear Address Masking`_ (LAM) also provides address tagging for
-x86_64, though it is not widely available in hardware yet.  For x86_64, HWASAN
+Intel's [Linear Address Masking][linear address masking] (LAM) also provides address tagging for
+x86_64, though it is not widely available in hardware yet. For x86_64, HWASAN
 has a limited implementation using page aliasing instead.
 
-Algorithm
-=========
-* Every heap/stack/global memory object is forcibly aligned by `TG` bytes
+## Algorithm
+
+- Every heap/stack/global memory object is forcibly aligned by `TG` bytes
   (`TG` is e.g. 16 or 64). We call `TG` the **tagging granularity**.
-* For every such object a random `TS`-bit tag `T` is chosen (`TS`, or tag size, is e.g. 4 or 8)
-* The pointer to the object is tagged with `T`.
-* The memory for the object is also tagged with `T` (using a `TG=>1` shadow memory)
-* Every load and store is instrumented to read the memory tag and compare it
+- For every such object a random `TS`-bit tag `T` is chosen (`TS`, or tag size, is e.g. 4 or 8)
+- The pointer to the object is tagged with `T`.
+- The memory for the object is also tagged with `T` (using a `TG=>1` shadow memory)
+- Every load and store is instrumented to read the memory tag and compare it
   with the pointer tag, exception is raised on tag mismatch.
 
-For a more detailed discussion of this approach see https://arxiv.org/pdf/1802.09517.pdf
+For a more detailed discussion of this approach see <https://arxiv.org/pdf/1802.09517.pdf>
 
-Short granules
---------------
+### Short granules
 
 A short granule is a granule of size between 1 and `TG-1` bytes. The size
 of a short granule is stored at the location in shadow memory where the
@@ -51,8 +46,8 @@ granule's tag is normally stored, while the granule's actual tag is stored
 in the last byte of the granule. This means that in order to verify that a
 pointer tag matches a memory tag, HWASAN must check for two possibilities:
 
-* the pointer tag is equal to the memory tag in shadow memory, or
-* the shadow memory tag is actually a short granule size, the value being loaded
+- the pointer tag is equal to the memory tag in shadow memory, or
+- the shadow memory tag is actually a short granule size, the value being loaded
   is in bounds of the granule and the pointer tag is equal to the last byte of
   the granule.
 
@@ -66,74 +61,71 @@ When HWASAN detects an error near a memory tag between 1 and `TG-1`, it
 will show both the memory tag and the last byte of the granule. Currently,
 it is up to the user to disambiguate the two possibilities.
 
-Instrumentation
-===============
+## Instrumentation
+
+### Memory Accesses
 
-Memory Accesses
----------------
 In the majority of cases, memory accesses are prefixed with a call to
 an outlined instruction sequence that verifies the tags. The code size
 and performance overhead of the call is reduced by using a custom calling
 convention that
 
-* preserves most registers, and
-* is specialized to the register containing the address, and the type and
+- preserves most registers, and
+- is specialized to the register containing the address, and the type and
   size of the memory access.
 
 Currently, the following sequence is used:
 
-.. code-block:: none
-
-  // int foo(int *a) { return *a; }
-  // clang -O2 --target=aarch64-linux-android30 -fsanitize=hwaddress -S -o - load.c
-  [...]
-  foo:
-        stp     x30, x20, [sp, #-16]!
-        adrp    x20, :got:__hwasan_shadow               // load shadow address from GOT into x20
-        ldr     x20, [x20, :got_lo12:__hwasan_shadow]
-        bl      __hwasan_check_x0_2_short_v2            // call outlined tag check
-                                                        // (arguments: x0 = address, x20 = shadow base;
-                                                        // "2" encodes the access type and size)
-        ldr     w0, [x0]                                // inline load
-        ldp     x30, x20, [sp], #16
-        ret
-
-  [...]
-  __hwasan_check_x0_2_short_v2:
-        sbfx    x16, x0, #4, #52                        // shadow offset
-        ldrb    w16, [x20, x16]                         // load shadow tag
-        cmp     x16, x0, lsr #56                        // extract address tag, compare with shadow tag
-        b.ne    .Ltmp0                                  // jump to short tag handler on mismatch
-  .Ltmp1:
-        ret
-  .Ltmp0:
-        cmp     w16, #15                                // is this a short tag?
-        b.hi    .Ltmp2                                  // if not, error
-        and     x17, x0, #0xf                           // find the address's position in the short granule
-        add     x17, x17, #3                            // adjust to the position of the last byte loaded
-        cmp     w16, w17                                // check that position is in bounds
-        b.ls    .Ltmp2                                  // if not, error
-        orr     x16, x0, #0xf                           // compute address of last byte of granule
-        ldrb    w16, [x16]                              // load tag from it
-        cmp     x16, x0, lsr #56                        // compare with pointer tag
-        b.eq    .Ltmp1                                  // if matches, continue
-  .Ltmp2:
-        stp     x0, x1, [sp, #-256]!                    // save original x0, x1 on stack (they will be overwritten)
-        stp     x29, x30, [sp, #232]                    // create frame record
-        mov     x1, #2                                  // set x1 to a constant indicating the type of failure
-        adrp    x16, :got:__hwasan_tag_mismatch_v2      // call runtime function to save remaining registers and report error
-        ldr     x16, [x16, :got_lo12:__hwasan_tag_mismatch_v2] // (load address from GOT to avoid potential register clobbers in delay load handler)
-        br      x16
-
-Heap
-----
+```none
+// int foo(int *a) { return *a; }
+// clang -O2 --target=aarch64-linux-android30 -fsanitize=hwaddress -S -o - load.c
+[...]
+foo:
+      stp     x30, x20, [sp, #-16]!
+      adrp    x20, :got:__hwasan_shadow               // load shadow address from GOT into x20
+      ldr     x20, [x20, :got_lo12:__hwasan_shadow]
+      bl      __hwasan_check_x0_2_short_v2            // call outlined tag check
+                                                      // (arguments: x0 = address, x20 = shadow base;
+                                                      // "2" encodes the access type and size)
+      ldr     w0, [x0]                                // inline load
+      ldp     x30, x20, [sp], #16
+      ret
+
+[...]
+__hwasan_check_x0_2_short_v2:
+      sbfx    x16, x0, #4, #52                        // shadow offset
+      ldrb    w16, [x20, x16]                         // load shadow tag
+      cmp     x16, x0, lsr #56                        // extract address tag, compare with shadow tag
+      b.ne    .Ltmp0                                  // jump to short tag handler on mismatch
+.Ltmp1:
+      ret
+.Ltmp0:
+      cmp     w16, #15                                // is this a short tag?
+      b.hi    .Ltmp2                                  // if not, error
+      and     x17, x0, #0xf                           // find the address's position in the short granule
+      add     x17, x17, #3                            // adjust to the position of the last byte loaded
+      cmp     w16, w17                                // check that position is in bounds
+      b.ls    .Ltmp2                                  // if not, error
+      orr     x16, x0, #0xf                           // compute address of last byte of granule
+      ldrb    w16, [x16]                              // load tag from it
+      cmp     x16, x0, lsr #56                        // compare with pointer tag
+      b.eq    .Ltmp1                                  // if matches, continue
+.Ltmp2:
+      stp     x0, x1, [sp, #-256]!                    // save original x0, x1 on stack (they will be overwritten)
+      stp     x29, x30, [sp, #232]                    // create frame record
+      mov     x1, #2                                  // set x1 to a constant indicating the type of failure
+      adrp    x16, :got:__hwasan_tag_mismatch_v2      // call runtime function to save remaining registers and report error
+      ldr     x16, [x16, :got_lo12:__hwasan_tag_mismatch_v2] // (load address from GOT to avoid potential register clobbers in delay load handler)
+      br      x16
+```
+
+### Heap
 
 Tagging the heap memory/pointers is done by `malloc`.
 This can be based on any malloc that forces all objects to be TG-aligned.
 `free` tags the memory with a different tag.
 
-Stack
------
+### Stack
 
 Stack frames are instrumented by aligning all non-promotable allocas
 by `TG` and tagging stack memory in function prologue and epilogue.
@@ -148,112 +140,104 @@ ReTag can be as simple as exclusive-or with constant `M`.
 Stack instrumentation is expected to be a major source of overhead,
 but could be optional.
 
-Globals
--------
+### Globals
 
 Most globals in HWASAN instrumented code are tagged. This is accomplished
 using the following mechanisms:
 
-  * The address of each global has a static tag associated with it. The first
-    defined global in a translation unit has a pseudorandom tag associated
-    with it, based on the hash of the file path. Subsequent global tags are
-    incremental from the previously-assigned tag.
-
-  * The global's tag is added to its symbol address in the object file's symbol
-    table. This causes the global's address to be tagged when its address is
-    taken.
-
-  * When the address of a global is taken directly (i.e. not via the GOT), a special
-    instruction sequence needs to be used to add the tag to the address,
-    because the tag would otherwise take the address outside of the small code
-    model (4GB on AArch64). No changes are required when the address is taken
-    via the GOT because the address stored in the GOT will contain the tag.
-
-  * An associated ``hwasan_globals`` section is emitted for each tagged global,
-    which indicates the address of the global, its size and its tag.  These
-    sections are concatenated by the linker into a single ``hwasan_globals``
-    section that is enumerated by the runtime (via an ELF note) when a binary
-    is loaded and the memory is tagged accordingly.
+> - The address of each global has a static tag associated with it. The first
+>   defined global in a translation unit has a pseudorandom tag associated
+>   with it, based on the hash of the file path. Subsequent global tags are
+>   incremental from the previously-assigned tag.
+> - The global's tag is added to its symbol address in the object file's symbol
+>   table. This causes the global's address to be tagged when its address is
+>   taken.
+> - When the address of a global is taken directly (i.e. not via the GOT), a special
+>   instruction sequence needs to be used to add the tag to the address,
+>   because the tag would otherwise take the address outside of the small code
+>   model (4GB on AArch64). No changes are required when the address is taken
+>   via the GOT because the address stored in the GOT will contain the tag.
+> - An associated `hwasan_globals` section is emitted for each tagged global,
+>   which indicates the address of the global, its size and its tag. These
+>   sections are concatenated by the linker into a single `hwasan_globals`
+>   section that is enumerated by the runtime (via an ELF note) when a binary
+>   is loaded and the memory is tagged accordingly.
 
 A complete example is given below:
 
-.. code-block:: none
-
-  // int x = 1; int *f() { return &x; }
-  // clang -O2 --target=aarch64-linux-android30 -fsanitize=hwaddress -S -o - global.c
-
-  [...]
-  f:
-        adrp    x0, :pg_hi21_nc:x            // set bits 12-63 to upper bits of untagged address
-        movk    x0, #:prel_g3:x+0x100000000  // set bits 48-63 to tag
-        add     x0, x0, :lo12:x              // set bits 0-11 to lower bits of address
-        ret
-
-  [...]
-        .data
-  .Lx.hwasan:
-        .word   1
-
-        .globl  x
-        .set x, .Lx.hwasan+0x2d00000000000000
-
-  [...]
-        .section        .note.hwasan.globals,"aG", at note,hwasan.module_ctor,comdat
-  .Lhwasan.note:
-        .word   8                            // namesz
-        .word   8                            // descsz
-        .word   3                            // NT_LLVM_HWASAN_GLOBALS
-        .asciz  "LLVM\000\000\000"
-        .word   __start_hwasan_globals-.Lhwasan.note
-        .word   __stop_hwasan_globals-.Lhwasan.note
-
-  [...]
-        .section        hwasan_globals,"ao", at progbits,.Lx.hwasan,unique,2
-  .Lx.hwasan.descriptor:
-        .word   .Lx.hwasan-.Lx.hwasan.descriptor
-        .word   0x2d000004                   // tag = 0x2d, size = 4
-
-Error reporting
----------------
+```none
+// int x = 1; int *f() { return &x; }
+// clang -O2 --target=aarch64-linux-android30 -fsanitize=hwaddress -S -o - global.c
+
+[...]
+f:
+      adrp    x0, :pg_hi21_nc:x            // set bits 12-63 to upper bits of untagged address
+      movk    x0, #:prel_g3:x+0x100000000  // set bits 48-63 to tag
+      add     x0, x0, :lo12:x              // set bits 0-11 to lower bits of address
+      ret
+
+[...]
+      .data
+.Lx.hwasan:
+      .word   1
+
+      .globl  x
+      .set x, .Lx.hwasan+0x2d00000000000000
+
+[...]
+      .section        .note.hwasan.globals,"aG", at note,hwasan.module_ctor,comdat
+.Lhwasan.note:
+      .word   8                            // namesz
+      .word   8                            // descsz
+      .word   3                            // NT_LLVM_HWASAN_GLOBALS
+      .asciz  "LLVM\000\000\000"
+      .word   __start_hwasan_globals-.Lhwasan.note
+      .word   __stop_hwasan_globals-.Lhwasan.note
+
+[...]
+      .section        hwasan_globals,"ao", at progbits,.Lx.hwasan,unique,2
+.Lx.hwasan.descriptor:
+      .word   .Lx.hwasan-.Lx.hwasan.descriptor
+      .word   0x2d000004                   // tag = 0x2d, size = 4
+```
+
+### Error reporting
 
 Errors are generated by the `HLT` instruction and are handled by a signal handler.
 
-Attribute
----------
+### Attribute
 
 HWASAN uses its own LLVM IR Attribute `sanitize_hwaddress` and a matching
 C function attribute. An alternative would be to re-use ASAN's attribute
 `sanitize_address`. The reasons to use a separate attribute are:
 
-  * Users may need to disable ASAN but not HWASAN, or vise versa,
-    because the tools have different trade-offs and compatibility issues.
-  * LLVM (ideally) does not use flags to decide which pass is being used,
-    ASAN or HWASAN are being applied, based on the function attributes.
+> - Users may need to disable ASAN but not HWASAN, or vise versa,
+>   because the tools have different trade-offs and compatibility issues.
+> - LLVM (ideally) does not use flags to decide which pass is being used,
+>   ASAN or HWASAN are being applied, based on the function attributes.
 
 This does mean that users of HWASAN may need to add the new attribute
 to the code that already uses the old attribute.
 
-
-Comparison with AddressSanitizer
-================================
+## Comparison with AddressSanitizer
 
 HWASAN:
-  * Is less portable than :doc:`AddressSanitizer`
-    as it relies on hardware `Address Tagging`_ (AArch64).
+: - Is less portable than {doc}`AddressSanitizer`
+    as it relies on hardware [Address Tagging][address tagging] (AArch64).
     Address Tagging can be emulated with compiler instrumentation,
     but it will require the instrumentation to remove the tags before
     any load or store, which is infeasible in any realistic environment
     that contains non-instrumented code.
-  * May have compatibility problems if the target code uses higher
+  - May have compatibility problems if the target code uses higher
     pointer bits for other purposes.
-  * May require changes in the OS kernels (e.g. Linux seems to dislike
+  - May require changes in the OS kernels (e.g. Linux seems to dislike
     tagged pointers passed from address space:
-    https://www.kernel.org/doc/Documentation/arm64/tagged-pointers.txt).
-  * **Does not require redzones to detect buffer overflows**,
+    <https://www.kernel.org/doc/Documentation/arm64/tagged-pointers.txt>).
+  - **Does not require redzones to detect buffer overflows**,
     but the buffer overflow detection is probabilistic, with roughly
     `1/(2**TS)` chance of missing a bug (6.25% or 0.39% with 4 and 8-bit TS
     respectively).
-  * **Does not require quarantine to detect heap-use-after-free,
+  - **Does not require quarantine to detect heap-use-after-free,
     or stack-use-after-return**.
     The detection is similarly probabilistic.
 
@@ -262,47 +246,45 @@ than that of AddressSanitizer:
 `1/TG` extra memory for the shadow
 and some overhead due to `TG`-aligning all objects.
 
-Security Considerations
-=======================
+## Security Considerations
 
 HWASAN is a bug detection tool and its runtime is not meant to be
 linked against production executables. While it may be useful for testing,
 HWASAN's runtime was not developed with security-sensitive
 constraints in mind and may compromise the security of the resulting executable.
 
-Supported architectures
-=======================
-HWASAN relies on `Address Tagging`_ which is only available on AArch64.
+## Supported architectures
+
+HWASAN relies on [Address Tagging][address tagging] which is only available on AArch64.
 For other 64-bit architectures it is possible to remove the address tags
 before every load and store by compiler instrumentation, but this variant
 will have limited deployability since not all of the code is
 typically instrumented.
 
 On x86_64, HWASAN utilizes page aliasing to place tags in userspace address
-bits.  Currently only heap tagging is supported.  The page aliases rely on
+bits. Currently only heap tagging is supported. The page aliases rely on
 shared memory, which will cause heap memory to be shared between processes if
-the application calls ``fork()``.  Therefore x86_64 is really only safe for
+the application calls `fork()`. Therefore x86_64 is really only safe for
 applications that do not fork.
 
 HWASAN does not currently support 32-bit architectures since they do not
-support `Address Tagging`_ and the address space is too constrained to easily
+support [Address Tagging][address tagging] and the address space is too constrained to easily
 implement page aliasing.
 
+## Related Work
 
-Related Work
-============
-* `SPARC ADI`_ and `Arm MTE`_ implement a similar tool mostly in hardware.
-* `Effective and Efficient Memory Protection Using Dynamic Tainting`_ discusses
+- [SPARC ADI][sparc adi] and [Arm MTE][arm mte] implement a similar tool mostly in hardware.
+- [Effective and Efficient Memory Protection Using Dynamic Tainting][effective and efficient memory protection using dynamic tainting] discusses
   similar approaches ("lock & key").
-* `Watchdog`_ discussed a heavier, but still somewhat similar
+- [Watchdog][watchdog] discussed a heavier, but still somewhat similar
   "lock & key" approach.
-* *TODO: add more "related work" links. Suggestions are welcome.*
+- *TODO: add more "related work" links. Suggestions are welcome.*
 
+[address tagging]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch12s05s01.html
+[addresssanitizer paper]: https://www.usenix.org/system/files/conference/atc12/atc12-final39.pdf
+[arm mte]: https://developer.arm.com/documentation/108035/0100/Introduction-to-the-Memory-Tagging-Extension
+[effective and efficient memory protection using dynamic tainting]: https://www.cc.gatech.edu/~orso/papers/clause.doudalis.orso.prvulovic.pdf
+[linear address masking]: https://software.intel.com/content/www/us/en/develop/download/intel-architecture-instruction-set-extensions-programming-reference.html
+[sparc adi]: https://lazytyped.blogspot.com/2017/09/getting-started-with-adi.html
+[watchdog]: https://www.cis.upenn.edu/acg/papers/isca12_watchdog.pdf
 
-.. _Watchdog: https://www.cis.upenn.edu/acg/papers/isca12_watchdog.pdf
-.. _Effective and Efficient Memory Protection Using Dynamic Tainting: https://www.cc.gatech.edu/~orso/papers/clause.doudalis.orso.prvulovic.pdf
-.. _SPARC ADI: https://lazytyped.blogspot.com/2017/09/getting-started-with-adi.html
-.. _Arm MTE: https://developer.arm.com/documentation/108035/0100/Introduction-to-the-Memory-Tagging-Extension
-.. _AddressSanitizer paper: https://www.usenix.org/system/files/conference/atc12/atc12-final39.pdf
-.. _Address Tagging: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch12s05s01.html
-.. _Linear Address Masking: https://software.intel.com/content/www/us/en/develop/download/intel-architecture-instruction-set-extensions-programming-reference.html
diff --git a/clang/docs/ItaniumMangleAbiTags.md b/clang/docs/ItaniumMangleAbiTags.md
index 2d65031b70e47..a3b07b8fe9b05 100644
--- a/clang/docs/ItaniumMangleAbiTags.md
+++ b/clang/docs/ItaniumMangleAbiTags.md
@@ -1,53 +1,47 @@
-========
-ABI tags
-========
+# ABI tags
 
-Introduction
-============
+## Introduction
 
 This text tries to describe gcc semantic for mangling "abi_tag" attributes
-described in https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
+described in <https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html>
 
 There is no guarantee the following rules are correct, complete or make sense
 in any way as they were determined empirically by experiments with gcc5.
 
-Declaration
-===========
+## Declaration
 
 ABI tags are declared in an abi_tag attribute and can be applied to a
 function, variable, class or inline namespace declaration. The attribute takes
 one or more strings (called tags); the order does not matter.
 
-See https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html for
+See <https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html> for
 details.
 
 Tags on an inline namespace are called "implicit tags", all other tags are
 "explicit tags".
 
-Mangling
-========
+## Mangling
 
-All tags that are "active" on an <unqualified-name> are emitted after the
-<unqualified-name>, before <template-args> or <discriminator>, and are part of
-the same <substitution> the <unqualified-name> is.
+All tags that are "active" on an \<unqualified-name> are emitted after the
+\<unqualified-name>, before \<template-args> or \<discriminator>, and are part of
+the same \<substitution> the \<unqualified-name> is.
 
 They are mangled as:
 
-.. code-block:: none
-
-    <abi-tags> ::= <abi-tag>*   # sort by name
-    <abi-tag> ::= B <tag source-name>
+```none
+<abi-tags> ::= <abi-tag>*   # sort by name
+<abi-tag> ::= B <tag source-name>
+```
 
 Example:
 
-.. code-block:: c++
-
-    __attribute__((abi_tag("test")))
-    void Func();
-    // gets mangled as: _Z4FuncB4testv (prettified as `Func[abi:test]()`)
+```c++
+__attribute__((abi_tag("test")))
+void Func();
+// gets mangled as: _Z4FuncB4testv (prettified as `Func[abi:test]()`)
+```
 
-Active tags
-===========
+## Active tags
 
 A namespace does not have any active tags. For types (class / struct / union /
 enum), the explicit tags are the active tags.
@@ -55,13 +49,12 @@ enum), the explicit tags are the active tags.
 For variables and functions, the active tags are the explicit tags plus any
 "required tags" which are not in the "available tags" set:
 
-.. code-block:: none
-
-    derived-tags := (required-tags - available-tags)
-    active-tags := explicit-tags + derived-tags
+```none
+derived-tags := (required-tags - available-tags)
+active-tags := explicit-tags + derived-tags
+```
 
-Required tags for a function
-============================
+## Required tags for a function
 
 If a function is used as a local scope for another name, and is part of
 another function as local scope, it doesn't have any required tags.
@@ -74,34 +67,33 @@ for the return type.
 
 Example:
 
-.. code-block:: c++
+```c++
+namespace A {
+  inline namespace B __attribute__((abi_tag)) {
+    struct C { int x; };
+  }
+}
 
-    namespace A {
-      inline namespace B __attribute__((abi_tag)) {
-        struct C { int x; };
-      }
-    }
+A::C foo(); // gets mangled as: _Z3fooB1Bv (prettified as `foo[abi:B]()`)
+```
 
-    A::C foo(); // gets mangled as: _Z3fooB1Bv (prettified as `foo[abi:B]()`)
-
-Required tags for a variable
-============================
+## Required tags for a variable
 
 A variable requires any implicit or explicit tag used in its type.
 
-Available tags
-==============
+## Available tags
 
 All tags used in the prefix and in the template arguments for a name are
-available. Also, for functions, all tags from the <bare-function-type>
+available. Also, for functions, all tags from the \<bare-function-type>
 (which might include the return type for template functions) are available.
 
-For <local-name>s all active tags used in the local part (<function-
+For \<local-name>s all active tags used in the local part (\<function-
 encoding>) are available, but not implicit tags which were not active.
 
-Implicit and explicit tags used in the <unqualified-name> for a function (as
+Implicit and explicit tags used in the \<unqualified-name> for a function (as
 in the type of a cast operator) are NOT available.
 
 Example: a cast operator to std::string (which is
-std::__cxx11::basic_string<...>) will use 'cxx11' as an active tag, as it is
+std::\_\_cxx11::basic_string\<...>) will use 'cxx11' as an active tag, as it is
 required from the return type `std::string` but not available.
+

>From ba34135f036236f65640c4c4d29f10b2042627be Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rkleckner at nvidia.com>
Date: Fri, 7 Aug 2026 02:18:01 +0000
Subject: [PATCH 2/3] [docs] Finish MyST migration for selected docs

---
 clang/docs/AutomaticReferenceCounting.md      | 192 +++++-----
 clang/docs/Block-ABI-Apple.md                 |  47 ++-
 clang/docs/BlockLanguageSpec.md               |   4 +-
 clang/docs/CIR/ABILowering.md                 |  11 +-
 clang/docs/CIR/CleanupAndEHDesign.md          |  77 ++--
 clang/docs/CommandGuide/clang.md              | 361 ++++++------------
 clang/docs/CommandGuide/diagtool.md           |  21 +-
 clang/docs/ConstantInterpreter.md             |  24 +-
 clang/docs/ControlFlowIntegrityDesign.md      | 225 +++++------
 clang/docs/DataFlowSanitizerDesign.md         |   3 +-
 clang/docs/HLSL/EntryFunctions.md             |   3 +-
 clang/docs/HLSL/ExpectedDifferences.md        |   2 +-
 clang/docs/HLSL/FunctionCalls.md              |   3 +-
 .../HardwareAssistedAddressSanitizerDesign.md |  47 ++-
 clang/docs/ItaniumMangleAbiTags.md            |  22 +-
 15 files changed, 436 insertions(+), 606 deletions(-)

diff --git a/clang/docs/AutomaticReferenceCounting.md b/clang/docs/AutomaticReferenceCounting.md
index 1f8dd7f15cb02..26dc68c55d3fe 100644
--- a/clang/docs/AutomaticReferenceCounting.md
+++ b/clang/docs/AutomaticReferenceCounting.md
@@ -54,16 +54,13 @@
 </style>
 ```
 
-```{eval-rst}
-.. role:: arc-term
+```{role} arc-term
 ```
 
-```{eval-rst}
-.. role:: revision
+```{role} revision
 ```
 
-```{eval-rst}
-.. role:: when-revised
+```{role} when-revised
 ```
 
 # Objective-C Automatic Reference Counting (ARC)
@@ -72,11 +69,11 @@
 :local: true
 ```
 
-(arc-meta)=
+(arc.meta)=
 
 ## About this document
 
-(arc-meta-purpose)=
+(arc.meta.purpose)=
 
 ### Purpose
 
@@ -89,7 +86,7 @@ The secondary purpose is to act as a rationale for why ARC was designed in this
 way. This should remain tightly focused on the technical design and should not
 stray into marketing speculation.
 
-(arc-meta-background)=
+(arc.meta.background)=
 
 ### Background
 
@@ -180,7 +177,7 @@ class that all block objects are considered to be objects of; this class
 implements `retain` by adjusting the reference count, not by calling
 `Block_copy`.
 
-(arc-meta-evolution)=
+(arc.meta.evolution)=
 
 ### Evolution
 
@@ -191,9 +188,9 @@ If a change increases the expressiveness of the language, for example by
 lifting a restriction or by adding new syntax, the change will be annotated
 with a revision marker, like so:
 
-> ARC applies to Objective-C pointer types, block pointer types, and
-> {when-revised}`[beginning Apple 8.0, LLVM 3.8]` {revision}`BPTRs declared
-> within` `extern "BCPL"` blocks.
+ARC applies to Objective-C pointer types, block pointer types, and
+{when-revised}`[beginning Apple 8.0, LLVM 3.8]` {revision}`BPTRs declared
+within` `extern "BCPL"` blocks.
 
 For now, it is sensible to version this document by the releases of its sole
 implementation (and its host project), clang. "LLVM X.Y" refers to an
@@ -207,7 +204,7 @@ imposing a new restriction, this should be taken as an oversight in the
 original specification and something to be avoided in all versions. Such
 changes are generally to be avoided.
 
-(arc-general)=
+(arc.general)=
 
 ## General
 
@@ -225,7 +222,7 @@ If ARC is enabled, `__has_feature(objc_arc)` will expand to 1 in the
 preprocessor. For more information about `__has_feature`, see the
 {ref}`language extensions <langext-__has_feature-__has_extension>` document.
 
-(arc-objects)=
+(arc.objects)=
 
 ## Retainable object pointers
 
@@ -282,7 +279,7 @@ will yield a type without the attribute, which may result in unexpected
 behavior.
 :::
 
-(arc-objects-retains)=
+(arc.objects.retains)=
 
 ### Retain count semantics
 
@@ -337,7 +334,7 @@ optimization of operations based on local knowledge of data flow. The
 semantics describe the high-level behaviors that the compiler implements, not
 an exact sequence of operations that a program will be compiled into.
 
-(arc-objects-operands)=
+(arc.objects.operands)=
 
 ### Retainable object pointers as operands and arguments
 
@@ -361,7 +358,7 @@ avoid needing to retain arguments across a large number of calls.
 The remainder of this section describes exceptions to these rules, how those
 exceptions are detected, and what those exceptions imply semantically.
 
-(arc-objects-operands-consumed)=
+(arc.objects.operands.consumed)=
 
 #### Consumed parameters
 
@@ -415,7 +412,7 @@ application of the existing C/C++ rule about calling functions through an
 incompatible function type, but it's useful to state it explicitly.
 :::
 
-(arc-object-operands-retained-return-values)=
+(arc.object.operands.retained-return-values)=
 
 #### Retained return values
 
@@ -465,7 +462,7 @@ just an application of the existing C/C++ rule about calling functions
 through an incompatible function type.
 :::
 
-(arc-objects-operands-unretained-returns)=
+(arc.objects.operands.unretained-returns)=
 
 #### Unretained return values
 
@@ -496,7 +493,7 @@ pointer which is guaranteed to be valid at least as long as the innermost
 autorelease pool. There are no additional semantics enforced in the definition
 of such a method; it merely enables optimizations in callers.
 
-(arc-objects-operands-casts)=
+(arc.objects.operands.casts)=
 
 #### Bridged casts
 
@@ -526,11 +523,11 @@ object pointers <arc.objects.restrictions.conversion>`.
 Using a `__bridge_retained` or `__bridge_transfer` cast purely to convince
 ARC to emit an unbalanced retain or release, respectively, is poor form.
 
-(arc-objects-restrictions)=
+(arc.objects.restrictions)=
 
 ### Restrictions
 
-(arc-objects-restrictions-conversion)=
+(arc.objects.restrictions.conversion)=
 
 #### Conversion of retainable object pointers
 
@@ -551,7 +548,7 @@ transfers control into or out of ARC.
 
 However, the following exceptions apply.
 
-(arc-objects-restrictions-conversion-with-known-semantics)=
+(arc.objects.restrictions.conversion.with.known.semantics)=
 
 #### Conversion to retainable object pointer type of expressions with known semantics
 
@@ -629,7 +626,7 @@ user constants might have been initialized with something dynamically
 allocated, using a global initializer.
 :::
 
-(arc-objects-restrictions-conversion-exception-contextual)=
+(arc.objects.restrictions.conversion-exception-contextual)=
 
 #### Conversion from retainable object pointer type in certain contexts
 
@@ -653,7 +650,7 @@ and it would be quite unfortunate for explicit releases to be silently
 balanced out in this way.
 :::
 
-(arc-ownership)=
+(arc.ownership)=
 
 ## Ownership qualification
 
@@ -702,7 +699,7 @@ There are four ownership qualifiers:
 A type is {arc-term}`nontrivially ownership-qualified` if it is qualified with
 `__autoreleasing`, `__strong`, or `__weak`.
 
-(arc-ownership-spelling)=
+(arc.ownership.spelling)=
 
 ### Spelling
 
@@ -745,7 +742,7 @@ before the entire declaration and have it apply in the leftmost
 sensible place.
 :::
 
-(arc-ownership-spelling-property)=
+(arc.ownership.spelling.property)=
 
 #### Property declarations
 
@@ -804,7 +801,7 @@ setter; direct accesses to the ivar (even if synthesized) still have primitive
 semantics, and the value in the ivar will not be automatically released during
 deallocation.
 
-(arc-ownership-semantics)=
+(arc.ownership.semantics)=
 
 ### Semantics
 
@@ -879,11 +876,11 @@ with primitive semantics, and then releasing the result of the load at the end
 of the current full-expression. For all other lvalues, moving is equivalent to
 reading the object.
 
-(arc-ownership-restrictions)=
+(arc.ownership.restrictions)=
 
 ### Restrictions
 
-(arc-ownership-restrictions-weak)=
+(arc.ownership.restrictions.weak)=
 
 #### Weak-unavailable types
 
@@ -912,7 +909,7 @@ attribute. A program is ill-formed if it applies the `__weak` ownership
 qualifier to a weak-unavailable type or if the value operand of a weak
 assignment operation has a weak-unavailable type.
 
-(arc-ownership-restrictions-autoreleasing)=
+(arc.ownership.restrictions.autoreleasing)=
 
 #### Storage duration of `__autoreleasing` objects
 
@@ -932,7 +929,7 @@ It is undefined behavior if a non-null pointer is assigned to an
 `__autoreleasing` object while an autorelease pool is in scope and then that
 object is read after the autorelease pool's scope is left.
 
-(arc-ownership-restrictions-conversion-indirect)=
+(arc.ownership.restrictions.conversion.indirect)=
 
 #### Conversion of pointers to ownership-qualified types
 
@@ -1027,7 +1024,7 @@ code because the non-ARC code will consider the element type to be POD.
 Such arrays that are `new[]`'d in ARC translation units cannot be
 `delete[]`'d in non-ARC translation units and vice-versa.
 
-(arc-ownership-restrictions-pass-by-writeback)=
+(arc.ownership.restrictions.pass_by_writeback)=
 
 #### Passing to an out parameter by writeback
 
@@ -1086,7 +1083,7 @@ However, it was judged unacceptably invasive to require programmers to write
 out-parameters. This was the least bad solution.
 :::
 
-(arc-ownership-restrictions-records)=
+(arc.ownership.restrictions.records)=
 
 #### Ownership-qualified fields of structs and unions
 
@@ -1206,12 +1203,12 @@ it to be enforced more strictly. The following rules apply:
 
 The *static subobjects* of a type `T` at a location `L` are:
 
-> - an object of type `T` spanning from `L` to `L + sizeof(T)`;
-> - if `T` is a struct type, then for each field `f` of that struct,
->   the static subobjects of `T` at location `L + offsetof(T, .f)`; and
-> - if `T` is the array type `E[N]`, then for each `i` satisfying
->   `0 <= i < N`, the static subobjects of `E` at location
->   `L + i * sizeof(E)`.
+- an object of type `T` spanning from `L` to `L + sizeof(T)`;
+- if `T` is a struct type, then for each field `f` of that struct,
+  the static subobjects of `T` at location `L + offsetof(T, .f)`; and
+- if `T` is the array type `E[N]`, then for each `i` satisfying
+  `0 <= i < N`, the static subobjects of `E` at location
+  `L + i * sizeof(E)`.
 
 If an l-value is converted to an r-value, then all static subobjects
 whose types are non-trivial to copy are accessed. If an l-value is
@@ -1297,10 +1294,10 @@ or between ARC and non-ARC modes) under the following conditions:
 - If two fields correspond as above, and at least one of the fields is
   ownership-qualified, then:
 
-  > - the fields must be identically qualified, or else
-  > - one type must be unqualified (and thus declared in a non-ARC mode),
-  >   and the other type must be qualified with `__unsafe_unretained`
-  >   or `__strong`.
+  - the fields must be identically qualified, or else
+  - one type must be unqualified (and thus declared in a non-ARC mode),
+    and the other type must be qualified with `__unsafe_unretained`
+    or `__strong`.
 
   Note that `__weak` fields must always be declared `__weak` because
   of the need to pin those fields in memory and keep them properly
@@ -1355,11 +1352,11 @@ force the use of the standard C++ ABI by declaring an empty (but
 non-defaulted) destructor.
 :::
 
-(arc-ownership-inference)=
+(arc.ownership.inference)=
 
 ### Ownership inference
 
-(arc-ownership-inference-variables)=
+(arc.ownership.inference.variables)=
 
 #### Objects
 
@@ -1371,7 +1368,7 @@ As a special case, if the object's base type is `Class` (possibly
 protocol-qualified), the type is adjusted to have `__unsafe_unretained`
 qualification instead.
 
-(arc-ownership-inference-indirect-parameters)=
+(arc.ownership.inference.indirect_parameters)=
 
 #### Indirect parameters
 
@@ -1403,7 +1400,7 @@ ill-formed.
 The convention is very unlikely to be intentional in template code.
 :::
 
-(arc-ownership-inference-template-arguments)=
+(arc.ownership.inference.template.arguments)=
 
 #### Template arguments
 
@@ -1420,7 +1417,7 @@ since they generally need to have a qualifier applied to the before being
 used.
 :::
 
-(arc-method-families)=
+(arc.method-families)=
 
 ## Method families
 
@@ -1482,7 +1479,7 @@ The families and their added restrictions are:
 A program is ill-formed if a method's declarations, implementations, and
 overrides do not all have the same method family.
 
-(arc-family-attribute)=
+(arc.family.attribute)=
 
 ### Explicit method family control
 
@@ -1515,7 +1512,7 @@ semantic intent, which is of use both to ARC (which, e.g., treats calls to
 `init` specially) and the static analyzer.
 :::
 
-(arc-family-semantics)=
+(arc.family.semantics)=
 
 ### Semantics of method families
 
@@ -1536,7 +1533,7 @@ to {ref}`retained objects <arc.object.operands.retained-return-values>`. This
 can be overridden by annotating the property with `ns_returns_not_retained`
 attribute.
 
-(arc-family-semantics-init)=
+(arc.family.semantics.init)=
 
 #### Semantics of `init`
 
@@ -1561,7 +1558,7 @@ It is undefined behavior for a program to cause two or more calls to `init`
 methods on the same object, except that each `init` method invocation may
 perform at most one delegate init call.
 
-(arc-family-semantics-result-type)=
+(arc.family.semantics.result_type)=
 
 #### Related result types
 
@@ -1594,7 +1591,7 @@ precise type information helps drastically lower this risk, as well as
 catching a number of latent bugs.
 :::
 
-(arc-optimization)=
+(arc.optimization)=
 
 ## Optimization
 
@@ -1665,7 +1662,7 @@ and double-released, ARC may eliminate the inner retain and release;
 it does not need to guard against code which performs an unbalanced
 release followed by a "balancing" retain.
 
-(arc-optimization-liveness)=
+(arc.optimization.liveness)=
 
 ### Object liveness
 
@@ -1744,7 +1741,7 @@ continued validity of the return value past the end of the
 full-expression.
 :::
 
-(arc-optimization-object-lifetime)=
+(arc.optimization.object_lifetime)=
 
 ### No object lifetime extension
 
@@ -1769,7 +1766,7 @@ of objects to have arbitrary side-effects, it's certainly possible.
 Hence the caveat.
 :::
 
-(arc-optimization-precise)=
+(arc.optimization.precise)=
 
 ### Precise lifetime semantics
 
@@ -1801,15 +1798,15 @@ requesting these semantics will not be burdensome, and may even make the code
 clearer.
 :::
 
-(arc-misc)=
+(arc.misc)=
 
 ## Miscellaneous
 
-(arc-misc-special-methods)=
+(arc.misc.special_methods)=
 
 ### Special methods
 
-(arc-misc-special-methods-retain)=
+(arc.misc.special_methods.retain)=
 
 #### Memory management methods
 
@@ -1857,7 +1854,7 @@ for example in a category; the implementations must obey the {ref}`semantics
 <arc.objects.retains>` laid out elsewhere in this document.
 :::
 
-(arc-misc-special-methods-dealloc)=
+(arc.misc.special_methods.dealloc)=
 
 #### `dealloc`
 
@@ -1916,7 +1913,7 @@ holistic solution is to move semantically important side-effects out of
 well-formed objects.
 :::
 
-(arc-misc-autoreleasepool)=
+(arc.misc.autoreleasepool)=
 
 ### `@autoreleasepool`
 
@@ -1946,7 +1943,7 @@ rest of the language. Not draining the pool during an unwind is apparently
 required by the Objective-C exceptions implementation.
 :::
 
-(arc-misc-externally-retained)=
+(arc.misc.externally_retained)=
 
 ### Externally-Retained Variables
 
@@ -2007,7 +2004,7 @@ You can test if your compiler has support for `objc_externally_retained` with
 #endif
 ```
 
-(arc-misc-self)=
+(arc.misc.self)=
 
 ### `self`
 
@@ -2015,7 +2012,7 @@ The `self` parameter variable of a non-init Objective-C method is considered
 {ref}`externally-retained <arc.misc.externally_retained>` by the implementation.
 It is undefined behavior, or at least dangerous, to cause an object to be
 deallocated during a message send to that object. In an init method, `self`
-follows the :ref:`init family rules <arc.family.semantics.init>`.
+follows the {ref}`init family rules <arc.family.semantics.init>`.
 
 :::{admonition} Rationale
 The cost of retaining `self` in all methods was found to be prohibitive, as
@@ -2030,7 +2027,7 @@ qualifying it with `__unsafe_unretained`), we chose to make this optimizing
 assumption and shift some amount of risk to the user.
 :::
 
-(arc-misc-enumeration)=
+(arc.misc.enumeration)=
 
 ### Fast enumeration iteration variables
 
@@ -2048,7 +2045,7 @@ qualifying the variable with `__strong`, which will make the variable
 mutable again and cause the loop to retain the objects it encounters.
 :::
 
-(arc-misc-blocks)=
+(arc.misc.blocks)=
 
 ### Blocks
 
@@ -2077,7 +2074,7 @@ on the stack won't get copied to the heap when the non-block pointer escapes.
 A block pointer is implicitly converted to `id` when it is passed to a
 function as a variadic argument.
 
-(arc-misc-exceptions)=
+(arc.misc.exceptions)=
 
 ### Exceptions
 
@@ -2121,7 +2118,7 @@ the process as this corruption is if the program does try to recover from
 exceptions.
 :::
 
-(arc-misc-interior)=
+(arc.misc.interior)=
 
 ### Interior pointers
 
@@ -2168,7 +2165,7 @@ this requires a very explicit annotation, which allows ARC to trust the user
 with good cheer.
 :::
 
-(arc-misc-c-retainable)=
+(arc.misc.c-retainable)=
 
 ### C retainable pointer types
 
@@ -2186,7 +2183,7 @@ for later tightening if a means of exhaustively marking CF types is made
 available.
 :::
 
-(arc-misc-c-retainable-audit)=
+(arc.misc.c-retainable.audit)=
 
 #### Auditing of C retainable pointer interfaces
 
@@ -2243,7 +2240,7 @@ designed to eliminate the risk of accidentally annotating some other header's
 interfaces.
 :::
 
-(arc-runtime)=
+(arc.runtime)=
 
 ## Runtime support
 
@@ -2282,7 +2279,7 @@ primarily as a code-size optimization, although in some cases there is also a
 real potential for avoiding redundant operations in the runtime.
 :::
 
-(arc-runtime-objc-autorelease)=
+(arc.runtime.objc_autorelease)=
 
 ### `id objc_autorelease(id value);`
 
@@ -2294,7 +2291,7 @@ to the innermost autorelease pool exactly as if the object had been sent the
 
 Always returns `value`.
 
-(arc-runtime-objc-autoreleasepoolpop)=
+(arc.runtime.objc_autoreleasePoolPop)=
 
 ### `void objc_autoreleasePoolPop(void *pool);`
 
@@ -2307,7 +2304,7 @@ Releases all the objects added to the given autorelease pool and any
 autorelease pools it encloses, then sets the current autorelease pool to the
 pool directly enclosing `pool`.
 
-(arc-runtime-objc-autoreleasepoolpush)=
+(arc.runtime.objc_autoreleasePoolPush)=
 
 ### `void *objc_autoreleasePoolPush(void);`
 
@@ -2320,7 +2317,7 @@ allow the implementation to just keep a stack of objects, using the stack
 depth as the opaque pool handle.
 :::
 
-(arc-runtime-objc-autoreleasereturnvalue)=
+(arc.runtime.objc_autoreleaseReturnValue)=
 
 ### `id objc_autoreleaseReturnValue(id value);`
 
@@ -2337,7 +2334,7 @@ above.
 
 Always returns `value`.
 
-(arc-runtime-objc-copyweak)=
+(arc.runtime.objc_copyWeak)=
 
 ### `void objc_copyWeak(id *dest, id *src);`
 
@@ -2356,7 +2353,7 @@ void objc_copyWeak(id *dest, id *src) {
 
 Must be atomic with respect to calls to `objc_storeWeak` on `src`.
 
-(arc-runtime-objc-destroyweak)=
+(arc.runtime.objc_destroyWeak)=
 
 ### `void objc_destroyWeak(id *object);`
 
@@ -2375,7 +2372,7 @@ void objc_destroyWeak(id *object) {
 Does not need to be atomic with respect to calls to `objc_storeWeak` on
 `object`.
 
-(arc-runtime-objc-initweak)=
+(arc.runtime.objc_initWeak)=
 
 ### `id objc_initWeak(id *object, id value);`
 
@@ -2399,7 +2396,7 @@ Returns the value of `object` after the call.
 Does not need to be atomic with respect to calls to `objc_storeWeak` on
 `object`.
 
-(arc-runtime-objc-loadweak)=
+(arc.runtime.objc_loadWeak)=
 
 ### `id objc_loadWeak(id *object);`
 
@@ -2424,7 +2421,7 @@ Loading weak references would be inherently prone to race conditions without
 the retain.
 :::
 
-(arc-runtime-objc-loadweakretained)=
+(arc.runtime.objc_loadWeakRetained)=
 
 ### `id objc_loadWeakRetained(id *object);`
 
@@ -2437,7 +2434,7 @@ that value and returns it. Otherwise returns null.
 
 Must be atomic with respect to calls to `objc_storeWeak` on `object`.
 
-(arc-runtime-objc-moveweak)=
+(arc.runtime.objc_moveWeak)=
 
 ### `void objc_moveWeak(id *dest, id *src);`
 
@@ -2452,7 +2449,7 @@ case this call is equivalent to {ref}`objc_copyWeak
 
 Must be atomic with respect to calls to `objc_storeWeak` on `src`.
 
-(arc-runtime-objc-release)=
+(arc.runtime.objc_release)=
 
 ### `void objc_release(id value);`
 
@@ -2462,7 +2459,7 @@ If `value` is null, this call has no effect. Otherwise, it performs a
 release operation exactly as if the object had been sent the `release`
 message.
 
-(arc-runtime-objc-retain)=
+(arc.runtime.objc_retain)=
 
 ### `id objc_retain(id value);`
 
@@ -2473,7 +2470,7 @@ operation exactly as if the object had been sent the `retain` message.
 
 Always returns `value`.
 
-(arc-runtime-objc-retainautorelease)=
+(arc.runtime.objc_retainAutorelease)=
 
 ### `id objc_retainAutorelease(id value);`
 
@@ -2491,7 +2488,7 @@ id objc_retainAutorelease(id value) {
 
 Always returns `value`.
 
-(arc-runtime-objc-retainautoreleasereturnvalue)=
+(arc.runtime.objc_retainAutoreleaseReturnValue)=
 
 ### `id objc_retainAutoreleaseReturnValue(id value);`
 
@@ -2510,7 +2507,7 @@ id objc_retainAutoreleaseReturnValue(id value) {
 
 Always returns `value`.
 
-(arc-runtime-objc-retainautoreleasedreturnvalue)=
+(arc.runtime.objc_retainAutoreleasedReturnValue)=
 
 ### `id objc_retainAutoreleasedReturnValue(id value);`
 
@@ -2525,7 +2522,7 @@ fails, it performs a retain operation exactly like {ref}`objc_retain
 
 Always returns `value`.
 
-(arc-runtime-objc-retainblock)=
+(arc.runtime.objc_retainBlock)=
 
 ### `id objc_retainBlock(id value);`
 
@@ -2536,7 +2533,7 @@ to by `value` is still on the stack, it is copied to the heap and the address
 of the copy is returned. Otherwise a retain operation is performed on the
 block exactly as if it had been sent the `retain` message.
 
-(arc-runtime-objc-storestrong)=
+(arc.runtime.objc_storeStrong)=
 
 ### `void objc_storeStrong(id *object, id value);`
 
@@ -2545,7 +2542,7 @@ adequately aligned for a pointer. `value` is null or a pointer to a valid
 object.
 
 Performs the complete sequence for assigning to a `__strong` object of
-non-block type [^footnote-1]. Equivalent to the following code:
+non-block type [^arc-store-strong-block]. Equivalent to the following code:
 
 ```objc
 void objc_storeStrong(id *object, id value) {
@@ -2556,12 +2553,12 @@ void objc_storeStrong(id *object, id value) {
 }
 ```
 
-[^footnote-1]: This does not imply that a `__strong` object of block type is an
-    invalid argument to this function. Rather it implies that an `objc_retain`
-    and not an `objc_retainBlock` operation will be emitted if the argument is
-    a block.
+[^arc-store-strong-block]: This does not imply that a `__strong` object of block
+    type is an invalid argument to this function. Rather it implies that an
+    `objc_retain` and not an `objc_retainBlock` operation will be emitted if the
+    argument is a block.
 
-(arc-runtime-objc-storeweak)=
+(arc.runtime.objc_storeWeak)=
 
 ### `id objc_storeWeak(id *object, id value);`
 
@@ -2576,7 +2573,7 @@ registration updated to point to `value`.
 
 Returns the value of `object` after the call.
 
-(arc-runtime-objc-unsafeclaimautoreleasedreturnvalue)=
+(arc.runtime.objc_unsafeClaimAutoreleasedReturnValue)=
 
 ### `id objc_unsafeClaimAutoreleasedReturnValue(id value);`
 
@@ -2592,4 +2589,3 @@ it performs a release operation exactly like {ref}`objc_release
 <arc.runtime.objc_release>`. If the handoff fails, this call has no effect.
 
 Always returns `value`.
-
diff --git a/clang/docs/Block-ABI-Apple.md b/clang/docs/Block-ABI-Apple.md
index b46ea99f34ab9..e30ff246a8ed1 100644
--- a/clang/docs/Block-ABI-Apple.md
+++ b/clang/docs/Block-ABI-Apple.md
@@ -102,15 +102,15 @@ initialized as follows:
 
 1. A `static` descriptor structure is declared and initialized as follows:
 
-> a. The `invoke` function pointer is set to a function that takes the
-> `Block` structure as its first argument and the rest of the arguments (if
-> any) to the `Block` and executes the `Block` compound statement.
->
-> b. The `size` field is set to the size of the following `Block` literal
-> structure.
->
-> c. The `copy_helper` and `dispose_helper` function pointers are set to
-> respective helper functions if they are required by the `Block` literal.
+   a. The `invoke` function pointer is set to a function that takes the
+      `Block` structure as its first argument and the rest of the arguments (if
+      any) to the `Block` and executes the `Block` compound statement.
+
+   b. The `size` field is set to the size of the following `Block` literal
+      structure.
+
+   c. The `copy_helper` and `dispose_helper` function pointers are set to
+      respective helper functions if they are required by the `Block` literal.
 
 2. A stack (or global) `Block` literal data structure is created and
    initialized as follows:
@@ -123,7 +123,7 @@ initialized as follows:
    b. The `flags` field is set to zero unless there are variables imported
    into the `Block` that need helper functions for program level
    `Block_copy()` and `Block_release()` operations, in which case the
-   (1\<<25) flags bit is set.
+     `(1<<25)` flags bit is set.
 
 As an example, the `Block` literal expression:
 
@@ -381,18 +381,18 @@ struct _block_byref_foo {
 
 The structure is initialized such that:
 
-> a. The `forwarding` pointer is set to the beginning of its enclosing
-> structure.
->
-> b. The `size` field is initialized to the total size of the enclosing
-> structure.
->
-> c. The `flags` field is set to either 0 if no helper functions are needed
-> or (1\<<25) if they are.
->
-> 4. The helper functions are initialized (if present).
-> 5. The variable itself is set to its initial value.
-> 6. The `isa` field is set to `NULL`.
+a. The `forwarding` pointer is set to the beginning of its enclosing
+   structure.
+
+b. The `size` field is initialized to the total size of the enclosing
+   structure.
+
+c. The `flags` field is set to either 0 if no helper functions are needed
+   or `(1<<25)` if they are.
+
+d. The helper functions are initialized (if present).
+e. The variable itself is set to its initial value.
+f. The `isa` field is set to `NULL`.
 
 #### Access to `__block` variables from within its lexical scope
 
@@ -826,7 +826,7 @@ for the appropriately named constructor and destructor for the class/struct
 To support member variable and function access the compiler will synthesize a
 `const` pointer to a block version of the `this` pointer.
 
-(runtimehelperfunctions)=
+(RuntimeHelperFunctions)=
 
 ## Runtime Helper Functions
 
@@ -918,4 +918,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
-
diff --git a/clang/docs/BlockLanguageSpec.md b/clang/docs/BlockLanguageSpec.md
index 76dafe4e4244a..f424f0a9f7d81 100644
--- a/clang/docs/BlockLanguageSpec.md
+++ b/clang/docs/BlockLanguageSpec.md
@@ -1,5 +1,4 @@
-```{eval-rst}
-.. role:: block-term
+```{role} block-term
 ```
 
 # Language Specification for Blocks
@@ -344,4 +343,3 @@ normal variable of C pointer type.
 
 Member variables that are Blocks may not be overloaded by the types of
 their arguments.
-
diff --git a/clang/docs/CIR/ABILowering.md b/clang/docs/CIR/ABILowering.md
index 59cd9bb6573f4..f7e9a4394b17a 100644
--- a/clang/docs/CIR/ABILowering.md
+++ b/clang/docs/CIR/ABILowering.md
@@ -55,7 +55,7 @@ System V ABI, a struct containing two 64-bit integers might be "expanded" into
 two separate arguments passed in registers, rather than being passed as a single
 aggregate:
 
-```
+```text
 // High-level CIR
 func @foo(i32, struct<i64, i64>) -> i32
 
@@ -169,7 +169,7 @@ CodeGen uses QualTypeMapper; MLIR uses ABITypeMapper and the ABI lowering pass.
 At the bottom, each dialect implements `ABIRewriteContext` only; FIR is shown
 as a consumer for cdecl/C interop (e.g. calling C from Fortran).
 
-```
+```text
 ┌─────────────────────────────────────────────────────────────────┐
 │  LLVM ABI Library (llvm/lib/ABI/)                               │
 │  ABIInfo, abi::Type*, target implementations (X86, AArch64,…)   │
@@ -206,7 +206,7 @@ implements only `ABIRewriteContext` for operation creation; there is no
 separate type abstraction layer in MLIR for classification—that lives in the ABI
 library.
 
-```
+```text
 ┌─────────────────────────────────────────────────────────────────────────┐
 │  LLVM ABI Library (llvm/lib/ABI/) — single source of truth              │
 │  abi::Type*, ABIInfo, target implementations (X86_64, AArch64, …)       │
@@ -287,7 +287,7 @@ At this stage, the types are still in their high-level, dialect-specific form
 these types into a list that will be fed to the classification logic in the next
 step.
 
-```
+```text
 Input: func @foo(%arg0: !cir.int<u, 32>,
        %arg1: !cir.struct<{!cir.int<u, 64>,
                             !cir.int<u, 64>}>) -> !cir.int<u, 32>
@@ -392,7 +392,7 @@ Value result = ctx.createLoad(loc, sretPtr);
 The diagram below combines the three-layer architecture (Section 4.1) with the
 step-by-step flow, showing which layer owns each step.
 
-```
+```text
  ┌─────────────────────────────────────────────────────────┐
  │ Input: High-Level Function (CIR/FIR/other dialect)      │
  │   func @foo(%arg0: i32, %arg1: struct<i64,i64>) -> i32  │
@@ -605,4 +605,3 @@ scoped to C calling conventions only, or be general enough to support arbitrary
 calling conventions (e.g. vectorcall, preserve_most) via extensible interfaces.
 Clarifying this scope will guide the design of the LLVM ABI library integration
 and the MLIR pass.
-
diff --git a/clang/docs/CIR/CleanupAndEHDesign.md b/clang/docs/CIR/CleanupAndEHDesign.md
index 5ce8a0624cb70..d616a4bf213ba 100644
--- a/clang/docs/CIR/CleanupAndEHDesign.md
+++ b/clang/docs/CIR/CleanupAndEHDesign.md
@@ -36,7 +36,7 @@ given target.
 Scopes that require normal or EH cleanup will be represented using a new
 operation, `cir.cleanup.scope`.
 
-```
+```text
 cir.cleanup.scope {
   // body region
 } cleanup [normal|eh|all] {
@@ -111,7 +111,7 @@ void someFunc() {
 
 **CIR**
 
-```
+```text
 cir.func @someFunc() {
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -156,7 +156,7 @@ void someFunc() {
 
 **CIR**
 
-```
+```text
 cir.func @someFunc() {
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   %1 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c2", init]
@@ -228,7 +228,7 @@ int someFunc() {
 
 **CIR**
 
-```
+```text
 cir.func @someFunc() -> !s32i {
   %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
   %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init]
@@ -321,7 +321,7 @@ public:
 
 **CIR**
 
-```
+```text
 cir.func @_ZN7DerivedC2Ev(%arg0: !cir.ptr<!rec_Derived>) {
   %0 = cir.alloca !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>, ["this", init]
   cir.store %arg0, %0 : !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>
@@ -371,7 +371,7 @@ The first operation in a catch handler region must be a `cir.begin_catch`
 operation. This must be followed by a `cir.cleanup.scope` operation,
 with the `cir.end_catch` operation in its cleanup region.
 
-```
+```text
 cir.try {
   cir.call exception @function() : () -> ()
   cir.yield
@@ -411,7 +411,7 @@ void someFunc() {
 
 **CIR**
 
-```
+```text
 cir.func @someFunc(){
   %0 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"]
   cir.scope {
@@ -465,7 +465,7 @@ void someFunc() {
 
 **CIR**
 
-```
+```text
 cir.func @someFunc(){
   %0 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"]
   cir.scope {
@@ -525,7 +525,7 @@ void someFunc() {
 
 **CIR**
 
-```
+```text
 cir.func @someFunc(){
   cir.scope {
     %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
@@ -575,7 +575,7 @@ void someFunc() {
 
 **CIR**
 
-```
+```text
 cir.func @someFunc(){
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   %1 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"]
@@ -638,7 +638,7 @@ high-level CIR representation, we have a single operation,
 cleanup needed is entirely within the scope of this operation, we can
 represent the cleanup by adding a cleanup region to this operation.
 
-```
+```text
 cir.array.ctor(%0 : !cir.ptr<!cir.array<!rec_SomeClass x 16>>) {
 ^bb0(%arg0: !cir.ptr<!rec_SomeClass>):
   cir.call @_ZN9SomeClassC1Ev(%arg0) : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -657,7 +657,7 @@ be expanded to a loop within a `cir.cleanup.scope` for the
 initialization, and a loop within the cleanup scope's cleanup region to
 perform the partial array cleanup, as follows
 
-```
+```text
 cir.scope {
   %1 = cir.const #cir.int<16> : !u64i
   %2 = cir.cast array_to_ptrdecay %0 : !cir.ptr<!cir.array<!rec_SomeClass x 16>> -> !cir.ptr<!rec_SomeClass>
@@ -741,7 +741,7 @@ cleanup, the call will be converted to a `cir.try_call` operation, with
 normal and unwind destinations. The first operation in the unwind
 destination block must be a `cir.eh.initiate` operation.
 
-```
+```text
 %eh_token = cir.eh.initiate [cleanup]
 ```
 
@@ -754,7 +754,7 @@ exception that was thrown and is passed as the argument to the
 `cir.begin_cleanup`, `cir.begin_catch`, and `cir.eh.dispatch`
 operations.
 
-```
+```text
 cir.eh.dispatch %eh_token : !cir.eh_token [
   catch (#cir.global_view<@_ZTIi> : !u32i) : ^bb6
   catch_all : ^bb7
@@ -782,7 +782,7 @@ by a branch to the cleanup block, passing the EH token as an operand to
 the block. The cleanup block will begin with a call to
 `cir.begin_cleanup` which returns a cleanup token.
 
-```
+```text
 ^bb4 (%eh_token : !cir.eh_token):
   %cleanup_token = cir.begin_cleanup %eh_token : !cir.eh_token -> !cir.cleanup_token
 ```
@@ -790,7 +790,7 @@ the block. The cleanup block will begin with a call to
 This is followed by the operations to perform the cleanup and then a
 cir.end_cleanup operation.
 
-```
+```text
 cir.end_cleanup(%cleanup_token : !cir.cleanup_token)
 ```
 
@@ -823,7 +823,7 @@ void someFunc() {
 
 **High-level CIR**
 
-```
+```text
 cir.func @someFunc(){
   cir.scope {
     %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
@@ -853,7 +853,7 @@ cir.func @someFunc(){
 
 **Flattened CIR**
 
-```
+```text
 cir.func @someFunc(){
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -912,7 +912,7 @@ void someFunc() {
 
 **High-level CIR**
 
-```
+```text
 cir.func @someFunc(){
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -929,7 +929,7 @@ cir.func @someFunc(){
 
 **Flattened CIR**
 
-```
+```text
 cir.func @someFunc(){
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -988,7 +988,7 @@ void someFunc() {
 
 **CIR**
 
-```
+```text
 cir.func @someFunc(){
   %0 = cir.alloca !rec_ThrowingDtor, !cir.ptr<!rec_ThrowingDtor>, ["c", init]
   cir.call @_ZN12ThrowingDtorC1Ev(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
@@ -1005,7 +1005,7 @@ cir.func @someFunc(){
 
 **Flattened CIR**
 
-```
+```text
 cir.func @someFunc(){
   %0 = cir.alloca !rec_ThrowingDtor, !cir.ptr<!rec_ThrowingDtor>, ["c", init]
   cir.call @_ZN12ThrowingDtorC1Ev(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
@@ -1061,7 +1061,7 @@ int someFunc() {
 
 **CIR**
 
-```
+```text
 cir.func @someFunc() -> !s32i {
   %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
   %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init]
@@ -1112,7 +1112,7 @@ cir.func @someFunc() -> !s32i {
 
 **Flattened CIR**
 
-```
+```text
 cir.func @someFunc() -> !s32i {
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__cleanup_dest_slot "]
@@ -1236,7 +1236,7 @@ followed by `std::terminate()`) and then an unreachable operation.
 The only operation that is specific to Itanium exception handling is
 `cir.eh.landingpad`.
 
-```
+```text
 %exn_ptr_0, %type_id = cir.eh.landingpad [@_ZTISt9exception] : !cir.ptr<!void>, !u32i
 ```
 
@@ -1249,7 +1249,7 @@ handler performs cleanup but does not catch any exceptions.
 
 **Flattened CIR**
 
-```
+```text
 cir.func @someFunc(){
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -1284,7 +1284,7 @@ cir.func @someFunc(){
 
 **ABI-lowered CIR**
 
-```
+```text
 cir.func @someFunc() #personality_fn = @__gxx_personality_v0 {
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -1324,7 +1324,7 @@ normal continuation block (`^bb8`).
 
 **Flattened CIR**
 
-```
+```text
 cir.func @someFunc(){
   cir.try_call @f() ^bb1, ^bb2
 ^bb1
@@ -1357,7 +1357,7 @@ cir.func @someFunc(){
 
 **ABI-lowered CIR**
 
-```
+```text
 cir.func @someFunc() #personality_fn = @__gxx_personality_v0 {
   cir.try_call @f() ^bb1, ^bb2
 ^bb1
@@ -1413,7 +1413,7 @@ instruction in LLVM IR and have the same semantics. The first operation
 in the unwind destination of a `cir.try_call` must be either
 `cir.eh.catchswitch` or `cir.cleanuppad`.
 
-```
+```text
 %4 = cir.eh.catchswitch within none [^bb2, ^bb3] unwind to caller
 ```
 
@@ -1428,7 +1428,7 @@ handled further in the current function. This operation returns a token
 that is used as the operand for `cir.catchpad` operations associated
 with this switch.
 
-```
+```text
 %5 = cir.cleanuppad within none []
 ```
 
@@ -1440,7 +1440,7 @@ handlers, the personality function will be `__CxxFrameHandler3` and the
 argument list will be empty. This operation returns a token that is used
 as the operand for the associated `cir.cleanupret` operation.
 
-```
+```text
 cir.cleanupret from %5 unwind to ^bb7
 ```
 
@@ -1449,7 +1449,7 @@ The `cir.cleanupret` operation takes an operand which specifies the
 block at which unwinding of the current exception continues (or unwind
 to caller if there is no catch handling in the current function).
 
-```
+```text
 %8 = cir.catchpad within %4 [ptr @"??_R0H at 8", i32 0, ptr %e]
 ```
 
@@ -1463,7 +1463,7 @@ operand for the associated `cir.catchret` operation or as the parent for
 any `cir.catchswitch` or `cir.cleanuppad` operations that are nested
 within this catch handler.
 
-```
+```text
 cir.catchret from %8 to ^bb8
 ```
 
@@ -1475,7 +1475,7 @@ block at which excution should be resumed.
 
 **Flattened CIR**
 
-```
+```text
 cir.func @someFunc() {
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -1510,7 +1510,7 @@ cir.func @someFunc() {
 
 **ABI-lowered CIR**
 
-```
+```text
 cir.func @someFunc() #personality_fn = @ __CxxFrameHandler3 {
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb4 : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -1537,7 +1537,7 @@ cir.func @someFunc() #personality_fn = @ __CxxFrameHandler3 {
 
 **Flattened CIR**
 
-```
+```text
 cir.func @someFunc(){
   cir.try_call @f() ^bb1, ^bb2
 ^bb1
@@ -1570,7 +1570,7 @@ cir.func @someFunc(){
 
 **ABI-lowered CIR**
 
-```
+```text
 cir.func @someFunc() #personality_fn = @__CxxFrameHandler3 {
   cir.try_call @f() ^bb1, ^bb2
 ^bb1
@@ -1599,4 +1599,3 @@ case will be handled by the personality function, using tables that are
 generated from the `cir.catchpad` operations. Each catch handler simply
 continues to the normal continuation block (`^bb6`) using the
 `cir.catchret` operation.
-
diff --git a/clang/docs/CommandGuide/clang.md b/clang/docs/CommandGuide/clang.md
index cf4dd98a29fb2..ae72e95d100f6 100644
--- a/clang/docs/CommandGuide/clang.md
+++ b/clang/docs/CommandGuide/clang.md
@@ -63,7 +63,7 @@ Linker
 
 The Clang Static Analyzer is a tool that scans source code to try to find bugs
 through code analysis. This tool uses many parts of Clang and is built into
-the same driver. Please see \<<https://clang-analyzer.llvm.org>> for more details
+the same driver. Please see <https://clang-analyzer.llvm.org> for more details
 on how to use the static analyzer.
 
 ## OPTIONS
@@ -103,172 +103,56 @@ Specify the language standard to compile for.
 
 Supported values for the C language are:
 
-> `c89`
->
-> `c90`
->
-> `iso9899:1990`
->
-> > ISO C 1990
->
-> `iso9899:199409`
->
-> > ISO C 1990 with amendment 1
->
-> `gnu89`
->
-> `gnu90`
->
-> > ISO C 1990 with GNU extensions
->
-> `c99`
->
-> `iso9899:1999`
->
-> > ISO C 1999
->
-> `gnu99`
->
-> > ISO C 1999 with GNU extensions
->
-> `c11`
->
-> `iso9899:2011`
->
-> > ISO C 2011
->
-> `gnu11`
->
-> > ISO C 2011 with GNU extensions
->
-> `c17`
->
-> `iso9899:2017`
->
-> > ISO C 2017
->
-> `gnu17`
->
-> > ISO C 2017 with GNU extensions
->
-> `c23`
->
-> `iso9899:2024`
->
-> > ISO C 2023
->
-> `gnu23`
->
-> > ISO C 2023 with GNU extensions
->
-> `c2y`
->
-> > ISO C 202y
->
-> `gnu2y`
->
-> > ISO C 202y with GNU extensions
+- `c89`, `c90`, `iso9899:1990`: ISO C 1990
+- `iso9899:199409`: ISO C 1990 with amendment 1
+- `gnu89`, `gnu90`: ISO C 1990 with GNU extensions
+- `c99`, `iso9899:1999`: ISO C 1999
+- `gnu99`: ISO C 1999 with GNU extensions
+- `c11`, `iso9899:2011`: ISO C 2011
+- `gnu11`: ISO C 2011 with GNU extensions
+- `c17`, `iso9899:2017`: ISO C 2017
+- `gnu17`: ISO C 2017 with GNU extensions
+- `c23`, `iso9899:2024`: ISO C 2023
+- `gnu23`: ISO C 2023 with GNU extensions
+- `c2y`: ISO C 202y
+- `gnu2y`: ISO C 202y with GNU extensions
 
 The default C language standard is `gnu17`, except on PS4, where it is
 `gnu99`.
 
 Supported values for the C++ language are:
 
-> `c++98`
->
-> `c++03`
->
-> > ISO C++ 1998 with amendments
->
-> `gnu++98`
->
-> `gnu++03`
->
-> > ISO C++ 1998 with amendments and GNU extensions
->
-> `c++11`
->
-> > ISO C++ 2011 with amendments
->
-> `gnu++11`
->
-> > ISO C++ 2011 with amendments and GNU extensions
->
-> `c++14`
->
-> > ISO C++ 2014 with amendments
->
-> `gnu++14`
->
-> > ISO C++ 2014 with amendments and GNU extensions
->
-> `c++17`
->
-> > ISO C++ 2017 with amendments
->
-> `gnu++17`
->
-> > ISO C++ 2017 with amendments and GNU extensions
->
-> `c++20`
->
-> > ISO C++ 2020 with amendments
->
-> `gnu++20`
->
-> > ISO C++ 2020 with amendments and GNU extensions
->
-> `c++23`
->
-> > ISO C++ 2023 with amendments
->
-> `gnu++23`
->
-> > ISO C++ 2023 with amendments and GNU extensions
->
-> `c++2c`
->
-> > Working draft for C++2c
->
-> `gnu++2c`
->
-> > Working draft for C++2c with GNU extensions
->
-> `c++2d`
->
-> > Working draft for C++2d
->
-> `gnu++2d`
->
-> > Working draft for C++2d with GNU extensions
+- `c++98`, `c++03`: ISO C++ 1998 with amendments
+- `gnu++98`, `gnu++03`: ISO C++ 1998 with amendments and GNU extensions
+- `c++11`: ISO C++ 2011 with amendments
+- `gnu++11`: ISO C++ 2011 with amendments and GNU extensions
+- `c++14`: ISO C++ 2014 with amendments
+- `gnu++14`: ISO C++ 2014 with amendments and GNU extensions
+- `c++17`: ISO C++ 2017 with amendments
+- `gnu++17`: ISO C++ 2017 with amendments and GNU extensions
+- `c++20`: ISO C++ 2020 with amendments
+- `gnu++20`: ISO C++ 2020 with amendments and GNU extensions
+- `c++23`: ISO C++ 2023 with amendments
+- `gnu++23`: ISO C++ 2023 with amendments and GNU extensions
+- `c++2c`: Working draft for C++2c
+- `gnu++2c`: Working draft for C++2c with GNU extensions
+- `c++2d`: Working draft for C++2d
+- `gnu++2d`: Working draft for C++2d with GNU extensions
 
 The default C++ language standard is `gnu++17`.
 
 Supported values for the OpenCL language are:
 
-> `cl1.0`
->
-> > OpenCL 1.0
->
-> `cl1.1`
->
-> > OpenCL 1.1
->
-> `cl1.2`
->
-> > OpenCL 1.2
->
-> `cl2.0`
->
-> > OpenCL 2.0
+- `cl1.0`: OpenCL 1.0
+- `cl1.1`: OpenCL 1.1
+- `cl1.2`: OpenCL 1.2
+- `cl2.0`: OpenCL 2.0
 
 The default OpenCL language standard is `cl1.0`.
 
 Supported values for the CUDA language are:
 
-> `cuda`
->
-> > NVIDIA CUDA(tm)
+- `cuda`: NVIDIA CUDA(tm)
 :::
 
 :::{option} -stdlib=<library>
@@ -319,7 +203,7 @@ library function in namespace `std`. For example,
 {cpp:func}`std::move_if_noexcept` library function.
 
 For C standard library functions that the C++ standard library also provides
-in namespace `std`, use {option}`-fno-builtin-\<function\>` instead.
+in namespace `std`, use `-fno-builtin-<function>` instead.
 :::
 
 :::{option} -fmath-errno
@@ -350,7 +234,7 @@ strings and other optimizations.
 
 :::{option} -flax-vector-conversions, -flax-vector-conversions=<kind>, -fno-lax-vector-conversions
 Allow loose type checking rules for implicit vector conversions.
-Possible values of \<kind>:
+Possible values of `<kind>`:
 
 - `none`: allow no implicit conversions between vectors
 - `integer`: allow implicit bitcasts between integer vectors of the same
@@ -358,7 +242,7 @@ Possible values of \<kind>:
 - `all`: allow implicit bitcasts between any vectors of the same
   overall bit-width
 
-\<kind> defaults to `integer` if unspecified.
+`<kind>` defaults to `integer` if unspecified.
 :::
 
 :::{option} -fblocks
@@ -447,49 +331,39 @@ AArch64 and RISC-V.
 :::{option} -O0, -O1, -O2, -O3, -Ofast, -Os, -Oz, -Og, -O, -O4
 Specify which optimization level to use:
 
-> {option}`-O0` Means "no optimization": this level compiles the fastest and
-> generates the most debuggable code.
->
-> {option}`-O1` Somewhere between {option}`-O0` and {option}`-O2`.
->
-> {option}`-O2` Moderate level of optimization which enables most
-> optimizations.
->
-> {option}`-O3` Like {option}`-O2`, except that it enables optimizations that
-> take longer to perform or that may generate larger code (in an attempt to
-> make the program run faster).
->
-> {option}`-Ofast` Enables all the optimizations from {option}`-O3` along with
-> other aggressive optimizations that may violate strict compliance with
-> language standards. This has been deprecated since Clang 19. There is no
-> timeline yet for removal; the aim is to discourage use of {option}`-Ofast`
-> due to the surprising behavior of an optimization flag changing the
-> observable behavior of correct code.
->
-> If {option}`-Ofast` has been specified and is the effective optimization
-> level (i.e. there is no later `-O` option specified), then the option can be
-> replaced in the option string with `-O3 -ffast-math -fstrict-aliasing`.
-> ({option}`-fstrict-aliasing` is the default on non-Windows, non-UEFI
-> platforms). If {option}`-Ofast` has been specified but is not the effective
-> optimization level, then it can be removed or replaced with {option}`-O3`.
->
-> {option}`-Os` Like {option}`-O2` with extra optimizations to reduce code
-> size.
->
-> {option}`-Oz` Like {option}`-Os` (and thus {option}`-O2`), but reduces code
-> size further.
->
-> {option}`-Og` Similar to {option}`-O1`, but with slightly reduced
-> optimization and better variable visibility. The same optimizations are run
-> as at {option}`-O1`, but the `-fextend-variable-liveness` flag is
-> also set, which tries to prevent optimizations from reducing the liveness of
-> user variables, improving their availability when debugging.
->
-> {option}`-O` Equivalent to {option}`-O1`.
->
-> {option}`-O4` and higher
->
-> > Currently equivalent to {option}`-O3`
+- {option}`-O0` means "no optimization": this level compiles the fastest and
+  generates the most debuggable code.
+- {option}`-O1` is somewhere between {option}`-O0` and {option}`-O2`.
+- {option}`-O2` is a moderate level of optimization which enables most
+  optimizations.
+- {option}`-O3` is like {option}`-O2`, except that it enables optimizations
+  that take longer to perform or that may generate larger code (in an attempt
+  to make the program run faster).
+- {option}`-Ofast` enables all the optimizations from {option}`-O3` along with
+  other aggressive optimizations that may violate strict compliance with
+  language standards. This has been deprecated since Clang 19. There is no
+  timeline yet for removal; the aim is to discourage use of {option}`-Ofast`
+  due to the surprising behavior of an optimization flag changing the
+  observable behavior of correct code.
+
+  If {option}`-Ofast` has been specified and is the effective optimization
+  level (i.e. there is no later `-O` option specified), then the option can be
+  replaced in the option string with `-O3 -ffast-math -fstrict-aliasing`.
+  ({option}`-fstrict-aliasing` is the default on non-Windows, non-UEFI
+  platforms). If {option}`-Ofast` has been specified but is not the effective
+  optimization level, then it can be removed or replaced with {option}`-O3`.
+
+- {option}`-Os` is like {option}`-O2` with extra optimizations to reduce code
+  size.
+- {option}`-Oz` is like {option}`-Os` (and thus {option}`-O2`), but reduces code
+  size further.
+- {option}`-Og` is similar to {option}`-O1`, but with slightly reduced
+  optimization and better variable visibility. The same optimizations are run
+  as at {option}`-O1`, but the `-fextend-variable-liveness` flag is also set,
+  which tries to prevent optimizations from reducing the liveness of user
+  variables, improving their availability when debugging.
+- {option}`-O` is equivalent to {option}`-O1`.
+- {option}`-O4` and higher are currently equivalent to {option}`-O3`.
 :::
 
 :::{option} -g, -gline-tables-only, -gmodules
@@ -497,25 +371,23 @@ Control debug information output. Note that Clang debug information works
 best at {option}`-O0`. When more than one option starting with `-g` is
 specified, the last one wins:
 
-> {option}`-g` Generate debug information.
->
-> {option}`-gline-tables-only` Generate only line table debug information. This
-> allows for symbolicated backtraces with inlining information, but does not
-> include any information about variables, their locations or types.
->
-> {option}`-gmodules` Generate debug information that contains external
-> references to types defined in Clang modules or precompiled headers instead
-> of emitting redundant debug type information into every object file. This
-> option transparently switches the Clang module format to object file
-> containers that hold the Clang module together with the debug information.
-> When compiling a program that uses Clang modules or precompiled headers,
-> this option produces complete debug information with faster compile
-> times and much smaller object files.
->
-> This option should not be used when building static libraries for
-> distribution to other machines because the debug info will contain
-> references to the module cache on the machine the object files in the
-> library were built on.
+- {option}`-g` generates debug information.
+- {option}`-gline-tables-only` generates only line table debug information.
+  This allows for symbolicated backtraces with inlining information, but does
+  not include any information about variables, their locations or types.
+- {option}`-gmodules` generates debug information that contains external
+  references to types defined in Clang modules or precompiled headers instead
+  of emitting redundant debug type information into every object file. This
+  option transparently switches the Clang module format to object file
+  containers that hold the Clang module together with the debug information.
+  When compiling a program that uses Clang modules or precompiled headers, this
+  option produces complete debug information with faster compile times and much
+  smaller object files.
+
+  This option should not be used when building static libraries for
+  distribution to other machines because the debug info will contain references
+  to the module cache on the machine the object files in the library were built
+  on.
 :::
 
 :::{option} -fstandalone-debug -fno-standalone-debug
@@ -761,48 +633,39 @@ the preprocessed file by compiling it separately.
 
 ## ENVIRONMENT
 
-```{eval-rst}
-.. envvar:: TMPDIR, TEMP, TMP
-
-  These environment variables are checked, in order, for the location to write
-  temporary files used during the compilation process.
-```
-
-```{eval-rst}
-.. envvar:: CPATH
-
-  This environment variable specifies additional (non-system) header search
-  paths to be used to find included header files. These paths are searched after
-  paths specified with the :option:`-I\<directory\>` option, but before any
-  system header search paths. Paths are delimited by the platform dependent
-  delimiter as used in the ``PATH`` environment variable. Empty entries in the
-  delimited path list, including those at the beginning or end of the list, are
-  treated as specifying the compiler's current working directory.
-```
-
-```{eval-rst}
-.. envvar:: C_INCLUDE_PATH, OBJC_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJCPLUS_INCLUDE_PATH
+:::{envvar} TMPDIR, TEMP, TMP
+These environment variables are checked, in order, for the location to write
+temporary files used during the compilation process.
+:::
 
-  These environment variables specify additional system header file search
-  paths to be used when processing the corresponding language. Search paths are
-  delimited as for the :envvar:`CPATH` environment variable.
-```
+:::{envvar} CPATH
+This environment variable specifies additional (non-system) header search
+paths to be used to find included header files. These paths are searched after
+paths specified with the `-I<directory>` option, but before any
+system header search paths. Paths are delimited by the platform dependent
+delimiter as used in the `PATH` environment variable. Empty entries in the
+delimited path list, including those at the beginning or end of the list, are
+treated as specifying the compiler's current working directory.
+:::
 
-```{eval-rst}
-.. envvar:: MACOSX_DEPLOYMENT_TARGET
+:::{envvar} C_INCLUDE_PATH, OBJC_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJCPLUS_INCLUDE_PATH
+These environment variables specify additional system header file search
+paths to be used when processing the corresponding language. Search paths are
+delimited as for the {envvar}`CPATH` environment variable.
+:::
 
-  If :option:`-mmacos-version-min` is unspecified, the default deployment
-  target is read from this environment variable. This option only affects
-  Darwin targets.
-```
+:::{envvar} MACOSX_DEPLOYMENT_TARGET
+If {option}`-mmacos-version-min` is unspecified, the default deployment
+target is read from this environment variable. This option only affects
+Darwin targets.
+:::
 
 ## BUGS
 
-To report bugs, please visit \<<https://github.com/llvm/llvm-project/issues/>>. Most bug reports should
+To report bugs, please visit <https://github.com/llvm/llvm-project/issues/>. Most bug reports should
 include preprocessed source files (use the {option}`-E` option) and the full
 output of the compiler, along with information to reproduce.
 
 ## SEE ALSO
 
 {manpage}`as(1)`, {manpage}`ld(1)`
-
diff --git a/clang/docs/CommandGuide/diagtool.md b/clang/docs/CommandGuide/diagtool.md
index 7c3790509fe4d..dae34550c98a1 100644
--- a/clang/docs/CommandGuide/diagtool.md
+++ b/clang/docs/CommandGuide/diagtool.md
@@ -2,7 +2,7 @@
 
 ## SYNOPSIS
 
-{program}`diagtool` *command* \[*args*\]
+{program}`diagtool` *command* [*args*]
 
 ## DESCRIPTION
 
@@ -14,32 +14,31 @@
 different purpose. A brief summary of each command follows, with more detail in
 the sections that follow.
 
-> - {ref}`find_diagnostic_id` - Print the id of the given diagnostic.
-> - {ref}`list_warnings` - List warnings and their corresponding flags.
-> - {ref}`show_enabled` - Show which warnings are enabled for a given command line.
-> - {ref}`tree` - Show warning flags in a tree view.
+- {ref}`find_diagnostic_id` - Print the id of the given diagnostic.
+- {ref}`list_warnings` - List warnings and their corresponding flags.
+- {ref}`show_enabled` - Show which warnings are enabled for a given command line.
+- {ref}`tree` - Show warning flags in a tree view.
 
-(find-diagnostic-id)=
+(find_diagnostic_id)=
 
 ### find-diagnostic-id
 
 {program}`diagtool` find-diagnostic-id *diagnostic-name*
 
-(list-warnings)=
+(list_warnings)=
 
 ### list-warnings
 
 {program}`diagtool` list-warnings
 
-(show-enabled)=
+(show_enabled)=
 
 ### show-enabled
 
-{program}`diagtool` show-enabled \[*options*\] *filename ...*
+{program}`diagtool` show-enabled [*options*] *filename ...*
 
 (tree)=
 
 ### tree
 
-{program}`diagtool` tree \[*diagnostic-group*\]
-
+{program}`diagtool` tree [*diagnostic-group*]
diff --git a/clang/docs/ConstantInterpreter.md b/clang/docs/ConstantInterpreter.md
index 7a86c266a7a74..1a2d3d0845a26 100644
--- a/clang/docs/ConstantInterpreter.md
+++ b/clang/docs/ConstantInterpreter.md
@@ -176,20 +176,19 @@ block types.
 
 Pointers, implemented in `Pointer.h` are represented as a tagged union.
 
-> - **BlockPointer**: used to reference memory allocated and managed by the
->   interpreter, being the only pointer kind which allows dereferencing in the
->   interpreter
-> - **TypeIDPointer**: tracks information for the opaque type returned by
->   `typeid`
-> - **IntegralPointer**: a pointer formed from an integer,
->   think `(int*)123`.
-> - **FunctionPointer**: a pointer to a function.
+- **BlockPointer**: used to reference memory allocated and managed by the
+  interpreter, being the only pointer kind which allows dereferencing in the
+  interpreter
+- **TypeIDPointer**: tracks information for the opaque type returned by
+  `typeid`
+- **IntegralPointer**: a pointer formed from an integer, think `(int*)123`.
+- **FunctionPointer**: a pointer to a function.
 
 Besides the previously mentioned union, a number of other pointer-like types
 have their own type:
 
-> - **FunctionPointer** tracks functions.
-> - **MemberPointer** tracks C++ object members
+- **FunctionPointer** tracks functions.
+- **MemberPointer** tracks C++ object members
 
 #### BlockPointer
 
@@ -227,7 +226,7 @@ In the interpreter, the object would require 240 bytes of storage and
 would have its fields interleaved with metadata. The pointers which can
 be derived to the object are illustrated in the following diagram:
 
-```
+```text
     0   16  32  40  56  64  80  96  112 120 136 144 160 176 184 200 208 224 240
 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
 + B | D | D | x | D | y | D | D | D | a | D | b | D | D | a | D | b | D | z |
@@ -275,7 +274,7 @@ static_assert(add(1, 2) == 3);
 
 Which generates the following bytecode (this can be produced via `interp::Function::dump()`):
 
-```
+```text
 add 0x7cb97f7e2000
 [...]
 0     GetParamSint32    0
@@ -303,4 +302,3 @@ Here are a few hints when working on the bytecode interpreter:
 - Printing `APValue` instances also works via `APValue::dump()`.
 - If you want to see *everything* that's being evaluated, add debugging output to
   the `evaluate*` functions in `Context.cpp`.
-
diff --git a/clang/docs/ControlFlowIntegrityDesign.md b/clang/docs/ControlFlowIntegrityDesign.md
index a4acd20cae4cd..d7c5088f06550 100644
--- a/clang/docs/ControlFlowIntegrityDesign.md
+++ b/clang/docs/ControlFlowIntegrityDesign.md
@@ -36,23 +36,21 @@ struct C : A {
 The scheme will cause the virtual tables for A, B and C to be laid out
 consecutively:
 
-```{eval-rst}
-.. csv-table:: Virtual Table Layout for A, B, C
-  :header: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
-
-  A::offset-to-top, &A::rtti, &A::f1, &A::f2, &A::f3, B::offset-to-top, &B::rtti, &B::f1, &B::f2, &B::f3, C::offset-to-top, &C::rtti, &C::f1, &C::f2, &C::f3
-```
+:::{table} Virtual Table Layout for A, B, C
+| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
+|---|---|---|---|---|---|---|---|---|---|----|----|----|----|----|
+| A::offset-to-top | &A::rtti | &A::f1 | &A::f2 | &A::f3 | B::offset-to-top | &B::rtti | &B::f1 | &B::f2 | &B::f3 | C::offset-to-top | &C::rtti | &C::f1 | &C::f2 | &C::f3 |
+:::
 
 The bit vector for static types A, B and C will look like this:
 
-```{eval-rst}
-.. csv-table:: Bit Vectors for A, B, C
-  :header: Class, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
-
-  A, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0
-  B, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0
-  C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0
-```
+:::{table} Bit Vectors for A, B, C
+| Class | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
+|-------|---|---|---|---|---|---|---|---|---|---|----|----|----|----|----|
+| A | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
+| B | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+| C | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
+:::
 
 Bit vectors are represented in the object file as byte arrays. By loading
 from indexed offsets into the byte array and applying a mask, a program can
@@ -73,7 +71,7 @@ relevant bit is set in the bit vector.
 
 For example on x86 a typical virtual call may look like this:
 
-```none
+```objdump
 ca7fbb:       48 8b 0f                mov    (%rdi),%rcx
 ca7fbe:       48 8d 15 c3 42 fb 07    lea    0x7fb42c3(%rip),%rdx
 ca7fc5:       48 89 c8                mov    %rcx,%rax
@@ -113,14 +111,13 @@ of the region covered by ones, and perform the bit vector check using a
 truncated version of the bit vector. For example, the bit vectors for our
 example class hierarchy will be emitted like this:
 
-```{eval-rst}
-.. csv-table:: Bit Vectors for A, B, C
-  :header: Class, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
-
-  A,  ,  , 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,  ,
-  B,  ,  ,  ,  ,  ,  ,  , 1,  ,  ,  ,  ,  ,  ,
-  C,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  , 1,  ,
-```
+:::{table} Bit Vectors for A, B, C
+| Class | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
+|-------|---|---|---|---|---|---|---|---|---|---|----|----|----|----|----|
+| A |   |   | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 |   |   |
+| B |   |   |   |   |   |   |   | 1 |   |   |   |   |   |   |   |
+| C |   |   |   |   |   |   |   |   |   |   |   |   | 1 |   |   |
+:::
 
 #### Short Inline Bit Vectors
 
@@ -130,7 +127,7 @@ of the bit vector.
 
 If the bit vector fits in 32 bits, the code looks like this:
 
-```none
+```objdump
  dc2:       48 8b 03                mov    (%rbx),%rax
  dc5:       48 8d 15 14 1e 00 00    lea    0x1e14(%rip),%rdx
  dcc:       48 89 c1                mov    %rax,%rcx
@@ -149,7 +146,7 @@ If the bit vector fits in 32 bits, the code looks like this:
 
 Or if the bit vector fits in 64 bits:
 
-```none
+```objdump
 11a6:       48 8b 03                mov    (%rbx),%rax
 11a9:       48 8d 15 d0 28 00 00    lea    0x28d0(%rip),%rdx
 11b0:       48 89 c1                mov    %rax,%rcx
@@ -170,7 +167,7 @@ Or if the bit vector fits in 64 bits:
 If the bit vector consists of a single bit, there is only one possible
 virtual table, and the check can consist of a single equality comparison:
 
-```none
+```objdump
 9a2:   48 8b 03                mov    (%rbx),%rax
 9a5:   48 8d 0d a4 13 00 00    lea    0x13a4(%rip),%rcx
 9ac:   48 39 c8                cmp    %rcx,%rax
@@ -221,29 +218,25 @@ struct C : A {
 
 The virtual tables will be laid out like this:
 
-```{eval-rst}
-.. csv-table:: Virtual Table Layout for A, B, C
-  :header: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
-
-  A::offset-to-top, &A::rtti, &A::f1, &A::f2, B::offset-to-top, &B::rtti, &B::f1, &B::f2, &B::f3, &B::f4, &B::f5, &B::f6, C::offset-to-top, &C::rtti, &C::f1, &C::f2
-```
+:::{table} Virtual Table Layout for A, B, C
+| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
+|---|---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|
+| A::offset-to-top | &A::rtti | &A::f1 | &A::f2 | B::offset-to-top | &B::rtti | &B::f1 | &B::f2 | &B::f3 | &B::f4 | &B::f5 | &B::f6 | C::offset-to-top | &C::rtti | &C::f1 | &C::f2 |
+:::
 
 Notice that each address point for A is separated by 4 words. This lets us
 emit a compressed bit vector for A that looks like this:
 
-```{eval-rst}
-.. csv-table::
-  :header: 2, 6, 10, 14
-
-  1, 1, 0, 1
-```
+| 2 | 6 | 10 | 14 |
+|---|---|----|----|
+| 1 | 1 | 0 | 1 |
 
 At call sites, the compiler will strengthen the alignment requirements by
 using a different rotate count. For example, on a 64-bit machine where the
 address points are 4-word aligned (as in A from our example), the `rol`
 instruction may look like this:
 
-```none
+```objdump
 dd2:       48 c1 c1 3b             rol    $0x3b,%rcx
 ```
 
@@ -270,7 +263,8 @@ likely to occur if the virtual tables are padded.
 
 ### Forward-Edge CFI for Virtual Calls by Interleaving Virtual Tables
 
-Dimitar et. al. proposed a novel approach that interleaves virtual tables in [^footnote-1].
+Dimitar et. al. proposed a novel approach that interleaves virtual tables in
+[^ivtbl].
 This approach is more efficient in terms of space because padding and bit vectors are no longer needed.
 At the same time, it is also more efficient in terms of performance because in the interleaved layout
 address points of the virtual tables are consecutive, thus the validity check of a virtual
@@ -280,10 +274,10 @@ At a high level, the interleaving scheme consists of three steps: 1) split virtu
 separate virtual tables, 2) order virtual tables by a pre-order traversal of the class hierarchy
 and 3) interleave virtual tables.
 
-The interleaving scheme implemented in LLVM is inspired by [^footnote-1] but has its own
+The interleaving scheme implemented in LLVM is inspired by [^ivtbl] but has its own
 enhancements (more in [Interleave virtual tables]).
 
-[^footnote-1]: [Protecting C++ Dynamic Dispatch Through VTable Interleaving](https://cseweb.ucsd.edu/~lerner/papers/ivtbl-ndss16.pdf). Dimitar Bounov, Rami Gökhan Kıcı, Sorin Lerner.
+[^ivtbl]: [Protecting C++ Dynamic Dispatch Through VTable Interleaving](https://cseweb.ucsd.edu/~lerner/papers/ivtbl-ndss16.pdf). Dimitar Bounov, Rami Gökhan Kıcı, Sorin Lerner.
 
 #### Split virtual table groups into separate virtual tables
 
@@ -341,54 +335,46 @@ For each virtual function the distance between a virtual table entry for this fu
 address point is always the same. This property ensures that dynamic dispatch still works with the interleaving layout.
 
 Note that the interleaving scheme in the CFI implementation guarantees both properties above whereas the original scheme proposed
-in [^footnote-1] only guarantees the second property.
+in [^ivtbl] only guarantees the second property.
 
 To illustrate how the interleaving algorithm works, let us continue with the running example.
 The algorithm first separates all the virtual table entries into two work lists. To do so,
 it starts by allocating two work lists, one initialized with all the offset-to-top entries of virtual tables in the order
 computed in the last step, one initialized with all the RTTI entries in the same order.
 
-```{eval-rst}
-.. csv-table:: Work list 1 Layout
-  :header: 0, 1, 2, 3
+:::{table} Work list 1 Layout
+| 0 | 1 | 2 | 3 |
+|---|---|---|---|
+| A::offset-to-top | B::offset-to-top | D::offset-to-top | C::offset-to-top |
+:::
 
-  A::offset-to-top, B::offset-to-top, D::offset-to-top, C::offset-to-top
-
-```
-
-```{eval-rst}
-.. csv-table:: Work list 2 layout
-  :header: 0, 1, 2, 3,
-
-  &A::rtti, &B::rtti, &D::rtti, &C::rtti
-```
+:::{table} Work list 2 layout
+| 0 | 1 | 2 | 3 |
+|---|---|---|---|
+| &A::rtti | &B::rtti | &D::rtti | &C::rtti |
+:::
 
 Then for each virtual function the algorithm goes through all the virtual tables in the previously computed order
 to collect all the related entries into a virtual function list.
 After this step, there are the following virtual function lists:
 
-```{eval-rst}
-.. csv-table:: f1 list
-  :header: 0, 1, 2, 3
+:::{table} f1 list
+| 0 | 1 | 2 | 3 |
+|---|---|---|---|
+| &A::f1 | &B::f1 | &D::f1 | &C::f1 |
+:::
 
-  &A::f1, &B::f1, &D::f1, &C::f1
+:::{table} f2 list
+| 0 | 1 |
+|---|---|
+| &B::f2 | &D::f2 |
+:::
 
-```
-
-```{eval-rst}
-.. csv-table:: f2 list
-  :header: 0, 1
-
-  &B::f2, &D::f2
-
-```
-
-```{eval-rst}
-.. csv-table:: f3 list
-  :header: 0
-
-  &C::f3
-```
+:::{table} f3 list
+| 0 |
+|---|
+| &C::f3 |
+:::
 
 Next, the algorithm picks the longest remaining virtual function list and appends the whole list to the shortest work list
 until no function lists are left, and pads the shorter work list so that they are of the same length.
@@ -396,30 +382,26 @@ In the example, f1 list will be first added to work list 1, then f2 list will be
 to work list 2, and finally f3 list will be added to the work list 2. Since work list 1 now has one more entry than
 work list 2, a padding entry is added to the latter. After this step, the two work lists look like:
 
-```{eval-rst}
-.. csv-table:: Work list 1 Layout
-  :header: 0, 1, 2, 3, 4, 5, 6, 7
-
-  A::offset-to-top, B::offset-to-top, D::offset-to-top, C::offset-to-top, &A::f1, &B::f1, &D::f1, &C::f1
+:::{table} Work list 1 Layout
+| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+|---|---|---|---|---|---|---|---|
+| A::offset-to-top | B::offset-to-top | D::offset-to-top | C::offset-to-top | &A::f1 | &B::f1 | &D::f1 | &C::f1 |
+:::
 
-```
-
-```{eval-rst}
-.. csv-table:: Work list 2 layout
-  :header: 0, 1, 2, 3, 4, 5, 6, 7
-
-  &A::rtti, &B::rtti, &D::rtti, &C::rtti, &B::f2, &D::f2, &C::f3, padding
-```
+:::{table} Work list 2 layout
+| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+|---|---|---|---|---|---|---|---|
+| &A::rtti | &B::rtti | &D::rtti | &C::rtti | &B::f2 | &D::f2 | &C::f3 | padding |
+:::
 
 Finally, the algorithm merges the two work lists into the interleaved layout by alternatingly
 moving the head of each list to the final layout. After this step, the final interleaved layout looks like:
 
-```{eval-rst}
-.. csv-table:: Interleaved layout
-  :header: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
-
-  A::offset-to-top, &A::rtti, B::offset-to-top, &B::rtti, D::offset-to-top, &D::rtti, C::offset-to-top, &C::rtti, &A::f1, &B::f2, &B::f1, &D::f2, &D::f1, &C::f3, &C::f1, padding
-```
+:::{table} Interleaved layout
+| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
+|---|---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|
+| A::offset-to-top | &A::rtti | B::offset-to-top | &B::rtti | D::offset-to-top | &D::rtti | C::offset-to-top | &C::rtti | &A::f1 | &B::f2 | &B::f1 | &D::f2 | &D::f1 | &C::f3 | &C::f1 | padding |
+:::
 
 In the above interleaved layout, each virtual table's offset-to-top and RTTI are always adjacent, which shows that the layout has the first property.
 For the second property, let us look at f2 as an example. In the interleaved layout,
@@ -452,7 +434,7 @@ In more concrete terms, suppose we have three functions `f`, `g`,
 `h` which are all of the same type, and a function foo that returns their
 addresses:
 
-```none
+```gas
 f:
 mov 0, %eax
 ret
@@ -474,7 +456,7 @@ ret
 
 Our jump table will (conceptually) look like this:
 
-```none
+```gas
 f:
 jmp .Ltmp0 ; 5 bytes
 int3       ; 1 byte
@@ -533,19 +515,21 @@ Assuming the following setup: the binary consists of several
 instrumented and several uninstrumented DSOs. Some of them may be
 dlopen-ed/dlclose-d periodically, even frequently.
 
-> - Calls made from uninstrumented DSOs are not checked and just work.
-> - Calls inside any instrumented DSO are fully protected.
-> - Calls between different instrumented DSOs are also protected, with
->   : a performance penalty (in addition to the monolithic CFI
->     overhead).
-> - Calls from an instrumented DSO to an uninstrumented one are
->   : unchecked and just work, with performance penalty.
-> - Calls from an instrumented DSO outside of any known DSO are
->   : detected as CFI violations.
+- Calls made from uninstrumented DSOs are not checked and just work.
+- Calls inside any instrumented DSO are fully protected.
+
+Calls between different instrumented DSOs are also protected, with
+: a performance penalty (in addition to the monolithic CFI overhead).
+
+Calls from an instrumented DSO to an uninstrumented one are
+: unchecked and just work, with performance penalty.
+
+Calls from an instrumented DSO outside of any known DSO are
+: detected as CFI violations.
 
 In the monolithic scheme a call site is instrumented as
 
-```none
+```text
 if (!InlinedFastCheck(f))
   abort();
 call *f
@@ -553,7 +537,7 @@ call *f
 
 In the cross-DSO scheme it becomes
 
-```none
+```text
 if (!InlinedFastCheck(f))
   __cfi_slowpath(CallSiteTypeId, f);
 call *f
@@ -568,10 +552,10 @@ mapping from a type to an identifier is an ABI detail. In the current,
 experimental, implementation the identifier of type T is calculated as
 follows:
 
-> - Obtain the mangled name for "typeinfo name for T".
-> - Calculate MD5 hash of the name as a string.
-> - Reinterpret the first 8 bytes of the hash as a little-endian
->   64-bit integer.
+- Obtain the mangled name for "typeinfo name for T".
+- Calculate MD5 hash of the name as a string.
+- Reinterpret the first 8 bytes of the hash as a little-endian
+  64-bit integer.
 
 It is possible, but unlikely, that collisions in the
 `CallSiteTypeId` hashing will result in weaker CFI checks that would
@@ -583,7 +567,7 @@ In the general case, only the target DSO knows whether the call to
 function `f` with type `CallSiteTypeId` is valid or not. To
 export this information, every DSO implements
 
-```none
+```c++
 void __cfi_check(uint64 CallSiteTypeId, void *TargetAddr, void *DiagData)
 ```
 
@@ -611,17 +595,17 @@ bytes) of memory. The table is kept readonly most of the time.
 
 There are 3 types of shadow values:
 
-> - Address in a CFI-instrumented DSO.
-> - Unchecked address (a “trusted” non-instrumented DSO). Encoded as
->   value 0xFFFF.
-> - Invalid address (everything else). Encoded as value 0.
+- Address in a CFI-instrumented DSO.
+- Unchecked address (a “trusted” non-instrumented DSO). Encoded as
+  value 0xFFFF.
+- Invalid address (everything else). Encoded as value 0.
 
 For a CFI-instrumented DSO, a shadow value encodes the address of the
 \_\_cfi_check function for all call targets in the corresponding memory
 page. If Addr is the target address, and V is the shadow value, then
 the address of \_\_cfi_check is calculated as
 
-```none
+```text
 __cfi_check = AlignUpTo(Addr, 4096) - (V + 1) * 4096
 ```
 
@@ -633,7 +617,7 @@ them.
 
 The slow path check is implemented in a runtime support library as
 
-```none
+```c++
 void __cfi_slowpath(uint64 CallSiteTypeId, void *TargetAddr)
 void __cfi_slowpath_diag(uint64 CallSiteTypeId, void *TargetAddr, void *DiagData)
 ```
@@ -751,7 +735,7 @@ and is properly aligned, and if the checks fail it will either trap (in monolith
 or call the slow path function (cross-DSO scheme).
 The bit vector lookup is probably too complex for a hardware implementation.
 
-```none
+```c++
 //  This instruction checks that 'Ptr'
 //   * is aligned by (1 << kAlignment) and
 //   * is inside [kRangeBeg, kRangeBeg+(kRangeSize<<kAlignment))
@@ -798,4 +782,3 @@ ability to protect against invalid casts between polymorphic types.
 [rfg]: https://xlab.tencent.com/en/2016/11/02/return-flow-guard
 [safestack]: https://clang.llvm.org/docs/SafeStack.html
 [type metadata]: https://llvm.org/docs/TypeMetadata.html
-
diff --git a/clang/docs/DataFlowSanitizerDesign.md b/clang/docs/DataFlowSanitizerDesign.md
index 764fbdbceaf7a..9cc468de4147c 100644
--- a/clang/docs/DataFlowSanitizerDesign.md
+++ b/clang/docs/DataFlowSanitizerDesign.md
@@ -212,7 +212,7 @@ identified by checking for nonzero labels in nominally unlabelled programs.
 
 ## Implementing the ABI list
 
-The [ABI list](DataFlowSanitizer.html#abi-list) provides a list of functions
+The {ref}`ABI list <abi-list>` provides a list of functions
 which conform to the native ABI, each of which is callable from an instrumented
 program. This is implemented by replacing each reference to a native ABI
 function with a reference to a function which uses the instrumented ABI.
@@ -265,4 +265,3 @@ of statically detecting instances of this problem is to append the suffix
 This will not catch every such problem; in particular function pointers passed
 across the instrumented-native barrier cannot be used on the other side.
 These problems could potentially be caught dynamically.
-
diff --git a/clang/docs/HLSL/EntryFunctions.md b/clang/docs/HLSL/EntryFunctions.md
index e82d3513151f8..706aa6bf4f007 100644
--- a/clang/docs/HLSL/EntryFunctions.md
+++ b/clang/docs/HLSL/EntryFunctions.md
@@ -57,7 +57,7 @@ Below is example IR that represents the planned implementation, subject to
 change as the `llvm.dx.store.output` and `llvm.dx.load.input` intrinsics are
 not yet implemented.
 
-```none
+```llvm
 ; Function Attrs: norecurse
 define void @main() #1 {
    entry:
@@ -67,4 +67,3 @@ define void @main() #1 {
    ret void
 }
 ```
-
diff --git a/clang/docs/HLSL/ExpectedDifferences.md b/clang/docs/HLSL/ExpectedDifferences.md
index c5f0e8508e602..a73a208afb3c6 100644
--- a/clang/docs/HLSL/ExpectedDifferences.md
+++ b/clang/docs/HLSL/ExpectedDifferences.md
@@ -138,7 +138,7 @@ precision relative to the other overloads (as FXC does) or generating code
 that will fail validation (as DXC does).
 :::
 
-(multi-argument-overloads)=
+(multi_argument_overloads)=
 
 ### Multi-Argument Overloads
 
diff --git a/clang/docs/HLSL/FunctionCalls.md b/clang/docs/HLSL/FunctionCalls.md
index 045a305ed9cc8..fd06cbca55c51 100644
--- a/clang/docs/HLSL/FunctionCalls.md
+++ b/clang/docs/HLSL/FunctionCalls.md
@@ -22,7 +22,7 @@ HLSL has 3 keywords which denote the parameter semantics (`in`, `out` and
 `inout`). In a function declaration a parameter may be annotated any of the
 following ways:
 
-1. \<no parameter annotation> - denotes input
+1. `<no parameter annotation>` - denotes input
 2. `in` - denotes input
 3. `out` - denotes output
 4. `in out` - denotes input and output
@@ -336,4 +336,3 @@ simplifies the code generation. IR generation does the following:
   \* For `out` arguments, emit an uninitialized temporary.
 - Emit the call
 - Emit the write-back BinaryOperator expression.
-
diff --git a/clang/docs/HardwareAssistedAddressSanitizerDesign.md b/clang/docs/HardwareAssistedAddressSanitizerDesign.md
index 2cc2b831006af..5d85270243b1c 100644
--- a/clang/docs/HardwareAssistedAddressSanitizerDesign.md
+++ b/clang/docs/HardwareAssistedAddressSanitizerDesign.md
@@ -76,7 +76,7 @@ convention that
 
 Currently, the following sequence is used:
 
-```none
+```text
 // int foo(int *a) { return *a; }
 // clang -O2 --target=aarch64-linux-android30 -fsanitize=hwaddress -S -o - load.c
 [...]
@@ -145,27 +145,27 @@ but could be optional.
 Most globals in HWASAN instrumented code are tagged. This is accomplished
 using the following mechanisms:
 
-> - The address of each global has a static tag associated with it. The first
->   defined global in a translation unit has a pseudorandom tag associated
->   with it, based on the hash of the file path. Subsequent global tags are
->   incremental from the previously-assigned tag.
-> - The global's tag is added to its symbol address in the object file's symbol
->   table. This causes the global's address to be tagged when its address is
->   taken.
-> - When the address of a global is taken directly (i.e. not via the GOT), a special
->   instruction sequence needs to be used to add the tag to the address,
->   because the tag would otherwise take the address outside of the small code
->   model (4GB on AArch64). No changes are required when the address is taken
->   via the GOT because the address stored in the GOT will contain the tag.
-> - An associated `hwasan_globals` section is emitted for each tagged global,
->   which indicates the address of the global, its size and its tag. These
->   sections are concatenated by the linker into a single `hwasan_globals`
->   section that is enumerated by the runtime (via an ELF note) when a binary
->   is loaded and the memory is tagged accordingly.
+- The address of each global has a static tag associated with it. The first
+  defined global in a translation unit has a pseudorandom tag associated
+  with it, based on the hash of the file path. Subsequent global tags are
+  incremental from the previously-assigned tag.
+- The global's tag is added to its symbol address in the object file's symbol
+  table. This causes the global's address to be tagged when its address is
+  taken.
+- When the address of a global is taken directly (i.e. not via the GOT), a special
+  instruction sequence needs to be used to add the tag to the address,
+  because the tag would otherwise take the address outside of the small code
+  model (4GB on AArch64). No changes are required when the address is taken
+  via the GOT because the address stored in the GOT will contain the tag.
+- An associated `hwasan_globals` section is emitted for each tagged global,
+  which indicates the address of the global, its size and its tag. These
+  sections are concatenated by the linker into a single `hwasan_globals`
+  section that is enumerated by the runtime (via an ELF note) when a binary
+  is loaded and the memory is tagged accordingly.
 
 A complete example is given below:
 
-```none
+```text
 // int x = 1; int *f() { return &x; }
 // clang -O2 --target=aarch64-linux-android30 -fsanitize=hwaddress -S -o - global.c
 
@@ -211,10 +211,10 @@ HWASAN uses its own LLVM IR Attribute `sanitize_hwaddress` and a matching
 C function attribute. An alternative would be to re-use ASAN's attribute
 `sanitize_address`. The reasons to use a separate attribute are:
 
-> - Users may need to disable ASAN but not HWASAN, or vise versa,
->   because the tools have different trade-offs and compatibility issues.
-> - LLVM (ideally) does not use flags to decide which pass is being used,
->   ASAN or HWASAN are being applied, based on the function attributes.
+- Users may need to disable ASAN but not HWASAN, or vise versa,
+  because the tools have different trade-offs and compatibility issues.
+- LLVM (ideally) does not use flags to decide which pass is being used,
+  ASAN or HWASAN are being applied, based on the function attributes.
 
 This does mean that users of HWASAN may need to add the new attribute
 to the code that already uses the old attribute.
@@ -287,4 +287,3 @@ implement page aliasing.
 [linear address masking]: https://software.intel.com/content/www/us/en/develop/download/intel-architecture-instruction-set-extensions-programming-reference.html
 [sparc adi]: https://lazytyped.blogspot.com/2017/09/getting-started-with-adi.html
 [watchdog]: https://www.cis.upenn.edu/acg/papers/isca12_watchdog.pdf
-
diff --git a/clang/docs/ItaniumMangleAbiTags.md b/clang/docs/ItaniumMangleAbiTags.md
index a3b07b8fe9b05..3ce98372edb27 100644
--- a/clang/docs/ItaniumMangleAbiTags.md
+++ b/clang/docs/ItaniumMangleAbiTags.md
@@ -22,13 +22,13 @@ Tags on an inline namespace are called "implicit tags", all other tags are
 
 ## Mangling
 
-All tags that are "active" on an \<unqualified-name> are emitted after the
-\<unqualified-name>, before \<template-args> or \<discriminator>, and are part of
-the same \<substitution> the \<unqualified-name> is.
+All tags that are "active" on an `<unqualified-name>` are emitted after the
+`<unqualified-name>`, before `<template-args>` or `<discriminator>`, and are
+part of the same `<substitution>` the `<unqualified-name>` is.
 
 They are mangled as:
 
-```none
+```text
 <abi-tags> ::= <abi-tag>*   # sort by name
 <abi-tag> ::= B <tag source-name>
 ```
@@ -49,7 +49,7 @@ enum), the explicit tags are the active tags.
 For variables and functions, the active tags are the explicit tags plus any
 "required tags" which are not in the "available tags" set:
 
-```none
+```text
 derived-tags := (required-tags - available-tags)
 active-tags := explicit-tags + derived-tags
 ```
@@ -84,16 +84,16 @@ A variable requires any implicit or explicit tag used in its type.
 ## Available tags
 
 All tags used in the prefix and in the template arguments for a name are
-available. Also, for functions, all tags from the \<bare-function-type>
+available. Also, for functions, all tags from the `<bare-function-type>`
 (which might include the return type for template functions) are available.
 
-For \<local-name>s all active tags used in the local part (\<function-
-encoding>) are available, but not implicit tags which were not active.
+For `<local-name>`s all active tags used in the local part
+(`<function-encoding>`) are available, but not implicit tags which were not
+active.
 
-Implicit and explicit tags used in the \<unqualified-name> for a function (as
+Implicit and explicit tags used in the `<unqualified-name>` for a function (as
 in the type of a cast operator) are NOT available.
 
 Example: a cast operator to std::string (which is
-std::\_\_cxx11::basic_string\<...>) will use 'cxx11' as an active tag, as it is
+`std::__cxx11::basic_string<...>`) will use 'cxx11' as an active tag, as it is
 required from the return type `std::string` but not available.
-

>From e8eace155bd1a38f17c703e3e9f7c99433d8e03b Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rkleckner at nvidia.com>
Date: Fri, 7 Aug 2026 21:26:35 +0000
Subject: [PATCH 3/3] Fix defects after reviewing HTML

---
 clang/docs/AutomaticReferenceCounting.md |   6 +-
 clang/docs/CIR/CleanupAndEHDesign.md     |  64 +++++------
 clang/docs/CommandGuide/clang.md         | 132 +++++++++++++++++------
 clang/docs/ControlFlowIntegrityDesign.md |  15 ++-
 4 files changed, 139 insertions(+), 78 deletions(-)

diff --git a/clang/docs/AutomaticReferenceCounting.md b/clang/docs/AutomaticReferenceCounting.md
index 26dc68c55d3fe..5e09af834e3a3 100644
--- a/clang/docs/AutomaticReferenceCounting.md
+++ b/clang/docs/AutomaticReferenceCounting.md
@@ -188,9 +188,9 @@ If a change increases the expressiveness of the language, for example by
 lifting a restriction or by adding new syntax, the change will be annotated
 with a revision marker, like so:
 
-ARC applies to Objective-C pointer types, block pointer types, and
-{when-revised}`[beginning Apple 8.0, LLVM 3.8]` {revision}`BPTRs declared
-within` `extern "BCPL"` blocks.
+> ARC applies to Objective-C pointer types, block pointer types, and
+> {when-revised}`[beginning Apple 8.0, LLVM 3.8]` {revision}`BPTRs declared
+> within` `extern "BCPL"` blocks.
 
 For now, it is sensible to version this document by the releases of its sole
 implementation (and its host project), clang. "LLVM X.Y" refers to an
diff --git a/clang/docs/CIR/CleanupAndEHDesign.md b/clang/docs/CIR/CleanupAndEHDesign.md
index d616a4bf213ba..092568f04b869 100644
--- a/clang/docs/CIR/CleanupAndEHDesign.md
+++ b/clang/docs/CIR/CleanupAndEHDesign.md
@@ -111,7 +111,7 @@ void someFunc() {
 
 **CIR**
 
-```text
+```mlir
 cir.func @someFunc() {
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -156,7 +156,7 @@ void someFunc() {
 
 **CIR**
 
-```text
+```mlir
 cir.func @someFunc() {
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   %1 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c2", init]
@@ -228,7 +228,7 @@ int someFunc() {
 
 **CIR**
 
-```text
+```mlir
 cir.func @someFunc() -> !s32i {
   %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
   %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init]
@@ -321,7 +321,7 @@ public:
 
 **CIR**
 
-```text
+```mlir
 cir.func @_ZN7DerivedC2Ev(%arg0: !cir.ptr<!rec_Derived>) {
   %0 = cir.alloca !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>, ["this", init]
   cir.store %arg0, %0 : !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>
@@ -371,7 +371,7 @@ The first operation in a catch handler region must be a `cir.begin_catch`
 operation. This must be followed by a `cir.cleanup.scope` operation,
 with the `cir.end_catch` operation in its cleanup region.
 
-```text
+```mlir
 cir.try {
   cir.call exception @function() : () -> ()
   cir.yield
@@ -411,7 +411,7 @@ void someFunc() {
 
 **CIR**
 
-```text
+```mlir
 cir.func @someFunc(){
   %0 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"]
   cir.scope {
@@ -465,7 +465,7 @@ void someFunc() {
 
 **CIR**
 
-```text
+```mlir
 cir.func @someFunc(){
   %0 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"]
   cir.scope {
@@ -525,7 +525,7 @@ void someFunc() {
 
 **CIR**
 
-```text
+```mlir
 cir.func @someFunc(){
   cir.scope {
     %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
@@ -575,7 +575,7 @@ void someFunc() {
 
 **CIR**
 
-```text
+```mlir
 cir.func @someFunc(){
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   %1 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"]
@@ -638,7 +638,7 @@ high-level CIR representation, we have a single operation,
 cleanup needed is entirely within the scope of this operation, we can
 represent the cleanup by adding a cleanup region to this operation.
 
-```text
+```mlir
 cir.array.ctor(%0 : !cir.ptr<!cir.array<!rec_SomeClass x 16>>) {
 ^bb0(%arg0: !cir.ptr<!rec_SomeClass>):
   cir.call @_ZN9SomeClassC1Ev(%arg0) : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -657,7 +657,7 @@ be expanded to a loop within a `cir.cleanup.scope` for the
 initialization, and a loop within the cleanup scope's cleanup region to
 perform the partial array cleanup, as follows
 
-```text
+```mlir
 cir.scope {
   %1 = cir.const #cir.int<16> : !u64i
   %2 = cir.cast array_to_ptrdecay %0 : !cir.ptr<!cir.array<!rec_SomeClass x 16>> -> !cir.ptr<!rec_SomeClass>
@@ -741,7 +741,7 @@ cleanup, the call will be converted to a `cir.try_call` operation, with
 normal and unwind destinations. The first operation in the unwind
 destination block must be a `cir.eh.initiate` operation.
 
-```text
+```mlir
 %eh_token = cir.eh.initiate [cleanup]
 ```
 
@@ -754,7 +754,7 @@ exception that was thrown and is passed as the argument to the
 `cir.begin_cleanup`, `cir.begin_catch`, and `cir.eh.dispatch`
 operations.
 
-```text
+```mlir
 cir.eh.dispatch %eh_token : !cir.eh_token [
   catch (#cir.global_view<@_ZTIi> : !u32i) : ^bb6
   catch_all : ^bb7
@@ -782,7 +782,7 @@ by a branch to the cleanup block, passing the EH token as an operand to
 the block. The cleanup block will begin with a call to
 `cir.begin_cleanup` which returns a cleanup token.
 
-```text
+```mlir
 ^bb4 (%eh_token : !cir.eh_token):
   %cleanup_token = cir.begin_cleanup %eh_token : !cir.eh_token -> !cir.cleanup_token
 ```
@@ -790,7 +790,7 @@ the block. The cleanup block will begin with a call to
 This is followed by the operations to perform the cleanup and then a
 cir.end_cleanup operation.
 
-```text
+```mlir
 cir.end_cleanup(%cleanup_token : !cir.cleanup_token)
 ```
 
@@ -823,7 +823,7 @@ void someFunc() {
 
 **High-level CIR**
 
-```text
+```mlir
 cir.func @someFunc(){
   cir.scope {
     %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
@@ -853,7 +853,7 @@ cir.func @someFunc(){
 
 **Flattened CIR**
 
-```text
+```mlir
 cir.func @someFunc(){
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -912,7 +912,7 @@ void someFunc() {
 
 **High-level CIR**
 
-```text
+```mlir
 cir.func @someFunc(){
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -929,7 +929,7 @@ cir.func @someFunc(){
 
 **Flattened CIR**
 
-```text
+```mlir
 cir.func @someFunc(){
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -988,7 +988,7 @@ void someFunc() {
 
 **CIR**
 
-```text
+```mlir
 cir.func @someFunc(){
   %0 = cir.alloca !rec_ThrowingDtor, !cir.ptr<!rec_ThrowingDtor>, ["c", init]
   cir.call @_ZN12ThrowingDtorC1Ev(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
@@ -1005,7 +1005,7 @@ cir.func @someFunc(){
 
 **Flattened CIR**
 
-```text
+```mlir
 cir.func @someFunc(){
   %0 = cir.alloca !rec_ThrowingDtor, !cir.ptr<!rec_ThrowingDtor>, ["c", init]
   cir.call @_ZN12ThrowingDtorC1Ev(%0) : (!cir.ptr<!rec_ThrowingDtor>) -> ()
@@ -1061,7 +1061,7 @@ int someFunc() {
 
 **CIR**
 
-```text
+```mlir
 cir.func @someFunc() -> !s32i {
   %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
   %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init]
@@ -1112,7 +1112,7 @@ cir.func @someFunc() -> !s32i {
 
 **Flattened CIR**
 
-```text
+```mlir
 cir.func @someFunc() -> !s32i {
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__cleanup_dest_slot "]
@@ -1236,7 +1236,7 @@ followed by `std::terminate()`) and then an unreachable operation.
 The only operation that is specific to Itanium exception handling is
 `cir.eh.landingpad`.
 
-```text
+```mlir
 %exn_ptr_0, %type_id = cir.eh.landingpad [@_ZTISt9exception] : !cir.ptr<!void>, !u32i
 ```
 
@@ -1249,7 +1249,7 @@ handler performs cleanup but does not catch any exceptions.
 
 **Flattened CIR**
 
-```text
+```mlir
 cir.func @someFunc(){
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -1324,7 +1324,7 @@ normal continuation block (`^bb8`).
 
 **Flattened CIR**
 
-```text
+```mlir
 cir.func @someFunc(){
   cir.try_call @f() ^bb1, ^bb2
 ^bb1
@@ -1413,7 +1413,7 @@ instruction in LLVM IR and have the same semantics. The first operation
 in the unwind destination of a `cir.try_call` must be either
 `cir.eh.catchswitch` or `cir.cleanuppad`.
 
-```text
+```mlir
 %4 = cir.eh.catchswitch within none [^bb2, ^bb3] unwind to caller
 ```
 
@@ -1428,7 +1428,7 @@ handled further in the current function. This operation returns a token
 that is used as the operand for `cir.catchpad` operations associated
 with this switch.
 
-```text
+```mlir
 %5 = cir.cleanuppad within none []
 ```
 
@@ -1440,7 +1440,7 @@ handlers, the personality function will be `__CxxFrameHandler3` and the
 argument list will be empty. This operation returns a token that is used
 as the operand for the associated `cir.cleanupret` operation.
 
-```text
+```mlir
 cir.cleanupret from %5 unwind to ^bb7
 ```
 
@@ -1463,7 +1463,7 @@ operand for the associated `cir.catchret` operation or as the parent for
 any `cir.catchswitch` or `cir.cleanuppad` operations that are nested
 within this catch handler.
 
-```text
+```mlir
 cir.catchret from %8 to ^bb8
 ```
 
@@ -1475,7 +1475,7 @@ block at which excution should be resumed.
 
 **Flattened CIR**
 
-```text
+```mlir
 cir.func @someFunc() {
   %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init]
   cir.try_call @_ZN9SomeClassC1Ev(%0) ^bb1, ^bb3 : (!cir.ptr<!rec_SomeClass>) -> ()
@@ -1537,7 +1537,7 @@ cir.func @someFunc() #personality_fn = @ __CxxFrameHandler3 {
 
 **Flattened CIR**
 
-```text
+```mlir
 cir.func @someFunc(){
   cir.try_call @f() ^bb1, ^bb2
 ^bb1
diff --git a/clang/docs/CommandGuide/clang.md b/clang/docs/CommandGuide/clang.md
index ae72e95d100f6..5fdd0d45fad0c 100644
--- a/clang/docs/CommandGuide/clang.md
+++ b/clang/docs/CommandGuide/clang.md
@@ -103,56 +103,120 @@ Specify the language standard to compile for.
 
 Supported values for the C language are:
 
-- `c89`, `c90`, `iso9899:1990`: ISO C 1990
-- `iso9899:199409`: ISO C 1990 with amendment 1
-- `gnu89`, `gnu90`: ISO C 1990 with GNU extensions
-- `c99`, `iso9899:1999`: ISO C 1999
-- `gnu99`: ISO C 1999 with GNU extensions
-- `c11`, `iso9899:2011`: ISO C 2011
-- `gnu11`: ISO C 2011 with GNU extensions
-- `c17`, `iso9899:2017`: ISO C 2017
-- `gnu17`: ISO C 2017 with GNU extensions
-- `c23`, `iso9899:2024`: ISO C 2023
-- `gnu23`: ISO C 2023 with GNU extensions
-- `c2y`: ISO C 202y
-- `gnu2y`: ISO C 202y with GNU extensions
+`c89`, `c90`, `iso9899:1990`
+: ISO C 1990
+
+`iso9899:199409`
+: ISO C 1990 with amendment 1
+
+`gnu89`, `gnu90`
+: ISO C 1990 with GNU extensions
+
+`c99`, `iso9899:1999`
+: ISO C 1999
+
+`gnu99`
+: ISO C 1999 with GNU extensions
+
+`c11`, `iso9899:2011`
+: ISO C 2011
+
+`gnu11`
+: ISO C 2011 with GNU extensions
+
+`c17`, `iso9899:2017`
+: ISO C 2017
+
+`gnu17`
+: ISO C 2017 with GNU extensions
+
+`c23`, `iso9899:2024`
+: ISO C 2023
+
+`gnu23`
+: ISO C 2023 with GNU extensions
+
+`c2y`
+: ISO C 202y
+
+`gnu2y`
+: ISO C 202y with GNU extensions
 
 The default C language standard is `gnu17`, except on PS4, where it is
 `gnu99`.
 
 Supported values for the C++ language are:
 
-- `c++98`, `c++03`: ISO C++ 1998 with amendments
-- `gnu++98`, `gnu++03`: ISO C++ 1998 with amendments and GNU extensions
-- `c++11`: ISO C++ 2011 with amendments
-- `gnu++11`: ISO C++ 2011 with amendments and GNU extensions
-- `c++14`: ISO C++ 2014 with amendments
-- `gnu++14`: ISO C++ 2014 with amendments and GNU extensions
-- `c++17`: ISO C++ 2017 with amendments
-- `gnu++17`: ISO C++ 2017 with amendments and GNU extensions
-- `c++20`: ISO C++ 2020 with amendments
-- `gnu++20`: ISO C++ 2020 with amendments and GNU extensions
-- `c++23`: ISO C++ 2023 with amendments
-- `gnu++23`: ISO C++ 2023 with amendments and GNU extensions
-- `c++2c`: Working draft for C++2c
-- `gnu++2c`: Working draft for C++2c with GNU extensions
-- `c++2d`: Working draft for C++2d
-- `gnu++2d`: Working draft for C++2d with GNU extensions
+`c++98`, `c++03`
+: ISO C++ 1998 with amendments
+
+`gnu++98`, `gnu++03`
+: ISO C++ 1998 with amendments and GNU extensions
+
+`c++11`
+: ISO C++ 2011 with amendments
+
+`gnu++11`
+: ISO C++ 2011 with amendments and GNU extensions
+
+`c++14`
+: ISO C++ 2014 with amendments
+
+`gnu++14`
+: ISO C++ 2014 with amendments and GNU extensions
+
+`c++17`
+: ISO C++ 2017 with amendments
+
+`gnu++17`
+: ISO C++ 2017 with amendments and GNU extensions
+
+`c++20`
+: ISO C++ 2020 with amendments
+
+`gnu++20`
+: ISO C++ 2020 with amendments and GNU extensions
+
+`c++23`
+: ISO C++ 2023 with amendments
+
+`gnu++23`
+: ISO C++ 2023 with amendments and GNU extensions
+
+`c++2c`
+: Working draft for C++2c
+
+`gnu++2c`
+: Working draft for C++2c with GNU extensions
+
+`c++2d`
+: Working draft for C++2d
+
+`gnu++2d`
+: Working draft for C++2d with GNU extensions
 
 The default C++ language standard is `gnu++17`.
 
 Supported values for the OpenCL language are:
 
-- `cl1.0`: OpenCL 1.0
-- `cl1.1`: OpenCL 1.1
-- `cl1.2`: OpenCL 1.2
-- `cl2.0`: OpenCL 2.0
+`cl1.0`
+: OpenCL 1.0
+
+`cl1.1`
+: OpenCL 1.1
+
+`cl1.2`
+: OpenCL 1.2
+
+`cl2.0`
+: OpenCL 2.0
 
 The default OpenCL language standard is `cl1.0`.
 
 Supported values for the CUDA language are:
 
-- `cuda`: NVIDIA CUDA(tm)
+`cuda`
+: NVIDIA CUDA(tm)
 :::
 
 :::{option} -stdlib=<library>
diff --git a/clang/docs/ControlFlowIntegrityDesign.md b/clang/docs/ControlFlowIntegrityDesign.md
index d7c5088f06550..ccfb36660ad6b 100644
--- a/clang/docs/ControlFlowIntegrityDesign.md
+++ b/clang/docs/ControlFlowIntegrityDesign.md
@@ -517,15 +517,12 @@ dlopen-ed/dlclose-d periodically, even frequently.
 
 - Calls made from uninstrumented DSOs are not checked and just work.
 - Calls inside any instrumented DSO are fully protected.
-
-Calls between different instrumented DSOs are also protected, with
-: a performance penalty (in addition to the monolithic CFI overhead).
-
-Calls from an instrumented DSO to an uninstrumented one are
-: unchecked and just work, with performance penalty.
-
-Calls from an instrumented DSO outside of any known DSO are
-: detected as CFI violations.
+- Calls between different instrumented DSOs are also protected, with a
+  performance penalty (in addition to the monolithic CFI overhead).
+- Calls from an instrumented DSO to an uninstrumented one are unchecked and
+  just work, with performance penalty.
+- Calls from an instrumented DSO outside of any known DSO are detected as CFI
+  violations.
 
 In the monolithic scheme a call site is instrumented as
 



More information about the llvm-branch-commits mailing list