Merge "Add a command line option to dump function declarations" am: 508383c403

am: 8a01a00c99

Change-Id: I9df8de483934030db971788ba33a8b96a1c7abac
This commit is contained in:
Hsin-Yi Chen
2018-11-08 00:45:54 -08:00
committed by android-build-merger
4 changed files with 42 additions and 29 deletions

View File

@@ -31,20 +31,14 @@ using abi_wrapper::EnumDeclWrapper;
using abi_wrapper::GlobalVarDeclWrapper; using abi_wrapper::GlobalVarDeclWrapper;
HeaderASTVisitor::HeaderASTVisitor( HeaderASTVisitor::HeaderASTVisitor(
clang::MangleContext *mangle_contextp, const HeaderCheckerOptions &options, clang::MangleContext *mangle_contextp,
clang::ASTContext *ast_contextp, clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p, const clang::CompilerInstance *compiler_instance_p,
const std::set<std::string> &exported_headers, const clang::Decl *tu_decl, abi_util::IRDumper *ir_dumper,
const clang::Decl *tu_decl,
abi_util::IRDumper *ir_dumper,
ast_util::ASTCaches *ast_caches) ast_util::ASTCaches *ast_caches)
: mangle_contextp_(mangle_contextp), : options_(options), mangle_contextp_(mangle_contextp),
ast_contextp_(ast_contextp), ast_contextp_(ast_contextp), cip_(compiler_instance_p), tu_decl_(tu_decl),
cip_(compiler_instance_p), ir_dumper_(ir_dumper), ast_caches_(ast_caches) {}
exported_headers_(exported_headers),
tu_decl_(tu_decl),
ir_dumper_(ir_dumper),
ast_caches_(ast_caches) {}
bool HeaderASTVisitor::VisitRecordDecl(const clang::RecordDecl *decl) { bool HeaderASTVisitor::VisitRecordDecl(const clang::RecordDecl *decl) {
// Avoid segmentation fault in getASTRecordLayout. // Avoid segmentation fault in getASTRecordLayout.
@@ -96,8 +90,15 @@ static bool AddMangledFunctions(const abi_util::FunctionIR *function,
return true; return true;
} }
static bool ShouldSkipFunctionDecl(const clang::FunctionDecl *decl) { bool HeaderASTVisitor::ShouldSkipFunctionDecl(const clang::FunctionDecl *decl) {
if (!decl->getDefinition()) { if (!decl->getDefinition()) {
if (!options_.dump_function_declarations_ ||
options_.source_file_ != ABIWrapper::GetDeclSourceFile(decl, cip_)) {
return true;
}
}
// Skip explicitly deleted functions such as `Foo operator=(Foo) = delete;`.
if (decl->isDeleted()) {
return true; return true;
} }
if (decl->getLinkageAndVisibility().getLinkage() != if (decl->getLinkageAndVisibility().getLinkage() !=
@@ -165,8 +166,9 @@ bool HeaderASTVisitor::TraverseDecl(clang::Decl *decl) {
ast_caches_->decl_to_source_file_cache_.insert( ast_caches_->decl_to_source_file_cache_.insert(
std::make_pair(decl, source_file)); std::make_pair(decl, source_file));
// If no exported headers are specified we assume the whole AST is exported. // If no exported headers are specified we assume the whole AST is exported.
if ((decl != tu_decl_) && AreHeadersExported(exported_headers_) && const auto &exported_headers = options_.exported_headers_;
(exported_headers_.find(source_file) == exported_headers_.end())) { if ((decl != tu_decl_) && AreHeadersExported(exported_headers) &&
(exported_headers.find(source_file) == exported_headers.end())) {
return true; return true;
} }
// If at all we're looking at the source file's AST decl node, it should be a // If at all we're looking at the source file's AST decl node, it should be a
@@ -202,9 +204,8 @@ void HeaderASTConsumer::HandleTranslationUnit(clang::ASTContext &ctx) {
std::unique_ptr<abi_util::IRDumper> ir_dumper = std::unique_ptr<abi_util::IRDumper> ir_dumper =
abi_util::IRDumper::CreateIRDumper(options_.text_format_, abi_util::IRDumper::CreateIRDumper(options_.text_format_,
options_.dump_name_); options_.dump_name_);
HeaderASTVisitor v(mangle_contextp.get(), &ctx, cip_, HeaderASTVisitor v(options_, mangle_contextp.get(), &ctx, cip_,
options_.exported_headers_, translation_unit, translation_unit, ir_dumper.get(), &ast_caches);
ir_dumper.get(), &ast_caches);
if (!v.TraverseDecl(translation_unit) || !ir_dumper->Dump()) { if (!v.TraverseDecl(translation_unit) || !ir_dumper->Dump()) {
llvm::errs() << "Serialization to ostream failed\n"; llvm::errs() << "Serialization to ostream failed\n";

View File

@@ -30,10 +30,10 @@
class HeaderASTVisitor class HeaderASTVisitor
: public clang::RecursiveASTVisitor<HeaderASTVisitor> { : public clang::RecursiveASTVisitor<HeaderASTVisitor> {
public: public:
HeaderASTVisitor(clang::MangleContext *mangle_contextp, HeaderASTVisitor(const HeaderCheckerOptions &options,
clang::MangleContext *mangle_contextp,
clang::ASTContext *ast_contextp, clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p, const clang::CompilerInstance *compiler_instance_p,
const std::set<std::string> &exported_headers,
const clang::Decl *tu_decl, const clang::Decl *tu_decl,
abi_util::IRDumper *ir_dumper, abi_util::IRDumper *ir_dumper,
ast_util::ASTCaches *ast_caches); ast_util::ASTCaches *ast_caches);
@@ -49,15 +49,15 @@ class HeaderASTVisitor
bool TraverseDecl(clang::Decl *decl); bool TraverseDecl(clang::Decl *decl);
// Enable recursive traversal of template instantiations. // Enable recursive traversal of template instantiations.
bool shouldVisitTemplateInstantiations() const { bool shouldVisitTemplateInstantiations() const { return true; }
return true;
}
private: private:
bool ShouldSkipFunctionDecl(const clang::FunctionDecl *decl);
const HeaderCheckerOptions &options_;
clang::MangleContext *mangle_contextp_; clang::MangleContext *mangle_contextp_;
clang::ASTContext *ast_contextp_; clang::ASTContext *ast_contextp_;
const clang::CompilerInstance *cip_; const clang::CompilerInstance *cip_;
const std::set<std::string> &exported_headers_;
// To optimize recursion into only exported abi. // To optimize recursion into only exported abi.
const clang::Decl *tu_decl_; const clang::Decl *tu_decl_;
abi_util::IRDumper *ir_dumper_; abi_util::IRDumper *ir_dumper_;

View File

@@ -57,6 +57,12 @@ static llvm::cl::opt<bool> suppress_errors(
llvm::cl::desc("Suppress preprocess and semantic errors"), llvm::cl::desc("Suppress preprocess and semantic errors"),
llvm::cl::Optional, llvm::cl::cat(header_checker_category)); llvm::cl::Optional, llvm::cl::cat(header_checker_category));
static llvm::cl::opt<bool> dump_function_declarations(
"dump-function-declarations",
llvm::cl::desc("Output the functions declared but not defined in the input "
"file"),
llvm::cl::Optional, llvm::cl::cat(header_checker_category));
static llvm::cl::opt<abi_util::TextFormatIR> output_format( static llvm::cl::opt<abi_util::TextFormatIR> output_format(
"output-format", llvm::cl::desc("Specify format of output dump file"), "output-format", llvm::cl::desc("Specify format of output dump file"),
llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat, llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat,
@@ -130,8 +136,9 @@ int main(int argc, const char **argv) {
// Initialize clang tools and run front-end action. // Initialize clang tools and run front-end action.
std::vector<std::string> header_files{ header_file }; std::vector<std::string> header_files{ header_file };
HeaderCheckerOptions options(out_dump, std::move(exported_headers), HeaderCheckerOptions options(abi_util::RealPath(header_file), out_dump,
output_format, suppress_errors); std::move(exported_headers), output_format,
dump_function_declarations, suppress_errors);
clang::tooling::ClangTool tool(*compilations, header_files); clang::tooling::ClangTool tool(*compilations, header_files);
std::unique_ptr<clang::tooling::FrontendActionFactory> factory( std::unique_ptr<clang::tooling::FrontendActionFactory> factory(

View File

@@ -22,18 +22,23 @@
class HeaderCheckerOptions { class HeaderCheckerOptions {
public: public:
std::string source_file_;
std::string dump_name_; std::string dump_name_;
std::set<std::string> exported_headers_; std::set<std::string> exported_headers_;
abi_util::TextFormatIR text_format_; abi_util::TextFormatIR text_format_;
bool dump_function_declarations_;
bool suppress_errors_; bool suppress_errors_;
public: public:
HeaderCheckerOptions(std::string dump_name, HeaderCheckerOptions(std::string source_file, std::string dump_name,
std::set<std::string> exported_headers, std::set<std::string> exported_headers,
abi_util::TextFormatIR text_format, bool suppress_errors) abi_util::TextFormatIR text_format,
: dump_name_(std::move(dump_name)), bool dump_function_declarations, bool suppress_errors)
: source_file_(std::move(source_file)), dump_name_(std::move(dump_name)),
exported_headers_(std::move(exported_headers)), exported_headers_(std::move(exported_headers)),
text_format_(text_format), suppress_errors_(suppress_errors) {} text_format_(text_format),
dump_function_declarations_(dump_function_declarations),
suppress_errors_(suppress_errors) {}
}; };
#endif // HEADER_CHECKER_H_ #endif // HEADER_CHECKER_H_