================
@@ -4912,3 +4922,279 @@ void AutoType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Context) {
Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(),
getTypeConstraintConcept(), getTypeConstraintArguments());
}
+
+FunctionEffect::~FunctionEffect() = default;
+
+bool FunctionEffect::diagnoseConversion(bool Adding, QualType OldType,
+ FunctionEffectSet OldFX,
+ QualType NewType,
+ FunctionEffectSet NewFX) const {
+ return false;
+}
+
+bool FunctionEffect::diagnoseRedeclaration(bool Adding,
+ const FunctionDecl &OldFunction,
+ FunctionEffectSet OldFX,
+ const FunctionDecl &NewFunction,
+ FunctionEffectSet NewFX) const {
+ return false;
+}
+
+bool FunctionEffect::diagnoseMethodOverride(bool Adding,
+ const CXXMethodDecl &OldMethod,
+ FunctionEffectSet OldFX,
+ const CXXMethodDecl &NewMethod,
+ FunctionEffectSet NewFX) const {
+ return false;
+}
+
+bool FunctionEffect::canInferOnDecl(const Decl *Caller,
+ FunctionEffectSet CallerFX) const {
+ return false;
+}
+
+bool FunctionEffect::diagnoseFunctionCall(bool Direct, const Decl *Caller,
+ FunctionEffectSet CallerFX,
+ CalleeDeclOrType Callee,
+ FunctionEffectSet CalleeFX) const {
+ return false;
+}
+
+const NoLockNoAllocEffect &NoLockNoAllocEffect::nolock_instance() {
+ static NoLockNoAllocEffect global(kNoLockTrue, "nolock");
+ return global;
+}
----------------
dougsonos wrote:
The GNU syntax is more liberal, and yes, this is supported (and tested as of my
next push):
```
// Alternate placement on the FunctionDecl
__attribute__((clang_nolock)) void nl_function();
// CHECK: FunctionDecl {{.*}} nl_function 'void ()
__attribute__((clang_nolock))'
```
One reason I prefer the square-bracket syntax is that it is not only consistent
with `noexcept`, but it becomes practical to apply both `nolock` and `noexcept`
with a single macro (not sure yet I want to do that to my codebase, but it's
possible).
Another is that the placement rules seem more consistent and sensible, to me
anyhow.
The `nolock/noalloc(true)` attributes do need to apply to function types, not
declarations, so as to be able to analyze indirect calls. They only applies to
declarations as a consequence of declarations having function types.
`nolock/noalloc(false)` have to be treated the same way as the `true` form for
parsing, but for analysis purposes, they end up being ignored until they land
on a `Decl`, since indirect calls prevent inference regardless.
As for the rule about square brackets, in SemaType.cpp:
```
FUNCTION_TYPE_ATTRS_CASELIST:
attr.setUsedAsTypeAttr();
// Attributes with standard syntax have strict rules for what they
// appertain to and hence should not use the "distribution" logic below.
if (attr.isStandardAttributeSyntax() ||
attr.isRegularKeywordAttribute()) {
if (!handleFunctionTypeAttr(state, attr, type, CFT)) {
diagnoseBadTypeAttribute(state.getSema(), attr, type);
attr.setInvalid();
}
break;
}
```
So with square-bracket syntax, the attribute has to follow the right
parenthesis enclosing the parameter list (and after const).
Incidentally, I realized that in Attr.td the attributes can derive from
`TypeAttr` rather than `DeclOrTypeAttr`.
https://github.com/llvm/llvm-project/pull/84983
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits