Skip to content

Commit 30cb02a

Browse files
authored
Merge pull request #66688 from apple/block-list-cherry-pick-5.9
[5.9] Add support for an externally defined block list configuration file
2 parents f1bf558 + b19c45f commit 30cb02a

18 files changed

+438
-1
lines changed

include/swift/AST/ASTContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/Basic/LangOptions.h"
3131
#include "swift/Basic/Located.h"
3232
#include "swift/Basic/Malloc.h"
33+
#include "swift/Basic/BlockList.h"
3334
#include "swift/SymbolGraphGen/SymbolGraphOptions.h"
3435
#include "clang/AST/DeclTemplate.h"
3536
#include "llvm/ADT/ArrayRef.h"
@@ -360,6 +361,8 @@ class ASTContext final {
360361
/// The Swift module currently being compiled.
361362
ModuleDecl *MainModule = nullptr;
362363

364+
/// The block list where we can find special actions based on module name;
365+
BlockListStore blockListConfig;
363366
private:
364367
/// The current generation number, which reflects the number of
365368
/// times that external modules have been loaded.

include/swift/Basic/BlockList.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//===--- BlockList.h ---------------------------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines some miscellaneous overloads of hash_value() and
14+
// simple_display().
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_BASIC_BLOCKLIST_H
19+
#define SWIFT_BASIC_BLOCKLIST_H
20+
21+
#include "swift/Basic/LLVM.h"
22+
#include "llvm/ADT/StringRef.h"
23+
24+
namespace swift {
25+
26+
enum class BlockListAction: uint8_t {
27+
Undefined = 0,
28+
#define BLOCKLIST_ACTION(NAME) NAME,
29+
#include "BlockListAction.def"
30+
};
31+
32+
enum class BlockListKeyKind: uint8_t {
33+
Undefined = 0,
34+
ModuleName,
35+
ProjectName
36+
};
37+
38+
class BlockListStore {
39+
public:
40+
struct Implementation;
41+
void addConfigureFilePath(StringRef path);
42+
bool hasBlockListAction(StringRef key, BlockListKeyKind keyKind,
43+
BlockListAction action);
44+
BlockListStore();
45+
~BlockListStore();
46+
private:
47+
Implementation &Impl;
48+
};
49+
50+
} // namespace swift
51+
52+
#endif // SWIFT_BASIC_BLOCKLIST_H
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===--- BlockListAction.def - Define all blocklist actions -----*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This definition file describes all block list actions for meta-programming
14+
// purposes.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef BLOCKLIST_ACTION
19+
#define BLOCKLIST_ACTION(NAME)
20+
#endif
21+
22+
BLOCKLIST_ACTION(ShouldUseBinaryModule)
23+
BLOCKLIST_ACTION(ShouldUseTextualModule)
24+
BLOCKLIST_ACTION(DowngradeInterfaceVerificationFailure)
25+
26+
#undef BLOCKLIST_ACTION

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,9 @@ namespace swift {
566566
/// The model of concurrency to be used.
567567
ConcurrencyModel ActiveConcurrencyModel = ConcurrencyModel::Standard;
568568

569+
/// All block list configuration files to be honored in this compilation.
570+
std::vector<std::string> BlocklistConfigFilePaths;
571+
569572
bool isConcurrencyModelTaskToThread() const {
570573
return ActiveConcurrencyModel == ConcurrencyModel::TaskToThread;
571574
}

include/swift/Frontend/Frontend.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ class CompilerInvocation {
232232
/// options have been parsed.
233233
void setDefaultPrebuiltCacheIfNecessary();
234234

235+
/// If we haven't explicitly passed -blocklist-paths, set it to the default value.
236+
void setDefaultBlocklistsIfNecessary();
237+
235238
/// Computes the runtime resource path relative to the given Swift
236239
/// executable.
237240
static void computeRuntimeResourcePathFromExecutablePath(

include/swift/Frontend/FrontendOptions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,8 @@ class FrontendOptions {
512512
/// textual imports
513513
bool EmitClangHeaderWithNonModularIncludes = false;
514514

515+
/// All block list configuration files to be honored in this compilation.
516+
std::vector<std::string> BlocklistConfigFilePaths;
515517
private:
516518
static bool canActionEmitDependencies(ActionType);
517519
static bool canActionEmitReferenceDependencies(ActionType);

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@ def Raccess_note : Separate<["-"], "Raccess-note">,
240240
def Raccess_note_EQ : Joined<["-"], "Raccess-note=">,
241241
Alias<Raccess_note>;
242242

243+
def block_list_file
244+
: Separate<["-"], "blocklist-file">, MetaVarName<"<path>">,
245+
HelpText<"The path to a blocklist configuration file">;
243246
} // end let Flags = [FrontendOption, NoDriverOption]
244247

245248
def debug_crash_Group : OptionGroup<"<automatic crashing options>">;

lib/AST/ASTContext.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,10 @@ ASTContext::ASTContext(
694694
// Register any request-evaluator functions available at the AST layer.
695695
registerAccessRequestFunctions(evaluator);
696696
registerNameLookupRequestFunctions(evaluator);
697+
// Insert all block list config paths.
698+
for (auto path: langOpts.BlocklistConfigFilePaths) {
699+
blockListConfig.addConfigureFilePath(path);
700+
}
697701
}
698702

699703
ASTContext::~ASTContext() {

lib/Basic/BlockList.cpp

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
//===--- BlockList.cpp - BlockList utilities ------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "llvm/ADT/STLExtras.h"
14+
#include "llvm/ADT/StringSwitch.h"
15+
#include "llvm/Support/YAMLParser.h"
16+
#include "llvm/Support/YAMLTraits.h"
17+
#include "swift/Basic/BlockList.h"
18+
#include "swift/Basic/SourceManager.h"
19+
20+
struct swift::BlockListStore::Implementation {
21+
SourceManager SM;
22+
llvm::StringMap<std::vector<BlockListAction>> ModuleActionDict;
23+
llvm::StringMap<std::vector<BlockListAction>> ProjectActionDict;
24+
void addConfigureFilePath(StringRef path);
25+
bool hasBlockListAction(StringRef key, BlockListKeyKind keyKind,
26+
BlockListAction action);
27+
void collectBlockList(llvm::yaml::Node *N, BlockListAction action);
28+
29+
llvm::StringMap<std::vector<BlockListAction>> *getDictToUse(BlockListKeyKind kind) {
30+
switch (kind) {
31+
case BlockListKeyKind::ModuleName:
32+
return &ModuleActionDict;
33+
case BlockListKeyKind::ProjectName:
34+
return &ProjectActionDict;
35+
case BlockListKeyKind::Undefined:
36+
return nullptr;
37+
}
38+
}
39+
static std::string getScalaString(llvm::yaml::Node *N) {
40+
llvm::SmallString<64> Buffer;
41+
if (auto *scala = dyn_cast<llvm::yaml::ScalarNode>(N)) {
42+
return scala->getValue(Buffer).str();
43+
}
44+
return std::string();
45+
}
46+
};
47+
48+
swift::BlockListStore::BlockListStore(): Impl(*new Implementation()) {}
49+
50+
swift::BlockListStore::~BlockListStore() { delete &Impl; }
51+
52+
bool swift::BlockListStore::hasBlockListAction(StringRef key,
53+
BlockListKeyKind keyKind, BlockListAction action) {
54+
return Impl.hasBlockListAction(key, keyKind, action);
55+
}
56+
57+
void swift::BlockListStore::addConfigureFilePath(StringRef path) {
58+
Impl.addConfigureFilePath(path);
59+
}
60+
61+
bool swift::BlockListStore::Implementation::hasBlockListAction(StringRef key,
62+
BlockListKeyKind keyKind, BlockListAction action) {
63+
auto *dict = getDictToUse(keyKind);
64+
assert(dict);
65+
auto it = dict->find(key);
66+
if (it == dict->end())
67+
return false;
68+
return llvm::is_contained(it->second, action);
69+
}
70+
71+
void swift::BlockListStore::Implementation::collectBlockList(llvm::yaml::Node *N,
72+
BlockListAction action) {
73+
namespace yaml = llvm::yaml;
74+
auto *pair = dyn_cast<yaml::KeyValueNode>(N);
75+
if (!pair)
76+
return;
77+
std::string rawKey = getScalaString(pair->getKey());
78+
auto keyKind = llvm::StringSwitch<BlockListKeyKind>(rawKey)
79+
#define CASE(X) .Case(#X, BlockListKeyKind::X)
80+
CASE(ModuleName)
81+
CASE(ProjectName)
82+
#undef CASE
83+
.Default(BlockListKeyKind::Undefined);
84+
if (keyKind == BlockListKeyKind::Undefined)
85+
return;
86+
auto *dictToUse = getDictToUse(keyKind);
87+
assert(dictToUse);
88+
auto *seq = dyn_cast<yaml::SequenceNode>(pair->getValue());
89+
if (!seq)
90+
return;
91+
for (auto &node: *seq) {
92+
std::string name = getScalaString(&node);
93+
dictToUse->insert({name, std::vector<BlockListAction>()})
94+
.first->second.push_back(action);
95+
}
96+
}
97+
98+
void swift::BlockListStore::Implementation::addConfigureFilePath(StringRef path) {
99+
namespace yaml = llvm::yaml;
100+
101+
// Load the input file.
102+
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
103+
vfs::getFileOrSTDIN(*SM.getFileSystem(), path,
104+
/*FileSize*/-1, /*RequiresNullTerminator*/true,
105+
/*IsVolatile*/false, /*RetryCount*/30);
106+
if (!FileBufOrErr) {
107+
return;
108+
}
109+
StringRef Buffer = FileBufOrErr->get()->getBuffer();
110+
yaml::Stream Stream(llvm::MemoryBufferRef(Buffer, path),
111+
SM.getLLVMSourceMgr());
112+
for (auto DI = Stream.begin(); DI != Stream.end(); ++ DI) {
113+
assert(DI != Stream.end() && "Failed to read a document");
114+
yaml::Node *N = DI->getRoot();
115+
for (auto &pair: *dyn_cast<yaml::MappingNode>(N)) {
116+
std::string key = getScalaString(pair.getKey());
117+
auto action = llvm::StringSwitch<BlockListAction>(key)
118+
#define BLOCKLIST_ACTION(X) .Case(#X, BlockListAction::X)
119+
#include "swift/Basic/BlockListAction.def"
120+
.Default(BlockListAction::Undefined);
121+
if (action == BlockListAction::Undefined)
122+
continue;
123+
auto *map = dyn_cast<yaml::MappingNode>(pair.getValue());
124+
if (!map)
125+
continue;
126+
for (auto &innerPair: *map) {
127+
collectBlockList(&innerPair, action);
128+
}
129+
}
130+
}
131+
}

lib/Basic/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ add_swift_host_library(swiftBasic STATIC
7878
Unicode.cpp
7979
UUID.cpp
8080
Version.cpp
81+
BlockList.cpp
8182

8283
${llvm_revision_inc}
8384
${clang_revision_inc}

0 commit comments

Comments
 (0)