Skip to content

Commit 791fe26

Browse files
[clang][ExtractAPI] Allow users to specify a list of symbols to ignore
Adds a `--extract-api-ignores=` command line option that allows users to provide a file containing a new line separated list of symbols to unconditionally ignore when extracting API information. Differential Revision: https://reviews.llvm.org/D136450
1 parent 1fe096e commit 791fe26

File tree

14 files changed

+211
-3
lines changed

14 files changed

+211
-3
lines changed

clang/include/clang/Basic/DiagnosticFrontendKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,4 +331,7 @@ def warn_profile_data_misexpect : Warning<
331331
InGroup<MisExpect>;
332332
} // end of instrumentation issue category
333333

334+
def err_extract_api_ignores_file_not_found :
335+
Error<"file '%0' specified by '--extract-api-ignores=' not found">, DefaultFatal;
336+
334337
}

clang/include/clang/Driver/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,9 @@ def extract_api : Flag<["-"], "extract-api">, Flags<[CC1Option]>, Group<Action_G
11211121
HelpText<"Extract API information">;
11221122
def product_name_EQ: Joined<["--"], "product-name=">, Flags<[CC1Option]>,
11231123
MarshallingInfoString<FrontendOpts<"ProductName">>;
1124+
def extract_api_ignores_EQ: Joined<["--"], "extract-api-ignores=">, Flags<[CC1Option]>,
1125+
HelpText<"File containing a new line separated list of API symbols to ignore when extracting API information.">,
1126+
MarshallingInfoString<FrontendOpts<"ExtractAPIIgnoresFile">>;
11241127
def e : JoinedOrSeparate<["-"], "e">, Flags<[LinkerInput]>, Group<Link_Group>;
11251128
def fmax_tokens_EQ : Joined<["-"], "fmax-tokens=">, Group<f_Group>, Flags<[CC1Option]>,
11261129
HelpText<"Max total number of preprocessed tokens for -Wmax-tokens.">,
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===- ExtractAPI/APIIgnoresList.h ---------------*- C++ -*-===//
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+
/// \file This file defines APIIgnoresList which is a type that allows querying
10+
/// a file containing symbols to ignore when extracting API information.
11+
///
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_CLANG_API_IGNORES_LIST_H
15+
#define LLVM_CLANG_API_IGNORES_LIST_H
16+
17+
#include "clang/Basic/FileManager.h"
18+
#include "llvm/ADT/SmallVector.h"
19+
#include "llvm/ADT/StringRef.h"
20+
#include "llvm/Support/Error.h"
21+
#include "llvm/Support/raw_ostream.h"
22+
23+
#include <memory>
24+
#include <system_error>
25+
26+
namespace llvm {
27+
class MemoryBuffer;
28+
} // namespace llvm
29+
30+
namespace clang {
31+
namespace extractapi {
32+
33+
struct IgnoresFileNotFound : public llvm::ErrorInfo<IgnoresFileNotFound> {
34+
std::string Path;
35+
static char ID;
36+
37+
explicit IgnoresFileNotFound(StringRef Path) : Path(Path) {}
38+
39+
virtual void log(llvm::raw_ostream &os) const override;
40+
41+
virtual std::error_code convertToErrorCode() const override;
42+
};
43+
44+
/// A type that provides access to a new line separated list of symbol names to
45+
/// ignore when extracting API information.
46+
struct APIIgnoresList {
47+
/// The API to use for generating from the file at \p IgnoresFilePath.
48+
///
49+
/// \returns an initialized APIIgnoresList or an Error.
50+
static llvm::Expected<APIIgnoresList> create(llvm::StringRef IgnoresFilePath,
51+
FileManager &FM);
52+
53+
APIIgnoresList() = default;
54+
55+
/// Check if \p SymbolName is specified in the APIIgnoresList and if it should
56+
/// therefore be ignored.
57+
bool shouldIgnore(llvm::StringRef SymbolName) const;
58+
59+
private:
60+
using SymbolNameList = llvm::SmallVector<llvm::StringRef, 32>;
61+
62+
APIIgnoresList(SymbolNameList SymbolsToIgnore,
63+
std::unique_ptr<llvm::MemoryBuffer> Buffer)
64+
: SymbolsToIgnore(std::move(SymbolsToIgnore)), Buffer(std::move(Buffer)) {
65+
}
66+
67+
SymbolNameList SymbolsToIgnore;
68+
std::unique_ptr<llvm::MemoryBuffer> Buffer;
69+
};
70+
71+
} // namespace extractapi
72+
} // namespace clang
73+
74+
#endif // LLVM_CLANG_API_IGNORES_LIST_H

clang/include/clang/ExtractAPI/FrontendActions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define LLVM_CLANG_EXTRACTAPI_FRONTEND_ACTIONS_H
1616

1717
#include "clang/ExtractAPI/API.h"
18+
#include "clang/ExtractAPI/APIIgnoresList.h"
1819
#include "clang/Frontend/FrontendAction.h"
1920

