Skip to content

Commit f8a76d1

Browse files
committed
Clang importer: add macros to the Swift name lookup tables.
Refactor the storage within the name lookup tables to handle declarations and macros together. Start populating the tables with macro information.
1 parent b553f7d commit f8a76d1

File tree

6 files changed

+232
-54
lines changed

6 files changed

+232
-54
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,46 @@ void ClangImporter::Implementation::addEntryToLookupTable(
742742
}
743743
}
744744

745+
void ClangImporter::Implementation::addMacrosToLookupTable(
746+
clang::ASTContext &clangCtx,
747+
clang::Preprocessor &pp,
748+
SwiftLookupTable &table) {
749+
for (const auto &macro : pp.macros(false)) {
750+
// Find the local history of this macro directive.
751+
clang::MacroDirective *MD = pp.getLocalMacroDirectiveHistory(macro.first);
752+
if (!MD) continue;
753+
754+
// Import the name.
755+
auto name = importIdentifier(macro.first);
756+
if (name.empty()) continue;
757+
758+
// Walk the history.
759+
for (; MD; MD = MD->getPrevious()) {
760+
// Check whether we have a macro defined in this module.
761+
auto info = pp.getMacroInfo(macro.first);
762+
if (!info || info->isFromASTFile() || info->isBuiltinMacro()) continue;
763+
764+
// Only interested in macro definitions.
765+
auto *defMD = dyn_cast<clang::DefMacroDirective>(MD);
766+
if (!defMD) continue;
767+
768+
// If we hit a builtin macro, we're done.
769+
if (auto info = defMD->getInfo()) {
770+
if (info->isBuiltinMacro()) break;
771+
}
772+
773+
// If we hit a macro with invalid or predefined location, we're done.
774+
auto loc = defMD->getLocation();
775+
if (loc.isInvalid()) break;
776+
if (pp.getSourceManager().getFileID(loc) == pp.getPredefinesFileID())
777+
break;
778+
779+
// Add this entry.
780+
table.addEntry(name, info, clangCtx.getTranslationUnitDecl());
781+
}
782+
}
783+
}
784+
745785
bool ClangImporter::Implementation::importHeader(
746786
Module *adapter, StringRef headerName, SourceLoc diagLoc,
747787
bool trackParsedSymbols,
@@ -793,6 +833,11 @@ bool ClangImporter::Implementation::importHeader(
793833
pp.EndSourceFile();
794834
bumpGeneration();
795835

836+
if (UseSwiftLookupTables) {
837+
addMacrosToLookupTable(getClangASTContext(), getClangPreprocessor(),
838+
BridgingHeaderLookupTable);
839+
}
840+
796841
// Wrap all Clang imports under a Swift import decl.
797842
for (auto &Import : BridgeHeaderTopLevelImports) {
798843
if (auto *ClangImport = Import.dyn_cast<clang::ImportDecl*>()) {
@@ -4353,6 +4398,9 @@ ClangImporter::Implementation::createExtensionWriter(clang::ASTWriter &writer) {
43534398
// Add this entry to the lookup tabke.
43544399
addEntryToLookupTable(sema, table, named);
43554400
}
4401+
4402+
// Add macros to the lookup table.
4403+
addMacrosToLookupTable(sema.Context, sema.getPreprocessor(), table);
43564404
};
43574405

43584406
return std::unique_ptr<clang::ModuleFileExtensionWriter>(

lib/ClangImporter/ImporterImpl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,11 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
655655
void addEntryToLookupTable(clang::Sema &clangSema, SwiftLookupTable &table,
656656
clang::NamedDecl *named);
657657

658+
/// Add the macros from the given Clang preprocessor to the given
659+
/// Swift name lookup table.
660+
void addMacrosToLookupTable(clang::ASTContext &clangCtx,
661+
clang::Preprocessor &pp, SwiftLookupTable &table);
662+
658663
public:
659664
void registerExternalDecl(Decl *D) {
660665
RegisteredExternalDecls.push_back(D);

lib/ClangImporter/SwiftLookupTable.cpp

Lines changed: 91 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ SwiftLookupTable::translateContext(clang::DeclContext *context) {
8080
return None;
8181
}
8282

83-
void SwiftLookupTable::addEntry(DeclName name, clang::NamedDecl *decl,
83+
void SwiftLookupTable::addEntry(DeclName name, SingleEntry newEntry,
8484
clang::DeclContext *effectiveContext) {
8585
assert(!Reader && "Cannot modify a lookup table stored on disk");
8686

@@ -91,32 +91,42 @@ void SwiftLookupTable::addEntry(DeclName name, clang::NamedDecl *decl,
9191

9292
// Find the list of entries for this base name.
9393
auto &entries = LookupTable[name.getBaseName().str()];
94+
auto decl = newEntry.dyn_cast<clang::NamedDecl *>();
95+
auto macro = newEntry.dyn_cast<clang::MacroInfo *>();
9496
for (auto &entry : entries) {
9597
if (entry.Context == context) {
9698
// We have entries for this context.
9799

98100
// Check whether this entry matches any existing entry.
99-
for (auto &existingEntry : entry.Decls) {
100-
if (matchesExistingDecl(decl, mapStoredDecl(existingEntry))) return;
101+
for (auto &existingEntry : entry.DeclsOrMacros) {
102+
if (decl && isDeclEntry(existingEntry) &&
103+
matchesExistingDecl(decl, mapStoredDecl(existingEntry)))
104+
return;
101105
}
102106

103107
// Add an entry to this context.
104-
entry.Decls.push_back(reinterpret_cast<uintptr_t>(decl));
108+
if (decl)
109+
entry.DeclsOrMacros.push_back(encodeEntry(decl));
110+
else
111+
entry.DeclsOrMacros.push_back(encodeEntry(macro));
105112
return;
106113
}
107114
}
108115

109116
// This is a new context for this name. Add it.
110-
FullTableEntry newEntry;
111-
newEntry.Context = context;;
112-
newEntry.Decls.push_back(reinterpret_cast<uintptr_t>(decl));
113-
entries.push_back(newEntry);
117+
FullTableEntry entry;
118+
entry.Context = context;
119+
if (decl)
120+
entry.DeclsOrMacros.push_back(encodeEntry(decl));
121+
else
122+
entry.DeclsOrMacros.push_back(encodeEntry(macro));
123+
entries.push_back(entry);
114124
}
115125

116-
SmallVector<clang::NamedDecl *, 4>
126+
SmallVector<SwiftLookupTable::SingleEntry, 4>
117127
SwiftLookupTable::lookup(StringRef baseName,
118128
clang::DeclContext *searchContext) {
119-
SmallVector<clang::NamedDecl *, 4> result;
129+
SmallVector<SwiftLookupTable::SingleEntry, 4> result;
120130

121131
if (baseName.empty()) return result;
122132

@@ -147,8 +157,11 @@ SwiftLookupTable::lookup(StringRef baseName,
147157
if (context && *context != entry.Context) continue;
148158

149159
// Map each of the declarations.
150-
for (auto &storedDecl : entry.Decls) {
151-
result.push_back(mapStoredDecl(storedDecl));
160+
for (auto &stored : entry.DeclsOrMacros) {
161+
if (isDeclEntry(stored))
162+
result.push_back(mapStoredDecl(stored));
163+
else
164+
result.push_back(mapStoredMacro(stored));
152165
}
153166
}
154167

@@ -239,13 +252,17 @@ void SwiftLookupTable::dump() const {
239252
}
240253
llvm::errs() << ": ";
241254

242-
interleave(entry.Decls.begin(), entry.Decls.end(),
243-
[](uint64_t entry) {
244-
if ((entry & 0x01) == 0) {
245-
auto decl = reinterpret_cast<clang::NamedDecl *>(entry);
246-
printName(decl, llvm::errs());
255+
interleave(entry.DeclsOrMacros.begin(), entry.DeclsOrMacros.end(),
256+
[this](uintptr_t entry) {
257+
if (isSerializationIDEntry(entry)) {
258+
llvm::errs() << (isMacroEntry(entry) ? "macro" : "decl")
259+
<< " ID #" << getSerializationID(entry);
260+
} else if (isMacroEntry(entry)) {
261+
llvm::errs() << "Macro";
247262
} else {
248-
llvm::errs() << "ID #" << (entry >> 1);
263+
auto decl = const_cast<SwiftLookupTable *>(this)
264+
->mapStoredDecl(entry);
265+
printName(decl, llvm::errs());
249266
}
250267
},
251268
[] {
@@ -323,7 +340,8 @@ namespace {
323340
dataLength += sizeof(uint16_t);
324341

325342
// Actual entries.
326-
dataLength += sizeof(clang::serialization::DeclID) * entry.Decls.size();
343+
dataLength += (sizeof(clang::serialization::DeclID) *
344+
entry.DeclsOrMacros.size());
327345
}
328346

329347
endian::Writer<little> writer(out);
@@ -343,21 +361,28 @@ namespace {
343361
// # of entries
344362
writer.write<uint16_t>(data.size());
345363

346-
for (auto &entry : data) {
364+
for (auto &fullEntry : data) {
347365
// Context.
348-
writer.write<uint8_t>(static_cast<uint8_t>(entry.Context.first));
349-
if (SwiftLookupTable::contextRequiresName(entry.Context.first)) {
350-
writer.write<uint16_t>(entry.Context.second.size());
351-
out << entry.Context.second;
366+
writer.write<uint8_t>(static_cast<uint8_t>(fullEntry.Context.first));
367+
if (SwiftLookupTable::contextRequiresName(fullEntry.Context.first)) {
368+
writer.write<uint16_t>(fullEntry.Context.second.size());
369+
out << fullEntry.Context.second;
352370
}
353371

354372
// # of entries.
355-
writer.write<uint16_t>(entry.Decls.size());
356-
357-
// Write the declarations.
358-
for (auto &declEntry : entry.Decls) {
359-
auto decl = Table.mapStoredDecl(declEntry);
360-
writer.write<clang::serialization::DeclID>(Writer.getDeclID(decl));
373+
writer.write<uint16_t>(fullEntry.DeclsOrMacros.size());
374+
375+
// Write the declarations and macros.
376+
for (auto &entry : fullEntry.DeclsOrMacros) {
377+
uint32_t id;
378+
if (SwiftLookupTable::isDeclEntry(entry)) {
379+
auto decl = Table.mapStoredDecl(entry);
380+
id = (Writer.getDeclID(decl) << 2) | 0x02;
381+
} else {
382+
auto macro = Table.mapStoredMacro(entry);
383+
id = (Writer.getMacroID(macro) << 2) | 0x02 | 0x01;
384+
}
385+
writer.write<uint32_t>(id);
361386
}
362387
}
363388
}
@@ -460,12 +485,12 @@ namespace {
460485
data += length;
461486
}
462487

463-
// Read the declarations.
464-
unsigned numDecls = endian::readNext<uint16_t, little, unaligned>(data);
465-
while (numDecls--) {
466-
auto declID = endian::readNext<clang::serialization::DeclID, little,
467-
unaligned>(data);
468-
entry.Decls.push_back((declID << 1) | 0x01);
488+
// Read the declarations and macros.
489+
unsigned numDeclsOrMacros =
490+
endian::readNext<uint16_t, little, unaligned>(data);
491+
while (numDeclsOrMacros--) {
492+
auto id = endian::readNext<uint32_t, little, unaligned>(data);
493+
entry.DeclsOrMacros.push_back(id);
469494
}
470495

471496
result.push_back(entry);
@@ -482,24 +507,48 @@ namespace swift {
482507
llvm::OnDiskIterableChainedHashTable<BaseNameToEntitiesTableReaderInfo>;
483508
}
484509

485-
clang::NamedDecl *SwiftLookupTable::mapStoredDecl(uint64_t &entry) {
486-
// If the low bit is unset, we have a pointer. Just cast.
487-
if ((entry & 0x01) == 0) {
488-
return reinterpret_cast<clang::NamedDecl *>(static_cast<uintptr_t>(entry));
510+
clang::NamedDecl *SwiftLookupTable::mapStoredDecl(uintptr_t &entry) {
511+
assert(isDeclEntry(entry) && "Not a declaration entry");
512+
513+
// If we have an AST node here, just cast it.
514+
if (isASTNodeEntry(entry)) {
515+
return static_cast<clang::NamedDecl *>(getPointerFromEntry(entry));
489516
}
490517

491518
// Otherwise, resolve the declaration.
492519
assert(Reader && "Cannot resolve the declaration without a reader");
493-
clang::serialization::DeclID declID = entry >> 1;
520+
clang::serialization::DeclID declID = getSerializationID(entry);
494521
auto decl = cast_or_null<clang::NamedDecl>(
495522
Reader->getASTReader().GetLocalDecl(Reader->getModuleFile(),
496523
declID));
497524

498525
// Update the entry now that we've resolved the declaration.
499-
entry = reinterpret_cast<uintptr_t>(decl);
526+
entry = encodeEntry(decl);
500527
return decl;
501528
}
502529

530+
clang::MacroInfo *SwiftLookupTable::mapStoredMacro(uintptr_t &entry) {
531+
assert(isMacroEntry(entry) && "Not a macro entry");
532+
533+
// If we have an AST node here, just cast it.
534+
if (isASTNodeEntry(entry)) {
535+
return static_cast<clang::MacroInfo *>(getPointerFromEntry(entry));
536+
}
537+
538+
// Otherwise, resolve the macro.
539+
assert(Reader && "Cannot resolve the macro without a reader");
540+
clang::serialization::MacroID macroID = getSerializationID(entry);
541+
auto macro = cast_or_null<clang::MacroInfo>(
542+
Reader->getASTReader().getMacro(
543+
Reader->getASTReader().getGlobalMacroID(
544+
Reader->getModuleFile(),
545+
macroID)));
546+
547+
// Update the entry now that we've resolved the macro.
548+
entry = encodeEntry(macro);
549+
return macro;
550+
}
551+
503552
SwiftLookupTableReader::~SwiftLookupTableReader() {
504553
OnRemove();
505554
delete static_cast<SerializedBaseNameToEntitiesTable *>(SerializedTable);

0 commit comments

Comments
 (0)