Skip to content

Commit c53a5f9

Browse files
authored
[SYCL] Move the lambda attribute hack logic into tablegen; NFC (#3381)
We have a hack in place that lets an attribute written in the type position of a lambda to slide into the declaration position. Instead of specifying that in a header file, each attribute can opt into the behavior within Attr.td.
1 parent d7276bf commit c53a5f9

File tree

7 files changed

+35
-25
lines changed

7 files changed

+35
-25
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,14 @@ class Attr {
566566
// attribute may be documented under multiple categories, more than one
567567
// Documentation entry may be listed.
568568
list<Documentation> Documentation;
569+
// The SYCL specification allows attributes on lambdas as a nonconforming
570+
// extension to C++. The attributes are written in the type position but will
571+
// be applied to the generated function declaration rather than type. Setting
572+
// this bit to 1 opts an attribute into this nonconforming extension. New
573+
// attributes should not set this bit unless the attribute is required by the
574+
// SYCL specification. This bit only applies to the [[]] spelling of an
575+
// attribute and has no effect on any other spellings.
576+
bit SupportsNonconformingLambdaSyntax = 0;
569577
}
570578

571579
/// A type attribute is not processed on a declaration or a statement.
@@ -1186,6 +1194,7 @@ def SYCLSimd : InheritableAttr {
11861194
let Subjects = SubjectList<[Function]>;
11871195
let LangOpts = [SYCLExplicitSIMD];
11881196
let Documentation = [SYCLSimdDocs];
1197+
let SupportsNonconformingLambdaSyntax = 1;
11891198
}
11901199

11911200
// Available in SYCL explicit SIMD extension. Binds a file scope private
@@ -1258,11 +1267,12 @@ def SYCLRequiresDecomposition : InheritableAttr {
12581267
}
12591268

12601269
def SYCLIntelKernelArgsRestrict : InheritableAttr {
1261-
let Spellings = [ CXX11<"intel", "kernel_args_restrict"> ];
1270+
let Spellings = [CXX11<"intel", "kernel_args_restrict">];
12621271
let Subjects = SubjectList<[Function], ErrorDiag>;
1263-
let LangOpts = [ SYCLIsDevice, SYCLIsHost ];
1264-
let Documentation = [ SYCLIntelKernelArgsRestrictDocs ];
1272+
let LangOpts = [SYCLIsDevice, SYCLIsHost];
1273+
let Documentation = [SYCLIntelKernelArgsRestrictDocs];
12651274
let SimpleHandler = 1;
1275+
let SupportsNonconformingLambdaSyntax = 1;
12661276
}
12671277

12681278
def SYCLIntelNumSimdWorkItems : InheritableAttr {
@@ -1272,13 +1282,15 @@ def SYCLIntelNumSimdWorkItems : InheritableAttr {
12721282
let LangOpts = [SYCLIsDevice, SYCLIsHost];
12731283
let Subjects = SubjectList<[Function], ErrorDiag>;
12741284
let Documentation = [SYCLIntelNumSimdWorkItemsAttrDocs];
1285+
let SupportsNonconformingLambdaSyntax = 1;
12751286
}
12761287

12771288
def SYCLIntelUseStallEnableClusters : InheritableAttr {
12781289
let Spellings = [CXX11<"intel","use_stall_enable_clusters">];
12791290
let LangOpts = [SYCLIsHost, SYCLIsDevice];
12801291
let Subjects = SubjectList<[Function], ErrorDiag>;
12811292
let Documentation = [SYCLIntelUseStallEnableClustersAttrDocs];
1293+
let SupportsNonconformingLambdaSyntax = 1;
12821294
}
12831295

12841296
def SYCLIntelSchedulerTargetFmaxMhz : InheritableAttr {
@@ -1288,6 +1300,7 @@ def SYCLIntelSchedulerTargetFmaxMhz : InheritableAttr {
12881300
let LangOpts = [SYCLIsDevice, SYCLIsHost];
12891301
let Subjects = SubjectList<[Function], ErrorDiag>;
12901302
let Documentation = [SYCLIntelSchedulerTargetFmaxMhzAttrDocs];
1303+
let SupportsNonconformingLambdaSyntax = 1;
12911304
}
12921305

12931306
def SYCLIntelMaxWorkGroupSize : InheritableAttr {
@@ -1313,6 +1326,7 @@ def SYCLIntelMaxWorkGroupSize : InheritableAttr {
13131326
}
13141327
}];
13151328
let Documentation = [SYCLIntelMaxWorkGroupSizeAttrDocs];
1329+
let SupportsNonconformingLambdaSyntax = 1;
13161330
}
13171331

13181332
def SYCLIntelMaxGlobalWorkDim : InheritableAttr {
@@ -1322,6 +1336,7 @@ def SYCLIntelMaxGlobalWorkDim : InheritableAttr {
13221336
let LangOpts = [SYCLIsDevice, SYCLIsHost];
13231337
let Subjects = SubjectList<[Function], ErrorDiag>;
13241338
let Documentation = [SYCLIntelMaxGlobalWorkDimAttrDocs];
1339+
let SupportsNonconformingLambdaSyntax = 1;
13251340
}
13261341

13271342
def SYCLIntelNoGlobalWorkOffset : InheritableAttr {
@@ -1331,6 +1346,7 @@ def SYCLIntelNoGlobalWorkOffset : InheritableAttr {
13311346
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
13321347
let Subjects = SubjectList<[Function], ErrorDiag>;
13331348
let Documentation = [SYCLIntelNoGlobalWorkOffsetAttrDocs];
1349+
let SupportsNonconformingLambdaSyntax = 1;
13341350
}
13351351

13361352
def SYCLIntelLoopFuse : InheritableAttr {
@@ -1342,6 +1358,7 @@ def SYCLIntelLoopFuse : InheritableAttr {
13421358
let Accessors = [Accessor<"isIndependent",
13431359
[CXX11<"intel", "loop_fuse_independent">]>];
13441360
let Documentation = [SYCLIntelLoopFuseDocs];
1361+
let SupportsNonconformingLambdaSyntax = 1;
13451362
}
13461363

13471364
def C11NoReturn : InheritableAttr {
@@ -1404,6 +1421,7 @@ def IntelReqdSubGroupSize: InheritableAttr {
14041421
let Subjects = SubjectList<[Function], ErrorDiag>;
14051422
let Documentation = [IntelReqdSubGroupSizeDocs];
14061423
let LangOpts = [OpenCL, SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
1424+
let SupportsNonconformingLambdaSyntax = 1;
14071425
}
14081426

14091427
// This attribute is both a type attribute, and a declaration attribute (for
@@ -2808,6 +2826,7 @@ def ReqdWorkGroupSize : InheritableAttr {
28082826
}
28092827
}];
28102828
let Documentation = [ReqdWorkGroupSizeAttrDocs];
2829+
let SupportsNonconformingLambdaSyntax = 1;
28112830
}
28122831

28132832
def WorkGroupSizeHint : InheritableAttr {

clang/include/clang/Basic/AttributeCommonInfo.h

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -153,26 +153,6 @@ class AttributeCommonInfo {
153153
return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
154154
}
155155

156-
bool isAllowedOnLambdas() const {
157-
// FIXME: Eventually we want to do a list here populated via tablegen. But
158-
// we want C++ attributes to be permissible on Lambdas, and get propagated
159-
// to the call operator declaration.
160-
auto ParsedAttr = getParsedKind();
161-
if (ParsedAttr == AT_SYCLIntelKernelArgsRestrict ||
162-
(ParsedAttr == AT_ReqdWorkGroupSize && isCXX11Attribute()) ||
163-
(ParsedAttr == AT_IntelReqdSubGroupSize && isCXX11Attribute()) ||
164-
ParsedAttr == AT_SYCLIntelNumSimdWorkItems ||
165-
ParsedAttr == AT_SYCLIntelSchedulerTargetFmaxMhz ||
166-
ParsedAttr == AT_SYCLIntelMaxWorkGroupSize ||
167-
ParsedAttr == AT_SYCLIntelMaxGlobalWorkDim ||
168-
ParsedAttr == AT_SYCLIntelNoGlobalWorkOffset ||
169-
ParsedAttr == AT_SYCLIntelUseStallEnableClusters ||
170-
ParsedAttr == AT_SYCLIntelLoopFuse || ParsedAttr == AT_SYCLSimd)
171-
return true;
172-
173-
return false;
174-
}
175-
176156
bool isC2xAttribute() const { return SyntaxUsed == AS_C2x; }
177157

178158
bool isKeywordAttribute() const {

clang/include/clang/Sema/ParsedAttr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ struct ParsedAttrInfo {
6060
unsigned IsKnownToGCC : 1;
6161
/// True if this attribute is supported by #pragma clang attribute.
6262
unsigned IsSupportedByPragmaAttribute : 1;
63+
/// True if this attribute supports a nonconforming behavior when applied to
64+
/// a lambda in the type position.
65+
unsigned SupportsNonconformingLambdaSyntax : 1;
6366
/// The syntaxes supported by this attribute and how they're spelled.
6467
struct Spelling {
6568
AttributeCommonInfo::Syntax Syntax;
@@ -590,6 +593,7 @@ class ParsedAttr final
590593
bool existsInTarget(const TargetInfo &Target) const;
591594
bool isKnownToGCC() const;
592595
bool isSupportedByPragmaAttribute() const;
596+
bool supportsNonconformingLambdaSyntax() const;
593597

594598
/// If the parsed attribute has a semantic equivalent, and it would
595599
/// have a semantic Spelling enumeration (due to having semantically-distinct

clang/lib/Sema/ParsedAttr.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,10 @@ bool ParsedAttr::isSupportedByPragmaAttribute() const {
193193
return getInfo().IsSupportedByPragmaAttribute;
194194
}
195195

196+
bool ParsedAttr::supportsNonconformingLambdaSyntax() const {
197+
return getInfo().SupportsNonconformingLambdaSyntax && isCXX11Attribute();
198+
}
199+
196200
unsigned ParsedAttr::getSemanticSpelling() const {
197201
return getInfo().spellingIndexToSemanticSpelling(*this);
198202
}

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8859,7 +8859,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
88598859
// Ignore C++11 attributes on declarator chunks: they appertain to the type
88608860
// instead.
88618861
if (AL.isCXX11Attribute() && !IncludeCXX11Attributes &&
8862-
(!IsDeclLambdaCallOperator(D) || !AL.isAllowedOnLambdas()))
8862+
(!IsDeclLambdaCallOperator(D) || !AL.supportsNonconformingLambdaSyntax()))
88638863
return;
88648864

88658865
// Unknown attributes are automatically warned on. Target-specific attributes

clang/lib/Sema/SemaType.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8123,7 +8123,8 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
81238123
default:
81248124
// A C++11 attribute on a declarator chunk must appertain to a type.
81258125
if (attr.isCXX11Attribute() && TAL == TAL_DeclChunk &&
8126-
(!state.isProcessingLambdaExpr() || !attr.isAllowedOnLambdas())) {
8126+
(!state.isProcessingLambdaExpr() ||
8127+
!attr.supportsNonconformingLambdaSyntax())) {
81278128
state.getSema().Diag(attr.getLoc(), diag::err_attribute_not_type_attr)
81288129
<< attr;
81298130
attr.setUsedAsTypeAttr();

clang/utils/TableGen/ClangAttrEmitter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3796,6 +3796,8 @@ void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
37963796
OS << IsKnownToGCC(Attr) << ";\n";
37973797
OS << " IsSupportedByPragmaAttribute = ";
37983798
OS << PragmaAttributeSupport.isAttributedSupported(*I->second) << ";\n";
3799+
OS << " SupportsNonconformingLambdaSyntax = ";
3800+
OS << Attr.getValueAsBit("SupportsNonconformingLambdaSyntax") << ";\n";
37993801
if (!Spellings.empty())
38003802
OS << " Spellings = " << I->first << "Spellings;\n";
38013803
OS << " }\n";

0 commit comments

Comments
 (0)