mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
158 lines
5.0 KiB
C++
158 lines
5.0 KiB
C++
//===--- api_notes.cpp - Swift Compiler Frontend --------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See http://swift.org/LICENSE.txt for license information
|
|
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// \brief This is the YAML to binary converter for API notes.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
#include "clang/APINotes/APINotesYAMLCompiler.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Support/FileSystem.h"
|
|
#include "llvm/Support/MemoryBuffer.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include "llvm/Support/PrettyStackTrace.h"
|
|
#include "llvm/Support/Signals.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/StringMap.h"
|
|
#include "llvm/ADT/Triple.h"
|
|
|
|
using namespace llvm;
|
|
namespace api_notes = clang::api_notes;
|
|
|
|
int apinotes_main(ArrayRef<const char *> Args) {
|
|
|
|
// Mark all our options with this category, everything else (except for
|
|
// -version and -help) will be hidden.
|
|
static cl::OptionCategory APINotesCategory("API Notes options");
|
|
|
|
static cl::opt<api_notes::ActionType>
|
|
Action(cl::desc("Mode:"), cl::init(api_notes::ActionType::None),
|
|
cl::values(
|
|
clEnumValN(api_notes::ActionType::YAMLToBinary,
|
|
"yaml-to-binary", "Convert YAML to binary format"),
|
|
clEnumValN(api_notes::ActionType::BinaryToYAML,
|
|
"binary-to-yaml",
|
|
"Convert binary format to YAML"),
|
|
clEnumValN(api_notes::ActionType::Dump,
|
|
"dump", "Parse and dump the output"),
|
|
clEnumValEnd),
|
|
cl::cat(APINotesCategory));
|
|
|
|
static cl::opt<std::string>
|
|
InputFilename(cl::Positional, cl::desc("<input file>"),
|
|
cl::Required, cl::cat(APINotesCategory));
|
|
|
|
static cl::opt<std::string>
|
|
Target("target", cl::desc("Generate binary format for the given target"),
|
|
cl::cat(APINotesCategory));
|
|
|
|
static cl::opt<std::string>
|
|
OutputFilename("o", cl::desc("Output file name"), cl::cat(APINotesCategory));
|
|
|
|
// Hide unrelated options.
|
|
StringMap<cl::Option *> &Options =
|
|
cl::getRegisteredOptions(*cl::TopLevelSubCommand);
|
|
for (auto &Option : Options)
|
|
if (Option.second->Category != &APINotesCategory &&
|
|
Option.first() != "help" && Option.first() != "version")
|
|
Option.second->setHiddenFlag(cl::ReallyHidden);
|
|
|
|
cl::ParseCommandLineOptions(Args.size(),
|
|
Args.data(),
|
|
"Swift API Notes Tool\n");
|
|
|
|
if (Action == clang::api_notes::ActionType::None) {
|
|
errs() << "action required\n";
|
|
cl::PrintHelpMessage();
|
|
return 1;
|
|
}
|
|
|
|
auto fileBufOrErr = MemoryBuffer::getFile(InputFilename);
|
|
if (std::error_code EC = fileBufOrErr.getError()) {
|
|
llvm::errs() << "\n Could not open input file: " + EC.message() << '\n';
|
|
return true;
|
|
}
|
|
StringRef input = fileBufOrErr.get()->getBuffer();
|
|
|
|
switch (Action) {
|
|
case api_notes::ActionType::None:
|
|
llvm_unreachable("handled above");
|
|
|
|
case api_notes::ActionType::YAMLToBinary: {
|
|
if (OutputFilename.empty()) {
|
|
errs() << "output file is required\n";
|
|
cl::PrintHelpMessage();
|
|
return 1;
|
|
}
|
|
|
|
api_notes::OSType targetOS = api_notes::OSType::Absent;
|
|
// TODO: Check that we've specified the target.
|
|
if (!Target.empty()) {
|
|
llvm::Triple target(llvm::Triple::normalize(Target));
|
|
switch (target.getOS()) {
|
|
case llvm::Triple::Darwin:
|
|
case llvm::Triple::MacOSX:
|
|
targetOS = api_notes::OSType::OSX;
|
|
break;
|
|
case llvm::Triple::IOS:
|
|
targetOS = api_notes::OSType::IOS;
|
|
break;
|
|
case llvm::Triple::TvOS:
|
|
targetOS = api_notes::OSType::TvOS;
|
|
break;
|
|
case llvm::Triple::WatchOS:
|
|
targetOS = api_notes::OSType::WatchOS;
|
|
break;
|
|
default:
|
|
errs() << "target is not supported\n";
|
|
return 1;
|
|
}
|
|
}
|
|
std::error_code EC;
|
|
llvm::raw_fd_ostream os(OutputFilename, EC,
|
|
llvm::sys::fs::OpenFlags::F_None);
|
|
|
|
if (api_notes::compileAPINotes(input, os, targetOS))
|
|
return 1;
|
|
|
|
os.flush();
|
|
|
|
return os.has_error();
|
|
}
|
|
|
|
case api_notes::ActionType::BinaryToYAML: {
|
|
if (OutputFilename.empty()) {
|
|
errs() << "output file required\n";
|
|
cl::PrintHelpMessage();
|
|
return 1;
|
|
}
|
|
|
|
std::error_code EC;
|
|
llvm::raw_fd_ostream os(OutputFilename, EC,
|
|
llvm::sys::fs::OpenFlags::F_None);
|
|
|
|
if (api_notes::decompileAPINotes(std::move(fileBufOrErr.get()), os))
|
|
return 1;
|
|
|
|
os.flush();
|
|
|
|
return os.has_error();
|
|
}
|
|
|
|
case api_notes::ActionType::Dump:
|
|
return api_notes::parseAndDumpAPINotes(input);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|