From 9704f355f0f56396f861568c76f0464763519e74 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 21 Jan 2009 17:13:47 +0000 Subject: [PATCH] Resolution of local structs, bug 255973. --- .../cdt/core/parser/tests/ASTComparer.java | 16 +++++- .../cdt/core/parser/tests/ast2/AST2Tests.java | 55 +++++++++++++------ .../core/dom/parser/IASTInternalScope.java | 2 +- .../internal/core/dom/parser/c/CScope.java | 16 +++--- .../core/dom/parser/c/CStructure.java | 17 +++--- .../internal/core/dom/parser/c/CVisitor.java | 44 ++++++++++----- .../parser/cpp/semantics/CPPSemantics.java | 5 +- .../composite/cpp/CPPCompositesFactory.java | 7 +-- 8 files changed, 107 insertions(+), 55 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ASTComparer.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ASTComparer.java index d085efdb147..2af63f30a0d 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ASTComparer.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ASTComparer.java @@ -1,3 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mike Kucera (IBM) - Initial API and implementation + *******************************************************************************/ package org.eclipse.cdt.core.parser.tests; import java.beans.BeanInfo; @@ -34,7 +44,11 @@ public class ASTComparer extends Assert { "getAllPreprocessorStatements", "getMacroExpansions", "getPreprocessorProblems", - "getComments" + "getComments", + // avoid name resolution + "isDeclaration", + "isDefinition", + "isReference" )); 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 860c15fb9a2..94b36cc80a5 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 @@ -3011,25 +3011,27 @@ public class AST2Tests extends AST2BaseTest { // struct s1 { struct s2 *s2p; /* ... */ }; // D1 // struct s2 { struct s1 *s1p; /* ... */ }; // D2 public void testBug84186() throws Exception { - final String code = getAboveComment(); - IASTTranslationUnit tu = parse(code, ParserLanguage.C); - CNameCollector col = new CNameCollector(); - tu.accept(col); - assertEquals(col.size(), 6); + for (ParserLanguage lang : ParserLanguage.values()) { + final String code = getAboveComment(); + IASTTranslationUnit tu = parse(code, lang); + CNameCollector col = new CNameCollector(); + tu.accept(col); + assertEquals(col.size(), 6); - ICompositeType s_ref = (ICompositeType) col.getName(1).resolveBinding(); - ICompositeType s_decl = (ICompositeType) col.getName(3).resolveBinding(); - assertSame(s_ref, s_decl); + ICompositeType s_ref = (ICompositeType) col.getName(1).resolveBinding(); + ICompositeType s_decl = (ICompositeType) col.getName(3).resolveBinding(); + assertSame(s_ref, s_decl); - - tu = parse(code, ParserLanguage.C); - col = new CNameCollector(); - tu.accept(col); - assertEquals(col.size(), 6); - s_decl = (ICompositeType) col.getName(3).resolveBinding(); - s_ref = (ICompositeType) col.getName(1).resolveBinding(); - assertSame(s_ref, s_decl); + tu = parse(code, lang); + col = new CNameCollector(); + tu.accept(col); + assertEquals(col.size(), 6); + + s_decl = (ICompositeType) col.getName(3).resolveBinding(); + s_ref = (ICompositeType) col.getName(1).resolveBinding(); + assertSame(s_ref, s_decl); + } } // typedef struct { int a; } S; @@ -5928,4 +5930,25 @@ public class AST2Tests extends AST2BaseTest { ITypedef td= bh.assertNonProblem("TInt; //", 4); IField f= bh.assertNonProblem("a;", 1); } + + // struct beta { + // int glob; + // }; + // void foo() { + // struct beta* pg; + // struct beta; + // struct beta* pl; + // + // struct beta { + // char loc; + // }; + // pg->glob= 0; + // pl->loc= 1; + // } + public void testLocalVsGlobalStruct_Bug255973() throws Exception { + final String code= getAboveComment(); + for (ParserLanguage lang : ParserLanguage.values()) { + IASTTranslationUnit tu= parseAndCheckBindings(code, lang, true); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalScope.java index 8b8ebb65894..aab740d46a4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalScope.java @@ -23,7 +23,7 @@ public interface IASTInternalScope extends IScope { /** * Return the physical IASTNode that this scope was created for */ - public IASTNode getPhysicalNode() throws DOMException; + public IASTNode getPhysicalNode(); /** * This adds an IBinding to the scope. It is primarily used by the parser to add diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java index 96e14d8f77d..b9bdc9d6b16 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java @@ -492,7 +492,7 @@ public class CScope implements ICScope, IASTInternalScope { return; collectNames(paramDecl.getDeclarator()); - collectNames(paramDecl.getDeclSpecifier()); + collectNames(paramDecl.getDeclSpecifier(), false); } private void collectNames(IASTDeclarator dtor) { @@ -519,19 +519,21 @@ public class CScope implements ICScope, IASTInternalScope { for (IASTDeclarator dtor : declarators) { collectNames(dtor); } - collectNames(simpleDeclaration.getDeclSpecifier()); + collectNames(simpleDeclaration.getDeclSpecifier(), declarators.length == 0); } else if (declaration instanceof IASTFunctionDefinition) { IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration; collectNames(functionDef.getDeclarator()); - collectNames(functionDef.getDeclSpecifier()); + collectNames(functionDef.getDeclSpecifier(), false); } } - private void collectNames(IASTDeclSpecifier declSpec) { + private void collectNames(IASTDeclSpecifier declSpec, boolean forceElabSpec) { IASTName tempName = null; if (declSpec instanceof ICASTElaboratedTypeSpecifier) { - tempName = ((ICASTElaboratedTypeSpecifier)declSpec).getName(); - ASTInternal.addName(this, tempName); + if (forceElabSpec || physicalNode instanceof IASTTranslationUnit) { + tempName = ((ICASTElaboratedTypeSpecifier)declSpec).getName(); + ASTInternal.addName(this, tempName); + } } else if (declSpec instanceof ICASTCompositeTypeSpecifier) { tempName = ((ICASTCompositeTypeSpecifier)declSpec).getName(); ASTInternal.addName(this, tempName); @@ -542,7 +544,7 @@ public class CScope implements ICScope, IASTInternalScope { if (element instanceof IASTSimpleDeclaration) { IASTDeclSpecifier d = ((IASTSimpleDeclaration)element).getDeclSpecifier(); if (d instanceof ICASTCompositeTypeSpecifier || d instanceof IASTEnumerationSpecifier) { - collectNames(d); + collectNames(d, false); } } } 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 3c46eebcb13..4a92f7dddd8 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 @@ -35,6 +35,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.Linkage; +import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.index.IIndexType; import org.eclipse.core.runtime.PlatformObject; @@ -234,20 +235,16 @@ public class CStructure extends PlatformObject implements ICompositeType, ICInte return; decl.setBinding(this); - if (declarations == null) { + if (declarations == null || declarations.length == 0) { declarations = new IASTName[] { decl }; return; } - for (int i = 0; i < declarations.length; i++) { - if (declarations[i] == null) { - declarations[i] = decl; - return; - } + IASTName first= declarations[0]; + if (((ASTNode) first).getOffset() > ((ASTNode) decl).getOffset()) { + declarations[0]= decl; + decl= first; } - IASTName tmp[] = new IASTName[declarations.length * 2]; - System.arraycopy(declarations, 0, tmp, 0, declarations.length); - tmp[declarations.length] = decl; - declarations = tmp; + declarations= (IASTName[]) ArrayUtil.append(IASTName.class, declarations, decl); } 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 5c712a4f672..62f9287f8a2 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 @@ -545,32 +545,50 @@ public class CVisitor extends ASTQueries { IASTName name = elabTypeSpec.getName(); if (parent instanceof IASTDeclaration) { IBinding binding= null; - if (parent instanceof IASTSimpleDeclaration && ((IASTSimpleDeclaration)parent).getDeclarators().length == 0) { + IScope insertIntoScope= null; + if (parent instanceof IASTSimpleDeclaration + && ((IASTSimpleDeclaration)parent).getDeclarators().length == 0) { IScope scope= getContainingScope(elabTypeSpec); try { + while (scope instanceof ICCompositeTypeScope) + scope= scope.getParent(); + binding= scope.getBinding(name, false); } catch (DOMException e) { } + if (binding != null) { + if (binding instanceof CEnumeration) { + ((CEnumeration)binding).addDeclaration(name); + } else if (binding instanceof CStructure) { + ((CStructure) binding).addDeclaration(name); + } + } } else { binding= resolveBinding(elabTypeSpec); + if (binding == null) { + insertIntoScope= elabTypeSpec.getTranslationUnit().getScope(); + try { + binding= insertIntoScope.getBinding(name, false); + if (binding != null) { + if (binding instanceof CEnumeration) { + ((CEnumeration)binding).addDeclaration(name); + } else if (binding instanceof CStructure) { + ((CStructure) binding).addDeclaration(name); + } + } + } catch (DOMException e) { + } + } } - if (binding != null) { - if (binding instanceof CEnumeration) { - ((CEnumeration)binding).addDeclaration(name); - } else if (binding instanceof CStructure) { - ((CStructure) binding).addDeclaration(name); - } - } else { + if (binding == null) { if (elabTypeSpec.getKind() == IASTElaboratedTypeSpecifier.k_enum) { binding = new CEnumeration(name); } else { binding = new CStructure(name); } - - try { - ASTInternal.addName(binding.getScope(), name); - } catch (DOMException e) { - } + if (insertIntoScope != null) { + ASTInternal.addName(insertIntoScope, name); + } } return binding; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 410aded9781..2c0487297e9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -1190,7 +1190,7 @@ public class CPPSemantics { continue; } } - if (item instanceof IASTLabelStatement) + while (item instanceof IASTLabelStatement) item= ((IASTLabelStatement) item).getNestedStatement(); if (item instanceof IASTDeclarationStatement) item = ((IASTDeclarationStatement)item).getDeclaration(); @@ -1345,7 +1345,8 @@ public class CPPSemantics { IASTName specName = null; if (declSpec instanceof IASTElaboratedTypeSpecifier) { - specName = ((IASTElaboratedTypeSpecifier)declSpec).getName(); + if (declarators.length == 0 || scope.getPhysicalNode() instanceof IASTTranslationUnit) + specName = ((IASTElaboratedTypeSpecifier)declSpec).getName(); } else if (declSpec instanceof ICPPASTCompositeTypeSpecifier) { ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) declSpec; specName = compSpec.getName(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java index af5ba7bcc8d..3919caf0722 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Symbian Software Systems and others. + * Copyright (c) 2007, 2009 Symbian Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -110,10 +110,7 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { } catch(CoreException ce) { CCorePlugin.log(ce); throw new CompositingNotImplementedError(ce.getMessage()); - } catch(DOMException ce) { - CCorePlugin.log(ce); - throw new CompositingNotImplementedError(ce.getMessage()); - } + } } /* (non-Javadoc)