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();
|
BindingAssertionHelper bh = getAssertionHelper();
|
||||||
bh.assertImplicitName("t{1};", 1, IProblemBinding.class);
|
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,11 +239,28 @@ public class ClassTypeHelper {
|
||||||
IASTDeclaration[] decls = host.getCompositeTypeSpecifier().getMembers();
|
IASTDeclaration[] decls = host.getCompositeTypeSpecifier().getMembers();
|
||||||
for (IASTDeclaration decl : decls) {
|
for (IASTDeclaration decl : decls) {
|
||||||
if (decl instanceof IASTSimpleDeclaration) {
|
if (decl instanceof IASTSimpleDeclaration) {
|
||||||
IASTDeclarator[] dtors = ((IASTSimpleDeclaration) decl).getDeclarators();
|
IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) decl;
|
||||||
for (IASTDeclarator dtor : dtors) {
|
IASTDeclarator[] dtors = simpleDecl.getDeclarators();
|
||||||
binding = ASTQueries.findInnermostDeclarator(dtor).getName().resolveBinding();
|
if (dtors.length == 0) {
|
||||||
if (binding instanceof ICPPField)
|
// check for union-like classes [class.union.anon]
|
||||||
result = ArrayUtil.appendAt(result, resultSize++, (ICPPField) binding);
|
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) {
|
} else if (decl instanceof ICPPASTUsingDeclaration) {
|
||||||
IASTName n = ((ICPPASTUsingDeclaration) decl).getName();
|
IASTName n = ((ICPPASTUsingDeclaration) decl).getName();
|
||||||
|
@ -260,6 +277,7 @@ public class ClassTypeHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ArrayUtil.trim(result, resultSize);
|
return ArrayUtil.trim(result, resultSize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -551,6 +569,23 @@ public class ClassTypeHelper {
|
||||||
return true;
|
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) {
|
public static ICPPClassType[] getNestedClasses(ICPPInternalClassTypeMixinHost host) {
|
||||||
if (host.getDefinition() == null) {
|
if (host.getDefinition() == null) {
|
||||||
host.checkForDefinition();
|
host.checkForDefinition();
|
||||||
|
@ -571,16 +606,10 @@ public class ClassTypeHelper {
|
||||||
while (decl instanceof ICPPASTTemplateDeclaration)
|
while (decl instanceof ICPPASTTemplateDeclaration)
|
||||||
decl = ((ICPPASTTemplateDeclaration) decl).getDeclaration();
|
decl = ((ICPPASTTemplateDeclaration) decl).getDeclaration();
|
||||||
if (decl instanceof IASTSimpleDeclaration) {
|
if (decl instanceof IASTSimpleDeclaration) {
|
||||||
IBinding binding = null;
|
ICPPClassType nestedClass = getNestedClass((IASTSimpleDeclaration) decl);
|
||||||
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) decl).getDeclSpecifier();
|
if (nestedClass != null) {
|
||||||
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
|
result = ArrayUtil.appendAt(result, resultSize++, nestedClass);
|
||||||
binding = ((ICPPASTCompositeTypeSpecifier) declSpec).getName().resolveBinding();
|
|
||||||
} else if (declSpec instanceof ICPPASTElaboratedTypeSpecifier
|
|
||||||
&& ((IASTSimpleDeclaration) decl).getDeclarators().length == 0) {
|
|
||||||
binding = ((ICPPASTElaboratedTypeSpecifier) declSpec).getName().resolveBinding();
|
|
||||||
}
|
}
|
||||||
if (binding instanceof ICPPClassType)
|
|
||||||
result = ArrayUtil.appendAt(result, resultSize++, (ICPPClassType) binding);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ArrayUtil.trim(result, resultSize);
|
return ArrayUtil.trim(result, resultSize);
|
||||||
|
|
Loading…
Add table
Reference in a new issue