[libc-commits] [libc] Libc/attribute (PR #79891)
via libc-commits
libc-commits at lists.llvm.org
Mon Jan 29 12:06:37 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Schrodinger ZHU Yifan (SchrodingerZhu)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/79891.diff
4 Files Affected:
- (modified) libc/spec/spec.td (+21-1)
- (modified) libc/spec/stdc.td (+6-1)
- (modified) libc/utils/HdrGen/PublicAPICommand.cpp (+79)
- (modified) libc/utils/HdrGen/PublicAPICommand.h (+2)
``````````diff
diff --git a/libc/spec/spec.td b/libc/spec/spec.td
index 818cfaee6b61c2b..9ed4fa4a31de678 100644
--- a/libc/spec/spec.td
+++ b/libc/spec/spec.td
@@ -169,10 +169,30 @@ class ArgSpec<Type type, list<Annotation> annotations = [], string name = ""> {
string Name = name;
}
-class FunctionSpec<string name, RetValSpec return, list<ArgSpec> args> {
+class FunctionAttr {}
+class GnuFunctionAttr<string attr> : FunctionAttr {
+ string Attr = attr;
+ string Style = "gnu";
+}
+class Cxx11FunctionAttr<string attr, string namespace> : FunctionAttr {
+ string Attr = attr;
+ string Namespace = namespace;
+ string Style = "cxx11";
+}
+class DeclspecFunctionAttr<string attr> : FunctionAttr {
+ string Attr = attr;
+ string Style = "declspec";
+}
+class FunctionAttrSpec<string macro, list<FunctionAttr> instances> {
+ list<FunctionAttr> Instances = instances;
+ string Macro = macro;
+}
+
+class FunctionSpec<string name, RetValSpec return, list<ArgSpec> args, list<FunctionAttrSpec> attrs = []> {
string Name = name;
RetValSpec Return = return;
list<ArgSpec> Args = args;
+ list<FunctionAttrSpec> Attributes = attrs;
}
class ObjectSpec<string name, string type> {
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 43b81c4abaa0e6b..a32a14812bec6fb 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -26,6 +26,11 @@ def StdC : StandardSpec<"stdc"> {
[]
>;
+ FunctionAttrSpec ConstAttr = FunctionAttrSpec<"__LIBC_CONST_ATTR", [
+ Cxx11FunctionAttr<"const", "gnu">,
+ GnuFunctionAttr<"const">,
+ ]>;
+
HeaderSpec CType = HeaderSpec<
"ctype.h",
[], // Macros
@@ -364,7 +369,7 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"ceilf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
FunctionSpec<"ceill", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
- FunctionSpec<"fabs", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
+ FunctionSpec<"fabs", RetValSpec<DoubleType>, [ArgSpec<DoubleType>], [ConstAttr]>,
FunctionSpec<"fabsf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
FunctionSpec<"fabsl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
FunctionSpec<"fabsf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>]>,
diff --git a/libc/utils/HdrGen/PublicAPICommand.cpp b/libc/utils/HdrGen/PublicAPICommand.cpp
index b1c7a072658ffbd..d24637db0f7888f 100644
--- a/libc/utils/HdrGen/PublicAPICommand.cpp
+++ b/libc/utils/HdrGen/PublicAPICommand.cpp
@@ -15,6 +15,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/TableGen/Record.h"
+#include <algorithm>
+#include <llvm/ADT/STLExtras.h>
// Text blocks for macro definitions and type decls can be indented to
// suit the surrounding tablegen listing. We need to dedent such blocks
@@ -87,6 +89,71 @@ 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;
+ };
+
+ 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());
+ for (auto &[Style, Instance] : Styles) {
+ if (Style == AttributeStyle::Cxx11) {
+ OS << "#if !defined(" << Macro << ") && defined(__cplusplus)\n";
+ OS << "#define " << Macro << " [[";
+ auto Namespace = Instance->getValueAsString("Namespace");
+ if (Namespace != "")
+ OS << Namespace << "::";
+ 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";
+ }
+
+ if (!MacroAttr.empty())
+ OS << '\n';
+
OS << "__BEGIN_C_DECLS\n\n";
for (auto &Name : EntrypointNameList) {
if (G.FunctionSpecMap.find(Name) == G.FunctionSpecMap.end()) {
@@ -102,6 +169,14 @@ void writeAPIFromIndex(APIIndexer &G,
llvm::Record *RetValSpec = FunctionSpec->getValueAsDef("Return");
llvm::Record *ReturnType = RetValSpec->getValueAsDef("ReturnType");
+ auto Attributes = FunctionSpec->getValueAsListOfDefs("Attributes");
+ llvm::interleave(
+ Attributes.begin(), Attributes.end(),
+ [&](llvm::Record *Attr) { OS << Attr->getValueAsString("Macro"); },
+ [&]() { OS << ' '; });
+ if (!Attributes.empty())
+ OS << ' ';
+
OS << G.getTypeAsString(ReturnType) << " " << Name << "(";
auto ArgsList = FunctionSpec->getValueAsListOfDefs("Args");
@@ -124,6 +199,10 @@ void writeAPIFromIndex(APIIndexer &G,
OS << "extern " << Type << " " << Name << ";\n";
}
OS << "__END_C_DECLS\n";
+
+ // undef the macros
+ for (auto &[Macro, Attr] : MacroAttr)
+ OS << "\n#undef " << Macro << '\n';
}
void writePublicAPI(llvm::raw_ostream &OS, llvm::RecordKeeper &Records) {}
diff --git a/libc/utils/HdrGen/PublicAPICommand.h b/libc/utils/HdrGen/PublicAPICommand.h
index fb0a7a81cf277a3..72401cfe068e33a 100644
--- a/libc/utils/HdrGen/PublicAPICommand.h
+++ b/libc/utils/HdrGen/PublicAPICommand.h
@@ -25,6 +25,8 @@ class RecordKeeper;
namespace llvm_libc {
+enum class AttributeStyle { Cxx11 = 0, Gnu = 1, Declspec = 2 };
+
class PublicAPICommand : public Command {
private:
const std::vector<std::string> &EntrypointNameList;
``````````
</details>
https://github.com/llvm/llvm-project/pull/79891
More information about the libc-commits
mailing list