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