Triviality of C++11 Copy/Move Constructor, Destructor in clang AST.

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Triviality of C++11 Copy/Move Constructor, Destructor in clang AST.

Kristof Beyls via cfe-dev
Hi All,

We're working DWARF-5 support in clang, c++11 Defaulted, deleted member functions. 
We're facing an issue while parsing attributes of a destructor which is defined out of class. as default.
as in
class foo {
      public;
           foo();
           ~foo();
};
foo::foo() = default;
foo::~foo() = default;

Here's the code snippet of clang changes--

if (const auto *DXXC = dyn_cast<CXXDestructorDecl>(Method)) {
1624       if (DXXC->getCanonicalDecl()->isDeleted())
1625         SPFlags |= llvm::DISubprogram::SPFlagDeleted;
1626
1627       if (DXXC->getCanonicalDecl()->isDefaulted())
1628         SPFlags |= llvm::DISubprogram::SPFlagDefaultedInClass;
1629       else if (DXXC->isDefined()) {
1630         if (DXXC->getDefinition()->isDefaulted()) {
1631           SPFlags |= llvm::DISubprogram::SPFlagDefaultedOutOfClass;
1632         }
1633         else {
1634           SPFlags |= llvm::DISubprogram::SPFlagNotDefaulted;
1635         }
1636       }
1637     }

For, out of class  destructor definition defaulted, as mentioned above. We're not able get  SPFlagDefaultedOutOfClass or  SPFlagNotDefaulted.

seems like their is no definition of destructor, even when, we are defining them out of class as default; ??
  1629       else if (DXXC->isDefined())  -- evaluates as false 

On the other side, If we declare our destructor as virtual, then above checks passes gracefully -- suggesting clang created a non-trivial destructor definition. 

Is this behavior okay  ?? , -- this behavior is also prevalent in copy/move constructor and assignments. 

Note-- For Constructor out of class definition as default -- clang create non-trivial constructor definition, and above check passes and we're are able to check capture the information about, whether the constructor is defaulted in class or out of class.

Any thoughts, greatly appreciated.

Thanks!
Sourabh Singh Tomar

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Triviality of C++11 Copy/Move Constructor, Destructor in clang AST.

Kristof Beyls via cfe-dev
Hmm - I didn't realize there was DWARF for describing defaulted operations. It looks like maybe this ended up in as a half fix to the issue of calling conventions (we had a few discussions with DWARF folks about whether knowing which ops were defaulted would be enough to know whether a class was to be passed by value or by reference in the calling convention - and eventually managed to demonstrate that it couldn't be and it would be best if DWARF encoded the decision, rather than the data for the decision - which is how we got DW_AT_calling_convention on types).

What's the motivation for implementing/emitting this DWARF? Are there any consumers or use cases you have in mind?

Anyway, let's see what the problem with the code is... looks pretty reasonable.

Might be easier with a test case/patch - perhaps you could post to Phabricator. 

