From acb86c08b9492876ad351502c8c9496ef847c161 Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Mon, 25 Apr 2005 17:56:46 +0000 Subject: [PATCH] bug 86639 - anonymous unions bug 80940 - content assist didn't consider delcarators subsequent to a match --- .../tests/ast2/AST2CPPSpecFailingTest.java | 29 ---- .../parser/tests/ast2/AST2CPPSpecTest.java | 26 ++++ .../core/parser/tests/ast2/AST2CPPTests.java | 36 +++++ .../core/dom/parser/c/CStructure.java | 35 +++-- .../core/dom/parser/cpp/CPPSemantics.java | 134 +++++++++++++----- 5 files changed, 186 insertions(+), 74 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java index 7f4eca185ab..41c4b0669f6 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java @@ -494,35 +494,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest { } } - /** - [--Start Example(CPP 9.5-2): - void f() - { - union { int a; char* p; }; - a = 1; - // ... - p = "Jennifer"; - // ... - } - --End Example] - */ - public void test9_5s2() { // TODO raised bug 90650 - StringBuffer buffer = new StringBuffer(); - buffer.append("void f()\n"); //$NON-NLS-1$ - buffer.append("{\n"); //$NON-NLS-1$ - buffer.append("union { int a; char* p; };\n"); //$NON-NLS-1$ - buffer.append("a = 1;\n"); //$NON-NLS-1$ - buffer.append("// ...\n"); //$NON-NLS-1$ - buffer.append("p = \"Jennifer\";\n"); //$NON-NLS-1$ - buffer.append("// ...\n"); //$NON-NLS-1$ - buffer.append("}\n"); //$NON-NLS-1$ - try { - parse(buffer.toString(), ParserLanguage.CPP, true, 0); - assertTrue(false); - } catch (Exception e) { - } - } - /** [--Start Example(CPP 10.2-3b): struct U { static int i; }; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index b60dada39f3..fc401ecb25b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -4727,6 +4727,32 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest { parse(buffer.toString(), ParserLanguage.CPP, false, 0); } + /** + [--Start Example(CPP 9.5-2): + void f() + { + union { int a; char* p; }; + a = 1; + // ... + p = "Jennifer"; + // ... + } + --End Example] + */ + public void test9_5s2() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("void f()\n"); //$NON-NLS-1$ + buffer.append("{\n"); //$NON-NLS-1$ + buffer.append("union { int a; char* p; };\n"); //$NON-NLS-1$ + buffer.append("a = 1;\n"); //$NON-NLS-1$ + buffer.append("// ...\n"); //$NON-NLS-1$ + buffer.append("p = \"Jennifer\";\n"); //$NON-NLS-1$ + buffer.append("// ...\n"); //$NON-NLS-1$ + buffer.append("}\n"); //$NON-NLS-1$ + + parse(buffer.toString(), ParserLanguage.CPP, true, 0); + } + /** [--Start Example(CPP 9.5-4): int foo() { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 62b63ada595..6e88a6b8529 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -3664,5 +3664,41 @@ public class AST2CPPTests extends AST2BaseTest { assertSame( f1, f2 ); assertSame( g1, g2 ); } + + public void testBug86639() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("void f(){ \n"); //$NON-NLS-1$ + buffer.append(" union { int a; char* p; }; \n"); //$NON-NLS-1$ + buffer.append(" a = 1; \n"); //$NON-NLS-1$ + buffer.append("} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$ + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + ICPPField a = (ICPPField) col.getName(2).resolveBinding(); + ICPPField a2 = (ICPPField) col.getName(4).resolveBinding(); + assertSame( a, a2 ); + } + + public void testBug80940() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "void f () { \n"); //$NON-NLS-1$ + buffer.append( " int aa1, aa2; \n"); //$NON-NLS-1$ + buffer.append( " a; \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$ + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + IVariable a1 = (IVariable) col.getName(1).resolveBinding(); + IVariable a2 = (IVariable) col.getName(2).resolveBinding(); + + IBinding [] bs = col.getName(3).resolvePrefix(); + assertEquals( bs.length, 2 ); + assertSame( bs[0], a1 ); + assertSame( bs[1], a2 ); + } } 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 dd29e960c5d..490664e5526 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 @@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef; 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; /** * Created on Nov 8, 2004 @@ -118,14 +119,14 @@ public class CStructure implements ICompositeType, ICInternalBinding { if( scope != null ) scope.addName( name ); if( binding != null ) - fields[i] = (IField) binding; + fields = (IField[]) ArrayUtil.append( IField.class, fields, binding ); } } } if( scope != null ) scope.setFullyCached( true ); } - return fields; + return (IField[]) ArrayUtil.trim( IField.class, fields ); } /* (non-Javadoc) @@ -146,10 +147,12 @@ public class CStructure implements ICompositeType, ICInternalBinding { return (IField) binding; } else { ICASTCompositeTypeSpecifier compSpec = (ICASTCompositeTypeSpecifier) definition.getParent(); + ICASTCompositeTypeSpecifier [] specStack = null; + int stackIdx = -1; IASTDeclaration[] members = compSpec.getMembers(); - int size = members.length; - if( size > 0 ){ - IField found = null; + 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 ){ @@ -165,14 +168,28 @@ public class CStructure implements ICompositeType, ICInternalBinding { 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( scope != null ) - scope.setFullyCached( true ); - if( found != null ) - return found; + if( specStack != null && ++stackIdx < specStack.length && specStack[stackIdx] != null ){ + members = specStack[stackIdx].getMembers(); + } else { + members = null; + } } + if( scope != null ) + scope.setFullyCached( true ); + if( found != null ) + return found; } + return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index 58557ce14cb..1b10b2eb978 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -1044,7 +1044,7 @@ public class CPPSemantics { * @throws DOMException */ static protected IASTName[] lookupInScope( CPPSemantics.LookupData data, ICPPScope scope, IASTNode blockItem ) throws DOMException { - IASTName possible = null; + Object possible = null; IASTNode [] nodes = null; IASTNode parent = scope.getPhysicalNode(); @@ -1121,18 +1121,33 @@ public class CPPSemantics { if( scope instanceof ICPPNamespaceScope ) ((ICPPNamespaceScope)scope).addUsingDirective( item ); } else { + //possible is IASTName or IASTName[] possible = collectResult( data, scope, item, (item == parent) ); - if( possible != null && - (checkWholeClassScope || declaredBefore( possible, data.astName )) && - (item != blockItem || data.includeBlockItem( item )) ) + if( possible != null ) { + int jdx = -1; + IASTName temp; + if( possible instanceof IASTName ) + temp = (IASTName) possible; + else + temp = ((IASTName[])possible)[++jdx]; + while( temp != null ) { - { - if( data.considerConstructors || - !( possible.getParent() instanceof IASTDeclarator && - CPPVisitor.isConstructor( scope, (IASTDeclarator) possible.getParent() ) ) ) - { - found = (IASTName[]) ArrayUtil.append( IASTName.class, found, possible ); - } + if( (checkWholeClassScope || declaredBefore( temp, data.astName )) && + (item != blockItem || data.includeBlockItem( item )) ) + + { + if( data.considerConstructors || + !( temp.getParent() instanceof IASTDeclarator && + CPPVisitor.isConstructor( scope, (IASTDeclarator) temp.getParent() ) ) ) + { + found = (IASTName[]) ArrayUtil.append( IASTName.class, found, temp ); + } + } + if( ++jdx > 0 && jdx < ((IASTName[])possible).length ) + temp = ((IASTName[])possible)[jdx]; + else + temp = null; + } } } @@ -1232,7 +1247,10 @@ public class CPPSemantics { return transitives; } - static private IASTName collectResult( CPPSemantics.LookupData data, ICPPScope scope, IASTNode node, boolean checkAux ) throws DOMException{ + static private Object collectResult( CPPSemantics.LookupData data, ICPPScope scope, IASTNode node, boolean checkAux ) throws DOMException{ + IASTName resultName = null; + IASTName [] resultArray = null; + IASTDeclaration declaration = null; if( node instanceof ICPPASTTemplateDeclaration ) declaration = ((ICPPASTTemplateDeclaration)node).getDeclaration(); @@ -1250,7 +1268,7 @@ public class CPPSemantics { IASTName declName = dtor.getName(); scope.addName( declName ); if( !data.typesOnly && nameMatches( data, declName ) ) { - return declName; + return declName; } } else if( node instanceof ICPPASTTemplateParameter ){ IASTName name = CPPTemplates.getTemplateParameterName( (ICPPASTTemplateParameter) node ); @@ -1273,44 +1291,88 @@ public class CPPSemantics { scope.addName( declaratorName ); if( !data.typesOnly || simpleDeclaration.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ) { if( nameMatches( data, declaratorName ) ) { - return declaratorName; + if( resultName == null ) + resultName = declaratorName; + else if( resultArray == null ) + resultArray = new IASTName[] { resultName, declaratorName }; + else + resultArray = (IASTName[]) ArrayUtil.append( IASTName.class, resultArray, declaratorName ); } } } //decl spec IASTDeclSpecifier declSpec = simpleDeclaration.getDeclSpecifier(); + IASTName specName = null; if( declarators.length == 0 && declSpec instanceof IASTElaboratedTypeSpecifier ){ - IASTName elabName = ((IASTElaboratedTypeSpecifier)declSpec).getName(); - scope.addName( elabName ); - if( nameMatches( data, elabName ) ) { - return elabName; - } + specName = ((IASTElaboratedTypeSpecifier)declSpec).getName(); } else if( declSpec instanceof ICPPASTCompositeTypeSpecifier ){ - IASTName compName = ((IASTCompositeTypeSpecifier)declSpec).getName(); - scope.addName( compName ); - if( nameMatches( data, compName ) ) { - return compName; + ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) declSpec; + specName = compSpec.getName(); + + //anonymous union? + if( declarators.length == 0 && compSpec.getKey() == IASTCompositeTypeSpecifier.k_union && + specName.toCharArray().length == 0 ) + { + Object o = null; + IASTDeclaration [] decls = compSpec.getMembers(); + for ( int i = 0; i < decls.length; i++ ) { + o = collectResult( data, scope, decls[i], checkAux ); + if( o instanceof IASTName ){ + if( resultName == null ) + resultName = (IASTName) o; + else if( resultArray == null ) + resultArray = new IASTName[] { resultName, (IASTName) o }; + else + resultArray = (IASTName[]) ArrayUtil.append( IASTName.class, resultArray, o ); + } else if( o instanceof IASTName [] ){ + IASTName [] oa = (IASTName[]) o; + if( resultName == null ){ + resultName = oa[0]; + resultArray = oa; + } else if( resultArray == null ){ + resultArray = new IASTName[ 1 + oa.length ]; + resultArray[0] = resultName; + resultArray = (IASTName[]) ArrayUtil.addAll( IASTName.class, resultArray, oa ); + } else { + resultArray = (IASTName[]) ArrayUtil.addAll( IASTName.class, resultArray, oa ); + } + } + } } } else if( declSpec instanceof IASTEnumerationSpecifier ){ IASTEnumerationSpecifier enumeration = (IASTEnumerationSpecifier) declSpec; - IASTName eName = enumeration.getName(); - scope.addName( eName ); - if( nameMatches( data, eName ) ) { - return eName; - } + specName = enumeration.getName(); + //check enumerators too IASTEnumerator [] list = enumeration.getEnumerators(); + IASTName tempName; for( int i = 0; i < list.length; i++ ) { IASTEnumerator enumerator = list[i]; if( enumerator == null ) break; - eName = enumerator.getName(); - scope.addName( eName ); - if( !data.typesOnly && nameMatches( data, eName ) ) { - return eName; + tempName = enumerator.getName(); + scope.addName( tempName ); + if( !data.typesOnly && nameMatches( data, tempName ) ) { + if( resultName == null ) + resultName = tempName; + else if( resultArray == null ) + resultArray = new IASTName[] { resultName, tempName }; + else + resultArray = (IASTName[]) ArrayUtil.append( IASTName.class, resultArray, tempName ); } } } + if( specName != null ) { + scope.addName( specName ); + if( nameMatches( data, specName ) ) { + if( resultName == null ) + resultName = specName; + else if( resultArray == null ) + resultArray = new IASTName[] { resultName, specName }; + else + resultArray = (IASTName[]) ArrayUtil.append( IASTName.class, resultArray, specName ); + } + } } else if( declaration instanceof ICPPASTUsingDeclaration ){ ICPPASTUsingDeclaration using = (ICPPASTUsingDeclaration) declaration; IASTName name = using.getName(); @@ -1332,9 +1394,7 @@ public class CPPSemantics { scope.addName( alias ); if( nameMatches( data, alias ) ) return alias; - } else - - if( declaration instanceof IASTFunctionDefinition ){ + } else if( declaration instanceof IASTFunctionDefinition ){ IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration; IASTFunctionDeclarator declarator = functionDef.getDeclarator(); @@ -1347,7 +1407,9 @@ public class CPPSemantics { } } - return null; + if( resultArray != null ) + return resultArray; + return resultName; } private static final boolean nameMatches( LookupData data, IASTName potential ){