1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Fix for 190730, Navigating functions containing a typedef to an anonymous type in the parameter list.

This commit is contained in:
Markus Schorn 2007-06-05 11:06:35 +00:00
parent 6375411080
commit cda496da2c
6 changed files with 322 additions and 68 deletions

View file

@ -16,6 +16,8 @@ import junit.framework.TestSuite;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IType;
@ -83,4 +85,46 @@ public class IndexCBindingResolutionBugs extends IndexBindingResolutionTestBase
IBinding b0 = getBindingFromASTName("func1;", 5);
assertTrue(b0 instanceof IFunction);
}
// typedef struct {
// int utm;
// } usertype;
// void func(usertype t);
// #include "header.h"
// void test() {
// usertype ut;
// func(ut);
// }
public void testFuncWithTypedefForAnonymousStruct_190730() throws Exception {
IBinding b0 = getBindingFromASTName("func(", 4);
assertTrue(b0 instanceof IFunction);
IFunction f= (IFunction) b0;
IParameter[] pars= f.getParameters();
assertEquals(1, pars.length);
IType type= pars[0].getType();
assertTrue(type instanceof ICompositeType);
}
// typedef enum {
// eItem
// } userEnum;
// void func(userEnum t);
// #include "header.h"
// void test() {
// userEnum ut;
// func(ut);
// }
public void testFuncWithTypedefForAnonymousEnum_190730() throws Exception {
IBinding b0 = getBindingFromASTName("func(", 4);
assertTrue(b0 instanceof IFunction);
IFunction f= (IFunction) b0;
IParameter[] pars= f.getParameters();
assertEquals(1, pars.length);
IType type= pars[0].getType();
assertTrue(type instanceof IEnumeration);
// type= ((ITypedef) type).getType();
// assertTrue(type instanceof IEnumeration);
}
}

View file

