Skip to content

Commit 727bccd

Browse files
authored
Merge pull request #65127 from DougGregor/arbitrary-peer-and-freestanding-macros-5.9
2 parents 23a3fbd + d1fe5f4 commit 727bccd

25 files changed

+396
-96
lines changed

docs/ABI/Mangling.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -396,13 +396,13 @@ Entities
396396

397397
macro-discriminator-list ::= macro-discriminator-list? file-discriminator? macro-expansion-operator INDEX
398398

399-
macro-expansion-operator ::= identifier 'fMa' // attached accessor macro
400-
macro-expansion-operator ::= identifier 'fMA' // attached member-attribute macro
399+
macro-expansion-operator ::= decl-name identifier 'fMa' // attached accessor macro
400+
macro-expansion-operator ::= decl-name identifier 'fMA' // attached member-attribute macro
401401
macro-expansion-operator ::= identifier 'fMf' // freestanding macro
402-
macro-expansion-operator ::= identifier 'fMm' // attached member macro
403-
macro-expansion-operator ::= identifier 'fMp' // attached peer macro
404-
macro-expansion-operator ::= identifier 'fMc' // attached conformance macro
405-
macro-expansion-operator ::= identifier 'fMu' // uniquely-named entity
402+
macro-expansion-operator ::= decl-name identifier 'fMm' // attached member macro
403+
macro-expansion-operator ::= decl-name identifier 'fMp' // attached peer macro
404+
macro-expansion-operator ::= decl-name identifier 'fMc' // attached conformance macro
405+
macro-expansion-operator ::= decl-name identifier 'fMu' // uniquely-named entity
406406

407407
file-discriminator ::= identifier 'Ll' // anonymous file-discriminated declaration
408408

