diff options
author | Adrian Prantl <aprantl@apple.com> | 2019-08-21 18:06:56 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2019-08-21 18:06:56 +0000 |
commit | 330ae19a1a563f5031954d1998001c624eb71b18 (patch) | |
tree | 5ca3e50c81b9b77a050e7d140944b6606bcea436 | |
parent | 2213bbb57aa7c928735c428cd1307ed277d2db7a (diff) | |
download | bcm5719-llvm-330ae19a1a563f5031954d1998001c624eb71b18.tar.gz bcm5719-llvm-330ae19a1a563f5031954d1998001c624eb71b18.zip |
Generalize FindTypes with CompilerContext to support fuzzy lookup
This patch generalizes the FindTypes with CompilerContext interface to
support looking up a type of unknown kind by name, as well as looking
up a type inside an unspecified submodule. These features are
motivated by the Swift branch, but are fully tested via unit tests and
lldb-test on llvm.org. Specifically, this patch adds an AnyModule and
an AnyType CompilerContext kind.
Differential Revision: https://reviews.llvm.org/D66507
rdar://problem/54471165
llvm-svn: 369555
19 files changed, 169 insertions, 71 deletions
diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index 3c53a35f7d7..0a5dcc3893c 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -189,8 +189,8 @@ public: bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types); - virtual size_t FindTypes(const std::vector<CompilerContext> &context, - bool append, TypeMap &types); + virtual size_t FindTypes(llvm::ArrayRef<CompilerContext> pattern, bool append, + TypeMap &types); virtual void GetMangledNamesForFunction(const std::string &scope_qualified_name, diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h index 3858ededc23..446e043a95e 100644 --- a/lldb/include/lldb/Symbol/Type.h +++ b/lldb/include/lldb/Symbol/Type.h @@ -21,22 +21,28 @@ #include <set> namespace lldb_private { -// CompilerContext allows an array of these items to be passed to perform -// detailed lookups in SymbolVendor and SymbolFile functions. + +/// CompilerContext allows an array of these items to be passed to perform +/// detailed lookups in SymbolVendor and SymbolFile functions. struct CompilerContext { - CompilerContext(CompilerContextKind t, ConstString n) - : type(t), name(n) {} + CompilerContext(CompilerContextKind t, ConstString n) : kind(t), name(n) {} bool operator==(const CompilerContext &rhs) const { - return type == rhs.type && name == rhs.name; + return kind == rhs.kind && name == rhs.name; } + bool operator!=(const CompilerContext &rhs) const { return !(*this == rhs); } void Dump() const; - CompilerContextKind type; + CompilerContextKind kind; ConstString name; }; +/// Match \p context_chain against \p pattern, which may contain "Any" +/// kinds. The \p context_chain should *not* contain any "Any" kinds. +bool contextMatches(llvm::ArrayRef<CompilerContext> context_chain, + llvm::ArrayRef<CompilerContext> pattern); + class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>, public UserID { public: diff --git a/lldb/include/lldb/lldb-private-enumerations.h b/lldb/include/lldb/lldb-private-enumerations.h index 3d8b360fb30..9b7879c05f9 100644 --- a/lldb/include/lldb/lldb-private-enumerations.h +++ b/lldb/include/lldb/lldb-private-enumerations.h @@ -198,18 +198,24 @@ enum class LineStatus { enum class TypeValidatorResult : bool { Success = true, Failure = false }; // Enumerations that can be used to specify scopes types when looking up types. -enum class CompilerContextKind { +enum class CompilerContextKind : uint16_t { Invalid = 0, - TranslationUnit, - Module, - Namespace, - Class, - Structure, - Union, - Function, - Variable, - Enumeration, - Typedef + TranslationUnit = 1, + Module = 1 << 1, + Namespace = 1 << 2, + Class = 1 << 3, + Struct = 1 << 4, + Union = 1 << 5, + Function = 1 << 6, + Variable = 1 << 7, + Enum = 1 << 8, + Typedef = 1 << 9, + + Any = 1 << 15, + /// Match 0..n nested modules. + AnyModule = Any | Module, + /// Match any type. + AnyType = Any | Class | Struct | Union | Enum | Typedef }; // Enumerations that can be used to specify the kind of metric we're looking at diff --git a/lldb/lit/SymbolFile/DWARF/compilercontext.ll b/lldb/lit/SymbolFile/DWARF/compilercontext.ll index 0bb69f18acc..76637baec8c 100644 --- a/lldb/lit/SymbolFile/DWARF/compilercontext.ll +++ b/lldb/lit/SymbolFile/DWARF/compilercontext.ll @@ -1,8 +1,22 @@ ; Test finding types by CompilerContext. ; RUN: llc %s -filetype=obj -o %t.o -; RUN: lldb-test symbols %t.o -find=type -compiler-context="Module:CModule,Module:SubModule,Structure:FromSubmodule" | FileCheck %s -; +; RUN: lldb-test symbols %t.o -find=type \ +; RUN: -compiler-context="Module:CModule,Module:SubModule,Struct:FromSubmoduleX" \ +; RUN: | FileCheck %s --check-prefix=NORESULTS +; RUN: lldb-test symbols %t.o -find=type \ +; RUN: -compiler-context="Module:CModule,Module:SubModule,Struct:FromSubmodule" \ +; RUN: | FileCheck %s +; RUN: lldb-test symbols %t.o -find=type \ +; RUN: -compiler-context="Module:CModule,AnyModule:*,Struct:FromSubmodule" \ +; RUN: | FileCheck %s +; RUN: lldb-test symbols %t.o -find=type \ +; RUN: -compiler-context="AnyModule:*,Struct:FromSubmodule" \ +; RUN: | FileCheck %s +; RUN: lldb-test symbols %t.o -find=type \ +; RUN: -compiler-context="Module:CModule,Module:SubModule,AnyType:FromSubmodule" \ +; RUN: | FileCheck %s ; +; NORESULTS: Found 0 types ; CHECK: Found 1 types: ; CHECK: struct FromSubmodule { ; CHECK-NEXT: unsigned int x; diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp index 73ee707394b..d5f51458eb1 100644 --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -318,9 +318,8 @@ uint32_t SymbolFileBreakpad::FindTypes( return types.GetSize(); } -size_t -SymbolFileBreakpad::FindTypes(const std::vector<CompilerContext> &context, - bool append, TypeMap &types) { +size_t SymbolFileBreakpad::FindTypes(llvm::ArrayRef<CompilerContext> pattern, + bool append, TypeMap &types) { if (!append) types.Clear(); return types.GetSize(); diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h index 6f256274b02..def975efc94 100644 --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -116,7 +116,7 @@ public: llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) override; - size_t FindTypes(const std::vector<CompilerContext> &context, bool append, + size_t FindTypes(llvm::ArrayRef<CompilerContext> pattern, bool append, TypeMap &types) override; llvm::Expected<TypeSystem &> diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 8a4e40dcd0a..f0c463726fb 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -144,11 +144,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) { // If this type comes from a Clang module, look in the DWARF section // of the pcm file in the module cache. Clang generates DWO skeleton // units as breadcrumbs to find them. - std::vector<CompilerContext> decl_context; + llvm::SmallVector<CompilerContext, 4> decl_context; die.GetDeclContext(decl_context); TypeMap dwo_types; - if (!dwo_module_sp->GetSymbolFile()->FindTypes(decl_context, true, + if (!dwo_module_sp->GetSymbolFile()->FindTypes({decl_context}, true, dwo_types)) { if (!IsClangModuleFwdDecl(die)) return TypeSP(); @@ -159,7 +159,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) { for (const auto &name_module : sym_file.getExternalTypeModules()) { if (!name_module.second) continue; - if (name_module.second->GetSymbolFile()->FindTypes(decl_context, true, + if (name_module.second->GetSymbolFile()->FindTypes({decl_context}, true, dwo_types)) break; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index 9d97ca15a25..5ee0687995a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -342,7 +342,8 @@ void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const { } } -void DWARFDIE::GetDeclContext(std::vector<CompilerContext> &context) const { +void DWARFDIE::GetDeclContext( + llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const { const dw_tag_t tag = Tag(); if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit) return; @@ -351,40 +352,33 @@ void DWARFDIE::GetDeclContext(std::vector<CompilerContext> &context) const { parent.GetDeclContext(context); switch (tag) { case DW_TAG_module: - context.push_back( - CompilerContext(CompilerContextKind::Module, ConstString(GetName()))); + context.push_back({CompilerContextKind::Module, ConstString(GetName())}); break; case DW_TAG_namespace: - context.push_back(CompilerContext(CompilerContextKind::Namespace, - ConstString(GetName()))); + context.push_back({CompilerContextKind::Namespace, ConstString(GetName())}); break; case DW_TAG_structure_type: - context.push_back(CompilerContext(CompilerContextKind::Structure, - ConstString(GetName()))); + context.push_back({CompilerContextKind::Struct, ConstString(GetName())}); break; case DW_TAG_union_type: - context.push_back( - CompilerContext(CompilerContextKind::Union, ConstString(GetName()))); + context.push_back({CompilerContextKind::Union, ConstString(GetName())}); break; case DW_TAG_class_type: - context.push_back( - CompilerContext(CompilerContextKind::Class, ConstString(GetName()))); + context.push_back({CompilerContextKind::Class, ConstString(GetName())}); break; case DW_TAG_enumeration_type: - context.push_back(CompilerContext(CompilerContextKind::Enumeration, - ConstString(GetName()))); + context.push_back({CompilerContextKind::Enum, ConstString(GetName())}); break; case DW_TAG_subprogram: - context.push_back(CompilerContext(CompilerContextKind::Function, - ConstString(GetPubname()))); + context.push_back( + {CompilerContextKind::Function, ConstString(GetPubname())}); break; case DW_TAG_variable: - context.push_back(CompilerContext(CompilerContextKind::Variable, - ConstString(GetPubname()))); + context.push_back( + {CompilerContextKind::Variable, ConstString(GetPubname())}); break; case DW_TAG_typedef: - context.push_back( - CompilerContext(CompilerContextKind::Typedef, ConstString(GetName()))); + context.push_back({CompilerContextKind::Typedef, ConstString(GetName())}); break; default: break; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index 7753ec9008c..a779c589611 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -78,8 +78,8 @@ public: /// Return this DIE's decl context as it is needed to look up types /// in Clang's -gmodules debug info format. - void - GetDeclContext(std::vector<lldb_private::CompilerContext> &context) const; + void GetDeclContext( + llvm::SmallVectorImpl<lldb_private::CompilerContext> &context) const; // Getting attribute values from the DIE. // diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 17f9241bb12..ba63b41a581 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2484,16 +2484,16 @@ uint32_t SymbolFileDWARF::FindTypes( return num_die_matches; } -size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context, +size_t SymbolFileDWARF::FindTypes(llvm::ArrayRef<CompilerContext> pattern, bool append, TypeMap &types) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); if (!append) types.Clear(); - if (context.empty()) + if (pattern.empty()) return 0; - ConstString name = context.back().name; + ConstString name = pattern.back().name; if (!name) return 0; @@ -2508,9 +2508,9 @@ size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context, DWARFDIE die = GetDIE(die_ref); if (die) { - std::vector<CompilerContext> die_context; + llvm::SmallVector<CompilerContext, 4> die_context; die.GetDeclContext(die_context); - if (die_context != context) + if (!contextMatches(die_context, pattern)) continue; Type *matching_type = ResolveType(die, true, true); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 25e231eb651..0d59013b014 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -184,7 +184,7 @@ public: llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap &types) override; - size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context, + size_t FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern, bool append, lldb_private::TypeMap &types) override; size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 20c873315af..32b13c950c0 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1269,9 +1269,8 @@ uint32_t SymbolFileNativePDB::FindTypes( return match_count; } -size_t -SymbolFileNativePDB::FindTypes(const std::vector<CompilerContext> &context, - bool append, TypeMap &types) { +size_t SymbolFileNativePDB::FindTypes(llvm::ArrayRef<CompilerContext> pattern, + bool append, TypeMap &types) { return 0; } diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index 6ddbea716ed..f64fb4f4252 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -134,7 +134,7 @@ public: llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) override; - size_t FindTypes(const std::vector<CompilerContext> &context, bool append, + size_t FindTypes(llvm::ArrayRef<CompilerContext> pattern, bool append, TypeMap &types) override; llvm::Expected<TypeSystem &> diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 59c0b5c9153..51b84c4cae6 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1584,9 +1584,8 @@ void SymbolFilePDB::FindTypesByName( } } -size_t SymbolFilePDB::FindTypes( - const std::vector<lldb_private::CompilerContext> &contexts, bool append, - lldb_private::TypeMap &types) { +size_t SymbolFilePDB::FindTypes(llvm::ArrayRef<CompilerContext> pattern, + bool append, lldb_private::TypeMap &types) { return 0; } diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index 8e4d40add03..15eed0f9f6c 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -132,7 +132,7 @@ public: llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap &types) override; - size_t FindTypes(const std::vector<lldb_private::CompilerContext> &context, + size_t FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern, bool append, lldb_private::TypeMap &types) override; void FindTypesByRegex(const lldb_private::RegularExpression ®ex, diff --git a/lldb/source/Symbol/SymbolFile.cpp b/lldb/source/Symbol/SymbolFile.cpp index 8b9d8d31144..1cbfb4cb0b0 100644 --- a/lldb/source/Symbol/SymbolFile.cpp +++ b/lldb/source/Symbol/SymbolFile.cpp @@ -149,7 +149,7 @@ uint32_t SymbolFile::FindTypes( return 0; } -size_t SymbolFile::FindTypes(const std::vector<CompilerContext> &context, +size_t SymbolFile::FindTypes(llvm::ArrayRef<CompilerContext> pattern, bool append, TypeMap &types) { if (!append) types.Clear(); diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index 717b49deb74..5666590c224 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -33,9 +33,38 @@ using namespace lldb; using namespace lldb_private; +bool lldb_private::contextMatches(llvm::ArrayRef<CompilerContext> context_chain, + llvm::ArrayRef<CompilerContext> pattern) { + auto ctx = context_chain.begin(); + auto ctx_end = context_chain.end(); + for (const CompilerContext &pat : pattern) { + // Early exit if the pattern is too long. + if (ctx == ctx_end) + return false; + if (*ctx != pat) { + // Skip any number of module matches. + if (pat.kind == CompilerContextKind::AnyModule) { + // Greedily match 0..n modules. + ctx = std::find_if(ctx, ctx_end, [](const CompilerContext &ctx) { + return ctx.kind != CompilerContextKind::Module; + }); + continue; + } + // See if there is a kind mismatch; they should have 1 bit in common. + if (((uint16_t)ctx->kind & (uint16_t)pat.kind) == 0) + return false; + // The name is ignored for AnyModule, but not for AnyType. + if (pat.kind != CompilerContextKind::AnyModule && ctx->name != pat.name) + return false; + } + ++ctx; + } + return true; +} + void CompilerContext::Dump() const { - switch (type) { - case CompilerContextKind::Invalid: + switch (kind) { + default: printf("Invalid"); break; case CompilerContextKind::TranslationUnit: @@ -50,7 +79,7 @@ void CompilerContext::Dump() const { case CompilerContextKind::Class: printf("Class"); break; - case CompilerContextKind::Structure: + case CompilerContextKind::Struct: printf("Structure"); break; case CompilerContextKind::Union: @@ -62,12 +91,18 @@ void CompilerContext::Dump() const { case CompilerContextKind::Variable: printf("Variable"); break; - case CompilerContextKind::Enumeration: + case CompilerContextKind::Enum: printf("Enumeration"); break; case CompilerContextKind::Typedef: printf("Typedef"); break; + case CompilerContextKind::AnyModule: + printf("AnyModule"); + break; + case CompilerContextKind::AnyType: + printf("AnyType"); + break; } printf("(\"%s\")\n", name.GetCString()); } diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp index a5ebac9a2f0..d7b67373e5e 100644 --- a/lldb/tools/lldb-test/lldb-test.cpp +++ b/lldb/tools/lldb-test/lldb-test.cpp @@ -242,12 +242,14 @@ std::vector<CompilerContext> parseCompilerContext() { .Case("Module", CompilerContextKind::Module) .Case("Namespace", CompilerContextKind::Namespace) .Case("Class", CompilerContextKind::Class) - .Case("Structure", CompilerContextKind::Structure) + .Case("Struct", CompilerContextKind::Struct) .Case("Union", CompilerContextKind::Union) .Case("Function", CompilerContextKind::Function) .Case("Variable", CompilerContextKind::Variable) - .Case("Enumeration", CompilerContextKind::Enumeration) + .Case("Enum", CompilerContextKind::Enum) .Case("Typedef", CompilerContextKind::Typedef) + .Case("AnyModule", CompilerContextKind::AnyModule) + .Case("AnyType", CompilerContextKind::AnyType) .Default(CompilerContextKind::Invalid); if (value.empty()) { WithColor::error() << "compiler context entry has no \"name\"\n"; @@ -511,7 +513,7 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) { Symfile.FindTypes(ConstString(Name), ContextPtr, true, UINT32_MAX, SearchedFiles, Map); else - Symfile.FindTypes(parseCompilerContext(), true, Map); + Symfile.FindTypes({parseCompilerContext()}, true, Map); outs() << formatv("Found {0} types:\n", Map.GetSize()); StreamString Stream; diff --git a/lldb/unittests/Symbol/TestType.cpp b/lldb/unittests/Symbol/TestType.cpp index 4b9b7bfaba3..d23d7a53e03 100644 --- a/lldb/unittests/Symbol/TestType.cpp +++ b/lldb/unittests/Symbol/TestType.cpp @@ -48,3 +48,47 @@ TEST(Type, GetTypeScopeAndBasename) { "std::set<int, std::less<int>>::iterator<bool>", true, "std::set<int, std::less<int>>::", "iterator<bool>"); } + +TEST(Type, CompilerContextPattern) { + std::vector<CompilerContext> mms = { + {CompilerContextKind::Module, ConstString("A")}, + {CompilerContextKind::Module, ConstString("B")}, + {CompilerContextKind::Struct, ConstString("S")}}; + EXPECT_TRUE(contextMatches(mms, mms)); + std::vector<CompilerContext> mmc = { + {CompilerContextKind::Module, ConstString("A")}, + {CompilerContextKind::Module, ConstString("B")}, + {CompilerContextKind::Class, ConstString("S")}}; + EXPECT_FALSE(contextMatches(mms, mmc)); + std::vector<CompilerContext> ms = { + {CompilerContextKind::Module, ConstString("A")}, + {CompilerContextKind::Struct, ConstString("S")}}; + std::vector<CompilerContext> mas = { + {CompilerContextKind::Module, ConstString("A")}, + {CompilerContextKind::AnyModule, ConstString("*")}, + {CompilerContextKind::Struct, ConstString("S")}}; + EXPECT_TRUE(contextMatches(mms, mas)); + EXPECT_TRUE(contextMatches(ms, mas)); + EXPECT_FALSE(contextMatches(mas, ms)); + std::vector<CompilerContext> mmms = { + {CompilerContextKind::Module, ConstString("A")}, + {CompilerContextKind::Module, ConstString("B")}, + {CompilerContextKind::Module, ConstString("C")}, + {CompilerContextKind::Struct, ConstString("S")}}; + EXPECT_TRUE(contextMatches(mmms, mas)); + std::vector<CompilerContext> mme = { + {CompilerContextKind::Module, ConstString("A")}, + {CompilerContextKind::Module, ConstString("B")}, + {CompilerContextKind::Enum, ConstString("S")}}; + std::vector<CompilerContext> mma = { + {CompilerContextKind::Module, ConstString("A")}, + {CompilerContextKind::Module, ConstString("B")}, + {CompilerContextKind::AnyType, ConstString("S")}}; + EXPECT_TRUE(contextMatches(mme, mma)); + EXPECT_TRUE(contextMatches(mms, mma)); + std::vector<CompilerContext> mme2 = { + {CompilerContextKind::Module, ConstString("A")}, + {CompilerContextKind::Module, ConstString("B")}, + {CompilerContextKind::Enum, ConstString("S2")}}; + EXPECT_FALSE(contextMatches(mme2, mma)); +} |