mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-19 23:15:24 +02:00
Bug 549362 - Aggregate init for union-like classes
ClassTypeHelper.getDeclaredFields() returns the first field of an anonymous union. Change-Id: I3f33dcdd7b274ffac7aad0b80ea8c523bfd6e5f2 Signed-off-by: Hannes Vogt <hannes@havogt.de>
This commit is contained in:
parent
39be625d8e
commit
9a6fd2ab97
2 changed files with 55 additions and 14 deletions
|
@ -13393,4 +13393,16 @@ public class AST2CPPTests extends AST2CPPTestBase {
|
|||
BindingAssertionHelper bh = getAssertionHelper();
|
||||
bh.assertImplicitName("t{1};", 1, IProblemBinding.class);
|
||||
}
|
||||
|
||||
// struct MyStruct {
|
||||
// union {
|
||||
// int num;
|
||||
// };
|
||||
// };
|
||||
// int main() {
|
||||
// MyStruct test = { 0 };
|
||||
// }
|
||||
public void testAggregateInitOfAnonymousUnion_549362() throws Exception {
|
||||
parseAndCheckImplicitNameBindings();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -239,12 +239,29 @@ public class ClassTypeHelper {
|
|||
IASTDeclaration[] decls = host.getCompositeTypeSpecifier().getMembers();
|
||||
for (IASTDeclaration decl : decls) {
|
||||
if (decl instanceof IASTSimpleDeclaration) {
|
||||
IASTDeclarator[] dtors = ((IASTSimpleDeclaration) decl).getDeclarators();
|
||||
IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) decl;
|
||||
IASTDeclarator[] dtors = simpleDecl.getDeclarators();
|
||||
if (dtors.length == 0) {
|
||||
// check for union-like classes [class.union.anon]
|
||||
ICPPClassType nestedClass = getNestedClass(simpleDecl);
|
||||
if (nestedClass != null && nestedClass.getName().length() == 0) {
|
||||
if (nestedClass.getFields().length > 0) {
|
||||
// TODO(havogt): Here we add only the first field of the anonymous union to the result
|
||||
// (as needed for aggregate initialization, see [dcl.init.aggr](c++17)p.16).
|
||||
// A proper solution will probably need to return a new implementation of ICPPField for anonymous unions.
|
||||
// TODO(havogt): This branch is also taken for anonymous structs (GNU extension), in that case
|
||||
// it should add all fields of the anonymous struct.
|
||||
binding = nestedClass.getFields()[0];
|
||||
result = ArrayUtil.appendAt(result, resultSize++, (ICPPField) binding);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (IASTDeclarator dtor : dtors) {
|
||||
binding = ASTQueries.findInnermostDeclarator(dtor).getName().resolveBinding();
|
||||
if (binding instanceof ICPPField)
|
||||
result = ArrayUtil.appendAt(result, resultSize++, (ICPPField) binding);
|
||||
}
|
||||
}
|
||||
} else if (decl instanceof ICPPASTUsingDeclaration) {
|
||||
IASTName n = ((ICPPASTUsingDeclaration) decl).getName();
|
||||
binding = n.resolveBinding();
|
||||
|
@ -260,6 +277,7 @@ public class ClassTypeHelper {
|
|||
}
|
||||
}
|
||||
return ArrayUtil.trim(result, resultSize);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -551,6 +569,23 @@ public class ClassTypeHelper {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param decl
|
||||
* @return if decl declares a nested class: return the class; else return null.
|
||||
*/
|
||||
public static ICPPClassType getNestedClass(IASTSimpleDeclaration decl) {
|
||||
IBinding binding = null;
|
||||
IASTDeclSpecifier declSpec = decl.getDeclSpecifier();
|
||||
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
|
||||
binding = ((ICPPASTCompositeTypeSpecifier) declSpec).getName().resolveBinding();
|
||||
} else if (declSpec instanceof ICPPASTElaboratedTypeSpecifier && decl.getDeclarators().length == 0) {
|
||||
binding = ((ICPPASTElaboratedTypeSpecifier) declSpec).getName().resolveBinding();
|
||||
}
|
||||
if (binding instanceof ICPPClassType)
|
||||
return (ICPPClassType) binding;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ICPPClassType[] getNestedClasses(ICPPInternalClassTypeMixinHost host) {
|
||||
if (host.getDefinition() == null) {
|
||||
host.checkForDefinition();
|
||||
|
@ -571,16 +606,10 @@ public class ClassTypeHelper {
|
|||
while (decl instanceof ICPPASTTemplateDeclaration)
|
||||
decl = ((ICPPASTTemplateDeclaration) decl).getDeclaration();
|
||||
if (decl instanceof IASTSimpleDeclaration) {
|
||||
IBinding binding = null;
|
||||
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) decl).getDeclSpecifier();
|
||||
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
|
||||
binding = ((ICPPASTCompositeTypeSpecifier) declSpec).getName().resolveBinding();
|
||||
} else if (declSpec instanceof ICPPASTElaboratedTypeSpecifier
|
||||
&& ((IASTSimpleDeclaration) decl).getDeclarators().length == 0) {
|
||||
binding = ((ICPPASTElaboratedTypeSpecifier) declSpec).getName().resolveBinding();
|
||||
ICPPClassType nestedClass = getNestedClass((IASTSimpleDeclaration) decl);
|
||||
if (nestedClass != null) {
|
||||
result = ArrayUtil.appendAt(result, resultSize++, nestedClass);
|
||||
}
|
||||
if (binding instanceof ICPPClassType)
|
||||
result = ArrayUtil.appendAt(result, resultSize++, (ICPPClassType) binding);
|
||||
}
|
||||
}
|
||||
return ArrayUtil.trim(result, resultSize);
|
||||
|
|
Loading…
Add table
Reference in a new issue