@@ -1478,6 +1478,213 @@ def SYCLIntelLoopFuse : InheritableAttr {
1478
1478
let SupportsNonconformingLambdaSyntax = 1;
1479
1479
}
1480
1480
1481
+ class SYCLAddIRAttrMemberCodeHolder<code Code> {
1482
+ code MemberCode = Code;
1483
+ }
1484
+
1485
+ // Common class for SYCL add_ir_attributes_* attributes.
1486
+ def SYCLAddIRAttrCommonMembers : SYCLAddIRAttrMemberCodeHolder<[{
1487
+ static Optional<std::string>
1488
+ getValidAttributeNameAsString(const Expr *NameE, const ASTContext &Context) {
1489
+ if (const auto *NameLiteral = dyn_cast<StringLiteral>(NameE))
1490
+ return NameLiteral->getString().str();
1491
+
1492
+ const auto *NameCE = dyn_cast<ConstantExpr>(NameE);
1493
+ if (!NameCE)
1494
+ return None;
1495
+
1496
+ APValue NameLValue;
1497
+ if (!NameCE->isCXX11ConstantExpr(Context, &NameLValue))
1498
+ NameLValue = NameCE->getAPValueResult();
1499
+
1500
+ if (!NameLValue.isLValue())
1501
+ return None;
1502
+
1503
+ if (const auto *NameValExpr =
1504
+ NameLValue.getLValueBase().dyn_cast<const Expr *>())
1505
+ return getValidAttributeNameAsString(NameValExpr, Context);
1506
+
1507
+ if (const auto *NameValDecl =
1508
+ NameLValue.getLValueBase().dyn_cast<const ValueDecl *>()) {
1509
+ if (const auto *NameVarDecl = dyn_cast<const VarDecl>(NameValDecl)) {
1510
+ return getValidAttributeNameAsString(NameVarDecl->getInit(), Context);
1511
+ }
1512
+ }
1513
+ return None;
1514
+ }
1515
+
1516
+ static Optional<std::string>
1517
+ getValidAttributeValueAsString(const APValue &Value,
1518
+ const ASTContext &Context,
1519
+ QualType ValueQType) {
1520
+ assert(!Value.isLValue());
1521
+ if (ValueQType->isCharType()) {
1522
+ char C = static_cast<char>(Value.getInt().getExtValue());
1523
+ return std::string(&C, 1);
1524
+ }
1525
+ if (ValueQType->isBooleanType())
1526
+ return std::string(Value.getInt().getExtValue() ? "true" : "false");
1527
+ if (ValueQType->isIntegralOrEnumerationType() ||
1528
+ ValueQType->isFloatingType())
1529
+ return Value.getAsString(Context, ValueQType);
1530
+ return None;
1531
+ }
1532
+
1533
+ static Optional<std::string>
1534
+ getValidAttributeValueAsString(const Expr *ValueE,
1535
+ const ASTContext &Context) {
1536
+ if (ValueE->getType()->isNullPtrType())
1537
+ return std::string("");
1538
+ if (const auto *StringVal = dyn_cast<StringLiteral>(ValueE))
1539
+ return StringVal->getString().str();
1540
+ if (const auto *BoolVal = dyn_cast<CXXBoolLiteralExpr>(ValueE))
1541
+ return std::string(BoolVal->getValue() ? "true" : "false");
1542
+ if (const auto *FloatingVal = dyn_cast<FloatingLiteral>(ValueE))
1543
+ return APValue(FloatingVal->getValue())
1544
+ .getAsString(Context, ValueE->getType());
1545
+ if (const auto *CharacterVal = dyn_cast<CharacterLiteral>(ValueE)) {
1546
+ char C = static_cast<char>(CharacterVal->getValue());
1547
+ return std::string(&C, 1);
1548
+ }
1549
+ if (const auto *IntegerVal = dyn_cast<IntegerLiteral>(ValueE)) {
1550
+ SmallString<10> IntegerStrBuffer;
1551
+ IntegerVal->getValue().toString(IntegerStrBuffer, 10,
1552
+ ValueE->getType()->isSignedIntegerType());
1553
+ return std::string(IntegerStrBuffer);
1554
+ }
1555
+
1556
+ const auto *ValueCE = dyn_cast<ConstantExpr>(ValueE);
1557
+ if (!ValueCE)
1558
+ return None;
1559
+
1560
+ APValue ValueAPV;
1561
+ if (!ValueCE->isCXX11ConstantExpr(Context, &ValueAPV))
1562
+ ValueAPV = ValueCE->getAPValueResult();
1563
+
1564
+ if (!ValueAPV.isLValue())
1565
+ return getValidAttributeValueAsString(ValueAPV, Context,
1566
+ ValueCE->getType());
1567
+
1568
+ if (ValueAPV.getLValueBase().isNull())
1569
+ return std::string("");
1570
+
1571
+ if (const auto *ValueValExpr =
1572
+ ValueAPV.getLValueBase().dyn_cast<const Expr *>())
1573
+ return getValidAttributeValueAsString(ValueValExpr, Context);
1574
+
1575
+ if (const auto *ValueValDecl =
1576
+ ValueAPV.getLValueBase().dyn_cast<const ValueDecl *>()) {
1577
+ if (const auto *ValueVarDecl = dyn_cast<const VarDecl>(ValueValDecl)) {
1578
+ return getValidAttributeValueAsString(ValueVarDecl->getInit(), Context);
1579
+ }
1580
+ }
1581
+ return None;
1582
+ }
1583
+
1584
+ static Optional<llvm::SmallSet<StringRef, 4>> getAttributeFilterFromExprs(
1585
+ Expr **AttributeExprs, size_t AttributeExprsSize) {
1586
+ if (!AttributeExprsSize)
1587
+ return None;
1588
+
1589
+ const auto *FilterListE = dyn_cast<InitListExpr>(AttributeExprs[0]);
1590
+ if (!FilterListE)
1591
+ return None;
1592
+
1593
+ llvm::SmallSet<StringRef, 4> Filter;
1594
+ for (const Expr *FilterE : FilterListE->inits()) {
1595
+ const auto *FilterStrLit = dyn_cast<StringLiteral>(FilterE);
1596
+ assert(FilterStrLit && "Element in filter list is not a string literal.");
1597
+ Filter.insert(FilterStrLit->getString());
1598
+ }
1599
+ return Filter;
1600
+ }
1601
+
1602
+ Optional<llvm::SmallSet<StringRef, 4>> getAttributeFilter() const {
1603
+ return getAttributeFilterFromExprs(args_begin(), args_size());
1604
+ }
1605
+
1606
+ bool hasFilterList() const {
1607
+ return args_size() && isa<InitListExpr>(*args_begin());
1608
+ }
1609
+
1610
+ SmallVector<std::pair<std::string, std::string>, 4>
1611
+ getFilteredAttributeNameValuePairs(
1612
+ const Optional<llvm::SmallSet<StringRef, 4>> &AttributeNameFilter,
1613
+ const ASTContext &Context) const {
1614
+ Expr **AttributeExprs = args_begin() + hasFilterList();
1615
+ size_t AttributeExprsSize = args_size() - hasFilterList();
1616
+
1617
+ assert((AttributeExprsSize & 1) == 0 && "Too few remaining expressions.");
1618
+
1619
+ SmallVector<std::pair<std::string, std::string>, 4> Attrs;
1620
+ for (size_t I = 0; I < AttributeExprsSize / 2; ++I) {
1621
+ Optional<std::string> NameStr =
1622
+ getValidAttributeNameAsString(AttributeExprs[I], Context);
1623
+ assert(NameStr && "Attribute name is not a valid string.");
1624
+
1625
+ // If attribute name is empty, then skip attribute.
1626
+ if (NameStr->empty())
1627
+ continue;
1628
+
1629
+ // If attribute name is not in the filter, we skip it.
1630
+ if (AttributeNameFilter && !AttributeNameFilter->contains(*NameStr))
1631
+ continue;
1632
+
1633
+ Optional<std::string> ValueStr = getValidAttributeValueAsString(
1634
+ AttributeExprs[I + AttributeExprsSize / 2], Context);
1635
+ assert(ValueStr && "Attribute value is not a valid type.");
1636
+
1637
+ Attrs.push_back(std::make_pair(*NameStr, *ValueStr));
1638
+ }
1639
+
1640
+ return Attrs;
1641
+ }
1642
+
1643
+ SmallVector<std::pair<std::string, std::string>, 4>
1644
+ getFilteredAttributeNameValuePairs(const ASTContext &Context) const {
1645
+ Optional<llvm::SmallSet<StringRef, 4>> AttributeNameFilter =
1646
+ getAttributeFilter();
1647
+ return getFilteredAttributeNameValuePairs(AttributeNameFilter, Context);
1648
+ }
1649
+
1650
+ SmallVector<std::pair<std::string, std::string>, 4>
1651
+ getAttributeNameValuePairs(const ASTContext &Context) const {
1652
+ return getFilteredAttributeNameValuePairs(None, Context);
1653
+ }
1654
+ }]>;
1655
+
1656
+ def SYCLAddIRAttributesFunction : InheritableAttr {
1657
+ let Spellings = [CXX11<"__sycl_detail__", "add_ir_attributes_function">];
1658
+ let Args = [VariadicExprArgument<"Args">];
1659
+ let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
1660
+ let Subjects = SubjectList<[Function], ErrorDiag>;
1661
+ let AcceptsExprPack = 1;
1662
+ let AdditionalMembers = SYCLAddIRAttrCommonMembers.MemberCode;
1663
+ let Documentation = [SYCLAddIRAttributesFunctionDocs];
1664
+ }
1665
+
1666
+ def SYCLAddIRAttributesKernelParameter : InheritableAttr {
1667
+ let Spellings = [CXX11<"__sycl_detail__",
1668
+ "add_ir_attributes_kernel_parameter">];
1669
+ let Args = [VariadicExprArgument<"Args">];
1670
+ let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
1671
+ let Subjects = SubjectList<[ParmVar], ErrorDiag>;
1672
+ let AcceptsExprPack = 1;
1673
+ let AdditionalMembers = SYCLAddIRAttrCommonMembers.MemberCode;
1674
+ let Documentation = [SYCLAddIRAttributesKernelParameterDocs];
1675
+ }
1676
+
1677
+ def SYCLAddIRAttributesGlobalVariable : InheritableAttr {
1678
+ let Spellings = [CXX11<"__sycl_detail__",
1679
+ "add_ir_attributes_global_variable">];
1680
+ let Args = [VariadicExprArgument<"Args">];
1681
+ let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
1682
+ let Subjects = SubjectList<[Record], ErrorDiag>;
1683
+ let AcceptsExprPack = 1;
1684
+ let AdditionalMembers = SYCLAddIRAttrCommonMembers.MemberCode;
1685
+ let Documentation = [SYCLAddIRAttributesGlobalVariableDocs];
1686
+ }
1687
+
1481
1688
def C11NoReturn : InheritableAttr {
1482
1689
let Spellings = [Keyword<"_Noreturn">];
1483
1690
let Subjects = SubjectList<[Function], ErrorDiag>;
0 commit comments