How to find implicitly deleted default constructors in clang's AST?

Viewed 128

Consider the following struct definition in foo.cc:

struct Foo
{
  int &bar;
};

Because bar has reference type, the implicit trivial default constructor Foo::Foo() is implicitly deleted. However, this fact does not seem to be reflected in the AST generated by clang. E.g. running clang -Xclang -ast-dump foo.cc results in:

`-CXXRecordDecl 0x5612ba4c03b8 <test.cc:1:1, col:24> col:8 struct Foo definition
  |-DefinitionData pass_in_registers aggregate trivially_copyable trivial literal
  | |-DefaultConstructor exists trivial needs_implicit
  | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
  | |-MoveConstructor exists simple trivial needs_implicit
  | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
  | |-MoveAssignment exists trivial needs_implicit
  | `-Destructor simple irrelevant trivial needs_implicit
  |-CXXRecordDecl 0x5612ba4c04e0 <col:1, col:8> col:8 implicit struct Foo
  `-FieldDecl 0x5612ba4c05b8 <col:14, col:19> col:19 bar 'int &'

So here it looks like an implicit trivial default constructor exists, but there is no mention of it being deleted. Similarly, the clang::CXXRecordDecl API seems to offer no way of determining this either. But shouldn't this information be available at this point (after semantic analysis)? How can I use the clang AST API to find out whether some class's implicit trivial default constructor is implicitly deleted?

1 Answers

Implicit constructors don't exist in the AST under CXXRecordDecl nodes but only under DefinitionData.

You can use Sema::ForceDeclarationOfImplicitMembers in AST plugin to get the constructors, then check whether is deleted.

// force declaration of implict constructors
clang::Sema &sema = Instance.getSema();
sema.ForceDeclarationOfImplicitMembers(const_cast<CXXRecordDecl*>(cxxRecordDecl));

// then check whether constructor is deleted
for (const auto* ctor : cxxRecordDecl->ctors()) {
    if (ctor->isDeleted() {
       // do something
    }
}
Related