[libcxx-commits] [libcxx] [libc++] Implements the new FTM header test generator. (PR #134542)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue May 6 09:20:05 PDT 2025


================
@@ -2296,24 +2424,160 @@ def version_header(self) -> str:
             )
         )
 
+    def header_ftm(self, header: str) -> Dict[Std, List[Dict[Ftm, FtmHeaderTest]]]:
+        """Generates the FTM information for a `header`."""
+
+        result = dict()
+        for std in self.std_dialects:
+            result[get_std_number(std)] = list()
+
+        for ftm, values in self.standard_ftms.items():
+            if not header in self.ftm_metadata[ftm].headers:
+                continue
+
+            last_value = None
+            last_entry = None
+
+            for std in self.std_dialects:
+                if not std in values.keys():
+                    result[get_std_number(std)].append(dict({ftm: None}))
+                    continue
+
+                result[get_std_number(std)].append(
+                    dict(
+                        {
+                            ftm: FtmHeaderTest(
+                                values[std],
+                                self.is_implemented(ftm, std),
+                                self.ftm_metadata[ftm].test_suite_guard,
+                            )
+                        }
+                    )
+                )
+
+        return result
+
+
+    def generate_header_test_ftm(self, std: Std, ftm: Ftm, value: FtmHeaderTest) -> str:
+        """Adds a single `ftm` test for C++ `std` based on the status information in `value`.
+
+        When std == None this test is generating the TEST_STD_VER < MIN. Where
+        MIN is the minimum version that has a FTM defined. (In the real data
+        this is 14, since FTM have been introduced in C++14.)
+        """
+
+        if std == None or value == None:
+            return ftm_unavailable_in_dialect.format(
+                ftm=ftm, dialect=self.ftm_metadata[ftm].available_since
+            )
+
+        if not value.implemented:
+            return libcxx_ftm_not_implemented.format(
+                ftm=ftm, value=value.value, dialect=std
+            )
+
+        if self.ftm_metadata[ftm].test_suite_guard:
+            return libcxx_ftm_conditionally_implemented.format(
+                ftm=ftm,
+                value=value.value,
+                dialect=std,
+                condition=self.ftm_metadata[ftm].test_suite_guard,
+            )
+
+        return libcxx_ftm_implemented.format(ftm=ftm, value=value.value, dialect=std)
+
+    def generate_header_test_dialect(
+        self, std: Std, data: List[Dict[Ftm, FtmHeaderTest]]
+    ) -> str:
+        """Returns the body a single `std` for the FTM test of a `header`."""
+        return "".join(
+            self.generate_header_test_ftm(std, ftm, value)
+            for element in data
+            for ftm, value in element.items()
+        )
+
+    def generate_lit_markup(self, header:str) -> str:
+        if not header in lit_markup.keys():
+            return ""
+
+        return "\n".join(f"// {markup}" for markup in lit_markup[header]) + "\n\n"
+
+    def generate_header_test(self, header: str) -> str:
+        """Returns the body for the FTM test of a `header`."""
+
+        return ftm_header_test_file_contents.format(
+            script_name=script_name,
+            lit_markup=self.generate_lit_markup(header),
+            header=header,
+            include=(
+                ftm_header_test_file_include_conditional.format(header=header)
+                if header in self.__unavailable_headers
+                else ftm_header_test_file_include_unconditional.format(header=header)
+            ),
+            data=
+            # FTM block before the first Standard that introduced them.
+            # This test the macros are not available before this version.
+            ftm_header_test_file_dialect_block.format(
+                pp_if="if",
+                operator="<",
+                dialect=self.std_dialects[0][3:],
+                tests=self.generate_header_test_dialect(
+                    None, next(iter(self.header_ftm(header).values()))
+                ),
+            )
+            +
----------------
ldionne wrote:

I think it would help to introduce variables here to hold the different parts that we're concatenating. Or maybe even

```
result = ftm_header_test_file_contents.format(...)
result += "".join(...)
result += whatever
```

Otherwise we end up with one really really large expression grouped together by a single (and subtle) `+` token.


https://github.com/llvm/llvm-project/pull/134542


More information about the libcxx-commits mailing list