compnerd updated this revision to Diff 293574.
compnerd marked 6 inline comments as done.
compnerd added a comment.
Update for feedback from @aaron.ballman
The `ParseAttrCommonArgs` refactoring still needs to be looked at, but this
should address the feedback, and doesn't need to be predicated on the
refactoring.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D87652/new/
https://reviews.llvm.org/D87652
Files:
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Parse/Parser.h
clang/lib/Parse/ParseDecl.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/AST/attr-swift_newtype.m
clang/test/Misc/pragma-attribute-supported-attributes-list.test
clang/test/SemaObjC/attr-swift_newtype.m
Index: clang/test/SemaObjC/attr-swift_newtype.m
===================================================================
--- /dev/null
+++ clang/test/SemaObjC/attr-swift_newtype.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef int Bad1 __attribute__((swift_newtype(invalid)));
+// expected-warning@-1 {{'swift_newtype' attribute argument not supported: 'invalid'}}
+typedef int Bad2 __attribute__((swift_newtype()));
+// expected-error@-1 {{argument required after attribute}}
+typedef int Bad3 __attribute__((swift_newtype(invalid, ignored)));
+// expected-error@-1 {{expected ')'}}
+// expected-note@-2 {{to match this '('}}
+// expected-warning@-3 {{'swift_newtype' attribute argument not supported: 'invalid'}}
+
+struct __attribute__((__swift_newtype__(struct))) Bad4 { };
+// expected-error@-1 {{'__swift_newtype__' attribute only applies to typedefs}}
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===================================================================
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -151,6 +151,7 @@
// CHECK-NEXT: SwiftError (SubjectMatchRule_function, SubjectMatchRule_objc_method)
// CHECK-NEXT: SwiftErrorResult (SubjectMatchRule_variable_is_parameter)
// CHECK-NEXT: SwiftIndirectResult (SubjectMatchRule_variable_is_parameter)
+// CHECK-NEXT: SwiftNewType (SubjectMatchRule_type_alias)
// CHECK-NEXT: SwiftObjCMembers (SubjectMatchRule_objc_interface)
// CHECK-NEXT: TLSModel (SubjectMatchRule_variable_is_thread_local)
// CHECK-NEXT: Target (SubjectMatchRule_function)
Index: clang/test/AST/attr-swift_newtype.m
===================================================================
--- /dev/null
+++ clang/test/AST/attr-swift_newtype.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -ast-dump %s | FileCheck %s
+
+typedef int T1 __attribute__((__swift_newtype__(struct)));
+typedef int T2 __attribute__((__swift_newtype__(enum)));
+
+typedef int T3 __attribute__((__swift_wrapper__(struct)));
+typedef int T4 __attribute__((__swift_wrapper__(enum)));
+
+typedef int T5;
+typedef int T5 __attribute__((__swift_wrapper__(struct)));
+typedef int T5;
+// CHECK-LABEL: TypedefDecl {{.+}} T5 'int'
+// CHECK-NEXT: BuiltinType {{.+}} 'int'
+// CHECK-NEXT: TypedefDecl {{.+}} T5 'int'
+// CHECK-NEXT: BuiltinType {{.+}} 'int'
+// CHECK-NEXT: SwiftNewTypeAttr {{.+}} NK_Struct
+// CHECK-NEXT: TypedefDecl {{.+}} T5 'int'
+// CHECK-NEXT: BuiltinType {{.+}} 'int'
+// CHECK-NEXT: SwiftNewTypeAttr {{.+}} NK_Struct
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -5942,6 +5942,33 @@
D->addAttr(::new (S.Context) SwiftNameAttr(S.Context, AL, Name));
}
+static void handleSwiftNewType(Sema &S, Decl *D, const ParsedAttr &AL) {
+ // Make sure that there is an identifier as the annotation's single argument.
+ if (!checkAttributeNumArgs(S, AL, 1))
+ return;
+
+ if (!AL.isArgIdent(0)) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_type) << AL
+ << AANT_ArgumentIdentifier;
+ return;
+ }
+
+ SwiftNewTypeAttr::NewtypeKind Kind;
+ IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
+ if (!SwiftNewTypeAttr::ConvertStrToNewtypeKind(II->getName(), Kind)) {
+ S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
+ return;
+ }
+
+ if (!isa<TypedefNameDecl>(D)) {
+ S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
+ << AL << /* typedefs */13;
+ return;
+ }
+
+ D->addAttr(::new (S.Context) SwiftNewTypeAttr(S.Context, AL, Kind));
+}
+
//===----------------------------------------------------------------------===//
// Microsoft specific attribute handlers.
//===----------------------------------------------------------------------===//
@@ -7867,6 +7894,9 @@
case ParsedAttr::AT_SwiftName:
handleSwiftName(S, D, AL);
break;
+ case ParsedAttr::AT_SwiftNewType:
+ handleSwiftNewType(S, D, AL);
+ break;
case ParsedAttr::AT_SwiftObjCMembers:
handleSimpleAttribute<SwiftObjCMembersAttr>(S, D, AL);
break;
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -23,6 +23,7 @@
#include "clang/Sema/Lookup.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
+#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
@@ -452,6 +453,10 @@
ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax);
return;
+ } else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
+ ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
+ ScopeLoc, Syntax);
+ return;
} else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax);
@@ -506,6 +511,10 @@
ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax);
break;
+ case ParsedAttr::AT_SwiftNewType:
+ ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
+ ScopeLoc, Syntax);
+ break;
case ParsedAttr::AT_TypeTagForDatatype:
ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
ScopeName, ScopeLoc, Syntax);
@@ -1409,6 +1418,52 @@
Syntax);
}
+
+void Parser::ParseSwiftNewTypeAttribute(IdentifierInfo &AttrName,
+ SourceLocation AttrNameLoc,
+ ParsedAttributes &Attrs,
+ SourceLocation *EndLoc,
+ IdentifierInfo *ScopeName,
+ SourceLocation ScopeLoc,
+ ParsedAttr::Syntax Syntax) {
+ BalancedDelimiterTracker T(*this, tok::l_paren);
+
+ // Opening '('
+ if (T.consumeOpen()) {
+ Diag(Tok, diag::err_expected) << tok::l_paren;
+ return;
+ }
+
+ if (Tok.is(tok::r_paren)) {
+ Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
+ T.consumeClose();
+ return;
+ }
+ if (Tok.isNot(tok::kw_struct) && Tok.isNot(tok::kw_enum)) {
+ Diag(Tok, diag::warn_attribute_type_not_supported) << &AttrName
+ << Tok.getIdentifierInfo();
+ if (!isTokenSpecial())
+ ConsumeToken();
+ T.consumeClose();
+ return;
+ }
+
+ auto *SwiftType = IdentifierLoc::create(Actions.Context, Tok.getLocation(),
+ Tok.getIdentifierInfo());
+ ConsumeToken();
+
+ // Closing ')'
+ if (T.consumeClose())
+ return;
+ if (EndLoc)
+ *EndLoc = T.getCloseLocation();
+
+ ArgsUnion Args[] = {SwiftType};
+ Attrs.addNew(&AttrName, SourceRange(AttrNameLoc, T.getCloseLocation()),
+ ScopeName, ScopeLoc, Args, llvm::array_lengthof(Args), Syntax);
+}
+
+
void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
SourceLocation AttrNameLoc,
ParsedAttributes &Attrs,
Index: clang/include/clang/Parse/Parser.h
===================================================================
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -2804,6 +2804,14 @@
SourceLocation ScopeLoc,
ParsedAttr::Syntax Syntax);
+ void ParseSwiftNewTypeAttribute(IdentifierInfo &AttrName,
+ SourceLocation AttrNameLoc,
+ ParsedAttributes &Attrs,
+ SourceLocation *EndLoc,
+ IdentifierInfo *ScopeName,
+ SourceLocation ScopeLoc,
+ ParsedAttr::Syntax Syntax);
+
void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
SourceLocation AttrNameLoc,
ParsedAttributes &Attrs,
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3271,7 +3271,8 @@
"|types and namespaces"
"|variables, functions and classes"
"|kernel functions"
- "|non-K&R-style functions}1">,
+ "|non-K&R-style functions"
+ "|typedefs}1">,
InGroup<IgnoredAttributes>;
def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
def warn_type_attribute_wrong_type : Warning<
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -3596,6 +3596,32 @@
}];
}
+def SwiftNewTypeDocs : Documentation {
+ let Category = SwiftDocs;
+ let Heading = "swift_newtype";
+ let Content = [{
+The ``swift_newtype`` attribute indicates that the typedef to which the
+attribute appertains is imported as a new Swift type of the typedef's name.
+
+* ``swift_newtype(struct)`` means that a Swift struct will be created for this
+typedef.
+
+* ``swift_newtype(enum)`` means that a Swift enum will be created for this
+ypedef.
+
+ .. code-block:: c
+
+ // Import UIFontTextStyle as an enum type, with enumerated values being
+ // constants.
+ typedef NSString * UIFontTextStyle __attribute__((__swift_newtype__(enum)));
+
+ // Import UIFontDescriptorFeatureKey as a structure type, with enumerated
+ // values being members of the type structure.
+ typedef NSString * UIFontDescriptorFeatureKey __attribute__((__swift_newtype__(struct)));
+
+ }];
+}
+
def OMPDeclareSimdDocs : Documentation {
let Category = DocCatFunction;
let Heading = "#pragma omp declare simd";
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -2168,6 +2168,17 @@
let Documentation = [SwiftNameDocs];
}
+def SwiftNewType : InheritableAttr {
+ // `swift_wrapper` is a "deprecated" alias and kept for compatibility with
+ // shipped toolchains. New users should prefer the `swift_newtype` spelling.
+ let Spellings = [GNU<"swift_newtype">, GNU<"swift_wrapper">];
+ let Args = [EnumArgument<"NewtypeKind", "NewtypeKind",
+ ["struct", "enum"], ["NK_Struct", "NK_Enum"]>];
+ let Subjects = SubjectList<[TypedefName], ErrorDiag>;
+ let Documentation = [SwiftNewTypeDocs];
+ let HasCustomParsing = 1;
+}
+
def NoDeref : TypeAttr {
let Spellings = [Clang<"noderef">];
let Documentation = [NoDerefDocs];
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits