Skip to content

[Macros] Use source locations to determine whether to suppress macro expansions. #66532

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
merged 14 commits into from
Jun 12, 2023
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
43 changes: 26 additions & 17 deletions include/swift/AST/ASTScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,10 @@ class ASTScopeImpl : public ASTAllocated<ASTScopeImpl> {
return nullptr;
}

virtual NullablePtr<MacroExpansionDecl> getFreestandingMacro() const {
return nullptr;
}

#pragma mark - debugging and printing

public:
Expand Down Expand Up @@ -278,6 +282,10 @@ class ASTScopeImpl : public ASTAllocated<ASTScopeImpl> {
static std::pair<CaseStmt *, CaseStmt *>
lookupFallthroughSourceAndDest(SourceFile *sourceFile, SourceLoc loc);

static void lookupEnclosingMacroScope(
SourceFile *sourceFile, SourceLoc loc,
llvm::function_ref<bool(ASTScope::PotentialMacro)> consume);

/// Scopes that cannot bind variables may set this to true to create more
/// compact scope tree in the debug info.
virtual bool ignoreInDebugInfo() const { return false; }
Expand Down Expand Up @@ -840,24 +848,20 @@ class DefaultArgumentInitializerScope final : public ASTScopeImpl {
bool ignoreInDebugInfo() const override { return true; }
};

/// Consider:
/// @_propertyWrapper
/// struct WrapperWithInitialValue {
/// }
/// struct HasWrapper {
/// @WrapperWithInitialValue var y = 17
/// }
/// Lookup has to be able to find the use of WrapperWithInitialValue, that's
/// what this scope is for. Because the source positions are screwy.

class AttachedPropertyWrapperScope final : public ASTScopeImpl {
/// The scope for custom attributes and their arguments, such as for
/// attached property wrappers and for attached macros.
///
/// Source locations for the attribute name and its arguments are in the
/// custom attribute, so lookup is invoked from within the attribute
/// itself.
class CustomAttributeScope final : public ASTScopeImpl {
public:
CustomAttr *attr;
VarDecl *decl;
Decl *decl;

AttachedPropertyWrapperScope(CustomAttr *attr, VarDecl *decl)
CustomAttributeScope(CustomAttr *attr,Decl *decl)
: attr(attr), decl(decl) {}
virtual ~AttachedPropertyWrapperScope() {}
virtual ~CustomAttributeScope() {}

protected:
ASTScopeImpl *expandSpecifically(ScopeCreator &) override;
Expand All @@ -871,7 +875,8 @@ class AttachedPropertyWrapperScope final : public ASTScopeImpl {
NullablePtr<DeclAttribute> getDeclAttributeIfAny() const override {
return attr;
}
bool ignoreInDebugInfo() const override { return true; }
bool ignoreInDebugInfo() const override { return true; }

private:
void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);
};
Expand Down Expand Up @@ -1134,9 +1139,9 @@ class SpecializeAttributeScope final : public ASTScopeImpl {
class DifferentiableAttributeScope final : public ASTScopeImpl {
public:
DifferentiableAttr *const differentiableAttr;
ValueDecl *const attributedDeclaration;
Decl *const attributedDeclaration;

DifferentiableAttributeScope(DifferentiableAttr *diffAttr, ValueDecl *decl)
DifferentiableAttributeScope(DifferentiableAttr *diffAttr, Decl *decl)
: differentiableAttr(diffAttr), attributedDeclaration(decl) {}
virtual ~DifferentiableAttributeScope() {}

Expand Down Expand Up @@ -1270,6 +1275,10 @@ class MacroExpansionDeclScope final : public ASTScopeImpl {
SourceRange
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;

NullablePtr<MacroExpansionDecl> getFreestandingMacro() const override {
return decl;
}

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

Expand Down
5 changes: 3 additions & 2 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3899,7 +3899,7 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
/// protocols to which the nominal type conforms. Furthermore, the resulting
/// set of declarations has not been filtered for visibility, nor have
/// overridden declarations been removed.
TinyPtrVector<ValueDecl *> lookupDirect(DeclName name,
TinyPtrVector<ValueDecl *> lookupDirect(DeclName name, SourceLoc loc = SourceLoc(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we plan to take away that default argument at some point, once we've managed to update all of the callers?

OptionSet<LookupDirectFlags> flags =
OptionSet<LookupDirectFlags>());

Expand Down Expand Up @@ -4454,7 +4454,8 @@ class ClassDecl final : public NominalTypeDecl {
// Force loading all the members, which will add this attribute if any of
// members are determined to be missing while loading.
auto mutableThis = const_cast<ClassDecl *>(this);
(void)mutableThis->lookupDirect(DeclBaseName::createConstructor());
(void)mutableThis->lookupDirect(DeclBaseName::createConstructor(),
getStartLoc());
}

if (Bits.ClassDecl.ComputedHasMissingDesignatedInitializers)
Expand Down
7 changes: 4 additions & 3 deletions include/swift/AST/DeclContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,8 @@ class alignas(1 << DeclContextAlignInBits) DeclContext
/// lookup.
///
/// \returns true if anything was found.
bool lookupQualified(Type type, DeclNameRef member, NLOptions options,
bool lookupQualified(Type type, DeclNameRef member,
SourceLoc loc, NLOptions options,
SmallVectorImpl<ValueDecl *> &decls) const;

/// Look for the set of declarations with the given name within the
Expand All @@ -616,12 +617,12 @@ class alignas(1 << DeclContextAlignInBits) DeclContext
///
/// \returns true if anything was found.
bool lookupQualified(ArrayRef<NominalTypeDecl *> types, DeclNameRef member,
NLOptions options,
SourceLoc loc, NLOptions options,
SmallVectorImpl<ValueDecl *> &decls) const;

/// Perform qualified lookup for the given member in the given module.
bool lookupQualified(ModuleDecl *module, DeclNameRef member,
NLOptions options,
SourceLoc loc, NLOptions options,
SmallVectorImpl<ValueDecl *> &decls) const;

/// Look up all Objective-C methods with the given selector visible
Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -7188,6 +7188,10 @@ ERROR(macro_accessor_missing_from_expansion,none,
ERROR(macro_init_accessor_not_documented,none,
"expansion of macro %0 produced an unexpected 'init' accessor",
(DeclName))
ERROR(global_arbitrary_name,none,
"'%0' macros are not allowed to introduce arbitrary names "
"at global scope",
(StringRef))

ERROR(macro_resolve_circular_reference, none,
"circular reference resolving %select{freestanding|attached}0 macro %1",
Expand Down
22 changes: 0 additions & 22 deletions include/swift/AST/Evaluator.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,18 +208,6 @@ class Evaluator {
/// is treated as a stack and is used to detect cycles.
llvm::SetVector<ActiveRequest> activeRequests;

/// How many `ResolveMacroRequest` requests are active.
///
/// This allows us to quickly determine whether there is any
/// `ResolveMacroRequest` active in the active request stack.
/// It saves us from a linear scan through `activeRequests` when
/// we need to determine this information.
///
/// Why on earth would we need to determine this information?
/// Please see the extended comment that goes with the constructor
/// of `UnqualifiedLookupRequest`.
unsigned numActiveResolveMacroRequests = 0;

/// A cache that stores the results of requests.
evaluator::RequestCache cache;

Expand Down Expand Up @@ -342,16 +330,6 @@ class Evaluator {
return activeRequests.count(ActiveRequest(request));
}

/// Determine whether there is any active "resolve macro" request
/// on the request stack.
///
/// Why on earth would we need to determine this information?
/// Please see the extended comment that goes with the constructor
/// of `UnqualifiedLookupRequest`.
bool hasActiveResolveMacroRequest() const {
return numActiveResolveMacroRequests > 0;
}

private:
/// Diagnose a cycle detected in the evaluation of the given
/// request.
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/ModuleNameLookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void lookupInModule(const DeclContext *moduleOrFile,
DeclName name, SmallVectorImpl<ValueDecl *> &decls,
NLKind lookupKind, ResolutionKind resolutionKind,
const DeclContext *moduleScopeContext,
NLOptions options);
SourceLoc loc, NLOptions options);

/// Performs a qualified lookup into the given module and, if necessary, its
/// reexports, observing proper shadowing rules.
Expand Down
27 changes: 26 additions & 1 deletion include/swift/AST/NameLookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ void lookupVisibleDecls(VisibleDeclConsumer &Consumer,
///
/// \param CurrDC the DeclContext from which the lookup is done.
void lookupVisibleMemberDecls(VisibleDeclConsumer &Consumer,
Type BaseTy,
Type BaseTy, SourceLoc loc,
const DeclContext *CurrDC,
bool includeInstanceMembers,
bool includeDerivedRequirements,
Expand Down Expand Up @@ -545,6 +545,15 @@ template <typename Result>
void filterForDiscriminator(SmallVectorImpl<Result> &results,
DebuggerClient *debugClient);

/// \returns The set of macro declarations with the given name that
/// fulfill any of the given macro roles.
SmallVector<MacroDecl *, 1>
lookupMacros(DeclContext *dc, DeclNameRef macroName, MacroRoles roles);

/// \returns Whether the given source location is inside an attached
/// or freestanding macro argument.
bool isInMacroArgument(SourceFile *sourceFile, SourceLoc loc);

/// Call the given function body with each macro declaration and its associated
/// role attribute for the given role.
///
Expand Down Expand Up @@ -816,6 +825,22 @@ class ASTScope : public ASTAllocated<ASTScope> {
static std::pair<CaseStmt *, CaseStmt *>
lookupFallthroughSourceAndDest(SourceFile *sourceFile, SourceLoc loc);

using PotentialMacro =
llvm::PointerUnion<FreestandingMacroExpansion *, CustomAttr *>;

/// Look up the scope tree for the nearest enclosing macro scope at
/// the given source location.
///
/// \param sourceFile The source file containing the given location.
/// \param loc The source location to start lookup from.
/// \param consume A function that is called when a potential macro
/// scope is found. If \c consume returns \c true, lookup
/// will stop. If \c consume returns \c false, lookup will
/// continue up the scope tree.
static void lookupEnclosingMacroScope(
SourceFile *sourceFile, SourceLoc loc,
llvm::function_ref<bool(PotentialMacro macro)> consume);

SWIFT_DEBUG_DUMP;
void print(llvm::raw_ostream &) const;
void dumpOneScopeMapLocation(std::pair<unsigned, unsigned>);
Expand Down
8 changes: 4 additions & 4 deletions include/swift/AST/NameLookupRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ class LookupInModuleRequest
LookupInModuleRequest(
const DeclContext *, DeclName, NLKind,
namelookup::ResolutionKind, const DeclContext *,
NLOptions);
SourceLoc, NLOptions);

private:
friend SimpleRequest;
Expand Down Expand Up @@ -511,7 +511,7 @@ class ModuleQualifiedLookupRequest
public:
ModuleQualifiedLookupRequest(const DeclContext *,
ModuleDecl *, DeclNameRef,
NLOptions);
SourceLoc, NLOptions);

private:
friend SimpleRequest;
Expand All @@ -537,7 +537,7 @@ class QualifiedLookupRequest
public:
QualifiedLookupRequest(const DeclContext *,
SmallVector<NominalTypeDecl *, 4>,
DeclNameRef, NLOptions);
DeclNameRef, SourceLoc, NLOptions);

private:
friend SimpleRequest;
Expand Down Expand Up @@ -588,7 +588,7 @@ class DirectLookupRequest
TinyPtrVector<ValueDecl *>(DirectLookupDescriptor),
RequestFlags::Uncached|RequestFlags::DependencySink> {
public:
DirectLookupRequest(DirectLookupDescriptor);
DirectLookupRequest(DirectLookupDescriptor, SourceLoc);

private:
friend SimpleRequest;
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/TypeCheckRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -3249,6 +3249,9 @@ class UnresolvedMacroReference {
public:
UnresolvedMacroReference(FreestandingMacroExpansion *exp) : pointer(exp) {}
UnresolvedMacroReference(CustomAttr *attr) : pointer(attr) {}
UnresolvedMacroReference(
llvm::PointerUnion<FreestandingMacroExpansion *, CustomAttr *> pointer)
: pointer(pointer) {}

FreestandingMacroExpansion *getFreestanding() const {
return pointer.dyn_cast<FreestandingMacroExpansion *>();
Expand Down
3 changes: 2 additions & 1 deletion include/swift/Sema/ConstraintSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -2910,7 +2910,8 @@ class ConstraintSystem {
/// and no new names are introduced after that point.
///
/// \returns A reference to the member-lookup result.
LookupResult &lookupMember(Type base, DeclNameRef name);
LookupResult &lookupMember(Type base, DeclNameRef name,
SourceLoc loc);

/// Retrieve the set of "alternative" literal types that we'll explore
/// for a given literal protocol kind.
Expand Down
7 changes: 4 additions & 3 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1072,8 +1072,8 @@ DECLTYPE *ASTContext::get##NAME##Decl() const { \
/* Note: lookupQualified() will search both the Swift overlay \
* and the Clang module it imports. */ \
SmallVector<ValueDecl *, 1> decls; \
M->lookupQualified(M, DeclNameRef(getIdentifier(#NAME)), NL_OnlyTypes, \
decls); \
M->lookupQualified(M, DeclNameRef(getIdentifier(#NAME)), SourceLoc(), \
NL_OnlyTypes, decls); \
if (decls.size() == 1 && isa<DECLTYPE>(decls[0])) { \
auto decl = cast<DECLTYPE>(decls[0]); \
if (isa<ProtocolDecl>(decl) \
Expand Down Expand Up @@ -1336,7 +1336,8 @@ ConcreteDeclRef ASTContext::getRegexInitDecl(Type regexType) const {
{Id_regexString, Id_version});
SmallVector<ValueDecl *, 1> results;
spModule->lookupQualified(getRegexType(), DeclNameRef(name),
NL_IncludeUsableFromInline, results);
SourceLoc(), NL_IncludeUsableFromInline,
results);
assert(results.size() == 1);
auto *foundDecl = cast<ConstructorDecl>(results[0]);
auto subs = regexType->getMemberSubstitutionMap(spModule, foundDecl);
Expand Down
8 changes: 7 additions & 1 deletion lib/AST/ASTScope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ std::pair<CaseStmt *, CaseStmt *> ASTScope::lookupFallthroughSourceAndDest(
return ASTScopeImpl::lookupFallthroughSourceAndDest(sourceFile, loc);
}

void ASTScope::lookupEnclosingMacroScope(
SourceFile *sourceFile, SourceLoc loc,
llvm::function_ref<bool(PotentialMacro)> body) {
return ASTScopeImpl::lookupEnclosingMacroScope(sourceFile, loc, body);
}

#if SWIFT_COMPILER_IS_MSVC
#pragma warning(push)
#pragma warning(disable : 4996)
Expand Down Expand Up @@ -138,7 +144,7 @@ DEFINE_GET_CLASS_NAME(AbstractFunctionDeclScope)
DEFINE_GET_CLASS_NAME(ParameterListScope)
DEFINE_GET_CLASS_NAME(FunctionBodyScope)
DEFINE_GET_CLASS_NAME(DefaultArgumentInitializerScope)
DEFINE_GET_CLASS_NAME(AttachedPropertyWrapperScope)
DEFINE_GET_CLASS_NAME(CustomAttributeScope)
DEFINE_GET_CLASS_NAME(PatternEntryDeclScope)
DEFINE_GET_CLASS_NAME(PatternEntryInitializerScope)
DEFINE_GET_CLASS_NAME(ConditionalClausePatternUseScope)
Expand Down
18 changes: 9 additions & 9 deletions lib/AST/ASTScopeCreation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ class ScopeCreator final : public ASTAllocated<ScopeCreator> {
addChildrenForParsedAccessors(AbstractStorageDecl *asd,
ASTScopeImpl *parent);

void addChildrenForKnownAttributes(ValueDecl *decl,
void addChildrenForKnownAttributes(Decl *decl,
ASTScopeImpl *parent);

/// Add PatternEntryDeclScopes for each pattern binding entry.
Expand Down Expand Up @@ -569,7 +569,7 @@ void ScopeCreator::addChildrenForParsedAccessors(
});
}

void ScopeCreator::addChildrenForKnownAttributes(ValueDecl *decl,
void ScopeCreator::addChildrenForKnownAttributes(Decl *decl,
ASTScopeImpl *parent) {
SmallVector<DeclAttribute *, 2> relevantAttrs;

Expand Down Expand Up @@ -601,10 +601,8 @@ void ScopeCreator::addChildrenForKnownAttributes(ValueDecl *decl,
parent, specAttr, afd);
}
} else if (auto *customAttr = dyn_cast<CustomAttr>(attr)) {
if (auto *vd = dyn_cast<VarDecl>(decl)) {
constructExpandAndInsert<AttachedPropertyWrapperScope>(
parent, customAttr, vd);
}
constructExpandAndInsert<CustomAttributeScope>(
parent, customAttr, decl);
}
}
}
Expand Down Expand Up @@ -716,7 +714,7 @@ CREATES_NEW_INSERTION_POINT(ConditionalClausePatternUseScope)

NO_NEW_INSERTION_POINT(FunctionBodyScope)
NO_NEW_INSERTION_POINT(AbstractFunctionDeclScope)
NO_NEW_INSERTION_POINT(AttachedPropertyWrapperScope)
NO_NEW_INSERTION_POINT(CustomAttributeScope)
NO_NEW_INSERTION_POINT(EnumElementScope)
NO_NEW_INSERTION_POINT(GuardStmtBodyScope)
NO_NEW_INSERTION_POINT(ParameterListScope)
Expand Down Expand Up @@ -1177,7 +1175,7 @@ void DefaultArgumentInitializerScope::
scopeCreator.addToScopeTree(initExpr, this);
}

void AttachedPropertyWrapperScope::
void CustomAttributeScope::
expandAScopeThatDoesNotCreateANewInsertionPoint(
ScopeCreator &scopeCreator) {
if (auto *args = attr->getArgs()) {
Expand All @@ -1192,7 +1190,9 @@ ASTScopeImpl *GenericTypeOrExtensionWholePortion::expandScope(
GenericTypeOrExtensionScope *scope, ScopeCreator &scopeCreator) const {
// Get now in case recursion emancipates scope
auto *const ip = scope->getParent().get();


scopeCreator.addChildrenForKnownAttributes(scope->getDecl(), scope);

auto *context = scope->getGenericContext();
auto *genericParams = (isa<TypeAliasDecl>(context)
? context->getParsedGenericParams()
Expand Down
Loading