Skip to content

Commit 447aabf

Browse files
committed
[APINotes] Upstream attributes that are created implicitly from APINotes
1 parent 74cb287 commit 447aabf

File tree

5 files changed

+93
-18
lines changed

5 files changed

+93
-18
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,9 @@ class VariadicEnumArgument<string name, string type, list<string> values,
306306
bit IsExternalType = isExternalType;
307307
}
308308

309+
// Represents an attribute wrapped by another attribute.
310+
class WrappedAttr<string name, bit opt = 0> : Argument<name, opt>;
311+
309312
// This handles one spelling of an attribute.
310313
class Spelling<string name, string variety, int version = 1> {
311314
string Name = name;
@@ -2291,7 +2294,7 @@ def ObjCBridgeRelated : InheritableAttr {
22912294
def NSErrorDomain : InheritableAttr {
22922295
let Spellings = [GNU<"ns_error_domain">];
22932296
let Subjects = SubjectList<[Enum], ErrorDiag>;
2294-
let Args = [DeclArgument<Var, "ErrorDomain">];
2297+
let Args = [IdentifierArgument<"ErrorDomain">];
22952298
let Documentation = [NSErrorDomainDocs];
22962299
}
22972300

@@ -2648,6 +2651,22 @@ def SwiftError : InheritableAttr {
26482651
let Documentation = [SwiftErrorDocs];
26492652
}
26502653

2654+
def SwiftImportAsNonGeneric : InheritableAttr {
2655+
// This attribute has no spellings as it is only ever created implicitly
2656+
// from API notes.
2657+
let Spellings = [];
2658+
let SemaHandler = 0;
2659+
let Documentation = [InternalOnly];
2660+
}
2661+
2662+
def SwiftImportPropertyAsAccessors : InheritableAttr {
2663+
// This attribute has no spellings as it is only ever created implicitly
2664+
// from API notes.
2665+
let Spellings = [];
2666+
let SemaHandler = 0;
2667+
let Documentation = [InternalOnly];
2668+
}
2669+
26512670
def SwiftName : InheritableAttr {
26522671
let Spellings = [GNU<"swift_name">];
26532672
let Args = [StringArgument<"Name">];
@@ -2669,6 +2688,31 @@ def SwiftPrivate : InheritableAttr {
26692688
let SimpleHandler = 1;
26702689
}
26712690

2691+
def SwiftVersionedAddition : Attr {
2692+
// This attribute has no spellings as it is only ever created implicitly
2693+
// from API notes.
2694+
let Spellings = [];
2695+
let Args = [VersionArgument<"Version">, WrappedAttr<"AdditionalAttr">,
2696+
BoolArgument<"IsReplacedByActive">];
2697+
let SemaHandler = 0;
2698+
let Documentation = [InternalOnly];
2699+
}
2700+
2701+
def SwiftVersionedRemoval : Attr {
2702+
// This attribute has no spellings as it is only ever created implicitly
2703+
// from API notes.
2704+
let Spellings = [];
2705+
let Args = [VersionArgument<"Version">, UnsignedArgument<"RawKind">,
2706+
BoolArgument<"IsReplacedByActive">];
2707+
let SemaHandler = 0;
2708+
let Documentation = [InternalOnly];
2709+
let AdditionalMembers = [{
2710+
attr::Kind getAttrKindToRemove() const {
2711+
return static_cast<attr::Kind>(getRawKind());
2712+
}
2713+
}];
2714+
}
2715+
26722716
def NoDeref : TypeAttr {
26732717
let Spellings = [Clang<"noderef">];
26742718
let Documentation = [NoDerefDocs];

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6236,29 +6236,35 @@ static void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
62366236
D->addAttr(::new (S.Context) ObjCRequiresSuperAttr(S.Context, Attrs));
62376237
}
62386238

6239-
static void handleNSErrorDomain(Sema &S, Decl *D, const ParsedAttr &AL) {
6240-
auto *E = AL.getArgAsExpr(0);
6241-
auto Loc = E ? E->getBeginLoc() : AL.getLoc();
6242-
6243-
auto *DRE = dyn_cast<DeclRefExpr>(AL.getArgAsExpr(0));
6244-
if (!DRE) {
6245-
S.Diag(Loc, diag::err_nserrordomain_invalid_decl) << 0;
6239+
static void handleNSErrorDomain(Sema &S, Decl *D, const ParsedAttr &Attr) {
6240+
if (!isa<TagDecl>(D)) {
6241+
S.Diag(D->getBeginLoc(), diag::err_nserrordomain_invalid_decl) << 0;
62466242
return;
62476243
}
62486244

6249-
auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
6250-
if (!VD) {
6251-
S.Diag(Loc, diag::err_nserrordomain_invalid_decl) << 1 << DRE->getDecl();
6245+
IdentifierLoc *IdentLoc =
6246+
Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr;
6247+
if (!IdentLoc || !IdentLoc->Ident) {
6248+
// Try to locate the argument directly.
6249+
SourceLocation Loc = Attr.getLoc();
6250+
if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0))
6251+
Loc = Attr.getArgAsExpr(0)->getBeginLoc();
6252+
6253+
S.Diag(Loc, diag::err_nserrordomain_invalid_decl) << 0;
62526254
return;
62536255
}
62546256

6255-
if (!isNSStringType(VD->getType(), S.Context) &&
6256-
!isCFStringType(VD->getType(), S.Context)) {
6257-
S.Diag(Loc, diag::err_nserrordomain_wrong_type) << VD;
6257+
// Verify that the identifier is a valid decl in the C decl namespace.
6258+
LookupResult Result(S, DeclarationName(IdentLoc->Ident), SourceLocation(),
6259+
Sema::LookupNameKind::LookupOrdinaryName);
6260+
if (!S.LookupName(Result, S.TUScope) || !Result.getAsSingle<VarDecl>()) {
6261+
S.Diag(IdentLoc->Loc, diag::err_nserrordomain_invalid_decl)
6262+
<< 1 << IdentLoc->Ident;
62586263
return;
62596264
}
62606265

6261-
D->addAttr(::new (S.Context) NSErrorDomainAttr(S.Context, AL, VD));
6266+
D->addAttr(::new (S.Context)
6267+
NSErrorDomainAttr(S.Context, Attr, IdentLoc->Ident));
62626268
}
62636269

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

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3095,6 +3095,8 @@ class AttrReader {
30953095

30963096
Expr *readExpr() { return Reader.readExpr(); }
30973097

3098+
Attr *readAttr() { return Reader.readAttr(); }
3099+
30983100
std::string readString() {
30993101
return Reader.readString();
31003102
}

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
};

clang/utils/TableGen/ClangAttrEmitter.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,29 @@ namespace {
14141414
}
14151415
};
14161416

1417-
} // end anonymous namespace
1417+
class WrappedAttr : public SimpleArgument {
1418+
public:
1419+
WrappedAttr(const Record &Arg, StringRef Attr)
1420+
: SimpleArgument(Arg, Attr, "Attr *") {}
1421+
1422+
void writePCHReadDecls(raw_ostream &OS) const override {
1423+
OS << " Attr *" << getLowerName() << " = Record.readAttr();";
1424+
}
1425+
1426+
void writePCHWrite(raw_ostream &OS) const override {
1427+
OS << " AddAttr(SA->get" << getUpperName() << "());";
1428+
}
1429+
1430+
void writeDump(raw_ostream &OS) const override {}
1431+
1432+
void writeDumpChildren(raw_ostream &OS) const override {
1433+
OS << " Visit(SA->get" << getUpperName() << "());\n";
1434+
}
1435+
1436+
void writeHasChildren(raw_ostream &OS) const override { OS << "true"; }
1437+
};
1438+
1439+
} // end anonymous namespace
14181440

14191441
static std::unique_ptr<Argument>
14201442
createArgument(const Record &Arg, StringRef Attr,
@@ -1470,6 +1492,8 @@ createArgument(const Record &Arg, StringRef Attr,
14701492
Ptr = std::make_unique<VariadicIdentifierArgument>(Arg, Attr);
14711493
else if (ArgName == "VersionArgument")
14721494
Ptr = std::make_unique<VersionArgument>(Arg, Attr);
1495+
else if (ArgName == "WrappedAttr")
1496+
Ptr = std::make_unique<WrappedAttr>(Arg, Attr);
14731497
else if (ArgName == "OMPTraitInfoArgument")
14741498
Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "OMPTraitInfo *");
14751499
else if (ArgName == "VariadicOMPInteropInfoArgument")

0 commit comments

Comments
 (0)