Skip to content

[Macros] Name lookup and type checking fixes for freestanding declaration macros #64761

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions include/swift/AST/ASTScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,32 @@ class MacroDefinitionScope final : public ASTScopeImpl {
ASTScopeImpl *expandSpecifically(ScopeCreator &scopeCreator) override;
};

class MacroExpansionDeclScope final : public ASTScopeImpl {
public:
MacroExpansionDecl *const decl;

MacroExpansionDeclScope(MacroExpansionDecl *e) : decl(e) {}
virtual ~MacroExpansionDeclScope() {}

protected:
ASTScopeImpl *expandSpecifically(ScopeCreator &scopeCreator) override;

private:
void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);

public:
std::string getClassName() const override;
SourceRange
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;

protected:
void printSpecifics(llvm::raw_ostream &out) const override;

public:
virtual NullablePtr<Decl> getDeclIfAny() const override { return decl; }
Decl *getDecl() const { return decl; }
};

class AbstractStmtScope : public ASTScopeImpl {
public:
SourceRange
Expand Down
49 changes: 37 additions & 12 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -8538,8 +8538,13 @@ class MacroDecl : public GenericContext, public ValueDecl {
using Decl::getASTContext;
};

class MacroExpansionDecl : public Decl {
SourceLoc PoundLoc;
/// Information about a macro expansion that is common between macro
/// expansion declarations and expressions.
///
/// Instances of these types will be shared among paired macro expansion
/// declaration/expression nodes.
struct MacroExpansionInfo : ASTAllocated<MacroExpansionInfo> {
SourceLoc SigilLoc;
DeclNameRef MacroName;
DeclNameLoc MacroNameLoc;
SourceLoc LeftAngleLoc, RightAngleLoc;
Expand All @@ -8549,33 +8554,53 @@ class MacroExpansionDecl : public Decl {
/// The referenced macro.
ConcreteDeclRef macroRef;

MacroExpansionInfo(SourceLoc sigilLoc,
DeclNameRef macroName,
DeclNameLoc macroNameLoc,
SourceLoc leftAngleLoc, SourceLoc rightAngleLoc,
ArrayRef<TypeRepr *> genericArgs,
ArgumentList *argList)
: SigilLoc(sigilLoc), MacroName(macroName), MacroNameLoc(macroNameLoc),
LeftAngleLoc(leftAngleLoc), RightAngleLoc(rightAngleLoc),
GenericArgs(genericArgs), ArgList(argList) { }
};

class MacroExpansionDecl : public Decl {
MacroExpansionInfo *info;

public:
enum : unsigned { InvalidDiscriminator = 0xFFFF };

MacroExpansionDecl(DeclContext *dc, MacroExpansionInfo *info);

MacroExpansionDecl(DeclContext *dc, SourceLoc poundLoc, DeclNameRef macro,
DeclNameLoc macroLoc,
SourceLoc leftAngleLoc,
ArrayRef<TypeRepr *> genericArgs,
SourceLoc rightAngleLoc,
ArgumentList *args);

ArrayRef<TypeRepr *> getGenericArgs() const { return GenericArgs; }
ArrayRef<TypeRepr *> getGenericArgs() const {
return info->GenericArgs;
}

SourceRange getGenericArgsRange() const {
return SourceRange(LeftAngleLoc, RightAngleLoc);
return SourceRange(info->LeftAngleLoc, info->RightAngleLoc);
}

SourceRange getSourceRange() const;
SourceLoc getLocFromSource() const { return PoundLoc; }
SourceLoc getPoundLoc() const { return PoundLoc; }
DeclNameLoc getMacroNameLoc() const { return MacroNameLoc; }
DeclNameRef getMacroName() const { return MacroName; }
ArgumentList *getArgs() const { return ArgList; }
void setArgs(ArgumentList *args) { ArgList = args; }
SourceLoc getLocFromSource() const { return info->SigilLoc; }
SourceLoc getPoundLoc() const { return info->SigilLoc; }
DeclNameLoc getMacroNameLoc() const { return info->MacroNameLoc; }
DeclNameRef getMacroName() const { return info->MacroName; }
ArgumentList *getArgs() const { return info->ArgList; }
void setArgs(ArgumentList *args) { info->ArgList = args; }
using ExprOrStmtExpansionCallback = llvm::function_ref<void(ASTNode)>;
void forEachExpandedExprOrStmt(ExprOrStmtExpansionCallback) const;
ConcreteDeclRef getMacroRef() const { return macroRef; }
void setMacroRef(ConcreteDeclRef ref) { macroRef = ref; }
ConcreteDeclRef getMacroRef() const { return info->macroRef; }
void setMacroRef(ConcreteDeclRef ref) { info->macroRef = ref; }

MacroExpansionInfo *getExpansionInfo() const { return info; }

/// Returns a discriminator which determines this macro expansion's index
/// in the sequence of macro expansions within the current function.
Expand Down
61 changes: 24 additions & 37 deletions include/swift/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -6189,22 +6189,24 @@ class TypeJoinExpr final : public Expr,
class MacroExpansionExpr final : public Expr {
private:
DeclContext *DC;
SourceLoc SigilLoc;
DeclNameRef MacroName;
DeclNameLoc MacroNameLoc;
SourceLoc LeftAngleLoc, RightAngleLoc;
ArrayRef<TypeRepr *> GenericArgs;
ArgumentList *ArgList;
MacroExpansionInfo *info;
Expr *Rewritten;
MacroRoles Roles;
MacroExpansionDecl *SubstituteDecl;

/// The referenced macro.
ConcreteDeclRef macroRef;

public:
enum : unsigned { InvalidDiscriminator = 0xFFFF };

explicit MacroExpansionExpr(DeclContext *dc, MacroExpansionInfo *info,
MacroRoles roles,
bool isImplicit = false,
Type ty = Type())
: Expr(ExprKind::MacroExpansion, isImplicit, ty),
DC(dc), info(info), Rewritten(nullptr), Roles(roles),
SubstituteDecl(nullptr) {
Bits.MacroExpansionExpr.Discriminator = InvalidDiscriminator;
}

explicit MacroExpansionExpr(DeclContext *dc,
SourceLoc sigilLoc, DeclNameRef macroName,
DeclNameLoc macroNameLoc,
Expand All @@ -6214,45 +6216,29 @@ class MacroExpansionExpr final : public Expr {
ArgumentList *argList,
MacroRoles roles,
bool isImplicit = false,
Type ty = Type())
: Expr(ExprKind::MacroExpansion, isImplicit, ty),
DC(dc), SigilLoc(sigilLoc),
MacroName(macroName), MacroNameLoc(macroNameLoc),
LeftAngleLoc(leftAngleLoc), RightAngleLoc(rightAngleLoc),
GenericArgs(genericArgs),
Rewritten(nullptr), Roles(roles), SubstituteDecl(nullptr) {
Bits.MacroExpansionExpr.Discriminator = InvalidDiscriminator;
Type ty = Type());

// Macro expansions always have an argument list. If one is not provided, create
// an implicit one.
if (argList) {
ArgList = argList;
} else {
ArgList = ArgumentList::createImplicit(dc->getASTContext(), {});
}
}

DeclNameRef getMacroName() const { return MacroName; }
DeclNameLoc getMacroNameLoc() const { return MacroNameLoc; }
DeclNameRef getMacroName() const { return info->MacroName; }
DeclNameLoc getMacroNameLoc() const { return info->MacroNameLoc; }

Expr *getRewritten() const { return Rewritten; }
void setRewritten(Expr *rewritten) { Rewritten = rewritten; }

ArrayRef<TypeRepr *> getGenericArgs() const { return GenericArgs; }
ArrayRef<TypeRepr *> getGenericArgs() const { return info->GenericArgs; }

SourceRange getGenericArgsRange() const {
return SourceRange(LeftAngleLoc, RightAngleLoc);
return SourceRange(info->LeftAngleLoc, info->RightAngleLoc);
}

ArgumentList *getArgs() const { return ArgList; }
void setArgs(ArgumentList *newArgs) { ArgList = newArgs; }
ArgumentList *getArgs() const { return info->ArgList; }
void setArgs(ArgumentList *newArgs) { info->ArgList = newArgs; }

MacroRoles getMacroRoles() const { return Roles; }

SourceLoc getLoc() const { return SigilLoc; }
SourceLoc getLoc() const { return info->SigilLoc; }

ConcreteDeclRef getMacroRef() const { return macroRef; }
void setMacroRef(ConcreteDeclRef ref) { macroRef = ref; }
ConcreteDeclRef getMacroRef() const { return info->macroRef; }
void setMacroRef(ConcreteDeclRef ref) { info->macroRef = ref; }

DeclContext *getDeclContext() const { return DC; }
void setDeclContext(DeclContext *dc) { DC = dc; }
Expand All @@ -6275,11 +6261,12 @@ class MacroExpansionExpr final : public Expr {
Bits.MacroExpansionExpr.Discriminator = discriminator;
}

MacroExpansionInfo *getExpansionInfo() const { return info; }

SourceRange getSourceRange() const;

MacroExpansionDecl *createSubstituteDecl() const;
MacroExpansionDecl *createSubstituteDecl();
MacroExpansionDecl *getSubstituteDecl() const;
void setSubstituteDecl(MacroExpansionDecl *decl);

static bool classof(const Expr *E) {
return E->getKind() == ExprKind::MacroExpansion;
Expand Down
1 change: 1 addition & 0 deletions lib/AST/ASTScope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ DEFINE_GET_CLASS_NAME(SubscriptDeclScope)
DEFINE_GET_CLASS_NAME(EnumElementScope)
DEFINE_GET_CLASS_NAME(MacroDeclScope)
DEFINE_GET_CLASS_NAME(MacroDefinitionScope)
DEFINE_GET_CLASS_NAME(MacroExpansionDeclScope)
DEFINE_GET_CLASS_NAME(IfStmtScope)
DEFINE_GET_CLASS_NAME(WhileStmtScope)
DEFINE_GET_CLASS_NAME(GuardStmtScope)
Expand Down
13 changes: 12 additions & 1 deletion lib/AST/ASTScopeCreation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,6 @@ class NodeAdder
VISIT_AND_IGNORE(PoundDiagnosticDecl)
VISIT_AND_IGNORE(MissingDecl)
VISIT_AND_IGNORE(MissingMemberDecl)
VISIT_AND_IGNORE(MacroExpansionDecl)

// Only members of the active clause are in scope, and those
// are visited separately.
Expand Down Expand Up @@ -353,6 +352,7 @@ class NodeAdder
VISIT_AND_CREATE(CaseStmt, CaseStmtScope)
VISIT_AND_CREATE(AbstractFunctionDecl, AbstractFunctionDeclScope)
VISIT_AND_CREATE(MacroDecl, MacroDeclScope)
VISIT_AND_CREATE(MacroExpansionDecl, MacroExpansionDeclScope)

#undef VISIT_AND_CREATE

Expand Down Expand Up @@ -724,6 +724,7 @@ NO_NEW_INSERTION_POINT(RepeatWhileScope)
NO_NEW_INSERTION_POINT(SubscriptDeclScope)
NO_NEW_INSERTION_POINT(MacroDeclScope)
NO_NEW_INSERTION_POINT(MacroDefinitionScope)
NO_NEW_INSERTION_POINT(MacroExpansionDeclScope)
NO_NEW_INSERTION_POINT(SwitchStmtScope)
NO_NEW_INSERTION_POINT(WhileStmtScope)

Expand Down Expand Up @@ -1131,6 +1132,16 @@ MacroDefinitionScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
scopeCreator.addToScopeTree(ASTNode(definition), this);
}

void MacroExpansionDeclScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
ScopeCreator &scopeCreator) {
// FIXME: If we get attributes on macro expansions, visit them here.
if (auto argList = decl->getArgs()) {
for (const auto &arg : *argList) {
scopeCreator.addExprToScopeTree(arg.getExpr(), this);
}
}
}

void CaptureListScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
ScopeCreator &scopeCreator) {
auto *closureExpr = expr->getClosureBody();
Expand Down
4 changes: 4 additions & 0 deletions lib/AST/ASTScopePrinting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ void MacroDeclScope::printSpecifics(llvm::raw_ostream &out) const {
decl->dumpRef(out);
}

void MacroExpansionDeclScope::printSpecifics(llvm::raw_ostream &out) const {
out << decl->getMacroName();
}

void ConditionalClausePatternUseScope::printSpecifics(
llvm::raw_ostream &out) const {
sec.getPattern()->print(out);
Expand Down
5 changes: 5 additions & 0 deletions lib/AST/ASTScopeSourceRange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ SourceRange MacroDefinitionScope::getSourceRangeOfThisASTNode(
return definition->getSourceRange();
}

SourceRange MacroExpansionDeclScope::getSourceRangeOfThisASTNode(
const bool omitAssertions) const {
return decl->getSourceRangeIncludingAttrs();
}

SourceRange
EnumElementScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
return decl->getSourceRange();
Expand Down
31 changes: 19 additions & 12 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10335,30 +10335,37 @@ MacroDefinition MacroDefinition::forExpanded(
ctx.AllocateCopy(replacements)};
}

MacroExpansionDecl::MacroExpansionDecl(
DeclContext *dc, MacroExpansionInfo *info
) : Decl(DeclKind::MacroExpansion, dc), info(info) {
Bits.MacroExpansionDecl.Discriminator = InvalidDiscriminator;
}

MacroExpansionDecl::MacroExpansionDecl(
DeclContext *dc, SourceLoc poundLoc, DeclNameRef macro,
DeclNameLoc macroLoc, SourceLoc leftAngleLoc,
ArrayRef<TypeRepr *> genericArgs, SourceLoc rightAngleLoc,
ArgumentList *args)
: Decl(DeclKind::MacroExpansion, dc), PoundLoc(poundLoc),
MacroName(macro), MacroNameLoc(macroLoc),
LeftAngleLoc(leftAngleLoc), RightAngleLoc(rightAngleLoc),
GenericArgs(genericArgs),
ArgList(args ? args
: ArgumentList::createImplicit(dc->getASTContext(), {})) {
ArgumentList *args
) : Decl(DeclKind::MacroExpansion, dc) {
ASTContext &ctx = dc->getASTContext();
info = new (ctx) MacroExpansionInfo{
poundLoc, macro, macroLoc,
leftAngleLoc, rightAngleLoc, genericArgs,
args ? args : ArgumentList::createImplicit(ctx, {})
};
Bits.MacroExpansionDecl.Discriminator = InvalidDiscriminator;
}

SourceRange MacroExpansionDecl::getSourceRange() const {
SourceLoc endLoc;
if (auto argsEndList = ArgList->getEndLoc())
if (auto argsEndList = info->ArgList->getEndLoc())
endLoc = argsEndList;
else if (RightAngleLoc.isValid())
endLoc = RightAngleLoc;
else if (info->RightAngleLoc.isValid())
endLoc = info->RightAngleLoc;
else
endLoc = MacroNameLoc.getEndLoc();
endLoc = info->MacroNameLoc.getEndLoc();

return SourceRange(PoundLoc, endLoc);
return SourceRange(info->SigilLoc, endLoc);
}

unsigned MacroExpansionDecl::getDiscriminator() const {
Expand Down
Loading