forked from OSchip/llvm-project
[libc] Extend WrapperGen to emit aliases.
Reviewed By: michaelrj Differential Revision: https://reviews.llvm.org/D90985
This commit is contained in:
parent
c75a0a1e9d
commit
d50149b42e
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/TableGen/Error.h"
|
||||
#include "llvm/TableGen/Main.h"
|
||||
|
||||
|
@ -19,8 +20,37 @@
|
|||
llvm::cl::opt<std::string>
|
||||
FunctionName("name", llvm::cl::desc("Name of the function to be wrapped."),
|
||||
llvm::cl::value_desc("<function name>"), llvm::cl::Required);
|
||||
llvm::cl::opt<std::string>
|
||||
AliaseeString("aliasee",
|
||||
llvm::cl::desc("Declare as an alias to this C name."),
|
||||
llvm::cl::value_desc("<aliasee string>"));
|
||||
llvm::cl::opt<std::string>
|
||||
AliaseeFile("aliasee-file",
|
||||
llvm::cl::desc("Declare as an alias to the C name read from "
|
||||
"this file."),
|
||||
llvm::cl::value_desc("<path to a file containing alias name>"));
|
||||
llvm::cl::opt<std::string>
|
||||
AppendToFile("append-to-file",
|
||||
llvm::cl::desc("Append the generated content at the end of "
|
||||
"the contents of this file."),
|
||||
llvm::cl::value_desc("<path to a file>"));
|
||||
|
||||
static std::string GetAliaseeName() {
|
||||
if (AliaseeString.size() > 0)
|
||||
return AliaseeString;
|
||||
|
||||
auto ErrorOrBuf = llvm::MemoryBuffer::getFile(AliaseeFile);
|
||||
if (!ErrorOrBuf)
|
||||
llvm::PrintFatalError("Unable to read the aliasee file " + AliaseeFile);
|
||||
return std::string(ErrorOrBuf.get()->getBuffer().trim());
|
||||
}
|
||||
|
||||
static bool WrapperGenMain(llvm::raw_ostream &OS, llvm::RecordKeeper &Records) {
|
||||
if (!AliaseeString.empty() && !AliaseeFile.empty()) {
|
||||
llvm::PrintFatalError("The options 'aliasee' and 'aliasee-file' cannot "
|
||||
"be specified simultaniously.");
|
||||
}
|
||||
|
||||
llvm_libc::APIIndexer Indexer(Records);
|
||||
auto Iter = Indexer.FunctionSpecMap.find(FunctionName);
|
||||
if (Iter == Indexer.FunctionSpecMap.end()) {
|
||||
|
@ -28,11 +58,27 @@ static bool WrapperGenMain(llvm::raw_ostream &OS, llvm::RecordKeeper &Records) {
|
|||
"' not found in any standard spec.");
|
||||
}
|
||||
|
||||
// To avoid all confusion, we include the implementation header using the
|
||||
// full path (relative the libc directory.)
|
||||
std::string Header = Indexer.FunctionToHeaderMap[FunctionName];
|
||||
auto RelPath = llvm::StringRef(Header).drop_back(2); // Drop the ".h" suffix.
|
||||
OS << "#include \"src/" << RelPath << "/" << FunctionName << ".h\"\n";
|
||||
bool EmitAlias = !(AliaseeString.empty() && AliaseeFile.empty());
|
||||
|
||||
if (!EmitAlias && AppendToFile.empty()) {
|
||||
// If not emitting an alias, and not appending to another file,
|
||||
// we should include the implementation header to ensure the wrapper
|
||||
// compiles.
|
||||
// To avoid all confusion, we include the implementation header using the
|
||||
// full path (relative to the libc directory.)
|
||||
std::string Header = Indexer.FunctionToHeaderMap[FunctionName];
|
||||
auto RelPath =
|
||||
llvm::StringRef(Header).drop_back(2); // Drop the ".h" suffix.
|
||||
OS << "#include \"src/" << RelPath << "/" << FunctionName << ".h\"\n";
|
||||
}
|
||||
if (!AppendToFile.empty()) {
|
||||
auto ErrorOrBuf = llvm::MemoryBuffer::getFile(AppendToFile);
|
||||
if (!ErrorOrBuf) {
|
||||
llvm::PrintFatalError("Unable to read the file '" + AppendToFile +
|
||||
"' to append to.");
|
||||
}
|
||||
OS << ErrorOrBuf.get()->getBuffer().trim() << '\n';
|
||||
}
|
||||
|
||||
auto &NameSpecPair = *Iter;
|
||||
llvm::Record *FunctionSpec = NameSpecPair.second;
|
||||
|
@ -79,14 +125,17 @@ static bool WrapperGenMain(llvm::raw_ostream &OS, llvm::RecordKeeper &Records) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Arg types of the C++ implementation functions need not
|
||||
// match the standard types. Either handle such differences here, or
|
||||
// avoid such a thing in the implementations.
|
||||
OS << ") {\n"
|
||||
<< " " << (ShouldReturn ? "return " : "")
|
||||
<< "__llvm_libc::" << FunctionName << "(" << CallArgs.str() << ");\n"
|
||||
<< "}\n";
|
||||
|
||||
if (EmitAlias) {
|
||||
OS << ") __attribute__((alias(\"" << GetAliaseeName() << "\")));\n";
|
||||
} else {
|
||||
// TODO: Arg types of the C++ implementation functions need not
|
||||
// match the standard types. Either handle such differences here, or
|
||||
// avoid such a thing in the implementations.
|
||||
OS << ") {\n"
|
||||
<< " " << (ShouldReturn ? "return " : "")
|
||||
<< "__llvm_libc::" << FunctionName << "(" << CallArgs.str() << ");\n"
|
||||
<< "}\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue