@@ -1891,16 +1891,6 @@ bool Decl::isObjCImplementation() const {
1891
1891
return getAttrs().hasAttribute<ObjCImplementationAttr>(/*AllowInvalid=*/true);
1892
1892
}
1893
1893
1894
- std::optional<Identifier>
1895
- ExtensionDecl::getCategoryNameForObjCImplementation() const {
1896
- auto attr = getAttrs()
1897
- .getAttribute<ObjCImplementationAttr>(/*AllowInvalid=*/true);
1898
- if (!attr || attr->isCategoryNameInvalid())
1899
- return std::nullopt;
1900
-
1901
- return attr->CategoryName;
1902
- }
1903
-
1904
1894
PatternBindingDecl::PatternBindingDecl(SourceLoc StaticLoc,
1905
1895
StaticSpellingKind StaticSpelling,
1906
1896
SourceLoc VarLoc,
@@ -3745,6 +3735,20 @@ void ValueDecl::setIsObjC(bool value) {
3745
3735
LazySemanticInfo.isObjC = value;
3746
3736
}
3747
3737
3738
+ Identifier ExtensionDecl::getObjCCategoryName() const {
3739
+ // If there's an @objc attribute, it's authoritative. (ClangImporter
3740
+ // attaches one automatically.)
3741
+ if (auto objcAttr = getAttrs().getAttribute<ObjCAttr>(/*AllowInvalid*/true)) {
3742
+ if (objcAttr->hasName() && objcAttr->getName()->getNumArgs() == 0)
3743
+ return objcAttr->getName()->getSimpleName();
3744
+
3745
+ return Identifier();
3746
+ }
3747
+
3748
+ // Not a category, evidently.
3749
+ return Identifier();
3750
+ }
3751
+
3748
3752
bool ValueDecl::isSemanticallyFinal() const {
3749
3753
// Actor types are semantically final.
3750
3754
if (auto classDecl = dyn_cast<ClassDecl>(this)) {
@@ -4039,25 +4043,86 @@ bool ValueDecl::canInferObjCFromRequirement(ValueDecl *requirement) {
4039
4043
return false;
4040
4044
}
4041
4045
4042
- SourceLoc ValueDecl::getAttributeInsertionLoc(bool forModifier) const {
4043
- if (isImplicit())
4046
+ SourceLoc Decl::getAttributeInsertionLoc(bool forModifier) const {
4047
+ // Some decls have a parent/child split where the introducer keyword is on the
4048
+ // parent, but the attributes are on the children. If this is a child in such
4049
+ // a pair, `introDecl` will be changed to point to the parent. (The parent
4050
+ // decl should delegate to one of its children.)
4051
+ const Decl *introDecl = this;
4052
+
4053
+ switch (getKind()) {
4054
+ case DeclKind::Module:
4055
+ case DeclKind::TopLevelCode:
4056
+ case DeclKind::IfConfig:
4057
+ case DeclKind::PoundDiagnostic:
4058
+ case DeclKind::Missing:
4059
+ case DeclKind::MissingMember:
4060
+ case DeclKind::MacroExpansion:
4061
+ case DeclKind::BuiltinTuple:
4062
+ // These don't take attributes.
4044
4063
return SourceLoc();
4045
4064
4046
- if (auto var = dyn_cast<VarDecl>(this)) {
4047
- // [attrs] var ...
4048
- // The attributes are part of the VarDecl, but the 'var' is part of the PBD.
4049
- SourceLoc resultLoc = var->getAttrs().getStartLoc(forModifier);
4050
- if (resultLoc.isValid()) {
4051
- return resultLoc;
4052
- } else if (auto pbd = var->getParentPatternBinding()) {
4053
- return pbd->getStartLoc();
4054
- } else {
4055
- return var->getStartLoc();
4065
+ case DeclKind::EnumCase:
4066
+ // An ECD's attributes are attached to its elements.
4067
+ if (auto elem = cast<EnumCaseDecl>(this)->getFirstElement())
4068
+ return elem->getAttributeInsertionLoc(forModifier);
4069
+ break;
4070
+
4071
+ case DeclKind::EnumElement:
4072
+ // An EED's introducer keyword is on its parent case.
4073
+ if (auto parent = cast<EnumElementDecl>(this)->getParentCase())
4074
+ introDecl = parent;
4075
+ break;
4076
+
4077
+ case DeclKind::PatternBinding: {
4078
+ // A PBD's attributes are attached to the vars in its patterns.
4079
+ auto pbd = cast<PatternBindingDecl>(this);
4080
+
4081
+ for (unsigned i = 0; i < pbd->getNumPatternEntries(); i++) {
4082
+ if (auto var = pbd->getAnchoringVarDecl(i)) {
4083
+ return var->getAttributeInsertionLoc(forModifier);
4084
+ }
4056
4085
}
4086
+
4087
+ break;
4057
4088
}
4058
4089
4090
+ case DeclKind::Var:
4091
+ case DeclKind::Param:
4092
+ // A VarDecl's introducer keyword, if it has one, is on its pattern binding.
4093
+ if (auto pbd = cast<VarDecl>(this)->getParentPatternBinding())
4094
+ introDecl = pbd;
4095
+ break;
4096
+
4097
+ case DeclKind::Enum:
4098
+ case DeclKind::Struct:
4099
+ case DeclKind::Class:
4100
+ case DeclKind::Protocol:
4101
+ case DeclKind::OpaqueType:
4102
+ case DeclKind::TypeAlias:
4103
+ case DeclKind::GenericTypeParam:
4104
+ case DeclKind::AssociatedType:
4105
+ case DeclKind::Subscript:
4106
+ case DeclKind::Constructor:
4107
+ case DeclKind::Destructor:
4108
+ case DeclKind::Func:
4109
+ case DeclKind::Accessor:
4110
+ case DeclKind::Macro:
4111
+ case DeclKind::Extension:
4112
+ case DeclKind::Import:
4113
+ case DeclKind::PrecedenceGroup:
4114
+ case DeclKind::InfixOperator:
4115
+ case DeclKind::PrefixOperator:
4116
+ case DeclKind::PostfixOperator:
4117
+ // Both the introducer keyword and the attributes are on `this`.
4118
+ break;
4119
+ }
4120
+
4121
+ if (isImplicit())
4122
+ return SourceLoc();
4123
+
4059
4124
SourceLoc resultLoc = getAttrs().getStartLoc(forModifier);
4060
- return resultLoc.isValid() ? resultLoc : getStartLoc();
4125
+ return resultLoc.isValid() ? resultLoc : introDecl-> getStartLoc();
4061
4126
}
4062
4127
4063
4128
/// Returns true if \p VD needs to be treated as publicly-accessible
@@ -11323,7 +11388,7 @@ void swift::simple_display(llvm::raw_ostream &out, const Decl *decl) {
11323
11388
}
11324
11389
11325
11390
if (auto value = dyn_cast<ValueDecl>(decl)) {
11326
- simple_display(out, value);
11391
+ return simple_display(out, value);
11327
11392
} else if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
11328
11393
out << "extension of ";
11329
11394
if (auto typeRepr = ext->getExtendedTypeRepr())
@@ -11333,13 +11398,13 @@ void swift::simple_display(llvm::raw_ostream &out, const Decl *decl) {
11333
11398
} else if (auto med = dyn_cast<MacroExpansionDecl>(decl)) {
11334
11399
out << '#' << med->getMacroName() << " in ";
11335
11400
printContext(out, med->getDeclContext());
11336
- if (med->getLoc().isValid()) {
11337
- out << '@';
11338
- med->getLoc().print(out, med->getASTContext().SourceMgr);
11339
- }
11340
11401
} else {
11341
11402
out << "(unknown decl)";
11342
11403
}
11404
+ if (decl->getLoc().isValid()) {
11405
+ out << '@';
11406
+ decl->getLoc().print(out, decl->getASTContext().SourceMgr);
11407
+ }
11343
11408
}
11344
11409
11345
11410
void swift::simple_display(llvm::raw_ostream &out,
0 commit comments