[libc-commits] [libc] [libc] add support for function level attributes (PR #79891)
Nick Desaulniers via libc-commits
libc-commits at lists.llvm.org
Mon Feb 12 08:56:28 PST 2024
================
@@ -87,6 +89,94 @@ void writeAPIFromIndex(APIIndexer &G,
if (G.Enumerations.size() != 0)
OS << "};\n\n";
+ // declare macros for attributes
+ llvm::DenseMap<llvm::StringRef, llvm::Record *> MacroAttr;
+ for (auto &Name : EntrypointNameList) {
+ if (G.FunctionSpecMap.find(Name) == G.FunctionSpecMap.end()) {
+ continue;
+ }
+ llvm::Record *FunctionSpec = G.FunctionSpecMap[Name];
+ auto Attributes = FunctionSpec->getValueAsListOfDefs("Attributes");
+ for (auto *Attr : Attributes) {
+ MacroAttr[Attr->getValueAsString("Macro")] = Attr;
+ }
+ }
+
+ auto GetStyle = [](llvm::Record *Instance) {
+ auto Style = Instance->getValueAsString("Style");
+ if (Style == "cxx11")
+ return AttributeStyle::Cxx11;
+ if (Style == "gnu")
+ return AttributeStyle::Gnu;
+ return AttributeStyle::Declspec;
+ };
+
+ auto GetNamespace = [](llvm::Record *Instance) {
+ auto Namespace = Instance->getValueAsString("Namespace");
+ // Empty namespace is likely to be most standard-compliant.
+ if (Namespace.empty())
+ return AttributeNamespace::None;
+ // Dispatch clang version before gnu version.
+ if (Namespace == "clang")
+ return AttributeNamespace::Clang;
+ return AttributeNamespace::Gnu;
+ };
+
+ for (auto &[Macro, Attr] : MacroAttr) {
+ auto Instances = Attr->getValueAsListOfDefs("Instances");
+ llvm::SmallVector<std::pair<AttributeStyle, llvm::Record *>> Styles;
+ std::transform(Instances.begin(), Instances.end(),
+ std::back_inserter(Styles),
+ [&](llvm::Record *Instance)
+ -> std::pair<AttributeStyle, llvm::Record *> {
+ auto Style = GetStyle(Instance);
+ return {Style, Instance};
+ });
+ // Effectively sort on the first field
+ std::sort(Styles.begin(), Styles.end(), [&](auto &a, auto &b) {
+ if (a.first == AttributeStyle::Cxx11 && b.first == AttributeStyle::Cxx11)
+ return GetNamespace(a.second) < GetNamespace(b.second);
+ return a.first < b.first;
+ });
+ for (auto &[Style, Instance] : Styles) {
+ if (Style == AttributeStyle::Cxx11) {
+ OS << "#if !defined(" << Macro << ") && defined(__cplusplus)";
+ auto Namespace = GetNamespace(Instance);
+ if (Namespace == AttributeNamespace::Clang)
+ OS << " && defined(__clang__)\n";
+ else if (Namespace == AttributeNamespace::Gnu)
+ OS << " && defined(__GNUC__)\n";
+ else
+ OS << '\n';
+ OS << "#define " << Macro << " [[";
+ if (Namespace == AttributeNamespace::Clang)
+ OS << "clang::";
+ else if (Namespace == AttributeNamespace::Gnu)
+ OS << "gnu::";
+ OS << Instance->getValueAsString("Attr") << "]]\n";
+ OS << "#endif\n";
+ }
+ if (Style == AttributeStyle::Gnu) {
+ OS << "#if !defined(" << Macro << ") && defined(__GNUC__)\n";
+ OS << "#define " << Macro << " __attribute__((";
+ OS << Instance->getValueAsString("Attr") << "))\n";
+ OS << "#endif\n";
+ }
+ if (Style == AttributeStyle::Declspec) {
+ OS << "#if !defined(" << Macro << ") && defined(_MSC_VER)\n";
+ OS << "#define " << Macro << " __declspec(";
+ OS << Instance->getValueAsString("Attr") << ")\n";
+ OS << "#endif\n";
+ }
+ }
+ OS << "#if !defined(" << Macro << ")\n";
+ OS << "#define " << Macro << '\n';
+ OS << "#endif\n";
----------------
nickdesaulniers wrote:
> I'd be curious to see examples of the resulting output.
Bump. Can you share how this changes the generated header declaration for `fabs`? That might be nice to include in the commit message even.
https://github.com/llvm/llvm-project/pull/79891
More information about the libc-commits
mailing list