Merge "Add a command line option to suppress compilation errors"
am: 419ef1bf8e
Change-Id: I47a7612b5000ead27229108f2efac1269be26008
This commit is contained in:
@@ -55,6 +55,7 @@ cc_binary_host {
|
||||
srcs: [
|
||||
"header-abi-dumper/src/abi_wrappers.cpp",
|
||||
"header-abi-dumper/src/ast_processing.cpp",
|
||||
"header-abi-dumper/src/diagnostic_consumer.cpp",
|
||||
"header-abi-dumper/src/fixed_argv.cpp",
|
||||
"header-abi-dumper/src/frontend_action.cpp",
|
||||
"header-abi-dumper/src/frontend_action_factory.cpp",
|
||||
|
||||
@@ -47,6 +47,10 @@ HeaderASTVisitor::HeaderASTVisitor(
|
||||
ast_caches_(ast_caches) {}
|
||||
|
||||
bool HeaderASTVisitor::VisitRecordDecl(const clang::RecordDecl *decl) {
|
||||
// Avoid segmentation fault in getASTRecordLayout.
|
||||
if (decl->isInvalidDecl()) {
|
||||
return true;
|
||||
}
|
||||
// Skip forward declarations, dependent records. Also skip anonymous records
|
||||
// as they will be traversed through record fields.
|
||||
if (!decl->isThisDeclarationADefinition() ||
|
||||
@@ -176,14 +180,8 @@ bool HeaderASTVisitor::TraverseDecl(clang::Decl *decl) {
|
||||
}
|
||||
|
||||
HeaderASTConsumer::HeaderASTConsumer(
|
||||
clang::CompilerInstance *compiler_instancep,
|
||||
const std::string &out_dump_name,
|
||||
std::set<std::string> &exported_headers,
|
||||
abi_util::TextFormatIR text_format)
|
||||
: cip_(compiler_instancep),
|
||||
out_dump_name_(out_dump_name),
|
||||
exported_headers_(exported_headers),
|
||||
text_format_(text_format) {}
|
||||
clang::CompilerInstance *compiler_instancep, HeaderCheckerOptions &options)
|
||||
: cip_(compiler_instancep), options_(options) {}
|
||||
|
||||
void HeaderASTConsumer::HandleTranslationUnit(clang::ASTContext &ctx) {
|
||||
clang::PrintingPolicy policy(ctx.getPrintingPolicy());
|
||||
@@ -198,13 +196,15 @@ void HeaderASTConsumer::HandleTranslationUnit(clang::ASTContext &ctx) {
|
||||
const std::string &translation_unit_source =
|
||||
ABIWrapper::GetDeclSourceFile(translation_unit, cip_);
|
||||
ast_util::ASTCaches ast_caches(translation_unit_source);
|
||||
if (!exported_headers_.empty()) {
|
||||
exported_headers_.insert(translation_unit_source);
|
||||
if (!options_.exported_headers_.empty()) {
|
||||
options_.exported_headers_.insert(translation_unit_source);
|
||||
}
|
||||
std::unique_ptr<abi_util::IRDumper> ir_dumper =
|
||||
abi_util::IRDumper::CreateIRDumper(text_format_, out_dump_name_);
|
||||
HeaderASTVisitor v(mangle_contextp.get(), &ctx, cip_, exported_headers_,
|
||||
translation_unit, ir_dumper.get(), &ast_caches);
|
||||
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);
|
||||
|
||||
if (!v.TraverseDecl(translation_unit) || !ir_dumper->Dump()) {
|
||||
llvm::errs() << "Serialization to ostream failed\n";
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#define AST_PROCESSING_H_
|
||||
|
||||
#include "ast_util.h"
|
||||
#include "ir_representation.h"
|
||||
#include "header_checker.h"
|
||||
|
||||
#include <clang/AST/AST.h>
|
||||
#include <clang/AST/ASTConsumer.h>
|
||||
@@ -69,17 +69,13 @@ class HeaderASTVisitor
|
||||
class HeaderASTConsumer : public clang::ASTConsumer {
|
||||
public:
|
||||
HeaderASTConsumer(clang::CompilerInstance *compiler_instancep,
|
||||
const std::string &out_dump_name,
|
||||
std::set<std::string> &exported_headers,
|
||||
abi_util::TextFormatIR text_format);
|
||||
HeaderCheckerOptions &options);
|
||||
|
||||
void HandleTranslationUnit(clang::ASTContext &ctx) override;
|
||||
|
||||
private:
|
||||
clang::CompilerInstance *cip_;
|
||||
const std::string &out_dump_name_;
|
||||
std::set<std::string> &exported_headers_;
|
||||
abi_util::TextFormatIR text_format_;
|
||||
HeaderCheckerOptions &options_;
|
||||
};
|
||||
|
||||
#endif // AST_PROCESSING_H_
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
// Copyright (C) 2018 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "diagnostic_consumer.h"
|
||||
|
||||
#include <clang/Basic/DiagnosticCategories.h>
|
||||
#include <clang/Basic/DiagnosticIDs.h>
|
||||
#include <clang/Lex/LexDiagnostic.h>
|
||||
|
||||
HeaderCheckerDiagnosticConsumer::HeaderCheckerDiagnosticConsumer(
|
||||
std::unique_ptr<clang::DiagnosticConsumer> wrapped)
|
||||
: wrapped_(std::move(wrapped)) {}
|
||||
|
||||
void HeaderCheckerDiagnosticConsumer::clear() {
|
||||
// Default implementation resets warning/error count.
|
||||
DiagnosticConsumer::clear();
|
||||
wrapped_->clear();
|
||||
}
|
||||
|
||||
void HeaderCheckerDiagnosticConsumer::BeginSourceFile(
|
||||
const clang::LangOptions &lang_opts,
|
||||
const clang::Preprocessor *preprocessor) {
|
||||
wrapped_->BeginSourceFile(lang_opts, preprocessor);
|
||||
}
|
||||
|
||||
void HeaderCheckerDiagnosticConsumer::EndSourceFile() {
|
||||
wrapped_->EndSourceFile();
|
||||
}
|
||||
|
||||
void HeaderCheckerDiagnosticConsumer::finish() { wrapped_->finish(); }
|
||||
|
||||
bool HeaderCheckerDiagnosticConsumer::IncludeInDiagnosticCounts() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void HeaderCheckerDiagnosticConsumer::HandleDiagnostic(
|
||||
clang::DiagnosticsEngine::Level level, const clang::Diagnostic &info) {
|
||||
if (level < clang::DiagnosticsEngine::Level::Error) {
|
||||
return;
|
||||
}
|
||||
unsigned id = info.getID();
|
||||
if (id == clang::diag::err_pp_hash_error ||
|
||||
id == clang::diag::fatal_too_many_errors) {
|
||||
return;
|
||||
}
|
||||
unsigned category = clang::DiagnosticIDs::getCategoryNumberForDiag(id);
|
||||
if (category == clang::diag::DiagCat_Semantic_Issue) {
|
||||
return;
|
||||
}
|
||||
// Default implementation increases warning/error count.
|
||||
DiagnosticConsumer::HandleDiagnostic(level, info);
|
||||
wrapped_->HandleDiagnostic(level, info);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2018 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef DIAGNOSTIC_CONSUMER_H_
|
||||
#define DIAGNOSTIC_CONSUMER_H_
|
||||
|
||||
#include <clang/Basic/Diagnostic.h>
|
||||
|
||||
class HeaderCheckerDiagnosticConsumer : public clang::DiagnosticConsumer {
|
||||
private:
|
||||
std::unique_ptr<clang::DiagnosticConsumer> wrapped_;
|
||||
|
||||
public:
|
||||
HeaderCheckerDiagnosticConsumer(
|
||||
std::unique_ptr<clang::DiagnosticConsumer> wrapped);
|
||||
void clear() override;
|
||||
void BeginSourceFile(const clang::LangOptions &lang_opts,
|
||||
const clang::Preprocessor *preprocessor) override;
|
||||
void EndSourceFile() override;
|
||||
void finish() override;
|
||||
bool IncludeInDiagnosticCounts() const override;
|
||||
void HandleDiagnostic(clang::DiagnosticsEngine::Level level,
|
||||
const clang::Diagnostic &info) override;
|
||||
};
|
||||
|
||||
#endif // DIAGNOSTIC_CONSUMER_H_
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "frontend_action.h"
|
||||
|
||||
#include "ast_processing.h"
|
||||
#include "diagnostic_consumer.h"
|
||||
#include "header_abi_util.h"
|
||||
#include "ir_representation.h"
|
||||
|
||||
@@ -25,15 +26,29 @@
|
||||
#include <llvm/ADT/STLExtras.h>
|
||||
|
||||
HeaderCheckerFrontendAction::HeaderCheckerFrontendAction(
|
||||
const std::string &dump_name, std::set<std::string> &exported_headers,
|
||||
abi_util::TextFormatIR text_format)
|
||||
: dump_name_(dump_name), exported_headers_(exported_headers),
|
||||
text_format_(text_format) {}
|
||||
HeaderCheckerOptions &options)
|
||||
: options_(options) {}
|
||||
|
||||
std::unique_ptr<clang::ASTConsumer>
|
||||
HeaderCheckerFrontendAction::CreateASTConsumer(clang::CompilerInstance &ci,
|
||||
llvm::StringRef header_file) {
|
||||
// Create AST consumers.
|
||||
return llvm::make_unique<HeaderASTConsumer>(&ci, dump_name_,
|
||||
exported_headers_, text_format_);
|
||||
return llvm::make_unique<HeaderASTConsumer>(&ci, options_);
|
||||
}
|
||||
|
||||
bool HeaderCheckerFrontendAction::BeginInvocation(clang::CompilerInstance &ci) {
|
||||
if (options_.suppress_errors_) {
|
||||
clang::DiagnosticsEngine &diagnostics = ci.getDiagnostics();
|
||||
diagnostics.setClient(
|
||||
new HeaderCheckerDiagnosticConsumer(diagnostics.takeClient()),
|
||||
/* ShouldOwnClient */ true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HeaderCheckerFrontendAction::BeginSourceFileAction(
|
||||
clang::CompilerInstance &ci) {
|
||||
ci.getPreprocessor().SetSuppressIncludeNotFoundError(
|
||||
options_.suppress_errors_);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef FRONTEND_ACTION_H_
|
||||
#define FRONTEND_ACTION_H_
|
||||
|
||||
#include "ir_representation.h"
|
||||
#include "header_checker.h"
|
||||
|
||||
#include <clang/Frontend/FrontendAction.h>
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
@@ -32,19 +32,17 @@ namespace clang {
|
||||
|
||||
class HeaderCheckerFrontendAction : public clang::ASTFrontendAction {
|
||||
private:
|
||||
const std::string &dump_name_;
|
||||
std::set<std::string> &exported_headers_;
|
||||
abi_util::TextFormatIR text_format_;
|
||||
HeaderCheckerOptions &options_;
|
||||
|
||||
public:
|
||||
HeaderCheckerFrontendAction(
|
||||
const std::string &dump_name,
|
||||
std::set<std::string> &exported_headers,
|
||||
abi_util::TextFormatIR text_format);
|
||||
HeaderCheckerFrontendAction(HeaderCheckerOptions &options);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
|
||||
clang::CompilerInstance &ci, llvm::StringRef header_file) override;
|
||||
|
||||
bool BeginInvocation(clang::CompilerInstance &ci) override;
|
||||
bool BeginSourceFileAction(clang::CompilerInstance &ci) override;
|
||||
};
|
||||
|
||||
#endif // FRONTEND_ACTION_H_
|
||||
|
||||
@@ -19,13 +19,9 @@
|
||||
#include <clang/Frontend/FrontendActions.h>
|
||||
|
||||
HeaderCheckerFrontendActionFactory::HeaderCheckerFrontendActionFactory(
|
||||
const std::string &dump_name,
|
||||
std::set<std::string> &exported_headers,
|
||||
abi_util::TextFormatIR text_format)
|
||||
: dump_name_(dump_name), exported_headers_(exported_headers),
|
||||
text_format_(text_format) {}
|
||||
HeaderCheckerOptions &options)
|
||||
: options_(options) {}
|
||||
|
||||
clang::FrontendAction *HeaderCheckerFrontendActionFactory::create() {
|
||||
return new HeaderCheckerFrontendAction(dump_name_, exported_headers_,
|
||||
text_format_);
|
||||
return new HeaderCheckerFrontendAction(options_);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#ifndef FRONTEND_ACTION_FACTORY_H_
|
||||
#define FRONTEND_ACTION_FACTORY_H_
|
||||
|
||||
#include "frontend_action.h"
|
||||
#include "ir_representation.h"
|
||||
|
||||
#include <clang/Tooling/Tooling.h>
|
||||
@@ -24,15 +25,10 @@
|
||||
class HeaderCheckerFrontendActionFactory
|
||||
: public clang::tooling::FrontendActionFactory {
|
||||
private:
|
||||
const std::string &dump_name_;
|
||||
std::set<std::string> &exported_headers_;
|
||||
abi_util::TextFormatIR text_format_;
|
||||
HeaderCheckerOptions &options_;
|
||||
|
||||
public:
|
||||
HeaderCheckerFrontendActionFactory(
|
||||
const std::string &dump_name,
|
||||
std::set<std::string> &exported_headers,
|
||||
abi_util::TextFormatIR text_format);
|
||||
HeaderCheckerFrontendActionFactory(HeaderCheckerOptions &options);
|
||||
|
||||
clang::FrontendAction *create() override;
|
||||
};
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "header_checker.h"
|
||||
|
||||
#include "fixed_argv.h"
|
||||
#include "frontend_action_factory.h"
|
||||
#include "header_abi_util.h"
|
||||
@@ -50,6 +52,11 @@ 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<bool> suppress_errors(
|
||||
"suppress-errors",
|
||||
llvm::cl::desc("Suppress preprocess and semantic errors"),
|
||||
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,
|
||||
@@ -72,7 +79,6 @@ static void HideIrrelevantCommandLineOptions() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
HideIrrelevantCommandLineOptions();
|
||||
|
||||
@@ -124,11 +130,11 @@ 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);
|
||||
|
||||
clang::tooling::ClangTool tool(*compilations, header_files);
|
||||
std::unique_ptr<clang::tooling::FrontendActionFactory> factory(
|
||||
new HeaderCheckerFrontendActionFactory(out_dump, exported_headers,
|
||||
output_format));
|
||||
|
||||
new HeaderCheckerFrontendActionFactory(options));
|
||||
return tool.run(factory.get());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2018 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef HEADER_CHECKER_H_
|
||||
#define HEADER_CHECKER_H_
|
||||
|
||||
#include "ir_representation.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
class HeaderCheckerOptions {
|
||||
public:
|
||||
std::string dump_name_;
|
||||
std::set<std::string> exported_headers_;
|
||||
abi_util::TextFormatIR text_format_;
|
||||
bool suppress_errors_;
|
||||
|
||||
public:
|
||||
HeaderCheckerOptions(std::string dump_name,
|
||||
std::set<std::string> exported_headers,
|
||||
abi_util::TextFormatIR text_format, bool suppress_errors)
|
||||
: dump_name_(std::move(dump_name)),
|
||||
exported_headers_(std::move(exported_headers)),
|
||||
text_format_(text_format), suppress_errors_(suppress_errors) {}
|
||||
};
|
||||
|
||||
#endif // HEADER_CHECKER_H_
|
||||
Reference in New Issue
Block a user