Skip to content

Commit 7a75dda

Browse files
committed
Add "#if hasAttribute(X)" support query attributes.
1 parent 15f7aa4 commit 7a75dda

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

include/swift/AST/Attr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2626,6 +2626,10 @@ inline SourceLoc extractNearestSourceLoc(const DeclAttribute *attr) {
26262626
return attr->getLocation();
26272627
}
26282628

2629+
/// Determine whether the given attribute is available, looking up the
2630+
/// attribute by name.
2631+
bool hasAttribute(const LangOptions &langOpts, llvm::StringRef attributeName);
2632+
26292633
} // end namespace swift
26302634

26312635
#endif

lib/AST/Attr.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2285,3 +2285,23 @@ void swift::simple_display(llvm::raw_ostream &out, const DeclAttribute *attr) {
22852285
if (attr)
22862286
attr->print(out);
22872287
}
2288+
2289+
bool swift::hasAttribute(
2290+
const LangOptions &langOpts, llvm::StringRef attributeName) {
2291+
DeclAttrKind kind = DeclAttribute::getAttrKindFromString(attributeName);
2292+
if (kind == DAK_Count)
2293+
return false;
2294+
2295+
if (DeclAttribute::isUserInaccessible(kind))
2296+
return false;
2297+
if (DeclAttribute::isDeclModifier(kind))
2298+
return false;
2299+
if (DeclAttribute::shouldBeRejectedByParser(kind))
2300+
return false;
2301+
if (DeclAttribute::isSilOnly(kind))
2302+
return false;
2303+
if (DeclAttribute::isConcurrencyOnly(kind))
2304+
return false;
2305+
2306+
return true;
2307+
}

lib/Parse/ParseIfConfig.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,16 @@ class ValidateIfConfigCondition :
346346
return E;
347347
}
348348

349+
if (*KindName == "hasAttribute") {
350+
if (!getDeclRefStr(Arg, DeclRefKind::Ordinary)) {
351+
D.diagnose(E->getLoc(), diag::unsupported_platform_condition_argument,
352+
"attribute name");
353+
return nullptr;
354+
}
355+
356+
return E;
357+
}
358+
349359
// ( 'os' | 'arch' | '_endian' | '_runtime' ) '(' identifier ')''
350360
auto Kind = getPlatformConditionKind(*KindName);
351361
if (!Kind.hasValue()) {
@@ -574,6 +584,9 @@ class EvaluateIfConfigCondition :
574584
} else if (KindName == "hasFeature") {
575585
auto featureName = getDeclRefStr(Arg);
576586
return Ctx.LangOpts.hasFeature(featureName);
587+
} else if (KindName == "hasAttribute") {
588+
auto attributeName = getDeclRefStr(Arg);
589+
return hasAttribute(Ctx.LangOpts, attributeName);
577590
}
578591

579592
auto Val = getDeclRefStr(Arg);

test/attr/has_attribute.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
#if !hasAttribute(dynamicCallable)
4+
BOOM
5+
#endif
6+
7+
#if hasAttribute(fortran)
8+
BOOM
9+
#endif
10+
11+
#if hasAttribute(cobol)
12+
this is unparsed junk // expected-error{{consecutive statements on a line must be separated by}}
13+
#endif
14+
15+
#if hasAttribute(optional)
16+
ModifiersAreNotAttributes
17+
#endif
18+
19+
#if hasAttribute(__raw_doc_comment)
20+
UserInaccessibleAreNotAttributes
21+
#endif
22+
23+
#if hasAttribute(17)
24+
// expected-error@-1{{unexpected platform condition argument: expected attribute name}}
25+
#endif

0 commit comments

Comments
 (0)