HelpText<"Extract API information">;
def product_name_EQ: Joined<["--"], "product-name=">, Flags<[CC1Option]>,
MarshallingInfoString<FrontendOpts<"ProductName">>;
-def extract_api_ignores_EQ: Joined<["--"], "extract-api-ignores=">, Flags<[CC1Option]>,
- HelpText<"File containing a new line separated list of API symbols to ignore when extracting API information.">,
- MarshallingInfoString<FrontendOpts<"ExtractAPIIgnoresFile">>;
+def extract_api_ignores_EQ: CommaJoined<["--"], "extract-api-ignores=">, Flags<[CC1Option]>,
+ HelpText<"Comma separated list of files containing a new line separated list of API symbols to ignore when extracting API information.">,
+ MarshallingInfoStringVector<FrontendOpts<"ExtractAPIIgnoresFileList">>;
def e : JoinedOrSeparate<["-"], "e">, Flags<[LinkerInput]>, Group<Link_Group>;
def fmax_tokens_EQ : Joined<["-"], "fmax-tokens=">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Max total number of preprocessed tokens for -Wmax-tokens.">,
//===----------------------------------------------------------------------===//
///
/// \file This file defines APIIgnoresList which is a type that allows querying
-/// a file containing symbols to ignore when extracting API information.
+/// files containing symbols to ignore when extracting API information.
///
//===----------------------------------------------------------------------===//
/// A type that provides access to a new line separated list of symbol names to
/// ignore when extracting API information.
struct APIIgnoresList {
- /// The API to use for generating from the file at \p IgnoresFilePath.
+ using FilePathList = std::vector<std::string>;
+
+ /// The API to use for generating from the files at \p IgnoresFilePathList.
///
/// \returns an initialized APIIgnoresList or an Error.
- static llvm::Expected<APIIgnoresList> create(llvm::StringRef IgnoresFilePath,
- FileManager &FM);
+ static llvm::Expected<APIIgnoresList>
+ create(const FilePathList &IgnoresFilePathList, FileManager &FM);
APIIgnoresList() = default;
private:
using SymbolNameList = llvm::SmallVector<llvm::StringRef, 32>;
+ using BufferList = llvm::SmallVector<std::unique_ptr<llvm::MemoryBuffer>>;
- APIIgnoresList(SymbolNameList SymbolsToIgnore,
- std::unique_ptr<llvm::MemoryBuffer> Buffer)
- : SymbolsToIgnore(std::move(SymbolsToIgnore)), Buffer(std::move(Buffer)) {
- }
+ APIIgnoresList(SymbolNameList SymbolsToIgnore, BufferList Buffers)
+ : SymbolsToIgnore(std::move(SymbolsToIgnore)),
+ Buffers(std::move(Buffers)) {}
SymbolNameList SymbolsToIgnore;
- std::unique_ptr<llvm::MemoryBuffer> Buffer;
+ BufferList Buffers;
};
} // namespace extractapi
std::string ProductName;
// Currently this is only used as part of the `-extract-api` action.
- /// The file providing a list of APIs to ignore when extracting documentation
- std::string ExtractAPIIgnoresFile;
+ // A comma seperated list of files providing a list of APIs to
+ // ignore when extracting documentation.
+ std::vector<std::string> ExtractAPIIgnoresFileList;
/// Args to pass to the plugins
std::map<std::string, std::vector<std::string>> PluginArgs;
return llvm::inconvertibleErrorCode();
}
-Expected<APIIgnoresList> APIIgnoresList::create(StringRef IgnoresFilePath,
- FileManager &FM) {
- auto BufferOrErr = FM.getBufferForFile(IgnoresFilePath);
- if (!BufferOrErr)
- return make_error<IgnoresFileNotFound>(IgnoresFilePath);
-
- auto Buffer = std::move(BufferOrErr.get());
+Expected<APIIgnoresList>
+APIIgnoresList::create(const FilePathList &IgnoresFilePathList,
+ FileManager &FM) {
SmallVector<StringRef, 32> Lines;
- Buffer->getBuffer().split(Lines, '\n', /*MaxSplit*/ -1, /*KeepEmpty*/ false);
- // Symbol names don't have spaces in them, let's just remove these in case the
- // input is slighlty malformed.
+ BufferList symbolBufferList;
+
+ for (const auto &CurrentIgnoresFilePath : IgnoresFilePathList) {
+ auto BufferOrErr = FM.getBufferForFile(CurrentIgnoresFilePath);
+
+ if (!BufferOrErr)
+ return make_error<IgnoresFileNotFound>(CurrentIgnoresFilePath);
+
+ auto Buffer = std::move(BufferOrErr.get());
+ Buffer->getBuffer().split(Lines, '\n', /*MaxSplit*/ -1,
+ /*KeepEmpty*/ false);
+ symbolBufferList.push_back(std::move(Buffer));
+ }
+
+ // Symbol names don't have spaces in them, let's just remove these in case
+ // the input is slighlty malformed.
transform(Lines, Lines.begin(), [](StringRef Line) { return Line.trim(); });
sort(Lines);
- return APIIgnoresList(std::move(Lines), std::move(Buffer));
+ return APIIgnoresList(std::move(Lines), std::move(symbolBufferList));
}
bool APIIgnoresList::shouldIgnore(StringRef SymbolName) const {
Policy.AnonymousTagLocations = false;
CI.getASTContext().setPrintingPolicy(Policy);
- if (!CI.getFrontendOpts().ExtractAPIIgnoresFile.empty()) {
+ if (!CI.getFrontendOpts().ExtractAPIIgnoresFileList.empty()) {
llvm::handleAllErrors(
- APIIgnoresList::create(CI.getFrontendOpts().ExtractAPIIgnoresFile,
+ APIIgnoresList::create(CI.getFrontendOpts().ExtractAPIIgnoresFileList,
CI.getFileManager())
.moveInto(IgnoresList),
[&CI](const IgnoresFileNotFound &Err) {
--- /dev/null
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
+// RUN: --extract-api-ignores=%t/ignores-list1,%t/ignores-list2,%t/ignores-list3 \
+// RUN: -x c-header %t/input.h -verify -o - | FileCheck %t/input.h
+
+//--- input.h
+#define IGNORED_6_FILE1 6
+#define IGNORED_2_FILE1 2
+#define IGNORED_5_FILE1 5
+
+#define IGNORED_4_FILE2 4
+#define IGNORED_3_FILE2 3
+
+typedef double IGNORED_1_FILE3;
+typedef int IGNORED_7_FILE3;
+
+typedef float NonIgnored;
+
+// CHECK-NOT: IGNORED_6_FILE1
+// CHECK-NOT: IGNORED_2_FILE1
+// CHECK-NOT: IGNORED_5_FILE1
+
+// CHECK-NOT: IGNORED_4_FILE2
+// CHECK-NOT: IGNORED_3_FILE2
+
+// CHECK-NOT: IGNORED_1_FILE3
+// CHECK-NOT: IGNORED_7_FILE3
+// CHECK: NonIgnored
+
+// expected-no-diagnostics
+
+//--- ignores-list1
+IGNORED_6_FILE1
+IGNORED_2_FILE1
+IGNORED_5_FILE1
+
+//--- ignores-list2
+IGNORED_4_FILE2
+IGNORED_3_FILE2
+
+//--- ignores-list3
+IGNORED_1_FILE3
+IGNORED_7_FILE3