@ -16,9 +16,12 @@ import junit.framework.TestSuite;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@ -338,4 +341,48 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas
IBinding b0 = getBindingFromASTName("field;//", 5);
assertTrue(b0 instanceof ICPPField);
}
// typedef struct {
// int utm;
// } usertype;
// void func(usertype t);
// #include "header.h"
// void test() {
// usertype ut;
// func(ut);
// }
public void testFuncWithTypedefForAnonymousStruct_190730() throws Exception {
IBinding b0 = getBindingFromASTName("func(", 4);
assertTrue(b0 instanceof IFunction);
IFunction f= (IFunction) b0;
IParameter[] pars= f.getParameters();
assertEquals(1, pars.length);
IType type= pars[0].getType();
assertTrue(type instanceof ITypedef);
type= ((ITypedef) type).getType();
assertTrue(type instanceof ICPPClassType);
}
// typedef enum {
// eItem
// } userEnum;
// void func(userEnum t);
// #include "header.h"
// void test() {
// userEnum ut;
// func(ut);
// }
public void testFuncWithTypedefForAnonymousEnum_190730() throws Exception {
IBinding b0 = getBindingFromASTName("func(", 4);
assertTrue(b0 instanceof IFunction);
IFunction f= (IFunction) b0;
IParameter[] pars= f.getParameters();
assertEquals(1, pars.length);
IType type= pars[0].getType();
assertTrue(type instanceof ITypedef);
type= ((ITypedef) type).getType();
assertTrue(type instanceof IEnumeration);
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* Copyright (c) 2005, 2007 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
@ -7,17 +7,28 @@
*
* Contributors:
* Rational Software - initial implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
import java.util.LinkedList;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
import org.eclipse.cdt.core.dom.ast.c.ICBasicType;
import org.eclipse.cdt.core.dom.ast.c.ICPointerType;
import org.eclipse.cdt.core.dom.ast.c.ICQualifierType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPBasicType;
@ -29,8 +40,10 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTTypeId;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.cdt.internal.core.dom.parser.c.ICInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
/**
* This is a utility class to help convert AST elements to Strings corresponding to the
@ -199,13 +212,13 @@ public class ASTTypeUtil {
// result.append(SPACE);
if(type instanceof ICPPClassType) {
try {
String qn = CPPVisitor.renderQualifiedName(((ICPPClassType)type).getQualifiedName());
String qn = CPPVisitor.renderQualifiedName(getQualifiedNameForAnonymous((ICPPClassType)type));
result.append(qn);
} catch(DOMException de) {
result.append(((ICompositeType)type).getName());
result.append(getNameForAnonymous((ICompositeType)type));
}
} else {
result.append(((ICompositeType)type).getName());
result.append(getNameForAnonymous((ICompositeType)type));
}
} else if (type instanceof ICPPReferenceType) {
result.append(Keywords.cpAMPER);
@ -216,7 +229,7 @@ public class ASTTypeUtil {
} else if (type instanceof IEnumeration) {
result.append(Keywords.ENUM);
result.append(SPACE);
result.append(((IEnumeration)type).getName());
result.append(getNameForAnonymous((IEnumeration)type));
} else if (type instanceof IFunctionType) {
try {
String temp = getType(((IFunctionType)type).getReturnType());
@ -256,7 +269,7 @@ public class ASTTypeUtil {
return result.toString();
}
/**
* Returns the type represntation of the IType as a String. This function uses the IType interfaces to build the
* String representation of the IType.
@ -448,4 +461,97 @@ public class ASTTypeUtil {
}
}
private static String[] getQualifiedNameForAnonymous(ICPPBinding binding) throws DOMException {
LinkedList result= new LinkedList();
result.addFirst(getNameForAnonymous(binding));
ICPPScope scope = (ICPPScope) binding.getScope();
while( scope != null ){
if (scope instanceof ICPPBlockScope || scope instanceof ICPPFunctionScope) {
break;
}
if (!(scope instanceof ICPPTemplateScope)) {
IName n = scope.getScopeName();
if (n == null) {
break;
}
char[] name= n.toCharArray();
if (name.length == 0){
if (!(scope instanceof ICPPNamespaceScope)) {
name= createNameForAnonymous(scope);
if (name == null) {
break;
}
result.addFirst(new String(name));
}
}
else {
result.addFirst(new String(name));
}
}
scope = (ICPPScope) scope.getParent();
}
return (String[]) result.toArray(new String[result.size()]);
}
private static String getNameForAnonymous(IBinding binding) {
char[] name= binding.getNameCharArray();
if (name == null || name.length == 0) {
char[] altname= createNameForAnonymous(binding);
if (altname != null) {
return new String(altname);
}
}
return new String(name);
}
private static char[] createNameForAnonymous(ICPPScope scope) {
if (scope instanceof ICPPClassScope) {
return createNameForAnonymous(((ICPPClassScope) scope).getClassType());
}
return null;
}
public static char[] createNameForAnonymous(IBinding binding) {
IASTNode node= null;
if (binding instanceof ICInternalBinding) {
node= ((ICInternalBinding) binding).getPhysicalNode();
}
else if (binding instanceof ICPPInternalBinding) {
node= ((ICPPInternalBinding) binding).getDefinition();
}
if (node != null) {
IASTFileLocation loc= node.getFileLocation();
if (loc == null) {
node= node.getParent();
if (node != null) {
loc= node.getFileLocation();
}
}
if (loc != null) {
char[] fname= loc.getFileName().toCharArray();
int fnamestart= findFileNameStart(fname);
StringBuffer buf= new StringBuffer();
buf.append('{');
buf.append(fname, fnamestart, fname.length-fnamestart);
buf.append(':');
buf.append(loc.getNodeOffset());
buf.append('}');
return buf.toString().toCharArray();
}
}
return null;
}
private static int findFileNameStart(char[] fname) {
for (int i= fname.length-2; i>=0; i--) {
switch (fname[i]) {
case '/':
case '\\':
return i+1;
}
}
return 0;
}
}

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.pdom.dom;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
@ -33,8 +34,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.internal.core.dom.parser.c.ICInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.core.runtime.CoreException;
public class PDOMASTAdapter {
@ -357,19 +356,19 @@ public class PDOMASTAdapter {
char[] name= binding.getNameCharArray();
if (name.length == 0) {
if (binding instanceof IEnumeration) {
name= createNameForAnonymous(binding);
name= ASTTypeUtil.createNameForAnonymous(binding);
if (name != null) {
return new AnonymousEnumeration(name, (IEnumeration) binding);
}
}
else if (binding instanceof ICPPClassType) {
name= createNameForAnonymous(binding);
name= ASTTypeUtil.createNameForAnonymous(binding);
if (name != null) {
return new AnonymousClassType(name, (ICPPClassType) binding);
}
}
else if (binding instanceof ICompositeType) {
name= createNameForAnonymous(binding);
name= ASTTypeUtil.createNameForAnonymous(binding);
if (name != null) {
return new AnonymousCompositeType(name, (ICompositeType) binding);
}
@ -380,48 +379,6 @@ public class PDOMASTAdapter {
return binding;
}
private static char[] createNameForAnonymous(IBinding binding) {
IASTNode node= null;
if (binding instanceof ICInternalBinding) {
node= ((ICInternalBinding) binding).getPhysicalNode();
}
else if (binding instanceof ICPPInternalBinding) {
node= ((ICPPInternalBinding) binding).getDefinition();
}
if (node != null) {
IASTFileLocation loc= node.getFileLocation();
if (loc == null) {
node= node.getParent();
if (node != null) {
loc= node.getFileLocation();
}
}
if (loc != null) {
char[] fname= loc.getFileName().toCharArray();
int fnamestart= findFileNameStart(fname);
StringBuffer buf= new StringBuffer();
buf.append('{');
buf.append(fname, fnamestart, fname.length-fnamestart);
buf.append(':');
buf.append(loc.getNodeOffset());
buf.append('}');
return buf.toString().toCharArray();
}
}
return null;
}
private static int findFileNameStart(char[] fname) {
for (int i= fname.length-2; i>=0; i--) {
switch (fname[i]) {
case '/':
case '\\':
return i+1;
}
}
return 0;
}
/**
* If the name is empty and has no file location, either an adapter
* that has a file location is returned, or <code>null</code> if that

View file

@ -791,4 +791,56 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
decl = testF3(cfile, offset1);
assertNode("c", offset0, decl);
}
// typedef struct {
// int a;
// } usertype;
// void func(usertype t);
// #include "testBug190730.h"
// void func(usertype t) {
// }
public void testFuncWithTypedefForAnonymousStruct_190730() throws Exception {
StringBuffer[] buffers= getContents(2);
String hcode= buffers[0].toString();
String scode= buffers[1].toString();
IFile hfile = importFile("testBug190730.h", hcode);
IFile file = importFile("testBug190730.cpp", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, MAX_WAIT_TIME);
IASTNode decl;
int offset0, offset1;
offset0 = hcode.indexOf("func");
offset1 = scode.indexOf("func");
decl = testF3(hfile, offset0);
assertNode("func", offset1, decl);
decl = testF3(file, offset1);
assertNode("func", offset0, decl);
}
// typedef enum {
// int eitem
// } userEnum;
// void func(userEnum t);
// #include "testBug190730_2.h"
// void func(userEnum t) {
// }
public void testFuncWithTypedefForAnonymousEnum_190730() throws Exception {
StringBuffer[] buffers= getContents(2);
String hcode= buffers[0].toString();
String scode= buffers[1].toString();
IFile hfile = importFile("testBug190730_2.h", hcode);
IFile file = importFile("testBug190730_2.cpp", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, MAX_WAIT_TIME);
IASTNode decl;
int offset0, offset1;
offset0 = hcode.indexOf("func");
offset1 = scode.indexOf("func");
decl = testF3(hfile, offset0);
assertNode("func", offset1, decl);
decl = testF3(file, offset1);
assertNode("func", offset0, decl);
}
}

View file

@ -15,7 +15,6 @@ import java.io.IOException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMManager;
@ -33,13 +32,10 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
public abstract class CSelectionTestsAnyIndexer extends BaseSelectionTestsIndexer {
private static final int MAX_WAIT_TIME = 8000;
private IFile file;
private IFile hfile;
private NullProgressMonitor monitor;
private String sourceIndexerID;
private IIndex index;
public CSelectionTestsAnyIndexer(String name, String indexerID) {
super(name);
sourceIndexerID= indexerID;
@ -96,8 +92,8 @@ public abstract class CSelectionTestsAnyIndexer extends BaseSelectionTestsIndexe
StringBuffer[] buffers= getContents(2);
String hcode= buffers[0].toString();
String scode= buffers[1].toString();
hfile = importFile("basicDefinition.h", hcode);
file = importFile("testBasicDefinition.c", scode);
IFile hfile = importFile("basicDefinition.h", hcode);
IFile file = importFile("testBasicDefinition.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, MAX_WAIT_TIME);
int hoffset= hcode.indexOf("MyInt");
@ -178,8 +174,8 @@ public abstract class CSelectionTestsAnyIndexer extends BaseSelectionTestsIndexe
StringBuffer[] buffers= getContents(2);
String hcode= buffers[0].toString();
String scode= buffers[1].toString();
hfile = importFile("testCPPSpecDeclsDefs.h", hcode);
file = importFile("testCPPSpecDeclsDefs.c", scode);
IFile hfile = importFile("testCPPSpecDeclsDefs.h", hcode);
IFile file = importFile("testCPPSpecDeclsDefs.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, MAX_WAIT_TIME);
int offset0= hcode.indexOf("a;");
@ -290,8 +286,8 @@ public abstract class CSelectionTestsAnyIndexer extends BaseSelectionTestsIndexe
StringBuffer[] buffers= getContents(2);
String hcode= buffers[0].toString();
String scode= buffers[1].toString();
hfile = importFile("testBug101287.h", hcode);
file = importFile("testBug101287.c", scode);
IFile hfile = importFile("testBug101287.h", hcode);
IFile file = importFile("testBug101287.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, MAX_WAIT_TIME);
IASTNode decl;
int offset0, offset1;
@ -314,8 +310,8 @@ public abstract class CSelectionTestsAnyIndexer extends BaseSelectionTestsIndexe
StringBuffer[] buffers= getContents(2);
String hcode= buffers[0].toString();
String scode= buffers[1].toString();
hfile = importFileWithLink("testBug103697.h", hcode);
file = importFileWithLink("testBug103697.c", scode);
IFile hfile = importFileWithLink("testBug103697.h", hcode);
IFile file = importFileWithLink("testBug103697.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, MAX_WAIT_TIME);
IASTNode decl;
int offset0, offset1;
@ -342,8 +338,8 @@ public abstract class CSelectionTestsAnyIndexer extends BaseSelectionTestsIndexe
StringBuffer[] buffers= getContents(2);
String hcode= buffers[0].toString();
String scode= buffers[1].toString();
hfile = importFile("testBug78354.h", hcode);
file = importFile("testBug78354.c", scode);
IFile hfile = importFile("testBug78354.h", hcode);
IFile file = importFile("testBug78354.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, MAX_WAIT_TIME);
IASTNode decl;
int offset0, offset1;
@ -362,4 +358,56 @@ public abstract class CSelectionTestsAnyIndexer extends BaseSelectionTestsIndexe
decl = testF3(file, offset1);
assertNode("TestTypeTwo", offset0, decl);
}
// typedef struct {
// int a;
// } usertype;
// void func(usertype t);
// #include "testBug190730.h"
// void func(usertype t) {
// }
public void testFuncWithTypedefForAnonymousStruct_190730() throws Exception {
StringBuffer[] buffers= getContents(2);
String hcode= buffers[0].toString();
String scode= buffers[1].toString();
IFile hfile = importFile("testBug190730.h", hcode);
IFile file = importFile("testBug190730.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, MAX_WAIT_TIME);
IASTNode decl;
int offset0, offset1;
offset0 = hcode.indexOf("func");
offset1 = scode.indexOf("func");
decl = testF3(hfile, offset0);
assertNode("func", offset1, decl);
decl = testF3(file, offset1);
assertNode("func", offset0, decl);
}
// typedef enum {
// int eitem
// } userEnum;
// void func(userEnum t);
// #include "testBug190730_2.h"
// void func(userEnum t) {
// }
public void testFuncWithTypedefForAnonymousEnum_190730() throws Exception {
StringBuffer[] buffers= getContents(2);
String hcode= buffers[0].toString();
String scode= buffers[1].toString();
IFile hfile = importFile("testBug190730_2.h", hcode);
IFile file = importFile("testBug190730_2.c", scode);
TestSourceReader.waitUntilFileIsIndexed(index, file, MAX_WAIT_TIME);
IASTNode decl;
int offset0, offset1;
offset0 = hcode.indexOf("func");
offset1 = scode.indexOf("func");
decl = testF3(hfile, offset0);
assertNode("func", offset1, decl);
decl = testF3(file, offset1);
assertNode("func", offset0, decl);
}
}