Merge "Add a command line option to dump function declarations"

This commit is contained in:
Treehugger Robot
2018-11-08 08:27:26 +00:00
committed by Gerrit Code Review
4 changed files with 42 additions and 29 deletions

View File

@@ -31,20 +31,14 @@ using abi_wrapper::EnumDeclWrapper;
using abi_wrapper::GlobalVarDeclWrapper;
HeaderASTVisitor::HeaderASTVisitor(
clang::MangleContext *mangle_contextp,
const HeaderCheckerOptions &options, clang::MangleContext *mangle_contextp,
clang::ASTContext *ast_contextp,
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)
: mangle_contextp_(mangle_contextp),
ast_contextp_(ast_contextp),
cip_(compiler_instance_p),
exported_headers_(exported_headers),
tu_decl_(tu_decl),
ir_dumper_(ir_dumper),
ast_caches_(ast_caches) {}
: options_(options), mangle_contextp_(mangle_contextp),
ast_contextp_(ast_contextp), cip_(compiler_instance_p), tu_decl_(tu_decl),
ir_dumper_(ir_dumper), ast_caches_(ast_caches) {}
bool HeaderASTVisitor::VisitRecordDecl(const clang::RecordDecl *decl) {
// Avoid segmentation fault in getASTRecordLayout.
@@ -96,8 +90,15 @@ static bool AddMangledFunctions(const abi_util::FunctionIR *function,
return true;
}
static bool ShouldSkipFunctionDecl(const clang::FunctionDecl *decl) {
bool HeaderASTVisitor::ShouldSkipFunctionDecl(const clang::FunctionDecl *decl) {
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;
}
if (decl->getLinkageAndVisibility().getLinkage() !=
@@ -165,8 +166,9 @@ bool HeaderASTVisitor::TraverseDecl(clang::Decl *decl) {
ast_caches_->decl_to_source_file_cache_.insert(
std::make_pair(decl, source_file));
// If no exported headers are specified we assume the whole AST is exported.
if ((decl != tu_decl_) && AreHeadersExported(exported_headers_) &&
(exported_headers_.find(source_file) == exported_headers_.end())) {
const auto &exported_headers = options_.exported_headers_;
if ((decl != tu_decl_) && AreHeadersExported(exported_headers) &&
(exported_headers.find(source_file) == exported_headers.end())) {
return true;
}
// 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 =
abi_util::IRDumper::CreateIRDumper(options_.text_format_,
options_.dump_name_);
HeaderASTVisitor v(mangle_contextp.get(), &ctx, cip_,
options_.exported_headers_, translation_unit,
ir_dumper.get(), &ast_caches);
HeaderASTVisitor v(options_, mangle_contextp.get(), &ctx, cip_,
translation_unit, ir_dumper.get(), &ast_caches);
if (!v.TraverseDecl(translation_unit) || !ir_dumper->Dump()) {
llvm::errs() << "Serialization to ostream failed\n";

View File

@@ -30,10 +30,10 @@
class HeaderASTVisitor
: public clang::RecursiveASTVisitor<HeaderASTVisitor> {
public:
HeaderASTVisitor(clang::MangleContext *mangle_contextp,
HeaderASTVisitor(const HeaderCheckerOptions &options,
clang::MangleContext *mangle_contextp,
clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p,
const std::set<std::string> &exported_headers,
const clang::Decl *tu_decl,
abi_util::IRDumper *ir_dumper,
ast_util::ASTCaches *ast_caches);
@@ -49,15 +49,15 @@ class HeaderASTVisitor
bool TraverseDecl(clang::Decl *decl);
// Enable recursive traversal of template instantiations.
bool shouldVisitTemplateInstantiations() const {
return true;
}
bool shouldVisitTemplateInstantiations() const { return true; }
private:
bool ShouldSkipFunctionDecl(const clang::FunctionDecl *decl);
const HeaderCheckerOptions &options_;
clang::MangleContext *mangle_contextp_;
clang::ASTContext *ast_contextp_;
const clang::CompilerInstance *cip_;
const std::set<std::string> &exported_headers_;
// To optimize recursion into only exported abi.
const clang::Decl *tu_decl_;
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::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(
"output-format", llvm::cl::desc("Specify format of output dump file"),
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.
std::vector<std::string> header_files{ header_file };
HeaderCheckerOptions options(out_dump, std::move(exported_headers),
output_format, suppress_errors);
HeaderCheckerOptions options(abi_util::RealPath(header_file), out_dump,
std::move(exported_headers), output_format,
dump_function_declarations, suppress_errors);
clang::tooling::ClangTool tool(*compilations, header_files);
std::unique_ptr<clang::tooling::FrontendActionFactory> factory(

View File

@@ -22,18 +22,23 @@
class HeaderCheckerOptions {
public:
std::string source_file_;
std::string dump_name_;
std::set<std::string> exported_headers_;
abi_util::TextFormatIR text_format_;
bool dump_function_declarations_;
bool suppress_errors_;
public:
HeaderCheckerOptions(std::string dump_name,
HeaderCheckerOptions(std::string source_file, std::string dump_name,
std::set<std::string> exported_headers,
abi_util::TextFormatIR text_format, bool suppress_errors)
: dump_name_(std::move(dump_name)),
abi_util::TextFormatIR text_format,
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)),
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_