include/swift/AST/ASTMangler.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,8 @@ class ASTMangler : public Mangler {
401401
void appendType(Type type, GenericSignature sig,
402402
const ValueDecl *forDecl = nullptr);
403403

404-
void appendDeclName(const ValueDecl *decl);
404+
void appendDeclName(
405+
const ValueDecl *decl, DeclBaseName name = DeclBaseName());
405406

406407
GenericTypeParamType *appendAssocType(DependentMemberType *DepTy,
407408
GenericSignature sig,

include/swift/AST/Decl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3835,6 +3835,8 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
38353835
/// Whether to include @_implements members.
38363836
/// Used by conformance-checking to find special @_implements members.
38373837
IncludeAttrImplements = 1 << 0,
3838+
/// Whether to exclude members of macro expansions.
3839+
ExcludeMacroExpansions = 1 << 1,
38383840
};
38393841

38403842
/// Find all of the declarations with the given name within this nominal type

include/swift/AST/Evaluator.h

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,18 @@ class Evaluator {
208208
/// is treated as a stack and is used to detect cycles.
209209
llvm::SetVector<ActiveRequest> activeRequests;
210210

211+
/// How many `ResolveMacroRequest` requests are active.
212+
///
213+
/// This allows us to quickly determine whether there is any
214+
/// `ResolveMacroRequest` active in the active request stack.
215+
/// It saves us from a linear scan through `activeRequests` when
216+
/// we need to determine this information.
217+
///
218+
/// Why on earth would we need to determine this information?
219+
/// Please see the extended comment that goes with the constructor
220+
/// of `UnqualifiedLookupRequest`.
221+
unsigned numActiveResolveMacroRequests = 0;
222+
211223
/// A cache that stores the results of requests.
212224
evaluator::RequestCache cache;
213225

@@ -324,6 +336,16 @@ class Evaluator {
324336
return activeRequests.count(ActiveRequest(request));
325337
}
326338

339+
/// Determine whether there is any active "resolve macro" request
340+
/// on the request stack.
341+
///
342+
/// Why on earth would we need to determine this information?
343+
/// Please see the extended comment that goes with the constructor
344+
/// of `UnqualifiedLookupRequest`.
345+
bool hasActiveResolveMacroRequest() const {
346+
return numActiveResolveMacroRequests > 0;
347+
}
348+
327349
private:
328350
/// Diagnose a cycle detected in the evaluation of the given
329351
/// request.
@@ -337,6 +359,10 @@ class Evaluator {
337359
/// request to the \c activeRequests stack.
338360
bool checkDependency(const ActiveRequest &request);
339361

362+
/// Note that we have finished this request, popping it from the
363+
/// \c activeRequests stack.
364+
void finishedRequest(const ActiveRequest &request);
365+
340366
/// Produce the result of the request without caching.
341367
template<typename Request>
342368
llvm::Expected<typename Request::OutputType>
@@ -366,8 +392,7 @@ class Evaluator {
366392

367393
// Make sure we remove this from the set of active requests once we're
368394
// done.
369-
assert(activeRequests.back() == activeReq);
370-
activeRequests.pop_back();
395+
finishedRequest(activeReq);
371396

372397
return std::move(result);
373398
}

include/swift/AST/NameLookupRequests.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ class UnqualifiedLookupRequest
430430
RequestFlags::Uncached |
431431
RequestFlags::DependencySink> {
432432
public:
433-
using SimpleRequest::SimpleRequest;
433+
UnqualifiedLookupRequest(UnqualifiedLookupDescriptor);
434434

435435
private:
436436
friend SimpleRequest;
@@ -456,7 +456,10 @@ class LookupInModuleRequest
456456
NLOptions),
457457
RequestFlags::Uncached | RequestFlags::DependencySink> {
458458
public:
459-
using SimpleRequest::SimpleRequest;
459+
LookupInModuleRequest(
460+
const DeclContext *, DeclName, NLKind,
461+
namelookup::ResolutionKind, const DeclContext *,
462+
NLOptions);
460463

461464
private:
462465
friend SimpleRequest;
@@ -504,7 +507,9 @@ class ModuleQualifiedLookupRequest
504507
RequestFlags::Uncached |
505508
RequestFlags::DependencySink> {
506509
public:
507-
using SimpleRequest::SimpleRequest;
510+
ModuleQualifiedLookupRequest(const DeclContext *,
511+
ModuleDecl *, DeclNameRef,
512+
NLOptions);
508513

509514
private:
510515
friend SimpleRequest;
@@ -528,7 +533,9 @@ class QualifiedLookupRequest
528533
DeclNameRef, NLOptions),
529534
RequestFlags::Uncached> {
530535
public:
531-
using SimpleRequest::SimpleRequest;
536+
QualifiedLookupRequest(const DeclContext *,
537+
SmallVector<NominalTypeDecl *, 4>,
538+
DeclNameRef, NLOptions);
532539

533540
private:
534541
friend SimpleRequest;
@@ -579,7 +586,7 @@ class DirectLookupRequest
579586
TinyPtrVector<ValueDecl *>(DirectLookupDescriptor),
580587
RequestFlags::Uncached|RequestFlags::DependencySink> {
581588
public:
582-
using SimpleRequest::SimpleRequest;
589+
DirectLookupRequest(DirectLookupDescriptor);
583590

584591
private:
585592
friend SimpleRequest;

lib/AST/ASTMangler.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,8 +1006,9 @@ static Optional<std::string> getOverriddenSwiftProtocolObjCName(
10061006
return None;
10071007
}
10081008

1009-
void ASTMangler::appendDeclName(const ValueDecl *decl) {
1010-
DeclBaseName name = decl->getBaseName();
1009+
void ASTMangler::appendDeclName(const ValueDecl *decl, DeclBaseName name) {
1010+
if (name.empty())
1011+
name = decl->getBaseName();
10111012
assert(!name.isSpecial() && "Cannot print special names");
10121013

10131014
auto *synthesizedTypeAttr =
@@ -4022,28 +4023,43 @@ std::string ASTMangler::mangleAttachedMacroExpansion(
40224023
const Decl *decl, CustomAttr *attr, MacroRole role) {
40234024
beginMangling();
40244025

4026+
// Append the context and name of the declaration.
4027+
// We don't mangle the declaration itself because doing so requires semantic
4028+
// information (e.g., its interface type), which introduces cyclic
4029+
// dependencies.
40254030
const Decl *attachedTo = decl;
4031+
DeclBaseName attachedToName;
40264032
if (auto valueDecl = dyn_cast<ValueDecl>(decl)) {
4027-
if (role != MacroRole::MemberAttribute) {
4028-
appendAnyDecl(valueDecl);
4029-
} else {
4030-
// Appending the member would result in a cycle since `VarDecl` appends
4031-
// its type, which would then loop back around to getting the attributes
4032-
// again. We'll instead add a discriminator for each member.
4033-
appendContextOf(valueDecl);
4033+
appendContextOf(valueDecl);
4034+
4035+
// Mangle the name, replacing special names with their user-facing names.
4036+
attachedToName = valueDecl->getName().getBaseName();
4037+
if (attachedToName.isSpecial()) {
4038+
attachedToName =
4039+
decl->getASTContext().getIdentifier(attachedToName.userFacingName());
4040+
}
4041+
appendDeclName(valueDecl, attachedToName);
4042+
4043+
// For member attribute macros, the attribute is attached to the enclosing
4044+
// declaration.
4045+
if (role == MacroRole::MemberAttribute) {
40344046
attachedTo = decl->getDeclContext()->getAsDecl();
40354047
}
40364048
} else {
40374049
appendContext(decl->getDeclContext(), "");
4050+
appendIdentifier("_");
40384051
}
40394052

4053+
// Determine the name of the macro.
40404054
DeclBaseName macroName;
40414055
if (auto *macroDecl = attachedTo->getResolvedMacro(attr)) {
40424056
macroName = macroDecl->getName().getBaseName();
40434057
} else {
40444058
macroName = decl->getASTContext().getIdentifier("__unknown_macro__");
40454059
}
40464060

4061+
// FIXME: attached macro discriminators should take attachedToName into
4062+
// account.
40474063
appendMacroExpansionOperator(
40484064
macroName.userFacingName(), role,
40494065
decl->getAttachedMacroDiscriminator(macroName, role, attr));

lib/AST/Evaluator.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/Evaluator.h"
1818
#include "swift/AST/DeclContext.h"
1919
#include "swift/AST/DiagnosticEngine.h"
20+
#include "swift/AST/TypeCheckRequests.h" // for ResolveMacroRequest
2021
#include "swift/Basic/LangOptions.h"
2122
#include "swift/Basic/Range.h"
2223
#include "swift/Basic/SourceManager.h"
@@ -61,14 +62,25 @@ Evaluator::Evaluator(DiagnosticEngine &diags, const LangOptions &opts)
6162

6263
bool Evaluator::checkDependency(const ActiveRequest &request) {
6364
// Record this as an active request.
64-
if (activeRequests.insert(request))
65+
if (activeRequests.insert(request)) {
66+
if (request.getAs<ResolveMacroRequest>())
67+
++numActiveResolveMacroRequests;
6568
return false;
69+
}
6670

6771
// Diagnose cycle.
6872
diagnoseCycle(request);
6973
return true;
7074
}
7175

76+
void Evaluator::finishedRequest(const ActiveRequest &request) {
77+
if (request.getAs<ResolveMacroRequest>())
78+
--numActiveResolveMacroRequests;
79+
80+
assert(activeRequests.back() == request);
81+
activeRequests.pop_back();
82+
}
83+
7284
void Evaluator::diagnoseCycle(const ActiveRequest &request) {
7385
if (debugDumpCycles) {
7486
const auto printIndent = [](llvm::raw_ostream &OS, unsigned indent) {

lib/AST/Module.cpp

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ class swift::SourceLookupCache {
174174

175175
using AuxiliaryDeclMap = llvm::DenseMap<DeclName, TinyPtrVector<MissingDecl *>>;
176176
AuxiliaryDeclMap TopLevelAuxiliaryDecls;
177+
178+
/// Top-level macros that produce arbitrary names.
179+
SmallVector<MissingDecl *, 4> TopLevelArbitraryMacros;
180+
177181
SmallVector<Decl *, 4> MayHaveAuxiliaryDecls;
178182
void populateAuxiliaryDeclCache();
179183

@@ -352,26 +356,46 @@ void SourceLookupCache::populateAuxiliaryDeclCache() {
352356
for (auto attrConst : decl->getAttrs().getAttributes<CustomAttr>()) {
353357
auto *attr = const_cast<CustomAttr *>(attrConst);
354358
UnresolvedMacroReference macroRef(attr);
359+
bool introducesArbitraryNames = false;
355360
namelookup::forEachPotentialResolvedMacro(
356361
decl->getDeclContext()->getModuleScopeContext(),
357362
macroRef.getMacroName(), MacroRole::Peer,
358363
[&](MacroDecl *macro, const MacroRoleAttr *roleAttr) {
364+
// First check for arbitrary names.
365+
if (roleAttr->hasNameKind(MacroIntroducedDeclNameKind::Arbitrary)) {
366+
introducesArbitraryNames = true;
367+
}
368+
359369
macro->getIntroducedNames(MacroRole::Peer,
360370
dyn_cast<ValueDecl>(decl),
361371
introducedNames[attr]);
362372
});
373+
374+
// Record this macro where appropriate.
375+
if (introducesArbitraryNames)
376+
TopLevelArbitraryMacros.push_back(MissingDecl::forUnexpandedMacro(attr, decl));
363377
}
364378

365379
if (auto *med = dyn_cast<MacroExpansionDecl>(decl)) {
366380
UnresolvedMacroReference macroRef(med);
381+
bool introducesArbitraryNames = false;
367382
namelookup::forEachPotentialResolvedMacro(
368383
decl->getDeclContext()->getModuleScopeContext(),
369384
macroRef.getMacroName(), MacroRole::Declaration,
370385
[&](MacroDecl *macro, const MacroRoleAttr *roleAttr) {
386+
// First check for arbitrary names.
387+
if (roleAttr->hasNameKind(MacroIntroducedDeclNameKind::Arbitrary)) {
388+
introducesArbitraryNames = true;
389+
}
390+
371391
macro->getIntroducedNames(MacroRole::Declaration,
372392
/*attachedTo*/ nullptr,
373393
introducedNames[med]);
374394
});
395+
396+
// Record this macro where appropriate.
397+
if (introducesArbitraryNames)
398+
TopLevelArbitraryMacros.push_back(MissingDecl::forUnexpandedMacro(med, decl));
375399
}
376400

377401
// Add macro-introduced names to the top-level auxiliary decl cache as
@@ -440,14 +464,31 @@ void SourceLookupCache::lookupValue(DeclName Name, NLKind LookupKind,
440464
? UniqueMacroNamePlaceholder
441465
: Name;
442466
auto auxDecls = TopLevelAuxiliaryDecls.find(keyName);
443-
if (auxDecls == TopLevelAuxiliaryDecls.end())
467+
468+
// Check macro expansions that could produce this name.
469+
SmallVector<MissingDecl *, 4> unexpandedDecls;
470+
if (auxDecls != TopLevelAuxiliaryDecls.end()) {
471+
unexpandedDecls.insert(
472+
unexpandedDecls.end(), auxDecls->second.begin(), auxDecls->second.end());
473+
}
474+
475+
// Check macro expansions that can produce arbitrary names.
476+
unexpandedDecls.insert(
477+
unexpandedDecls.end(),
478+
TopLevelArbitraryMacros.begin(), TopLevelArbitraryMacros.end());
479+
480+
if (unexpandedDecls.empty())
444481
return;
445482

446-
for (auto *unexpandedDecl : auxDecls->second) {
447-
// Add expanded peers to the result.
483+
// Add matching expanded peers and freestanding declarations to the results.
484+
SmallPtrSet<ValueDecl *, 4> macroExpandedDecls;
485+
for (auto *unexpandedDecl : unexpandedDecls) {
448486
unexpandedDecl->forEachMacroExpandedDecl(
449487
[&](ValueDecl *decl) {
450-
Result.push_back(decl);
488+
if (decl->getName().matchesRef(Name)) {
489+
if (macroExpandedDecls.insert(decl).second)
490+
Result.push_back(decl);
491+
}
451492
});
452493
}
453494
}

0 commit comments

Comments
 (0)