mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
bug 86639 - anonymous unions
bug 80940 - content assist didn't consider delcarators subsequent to a match
This commit is contained in:
parent
141d4a2510
commit
acb86c08b9
5 changed files with 186 additions and 74 deletions
|
@ -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):
|
[--Start Example(CPP 10.2-3b):
|
||||||
struct U { static int i; };
|
struct U { static int i; };
|
||||||
|
|
|
@ -4727,6 +4727,32 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
||||||
parse(buffer.toString(), ParserLanguage.CPP, false, 0);
|
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):
|
[--Start Example(CPP 9.5-4):
|
||||||
int foo() {
|
int foo() {
|
||||||
|
|
|
@ -3664,5 +3664,41 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
assertSame( f1, f2 );
|
assertSame( f1, f2 );
|
||||||
assertSame( g1, g2 );
|
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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.ICASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.c.ICASTElaboratedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.c.ICASTElaboratedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope;
|
import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope;
|
||||||
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created on Nov 8, 2004
|
* Created on Nov 8, 2004
|
||||||
|
@ -118,14 +119,14 @@ public class CStructure implements ICompositeType, ICInternalBinding {
|
||||||
if( scope != null )
|
if( scope != null )
|
||||||
scope.addName( name );
|
scope.addName( name );
|
||||||
if( binding != null )
|
if( binding != null )
|
||||||
fields[i] = (IField) binding;
|
fields = (IField[]) ArrayUtil.append( IField.class, fields, binding );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( scope != null )
|
if( scope != null )
|
||||||
scope.setFullyCached( true );
|
scope.setFullyCached( true );
|
||||||
}
|
}
|
||||||
return fields;
|
return (IField[]) ArrayUtil.trim( IField.class, fields );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -146,10 +147,12 @@ public class CStructure implements ICompositeType, ICInternalBinding {
|
||||||
return (IField) binding;
|
return (IField) binding;
|
||||||
} else {
|
} else {
|
||||||
ICASTCompositeTypeSpecifier compSpec = (ICASTCompositeTypeSpecifier) definition.getParent();
|
ICASTCompositeTypeSpecifier compSpec = (ICASTCompositeTypeSpecifier) definition.getParent();
|
||||||
|
ICASTCompositeTypeSpecifier [] specStack = null;
|
||||||
|
int stackIdx = -1;
|
||||||
IASTDeclaration[] members = compSpec.getMembers();
|
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++ ){
|
for( int i = 0; i < size; i++ ){
|
||||||
IASTNode node = members[i];
|
IASTNode node = members[i];
|
||||||
if( node instanceof IASTSimpleDeclaration ){
|
if( node instanceof IASTSimpleDeclaration ){
|
||||||
|
@ -165,6 +168,20 @@ public class CStructure implements ICompositeType, ICInternalBinding {
|
||||||
found = (IField) binding;
|
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 )
|
if( scope != null )
|
||||||
|
@ -172,7 +189,7 @@ public class CStructure implements ICompositeType, ICInternalBinding {
|
||||||
if( found != null )
|
if( found != null )
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1044,7 +1044,7 @@ public class CPPSemantics {
|
||||||
* @throws DOMException
|
* @throws DOMException
|
||||||
*/
|
*/
|
||||||
static protected IASTName[] lookupInScope( CPPSemantics.LookupData data, ICPPScope scope, IASTNode blockItem ) 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 [] nodes = null;
|
||||||
IASTNode parent = scope.getPhysicalNode();
|
IASTNode parent = scope.getPhysicalNode();
|
||||||
|
|
||||||
|
@ -1121,17 +1121,32 @@ public class CPPSemantics {
|
||||||
if( scope instanceof ICPPNamespaceScope )
|
if( scope instanceof ICPPNamespaceScope )
|
||||||
((ICPPNamespaceScope)scope).addUsingDirective( item );
|
((ICPPNamespaceScope)scope).addUsingDirective( item );
|
||||||
} else {
|
} else {
|
||||||
|
//possible is IASTName or IASTName[]
|
||||||
possible = collectResult( data, scope, item, (item == parent) );
|
possible = collectResult( data, scope, item, (item == parent) );
|
||||||
if( possible != null &&
|
if( possible != null ) {
|
||||||
(checkWholeClassScope || declaredBefore( possible, data.astName )) &&
|
int jdx = -1;
|
||||||
|
IASTName temp;
|
||||||
|
if( possible instanceof IASTName )
|
||||||
|
temp = (IASTName) possible;
|
||||||
|
else
|
||||||
|
temp = ((IASTName[])possible)[++jdx];
|
||||||
|
while( temp != null ) {
|
||||||
|
|
||||||
|
if( (checkWholeClassScope || declaredBefore( temp, data.astName )) &&
|
||||||
(item != blockItem || data.includeBlockItem( item )) )
|
(item != blockItem || data.includeBlockItem( item )) )
|
||||||
|
|
||||||
{
|
{
|
||||||
if( data.considerConstructors ||
|
if( data.considerConstructors ||
|
||||||
!( possible.getParent() instanceof IASTDeclarator &&
|
!( temp.getParent() instanceof IASTDeclarator &&
|
||||||
CPPVisitor.isConstructor( scope, (IASTDeclarator) possible.getParent() ) ) )
|
CPPVisitor.isConstructor( scope, (IASTDeclarator) temp.getParent() ) ) )
|
||||||
{
|
{
|
||||||
found = (IASTName[]) ArrayUtil.append( IASTName.class, found, possible );
|
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;
|
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;
|
IASTDeclaration declaration = null;
|
||||||
if( node instanceof ICPPASTTemplateDeclaration )
|
if( node instanceof ICPPASTTemplateDeclaration )
|
||||||
declaration = ((ICPPASTTemplateDeclaration)node).getDeclaration();
|
declaration = ((ICPPASTTemplateDeclaration)node).getDeclaration();
|
||||||
|
@ -1273,44 +1291,88 @@ public class CPPSemantics {
|
||||||
scope.addName( declaratorName );
|
scope.addName( declaratorName );
|
||||||
if( !data.typesOnly || simpleDeclaration.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ) {
|
if( !data.typesOnly || simpleDeclaration.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ) {
|
||||||
if( nameMatches( data, declaratorName ) ) {
|
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
|
//decl spec
|
||||||
IASTDeclSpecifier declSpec = simpleDeclaration.getDeclSpecifier();
|
IASTDeclSpecifier declSpec = simpleDeclaration.getDeclSpecifier();
|
||||||
|
IASTName specName = null;
|
||||||
if( declarators.length == 0 && declSpec instanceof IASTElaboratedTypeSpecifier ){
|
if( declarators.length == 0 && declSpec instanceof IASTElaboratedTypeSpecifier ){
|
||||||
IASTName elabName = ((IASTElaboratedTypeSpecifier)declSpec).getName();
|
specName = ((IASTElaboratedTypeSpecifier)declSpec).getName();
|
||||||
scope.addName( elabName );
|
|
||||||
if( nameMatches( data, elabName ) ) {
|
|
||||||
return elabName;
|
|
||||||
}
|
|
||||||
} else if( declSpec instanceof ICPPASTCompositeTypeSpecifier ){
|
} else if( declSpec instanceof ICPPASTCompositeTypeSpecifier ){
|
||||||
IASTName compName = ((IASTCompositeTypeSpecifier)declSpec).getName();
|
ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) declSpec;
|
||||||
scope.addName( compName );
|
specName = compSpec.getName();
|
||||||
if( nameMatches( data, compName ) ) {
|
|
||||||
return compName;
|
//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 ){
|
} else if( declSpec instanceof IASTEnumerationSpecifier ){
|
||||||
IASTEnumerationSpecifier enumeration = (IASTEnumerationSpecifier) declSpec;
|
IASTEnumerationSpecifier enumeration = (IASTEnumerationSpecifier) declSpec;
|
||||||
IASTName eName = enumeration.getName();
|
specName = enumeration.getName();
|
||||||
scope.addName( eName );
|
|
||||||
if( nameMatches( data, eName ) ) {
|
|
||||||
return eName;
|
|
||||||
}
|
|
||||||
//check enumerators too
|
//check enumerators too
|
||||||
IASTEnumerator [] list = enumeration.getEnumerators();
|
IASTEnumerator [] list = enumeration.getEnumerators();
|
||||||
|
IASTName tempName;
|
||||||
for( int i = 0; i < list.length; i++ ) {
|
for( int i = 0; i < list.length; i++ ) {
|
||||||
IASTEnumerator enumerator = list[i];
|
IASTEnumerator enumerator = list[i];
|
||||||
if( enumerator == null ) break;
|
if( enumerator == null ) break;
|
||||||
eName = enumerator.getName();
|
tempName = enumerator.getName();
|
||||||
scope.addName( eName );
|
scope.addName( tempName );
|
||||||
if( !data.typesOnly && nameMatches( data, eName ) ) {
|
if( !data.typesOnly && nameMatches( data, tempName ) ) {
|
||||||
return eName;
|
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 ){
|
} else if( declaration instanceof ICPPASTUsingDeclaration ){
|
||||||
ICPPASTUsingDeclaration using = (ICPPASTUsingDeclaration) declaration;
|
ICPPASTUsingDeclaration using = (ICPPASTUsingDeclaration) declaration;
|
||||||
IASTName name = using.getName();
|
IASTName name = using.getName();
|
||||||
|
@ -1332,9 +1394,7 @@ public class CPPSemantics {
|
||||||
scope.addName( alias );
|
scope.addName( alias );
|
||||||
if( nameMatches( data, alias ) )
|
if( nameMatches( data, alias ) )
|
||||||
return alias;
|
return alias;
|
||||||
} else
|
} else if( declaration instanceof IASTFunctionDefinition ){
|
||||||
|
|
||||||
if( declaration instanceof IASTFunctionDefinition ){
|
|
||||||
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
|
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
|
||||||
IASTFunctionDeclarator declarator = functionDef.getDeclarator();
|
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 ){
|
private static final boolean nameMatches( LookupData data, IASTName potential ){
|
||||||
|
|
Loading…
Add table
Reference in a new issue