Skip to content

Commit 283c5cd

Browse files
committed
[Macros] Freestanding macro expansions in code blocks
Parse freestanding macro expansions as declarations rather than expressions when it's not part of a statement or expression (i.e. "top-level"). Teach name lookup to look into the result of macro expansions.
1 parent c707643 commit 283c5cd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+767
-380
lines changed

include/swift/AST/ASTScope.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,10 +278,12 @@ class ASTScopeImpl : public ASTAllocated<ASTScopeImpl> {
278278
static const ASTScopeImpl *findStartingScopeForLookup(SourceFile *,
279279
const SourceLoc where);
280280

281-
protected:
281+
public:
282282
/// Not const because may reexpand some scopes.
283283
ASTScopeImpl *findInnermostEnclosingScope(SourceLoc,
284284
NullablePtr<raw_ostream>);
285+
286+
protected:
285287
ASTScopeImpl *findInnermostEnclosingScopeImpl(SourceLoc,
286288
NullablePtr<raw_ostream>,
287289
SourceManager &,
@@ -1216,6 +1218,29 @@ class MacroDeclScope final : public ASTScopeImpl {
12161218
NullablePtr<const GenericParamList> genericParams() const override;
12171219
};
12181220

1221+
class MacroExpansionDeclScope final : public ASTScopeImpl {
1222+
public:
1223+
MacroExpansionDecl *const decl;
1224+
1225+
MacroExpansionDeclScope(MacroExpansionDecl *d) : decl(d) {}
1226+
virtual ~MacroExpansionDeclScope() {}
1227+
1228+
protected:
1229+
ASTScopeImpl *expandSpecifically(ScopeCreator &scopeCreator) override;
1230+
1231+
private:
1232+
void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);
1233+
1234+
public:
1235+
std::string getClassName() const override;
1236+
SourceRange
1237+
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
1238+
1239+
public:
1240+
virtual NullablePtr<Decl> getDeclIfAny() const override { return decl; }
1241+
Decl *getDecl() const { return decl; }
1242+
};
1243+
12191244
class AbstractStmtScope : public ASTScopeImpl {
12201245
public:
12211246
SourceRange

include/swift/AST/Decl.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ namespace swift {
110110
class VarDecl;
111111
class OpaqueReturnTypeRepr;
112112
class Witness;
113+
class MacroExpansionExpr;
113114

114115
namespace ast_scope {
115116
class AbstractPatternEntryScope;
@@ -8446,7 +8447,8 @@ class MacroExpansionDecl : public Decl {
84468447
SourceLoc LeftAngleLoc, RightAngleLoc;
84478448
ArrayRef<TypeRepr *> GenericArgs;
84488449
ArgumentList *ArgList;
8449-
ArrayRef<Decl *> Rewritten;
8450+
// An implicit brace statement serving as the container for the expansion.
8451+
BraceStmt *Rewritten = nullptr;
84508452

84518453
/// The referenced macro.
84528454
ConcreteDeclRef macroRef;
@@ -8461,7 +8463,7 @@ class MacroExpansionDecl : public Decl {
84618463
: Decl(DeclKind::MacroExpansion, dc), PoundLoc(poundLoc),
84628464
Macro(macro), MacroLoc(macroLoc),
84638465
LeftAngleLoc(leftAngleLoc), RightAngleLoc(rightAngleLoc),
8464-
GenericArgs(genericArgs), ArgList(args), Rewritten({}) {}
8466+
GenericArgs(genericArgs), ArgList(args) {}
84658467

84668468
ArrayRef<TypeRepr *> getGenericArgs() const { return GenericArgs; }
84678469

@@ -8475,10 +8477,12 @@ class MacroExpansionDecl : public Decl {
84758477
DeclNameLoc getMacroLoc() const { return MacroLoc; }
84768478
DeclNameRef getMacro() const { return Macro; }
84778479
ArgumentList *getArgs() const { return ArgList; }
8478-
ArrayRef<Decl *> getRewritten() const { return Rewritten; }
8479-
void setRewritten(ArrayRef<Decl *> rewritten) { Rewritten = rewritten; }
8480+
void setArgs(ArgumentList *args) { ArgList = args; }
8481+
BraceStmt *getRewritten() const { return Rewritten; }
8482+
void setRewritten(BraceStmt *rewritten) { Rewritten = rewritten; }
84808483
ConcreteDeclRef getMacroRef() const { return macroRef; }
84818484
void setMacroRef(ConcreteDeclRef ref) { macroRef = ref; }
8485+
MacroExpansionExpr *createExpr() const;
84828486

84838487
static bool classof(const Decl *D) {
84848488
return D->getKind() == DeclKind::MacroExpansion;

include/swift/AST/FileUnit.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,15 @@ class FileUnit : public DeclContext, public ASTAllocated<FileUnit> {
6464
/// within this file.
6565
///
6666
/// This does a simple local lookup, not recursively looking through imports.
67-
virtual void lookupValue(DeclName name, NLKind lookupKind,
67+
virtual void lookupValue(DeclName name, NLKind lookupKind, NLOptions options,
6868
SmallVectorImpl<ValueDecl*> &result) const = 0;
6969

70+
void lookupValue(DeclName name, NLKind lookupKind,
71+
SmallVectorImpl<ValueDecl*> &result) const {
72+
lookupValue(name, lookupKind, getDefaultNLOptions(lookupKind), result);
73+
}
74+
75+
7076
/// Look up a local type declaration by its mangled name.
7177
///
7278
/// This does a simple local lookup, not recursively looking through imports.
@@ -366,7 +372,7 @@ class BuiltinUnit final : public FileUnit {
366372
public:
367373
explicit BuiltinUnit(ModuleDecl &M);
368374

369-
virtual void lookupValue(DeclName name, NLKind lookupKind,
375+
virtual void lookupValue(DeclName name, NLKind lookupKind, NLOptions options,
370376
SmallVectorImpl<ValueDecl*> &result) const override;
371377

372378
/// Find all Objective-C methods with the given selector.

include/swift/AST/LookupKinds.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ enum NLOptions : unsigned {
5353
// Include @usableFromInline and @inlinable
5454
NL_IncludeUsableFromInline = 1 << 6,
5555

56+
/// Don't expand macros.
57+
NL_DisableMacroExpansions = 1 << 7,
58+
5659
/// The default set of options used for qualified name lookup.
5760
///
5861
/// FIXME: Eventually, add NL_ProtocolMembers to this, once all of the
@@ -79,6 +82,13 @@ static inline NLOptions operator~(NLOptions value) {
7982
return NLOptions(~(unsigned)value);
8083
}
8184

85+
static inline NLOptions getDefaultNLOptions(NLKind kind) {
86+
switch (kind) {
87+
case NLKind::QualifiedLookup: return NL_QualifiedDefault;
88+
case NLKind::UnqualifiedLookup: return NL_UnqualifiedDefault;
89+
}
90+
}
91+
8292
void simple_display(llvm::raw_ostream &out, NLOptions options);
8393

8494
} // end namespace swift

include/swift/AST/Module.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,9 +637,19 @@ class ModuleDecl
637637
/// within the current module.
638638
///
639639
/// This does a simple local lookup, not recursively looking through imports.
640-
void lookupValue(DeclName Name, NLKind LookupKind,
640+
void lookupValue(DeclName Name, NLKind LookupKind, NLOptions Options,
641641
SmallVectorImpl<ValueDecl*> &Result) const;
642642

643+
/// Look up a (possibly overloaded) value set at top-level scope
644+
/// (but with the specified access path, which may come from an import decl)
645+
/// within the current module.
646+
///
647+
/// This does a simple local lookup, not recursively looking through imports.
648+
void lookupValue(DeclName Name, NLKind LookupKind,
649+
SmallVectorImpl<ValueDecl*> &Result) const {
650+
lookupValue(Name, LookupKind, getDefaultNLOptions(LookupKind), Result);
651+
}
652+
643653
/// Look up a local type declaration by its mangled name.
644654
///
645655
/// This does a simple local lookup, not recursively looking through imports.

include/swift/AST/NameLookup.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ enum class UnqualifiedLookupFlags {
239239
// This lookup should include results that are @inlinable or
240240
// @usableFromInline.
241241
IncludeUsableFromInline = 1 << 5,
242+
// This lookup should not expand macros.
243+
DisableMacroExpansions = 1 << 6,
244+
// This lookup should only return macros.
245+
MacroLookup = 1 << 7,
242246
};
243247

244248
using UnqualifiedLookupOptions = OptionSet<UnqualifiedLookupFlags>;
@@ -794,6 +798,11 @@ class ASTScope : public ASTAllocated<ASTScope> {
794798
static std::pair<CaseStmt *, CaseStmt *>
795799
lookupFallthroughSourceAndDest(SourceFile *sourceFile, SourceLoc loc);
796800

801+
/// Returns true if the given location is within a \c MacroDecl or a top-level
802+
/// \c MacroExpansionDecl.
803+
static bool isLocWithinMacroDeclOrTopLevelMacroExpansionDeclScope(
804+
SourceFile *sf, SourceLoc loc);
805+
797806
SWIFT_DEBUG_DUMP;
798807
void print(llvm::raw_ostream &) const;
799808
void dumpOneScopeMapLocation(std::pair<unsigned, unsigned>);

include/swift/AST/SourceFile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ class SourceFile final : public FileUnit {
427427
void cacheVisibleDecls(SmallVectorImpl<ValueDecl *> &&globals) const;
428428
const SmallVectorImpl<ValueDecl *> &getCachedVisibleDecls() const;
429429

430-
virtual void lookupValue(DeclName name, NLKind lookupKind,
430+
virtual void lookupValue(DeclName name, NLKind lookupKind, NLOptions options,
431431
SmallVectorImpl<ValueDecl*> &result) const override;
432432

433433
virtual void lookupVisibleDecls(ImportPath::Access accessPath,

include/swift/AST/SynthesizedFileUnit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class SynthesizedFileUnit final : public FileUnit {
4343
/// Add a synthesized top-level declaration.
4444
void addTopLevelDecl(Decl *D) { TopLevelDecls.push_back(D); }
4545

46-
virtual void lookupValue(DeclName name, NLKind lookupKind,
46+
virtual void lookupValue(DeclName name, NLKind lookupKind, NLOptions options,
4747
SmallVectorImpl<ValueDecl *> &result) const override;
4848

4949
void lookupObjCMethods(

include/swift/AST/TypeCheckRequests.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3823,16 +3823,15 @@ class MacroDefinitionRequest
38233823
/// Find the definition of a given macro.
38243824
class ExpandMacroExpansionDeclRequest
38253825
: public SimpleRequest<ExpandMacroExpansionDeclRequest,
3826-
ArrayRef<Decl *>(MacroExpansionDecl *),
3826+
BraceStmt *(MacroExpansionDecl *),
38273827
RequestFlags::Cached> {
38283828
public:
38293829
using SimpleRequest::SimpleRequest;
38303830

38313831
private:
38323832
friend SimpleRequest;
38333833

3834-
ArrayRef<Decl *> evaluate(Evaluator &evaluator,
3835-
MacroExpansionDecl *med) const;
3834+
BraceStmt *evaluate(Evaluator &evaluator, MacroExpansionDecl *med) const;
38363835

38373836
public:
38383837
bool isCached() const { return true; }

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ SWIFT_REQUEST(TypeChecker, DefaultArgumentInitContextRequest,
6565
SWIFT_REQUEST(TypeChecker, DefaultDefinitionTypeRequest,
6666
Type(AssociatedTypeDecl *), Cached, NoLocationInfo)
6767
SWIFT_REQUEST(TypeChecker, DefaultTypeRequest,
68-
Type(KnownProtocolKind, const DeclContext *), SeparatelyCached,
69-
NoLocationInfo)
68+
Type(KnownProtocolKind, const DeclContext *),
69+
SeparatelyCached, NoLocationInfo)
7070
SWIFT_REQUEST(TypeChecker, DifferentiableAttributeTypeCheckRequest,
7171
IndexSubset *(DifferentiableAttr *),
7272
SeparatelyCached, NoLocationInfo)
@@ -453,7 +453,7 @@ SWIFT_REQUEST(TypeChecker, ExternalMacroDefinitionRequest,
453453
ExternalMacroDefinition(ASTContext *, Identifier, Identifier),
454454
Cached, NoLocationInfo)
455455
SWIFT_REQUEST(TypeChecker, ExpandMacroExpansionDeclRequest,
456-
ArrayRef<Decl *>(MacroExpansionDecl *),
456+
BraceStmt *(MacroExpansionDecl *),
457457
Cached, NoLocationInfo)
458458
SWIFT_REQUEST(TypeChecker, ExpandMemberAttributeMacros,
459459
bool(Decl *),

include/swift/AST/TypeMemberVisitor.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,10 @@ class TypeMemberVisitor : public DeclVisitor<ImplClass, RetTy> {
8181

8282
/// Visit expanded macros.
8383
void visitMacroExpansionDecl(MacroExpansionDecl *D) {
84-
for (auto *decl : D->getRewritten())
85-
asImpl().visit(decl);
84+
if (auto *rewritten = D->getRewritten())
85+
for (auto node : rewritten->getElements())
86+
if (auto *decl = node.dyn_cast<Decl *>())
87+
asImpl().visit(decl);
8688
}
8789
};
8890

include/swift/ClangImporter/ClangModule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class ClangModuleUnit final : public LoadedFile {
6565

6666
virtual bool isSystemModule() const override;
6767

68-
virtual void lookupValue(DeclName name, NLKind lookupKind,
68+
virtual void lookupValue(DeclName name, NLKind lookupKind, NLOptions options,
6969
SmallVectorImpl<ValueDecl*> &results) const override;
7070

7171
virtual TypeDecl *

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ class SerializedASTFile final : public LoadedFile {
352352

353353
virtual bool isSystemModule() const override;
354354

355-
virtual void lookupValue(DeclName name, NLKind lookupKind,
355+
virtual void lookupValue(DeclName name, NLKind lookupKind, NLOptions options,
356356
SmallVectorImpl<ValueDecl*> &results) const override;
357357

358358
virtual StringRef

lib/AST/ASTContext.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,8 @@ void ASTContext::lookupInModule(
759759

760760
// Find all of the declarations with this name in the Swift module.
761761
auto identifier = getIdentifier(name);
762-
M->lookupValue(identifier, NLKind::UnqualifiedLookup, results);
762+
M->lookupValue(identifier, NLKind::UnqualifiedLookup, NL_UnqualifiedDefault,
763+
results);
763764
}
764765

765766
void ASTContext::lookupInSwiftModule(
@@ -1133,7 +1134,7 @@ ProtocolDecl *ASTContext::getProtocol(KnownProtocolKind kind) const {
11331134
if (!M)
11341135
return nullptr;
11351136
M->lookupValue(getIdentifier(getProtocolName(kind)),
1136-
NLKind::UnqualifiedLookup, results);
1137+
NLKind::UnqualifiedLookup, NL_UnqualifiedDefault, results);
11371138

11381139
for (auto result : results) {
11391140
if (auto protocol = dyn_cast<ProtocolDecl>(result)) {
@@ -5118,7 +5119,8 @@ static NominalTypeDecl *findUnderlyingTypeInModule(ASTContext &ctx,
51185119
ModuleDecl *module) {
51195120
// Find all of the declarations with this name in the Swift module.
51205121
SmallVector<ValueDecl *, 1> results;
5121-
module->lookupValue(name, NLKind::UnqualifiedLookup, results);
5122+
module->lookupValue(name, NLKind::UnqualifiedLookup, NL_UnqualifiedDefault,
5123+
results);
51225124
for (auto result : results) {
51235125
if (auto nominal = dyn_cast<NominalTypeDecl>(result))
51245126
return nominal;

lib/AST/ASTDemangler.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ ASTBuilder::createBuiltinType(StringRef builtinName,
107107
builtinName.drop_front(BUILTIN_TYPE_NAME_PREFIX.size());
108108
Ctx.TheBuiltinModule->lookupValue(Ctx.getIdentifier(strippedName),
109109
NLKind::QualifiedLookup,
110+
NL_QualifiedDefault,
110111
decls);
111112

112113
if (decls.size() == 1 && isa<TypeDecl>(decls[0]))

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,10 +1324,13 @@ namespace {
13241324
OS << MED->getMacro();
13251325
if (MED->getArgs()) {
13261326
OS << '\n';
1327-
OS.indent(Indent + 2);
13281327
printArgumentList(OS, MED->getArgs(), Indent,
13291328
[&](Expr *E) { printRec(E); });
13301329
}
1330+
if (auto *rewritten = MED->getRewritten()) {
1331+
OS << " rewritten=\n";
1332+
printRec(rewritten, MED->getASTContext());
1333+
}
13311334
PrintWithColorRAII(OS, ParenthesisColor) << ')';
13321335
}
13331336
};
@@ -3026,7 +3029,7 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
30263029
printArgumentList(E->getArgs());
30273030
}
30283031
if (auto rewritten = E->getRewritten()) {
3029-
OS << '\n';
3032+
OS << " rewritten=\n";
30303033
printRec(rewritten);
30313034
}
30323035
PrintWithColorRAII(OS, ParenthesisColor) << ')';

lib/AST/ASTScope.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,34 @@ void ASTScope::dumpOneScopeMapLocation(std::pair<unsigned, unsigned> lineCol) {
7676
impl->dumpOneScopeMapLocation(lineCol);
7777
}
7878

79+
bool ASTScope::isLocWithinMacroDeclOrTopLevelMacroExpansionDeclScope(
80+
SourceFile *sf, SourceLoc loc) {
81+
// The innermost scope containing the loc.
82+
auto *innermostScope = sf->getScope().impl->findInnermostEnclosingScope(
83+
loc, nullptr);
84+
auto isMDOrTopLevelMED = [&](const ASTScopeImpl *scope) -> bool {
85+
if (auto *decl = scope->getDeclIfAny().getPtrOrNull()) {
86+
if (auto *med = dyn_cast<MacroExpansionDecl>(decl)) {
87+
if (med->getDeclContext()->getContextKind() ==
88+
DeclContextKind::FileUnit)
89+
return true;
90+
} else if (auto *md = dyn_cast<MacroDecl>(decl)) {
91+
return true;
92+
}
93+
}
94+
return false;
95+
};
96+
// Climb up the tree until we find a matching scope.
97+
const ASTScopeImpl *scope = innermostScope;
98+
while (!isMDOrTopLevelMED(scope)) {
99+
auto *parentScope = scope->getLookupParent().getPtrOrNull();
100+
if (!parentScope || parentScope == scope)
101+
return false;
102+
scope = parentScope;
103+
}
104+
return true;
105+
}
106+
79107
#pragma mark ASTScopeImpl
80108

81109

@@ -151,6 +179,7 @@ DEFINE_GET_CLASS_NAME(DifferentiableAttributeScope)
151179
DEFINE_GET_CLASS_NAME(SubscriptDeclScope)
152180
DEFINE_GET_CLASS_NAME(EnumElementScope)
153181
DEFINE_GET_CLASS_NAME(MacroDeclScope)
182+
DEFINE_GET_CLASS_NAME(MacroExpansionDeclScope)
154183
DEFINE_GET_CLASS_NAME(IfStmtScope)
155184
DEFINE_GET_CLASS_NAME(WhileStmtScope)
156185
DEFINE_GET_CLASS_NAME(GuardStmtScope)

0 commit comments

Comments
 (0)