diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index e478cff2941..06eaaf0990f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -5581,4 +5581,17 @@ public class AST2Tests extends AST2BaseTest { assertEquals(0, children[0].getChildren().length); } } + + // struct s { + // int (mem); + // }; + // void foo() { + // struct s v; + // v.mem = 1; + // } + public void testNestedDeclarator_Bug257540() throws Exception { + final String code= getAboveComment(); + parseAndCheckBindings(code, ParserLanguage.C); + parseAndCheckBindings(code, ParserLanguage.CPP); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CStructure.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CStructure.java index 427f729b041..1979afff685 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CStructure.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CStructure.java @@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; @@ -156,67 +157,65 @@ public class CStructure extends PlatformObject implements ICompositeType, ICInte return (IField[]) ArrayUtil.trim( IField.class, fields ); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.ICompositeType#findField(org.eclipse.cdt.core.dom.ast.IASTName) - */ public IField findField(String name) throws DOMException { - if( definition == null ){ - ICASTCompositeTypeSpecifier temp = checkForDefinition( (IASTElaboratedTypeSpecifier) declarations[0].getParent() ); - if( temp == null ) - return new CField.CFieldProblem( declarations[0], IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ); - definition = temp.getName(); - } - - ICCompositeTypeScope scope = (ICCompositeTypeScope) getCompositeScope(); - if( scope != null && ASTInternal.isFullyCached(scope) ){ - IBinding binding = scope.getBinding( name.toCharArray() ); - if( binding instanceof IField ) - return (IField) binding; - } else { - ICASTCompositeTypeSpecifier compSpec = (ICASTCompositeTypeSpecifier) definition.getParent(); - ICASTCompositeTypeSpecifier [] specStack = null; - int stackIdx = -1; - IASTDeclaration[] members = compSpec.getMembers(); - IField found = null; - while( members != null ){ - int size = members.length; - for( int i = 0; i < size; i++ ){ - IASTNode node = members[i]; - if( node instanceof IASTSimpleDeclaration ){ - IASTDeclarator[] declarators = ((IASTSimpleDeclaration)node).getDeclarators(); - for( int j = 0; j < declarators.length; j++ ){ - IASTDeclarator declarator = declarators[j]; - IASTName dtorName = declarator.getName(); - if( scope != null ) - ASTInternal.addName( scope, dtorName ); - if( name.equals( dtorName.toString() ) ){ - IBinding binding = dtorName.resolveBinding(); - if( binding instanceof IField ) - found = (IField) binding; - } - } - //anonymous structurs and unions - if( declarators.length == 0 && ((IASTSimpleDeclaration)node).getDeclSpecifier() instanceof IASTCompositeTypeSpecifier ){ - IASTCompositeTypeSpecifier declSpec = (IASTCompositeTypeSpecifier) ((IASTSimpleDeclaration)node).getDeclSpecifier(); - IASTName n = declSpec.getName(); - if( n.toCharArray().length == 0 ){ - specStack = (ICASTCompositeTypeSpecifier[])ArrayUtil.append( ICASTCompositeTypeSpecifier.class, specStack, declSpec ); - } - } - } - } - if( specStack != null && ++stackIdx < specStack.length && specStack[stackIdx] != null ){ - members = specStack[stackIdx].getMembers(); - } else { - members = null; - } - } - if( scope != null ) - ASTInternal.setFullyCached(scope, true); - if( found != null ) - return found; - } - + if (definition == null) { + ICASTCompositeTypeSpecifier temp = checkForDefinition((IASTElaboratedTypeSpecifier) declarations[0].getParent()); + if (temp == null) + return new CField.CFieldProblem(declarations[0], IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray()); + definition = temp.getName(); + } + + final char[] nchars= name.toCharArray(); + ICCompositeTypeScope scope = (ICCompositeTypeScope) getCompositeScope(); + if (scope != null && ASTInternal.isFullyCached(scope)) { + IBinding binding = scope.getBinding(nchars); + if (binding instanceof IField) + return (IField) binding; + } else { + ICASTCompositeTypeSpecifier compSpec = (ICASTCompositeTypeSpecifier) definition.getParent(); + ICASTCompositeTypeSpecifier[] specStack = null; + int stackIdx = -1; + IASTDeclaration[] members = compSpec.getMembers(); + IField found = null; + while (members != null) { + int size = members.length; + for (int i = 0; i < size; i++) { + IASTNode node = members[i]; + if (node instanceof IASTSimpleDeclaration) { + IASTDeclarator[] declarators = ((IASTSimpleDeclaration) node).getDeclarators(); + for (int j = 0; j < declarators.length; j++) { + IASTDeclarator declarator = declarators[j]; + IASTName dtorName = CVisitor.findInnermostDeclarator(declarator).getName(); + if (scope != null) + ASTInternal.addName(scope, dtorName); + if (CharArrayUtils.equals(nchars, dtorName.toCharArray())) { + IBinding binding = dtorName.resolveBinding(); + if (binding instanceof IField) + found = (IField) binding; + } + } + // anonymous structures and unions + if (declarators.length == 0 && ((IASTSimpleDeclaration) node).getDeclSpecifier() instanceof IASTCompositeTypeSpecifier) { + IASTCompositeTypeSpecifier declSpec = (IASTCompositeTypeSpecifier) ((IASTSimpleDeclaration) node).getDeclSpecifier(); + IASTName n = declSpec.getName(); + if (n.toCharArray().length == 0) { + specStack = (ICASTCompositeTypeSpecifier[]) ArrayUtil.append(ICASTCompositeTypeSpecifier.class, specStack, declSpec); + } + } + } + } + if (specStack != null && ++stackIdx < specStack.length && specStack[stackIdx] != null) { + members = specStack[stackIdx].getMembers(); + } else { + members = null; + } + } + if (scope != null) + ASTInternal.setFullyCached(scope, true); + if (found != null) + return found; + } + return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index 2ec27e2a0be..cfdbd85c075 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -886,32 +886,18 @@ public class CVisitor { private static IBinding createBinding(IASTDeclarator declarator) { IASTNode parent = declarator.getParent(); - while (parent instanceof IASTDeclarator) { parent = parent.getParent(); } - while (declarator.getNestedDeclarator() != null) - declarator = declarator.getNestedDeclarator(); - + declarator= CVisitor.findInnermostDeclarator(declarator); + IASTDeclarator typeRelevant= CVisitor.findTypeRelevantDeclarator(declarator); IASTFunctionDeclarator funcDeclarator= null; - IASTNode node= declarator; - do { - if (node instanceof IASTFunctionDeclarator) { - funcDeclarator= (IASTFunctionDeclarator) node; - break; - } - if (((IASTDeclarator) node).getPointerOperators().length > 0 || - node.getPropertyInParent() != IASTDeclarator.NESTED_DECLARATOR) { - break; - } - node= node.getParent(); + if (typeRelevant instanceof IASTFunctionDeclarator) { + funcDeclarator= (IASTFunctionDeclarator) typeRelevant; } - while (node instanceof IASTDeclarator) - ; - - IScope scope = getContainingScope(parent); + IScope scope= getContainingScope(parent); ASTNodeProperty prop = parent.getPropertyInParent(); if (prop == IASTDeclarationStatement.DECLARATION) { //implicit scope, see 6.8.4-3