19
19
#include " clang/AST/DeclObjC.h"
20
20
using namespace swift ;
21
21
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
-
44
22
// / Determine whether the new declarations matches an existing declaration.
45
23
static bool matchesExistingDecl (clang::Decl *decl, clang::Decl *existingDecl) {
46
24
// If the canonical declarations are equivalent, we have a match.
@@ -51,9 +29,38 @@ static bool matchesExistingDecl(clang::Decl *decl, clang::Decl *existingDecl) {
51
29
return false ;
52
30
}
53
31
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
+
54
58
void SwiftLookupTable::addEntry (DeclName name, clang::NamedDecl *decl,
55
59
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;
57
64
58
65
// First, check whether there is already a full name entry.
59
66
auto knownFull = FullNameTable.find (name);
@@ -86,7 +93,7 @@ void SwiftLookupTable::addEntry(DeclName name, clang::NamedDecl *decl,
86
93
87
94
// This is a new context for this name. Add it.
88
95
FullTableEntry newEntry;
89
- newEntry.Context = context;
96
+ newEntry.Context = context;;
90
97
newEntry.Decls .push_back (decl);
91
98
fullEntries.push_back (newEntry);
92
99
}
@@ -181,13 +188,15 @@ void SwiftLookupTable::dump() const {
181
188
llvm::errs () << " " << fullName << " :\n " ;
182
189
const auto &fullEntries = FullNameTable.find (fullName)->second ;
183
190
for (const auto &fullEntry : fullEntries) {
184
- llvm::errs () << " " ;
185
- if (fullEntry. Context -> isTranslationUnit ()) {
191
+ switch (fullEntry. Context . first ) {
192
+ case ContextKind::TranslationUnit:
186
193
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 ;
191
200
}
192
201
llvm::errs () << " : " ;
193
202
0 commit comments