Skip to content

Commit 9d74b1d

Browse files
committed
Swift lookup tables: translate DeclContext into something less tied to the AST.
We want to serialize this data structure, so make that easier.
1 parent 90c5cfe commit 9d74b1d

File tree

2 files changed

+60
-37
lines changed

2 files changed

+60
-37
lines changed

lib/ClangImporter/SwiftLookupTable.cpp

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,6 @@
1919
#include "clang/AST/DeclObjC.h"
2020
using namespace swift;
2121

22-
bool SwiftLookupTable::matchesContext(clang::DeclContext *foundContext,
23-
clang::DeclContext *requestedContext) {
24-
/// If the requested context was null, we match.
25-
if (!requestedContext)
26-
return true;
27-
28-
// If the contexts match, we match.
29-
if (foundContext == requestedContext)
30-
return true;
31-
32-
// If we found something in an Objective-C protocol to which a class
33-
// conforms, we match.
34-
if (auto objcProto = dyn_cast<clang::ObjCProtocolDecl>(foundContext)) {
35-
if (auto objcClass = dyn_cast<clang::ObjCInterfaceDecl>(requestedContext)) {
36-
return objcClass->ClassImplementsProtocol(objcProto,
37-
/*lookupCategory=*/true);
38-
}
39-
}
40-
41-
return false;
42-
}
43-
4422
/// Determine whether the new declarations matches an existing declaration.
4523
static bool matchesExistingDecl(clang::Decl *decl, clang::Decl *existingDecl) {
4624
// If the canonical declarations are equivalent, we have a match.
@@ -51,9 +29,38 @@ static bool matchesExistingDecl(clang::Decl *decl, clang::Decl *existingDecl) {
5129
return false;
5230
}
5331

32+
Optional<std::pair<SwiftLookupTable::ContextKind, StringRef>>
33+
SwiftLookupTable::translateContext(clang::DeclContext *context) {
34+
// Translation unit context.
35+
if (context->isTranslationUnit())
36+
return std::make_pair(ContextKind::TranslationUnit, StringRef());
37+
38+
// Tag declaration context.
39+
if (auto tag = dyn_cast<clang::TagDecl>(context)) {
40+
if (tag->getIdentifier())
41+
return std::make_pair(ContextKind::Tag, tag->getName());
42+
if (auto typedefDecl = tag->getTypedefNameForAnonDecl())
43+
return std::make_pair(ContextKind::Tag, typedefDecl->getName());
44+
return None;
45+
}
46+
47+
// Objective-C class context.
48+
if (auto objcClass = dyn_cast<clang::ObjCInterfaceDecl>(context))
49+
return std::make_pair(ContextKind::ObjCClass, objcClass->getName());
50+
51+
// Objective-C protocol context.
52+
if (auto objcProtocol = dyn_cast<clang::ObjCProtocolDecl>(context))
53+
return std::make_pair(ContextKind::ObjCProtocol, objcProtocol->getName());
54+
55+
return None;
56+
}
57+
5458
void SwiftLookupTable::addEntry(DeclName name, clang::NamedDecl *decl,
5559
clang::DeclContext *effectiveContext) {
56-
clang::DeclContext *context = effectiveContext->getPrimaryContext();
60+
// Translate the context.
61+
auto contextOpt = translateContext(effectiveContext);
62+
if (!contextOpt) return;
63+
auto context = *contextOpt;
5764

5865
// First, check whether there is already a full name entry.
5966
auto knownFull = FullNameTable.find(name);
@@ -86,7 +93,7 @@ void SwiftLookupTable::addEntry(DeclName name, clang::NamedDecl *decl,
8693

8794
// This is a new context for this name. Add it.
8895
FullTableEntry newEntry;
89-
newEntry.Context = context;
96+
newEntry.Context = context;;
9097
newEntry.Decls.push_back(decl);
9198
fullEntries.push_back(newEntry);
9299
}
@@ -181,13 +188,15 @@ void SwiftLookupTable::dump() const {
181188
llvm::errs() << " " << fullName << ":\n";
182189
const auto &fullEntries = FullNameTable.find(fullName)->second;
183190
for (const auto &fullEntry : fullEntries) {
184-
llvm::errs() << " ";
185-
if (fullEntry.Context->isTranslationUnit()) {
191+
switch (fullEntry.Context.first) {
192+
case ContextKind::TranslationUnit:
186193
llvm::errs() << "TU";
187-
} else if (auto named = dyn_cast<clang::NamedDecl>(fullEntry.Context)) {
188-
printName(named, llvm::errs());
189-
} else {
190-
llvm::errs() << "<unknown>";
194+
break;
195+
196+
case ContextKind::Tag:
197+
case ContextKind::ObjCClass:
198+
case ContextKind::ObjCProtocol:
199+
llvm::errs() << fullEntry.Context.second;
191200
}
192201
llvm::errs() << ": ";
193202

lib/ClangImporter/SwiftLookupTable.h

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
#include "swift/Basic/LLVM.h"
2121
#include "swift/AST/Identifier.h"
2222
#include "llvm/ADT/DenseMap.h"
23+
#include "llvm/ADT/Optional.h"
2324
#include "llvm/ADT/SmallVector.h"
2425
#include "llvm/ADT/TinyPtrVector.h"
26+
#include <utility>
2527

2628
namespace clang {
2729
class NamedDecl;
@@ -40,20 +42,32 @@ namespace swift {
4042
/// entities based on their Swift names, and is used by the Clang
4143
/// importer to satisfy the Swift compiler's queries.
4244
class SwiftLookupTable {
45+
public:
46+
/// The kind of context in which a name occurs.
47+
enum class ContextKind : uint8_t {
48+
/// A translation unit.
49+
TranslationUnit = 0,
50+
/// A tag declaration (struct, enum, union, C++ class).
51+
Tag,
52+
/// An Objective-C class.
53+
ObjCClass,
54+
/// An Objective-C protocol.
55+
ObjCProtocol,
56+
};
57+
4358
/// An entry in the table of C entities indexed by full Swift name.
4459
struct FullTableEntry {
4560
/// The context in which the entities with the given name occur, e.g.,
4661
/// a class, struct, translation unit, etc.
47-
///
48-
/// Many Clang DeclContexts can have redeclarations, so this entry
4962
/// is always the canonical DeclContext for the entity.
50-
clang::DeclContext *Context;
63+
std::pair<ContextKind, StringRef> Context;
5164

5265
/// The set of Clang declarations with this name and in this
5366
/// context.
5467
llvm::TinyPtrVector<clang::NamedDecl *> Decls;
5568
};
5669

70+
private:
5771
/// A table mapping from the full name of Swift entities to all of
5872
/// the C entities that have that name, in all contexts.
5973
llvm::DenseMap<DeclName, SmallVector<FullTableEntry, 2>> FullNameTable;
@@ -62,11 +76,11 @@ class SwiftLookupTable {
6276
/// full Swift names based on that identifier.
6377
llvm::DenseMap<Identifier, SmallVector<DeclName, 2>> BaseNameTable;
6478

65-
/// Determine whether the given context we found matches the
66-
/// requested context.
67-
bool matchesContext(clang::DeclContext *foundContext,
68-
clang::DeclContext *requestedContext);
6979
public:
80+
/// Translate a Clang DeclContext into a context kind and name.
81+
llvm::Optional<std::pair<ContextKind, StringRef>>
82+
translateContext(clang::DeclContext *context);
83+
7084
/// Add an entry to the lookup table.
7185
///
7286
/// \param name The Swift name of the entry.

0 commit comments

Comments
 (0)