<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/57655>57655</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [lldb] CXXRecordDecl::IsStandardLayout incorrectly unset when importing a class with a single base class
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          Michael137
      </td>
    </tr>
</table>

<pre>
    Essentially it’s just about importing a type with a single base class with member fields. There isn't anything problematic I ran into with this per-se, but it was a discrepancy I noticed while working on a different issue.

Setup:
```
// lib.h
class Base {
  void* Field;
};

class Derived : Base {};

struct Foo {
  Derived d;
};

// main.cpp
#include "lib.h"

int main() {
  Foo f;

  return 0;
}
```

```
./bin/lldb \
    -o "br se -p return -X main" \      
    -o "log enable lldb ast" \          
    -o "r" \                            
    -o "p f" \                          
    -o "q" \                            
    a.out                               
```

Executing `run.sh` will print:
```
-CXXRecordDecl 0x159f31d10 <<invalid sloc>> <invalid sloc> <undeserialized declarations> class Foo definition
 |-DefinitionData pass_in_registers 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 simple trivial has_const_param needs_implicit implicit_has_const_param
 | |-MoveAssignment exists simple trivial needs_implicit                                                
 | `-Destructor simple irrelevant trivial needs_implicit                                                
 `-FieldDecl 0x159f32180 <<invalid sloc>> <invalid sloc> d 'test::Derived'
-CXXRecordDecl 0x159f31e50 <<invalid sloc>> <invalid sloc> class Derived definition
 |-DefinitionData pass_in_registers 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 simple trivial has_const_param needs_implicit implicit_has_const_param
 | |-MoveAssignment exists simple trivial needs_implicit                                                
 | `-Destructor simple irrelevant trivial needs_implicit                                                
 `-private 'test::Base'                           
-CXXRecordDecl 0x159f31f90 <<invalid sloc>> <invalid sloc> class Base definition
 |-DefinitionData pass_in_registers standard_layout 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 simple trivial has_const_param needs_implicit implicit_has_const_param
 | |-MoveAssignment exists simple trivial needs_implicit                                                
 | `-Destructor simple irrelevant trivial needs_implicit                                                
 `-FieldDecl 0x159f32110 <<invalid sloc>> <invalid sloc> Mem 'void *'
```

Note that both `class Derived` and `class Foo` don’t have `standard_layout` set in its DeinitionData despite `class Base` having it set.

According to the standard, a standard-layout class is allowed to have a single base class with member fields. This is codified in `RecordDecl::setBases` as follows:

```

// C++2a [class]p7:                                                     
//   A standard-layout class is a class that:                           
//    [...]                                                             
//    -- has all non-static data members and bit-fields in the class and
//       its base classes first declared in the same class              
if (BaseClassDecl->data().HasBasesWithFields ||                         
    !BaseClassDecl->field_empty()) {                                    
  if (data().HasBasesWithFields) {
    data().IsStandardLayout = false;                     
  }                                                                     
  data().HasBasesWithFields = true;                                     
}                                                        
…               
```

When we're asked to complete `Foo` we call into `DWARFASTParserClang::CompleteRecordType` and then `TypeSystemClang::TransferBaseClasses` which calls `CXXRecordDecl::setBases`.

When we then import the definition into the scratch AST (see `ASTNodeImporter::ImportDefinition`), we do:
```
struct CXXRecordDecl::DefinitionData &ToData = ToCXX->data();    
struct CXXRecordDecl::DefinitionData &FromData = FromCXX->data();
#define FIELD(Name, Width, Merge) \                 
ToData.Name = FromData.Name;                        
#include "clang/AST/CXXRecordDeclDefinitionBits.def"

if (!Bases.empty())                           
  ToCXX->setBases(Bases.data(), Bases.size());
```

