mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[AST] Break down IdentTypeRepr to different subtypes.
This makes memory allocation for it more efficient and it's more convenient to handle. Swift SVN r12541
This commit is contained in:
@@ -135,6 +135,7 @@ public:
|
||||
return static_cast<ImplClass*>(this)->visit##PARENT(T, \
|
||||
::std::forward<Args>(AA)...); \
|
||||
}
|
||||
#define ABSTRACT_TYPEREPR(CLASS, PARENT) TYPEREPR(CLASS, PARENT)
|
||||
#include "swift/AST/TypeReprNodes.def"
|
||||
};
|
||||
|
||||
|
||||
@@ -144,38 +144,53 @@ private:
|
||||
friend class TypeRepr;
|
||||
};
|
||||
|
||||
/// \brief A type with identifier components.
|
||||
class ComponentIdentTypeRepr;
|
||||
|
||||
/// \brief This is the abstract base class for types with identifier components.
|
||||
/// \code
|
||||
/// Foo.Bar<Gen>
|
||||
/// \endcode
|
||||
/// FIXME: Investigate splitting into a TypeRepr for each component,
|
||||
/// so that "Int" does not need an allocation for the components array and the
|
||||
/// generic arguments info.
|
||||
class IdentTypeRepr : public TypeRepr {
|
||||
protected:
|
||||
explicit IdentTypeRepr(TypeReprKind K) : TypeRepr(K) {}
|
||||
|
||||
public:
|
||||
class Component {
|
||||
/// Copies the provided array and creates a CompoundIdentTypeRepr or just
|
||||
/// returns the single entry in the array if it contains only one.
|
||||
static IdentTypeRepr *create(ASTContext &C,
|
||||
ArrayRef<ComponentIdentTypeRepr *> Components);
|
||||
|
||||
class ComponentRange;
|
||||
inline ComponentRange getComponentRange();
|
||||
|
||||
static bool classof(const TypeRepr *T) {
|
||||
return T->getKind() == TypeReprKind::SimpleIdent ||
|
||||
T->getKind() == TypeReprKind::GenericIdent ||
|
||||
T->getKind() == TypeReprKind::CompoundIdent;
|
||||
}
|
||||
static bool classof(const IdentTypeRepr *T) { return true; }
|
||||
};
|
||||
|
||||
class ComponentIdentTypeRepr : public IdentTypeRepr {
|
||||
SourceLoc Loc;
|
||||
Identifier Id;
|
||||
MutableArrayRef<TypeRepr*> GenericArgs;
|
||||
|
||||
/// Value is the decl, type, or module that this refers to.
|
||||
///
|
||||
/// After name binding, the value is set to the decl being referenced, and
|
||||
/// the last entry in the component list is known to be a Type.
|
||||
/// After name binding, the value is set to the decl being referenced.
|
||||
///
|
||||
/// FIXME: Can we sneak the Id into this union?
|
||||
llvm::PointerUnion3<ValueDecl*, Type, Module*> Value;
|
||||
|
||||
public:
|
||||
Component(SourceLoc Loc, Identifier Id,
|
||||
MutableArrayRef<TypeRepr*> GenericArgs) :
|
||||
Loc(Loc), Id(Id), GenericArgs(GenericArgs) {}
|
||||
protected:
|
||||
ComponentIdentTypeRepr(TypeReprKind K, SourceLoc Loc, Identifier Id)
|
||||
: IdentTypeRepr(K), Loc(Loc), Id(Id) {}
|
||||
|
||||
public:
|
||||
SourceLoc getIdLoc() const { return Loc; }
|
||||
Identifier getIdentifier() const { return Id; }
|
||||
MutableArrayRef<TypeRepr*> getGenericArgs() const { return GenericArgs; }
|
||||
|
||||
/// Return true if this Component has been name-bound already.
|
||||
/// Return true if this has been name-bound already.
|
||||
bool isBound() const { return !Value.isNull(); }
|
||||
bool isBoundDecl() const { return Value.is<ValueDecl*>() && isBound(); }
|
||||
bool isBoundType() const { return Value.is<Type>() && isBound(); }
|
||||
@@ -196,37 +211,121 @@ public:
|
||||
void setValue(Module *M) { Value = M; }
|
||||
|
||||
void revert() { Value = (ValueDecl*)nullptr; }
|
||||
};
|
||||
|
||||
public:
|
||||
const MutableArrayRef<Component> Components;
|
||||
|
||||
IdentTypeRepr(MutableArrayRef<Component> Components)
|
||||
: TypeRepr(TypeReprKind::Ident), Components(Components) {
|
||||
assert(!Components.empty());
|
||||
}
|
||||
|
||||
static IdentTypeRepr *create(ASTContext &C, ArrayRef<Component> Components);
|
||||
|
||||
static IdentTypeRepr *createSimple(ASTContext &C, SourceLoc Loc,
|
||||
Identifier Id);
|
||||
|
||||
static bool classof(const TypeRepr *T) {
|
||||
return T->getKind() == TypeReprKind::Ident;
|
||||
return T->getKind() == TypeReprKind::SimpleIdent ||
|
||||
T->getKind() == TypeReprKind::GenericIdent;
|
||||
}
|
||||
static bool classof(const IdentTypeRepr *T) { return true; }
|
||||
static bool classof(const ComponentIdentTypeRepr *T) { return true; }
|
||||
|
||||
protected:
|
||||
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
|
||||
};
|
||||
|
||||
/// \brief A simple identifier type like "Int".
|
||||
class SimpleIdentTypeRepr : public ComponentIdentTypeRepr {
|
||||
public:
|
||||
SimpleIdentTypeRepr(SourceLoc Loc, Identifier Id)
|
||||
: ComponentIdentTypeRepr(TypeReprKind::SimpleIdent, Loc, Id) {}
|
||||
|
||||
static bool classof(const TypeRepr *T) {
|
||||
return T->getKind() == TypeReprKind::SimpleIdent;
|
||||
}
|
||||
static bool classof(const SimpleIdentTypeRepr *T) { return true; }
|
||||
|
||||
private:
|
||||
SourceLoc getStartLocImpl() const { return Components.front().getIdLoc(); }
|
||||
SourceLoc getEndLocImpl() const {
|
||||
if (!Components.back().getGenericArgs().empty())
|
||||
return Components.back().getGenericArgs().back()->getEndLoc();
|
||||
return Components.back().getIdLoc();
|
||||
SourceLoc getStartLocImpl() const { return getIdLoc(); }
|
||||
SourceLoc getEndLocImpl() const { return getIdLoc(); }
|
||||
friend class TypeRepr;
|
||||
};
|
||||
|
||||
/// \brief An identifier type with generic arguments.
|
||||
/// \code
|
||||
/// Bar<Gen>
|
||||
/// \endcode
|
||||
class GenericIdentTypeRepr : public ComponentIdentTypeRepr {
|
||||
ArrayRef<TypeRepr*> GenericArgs;
|
||||
|
||||
public:
|
||||
GenericIdentTypeRepr(SourceLoc Loc, Identifier Id,
|
||||
ArrayRef<TypeRepr*> GenericArgs)
|
||||
: ComponentIdentTypeRepr(TypeReprKind::GenericIdent, Loc, Id),
|
||||
GenericArgs(GenericArgs) {
|
||||
assert(!GenericArgs.empty());
|
||||
}
|
||||
|
||||
ArrayRef<TypeRepr*> getGenericArgs() const { return GenericArgs; }
|
||||
|
||||
static bool classof(const TypeRepr *T) {
|
||||
return T->getKind() == TypeReprKind::GenericIdent;
|
||||
}
|
||||
static bool classof(const GenericIdentTypeRepr *T) { return true; }
|
||||
|
||||
private:
|
||||
SourceLoc getStartLocImpl() const { return getIdLoc(); }
|
||||
SourceLoc getEndLocImpl() const { return GenericArgs.back()->getEndLoc(); }
|
||||
friend class TypeRepr;
|
||||
};
|
||||
|
||||
/// \brief A type with identifier components.
|
||||
/// \code
|
||||
/// Foo.Bar<Gen>
|
||||
/// \endcode
|
||||
class CompoundIdentTypeRepr : public IdentTypeRepr {
|
||||
public:
|
||||
const ArrayRef<ComponentIdentTypeRepr *> Components;
|
||||
|
||||
explicit CompoundIdentTypeRepr(ArrayRef<ComponentIdentTypeRepr *> Components)
|
||||
: IdentTypeRepr(TypeReprKind::CompoundIdent),
|
||||
Components(Components) {
|
||||
assert(Components.size() > 1 &&
|
||||
"should have just used the single ComponentIdentTypeRepr directly");
|
||||
}
|
||||
|
||||
static bool classof(const TypeRepr *T) {
|
||||
return T->getKind() == TypeReprKind::CompoundIdent;
|
||||
}
|
||||
static bool classof(const CompoundIdentTypeRepr *T) { return true; }
|
||||
|
||||
private:
|
||||
SourceLoc getStartLocImpl() const { return Components.front()->getStartLoc();}
|
||||
SourceLoc getEndLocImpl() const { return Components.back()->getEndLoc(); }
|
||||
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
|
||||
friend class TypeRepr;
|
||||
};
|
||||
|
||||
/// This wraps an IdentTypeRepr and provides an iterator interface for the
|
||||
/// components (or the single component) it represents.
|
||||
class IdentTypeRepr::ComponentRange {
|
||||
IdentTypeRepr *IdT;
|
||||
|
||||
public:
|
||||
explicit ComponentRange(IdentTypeRepr *T) : IdT(T) {}
|
||||
|
||||
typedef ComponentIdentTypeRepr * const* iterator;
|
||||
|
||||
iterator begin() const {
|
||||
if (isa<ComponentIdentTypeRepr>(IdT))
|
||||
return reinterpret_cast<iterator>(&IdT);
|
||||
return cast<CompoundIdentTypeRepr>(IdT)->Components.begin();
|
||||
}
|
||||
|
||||
iterator end() const {
|
||||
if (isa<ComponentIdentTypeRepr>(IdT))
|
||||
return reinterpret_cast<iterator>(&IdT) + 1;
|
||||
return cast<CompoundIdentTypeRepr>(IdT)->Components.end();
|
||||
}
|
||||
|
||||
bool empty() const { return begin() == end(); }
|
||||
|
||||
ComponentIdentTypeRepr *front() const { return *begin(); }
|
||||
ComponentIdentTypeRepr *back() const { return *(end()-1); }
|
||||
};
|
||||
|
||||
inline IdentTypeRepr::ComponentRange IdentTypeRepr::getComponentRange() {
|
||||
return ComponentRange(this);
|
||||
}
|
||||
|
||||
/// \brief A function type.
|
||||
/// \code
|
||||
/// Foo -> Bar
|
||||
@@ -469,7 +568,9 @@ inline bool TypeRepr::isSimple() const {
|
||||
case TypeReprKind::Function:
|
||||
case TypeReprKind::Array:
|
||||
return false;
|
||||
case TypeReprKind::Ident:
|
||||
case TypeReprKind::SimpleIdent:
|
||||
case TypeReprKind::GenericIdent:
|
||||
case TypeReprKind::CompoundIdent:
|
||||
case TypeReprKind::Metatype:
|
||||
case TypeReprKind::Named:
|
||||
case TypeReprKind::Optional:
|
||||
|
||||
@@ -21,9 +21,25 @@
|
||||
# error Included TypeReprNodes.def without defining TYPEREPR!
|
||||
#endif
|
||||
|
||||
/// An abstract node is an abstract base class in the hierarchy;
|
||||
/// it is never a most-derived type, and it does not have an enumerator in
|
||||
/// TypeReprKind.
|
||||
///
|
||||
/// Most metaprograms do not care about abstract classes, so the default
|
||||
/// is to ignore them.
|
||||
#ifndef ABSTRACT_TYPEREPR
|
||||
#define ABSTRACT_TYPEREPR(Id, Parent)
|
||||
#endif
|
||||
|
||||
TYPEREPR(Error, TypeRepr)
|
||||
TYPEREPR(Attributed, TypeRepr)
|
||||
TYPEREPR(Ident, TypeRepr)
|
||||
|
||||
ABSTRACT_TYPEREPR(Ident, TypeRepr)
|
||||
ABSTRACT_TYPEREPR(ComponentIdent, IdentTypeRepr)
|
||||
TYPEREPR(SimpleIdent, ComponentIdentTypeRepr)
|
||||
TYPEREPR(GenericIdent, ComponentIdentTypeRepr)
|
||||
TYPEREPR(CompoundIdent, IdentTypeRepr)
|
||||
|
||||
TYPEREPR(Function, TypeRepr)
|
||||
TYPEREPR(Array, TypeRepr)
|
||||
TYPEREPR(Optional, TypeRepr)
|
||||
@@ -32,4 +48,5 @@ TYPEREPR(Named, TypeRepr)
|
||||
TYPEREPR(ProtocolComposition, TypeRepr)
|
||||
TYPEREPR(Metatype, TypeRepr)
|
||||
|
||||
#undef ABSTRACT_TYPEREPR
|
||||
#undef TYPEREPR
|
||||
|
||||
@@ -1515,21 +1515,23 @@ public:
|
||||
void visitIdentTypeRepr(IdentTypeRepr *T) {
|
||||
printCommon(T, "type_ident");
|
||||
Indent += 2;
|
||||
for (auto &comp : T->Components) {
|
||||
for (auto comp : T->getComponentRange()) {
|
||||
OS << '\n';
|
||||
printCommon(nullptr, "component");
|
||||
OS << " id='" << comp.getIdentifier() << '\'';
|
||||
OS << " id='" << comp->getIdentifier() << '\'';
|
||||
OS << " bind=";
|
||||
if (comp.isBoundDecl()) OS << "decl";
|
||||
else if (comp.isBoundModule()) OS << "module";
|
||||
else if (comp.isBoundType()) OS << "type";
|
||||
if (comp->isBoundDecl()) OS << "decl";
|
||||
else if (comp->isBoundModule()) OS << "module";
|
||||
else if (comp->isBoundType()) OS << "type";
|
||||
else OS << "none";
|
||||
OS << ')';
|
||||
for (auto genArg : comp.getGenericArgs()) {
|
||||
if (auto GenIdT = dyn_cast<GenericIdentTypeRepr>(comp)) {
|
||||
for (auto genArg : GenIdT->getGenericArgs()) {
|
||||
OS << '\n';
|
||||
printRec(genArg);
|
||||
}
|
||||
}
|
||||
}
|
||||
OS << ')';
|
||||
Indent -= 2;
|
||||
}
|
||||
|
||||
@@ -1066,12 +1066,22 @@ bool Traversal::visitAttributedTypeRepr(AttributedTypeRepr *T) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Traversal::visitIdentTypeRepr(IdentTypeRepr *T) {
|
||||
for (auto &comp : T->Components) {
|
||||
for (auto genArg : comp.getGenericArgs()) {
|
||||
bool Traversal::visitSimpleIdentTypeRepr(SimpleIdentTypeRepr *T) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Traversal::visitGenericIdentTypeRepr(GenericIdentTypeRepr *T) {
|
||||
for (auto genArg : T->getGenericArgs()) {
|
||||
if (doIt(genArg))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Traversal::visitCompoundIdentTypeRepr(CompoundIdentTypeRepr *T) {
|
||||
for (auto comp : T->Components) {
|
||||
if (doIt(comp))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -649,17 +649,17 @@ public:
|
||||
return true;
|
||||
|
||||
// For each of the components...
|
||||
for (auto &comp : identRepr->Components) {
|
||||
for (auto comp : identRepr->getComponentRange()) {
|
||||
// If there is no type binding, we don't care.
|
||||
if (!comp.isBoundType())
|
||||
if (!comp->isBoundType())
|
||||
continue;
|
||||
|
||||
// If there are no generic arguments, we don't care.
|
||||
if (comp.getGenericArgs().empty())
|
||||
if (!isa<GenericIdentTypeRepr>(comp))
|
||||
continue;
|
||||
|
||||
// If it's not a bound generic type, we don't care.
|
||||
auto boundGeneric = comp.getBoundType()->getAs<BoundGenericType>();
|
||||
auto boundGeneric = comp->getBoundType()->getAs<BoundGenericType>();
|
||||
if (!boundGeneric)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -728,11 +728,10 @@ void NominalTypeDecl::computeType() {
|
||||
auto selfId = ctx.getIdentifier("Self");
|
||||
auto selfDecl = new (ctx) GenericTypeParamDecl(proto, selfId,
|
||||
proto->getLoc(), 0, 0);
|
||||
IdentTypeRepr::Component protoRef(proto->getLoc(), proto->getName(), { });
|
||||
protoRef.setValue(proto);
|
||||
TypeLoc selfInherited[1] = {
|
||||
TypeLoc(IdentTypeRepr::create(ctx, protoRef))
|
||||
};
|
||||
auto protoRef = new (ctx) SimpleIdentTypeRepr(proto->getLoc(),
|
||||
proto->getName());
|
||||
protoRef->setValue(proto);
|
||||
TypeLoc selfInherited[1] = { TypeLoc(protoRef) };
|
||||
selfInherited[0].setType(DeclaredTy);
|
||||
selfDecl->setInherited(ctx.AllocateCopy(selfInherited));
|
||||
selfDecl->setImplicit();
|
||||
|
||||
@@ -104,28 +104,27 @@ TypeRepr *CloneVisitor::visitAttributedTypeRepr(AttributedTypeRepr *T) {
|
||||
return new (Ctx) AttributedTypeRepr(T->getAttrs(), visit(T->getTypeRepr()));
|
||||
}
|
||||
|
||||
TypeRepr *CloneVisitor::visitIdentTypeRepr(IdentTypeRepr *T) {
|
||||
// Clone the components.
|
||||
auto componentsMem = (IdentTypeRepr::Component*)
|
||||
Ctx.Allocate(sizeof(IdentTypeRepr::Component) * T->Components.size(),
|
||||
alignof(IdentTypeRepr::Component));
|
||||
|
||||
MutableArrayRef<IdentTypeRepr::Component> components(componentsMem,
|
||||
T->Components.size());
|
||||
for (unsigned i : indices(components)) {
|
||||
auto &old = T->Components[i];
|
||||
TypeRepr *CloneVisitor::visitSimpleIdentTypeRepr(SimpleIdentTypeRepr *T) {
|
||||
return new (Ctx) SimpleIdentTypeRepr(T->getIdLoc(), T->getIdentifier());
|
||||
}
|
||||
|
||||
TypeRepr *CloneVisitor::visitGenericIdentTypeRepr(GenericIdentTypeRepr *T) {
|
||||
// Clone the generic arguments.
|
||||
auto genericArgs = Ctx.Allocate<TypeRepr*>(old.getGenericArgs().size());
|
||||
auto genericArgs = Ctx.Allocate<TypeRepr*>(T->getGenericArgs().size());
|
||||
for (unsigned argI : indices(genericArgs)) {
|
||||
genericArgs[argI] = visit(old.getGenericArgs()[argI]);
|
||||
genericArgs[argI] = visit(T->getGenericArgs()[argI]);
|
||||
}
|
||||
|
||||
new (&components[i]) IdentTypeRepr::Component(old.getIdLoc(),
|
||||
old.getIdentifier(),
|
||||
return new (Ctx) GenericIdentTypeRepr(T->getIdLoc(), T->getIdentifier(),
|
||||
genericArgs);
|
||||
}
|
||||
|
||||
TypeRepr *CloneVisitor::visitCompoundIdentTypeRepr(CompoundIdentTypeRepr *T) {
|
||||
// Clone the components.
|
||||
auto components = Ctx.Allocate<ComponentIdentTypeRepr*>(T->Components.size());
|
||||
for (unsigned I : indices(components)) {
|
||||
components[I] = cast<ComponentIdentTypeRepr>(visit(T->Components[I]));
|
||||
}
|
||||
return new (Ctx) IdentTypeRepr(components);
|
||||
return new (Ctx) CompoundIdentTypeRepr(components);
|
||||
}
|
||||
|
||||
TypeRepr *CloneVisitor::visitFunctionTypeRepr(FunctionTypeRepr *T) {
|
||||
@@ -207,14 +206,12 @@ void AttributedTypeRepr::printAttrs(ASTPrinter &Printer) const {
|
||||
}
|
||||
|
||||
IdentTypeRepr *IdentTypeRepr::create(ASTContext &C,
|
||||
ArrayRef<Component> Components) {
|
||||
return new (C) IdentTypeRepr(C.AllocateCopy(Components));
|
||||
}
|
||||
ArrayRef<ComponentIdentTypeRepr *> Components) {
|
||||
assert(!Components.empty());
|
||||
if (Components.size() == 1)
|
||||
return Components.front();
|
||||
|
||||
IdentTypeRepr *IdentTypeRepr::createSimple(ASTContext &C, SourceLoc Loc,
|
||||
Identifier Id) {
|
||||
IdentTypeRepr::Component IdTypeComponent(Loc, Id, {});
|
||||
return create(C, llvm::makeArrayRef(IdTypeComponent));
|
||||
return new (C) CompoundIdentTypeRepr(C.AllocateCopy(Components));
|
||||
}
|
||||
|
||||
static void printGenericArgs(ASTPrinter &Printer, const PrintOptions &Opts,
|
||||
@@ -234,26 +231,28 @@ static void printGenericArgs(ASTPrinter &Printer, const PrintOptions &Opts,
|
||||
Printer << ">";
|
||||
}
|
||||
|
||||
void IdentTypeRepr::printImpl(ASTPrinter &Printer,
|
||||
void ComponentIdentTypeRepr::printImpl(ASTPrinter &Printer,
|
||||
const PrintOptions &Opts) const {
|
||||
bool isFirst = true;
|
||||
for (const Component &C : Components) {
|
||||
if (!isFirst)
|
||||
Printer << ".";
|
||||
else
|
||||
isFirst = false;
|
||||
|
||||
if (Module *Mod = C.getBoundModule()) {
|
||||
Printer.printModuleRef(Mod, C.getIdentifier().str());
|
||||
} else if (Type Ty = C.getBoundType()) {
|
||||
if (Module *Mod = getBoundModule()) {
|
||||
Printer.printModuleRef(Mod, getIdentifier().str());
|
||||
} else if (Type Ty = getBoundType()) {
|
||||
if (auto NTD = Ty->getAnyNominal())
|
||||
Printer.printTypeRef(NTD, C.getIdentifier().str());
|
||||
Printer.printTypeRef(NTD, getIdentifier().str());
|
||||
else
|
||||
Printer << C.getIdentifier().str();
|
||||
Printer << getIdentifier().str();
|
||||
} else {
|
||||
Printer << C.getIdentifier().str();
|
||||
Printer << getIdentifier().str();
|
||||
}
|
||||
printGenericArgs(Printer, Opts, C.getGenericArgs());
|
||||
if (auto GenIdT = dyn_cast<GenericIdentTypeRepr>(this))
|
||||
printGenericArgs(Printer, Opts, GenIdT->getGenericArgs());
|
||||
}
|
||||
|
||||
void CompoundIdentTypeRepr::printImpl(ASTPrinter &Printer,
|
||||
const PrintOptions &Opts) const {
|
||||
Components.front()->print(Printer, Opts);
|
||||
for (auto C : Components.slice(1)) {
|
||||
Printer << ".";
|
||||
C->print(Printer, Opts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -185,13 +185,11 @@ bool SemaAnnotator::walkToTypeReprPre(TypeRepr *T) {
|
||||
if (isDone())
|
||||
return false;
|
||||
|
||||
if (IdentTypeRepr *IdT = dyn_cast<IdentTypeRepr>(T)) {
|
||||
for (auto &Comp : IdT->Components) {
|
||||
if (ValueDecl *VD = Comp.getBoundDecl())
|
||||
return passReference(VD, Comp.getIdLoc());
|
||||
if (TypeDecl *TyD = getTypeDecl(Comp.getBoundType()))
|
||||
return passReference(TyD, Comp.getIdLoc());
|
||||
}
|
||||
if (auto IdT = dyn_cast<ComponentIdentTypeRepr>(T)) {
|
||||
if (ValueDecl *VD = IdT->getBoundDecl())
|
||||
return passReference(VD, IdT->getIdLoc());
|
||||
if (TypeDecl *TyD = getTypeDecl(IdT->getBoundType()))
|
||||
return passReference(TyD, IdT->getIdLoc());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -294,15 +294,13 @@ bool ModelASTWalker::walkToTypeReprPre(TypeRepr *T) {
|
||||
if (!handleAttrs(AttrT->getAttrs()))
|
||||
return false;
|
||||
|
||||
} else if (auto IdT = dyn_cast<IdentTypeRepr>(T)) {
|
||||
for (auto &comp : IdT->Components) {
|
||||
} else if (auto IdT = dyn_cast<ComponentIdentTypeRepr>(T)) {
|
||||
if (!passNonTokenNode({ SyntaxNodeKind::TypeId,
|
||||
CharSourceRange(comp.getIdLoc(),
|
||||
comp.getIdentifier().getLength())
|
||||
CharSourceRange(IdT->getIdLoc(),
|
||||
IdT->getIdentifier().getLength())
|
||||
}))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -919,7 +919,7 @@ ParserResult<ExtensionDecl> Parser::parseDeclExtension(unsigned Flags,
|
||||
diag::invalid_diagnostic).isError())
|
||||
return nullptr;
|
||||
Ty = makeParserErrorResult(
|
||||
IdentTypeRepr::createSimple(Context, NameLoc, ExtensionName));
|
||||
new (Context) SimpleIdentTypeRepr(NameLoc, ExtensionName));
|
||||
}
|
||||
if (Ty.isNull())
|
||||
return nullptr;
|
||||
|
||||
@@ -262,7 +262,7 @@ ParserResult<IdentTypeRepr> Parser::parseTypeIdentifier() {
|
||||
}
|
||||
|
||||
ParserStatus Status;
|
||||
SmallVector<IdentTypeRepr::Component, 4> ComponentsR;
|
||||
SmallVector<ComponentIdentTypeRepr *, 4> ComponentsR;
|
||||
SourceLoc EndLoc;
|
||||
while (true) {
|
||||
SourceLoc Loc;
|
||||
@@ -292,7 +292,13 @@ ParserResult<IdentTypeRepr> Parser::parseTypeIdentifier() {
|
||||
}
|
||||
EndLoc = Loc;
|
||||
|
||||
ComponentsR.push_back({Loc, Name, Context.AllocateCopy(GenericArgs)});
|
||||
ComponentIdentTypeRepr *CompT;
|
||||
if (!GenericArgs.empty())
|
||||
CompT = new (Context) GenericIdentTypeRepr(Loc, Name,
|
||||
Context.AllocateCopy(GenericArgs));
|
||||
else
|
||||
CompT = new (Context) SimpleIdentTypeRepr(Loc, Name);
|
||||
ComponentsR.push_back(CompT);
|
||||
}
|
||||
|
||||
// Treat 'Foo.<anything>' as an attempt to write a dotted type
|
||||
@@ -314,11 +320,11 @@ ParserResult<IdentTypeRepr> Parser::parseTypeIdentifier() {
|
||||
}
|
||||
|
||||
IdentTypeRepr *ITR = nullptr;
|
||||
if (ComponentsR.size() != 0) {
|
||||
if (!ComponentsR.empty()) {
|
||||
// Lookup element #0 through our current scope chains in case it is some thing
|
||||
// local (this returns null if nothing is found).
|
||||
if (auto Entry = lookupInScope(ComponentsR[0].getIdentifier()))
|
||||
ComponentsR[0].setValue(Entry);
|
||||
if (auto Entry = lookupInScope(ComponentsR[0]->getIdentifier()))
|
||||
ComponentsR[0]->setValue(Entry);
|
||||
|
||||
ITR = IdentTypeRepr::create(Context, ComponentsR);
|
||||
}
|
||||
|
||||
@@ -651,13 +651,13 @@ static void revertDependentTypeLoc(TypeLoc &tl) {
|
||||
if (!identType)
|
||||
return true;
|
||||
|
||||
for (auto &comp : identType->Components) {
|
||||
for (auto &comp : identType->getComponentRange()) {
|
||||
// If it's not a bound type, we're done.
|
||||
if (!comp.isBoundType())
|
||||
if (!comp->isBoundType())
|
||||
return true;
|
||||
|
||||
// If the bound type isn't dependent, there's nothing to do.
|
||||
auto type = comp.getBoundType();
|
||||
auto type = comp->getBoundType();
|
||||
if (!type->isDependentType())
|
||||
return true;
|
||||
|
||||
@@ -666,10 +666,10 @@ static void revertDependentTypeLoc(TypeLoc &tl) {
|
||||
if (auto genericParamType
|
||||
= dyn_cast<GenericTypeParamType>(type.getPointer())) {
|
||||
// FIXME: Assert that it has a decl.
|
||||
comp.setValue(genericParamType->getDecl());
|
||||
comp->setValue(genericParamType->getDecl());
|
||||
} else {
|
||||
// FIXME: Often, we could revert to a decl here.
|
||||
comp.revert();
|
||||
comp->revert();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace {
|
||||
// Build up an IdentTypeRepr and see what it resolves to.
|
||||
struct ExprToIdentTypeRepr : public ASTVisitor<ExprToIdentTypeRepr, bool>
|
||||
{
|
||||
SmallVectorImpl<IdentTypeRepr::Component> &components;
|
||||
SmallVectorImpl<ComponentIdentTypeRepr *> &components;
|
||||
ASTContext &C;
|
||||
|
||||
ExprToIdentTypeRepr(decltype(components) &components, ASTContext &C)
|
||||
@@ -93,8 +93,9 @@ struct ExprToIdentTypeRepr : public ASTVisitor<ExprToIdentTypeRepr, bool>
|
||||
|
||||
// Get the declared type.
|
||||
if (auto *td = dyn_cast<TypeDecl>(dre->getDecl())) {
|
||||
components.push_back({dre->getLoc(), dre->getDecl()->getName(), {}});
|
||||
components.back().setValue(td);
|
||||
components.push_back(
|
||||
new (C) SimpleIdentTypeRepr(dre->getLoc(), dre->getDecl()->getName()));
|
||||
components.back()->setValue(td);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -105,15 +106,17 @@ struct ExprToIdentTypeRepr : public ASTVisitor<ExprToIdentTypeRepr, bool>
|
||||
|
||||
// Add the declared module.
|
||||
auto module = me->getType()->getAs<ModuleType>()->getModule();
|
||||
components.push_back({me->getLoc(), module->Name, {}});
|
||||
components.back().setValue(module);
|
||||
components.push_back(
|
||||
new (C) SimpleIdentTypeRepr(me->getLoc(), module->Name));
|
||||
components.back()->setValue(module);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool visitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *udre) {
|
||||
assert(components.empty() && "decl ref should be root element of expr");
|
||||
// Track the AST location of the component.
|
||||
components.push_back({udre->getLoc(), udre->getName(), {}});
|
||||
components.push_back(
|
||||
new (C) SimpleIdentTypeRepr(udre->getLoc(), udre->getName()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -124,7 +127,8 @@ struct ExprToIdentTypeRepr : public ASTVisitor<ExprToIdentTypeRepr, bool>
|
||||
assert(!components.empty() && "no components before dot expr?!");
|
||||
|
||||
// Track the AST location of the new component.
|
||||
components.push_back({ude->getLoc(), ude->getName(), {}});
|
||||
components.push_back(
|
||||
new (C) SimpleIdentTypeRepr(ude->getLoc(), ude->getName()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -139,9 +143,9 @@ struct ExprToIdentTypeRepr : public ASTVisitor<ExprToIdentTypeRepr, bool>
|
||||
for (auto &arg : use->getUnresolvedParams())
|
||||
argTypeReprs.push_back(arg.getTypeRepr());
|
||||
auto origComponent = components.back();
|
||||
components.back() = {origComponent.getIdLoc(),
|
||||
origComponent.getIdentifier(),
|
||||
C.AllocateCopy(argTypeReprs)};
|
||||
components.back() = new (C) GenericIdentTypeRepr(origComponent->getIdLoc(),
|
||||
origComponent->getIdentifier(),
|
||||
C.AllocateCopy(argTypeReprs));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -259,12 +263,11 @@ public:
|
||||
// member name is a member of the enum.
|
||||
Pattern *visitUnresolvedDotExpr(UnresolvedDotExpr *ude) {
|
||||
DependentGenericTypeResolver resolver;
|
||||
SmallVector<IdentTypeRepr::Component, 2> components;
|
||||
SmallVector<ComponentIdentTypeRepr *, 2> components;
|
||||
if (!ExprToIdentTypeRepr(components, TC.Context).visit(ude->getBase()))
|
||||
return nullptr;
|
||||
|
||||
auto *repr
|
||||
= new (TC.Context) IdentTypeRepr(TC.Context.AllocateCopy(components));
|
||||
auto *repr = IdentTypeRepr::create(TC.Context, components);
|
||||
|
||||
// See if the repr resolves to a type.
|
||||
Type ty = TC.resolveIdentifierType(DC, repr,
|
||||
@@ -334,12 +337,13 @@ public:
|
||||
Pattern *visitCallExpr(CallExpr *ce) {
|
||||
DependentGenericTypeResolver resolver;
|
||||
|
||||
SmallVector<IdentTypeRepr::Component, 2> components;
|
||||
SmallVector<ComponentIdentTypeRepr *, 2> components;
|
||||
if (!ExprToIdentTypeRepr(components, TC.Context).visit(ce->getFn()))
|
||||
return nullptr;
|
||||
|
||||
auto *repr
|
||||
= new (TC.Context) IdentTypeRepr(TC.Context.AllocateCopy(components));
|
||||
if (components.empty())
|
||||
return nullptr;
|
||||
auto *repr = IdentTypeRepr::create(TC.Context, components);
|
||||
|
||||
// See first if the entire repr resolves to a type.
|
||||
Type ty = TC.resolveIdentifierType(DC, repr,
|
||||
@@ -386,11 +390,10 @@ public:
|
||||
}
|
||||
|
||||
// If we had a single component, try looking up an enum element in context.
|
||||
if (repr->Components.size() == 1) {
|
||||
auto &backComp = repr->Components.back();
|
||||
if (auto compId = dyn_cast<ComponentIdentTypeRepr>(repr)) {
|
||||
// Try looking up an enum element in context.
|
||||
EnumElementDecl *referencedElement
|
||||
= lookupUnqualifiedEnumMemberElement(TC, DC, backComp.getIdentifier());
|
||||
= lookupUnqualifiedEnumMemberElement(TC, DC, compId->getIdentifier());
|
||||
|
||||
if (!referencedElement)
|
||||
return nullptr;
|
||||
@@ -402,44 +405,48 @@ public:
|
||||
auto *subPattern = getSubExprPattern(ce->getArg());
|
||||
return new (TC.Context) EnumElementPattern(loc,
|
||||
SourceLoc(),
|
||||
backComp.getIdLoc(),
|
||||
backComp.getIdentifier(),
|
||||
compId->getIdLoc(),
|
||||
compId->getIdentifier(),
|
||||
referencedElement,
|
||||
subPattern);
|
||||
}
|
||||
|
||||
// Otherwise, see whether we had an enum type as the penultimate component,
|
||||
// and look up an element inside it.
|
||||
if (repr->Components.empty())
|
||||
return nullptr;
|
||||
if (!repr->Components.end()[-2].isBoundType())
|
||||
auto compoundR = cast<CompoundIdentTypeRepr>(repr);
|
||||
if (!compoundR->Components.end()[-2]->isBoundType())
|
||||
return nullptr;
|
||||
|
||||
Type enumTy = repr->Components.end()[-2].getBoundType();
|
||||
Type enumTy = compoundR->Components.end()[-2]->getBoundType();
|
||||
auto *enumDecl = dyn_cast_or_null<EnumDecl>(enumTy->getAnyNominal());
|
||||
if (!enumDecl)
|
||||
return nullptr;
|
||||
|
||||
auto &tailComponent = repr->Components.back();
|
||||
auto tailComponent = compoundR->Components.back();
|
||||
|
||||
EnumElementDecl *referencedElement
|
||||
= lookupEnumMemberElement(TC, enumDecl, enumTy,
|
||||
tailComponent.getIdentifier());
|
||||
tailComponent->getIdentifier());
|
||||
if (!referencedElement)
|
||||
return nullptr;
|
||||
|
||||
// Build a TypeRepr from the head of the full path.
|
||||
TypeLoc loc;
|
||||
auto subRepr = new (TC.Context) IdentTypeRepr(
|
||||
repr->Components.slice(0, repr->Components.size() - 1));
|
||||
IdentTypeRepr *subRepr;
|
||||
auto headComps =
|
||||
compoundR->Components.slice(0, compoundR->Components.size() - 1);
|
||||
if (headComps.size() == 1)
|
||||
subRepr = headComps.front();
|
||||
else
|
||||
subRepr = new (TC.Context) CompoundIdentTypeRepr(headComps);
|
||||
loc = TypeLoc(subRepr);
|
||||
loc.setType(enumTy);
|
||||
|
||||
auto *subPattern = getSubExprPattern(ce->getArg());
|
||||
return new (TC.Context) EnumElementPattern(loc,
|
||||
SourceLoc(),
|
||||
tailComponent.getIdLoc(),
|
||||
tailComponent.getIdentifier(),
|
||||
tailComponent->getIdLoc(),
|
||||
tailComponent->getIdentifier(),
|
||||
referencedElement,
|
||||
subPattern);
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ Type TypeChecker::applyGenericArguments(Type type,
|
||||
|
||||
static Type applyGenericTypeReprArgs(TypeChecker &TC, Type type, SourceLoc loc,
|
||||
DeclContext *dc,
|
||||
MutableArrayRef<TypeRepr *> genericArgs,
|
||||
ArrayRef<TypeRepr *> genericArgs,
|
||||
GenericTypeResolver *resolver) {
|
||||
SmallVector<TypeLoc, 8> args;
|
||||
for (auto tyR : genericArgs)
|
||||
@@ -267,7 +267,7 @@ static void diagnoseUnboundGenericType(TypeChecker &tc, Type ty,SourceLoc loc) {
|
||||
/// \brief Returns a valid type or ErrorType in case of an error.
|
||||
static Type resolveTypeDecl(TypeChecker &TC, TypeDecl *typeDecl, SourceLoc loc,
|
||||
DeclContext *dc,
|
||||
MutableArrayRef<TypeRepr *> genericArgs,
|
||||
ArrayRef<TypeRepr *> genericArgs,
|
||||
bool allowUnboundGenerics,
|
||||
GenericTypeResolver *resolver) {
|
||||
TC.validateDecl(typeDecl);
|
||||
@@ -304,17 +304,17 @@ static Type resolveTypeDecl(TypeChecker &TC, TypeDecl *typeDecl, SourceLoc loc,
|
||||
|
||||
static llvm::PointerUnion<Type, Module *>
|
||||
resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
|
||||
MutableArrayRef<IdentTypeRepr::Component> components,
|
||||
ArrayRef<ComponentIdentTypeRepr *> components,
|
||||
bool allowUnboundGenerics,
|
||||
bool diagnoseErrors,
|
||||
GenericTypeResolver *resolver) {
|
||||
auto &comp = components.back();
|
||||
if (!comp.isBound()) {
|
||||
if (!comp->isBound()) {
|
||||
auto parentComps = components.slice(0, components.size()-1);
|
||||
if (parentComps.empty()) {
|
||||
// Resolve the first component, which is the only one that requires
|
||||
// unqualified name lookup.
|
||||
UnqualifiedLookup Globals(comp.getIdentifier(), DC, &TC, comp.getIdLoc(),
|
||||
UnqualifiedLookup Globals(comp->getIdentifier(), DC, &TC,comp->getIdLoc(),
|
||||
/*TypeLookup*/true);
|
||||
|
||||
// Process the names we found.
|
||||
@@ -331,7 +331,7 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
|
||||
|
||||
// Save this result.
|
||||
current = result.getNamedModule();
|
||||
comp.setValue(result.getNamedModule());
|
||||
comp->setValue(result.getNamedModule());
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -340,19 +340,22 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
|
||||
if (!typeDecl)
|
||||
continue;
|
||||
|
||||
Type type = resolveTypeDecl(TC, typeDecl, comp.getIdLoc(),
|
||||
DC, comp.getGenericArgs(),
|
||||
ArrayRef<TypeRepr *> genericArgs;
|
||||
if (auto genComp = dyn_cast<GenericIdentTypeRepr>(comp))
|
||||
genericArgs = genComp->getGenericArgs();
|
||||
Type type = resolveTypeDecl(TC, typeDecl, comp->getIdLoc(),
|
||||
DC, genericArgs,
|
||||
allowUnboundGenerics,
|
||||
resolver);
|
||||
if (type->is<ErrorType>()) {
|
||||
comp.setValue(type);
|
||||
comp->setValue(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
// If this is the first result we found, record it.
|
||||
if (current.isNull()) {
|
||||
current = type;
|
||||
comp.setValue(type);
|
||||
comp->setValue(type);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -369,13 +372,13 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
|
||||
// If we found nothing, complain and fail.
|
||||
if (current.isNull()) {
|
||||
if (diagnoseErrors)
|
||||
TC.diagnose(comp.getIdLoc(), components.size() == 1 ?
|
||||
TC.diagnose(comp->getIdLoc(), components.size() == 1 ?
|
||||
diag::use_undeclared_type : diag::unknown_name_in_type,
|
||||
comp.getIdentifier())
|
||||
.highlight(SourceRange(comp.getIdLoc(),
|
||||
components.back().getIdLoc()));
|
||||
comp->getIdentifier())
|
||||
.highlight(SourceRange(comp->getIdLoc(),
|
||||
components.back()->getIdLoc()));
|
||||
Type ty = ErrorType::get(TC.Context);
|
||||
comp.setValue(ty);
|
||||
comp->setValue(ty);
|
||||
return ty;
|
||||
}
|
||||
|
||||
@@ -383,19 +386,19 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
|
||||
// FIXME: We could recover by looking at later components.
|
||||
if (isAmbiguous) {
|
||||
if (diagnoseErrors) {
|
||||
TC.diagnose(comp.getIdLoc(), diag::ambiguous_type_base,
|
||||
comp.getIdentifier())
|
||||
.highlight(SourceRange(comp.getIdLoc(),
|
||||
components.back().getIdLoc()));
|
||||
TC.diagnose(comp->getIdLoc(), diag::ambiguous_type_base,
|
||||
comp->getIdentifier())
|
||||
.highlight(SourceRange(comp->getIdLoc(),
|
||||
components.back()->getIdLoc()));
|
||||
for (auto Result : Globals.Results) {
|
||||
if (Globals.Results[0].hasValueDecl())
|
||||
TC.diagnose(Result.getValueDecl(), diag::found_candidate);
|
||||
else
|
||||
TC.diagnose(comp.getIdLoc(), diag::found_candidate);
|
||||
TC.diagnose(comp->getIdLoc(), diag::found_candidate);
|
||||
}
|
||||
}
|
||||
Type ty = ErrorType::get(TC.Context);
|
||||
comp.setValue(ty);
|
||||
comp->setValue(ty);
|
||||
return ty;
|
||||
}
|
||||
|
||||
@@ -408,8 +411,8 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
|
||||
// If the last resolved component is a type, perform member type lookup.
|
||||
if (parent.is<Type>()) {
|
||||
// FIXME: Want the end of the back range.
|
||||
SourceRange parentRange(parentComps.front().getIdLoc(),
|
||||
parentComps.back().getIdLoc());
|
||||
SourceRange parentRange(parentComps.front()->getIdLoc(),
|
||||
parentComps.back()->getIdLoc());
|
||||
|
||||
auto parentTy = parent.get<Type>();
|
||||
if (parentTy->is<ErrorType>())
|
||||
@@ -422,36 +425,36 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
|
||||
Type memberType = resolver->resolveDependentMemberType(
|
||||
parentTy, DC,
|
||||
parentRange,
|
||||
comp.getIdentifier(),
|
||||
comp.getIdLoc());
|
||||
comp->getIdentifier(),
|
||||
comp->getIdLoc());
|
||||
assert(memberType && "Received null dependent member type");
|
||||
|
||||
if (!comp.getGenericArgs().empty() && !memberType->is<ErrorType>()) {
|
||||
if (isa<GenericIdentTypeRepr>(comp) && !memberType->is<ErrorType>()) {
|
||||
// FIXME: Highlight generic arguments and introduce a Fix-It to
|
||||
// remove them.
|
||||
if (diagnoseErrors)
|
||||
TC.diagnose(comp.getIdLoc(), diag::not_a_generic_type, memberType);
|
||||
TC.diagnose(comp->getIdLoc(), diag::not_a_generic_type, memberType);
|
||||
|
||||
// Drop the arguments.
|
||||
}
|
||||
|
||||
comp.setValue(memberType);
|
||||
comp->setValue(memberType);
|
||||
return memberType;
|
||||
}
|
||||
|
||||
// Look for member types with the given name.
|
||||
auto memberTypes = TC.lookupMemberType(parentTy, comp.getIdentifier(),
|
||||
auto memberTypes = TC.lookupMemberType(parentTy, comp->getIdentifier(),
|
||||
DC);
|
||||
|
||||
// If we didn't find anything, complain.
|
||||
// FIXME: Typo correction!
|
||||
if (!memberTypes) {
|
||||
if (diagnoseErrors)
|
||||
TC.diagnose(comp.getIdLoc(), diag::invalid_member_type,
|
||||
comp.getIdentifier(), parent.get<Type>())
|
||||
TC.diagnose(comp->getIdLoc(), diag::invalid_member_type,
|
||||
comp->getIdentifier(), parent.get<Type>())
|
||||
.highlight(parentRange);
|
||||
Type ty = ErrorType::get(TC.Context);
|
||||
comp.setValue(ty);
|
||||
comp->setValue(ty);
|
||||
return ty;
|
||||
}
|
||||
|
||||
@@ -462,47 +465,48 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
|
||||
if (diagnoseErrors)
|
||||
TC.diagnoseAmbiguousMemberType(parent.get<Type>(),
|
||||
parentRange,
|
||||
comp.getIdentifier(),
|
||||
comp.getIdLoc(),
|
||||
comp->getIdentifier(),
|
||||
comp->getIdLoc(),
|
||||
memberTypes);
|
||||
Type ty = ErrorType::get(TC.Context);
|
||||
comp.setValue(ty);
|
||||
comp->setValue(ty);
|
||||
return ty;
|
||||
}
|
||||
|
||||
auto memberType = memberTypes.back().second;
|
||||
|
||||
// If there are generic arguments, apply them now.
|
||||
if (!comp.getGenericArgs().empty())
|
||||
memberType = applyGenericTypeReprArgs(TC, memberType, comp.getIdLoc(),
|
||||
DC, comp.getGenericArgs(),
|
||||
if (auto genComp = dyn_cast<GenericIdentTypeRepr>(comp))
|
||||
memberType = applyGenericTypeReprArgs(TC, memberType,
|
||||
genComp->getIdLoc(),
|
||||
DC, genComp->getGenericArgs(),
|
||||
resolver);
|
||||
|
||||
comp.setValue(memberType);
|
||||
comp->setValue(memberType);
|
||||
return memberType;
|
||||
}
|
||||
|
||||
// Lookup into a module.
|
||||
auto module = parent.get<Module *>();
|
||||
LookupTypeResult foundModuleTypes =
|
||||
TC.lookupMemberType(ModuleType::get(module), comp.getIdentifier(), DC);
|
||||
TC.lookupMemberType(ModuleType::get(module), comp->getIdentifier(), DC);
|
||||
|
||||
// If we didn't find a type, complain.
|
||||
if (!foundModuleTypes) {
|
||||
// FIXME: Fully-qualified module name?
|
||||
if (diagnoseErrors)
|
||||
TC.diagnose(comp.getIdLoc(), diag::no_module_type, comp.getIdentifier(),
|
||||
module->Name);
|
||||
TC.diagnose(comp->getIdLoc(), diag::no_module_type,
|
||||
comp->getIdentifier(), module->Name);
|
||||
Type ty = ErrorType::get(TC.Context);
|
||||
comp.setValue(ty);
|
||||
comp->setValue(ty);
|
||||
return ty;
|
||||
}
|
||||
|
||||
// If lookup was ambiguous, complain.
|
||||
if (foundModuleTypes.isAmbiguous()) {
|
||||
if (diagnoseErrors) {
|
||||
TC.diagnose(comp.getIdLoc(), diag::ambiguous_module_type,
|
||||
comp.getIdentifier(), module->Name);
|
||||
TC.diagnose(comp->getIdLoc(), diag::ambiguous_module_type,
|
||||
comp->getIdentifier(), module->Name);
|
||||
for (auto foundType : foundModuleTypes) {
|
||||
// Only consider type declarations.
|
||||
auto typeDecl = foundType.first;
|
||||
@@ -514,44 +518,48 @@ resolveIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
|
||||
}
|
||||
}
|
||||
Type ty = ErrorType::get(TC.Context);
|
||||
comp.setValue(ty);
|
||||
comp->setValue(ty);
|
||||
return ty;
|
||||
}
|
||||
Type foundType = foundModuleTypes[0].second;
|
||||
|
||||
// If there are generic arguments, apply them now.
|
||||
if (!comp.getGenericArgs().empty()) {
|
||||
foundType = applyGenericTypeReprArgs(TC, foundType, comp.getIdLoc(),
|
||||
DC, comp.getGenericArgs(),
|
||||
if (auto genComp = dyn_cast<GenericIdentTypeRepr>(comp)) {
|
||||
foundType = applyGenericTypeReprArgs(TC, foundType, genComp->getIdLoc(),
|
||||
DC, genComp->getGenericArgs(),
|
||||
resolver);
|
||||
}
|
||||
|
||||
comp.setValue(foundType);
|
||||
comp->setValue(foundType);
|
||||
}
|
||||
}
|
||||
|
||||
assert(comp.isBound());
|
||||
if (Type ty = comp.getBoundType())
|
||||
assert(comp->isBound());
|
||||
if (Type ty = comp->getBoundType())
|
||||
return ty;
|
||||
if (Module *mod = comp.getBoundModule())
|
||||
if (Module *mod = comp->getBoundModule())
|
||||
return mod;
|
||||
|
||||
ValueDecl *VD = comp.getBoundDecl();
|
||||
ValueDecl *VD = comp->getBoundDecl();
|
||||
auto typeDecl = dyn_cast<TypeDecl>(VD);
|
||||
if (!typeDecl) {
|
||||
if (diagnoseErrors) {
|
||||
TC.diagnose(comp.getIdLoc(), diag::use_non_type_value, VD->getName());
|
||||
TC.diagnose(comp->getIdLoc(), diag::use_non_type_value, VD->getName());
|
||||
TC.diagnose(VD, diag::use_non_type_value_prev, VD->getName());
|
||||
}
|
||||
Type ty = ErrorType::get(TC.Context);
|
||||
comp.setValue(ty);
|
||||
comp->setValue(ty);
|
||||
return ty;
|
||||
}
|
||||
|
||||
Type type = resolveTypeDecl(TC, typeDecl, comp.getIdLoc(), nullptr,
|
||||
comp.getGenericArgs(), allowUnboundGenerics,
|
||||
ArrayRef<TypeRepr *> genericArgs;
|
||||
if (auto genComp = dyn_cast<GenericIdentTypeRepr>(comp))
|
||||
genericArgs = genComp->getGenericArgs();
|
||||
|
||||
Type type = resolveTypeDecl(TC, typeDecl, comp->getIdLoc(), nullptr,
|
||||
genericArgs, allowUnboundGenerics,
|
||||
resolver);
|
||||
comp.setValue(type);
|
||||
comp->setValue(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -563,17 +571,20 @@ Type TypeChecker::resolveIdentifierType(DeclContext *DC,
|
||||
GenericTypeResolver *resolver) {
|
||||
assert(resolver && "Missing generic type resolver");
|
||||
|
||||
auto ComponentRange = IdType->getComponentRange();
|
||||
auto Components = llvm::makeArrayRef(ComponentRange.begin(),
|
||||
ComponentRange.end());
|
||||
llvm::PointerUnion<Type, Module *>
|
||||
result = resolveIdentTypeComponent(*this, DC, IdType->Components,
|
||||
result = resolveIdentTypeComponent(*this, DC, Components,
|
||||
allowUnboundGenerics,
|
||||
diagnoseErrors,
|
||||
resolver);
|
||||
if (auto mod = result.dyn_cast<Module*>()) {
|
||||
if (diagnoseErrors)
|
||||
diagnose(IdType->Components.back().getIdLoc(),
|
||||
diagnose(Components.back()->getIdLoc(),
|
||||
diag::use_module_as_type, mod->Name);
|
||||
Type ty = ErrorType::get(Context);
|
||||
IdType->Components.back().setValue(ty);
|
||||
Components.back()->setValue(ty);
|
||||
return ty;
|
||||
}
|
||||
|
||||
@@ -667,7 +678,9 @@ Type TypeResolver::resolveType(TypeRepr *repr, bool isSILType) {
|
||||
case TypeReprKind::Attributed:
|
||||
return resolveAttributedType(cast<AttributedTypeRepr>(repr), isSILType);
|
||||
|
||||
case TypeReprKind::Ident:
|
||||
case TypeReprKind::SimpleIdent:
|
||||
case TypeReprKind::GenericIdent:
|
||||
case TypeReprKind::CompoundIdent:
|
||||
return TC.resolveIdentifierType(DC, cast<IdentTypeRepr>(repr),
|
||||
AllowUnboundGenerics,
|
||||
/*diagnoseErrors*/ true,
|
||||
|
||||
@@ -418,12 +418,13 @@ static bool mayConformToKnownProtocol(const DeclTy *D) {
|
||||
if (!identRepr)
|
||||
continue;
|
||||
|
||||
const IdentTypeRepr::Component &lastID = identRepr->Components.back();
|
||||
if (!lastID.getGenericArgs().empty())
|
||||
auto lastSimpleID =
|
||||
dyn_cast<SimpleIdentTypeRepr>(identRepr->getComponentRange().back());
|
||||
if (!lastSimpleID)
|
||||
continue;
|
||||
|
||||
bool matchesKnownProtocol =
|
||||
llvm::StringSwitch<bool>(lastID.getIdentifier().str())
|
||||
llvm::StringSwitch<bool>(lastSimpleID->getIdentifier().str())
|
||||
#define PROTOCOL(Name) \
|
||||
.Case(#Name, true)
|
||||
#include "swift/AST/KnownProtocols.def"
|
||||
|
||||
Reference in New Issue
Block a user