@@ -171,12 +171,13 @@ static StringRef NormalizeGNUAttrSpelling(StringRef AttrSpelling) {
171
171
typedef std::vector<std::pair<std::string, const Record *>> ParsedAttrMap;
172
172
173
173
static ParsedAttrMap getParsedAttrList (const RecordKeeper &Records,
174
- ParsedAttrMap *Dupes = nullptr ) {
174
+ ParsedAttrMap *Dupes = nullptr ,
175
+ bool SemaOnly = true ) {
175
176
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions (" Attr" );
176
177
std::set<std::string> Seen;
177
178
ParsedAttrMap R;
178
179
for (const auto *Attr : Attrs) {
179
- if (Attr->getValueAsBit (" SemaHandler" )) {
180
+ if (!SemaOnly || Attr->getValueAsBit (" SemaHandler" )) {
180
181
std::string AN;
181
182
if (Attr->isSubClassOf (" TargetSpecificAttr" ) &&
182
183
!Attr->isValueUnset (" ParseKind" )) {
@@ -2335,19 +2336,21 @@ static bool isVariadicExprArgument(const Record *Arg) {
2335
2336
}
2336
2337
2337
2338
static bool isStringLiteralArgument (const Record *Arg) {
2338
- return !Arg->getSuperClasses ().empty () &&
2339
- llvm::StringSwitch<bool >(
2340
- Arg->getSuperClasses ().back ().first ->getName ())
2341
- .Case (" StringArgument" , true )
2342
- .Default (false );
2339
+ if (Arg->getSuperClasses ().empty ())
2340
+ return false ;
2341
+ StringRef ArgKind = Arg->getSuperClasses ().back ().first ->getName ();
2342
+ if (ArgKind == " EnumArgument" )
2343
+ return Arg->getValueAsBit (" IsString" );
2344
+ return ArgKind == " StringArgument" ;
2343
2345
}
2344
2346
2345
2347
static bool isVariadicStringLiteralArgument (const Record *Arg) {
2346
- return !Arg->getSuperClasses ().empty () &&
2347
- llvm::StringSwitch<bool >(
2348
- Arg->getSuperClasses ().back ().first ->getName ())
2349
- .Case (" VariadicStringArgument" , true )
2350
- .Default (false );
2348
+ if (Arg->getSuperClasses ().empty ())
2349
+ return false ;
2350
+ StringRef ArgKind = Arg->getSuperClasses ().back ().first ->getName ();
2351
+ if (ArgKind == " VariadicEnumArgument" )
2352
+ return Arg->getValueAsBit (" IsString" );
2353
+ return ArgKind == " VariadicStringArgument" ;
2351
2354
}
2352
2355
2353
2356
static void emitClangAttrVariadicIdentifierArgList (RecordKeeper &Records,
@@ -2370,14 +2373,18 @@ static void emitClangAttrVariadicIdentifierArgList(RecordKeeper &Records,
2370
2373
OS << " #endif // CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST\n\n " ;
2371
2374
}
2372
2375
2376
+ static bool GenerateTargetSpecificAttrChecks (const Record *R,
2377
+ std::vector<StringRef> &Arches,
2378
+ std::string &Test,
2379
+ std::string *FnName);
2380
+
2373
2381
// Emits the list of arguments that should be parsed as unevaluated string
2374
2382
// literals for each attribute.
2375
2383
static void emitClangAttrUnevaluatedStringLiteralList (RecordKeeper &Records,
2376
2384
raw_ostream &OS) {
2377
2385
OS << " #if defined(CLANG_ATTR_STRING_LITERAL_ARG_LIST)\n " ;
2378
- std::vector<Record *> Attrs = Records.getAllDerivedDefinitions (" Attr" );
2379
- for (const auto *Attr : Attrs) {
2380
- std::vector<Record *> Args = Attr->getValueAsListOfDefs (" Args" );
2386
+
2387
+ auto MakeMask = [](ArrayRef<Record *> Args) {
2381
2388
uint32_t Bits = 0 ;
2382
2389
assert (Args.size () <= 32 && " unsupported number of arguments in attribute" );
2383
2390
for (uint32_t N = 0 ; N < Args.size (); ++N) {
@@ -2388,11 +2395,46 @@ static void emitClangAttrUnevaluatedStringLiteralList(RecordKeeper &Records,
2388
2395
break ;
2389
2396
}
2390
2397
}
2391
- if (!Bits)
2398
+ return Bits;
2399
+ };
2400
+
2401
+ auto AddMaskWithTargetCheck = [](const Record *Attr, uint32_t Mask,
2402
+ std::string &MaskStr) {
2403
+ const Record *T = Attr->getValueAsDef (" Target" );
2404
+ std::vector<StringRef> Arches = T->getValueAsListOfStrings (" Arches" );
2405
+ std::string Test;
2406
+ GenerateTargetSpecificAttrChecks (T, Arches, Test, nullptr );
2407
+ MaskStr.append (Test + " ? " + std::to_string (Mask) + " : " );
2408
+ };
2409
+
2410
+ ParsedAttrMap Dupes;
2411
+ ParsedAttrMap Attrs = getParsedAttrList (Records, &Dupes, /* SemaOnly=*/ false );
2412
+ for (const auto &[AttrName, Attr] : Attrs) {
2413
+ std::string MaskStr;
2414
+ if (Attr->isSubClassOf (" TargetSpecificAttr" ) &&
2415
+ !Attr->isValueUnset (" ParseKind" )) {
2416
+ if (uint32_t Mask = MakeMask (Attr->getValueAsListOfDefs (" Args" )))
2417
+ AddMaskWithTargetCheck (Attr, Mask, MaskStr);
2418
+ StringRef ParseKind = Attr->getValueAsString (" ParseKind" );
2419
+ for (const auto &[DupeParseKind, DupAttr] : Dupes) {
2420
+ if (DupeParseKind != ParseKind)
2421
+ continue ;
2422
+ if (uint32_t Mask = MakeMask (DupAttr->getValueAsListOfDefs (" Args" )))
2423
+ AddMaskWithTargetCheck (DupAttr, Mask, MaskStr);
2424
+ }
2425
+ if (!MaskStr.empty ())
2426
+ MaskStr.append (" 0" );
2427
+ } else {
2428
+ if (uint32_t Mask = MakeMask (Attr->getValueAsListOfDefs (" Args" )))
2429
+ MaskStr = std::to_string (Mask);
2430
+ }
2431
+
2432
+ if (MaskStr.empty ())
2392
2433
continue ;
2434
+
2393
2435
// All these spellings have at least one string literal has argument.
2394
2436
forEachUniqueSpelling (*Attr, [&](const FlattenedSpelling &S) {
2395
- OS << " .Case(\" " << S.name () << " \" , " << Bits << " )\n " ;
2437
+ OS << " .Case(\" " << S.name () << " \" , " << MaskStr << " )\n " ;
2396
2438
});
2397
2439
}
2398
2440
OS << " #endif // CLANG_ATTR_STRING_LITERAL_ARG_LIST\n\n " ;
@@ -3381,6 +3423,8 @@ void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
3381
3423
OS << " }\n " ;
3382
3424
}
3383
3425
3426
+ } // namespace clang
3427
+
3384
3428
// Helper function for GenerateTargetSpecificAttrChecks that alters the 'Test'
3385
3429
// parameter with only a single check type, if applicable.
3386
3430
static bool GenerateTargetSpecificAttrCheck (const Record *R, std::string &Test,
@@ -3547,6 +3591,8 @@ static void GenerateHasAttrSpellingStringSwitch(
3547
3591
OS << " .Default(0);\n " ;
3548
3592
}
3549
3593
3594
+ namespace clang {
3595
+
3550
3596
// Emits the list of tokens for regular keyword attributes.
3551
3597
void EmitClangAttrTokenKinds (RecordKeeper &Records, raw_ostream &OS) {
3552
3598
emitSourceFileHeader (" A list of tokens generated from the attribute"
0 commit comments