Skip to content

Commit 85fee88

Browse files
authored
Merge pull request #3101 from apple/eng/ns_error_enum_fix
Revert back to previous ns_Error_enum behavior
2 parents c287d91 + 10c7a0d commit 85fee88

File tree

4 files changed

+29
-33
lines changed

4 files changed

+29
-33
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2040,7 +2040,7 @@ def ObjCBridgeRelated : InheritableAttr {
20402040
def NSErrorDomain : InheritableAttr {
20412041
let Spellings = [GNU<"ns_error_domain">];
20422042
let Subjects = SubjectList<[Enum], ErrorDiag>;
2043-
let Args = [DeclArgument<Var, "ErrorDomain">];
2043+
let Args = [IdentifierArgument<"ErrorDomain">];
20442044
let Documentation = [NSErrorDomainDocs];
20452045
}
20462046

clang/lib/Sema/SemaAPINotes.cpp

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -348,22 +348,11 @@ static void ProcessAPINotes(Sema &S, Decl *D,
348348

349349
// ns_error_domain
350350
if (auto nsErrorDomain = info.getNSErrorDomain()) {
351-
handleAPINotedAttribute<NSErrorDomainAttr>(
352-
S, D, !nsErrorDomain->empty(), metadata, [&]() -> NSErrorDomainAttr * {
353-
LookupResult lookupResult(
354-
S, DeclarationName(&S.Context.Idents.get(*nsErrorDomain)),
355-
SourceLocation(), Sema::LookupNameKind::LookupOrdinaryName);
356-
S.LookupName(lookupResult, S.TUScope);
357-
auto *VD = lookupResult.getAsSingle<VarDecl>();
358-
359-
if (!VD) {
360-
S.Diag(D->getLocation(), diag::err_nserrordomain_invalid_decl) << 0;
361-
return nullptr;
362-
}
363-
364-
return new (S.Context)
365-
NSErrorDomainAttr(S.Context, getDummyAttrInfo(), VD);
366-
});
351+
handleAPINotedAttribute<NSErrorDomainAttr>(S, D, !nsErrorDomain->empty(),
352+
metadata, [&] {
353+
return new (S.Context) NSErrorDomainAttr(
354+
S.Context, getDummyAttrInfo(), &S.Context.Idents.get(*nsErrorDomain));
355+
});
367356
}
368357

369358
ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(info),

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5509,29 +5509,37 @@ static void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
55095509
D->addAttr(::new (S.Context) ObjCRequiresSuperAttr(S.Context, Attrs));
55105510
}
55115511

5512-
static void handleNSErrorDomain(Sema &S, Decl *D, const ParsedAttr &AL) {
5513-
auto *E = AL.getArgAsExpr(0);
5514-
auto Loc = E ? E->getBeginLoc() : AL.getLoc();
5515-
5516-
auto *DRE = dyn_cast<DeclRefExpr>(AL.getArgAsExpr(0));
5517-
if (!DRE) {
5518-
S.Diag(Loc, diag::err_nserrordomain_invalid_decl) << 0;
5512+
static void handleNSErrorDomain(Sema &S, Decl *D, const ParsedAttr &Attr) {
5513+
if (!isa<TagDecl>(D)) {
5514+
S.Diag(D->getBeginLoc(), diag::err_nserrordomain_invalid_decl)
5515+
<< 0;
55195516
return;
55205517
}
5518+
IdentifierLoc *identLoc =
5519+
Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr;
5520+
if (!identLoc || !identLoc->Ident) {
5521+
// Try to locate the argument directly
5522+
SourceLocation loc = Attr.getLoc();
5523+
if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0))
5524+
loc = Attr.getArgAsExpr(0)->getBeginLoc();
55215525

5522-
auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
5523-
if (!VD) {
5524-
S.Diag(Loc, diag::err_nserrordomain_invalid_decl) << 1 << DRE->getDecl();
5526+
S.Diag(loc, diag::err_nserrordomain_invalid_decl) << 0;
55255527
return;
55265528
}
55275529

5528-
if (!isNSStringType(VD->getType(), S.Context) &&
5529-
!isCFStringType(VD->getType(), S.Context)) {
5530-
S.Diag(Loc, diag::err_nserrordomain_wrong_type) << VD;
5530+
// Verify that the identifier is a valid decl in the C decl namespace
5531+
LookupResult lookupResult(S, DeclarationName(identLoc->Ident),
5532+
SourceLocation(),
5533+
Sema::LookupNameKind::LookupOrdinaryName);
5534+
if (!S.LookupName(lookupResult, S.TUScope) ||
5535+
!lookupResult.getAsSingle<VarDecl>()) {
5536+
S.Diag(identLoc->Loc, diag::err_nserrordomain_invalid_decl)
5537+
<< 1 << identLoc->Ident;
55315538
return;
55325539
}
55335540

5534-
D->addAttr(::new (S.Context) NSErrorDomainAttr(S.Context, AL, VD));
5541+
D->addAttr(::new (S.Context)
5542+
NSErrorDomainAttr(S.Context, Attr, identLoc->Ident));
55355543
}
55365544

55375545
static void handleObjCBridgeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {

clang/test/Sema/ns_error_enum.m

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ typedef NS_ERROR_ENUM(unsigned char, MyCFTypedefErrorEnum, MyCFTypedefErrorDomai
5353

5454
extern char *const WrongErrorDomainType;
5555
enum __attribute__((ns_error_domain(WrongErrorDomainType))) MyWrongErrorDomainType { MyWrongErrorDomain };
56-
// expected-error@-1{{domain argument 'WrongErrorDomainType' does not point to an NSString or CFString constant}}
5756

5857
struct __attribute__((ns_error_domain(MyErrorDomain))) MyStructWithErrorDomain {};
5958
// expected-error@-1{{'ns_error_domain' attribute only applies to enums}}
@@ -68,7 +67,7 @@ typedef NS_ERROR_ENUM(unsigned char, MyCFTypedefErrorEnum, MyCFTypedefErrorDomai
6867
// expected-error@-1{{'ns_error_domain' attribute takes one argument}}
6968

7069
typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, InvalidDomain) {
71-
// expected-error@-1{{use of undeclared identifier 'InvalidDomain'}}
70+
// expected-error@-1{{domain argument 'InvalidDomain' does not refer to global constant}}
7271
MyErrFirstInvalid,
7372
MyErrSecondInvalid,
7473
};

0 commit comments

Comments
 (0)