Skip to content

Commit d036ebc

Browse files
committed
---
yaml --- r: 349553 b: refs/heads/master-next c: 7c8b085 h: refs/heads/master i: 349551: 5ad3b25
1 parent 80d46c0 commit d036ebc

File tree

10 files changed

+95
-62
lines changed

10 files changed

+95
-62
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
refs/heads/master: 3574c513bbc5578dd9346b4ea9ab5995c5927bb5
3-
refs/heads/master-next: d9f20a99d43f5b13eecf2532b66bf14bbd6f3ecf
3+
refs/heads/master-next: 7c8b08501e500256e2ee65a0905d4dc564bc5535
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea
66
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-b: 66d897bfcf64a82cb9a87f5e663d889189d06d07

branches/master-next/include/swift/AST/ASTTypeIDZone.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ SWIFT_TYPEID(CtorInitializerKind)
2727
SWIFT_TYPEID(ResilienceExpansion)
2828
SWIFT_TYPEID_NAMED(Optional<PropertyWrapperMutability>, PropertyWrapperMutability)
2929
SWIFT_TYPEID_NAMED(CustomAttr *, CustomAttr)
30+
SWIFT_TYPEID_NAMED(OperatorDecl *, OperatorDecl)
3031
SWIFT_TYPEID_NAMED(TypeAliasDecl *, TypeAliasDecl)
3132
SWIFT_TYPEID(AncestryFlags)
3233
SWIFT_TYPEID_NAMED(GenericSignature *, GenericSignature)

