Add command line option(s) to chose text format.

Added command line options to header-abi-dumper and header-abi-diff to
support multiple text formats.

Bug: 63865902

Test: BOARD_VNDK_VERSION=current mm -j64 in
      frameworks/compile/libbcc/bcinfo produces libbcinfo.so.lsdump
      successfully.

Test: tests/test.py; all tests pass.

Change-Id: I291d3af16e90b12ee131bb864f90a5b96189db13
This commit is contained in:
Jayant Chowdhary
2017-10-25 13:19:32 -07:00
parent b297a70f18
commit 33ea1d01eb
13 changed files with 129 additions and 66 deletions

View File

@@ -18,9 +18,6 @@
#include <llvm/Support/raw_ostream.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <memory>
#include <string>
#include <vector>
@@ -30,16 +27,16 @@
abi_util::CompatibilityStatusIR HeaderAbiDiff::GenerateCompatibilityReport() {
using abi_util::TextFormatToIRReader;
std::unique_ptr<abi_util::TextFormatToIRReader> old_reader =
TextFormatToIRReader::CreateTextFormatToIRReader("protobuf");
TextFormatToIRReader::CreateTextFormatToIRReader(text_format_old_);
std::unique_ptr<abi_util::TextFormatToIRReader> new_reader =
TextFormatToIRReader::CreateTextFormatToIRReader("protobuf");
TextFormatToIRReader::CreateTextFormatToIRReader(text_format_new_);
if (!old_reader || !new_reader || !old_reader->ReadDump(old_dump_) ||
!new_reader->ReadDump(new_dump_)) {
llvm::errs() << "Could not create Text Format readers\n";
::exit(1);
}
std::unique_ptr<abi_util::IRDiffDumper> ir_diff_dumper =
abi_util::IRDiffDumper::CreateIRDiffDumper("protobuf", cr_);
abi_util::IRDiffDumper::CreateIRDiffDumper(text_format_diff_, cr_);
abi_util::CompatibilityStatusIR status =
CompareTUs(old_reader.get(), new_reader.get(), ir_diff_dumper.get());
if (!ir_diff_dumper->Dump()) {

View File

@@ -34,10 +34,14 @@ class HeaderAbiDiff {
const std::string &old_dump, const std::string &new_dump,
const std::string &compatibility_report,
const std::set<std::string> &ignored_symbols,
bool check_all_apis)
bool check_all_apis, abi_util::TextFormatIR text_format_old,
abi_util::TextFormatIR text_format_new,
abi_util::TextFormatIR text_format_diff)
: lib_name_(lib_name), arch_(arch), old_dump_(old_dump),
new_dump_(new_dump), cr_(compatibility_report),
ignored_symbols_(ignored_symbols), check_all_apis_(check_all_apis) { }
ignored_symbols_(ignored_symbols), check_all_apis_(check_all_apis),
text_format_old_(text_format_old), text_format_new_(text_format_new),
text_format_diff_(text_format_diff) { }
abi_util::CompatibilityStatusIR GenerateCompatibilityReport();
@@ -131,4 +135,7 @@ class HeaderAbiDiff {
const std::set<std::string> &ignored_symbols_;
bool check_all_apis_;
std::set<std::string> type_cache_;
abi_util::TextFormatIR text_format_old_;
abi_util::TextFormatIR text_format_new_;
abi_util::TextFormatIR text_format_diff_;
};

View File

@@ -85,6 +85,30 @@ static llvm::cl::opt<bool> allow_unreferenced_changes(
" APIs."),
llvm::cl::Optional, llvm::cl::cat(header_checker_category));
static llvm::cl::opt<abi_util::TextFormatIR> text_format_old(
"text-format-old", llvm::cl::desc("Specify text format of old abi dump"),
llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat,
"ProtobufTextFormat","ProtobufTextFormat"),
clEnumValEnd),
llvm::cl::init(abi_util::TextFormatIR::ProtobufTextFormat),
llvm::cl::cat(header_checker_category));
static llvm::cl::opt<abi_util::TextFormatIR> text_format_new(
"text-format-new", llvm::cl::desc("Specify text format of new abi dump"),
llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat,
"ProtobufTextFormat", "ProtobugTextFormat"),
clEnumValEnd),
llvm::cl::init(abi_util::TextFormatIR::ProtobufTextFormat),
llvm::cl::cat(header_checker_category));
static llvm::cl::opt<abi_util::TextFormatIR> text_format_diff(
"text-format-diff", llvm::cl::desc("Specify text format of abi-diff"),
llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat,
"ProtobufTextFormat", "ProtobufTextFormat"),
clEnumValEnd),
llvm::cl::init(abi_util::TextFormatIR::ProtobufTextFormat),
llvm::cl::cat(header_checker_category));
static std::set<std::string> LoadIgnoredSymbols(std::string &symbol_list_path) {
std::ifstream symbol_ifstream(symbol_list_path);
std::set<std::string> ignored_symbols;
@@ -100,14 +124,14 @@ static std::set<std::string> LoadIgnoredSymbols(std::string &symbol_list_path) {
}
int main(int argc, const char **argv) {
GOOGLE_PROTOBUF_VERIFY_VERSION;
llvm::cl::ParseCommandLineOptions(argc, argv, "header-checker");
std::set<std::string> ignored_symbols;
if (llvm::sys::fs::exists(ignore_symbol_list)) {
ignored_symbols = LoadIgnoredSymbols(ignore_symbol_list);
}
HeaderAbiDiff judge(lib_name, arch, old_dump, new_dump, compatibility_report,
ignored_symbols, check_all_apis);
ignored_symbols, check_all_apis, text_format_old,
text_format_new, text_format_diff);
abi_util::CompatibilityStatusIR status = judge.GenerateCompatibilityReport();

View File

@@ -33,7 +33,6 @@ HeaderASTVisitor::HeaderASTVisitor(
clang::MangleContext *mangle_contextp,
clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p,
const std::string &current_file_name,
const std::set<std::string> &exported_headers,
const clang::Decl *tu_decl,
std::set<std::string> *type_cache,
@@ -41,7 +40,6 @@ HeaderASTVisitor::HeaderASTVisitor(
: mangle_contextp_(mangle_contextp),
ast_contextp_(ast_contextp),
cip_(compiler_instance_p),
current_file_name_(current_file_name),
exported_headers_(exported_headers),
tu_decl_(tu_decl),
type_cache_(type_cache),
@@ -167,14 +165,14 @@ bool HeaderASTVisitor::TraverseDecl(clang::Decl *decl) {
}
HeaderASTConsumer::HeaderASTConsumer(
const std::string &file_name,
clang::CompilerInstance *compiler_instancep,
const std::string &out_dump_name,
const std::set<std::string> &exported_headers)
: file_name_(file_name),
cip_(compiler_instancep),
const std::set<std::string> &exported_headers,
abi_util::TextFormatIR text_format)
: cip_(compiler_instancep),
out_dump_name_(out_dump_name),
exported_headers_(exported_headers) { }
exported_headers_(exported_headers),
text_format_(text_format){ }
void HeaderASTConsumer::HandleTranslationUnit(clang::ASTContext &ctx) {
clang::PrintingPolicy policy(ctx.getPrintingPolicy());
@@ -188,10 +186,9 @@ void HeaderASTConsumer::HandleTranslationUnit(clang::ASTContext &ctx) {
ctx.createMangleContext());
std::set<std::string> type_cache;
std::unique_ptr<abi_util::IRDumper> ir_dumper =
abi_util::IRDumper::CreateIRDumper("protobuf", out_dump_name_);
HeaderASTVisitor v(mangle_contextp.get(), &ctx, cip_, file_name_,
exported_headers_, translation_unit, &type_cache,
ir_dumper.get());
abi_util::IRDumper::CreateIRDumper(text_format_, out_dump_name_);
HeaderASTVisitor v(mangle_contextp.get(), &ctx, cip_, exported_headers_,
translation_unit, &type_cache, ir_dumper.get());
if (!v.TraverseDecl(translation_unit) || !ir_dumper->Dump()) {
llvm::errs() << "Serialization to ostream failed\n";
::exit(1);

View File

@@ -38,7 +38,6 @@ class HeaderASTVisitor
HeaderASTVisitor(clang::MangleContext *mangle_contextp,
clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p,
const std::string &current_file_name,
const std::set<std::string> &exported_headers,
const clang::Decl *tu_decl,
std::set<std::string> *type_cache,
@@ -63,7 +62,6 @@ class HeaderASTVisitor
clang::MangleContext *mangle_contextp_;
clang::ASTContext *ast_contextp_;
const clang::CompilerInstance *cip_;
const std::string current_file_name_;
const std::set<std::string> &exported_headers_;
// To optimize recursion into only exported abi.
const clang::Decl *tu_decl_;
@@ -76,18 +74,18 @@ class HeaderASTVisitor
class HeaderASTConsumer : public clang::ASTConsumer {
public:
HeaderASTConsumer(const std::string &file_name,
clang::CompilerInstance *compiler_instancep,
HeaderASTConsumer(clang::CompilerInstance *compiler_instancep,
const std::string &out_dump_name,
const std::set<std::string> &exported_headers);
const std::set<std::string> &exported_headers,
abi_util::TextFormatIR text_format);
void HandleTranslationUnit(clang::ASTContext &ctx) override;
private:
std::string file_name_;
clang::CompilerInstance *cip_;
std::string out_dump_name_;
const std::string &out_dump_name_;
const std::set<std::string> &exported_headers_;
abi_util::TextFormatIR text_format_;
};
#endif // AST_PROCESSING_H_

View File

@@ -16,6 +16,7 @@
#include "ast_processing.h"
#include "frontend_action.h"
#include <header_abi_util.h>
#include <ir_representation.h>
#include <clang/AST/ASTConsumer.h>
#include <clang/Frontend/CompilerInstance.h>
@@ -25,13 +26,15 @@
#include <llvm/Support/Path.h>
HeaderCheckerFrontendAction::HeaderCheckerFrontendAction(
const std::string &dump_name, const std::set<std::string> &exported_headers)
: dump_name_(dump_name), exported_headers_(exported_headers) { }
const std::string &dump_name, const std::set<std::string> &exported_headers,
abi_util::TextFormatIR text_format)
: dump_name_(dump_name), exported_headers_(exported_headers),
text_format_(text_format) { }
std::unique_ptr<clang::ASTConsumer>
HeaderCheckerFrontendAction::CreateASTConsumer(clang::CompilerInstance &ci,
llvm::StringRef header_file) {
// Create AST consumers.
return llvm::make_unique<HeaderASTConsumer>(header_file, &ci, dump_name_,
exported_headers_);
return llvm::make_unique<HeaderASTConsumer>(&ci, dump_name_,
exported_headers_, text_format_);
}

View File

@@ -15,6 +15,8 @@
#ifndef FRONTEND_ACTION_H_
#define FRONTEND_ACTION_H_
#include <ir_representation.h>
#include <clang/Frontend/FrontendAction.h>
#include <llvm/ADT/StringRef.h>
@@ -30,13 +32,15 @@ namespace clang {
class HeaderCheckerFrontendAction : public clang::ASTFrontendAction {
private:
std::string dump_name_;
const std::string &dump_name_;
const std::set<std::string> &exported_headers_;
abi_util::TextFormatIR text_format_;
public:
HeaderCheckerFrontendAction(
const std::string &dump_name,
const std::set<std::string> &exported_headers);
const std::set<std::string> &exported_headers,
abi_util::TextFormatIR text_format);
protected:
std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(

View File

@@ -20,9 +20,12 @@
HeaderCheckerFrontendActionFactory::HeaderCheckerFrontendActionFactory(
const std::string &dump_name,
const std::set<std::string> &exported_headers)
: dump_name_(dump_name), exported_headers_(exported_headers) { }
const std::set<std::string> &exported_headers,
abi_util::TextFormatIR text_format)
: dump_name_(dump_name), exported_headers_(exported_headers),
text_format_(text_format) { }
clang::FrontendAction *HeaderCheckerFrontendActionFactory::create() {
return new HeaderCheckerFrontendAction(dump_name_, exported_headers_);
return new HeaderCheckerFrontendAction(dump_name_, exported_headers_,
text_format_);
}

View File

@@ -15,6 +15,7 @@
#ifndef FRONTEND_ACTION_FACTORY_H_
#define FRONTEND_ACTION_FACTORY_H_
#include <ir_representation.h>
#include <clang/Tooling/Tooling.h>
#include <vector>
@@ -22,13 +23,15 @@
class HeaderCheckerFrontendActionFactory
: public clang::tooling::FrontendActionFactory {
private:
std::string dump_name_;
const std::string &dump_name_;
const std::set<std::string> &exported_headers_;
abi_util::TextFormatIR text_format_;
public:
HeaderCheckerFrontendActionFactory(
const std::string &dump_name,
const std::set<std::string> &exported_headers);
const std::set<std::string> &exported_headers,
abi_util::TextFormatIR text_format);
clang::FrontendAction *create() override;
};

View File

@@ -49,6 +49,14 @@ static llvm::cl::opt<bool> no_filter(
"no-filter", llvm::cl::desc("Do not filter any abi"), llvm::cl::Optional,
llvm::cl::cat(header_checker_category));
static llvm::cl::opt<abi_util::TextFormatIR> text_format(
"text-format", llvm::cl::desc("Specify text format of abi dump"),
llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat,
"ProtobufTextFormat", "ProtobufTextFormat"),
clEnumValEnd),
llvm::cl::init(abi_util::TextFormatIR::ProtobufTextFormat),
llvm::cl::cat(header_checker_category));
// Hide irrelevant command line options defined in LLVM libraries.
static void HideIrrelevantCommandLineOptions() {
llvm::StringMap<llvm::cl::Option *> &map = llvm::cl::getRegisteredOptions();
@@ -108,7 +116,8 @@ int main(int argc, const char **argv) {
clang::tooling::ClangTool tool(*compilations, header_files);
std::unique_ptr<clang::tooling::FrontendActionFactory> factory(
new HeaderCheckerFrontendActionFactory(out_dump, exported_headers));
new HeaderCheckerFrontendActionFactory(out_dump, exported_headers,
text_format));
return tool.run(factory.get());
}

View File

@@ -65,6 +65,14 @@ static llvm::cl::opt<std::string> so_file(
"so", llvm::cl::desc("<path to so file>"), llvm::cl::Optional,
llvm::cl::cat(header_linker_category));
static llvm::cl::opt<abi_util::TextFormatIR> text_format(
"text-format", llvm::cl::desc("Specify text format of abi dumps"),
llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat,
"ProtobufTextFormat", "ProtobufTextFormat"),
clEnumValEnd),
llvm::cl::init(abi_util::TextFormatIR::ProtobufTextFormat),
llvm::cl::cat(header_linker_category));
class HeaderAbiLinker {
public:
HeaderAbiLinker(
@@ -153,7 +161,7 @@ static void DeDuplicateAbiElementsThread(
std::atomic<std::size_t> *cnt) {
std::unique_ptr<abi_util::TextFormatToIRReader> local_reader =
abi_util::TextFormatToIRReader::CreateTextFormatToIRReader(
"protobuf", exported_headers);
text_format, exported_headers);
auto begin_it = dump_files.begin();
std::size_t num_sources = dump_files.size();
while (1) {
@@ -164,7 +172,7 @@ static void DeDuplicateAbiElementsThread(
std::size_t end = std::min(i + kSourcesPerBatchThread, num_sources);
std::unique_ptr<abi_util::TextFormatToIRReader> reader =
abi_util::TextFormatToIRReader::CreateTextFormatToIRReader(
"protobuf", exported_headers);
text_format, exported_headers);
assert(reader != nullptr);
if (!reader->ReadDumps(begin_it + i, begin_it + end)) {
llvm::errs() << "ReadDump failed\n";
@@ -191,14 +199,14 @@ bool HeaderAbiLinker::LinkAndDump() {
return false;
}
std::unique_ptr<abi_util::IRDumper> ir_dumper =
abi_util::IRDumper::CreateIRDumper("protobuf", out_dump_name_);
abi_util::IRDumper::CreateIRDumper(text_format, out_dump_name_);
assert(ir_dumper != nullptr);
AddElfSymbols(ir_dumper.get());
// Create a reader, on which we never actually call ReadDump(), since multiple
// dump files are associated with it.
std::unique_ptr<abi_util::TextFormatToIRReader> greader =
abi_util::TextFormatToIRReader::CreateTextFormatToIRReader(
"protobuf", &exported_headers_);
text_format, &exported_headers_);
std::size_t max_threads = std::thread::hardware_concurrency();
std::size_t num_threads = kSourcesPerBatchThread < dump_files_.size() ?
std::min(dump_files_.size() / kSourcesPerBatchThread,

View File

@@ -28,6 +28,10 @@ namespace abi_util {
template <typename T>
using AbiElementMap = std::map<std::string, T>;
enum TextFormatIR {
ProtobufTextFormat = 0,
};
enum CompatibilityStatusIR {
Compatible = 0,
UnreferencedChanges = 1,
@@ -694,8 +698,8 @@ class IRDumper {
public:
IRDumper(const std::string &dump_path) : dump_path_(dump_path) { }
static std::unique_ptr<IRDumper> CreateIRDumper(const std::string &type,
const std::string &dump_path);
static std::unique_ptr<IRDumper> CreateIRDumper(
TextFormatIR text_format, const std::string &dump_path);
virtual bool AddLinkableMessageIR(const LinkableMessageIR *) = 0;
@@ -797,7 +801,7 @@ class TextFormatToIRReader {
}
static std::unique_ptr<TextFormatToIRReader> CreateTextFormatToIRReader(
const std::string &text_format,
TextFormatIR text_format,
const std::set<std::string> *exported_headers = nullptr);
protected:
@@ -1164,7 +1168,7 @@ class IRDiffDumper {
virtual ~IRDiffDumper() {}
static std::unique_ptr<IRDiffDumper> CreateIRDiffDumper(
const std::string &type, const std::string &dump_path);
TextFormatIR, const std::string &dump_path);
protected:
const std::string &dump_path_;
};

View File

@@ -33,35 +33,41 @@
namespace abi_util {
std::unique_ptr<IRDumper> IRDumper::CreateIRDumper(
const std::string &type, const std::string &dump_path) {
if (type == "protobuf") {
TextFormatIR text_format, const std::string &dump_path) {
switch (text_format) {
case TextFormatIR::ProtobufTextFormat:
return std::make_unique<ProtobufIRDumper>(dump_path);
}
default:
// Nothing else is supported yet.
llvm::errs() << type << " message format is not supported yet!\n";
llvm::errs() << "Text format not supported yet\n";
return nullptr;
}
}
std::unique_ptr<IRDiffDumper> IRDiffDumper::CreateIRDiffDumper(
const std::string &type, const std::string &dump_path) {
if (type == "protobuf") {
TextFormatIR text_format, const std::string &dump_path) {
switch (text_format) {
case TextFormatIR::ProtobufTextFormat:
return std::make_unique<ProtobufIRDiffDumper>(dump_path);
}
default:
// Nothing else is supported yet.
llvm::errs() << type << " message format is not supported yet!\n";
llvm::errs() << "Text format not supported yet\n";
return nullptr;
}
}
std::unique_ptr<TextFormatToIRReader>
TextFormatToIRReader::CreateTextFormatToIRReader(
const std::string &type, const std::set<std::string> *exported_headers) {
if (type == "protobuf") {
TextFormatIR text_format, const std::set<std::string> *exported_headers) {
switch (text_format) {
case TextFormatIR::ProtobufTextFormat:
return std::make_unique<ProtobufTextFormatToIRReader>(exported_headers);
}
default:
// Nothing else is supported yet.
llvm::errs() << type << " message format is not supported yet!\n";
llvm::errs() << "Text format not supported yet\n";
return nullptr;
}
}
} // namespace abi_util