Skip to content

Fix precedencegroup and operator decl lookup #30269

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

Closed
wants to merge 7 commits into from
Closed
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
2 changes: 2 additions & 0 deletions include/swift/AST/ASTTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ SWIFT_TYPEID_NAMED(Optional<PropertyWrapperMutability>,
PropertyWrapperMutability)
SWIFT_TYPEID_NAMED(ParamDecl *, ParamDecl)
SWIFT_TYPEID_NAMED(PatternBindingEntry *, PatternBindingEntry)
SWIFT_TYPEID_NAMED(PostfixOperatorDecl *, PostfixOperatorDecl)
SWIFT_TYPEID_NAMED(PrecedenceGroupDecl *, PrecedenceGroupDecl)
SWIFT_TYPEID_NAMED(PrefixOperatorDecl *, PrefixOperatorDecl)
SWIFT_TYPEID_NAMED(ProtocolDecl *, ProtocolDecl)
SWIFT_TYPEID_NAMED(SourceFile *, SourceFile)
SWIFT_TYPEID_NAMED(TypeAliasDecl *, TypeAliasDecl)
Expand Down
2 changes: 2 additions & 0 deletions include/swift/AST/ASTTypeIDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ class OpaqueTypeDecl;
class PatternBindingEntry;
class ParamDecl;
enum class ParamSpecifier : uint8_t;
class PostfixOperatorDecl;
class PrecedenceGroupDecl;
class PrefixOperatorDecl;
struct PropertyWrapperBackingPropertyInfo;
struct PropertyWrapperTypeInfo;
enum class CtorInitializerKind;
Expand Down
49 changes: 31 additions & 18 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -6963,6 +6963,11 @@ class PrecedenceGroupDecl : public Decl {
return Name;
}

// These are needed to allow templated code to work with both ValueDecls and
// PrecedenceGroupDecls.
DeclName getFullName() const { return Name; }
DeclBaseName getBaseName() const { return Name; }

SourceLoc getLBraceLoc() const { return LBraceLoc; }
SourceLoc getRBraceLoc() const { return RBraceLoc; }

