diff options
Diffstat (limited to 'llvm/include')
| -rw-r--r-- | llvm/include/llvm/ADT/RadixTree.h | 11 | ||||
| -rw-r--r-- | llvm/include/llvm/Analysis/DXILResource.h | 1 | ||||
| -rw-r--r-- | llvm/include/llvm/CodeGen/BasicTTIImpl.h | 11 | ||||
| -rw-r--r-- | llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h | 47 | ||||
| -rw-r--r-- | llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h | 4 | ||||
| -rw-r--r-- | llvm/include/llvm/CodeGen/TargetLowering.h | 29 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h | 6 | ||||
| -rw-r--r-- | llvm/include/llvm/IR/AbstractCallSite.h | 10 | ||||
| -rw-r--r-- | llvm/include/llvm/IR/IRBuilder.h | 2 | ||||
| -rw-r--r-- | llvm/include/llvm/Remarks/Remark.h | 21 | ||||
| -rw-r--r-- | llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h | 6 | ||||
| -rw-r--r-- | llvm/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h | 22 |
12 files changed, 117 insertions, 53 deletions
diff --git a/llvm/include/llvm/ADT/RadixTree.h b/llvm/include/llvm/ADT/RadixTree.h index 9e2ab97..87e2a3e 100644 --- a/llvm/include/llvm/ADT/RadixTree.h +++ b/llvm/include/llvm/ADT/RadixTree.h @@ -20,6 +20,7 @@ #include <cstddef> #include <iterator> #include <list> +#include <optional> #include <utility> #include <vector> @@ -92,7 +93,7 @@ private: /// If this node does not have a value (i.e., it's an internal node that /// only serves as a path to other values), this iterator will be equal /// to default constructed `ContainerType::iterator()`. - typename ContainerType::iterator Value; + std::optional<typename ContainerType::iterator> Value; /// The first character of the Key. Used for fast child lookup. KeyValueType KeyFront; @@ -215,7 +216,7 @@ private: KeyConstIteratorType{}}; void findNextValid() { - while (Curr && Curr->Value == typename ContainerType::iterator()) + while (Curr && !Curr->Value.has_value()) advance(); } @@ -249,7 +250,7 @@ private: public: IteratorImpl() = default; - MappedType &operator*() const { return *Curr->Value; } + MappedType &operator*() const { return **Curr->Value; } IteratorImpl &operator++() { advance(); @@ -315,12 +316,12 @@ public: const value_type &NewValue = KeyValuePairs.emplace_front( std::move(Key), T(std::forward<Ts>(Args)...)); Node &Node = findOrCreate(NewValue.first); - bool HasValue = Node.Value != typename ContainerType::iterator(); + bool HasValue = Node.Value.has_value(); if (!HasValue) Node.Value = KeyValuePairs.begin(); else KeyValuePairs.pop_front(); - return {Node.Value, !HasValue}; + return {*Node.Value, !HasValue}; } /// diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h index c7aff16..2b0dcb9 100644 --- a/llvm/include/llvm/Analysis/DXILResource.h +++ b/llvm/include/llvm/Analysis/DXILResource.h @@ -293,6 +293,7 @@ public: struct TypedInfo { dxil::ElementType ElementTy; + dxil::ElementType DXILStorageTy; uint32_t ElementCount; bool operator==(const TypedInfo &RHS) const { diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h index 76b6c8e..e8dbc96 100644 --- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -594,12 +594,13 @@ public: // Check if suitable for a bit test if (N <= DL.getIndexSizeInBits(0u)) { - SmallPtrSet<const BasicBlock *, 4> Dests; - for (auto I : SI.cases()) - Dests.insert(I.getCaseSuccessor()); + DenseMap<const BasicBlock *, unsigned int> DestMap; + for (auto I : SI.cases()) { + const BasicBlock *BB = I.getCaseSuccessor(); + ++DestMap[BB]; + } - if (TLI->isSuitableForBitTests(Dests.size(), N, MinCaseVal, MaxCaseVal, - DL)) + if (TLI->isSuitableForBitTests(DestMap, MinCaseVal, MaxCaseVal, DL)) return 1; } diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h index 6dccdc2..d8d7ccc 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h @@ -356,7 +356,7 @@ public: // trunc(ext x) -> x ArtifactValueFinder Finder(MRI, Builder, LI); if (Register FoundReg = - Finder.findValueFromDef(DstReg, 0, DstTy.getSizeInBits())) { + Finder.findValueFromDef(DstReg, 0, DstTy.getSizeInBits(), DstTy)) { LLT FoundRegTy = MRI.getType(FoundReg); if (DstTy == FoundRegTy) { LLVM_DEBUG(dbgs() << ".. Combine G_TRUNC(G_[S,Z,ANY]EXT/G_TRUNC...): " @@ -641,10 +641,11 @@ public: Register SrcReg = Concat.getReg(StartSrcIdx); if (InRegOffset == 0 && Size == SrcSize) { CurrentBest = SrcReg; - return findValueFromDefImpl(SrcReg, 0, Size); + return findValueFromDefImpl(SrcReg, 0, Size, MRI.getType(SrcReg)); } - return findValueFromDefImpl(SrcReg, InRegOffset, Size); + return findValueFromDefImpl(SrcReg, InRegOffset, Size, + MRI.getType(SrcReg)); } /// Given an build_vector op \p BV and a start bit and size, try to find @@ -759,7 +760,8 @@ public: if (EndBit <= InsertOffset || InsertedEndBit <= StartBit) { SrcRegToUse = ContainerSrcReg; NewStartBit = StartBit; - return findValueFromDefImpl(SrcRegToUse, NewStartBit, Size); + return findValueFromDefImpl(SrcRegToUse, NewStartBit, Size, + MRI.getType(SrcRegToUse)); } if (InsertOffset <= StartBit && EndBit <= InsertedEndBit) { SrcRegToUse = InsertedReg; @@ -767,7 +769,8 @@ public: if (NewStartBit == 0 && Size == MRI.getType(SrcRegToUse).getSizeInBits()) CurrentBest = SrcRegToUse; - return findValueFromDefImpl(SrcRegToUse, NewStartBit, Size); + return findValueFromDefImpl(SrcRegToUse, NewStartBit, Size, + MRI.getType(SrcRegToUse)); } // The bit range spans both the inserted and container regions. return Register(); @@ -799,7 +802,7 @@ public: if (StartBit == 0 && SrcType.getSizeInBits() == Size) CurrentBest = SrcReg; - return findValueFromDefImpl(SrcReg, StartBit, Size); + return findValueFromDefImpl(SrcReg, StartBit, Size, SrcType); } /// Given an G_TRUNC op \p MI and a start bit and size, try to find @@ -819,14 +822,14 @@ public: if (!SrcType.isScalar()) return CurrentBest; - return findValueFromDefImpl(SrcReg, StartBit, Size); + return findValueFromDefImpl(SrcReg, StartBit, Size, SrcType); } /// Internal implementation for findValueFromDef(). findValueFromDef() /// initializes some data like the CurrentBest register, which this method /// and its callees rely upon. Register findValueFromDefImpl(Register DefReg, unsigned StartBit, - unsigned Size) { + unsigned Size, LLT DstTy) { std::optional<DefinitionAndSourceRegister> DefSrcReg = getDefSrcRegIgnoringCopies(DefReg, MRI); MachineInstr *Def = DefSrcReg->MI; @@ -847,7 +850,7 @@ public: } Register SrcReg = Def->getOperand(Def->getNumOperands() - 1).getReg(); Register SrcOriginReg = - findValueFromDefImpl(SrcReg, StartBit + DefStartBit, Size); + findValueFromDefImpl(SrcReg, StartBit + DefStartBit, Size, DstTy); if (SrcOriginReg) return SrcOriginReg; // Failed to find a further value. If the StartBit and Size perfectly @@ -868,6 +871,12 @@ public: case TargetOpcode::G_ZEXT: case TargetOpcode::G_ANYEXT: return findValueFromExt(*Def, StartBit, Size); + case TargetOpcode::G_IMPLICIT_DEF: { + if (MRI.getType(DefReg) == DstTy) + return DefReg; + MIB.setInstrAndDebugLoc(*Def); + return MIB.buildUndef(DstTy).getReg(0); + } default: return CurrentBest; } @@ -882,10 +891,10 @@ public: /// at position \p StartBit with size \p Size. /// \returns a register with the requested size, or an empty Register if no /// better value could be found. - Register findValueFromDef(Register DefReg, unsigned StartBit, - unsigned Size) { + Register findValueFromDef(Register DefReg, unsigned StartBit, unsigned Size, + LLT DstTy) { CurrentBest = Register(); - Register FoundReg = findValueFromDefImpl(DefReg, StartBit, Size); + Register FoundReg = findValueFromDefImpl(DefReg, StartBit, Size, DstTy); return FoundReg != DefReg ? FoundReg : Register(); } @@ -904,7 +913,8 @@ public: DeadDefs[DefIdx] = true; continue; } - Register FoundVal = findValueFromDef(DefReg, 0, DestTy.getSizeInBits()); + Register FoundVal = + findValueFromDef(DefReg, 0, DestTy.getSizeInBits(), DestTy); if (!FoundVal) continue; if (MRI.getType(FoundVal) != DestTy) @@ -923,7 +933,7 @@ public: GUnmerge *findUnmergeThatDefinesReg(Register Reg, unsigned Size, unsigned &DefOperandIdx) { - if (Register Def = findValueFromDefImpl(Reg, 0, Size)) { + if (Register Def = findValueFromDefImpl(Reg, 0, Size, MRI.getType(Reg))) { if (auto *Unmerge = dyn_cast<GUnmerge>(MRI.getVRegDef(Def))) { DefOperandIdx = Unmerge->findRegisterDefOperandIdx(Def, /*TRI=*/nullptr); @@ -1288,12 +1298,19 @@ public: // for N >= %2.getSizeInBits() / 2 // %3 = G_EXTRACT %1, (N - %0.getSizeInBits() + Register DstReg = MI.getOperand(0).getReg(); Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg()); MachineInstr *MergeI = MRI.getVRegDef(SrcReg); + if (MergeI && MergeI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) { + Builder.setInstrAndDebugLoc(MI); + Builder.buildUndef(DstReg); + UpdatedDefs.push_back(DstReg); + markInstAndDefDead(MI, *MergeI, DeadInsts); + return true; + } if (!MergeI || !isa<GMergeLikeInstr>(MergeI)) return false; - Register DstReg = MI.getOperand(0).getReg(); LLT DstTy = MRI.getType(DstReg); LLT SrcTy = MRI.getType(SrcReg); diff --git a/llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h b/llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h index a9e53ba..f980d3d 100644 --- a/llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h +++ b/llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h @@ -84,6 +84,10 @@ LLVM_ABI Libcall getSINCOS(EVT RetVT); /// UNKNOWN_LIBCALL if there is none. LLVM_ABI Libcall getSINCOSPI(EVT RetVT); +/// Return the SINCOS_STRET_ value for the given types, or UNKNOWN_LIBCALL if +/// there is none. +LLVM_ABI Libcall getSINCOS_STRET(EVT RetVT); + /// getMODF - Return the MODF_* value for the given types, or /// UNKNOWN_LIBCALL if there is none. LLVM_ABI Libcall getMODF(EVT RetVT); diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index d6ed3a8..4058dd7 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -1433,9 +1433,9 @@ public: /// \p High as its lowest and highest case values, and expects \p NumCmps /// case value comparisons. Check if the number of destinations, comparison /// metric, and range are all suitable. - bool isSuitableForBitTests(unsigned NumDests, unsigned NumCmps, - const APInt &Low, const APInt &High, - const DataLayout &DL) const { + bool isSuitableForBitTests( + const DenseMap<const BasicBlock *, unsigned int> &DestCmps, + const APInt &Low, const APInt &High, const DataLayout &DL) const { // FIXME: I don't think NumCmps is the correct metric: a single case and a // range of cases both require only one branch to lower. Just looking at the // number of clusters and destinations should be enough to decide whether to @@ -1446,6 +1446,20 @@ public: if (!rangeFitsInWord(Low, High, DL)) return false; + unsigned NumDests = DestCmps.size(); + unsigned NumCmps = 0; + unsigned int MaxBitTestEntry = 0; + for (auto &DestCmp : DestCmps) { + NumCmps += DestCmp.second; + if (DestCmp.second > MaxBitTestEntry) + MaxBitTestEntry = DestCmp.second; + } + + // Comparisons might be cheaper for small number of comparisons, which can + // be Arch Target specific. + if (MaxBitTestEntry < getMinimumBitTestCmps()) + return false; + // Decide whether it's profitable to lower this range with bit tests. Each // destination requires a bit test and branch, and there is an overall range // check branch. For a small number of clusters, separate comparisons might @@ -2055,6 +2069,9 @@ public: virtual bool isJumpTableRelative() const; + /// Retuen the minimum of largest number of comparisons in BitTest. + unsigned getMinimumBitTestCmps() const; + /// If a physical register, this specifies the register that /// llvm.savestack/llvm.restorestack should save and restore. Register getStackPointerRegisterToSaveRestore() const { @@ -2577,6 +2594,9 @@ protected: /// Set to zero to generate unlimited jump tables. void setMaximumJumpTableSize(unsigned); + /// Set the minimum of largest of number of comparisons to generate BitTest. + void setMinimumBitTestCmps(unsigned Val); + /// If set to a physical register, this specifies the register that /// llvm.savestack/llvm.restorestack should save and restore. void setStackPointerRegisterToSaveRestore(Register R) { @@ -3719,6 +3739,9 @@ private: /// backend supports. unsigned MinCmpXchgSizeInBits; + /// The minimum of largest number of comparisons to use bit test for switch. + unsigned MinimumBitTestCmps; + /// This indicates if the target supports unaligned atomic operations. bool SupportsUnalignedAtomics; diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h index 7f9bf12..be78647 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -143,7 +143,11 @@ public: decltype(make_filter_range(std::declval<iterator_range>(), isCompileUnit)); LLVM_ABI DWARFUnit *getUnitForOffset(uint64_t Offset) const; - LLVM_ABI DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E); + /// Returns the Unit from the .debug_info or .debug_types section by the index + /// entry. + LLVM_ABI DWARFUnit * + getUnitForIndexEntry(const DWARFUnitIndex::Entry &E, DWARFSectionKind Sec, + const DWARFSection *Section = nullptr); /// Read units from a .debug_info or .debug_types section. Calls made /// before finishedInfoUnits() are assumed to be for .debug_info sections, diff --git a/llvm/include/llvm/IR/AbstractCallSite.h b/llvm/include/llvm/IR/AbstractCallSite.h index 9e24ae7..f431e1d 100644 --- a/llvm/include/llvm/IR/AbstractCallSite.h +++ b/llvm/include/llvm/IR/AbstractCallSite.h @@ -137,7 +137,7 @@ public: /// Return true if @p U is the use that defines the callee of this ACS. bool isCallee(const Use *U) const { - if (isDirectCall()) + if (!isCallbackCall()) return CB->isCallee(U); assert(!CI.ParameterEncoding.empty() && @@ -154,7 +154,7 @@ public: /// Return the number of parameters of the callee. unsigned getNumArgOperands() const { - if (isDirectCall()) + if (!isCallbackCall()) return CB->arg_size(); // Subtract 1 for the callee encoding. return CI.ParameterEncoding.size() - 1; @@ -169,7 +169,7 @@ public: /// Return the operand index of the underlying instruction associated with /// the function parameter number @p ArgNo or -1 if there is none. int getCallArgOperandNo(unsigned ArgNo) const { - if (isDirectCall()) + if (!isCallbackCall()) return ArgNo; // Add 1 for the callee encoding. return CI.ParameterEncoding[ArgNo + 1]; @@ -183,7 +183,7 @@ public: /// Return the operand of the underlying instruction associated with the /// function parameter number @p ArgNo or nullptr if there is none. Value *getCallArgOperand(unsigned ArgNo) const { - if (isDirectCall()) + if (!isCallbackCall()) return CB->getArgOperand(ArgNo); // Add 1 for the callee encoding. return CI.ParameterEncoding[ArgNo + 1] >= 0 @@ -210,7 +210,7 @@ public: /// Return the pointer to function that is being called. Value *getCalledOperand() const { - if (isDirectCall()) + if (!isCallbackCall()) return CB->getCalledOperand(); return CB->getArgOperand(getCallArgOperandNoForCallee()); } diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index dacda0a..972a253 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -2191,7 +2191,7 @@ public: FMFSource); } Value *CreatePtrToAddr(Value *V, const Twine &Name = "") { - return CreateCast(Instruction::PtrToInt, V, + return CreateCast(Instruction::PtrToAddr, V, BB->getDataLayout().getAddressType(V->getType()), Name); } Value *CreatePtrToInt(Value *V, Type *DestTy, diff --git a/llvm/include/llvm/Remarks/Remark.h b/llvm/include/llvm/Remarks/Remark.h index 8c8ca76..663af63 100644 --- a/llvm/include/llvm/Remarks/Remark.h +++ b/llvm/include/llvm/Remarks/Remark.h @@ -51,12 +51,21 @@ struct Argument { // If set, the debug location corresponding to the value. std::optional<RemarkLocation> Loc; + Argument() = default; + Argument(StringRef Key, StringRef Val) : Key(Key), Val(Val) {} + /// Implement operator<< on Argument. LLVM_ABI void print(raw_ostream &OS) const; - /// Return the value of argument as int. - LLVM_ABI std::optional<int> getValAsInt() const; - /// Check if the argument value can be parsed as int. - LLVM_ABI bool isValInt() const; + + /// Return the value of argument as an integer of type T. + template <typename T> + std::optional<T> getValAsInt(unsigned Radix = 10) const { + StringRef Str = Val; + T Res; + if (Str.consumeInteger<T>(Radix, Res) || !Str.empty()) + return std::nullopt; + return Res; + } }; // Create wrappers for C Binding types (see CBindingWrapping.h). @@ -127,6 +136,10 @@ struct Remark { /// Return a message composed from the arguments as a string. LLVM_ABI std::string getArgsAsMsg() const; + /// Return the first argument with the specified key or nullptr if no such + /// argument was found. + LLVM_ABI Argument *getArgByKey(StringRef Key); + /// Clone this remark to explicitly ask for a copy. Remark clone() const { return *this; } diff --git a/llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h b/llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h index 0540166..63c5990 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h +++ b/llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h @@ -13,6 +13,7 @@ #define LLVM_TRANSFORMS_INSTRUMENTATION_SANITIZERBINARYMETADATA_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/IR/Function.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" @@ -20,6 +21,9 @@ #include "llvm/Transforms/Utils/Instrumentation.h" namespace llvm { +namespace vfs { +class FileSystem; +} // namespace vfs struct SanitizerBinaryMetadataOptions { bool Covered = false; @@ -53,12 +57,14 @@ class SanitizerBinaryMetadataPass public: LLVM_ABI explicit SanitizerBinaryMetadataPass( SanitizerBinaryMetadataOptions Opts = {}, + IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr, ArrayRef<std::string> IgnorelistFiles = {}); LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); static bool isRequired() { return true; } private: const SanitizerBinaryMetadataOptions Options; + IntrusiveRefCntPtr<vfs::FileSystem> VFS; const ArrayRef<std::string> IgnorelistFiles; }; diff --git a/llvm/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h b/llvm/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h index f14f5b9..a8a09fb 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h +++ b/llvm/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h @@ -15,14 +15,17 @@ #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_SANITIZERCOVERAGE_H #define LLVM_TRANSFORMS_INSTRUMENTATION_SANITIZERCOVERAGE_H +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/IR/PassManager.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/SpecialCaseList.h" -#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Transforms/Utils/Instrumentation.h" namespace llvm { class Module; +namespace vfs { +class FileSystem; +} // namespace vfs /// This is the ModuleSanitizerCoverage pass used in the new pass manager. The /// pass instruments functions for coverage, adds initialization calls to the @@ -32,24 +35,15 @@ class SanitizerCoveragePass : public PassInfoMixin<SanitizerCoveragePass> { public: explicit SanitizerCoveragePass( SanitizerCoverageOptions Options = SanitizerCoverageOptions(), - const std::vector<std::string> &AllowlistFiles = - std::vector<std::string>(), - const std::vector<std::string> &BlocklistFiles = - std::vector<std::string>()) - : Options(Options) { - if (AllowlistFiles.size() > 0) - Allowlist = SpecialCaseList::createOrDie(AllowlistFiles, - *vfs::getRealFileSystem()); - if (BlocklistFiles.size() > 0) - Blocklist = SpecialCaseList::createOrDie(BlocklistFiles, - *vfs::getRealFileSystem()); - } + IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr, + const std::vector<std::string> &AllowlistFiles = {}, + const std::vector<std::string> &BlocklistFiles = {}); LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); static bool isRequired() { return true; } private: SanitizerCoverageOptions Options; - + IntrusiveRefCntPtr<vfs::FileSystem> VFS; std::unique_ptr<SpecialCaseList> Allowlist; std::unique_ptr<SpecialCaseList> Blocklist; }; |
