本文整理汇总了C++中Pattern::setType方法的典型用法代码示例。如果您正苦于以下问题:C++ Pattern::setType方法的具体用法?C++ Pattern::setType怎么用?C++ Pattern::setType使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Pattern
的用法示例。
在下文中一共展示了Pattern::setType方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: processREPLTopLevelExpr
/// When we see an expression in a TopLevelCodeDecl in the REPL, process it,
/// adding the proper decls back to the top level of the file.
void REPLChecker::processREPLTopLevelExpr(Expr *E) {
CanType T = E->getType()->getCanonicalType();
// Don't try to print invalid expressions, module exprs, or void expressions.
if (T->hasError() || isa<ModuleType>(T) || T->isVoid())
return;
// Okay, we need to print this expression. We generally do this by creating a
// REPL metavariable (e.g. r4) to hold the result, so it can be referred to
// in the future. However, if this is a direct reference to a decl (e.g. "x")
// then don't create a repl metavariable.
if (VarDecl *d = getObviousDeclFromExpr(E)) {
generatePrintOfExpression(d->getName().str(), E);
return;
}
// Remove the expression from being in the list of decls to execute, we're
// going to reparent it.
auto TLCD = cast<TopLevelCodeDecl>(SF.Decls.back());
E = TC.coerceToRValue(E);
// Create the meta-variable, let the typechecker name it.
Identifier name = TC.getNextResponseVariableName(SF.getParentModule());
VarDecl *vd = new (Context) VarDecl(/*IsStatic*/false,
VarDecl::Specifier::Let,
/*IsCaptureList*/false, E->getStartLoc(),
name, E->getType(), &SF);
vd->setInterfaceType(E->getType());
SF.Decls.push_back(vd);
// Create a PatternBindingDecl to bind the expression into the decl.
Pattern *metavarPat = new (Context) NamedPattern(vd);
metavarPat->setType(E->getType());
PatternBindingDecl *metavarBinding = PatternBindingDecl::create(
Context, /*StaticLoc*/ SourceLoc(), StaticSpellingKind::None,
/*VarLoc*/ E->getStartLoc(), metavarPat, /*EqualLoc*/ SourceLoc(), E,
TLCD);
// Overwrite the body of the existing TopLevelCodeDecl.
TLCD->setBody(BraceStmt::create(Context,
metavarBinding->getStartLoc(),
ASTNode(metavarBinding),
metavarBinding->getEndLoc(),
/*implicit*/true));
// Finally, print the variable's value.
E = TC.buildCheckedRefExpr(vd, &SF, DeclNameLoc(E->getStartLoc()),
/*Implicit=*/true);
generatePrintOfExpression(vd->getName().str(), E);
}
示例2: getConformanceContext
std::pair<VarDecl *, PatternBindingDecl *>
DerivedConformance::declareDerivedProperty(Identifier name,
Type propertyInterfaceType,
Type propertyContextType,
bool isStatic, bool isFinal) {
auto &C = TC.Context;
auto parentDC = getConformanceContext();
VarDecl *propDecl = new (C) VarDecl(/*IsStatic*/isStatic, VarDecl::Specifier::Var,
/*IsCaptureList*/false, SourceLoc(), name,
propertyContextType, parentDC);
propDecl->setImplicit();
propDecl->copyFormalAccessFrom(Nominal, /*sourceIsParentContext*/ true);
propDecl->setInterfaceType(propertyInterfaceType);
propDecl->setValidationStarted();
// If this is supposed to be a final property, mark it as such.
assert(isFinal || !parentDC->getAsClassOrClassExtensionContext());
if (isFinal && parentDC->getAsClassOrClassExtensionContext() &&
!propDecl->isFinal())
propDecl->getAttrs().add(new (C) FinalAttr(/*IsImplicit=*/true));
Pattern *propPat = new (C) NamedPattern(propDecl, /*implicit*/ true);
propPat->setType(propertyContextType);
propPat = new (C) TypedPattern(propPat,
TypeLoc::withoutLoc(propertyContextType),
/*implicit*/ true);
propPat->setType(propertyContextType);
auto pbDecl = PatternBindingDecl::create(C, SourceLoc(),
StaticSpellingKind::None,
SourceLoc(), propPat, nullptr,
parentDC);
pbDecl->setImplicit();
return {propDecl, pbDecl};
}
示例3: new
std::pair<VarDecl *, PatternBindingDecl *>
DerivedConformance::declareDerivedReadOnlyProperty(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *typeDecl,
Identifier name,
Type propertyInterfaceType,
Type propertyContextType,
FuncDecl *getterDecl,
bool isStatic,
bool isFinal) {
auto &C = tc.Context;
auto parentDC = cast<DeclContext>(parentDecl);
VarDecl *propDecl = new (C) VarDecl(/*IsStatic*/isStatic, /*IsLet*/false,
/*IsCaptureList*/false, SourceLoc(), name,
propertyContextType, parentDC);
propDecl->setImplicit();
propDecl->makeComputed(SourceLoc(), getterDecl, nullptr, nullptr,
SourceLoc());
propDecl->setAccessibility(getterDecl->getFormalAccess());
propDecl->setInterfaceType(propertyInterfaceType);
// If this is supposed to be a final property, mark it as such.
assert(isFinal || !parentDC->getAsClassOrClassExtensionContext());
if (isFinal && parentDC->getAsClassOrClassExtensionContext() &&
!propDecl->isFinal())
propDecl->getAttrs().add(new (C) FinalAttr(/*IsImplicit=*/true));
Pattern *propPat = new (C) NamedPattern(propDecl, /*implicit*/ true);
propPat->setType(propertyContextType);
propPat = new (C) TypedPattern(propPat,
TypeLoc::withoutLoc(propertyContextType),
/*implicit*/ true);
auto pbDecl = PatternBindingDecl::create(C, SourceLoc(),
StaticSpellingKind::None,
SourceLoc(), propPat, nullptr,
parentDC);
pbDecl->setImplicit();
return {propDecl, pbDecl};
}
示例4: new
std::pair<VarDecl *, PatternBindingDecl *>
DerivedConformance::declareDerivedReadOnlyProperty(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *typeDecl,
Identifier name,
Type propertyInterfaceType,
Type propertyContextType,
FuncDecl *getterDecl,
bool isStatic) {
auto &C = tc.Context;
auto parentDC = cast<DeclContext>(parentDecl);
VarDecl *propDecl = new (C) VarDecl(isStatic, /*let*/ false,
SourceLoc(), name,
propertyContextType,
parentDC);
propDecl->setImplicit();
propDecl->makeComputed(SourceLoc(), getterDecl, nullptr, nullptr,
SourceLoc());
propDecl->setAccessibility(typeDecl->getFormalAccess());
propDecl->setInterfaceType(propertyInterfaceType);
Pattern *propPat = new (C) NamedPattern(propDecl, /*implicit*/ true);
propPat->setType(propertyContextType);
propPat = new (C) TypedPattern(propPat,
TypeLoc::withoutLoc(propertyContextType),
/*implicit*/ true);
auto pbDecl = PatternBindingDecl::create(C, SourceLoc(),
StaticSpellingKind::None,
SourceLoc(), propPat, nullptr,
parentDC);
pbDecl->setImplicit();
return {propDecl, pbDecl};
}
示例5: processREPLTopLevelPatternBinding
/// processREPLTopLevelPatternBinding - When we see a new PatternBinding parsed
/// into the REPL, process it by generating code to print it out.
void REPLChecker::processREPLTopLevelPatternBinding(PatternBindingDecl *PBD) {
// If there is no initializer for the new variable, don't auto-print it.
// This would just cause a confusing definite initialization error. Some
// day we will do some high level analysis of uninitialized variables
// (rdar://15157729) but until then, output a specialized error.
unsigned entryIdx = 0U-1;
for (auto patternEntry : PBD->getPatternList()) {
++entryIdx;
if (!patternEntry.getInit()) {
TC.diagnose(PBD->getStartLoc(), diag::repl_must_be_initialized);
continue;
}
auto pattern = patternEntry.getPattern();
llvm::SmallString<16> PatternString;
PatternBindingPrintLHS(PatternString).visit(pattern);
// If the bound pattern is a single value, use a DeclRefExpr on the
// underlying Decl to print it.
if (auto *NP = dyn_cast<NamedPattern>(pattern->
getSemanticsProvidingPattern())) {
Expr *E = TC.buildCheckedRefExpr(NP->getDecl(), &SF, PBD->getStartLoc(),
/*Implicit=*/true);
generatePrintOfExpression(PatternString, E);
continue;
}
// Otherwise, we may not have a way to name all of the pieces of the pattern.
// Create a repl metavariable to capture the whole thing so we can reference
// it, then assign that into the pattern. For example, translate:
// var (x, y, _) = foo()
// into:
// var r123 = foo()
// var (x, y, _) = r123
// replPrint(r123)
// Remove PBD from the list of Decls so we can insert before it.
auto PBTLCD = cast<TopLevelCodeDecl>(SF.Decls.back());
SF.Decls.pop_back();
// Create the meta-variable, let the typechecker name it.
Identifier name = TC.getNextResponseVariableName(SF.getParentModule());
VarDecl *vd = new (Context) VarDecl(/*static*/ false, /*IsLet*/true,
PBD->getStartLoc(), name,
pattern->getType(), &SF);
SF.Decls.push_back(vd);
// Create a PatternBindingDecl to bind the expression into the decl.
Pattern *metavarPat = new (Context) NamedPattern(vd);
metavarPat->setType(vd->getType());
PatternBindingDecl *metavarBinding
= PatternBindingDecl::create(Context, SourceLoc(),
StaticSpellingKind::None,
PBD->getStartLoc(), metavarPat,
patternEntry.getInit(), &SF);
auto MVBrace = BraceStmt::create(Context, metavarBinding->getStartLoc(),
ASTNode(metavarBinding),
metavarBinding->getEndLoc());
auto *MVTLCD = new (Context) TopLevelCodeDecl(&SF, MVBrace);
SF.Decls.push_back(MVTLCD);
// Replace the initializer of PBD with a reference to our repl temporary.
Expr *E = TC.buildCheckedRefExpr(vd, &SF,
vd->getStartLoc(), /*Implicit=*/true);
E = TC.coerceToMaterializable(E);
PBD->setInit(entryIdx, E);
SF.Decls.push_back(PBTLCD);
// Finally, print out the result, by referring to the repl temp.
E = TC.buildCheckedRefExpr(vd, &SF, vd->getStartLoc(), /*Implicit=*/true);
generatePrintOfExpression(PatternString, E);
}
}
示例6: new
/// Create AST statements which convert from an enum to an Int with a switch.
/// \p stmts The generated statements are appended to this vector.
/// \p parentDC Either an extension or the enum itself.
/// \p enumDecl The enum declaration.
/// \p enumVarDecl The enum input variable.
/// \p funcDecl The parent function.
/// \p indexName The name of the output variable.
/// \return A DeclRefExpr of the output variable (of type Int).
static DeclRefExpr *convertEnumToIndex(SmallVectorImpl<ASTNode> &stmts,
DeclContext *parentDC,
EnumDecl *enumDecl,
VarDecl *enumVarDecl,
AbstractFunctionDecl *funcDecl,
const char *indexName) {
ASTContext &C = enumDecl->getASTContext();
Type enumType = enumVarDecl->getType();
Type intType = C.getIntDecl()->getDeclaredType();
auto indexVar = new (C) VarDecl(/*IsStatic*/false, VarDecl::Specifier::Var,
/*IsCaptureList*/false, SourceLoc(),
C.getIdentifier(indexName), intType,
funcDecl);
indexVar->setInterfaceType(intType);
indexVar->setImplicit();
// generate: var indexVar
Pattern *indexPat = new (C) NamedPattern(indexVar, /*implicit*/ true);
indexPat->setType(intType);
indexPat = new (C) TypedPattern(indexPat, TypeLoc::withoutLoc(intType));
indexPat->setType(intType);
auto *indexBind = PatternBindingDecl::createImplicit(
C, StaticSpellingKind::None, indexPat, /*InitExpr*/ nullptr, funcDecl);
unsigned index = 0;
SmallVector<ASTNode, 4> cases;
for (auto elt : enumDecl->getAllElements()) {
// generate: case .<Case>:
auto pat = new (C) EnumElementPattern(TypeLoc::withoutLoc(enumType),
SourceLoc(), SourceLoc(),
Identifier(), elt, nullptr);
pat->setImplicit();
auto labelItem = CaseLabelItem(pat);
// generate: indexVar = <index>
auto indexExpr = IntegerLiteralExpr::createFromUnsigned(C, index++);
auto indexRef = new (C) DeclRefExpr(indexVar, DeclNameLoc(),
/*implicit*/true);
auto assignExpr = new (C) AssignExpr(indexRef, SourceLoc(),
indexExpr, /*implicit*/ true);
auto body = BraceStmt::create(C, SourceLoc(), ASTNode(assignExpr),
SourceLoc());
cases.push_back(CaseStmt::create(C, SourceLoc(), labelItem,
/*HasBoundDecls=*/false, SourceLoc(),
SourceLoc(), body));
}
// generate: switch enumVar { }
auto enumRef = new (C) DeclRefExpr(enumVarDecl, DeclNameLoc(),
/*implicit*/true);
auto switchStmt = SwitchStmt::create(LabeledStmtInfo(), SourceLoc(), enumRef,
SourceLoc(), cases, SourceLoc(), C);
stmts.push_back(indexBind);
stmts.push_back(switchStmt);
return new (C) DeclRefExpr(indexVar, DeclNameLoc(), /*implicit*/ true,
AccessSemantics::Ordinary, intType);
}
示例7: void
//.........这里部分代码省略.........
// var x: Int
// var y: String
// @derived var hashValue: Int {
// var result = 0
// result = _combineHashValues(result, x.hashValue)
// result = _combineHashValues(result, y.hashValue)
// return result
// }
// }
ASTContext &C = tc.Context;
auto parentDC = cast<DeclContext>(parentDecl);
Type intType = C.getIntDecl()->getDeclaredType();
// We can't form a Hashable conformance if Int isn't Hashable or
// ExpressibleByIntegerLiteral.
if (!tc.conformsToProtocol(intType,C.getProtocol(KnownProtocolKind::Hashable),
typeDecl, None)) {
tc.diagnose(typeDecl->getLoc(), diag::broken_int_hashable_conformance);
return nullptr;
}
ProtocolDecl *intLiteralProto =
C.getProtocol(KnownProtocolKind::ExpressibleByIntegerLiteral);
if (!tc.conformsToProtocol(intType, intLiteralProto, typeDecl, None)) {
tc.diagnose(typeDecl->getLoc(),
diag::broken_int_integer_literal_convertible_conformance);
return nullptr;
}
VarDecl *hashValueDecl =
new (C) VarDecl(/*IsStatic*/false, VarDecl::Specifier::Var,
/*IsCaptureList*/false, SourceLoc(),
C.Id_hashValue, intType, parentDC);
auto selfDecl = ParamDecl::createSelf(SourceLoc(), parentDC);
ParameterList *params[] = {
ParameterList::createWithoutLoc(selfDecl),
ParameterList::createEmpty(C)
};
AccessorDecl *getterDecl = AccessorDecl::create(C,
/*FuncLoc=*/SourceLoc(), /*AccessorKeywordLoc=*/SourceLoc(),
AccessorKind::IsGetter, AddressorKind::NotAddressor, hashValueDecl,
/*StaticLoc=*/SourceLoc(), StaticSpellingKind::None,
/*Throws=*/false, /*ThrowsLoc=*/SourceLoc(),
/*GenericParams=*/nullptr, params,
TypeLoc::withoutLoc(intType), parentDC);
getterDecl->setImplicit();
getterDecl->setBodySynthesizer(bodySynthesizer);
// Compute the type of hashValue().
Type methodType = FunctionType::get(TupleType::getEmpty(tc.Context), intType);
// Compute the interface type of hashValue().
Type interfaceType;
auto selfParam = computeSelfParam(getterDecl);
if (auto sig = parentDC->getGenericSignatureOfContext()) {
getterDecl->setGenericEnvironment(parentDC->getGenericEnvironmentOfContext());
interfaceType = GenericFunctionType::get(sig, {selfParam}, methodType,
AnyFunctionType::ExtInfo());
} else
interfaceType = FunctionType::get({selfParam}, methodType,
AnyFunctionType::ExtInfo());
getterDecl->setInterfaceType(interfaceType);
getterDecl->setValidationStarted();
getterDecl->copyFormalAccessFrom(typeDecl, /*sourceIsParentContext*/true);
// Finish creating the property.
hashValueDecl->setImplicit();
hashValueDecl->setInterfaceType(intType);
hashValueDecl->setValidationStarted();
hashValueDecl->makeComputed(SourceLoc(), getterDecl,
nullptr, nullptr, SourceLoc());
hashValueDecl->copyFormalAccessFrom(typeDecl, /*sourceIsParentContext*/true);
Pattern *hashValuePat = new (C) NamedPattern(hashValueDecl, /*implicit*/true);
hashValuePat->setType(intType);
hashValuePat
= new (C) TypedPattern(hashValuePat, TypeLoc::withoutLoc(intType),
/*implicit*/ true);
hashValuePat->setType(intType);
auto patDecl = PatternBindingDecl::create(C, SourceLoc(),
StaticSpellingKind::None,
SourceLoc(), hashValuePat, nullptr,
parentDC);
patDecl->setImplicit();
tc.Context.addSynthesizedDecl(hashValueDecl);
tc.Context.addSynthesizedDecl(getterDecl);
auto dc = cast<IterableDeclContext>(parentDecl);
dc->addMember(getterDecl);
dc->addMember(hashValueDecl);
dc->addMember(patDecl);
return hashValueDecl;
}
示例8: new
/// Derive the body for the 'hashValue' getter for a struct.
static void
deriveBodyHashable_struct_hashValue(AbstractFunctionDecl *hashValueDecl) {
auto parentDC = hashValueDecl->getDeclContext();
ASTContext &C = parentDC->getASTContext();
auto structDecl = parentDC->getAsStructOrStructExtensionContext();
SmallVector<ASTNode, 6> statements;
auto selfDecl = hashValueDecl->getImplicitSelfDecl();
Type intType = C.getIntDecl()->getDeclaredType();
auto resultVar = new (C) VarDecl(/*IsStatic*/ false, VarDecl::Specifier::Var,
/*IsCaptureList*/ false, SourceLoc(),
C.getIdentifier("result"), intType,
hashValueDecl);
resultVar->setInterfaceType(intType);
resultVar->setImplicit();
// var result: Int
Pattern *resultPat = new (C) NamedPattern(resultVar, /*implicit*/ true);
resultPat->setType(intType);
resultPat = new (C) TypedPattern(resultPat, TypeLoc::withoutLoc(intType));
resultPat->setType(intType);
auto resultBind = PatternBindingDecl::create(C, SourceLoc(),
StaticSpellingKind::None,
SourceLoc(),
resultPat, nullptr,
hashValueDecl);
statements.push_back(resultBind);
// result = 0
{
auto resultRef = new (C) DeclRefExpr(resultVar, DeclNameLoc(),
/*implicit*/ true);
auto assignExpr = new (C) AssignExpr(resultRef, SourceLoc(),
integerLiteralExpr(C, 0),
/*implicit*/ true);
statements.emplace_back(ASTNode(assignExpr));
}
auto storedProperties =
structDecl->getStoredProperties(/*skipInaccessible=*/true);
// For each stored property, generate a statement that combines its hash value
// into the result.
for (auto propertyDecl : storedProperties) {
auto propertyRef = new (C) DeclRefExpr(propertyDecl, DeclNameLoc(),
/*implicit*/ true);
auto selfRef = new (C) DeclRefExpr(selfDecl, DeclNameLoc(),
/*implicit*/ true);
auto selfPropertyExpr = new (C) DotSyntaxCallExpr(propertyRef, SourceLoc(),
selfRef);
// result = _combineHashValues(result, <property>.hashValue)
auto combineExpr = combineHashValuesAssignmentExpr(C, resultVar,
selfPropertyExpr);
statements.emplace_back(ASTNode(combineExpr));
}
{
// return result
auto resultRef = new (C) DeclRefExpr(resultVar, DeclNameLoc(),
/*implicit*/ true,
AccessSemantics::Ordinary, intType);
auto returnStmt = new (C) ReturnStmt(SourceLoc(), resultRef);
statements.push_back(returnStmt);
}
auto body = BraceStmt::create(C, SourceLoc(), statements, SourceLoc());
hashValueDecl->setBody(body);
}
示例9: SourceLoc
/// Derive a 'hashValue' implementation for an enum.
static ValueDecl *
deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
EnumDecl *enumDecl) {
// enum SomeEnum {
// case A, B, C
// @derived var hashValue: Int {
// var index: Int
// switch self {
// case A:
// index = 0
// case B:
// index = 1
// case C:
// index = 2
// }
// return index.hashValue
// }
// }
ASTContext &C = tc.Context;
auto parentDC = cast<DeclContext>(parentDecl);
Type intType = C.getIntDecl()->getDeclaredType();
// We can't form a Hashable conformance if Int isn't Hashable or
// IntegerLiteralConvertible.
if (!tc.conformsToProtocol(intType,C.getProtocol(KnownProtocolKind::Hashable),
enumDecl, None)) {
tc.diagnose(enumDecl->getLoc(), diag::broken_int_hashable_conformance);
return nullptr;
}
ProtocolDecl *intLiteralProto =
C.getProtocol(KnownProtocolKind::IntegerLiteralConvertible);
if (!tc.conformsToProtocol(intType, intLiteralProto, enumDecl, None)) {
tc.diagnose(enumDecl->getLoc(),
diag::broken_int_integer_literal_convertible_conformance);
return nullptr;
}
auto selfDecl = ParamDecl::createSelf(SourceLoc(), parentDC);
ParameterList *params[] = {
ParameterList::createWithoutLoc(selfDecl),
ParameterList::createEmpty(C)
};
FuncDecl *getterDecl =
FuncDecl::create(C, SourceLoc(), StaticSpellingKind::None, SourceLoc(),
Identifier(), SourceLoc(), SourceLoc(), SourceLoc(),
nullptr, Type(), params, TypeLoc::withoutLoc(intType),
parentDC);
getterDecl->setImplicit();
getterDecl->setBodySynthesizer(deriveBodyHashable_enum_hashValue);
// Compute the type of hashValue().
GenericParamList *genericParams = getterDecl->getGenericParamsOfContext();
Type methodType = FunctionType::get(TupleType::getEmpty(tc.Context), intType);
Type selfType = getterDecl->computeSelfType();
selfDecl->overwriteType(selfType);
Type type;
if (genericParams)
type = PolymorphicFunctionType::get(selfType, methodType, genericParams);
else
type = FunctionType::get(selfType, methodType);
getterDecl->setType(type);
getterDecl->setBodyResultType(intType);
// Compute the interface type of hashValue().
Type interfaceType;
Type selfIfaceType = getterDecl->computeInterfaceSelfType(false);
if (auto sig = parentDC->getGenericSignatureOfContext())
interfaceType = GenericFunctionType::get(sig, selfIfaceType, methodType,
AnyFunctionType::ExtInfo());
else
interfaceType = FunctionType::get(selfType, methodType);
getterDecl->setInterfaceType(interfaceType);
getterDecl->setAccessibility(enumDecl->getFormalAccess());
// If the enum was not imported, the derived conformance is either from the
// enum itself or an extension, in which case we will emit the declaration
// normally.
if (enumDecl->hasClangNode())
tc.Context.addExternalDecl(getterDecl);
// Create the property.
VarDecl *hashValueDecl = new (C) VarDecl(/*static*/ false,
/*let*/ false,
SourceLoc(), C.Id_hashValue,
intType, parentDC);
hashValueDecl->setImplicit();
hashValueDecl->makeComputed(SourceLoc(), getterDecl,
nullptr, nullptr, SourceLoc());
hashValueDecl->setAccessibility(enumDecl->getFormalAccess());
Pattern *hashValuePat = new (C) NamedPattern(hashValueDecl, /*implicit*/true);
hashValuePat->setType(intType);
hashValuePat
//.........这里部分代码省略.........
示例10: name
static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
Decl *parentDecl,
EnumDecl *enumDecl) {
ASTContext &C = tc.Context;
auto parentDC = cast<DeclContext>(parentDecl);
auto rawInterfaceType = enumDecl->getRawType();
auto rawType = ArchetypeBuilder::mapTypeIntoContext(parentDC,
rawInterfaceType);
// Make sure that the raw type is Equatable. We need it to ensure that we have
// a suitable ~= for the switch.
auto equatableProto = tc.getProtocol(enumDecl->getLoc(),
KnownProtocolKind::Equatable);
if (!equatableProto)
return nullptr;
if (!tc.conformsToProtocol(rawType, equatableProto, enumDecl, None)) {
SourceLoc loc = enumDecl->getInherited()[0].getSourceRange().Start;
tc.diagnose(loc, diag::enum_raw_type_not_equatable, rawType);
return nullptr;
}
Type enumType = parentDC->getDeclaredTypeInContext();
VarDecl *selfDecl = new (C) ParamDecl(/*IsLet*/false,
SourceLoc(),
Identifier(),
SourceLoc(),
C.Id_self,
enumType,
parentDC);
selfDecl->setImplicit();
Pattern *selfParam = new (C) NamedPattern(selfDecl, /*implicit*/ true);
selfParam->setType(enumType);
selfParam = new (C) TypedPattern(selfParam,
TypeLoc::withoutLoc(enumType));
selfParam->setType(enumType);
selfParam->setImplicit();
VarDecl *rawDecl = new (C) ParamDecl(/*IsVal*/true,
SourceLoc(),
C.Id_rawValue,
SourceLoc(),
C.Id_rawValue,
rawType,
parentDC);
rawDecl->setImplicit();
Pattern *rawParam = new (C) NamedPattern(rawDecl, /*implicit*/ true);
rawParam->setType(rawType);
rawParam = new (C) TypedPattern(rawParam, TypeLoc::withoutLoc(rawType));
rawParam->setType(rawType);
rawParam->setImplicit();
rawParam = new (C) ParenPattern(SourceLoc(), rawParam, SourceLoc());
rawParam->setType(rawType);
rawParam->setImplicit();
auto retTy = OptionalType::get(enumType);
DeclName name(C, C.Id_init, { C.Id_rawValue });
auto initDecl = new (C) ConstructorDecl(name, SourceLoc(),
/*failability*/ OTK_Optional,
SourceLoc(),
selfParam,
rawParam,
nullptr,
SourceLoc(),
parentDC);
initDecl->setImplicit();
initDecl->setBodySynthesizer(&deriveBodyRawRepresentable_init);
// Compute the type of the initializer.
GenericParamList *genericParams = initDecl->getGenericParamsOfContext();
TupleTypeElt element(rawType, C.Id_rawValue);
auto argType = TupleType::get(element, C);
TupleTypeElt interfaceElement(rawInterfaceType, C.Id_rawValue);
auto interfaceArgType = TupleType::get(interfaceElement, C);
Type type = FunctionType::get(argType, retTy);
Type selfType = initDecl->computeSelfType();
Type selfMetatype = MetatypeType::get(selfType->getInOutObjectType());
Type allocType;
Type initType;
if (genericParams) {
allocType = PolymorphicFunctionType::get(selfMetatype, type, genericParams);
initType = PolymorphicFunctionType::get(selfType, type, genericParams);
} else {
allocType = FunctionType::get(selfMetatype, type);
initType = FunctionType::get(selfType, type);
}
initDecl->setType(allocType);
initDecl->setInitializerType(initType);
// Compute the interface type of the initializer.
Type retInterfaceType
= OptionalType::get(parentDC->getDeclaredInterfaceType());
Type interfaceType = FunctionType::get(interfaceArgType, retInterfaceType);
//.........这里部分代码省略.........
示例11: validateGenericFuncSignature
//.........这里部分代码省略.........
funcTy = getResultType(*this, fn, funcTy);
}
} else if (auto ctor = dyn_cast<ConstructorDecl>(func)) {
// FIXME: shouldn't this just be
// ctor->getDeclContext()->getDeclaredInterfaceType()?
if (ctor->getDeclContext()->isProtocolOrProtocolExtensionContext()) {
funcTy = ctor->getDeclContext()->getProtocolSelf()->getDeclaredType();
} else {
funcTy = ctor->getExtensionType()->getAnyNominal()
->getDeclaredInterfaceType();
}
// Adjust result type for failability.
if (ctor->getFailability() != OTK_None)
funcTy = OptionalType::get(ctor->getFailability(), funcTy);
initFuncTy = funcTy;
} else {
assert(isa<DestructorDecl>(func));
funcTy = TupleType::getEmpty(Context);
}
auto patterns = func->getBodyParamPatterns();
SmallVector<Pattern *, 4> storedPatterns;
// FIXME: Destructors don't have the '()' pattern in their signature, so
// paste it here.
if (isa<DestructorDecl>(func)) {
storedPatterns.append(patterns.begin(), patterns.end());
Pattern *pattern = TuplePattern::create(Context, SourceLoc(), { },
SourceLoc(), /*Implicit=*/true);
pattern->setType(TupleType::getEmpty(Context));
storedPatterns.push_back(pattern);
patterns = storedPatterns;
}
bool hasSelf = func->getDeclContext()->isTypeContext();
for (unsigned i = 0, e = patterns.size(); i != e; ++i) {
Type argTy;
Type initArgTy;
Type selfTy;
if (i == e-1 && hasSelf) {
selfTy = func->computeInterfaceSelfType(/*isInitializingCtor=*/false);
// Substitute in our own 'self' parameter.
argTy = selfTy;
if (initFuncTy) {
initArgTy = func->computeInterfaceSelfType(/*isInitializingCtor=*/true);
}
} else {
argTy = patterns[e - i - 1]->getType();
// For an implicit declaration, our argument type will be in terms of
// archetypes rather than dependent types. Replace the
// archetypes with their corresponding dependent types.
if (func->isImplicit()) {
argTy = getInterfaceTypeFromInternalType(func, argTy);
}
if (initFuncTy)
initArgTy = argTy;
}
示例12: new
/// Create AST statements which convert from an enum to an Int with a switch.
/// \p stmts The generated statements are appended to this vector.
/// \p parentDC Either an extension or the enum itself.
/// \p enumDecl The enum declaration.
/// \p enumVarDecl The enum input variable.
/// \p funcDecl The parent function.
/// \p indexName The name of the output variable.
/// \return A DeclRefExpr of the output variable (of type Int).
static DeclRefExpr *convertEnumToIndex(SmallVectorImpl<ASTNode> &stmts,
DeclContext *parentDC,
EnumDecl *enumDecl,
VarDecl *enumVarDecl,
AbstractFunctionDecl *funcDecl,
const char *indexName) {
ASTContext &C = enumDecl->getASTContext();
Type enumType = enumVarDecl->getType();
Type intType = C.getIntDecl()->getDeclaredType();
auto indexVar = new (C) VarDecl(/*static*/false, /*let*/false,
SourceLoc(), C.getIdentifier(indexName),
intType, funcDecl);
indexVar->setImplicit();
// generate: var indexVar
Pattern *indexPat = new (C) NamedPattern(indexVar, /*implicit*/ true);
indexPat->setType(intType);
indexPat = new (C) TypedPattern(indexPat, TypeLoc::withoutLoc(intType));
indexPat->setType(intType);
auto indexBind = PatternBindingDecl::create(C, SourceLoc(),
StaticSpellingKind::None,
SourceLoc(),
indexPat, nullptr, funcDecl);
unsigned index = 0;
SmallVector<CaseStmt*, 4> cases;
for (auto elt : enumDecl->getAllElements()) {
// generate: case .<Case>:
auto pat = new (C) EnumElementPattern(TypeLoc::withoutLoc(enumType),
SourceLoc(), SourceLoc(),
Identifier(), elt, nullptr);
pat->setImplicit();
auto labelItem = CaseLabelItem(/*IsDefault=*/false, pat, SourceLoc(),
nullptr);
// generate: indexVar = <index>
llvm::SmallString<8> indexVal;
APInt(32, index++).toString(indexVal, 10, /*signed*/ false);
auto indexStr = C.AllocateCopy(indexVal);
auto indexExpr = new (C) IntegerLiteralExpr(StringRef(indexStr.data(),
indexStr.size()), SourceLoc(),
/*implicit*/ true);
auto indexRef = new (C) DeclRefExpr(indexVar, SourceLoc(),
/*implicit*/true);
auto assignExpr = new (C) AssignExpr(indexRef, SourceLoc(),
indexExpr, /*implicit*/ true);
auto body = BraceStmt::create(C, SourceLoc(), ASTNode(assignExpr),
SourceLoc());
cases.push_back(CaseStmt::create(C, SourceLoc(), labelItem,
/*HasBoundDecls=*/false,
SourceLoc(), body));
}
// generate: switch enumVar { }
auto enumRef = new (C) DeclRefExpr(enumVarDecl, SourceLoc(),
/*implicit*/true);
auto switchStmt = SwitchStmt::create(LabeledStmtInfo(), SourceLoc(), enumRef,
SourceLoc(), cases, SourceLoc(), C);
stmts.push_back(indexBind);
stmts.push_back(switchStmt);
return new (C) DeclRefExpr(indexVar, SourceLoc(), /*implicit*/ true,
AccessSemantics::Ordinary, intType);
}