Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
7 changes: 5 additions & 2 deletions include/swift/AST/ASTBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,13 @@ BridgedDeclNameRef_createParsed(BridgedASTContext cContext,

class BridgedDeclNameLoc {
const void *_Nullable LocationInfo;
size_t NumArgumentLabels;
uint32_t NumArgumentLabels;
bool HasModuleSelectorLoc;

public:
BridgedDeclNameLoc() : LocationInfo(nullptr), NumArgumentLabels(0) {}
BridgedDeclNameLoc()
: LocationInfo(nullptr), NumArgumentLabels(0), HasModuleSelectorLoc(false)
{}

BRIDGED_INLINE BridgedDeclNameLoc(swift::DeclNameLoc loc);

Expand Down
6 changes: 4 additions & 2 deletions include/swift/AST/ASTBridgingImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@ swift::DeclNameRef BridgedDeclNameRef::unbridged() const {

BridgedDeclNameLoc::BridgedDeclNameLoc(swift::DeclNameLoc loc)
: LocationInfo(loc.LocationInfo),
NumArgumentLabels(loc.NumArgumentLabels) {}
NumArgumentLabels(loc.NumArgumentLabels),
HasModuleSelectorLoc(loc.HasModuleSelectorLoc) {}

swift::DeclNameLoc BridgedDeclNameLoc::unbridged() const {
return swift::DeclNameLoc(LocationInfo, NumArgumentLabels);
return swift::DeclNameLoc(LocationInfo, NumArgumentLabels,
HasModuleSelectorLoc);
}

//===----------------------------------------------------------------------===//
Expand Down
9 changes: 4 additions & 5 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3072,11 +3072,10 @@ class ValueDecl : public Decl {
return Name.getBaseIdentifier();
}

/// Generates a DeclNameRef referring to this declaration with as much
/// specificity as possible.
DeclNameRef createNameRef() const {
return DeclNameRef(Name);
}
/// Generates a DeclNameRef referring to this declaration.
///
/// \param moduleSelector If true, the name ref includes the module name.
DeclNameRef createNameRef(bool moduleSelector = false) const;

/// Retrieve the C declaration name that names this function, or empty
/// string if it has none.
Expand Down
47 changes: 27 additions & 20 deletions include/swift/AST/DeclNameLoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,61 +35,69 @@ class DeclNameLoc {

/// Source location information.
///
/// If \c NumArgumentLabels == 0, this is the SourceLoc for the base name.
/// Otherwise, it points to an array of SourceLocs, which contains:
/// If \c NumArgumentLabels == 0 and \c !HasModuleSelectorLoc, this is the
/// SourceLoc for the base name. Otherwise, it points to an array of
/// SourceLocs, which contains:
/// * The base name location
/// * The module selector location
/// * The left parentheses location
/// * The right parentheses location
/// * The locations of each of the argument labels.
const void *LocationInfo;

/// The number of argument labels stored in the name.
unsigned NumArgumentLabels;
uint32_t NumArgumentLabels;
bool HasModuleSelectorLoc;

enum {
BaseNameIndex = 0,
LParenIndex = 1,
RParenIndex = 2,
FirstArgumentLabelIndex = 3,
ModuleSelectorIndex = 1,
LParenIndex = 2,
RParenIndex = 3,
FirstArgumentLabelIndex = 4,
};

/// Retrieve a pointer to either the only source location that was
/// stored or to the array of source locations that was stored.
SourceLoc const * getSourceLocs() const {
if (NumArgumentLabels == 0)
if (NumArgumentLabels == 0 && !HasModuleSelectorLoc)
return reinterpret_cast<SourceLoc const *>(&LocationInfo);

return reinterpret_cast<SourceLoc const *>(LocationInfo);
}

DeclNameLoc(const void *LocationInfo, unsigned NumArgumentLabels)
: LocationInfo(LocationInfo), NumArgumentLabels(NumArgumentLabels) {}
DeclNameLoc(const void *LocationInfo, unsigned NumArgumentLabels,
bool HasModuleSelectorLoc)
: LocationInfo(LocationInfo), NumArgumentLabels(NumArgumentLabels),
HasModuleSelectorLoc(HasModuleSelectorLoc) {}

public:
/// Create an invalid declaration name location.
DeclNameLoc() : DeclNameLoc(nullptr, 0) {}
DeclNameLoc() : DeclNameLoc(nullptr, 0, false) {}

/// Create declaration name location information for a base name.
explicit DeclNameLoc(SourceLoc baseNameLoc)
: DeclNameLoc(baseNameLoc.getOpaquePointerValue(), 0) {}
: DeclNameLoc(baseNameLoc.getOpaquePointerValue(), 0, false) {}

explicit DeclNameLoc(ASTContext &ctx, SourceLoc moduleSelectorLoc,
SourceLoc baseNameLoc)
: DeclNameLoc(baseNameLoc) { }
: DeclNameLoc(ctx, moduleSelectorLoc, baseNameLoc,
SourceLoc(), {}, SourceLoc()) { }

/// Create declaration name location information for a compound
/// name.
DeclNameLoc(ASTContext &ctx, SourceLoc baseNameLoc,
SourceLoc lParenLoc,
ArrayRef<SourceLoc> argumentLabelLocs,
SourceLoc rParenLoc);
SourceLoc rParenLoc)
: DeclNameLoc(ctx, SourceLoc(), baseNameLoc,
lParenLoc, argumentLabelLocs, rParenLoc) { }

DeclNameLoc(ASTContext &ctx, SourceLoc moduleSelectorLoc,
SourceLoc baseNameLoc,
SourceLoc lParenLoc,
ArrayRef<SourceLoc> argumentLabelLocs,
SourceLoc rParenLoc)
: DeclNameLoc(ctx, baseNameLoc, lParenLoc, argumentLabelLocs, rParenLoc) { }
SourceLoc rParenLoc);

/// Whether the location information is valid.
bool isValid() const { return getBaseNameLoc().isValid(); }
Expand Down Expand Up @@ -125,11 +133,12 @@ class DeclNameLoc {
}

SourceLoc getModuleSelectorLoc() const {
return SourceLoc();
if (!HasModuleSelectorLoc) return SourceLoc();
return getSourceLocs()[ModuleSelectorIndex];
}

SourceLoc getStartLoc() const {
return getBaseNameLoc();
return HasModuleSelectorLoc ? getModuleSelectorLoc() : getBaseNameLoc();
}

SourceLoc getEndLoc() const {
Expand All @@ -138,9 +147,7 @@ class DeclNameLoc {

/// Retrieve the complete source range for this declaration name.
SourceRange getSourceRange() const {
if (NumArgumentLabels == 0) return getBaseNameLoc();

return SourceRange(getBaseNameLoc(), getRParenLoc());
return SourceRange(getStartLoc(), getEndLoc());
}
};

Expand Down
16 changes: 15 additions & 1 deletion include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,10 @@ ERROR(no_module_type,none,
"no type named %0 in module %1", (DeclNameRef, Identifier))
ERROR(ambiguous_module_type,none,
"ambiguous type name %0 in module %1", (DeclNameRef, Identifier))
ERROR(module_selector_dependent_member_type_not_allowed,none,
"module selector is not allowed on generic member type; associated types "
"with the same name are merged instead of shadowing one another",
())
ERROR(use_nonmatching_operator,none,
"%0 is not a %select{binary|prefix unary|postfix unary}1 operator",
(DeclNameRef, unsigned))
Expand Down Expand Up @@ -1191,6 +1195,16 @@ ERROR(cannot_find_type_in_cast_expression,none,
"type-casting operator expects a type on its right-hand side (got: %kind0)", (const ValueDecl *))
ERROR(cannot_find_type_in_scope_did_you_mean,none,
"cannot find type %0 in scope; did you mean to use '%1'?", (DeclNameRef, StringRef))
ERROR(wrong_module_selector,none,
"%0 is not imported through module %1", (DeclName, Identifier))
NOTE(note_change_module_selector,none,
"did you mean module %0?", (Identifier))
NOTE(note_remove_module_selector_local_decl,none,
"did you mean the local declaration?", ())
NOTE(note_remove_module_selector_outer_type,none,
"did you mean an outer type member?", ())
NOTE(note_add_explicit_self_with_module_selector,none,
"did you mean the member of 'self'?", ())
NOTE(note_typo_candidate_implicit_member,none,
"did you mean the implicitly-synthesized %kindbase0?", (const ValueDecl *))
NOTE(note_remapped_type,none,
Expand Down Expand Up @@ -8010,7 +8024,7 @@ ERROR(expected_macro_expansion_expr,PointsToFirstBadToken,
ERROR(expected_macro_expansion_decls,PointsToFirstBadToken,
"expected macro expansion to produce a declaration", ())
ERROR(macro_undefined,PointsToFirstBadToken,
"no macro named %0", (DeclName))
"no macro named %0", (DeclNameRef))
ERROR(external_macro_not_found,none,
"external macro implementation type '%0.%1' could not be found for "
"macro %2; %3", (StringRef, StringRef, DeclName, StringRef))
Expand Down
64 changes: 50 additions & 14 deletions include/swift/AST/Identifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -738,39 +738,76 @@ void simple_display(llvm::raw_ostream &out, DeclName name);
/// An in-source reference to another declaration, including qualification
/// information.
class DeclNameRef {
DeclName FullName;
friend class ASTContext;
friend struct llvm::PointerLikeTypeTraits<DeclNameRef>;

/// Contains the name and module for a DeclNameRef with a module selector.
struct alignas(Identifier) SelectiveDeclNameRef : llvm::FoldingSetNode {
Identifier moduleSelector; // Note: currently can never be empty().
DeclName fullName;

SelectiveDeclNameRef(Identifier moduleSelector, DeclName fullName)
: moduleSelector(moduleSelector), fullName(fullName) { }

/// Uniquing for the ASTContext.
static void Profile(llvm::FoldingSetNodeID &id, Identifier moduleSelector,
DeclName fullName);

void Profile(llvm::FoldingSetNodeID &id) {
Profile(id, moduleSelector, fullName);
}
};

using Storage = llvm::PointerUnion<DeclName, SelectiveDeclNameRef *>;
Storage storage;

explicit DeclNameRef(void *_Nullable Opaque)
: storage(decltype(storage)::getFromOpaqueValue(Opaque)) { }

void initialize(ASTContext &C, Identifier moduleScope, DeclName fullName);

public:
static DeclNameRef createSubscript();
static DeclNameRef createConstructor();
static DeclNameRef createSelf(const ASTContext &ctx);

DeclNameRef() : FullName() { }
DeclNameRef() : storage(DeclName()) { }

void *_Nullable getOpaqueValue() const { return FullName.getOpaqueValue(); }
void *_Nullable getOpaqueValue() const {
return storage.getOpaqueValue();
}
static DeclNameRef getFromOpaqueValue(void *_Nullable p);

explicit DeclNameRef(ASTContext &C, Identifier moduleSelector,
DeclName fullName)
: FullName(fullName) { }
DeclName fullName) {
initialize(C, moduleSelector, fullName);
}

explicit DeclNameRef(ASTContext &C, Identifier moduleSelector,
DeclBaseName baseName, ArrayRef<Identifier> argLabels)
: FullName(C, baseName, argLabels) { }
DeclBaseName baseName, ArrayRef<Identifier> argLabels) {
initialize(C, moduleSelector, DeclName(C, baseName, argLabels));
}

explicit DeclNameRef(DeclName FullName)
: FullName(FullName) { }
: storage(FullName) { }

bool hasModuleSelector() const {
return false;
return isa<SelectiveDeclNameRef *>(storage);
}

Identifier getModuleSelector() const {
return Identifier();
if (!hasModuleSelector())
return Identifier();

return cast<SelectiveDeclNameRef *>(storage)->moduleSelector;
}

/// The name of the declaration being referenced.
DeclName getFullName() const {
return FullName;
if (!hasModuleSelector())
return cast<DeclName>(storage);

return cast<SelectiveDeclNameRef *>(storage)->fullName;
}

/// The base name of the declaration being referenced.
Expand Down Expand Up @@ -885,7 +922,7 @@ class DeclNameRef {
};

inline DeclNameRef DeclNameRef::getFromOpaqueValue(void *_Nullable p) {
return DeclNameRef(DeclName::getFromOpaqueValue(p));
return DeclNameRef(p);
}

inline DeclNameRef DeclNameRef::withoutArgumentLabels(ASTContext &C) const {
Expand Down Expand Up @@ -1059,7 +1096,6 @@ namespace llvm {
};

// A DeclNameRef is "pointer like" just like DeclNames.
template<typename T> struct PointerLikeTypeTraits;
template<>
struct PointerLikeTypeTraits<swift::DeclNameRef> {
public:
Expand All @@ -1069,7 +1105,7 @@ namespace llvm {
static inline swift::DeclNameRef getFromVoidPointer(void *_Nullable ptr) {
return swift::DeclNameRef::getFromOpaqueValue(ptr);
}
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::DeclName>::NumLowBitsAvailable };
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::DeclNameRef::Storage>::NumLowBitsAvailable };
};

// DeclNameRefs hash just like DeclNames.
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/LookupKinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ enum class ModuleLookupFlags : unsigned {
/// If @abi attributes are present, return the decls representing the ABI,
/// not the API.
ABIProviding = 1 << 1,
/// The lookup is qualified by a module selector which has specified this
/// module explicitly.
HasModuleSelector = 1 << 2,
};

} // end namespace swift
Expand Down
5 changes: 5 additions & 0 deletions include/swift/AST/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,11 @@ class ModuleDecl
void getDeclaredCrossImportBystanders(
SmallVectorImpl<Identifier> &bystanderNames);

/// Returns the name that should be used for this module in a module
/// selector. For separately-imported overlays, this will be the declaring
/// module's name.
Identifier getNameForModuleSelector();

/// Retrieve the ABI name of the module, which is used for metadata and
/// mangling.
Identifier getABIName() const;
Expand Down
21 changes: 15 additions & 6 deletions include/swift/AST/ModuleNameLookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,35 @@ enum class ResolutionKind {

void simple_display(llvm::raw_ostream &out, ResolutionKind kind);

/// Performs a lookup into the given module and it's imports.
/// Performs a lookup into the given module and its imports.
///
/// If 'moduleOrFile' is a ModuleDecl, we search the module and it's
/// If 'moduleOrFile' is a ModuleDecl, we search the module and its
/// public imports. If 'moduleOrFile' is a SourceFile, we search the
/// file's parent module, the module's public imports, and the source
/// file's private imports.
///
/// \param moduleOrFile The module or file unit whose imports to search.
/// \param moduleOrFile The module or file unit to search, including imports.
/// \param name The name to look up.
/// \param hasModuleSelector Whether \p name was originally qualified by a
/// module selector. This information is threaded through to underlying
/// lookup calls; the callee is responsible for actually applying the
/// module selector.
/// \param[out] decls Any found decls will be added to this vector.
/// \param lookupKind Whether this lookup is qualified or unqualified.
/// \param resolutionKind What sort of decl is expected.
/// \param moduleScopeContext The top-level context from which the lookup is
/// being performed, for checking access. This must be either a
/// FileUnit or a Module.
/// \param loc Source location of the lookup. Used to add contextual options,
/// such as disabling macro expansions inside macro arguments.
/// \param options name lookup options. Currently only used to communicate the
/// NL_IncludeUsableFromInline option.
/// NL_IncludeUsableFromInline option.
void lookupInModule(const DeclContext *moduleOrFile,
DeclName name, SmallVectorImpl<ValueDecl *> &decls,
NLKind lookupKind, ResolutionKind resolutionKind,
DeclName name,
bool hasModuleSelector,
SmallVectorImpl<ValueDecl *> &decls,
NLKind lookupKind,
ResolutionKind resolutionKind,
const DeclContext *moduleScopeContext,
SourceLoc loc, NLOptions options);

Expand Down
Loading