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):
|
||||
struct U { static int i; };
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ){
|
||||
|
|
Loading…
Add table
Reference in a new issue