@@ -1593,19 +1593,54 @@ bool SemaARM::areLaxCompatibleSveTypes(QualType FirstType,
15931593 IsLaxCompatible (SecondType, FirstType);
15941594}
15951595
1596+ static void appendFeature (StringRef Feat, SmallString<64 > &Buffer) {
1597+ if (!Buffer.empty ())
1598+ Buffer.append (" +" );
1599+ Buffer.append (Feat);
1600+ }
1601+
1602+ static void convertPriorityString (unsigned Priority,
1603+ SmallString<64 > &NewParam) {
1604+ StringRef PriorityString[8 ] = {" P0" , " P1" , " P2" , " P3" ,
1605+ " P4" , " P5" , " P6" , " P7" };
1606+
1607+ assert (Priority > 0 && Priority < 256 && " priority out of range" );
1608+ // Convert priority=[1-255] -> P0 + ... + P7
1609+ for (unsigned BitPos = 0 ; BitPos < 8 ; ++BitPos)
1610+ if (Priority & (1U << BitPos))
1611+ appendFeature (PriorityString[BitPos], NewParam);
1612+ }
1613+
15961614bool SemaARM::checkTargetVersionAttr (const StringRef Param,
1597- const SourceLocation Loc) {
1615+ const SourceLocation Loc,
1616+ SmallString<64 > &NewParam) {
15981617 using namespace DiagAttrParams ;
15991618
1619+ auto [LHS, RHS] = Param.split (' ;' );
1620+ RHS = RHS.trim ();
1621+ bool IsDefault = false ;
16001622 llvm::SmallVector<StringRef, 8 > Features;
1601- Param .split (Features, ' +' );
1623+ LHS .split (Features, ' +' );
16021624 for (StringRef Feat : Features) {
16031625 Feat = Feat.trim ();
16041626 if (Feat == " default" )
1605- continue ;
1606- if (!getASTContext ().getTargetInfo ().validateCpuSupports (Feat))
1627+ IsDefault = true ;
1628+ else if (!getASTContext ().getTargetInfo ().validateCpuSupports (Feat))
16071629 return Diag (Loc, diag::warn_unsupported_target_attribute)
16081630 << Unsupported << None << Feat << TargetVersion;
1631+ appendFeature (Feat, NewParam);
1632+ }
1633+
1634+ if (!RHS.empty () && RHS.consume_front (" priority=" )) {
1635+ if (IsDefault)
1636+ Diag (Loc, diag::warn_invalid_default_version_priority);
1637+ else {
1638+ unsigned Digit;
1639+ if (RHS.getAsInteger (0 , Digit) || Digit < 1 || Digit > 255 )
1640+ Diag (Loc, diag::warn_version_priority_out_of_range) << RHS;
1641+ else
1642+ convertPriorityString (Digit, NewParam);
1643+ }
16091644 }
16101645 return false ;
16111646}
@@ -1627,15 +1662,21 @@ bool SemaARM::checkTargetClonesAttr(
16271662 const StringRef Param = Params[I].trim ();
16281663 const SourceLocation &Loc = Locs[I];
16291664
1630- if (Param.empty ())
1665+ auto [LHS, RHS] = Param.split (' ;' );
1666+ RHS = RHS.trim ();
1667+ bool HasPriority = !RHS.empty () && RHS.consume_front (" priority=" );
1668+
1669+ if (LHS.empty ())
16311670 return Diag (Loc, diag::warn_unsupported_target_attribute)
16321671 << Unsupported << None << " " << TargetClones;
16331672
1634- if (Param == " default" ) {
1673+ if (LHS == " default" ) {
16351674 if (HasDefault)
16361675 Diag (Loc, diag::warn_target_clone_duplicate_options);
16371676 else {
1638- NewParams.push_back (Param);
1677+ if (HasPriority)
1678+ Diag (Loc, diag::warn_invalid_default_version_priority);
1679+ NewParams.push_back (LHS);
16391680 HasDefault = true ;
16401681 }
16411682 continue ;
@@ -1644,7 +1685,7 @@ bool SemaARM::checkTargetClonesAttr(
16441685 bool HasCodeGenImpact = false ;
16451686 llvm::SmallVector<StringRef, 8 > Features;
16461687 llvm::SmallVector<StringRef, 8 > ValidFeatures;
1647- Param .split (Features, ' +' );
1688+ LHS .split (Features, ' +' );
16481689 for (StringRef Feat : Features) {
16491690 Feat = Feat.trim ();
16501691 if (!getASTContext ().getTargetInfo ().validateCpuSupports (Feat)) {
@@ -1674,6 +1715,14 @@ bool SemaARM::checkTargetClonesAttr(
16741715 continue ;
16751716 }
16761717
1718+ if (HasPriority) {
1719+ unsigned Digit;
1720+ if (RHS.getAsInteger (0 , Digit) || Digit < 1 || Digit > 255 )
1721+ Diag (Loc, diag::warn_version_priority_out_of_range) << RHS;
1722+ else
1723+ convertPriorityString (Digit, NewParam);
1724+ }
1725+
16771726 // Valid non-default argument.
16781727 NewParams.push_back (NewParam);
16791728 HasNonDefault = true ;
0 commit comments