Merge "Add a command line option to dump function declarations"
This commit is contained in:
@@ -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";
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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_
|
||||
|
||||
Reference in New Issue
Block a user