So now the `To` decl has `HasBasesWithFields` set going into `CXXRecordDecl::setBases`, and unset `IsStandardLayout` because we mistakenly claimed that `To` has more than one base class with members.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztWd9v4jgQ_mvCi0UEyQLlgQcKRbfS7ep0rbT7VjmJA74Ncc42Zbm__r6xA4E0pdvdu4fTLUJtMvb89HzjsUlUdpjdGSNKK3lRHJi0wV0U3AyC6dSwP3bGMp6onWVyWyltZblmnNlDJdhe2g2eDUiFYAk3gqUFN8YPbMU2EZrlUhSZCdnDRmjBpCmDaAKJ5cFuSFSlVVKILbcyZe-Z5iWTpVVeAmYYVgndNyKIFiwhGyzbcwOlmTSpFhUv0wP4SgV-kbH9RsKSvdJfSLYq3cQ8h-YSvMbsRBgMlsFg7v_eC7urgrh-C8aD-utfoxW-rJBJuPEU79wt-RlMbj2NsSclsyCasxU5GsQ1PZgsm-cz7qXQ8gmWQmsj6dlcY_UutWyl1LmmI-81LbXVWy7LMK2qIzGWZVrsMqiLIu9RFJ2zIeiOJ4hugmh6rpRsyFtKGNOInC7Z4MKSzih2EUOYmJCyVVFkCQtGi6NcxvqKbEw0Q2z61VFR_3NtXkSzmfu0eQq1ZqLkSCfmxHJjL-Z38ehnM55_2jwV4vEaV5vnzzfp4SHh7frnSrTvvop054CKAb0rQ7PBAzBVFMAblvqllO8vPn_-XaRKZ0uRFmzwdTia5vEwGw6Qrwt8ZfnEC5kxU6g0iO_wZc-pRNqVmTBIV9D_ooyFOK4BclUamuGxQKmViVyWkgZq94PJor88EZfcclZh8qMsH7VYS2OFNswCCK5YPaaqOrglr0nAK2bwopF2lMh3hV1Av4OW0kx8hbCTKFYKkUHLtipkKl8L_pXlO2pcwLBzdYZEN2ZuuIHtGH6sEJhtW_3x4bE1r6Xkg3oSHT61dP2Qax1uzY2R63JLNfVf8-pMx7_g1IVX4wHSo71OUmtRiCcO_f-sRmhzO8U5wqLhzdsQhv0DuyiMJiTH83pjAO0qjsXobVoud6yfSP2J1P8bUrFbPnErLtFGbRsIr0p4AYX59HtQ6HrF74OgsbzMuM4eC36gvuInJH9C8r8LyY7N843t6QexJUDTuQ3_56dds7OX_qgAf7vhliUKR1KMXuyK1FcDXQ0dPS3RMkD0eIi2WNknQVNaSKSJRmBlcei1JPIcx-ifK2lFI9mVHXBAGLX2CCJ4L46z85SKDQ3iBG034oR8Oj3z01u_rgNeLI7YqAVqjx0eXM7Sbz_SS8efKhyyJQTAEVjY1DxfL2Em2W5crAzLFakzzRmkM_g-ePPxxal2EUS3-EYcR6lbZ1cwWlYTOkt_z-dCNmPzKxGqHykRrmtrySRDwzCEmd9l4UtS-32qFrRwrFRlH3bT_UlGeePXyLisTKTt-8WipaGM8G5grC0RH8rBZsUFVkpqY-uzm19dl1R8e5TTYaPMgakbWu8FTaEs6AN0ZJq_Wwh_4calwydk1Mobh0pCxeS69-4pGj4T7Rx8FNvKHryG-gLj2-MK153VV41sXYswdjb7vbmvM-dXnzhBvGQ5LwDYuNuOo5hg8mOJ0Zb3SpxhFkr1i1Z1S_0BG1tg7h7tKrufNqJke2qzNOqR-eKrU6poe_FFsS60e-QiwcDdGoKw_DT_fTW_f_iNayM0EqVc-yq0qHl9dXo4VOJYuy3pwgvR7g_ombZnbA-alyYX-pR2vo7tNzLdOM2GWC86vWdVL-zwzGv1V6oOVk1v531xUEs1t9ADfyg_jXCe4-2jysR7xyu0V-ffml6Q4klQWJCuTL1041NfNHbY32org2j8oPwTkuhBgeMS13VOvV3sSqvtSTC9dIk-3WO6MAm2en_36xKjH1GMyMlPMrMbevgg9Fo4rHZctnkp3o-QWE86T5Qr0Oi6S01dpkSUcfh74W_j6S0qawjD23eurujUJc2ErQr2GqhYswinVPOFF7qa0CEknmbkX-IkvYloF_juFXaVvctAgoVvaKjjoj0HLx3Fse5k1sq1JjUWr6PCNSWA364kThDaVZSEJiLlO2xJSOItGln-RZTFgXYfuaWSQH3ZyUSybqu0a9dKpsqX-hcT9sRsOB5Hk_hmGA962SzOpvGU96y0hZhhx6brY9qyOxx4VuqRDArtbmphl3dl3yDb_1hyZkFHa9Xb6WK2sbZyLZHbkNeYuktClDt3Rf50_IfzqPoDqvDqfszAiq9Gk_Fo1NvM0lGa82E8EXmcp4Mkz6Y8GudJko-TPI-mo17BE1EYcg95WIq9_z2EcnK07MlZNIiiwXQwHY7eRcNByOPp8F2UT5JxFg_iNA7eDcSWyyIkO0Kl1z09cyYlu7XBYEHHjGaQuxOIcNEk-XxnN0rPPqBqclHAzJ7TPnPW_w3wQ7uM">