Add thinlto support. Closes #7493.
diff --git a/docs/markdown/snippets/thinlto.md b/docs/markdown/snippets/thinlto.md
new file mode 100644
index 0000000..ac242a8
--- /dev/null
+++ b/docs/markdown/snippets/thinlto.md
@@ -0,0 +1,27 @@
+## Add support for thin LTO
+
+The `b_lto` option has been updated and now can be set to the value
+`thin`. This enables [thin
+LTO](https://clang.llvm.org/docs/ThinLTO.html) on all compilers where
+it is supported. At the time of writing this means only Clang.
+
+This change is potentially backwards incompatible. If you have
+examined the value of `b_lto` in your build file, note that its type
+has changed from a boolean to a string. Thus comparisons like this:
+
+```meson
+if get_option('b_lto')
+...
+endif
+```
+
+need to be changed to something like this instead:
+
+```meson
+if get_option('b_lto') == 'true'
+...
+endif
+```
+
+This should not affect any comman line invocations as configuring LTO
+with `-Db_lto=true` still works and behaves the same way as before.
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 0f074bb..f6912f1 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -266,7 +266,9 @@
                     True: ['-g']}  # type: T.Dict[bool, T.List[str]]
 
 base_options = {'b_pch': coredata.UserBooleanOption('Use precompiled headers', True),
-                'b_lto': coredata.UserBooleanOption('Use link time optimization', False),
+                'b_lto': coredata.UserComboOption('Use link time optimization',
+                                                  ['false', 'true', 'thin'],
+                                                  'false'),
                 'b_sanitize': coredata.UserComboOption('Code sanitizer to use',
                                                        ['none', 'address', 'thread', 'undefined', 'memory', 'address,undefined'],
                                                        'none'),
@@ -307,8 +309,7 @@
 def get_base_compile_args(options: 'OptionDictType', compiler: 'Compiler') -> T.List[str]:
     args = []  # type T.List[str]
     try:
-        if options['b_lto'].value:
-            args.extend(compiler.get_lto_compile_args())
+        args.extend(compiler.get_lto_compile_args(options['b_lto'].value))
     except KeyError:
         pass
     try:
@@ -940,7 +941,7 @@
             ret.append(arg)
         return ret
 
-    def get_lto_compile_args(self) -> T.List[str]:
+    def get_lto_compile_args(self, lto_type: str) -> T.List[str]:
         return []
 
     def get_lto_link_args(self) -> T.List[str]:
diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py
index acdb352..773d9dc 100644
--- a/mesonbuild/compilers/mixins/clang.py
+++ b/mesonbuild/compilers/mixins/clang.py
@@ -77,6 +77,13 @@
         # so it might change semantics at any time.
         return ['-include-pch', os.path.join(pch_dir, self.get_pch_name(header))]
 
+    def get_lto_compile_args(self, lto_type: str) -> T.List[str]:
+        if lto_type == 'thin':
+            return ['-flto=thin']
+        if lto_type == 'true':
+            return ['-flto']
+        return []
+
     def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
         myargs = []  # type: T.List[str]
         if mode is CompileCheckMode.COMPILE:
diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py
index bb1fc66..5771ad8 100644
--- a/mesonbuild/compilers/mixins/gnu.py
+++ b/mesonbuild/compilers/mixins/gnu.py
@@ -295,8 +295,10 @@
                 return self._split_fetch_real_dirs(line.split('=', 1)[1])
         return []
 
-    def get_lto_compile_args(self) -> T.List[str]:
-        return ['-flto']
+    def get_lto_compile_args(self, lto_type: str) -> T.List[str]:
+        if lto_type != 'false':
+            return ['-flto']
+        return []
 
     def sanitizer_compile_args(self, value: str) -> T.List[str]:
         if value == 'none':
diff --git a/test cases/common/41 options/meson.build b/test cases/common/41 options/meson.build
index 2eccef7..4b38c6f 100644
--- a/test cases/common/41 options/meson.build
+++ b/test cases/common/41 options/meson.build
@@ -18,7 +18,7 @@
 endif
 
 # If the default changes, update test cases/unit/13 reconfigure
-if get_option('b_lto') != false
+if get_option('b_lto') != 'false'
   error('Incorrect value in base option.')
 endif