john.brawn marked an inline comment as done.
john.brawn added inline comments.


================
Comment at: clang/lib/Sema/SemaDeclAttr.cpp:6701-6707
     if (!AL.isStmtAttr()) {
       // Type attributes are handled elsewhere; silently move on.
       assert(AL.isTypeAttr() && "Non-type attribute not handled");
       break;
     }
     S.Diag(AL.getLoc(), diag::err_stmt_attribute_invalid_on_decl)
         << AL << D->getLocation();
----------------
aaron.ballman wrote:
> john.brawn wrote:
> > aaron.ballman wrote:
> > > If we're in the situation where we parse a plugin-based attribute (so 
> > > `AL.getKind()` falls into the `default` label) and its 
> > > `handleDeclAttributes()` (incorrectly) returns false rather than true, it 
> > > seems like we would not want to trigger either of these tests, correct? 
> > > I'm thinking about a case where the plugin knows about that attribute but 
> > > cannot apply it because of some other issues (maybe the subject is wrong, 
> > > or args are incorrect, etc) and returns `false` here. We wouldn't want to 
> > > assert or claim that this is an invalid statement attribute applied to a 
> > > decl in that case.
> > > 
> > > Rather than requiring the user to return true from 
> > > `handleDeclAttribute()`, it seems that what we really want is something 
> > > more like:
> > > ```
> > > if (AL.getInfo().hasHandlerFunc()) {
> > >   AL.getInfo().handleDeclAttribute(S, D, AL);
> > >   break;
> > > }
> > > if (!AL.isStmtAttr()) {
> > >   ...
> > > }
> > > S.Diag(...);
> > > ```
> > > where an unknown attribute does not have a handler, but simple and plugin 
> > > attributes do have a handler. This way the user doesn't have the chance 
> > > to accidentally get confused about what it means to handle an attribute. 
> > > WDYT?
> > That sounds a little overly complex, as instead of defining one thing you 
> > now have to define two things so you have the possibility of defining one 
> > but not the other which won't do anything useful.
> I was hoping we could do it in such a way that the plugin user defines 
> `handleDeclAttribute()` and the `hasHandlerFunc()` logic is automatic. This 
> way, the user just has to define their function and "everything just works".
> 
> My big concern here is that we have a function with a useless return value 
> (from the plugin author's perspective) but they're likely to get the behavior 
> wrong through simple misunderstanding. Unless the plugin author is careful 
> with their testing, this will lead to failed assertions when we go to check 
> for whether it's type attribute or not.
I don't think there's any straightforward way that hasHanderFunc could be 
implemented automatically. The obvious choice of

```
  return &AL.handleDeclAttribute == &ParsedAttrInfo::handleDeclAttribute;
```
doesn't work as &X.Y is only allowed if X.Y is an lvalue, which isn't the case 
for a member function.

We could do something by use of a template:

```
class ParsedAttrInfo {
public:
  virtual bool hasHandlerFunc() = 0;
  virtual void handleDeclAttribute() { }
};

template<class C> class ParsedAttrInfoTemplate : public ParsedAttrInfo {
public:
  virtual bool hasHandlerFunc() {
    return &C::handleDeclAttribute != &ParsedAttrInfo::handleDeclAttribute;
  }
};

class ExampleAttribute : public ParsedAttrInfoTemplate<ExampleAttribute> {
public:
  virtual void handleDeclAttribute() { }
};

void call_fn(ParsedAttrInfo *p) {
  if (p->hasHandlerFunc()) {
    p->handleDeclAttribute();
  }
}
```
This works, but now we have to be careful to inherit from 
ParsedAttrInfoTemplate in the right way.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D31342/new/

https://reviews.llvm.org/D31342



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to