2021
namespace clang {
@@ -39,6 +40,9 @@ class ExtractAPIAction : public ASTFrontendAction {
3940
/// files.
4041
std::unique_ptr<llvm::MemoryBuffer> Buffer;
4142

43+
/// The list of symbols to ignore during serialization
44+
extractapi::APIIgnoresList IgnoresList;
45+
4246
/// The input file originally provided on the command line.
4347
///
4448
/// This captures the spelling used to include the file and whether the

clang/include/clang/ExtractAPI/Serialization/SerializerBase.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H
1616

1717
#include "clang/ExtractAPI/API.h"
18+
#include "clang/ExtractAPI/APIIgnoresList.h"
1819
#include "llvm/Support/raw_ostream.h"
1920

2021
namespace clang {
@@ -40,6 +41,11 @@ class APISerializer {
4041
/// Note: This should be used for populating metadata about the API.
4142
StringRef ProductName;
4243

44+
/// The list of symbols to ignore.
45+
///
46+
/// Note: This should be consulted before emitting a symbol.
47+
const APIIgnoresList &IgnoresList;
48+
4349
APISerializerOption Options;
4450

4551
public:
@@ -51,8 +57,10 @@ class APISerializer {
5157

5258
protected:
5359
APISerializer(const APISet &API, StringRef ProductName,
60+
const APIIgnoresList &IgnoresList,
5461
APISerializerOption Options = {})
55-
: API(API), ProductName(ProductName), Options(Options) {}
62+
: API(API), ProductName(ProductName), IgnoresList(IgnoresList),
63+
Options(Options) {}
5664

5765
virtual ~APISerializer() = default;
5866
};

clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H
1919

2020
#include "clang/ExtractAPI/API.h"
21+
#include "clang/ExtractAPI/APIIgnoresList.h"
2122
#include "clang/ExtractAPI/Serialization/SerializerBase.h"
2223
#include "llvm/ADT/SmallVector.h"
2324
#include "llvm/Support/JSON.h"
@@ -168,8 +169,9 @@ class SymbolGraphSerializer : public APISerializer {
168169

169170
public:
170171
SymbolGraphSerializer(const APISet &API, StringRef ProductName,
172+
const APIIgnoresList &IgnoresList,
171173
APISerializerOption Options = {})
172-
: APISerializer(API, ProductName, Options) {}
174+
: APISerializer(API, ProductName, IgnoresList, Options) {}
173175
};
174176

175177
} // namespace extractapi

clang/include/clang/Frontend/FrontendOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,10 @@ class FrontendOptions {
454454
/// The name of the product the input files belong too.
455455
std::string ProductName;
456456

457+
// Currently this is only used as part of the `-extract-api` action.
458+
/// The file providing a list of APIs to ignore when extracting documentation
459+
std::string ExtractAPIIgnoresFile;
460+
457461
/// Args to pass to the plugins
458462
std::map<std::string, std::vector<std::string>> PluginArgs;
459463

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4813,6 +4813,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
48134813
CmdArgs.push_back("-extract-api");
48144814
if (Arg *ProductNameArg = Args.getLastArg(options::OPT_product_name_EQ))
48154815
ProductNameArg->render(Args, CmdArgs);
4816+
if (Arg *ExtractAPIIgnoresFileArg =
4817+
Args.getLastArg(options::OPT_extract_api_ignores_EQ))
4818+
ExtractAPIIgnoresFileArg->render(Args, CmdArgs);
48164819
} else {
48174820
assert((isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) &&
48184821
"Invalid action for clang tool.");
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//===- ExtractAPI/APIIgnoresList.cpp -------*- C++ -*-===//
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+
/// \file
10+
/// This file implements APIIgnoresList that allows users to specifiy a file
11+
/// containing symbols to ignore during API extraction.
12+
///
13+
//===----------------------------------------------------------------------===//
14+
15+
#include "clang/ExtractAPI/APIIgnoresList.h"
16+
#include "clang/Basic/FileManager.h"
17+
#include "llvm/ADT/STLExtras.h"
18+
#include "llvm/Support/Error.h"
19+
20+
using namespace clang;
21+
using namespace clang::extractapi;
22+
using namespace llvm;
23+
24+
char IgnoresFileNotFound::ID;
25+
26+
void IgnoresFileNotFound::log(llvm::raw_ostream &os) const {
27+
os << "Could not find API ignores file " << Path;
28+
}
29+
30+
std::error_code IgnoresFileNotFound::convertToErrorCode() const {
31+
return llvm::inconvertibleErrorCode();
32+
}
33+
34+
Expected<APIIgnoresList> APIIgnoresList::create(StringRef IgnoresFilePath,
35+
FileManager &FM) {
36+
auto BufferOrErr = FM.getBufferForFile(IgnoresFilePath);
37+
if (!BufferOrErr)
38+
return make_error<IgnoresFileNotFound>(IgnoresFilePath);
39+
40+
auto Buffer = std::move(BufferOrErr.get());
41+
SmallVector<StringRef, 32> Lines;
42+
Buffer->getBuffer().split(Lines, '\n', /*MaxSplit*/ -1, /*KeepEmpty*/ false);
43+
// Symbol names don't have spaces in them, let's just remove these in case the
44+
// input is slighlty malformed.
45+
transform(Lines, Lines.begin(), [](StringRef Line) { return Line.trim(); });
46+
sort(Lines);
47+
return APIIgnoresList(std::move(Lines), std::move(Buffer));
48+
}
49+
50+
bool APIIgnoresList::shouldIgnore(StringRef SymbolName) const {
51+
auto It = lower_bound(SymbolsToIgnore, SymbolName);
52+
return (It != SymbolsToIgnore.end()) && (*It == SymbolName);
53+
}

clang/lib/ExtractAPI/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
44

55
add_clang_library(clangExtractAPI
66
API.cpp
7+
APIIgnoresList.cpp
78
AvailabilityInfo.cpp
89
ExtractAPIConsumer.cpp
910
DeclarationFragments.cpp

0 commit comments

Comments
 (0)