diff --git a/vndk/tools/header-checker/Android.bp b/vndk/tools/header-checker/Android.bp index ccffdad56..8a2d3629e 100644 --- a/vndk/tools/header-checker/Android.bp +++ b/vndk/tools/header-checker/Android.bp @@ -77,14 +77,14 @@ cc_defaults { } cc_binary_host { - name: "header-checker", + name: "header-abi-dumper", defaults: [ "header-checker-defaults", "header-checker-lib-debug-defaults", ], - srcs: ["src/*.cpp"], + srcs: ["header-abi-dumper/src/*.cpp"], target: { windows: { diff --git a/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.cpp b/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.cpp new file mode 100644 index 000000000..19750e3f6 --- /dev/null +++ b/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.cpp @@ -0,0 +1,37 @@ +#include "ast_processing.h" + +bool HeaderASTVisitor::VisitRecordDecl(const clang::RecordDecl *decl) { + llvm::errs() << "struct: " << decl->getName() << "\n"; + return true; +} + +bool HeaderASTVisitor::VisitCXXRecordDecl(const clang::CXXRecordDecl *decl) { + llvm::errs() << "class: " << decl->getName() << "\n"; + return true; +} + +bool HeaderASTVisitor::VisitFunctionDecl(const clang::FunctionDecl *decl) { + llvm::errs() << "func: " << decl->getName() << "\n"; + return true; +} + +void HeaderASTConsumer::HandleTranslationUnit(clang::ASTContext &ctx) { + llvm::errs() << "HandleTranslationUnit ------------------------------\n"; + clang::TranslationUnitDecl* translation_unit = ctx.getTranslationUnitDecl(); + HeaderASTVisitor v; + v.TraverseDecl(translation_unit); +} + +void HeaderASTConsumer::HandleVTable(clang::CXXRecordDecl *crd) { + llvm::errs() << "HandleVTable: " << crd->getName() << "\n"; +} + +llvm::StringRef HeaderASTPPCallbacks::ToString(const clang::Token &tok) { + return tok.getIdentifierInfo()->getName(); +} + +void HeaderASTPPCallbacks::MacroDefined(const clang::Token ¯o_name_tok, + const clang::MacroDirective *) { + assert(macro_name_tok.isAnyIdentifier()); + llvm::errs() << "defines: " << ToString(macro_name_tok) << "\n"; +} diff --git a/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.h b/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.h new file mode 100644 index 000000000..4aaf77da2 --- /dev/null +++ b/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.h @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include + +class HeaderASTVisitor + : public clang::RecursiveASTVisitor { + public: + bool VisitRecordDecl(const clang::RecordDecl *decl); + bool VisitCXXRecordDecl(const clang::CXXRecordDecl *decl); + bool VisitFunctionDecl(const clang::FunctionDecl *decl); +}; + +class HeaderASTConsumer : public clang::ASTConsumer { + public: + void HandleTranslationUnit(clang::ASTContext &ctx) override; + void HandleVTable(clang::CXXRecordDecl *crd) override; +}; + +class HeaderASTPPCallbacks : public clang::PPCallbacks { + private: + llvm::StringRef ToString(const clang::Token &tok); + + public: + void MacroDefined(const clang::Token ¯o_name_tok, + const clang::MacroDirective *) override; +}; diff --git a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.cpp b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.cpp new file mode 100644 index 000000000..48bd89b5e --- /dev/null +++ b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.cpp @@ -0,0 +1,47 @@ +// Copyright (C) 2016 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 "frontend_action.h" +#include "ast_processing.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +HeaderCheckerFrontendAction::HeaderCheckerFrontendAction( + const std::string &dump_name) + : dump_name_(dump_name) {} + +std::unique_ptr +HeaderCheckerFrontendAction::CreateASTConsumer(clang::CompilerInstance &ci, + llvm::StringRef header_file) { + // Add preprocessor callbacks. + clang::Preprocessor &pp = ci.getPreprocessor(); + pp.addPPCallbacks(llvm::make_unique()); + + // Create AST consumers. + std::vector> consumers; + consumers.push_back(llvm::make_unique()); + // Still have a MultiplexConsumer in case other consumers need to be + // added later. + return llvm::make_unique(std::move(consumers)); +} diff --git a/vndk/tools/header-checker/src/frontend_action.h b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.h similarity index 73% rename from vndk/tools/header-checker/src/frontend_action.h rename to vndk/tools/header-checker/header-abi-dumper/src/frontend_action.h index 0d07f9d06..041a255ce 100644 --- a/vndk/tools/header-checker/src/frontend_action.h +++ b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.h @@ -28,20 +28,12 @@ namespace clang { class HeaderCheckerFrontendAction : public clang::ASTFrontendAction { private: - std::string ref_dump_name_; - std::unique_ptr ref_dump_; - bool should_generate_ref_dump_; + std::string dump_name_; public: - HeaderCheckerFrontendAction(const std::string &ref_dump_name, - bool should_generate_ref_dump); + HeaderCheckerFrontendAction(const std::string &dump_name); protected: - bool BeginSourceFileAction(clang::CompilerInstance &ci, - llvm::StringRef header_file) override; - - void EndSourceFileAction() override; - std::unique_ptr CreateASTConsumer( clang::CompilerInstance &ci, llvm::StringRef header_file) override; }; diff --git a/vndk/tools/header-checker/src/frontend_action_factory.cpp b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.cpp similarity index 75% rename from vndk/tools/header-checker/src/frontend_action_factory.cpp rename to vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.cpp index da17ec4f7..46e453ccf 100644 --- a/vndk/tools/header-checker/src/frontend_action_factory.cpp +++ b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.cpp @@ -19,11 +19,9 @@ #include HeaderCheckerFrontendActionFactory::HeaderCheckerFrontendActionFactory( - const std::string &ref_dump_name, bool should_generate_ref_dump) - : ref_dump_name_(ref_dump_name), - should_generate_ref_dump_(should_generate_ref_dump) { } + const std::string &dump_name) + : dump_name_(dump_name) {} clang::FrontendAction *HeaderCheckerFrontendActionFactory::create() { - return new HeaderCheckerFrontendAction(ref_dump_name_, - should_generate_ref_dump_); + return new HeaderCheckerFrontendAction(dump_name_); } diff --git a/vndk/tools/header-checker/src/frontend_action_factory.h b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.h similarity index 87% rename from vndk/tools/header-checker/src/frontend_action_factory.h rename to vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.h index 03b99f3ed..2a7383439 100644 --- a/vndk/tools/header-checker/src/frontend_action_factory.h +++ b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.h @@ -20,12 +20,10 @@ class HeaderCheckerFrontendActionFactory : public clang::tooling::FrontendActionFactory { private: - std::string ref_dump_name_; - bool should_generate_ref_dump_; + std::string dump_name_; public: - HeaderCheckerFrontendActionFactory(const std::string &ref_dump_name, - bool should_generate_ref_dump); + HeaderCheckerFrontendActionFactory(const std::string &ref_dump_name); clang::FrontendAction *create() override; }; diff --git a/vndk/tools/header-checker/src/header_checker.cpp b/vndk/tools/header-checker/header-abi-dumper/src/header_checker.cpp similarity index 84% rename from vndk/tools/header-checker/src/header_checker.cpp rename to vndk/tools/header-checker/header-abi-dumper/src/header_checker.cpp index e498e2d94..570cc7cce 100644 --- a/vndk/tools/header-checker/src/header_checker.cpp +++ b/vndk/tools/header-checker/header-abi-dumper/src/header_checker.cpp @@ -34,16 +34,11 @@ static llvm::cl::opt header_file( llvm::cl::Positional, llvm::cl::desc("
"), llvm::cl::Required, llvm::cl::cat(header_checker_category)); -static llvm::cl::opt ref_dump( - "r", llvm::cl::value_desc("refdump"), llvm::cl::Required, +static llvm::cl::opt out_dump( + "o", llvm::cl::value_desc("out_dump"), llvm::cl::Required, llvm::cl::desc("Specify the reference dump file name"), llvm::cl::cat(header_checker_category)); -static llvm::cl::opt gen_ref_dump( - "g", llvm::cl::init(false), - llvm::cl::desc("Generate reference dump for header file"), - llvm::cl::cat(header_checker_category)); - // Hide irrelevant command line options defined in LLVM libraries. static void HideIrrelevantCommandLineOptions() { llvm::StringMap &map = llvm::cl::getRegisteredOptions(); @@ -75,11 +70,6 @@ int main(int argc, const char **argv) { ::exit(1); } - if (!gen_ref_dump && !llvm::sys::fs::exists(ref_dump)) { - llvm::errs() << "ERROR: Reference file \"" << ref_dump << "\" not found\n"; - ::exit(1); - } - // Check the availability of clang compilation options. if (!compilations) { llvm::errs() << "ERROR: Clang compilation options not specified.\n"; @@ -92,7 +82,7 @@ int main(int argc, const char **argv) { clang::tooling::ClangTool tool(*compilations, header_files); std::unique_ptr factory( - new HeaderCheckerFrontendActionFactory(ref_dump, gen_ref_dump)); + new HeaderCheckerFrontendActionFactory(out_dump)); return tool.run(factory.get()); } diff --git a/vndk/tools/header-checker/src/frontend_action.cpp b/vndk/tools/header-checker/src/frontend_action.cpp deleted file mode 100644 index 8e1b8f0a2..000000000 --- a/vndk/tools/header-checker/src/frontend_action.cpp +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (C) 2016 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 "frontend_action.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static constexpr bool kLoadRefAsImplicitPCH = false; - -class HeaderCheckVisitor - : public clang::RecursiveASTVisitor { - public: - bool VisitRecordDecl(const clang::RecordDecl *decl) { - llvm::errs() << "struct: " << decl->getName() << "\n"; - return true; - } - - bool VisitCXXRecordDecl(const clang::CXXRecordDecl *decl) { - llvm::errs() << "class: " << decl->getName() << "\n"; - return true; - } - - bool VisitFunctionDecl(const clang::FunctionDecl *decl) { - llvm::errs() << "func: " << decl->getName() << "\n"; - return true; - } -}; - -class HeaderCheckerConsumer : public clang::ASTConsumer { - public: - void HandleTranslationUnit(clang::ASTContext &ctx) override { - llvm::errs() << "HandleTranslationUnit ------------------------------\n"; - clang::TranslationUnitDecl* translation_unit = ctx.getTranslationUnitDecl(); - HeaderCheckVisitor v; - v.TraverseDecl(translation_unit); - } - - void HandleVTable(clang::CXXRecordDecl *crd) override { - llvm::errs() << "HandleVTable: " << crd->getName() << "\n"; - } -}; - -class HeaderCheckerPPCallbacks : public clang::PPCallbacks { - private: - llvm::StringRef ToString(const clang::Token &tok) { - return tok.getIdentifierInfo()->getName(); - } - - public: - void MacroDefined(const clang::Token ¯o_name_tok, - const clang::MacroDirective *) override { - assert(macro_name_tok.isAnyIdentifier()); - llvm::errs() << "defines: " << ToString(macro_name_tok) << "\n"; - } -}; - -HeaderCheckerFrontendAction::HeaderCheckerFrontendAction( - const std::string &ref_dump_name, bool should_generate_ref_dump) - : ref_dump_name_(ref_dump_name), - should_generate_ref_dump_(should_generate_ref_dump) { } - -static bool VisitRefDumpDecls(void *ctx, const clang::Decl *decl) { - HeaderCheckVisitor v; - v.TraverseDecl(const_cast(decl)); - return true; -} - -bool HeaderCheckerFrontendAction::BeginSourceFileAction( - clang::CompilerInstance &ci, llvm::StringRef header_file) { - - // Load reference dump file. - if (llvm::sys::fs::exists(ref_dump_name_)) { - if (kLoadRefAsImplicitPCH) { - ci.getPreprocessorOpts().ImplicitPCHInclude = ref_dump_name_; - } else { - clang::DiagnosticsEngine &diag = ci.getDiagnostics(); - - diag.getClient()->BeginSourceFile(ci.getLangOpts(), - &ci.getPreprocessor()); - - // FIXME: Must replace getPCHContainerReader() with other ASTReader. - ref_dump_ = clang::ASTUnit::LoadFromASTFile( - ref_dump_name_, ci.getPCHContainerReader(), &diag, - ci.getFileSystemOpts(), ci.getCodeGenOpts().DebugTypeExtRefs); - - diag.getClient()->EndSourceFile(); - - if (ref_dump_) { - llvm::errs() << "Loaded: " << ref_dump_name_ << " : " - << ref_dump_->top_level_size() << "\n"; - - ref_dump_->visitLocalTopLevelDecls(nullptr, VisitRefDumpDecls); - llvm::errs() << "----------------------------------------\n"; - } - } - } - return true; -} - -void HeaderCheckerFrontendAction::EndSourceFileAction() { - ref_dump_.reset(); -} - -std::unique_ptr -HeaderCheckerFrontendAction::CreateASTConsumer(clang::CompilerInstance &ci, - llvm::StringRef header_file) { - // Add preprocessor callbacks. - clang::Preprocessor &pp = ci.getPreprocessor(); - pp.addPPCallbacks(llvm::make_unique()); - - // Create AST consumers. - std::vector> consumers; - consumers.push_back(llvm::make_unique()); - - if (should_generate_ref_dump_) { - std::string sysroot; - llvm::raw_pwrite_stream *ref_dump_os = ci.createOutputFile( - ref_dump_name_, true, false, header_file, "", true); - if (!ref_dump_os) { - llvm::errs() << "ERROR: Failed to create reference dump file: " - << ref_dump_name_ << "\n"; - return nullptr; - } - - auto buffer = std::make_shared(); - consumers.push_back( - llvm::make_unique( - ci.getPreprocessor(), ref_dump_name_, nullptr, "", buffer, - ci.getFrontendOpts().ModuleFileExtensions, false, false)); - consumers.push_back( - ci.getPCHContainerWriter().CreatePCHContainerGenerator( - ci, header_file, ref_dump_name_, ref_dump_os, buffer)); - } - - return llvm::make_unique(std::move(consumers)); -}