@@ -4021,25 +4021,86 @@ bool ValueDecl::canInferObjCFromRequirement(ValueDecl *requirement) {
40214021 return false ;
40224022}
40234023
4024- SourceLoc ValueDecl::getAttributeInsertionLoc (bool forModifier) const {
4025- if (isImplicit ())
4024+ SourceLoc Decl::getAttributeInsertionLoc (bool forModifier) const {
4025+ // Some decls have a parent/child split where the introducer keyword is on the
4026+ // parent, but the attributes are on the children. If this is a child in such
4027+ // a pair, `introDecl` will be changed to point to the parent. (The parent
4028+ // decl should delegate to one of its children.)
4029+ const Decl *introDecl = this ;
4030+
4031+ switch (getKind ()) {
4032+ case DeclKind::Module:
4033+ case DeclKind::TopLevelCode:
4034+ case DeclKind::IfConfig:
4035+ case DeclKind::PoundDiagnostic:
4036+ case DeclKind::Missing:
4037+ case DeclKind::MissingMember:
4038+ case DeclKind::MacroExpansion:
4039+ case DeclKind::BuiltinTuple:
4040+ // These don't take attributes.
40264041 return SourceLoc ();
40274042
4028- if (auto var = dyn_cast<VarDecl>(this )) {
4029- // [attrs] var ...
4030- // The attributes are part of the VarDecl, but the 'var' is part of the PBD.
4031- SourceLoc resultLoc = var->getAttrs ().getStartLoc (forModifier);
4032- if (resultLoc.isValid ()) {
4033- return resultLoc;
4034- } else if (auto pbd = var->getParentPatternBinding ()) {
4035- return pbd->getStartLoc ();
4036- } else {
4037- return var->getStartLoc ();
4043+ case DeclKind::EnumCase:
4044+ // An ECD's attributes are attached to its elements.
4045+ if (auto elem = cast<EnumCaseDecl>(this )->getFirstElement ())
4046+ return elem->getAttributeInsertionLoc (forModifier);
4047+ break ;
4048+
4049+ case DeclKind::EnumElement:
4050+ // An EED's introducer keyword is on its parent case.
4051+ if (auto parent = cast<EnumElementDecl>(this )->getParentCase ())
4052+ introDecl = parent;
4053+ break ;
4054+
4055+ case DeclKind::PatternBinding: {
4056+ // A PBD's attributes are attached to the vars in its patterns.
4057+ auto pbd = cast<PatternBindingDecl>(this );
4058+
4059+ for (unsigned i = 0 ; i < pbd->getNumPatternEntries (); i++) {
4060+ if (auto var = pbd->getAnchoringVarDecl (i)) {
4061+ return var->getAttributeInsertionLoc (forModifier);
4062+ }
40384063 }
4064+
4065+ break ;
4066+ }
4067+
4068+ case DeclKind::Var:
4069+ case DeclKind::Param:
4070+ // A VarDecl's introducer keyword, if it has one, is on its pattern binding.
4071+ if (auto pbd = cast<VarDecl>(this )->getParentPatternBinding ())
4072+ introDecl = pbd;
4073+ break ;
4074+
4075+ case DeclKind::Enum:
4076+ case DeclKind::Struct:
4077+ case DeclKind::Class:
4078+ case DeclKind::Protocol:
4079+ case DeclKind::OpaqueType:
4080+ case DeclKind::TypeAlias:
4081+ case DeclKind::GenericTypeParam:
4082+ case DeclKind::AssociatedType:
4083+ case DeclKind::Subscript:
4084+ case DeclKind::Constructor:
4085+ case DeclKind::Destructor:
4086+ case DeclKind::Func:
4087+ case DeclKind::Accessor:
4088+ case DeclKind::Macro:
4089+ case DeclKind::Extension:
4090+ case DeclKind::Import:
4091+ case DeclKind::PrecedenceGroup:
4092+ case DeclKind::InfixOperator:
4093+ case DeclKind::PrefixOperator:
4094+ case DeclKind::PostfixOperator:
4095+ // Both the introducer keyword and the attributes are on `this`.
4096+ break ;
40394097 }
40404098
4099+ if (isImplicit ())
4100+ return SourceLoc ();
4101+
40414102 SourceLoc resultLoc = getAttrs ().getStartLoc (forModifier);
4042- return resultLoc.isValid () ? resultLoc : getStartLoc ();
4103+ return resultLoc.isValid () ? resultLoc : introDecl-> getStartLoc ();
40434104}
40444105
40454106// / Returns true if \p VD needs to be treated as publicly-accessible
0 commit comments