Skip to content

Commit

Permalink
Merge branch 'master' into prespecialize-enum
Browse files Browse the repository at this point in the history
  • Loading branch information
moiseev authored Jan 10, 2018
2 parents 2093df6 + ea848d9 commit e13ec74
Show file tree
Hide file tree
Showing 130 changed files with 1,198 additions and 694 deletions.
2 changes: 1 addition & 1 deletion include/swift/AST/KnownIdentifiers.def
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ IDENTIFIER(stringValue)
IDENTIFIER(super)
IDENTIFIER(superDecoder)
IDENTIFIER(superEncoder)
IDENTIFIER(SwiftObject)
IDENTIFIER_WITH_NAME(SwiftObject, "_TtCs12_SwiftObject")
IDENTIFIER(to)
IDENTIFIER(toRaw)
IDENTIFIER(Type)
Expand Down
17 changes: 11 additions & 6 deletions include/swift/Demangling/Demangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,26 +221,31 @@ class Node {
/// Returns the length of the swift mangling prefix of the \p SymbolName.
///
/// Returns 0 if \p SymbolName is not a mangled swift (>= swift 4.x) name.
int getManglingPrefixLength(const char *mangledName);
int getManglingPrefixLength(llvm::StringRef mangledName);

/// Returns true if \p SymbolName is a mangled swift name.
///
/// This does not include the old (<= swift 3.x) mangling prefix "_T".
inline bool isMangledName(llvm::StringRef MangledName) {
return getManglingPrefixLength(MangledName.data()) != 0;
inline bool isMangledName(llvm::StringRef mangledName) {
return getManglingPrefixLength(mangledName) != 0;
}

/// Returns true if the mangledName starts with the swift mangling prefix.
///
/// This includes the old (<= swift 3.x) mangling prefix "_T".
/// \param mangledName A null-terminated string containing a mangled name.
bool isSwiftSymbol(const char *mangledName);
bool isSwiftSymbol(llvm::StringRef mangledName);

/// Drops the Swift mangling prefix from the given mangled name, if there is
/// one.
///
/// This does not include the old (<= swift 3.x) mangling prefix "_T".
llvm::StringRef dropSwiftManglingPrefix(llvm::StringRef mangledName);

/// Returns true if the mangled name has the old scheme of function type
/// mangling where labels are part of the type.
///
/// \param mangledName A null-terminated string containing a mangled name.
bool isOldFunctionTypeMangling(const char *mangledName);
bool isOldFunctionTypeMangling(llvm::StringRef mangledName);

class Demangler;

Expand Down
117 changes: 49 additions & 68 deletions include/swift/Demangling/TypeDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ template <typename BuilderType>
class TypeDecoder {
using BuiltType = typename BuilderType::BuiltType;
using BuiltNominalTypeDecl = typename BuilderType::BuiltNominalTypeDecl;
using BuiltProtocolDecl = typename BuilderType::BuiltProtocolDecl;
using NodeKind = Demangle::Node::Kind;

BuilderType &Builder;
Expand Down Expand Up @@ -175,92 +176,57 @@ class TypeDecoder {
return nullptr;
}
}
case NodeKind::ProtocolList: {
case NodeKind::ProtocolList:
case NodeKind::ProtocolListWithAnyObject:
case NodeKind::ProtocolListWithClass: {
if (Node->getNumChildren() < 1)
return BuiltType();

std::vector<BuiltType> protocols;
// Find the protocol list.
std::vector<BuiltProtocolDecl> Protocols;
auto TypeList = Node->getChild(0);
for (auto componentType : *TypeList) {
if (auto protocol = decodeMangledType(componentType))
protocols.push_back(protocol);
else
return BuiltType();
if (TypeList->getKind() == NodeKind::ProtocolList &&
TypeList->getNumChildren() >= 1) {
TypeList = TypeList->getChild(0);
}
if (protocols.size() == 1)
return protocols.front();
return Builder.createProtocolCompositionType(
protocols,
/*hasExplicitAnyObject=*/false);
}
case NodeKind::ProtocolListWithAnyObject: {
if (Node->getNumChildren() < 1)
return BuiltType();

std::vector<BuiltType> protocols;
auto ProtocolList = Node->getChild(0);
auto TypeList = ProtocolList->getChild(0);
// Demangle the protocol list.
for (auto componentType : *TypeList) {
if (auto protocol = decodeMangledType(componentType))
protocols.push_back(protocol);
if (auto Protocol = decodeMangledProtocolType(componentType))
Protocols.push_back(Protocol);
else
return BuiltType();
}
return Builder.createProtocolCompositionType(
protocols,
/*hasExplicitAnyObject=*/true);
}
case NodeKind::ProtocolListWithClass: {
if (Node->getNumChildren() < 2)
return BuiltType();

std::vector<BuiltType> members;
auto ProtocolList = Node->getChild(0);
auto TypeList = ProtocolList->getChild(0);
for (auto componentType : *TypeList) {
if (auto protocol = decodeMangledType(componentType))
members.push_back(protocol);
else
// Superclass or AnyObject, if present.
bool IsClassBound = false;
auto Superclass = BuiltType();
if (Node->getKind() == NodeKind::ProtocolListWithClass) {
if (Node->getNumChildren() < 2)
return BuiltType();
}

auto SuperclassNode = Node->getChild(1);
if (auto superclass = decodeMangledType(SuperclassNode))
members.push_back(superclass);
auto superclassNode = Node->getChild(1);
Superclass = decodeMangledType(superclassNode);
if (!Superclass) return BuiltType();

IsClassBound = true;
} else if (Node->getKind() == NodeKind::ProtocolListWithAnyObject) {
IsClassBound = true;
}

return Builder.createProtocolCompositionType(
members,
/*hasExplicitAnyObject=*/true);
return Builder.createProtocolCompositionType(Protocols, Superclass,
IsClassBound);
}
case NodeKind::Protocol: {
if (Node->getNumChildren() < 2)
return BuiltType();

auto moduleName = Node->getChild(0)->getText();
auto nameNode = Node->getChild(1);
std::string privateDiscriminator, name;
if (nameNode->getKind() == NodeKind::PrivateDeclName) {
privateDiscriminator = nameNode->getChild(0)->getText();
name = nameNode->getChild(1)->getText();
} else if (nameNode->getKind() == NodeKind::Identifier) {
name = Node->getChild(1)->getText();
} else {
return BuiltType();
case NodeKind::Protocol: {
if (auto Proto = decodeMangledProtocolType(Node)) {
return Builder.createProtocolCompositionType(Proto, BuiltType(),
/*IsClassBound=*/false);
}

// Consistent handling of protocols and protocol compositions
Demangle::Demangler Dem;
auto protocolList = Dem.createNode(NodeKind::ProtocolList);
auto typeList = Dem.createNode(NodeKind::TypeList);
auto type = Dem.createNode(NodeKind::Type);
type->addChild(Node, Dem);
typeList->addChild(type, Dem);
protocolList->addChild(typeList, Dem);

auto mangledName = Demangle::mangleNode(protocolList);
return Builder.createProtocolType(mangledName, moduleName,
privateDiscriminator, name);
return BuiltType();
}

case NodeKind::DependentGenericParamType: {
auto depth = Node->getChild(0)->getIndex();
auto index = Node->getChild(1)->getIndex();
Expand Down Expand Up @@ -425,7 +391,11 @@ class TypeDecoder {
if (!base)
return BuiltType();
auto member = Node->getChild(1)->getText();
auto protocol = decodeMangledType(Node->getChild(1));
auto assocTypeChild = Node->getChild(1);
if (assocTypeChild->getNumChildren() < 1)
return BuiltType();

auto protocol = decodeMangledProtocolType(assocTypeChild->getChild(0));
if (!protocol)
return BuiltType();
return Builder.createDependentMemberType(member, base, protocol);
Expand Down Expand Up @@ -510,6 +480,17 @@ class TypeDecoder {
return true;
}

BuiltProtocolDecl decodeMangledProtocolType(
const Demangle::NodePointer &node) {
if (node->getKind() == NodeKind::Type)
return decodeMangledProtocolType(node->getChild(0));

if (node->getNumChildren() < 2 || node->getKind() != NodeKind::Protocol)
return BuiltProtocolDecl();

return Builder.createProtocolDecl(node);
}

bool decodeMangledFunctionInputType(
const Demangle::NodePointer &node,
std::vector<FunctionParam<BuiltType>> &params,
Expand Down
1 change: 1 addition & 0 deletions include/swift/IDE/SyntaxModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ enum class SyntaxStructureKind : uint8_t {
TypeAlias,
Subscript,
AssociatedType,
GenericTypeParam,

ForEachStatement,
WhileStatement,
Expand Down
90 changes: 32 additions & 58 deletions include/swift/Reflection/TypeRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@ class NominalTypeTrait {
bool isStruct() const;
bool isEnum() const;
bool isClass() const;
bool isProtocol() const;

bool isErrorProtocol() const {
return MangledName == "s5ErrorP";
}

const TypeRef *getParent() const {
return Parent;
Expand Down Expand Up @@ -379,76 +384,45 @@ class FunctionTypeRef final : public TypeRef {
}
};

class ProtocolTypeRef final : public TypeRef {
std::string MangledName;

static TypeRefID Profile(const std::string &MangledName) {
TypeRefID ID;
ID.addString(MangledName);
return ID;
}
public:
ProtocolTypeRef(const std::string &MangledName)
: TypeRef(TypeRefKind::Protocol), MangledName(MangledName) {}

template <typename Allocator>
static const ProtocolTypeRef *
create(Allocator &A, const std::string &MangledName) {
FIND_OR_CREATE_TYPEREF(A, ProtocolTypeRef, MangledName);
}

bool isError() const {
return MangledName == "s5Error_p";
}

const std::string &getMangledName() const {
return MangledName;
}

static bool classof(const TypeRef *TR) {
return TR->getKind() == TypeRefKind::Protocol;
}

bool operator==(const ProtocolTypeRef &Other) const {
return MangledName == Other.MangledName;
}
bool operator!=(const ProtocolTypeRef &Other) const {
return !(*this == Other);
}
};

class ProtocolCompositionTypeRef final : public TypeRef {
std::vector<const TypeRef *> Members;
std::vector<const NominalTypeRef *> Protocols;
const TypeRef *Superclass;
bool HasExplicitAnyObject;

static TypeRefID Profile(const std::vector<const TypeRef *> &Members,
static TypeRefID Profile(std::vector<const NominalTypeRef *> Protocols,
const TypeRef *Superclass,
bool HasExplicitAnyObject) {
TypeRefID ID;
ID.addInteger((uint32_t)HasExplicitAnyObject);
for (auto Member : Members) {
ID.addPointer(Member);
for (auto Protocol : Protocols) {
ID.addPointer(Protocol);
}
ID.addPointer(Superclass);
return ID;
}

public:
ProtocolCompositionTypeRef(std::vector<const TypeRef *> Members,
bool HasExplicitAnyObject)
ProtocolCompositionTypeRef(std::vector<const NominalTypeRef *> Protocols,
const TypeRef *Superclass,
bool HasExplicitAnyObject)
: TypeRef(TypeRefKind::ProtocolComposition),
Members(Members), HasExplicitAnyObject(HasExplicitAnyObject) {}
Protocols(Protocols), Superclass(Superclass),
HasExplicitAnyObject(HasExplicitAnyObject) {}

template <typename Allocator>
static const ProtocolCompositionTypeRef *
create(Allocator &A, std::vector<const TypeRef *> Members,
bool HasExplicitAnyObject) {
FIND_OR_CREATE_TYPEREF(A, ProtocolCompositionTypeRef, Members,
HasExplicitAnyObject);
create(Allocator &A, std::vector<const NominalTypeRef *> Protocols,
const TypeRef *Superclass, bool HasExplicitAnyObject) {
FIND_OR_CREATE_TYPEREF(A, ProtocolCompositionTypeRef, Protocols,
Superclass, HasExplicitAnyObject);
}

const std::vector<const TypeRef *> &getMembers() const {
return Members;
const std::vector<const NominalTypeRef *> &getProtocols() const {
return Protocols;
}

const TypeRef *getSuperclass() const { return Superclass; }

bool hasExplicitAnyObject() const {
return HasExplicitAnyObject;
}
Expand Down Expand Up @@ -558,28 +532,28 @@ class GenericTypeParameterTypeRef final : public TypeRef {
class DependentMemberTypeRef final : public TypeRef {
std::string Member;
const TypeRef *Base;
const TypeRef *Protocol;
std::string Protocol;

static TypeRefID Profile(const std::string &Member, const TypeRef *Base,
const TypeRef *Protocol) {
const std::string &Protocol) {
TypeRefID ID;
ID.addString(Member);
ID.addPointer(Base);
ID.addPointer(Protocol);
ID.addString(Protocol);
return ID;
}

public:

DependentMemberTypeRef(const std::string &Member, const TypeRef *Base,
const TypeRef *Protocol)
const std::string &Protocol)
: TypeRef(TypeRefKind::DependentMember), Member(Member), Base(Base),
Protocol(Protocol) {}

template <typename Allocator>
static const DependentMemberTypeRef *
create(Allocator &A, const std::string &Member,
const TypeRef *Base, const TypeRef *Protocol) {
const TypeRef *Base, const std::string &Protocol) {
FIND_OR_CREATE_TYPEREF(A, DependentMemberTypeRef, Member, Base, Protocol);
}

Expand All @@ -591,8 +565,8 @@ class DependentMemberTypeRef final : public TypeRef {
return Base;
}

const ProtocolTypeRef *getProtocol() const {
return cast<ProtocolTypeRef>(Protocol);
const std::string &getProtocol() const {
return Protocol;
}

static bool classof(const TypeRef *TR) {
Expand Down
Loading

0 comments on commit e13ec74

Please sign in to comment.