aboutsummaryrefslogtreecommitdiff
path: root/libc/utils
diff options
context:
space:
mode:
authorPaula Toth <paulatoth@google.com>2020-06-01 12:27:25 -0700
committerPaula Toth <paulatoth@google.com>2020-06-01 12:30:35 -0700
commit1ab092b75859137c48d279a137fe5dce61a925b6 (patch)
treef1de4a36d8ca72405b37c9e55acf8209ab813286 /libc/utils
parent8f0a6600306417227da72d93d11b2fa6f0be6b4c (diff)
downloadllvm-1ab092b75859137c48d279a137fe5dce61a925b6.zip
llvm-1ab092b75859137c48d279a137fe5dce61a925b6.tar.gz
llvm-1ab092b75859137c48d279a137fe5dce61a925b6.tar.bz2
[libc] Expose APIGenerator.
Summary: This is split off from D79192 and exposes APIGenerator (renames to APIIndexer) for use in generating the integrations tests. Reviewers: sivachandra Reviewed By: sivachandra Subscribers: tschuett, ecnelises, libc-commits Tags: #libc-project Differential Revision: https://reviews.llvm.org/D80832
Diffstat (limited to 'libc/utils')
-rw-r--r--libc/utils/HdrGen/PublicAPICommand.cpp348
-rw-r--r--libc/utils/HdrGen/PublicAPICommand.h55
2 files changed, 218 insertions, 185 deletions
diff --git a/libc/utils/HdrGen/PublicAPICommand.cpp b/libc/utils/HdrGen/PublicAPICommand.cpp
index 8c260b4..11b8258 100644
--- a/libc/utils/HdrGen/PublicAPICommand.cpp
+++ b/libc/utils/HdrGen/PublicAPICommand.cpp
@@ -57,218 +57,196 @@ static void dedentAndWrite(llvm::StringRef Text, llvm::raw_ostream &OS) {
}
}
-class APIGenerator {
- llvm::StringRef StdHeader;
-
- // TableGen classes in spec.td.
- llvm::Record *NamedTypeClass;
- llvm::Record *PtrTypeClass;
- llvm::Record *RestrictedPtrTypeClass;
- llvm::Record *ConstTypeClass;
- llvm::Record *StructClass;
- llvm::Record *StandardSpecClass;
- llvm::Record *PublicAPIClass;
-
- using NameToRecordMapping = std::unordered_map<std::string, llvm::Record *>;
- using NameSet = std::unordered_set<std::string>;
+namespace llvm_libc {
- // Mapping from names to records defining them.
- NameToRecordMapping MacroSpecMap;
- NameToRecordMapping TypeSpecMap;
- NameToRecordMapping EnumerationSpecMap;
- NameToRecordMapping FunctionSpecMap;
- NameToRecordMapping MacroDefsMap;
- NameToRecordMapping TypeDeclsMap;
+bool APIIndexer::isaNamedType(llvm::Record *Def) {
+ return isa(Def, NamedTypeClass);
+}
- NameSet Structs;
- NameSet Enumerations;
- NameSet Functions;
+bool APIIndexer::isaStructType(llvm::Record *Def) {
+ return isa(Def, StructClass);
+}
- bool isaNamedType(llvm::Record *Def) { return isa(Def, NamedTypeClass); }
+bool APIIndexer::isaPtrType(llvm::Record *Def) {
+ return isa(Def, PtrTypeClass);
+}
- bool isaStructType(llvm::Record *Def) { return isa(Def, StructClass); }
+bool APIIndexer::isaConstType(llvm::Record *Def) {
+ return isa(Def, ConstTypeClass);
+}
- bool isaPtrType(llvm::Record *Def) { return isa(Def, PtrTypeClass); }
+bool APIIndexer::isaRestrictedPtrType(llvm::Record *Def) {
+ return isa(Def, RestrictedPtrTypeClass);
+}
- bool isaConstType(llvm::Record *Def) { return isa(Def, ConstTypeClass); }
+bool APIIndexer::isaStandardSpec(llvm::Record *Def) {
+ return isa(Def, StandardSpecClass);
+}
- bool isaRestrictedPtrType(llvm::Record *Def) {
- return isa(Def, RestrictedPtrTypeClass);
- }
+bool APIIndexer::isaPublicAPI(llvm::Record *Def) {
+ return isa(Def, PublicAPIClass);
+}
- bool isaStandardSpec(llvm::Record *Def) {
- return isa(Def, StandardSpecClass);
+std::string APIIndexer::getTypeAsString(llvm::Record *TypeRecord) {
+ if (isaNamedType(TypeRecord) || isaStructType(TypeRecord)) {
+ return std::string(TypeRecord->getValueAsString("Name"));
+ } else if (isaPtrType(TypeRecord)) {
+ return getTypeAsString(TypeRecord->getValueAsDef("PointeeType")) + " *";
+ } else if (isaConstType(TypeRecord)) {
+ return std::string("const ") +
+ getTypeAsString(TypeRecord->getValueAsDef("UnqualifiedType"));
+ } else if (isaRestrictedPtrType(TypeRecord)) {
+ return getTypeAsString(TypeRecord->getValueAsDef("PointeeType")) +
+ " *__restrict";
+ } else {
+ llvm::PrintFatalError(TypeRecord->getLoc(), "Invalid type.\n");
}
+}
- bool isaPublicAPI(llvm::Record *Def) { return isa(Def, PublicAPIClass); }
-
- std::string getTypeAsString(llvm::Record *TypeRecord) {
- if (isaNamedType(TypeRecord) || isaStructType(TypeRecord)) {
- return std::string(TypeRecord->getValueAsString("Name"));
- } else if (isaPtrType(TypeRecord)) {
- return getTypeAsString(TypeRecord->getValueAsDef("PointeeType")) + " *";
- } else if (isaConstType(TypeRecord)) {
- return std::string("const ") +
- getTypeAsString(TypeRecord->getValueAsDef("UnqualifiedType"));
- } else if (isaRestrictedPtrType(TypeRecord)) {
- return getTypeAsString(TypeRecord->getValueAsDef("PointeeType")) +
- " *__restrict";
- } else {
- llvm::PrintFatalError(TypeRecord->getLoc(), "Invalid type.\n");
- }
- }
+void APIIndexer::indexStandardSpecDef(llvm::Record *StandardSpec) {
+ auto HeaderSpecList = StandardSpec->getValueAsListOfDefs("Headers");
+ for (llvm::Record *HeaderSpec : HeaderSpecList) {
+ llvm::StringRef Header = HeaderSpec->getValueAsString("Name");
+ if (!StdHeader.hasValue() || Header == StdHeader) {
+ PublicHeaders.emplace(Header);
+ auto MacroSpecList = HeaderSpec->getValueAsListOfDefs("Macros");
+ // TODO: Trigger a fatal error on duplicate specs.
+ for (llvm::Record *MacroSpec : MacroSpecList)
+ MacroSpecMap[std::string(MacroSpec->getValueAsString("Name"))] =
+ MacroSpec;
+
+ auto TypeSpecList = HeaderSpec->getValueAsListOfDefs("Types");
+ for (llvm::Record *TypeSpec : TypeSpecList)
+ TypeSpecMap[std::string(TypeSpec->getValueAsString("Name"))] = TypeSpec;
+
+ auto FunctionSpecList = HeaderSpec->getValueAsListOfDefs("Functions");
+ for (llvm::Record *FunctionSpec : FunctionSpecList) {
+ FunctionSpecMap[std::string(FunctionSpec->getValueAsString("Name"))] =
+ FunctionSpec;
+ }
- void indexStandardSpecDef(llvm::Record *StandardSpec) {
- auto HeaderSpecList = StandardSpec->getValueAsListOfDefs("Headers");
- for (llvm::Record *HeaderSpec : HeaderSpecList) {
- if (HeaderSpec->getValueAsString("Name") == StdHeader) {
- auto MacroSpecList = HeaderSpec->getValueAsListOfDefs("Macros");
- // TODO: Trigger a fatal error on duplicate specs.
- for (llvm::Record *MacroSpec : MacroSpecList)
- MacroSpecMap[std::string(MacroSpec->getValueAsString("Name"))] =
- MacroSpec;
-
- auto TypeSpecList = HeaderSpec->getValueAsListOfDefs("Types");
- for (llvm::Record *TypeSpec : TypeSpecList)
- TypeSpecMap[std::string(TypeSpec->getValueAsString("Name"))] =
- TypeSpec;
-
- auto FunctionSpecList = HeaderSpec->getValueAsListOfDefs("Functions");
- for (llvm::Record *FunctionSpec : FunctionSpecList) {
- FunctionSpecMap[std::string(FunctionSpec->getValueAsString("Name"))] =
- FunctionSpec;
- }
-
- auto EnumerationSpecList =
- HeaderSpec->getValueAsListOfDefs("Enumerations");
- for (llvm::Record *EnumerationSpec : EnumerationSpecList) {
- EnumerationSpecMap[std::string(
- EnumerationSpec->getValueAsString("Name"))] = EnumerationSpec;
- }
+ auto EnumerationSpecList =
+ HeaderSpec->getValueAsListOfDefs("Enumerations");
+ for (llvm::Record *EnumerationSpec : EnumerationSpecList) {
+ EnumerationSpecMap[std::string(
+ EnumerationSpec->getValueAsString("Name"))] = EnumerationSpec;
}
}
}
+}
- void indexPublicAPIDef(llvm::Record *PublicAPI) {
- // While indexing the public API, we do not check if any of the entities
- // requested is from an included standard. Such a check is done while
- // generating the API.
- auto MacroDefList = PublicAPI->getValueAsListOfDefs("Macros");
- for (llvm::Record *MacroDef : MacroDefList)
- MacroDefsMap[std::string(MacroDef->getValueAsString("Name"))] = MacroDef;
-
- auto TypeDeclList = PublicAPI->getValueAsListOfDefs("TypeDeclarations");
- for (llvm::Record *TypeDecl : TypeDeclList)
- TypeDeclsMap[std::string(TypeDecl->getValueAsString("Name"))] = TypeDecl;
-
- auto StructList = PublicAPI->getValueAsListOfStrings("Structs");
- for (llvm::StringRef StructName : StructList)
- Structs.insert(std::string(StructName));
-
- auto FunctionList = PublicAPI->getValueAsListOfStrings("Functions");
- for (llvm::StringRef FunctionName : FunctionList)
- Functions.insert(std::string(FunctionName));
-
- auto EnumerationList = PublicAPI->getValueAsListOfStrings("Enumerations");
- for (llvm::StringRef EnumerationName : EnumerationList)
- Enumerations.insert(std::string(EnumerationName));
- }
+void APIIndexer::indexPublicAPIDef(llvm::Record *PublicAPI) {
+ // While indexing the public API, we do not check if any of the entities
+ // requested is from an included standard. Such a check is done while
+ // generating the API.
+ auto MacroDefList = PublicAPI->getValueAsListOfDefs("Macros");
+ for (llvm::Record *MacroDef : MacroDefList)
+ MacroDefsMap[std::string(MacroDef->getValueAsString("Name"))] = MacroDef;
+
+ auto TypeDeclList = PublicAPI->getValueAsListOfDefs("TypeDeclarations");
+ for (llvm::Record *TypeDecl : TypeDeclList)
+ TypeDeclsMap[std::string(TypeDecl->getValueAsString("Name"))] = TypeDecl;
+
+ auto StructList = PublicAPI->getValueAsListOfStrings("Structs");
+ for (llvm::StringRef StructName : StructList)
+ Structs.insert(std::string(StructName));
+
+ auto FunctionList = PublicAPI->getValueAsListOfStrings("Functions");
+ for (llvm::StringRef FunctionName : FunctionList)
+ Functions.insert(std::string(FunctionName));
+
+ auto EnumerationList = PublicAPI->getValueAsListOfStrings("Enumerations");
+ for (llvm::StringRef EnumerationName : EnumerationList)
+ Enumerations.insert(std::string(EnumerationName));
+}
- void index(llvm::RecordKeeper &Records) {
- NamedTypeClass = Records.getClass(NamedTypeClassName);
- PtrTypeClass = Records.getClass(PtrTypeClassName);
- RestrictedPtrTypeClass = Records.getClass(RestrictedPtrTypeClassName);
- StructClass = Records.getClass(StructTypeClassName);
- ConstTypeClass = Records.getClass(ConstTypeClassName);
- StandardSpecClass = Records.getClass(StandardSpecClassName);
- PublicAPIClass = Records.getClass(PublicAPIClassName);
-
- const auto &DefsMap = Records.getDefs();
- for (auto &Pair : DefsMap) {
- llvm::Record *Def = Pair.second.get();
- if (isaStandardSpec(Def))
- indexStandardSpecDef(Def);
- if (isaPublicAPI(Def)) {
- if (Def->getValueAsString("HeaderName") == StdHeader)
- indexPublicAPIDef(Def);
- }
+void APIIndexer::index(llvm::RecordKeeper &Records) {
+ NamedTypeClass = Records.getClass(NamedTypeClassName);
+ PtrTypeClass = Records.getClass(PtrTypeClassName);
+ RestrictedPtrTypeClass = Records.getClass(RestrictedPtrTypeClassName);
+ StructClass = Records.getClass(StructTypeClassName);
+ ConstTypeClass = Records.getClass(ConstTypeClassName);
+ StandardSpecClass = Records.getClass(StandardSpecClassName);
+ PublicAPIClass = Records.getClass(PublicAPIClassName);
+
+ const auto &DefsMap = Records.getDefs();
+ for (auto &Pair : DefsMap) {
+ llvm::Record *Def = Pair.second.get();
+ if (isaStandardSpec(Def))
+ indexStandardSpecDef(Def);
+ if (isaPublicAPI(Def)) {
+ if (!StdHeader.hasValue() ||
+ Def->getValueAsString("HeaderName") == StdHeader)
+ indexPublicAPIDef(Def);
}
}
+}
-public:
- APIGenerator(llvm::StringRef Header, llvm::RecordKeeper &Records)
- : StdHeader(Header) {
- index(Records);
- }
+void writeAPIFromIndex(APIIndexer &G, llvm::raw_ostream &OS) {
+ for (auto &Pair : G.MacroDefsMap) {
+ const std::string &Name = Pair.first;
+ if (G.MacroSpecMap.find(Name) == G.MacroSpecMap.end())
+ llvm::PrintFatalError(Name + " not found in any standard spec.\n");
- void write(llvm::raw_ostream &OS) {
- for (auto &Pair : MacroDefsMap) {
- const std::string &Name = Pair.first;
- if (MacroSpecMap.find(Name) == MacroSpecMap.end())
- llvm::PrintFatalError(Name + " not found in any standard spec.\n");
+ llvm::Record *MacroDef = Pair.second;
+ dedentAndWrite(MacroDef->getValueAsString("Defn"), OS);
- llvm::Record *MacroDef = Pair.second;
- dedentAndWrite(MacroDef->getValueAsString("Defn"), OS);
+ OS << '\n';
+ }
- OS << '\n';
- }
+ for (auto &Pair : G.TypeDeclsMap) {
+ const std::string &Name = Pair.first;
+ if (G.TypeSpecMap.find(Name) == G.TypeSpecMap.end())
+ llvm::PrintFatalError(Name + " not found in any standard spec.\n");
- for (auto &Pair : TypeDeclsMap) {
- const std::string &Name = Pair.first;
- if (TypeSpecMap.find(Name) == TypeSpecMap.end())
- llvm::PrintFatalError(Name + " not found in any standard spec.\n");
+ llvm::Record *TypeDecl = Pair.second;
+ dedentAndWrite(TypeDecl->getValueAsString("Decl"), OS);
- llvm::Record *TypeDecl = Pair.second;
- dedentAndWrite(TypeDecl->getValueAsString("Decl"), OS);
+ OS << '\n';
+ }
- OS << '\n';
+ if (G.Enumerations.size() != 0)
+ OS << "enum {" << '\n';
+ for (const auto &Name : G.Enumerations) {
+ if (G.EnumerationSpecMap.find(Name) == G.EnumerationSpecMap.end())
+ llvm::PrintFatalError(
+ Name + " is not listed as an enumeration in any standard spec.\n");
+
+ llvm::Record *EnumerationSpec = G.EnumerationSpecMap[Name];
+ OS << " " << EnumerationSpec->getValueAsString("Name");
+ auto Value = EnumerationSpec->getValueAsString("Value");
+ if (Value == "__default__") {
+ OS << ",\n";
+ } else {
+ OS << " = " << Value << ",\n";
}
-
- if (Enumerations.size() != 0)
- OS << "enum {" << '\n';
- for (const auto &Name : Enumerations) {
- if (EnumerationSpecMap.find(Name) == EnumerationSpecMap.end())
- llvm::PrintFatalError(
- Name + " is not listed as an enumeration in any standard spec.\n");
-
- llvm::Record *EnumerationSpec = EnumerationSpecMap[Name];
- OS << " " << EnumerationSpec->getValueAsString("Name");
- auto Value = EnumerationSpec->getValueAsString("Value");
- if (Value == "__default__") {
- OS << ",\n";
- } else {
- OS << " = " << Value << ",\n";
- }
+ }
+ if (G.Enumerations.size() != 0)
+ OS << "};\n\n";
+
+ OS << "__BEGIN_C_DECLS\n\n";
+ for (auto &Name : G.Functions) {
+ if (G.FunctionSpecMap.find(Name) == G.FunctionSpecMap.end())
+ llvm::PrintFatalError(Name + " not found in any standard spec.\n");
+
+ llvm::Record *FunctionSpec = G.FunctionSpecMap[Name];
+ llvm::Record *RetValSpec = FunctionSpec->getValueAsDef("Return");
+ llvm::Record *ReturnType = RetValSpec->getValueAsDef("ReturnType");
+
+ OS << G.getTypeAsString(ReturnType) << " " << Name << "(";
+
+ auto ArgsList = FunctionSpec->getValueAsListOfDefs("Args");
+ for (size_t i = 0; i < ArgsList.size(); ++i) {
+ llvm::Record *ArgType = ArgsList[i]->getValueAsDef("ArgType");
+ OS << G.getTypeAsString(ArgType);
+ if (i < ArgsList.size() - 1)
+ OS << ", ";
}
- if (Enumerations.size() != 0)
- OS << "};\n\n";
-
- OS << "__BEGIN_C_DECLS\n\n";
- for (auto &Name : Functions) {
- if (FunctionSpecMap.find(Name) == FunctionSpecMap.end())
- llvm::PrintFatalError(Name + " not found in any standard spec.\n");
-
- llvm::Record *FunctionSpec = FunctionSpecMap[Name];
- llvm::Record *RetValSpec = FunctionSpec->getValueAsDef("Return");
- llvm::Record *ReturnType = RetValSpec->getValueAsDef("ReturnType");
-
- OS << getTypeAsString(ReturnType) << " " << Name << "(";
-
- auto ArgsList = FunctionSpec->getValueAsListOfDefs("Args");
- for (size_t i = 0; i < ArgsList.size(); ++i) {
- llvm::Record *ArgType = ArgsList[i]->getValueAsDef("ArgType");
- OS << getTypeAsString(ArgType);
- if (i < ArgsList.size() - 1)
- OS << ", ";
- }
- OS << ");\n\n";
- }
- OS << "__END_C_DECLS\n";
+ OS << ");\n\n";
}
-};
-
-namespace llvm_libc {
+ OS << "__END_C_DECLS\n";
+}
void writePublicAPI(llvm::raw_ostream &OS, llvm::RecordKeeper &Records) {}
@@ -282,8 +260,8 @@ void PublicAPICommand::run(llvm::raw_ostream &OS, const ArgVector &Args,
Reporter.printFatalError("public_api command does not take any arguments.");
}
- APIGenerator G(StdHeader, Records);
- G.write(OS);
+ APIIndexer G(StdHeader, Records);
+ writeAPIFromIndex(G, OS);
}
} // namespace llvm_libc
diff --git a/libc/utils/HdrGen/PublicAPICommand.h b/libc/utils/HdrGen/PublicAPICommand.h
index 45ea1cf..c95ad52 100644
--- a/libc/utils/HdrGen/PublicAPICommand.h
+++ b/libc/utils/HdrGen/PublicAPICommand.h
@@ -36,6 +36,61 @@ public:
const Command::ErrorReporter &Reporter) const override;
};
+class APIIndexer {
+private:
+ llvm::Optional<llvm::StringRef> StdHeader;
+
+ // TableGen classes in spec.td.
+ llvm::Record *NamedTypeClass;
+ llvm::Record *PtrTypeClass;
+ llvm::Record *RestrictedPtrTypeClass;
+ llvm::Record *ConstTypeClass;
+ llvm::Record *StructClass;
+ llvm::Record *StandardSpecClass;
+ llvm::Record *PublicAPIClass;
+
+ bool isaNamedType(llvm::Record *Def);
+ bool isaStructType(llvm::Record *Def);
+ bool isaPtrType(llvm::Record *Def);
+ bool isaConstType(llvm::Record *Def);
+ bool isaRestrictedPtrType(llvm::Record *Def);
+ bool isaStandardSpec(llvm::Record *Def);
+ bool isaPublicAPI(llvm::Record *Def);
+
+ void indexStandardSpecDef(llvm::Record *StandardSpec);
+ void indexPublicAPIDef(llvm::Record *PublicAPI);
+ void index(llvm::RecordKeeper &Records);
+
+public:
+ using NameToRecordMapping = std::unordered_map<std::string, llvm::Record *>;
+ using NameSet = std::unordered_set<std::string>;
+
+ // This indexes all headers, not just a specified one.
+ explicit APIIndexer(llvm::RecordKeeper &Records) : StdHeader(llvm::None) {
+ index(Records);
+ }
+
+ APIIndexer(llvm::StringRef Header, llvm::RecordKeeper &Records)
+ : StdHeader(Header) {
+ index(Records);
+ }
+
+ // Mapping from names to records defining them.
+ NameToRecordMapping MacroSpecMap;
+ NameToRecordMapping TypeSpecMap;
+ NameToRecordMapping EnumerationSpecMap;
+ NameToRecordMapping FunctionSpecMap;
+ NameToRecordMapping MacroDefsMap;
+ NameToRecordMapping TypeDeclsMap;
+
+ NameSet Structs;
+ NameSet Enumerations;
+ NameSet Functions;
+ NameSet PublicHeaders;
+
+ std::string getTypeAsString(llvm::Record *TypeRecord);
+};
+
} // namespace llvm_libc
#endif // LLVM_LIBC_UTILS_HDRGEN_PUBLICAPICOMMAND_H