1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "clang-tidy/ClangTidyCheck.h" 10 11 #include "llvm/ADT/StringRef.h" 12 13 #include <fstream> 14 #include <set> 15 #include <string> 16 17 namespace libcpp { 18 class header_exportable_declarations : public clang::tidy::ClangTidyCheck { 19 public: 20 explicit header_exportable_declarations(llvm::StringRef, clang::tidy::ClangTidyContext*); 21 ~header_exportable_declarations(); 22 void registerMatchers(clang::ast_matchers::MatchFinder*) override; 23 void check(const clang::ast_matchers::MatchFinder::MatchResult&) override; 24 25 enum class FileType { 26 // std module specific 27 Header, 28 CompatModulePartition, 29 Module, 30 // std.compat module specific 31 CHeader, 32 ModulePartition, 33 CompatModule, 34 // invalid value 35 Unknown 36 }; 37 38 private: 39 llvm::StringRef filename_; 40 FileType file_type_; 41 llvm::StringRef extra_header_; 42 std::set<std::string> decls_; 43 std::set<std::string> global_decls_; 44 45 // The named declarations in .h C headers are "tricky". On POSIX 46 // systems these headers contain POSIX specific functions that do not 47 // use a reserved name. For example, fmemopen is provided by stdio.h. 48 // We filter the names that should be provided by the headers as follows: 49 // - record all named declarations the global namespace 50 // - wait until the header is completely processed 51 // - every named declaration in the global namespace that has a matching 52 // "export" in the std namespace is exported. 53 // 54 // The only place where we can do the above while ensuring that all 55 // the declarations in the header have been seen is in the clang tidy 56 // plugin's destructor. 57 // 58 // It is possible to skip some declarations in the std namespace, 59 // these are added to decls_ before processing. To differentiate 60 // between a skipped declaration and a real declaration the skipped 61 // declarations are recorded in an extra variable. 62 std::set<std::string> skip_decls_; 63 }; 64 } // namespace libcpp 65