Skip to content

Commit 5a54e98

Browse files
authored
Merge pull request #2634 from apple/nserrordom2
Make NSErrorDomain argument operate on the identifier instead of VarDecl
2 parents a942aa5 + 4c9ba44 commit 5a54e98

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
@@ -1944,7 +1944,7 @@ def ObjCBridgeRelated : InheritableAttr {
19441944
def NSErrorDomain : InheritableAttr {
19451945
let Spellings = [GNU<"ns_error_domain">];
19461946
let Subjects = SubjectList<[Enum], ErrorDiag>;
1947-
let Args = [DeclArgument<Var, "ErrorDomain">];
1947+
let Args = [IdentifierArgument<"ErrorDomain">];
19481948
let Documentation = [NSErrorDomainDocs];
19491949
}
19501950

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
@@ -5536,29 +5536,37 @@ static void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
55365536
D->addAttr(::new (S.Context) ObjCRequiresSuperAttr(S.Context, Attrs));
55375537
}
55385538

5539-
static void handleNSErrorDomain(Sema &S, Decl *D, const ParsedAttr &AL) {
5540-
auto *E = AL.getArgAsExpr(0);
5541-
auto Loc = E ? E->getBeginLoc() : AL.getLoc();
5542-
5543-
auto *DRE = dyn_cast<DeclRefExpr>(AL.getArgAsExpr(0));
5544-
if (!DRE) {
5545-
S.Diag(Loc, diag::err_nserrordomain_invalid_decl) << 0;
5539+
static void handleNSErrorDomain(Sema &S, Decl *D, const ParsedAttr &Attr) {
5540+
if (!isa<TagDecl>(D)) {
5541+
S.Diag(D->getBeginLoc(), diag::err_nserrordomain_invalid_decl)
5542+
<< 0;
55465543
return;
55475544
}
5545+
IdentifierLoc *identLoc =
5546+
Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr;
5547+
if (!identLoc || !identLoc->Ident) {
5548+
// Try to locate the argument directly
5549+
SourceLocation loc = Attr.getLoc();
5550+
if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0))
5551+
loc = Attr.getArgAsExpr(0)->getBeginLoc();
55485552

5549-
auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
5550-
if (!VD) {
5551-
S.Diag(Loc, diag::err_nserrordomain_invalid_decl) << 1 << DRE->getDecl();
5553+
S.Diag(loc, diag::err_nserrordomain_invalid_decl) << 0;
55525554
return;
55535555
}
55545556

5555-
if (!isNSStringType(VD->getType(), S.Context) &&
5556-
!isCFStringType(VD->getType(), S.Context)) {
5557-
S.Diag(Loc, diag::err_nserrordomain_wrong_type) << VD;
5557+
// Verify that the identifier is a valid decl in the C decl namespace
5558+
LookupResult lookupResult(S, DeclarationName(identLoc->Ident),
5559+
SourceLocation(),
5560+
Sema::LookupNameKind::LookupOrdinaryName);
5561+
if (!S.LookupName(lookupResult, S.TUScope) ||
5562+
!lookupResult.getAsSingle<VarDecl>()) {
5563+
S.Diag(identLoc->Loc, diag::err_nserrordomain_invalid_decl)
5564+
<< 1 << identLoc->Ident;
55585565
return;
55595566
}
55605567

5561-
D->addAttr(::new (S.Context) NSErrorDomainAttr(S.Context, AL, VD));
5568+
D->addAttr(::new (S.Context)
5569+
NSErrorDomainAttr(S.Context, Attr, identLoc->Ident));
55625570
}
55635571

55645572
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)