Expand Down Expand Up @@ -7079,11 +7084,37 @@ class OperatorDecl : public Decl {
: Decl(kind, DC), OperatorLoc(OperatorLoc), NameLoc(NameLoc), name(Name),
DesignatedNominalTypes(DesignatedNominalTypes) {}

enum class Fixity : uint8_t {
Infix,
Prefix,
Postfix
};

/// Retrieve the operator's fixity, corresponding to the concrete subclass
/// of the OperatorDecl.
Fixity getFixity() const {
switch (getKind()) {
#define DECL(Id, Name) case DeclKind::Id: llvm_unreachable("Not an operator!");
#define OPERATOR_DECL(Id, Name)
#include "swift/AST/DeclNodes.def"
case DeclKind::InfixOperator:
return Fixity::Infix;
case DeclKind::PrefixOperator:
return Fixity::Prefix;
case DeclKind::PostfixOperator:
return Fixity::Postfix;
}
}

SourceLoc getOperatorLoc() const { return OperatorLoc; }
SourceLoc getNameLoc() const { return NameLoc; }
Identifier getName() const { return name; }

// These are needed to allow templated code to work with both ValueDecls and
// OperatorDecls.
DeclName getFullName() const { return name; }
DeclBaseName getBaseName() const { return name; }

/// Get the list of identifiers after the colon in the operator declaration.
///
/// This list includes the names of designated types. For infix operators, the
Expand Down Expand Up @@ -7149,12 +7180,6 @@ class InfixOperatorDecl : public OperatorDecl {

PrecedenceGroupDecl *getPrecedenceGroup() const;

/// True if this decl's attributes conflict with those declared by another
/// operator.
bool conflictsWith(InfixOperatorDecl *other) {
return getPrecedenceGroup() != other->getPrecedenceGroup();
}

static bool classof(const Decl *D) {
return D->getKind() == DeclKind::InfixOperator;
}
Expand Down Expand Up @@ -7184,12 +7209,6 @@ class PrefixOperatorDecl : public OperatorDecl {
return { getOperatorLoc(), getNameLoc() };
}

/// True if this decl's attributes conflict with those declared by another
/// PrefixOperatorDecl.
bool conflictsWith(PrefixOperatorDecl *other) {
return false;
}

static bool classof(const Decl *D) {
return D->getKind() == DeclKind::PrefixOperator;
}
Expand Down Expand Up @@ -7218,12 +7237,6 @@ class PostfixOperatorDecl : public OperatorDecl {
SourceRange getSourceRange() const {
return { getOperatorLoc(), getNameLoc() };
}

/// True if this decl's attributes conflict with those declared by another
/// PostfixOperatorDecl.
bool conflictsWith(PostfixOperatorDecl *other) {
return false;
}

static bool classof(const Decl *D) {
return D->getKind() == DeclKind::PostfixOperator;
Expand Down
32 changes: 32 additions & 0 deletions include/swift/AST/DeclContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "swift/AST/TypeAlignments.h"
#include "swift/Basic/Debug.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/NullablePtr.h"
#include "swift/Basic/STLExtras.h"
#include "swift/Basic/SourceLoc.h"
#include "llvm/ADT/PointerEmbeddedInt.h"
Expand Down Expand Up @@ -54,13 +55,19 @@ namespace swift {
class GenericSignature;
class GenericTypeParamDecl;
class GenericTypeParamType;
class InfixOperatorDecl;
class InfixOperatorLookupResult;
class PrecedenceGroupDecl;
class ProtocolDecl;
class Requirement;
class SourceFile;
class Type;
class ModuleDecl;
class GenericTypeDecl;
class NominalTypeDecl;
class PrecedenceGroupLookupResult;
class PostfixOperatorDecl;
class PrefixOperatorDecl;
class ProtocolConformance;
class ValueDecl;
class Initializer;
Expand Down Expand Up @@ -537,6 +544,31 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
ObjCSelector selector,
SmallVectorImpl<AbstractFunctionDecl *> &results) const;

/// Looks up an infix operator with a given \p name.
///
/// This returns a vector of results, as it's possible to find multiple infix
/// operators with different precedence groups.
InfixOperatorLookupResult lookupInfixOperator(Identifier name,
bool isCascading = true) const;

/// Looks up an prefix operator with a given \p name.
///
/// If multiple results are found, one is chosen in a stable manner, as
/// prefix operator decls cannot differ other than in name.
NullablePtr<PrefixOperatorDecl>
lookupPrefixOperator(Identifier name, bool isCascading = true) const;

/// Looks up an postfix operator with a given \p name.
///
/// If multiple results are found, one is chosen in a stable manner, as
/// postfix operator decls cannot differ other than in name.
NullablePtr<PostfixOperatorDecl>
lookupPostfixOperator(Identifier name, bool isCascading = true) const;

/// Looks up a precedence group with a given \p name.
PrecedenceGroupLookupResult
lookupPrecedenceGroup(Identifier name, bool isCascading = true) const;

/// Return the ASTContext for a specified DeclContext by
/// walking up to the enclosing module and returning its ASTContext.
LLVM_READONLY
Expand Down
43 changes: 27 additions & 16 deletions include/swift/AST/FileUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,26 @@ class FileUnit : public DeclContext {
const ModuleDecl *importedModule,
SmallVectorImpl<Identifier> &spiGroups) const {};

/// Look up an operator declaration. This does a simple local lookup, not
/// recursively looking through imports, and doesn't record dependencies. You
/// almost certainly want to be using DeclContext's operator lookup members
/// instead.
///
/// \param name The operator name ("+", ">>", etc.)
/// \param fixity The fixity of the operator (infix, prefix or postfix).
virtual void
lookupOperatorDirect(Identifier name, OperatorDecl::Fixity fixity,
TinyPtrVector<OperatorDecl *> &results) const {}

/// Look up a precedence group. This does a simple local lookup, not
/// recursively looking through imports, and doesn't record dependencies. You
/// almost certainly want to be using DeclContext's precedencegroup lookup
/// member instead.
///
/// \param name The precedence group name.
virtual void lookupPrecedenceGroupDirect(
Identifier name, TinyPtrVector<PrecedenceGroupDecl *> &results) const {}

/// Returns the comment attached to the given declaration.
///
/// This function is an implementation detail for comment serialization.
Expand Down Expand Up @@ -174,6 +194,13 @@ class FileUnit : public DeclContext {
SmallVectorImpl<Decl*> &Results,
llvm::function_ref<bool(DeclAttributes)> matchAttributes) const;

/// Finds all operator decls in this file.
///
/// This does a simple local lookup, not recursively looking through imports.
/// The order of the results is not guaranteed to be meaningful.
virtual void
getOperatorDecls(SmallVectorImpl<OperatorDecl *> &results) const {}

/// Finds all precedence group decls in this file.
///
/// This does a simple local lookup, not recursively looking through imports.
Expand Down Expand Up @@ -342,22 +369,6 @@ class LoadedFile : public FileUnit {
return StringRef();
}

/// Look up an operator declaration.
///
/// \param name The operator name ("+", ">>", etc.)
///
/// \param fixity One of PrefixOperator, InfixOperator, or PostfixOperator.
virtual OperatorDecl *lookupOperator(Identifier name, DeclKind fixity) const {
return nullptr;
}

/// Look up a precedence group.
///
/// \param name The precedence group name.
virtual PrecedenceGroupDecl *lookupPrecedenceGroup(Identifier name) const {
return nullptr;
}

/// Returns the Swift module that overlays a Clang module.
virtual ModuleDecl *getOverlayModule() const { return nullptr; }

Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/Identifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ class Identifier {
return Identifier((const char*)P);
}

friend llvm::hash_code hash_value(Identifier identifier) {
return llvm::hash_value(identifier.getAsOpaquePointer());
}

/// Compare two identifiers, producing -1 if \c *this comes before \c other,
/// 1 if \c *this comes after \c other, and 0 if they are equal.
///
Expand Down
30 changes: 18 additions & 12 deletions include/swift/AST/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,20 +444,20 @@ class ModuleDecl : public DeclContext, public TypeDecl {
/// FIXME: Remove the integrated REPL.
void clearLookupCache();

/// @{
/// Look up an operator declaration. This does a simple local lookup, not
/// recursively looking through imports, and doesn't record dependencies.
///
/// \param name The operator name ("+", ">>", etc.)
/// \param fixity The fixity of the operator (infix, prefix or postfix).
void lookupOperatorDirect(Identifier name, OperatorDecl::Fixity fixity,
TinyPtrVector<OperatorDecl *> &results) const;

/// Look up the given operator in this module.
/// Look up a precedence group. This does a simple local lookup, not
/// recursively looking through imports, and doesn't record dependencies.
///
/// If the operator is not found, or if there is an ambiguity, returns null.
InfixOperatorDecl *lookupInfixOperator(Identifier name,
SourceLoc diagLoc = {});
PrefixOperatorDecl *lookupPrefixOperator(Identifier name,
SourceLoc diagLoc = {});
PostfixOperatorDecl *lookupPostfixOperator(Identifier name,
SourceLoc diagLoc = {});
PrecedenceGroupDecl *lookupPrecedenceGroup(Identifier name,
SourceLoc diagLoc = {});
/// @}
/// \param name The precedence group name.
void lookupPrecedenceGroupDirect(
Identifier name, TinyPtrVector<PrecedenceGroupDecl *> &results) const;

/// Finds all class members defined in this module.
///
Expand Down Expand Up @@ -583,6 +583,12 @@ class ModuleDecl : public DeclContext, public TypeDecl {
/// The order of the results is not guaranteed to be meaningful.
void getLocalTypeDecls(SmallVectorImpl<TypeDecl*> &Results) const;

/// Finds all operator decls of this module.
///
/// This does a simple local lookup, not recursively looking through imports.
/// The order of the results is not guaranteed to be meaningful.
void getOperatorDecls(SmallVectorImpl<OperatorDecl *> &results) const;

/// Finds all precedence group decls of this module.
///
/// This does a simple local lookup, not recursively looking through imports.
Expand Down
Loading