Though I don't see anything immediately wrong, it might be simpler/more efficient to use "getDefinition" to determine if the function is defined - rather than separately calling isDefined+getDefinition later. Call getDefinition and check if it's non-null:

 else if (DXXC->isDefined()) {
  if (DXXC->getDefinition()->isDefaulted())
    SPFlags |= llvm::DISubprogram::SPFlagDefaultedOutOfClass;
  else
    SPFlags |= llvm::DISubprogram::SPFlagNotDefaulted;

->

if (const auto *Def = DXXC->getDefinition())
  if (Def->isDefaulted()
    ...
  else
    ...

On Fri, Sep 20, 2019 at 5:04 AM Sourabh Singh Tomar via cfe-dev <[hidden email]> wrote:
Hi All,

We're working DWARF-5 support in clang, c++11 Defaulted, deleted member functions. 
We're facing an issue while parsing attributes of a destructor which is defined out of class. as default.
as in
class foo {
      public;
           foo();
           ~foo();
};
foo::foo() = default;
foo::~foo() = default;

Here's the code snippet of clang changes--

if (const auto *DXXC = dyn_cast<CXXDestructorDecl>(Method)) {
1624       if (DXXC->getCanonicalDecl()->isDeleted())
1625         SPFlags |= llvm::DISubprogram::SPFlagDeleted;
1626
1627       if (DXXC->getCanonicalDecl()->isDefaulted())
1628         SPFlags |= llvm::DISubprogram::SPFlagDefaultedInClass;
1629       else if (DXXC->isDefined()) {
1630         if (DXXC->getDefinition()->isDefaulted()) {
1631           SPFlags |= llvm::DISubprogram::SPFlagDefaultedOutOfClass;
1632         }
1633         else {
1634           SPFlags |= llvm::DISubprogram::SPFlagNotDefaulted;
1635         }
1636       }
1637     }

For, out of class  destructor definition defaulted, as mentioned above. We're not able get  SPFlagDefaultedOutOfClass or  SPFlagNotDefaulted.

seems like their is no definition of destructor, even when, we are defining them out of class as default; ??
  1629       else if (DXXC->isDefined())  -- evaluates as false 

On the other side, If we declare our destructor as virtual, then above checks passes gracefully -- suggesting clang created a non-trivial destructor definition. 

Is this behavior okay  ?? , -- this behavior is also prevalent in copy/move constructor and assignments. 

Note-- For Constructor out of class definition as default -- clang create non-trivial constructor definition, and above check passes and we're are able to check capture the information about, whether the constructor is defaulted in class or out of class.

Any thoughts, greatly appreciated.

Thanks!
Sourabh Singh Tomar
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Triviality of C++11 Copy/Move Constructor, Destructor in clang AST.

Kristof Beyls via cfe-dev
Posted a patch for this. Please have a look ->

-- Sourabh Singh Tomar

On Sat, Sep 21, 2019 at 12:50 AM David Blaikie <[hidden email]> wrote:
Hmm - I didn't realize there was DWARF for describing defaulted operations. It looks like maybe this ended up in as a half fix to the issue of calling conventions (we had a few discussions with DWARF folks about whether knowing which ops were defaulted would be enough to know whether a class was to be passed by value or by reference in the calling convention - and eventually managed to demonstrate that it couldn't be and it would be best if DWARF encoded the decision, rather than the data for the decision - which is how we got DW_AT_calling_convention on types).

What's the motivation for implementing/emitting this DWARF? Are there any consumers or use cases you have in mind?

Anyway, let's see what the problem with the code is... looks pretty reasonable.

Might be easier with a test case/patch - perhaps you could post to Phabricator. 

Though I don't see anything immediately wrong, it might be simpler/more efficient to use "getDefinition" to determine if the function is defined - rather than separately calling isDefined+getDefinition later. Call getDefinition and check if it's non-null:

 else if (DXXC->isDefined()) {
  if (DXXC->getDefinition()->isDefaulted())
    SPFlags |= llvm::DISubprogram::SPFlagDefaultedOutOfClass;
  else
    SPFlags |= llvm::DISubprogram::SPFlagNotDefaulted;

->

if (const auto *Def = DXXC->getDefinition())
  if (Def->isDefaulted()
    ...
  else
    ...

On Fri, Sep 20, 2019 at 5:04 AM Sourabh Singh Tomar via cfe-dev <[hidden email]> wrote:
Hi All,

We're working DWARF-5 support in clang, c++11 Defaulted, deleted member functions. 
We're facing an issue while parsing attributes of a destructor which is defined out of class. as default.
as in
class foo {
      public;
           foo();
           ~foo();
};
foo::foo() = default;
foo::~foo() = default;

Here's the code snippet of clang changes--

if (const auto *DXXC = dyn_cast<CXXDestructorDecl>(Method)) {
1624       if (DXXC->getCanonicalDecl()->isDeleted())
1625         SPFlags |= llvm::DISubprogram::SPFlagDeleted;
1626
1627       if (DXXC->getCanonicalDecl()->isDefaulted())
1628         SPFlags |= llvm::DISubprogram::SPFlagDefaultedInClass;
1629       else if (DXXC->isDefined()) {
1630         if (DXXC->getDefinition()->isDefaulted()) {
1631           SPFlags |= llvm::DISubprogram::SPFlagDefaultedOutOfClass;
1632         }
1633         else {
1634           SPFlags |= llvm::DISubprogram::SPFlagNotDefaulted;
1635         }
1636       }
1637     }

For, out of class  destructor definition defaulted, as mentioned above. We're not able get  SPFlagDefaultedOutOfClass or  SPFlagNotDefaulted.

seems like their is no definition of destructor, even when, we are defining them out of class as default; ??
  1629       else if (DXXC->isDefined())  -- evaluates as false 

On the other side, If we declare our destructor as virtual, then above checks passes gracefully -- suggesting clang created a non-trivial destructor definition. 

Is this behavior okay  ?? , -- this behavior is also prevalent in copy/move constructor and assignments. 

Note-- For Constructor out of class definition as default -- clang create non-trivial constructor definition, and above check passes and we're are able to check capture the information about, whether the constructor is defaulted in class or out of class.

Any thoughts, greatly appreciated.

Thanks!
Sourabh Singh Tomar
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev