Skip to content

Parser: avoid on-demand parsing when parsing interface tokens. #19192

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 35 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3c68be4
Parser: avoid on-demand parsing when parsing interface tokens.
nkcsgexi Sep 7, 2018
4aeee27
[stdlib] Update Array.subscript to use _modify (#19154)
airspeedswift Sep 7, 2018
317353a
Add ModuleDecl::ReverseFullNameIterator
jrose-apple Sep 7, 2018
f0528e4
When sorting imports for uniquing purposes, use full module names
jrose-apple Sep 7, 2018
9ae5b48
SwiftDemangle: disable ABI breaking checks
compnerd Sep 6, 2018
56e1105
IRGen: Refuse to compute witness table layouts of resilient protocols
slavapestov Sep 7, 2018
28df4d6
IRGen: Use a method descriptor to identify methods where possible
slavapestov Sep 7, 2018
807bf01
IRGen: Remove a few unused methods
slavapestov Sep 7, 2018
a719788
XFAIL array_mutable_assertonly
Sep 7, 2018
f07a973
[AST] Remove stored TypeLoc from TypedPattern (#19175)
Sep 8, 2018
aba5815
[sil-ownership] Tighten up the verification of guaranteed phi arguments.
gottesmm Sep 6, 2018
ae28876
[Loadable-by-address] Replace a never-fails dyn_cast with a cast.
DougGregor Sep 7, 2018
be77571
[Associated type inference] Never infer a type involving archetypes a…
DougGregor Sep 7, 2018
50cc0e6
[Associated type inference] Only check for type parameters when baili…
DougGregor Sep 7, 2018
690b757
[Type checker] Make sure we have a generic signature when inheriting …
DougGregor Sep 7, 2018
8160ae0
IRGen: Add mangling for method lookup functions
slavapestov Sep 6, 2018
83b58cd
Runtime: Introduce swift_lookUpClassMethod()
slavapestov Sep 6, 2018
de5b21a
IRGen: Emit method lookup function
slavapestov Sep 6, 2018
0c3ec79
IRGen: Use method lookup function for resilient super method calls
slavapestov Sep 6, 2018
ce4012c
IRGen: Fix case where we would go through the vtable entry and not th…
slavapestov Sep 7, 2018
9455353
IRGen: Don't visit class members when building resilient class metada…
slavapestov Sep 7, 2018
789c735
Store ProtocolDecl rather than TypeLoc for designated protocol.
rudkx Sep 8, 2018
ae0a2f5
Parser: Ignore and recover marked parse position during on-demand mem…
nkcsgexi Sep 9, 2018
129ea89
[stdlib] Implement the new _modify accessor in Dictionary.subscript
lorentey Aug 24, 2018
c60840e
[stdlib] Fix crucial thinko
lorentey Aug 26, 2018
d18beb6
[Parse] Disable support for multiline/extended escaping string literal
rintaro Sep 8, 2018
1616178
Parser: calculating interface hash only for primary files.
nkcsgexi Sep 7, 2018
7546206
Merge closures_swift4.swift back into closures.swift.
rudkx Sep 7, 2018
7524ca1
[SILGen] Cope with protocol requirement overrides for keypaths.
DougGregor Sep 9, 2018
e3f8e0c
[IRGen] Adjust keypath component id for overriding witness methods.
DougGregor Sep 10, 2018
1d2fb60
Fix mangled CHECK-SAME line.
DougGregor Sep 10, 2018
252854f
Revert "Store ProtocolDecl rather than TypeLoc for designated protocol."
rudkx Sep 10, 2018
e01a78b
Disable failing test while investigating.
rudkx Sep 10, 2018
33d63ed
Propagate concrete types for all arguments of an apply instruction
Jun 20, 2018
8694dba
add assertion for no interface hash.
nkcsgexi Sep 10, 2018
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
1 change: 1 addition & 0 deletions docs/ABI/Mangling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Globals
global ::= nominal-type 'Ml' // in-place type initialization cache
global ::= nominal-type 'Mm' // class metaclass
global ::= nominal-type 'Mn' // nominal type descriptor
global ::= nominal-type 'Mu' // class method lookup function
global ::= module 'MXM' // module descriptor
global ::= context 'MXE' // extension descriptor
global ::= context 'MXX' // anonymous context descriptor
Expand Down
2 changes: 2 additions & 0 deletions include/swift/ABI/Metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,8 @@ struct TargetMethodDescriptor {
// TODO: add method types or anything else needed for reflection.
};

using MethodDescriptor = TargetMethodDescriptor<InProcess>;

/// Header for a class vtable descriptor. This is a variable-sized
/// structure that describes how to find and parse a vtable
/// within the type metadata for a class.
Expand Down
6 changes: 5 additions & 1 deletion include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -1295,7 +1295,11 @@ ERROR(swift_native_objc_runtime_base_must_be_identifier,none,
"@_swift_native_objc_runtime_base class name must be an identifier", ())

ERROR(attr_interpolated_string,none,
"%0 cannot be an interpolated string literal", (StringRef))
"'%0' cannot be an interpolated string literal", (StringRef))
ERROR(attr_multiline_string,none,
"'%0' cannot be a multiline string literal", (StringRef))
ERROR(attr_extended_escaping_string,none,
"'%0' cannot be an extended escaping string literal", (StringRef))

ERROR(attr_only_at_non_local_scope, none,
"attribute '%0' can only be used in a non-local scope", (StringRef))
Expand Down
69 changes: 62 additions & 7 deletions include/swift/AST/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,45 @@ class ModuleDecl : public DeclContext, public TypeDecl {
}
};