branches/master-next/include/swift/AST/Decl.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5926,7 +5926,6 @@ class FuncDecl : public AbstractFunctionDecl {
59265926

59275927
TypeLoc FnRetType;
59285928

5929-
OperatorDecl *Operator = nullptr;
59305929
OpaqueTypeDecl *OpaqueReturn = nullptr;
59315930

59325931
protected:
@@ -6073,13 +6072,7 @@ class FuncDecl : public AbstractFunctionDecl {
60736072
return cast_or_null<FuncDecl>(AbstractFunctionDecl::getOverriddenDecl());
60746073
}
60756074

6076-
OperatorDecl *getOperatorDecl() const {
6077-
return Operator;
6078-
}
6079-
void setOperatorDecl(OperatorDecl *o) {
6080-
assert(isOperator() && "can't set an OperatorDecl for a non-operator");
6081-
Operator = o;
6082-
}
6075+
OperatorDecl *getOperatorDecl() const;
60836076

60846077
OpaqueTypeDecl *getOpaqueResultTypeDecl() const {
60856078
return OpaqueReturn;

branches/master-next/include/swift/AST/TypeCheckRequests.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1067,7 +1067,6 @@ class ClassAncestryFlagsRequest :
10671067
// Evaluation.
10681068
llvm::Expected<AncestryFlags>
10691069
evaluate(Evaluator &evaluator, ClassDecl *value) const;
1070-
10711070
public:
10721071
// Caching.
10731072
bool isCached() const { return true; }
@@ -1116,7 +1115,25 @@ class ExtendedTypeRequest
11161115

11171116
// Evaluation.
11181117
llvm::Expected<Type> evaluate(Evaluator &eval, ExtensionDecl *) const;
1118+
public:
1119+
// Caching.
1120+
bool isCached() const { return true; }
1121+
};
11191122

1123+
class FunctionOperatorRequest :
1124+
public SimpleRequest<FunctionOperatorRequest,
1125+
OperatorDecl *(FuncDecl *),
1126+
CacheKind::Cached> {
1127+
public:
1128+
using SimpleRequest::SimpleRequest;
1129+
1130+
private:
1131+
friend SimpleRequest;
1132+
1133+
// Evaluation.
1134+
llvm::Expected<OperatorDecl *>
1135+
evaluate(Evaluator &evaluator, FuncDecl *value) const;
1136+
11201137
public:
11211138
// Caching.
11221139
bool isCached() const { return true; }

branches/master-next/include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,4 @@ SWIFT_TYPEID(IsImplicitlyUnwrappedOptionalRequest)
5959
SWIFT_TYPEID(ClassAncestryFlagsRequest)
6060
SWIFT_TYPEID(AbstractGenericSignatureRequest)
6161
SWIFT_TYPEID(ExtendedTypeRequest)
62+
SWIFT_TYPEID(FunctionOperatorRequest)

branches/master-next/include/swift/Serialization/ModuleFormat.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -901,9 +901,9 @@ namespace decls_block {
901901
BCFixed<1>, // pseudogeneric?
902902
BCFixed<1>, // noescape?
903903
BCFixed<1>, // error result?
904-
BCFixed<30>, // number of parameters
905-
BCFixed<30>, // number of yields
906-
BCFixed<30>, // number of results
904+
BCVBR<6>, // number of parameters
905+
BCVBR<5>, // number of yields
906+
BCVBR<5>, // number of results
907907
GenericSignatureIDField, // generic signature
908908
BCArray<TypeIDField> // parameter types/conventions, alternating
909909
// followed by result types/conventions, alternating
@@ -919,7 +919,7 @@ namespace decls_block {
919919
using SILLayoutLayout = BCRecordLayout<
920920
SIL_LAYOUT,
921921
GenericSignatureIDField, // generic signature
922-
BCFixed<31>, // number of fields
922+
BCVBR<8>, // number of fields
923923
BCArray<TypeIDWithBitField> // field types with mutability
924924
>;
925925

@@ -1106,7 +1106,7 @@ namespace decls_block {
11061106
AccessLevelField, // setter access, if applicable
11071107
DeclIDField, // opaque return type decl
11081108
BCFixed<2>, // # of property wrapper backing properties
1109-
BCVBR<4>, // total number of vtable entries introduced by all accessors
1109+
BCVBR<4>, // total number of vtable entries introduced by all accessors
11101110
BCArray<TypeIDField> // accessors, backing properties, and dependencies
11111111
>;
11121112

@@ -1272,7 +1272,7 @@ namespace decls_block {
12721272
StaticSpellingKindField, // is subscript static?
12731273
BCVBR<5>, // number of parameter name components
12741274
DeclIDField, // opaque return type decl
1275-
BCFixed<8>, // total number of vtable entries introduced by all accessors
1275+
BCVBR<4>, // total number of vtable entries introduced by all accessors
12761276
BCArray<IdentifierIDField> // name components,
12771277
// followed by DeclID accessors,
12781278
// followed by TypeID dependencies
@@ -1396,8 +1396,8 @@ namespace decls_block {
13961396
LAYOUT_REQUIREMENT,
13971397
LayoutRequirementKindField, // requirement kind
13981398
TypeIDField, // type being constrained
1399-
BCFixed<24>, // size
1400-
BCFixed<32> // alignment
1399+
BCVBR<16>, // size
1400+
BCVBR<8> // alignment
14011401
>;
14021402

14031403
/// Specifies the private discriminator string for a private declaration. This
@@ -1549,7 +1549,7 @@ namespace decls_block {
15491549
using AlignmentDeclAttrLayout = BCRecordLayout<
15501550
Alignment_DECL_ATTR,
15511551
BCFixed<1>, // implicit flag
1552-
BCFixed<31> // alignment
1552+
BCVBR<8> // alignment
15531553
>;
15541554

15551555
using SwiftNativeObjCRuntimeBaseDeclAttrLayout = BCRecordLayout<

branches/master-next/lib/AST/Decl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6887,6 +6887,18 @@ FuncDecl *FuncDecl::create(ASTContext &Context, SourceLoc StaticLoc,
68876887
FD->getBodyResultTypeLoc() = FnRetType;
68886888
return FD;
68896889
}
6890+
6891+
OperatorDecl *FuncDecl::getOperatorDecl() const {
6892+
// Fast-path: Most functions are not operators.
6893+
if (!isOperator()) {
6894+
return nullptr;
6895+
}
6896+
return evaluateOrDefault(getASTContext().evaluator,
6897+
FunctionOperatorRequest{
6898+
const_cast<FuncDecl *>(this)
6899+
},
6900+
nullptr);
6901+
}
68906902

68916903
AccessorDecl *AccessorDecl::createImpl(ASTContext &ctx,
68926904
SourceLoc declLoc,

branches/master-next/lib/Sema/TypeCheckDecl.cpp

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3430,19 +3430,19 @@ static void validateTypealiasType(TypeChecker &tc, TypeAliasDecl *typeAlias) {
34303430
}
34313431

34323432

3433-
/// Bind the given function declaration, which declares an operator, to
3434-
/// the corresponding operator declaration.
3435-
void bindFuncDeclToOperator(TypeChecker &TC, FuncDecl *FD) {
3436-
OperatorDecl *op = nullptr;
3433+
/// Bind the given function declaration, which declares an operator, to the corresponding operator declaration.
3434+
llvm::Expected<OperatorDecl *>
3435+
FunctionOperatorRequest::evaluate(Evaluator &evaluator, FuncDecl *FD) const {
3436+
auto &C = FD->getASTContext();
3437+
auto &diags = C.Diags;
34373438
auto operatorName = FD->getFullName().getBaseIdentifier();
34383439

34393440
// Check for static/final/class when we're in a type.
34403441
auto dc = FD->getDeclContext();
34413442
if (dc->isTypeContext()) {
34423443
if (!FD->isStatic()) {
3443-
TC.diagnose(FD->getLoc(), diag::nonstatic_operator_in_type,
3444-
operatorName,
3445-
dc->getDeclaredInterfaceType())
3444+
FD->diagnose(diag::nonstatic_operator_in_type,
3445+
operatorName, dc->getDeclaredInterfaceType())
34463446
.fixItInsert(FD->getAttributeInsertionLoc(/*forModifier=*/true),
34473447
"static ");
34483448

@@ -3451,17 +3451,18 @@ void bindFuncDeclToOperator(TypeChecker &TC, FuncDecl *FD) {
34513451
// For a class, we also need the function or class to be 'final'.
34523452
if (!classDecl->isFinal() && !FD->isFinal() &&
34533453
FD->getStaticSpelling() != StaticSpellingKind::KeywordStatic) {
3454-
TC.diagnose(FD->getLoc(), diag::nonfinal_operator_in_class,
3455-
operatorName, dc->getDeclaredInterfaceType())
3454+
FD->diagnose(diag::nonfinal_operator_in_class,
3455+
operatorName, dc->getDeclaredInterfaceType())
34563456
.fixItInsert(FD->getAttributeInsertionLoc(/*forModifier=*/true),
34573457
"final ");
3458-
FD->getAttrs().add(new (TC.Context) FinalAttr(/*IsImplicit=*/true));
3458+
FD->getAttrs().add(new (C) FinalAttr(/*IsImplicit=*/true));
34593459
}
34603460
}
34613461
} else if (!dc->isModuleScopeContext()) {
3462-
TC.diagnose(FD, diag::operator_in_local_scope);
3462+
FD->diagnose(diag::operator_in_local_scope);
34633463
}
34643464

3465+
OperatorDecl *op = nullptr;
34653466
SourceFile &SF = *FD->getDeclContext()->getParentSourceFile();
34663467
if (FD->isUnaryOperator()) {
34673468
if (FD->getAttrs().hasAttribute<PrefixAttr>()) {
@@ -3485,21 +3486,21 @@ void bindFuncDeclToOperator(TypeChecker &TC, FuncDecl *FD) {
34853486
// If we found both prefix and postfix, or neither prefix nor postfix,
34863487
// complain. We can't fix this situation.
34873488
if (static_cast<bool>(prefixOp) == static_cast<bool>(postfixOp)) {
3488-
TC.diagnose(FD, diag::declared_unary_op_without_attribute);
3489+
diags.diagnose(FD, diag::declared_unary_op_without_attribute);
34893490

34903491
// If we found both, point at them.
34913492
if (prefixOp) {
3492-
TC.diagnose(prefixOp, diag::unary_operator_declaration_here, false)
3493+
diags.diagnose(prefixOp, diag::unary_operator_declaration_here, false)
34933494
.fixItInsert(FD->getLoc(), "prefix ");
3494-
TC.diagnose(postfixOp, diag::unary_operator_declaration_here, true)
3495+
diags.diagnose(postfixOp, diag::unary_operator_declaration_here, true)
34953496
.fixItInsert(FD->getLoc(), "postfix ");
34963497
} else {
34973498
// FIXME: Introduce a Fix-It that adds the operator declaration?
34983499
}
34993500

35003501
// FIXME: Errors could cascade here, because name lookup for this
35013502
// operator won't find this declaration.
3502-
return;
3503+
return nullptr;
35033504
}
35043505

35053506
// We found only one operator declaration, so we know whether this
@@ -3519,29 +3520,33 @@ void bindFuncDeclToOperator(TypeChecker &TC, FuncDecl *FD) {
35193520
}
35203521

35213522
// Emit diagnostic with the Fix-It.
3522-
TC.diagnose(FD->getFuncLoc(), diag::unary_op_missing_prepos_attribute,
3523+
diags.diagnose(FD->getFuncLoc(), diag::unary_op_missing_prepos_attribute,
35233524
static_cast<bool>(postfixOp))
35243525
.fixItInsert(FD->getFuncLoc(), insertionText);
3525-
TC.diagnose(op, diag::unary_operator_declaration_here,
3526+
diags.diagnose(op, diag::unary_operator_declaration_here,
35263527
static_cast<bool>(postfixOp));
35273528
}
35283529
} else if (FD->isBinaryOperator()) {
35293530
op = SF.lookupInfixOperator(operatorName,
35303531
FD->isCascadingContextForLookup(false),
35313532
FD->getLoc());
35323533
} else {
3533-
TC.diagnose(FD, diag::invalid_arg_count_for_operator);
3534-
return;
3534+
diags.diagnose(FD, diag::invalid_arg_count_for_operator);
3535+
return nullptr;
35353536
}
35363537

35373538
if (!op) {
35383539
SourceLoc insertionLoc;
35393540
if (isa<SourceFile>(FD->getParent())) {
3540-
// Parent context is SourceFile, insertion location is start of func declaration
3541-
// or unary operator
3542-
insertionLoc = FD->isUnaryOperator() ? FD->getAttrs().getStartLoc() : FD->getStartLoc();
3541+
// Parent context is SourceFile, insertion location is start of func
3542+
// declaration or unary operator
3543+
if (FD->isUnaryOperator()) {
3544+
insertionLoc = FD->getAttrs().getStartLoc();
3545+
} else {
3546+
insertionLoc = FD->getStartLoc();
3547+
}
35433548
} else {
3544-
// Finding top-level decl context before SourceFile and inserting before it
3549+
// Find the topmost non-file decl context and insert there.
35453550
for (DeclContext *CurContext = FD->getLocalContext();
35463551
!isa<SourceFile>(CurContext);
35473552
CurContext = CurContext->getParent()) {
@@ -3552,25 +3557,28 @@ void bindFuncDeclToOperator(TypeChecker &TC, FuncDecl *FD) {
35523557
}
35533558

35543559
SmallString<128> insertion;
3555-
auto numOfParams = FD->getParameters()->size();
3556-
if (numOfParams == 1) {
3557-
if (FD->getAttrs().hasAttribute<PrefixAttr>())
3558-
insertion += "prefix operator ";
3559-
else
3560-
insertion += "postfix operator ";
3561-
} else if (numOfParams == 2) {
3562-
insertion += "infix operator ";
3563-
}
3560+
{
3561+
llvm::raw_svector_ostream str(insertion);
3562+
assert(FD->isUnaryOperator() || FD->isBinaryOperator());
3563+
if (FD->isUnaryOperator()) {
3564+
if (FD->getAttrs().hasAttribute<PrefixAttr>())
3565+
str << "prefix operator ";
3566+
else
3567+
str << "postfix operator ";
3568+
} else {
3569+
str << "infix operator ";
3570+
}
35643571

3565-
insertion += operatorName.str();
3566-
insertion += " : <# Precedence Group #>\n";
3567-
InFlightDiagnostic opDiagnostic = TC.diagnose(FD, diag::declared_operator_without_operator_decl);
3572+
str << operatorName.str() << " : <# Precedence Group #>\n";
3573+
}
3574+
InFlightDiagnostic opDiagnostic =
3575+
diags.diagnose(FD, diag::declared_operator_without_operator_decl);
35683576
if (insertionLoc.isValid())
35693577
opDiagnostic.fixItInsert(insertionLoc, insertion);
3570-
return;
3578+
return nullptr;
35713579
}
35723580

3573-
FD->setOperatorDecl(op);
3581+
return op;
35743582
}
35753583

35763584
bool swift::isMemberOperator(FuncDecl *decl, Type type) {
@@ -3868,10 +3876,9 @@ void TypeChecker::validateDecl(ValueDecl *D) {
38683876

38693877
DeclValidationRAII IBV(FD);
38703878

3871-
// Bind operator functions to the corresponding operator declaration.
3872-
if (FD->isOperator())
3873-
bindFuncDeclToOperator(*this, FD);
3874-
3879+
// Force computing the operator decl in case it emits diagnostics.
3880+
(void) FD->getOperatorDecl();
3881+
38753882
// Validate 'static'/'class' on functions in extensions.
38763883
auto StaticSpelling = FD->getStaticSpelling();
38773884
if (StaticSpelling != StaticSpellingKind::None &&

branches/master-next/lib/Sema/TypeCheckDecl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,5 @@ void validatePatternBindingEntries(TypeChecker &tc,
4242
PatternBindingDecl *binding);
4343
}
4444

45-
#endif
45+
#endif
46+

branches/master-next/lib/Serialization/Deserialization.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3026,7 +3026,8 @@ class swift::DeclDeserializer {
30263026
if (!isAccessor) {
30273027
if (Decl *associated = MF.getDecl(associatedDeclID)) {
30283028
if (auto op = dyn_cast<OperatorDecl>(associated)) {
3029-
fn->setOperatorDecl(op);
3029+
ctx.evaluator.cacheOutput(FunctionOperatorRequest{fn},
3030+
std::move(op));
30303031

30313032
if (isa<PrefixOperatorDecl>(op))
30323033
fn->getAttrs().add(new (ctx) PrefixAttr(/*implicit*/false));

0 commit comments

Comments
 (0)