/// Produces the components of a given module's full name in reverse order.
///
/// For a Swift module, this will only ever have one component, but an
/// imported Clang module might actually be a submodule.
class ReverseFullNameIterator {
public:
// Make this look like a valid STL iterator.
using difference_type = int;
using value_type = StringRef;
using pointer = StringRef *;
using reference = StringRef;
using iterator_category = std::forward_iterator_tag;

private:
PointerUnion<const ModuleDecl *, const /* clang::Module */ void *> current;
public:
ReverseFullNameIterator() = default;
explicit ReverseFullNameIterator(const ModuleDecl *M);
explicit ReverseFullNameIterator(const clang::Module *clangModule) {
current = clangModule;
}

StringRef operator*() const;
ReverseFullNameIterator &operator++();

friend bool operator==(ReverseFullNameIterator left,
ReverseFullNameIterator right) {
return left.current == right.current;
}
friend bool operator!=(ReverseFullNameIterator left,
ReverseFullNameIterator right) {
return !(left == right);
}

/// This is a convenience function that writes the entire name, in forward
/// order, to \p out.
void printForward(raw_ostream &out) const;
};

private:
/// If non-NULL, a plug-in that should be used when performing external
/// lookups.
Expand Down Expand Up @@ -490,6 +529,15 @@ class ModuleDecl : public DeclContext, public TypeDecl {
/// Returns the associated clang module if one exists.
const clang::Module *findUnderlyingClangModule() const;

/// Returns a generator with the components of this module's full,
/// hierarchical name.
///
/// For a Swift module, this will only ever have one component, but an
/// imported Clang module might actually be a submodule.
ReverseFullNameIterator getReverseFullModuleName() const {
return ReverseFullNameIterator(this);
}

SourceRange getSourceRange() const { return SourceRange(); }

static bool classof(const DeclContext *DC) {
Expand Down Expand Up @@ -825,7 +873,8 @@ class SourceFile final : public FileUnit {

/// A hash of all interface-contributing tokens that have been lexed for
/// this source file so far.
llvm::MD5 InterfaceHash;
/// We only collect interface hash for primary input files.
llvm::Optional<llvm::MD5> InterfaceHash;

/// \brief The ID for the memory buffer containing this file's source.
///
Expand Down Expand Up @@ -1069,20 +1118,26 @@ class SourceFile final : public FileUnit {
/// Set the root refinement context for the file.
void setTypeRefinementContext(TypeRefinementContext *TRC);

void enableInterfaceHash() {
assert(!hasInterfaceHash());
InterfaceHash.emplace();
}

bool hasInterfaceHash() const {
return InterfaceHash.hasValue();
}

void recordInterfaceToken(StringRef token) {
assert(!token.empty());
InterfaceHash.update(token);
InterfaceHash->update(token);
// Add null byte to separate tokens.
uint8_t a[1] = {0};
InterfaceHash.update(a);
InterfaceHash->update(a);
}

const llvm::MD5 &getInterfaceHashState() { return InterfaceHash; }
void setInterfaceHashState(const llvm::MD5 &state) { InterfaceHash = state; }

void getInterfaceHash(llvm::SmallString<32> &str) {
llvm::MD5::MD5Result result;
InterfaceHash.final(result);
InterfaceHash->final(result);
llvm::MD5::stringifyResult(result, str);
}

Expand Down
46 changes: 20 additions & 26 deletions include/swift/AST/Pattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,14 +383,25 @@ class AnyPattern : public Pattern {
/// dynamic type match.
class TypedPattern : public Pattern {
Pattern *SubPattern;
mutable TypeLoc PatType;
TypeRepr *PatTypeRepr;

public:
TypedPattern(Pattern *pattern, TypeLoc tl, Optional<bool> implicit = None)
: Pattern(PatternKind::Typed), SubPattern(pattern), PatType(tl) {
if (implicit.hasValue() ? *implicit : !tl.hasLocation())
setImplicit();
Bits.TypedPattern.IsPropagatedType = false;
/// Creates a new TypedPattern which annotates the provided sub-pattern with
/// the provided TypeRepr. If 'implicit' is true, the pattern will be
/// set to implicit. If false, it will not. If 'implicit' is not provided,
/// then the pattern will be set to 'implicit' if there is a provided TypeRepr
/// which has a valid SourceRange.
TypedPattern(Pattern *pattern, TypeRepr *tr, Optional<bool> implicit = None);

/// Creates an implicit typed pattern annotating the provided sub-pattern
/// with a given type.
static TypedPattern *
createImplicit(ASTContext &ctx, Pattern *pattern, Type type) {
auto tp = new (ctx) TypedPattern(pattern, /*typeRepr*/nullptr,
/*implicit*/true);
if (!type.isNull())
tp->setType(type);
return tp;
}

/// True if the type in this \c TypedPattern was propagated from a different
Expand All @@ -412,27 +423,10 @@ class TypedPattern : public Pattern {
const Pattern *getSubPattern() const { return SubPattern; }
void setSubPattern(Pattern *p) { SubPattern = p; }

TypeLoc &getTypeLoc() {
// If we have a delayed interface type, set our type from that.
if (getDelayedInterfaceType())
PatType.setType(getType());

return PatType;
}
TypeLoc getTypeLoc() const {
// If we have a delayed interface type, set our type from that.
if (getDelayedInterfaceType())
PatType.setType(getType());

return PatType;
}

SourceLoc getLoc() const {
if (SubPattern->isImplicit())
return PatType.getSourceRange().Start;
TypeRepr *getTypeRepr() const { return PatTypeRepr; }

return SubPattern->getLoc();
}
TypeLoc getTypeLoc() const;
SourceLoc getLoc() const;
SourceRange getSourceRange() const;

static bool classof(const Pattern *P) {
Expand Down
1 change: 1 addition & 0 deletions include/swift/Demangling/DemangleNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ NODE(MergedFunction)
NODE(Metatype)
NODE(MetatypeRepresentation)
NODE(Metaclass)
NODE(MethodLookupFunction)
CONTEXT_NODE(ModifyAccessor)
CONTEXT_NODE(Module)
CONTEXT_NODE(NativeOwningAddressor)
Expand Down
9 changes: 9 additions & 0 deletions include/swift/IRGen/Linking.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ class LinkEntity {
/// ConstructorDecl* inside a protocol or a class.
MethodDescriptorAllocator,

/// A method lookup function for a class. The pointer is a ClassDecl*.
MethodLookupFunction,

/// A resilient enum tag index. The pointer is a EnumElementDecl*.
EnumCase,

Expand Down Expand Up @@ -482,6 +485,12 @@ class LinkEntity {
return entity;
}

static LinkEntity forMethodLookupFunction(ClassDecl *classDecl) {
LinkEntity entity;
entity.setForDecl(Kind::MethodLookupFunction, classDecl);
return entity;
}

static LinkEntity forFieldOffset(VarDecl *decl) {
LinkEntity entity;
entity.setForDecl(Kind::FieldOffset, decl);
Expand Down
9 changes: 9 additions & 0 deletions include/swift/Runtime/Metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,15 @@ void swift_initClassMetadata(ClassMetadata *self,
const TypeLayout * const *fieldTypes,
size_t *fieldOffsets);

/// Given class metadata, a class descriptor and a method descriptor, look up
/// and load the vtable entry from the given metadata. The metadata must be of
/// the same class or a subclass of the descriptor.
SWIFT_RUNTIME_EXPORT
void *
swift_lookUpClassMethod(ClassMetadata *metadata,
MethodDescriptor *method,
ClassDescriptor *description);

/// \brief Fetch a uniqued metadata for a metatype type.
SWIFT_RUNTIME_EXPORT
const MetatypeMetadata *
Expand Down
11 changes: 11 additions & 0 deletions include/swift/Runtime/RuntimeFunctions.def
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,17 @@ FUNCTION(InitClassMetadata,
SizeTy->getPointerTo()),
ATTRS(NoUnwind))

// void *swift_lookUpClassMethod(Metadata *metadata,
// ClassDescriptor *description,
// MethodDescriptor *method);
FUNCTION(LookUpClassMethod,
swift_lookUpClassMethod, C_CC,
RETURNS(Int8PtrTy),
ARGS(TypeMetadataPtrTy,
MethodDescriptorStructTy->getPointerTo(),
TypeContextDescriptorPtrTy),
ATTRS(NoUnwind))

// void swift_initStructMetadata(Metadata *structType,
// StructLayoutFlags flags,
// size_t numFields,
Expand Down
5 changes: 5 additions & 0 deletions include/swift/SIL/SILDeclRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,11 @@ struct SILDeclRef {
/// entry overridden by this method.
SILDeclRef getOverriddenWitnessTableEntry() const;

/// Return the original protocol requirement that introduced the witness table
/// entry overridden by this method.
static AbstractFunctionDecl *getOverriddenWitnessTableEntry(
AbstractFunctionDecl *func);

/// True if the referenced entity is some kind of thunk.
bool isThunk() const;

Expand Down
5 changes: 3 additions & 2 deletions lib/AST/ASTWalker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1571,8 +1571,9 @@ Pattern *Traversal::visitTypedPattern(TypedPattern *P) {
else
return nullptr;
if (!P->isImplicit())
if (doIt(P->getTypeLoc()))
return nullptr;
if (auto *TR = P->getTypeRepr())
if (doIt(TR))
return nullptr;
return P;
}

Expand Down
57 changes: 54 additions & 3 deletions lib/AST/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1005,14 +1005,65 @@ bool ModuleDecl::isSameAccessPath(AccessPathTy lhs, AccessPathTy rhs) {
});
}

ModuleDecl::ReverseFullNameIterator::ReverseFullNameIterator(
const ModuleDecl *M) {
assert(M);
// Note: This will look through overlays as well, but that's fine for name
// generation purposes. The point of an overlay is to
if (auto *clangModule = M->findUnderlyingClangModule())
current = clangModule;
else
current = M;
}

StringRef ModuleDecl::ReverseFullNameIterator::operator*() const {
assert(current && "all name components exhausted");

if (auto *swiftModule = current.dyn_cast<const ModuleDecl *>())
return swiftModule->getName().str();

auto *clangModule =
static_cast<const clang::Module *>(current.get<const void *>());
return clangModule->Name;
}

ModuleDecl::ReverseFullNameIterator &
ModuleDecl::ReverseFullNameIterator::operator++() {
if (!current)
return *this;

if (auto *swiftModule = current.dyn_cast<const ModuleDecl *>()) {
current = nullptr;
return *this;
}

auto *clangModule =
static_cast<const clang::Module *>(current.get<const void *>());
if (clangModule->Parent)
current = clangModule->Parent;
else
current = nullptr;
return *this;
}

void
ModuleDecl::ReverseFullNameIterator::printForward(raw_ostream &out) const {
SmallVector<StringRef, 8> elements(*this, {});
swift::interleave(swift::reversed(elements),
[&out](StringRef next) { out << next; },
[&out] { out << '.'; });
}

void
ModuleDecl::removeDuplicateImports(SmallVectorImpl<ImportedModule> &imports) {
std::sort(imports.begin(), imports.end(),
[](const ImportedModule &lhs, const ImportedModule &rhs) -> bool {
// Arbitrarily sort by name to get a deterministic order.
// FIXME: Submodules don't get sorted properly here.
if (lhs.second != rhs.second)
return lhs.second->getName().str() < rhs.second->getName().str();
if (lhs.second != rhs.second) {
return std::lexicographical_compare(
lhs.second->getReverseFullModuleName(), {},
rhs.second->getReverseFullModuleName(), {});
}
using AccessPathElem = std::pair<Identifier, SourceLoc>;
return std::lexicographical_compare(lhs.first.begin(), lhs.first.end(),
rhs.first.begin(), rhs.first.end(),
Expand Down
Loading